No empty .Rs/.Re
[netbsd-mini2440.git] / external / bsd / bind / dist / contrib / sdb / sqlite / sqlitedb.c
blob842096c02bd34499387c3f6a437ba4924cac543a
1 /* $NetBSD$ */
3 /*
4 * Copyright (C) 2007 Internet Software Consortium.
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
11 * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
12 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
13 * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
15 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
16 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
17 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 /* Id: sqlitedb.c,v 1.1 2007/03/05 05:30:22 marka Exp */
22 #include <config.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include <stdlib.h>
27 #include <unistd.h>
29 #include <sqlite3.h>
31 #include <isc/mem.h>
32 #include <isc/print.h>
33 #include <isc/result.h>
34 #include <isc/util.h>
36 #include <dns/sdb.h>
37 #include <dns/result.h>
39 #include <named/globals.h>
41 #include "sqlitedb.h"
44 * A simple database driver that interfaces to a SQLite database.
46 * The table must contain the fields "name", "rdtype", and "rdata", and
47 * is expected to contain a properly constructed zone. The program "zonetodb"
48 * creates such a table.
51 static dns_sdbimplementation_t *sqlitedb = NULL;
53 typedef struct _dbinfo {
54 sqlite3 *db;
55 char *filename;
56 char *table;
57 } dbinfo_t;
60 static isc_result_t
61 db_connect(dbinfo_t *dbi)
63 if (sqlite3_open(dbi->filename, &dbi->db) == SQLITE_OK) {
64 return (ISC_R_SUCCESS);
65 } else {
66 /* a connection is returned even if the open fails */
67 sqlite3_close(dbi->db);
68 dbi->db = NULL;
69 return (ISC_R_FAILURE);
74 typedef struct _lookup_parm_t {
75 int i;
76 dns_sdblookup_t *lookup;
77 isc_result_t result;
78 } lookup_parm_t;
81 static int
82 sqlitedb_lookup_cb(void *p, int cc, char **cv, char **cn)
84 lookup_parm_t *parm = p;
85 dns_ttl_t ttl;
86 char *endp;
88 /* FIXME - check these(num/names); I'm assuming a mapping for now */
89 char *ttlstr = cv[0];
90 char *type = cv[1];
91 char *data = cv[2];
93 UNUSED(cc);
94 UNUSED(cn);
96 ttl = strtol(ttlstr, &endp, 10);
97 if (*endp) {
98 parm->result = DNS_R_BADTTL;
99 return 1;
102 parm->result = dns_sdb_putrr(parm->lookup, type, ttl, data);
104 if (parm->result != ISC_R_SUCCESS)
105 return 1;
107 (parm->i)++;
109 return 0;
113 static isc_result_t
114 sqlitedb_lookup(const char *zone,
115 const char *name, void *dbdata,
116 dns_sdblookup_t *lookup)
118 * synchronous absolute name lookup
121 dbinfo_t *dbi = (dbinfo_t *) dbdata;
122 char *sql;
123 lookup_parm_t parm = { 0, lookup, ISC_R_SUCCESS };
124 char *errmsg = NULL;
125 int result;
127 UNUSED(zone);
129 sql = sqlite3_mprintf(
130 "SELECT TTL,RDTYPE,RDATA FROM \"%q\" WHERE "
131 "lower(NAME) = lower('%q')",
132 dbi->table, name);
134 result = sqlite3_exec(dbi->db, sql,
135 &sqlitedb_lookup_cb, &parm,
136 &errmsg);
137 sqlite3_free(sql);
139 if (result != SQLITE_OK)
140 return (ISC_R_FAILURE);
141 if (parm.i == 0)
142 return (ISC_R_NOTFOUND);
144 return (ISC_R_SUCCESS);
148 typedef struct _allnodes_parm_t {
149 int i;
150 dns_sdballnodes_t *allnodes;
151 isc_result_t result;
152 } allnodes_parm_t;
155 static int
156 sqlitedb_allnodes_cb(void *p, int cc, char **cv, char **cn)
158 allnodes_parm_t *parm = p;
159 dns_ttl_t ttl;
160 char *endp;
162 /* FIXME - check these(num/names); I'm assuming a mapping for now */
163 char *ttlstr = cv[0];
164 char *name = cv[1];
165 char *type = cv[2];
166 char *data = cv[3];
168 UNUSED(cc);
169 UNUSED(cn);
171 ttl = strtol(ttlstr, &endp, 10);
172 if (*endp) {
173 parm->result = DNS_R_BADTTL;
174 return 1;
177 parm->result = dns_sdb_putnamedrr(parm->allnodes, name, type, ttl, data);
179 if (parm->result != ISC_R_SUCCESS)
180 return 1;
182 (parm->i)++;
184 return 0;
188 static isc_result_t
189 sqlitedb_allnodes(const char *zone,
190 void *dbdata,
191 dns_sdballnodes_t *allnodes)
193 dbinfo_t *dbi = (dbinfo_t *) dbdata;
194 char *sql;
195 allnodes_parm_t parm = { 0, allnodes, ISC_R_SUCCESS };
196 char *errmsg = NULL;
197 int result;
199 UNUSED(zone);
201 sql = sqlite3_mprintf(
202 "SELECT TTL,NAME,RDTYPE,RDATA FROM \"%q\" ORDER BY NAME",
203 dbi->table);
205 result = sqlite3_exec(dbi->db, sql,
206 &sqlitedb_allnodes_cb, &parm,
207 &errmsg);
208 sqlite3_free(sql);
210 if (result != SQLITE_OK)
211 return (ISC_R_FAILURE);
212 if (parm.i == 0)
213 return (ISC_R_NOTFOUND);
215 return (ISC_R_SUCCESS);
219 static void
220 sqlitedb_destroy(const char *zone, void *driverdata, void **dbdata)
222 dbinfo_t *dbi = *dbdata;
224 UNUSED(zone);
225 UNUSED(driverdata);
227 if (dbi->db != NULL)
228 sqlite3_close(dbi->db);
229 if (dbi->table != NULL)
230 isc_mem_free(ns_g_mctx, dbi->table);
231 if (dbi->filename != NULL)
232 isc_mem_free(ns_g_mctx, dbi->filename);
234 isc_mem_put(ns_g_mctx, dbi, sizeof(dbinfo_t));
238 #define STRDUP_OR_FAIL(target, source) \
239 do { \
240 target = isc_mem_strdup(ns_g_mctx, source); \
241 if (target == NULL) { \
242 result = ISC_R_NOMEMORY; \
243 goto cleanup; \
245 } while (0);
248 * Create a connection to the database and save any necessary information
249 * in dbdata.
251 * argv[0] is the name of the database file
252 * argv[1] is the name of the table
254 static isc_result_t
255 sqlitedb_create(const char *zone,
256 int argc, char **argv,
257 void *driverdata, void **dbdata)
259 dbinfo_t *dbi;
260 isc_result_t result;
262 UNUSED(zone);
263 UNUSED(driverdata);
265 if (argc < 2)
266 return (ISC_R_FAILURE);
268 dbi = isc_mem_get(ns_g_mctx, sizeof(dbinfo_t));
269 if (dbi == NULL)
270 return (ISC_R_NOMEMORY);
271 dbi->db = NULL;
272 dbi->filename = NULL;
273 dbi->table = NULL;
275 STRDUP_OR_FAIL(dbi->filename, argv[0]);
276 STRDUP_OR_FAIL(dbi->table, argv[1]);
278 result = db_connect(dbi);
279 if (result != ISC_R_SUCCESS)
280 goto cleanup;
282 *dbdata = dbi;
283 return (ISC_R_SUCCESS);
285 cleanup:
286 sqlitedb_destroy(zone, driverdata, (void **)&dbi);
287 return (result);
292 * Since the SQL database corresponds to a zone, the authority data should
293 * be returned by the lookup() function. Therefore the authority() function
294 * is NULL.
296 static dns_sdbmethods_t sqlitedb_methods = {
297 sqlitedb_lookup,
298 NULL, /* authority */
299 sqlitedb_allnodes,
300 sqlitedb_create,
301 sqlitedb_destroy
306 * Wrapper around dns_sdb_register().
308 isc_result_t
309 sqlitedb_init(void)
311 unsigned int flags;
312 flags = 0;
313 return (dns_sdb_register("sqlite", &sqlitedb_methods, NULL, flags,
314 ns_g_mctx, &sqlitedb));
319 * Wrapper around dns_sdb_unregister().
321 void
322 sqlitedb_clear(void)
324 if (sqlitedb != NULL)
325 dns_sdb_unregister(&sqlitedb);