Added optional 'filter' parameter to search. Right now, only value supported is
authorSebastian Hammer <quinn@indexdata.com>
Tue, 20 Mar 2007 05:32:58 +0000 (05:32 +0000)
committerSebastian Hammer <quinn@indexdata.com>
Tue, 20 Mar 2007 05:32:58 +0000 (05:32 +0000)
(URL-escaped) id=targetId, where targetId is the ZUrl of a known target.

src/database.c
src/database.h
src/http_command.c
src/pazpar2.c
src/pazpar2.h

index b1cd969..9cb2406 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: database.c,v 1.2 2007-03-16 09:34:55 adam Exp $ */
+/* $Id: database.c,v 1.3 2007-03-20 05:32:58 quinn Exp $ */
 
 #include <libxml/parser.h>
 #include <libxml/tree.h>
@@ -157,7 +157,7 @@ static struct database *load_database(const char *id)
     memset(db, 0, sizeof(*db));
     db->host = host;
     db->url = nmem_strdup(nmem, id);
-    db->name = dbname;
+    db->name = 0;
     db->databases = xmalloc(2 * sizeof(char *));
     db->databases[0] = nmem_strdup(nmem, dbname);
     db->databases[1] = 0;
@@ -185,17 +185,40 @@ struct database *find_database(const char *id, int new)
     return load_database(id);
 }
 
-// Needs to be extended with criteria
-// Cycles through databases, calling a handler function on each.
-int grep_databases(void *context, void (*fun)(void *context, struct database *db))
+static int match_criterion(struct database *db, struct database_criterion *c)
+{
+    if (!strcmp(c->name, "id"))
+        return (!strcmp(c->value, db->url));
+    else
+        return 0;
+}
+
+int database_match_criteria(struct database *db, struct database_criterion *cl)
+{
+    for (; cl; cl = cl->next)
+        if (!match_criterion(db, cl))
+            break;
+    if (cl) // one of the criteria failed to match -- skip this db
+        return 0;
+    else
+        return 1;
+}
+
+// Cycles through databases, calling a handler function on the ones for
+// which all criteria matched.
+int grep_databases(void *context, struct database_criterion *cl,
+        void (*fun)(void *context, struct database *db))
 {
     struct database *p;
     int i;
 
     for (p = databases; p; p = p->next)
     {
-        (*fun)(context, p);
-        i++;
+        if (database_match_criteria(p, cl))
+        {
+            (*fun)(context, p);
+            i++;
+        }
     }
     return i;
 }
@@ -217,6 +240,7 @@ void load_simpletargets(const char *fn)
     {
         char *url;
         char *name;
+        struct database *db;
 
         if (strncmp(line, "target ", 7))
             continue;
@@ -227,8 +251,10 @@ void load_simpletargets(const char *fn)
 
         url = line + 7;
 
-        if (!find_database(url, 0))
+        if (!(db = find_database(url, 0)))
             yaz_log(YLOG_WARN, "Unable to load database %s", url);
+        if (name && db)
+            db->name = nmem_strdup(nmem, name);
     }
     fclose(f);
 }
index 25aee00..7ffeb86 100644 (file)
@@ -2,6 +2,8 @@
 #define DATABASE_H
 
 void load_simpletargets(const char *fn);
-int grep_databases(void *context, void (*fun)(void *context, struct database *db));
+int grep_databases(void *context, struct database_criterion *cl,
+        void (*fun)(void *context, struct database *db));
+int database_match_criteria(struct database *db, struct database_criterion *cl);
 
 #endif
index f304e61..0dfbc6d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: http_command.c,v 1.26 2007-01-18 18:11:19 quinn Exp $
+ * $Id: http_command.c,v 1.27 2007-03-20 05:32:58 quinn Exp $
  */
 
 #include <stdio.h>
@@ -168,6 +168,7 @@ static void targets_termlist(WRBUF wrbuf, struct session *se, int num)
     for (i = 0; i < count && i < num && ht[i].hits > 0; i++)
     {
         wrbuf_puts(wrbuf, "\n<term>\n");
+        wrbuf_printf(wrbuf, "<id>%s</id>\n", ht[i].id);
         wrbuf_printf(wrbuf, "<name>%s</name>\n", ht[i].name);
         wrbuf_printf(wrbuf, "<frequency>%d</frequency>\n", ht[i].hits);
         wrbuf_printf(wrbuf, "<state>%s</state>\n", ht[i].state);
@@ -468,6 +469,7 @@ static void cmd_search(struct http_channel *c)
     struct http_response *rs = c->response;
     struct http_session *s = locate_session(rq, rs);
     char *query = http_argbyname(rq, "query");
+    char *filter = http_argbyname(rq, "filter");
     char *res;
 
     if (!s)
@@ -477,7 +479,7 @@ static void cmd_search(struct http_channel *c)
         error(rs, "417", "Must supply query", 0);
         return;
     }
-    res = search(s->psession, query);
+    res = search(s->psession, query, filter);
     if (res)
     {
         error(rs, "417", res, res);
index acc494b..3c37fc7 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: pazpar2.c,v 1.49 2007-03-15 16:50:56 quinn Exp $ */
+/* $Id: pazpar2.c,v 1.50 2007-03-20 05:32:58 quinn Exp $ */
 
 #include <stdlib.h>
 #include <stdio.h>
@@ -46,7 +46,7 @@ static void client_fatal(struct client *cl);
 static void connection_destroy(struct connection *co);
 static int client_prep_connection(struct client *cl);
 static void ingest_records(struct client *cl, Z_Records *r);
-static struct conf_retrievalprofile *database_retrieval_profile(struct database *db);
+//static struct conf_retrievalprofile *database_retrieval_profile(struct database *db);
 void session_alert_watch(struct session *s, int what);
 
 IOCHAN channel_list = 0;  // Master list of connections we're handling events to
@@ -1253,12 +1253,12 @@ static void select_targets_callback(void *context, struct database *db)
 
 // This should be extended with parameters to control selection criteria
 // Associates a set of clients with a session;
-int select_targets(struct session *se)
+int select_targets(struct session *se, struct database_criterion *crit)
 {
     while (se->clients)
         client_destroy(se->clients);
 
-    return grep_databases(se, select_targets_callback);
+    return grep_databases(se, crit, select_targets_callback);
 }
 
 int session_active_clients(struct session *s)
@@ -1276,22 +1276,51 @@ int session_active_clients(struct session *s)
     return res;
 }
 
-char *search(struct session *se, char *query)
+// parses crit1=val1,crit2=val2,...
+static struct database_criterion *parse_filter(NMEM m, const char *buf)
+{
+    struct database_criterion *res = 0;
+    char **values;
+    int num;
+    int i;
+
+    if (!buf || !*buf)
+        return 0;
+    nmem_strsplit(m, ",", buf,  &values, &num);
+    for (i = 0; i < num; i++)
+    {
+        struct database_criterion *new = nmem_malloc(m, sizeof(*new));
+        char *eq = strchr(values[i], '=');
+        if (!eq)
+        {
+            yaz_log(YLOG_WARN, "Missing equal-sign in filter");
+            return 0;
+        }
+        *(eq++) = '\0';
+        new->name = values[i];
+        new->value = eq;
+        new->next = res;
+        res = new;
+    }
+    return res;
+}
+
+char *search(struct session *se, char *query, char *filter)
 {
     int live_channels = 0;
     struct client *cl;
+    struct database_criterion *criteria;
 
     yaz_log(YLOG_DEBUG, "Search");
 
+    nmem_reset(se->nmem);
+    criteria = parse_filter(se->nmem, filter);
     strcpy(se->query, query);
     se->requestid++;
-    nmem_reset(se->nmem);
+    // Release any existing clients
+    select_targets(se, criteria);
     for (cl = se->clients; cl; cl = cl->next)
     {
-        cl->hits = -1;
-        cl->records = 0;
-        cl->diagnostic = 0;
-
         if (client_prep_connection(cl))
             live_channels++;
     }
@@ -1344,8 +1373,6 @@ struct session *new_session()
         session->watchlist[i].fun = 0;
     }
 
-    select_targets(session);
-
     return session;
 }
 
index e64505e..5b04d73 100644 (file)
@@ -75,6 +75,12 @@ struct database {
     struct database *next;
 };
 
+struct database_criterion {
+    char *name;
+    char *value;
+    struct database_criterion *next;
+};
+
 // Represents a physical, reusable  connection to a remote Z39.50 host
 struct connection {
     IOCHAN iochan;
@@ -195,12 +201,12 @@ struct parameters {
 };
 
 struct hitsbytarget *hitsbytarget(struct session *s, int *count);
-int select_targets(struct session *se);
+int select_targets(struct session *se, struct database_criterion *crit);
 struct session *new_session();
 void destroy_session(struct session *s);
 int load_targets(struct session *s, const char *fn);
 void statistics(struct session *s, struct statistics *stat);
-char *search(struct session *s, char *query);
+char *search(struct session *s, char *query, char *filter);
 struct record_cluster **show(struct session *s, struct reclist_sortparms *sp, int start,
         int *num, int *total, int *sumhits, NMEM nmem_show);
 struct record_cluster *show_single(struct session *s, int id);