command=termlist without name parameter returns all termlists
authorAdam Dickmeiss <adam@indexdata.dk>
Fri, 30 Sep 2011 12:00:56 +0000 (14:00 +0200)
committerAdam Dickmeiss <adam@indexdata.dk>
Fri, 30 Sep 2011 12:00:56 +0000 (14:00 +0200)
Previously if name parameter was omitted, only "subject" was returned.

NEWS
doc/pazpar2_protocol.xml
src/http_command.c
src/session.c
src/session.h
test/test_facets_11.res
test/test_facets_14.res
test/test_facets_17.res
test/test_facets_18.res
test/test_facets_24.res
test/test_facets_6.res

diff --git a/NEWS b/NEWS
index 142f08e..66ab475 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,7 @@
+
+command=termlist without name parameter returns all termlists/facets.
+Previously if name parameter was omitted, only "subject" was returned.
+
 --- 1.6.3 2011/09/22
 
 Make termlist sorting stable. Terms with same frequency are now sorted by
index 893043a..a9e28b8 100644 (file)
@@ -514,7 +514,8 @@ search.pz2?session=605047297&command=record&id=3
       <term>name</term>
       <listitem>
        <para>
-       comma-separated list of termlist names (default "subject")
+       comma-separated list of termlist names. If omitted,
+       all termlists are returned.
        </para>
       </listitem>
      </varlistentry>
index b46ba7b..07e37be 100644 (file)
@@ -489,55 +489,6 @@ static void cmd_settings(struct http_channel *c)
     release_session(c, s);
 }
 
-// Compares two hitsbytarget nodes by hitcount
-static int cmp_ht(const void *p1, const void *p2)
-{
-    const struct hitsbytarget *h1 = p1;
-    const struct hitsbytarget *h2 = p2;
-    return h2->hits - h1->hits;
-}
-
-// This implements functionality somewhat similar to 'bytarget', but in a termlist form
-static int targets_termlist(WRBUF wrbuf, struct session *se, int num,
-                             NMEM nmem)
-{
-    struct hitsbytarget *ht;
-    int count, i;
-
-    ht = hitsbytarget(se, &count, nmem);
-    qsort(ht, count, sizeof(struct hitsbytarget), cmp_ht);
-    for (i = 0; i < count && i < num && ht[i].hits > 0; i++)
-    {
-
-        // do only print terms which have display names
-    
-        wrbuf_puts(wrbuf, "<term>\n");
-
-        wrbuf_puts(wrbuf, "<id>");
-        wrbuf_xmlputs(wrbuf, ht[i].id);
-        wrbuf_puts(wrbuf, "</id>\n");
-        
-        wrbuf_puts(wrbuf, "<name>");
-        if (!ht[i].name || !ht[i].name[0])
-            wrbuf_xmlputs(wrbuf, "NO TARGET NAME");
-        else
-            wrbuf_xmlputs(wrbuf, ht[i].name);
-        wrbuf_puts(wrbuf, "</name>\n");
-        
-        wrbuf_printf(wrbuf, "<frequency>" ODR_INT_PRINTF "</frequency>\n",
-                     ht[i].hits);
-        
-        wrbuf_puts(wrbuf, "<state>");
-        wrbuf_xmlputs(wrbuf, ht[i].state);
-        wrbuf_puts(wrbuf, "</state>\n");
-        
-        wrbuf_printf(wrbuf, "<diagnostic>%d</diagnostic>\n", 
-                     ht[i].diagnostic);
-        wrbuf_puts(wrbuf, "</term>\n");
-    }
-    return count;
-}
-
 static void cmd_termlist(struct http_channel *c)
 {
     struct http_response *rs = c->response;
@@ -547,79 +498,23 @@ static void cmd_termlist(struct http_channel *c)
     const char *nums = http_argbyname(rq, "num");
     int num = 15;
     int status;
-    WRBUF debug_log = 0;
 
     if (!s)
         return;
 
     status = session_active_clients(s->psession);
 
-    if (!name)
-        name = "subject";
-    if (strlen(name) > 255)
-        return;
     if (nums)
         num = atoi(nums);
 
-    debug_log = wrbuf_alloc();
-
     wrbuf_rewind(c->wrbuf);
 
     wrbuf_puts(c->wrbuf, "<termlist>\n");
     wrbuf_printf(c->wrbuf, "<activeclients>%d</activeclients>\n", status);
-    while (*name)
-    {
-        char tname[256];
-        const char *tp;
-
-        if (!(tp = strchr(name, ',')))
-            tp = name + strlen(name);
-        strncpy(tname, name, tp - name);
-        tname[tp - name] = '\0';
-        wrbuf_puts(c->wrbuf, "<list name=\"");
-        wrbuf_xmlputs(c->wrbuf, tname);
-        wrbuf_puts(c->wrbuf, "\">\n");
-        if (!strcmp(tname, "xtargets"))
-        {
-            int targets = targets_termlist(c->wrbuf, s->psession, num, c->nmem);
-            wrbuf_printf(debug_log, " xtargets: %d", targets);
-        }
-        else
-        {
-            int len;
-            struct termlist_score **p = 
-                get_termlist_score(s->psession, tname, &len);
-            if (p && len)
-                wrbuf_printf(debug_log, " %s: %d", tname, len);
-            if (p)
-            {
-                int i;
-                for (i = 0; i < len && i < num; i++)
-                {
-                    // prevnt sending empty term elements
-                    if (!p[i]->display_term || !p[i]->display_term[0])
-                        continue;
-
-                    wrbuf_puts(c->wrbuf, "<term>");
-                    wrbuf_puts(c->wrbuf, "<name>");
-                    wrbuf_xmlputs(c->wrbuf, p[i]->display_term);
-                    wrbuf_puts(c->wrbuf, "</name>");
-                    
-                    wrbuf_printf(c->wrbuf, 
-                                 "<frequency>%d</frequency>", 
-                                 p[i]->frequency);
-                    wrbuf_puts(c->wrbuf, "</term>\n");
-                }
-            }
-        }
-        wrbuf_puts(c->wrbuf, "</list>\n");
-        name = tp;
-        if (*name == ',')
-            name++;
-    }
+
+    perform_termlist(c, s->psession, name, num);
+
     wrbuf_puts(c->wrbuf, "</termlist>\n");
-    yaz_log(YLOG_DEBUG, "termlist response: %s ", wrbuf_cstr(debug_log));
-    wrbuf_destroy(debug_log);
     rs->payload = nmem_strdup(rq->channel->nmem, wrbuf_cstr(c->wrbuf));
     http_send_response(c);
     release_session(c, s);
@@ -711,7 +606,7 @@ static void cmd_bytarget(struct http_channel *c)
 
     if (!s)
         return;
-    ht = hitsbytarget(s->psession, &count, c->nmem);
+    ht = get_hitsbytarget(s->psession, &count, c->nmem);
     wrbuf_rewind(c->wrbuf);
     wrbuf_puts(c->wrbuf, HTTP_COMMAND_RESPONSE_PREFIX "<bytarget><status>OK</status>");
 
index 72feef6..697df85 100644 (file)
@@ -837,13 +837,13 @@ struct session *new_session(NMEM nmem, struct conf_service *service,
     return session;
 }
 
-struct hitsbytarget *hitsbytarget(struct session *se, int *count, NMEM nmem)
+static struct hitsbytarget *hitsbytarget_nb(struct session *se,
+                                            int *count, NMEM nmem)
 {
     struct hitsbytarget *res = 0;
     struct client_list *l;
     size_t sz = 0;
 
-    session_enter(se);
     for (l = se->clients; l; l = l->next)
         sz++;
 
@@ -868,10 +868,18 @@ struct hitsbytarget *hitsbytarget(struct session *se, int *count, NMEM nmem)
         wrbuf_destroy(w);
         (*count)++;
     }
-    session_leave(se);
     return res;
 }
 
+struct hitsbytarget *get_hitsbytarget(struct session *se, int *count, NMEM nmem)
+{
+    struct hitsbytarget *p;
+    session_enter(se);
+    p = hitsbytarget_nb(se, count, nmem);
+    session_leave(se);
+    return p;
+}
+    
 struct termlist_score **get_termlist_score(struct session *se,
                                            const char *name, int *num)
 {
@@ -889,6 +897,118 @@ struct termlist_score **get_termlist_score(struct session *se,
     return tl;
 }
 
+// Compares two hitsbytarget nodes by hitcount
+static int cmp_ht(const void *p1, const void *p2)
+{
+    const struct hitsbytarget *h1 = p1;
+    const struct hitsbytarget *h2 = p2;
+    return h2->hits - h1->hits;
+}
+
+static int targets_termlist_nb(WRBUF wrbuf, struct session *se, int num,
+                               NMEM nmem)
+{
+    struct hitsbytarget *ht;
+    int count, i;
+
+    ht = hitsbytarget_nb(se, &count, nmem);
+    qsort(ht, count, sizeof(struct hitsbytarget), cmp_ht);
+    for (i = 0; i < count && i < num && ht[i].hits > 0; i++)
+    {
+
+        // do only print terms which have display names
+    
+        wrbuf_puts(wrbuf, "<term>\n");
+
+        wrbuf_puts(wrbuf, "<id>");
+        wrbuf_xmlputs(wrbuf, ht[i].id);
+        wrbuf_puts(wrbuf, "</id>\n");
+        
+        wrbuf_puts(wrbuf, "<name>");
+        if (!ht[i].name || !ht[i].name[0])
+            wrbuf_xmlputs(wrbuf, "NO TARGET NAME");
+        else
+            wrbuf_xmlputs(wrbuf, ht[i].name);
+        wrbuf_puts(wrbuf, "</name>\n");
+        
+        wrbuf_printf(wrbuf, "<frequency>" ODR_INT_PRINTF "</frequency>\n",
+                     ht[i].hits);
+        
+        wrbuf_puts(wrbuf, "<state>");
+        wrbuf_xmlputs(wrbuf, ht[i].state);
+        wrbuf_puts(wrbuf, "</state>\n");
+        
+        wrbuf_printf(wrbuf, "<diagnostic>%d</diagnostic>\n", 
+                     ht[i].diagnostic);
+        wrbuf_puts(wrbuf, "</term>\n");
+    }
+    return count;
+}
+
+void perform_termlist(struct http_channel *c, struct session *se,
+                      const char *name, int num)
+{
+    int i, j;
+    NMEM nmem_tmp = nmem_create();
+    char **names;
+    int num_names = 0;
+
+    if (name)
+        nmem_strsplit(nmem_tmp, ",", name, &names, &num_names);
+
+    session_enter(se);
+
+    for (j = 0; j < num_names; j++)
+    {
+        const char *tname;
+        for (i = 0; i < se->num_termlists; i++)
+        {
+            tname = se->termlists[i].name;
+            if (num_names > 0 && !strcmp(names[j], tname))
+            {
+                struct termlist_score **p = 0;
+                int len;
+                p = termlist_highscore(se->termlists[i].termlist, &len);
+                if (p)
+                {
+                    int i;
+                    wrbuf_puts(c->wrbuf, "<list name=\"");
+                    wrbuf_xmlputs(c->wrbuf, tname);
+                    wrbuf_puts(c->wrbuf, "\">\n");
+                    for (i = 0; i < len && i < num; i++)
+                    {
+                        // prevent sending empty term elements
+                        if (!p[i]->display_term || !p[i]->display_term[0])
+                            continue;
+                        
+                        wrbuf_puts(c->wrbuf, "<term>");
+                        wrbuf_puts(c->wrbuf, "<name>");
+                        wrbuf_xmlputs(c->wrbuf, p[i]->display_term);
+                        wrbuf_puts(c->wrbuf, "</name>");
+                        
+                        wrbuf_printf(c->wrbuf, 
+                                     "<frequency>%d</frequency>", 
+                                     p[i]->frequency);
+                        wrbuf_puts(c->wrbuf, "</term>\n");
+                    }
+                    wrbuf_puts(c->wrbuf, "</list>\n");
+                }
+            }
+        }
+        tname = "xtargets";
+        if (num_names > 0 && !strcmp(names[j], tname))
+        {
+            wrbuf_puts(c->wrbuf, "<list name=\"");
+            wrbuf_xmlputs(c->wrbuf, tname);
+            wrbuf_puts(c->wrbuf, "\">\n");
+            targets_termlist_nb(c->wrbuf, se, num, c->nmem);
+            wrbuf_puts(c->wrbuf, "</list>\n");
+        }
+    }
+    session_leave(se);
+    nmem_destroy(nmem_tmp);
+}
+
 #ifdef MISSING_HEADERS
 void report_nmem_stats(void)
 {
index fbb4e3c..342665e 100644 (file)
@@ -145,7 +145,7 @@ struct hitsbytarget {
     char *settings_xml;
 };
 
-struct hitsbytarget *hitsbytarget(struct session *s, int *count, NMEM nmem);
+struct hitsbytarget *get_hitsbytarget(struct session *s, int *count, NMEM nmem);
 struct session *new_session(NMEM nmem, struct conf_service *service,
                             unsigned session_id);
 void destroy_session(struct session *s);
@@ -179,6 +179,9 @@ int host_getaddrinfo(struct host *host, iochan_man_t iochan_man);
 int ingest_record(struct client *cl, const char *rec, int record_no, NMEM nmem);
 void session_alert_watch(struct session *s, int what);
 void add_facet(struct session *s, const char *type, const char *value, int count);
+
+void perform_termlist(struct http_channel *c, struct session *se,
+                      const char *name, int num);
 void session_log(struct session *s, int level, const char *fmt, ...)
 #ifdef __GNUC__
     __attribute__ ((format (printf, 3, 4)))
index a63c538..0a65480 100644 (file)
@@ -45,6 +45,4 @@
 <term><name>date8</name><frequency>20</frequency></term>
 <term><name>date9</name><frequency>10</frequency></term>
 </list>
-<list name="medium">
-</list>
 </termlist>
index 812c1c9..f9bb62c 100644 (file)
@@ -45,6 +45,4 @@
 <term><name>date8</name><frequency>20</frequency></term>
 <term><name>date9</name><frequency>10</frequency></term>
 </list>
-<list name="medium">
-</list>
 </termlist>
index abb5f68..babcb32 100644 (file)
@@ -45,6 +45,4 @@
 <term><name>date8</name><frequency>20</frequency></term>
 <term><name>date9</name><frequency>10</frequency></term>
 </list>
-<list name="medium">
-</list>
 </termlist>
index abb5f68..babcb32 100644 (file)
@@ -45,6 +45,4 @@
 <term><name>date8</name><frequency>20</frequency></term>
 <term><name>date9</name><frequency>10</frequency></term>
 </list>
-<list name="medium">
-</list>
 </termlist>
index 8be225c..859ee69 100644 (file)
@@ -40,6 +40,4 @@
 <term><name>date8</name><frequency>20</frequency></term>
 <term><name>date9</name><frequency>10</frequency></term>
 </list>
-<list name="medium">
-</list>
 </termlist>
index 8755ee8..65e9fe2 100644 (file)
@@ -30,6 +30,4 @@
 <term><name>1973</name><frequency>1</frequency></term>
 <term><name>1980</name><frequency>1</frequency></term>
 </list>
-<list name="medium">
-</list>
 </termlist>