+const char *client_get_facet_limit_local(struct client *cl,
+ struct session_database *sdb,
+ int *l,
+ NMEM nmem, int *num, char ***values)
+{
+ const char *name = 0;
+ const char *value = 0;
+ for (; (name = facet_limits_get(cl->facet_limits, *l, &value)); (*l)++)
+ {
+ struct setting *s = 0;
+
+ 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))
+ {
+ const char *cp = s->value + 6;
+ while (*cp == ' ')
+ cp++;
+
+ nmem_strsplit_escape2(nmem, "|", value, values,
+ num, 1, '\\', 1);
+ (*l)++;
+ return *cp ? cp : name;
+ }
+ }
+ }
+ return 0;
+}
+
+static int apply_limit(struct session_database *sdb,
+ facet_limits_t facet_limits,
+ WRBUF w_pqf, CCL_bibset ccl_map)
+{
+ int ret = 0;
+ int i = 0;
+ const char *name;
+ const char *value;
+
+ NMEM nmem_tmp = nmem_create();
+ for (i = 0; (name = facet_limits_get(facet_limits, i, &value)); i++)
+ {
+ struct setting *s = 0;
+ nmem_reset(nmem_tmp);
+ 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)
+ {
+ char **values = 0;
+ int i, num = 0;
+ nmem_strsplit_escape2(nmem_tmp, "|", value, &values,
+ &num, 1, '\\', 1);
+
+ if (!strncmp(s->value, "rpn:", 4))
+ {
+ const char *pqf = s->value + 4;
+
+ 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))
+ {
+ const char *ccl = s->value + 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(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 */
+ }
+ break;
+ }
+ }
+ if (!s)
+ {
+ yaz_log(YLOG_WARN, "Target %s: limit %s used, but no limitmap defined",
+ (sdb->database ? sdb->database->id : "<no id>"), name);
+ }
+ }
+ nmem_destroy(nmem_tmp);
+ return ret;
+}
+