From 58aba67e02b51934a2cae721269fb381d8b0b08b Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Fri, 5 Aug 2011 16:03:18 +0200 Subject: [PATCH] Command search takes limit parameter The limit parameter allows a search to be limited one or more facets and the corresponding values. This is for server side filtering. --- src/Makefile.am | 1 + src/client.c | 37 ++++++++++++++++++++- src/client.h | 5 ++- src/facet_limit.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/facet_limit.h | 45 +++++++++++++++++++++++++ src/http_command.c | 4 ++- src/session.c | 11 +++++- src/session.h | 3 +- 8 files changed, 195 insertions(+), 5 deletions(-) create mode 100644 src/facet_limit.c create mode 100644 src/facet_limit.h diff --git a/src/Makefile.am b/src/Makefile.am index baa7a0d..5d69f20 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -21,6 +21,7 @@ libpazpar2_a_SOURCES = \ connection.c connection.h \ database.c database.h \ eventl.c eventl.h \ + facet_limit.c facet_limit.h \ getaddrinfo.c \ host.h \ http.c http.h http_command.c \ diff --git a/src/client.c b/src/client.c index 0ea7512..8841c10 100644 --- a/src/client.c +++ b/src/client.c @@ -945,8 +945,41 @@ static char *make_solrquery(struct client *cl) return r; } +static void apply_limit(struct session_database *sdb, + facet_limits_t facet_limits, + WRBUF w) +{ + int i = 0; + const char *name; + const char *value; + for (i = 0; (name = facet_limits_get(facet_limits, i, &value)); i++) + { + struct setting *s = 0; + + for (s = sdb->settings[PZ_FACETMAP]; s; s = s->next) + { + const char *p = strchr(s->name + 3, ':'); + if (p && !strcmp(p + 1, name) && s->value && s->value[0]) + { + wrbuf_insert(w, 0, "@and ", 5); + wrbuf_puts(w, " @attr 1="); + yaz_encode_pqf_term(w, s->value, strlen(s->value)); + wrbuf_puts(w, " "); + yaz_encode_pqf_term(w, value, strlen(value)); + break; + } + } + if (!s) + { + yaz_log(YLOG_WARN, "facet %s used, but no facetmap defined", + name); + } + } +} + // 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); @@ -996,6 +1029,8 @@ int client_parse_query(struct client *cl, const char *query) wrbuf_puts(se->wrbuf, " "); } + apply_limit(sdb, facet_limits, se->wrbuf); + if (!pqf_strftime || !*pqf_strftime) ccl_pquery(se->wrbuf, cn); else diff --git a/src/client.h b/src/client.h index 52c8691..fcb4c9c 100644 --- a/src/client.h +++ b/src/client.h @@ -24,6 +24,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #ifndef CLIENT_H #define CLIENT_H +#include "facet_limit.h" + struct client; struct connection; @@ -80,7 +82,8 @@ int client_is_active(struct client *cl); int client_is_active_preferred(struct client *cl); struct client *client_next_in_session(struct client *cl); -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); Odr_int client_get_hits(struct client *cl); int client_get_num_records(struct client *cl); int client_get_diagnostic(struct client *cl); diff --git a/src/facet_limit.c b/src/facet_limit.c new file mode 100644 index 0000000..dca5c29 --- /dev/null +++ b/src/facet_limit.c @@ -0,0 +1,94 @@ +/* This file is part of Pazpar2. + Copyright (C) 2006-2011 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 +Software Foundation; either version 2, or (at your option) any later +version. + +Pazpar2 is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + +/** \file facet_limit.c + \brief Parse facet limit +*/ + +#if HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include +#include + +#include "facet_limit.h" + +struct facet_limits { + NMEM nmem; + int num; + char **darray; +}; + +facet_limits_t facet_limits_create(const char *param) +{ + int i; + NMEM nmem = nmem_create(); + facet_limits_t fl = nmem_malloc(nmem, sizeof(*fl)); + fl->nmem = nmem; + fl->num = 0; + fl->darray = 0; + if (param) + nmem_strsplit_escape(fl->nmem, ",", param, &fl->darray, + &fl->num, 1, '\\'); + /* replace = with \0 .. for each item */ + for (i = 0; i < fl->num; i++) + { + char *cp = strchr(fl->darray[i], '='); + if (!cp) + { + facet_limits_destroy(fl); + return 0; + } + *cp = '\0'; + } + return fl; +} + +int facet_limits_num(facet_limits_t fl) +{ + return fl->num; +} + +const char *facet_limits_get(facet_limits_t fl, int idx, const char **value) +{ + if (idx >= fl->num || idx < 0) + return 0; + *value = fl->darray[idx] + strlen(fl->darray[idx]) + 1; + return fl->darray[idx]; +} + +void facet_limits_destroy(facet_limits_t fl) +{ + if (fl) + nmem_destroy(fl->nmem); +} + +/* + * Local variables: + * c-basic-offset: 4 + * c-file-style: "Stroustrup" + * indent-tabs-mode: nil + * End: + * vim: shiftwidth=4 tabstop=8 expandtab + */ + diff --git a/src/facet_limit.h b/src/facet_limit.h new file mode 100644 index 0000000..60b8e9a --- /dev/null +++ b/src/facet_limit.h @@ -0,0 +1,45 @@ +/* This file is part of Pazpar2. + Copyright (C) 2006-2011 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 +Software Foundation; either version 2, or (at your option) any later +version. + +Pazpar2 is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + +#ifndef FACET_LIMIT_H +#define FACET_LIMIT_H + +#include + +typedef struct facet_limits *facet_limits_t; + +facet_limits_t facet_limits_create(const char *param); + +int facet_limits_num(facet_limits_t fl); + +const char *facet_limits_get(facet_limits_t fl, int idx, const char **value); + +void facet_limits_destroy(facet_limits_t fl); + +#endif + +/* + * Local variables: + * c-basic-offset: 4 + * c-file-style: "Stroustrup" + * indent-tabs-mode: nil + * End: + * vim: shiftwidth=4 tabstop=8 expandtab + */ + diff --git a/src/http_command.c b/src/http_command.c index 436d4e1..4258b29 100644 --- a/src/http_command.c +++ b/src/http_command.c @@ -1117,6 +1117,7 @@ static void cmd_search(struct http_channel *c) const char *filter = http_argbyname(rq, "filter"); const char *maxrecs = http_argbyname(rq, "maxrecs"); const char *startrecs = http_argbyname(rq, "startrecs"); + const char *limit = http_argbyname(rq, "limit"); enum pazpar2_error_code code; const char *addinfo = 0; @@ -1134,7 +1135,8 @@ static void cmd_search(struct http_channel *c) release_session(c, s); return; } - code = search(s->psession, query, startrecs, maxrecs, filter, &addinfo); + code = search(s->psession, query, startrecs, maxrecs, filter, limit, + &addinfo); if (code) { error(rs, code, addinfo); diff --git a/src/session.c b/src/session.c index 6002a80..622d6d6 100644 --- a/src/session.c +++ b/src/session.c @@ -594,6 +594,7 @@ enum pazpar2_error_code search(struct session *se, const char *query, const char *startrecs, const char *maxrecs, const char *filter, + const char *limit, const char **addinfo) { int live_channels = 0; @@ -601,6 +602,7 @@ enum pazpar2_error_code search(struct session *se, int no_failed = 0; struct client_list *l; struct timeval tval; + facet_limits_t facet_limits; session_log(se, YLOG_DEBUG, "Search"); @@ -627,6 +629,12 @@ enum pazpar2_error_code search(struct session *se, tval.tv_sec += 5; + facet_limits = facet_limits_create(limit); + if (!facet_limits) + { + *addinfo = "limit"; + return PAZPAR2_MALFORMED_PARAMETER_VALUE; + } for (l = se->clients; l; l = l->next) { struct client *cl = l->client; @@ -637,7 +645,7 @@ enum pazpar2_error_code search(struct session *se, client_set_startrecs(cl, atoi(startrecs)); if (prepare_session_database(se, client_get_database(cl)) < 0) ; - else if (client_parse_query(cl, query) < 0) + else if (client_parse_query(cl, query, facet_limits) < 0) no_failed++; else { @@ -649,6 +657,7 @@ enum pazpar2_error_code search(struct session *se, client_start_search(cl); } } + facet_limits_destroy(facet_limits); session_leave(se); if (no_working == 0) { diff --git a/src/session.h b/src/session.h index 179ade2..ec699ee 100644 --- a/src/session.h +++ b/src/session.h @@ -155,7 +155,8 @@ int load_targets(struct session *s, const char *fn); void statistics(struct session *s, struct statistics *stat); enum pazpar2_error_code search(struct session *s, const char *query, const char *startrecs, const char *maxrecs, - const char *filter, const char **addinfo); + const char *filter, const char *limit, + const char **addinfo); struct record_cluster **show_range_start(struct session *s, struct reclist_sortparms *sp, int start, -- 1.7.10.4