41d45dee7b63a8843310619c96fda0a78326dfc8
[strongswan.git] / src / libstrongswan / plugins / sqlite / sqlite_database.c
1 /*
2 * Copyright (C) 2007 Martin Willi
3 * Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include "sqlite_database.h"
17
18 #include <sqlite3.h>
19 #include <unistd.h>
20 #include <library.h>
21 #include <utils/debug.h>
22 #include <threading/mutex.h>
23
24 typedef struct private_sqlite_database_t private_sqlite_database_t;
25
26 /**
27 * private data of sqlite_database
28 */
29 struct private_sqlite_database_t {
30
31 /**
32 * public functions
33 */
34 sqlite_database_t public;
35
36 /**
37 * sqlite database connection
38 */
39 sqlite3 *db;
40
41 /**
42 * mutex used to lock execute()
43 */
44 mutex_t *mutex;
45 };
46
47 /**
48 * Create and run a sqlite stmt using a sql string and args
49 */
50 static sqlite3_stmt* run(private_sqlite_database_t *this, char *sql,
51 va_list *args)
52 {
53 sqlite3_stmt *stmt = NULL;
54 int params, i, res = SQLITE_OK;
55
56 #ifdef HAVE_SQLITE3_PREPARE_V2
57 if (sqlite3_prepare_v2(this->db, sql, -1, &stmt, NULL) == SQLITE_OK)
58 #else
59 if (sqlite3_prepare(this->db, sql, -1, &stmt, NULL) == SQLITE_OK)
60 #endif
61 {
62 params = sqlite3_bind_parameter_count(stmt);
63 for (i = 1; i <= params; i++)
64 {
65 switch (va_arg(*args, db_type_t))
66 {
67 case DB_INT:
68 {
69 res = sqlite3_bind_int(stmt, i, va_arg(*args, int));
70 break;
71 }
72 case DB_UINT:
73 {
74 res = sqlite3_bind_int64(stmt, i, va_arg(*args, u_int));
75 break;
76 }
77 case DB_TEXT:
78 {
79 const char *text = va_arg(*args, const char*);
80 res = sqlite3_bind_text(stmt, i, text, -1, SQLITE_STATIC);
81 break;
82 }
83 case DB_BLOB:
84 {
85 chunk_t c = va_arg(*args, chunk_t);
86 res = sqlite3_bind_blob(stmt, i, c.ptr, c.len, SQLITE_STATIC);
87 break;
88 }
89 case DB_DOUBLE:
90 {
91 res = sqlite3_bind_double(stmt, i, va_arg(*args, double));
92 break;
93 }
94 case DB_NULL:
95 {
96 res = sqlite3_bind_null(stmt, i);
97 break;
98 }
99 default:
100 {
101 res = SQLITE_MISUSE;
102 break;
103 }
104 }
105 if (res != SQLITE_OK)
106 {
107 break;
108 }
109 }
110 }
111 else
112 {
113 DBG1(DBG_LIB, "preparing sqlite statement failed: %s",
114 sqlite3_errmsg(this->db));
115 }
116 if (res != SQLITE_OK)
117 {
118 DBG1(DBG_LIB, "binding sqlite statement failed: %s",
119 sqlite3_errmsg(this->db));
120 sqlite3_finalize(stmt);
121 return NULL;
122 }
123 return stmt;
124 }
125
126 typedef struct {
127 /** implements enumerator_t */
128 enumerator_t public;
129 /** associated sqlite statement */
130 sqlite3_stmt *stmt;
131 /** number of result columns */
132 int count;
133 /** column types */
134 db_type_t *columns;
135 /** back reference to parent */
136 private_sqlite_database_t *database;
137 } sqlite_enumerator_t;
138
139 /**
140 * destroy a sqlite enumerator
141 */
142 static void sqlite_enumerator_destroy(sqlite_enumerator_t *this)
143 {
144 sqlite3_finalize(this->stmt);
145 #if SQLITE_VERSION_NUMBER < 3005000
146 this->database->mutex->unlock(this->database->mutex);
147 #endif
148 free(this->columns);
149 free(this);
150 }
151
152 /**
153 * Implementation of database.query().enumerate
154 */
155 static bool sqlite_enumerator_enumerate(sqlite_enumerator_t *this, ...)
156 {
157 int i;
158 va_list args;
159
160 switch (sqlite3_step(this->stmt))
161 {
162 case SQLITE_ROW:
163 break;
164 default:
165 DBG1(DBG_LIB, "stepping sqlite statement failed: %s",
166 sqlite3_errmsg(this->database->db));
167 /* fall */
168 case SQLITE_DONE:
169 return FALSE;
170 }
171 va_start(args, this);
172 for (i = 0; i < this->count; i++)
173 {
174 switch (this->columns[i])
175 {
176 case DB_INT:
177 {
178 int *value = va_arg(args, int*);
179 *value = sqlite3_column_int(this->stmt, i);
180 break;
181 }
182 case DB_UINT:
183 {
184 u_int *value = va_arg(args, u_int*);
185 *value = (u_int)sqlite3_column_int64(this->stmt, i);
186 break;
187 }
188 case DB_TEXT:
189 {
190 const unsigned char **value = va_arg(args, const unsigned char**);
191 *value = sqlite3_column_text(this->stmt, i);
192 break;
193 }
194 case DB_BLOB:
195 {
196 chunk_t *chunk = va_arg(args, chunk_t*);
197 chunk->len = sqlite3_column_bytes(this->stmt, i);
198 chunk->ptr = (u_char*)sqlite3_column_blob(this->stmt, i);
199 break;
200 }
201 case DB_DOUBLE:
202 {
203 double *value = va_arg(args, double*);
204 *value = sqlite3_column_double(this->stmt, i);
205 break;
206 }
207 default:
208 DBG1(DBG_LIB, "invalid result type supplied");
209 va_end(args);
210 return FALSE;
211 }
212 }
213 va_end(args);
214 return TRUE;
215 }
216
217 METHOD(database_t, query, enumerator_t*,
218 private_sqlite_database_t *this, char *sql, ...)
219 {
220 sqlite3_stmt *stmt;
221 va_list args;
222 sqlite_enumerator_t *enumerator = NULL;
223 int i;
224
225 #if SQLITE_VERSION_NUMBER < 3005000
226 /* sqlite connections prior to 3.5 may be used by a single thread only, */
227 this->mutex->lock(this->mutex);
228 #endif
229
230 va_start(args, sql);
231 stmt = run(this, sql, &args);
232 if (stmt)
233 {
234 enumerator = malloc_thing(sqlite_enumerator_t);
235 enumerator->public.enumerate = (void*)sqlite_enumerator_enumerate;
236 enumerator->public.destroy = (void*)sqlite_enumerator_destroy;
237 enumerator->stmt = stmt;
238 enumerator->count = sqlite3_column_count(stmt);
239 enumerator->columns = malloc(sizeof(db_type_t) * enumerator->count);
240 enumerator->database = this;
241 for (i = 0; i < enumerator->count; i++)
242 {
243 enumerator->columns[i] = va_arg(args, db_type_t);
244 }
245 }
246 va_end(args);
247 return (enumerator_t*)enumerator;
248 }
249
250 METHOD(database_t, execute, int,
251 private_sqlite_database_t *this, int *rowid, char *sql, ...)
252 {
253 sqlite3_stmt *stmt;
254 int affected = -1;
255 va_list args;
256
257 /* we need a lock to get our rowid/changes correctly */
258 this->mutex->lock(this->mutex);
259 va_start(args, sql);
260 stmt = run(this, sql, &args);
261 va_end(args);
262 if (stmt)
263 {
264 if (sqlite3_step(stmt) == SQLITE_DONE)
265 {
266 if (rowid)
267 {
268 *rowid = sqlite3_last_insert_rowid(this->db);
269 }
270 affected = sqlite3_changes(this->db);
271 }
272 else
273 {
274 DBG1(DBG_LIB, "sqlite execute failed: %s",
275 sqlite3_errmsg(this->db));
276 }
277 sqlite3_finalize(stmt);
278 }
279 this->mutex->unlock(this->mutex);
280 return affected;
281 }
282
283 METHOD(database_t, get_driver, db_driver_t,
284 private_sqlite_database_t *this)
285 {
286 return DB_SQLITE;
287 }
288
289 /**
290 * Busy handler implementation
291 */
292 static int busy_handler(private_sqlite_database_t *this, int count)
293 {
294 /* add a backoff time, quadratically increasing with every try */
295 usleep(count * count * 1000);
296 /* always retry */
297 return 1;
298 }
299
300 METHOD(database_t, destroy, void,
301 private_sqlite_database_t *this)
302 {
303 if (sqlite3_close(this->db) == SQLITE_BUSY)
304 {
305 DBG1(DBG_LIB, "sqlite close failed because database is busy");
306 }
307 this->mutex->destroy(this->mutex);
308 free(this);
309 }
310
311 /*
312 * see header file
313 */
314 sqlite_database_t *sqlite_database_create(char *uri)
315 {
316 char *file;
317 private_sqlite_database_t *this;
318
319 /**
320 * parse sqlite:///path/to/file.db uri
321 */
322 if (!strpfx(uri, "sqlite://"))
323 {
324 return NULL;
325 }
326 file = uri + 9;
327
328 INIT(this,
329 .public = {
330 .db = {
331 .query = _query,
332 .execute = _execute,
333 .get_driver = _get_driver,
334 .destroy = _destroy,
335 },
336 },
337 .mutex = mutex_create(MUTEX_TYPE_RECURSIVE),
338 );
339
340 if (sqlite3_open(file, &this->db) != SQLITE_OK)
341 {
342 DBG1(DBG_LIB, "opening SQLite database '%s' failed: %s",
343 file, sqlite3_errmsg(this->db));
344 _destroy(this);
345 return NULL;
346 }
347
348 sqlite3_busy_handler(this->db, (void*)busy_handler, this);
349
350 return &this->public;
351 }
352