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 */
32 #include <isc/print.h>
33 #include <isc/result.h>
37 #include <dns/result.h>
39 #include <named/globals.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
{
61 db_connect(dbinfo_t
*dbi
)
63 if (sqlite3_open(dbi
->filename
, &dbi
->db
) == SQLITE_OK
) {
64 return (ISC_R_SUCCESS
);
66 /* a connection is returned even if the open fails */
67 sqlite3_close(dbi
->db
);
69 return (ISC_R_FAILURE
);
74 typedef struct _lookup_parm_t
{
76 dns_sdblookup_t
*lookup
;
82 sqlitedb_lookup_cb(void *p
, int cc
, char **cv
, char **cn
)
84 lookup_parm_t
*parm
= p
;
88 /* FIXME - check these(num/names); I'm assuming a mapping for now */
96 ttl
= strtol(ttlstr
, &endp
, 10);
98 parm
->result
= DNS_R_BADTTL
;
102 parm
->result
= dns_sdb_putrr(parm
->lookup
, type
, ttl
, data
);
104 if (parm
->result
!= ISC_R_SUCCESS
)
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
;
123 lookup_parm_t parm
= { 0, lookup
, ISC_R_SUCCESS
};
129 sql
= sqlite3_mprintf(
130 "SELECT TTL,RDTYPE,RDATA FROM \"%q\" WHERE "
131 "lower(NAME) = lower('%q')",
134 result
= sqlite3_exec(dbi
->db
, sql
,
135 &sqlitedb_lookup_cb
, &parm
,
139 if (result
!= SQLITE_OK
)
140 return (ISC_R_FAILURE
);
142 return (ISC_R_NOTFOUND
);
144 return (ISC_R_SUCCESS
);
148 typedef struct _allnodes_parm_t
{
150 dns_sdballnodes_t
*allnodes
;
156 sqlitedb_allnodes_cb(void *p
, int cc
, char **cv
, char **cn
)
158 allnodes_parm_t
*parm
= p
;
162 /* FIXME - check these(num/names); I'm assuming a mapping for now */
163 char *ttlstr
= cv
[0];
171 ttl
= strtol(ttlstr
, &endp
, 10);
173 parm
->result
= DNS_R_BADTTL
;
177 parm
->result
= dns_sdb_putnamedrr(parm
->allnodes
, name
, type
, ttl
, data
);
179 if (parm
->result
!= ISC_R_SUCCESS
)
189 sqlitedb_allnodes(const char *zone
,
191 dns_sdballnodes_t
*allnodes
)
193 dbinfo_t
*dbi
= (dbinfo_t
*) dbdata
;
195 allnodes_parm_t parm
= { 0, allnodes
, ISC_R_SUCCESS
};
201 sql
= sqlite3_mprintf(
202 "SELECT TTL,NAME,RDTYPE,RDATA FROM \"%q\" ORDER BY NAME",
205 result
= sqlite3_exec(dbi
->db
, sql
,
206 &sqlitedb_allnodes_cb
, &parm
,
210 if (result
!= SQLITE_OK
)
211 return (ISC_R_FAILURE
);
213 return (ISC_R_NOTFOUND
);
215 return (ISC_R_SUCCESS
);
220 sqlitedb_destroy(const char *zone
, void *driverdata
, void **dbdata
)
222 dbinfo_t
*dbi
= *dbdata
;
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) \
240 target = isc_mem_strdup(ns_g_mctx, source); \
241 if (target == NULL) { \
242 result = ISC_R_NOMEMORY; \
248 * Create a connection to the database and save any necessary information
251 * argv[0] is the name of the database file
252 * argv[1] is the name of the table
255 sqlitedb_create(const char *zone
,
256 int argc
, char **argv
,
257 void *driverdata
, void **dbdata
)
266 return (ISC_R_FAILURE
);
268 dbi
= isc_mem_get(ns_g_mctx
, sizeof(dbinfo_t
));
270 return (ISC_R_NOMEMORY
);
272 dbi
->filename
= 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
)
283 return (ISC_R_SUCCESS
);
286 sqlitedb_destroy(zone
, driverdata
, (void **)&dbi
);
292 * Since the SQL database corresponds to a zone, the authority data should
293 * be returned by the lookup() function. Therefore the authority() function
296 static dns_sdbmethods_t sqlitedb_methods
= {
298 NULL
, /* authority */
306 * Wrapper around dns_sdb_register().
313 return (dns_sdb_register("sqlite", &sqlitedb_methods
, NULL
, flags
,
314 ns_g_mctx
, &sqlitedb
));
319 * Wrapper around dns_sdb_unregister().
324 if (sqlitedb
!= NULL
)
325 dns_sdb_unregister(&sqlitedb
);