X-Git-Url: http://git.indexdata.com/?a=blobdiff_plain;f=src%2Fclient.c;h=5f05633bdf77041e25ba98283d69f0de60f005c7;hb=0198d9a410e2664e29f8fa526cf9bcf8f5bea89a;hp=44ee5d576ce3eb5991441db7683e737da4e3ed2d;hpb=3fcbed280bd20e84d9062e3b6b7ac6d7decb80bb;p=pazpar2-moved-to-github.git diff --git a/src/client.c b/src/client.c index 44ee5d5..5f05633 100644 --- a/src/client.c +++ b/src/client.c @@ -1,5 +1,5 @@ /* This file is part of Pazpar2. - Copyright (C) 2006-2012 Index Data + Copyright (C) 2006-2013 Index Data Pazpar2 is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free @@ -119,6 +119,7 @@ struct client { int maxrecs; int startrecs; int diagnostic; + char *message; int preferred; struct suggestions *suggestions; enum client_state state; @@ -582,17 +583,18 @@ static void client_record_ingest(struct client *cl) const char *msg, *addinfo; ZOOM_record rec = 0; ZOOM_resultset resultset = cl->resultset; - int offset = cl->record_offset; - if ((rec = ZOOM_resultset_record_immediate(resultset, offset))) + struct session *se = client_get_session(cl); + + if ((rec = ZOOM_resultset_record_immediate(resultset, cl->record_offset))) { - cl->record_offset++; + int offset = ++cl->record_offset; if (cl->session == 0) { /* no operation */ } else if (ZOOM_record_error(rec, &msg, &addinfo, 0)) { - yaz_log(YLOG_WARN, "Record error %s (%s): %s (rec #%d)", - msg, addinfo, client_get_id(cl), cl->record_offset); + session_log(se, YLOG_WARN, "Record error %s (%s): %s #%d", + msg, addinfo, client_get_id(cl), offset); } else { @@ -603,17 +605,33 @@ static void client_record_ingest(struct client *cl) const char *s = session_setting_oneval(sdb, PZ_NATIVESYNTAX); if (nativesyntax_to_type(s, type, rec)) - yaz_log(YLOG_WARN, "Failed to determine record type"); + session_log(se, YLOG_WARN, "Failed to determine record type"); xmlrec = ZOOM_record_get(rec, type, NULL); if (!xmlrec) - yaz_log(YLOG_WARN, "ZOOM_record_get failed from %s", - client_get_id(cl)); + { + const char *rec_syn = ZOOM_record_get(rec, "syntax", NULL); + session_log(se, YLOG_WARN, "ZOOM_record_get failed from %s #%d", + client_get_id(cl), offset); + session_log(se, YLOG_LOG, "pz:nativesyntax=%s . " + "ZOOM record type=%s . Actual record syntax=%s", + s ? s : "null", type, + rec_syn ? rec_syn : "null"); + } else { /* OK = 0, -1 = failure, -2 = Filtered */ int rc = ingest_record(cl, xmlrec, cl->record_offset, nmem); if (rc == -1) - yaz_log(YLOG_WARN, "Failed to ingest from %s", client_get_id(cl)); + { + const char *rec_syn = ZOOM_record_get(rec, "syntax", NULL); + session_log(se, YLOG_WARN, + "Failed to ingest record from %s #%d", + client_get_id(cl), offset); + session_log(se, YLOG_LOG, "pz:nativesyntax=%s . " + "ZOOM record type=%s . Actual record syntax=%s", + s ? s : "null", type, + rec_syn ? rec_syn : "null"); + } if (rc == -2) cl->filtered += 1; } @@ -622,7 +640,8 @@ static void client_record_ingest(struct client *cl) } else { - yaz_log(YLOG_WARN, "Expected record, but got NULL, offset=%d", offset); + session_log(se, YLOG_WARN, "Got NULL record from %s #%d", + client_get_id(cl), cl->record_offset); } } @@ -743,6 +762,24 @@ static const char *get_strategy_plus_sort(struct client *l, const char *field) return strategy_plus_sort; } +int client_fetch_more(struct client *cl) +{ + int extra = cl->hits - cl->record_offset; + if (extra > 0) + { + ZOOM_resultset set = cl->resultset; + int max_extra = 10; + + if (extra > max_extra) + extra = max_extra; + + ZOOM_resultset_records(set, 0, cl->record_offset, extra); + client_set_state(cl, Client_Working); + return 1; + } + return 0; +} + int client_parse_init(struct client *cl, int same_search) { cl->same_search = same_search; @@ -915,6 +952,7 @@ struct client *client_create(const char *id) cl->pquery = 0; cl->cqlquery = 0; cl->addinfo = 0; + cl->message = 0; cl->database = 0; cl->connection = 0; cl->session = 0; @@ -971,6 +1009,8 @@ int client_destroy(struct client *c) c->cqlquery = 0; xfree(c->addinfo); c->addinfo = 0; + xfree(c->message); + c->message = 0; xfree(c->id); xfree(c->sort_strategy); xfree(c->sort_criteria); @@ -1037,7 +1077,9 @@ static CCL_bibset prepare_cclmap(struct client *cl, CCL_bibset base_bibset) WRBUF w = wrbuf_alloc(); wrbuf_printf(w, "Malformed cclmap. name=%s", s->name); yaz_log(YLOG_WARN, "%s: %s", client_get_id(cl), wrbuf_cstr(w)); - client_set_diagnostic(cl, ZOOM_ERROR_CCL_CONFIG, wrbuf_cstr(w)); + client_set_diagnostic(cl, ZOOM_ERROR_CCL_CONFIG, + ZOOM_diag_str(ZOOM_ERROR_CCL_CONFIG), + wrbuf_cstr(w)); client_set_state_nb(cl, Client_Error); ccl_qual_rm(&res); wrbuf_destroy(w); @@ -1051,7 +1093,9 @@ static CCL_bibset prepare_cclmap(struct client *cl, CCL_bibset base_bibset) wrbuf_printf(w, "Malformed cclmap. name=%s: value=%s (%s)", s->name, p, addinfo); yaz_log(YLOG_WARN, "%s: %s", client_get_id(cl), wrbuf_cstr(w)); - client_set_diagnostic(cl, ZOOM_ERROR_CCL_CONFIG, wrbuf_cstr(w)); + client_set_diagnostic(cl, ZOOM_ERROR_CCL_CONFIG, + ZOOM_diag_str(ZOOM_ERROR_CCL_CONFIG), + wrbuf_cstr(w)); client_set_state_nb(cl, Client_Error); ccl_qual_rm(&res); wrbuf_destroy(w); @@ -1118,17 +1162,28 @@ const char *client_get_facet_limit_local(struct client *cl, for (s = sdb->settings[PZ_LIMITMAP]; s; s = s->next) { const char *p = strchr(s->name + 3, ':'); - if (p && !strcmp(p + 1, name) && s->value && - !strncmp(s->value, "local:", 6)) + if (p && !strcmp(p + 1, name) && s->value) { - const char *cp = s->value + 6; - while (*cp == ' ') - cp++; - - nmem_strsplit_escape2(nmem, "|", value, values, - num, 1, '\\', 1); - (*l)++; - return *cp ? cp : name; + int j, cnum; + char **cvalues; + nmem_strsplit_escape2(nmem, ",", s->value, &cvalues, + &cnum, 1, '\\', 1); + for (j = 0; j < cnum; j++) + { + const char *cvalue = cvalues[j]; + while (*cvalue == ' ') + cvalue++; + if (!strncmp(cvalue, "local:", 6)) + { + const char *cp = cvalue + 6; + while (*cp == ' ') + cp++; + nmem_strsplit_escape2(nmem, "|", value, values, + num, 1, '\\', 1); + (*l)++; + return *cp ? cp : name; + } + } } } } @@ -1137,7 +1192,8 @@ const char *client_get_facet_limit_local(struct client *cl, static int apply_limit(struct session_database *sdb, facet_limits_t facet_limits, - WRBUF w_pqf, CCL_bibset ccl_map) + WRBUF w_pqf, CCL_bibset ccl_map, + struct conf_service *service) { int ret = 0; int i = 0; @@ -1149,6 +1205,7 @@ static int apply_limit(struct session_database *sdb, { struct setting *s = 0; nmem_reset(nmem_tmp); + /* name="pz:limitmap:author" value="rpn:@attr 1=4|local:other" */ for (s = sdb->settings[PZ_LIMITMAP]; s; s = s->next) { const char *p = strchr(s->name + 3, ':'); @@ -1156,72 +1213,96 @@ static int apply_limit(struct session_database *sdb, { char **values = 0; int i, num = 0; + char **cvalues = 0; + int j, cnum = 0; nmem_strsplit_escape2(nmem_tmp, "|", value, &values, &num, 1, '\\', 1); - if (!strncmp(s->value, "rpn:", 4)) - { - const char *pqf = s->value + 4; + nmem_strsplit_escape2(nmem_tmp, ",", s->value, &cvalues, + &cnum, 1, '\\', 1); - wrbuf_puts(w_pqf, "@and "); - wrbuf_puts(w_pqf, pqf); - wrbuf_puts(w_pqf, " "); - for (i = 0; i < num; i++) - { - if (i < num - 1) - wrbuf_puts(w_pqf, "@or "); - yaz_encode_pqf_term(w_pqf, values[i], - strlen(values[i])); - } - } - else if (!strncmp(s->value, "ccl:", 4)) + for (j = 0; ret == 0 && j < cnum; j++) { - const char *ccl = s->value + 4; - WRBUF ccl_w = wrbuf_alloc(); - for (i = 0; i < num; i++) + const char *cvalue = cvalues[j]; + while (*cvalue == ' ') + cvalue++; + if (!strncmp(cvalue, "rpn:", 4)) { - int cerror, cpos; - struct ccl_rpn_node *cn; - - wrbuf_rewind(ccl_w); - wrbuf_puts(ccl_w, ccl); - wrbuf_puts(ccl_w, "=\""); - wrbuf_puts(ccl_w, values[i]); - wrbuf_puts(ccl_w, "\""); - - cn = ccl_find_str(ccl_map, wrbuf_cstr(ccl_w), - &cerror, &cpos); - if (cn) + const char *pqf = cvalue + 4; + wrbuf_puts(w_pqf, "@and "); + wrbuf_puts(w_pqf, pqf); + wrbuf_puts(w_pqf, " "); + for (i = 0; i < num; i++) { - if (i == 0) - wrbuf_printf(w_pqf, "@and "); - - /* or multiple values.. could be bad if last CCL - parse fails, but this is unlikely to happen */ if (i < num - 1) - wrbuf_printf(w_pqf, "@or "); - ccl_pquery(w_pqf, cn); - ccl_rpn_delete(cn); + wrbuf_puts(w_pqf, "@or "); + yaz_encode_pqf_term(w_pqf, values[i], + strlen(values[i])); } } - wrbuf_destroy(ccl_w); - } - else if (!strncmp(s->value, "local:", 6)) { - /* no operation */ - } - else - { - yaz_log(YLOG_WARN, "Target %s: Bad limitmap '%s'", - sdb->database->id, s->value); - ret = -1; /* bad limitmap */ + else if (!strncmp(cvalue, "ccl:", 4)) + { + const char *ccl = cvalue + 4; + WRBUF ccl_w = wrbuf_alloc(); + for (i = 0; i < num; i++) + { + int cerror, cpos; + struct ccl_rpn_node *cn; + wrbuf_rewind(ccl_w); + wrbuf_puts(ccl_w, ccl); + wrbuf_puts(ccl_w, "=\""); + wrbuf_puts(ccl_w, values[i]); + wrbuf_puts(ccl_w, "\""); + + cn = ccl_find_str(ccl_map, wrbuf_cstr(ccl_w), + &cerror, &cpos); + if (cn) + { + if (i == 0) + wrbuf_printf(w_pqf, "@and "); + + /* or multiple values.. could be bad if last + CCL parse fails, but this is unlikely to + happen */ + if (i < num - 1) + wrbuf_printf(w_pqf, "@or "); + ccl_pquery(w_pqf, cn); + ccl_rpn_delete(cn); + } + } + wrbuf_destroy(ccl_w); + } + else if (!strncmp(cvalue, "local:", 6)) { + /* no operation */ + } + else + { + yaz_log(YLOG_WARN, "Target %s: Bad limitmap '%s'", + sdb->database->id, cvalue); + ret = -1; /* bad limitmap */ + } + break; } - break; } } if (!s) { - yaz_log(YLOG_WARN, "Target %s: limit %s used, but no limitmap defined", - (sdb->database ? sdb->database->id : ""), name); + int i; + for (i = 0; i < service->num_metadata; i++) + { + struct conf_metadata *md = service->metadata + i; + if (!strcmp(md->name, name) && md->limitcluster) + { + yaz_log(YLOG_LOG, "limitcluster in use for %s", + md->name); + break; + } + } + if (i == service->num_metadata) + { + yaz_log(YLOG_WARN, "Target %s: limit %s used, but no limitmap defined", + (sdb->database ? sdb->database->id : ""), name); + } } } nmem_destroy(nmem_tmp); @@ -1235,15 +1316,15 @@ static int apply_limit(struct session_database *sdb, // return -1 on query error // return -2 on limit error int client_parse_query(struct client *cl, const char *query, - facet_limits_t facet_limits, - CCL_bibset bibset) + facet_limits_t facet_limits) { struct session *se = client_get_session(cl); + struct conf_service *service = se->service; struct session_database *sdb = client_get_database(cl); struct ccl_rpn_node *cn; int cerror, cpos; ODR odr_out; - CCL_bibset ccl_map = prepare_cclmap(cl, bibset); + CCL_bibset ccl_map = prepare_cclmap(cl, service->ccl_bibset); const char *sru = session_setting_oneval(sdb, PZ_SRU); const char *pqf_prefix = session_setting_oneval(sdb, PZ_PQF_PREFIX); const char *pqf_strftime = session_setting_oneval(sdb, PZ_PQF_STRFTIME); @@ -1265,7 +1346,7 @@ int client_parse_query(struct client *cl, const char *query, wrbuf_puts(w_pqf, " "); } - if (apply_limit(sdb, facet_limits, w_pqf, ccl_map)) + if (apply_limit(sdb, facet_limits, w_pqf, ccl_map, service)) { ccl_qual_rm(&ccl_map); return -2; @@ -1414,7 +1495,7 @@ int client_parse_sort(struct client *cl, struct reclist_sortparms *sp) cl->sort_criteria = 0; } } else { - yaz_log(YLOG_LOG, "Client %s: No sort strategy and spec found.", client_get_id(cl)); + yaz_log(YLOG_DEBUG, "Client %s: No sort strategy and spec found.", client_get_id(cl)); xfree(cl->sort_strategy); cl->sort_strategy = 0; xfree(cl->sort_criteria); @@ -1476,17 +1557,22 @@ int client_get_num_records_filtered(struct client *cl) } void client_set_diagnostic(struct client *cl, int diagnostic, - const char *addinfo) + const char *message, const char *addinfo) { cl->diagnostic = diagnostic; + xfree(cl->message); + cl->message = xstrdup(message); xfree(cl->addinfo); cl->addinfo = 0; if (addinfo) cl->addinfo = xstrdup(addinfo); } -int client_get_diagnostic(struct client *cl, const char **addinfo) +int client_get_diagnostic(struct client *cl, const char **message, + const char **addinfo) { + if (message) + *message = cl->message; if (addinfo) *addinfo = cl->addinfo; return cl->diagnostic;