1 /* $Id: database.c,v 1.1 2007-03-15 16:55:34 quinn Exp $ */
3 #include <libxml/parser.h>
4 #include <libxml/tree.h>
5 #include <libxslt/xslt.h>
6 #include <libxslt/transform.h>
7 #include <libxslt/xsltutils.h>
15 static struct host *hosts = 0; // The hosts we know about
16 static struct database *databases = 0; // The databases we know about
19 // This needs to be extended with selection criteria
20 static struct conf_retrievalprofile *database_retrievalprofile(const char *id)
24 yaz_log(YLOG_FATAL, "Must load configuration (-f)");
27 if (!config->retrievalprofiles)
29 yaz_log(YLOG_FATAL, "No retrieval profiles defined");
31 return config->retrievalprofiles;
34 static struct conf_queryprofile *database_queryprofile(const char *id)
36 return (struct conf_queryprofile*) 1;
39 static xmlDoc *get_explain_xml(const char *id)
44 if (!config || !config->targetprofiles)
46 yaz_log(YLOG_WARN, "Config must be loaded and specify targetprofiles");
49 if (config->targetprofiles->type != Targetprofiles_local)
51 yaz_log(YLOG_FATAL, "Only supports local type");
54 dir = config->targetprofiles->src;
56 sprintf(path, "%s/%s", dir, ide);
57 yaz_log(YLOG_LOG, "Path: %s", path);
58 return xmlParseFile(path);
61 // Create a new host structure for hostport
62 static struct host *create_host(const char *hostport)
64 struct addrinfo *addrinfo, hints;
68 unsigned char addrbuf[4];
71 host = xmalloc(sizeof(struct host));
72 host->hostport = xstrdup(hostport);
73 host->connections = 0;
75 if ((port = strchr(hostport, ':')))
81 hints.ai_family = PF_INET;
82 hints.ai_socktype = SOCK_STREAM;
83 hints.ai_protocol = IPPROTO_TCP;
86 hints.ai_canonname = 0;
88 // This is not robust code. It assumes that getaddrinfo always
89 // returns AF_INET address.
90 if ((res = getaddrinfo(hostport, port, &hints, &addrinfo)))
92 yaz_log(YLOG_WARN, "Failed to resolve %s: %s", hostport, gai_strerror(res));
93 xfree(host->hostport);
97 assert(addrinfo->ai_family == PF_INET);
98 memcpy(addrbuf, &((struct sockaddr_in*)addrinfo->ai_addr)->sin_addr.s_addr, 4);
99 sprintf(ipport, "%u.%u.%u.%u:%s",
100 addrbuf[0], addrbuf[1], addrbuf[2], addrbuf[3], port);
101 host->ipport = xstrdup(ipport);
102 freeaddrinfo(addrinfo);
108 static struct host *find_host(const char *hostport)
111 for (p = hosts; p; p = p->next)
112 if (!strcmp(p->hostport, hostport))
114 return create_host(hostport);
117 static struct database *load_database(const char *id)
119 xmlDoc *doc = get_explain_xml(id);
120 struct zr_explain *explain;
121 struct conf_retrievalprofile *retrieval;
122 struct conf_queryprofile *query;
129 nmem = nmem_create();
132 explain = zr_read_xml(nmem, xmlDocGetRootElement(doc));
136 if (!(retrieval = database_retrievalprofile(id)) ||
137 !(query = database_queryprofile(id)))
142 if (strlen(id) > 255)
144 strcpy(hostport, id);
145 if ((dbname = strchr(hostport, '/')))
149 if (!(host = find_host(hostport)))
151 db = nmem_malloc(nmem, sizeof(*db));
152 memset(db, 0, sizeof(*db));
154 db->url = nmem_strdup(nmem, id);
156 db->databases = xmalloc(2 * sizeof(char *));
157 db->databases[0] = nmem_strdup(nmem, dbname);
158 db->databases[1] = 0;
160 db->explain = explain;
161 db->qprofile = query;
162 db->rprofile = retrieval;
163 db->next = databases;
169 // Return a database structure by ID. Load and add to list if necessary
170 // new==1 just means we know it's not in the list
171 struct database *find_database(const char *id, int new)
176 for (p = databases; p; p = p->next)
177 if (!strcmp(p->url, id))
180 return load_database(id);
183 // Needs to be extended with criteria
184 // Cycles through databases, calling a handler function on each.
185 int grep_databases(void *context, void (*fun)(void *context, struct database *db))
190 for (p = databases; p; p = p->next)
198 // This function will most likely vanish when a proper target profile mechanism is
200 void load_simpletargets(const char *fn)
202 FILE *f = fopen(fn, "r");
207 yaz_log(YLOG_WARN|YLOG_ERRNO, "open %s", fn);
211 while (fgets(line, 255, f))
216 if (strncmp(line, "target ", 7))
218 line[strlen(line) - 1] = '\0';
220 if ((name = strchr(line, ';')))
225 if (!find_database(url, 0))
226 yaz_log(YLOG_WARN, "Unable to load database %s", url);
235 * indent-tabs-mode: nil
237 * vim: shiftwidth=4 tabstop=8 expandtab