2
* Copyright (C) 2007 Internet Software Consortium.
4
* Permission to use, copy, modify, and distribute this software for any
5
* purpose with or without fee is hereby granted, provided that the above
6
* copyright notice and this permission notice appear in all copies.
8
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
9
* DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
10
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
11
* INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
12
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
13
* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
14
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
15
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
/* $Id: sqlitedb.c,v 1.1 2007/03/05 05:30:22 marka Exp $ */
30
#include <isc/print.h>
31
#include <isc/result.h>
35
#include <dns/result.h>
37
#include <named/globals.h>
42
* A simple database driver that interfaces to a SQLite database.
44
* The table must contain the fields "name", "rdtype", and "rdata", and
45
* is expected to contain a properly constructed zone. The program "zonetodb"
46
* creates such a table.
49
static dns_sdbimplementation_t *sqlitedb = NULL;
51
typedef struct _dbinfo {
59
db_connect(dbinfo_t *dbi)
61
if (sqlite3_open(dbi->filename, &dbi->db) == SQLITE_OK) {
62
return (ISC_R_SUCCESS);
64
/* a connection is returned even if the open fails */
65
sqlite3_close(dbi->db);
67
return (ISC_R_FAILURE);
72
typedef struct _lookup_parm_t {
74
dns_sdblookup_t *lookup;
80
sqlitedb_lookup_cb(void *p, int cc, char **cv, char **cn)
82
lookup_parm_t *parm = p;
86
/* FIXME - check these(num/names); I'm assuming a mapping for now */
94
ttl = strtol(ttlstr, &endp, 10);
96
parm->result = DNS_R_BADTTL;
100
parm->result = dns_sdb_putrr(parm->lookup, type, ttl, data);
102
if (parm->result != ISC_R_SUCCESS)
112
sqlitedb_lookup(const char *zone,
113
const char *name, void *dbdata,
114
dns_sdblookup_t *lookup)
116
* synchronous absolute name lookup
119
dbinfo_t *dbi = (dbinfo_t *) dbdata;
121
lookup_parm_t parm = { 0, lookup, ISC_R_SUCCESS };
127
sql = sqlite3_mprintf(
128
"SELECT TTL,RDTYPE,RDATA FROM \"%q\" WHERE "
129
"lower(NAME) = lower('%q')",
132
result = sqlite3_exec(dbi->db, sql,
133
&sqlitedb_lookup_cb, &parm,
137
if (result != SQLITE_OK)
138
return (ISC_R_FAILURE);
140
return (ISC_R_NOTFOUND);
142
return (ISC_R_SUCCESS);
146
typedef struct _allnodes_parm_t {
148
dns_sdballnodes_t *allnodes;
154
sqlitedb_allnodes_cb(void *p, int cc, char **cv, char **cn)
156
allnodes_parm_t *parm = p;
160
/* FIXME - check these(num/names); I'm assuming a mapping for now */
161
char *ttlstr = cv[0];
169
ttl = strtol(ttlstr, &endp, 10);
171
parm->result = DNS_R_BADTTL;
175
parm->result = dns_sdb_putnamedrr(parm->allnodes, name, type, ttl, data);
177
if (parm->result != ISC_R_SUCCESS)
187
sqlitedb_allnodes(const char *zone,
189
dns_sdballnodes_t *allnodes)
191
dbinfo_t *dbi = (dbinfo_t *) dbdata;
193
allnodes_parm_t parm = { 0, allnodes, ISC_R_SUCCESS };
199
sql = sqlite3_mprintf(
200
"SELECT TTL,NAME,RDTYPE,RDATA FROM \"%q\" ORDER BY NAME",
203
result = sqlite3_exec(dbi->db, sql,
204
&sqlitedb_allnodes_cb, &parm,
208
if (result != SQLITE_OK)
209
return (ISC_R_FAILURE);
211
return (ISC_R_NOTFOUND);
213
return (ISC_R_SUCCESS);
218
sqlitedb_destroy(const char *zone, void *driverdata, void **dbdata)
220
dbinfo_t *dbi = *dbdata;
226
sqlite3_close(dbi->db);
227
if (dbi->table != NULL)
228
isc_mem_free(ns_g_mctx, dbi->table);
229
if (dbi->filename != NULL)
230
isc_mem_free(ns_g_mctx, dbi->filename);
232
isc_mem_put(ns_g_mctx, dbi, sizeof(dbinfo_t));
236
#define STRDUP_OR_FAIL(target, source) \
238
target = isc_mem_strdup(ns_g_mctx, source); \
239
if (target == NULL) { \
240
result = ISC_R_NOMEMORY; \
246
* Create a connection to the database and save any necessary information
249
* argv[0] is the name of the database file
250
* argv[1] is the name of the table
253
sqlitedb_create(const char *zone,
254
int argc, char **argv,
255
void *driverdata, void **dbdata)
264
return (ISC_R_FAILURE);
266
dbi = isc_mem_get(ns_g_mctx, sizeof(dbinfo_t));
268
return (ISC_R_NOMEMORY);
270
dbi->filename = NULL;
273
STRDUP_OR_FAIL(dbi->filename, argv[0]);
274
STRDUP_OR_FAIL(dbi->table, argv[1]);
276
result = db_connect(dbi);
277
if (result != ISC_R_SUCCESS)
281
return (ISC_R_SUCCESS);
284
sqlitedb_destroy(zone, driverdata, (void **)&dbi);
290
* Since the SQL database corresponds to a zone, the authority data should
291
* be returned by the lookup() function. Therefore the authority() function
294
static dns_sdbmethods_t sqlitedb_methods = {
296
NULL, /* authority */
304
* Wrapper around dns_sdb_register().
311
return (dns_sdb_register("sqlite", &sqlitedb_methods, NULL, flags,
312
ns_g_mctx, &sqlitedb));
317
* Wrapper around dns_sdb_unregister().
322
if (sqlitedb != NULL)
323
dns_sdb_unregister(&sqlitedb);