From d71af70a6a3546cab2e370140d47c1bd628d9753 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Thu, 6 Dec 2012 17:06:50 +0100 Subject: [PATCH] Allow repeated list in limitmap spec Separated by comma. For example: value="local:title,rpn:@attr 1=4". --- doc/pazpar2_conf.xml | 6 +++ src/client.c | 140 +++++++++++++++++++++++++++++--------------------- 2 files changed, 87 insertions(+), 59 deletions(-) diff --git a/doc/pazpar2_conf.xml b/doc/pazpar2_conf.xml index df8bd6a..60cd710 100644 --- a/doc/pazpar2_conf.xml +++ b/doc/pazpar2_conf.xml @@ -1474,6 +1474,12 @@ by a field a metadata field (default is to use the name of the limitmap itself). + + For Pazpar2 version 1.6.23 and later the limitmap may include multiple + specifications, separated by , (comma). + For example: + ccl:title,local:ltitle,rpn:@attr 1=4. + The limitmap facility is supported for Pazpar2 version 1.6.0. diff --git a/src/client.c b/src/client.c index a194a7e..0618d3a 100644 --- a/src/client.c +++ b/src/client.c @@ -1144,17 +1144,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; + } + } } } } @@ -1175,6 +1186,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, ':'); @@ -1182,66 +1194,76 @@ 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) -- 1.7.10.4