X-Git-Url: http://jsfdemo.indexdata.com/?a=blobdiff_plain;f=src%2Fsettings.c;h=124d9db7eb23f3fb8495ab44dd2112af6f261086;hb=512a11133b1ccc4a44d6e971c8a446865136bb15;hp=b8c1d0a12f50140950a000ea48882fdff415b453;hpb=ebf44db2f0c270b3ae1c25a5dc627f8e2a932da7;p=pazpar2-moved-to-github.git diff --git a/src/settings.c b/src/settings.c index b8c1d0a..124d9db 100644 --- a/src/settings.c +++ b/src/settings.c @@ -1,5 +1,5 @@ /* This file is part of Pazpar2. - Copyright (C) 2006-2011 Index Data + Copyright (C) 2006-2012 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 @@ -59,7 +59,6 @@ static char *hard_settings[] = { "pz:id", "pz:name", "pz:queryencoding", - "pz:ip", "pz:zproxy", "pz:apdulog", "pz:sru", @@ -70,13 +69,18 @@ static char *hard_settings[] = { "pz:pqf_strftime", "pz:negotiation_charset", "pz:max_connections", - "pz:reuse_connections", /* PZ_REUSE_CONNECTION */ - "pz:termlist_term_factor", /* PZ_TERMLIST_TERM_FACTOR*/ - "pz:preferred", /* PZ_PREFERRED */ - "pz:extra_args", /* PZ_EXTRA_ARGS */ - "pz:query_syntax", /* PZ_QUERY_SYNTAX */ - "pz:option_recordfilter", /* PZ_OPTION_RECORDFILTER */ - "pz:facetmap:", /* PZ_FACETMAP */ + "pz:reuse_connections", + "pz:termlist_term_factor", + "pz:termlist_term_count", + "pz:preferred", + "pz:extra_args", + "pz:query_syntax", + "pz:facetmap:", + "pz:limitmap:", + "pz:url", + "pz:sortmap:", + "pz:present_chunk", + "pz:block_timeout", 0 }; @@ -98,13 +102,12 @@ int settings_num(struct conf_service *service) return service->dictionary->num; } -static int settings_lookup(struct conf_service *service, const char *name, - int allow_create) +/* Find and possible create a new dictionary entry. Pass valid NMEM pointer if creation is allowed, otherwise null */ +static int settings_index_lookup(struct setting_dictionary *dictionary, const char *name, NMEM nmem) { size_t maxlen; int i; const char *p; - struct setting_dictionary *dictionary = service->dictionary; assert(name); @@ -115,31 +118,31 @@ static int settings_lookup(struct conf_service *service, const char *name, for (i = 0; i < dictionary->num; i++) if (!strncmp(name, dictionary->dict[i], maxlen)) return i; - if (!allow_create) + if (!nmem) return -1; if (!strncmp("pz:", name, 3)) yaz_log(YLOG_WARN, "Adding pz-type setting name %s", name); if (dictionary->num + 1 > dictionary->size) { char **tmp = - nmem_malloc(service->nmem, dictionary->size * 2 * sizeof(char*)); + nmem_malloc(nmem, dictionary->size * 2 * sizeof(char*)); memcpy(tmp, dictionary->dict, dictionary->size * sizeof(char*)); dictionary->dict = tmp; dictionary->size *= 2; } - dictionary->dict[dictionary->num] = nmem_strdup(service->nmem, name); + dictionary->dict[dictionary->num] = nmem_strdup(nmem, name); dictionary->dict[dictionary->num][maxlen-1] = '\0'; return dictionary->num++; } int settings_create_offset(struct conf_service *service, const char *name) { - return settings_lookup(service, name, 1); + return settings_index_lookup(service->dictionary, name, service->nmem); } int settings_lookup_offset(struct conf_service *service, const char *name) { - return settings_lookup(service, name, 0); + return settings_index_lookup(service->dictionary, name, 0); } char *settings_name(struct conf_service *service, int offset) @@ -148,6 +151,22 @@ char *settings_name(struct conf_service *service, int offset) return service->dictionary->dict[offset]; } + +// Apply a session override to a database +void service_apply_setting(struct conf_service *service, char *setting, char *value) +{ + struct setting *new = nmem_malloc(service->nmem, sizeof(*new)); + int offset = settings_create_offset(service, setting); + expand_settings_array(&service->settings->settings, &service->settings->num_settings, offset, service->nmem); + new->precedence = 0; + new->target = NULL; + new->name = setting; + new->value = value; + new->next = service->settings->settings[offset]; + service->settings->settings[offset] = new; +} + + static int isdir(const char *path) { struct stat st; @@ -332,9 +351,75 @@ void expand_settings_array(struct setting ***set_ar, int *num, int offset, } } +void expand_settings_array2(struct settings *settings, int offset, NMEM nmem) +{ + assert(offset >= 0); + assert(settings); + if (offset >= settings->num_settings) + { + int i, n_num = offset + 10; + struct setting **n_ar = nmem_malloc(nmem, n_num * sizeof(*n_ar)); + for (i = 0; i < settings->num_settings; i++) + n_ar[i] = settings->settings[i]; + for (; i < n_num; i++) + n_ar[i] = 0; + settings->num_settings = n_num; + settings->settings = n_ar; + } +} + +static void update_settings(struct setting *set, struct settings *settings, int offset, NMEM nmem) +{ + struct setting **sp; + yaz_log(YLOG_LOG, "update service settings offset %d with %s=%s", offset, set->name, set->value); + expand_settings_array2(settings, offset, nmem); + + // First we determine if this setting is overriding any existing settings + // with the same name. + assert(offset < settings->num_settings); + for (sp = &settings->settings[offset]; *sp; ) + if (!strcmp((*sp)->name, set->name)) + { + if ((*sp)->precedence < set->precedence) + { + // We discard the value (nmem keeps track of the space) + *sp = (*sp)->next; // unlink value from existing setting + } + else if ((*sp)->precedence > set->precedence) + { + // Db contains a higher-priority setting. Abort search + break; + } + else if (zurl_wildcard((*sp)->target) > zurl_wildcard(set->target)) + { + // target-specific value trumps wildcard. Delete. + *sp = (*sp)->next; // unlink..... + } + else if (zurl_wildcard((*sp)->target) < zurl_wildcard(set->target)) + // Db already contains higher-priority setting. Abort search + break; + else + sp = &(*sp)->next; + } + else + sp = &(*sp)->next; + if (!*sp) // is null when there are no higher-priority settings, so we add one + { + struct setting *new = nmem_malloc(nmem, sizeof(*new)); + memset(new, 0, sizeof(*new)); + new->precedence = set->precedence; + new->target = nmem_strdup_null(nmem, set->target); + new->name = nmem_strdup_null(nmem, set->name); + new->value = nmem_strdup_null(nmem, set->value); + new->next = settings->settings[offset]; + settings->settings[offset] = new; + } +} + + // This is called from grep_databases -- adds/overrides setting for a target // This is also where the rules for precedence of settings are implemented -static void update_database(void *context, struct database *db) +static void update_database_fun(void *context, struct database *db) { struct setting *set = ((struct update_database_context *) context)->set; @@ -344,12 +429,11 @@ static void update_database(void *context, struct database *db) int offset; // Is this the right database? - if (!match_zurl(db->url, set->target)) + if (!match_zurl(db->id, set->target)) return; offset = settings_create_offset(service, set->name); - expand_settings_array(&db->settings, &db->num_settings, offset, - service->nmem); + expand_settings_array(&db->settings, &db->num_settings, offset, service->nmem); // First we determine if this setting is overriding any existing settings // with the same name. @@ -402,7 +486,7 @@ static void update_databases(void *client_data, struct setting *set) struct update_database_context context; context.set = set; context.service = service; - predef_grep_databases(&context, service, update_database); + predef_grep_databases(&context, service, update_database_fun); } // This simply copies the 'hard' (application-specific) settings @@ -418,40 +502,49 @@ static void initialize_hard_settings(struct conf_service *service) // Read any settings names introduced in service definition (config) and add to dictionary // This is done now to avoid errors if user settings are declared in session overrides -static void initialize_soft_settings(struct conf_service *service) +void initialize_soft_settings(struct conf_service *service) { int i; - for (i = 0; i < service->num_metadata; i++) { struct conf_metadata *md = &service->metadata[i]; - if (md->setting == Metadata_setting_no) - continue; - - settings_create_offset(service, md->name); + if (md->setting != Metadata_setting_no) + settings_create_offset(service, md->name); + + // Also create setting for some metadata attributes. + if (md->limitmap) { + int index; + WRBUF wrbuf = wrbuf_alloc(); + yaz_log(YLOG_DEBUG, "Metadata %s has limitmap: %s ",md->name, md->limitmap); + wrbuf_printf(wrbuf, "pz:limitmap:%s", md->name); + index = settings_create_offset(service, wrbuf_cstr(wrbuf)); + if (index >= 0) { + struct setting new; + int offset; + yaz_log(YLOG_DEBUG, "Service %s default %s=%s", + (service->id ? service->id: "unknown"), wrbuf_cstr(wrbuf), md->limitmap); + new.name = (char *) wrbuf_cstr(wrbuf); + new.value = md->limitmap; + new.next = 0; + new.target = 0; + new.precedence = 0; + offset = settings_create_offset(service, new.name); + update_settings(&new, service->settings, offset, service->nmem); + } + wrbuf_destroy(wrbuf); + // TODO same for facetmap + } } } static void prepare_target_dictionary(void *client_data, struct setting *set) { struct conf_service *service = (struct conf_service *) client_data; - struct setting_dictionary *dictionary = service->dictionary; - - int i; - char *p; // If target address is not wildcard, add the database if (*set->target && !zurl_wildcard(set->target)) - find_database(set->target, service); - - // Determine if we already have a dictionary entry - if (!strncmp(set->name, "pz:", 3) && (p = strchr(set->name + 3, ':'))) - *(p + 1) = '\0'; - for (i = 0; i < dictionary->num; i++) - if (!strcmp(dictionary->dict[i], set->name)) - return; - yaz_log(YLOG_WARN, "Setting '%s' not configured as metadata", set->name); + create_database_for_service(set->target, service); } void init_settings(struct conf_service *service)