Filter handling now in database.c.
#include <netinet/in.h>
#endif
+enum pazpar2_database_criterion_type {
+ PAZPAR2_STRING_MATCH,
+ PAZPAR2_SUBSTRING_MATCH
+};
+
+struct database_criterion_value {
+ char *value;
+ struct database_criterion_value *next;
+};
+
+struct database_criterion {
+ char *name;
+ enum pazpar2_database_criterion_type type;
+ struct database_criterion_value *values;
+ struct database_criterion *next;
+};
+
static struct host *hosts = 0; /* thread pr */
static xmlDoc *get_explain_xml(struct conf_targetprofiles *targetprofiles,
char *dbname;
struct setting *idset;
- yaz_log(YLOG_LOG, "New database: %s", id);
-
if (service->targetprofiles
&& (doc = get_explain_xml(service->targetprofiles, id)))
{
db->errors = 0;
db->explain = explain;
- db->settings = 0;
-
- db->settings = nmem_malloc(service->nmem, sizeof(struct settings*) *
- settings_num(service));
db->num_settings = settings_num(service);
- memset(db->settings, 0, sizeof(struct settings*) * settings_num(service));
+ db->settings = nmem_malloc(service->nmem, sizeof(struct settings*) *
+ db->num_settings);
+ memset(db->settings, 0, sizeof(struct settings*) * db->num_settings);
idset = nmem_malloc(service->nmem, sizeof(*idset));
idset->precedence = 0;
idset->name = "pz:id";
// Return a database structure by ID. Load and add to list if necessary
// new==1 just means we know it's not in the list
-struct database *find_database(const char *id, int new,
- struct conf_service *service)
+struct database *find_database(const char *id, struct conf_service *service)
{
struct database *p;
- if (!new)
- {
- for (p = service->databases; p; p = p->next)
- if (!strcmp(p->url, id))
- return p;
- }
+ for (p = service->databases; p; p = p->next)
+ if (!strcmp(p->url, id))
+ return p;
return load_database(id, service);
}
return 0;
}
-int database_match_criteria(struct setting **settings,
- struct conf_service *service,
- struct database_criterion *cl)
+// parses crit1=val1,crit2=val2|val3,...
+static struct database_criterion *create_database_criterion(NMEM m,
+ const char *buf)
+{
+ struct database_criterion *res = 0;
+ char **values;
+ int num;
+ int i;
+
+ if (!buf || !*buf)
+ return 0;
+ nmem_strsplit(m, ",", buf, &values, &num);
+ for (i = 0; i < num; i++)
+ {
+ char **subvalues;
+ int subnum;
+ int subi;
+ struct database_criterion *new = nmem_malloc(m, sizeof(*new));
+ char *eq;
+ if ((eq = strchr(values[i], '=')))
+ new->type = PAZPAR2_STRING_MATCH;
+ else if ((eq = strchr(values[i], '~')))
+ new->type = PAZPAR2_SUBSTRING_MATCH;
+ else
+ {
+ yaz_log(YLOG_WARN, "Missing equal-sign/tilde in filter");
+ return 0;
+ }
+ *(eq++) = '\0';
+ new->name = values[i];
+ nmem_strsplit(m, "|", eq, &subvalues, &subnum);
+ new->values = 0;
+ for (subi = 0; subi < subnum; subi++)
+ {
+ struct database_criterion_value *newv
+ = nmem_malloc(m, sizeof(*newv));
+ newv->value = subvalues[subi];
+ newv->next = new->values;
+ new->values = newv;
+ }
+ new->next = res;
+ res = new;
+ }
+ return res;
+}
+
+static int database_match_criteria(struct setting **settings,
+ struct conf_service *service,
+ struct database_criterion *cl)
{
for (; cl; cl = cl->next)
if (!match_criterion(settings, service, cl))
// Cycles through databases, calling a handler function on the ones for
// which all criteria matched.
-int session_grep_databases(struct session *se, struct database_criterion *cl,
- void (*fun)(void *context, struct session_database *db))
+int session_grep_databases(struct session *se, const char *filter,
+ void (*fun)(void *context, struct session_database *db))
{
struct session_database *p;
+ NMEM nmem = nmem_create();
int i = 0;
+ struct database_criterion *cl = create_database_criterion(nmem, filter);
for (p = se->databases; p; p = p->next)
{
i++;
}
}
+ nmem_destroy(nmem);
return i;
}
int predef_grep_databases(void *context, struct conf_service *service,
- struct database_criterion *cl,
void (*fun)(void *context, struct database *db))
{
struct database *p;
int i = 0;
for (p = service->databases; p; p = p->next)
- if (database_match_criteria(p->settings, service, cl))
+ if (database_match_criteria(p->settings, service, 0))
{
(*fun)(context, p);
i++;
#ifndef DATABASE_H
#define DATABASE_H
-void prepare_databases(void);
-struct database *find_database(const char *id, int new, struct conf_service *service);
-int session_grep_databases(struct session *se, struct database_criterion *cl,
+struct database *find_database(const char *id, struct conf_service *service);
+int session_grep_databases(struct session *se, const char *filter,
void (*fun)(void *context, struct session_database *db));
int predef_grep_databases(void *context, struct conf_service *service,
- struct database_criterion *cl,
void (*fun)(void *context, struct database *db));
int match_zurl(const char *zurl, const char *pattern);
int resolve_database(struct database *db);
-
#endif
// Associates a set of clients with a session;
// Note: Session-databases represent databases with per-session
// setting overrides
-int select_targets(struct session *se, struct database_criterion *crit)
+static int select_targets(struct session *se, const char *filter)
{
while (se->clients)
client_destroy(se->clients);
- return session_grep_databases(se, crit, select_targets_callback);
+ return session_grep_databases(se, filter, select_targets_callback);
}
int session_active_clients(struct session *s)
return res;
}
-// parses crit1=val1,crit2=val2|val3,...
-static struct database_criterion *parse_filter(NMEM m, const char *buf)
-{
- struct database_criterion *res = 0;
- char **values;
- int num;
- int i;
-
- if (!buf || !*buf)
- return 0;
- nmem_strsplit(m, ",", buf, &values, &num);
- for (i = 0; i < num; i++)
- {
- char **subvalues;
- int subnum;
- int subi;
- struct database_criterion *new = nmem_malloc(m, sizeof(*new));
- char *eq;
- if ((eq = strchr(values[i], '=')))
- new->type = PAZPAR2_STRING_MATCH;
- else if ((eq = strchr(values[i], '~')))
- new->type = PAZPAR2_SUBSTRING_MATCH;
- else
- {
- yaz_log(YLOG_WARN, "Missing equal-sign/tilde in filter");
- return 0;
- }
- *(eq++) = '\0';
- new->name = values[i];
- nmem_strsplit(m, "|", eq, &subvalues, &subnum);
- new->values = 0;
- for (subi = 0; subi < subnum; subi++)
- {
- struct database_criterion_value *newv
- = nmem_malloc(m, sizeof(*newv));
- newv->value = subvalues[subi];
- newv->next = new->values;
- new->values = newv;
- }
- new->next = res;
- res = new;
- }
- return res;
-}
enum pazpar2_error_code search(struct session *se,
const char *query,
int no_working = 0;
int no_failed = 0;
struct client *cl;
- struct database_criterion *criteria;
yaz_log(YLOG_DEBUG, "Search");
se->total_records = se->total_hits = se->total_merged = 0;
se->reclist = 0;
se->num_termlists = 0;
- criteria = parse_filter(se->nmem, filter);
- live_channels = select_targets(se, criteria);
+ live_channels = select_targets(se, filter);
if (live_channels)
{
se->reclist = reclist_create(se->nmem);
void session_init_databases(struct session *se)
{
se->databases = 0;
- predef_grep_databases(se, se->service, 0, session_init_databases_fun);
+ predef_grep_databases(se, se->service, session_init_databases_fun);
}
// Probably session_init_databases_fun should be refactored instead of
static struct session_database *load_session_database(struct session *se,
char *id)
{
- struct database *db = find_database(id, 0, se->service);
+ struct database *db = find_database(id, se->service);
resolve_database(db);
PAZPAR2_LAST_ERROR
};
-enum pazpar2_database_criterion_type {
- PAZPAR2_STRING_MATCH,
- PAZPAR2_SUBSTRING_MATCH
-};
-
+struct host;
// Represents a (virtual) database on a host
struct database {
struct host *host;
struct database *next;
};
-struct database_criterion_value {
- char *value;
- struct database_criterion_value *next;
-};
-
-struct database_criterion {
- char *name;
- enum pazpar2_database_criterion_type type;
- struct database_criterion_value *values;
- struct database_criterion *next;
-};
// Represents a database as viewed from one session, possibly with settings overriden
// for that session
struct session_database *next;
};
-
-
#define SESSION_WATCH_SHOW 0
#define SESSION_WATCH_RECORD 1
#define SESSION_WATCH_MAX 1
};
struct hitsbytarget *hitsbytarget(struct session *s, int *count, NMEM nmem);
-int select_targets(struct session *se, struct database_criterion *crit);
struct session *new_session(NMEM nmem, struct conf_service *service);
void destroy_session(struct session *s);
void session_init_databases(struct session *s);
struct update_database_context context;
context.set = set;
context.service = service;
- predef_grep_databases(&context, service, 0, update_database);
+ predef_grep_databases(&context, service, update_database);
}
// This simply copies the 'hard' (application-specific) settings
// If target address is not wildcard, add the database
if (*set->target && !zurl_wildcard(set->target))
- find_database(set->target, 0, service);
+ find_database(set->target, service);
// Determine if we already have a dictionary entry
if (!strncmp(set->name, "pz:", 3) && (p = strchr(set->name + 3, ':')))