X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=src%2Flogic.c;h=c76ba2892772682b972e8fa98a72b40d5caa58a7;hb=8b9b24543393aabb69c0efb0ee9b1390ee9d22f2;hp=0a0c59b17ce21c47d6a4d10e7e3401607ac18c51;hpb=216073a7a0d2fdfc9d88c58b1a2ff83fa76d4628;p=pazpar2-moved-to-github.git diff --git a/src/logic.c b/src/logic.c index 0a0c59b..c76ba28 100644 --- a/src/logic.c +++ b/src/logic.c @@ -57,7 +57,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include #endif - +#include "parameters.h" #include "pazpar2.h" #include "eventl.h" #include "http.h" @@ -68,6 +68,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "client.h" #include "settings.h" #include "normalize7bit.h" +#include "marcmap.h" #define TERMLIST_HIGH_SCORE 25 @@ -76,22 +77,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // Note: Some things in this structure will eventually move to configuration struct parameters global_parameters = { - "", - "", - 0, 0, // dump_records 0, // debug_mode - 30, // operations timeout - "81", - "Index Data PazPar2", - VERSION, - 60, // session timeout 100, - MAX_CHUNK, - 0, - 0, - 180, // Z39.50 session timeout - 15 // Connect timeout }; static void log_xml_doc(xmlDoc *doc) @@ -270,8 +258,17 @@ xmlDoc *normalize_record(struct session_database *sdb, struct session *se, insert_settings_parameters(sdb, se, parms); - new = xsltApplyStylesheet(m->stylesheet, rdoc, (const char **) parms); - root= xmlDocGetRootElement(new); + if (m->stylesheet) + { + new = xsltApplyStylesheet(m->stylesheet, rdoc, (const char **) parms); + } + else if (m->marcmap) + { + new = marcmap_apply(m->marcmap, rdoc); + } + + root = xmlDocGetRootElement(new); + if (!new || !root || !(root->children)) { yaz_log(YLOG_WARN, "XSLT transformation failed from %s", @@ -355,12 +352,30 @@ static int prepare_map(struct session *se, struct session_database *sdb) { (*m) = nmem_malloc(se->session_nmem, sizeof(**m)); (*m)->next = 0; - if (!((*m)->stylesheet = conf_load_stylesheet(stylesheets[i]))) + + // XSLT + if (!strcmp(&stylesheets[i][strlen(stylesheets[i])-4], ".xsl")) + { + (*m)->marcmap = NULL; + if (!((*m)->stylesheet = conf_load_stylesheet(se->service, stylesheets[i]))) + { + yaz_log(YLOG_FATAL|YLOG_ERRNO, "Unable to load stylesheet: %s", + stylesheets[i]); + return -1; + } + } + // marcmap + else if (!strcmp(&stylesheets[i][strlen(stylesheets[i])-5], ".mmap")) { - yaz_log(YLOG_FATAL|YLOG_ERRNO, "Unable to load stylesheet: %s", - stylesheets[i]); - return -1; + (*m)->stylesheet = NULL; + if (!((*m)->marcmap = marcmap_load(stylesheets[i], se->session_nmem))) + { + yaz_log(YLOG_FATAL|YLOG_ERRNO, "Unable to load marcmap: %s", + stylesheets[i]); + return -1; + } } + m = &(*m)->next; } } @@ -510,7 +525,7 @@ static struct database_criterion *parse_filter(NMEM m, const char *buf) } enum pazpar2_error_code search(struct session *se, - char *query, char *filter, + const char *query, const char *filter, const char **addinfo) { int live_channels = 0; @@ -551,7 +566,8 @@ enum pazpar2_error_code search(struct session *se, else { no_working++; - if (client_prep_connection(cl)) + if (client_prep_connection(cl, se->service->z3950_connect_timeout, + se->service->z3950_session_timeout)) client_start_search(cl); } } @@ -614,6 +630,8 @@ static struct session_database *load_session_database(struct session *se, { struct database *db = find_database(id, 0, se->service); + resolve_database(db); + session_init_databases_fun((void*) se, db); // New sdb is head of se->databases list return se->databases; @@ -684,6 +702,7 @@ void destroy_session(struct session *s) for (sdb = s->databases; sdb; sdb = sdb->next) session_database_destroy(sdb); nmem_destroy(s->nmem); + service_destroy(s->service); wrbuf_destroy(s->wrbuf); } @@ -876,52 +895,10 @@ void statistics(struct session *se, struct statistics *stat) stat->num_clients = count; } -int start_http_listener(void) -{ - char hp[128] = ""; - struct conf_server *ser = global_parameters.server; - - if (*global_parameters.listener_override) - strcpy(hp, global_parameters.listener_override); - else - { - strcpy(hp, ser->host ? ser->host : ""); - if (ser->port) - { - if (*hp) - strcat(hp, ":"); - sprintf(hp + strlen(hp), "%d", ser->port); - } - } - return http_init(hp); -} - -void start_proxy(void) -{ - char hp[128] = ""; - struct conf_server *ser = global_parameters.server; - - if (*global_parameters.proxy_override) - strcpy(hp, global_parameters.proxy_override); - else if (ser->proxy_host || ser->proxy_port) - { - strcpy(hp, ser->proxy_host ? ser->proxy_host : ""); - if (ser->proxy_port) - { - if (*hp) - strcat(hp, ":"); - sprintf(hp + strlen(hp), "%d", ser->proxy_port); - } - } - else - return; - - http_set_proxyaddr(hp, ser->myurl ? ser->myurl : ""); -} - // Master list of connections we're handling events to -static IOCHAN channel_list = 0; +static IOCHAN channel_list = 0; /* thread pr */ + void pazpar2_add_channel(IOCHAN chan) { chan->next = channel_list; @@ -963,8 +940,8 @@ static struct record_metadata *record_metadata_init( return rec_md; } -const char *get_mergekey(xmlDoc *doc, struct client *cl, int record_no, - struct conf_service *service, NMEM nmem) +static const char *get_mergekey(xmlDoc *doc, struct client *cl, int record_no, + struct conf_service *service, NMEM nmem) { char *mergekey_norm = 0; xmlNode *root = xmlDocGetRootElement(doc); @@ -978,7 +955,7 @@ const char *get_mergekey(xmlDoc *doc, struct client *cl, int record_no, const char *norm_str; pp2_relevance_token_t prt = pp2_relevance_tokenize( - global_parameters.server->mergekey_pct, + service->mergekey_pct, (const char *) mergekey); while ((norm_str = pp2_relevance_token_next(prt))) @@ -1022,7 +999,7 @@ const char *get_mergekey(xmlDoc *doc, struct client *cl, int record_no, const char *norm_str; pp2_relevance_token_t prt = pp2_relevance_tokenize( - global_parameters.server->mergekey_pct, + service->mergekey_pct, (const char *) value); while ((norm_str = pp2_relevance_token_next(prt))) @@ -1055,6 +1032,71 @@ const char *get_mergekey(xmlDoc *doc, struct client *cl, int record_no, return mergekey_norm; } +static const char *str_tok_n(const char *s, const char *delim, + const char **res, size_t *len) +{ + *res = s; + while (*s && !strchr(delim, *s)) + s++; + *len = s - *res; + if (*len == 0) + return 0; + if (*s && strchr(delim, *s)) + s++; + return s; +} + +/** \brief see if metadata for pz:recordfilter exists + \param root xml root element of normalized record + \param sdb session database for client + \retval 0 if there is no metadata for pz:recordfilter + \retval 1 if there is metadata for pz:recordfilter + + If there is no pz:recordfilter defined, this function returns 1 + as well. +*/ + +static int check_record_filter(xmlNode *root, struct session_database *sdb) +{ + int match = 0; + xmlNode *n; + const char *s; + s = session_setting_oneval(sdb, PZ_RECORDFILTER); + + if (!s || !*s) + return 1; + + for (n = root->children; n; n = n->next) + { + if (n->type != XML_ELEMENT_NODE) + continue; + if (!strcmp((const char *) n->name, "metadata")) + { + xmlChar *type = xmlGetProp(n, (xmlChar *) "type"); + if (type) + { + const char *s1 = s; + size_t len; + const char *value; + while ((s1 = str_tok_n(s1, ",", &value, &len)) != 0) + { + if (len == strlen((const char *)type) && + !memcmp((const char *) type, s, len)) + { + xmlChar *value = xmlNodeGetContent(n); + if (value && *value) + { + xmlFree(value); + match = 1; + } + } + } + xmlFree(type); + } + } + } + return match; +} /** \brief ingest XML record @@ -1066,12 +1108,12 @@ const char *get_mergekey(xmlDoc *doc, struct client *cl, int record_no, struct record *ingest_record(struct client *cl, const char *rec, int record_no) { - xmlDoc *xdoc = normalize_record(client_get_database(cl), - client_get_session(cl), rec); + struct session_database *sdb = client_get_database(cl); + struct session *se = client_get_session(cl); + xmlDoc *xdoc = normalize_record(sdb, se, rec); xmlNode *root, *n; struct record *record; struct record_cluster *cluster; - struct session *se = client_get_session(cl); const char *mergekey_norm; xmlChar *type = 0; xmlChar *value = 0; @@ -1082,6 +1124,14 @@ struct record *ingest_record(struct client *cl, const char *rec, root = xmlDocGetRootElement(xdoc); + if (!check_record_filter(root, sdb)) + { + yaz_log(YLOG_WARN, "Filtered out record no %d from %s", record_no, + sdb->database->url); + xmlFreeDoc(xdoc); + return 0; + } + mergekey_norm = get_mergekey(xdoc, cl, record_no, service, se->nmem); if (!mergekey_norm) { @@ -1099,7 +1149,7 @@ struct record *ingest_record(struct client *cl, const char *rec, &se->total_merged); if (global_parameters.dump_records) yaz_log(YLOG_LOG, "Cluster id %s from %s (#%d)", cluster->recid, - client_get_database(cl)->database->url, record_no); + sdb->database->url, record_no); if (!cluster) { /* no room for record */ @@ -1208,7 +1258,7 @@ struct record *ingest_record(struct client *cl, const char *rec, sizeof(union data_types)); prt = pp2_relevance_tokenize( - global_parameters.server->sort_pct, + service->sort_pct, rec_md->data.text.disp); pp2_relevance_token_next(prt);