1 /* $NetBSD: sqlitedb.c,v 1.4 2014/12/10 04:37:57 christos Exp $ */
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.2 2011/10/11 00:09:02 each 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
)
113 #ifdef DNS_CLIENTINFO_VERSION
115 sqlitedb_lookup(const char *zone
, const char *name
, void *dbdata
,
116 dns_sdblookup_t
*lookup
, dns_clientinfomethods_t
*methods
,
117 dns_clientinfo_t
*clientinfo
)
120 sqlitedb_lookup(const char *zone
, const char *name
, void *dbdata
,
121 dns_sdblookup_t
*lookup
)
122 #endif /* DNS_CLIENTINFO_VERSION */
124 * synchronous absolute name lookup
127 dbinfo_t
*dbi
= (dbinfo_t
*) dbdata
;
129 lookup_parm_t parm
= { 0, lookup
, ISC_R_SUCCESS
};
134 #ifdef DNS_CLIENTINFO_VERSION
137 #endif /* DNS_CLIENTINFO_VERSION */
139 sql
= sqlite3_mprintf(
140 "SELECT TTL,RDTYPE,RDATA FROM \"%q\" WHERE "
141 "lower(NAME) = lower('%q')",
144 result
= sqlite3_exec(dbi
->db
, sql
,
145 &sqlitedb_lookup_cb
, &parm
,
149 if (result
!= SQLITE_OK
)
150 return (ISC_R_FAILURE
);
152 return (ISC_R_NOTFOUND
);
154 return (ISC_R_SUCCESS
);
158 typedef struct _allnodes_parm_t
{
160 dns_sdballnodes_t
*allnodes
;
166 sqlitedb_allnodes_cb(void *p
, int cc
, char **cv
, char **cn
)
168 allnodes_parm_t
*parm
= p
;
172 /* FIXME - check these(num/names); I'm assuming a mapping for now */
173 char *ttlstr
= cv
[0];
181 ttl
= strtol(ttlstr
, &endp
, 10);
183 parm
->result
= DNS_R_BADTTL
;
187 parm
->result
= dns_sdb_putnamedrr(parm
->allnodes
, name
, type
, ttl
, data
);
189 if (parm
->result
!= ISC_R_SUCCESS
)
199 sqlitedb_allnodes(const char *zone
,
201 dns_sdballnodes_t
*allnodes
)
203 dbinfo_t
*dbi
= (dbinfo_t
*) dbdata
;
205 allnodes_parm_t parm
= { 0, allnodes
, ISC_R_SUCCESS
};
211 sql
= sqlite3_mprintf(
212 "SELECT TTL,NAME,RDTYPE,RDATA FROM \"%q\" ORDER BY NAME",
215 result
= sqlite3_exec(dbi
->db
, sql
,
216 &sqlitedb_allnodes_cb
, &parm
,
220 if (result
!= SQLITE_OK
)
221 return (ISC_R_FAILURE
);
223 return (ISC_R_NOTFOUND
);
225 return (ISC_R_SUCCESS
);
230 sqlitedb_destroy(const char *zone
, void *driverdata
, void **dbdata
)
232 dbinfo_t
*dbi
= *dbdata
;
238 sqlite3_close(dbi
->db
);
239 if (dbi
->table
!= NULL
)
240 isc_mem_free(ns_g_mctx
, dbi
->table
);
241 if (dbi
->filename
!= NULL
)
242 isc_mem_free(ns_g_mctx
, dbi
->filename
);
244 isc_mem_put(ns_g_mctx
, dbi
, sizeof(dbinfo_t
));
248 #define STRDUP_OR_FAIL(target, source) \
250 target = isc_mem_strdup(ns_g_mctx, source); \
251 if (target == NULL) { \
252 result = ISC_R_NOMEMORY; \
255 } while (/*CONSTCOND*/0);
258 * Create a connection to the database and save any necessary information
261 * argv[0] is the name of the database file
262 * argv[1] is the name of the table
265 sqlitedb_create(const char *zone
,
266 int argc
, char **argv
,
267 void *driverdata
, void **dbdata
)
276 return (ISC_R_FAILURE
);
278 dbi
= isc_mem_get(ns_g_mctx
, sizeof(dbinfo_t
));
280 return (ISC_R_NOMEMORY
);
282 dbi
->filename
= NULL
;
285 STRDUP_OR_FAIL(dbi
->filename
, argv
[0]);
286 STRDUP_OR_FAIL(dbi
->table
, argv
[1]);
288 result
= db_connect(dbi
);
289 if (result
!= ISC_R_SUCCESS
)
293 return (ISC_R_SUCCESS
);
296 sqlitedb_destroy(zone
, driverdata
, (void **)&dbi
);
302 * Since the SQL database corresponds to a zone, the authority data should
303 * be returned by the lookup() function. Therefore the authority() function
306 static dns_sdbmethods_t sqlitedb_methods
= {
308 NULL
, /* authority */
317 * Wrapper around dns_sdb_register().
324 return (dns_sdb_register("sqlite", &sqlitedb_methods
, NULL
, flags
,
325 ns_g_mctx
, &sqlitedb
));
330 * Wrapper around dns_sdb_unregister().
335 if (sqlitedb
!= NULL
)
336 dns_sdb_unregister(&sqlitedb
);