added sqlite busy handler: retries on locking conflicts
[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 * $Id$
16 */
17
18 #include "sqlite_database.h"
19
20 #include <sqlite3.h>
21 #include <unistd.h>
22 #include <library.h>
23 #include <debug.h>
24 #include <utils/mutex.h>
25
26 typedef struct private_sqlite_database_t private_sqlite_database_t;
27
28 /**
29 * private data of sqlite_database
30 */
31 struct private_sqlite_database_t {
32
33 /**
34 * public functions
35 */
36 sqlite_database_t public;
37
38 /**
39 * sqlite database connection
40 */
41 sqlite3 *db;
42
43 /**
44 * mutex used to lock execute()
45 */
46 mutex_t *mutex;
47 };
48
49 /**
50 * Create and run a sqlite stmt using a sql string and args
51 */
52 static sqlite3_stmt* run(private_sqlite_database_t *this, char *sql,
53 va_list *args)
54 {
55 sqlite3_stmt *stmt = NULL;
56 int params, i, res = SQLITE_OK;
57
58 #ifdef HAVE_SQLITE3_PREPARE_V2
59 if (sqlite3_prepare_v2(this->db, sql, -1, &stmt, NULL) == SQLITE_OK)
60 #else
61 if (sqlite3_prepare(this->db, sql, -1, &stmt, NULL) == SQLITE_OK)
62 #endif
63 {
64 params = sqlite3_bind_parameter_count(stmt);
65 for (i = 1; i <= params; i++)
66 {
67 switch (va_arg(*args, db_type_t))
68 {
69 case DB_INT:
70 {
71 res = sqlite3_bind_int(stmt, i, va_arg(*args, int));
72 break;
73 }
74 case DB_UINT:
75 {
76 res = sqlite3_bind_int64(stmt, i, va_arg(*args, u_int));
77 break;
78 }
79 case DB_TEXT:
80 {
81 const char *text = va_arg(*args, const char*);
82 res = sqlite3_bind_text(stmt, i, text, -1, SQLITE_STATIC);
83 break;
84 }
85 case DB_BLOB:
86 {
87 chunk_t c = va_arg(*args, chunk_t);
88 res = sqlite3_bind_blob(stmt, i, c.ptr, c.len, SQLITE_STATIC);
89 break;
90 }
91 case DB_DOUBLE:
92 {
93 res = sqlite3_bind_double(stmt, i, va_arg(*args, double));
94 break;
95 }
96 case DB_NULL:
97 {
98 res = sqlite3_bind_null(stmt, i);
99 break;
100 }
101 default:
102 {
103 res = SQLITE_MISUSE;
104 break;
105 }
106 }
107 if (res != SQLITE_OK)
108 {
109 break;
110 }
111 }
112 }
113 else
114 {
115 DBG1("preparing sqlite statement failed: %s", sqlite3_errmsg(this->db));
116 }
117 if (res != SQLITE_OK)
118 {
119 DBG1("binding sqlite statement failed: %s", 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("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("invalid result type supplied");
209 return FALSE;
210 }
211 }
212 va_end(args);
213 return TRUE;
214 }
215
216 /**
217 * Implementation of database_t.query.
218 */
219 static enumerator_t* query(private_sqlite_database_t *this, char *sql, ...)
220 {
221 sqlite3_stmt *stmt;
222 va_list args;
223 sqlite_enumerator_t *enumerator = NULL;
224 int i;
225
226 #if SQLITE_VERSION_NUMBER < 3005000
227 /* sqlite connections prior to 3.5 may be used by a single thread only, */
228 this->mutex->lock(this->mutex);
229 #endif
230
231 va_start(args, sql);
232 stmt = run(this, sql, &args);
233 if (stmt)
234 {
235 enumerator = malloc_thing(sqlite_enumerator_t);
236 enumerator->public.enumerate = (void*)sqlite_enumerator_enumerate;
237 enumerator->public.destroy = (void*)sqlite_enumerator_destroy;
238 enumerator->stmt = stmt;
239 enumerator->count = sqlite3_column_count(stmt);
240 enumerator->columns = malloc(sizeof(db_type_t) * enumerator->count);
241 enumerator->database = this;
242 for (i = 0; i < enumerator->count; i++)
243 {
244 enumerator->columns[i] = va_arg(args, db_type_t);
245 }
246 }
247 va_end(args);
248 return (enumerator_t*)enumerator;
249 }
250
251 /**
252 * Implementation of database_t.execute.
253 */
254 static int execute(private_sqlite_database_t *this, int *rowid, char *sql, ...)
255 {
256 sqlite3_stmt *stmt;
257 int affected = -1;
258 va_list args;
259
260 /* we need a lock to get our rowid/changes correctly */
261 this->mutex->lock(this->mutex);
262 va_start(args, sql);
263 stmt = run(this, sql, &args);
264 va_end(args);
265 if (stmt)
266 {
267 if (sqlite3_step(stmt) == SQLITE_DONE)
268 {
269 if (rowid)
270 {
271 *rowid = sqlite3_last_insert_rowid(this->db);
272 }
273 affected = sqlite3_changes(this->db);
274 }
275 else
276 {
277 DBG1("sqlite execute failed: %s", sqlite3_errmsg(this->db));
278 }
279 sqlite3_finalize(stmt);
280 }
281 this->mutex->unlock(this->mutex);
282 return affected;
283 }
284
285 /**
286 * Implementation of database_t.get_driver
287 */
288 static db_driver_t get_driver(private_sqlite_database_t *this)
289 {
290 return DB_SQLITE;
291 }
292
293 /**
294 * Busy handler implementation
295 */
296 static int busy_handler(private_sqlite_database_t *this, int count)
297 {
298 /* add an sleep, exponentially longer on every try */
299 usleep(count * count * 1000);
300 /* always retry */
301 return 1;
302 }
303
304 /**
305 * Implementation of database_t.destroy
306 */
307 static void destroy(private_sqlite_database_t *this)
308 {
309 sqlite3_close(this->db);
310 this->mutex->destroy(this->mutex);
311 free(this);
312 }
313
314 /*
315 * see header file
316 */
317 sqlite_database_t *sqlite_database_create(char *uri)
318 {
319 char *file;
320 private_sqlite_database_t *this;
321
322 /**
323 * parse sqlite:///path/to/file.db uri
324 */
325 if (!strneq(uri, "sqlite://", 9))
326 {
327 return NULL;
328 }
329 file = uri + 9;
330
331 this = malloc_thing(private_sqlite_database_t);
332
333 this->public.db.query = (enumerator_t* (*)(database_t *this, char *sql, ...))query;
334 this->public.db.execute = (int (*)(database_t *this, int *rowid, char *sql, ...))execute;
335 this->public.db.get_driver = (db_driver_t(*)(database_t*))get_driver;
336 this->public.db.destroy = (void(*)(database_t*))destroy;
337
338 this->mutex = mutex_create(MUTEX_RECURSIVE);
339
340 if (sqlite3_open(file, &this->db) != SQLITE_OK)
341 {
342 DBG1("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