From 164c2d7f655059826a900183fa44e76bb8618303 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Mon, 25 Jun 2012 15:38:05 +0200 Subject: [PATCH] New service setting: ccldirective which allows CCl directives to be set. Such as as names for and, or, and-not operators. --- src/client.c | 31 ++++++++++++++++++++++--------- src/client.h | 3 ++- src/pazpar2_config.c | 25 +++++++++++++++++++++++++ src/pazpar2_config.h | 2 ++ src/session.c | 2 +- test/test_http.cfg | 6 ++++++ test/test_http.urls | 4 +++- test/test_http_80.res | 2 ++ test/test_http_81.res | 31 +++++++++++++++++++++++++++++++ 9 files changed, 94 insertions(+), 12 deletions(-) create mode 100644 test/test_http_80.res create mode 100644 test/test_http_81.res diff --git a/src/client.c b/src/client.c index c2187a9..307203e 100644 --- a/src/client.c +++ b/src/client.c @@ -978,7 +978,7 @@ void client_disconnect(struct client *cl) // Initialize CCL map for a target -static CCL_bibset prepare_cclmap(struct client *cl) +static CCL_bibset prepare_cclmap(struct client *cl, CCL_bibset base_bibset) { struct session_database *sdb = client_get_database(cl); struct setting *s; @@ -986,7 +986,10 @@ static CCL_bibset prepare_cclmap(struct client *cl) if (!sdb->settings) return 0; - res = ccl_qual_mk(); + if (base_bibset) + res = ccl_qual_dup(base_bibset); + else + res = ccl_qual_mk(); for (s = sdb->settings[PZ_CCLMAP]; s; s = s->next) { char *p = strchr(s->name + 3, ':'); @@ -1078,12 +1081,18 @@ 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, WRBUF w_ccl) + WRBUF w_pqf, WRBUF w_ccl, + CCL_bibset ccl_map) { int ret = 0; int i = 0; const char *name; const char *value; + const char **and_op_names = ccl_qual_search_special(ccl_map, "and"); + const char *and_op = and_op_names ? and_op_names[0] : "and"; + const char **or_op_names = ccl_qual_search_special(ccl_map, "or"); + const char *or_op = or_op_names ? or_op_names[0] : "or"; + NMEM nmem_tmp = nmem_create(); for (i = 0; (name = facet_limits_get(facet_limits, i, &value)); i++) { @@ -1117,13 +1126,13 @@ static int apply_limit(struct session_database *sdb, else if (!strncmp(s->value, "ccl:", 4)) { const char *ccl = s->value + 4; - - wrbuf_puts(w_ccl, " and ("); + + wrbuf_printf(w_ccl, " %s (", and_op); for (i = 0; i < num; i++) { if (i) - wrbuf_puts(w_ccl, " or "); + wrbuf_printf(w_ccl, " %s ", or_op); wrbuf_puts(w_ccl, ccl); wrbuf_puts(w_ccl, "=\""); wrbuf_puts(w_ccl, values[i]); @@ -1161,14 +1170,15 @@ static int apply_limit(struct session_database *sdb, // return -2 on limit error int client_parse_query(struct client *cl, const char *query, facet_limits_t facet_limits, - const char *startrecs, const char *maxrecs) + const char *startrecs, const char *maxrecs, + CCL_bibset bibset) { struct session *se = client_get_session(cl); 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); + CCL_bibset ccl_map = prepare_cclmap(cl, 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); @@ -1202,8 +1212,11 @@ int client_parse_query(struct client *cl, const char *query, wrbuf_puts(w_pqf, " "); } - if (apply_limit(sdb, facet_limits, w_pqf, w_ccl)) + if (apply_limit(sdb, facet_limits, w_pqf, w_ccl, ccl_map)) + { + ccl_qual_rm(&ccl_map); return -2; + } facet_limits_destroy(cl->facet_limits); cl->facet_limits = facet_limits_dup(facet_limits); diff --git a/src/client.h b/src/client.h index 10b3fb4..e5861b3 100644 --- a/src/client.h +++ b/src/client.h @@ -86,7 +86,8 @@ struct client *client_next_in_session(struct client *cl); int client_parse_query(struct client *cl, const char *query, facet_limits_t facet_limits, const char *startrecs, - const char *maxrecs); + const char *maxrecs, + CCL_bibset bibset); Odr_int client_get_hits(struct client *cl); Odr_int client_get_approximation(struct client *cl); int client_get_num_records(struct client *cl); diff --git a/src/pazpar2_config.c b/src/pazpar2_config.c index b2064f9..f0e395f 100644 --- a/src/pazpar2_config.c +++ b/src/pazpar2_config.c @@ -127,6 +127,7 @@ struct conf_service *service_init(struct conf_server *server, service->next = 0; service->databases = 0; service->xslt_list = 0; + service->ccl_bibset = 0; service->server = server; service->session_timeout = 60; /* default session timeout */ service->z3950_session_timeout = 180; @@ -259,6 +260,7 @@ void service_destroy(struct conf_service *service) { service_xslt_destroy(service); pp2_charset_fact_destroy(service->charsets); + ccl_qual_rm(&service->ccl_bibset); yaz_mutex_destroy(&service->mutex); nmem_destroy(service->nmem); } @@ -542,6 +544,29 @@ static struct conf_service *service_create_static(struct conf_server *server, } } } + else if (!strcmp((const char *) n->name, "ccldirective")) + { + char *name; + char *value; + if (!service->ccl_bibset) + service->ccl_bibset = ccl_qual_mk(); + name = (char *) xmlGetProp(n, (xmlChar *) "name"); + if (!name) + { + yaz_log(YLOG_FATAL, "ccldirective: missing @name"); + return 0; + } + value = (char *) xmlGetProp(n, (xmlChar *) "value"); + if (!value) + { + xmlFree(name); + yaz_log(YLOG_FATAL, "ccldirective: missing @value"); + return 0; + } + ccl_qual_add_special(service->ccl_bibset, name, value); + xmlFree(value); + xmlFree(name); + } else if (!strcmp((const char *) n->name, "settings")) got_settings++; else if (!strcmp((const char *) n->name, "icu_chain")) diff --git a/src/pazpar2_config.h b/src/pazpar2_config.h index 193adcf..5eb9c5e 100644 --- a/src/pazpar2_config.h +++ b/src/pazpar2_config.h @@ -24,6 +24,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include #include +#include #include "charsets.h" #include "http.h" #include "database.h" @@ -122,6 +123,7 @@ struct conf_service struct service_xslt *xslt_list; + CCL_bibset ccl_bibset; struct database *databases; struct conf_server *server; }; diff --git a/src/session.c b/src/session.c index 18ba514..8edaa8d 100644 --- a/src/session.c +++ b/src/session.c @@ -754,7 +754,7 @@ enum pazpar2_error_code session_search(struct session *se, continue; parse_ret = client_parse_query(cl, query, facet_limits, startrecs, - maxrecs); + maxrecs, se->service->ccl_bibset); if (parse_ret == -1) no_failed_query++; else if (parse_ret == -2) diff --git a/test/test_http.cfg b/test/test_http.cfg index 53a0ff0..5e92e0c 100644 --- a/test/test_http.cfg +++ b/test/test_http.cfg @@ -6,7 +6,12 @@ + + + + + @@ -23,6 +28,7 @@ + diff --git a/test/test_http.urls b/test/test_http.urls index 47247d2..c83b70d 100644 --- a/test/test_http.urls +++ b/test/test_http.urls @@ -53,7 +53,7 @@ http://localhost:9763/search.pz2?command=init http://localhost:9763/search.pz2?session=8&command=settings&pz:name%5Bz3950.indexdata.com%2Fmarc%5D=marc&pz:requestsyntax%5Bz3950.indexdata.com%2Fmarc%5D=usmarc&pz:nativesyntax%5Bz3950.indexdata.com%2Fmarc%5D=iso2709&pz:xslt%5Bz3950.indexdata.com%2Fmarc%5D=marc21%5Ftest.xsl&pz:recordfilter%5Bz3950.indexdata.com%2Fmarc%5D=date http://localhost:9763/search.pz2?session=8&command=search&query=xyzzyz 2 http://localhost:9763/search.pz2?session=8&command=show&block=1 -http://localhost:9763/search.pz2?session=8&command=search&query=a+and +http://localhost:9763/search.pz2?session=8&command=search&query=a+AND 1 http://localhost:9763/search.pz2?session=8&command=show&block=1 http://localhost:9763/search.pz2?command=init&pz:limitmap:author%5Bz3950.indexdata.com%2Fmarc%5D=ccl:author_phrase&pz:limitmap:Mysubject%5Bz3950.indexdata.com%2fmarc%5D=local:subject&pz:limitmap:date%5Bz3950.indexdata.com%2fmarc%5D=local: 1 http://localhost:9763/search.pz2?session=9&command=search&query=greece&limit=author%3Dadam\,+james%7Cother_author @@ -77,3 +77,5 @@ http://localhost:9763/search.pz2?session=9&command=show&block=1 http://localhost:9763/search.pz2?command=init http://localhost:9763/search.pz2?session=10&command=search&query=au%3dadam http://localhost:9763/search.pz2?session=10&command=show&block=1 +http://localhost:9763/search.pz2?session=10&command=search&query=teachers+AND+greece +http://localhost:9763/search.pz2?session=10&command=show&block=1 diff --git a/test/test_http_80.res b/test/test_http_80.res new file mode 100644 index 0000000..ab63fe6 --- /dev/null +++ b/test/test_http_80.res @@ -0,0 +1,2 @@ + +OK \ No newline at end of file diff --git a/test/test_http_81.res b/test/test_http_81.res new file mode 100644 index 0000000..33d874f --- /dev/null +++ b/test/test_http_81.res @@ -0,0 +1,31 @@ + +OK +0 +1 +1 +0 +1 + + +The religious teachers of Greece +1972 +Adam, James +Greek literature +Philosophy, Ancient +Greece +Reprint of the 1909 ed., which was issued as the 1904-1906 Gifford lectures +The religious teachers of Greece +1972 +Adam, James +Greek literature +Philosophy, Ancient +Greece +Reprint of the 1909 ed., which was issued as the 1904-1906 Gifford lectures +Includes bibliographical references +XXXXXXXXXX +test-usersetting-2 data: + YYYYYYYYY +540000 +content: title the religious teachers of greece author adam james medium book + + \ No newline at end of file -- 1.7.10.4