strcpy(type, "xml");
return 0;
}
- else if (!strcmp(syntax, "TXML"))
- {
- strcpy(type, "txml");
- return 0;
- }
else if (!strcmp(syntax, "USmarc") || !strcmp(syntax, "MARC21"))
{
strcpy(type, "xml; charset=marc8-s");
*/
void client_report_facets(struct client *cl, ZOOM_resultset rs)
{
- int facet_idx;
struct session_database *sdb = client_get_database(cl);
ZOOM_facet_field *facets = ZOOM_resultset_facets(rs);
- int facet_num;
- struct session *se = client_get_session(cl);
- struct setting *s;
- facet_num = ZOOM_resultset_facets_size(rs);
- yaz_log(YLOG_DEBUG, "client_report_facets: %d", facet_num);
- for (s = sdb->settings[PZ_FACETMAP]; s; s = s->next)
+ if (sdb && facets)
{
- const char *p = strchr(s->name + 3, ':');
- if (p && p[1] && s->value && s->value[0])
+ struct session *se = client_get_session(cl);
+ int facet_num = ZOOM_resultset_facets_size(rs);
+ struct setting *s;
+
+ for (s = sdb->settings[PZ_FACETMAP]; s; s = s->next)
{
- p++; /* p now holds logical facet name */
- for (facet_idx = 0; facet_idx < facet_num; facet_idx++)
+ const char *p = strchr(s->name + 3, ':');
+ if (p && p[1] && s->value && s->value[0])
{
- const char *native_name =
- ZOOM_facet_field_name(facets[facet_idx]);
- if (native_name && !strcmp(s->value, native_name))
+ int facet_idx;
+ p++; /* p now holds logical facet name */
+ for (facet_idx = 0; facet_idx < facet_num; facet_idx++)
{
- size_t term_idx;
- size_t term_num =
- ZOOM_facet_field_term_count(facets[facet_idx]);
- for (term_idx = 0; term_idx < term_num; term_idx++ )
+ const char *native_name =
+ ZOOM_facet_field_name(facets[facet_idx]);
+ if (native_name && !strcmp(s->value, native_name))
{
- int freq;
- const char *term =
- ZOOM_facet_field_get_term(facets[facet_idx],
- term_idx, &freq);
- if (term)
- add_facet(se, p, term, freq);
+ size_t term_idx;
+ size_t term_num =
+ ZOOM_facet_field_term_count(facets[facet_idx]);
+ for (term_idx = 0; term_idx < term_num; term_idx++ )
+ {
+ int freq;
+ const char *term =
+ ZOOM_facet_field_get_term(facets[facet_idx],
+ term_idx, &freq);
+ if (term)
+ add_facet(se, p, term, freq);
+ }
+ break;
}
- break;
}
}
}
client_set_connection(cl, 0);
}
-// Extract terms from query into null-terminated termlist
-static void extract_terms(NMEM nmem, struct ccl_rpn_node *query, char **termlist)
-{
- int num = 0;
-
- pull_terms(nmem, query, termlist, &num);
- termlist[num] = 0;
-}
// Initialize CCL map for a target
static CCL_bibset prepare_cclmap(struct client *cl)
return r;
}
+static void apply_limit(struct session_database *sdb,
+ facet_limits_t facet_limits,
+ WRBUF w_pqf, WRBUF w_ccl)
+{
+ 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;
+
+ 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_puts(w_ccl, " and (");
+
+ for (i = 0; i < num; i++)
+ {
+ if (i)
+ wrbuf_puts(w_ccl, " or ");
+ wrbuf_puts(w_ccl, ccl);
+ wrbuf_puts(w_ccl, "=\"");
+ wrbuf_puts(w_ccl, values[i]);
+ wrbuf_puts(w_ccl, "\"");
+ }
+ wrbuf_puts(w_ccl, ")");
+
+ }
+ break;
+ }
+ }
+ nmem_reset(nmem_tmp);
+ if (!s)
+ {
+ yaz_log(YLOG_WARN, "Target %s: limit %s used, but no limitmap defined",
+ (sdb->database ? sdb->database->url : "<no url>"), name);
+ }
+ }
+ nmem_destroy(nmem_tmp);
+}
+
// Parse the query given the settings specific to this client
-int client_parse_query(struct client *cl, const char *query)
+int client_parse_query(struct client *cl, const char *query,
+ facet_limits_t facet_limits)
{
struct session *se = client_get_session(cl);
struct session_database *sdb = client_get_database(cl);
struct ccl_rpn_node *cn;
- struct ccl_rpn_node *cn_recordfilter = 0;
int cerror, cpos;
CCL_bibset ccl_map = prepare_cclmap(cl);
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);
const char *query_syntax = session_setting_oneval(sdb, PZ_QUERY_SYNTAX);
- /* Collected, Mixed, Remote */
- const char *option_recordfilter = session_setting_oneval(sdb, PZ_OPTION_RECORDFILTER);
- const char *record_filter = session_setting_oneval(sdb, PZ_RECORDFILTER);
+ WRBUF w_ccl, w_pqf;
if (!ccl_map)
return -1;
- yaz_log(YLOG_DEBUG, "query: %s", query);
- cn = ccl_find_str(ccl_map, query, &cerror, &cpos);
- if (strcmp("remote", option_recordfilter) == 0 && record_filter != 0 && record_filter[0] != 0) {
- int cerror, cpos;
- yaz_log(YLOG_DEBUG, "record_filter: %s", record_filter);
- cn_recordfilter = ccl_find_str(ccl_map, record_filter, &cerror, &cpos);
- if (!cn_recordfilter)
- session_log(se, YLOG_WARN, "Failed to parse CCL record filter '%s' for %s",
- record_filter, client_get_database(cl)->database->url);
+ w_ccl = wrbuf_alloc();
+ wrbuf_puts(w_ccl, query);
+
+ w_pqf = wrbuf_alloc();
+ if (*pqf_prefix)
+ {
+ wrbuf_puts(w_pqf, pqf_prefix);
+ wrbuf_puts(w_pqf, " ");
}
+
+ apply_limit(sdb, facet_limits, w_pqf, w_ccl);
+
+ yaz_log(YLOG_LOG, "CCL query: %s", wrbuf_cstr(w_ccl));
+ cn = ccl_find_str(ccl_map, wrbuf_cstr(w_ccl), &cerror, &cpos);
ccl_qual_rm(&ccl_map);
if (!cn)
{
client_set_state(cl, Client_Error);
session_log(se, YLOG_WARN, "Failed to parse CCL query '%s' for %s",
- query,
- client_get_database(cl)->database->url);
+ wrbuf_cstr(w_ccl),
+ client_get_database(cl)->database->url);
+ wrbuf_destroy(w_ccl);
+ wrbuf_destroy(w_pqf);
return -1;
}
- wrbuf_rewind(se->wrbuf);
- if (*pqf_prefix)
- {
- wrbuf_puts(se->wrbuf, pqf_prefix);
- wrbuf_puts(se->wrbuf, " ");
- }
-
- if (cn_recordfilter) {
- wrbuf_puts(se->wrbuf, "@and ");
- ccl_pquery(se->wrbuf, cn_recordfilter);
- wrbuf_puts(se->wrbuf, " ");
- }
+ wrbuf_destroy(w_ccl);
if (!pqf_strftime || !*pqf_strftime)
- ccl_pquery(se->wrbuf, cn);
+ ccl_pquery(w_pqf, cn);
else
{
time_t cur_time = time(0);
for (; *cp; cp++)
{
if (cp[0] == '%')
- ccl_pquery(se->wrbuf, cn);
+ ccl_pquery(w_pqf, cn);
else
- wrbuf_putc(se->wrbuf, cp[0]);
+ wrbuf_putc(w_pqf, cp[0]);
}
}
xfree(cl->pquery);
- cl->pquery = xstrdup(wrbuf_cstr(se->wrbuf));
+ cl->pquery = xstrdup(wrbuf_cstr(w_pqf));
+ wrbuf_destroy(w_pqf);
- yaz_log(YLOG_DEBUG, "PQF query: %s", cl->pquery);
+ yaz_log(YLOG_LOG, "PQF query: %s", cl->pquery);
xfree(cl->cqlquery);
if (!se->relevance)
{
// Initialize relevance structure with query terms
- char *p[512];
- extract_terms(se->nmem, cn, p);
- se->relevance = relevance_create(
- se->service->relevance_pct,
- se->nmem, (const char **) p);
+ se->relevance = relevance_create_ccl(
+ se->service->charsets, se->nmem, cn);
}
ccl_rpn_delete(cn);