X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=src%2Flogic.c;h=e8c2e8886afb190a77373c0905cc1c3e662bb24a;hb=7db06f8379d23e8f1bce2c87f3ce082bb56ac2db;hp=eae862b13e2e43707e4befb1d5647ffbd9a90b1e;hpb=a085694d89c72f473733b58d08ddc2f5b37390e2;p=pazpar2-moved-to-github.git diff --git a/src/logic.c b/src/logic.c index eae862b..e8c2e88 100644 --- a/src/logic.c +++ b/src/logic.c @@ -1,4 +1,4 @@ -/* $Id: logic.c,v 1.54 2007-07-16 17:01:46 adam Exp $ +/* $Id: logic.c,v 1.64 2007-09-05 08:40:12 adam Exp $ Copyright (c) 2006-2007, Index Data. This file is part of Pazpar2. @@ -46,6 +46,7 @@ Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include #include #include +#include #if HAVE_CONFIG_H #include "cconfig.h" @@ -92,10 +93,11 @@ struct parameters global_parameters = 100, MAX_CHUNK, 0, - 0 + 0, + 180, + 30 }; - // Recursively traverse query structure to extract terms. void pull_terms(NMEM nmem, struct ccl_rpn_node *n, char **termlist, int *num) { @@ -189,7 +191,18 @@ xmlDoc *record_to_xml(struct session_database *sdb, Z_External *rec) rdoc = xmlParseMemory((char*) wrbuf_buf(wrbuf_opac), wrbuf_len(wrbuf_opac)); if (!rdoc) + { yaz_log(YLOG_WARN, "Unable to parse OPAC XML"); + /* Was used to debug bug #1348 */ +#if 0 + FILE *f = fopen("/tmp/opac.xml.txt", "wb"); + if (f) + { + fwrite(wrbuf_buf(wrbuf_opac), 1, wrbuf_len(wrbuf_opac), f); + fclose(f); + } +#endif + } wrbuf_destroy(wrbuf_opac); } } @@ -221,7 +234,6 @@ xmlDoc *record_to_xml(struct session_database *sdb, Z_External *rec) return 0; } - yaz_marc_write_using_libxml2(sdb->yaz_marc, 1); if (yaz_marc_write_xml(sdb->yaz_marc, &res, "http://www.loc.gov/MARC21/slim", 0, 0) < 0) { @@ -260,18 +272,88 @@ xmlDoc *record_to_xml(struct session_database *sdb, Z_External *rec) return rdoc; } -xmlDoc *normalize_record(struct session_database *sdb, Z_External *rec) +#define MAX_XSLT_ARGS 16 + +// Add static values from session database settings if applicable +static void insert_settings_parameters(struct session_database *sdb, + struct session *se, char **parms) +{ + struct conf_service *service = global_parameters.server->service; + int i; + int nparms = 0; + int offset = 0; + + for (i = 0; i < service->num_metadata; i++) + { + struct conf_metadata *md = &service->metadata[i]; + int setting; + + if (md->setting == Metadata_setting_parameter && + (setting = settings_offset(md->name)) > 0) + { + const char *val = session_setting_oneval(sdb, setting); + if (val && nparms < MAX_XSLT_ARGS) + { + char *buf; + int len = strlen(val); + buf = nmem_malloc(se->nmem, len + 3); + buf[0] = '\''; + strcpy(buf + 1, val); + buf[len+1] = '\''; + buf[len+2] = '\0'; + parms[offset++] = md->name; + parms[offset++] = buf; + nparms++; + } + } + } + parms[offset] = 0; +} + +// Add static values from session database settings if applicable +static void insert_settings_values(struct session_database *sdb, xmlDoc *doc) +{ + struct conf_service *service = global_parameters.server->service; + int i; + + for (i = 0; i < service->num_metadata; i++) + { + struct conf_metadata *md = &service->metadata[i]; + int offset; + + if (md->setting == Metadata_setting_postproc && + (offset = settings_offset(md->name)) > 0) + { + const char *val = session_setting_oneval(sdb, offset); + if (val) + { + xmlNode *r = xmlDocGetRootElement(doc); + xmlNode *n = xmlNewTextChild(r, 0, (xmlChar *) "metadata", + (xmlChar *) val); + xmlSetProp(n, (xmlChar *) "type", (xmlChar *) md->name); + } + } + } +} + +xmlDoc *normalize_record(struct session_database *sdb, struct session *se, + Z_External *rec) { struct database_retrievalmap *m; xmlDoc *rdoc = record_to_xml(sdb, rec); if (rdoc) { - for (m = sdb->map; m; m = m->next){ + for (m = sdb->map; m; m = m->next) + { xmlDoc *new = 0; { xmlNodePtr root = 0; - new = xsltApplyStylesheet(m->stylesheet, rdoc, 0); + char *parms[MAX_XSLT_ARGS*2+1]; + + insert_settings_parameters(sdb, se, parms); + + new = xsltApplyStylesheet(m->stylesheet, rdoc, (const char **) parms); root= xmlDocGetRootElement(new); if (!new || !root || !(root->children)) { @@ -286,6 +368,9 @@ xmlDoc *normalize_record(struct session_database *sdb, Z_External *rec) xmlFreeDoc(rdoc); rdoc = new; } + + insert_settings_values(sdb, rdoc); + if (global_parameters.dump_records) { FILE *lf = yaz_log_file(); @@ -308,7 +393,7 @@ xmlDoc *normalize_record(struct session_database *sdb, Z_External *rec) // Retrieve first defined value for 'name' for given database. // Will be extended to take into account user associated with session -char *session_setting_oneval(struct session_database *db, int offset) +const char *session_setting_oneval(struct session_database *db, int offset) { if (!db->settings[offset]) return ""; @@ -320,7 +405,7 @@ char *session_setting_oneval(struct session_database *db, int offset) // Initialize YAZ Map structures for MARC-based targets static int prepare_yazmarc(struct session_database *sdb) { - char *s; + const char *s; if (!sdb->settings) { @@ -360,7 +445,7 @@ static int prepare_yazmarc(struct session_database *sdb) // setting. However, this is not a realistic use scenario. static int prepare_map(struct session *se, struct session_database *sdb) { - char *s; + const char *s; if (!sdb->settings) { @@ -372,7 +457,30 @@ static int prepare_map(struct session *se, struct session_database *sdb) char **stylesheets; struct database_retrievalmap **m = &sdb->map; int num, i; + char auto_stylesheet[256]; + if (!strcmp(s, "auto")) + { + const char *request_syntax = session_setting_oneval( + sdb, PZ_REQUESTSYNTAX); + if (request_syntax) + { + char *cp; + yaz_snprintf(auto_stylesheet, sizeof(auto_stylesheet), + "%s.xsl", request_syntax); + for (cp = auto_stylesheet; *cp; cp++) + { + /* deliberately only consider ASCII */ + if (*cp > 32 && *cp < 127) + *cp = tolower(*cp); + } + s = auto_stylesheet; + } + else + { + yaz_log(YLOG_WARN, "No pz:requestsyntax for auto stylesheet"); + } + } nmem_strsplit(se->session_nmem, ",", s, &stylesheets, &num); for (i = 0; i < num; i++) { @@ -443,13 +551,21 @@ int session_set_watch(struct session *s, int what, void session_alert_watch(struct session *s, int what) { - if (!s->watchlist[what].fun) - return; - http_remove_observer(s->watchlist[what].obs); - (*s->watchlist[what].fun)(s->watchlist[what].data); - s->watchlist[what].fun = 0; - s->watchlist[what].data = 0; - s->watchlist[what].obs = 0; + if (s->watchlist[what].fun) + { + /* our watch is no longer associated with http_channel */ + http_remove_observer(s->watchlist[what].obs); + session_watchfun fun = s->watchlist[what].fun; + void *data = s->watchlist[what].data; + + /* reset watch before fun is invoked - in case fun wants to set + it again */ + s->watchlist[what].fun = 0; + s->watchlist[what].data = 0; + s->watchlist[what].obs = 0; + + fun(data); + } } //callback for grep_databases @@ -539,23 +655,22 @@ enum pazpar2_error_code search(struct session *se, *addinfo = 0; nmem_reset(se->nmem); + se->relevance = 0; + se->total_records = se->total_hits = se->total_merged = 0; + se->reclist = 0; + se->num_termlists = 0; criteria = parse_filter(se->nmem, filter); se->requestid++; live_channels = select_targets(se, criteria); if (live_channels) { int maxrecs = live_channels * global_parameters.toget; - se->num_termlists = 0; se->reclist = reclist_create(se->nmem, maxrecs); - // This will be initialized in send_search() - se->total_records = se->total_hits = se->total_merged = 0; se->expected_maxrecs = maxrecs; } else return PAZPAR2_NO_TARGETS; - se->relevance = 0; - for (cl = se->clients; cl; cl = client_next_in_session(cl)) { if (prepare_session_database(se, client_get_database(cl)) < 0) @@ -751,15 +866,21 @@ struct session *new_session(NMEM nmem) return session; } -struct hitsbytarget *hitsbytarget(struct session *se, int *count) +struct hitsbytarget *hitsbytarget(struct session *se, int *count, NMEM nmem) { - static struct hitsbytarget res[1000]; // FIXME MM + struct hitsbytarget *res = 0; struct client *cl; + size_t sz = 0; + for (cl = se->clients; cl; cl = client_next_in_session(cl)) + sz++; + + res = nmem_malloc(nmem, sizeof(*res) * sz); *count = 0; for (cl = se->clients; cl; cl = client_next_in_session(cl)) { - char *name = session_setting_oneval(client_get_database(cl), PZ_NAME); + const char *name = session_setting_oneval(client_get_database(cl), + PZ_NAME); res[*count].id = client_get_database(cl)->database->url; res[*count].name = *name ? name : "Unknown"; @@ -770,7 +891,6 @@ struct hitsbytarget *hitsbytarget(struct session *se, int *count) res[*count].connected = client_get_connection(cl) ? 1 : 0; (*count)++; } - return res; } @@ -982,7 +1102,8 @@ static struct record_metadata *record_metadata_init( struct record *ingest_record(struct client *cl, Z_External *rec, int record_no) { - xmlDoc *xdoc = normalize_record(client_get_database(cl), rec); + xmlDoc *xdoc = normalize_record(client_get_database(cl), + client_get_session(cl), rec); xmlNode *root, *n; struct record *record; struct record_cluster *cluster; @@ -1050,7 +1171,7 @@ struct record *ingest_record(struct client *cl, Z_External *rec, type = xmlGetProp(n, (xmlChar *) "type"); value = xmlNodeListGetString(xdoc, n->children, 1); - if (!type || !value) + if (!type || !value || !*value) continue; md_field_id