From 975482621691b3dbd8d08cb5fbd81eeb6d9b05dd Mon Sep 17 00:00:00 2001 From: Sebastian Hammer Date: Tue, 20 Mar 2007 05:32:58 +0000 Subject: [PATCH] Added optional 'filter' parameter to search. Right now, only value supported is (URL-escaped) id=targetId, where targetId is the ZUrl of a known target. --- src/database.c | 42 ++++++++++++++++++++++++++++++++++-------- src/database.h | 4 +++- src/http_command.c | 6 ++++-- src/pazpar2.c | 51 +++++++++++++++++++++++++++++++++++++++------------ src/pazpar2.h | 10 ++++++++-- 5 files changed, 88 insertions(+), 25 deletions(-) diff --git a/src/database.c b/src/database.c index b1cd969..9cb2406 100644 --- a/src/database.c +++ b/src/database.c @@ -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 #include @@ -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); } diff --git a/src/database.h b/src/database.h index 25aee00..7ffeb86 100644 --- a/src/database.h +++ b/src/database.h @@ -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 diff --git a/src/http_command.c b/src/http_command.c index f304e61..0dfbc6d 100644 --- a/src/http_command.c +++ b/src/http_command.c @@ -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 @@ -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\n"); + wrbuf_printf(wrbuf, "%s\n", ht[i].id); wrbuf_printf(wrbuf, "%s\n", ht[i].name); wrbuf_printf(wrbuf, "%d\n", ht[i].hits); wrbuf_printf(wrbuf, "%s\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); diff --git a/src/pazpar2.c b/src/pazpar2.c index acc494b..3c37fc7 100644 --- a/src/pazpar2.c +++ b/src/pazpar2.c @@ -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 #include @@ -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; } diff --git a/src/pazpar2.h b/src/pazpar2.h index e64505e..5b04d73 100644 --- a/src/pazpar2.h +++ b/src/pazpar2.h @@ -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); -- 1.7.10.4