return create_host(hostport);
}
+int resolve_database(struct database *db)
+{
+ if (db->host == 0)
+ {
+ struct host *host;
+ char *p;
+ char hostport[256];
+ strcpy(hostport, db->url);
+ if ((p = strchr(hostport, '/')))
+ *p = '\0';
+ if (!(host = find_host(hostport)))
+ return -1;
+ db->host = host;
+ }
+ return 0;
+}
+
+void resolve_databases(struct conf_service *service)
+{
+ struct database *db = service->databases;
+ for (; db; db = db->next)
+ resolve_database(db);
+}
+
static struct database *load_database(const char *id,
struct conf_service *service)
{
xmlDoc *doc = 0;
struct zr_explain *explain = 0;
struct database *db;
- struct host *host;
char hostport[256];
char *dbname;
struct setting *idset;
*(dbname++) = '\0';
else
dbname = "";
- if (!(host = find_host(hostport)))
- return 0;
db = nmem_malloc(service->nmem, sizeof(*db));
memset(db, 0, sizeof(*db));
- db->host = host;
+ db->host = 0;
db->url = nmem_strdup(service->nmem, id);
db->databases = xmalloc(2 * sizeof(char *));
db->databases[0] = nmem_strdup(service->nmem, dbname);
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
{
struct database *db = find_database(id, 0, se->service);
+ resolve_database(db);
+
session_init_databases_fun((void*) se, db);
// New sdb is head of se->databases list
return se->databases;
void child_handler(void *data)
{
struct conf_config *config = (struct conf_config *) data;
- config_read_settings(config);
+
+ config_start_databases(config);
pazpar2_event_loop();
}
}
static struct conf_service *service_create(struct conf_config *config,
- xmlNode *node, const char *service_id)
+ xmlNode *node,
+ const char *service_id,
+ const char *server_settings)
{
xmlNode *n;
int md_node = 0;
struct conf_service *service = 0;
int num_metadata = 0;
int num_sortkeys = 0;
+ int got_settings = 0;
// count num_metadata and num_sortkeys
for (n = node->children; n; n = n->next)
if (n->type != XML_ELEMENT_NODE)
continue;
if (!strcmp((const char *) n->name, "settings"))
- {
- if (service->settings)
- {
- yaz_log(YLOG_FATAL, "Can't repeat 'settings'");
- return 0;
- }
- service->settings = parse_settings(config, service->nmem, n);
- if (!service->settings)
- return 0;
- }
+ got_settings++;
else if (!strcmp((const char *) n->name, (const char *) "targetprofiles"))
{
if (service->targetprofiles)
return 0;
}
}
+ init_settings(service);
+ if (got_settings)
+ {
+ int pass;
+ /* metadata has been read.. Consider now settings */
+ for (pass = 1; pass <= 2; pass++)
+ {
+ for (n = node->children; n; n = n->next)
+ {
+ if (n->type != XML_ELEMENT_NODE)
+ continue;
+ if (!strcmp((const char *) n->name, "settings"))
+ {
+ xmlChar *src = xmlGetProp(n, (xmlChar *) "src");
+ if (src)
+ {
+ WRBUF w = wrbuf_alloc();
+ conf_dir_path(config, w, (const char *) src);
+ settings_read_file(service, wrbuf_cstr(w), pass);
+ wrbuf_destroy(w);
+ xmlFree(src);
+ }
+ else
+ {
+ settings_read_node(service, n, pass);
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ if (server_settings)
+ {
+ settings_read_file(service, server_settings, 1);
+ settings_read_file(service, server_settings, 2);
+ }
+ }
return service;
}
NMEM nmem, xmlNode *node)
{
xmlNode *n;
+ const char *server_settings = 0;
struct conf_server *server = nmem_malloc(nmem, sizeof(struct conf_server));
server->host = 0;
server->proxy_addr = 0;
server->service = 0;
server->next = 0;
- server->server_settings = 0;
server->relevance_pct = 0;
server->sort_pct = 0;
server->mergekey_pct = 0;
}
else if (!strcmp((const char *) n->name, "settings"))
{
- if (server->server_settings)
+ if (server_settings)
{
yaz_log(YLOG_FATAL, "Can't repeat 'settings'");
return 0;
}
- if (!(server->server_settings = parse_settings(config, nmem, n)))
+ if (!(server_settings = parse_settings(config, nmem, n)))
return 0;
}
else if (!strcmp((const char *) n->name, "relevance"))
return 0;
else
{
- struct conf_service *s = service_create(config, n, service_id);
+ struct conf_service *s = service_create(config, n,
+ service_id,
+ server_settings);
if (s)
{
if (server->relevance_pct)
if (server->sort_pct)
{
-
s->sort_pct = server->sort_pct;
pp2_charset_incref(s->sort_pct);
}
if ((st.st_mode & S_IFMT) == S_IFREG)
{
xmlDoc *doc = xmlParseFile(path);
- yaz_log(YLOG_LOG, "processing include path=%s", path);
if (doc)
{
xmlNodePtr t = xmlDocGetRootElement(doc);
}
}
-void config_read_settings(struct conf_config *config)
+void config_stop_listeners(struct conf_config *conf)
{
- struct conf_service *s = config->servers->service;
- for (;s ; s = s->next)
- {
- init_settings(s);
- if (s->settings)
- settings_read(s, s->settings);
- else if (config->servers->server_settings)
- settings_read(s, config->servers->server_settings);
- else
- yaz_log(YLOG_WARN, "No settings for service");
- }
+ struct conf_server *ser;
+ for (ser = conf->servers; ser; ser = ser->next)
+ http_close_server(ser);
}
-void config_stop_listeners(struct conf_config *conf)
+void config_start_databases(struct conf_config *conf)
{
struct conf_server *ser;
for (ser = conf->servers; ser; ser = ser->next)
- http_close_server(ser);
+ {
+ struct conf_service *s = ser->service;
+ for (;s ; s = s->next)
+ resolve_databases(s);
+ }
}
int config_start_listeners(struct conf_config *conf,
struct sockaddr_in *proxy_addr;
int listener_socket;
- char *server_settings;
-
pp2_charset_t relevance_pct;
pp2_charset_t sort_pct;
pp2_charset_t mergekey_pct;
xsltStylesheet *conf_load_stylesheet(struct conf_config *config,
const char *fname);
-void config_read_settings(struct conf_config *config);
+void config_start_databases(struct conf_config *config);
struct conf_service *locate_service(struct conf_server *server,
const char *service_id);
int i;
char *p;
- // If target address is not wildcard, add the database
- if (*set->target && !zurl_wildcard(set->target))
- find_database(set->target, 0, service);
-
// Determine if we already have a dictionary entry
if (!strncmp(set->name, "pz:", 3) && (p = strchr(set->name + 3, ':')))
*(p + 1) = '\0';
yaz_log(YLOG_WARN, "Setting '%s' not configured as metadata", set->name);
}
-// If we ever decide we need to be able to specify multiple settings directories,
-// the two calls to read_settings must be split -- so the dictionary is prepared
-// for the contents of every directory before the databases are updated.
-void settings_read(struct conf_service *service, const char *path)
-{
- read_settings(path, service, prepare_target_dictionary);
- read_settings(path, service, update_databases);
-}
-
void init_settings(struct conf_service *service)
{
struct setting_dictionary *new;
-
+
assert(service->nmem);
-
+
new = nmem_malloc(service->nmem, sizeof(*new));
memset(new, 0, sizeof(*new));
service->dictionary = new;
initialize_soft_settings(service);
}
+void settings_read_file(struct conf_service *service, const char *path,
+ int pass)
+{
+ if (pass == 1)
+ read_settings(path, service, prepare_target_dictionary);
+ else
+ read_settings(path, service, update_databases);
+}
+
+void settings_read_node(struct conf_service *service, xmlNode *n,
+ int pass)
+{
+ if (pass == 1)
+ read_settings_node(n, service, prepare_target_dictionary);
+ else
+ read_settings_node(n, service, update_databases);
+}
+
/*
* Local variables:
* c-basic-offset: 4
struct setting *next;
};
+void settings_read_file(struct conf_service *service, const char *path,
+ int pass);
+void settings_read_node(struct conf_service *service, xmlNode *n,
+ int pass);
int settings_num(struct conf_service *service);
-void settings_read(struct conf_service *service, const char *path);
int settings_offset(struct conf_service *service, const char *name);
int settings_offset_cprefix(struct conf_service *service, const char *name);
void init_settings(struct conf_service *service);
+void resolve_databases(struct conf_service *service);
#endif
<proxy host="localhost"/>
<service>
- <settings src="z3950_indexdata_com_marc.xml"/>
+ <include src="z3950_indexdata_com_marc.xml"/>
<targetprofiles type="local" src="../zeerex/records/"/>
<metadata name="url" merge="unique"/>
<metadata name="title" brief="yes" sortkey="skiparticle" merge="longest" rank="6"/>