Mercurial > dovecot > original-hg > dovecot-1.2
annotate src/lib-sql/driver-sqlite.c @ 9658:8ba4253adc9b HEAD tip
*-login: SSL connections didn't get closed when the client got destroyed.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Thu, 08 May 2014 16:41:29 +0300 |
parents | 4530228c8993 |
children |
rev | line source |
---|---|
3923 | 1 /* Copyright (C) 2006 Jakob Hirsch */ |
2 | |
3 #include "lib.h" | |
6476
af14dc005392
Let deinit() free all the memory itself after all.
Timo Sirainen <tss@iki.fi>
parents:
6474
diff
changeset
|
4 #include "array.h" |
3923 | 5 #include "str.h" |
6 #include "sql-api-private.h" | |
7 | |
3943
cbe5c6772e0d
Added support for dynamically building SQL drivers.
Timo Sirainen <tss@iki.fi>
parents:
3936
diff
changeset
|
8 #ifdef BUILD_SQLITE |
3923 | 9 #include <sqlite3.h> |
10 | |
11 /* retry time if db is busy (in ms) */ | |
8027
62cf70991cf2
extern/static fixes (from a sparse check by Diego Liziero)
Timo Sirainen <tss@iki.fi>
parents:
6476
diff
changeset
|
12 static const int sqlite_busy_timeout = 1000; |
3923 | 13 |
14 struct sqlite_db { | |
15 struct sql_db api; | |
16 | |
17 pool_t pool; | |
18 const char *dbfile; | |
19 sqlite3 *sqlite; | |
20 unsigned int connected:1; | |
21 int rc; | |
22 }; | |
23 | |
24 struct sqlite_result { | |
25 struct sql_result api; | |
26 sqlite3_stmt *stmt; | |
27 unsigned int cols; | |
28 const char **row; | |
29 }; | |
30 | |
31 struct sqlite_transaction_context { | |
32 struct sql_transaction_context ctx; | |
33 unsigned int failed:1; | |
34 }; | |
35 | |
3943
cbe5c6772e0d
Added support for dynamically building SQL drivers.
Timo Sirainen <tss@iki.fi>
parents:
3936
diff
changeset
|
36 extern struct sql_db driver_sqlite_db; |
3923 | 37 extern struct sql_result driver_sqlite_result; |
38 extern struct sql_result driver_sqlite_error_result; | |
39 | |
40 static int driver_sqlite_connect(struct sql_db *_db) | |
41 { | |
42 struct sqlite_db *db = (struct sqlite_db *)_db; | |
43 | |
44 if (db->connected) | |
45 return 1; | |
46 | |
47 db->rc = sqlite3_open(db->dbfile, &db->sqlite); | |
48 | |
49 if (db->rc == SQLITE_OK) { | |
50 db->connected = TRUE; | |
51 sqlite3_busy_timeout(db->sqlite, sqlite_busy_timeout); | |
52 return 1; | |
53 } else { | |
54 i_error("sqlite: open(%s) failed: %s", db->dbfile, | |
55 sqlite3_errmsg(db->sqlite)); | |
56 sqlite3_close(db->sqlite); | |
57 return -1; | |
58 } | |
59 } | |
60 | |
6420
a8b515e1a26f
Removed _ prefixes from function names.
Timo Sirainen <tss@iki.fi>
parents:
6411
diff
changeset
|
61 static struct sql_db *driver_sqlite_init_v(const char *connect_string) |
3923 | 62 { |
63 struct sqlite_db *db; | |
6476
af14dc005392
Let deinit() free all the memory itself after all.
Timo Sirainen <tss@iki.fi>
parents:
6474
diff
changeset
|
64 pool_t pool; |
3923 | 65 |
66 i_assert(connect_string != NULL); | |
67 | |
6476
af14dc005392
Let deinit() free all the memory itself after all.
Timo Sirainen <tss@iki.fi>
parents:
6474
diff
changeset
|
68 pool = pool_alloconly_create("sqlite driver", 512); |
af14dc005392
Let deinit() free all the memory itself after all.
Timo Sirainen <tss@iki.fi>
parents:
6474
diff
changeset
|
69 db = p_new(pool, struct sqlite_db, 1); |
af14dc005392
Let deinit() free all the memory itself after all.
Timo Sirainen <tss@iki.fi>
parents:
6474
diff
changeset
|
70 db->pool = pool; |
3923 | 71 db->api = driver_sqlite_db; |
72 db->dbfile = p_strdup(db->pool, connect_string); | |
73 db->connected = FALSE; | |
74 | |
75 return &db->api; | |
76 } | |
77 | |
6420
a8b515e1a26f
Removed _ prefixes from function names.
Timo Sirainen <tss@iki.fi>
parents:
6411
diff
changeset
|
78 static void driver_sqlite_deinit_v(struct sql_db *_db) |
3923 | 79 { |
80 struct sqlite_db *db = (struct sqlite_db *)_db; | |
81 | |
82 sqlite3_close(db->sqlite); | |
6476
af14dc005392
Let deinit() free all the memory itself after all.
Timo Sirainen <tss@iki.fi>
parents:
6474
diff
changeset
|
83 array_free(&_db->module_contexts); |
6428
7cad076906eb
pool_unref() now takes ** pointer.
Timo Sirainen <tss@iki.fi>
parents:
6420
diff
changeset
|
84 pool_unref(&db->pool); |
3923 | 85 } |
86 | |
87 static enum sql_db_flags | |
6411
6a64e64fa3a3
Renamed __attr_*__ to ATTR_*. Renamed __attrs_used__ to ATTRS_DEFINED.
Timo Sirainen <tss@iki.fi>
parents:
5496
diff
changeset
|
88 driver_sqlite_get_flags(struct sql_db *db ATTR_UNUSED) |
3923 | 89 { |
90 return SQL_DB_FLAG_BLOCKING; | |
91 } | |
92 | |
4458
3e196acd60b7
sql_escape_string() should return const char *, not char *.
Timo Sirainen <tss@iki.fi>
parents:
4444
diff
changeset
|
93 static const char * |
6411
6a64e64fa3a3
Renamed __attr_*__ to ATTR_*. Renamed __attrs_used__ to ATTRS_DEFINED.
Timo Sirainen <tss@iki.fi>
parents:
5496
diff
changeset
|
94 driver_sqlite_escape_string(struct sql_db *_db ATTR_UNUSED, |
4458
3e196acd60b7
sql_escape_string() should return const char *, not char *.
Timo Sirainen <tss@iki.fi>
parents:
4444
diff
changeset
|
95 const char *string) |
4294 | 96 { |
4444
d0d04db8e7a6
Escape ' with '' instead of with \'.
Timo Sirainen <tss@iki.fi>
parents:
4294
diff
changeset
|
97 const char *p; |
d0d04db8e7a6
Escape ' with '' instead of with \'.
Timo Sirainen <tss@iki.fi>
parents:
4294
diff
changeset
|
98 char *dest, *destbegin; |
d0d04db8e7a6
Escape ' with '' instead of with \'.
Timo Sirainen <tss@iki.fi>
parents:
4294
diff
changeset
|
99 |
d0d04db8e7a6
Escape ' with '' instead of with \'.
Timo Sirainen <tss@iki.fi>
parents:
4294
diff
changeset
|
100 /* find the first ' */ |
d0d04db8e7a6
Escape ' with '' instead of with \'.
Timo Sirainen <tss@iki.fi>
parents:
4294
diff
changeset
|
101 for (p = string; *p != '\''; p++) { |
d0d04db8e7a6
Escape ' with '' instead of with \'.
Timo Sirainen <tss@iki.fi>
parents:
4294
diff
changeset
|
102 if (*p == '\0') |
d0d04db8e7a6
Escape ' with '' instead of with \'.
Timo Sirainen <tss@iki.fi>
parents:
4294
diff
changeset
|
103 return t_strdup_noconst(string); |
d0d04db8e7a6
Escape ' with '' instead of with \'.
Timo Sirainen <tss@iki.fi>
parents:
4294
diff
changeset
|
104 } |
d0d04db8e7a6
Escape ' with '' instead of with \'.
Timo Sirainen <tss@iki.fi>
parents:
4294
diff
changeset
|
105 |
d0d04db8e7a6
Escape ' with '' instead of with \'.
Timo Sirainen <tss@iki.fi>
parents:
4294
diff
changeset
|
106 /* @UNSAFE: escape ' with '' */ |
d0d04db8e7a6
Escape ' with '' instead of with \'.
Timo Sirainen <tss@iki.fi>
parents:
4294
diff
changeset
|
107 dest = destbegin = t_buffer_get((p - string) + strlen(string) * 2 + 1); |
d0d04db8e7a6
Escape ' with '' instead of with \'.
Timo Sirainen <tss@iki.fi>
parents:
4294
diff
changeset
|
108 |
d0d04db8e7a6
Escape ' with '' instead of with \'.
Timo Sirainen <tss@iki.fi>
parents:
4294
diff
changeset
|
109 memcpy(dest, string, p - string); |
d0d04db8e7a6
Escape ' with '' instead of with \'.
Timo Sirainen <tss@iki.fi>
parents:
4294
diff
changeset
|
110 dest += p - string; |
d0d04db8e7a6
Escape ' with '' instead of with \'.
Timo Sirainen <tss@iki.fi>
parents:
4294
diff
changeset
|
111 |
d0d04db8e7a6
Escape ' with '' instead of with \'.
Timo Sirainen <tss@iki.fi>
parents:
4294
diff
changeset
|
112 for (; *p != '\0'; p++) { |
d0d04db8e7a6
Escape ' with '' instead of with \'.
Timo Sirainen <tss@iki.fi>
parents:
4294
diff
changeset
|
113 *dest++ = *p; |
d0d04db8e7a6
Escape ' with '' instead of with \'.
Timo Sirainen <tss@iki.fi>
parents:
4294
diff
changeset
|
114 if (*p == '\'') |
d0d04db8e7a6
Escape ' with '' instead of with \'.
Timo Sirainen <tss@iki.fi>
parents:
4294
diff
changeset
|
115 *dest++ = *p; |
d0d04db8e7a6
Escape ' with '' instead of with \'.
Timo Sirainen <tss@iki.fi>
parents:
4294
diff
changeset
|
116 } |
d0d04db8e7a6
Escape ' with '' instead of with \'.
Timo Sirainen <tss@iki.fi>
parents:
4294
diff
changeset
|
117 *dest++ = '\0'; |
d0d04db8e7a6
Escape ' with '' instead of with \'.
Timo Sirainen <tss@iki.fi>
parents:
4294
diff
changeset
|
118 t_buffer_alloc(dest - destbegin); |
d0d04db8e7a6
Escape ' with '' instead of with \'.
Timo Sirainen <tss@iki.fi>
parents:
4294
diff
changeset
|
119 |
d0d04db8e7a6
Escape ' with '' instead of with \'.
Timo Sirainen <tss@iki.fi>
parents:
4294
diff
changeset
|
120 return destbegin; |
4294 | 121 } |
122 | |
3923 | 123 static void driver_sqlite_exec(struct sql_db *_db, const char *query) |
124 { | |
125 struct sqlite_db *db = (struct sqlite_db *)_db; | |
126 | |
8102
277aadb0ef8c
sqlite crashed with dict server. Patch by Bernhard Herzog.
Timo Sirainen <tss@iki.fi>
parents:
8027
diff
changeset
|
127 if (driver_sqlite_connect(_db) < 0) |
277aadb0ef8c
sqlite crashed with dict server. Patch by Bernhard Herzog.
Timo Sirainen <tss@iki.fi>
parents:
8027
diff
changeset
|
128 return; |
277aadb0ef8c
sqlite crashed with dict server. Patch by Bernhard Herzog.
Timo Sirainen <tss@iki.fi>
parents:
8027
diff
changeset
|
129 |
3923 | 130 db->rc = sqlite3_exec(db->sqlite, query, NULL, 0, NULL); |
131 if (db->rc != SQLITE_OK) { | |
132 i_error("sqlite: exec(%s) failed: %s (%d)", | |
133 query, sqlite3_errmsg(db->sqlite), db->rc); | |
134 } | |
135 } | |
136 | |
137 static void driver_sqlite_query(struct sql_db *db, const char *query, | |
5496
72ee0521dfaf
Added sql_result_setup_fetch() which makes it easier to fetch rows into
Timo Sirainen <tss@iki.fi>
parents:
4458
diff
changeset
|
138 sql_query_callback_t *callback, void *context) |
3923 | 139 { |
140 struct sql_result *result; | |
141 | |
142 result = sql_query_s(db, query); | |
143 result->callback = TRUE; | |
144 callback(result, context); | |
3946 | 145 result->callback = FALSE; |
3923 | 146 sql_result_free(result); |
147 } | |
148 | |
149 static struct sql_result * | |
150 driver_sqlite_query_s(struct sql_db *_db, const char *query) | |
151 { | |
152 struct sqlite_db *db = (struct sqlite_db *)_db; | |
153 struct sqlite_result *result; | |
154 int rc; | |
155 | |
156 result = i_new(struct sqlite_result, 1); | |
157 | |
8102
277aadb0ef8c
sqlite crashed with dict server. Patch by Bernhard Herzog.
Timo Sirainen <tss@iki.fi>
parents:
8027
diff
changeset
|
158 if (driver_sqlite_connect(_db) < 0) { |
3923 | 159 result->api = driver_sqlite_error_result; |
160 result->stmt = NULL; | |
161 result->cols = 0; | |
8102
277aadb0ef8c
sqlite crashed with dict server. Patch by Bernhard Herzog.
Timo Sirainen <tss@iki.fi>
parents:
8027
diff
changeset
|
162 } else { |
277aadb0ef8c
sqlite crashed with dict server. Patch by Bernhard Herzog.
Timo Sirainen <tss@iki.fi>
parents:
8027
diff
changeset
|
163 rc = sqlite3_prepare(db->sqlite, query, -1, &result->stmt, NULL); |
277aadb0ef8c
sqlite crashed with dict server. Patch by Bernhard Herzog.
Timo Sirainen <tss@iki.fi>
parents:
8027
diff
changeset
|
164 if (rc == SQLITE_OK) { |
277aadb0ef8c
sqlite crashed with dict server. Patch by Bernhard Herzog.
Timo Sirainen <tss@iki.fi>
parents:
8027
diff
changeset
|
165 result->api = driver_sqlite_result; |
277aadb0ef8c
sqlite crashed with dict server. Patch by Bernhard Herzog.
Timo Sirainen <tss@iki.fi>
parents:
8027
diff
changeset
|
166 result->cols = sqlite3_column_count(result->stmt); |
277aadb0ef8c
sqlite crashed with dict server. Patch by Bernhard Herzog.
Timo Sirainen <tss@iki.fi>
parents:
8027
diff
changeset
|
167 result->row = i_new(const char *, result->cols); |
277aadb0ef8c
sqlite crashed with dict server. Patch by Bernhard Herzog.
Timo Sirainen <tss@iki.fi>
parents:
8027
diff
changeset
|
168 } else { |
277aadb0ef8c
sqlite crashed with dict server. Patch by Bernhard Herzog.
Timo Sirainen <tss@iki.fi>
parents:
8027
diff
changeset
|
169 result->api = driver_sqlite_error_result; |
277aadb0ef8c
sqlite crashed with dict server. Patch by Bernhard Herzog.
Timo Sirainen <tss@iki.fi>
parents:
8027
diff
changeset
|
170 result->stmt = NULL; |
277aadb0ef8c
sqlite crashed with dict server. Patch by Bernhard Herzog.
Timo Sirainen <tss@iki.fi>
parents:
8027
diff
changeset
|
171 result->cols = 0; |
277aadb0ef8c
sqlite crashed with dict server. Patch by Bernhard Herzog.
Timo Sirainen <tss@iki.fi>
parents:
8027
diff
changeset
|
172 } |
3923 | 173 } |
174 result->api.db = _db; | |
175 | |
176 return &result->api; | |
177 } | |
178 | |
179 static void driver_sqlite_result_free(struct sql_result *_result) | |
180 { | |
181 struct sqlite_result *result = (struct sqlite_result *)_result; | |
182 struct sqlite_db *db = (struct sqlite_db *) result->api.db; | |
183 int rc; | |
184 | |
3947 | 185 if (_result->callback) |
186 return; | |
187 | |
3923 | 188 if (result->stmt != NULL) { |
189 if ((rc = sqlite3_finalize(result->stmt)) != SQLITE_OK) { | |
190 i_warning("sqlite: finalize failed: %s (%d)", | |
191 sqlite3_errmsg(db->sqlite), rc); | |
192 } | |
193 i_free(result->row); | |
194 } | |
195 i_free(result); | |
196 } | |
197 | |
198 static int driver_sqlite_result_next_row(struct sql_result *_result) | |
199 { | |
200 struct sqlite_result *result = (struct sqlite_result *)_result; | |
201 | |
202 switch (sqlite3_step(result->stmt)) { | |
203 case SQLITE_ROW: | |
204 return 1; | |
205 case SQLITE_DONE: | |
206 return 0; | |
207 default: | |
208 return -1; | |
209 } | |
210 } | |
211 | |
212 static unsigned int | |
213 driver_sqlite_result_get_fields_count(struct sql_result *_result) | |
214 { | |
215 struct sqlite_result *result = (struct sqlite_result *)_result; | |
216 | |
217 return result->cols; | |
218 } | |
219 | |
220 static const char * | |
221 driver_sqlite_result_get_field_name(struct sql_result *_result, | |
222 unsigned int idx) | |
223 { | |
224 struct sqlite_result *result = (struct sqlite_result *)_result; | |
225 | |
226 return sqlite3_column_name(result->stmt, idx); | |
227 } | |
228 | |
229 static int driver_sqlite_result_find_field(struct sql_result *_result, | |
230 const char *field_name) | |
231 { | |
232 struct sqlite_result *result = (struct sqlite_result *)_result; | |
233 unsigned int i; | |
234 | |
235 for (i = 0; i < result->cols; ++i) { | |
236 const char *col = sqlite3_column_name(result->stmt, i); | |
237 | |
238 if (strcmp(col, field_name) == 0) | |
239 return i; | |
240 } | |
241 | |
242 return -1; | |
243 } | |
244 | |
245 static const char * | |
246 driver_sqlite_result_get_field_value(struct sql_result *_result, | |
5496
72ee0521dfaf
Added sql_result_setup_fetch() which makes it easier to fetch rows into
Timo Sirainen <tss@iki.fi>
parents:
4458
diff
changeset
|
247 unsigned int idx) |
3923 | 248 { |
249 struct sqlite_result *result = (struct sqlite_result *)_result; | |
250 | |
3936
8e827b05047b
Compiler warning fix. Patch by Marcus Rueckert
Timo Sirainen <tss@iki.fi>
parents:
3923
diff
changeset
|
251 return (const char*)sqlite3_column_text(result->stmt, idx); |
3923 | 252 } |
253 | |
5496
72ee0521dfaf
Added sql_result_setup_fetch() which makes it easier to fetch rows into
Timo Sirainen <tss@iki.fi>
parents:
4458
diff
changeset
|
254 static const unsigned char * |
72ee0521dfaf
Added sql_result_setup_fetch() which makes it easier to fetch rows into
Timo Sirainen <tss@iki.fi>
parents:
4458
diff
changeset
|
255 driver_sqlite_result_get_field_value_binary(struct sql_result *_result, |
72ee0521dfaf
Added sql_result_setup_fetch() which makes it easier to fetch rows into
Timo Sirainen <tss@iki.fi>
parents:
4458
diff
changeset
|
256 unsigned int idx, size_t *size_r) |
72ee0521dfaf
Added sql_result_setup_fetch() which makes it easier to fetch rows into
Timo Sirainen <tss@iki.fi>
parents:
4458
diff
changeset
|
257 { |
72ee0521dfaf
Added sql_result_setup_fetch() which makes it easier to fetch rows into
Timo Sirainen <tss@iki.fi>
parents:
4458
diff
changeset
|
258 struct sqlite_result *result = (struct sqlite_result *)_result; |
72ee0521dfaf
Added sql_result_setup_fetch() which makes it easier to fetch rows into
Timo Sirainen <tss@iki.fi>
parents:
4458
diff
changeset
|
259 |
72ee0521dfaf
Added sql_result_setup_fetch() which makes it easier to fetch rows into
Timo Sirainen <tss@iki.fi>
parents:
4458
diff
changeset
|
260 *size_r = sqlite3_column_bytes(result->stmt, idx); |
72ee0521dfaf
Added sql_result_setup_fetch() which makes it easier to fetch rows into
Timo Sirainen <tss@iki.fi>
parents:
4458
diff
changeset
|
261 return sqlite3_column_blob(result->stmt, idx); |
72ee0521dfaf
Added sql_result_setup_fetch() which makes it easier to fetch rows into
Timo Sirainen <tss@iki.fi>
parents:
4458
diff
changeset
|
262 } |
72ee0521dfaf
Added sql_result_setup_fetch() which makes it easier to fetch rows into
Timo Sirainen <tss@iki.fi>
parents:
4458
diff
changeset
|
263 |
3923 | 264 static const char * |
265 driver_sqlite_result_find_field_value(struct sql_result *result, | |
266 const char *field_name) | |
267 { | |
268 int idx; | |
269 | |
270 idx = driver_sqlite_result_find_field(result, field_name); | |
271 if (idx < 0) | |
272 return NULL; | |
273 return driver_sqlite_result_get_field_value(result, idx); | |
274 } | |
275 | |
276 static const char *const * | |
277 driver_sqlite_result_get_values(struct sql_result *_result) | |
278 { | |
279 struct sqlite_result *result = (struct sqlite_result *)_result; | |
280 unsigned int i; | |
281 | |
282 for (i = 0; i < result->cols; ++i) { | |
283 result->row[i] = | |
284 driver_sqlite_result_get_field_value(_result, i); | |
285 } | |
286 | |
287 return (const char *const *)result->row; | |
288 } | |
289 | |
290 static const char *driver_sqlite_result_get_error(struct sql_result *_result) | |
291 { | |
292 struct sqlite_result *result = (struct sqlite_result *)_result; | |
293 struct sqlite_db *db = (struct sqlite_db *)result->api.db; | |
294 | |
295 return sqlite3_errmsg(db->sqlite); | |
296 } | |
297 | |
298 static struct sql_transaction_context * | |
299 driver_sqlite_transaction_begin(struct sql_db *_db) | |
300 { | |
301 struct sqlite_transaction_context *ctx; | |
302 struct sqlite_db *db = (struct sqlite_db *)_db; | |
303 | |
304 ctx = i_new(struct sqlite_transaction_context, 1); | |
305 ctx->ctx.db = _db; | |
306 | |
307 sql_exec(_db, "BEGIN TRANSACTION"); | |
308 if (db->rc != SQLITE_OK) | |
309 ctx->failed = TRUE; | |
310 | |
311 return &ctx->ctx; | |
312 } | |
313 | |
314 static void | |
315 driver_sqlite_transaction_rollback(struct sql_transaction_context *_ctx) | |
316 { | |
317 struct sqlite_transaction_context *ctx = | |
318 (struct sqlite_transaction_context *)_ctx; | |
319 | |
320 sql_exec(_ctx->db, "ROLLBACK"); | |
321 i_free(ctx); | |
322 } | |
323 | |
324 static void | |
325 driver_sqlite_transaction_commit(struct sql_transaction_context *_ctx, | |
326 sql_commit_callback_t *callback, void *context) | |
327 { | |
328 struct sqlite_transaction_context *ctx = | |
329 (struct sqlite_transaction_context *)_ctx; | |
330 struct sqlite_db *db = (struct sqlite_db *)ctx->ctx.db; | |
331 const char *errmsg; | |
332 | |
333 if (!ctx->failed) { | |
334 sql_exec(_ctx->db, "COMMIT"); | |
335 if (db->rc != SQLITE_OK) | |
336 ctx->failed = TRUE; | |
337 } | |
338 | |
339 if (ctx->failed) { | |
340 errmsg = sqlite3_errmsg(db->sqlite); | |
341 callback(errmsg, context); | |
342 /* also does i_free(ctx) */ | |
343 driver_sqlite_transaction_rollback(_ctx); | |
344 } else { | |
345 callback(NULL, context); | |
346 i_free(ctx); | |
347 } | |
348 } | |
349 | |
350 static int | |
351 driver_sqlite_transaction_commit_s(struct sql_transaction_context *_ctx, | |
352 const char **error_r) | |
353 { | |
354 struct sqlite_transaction_context *ctx = | |
355 (struct sqlite_transaction_context *)_ctx; | |
356 struct sqlite_db *db = (struct sqlite_db *) ctx->ctx.db; | |
357 | |
358 if (ctx->failed) { | |
359 /* also does i_free(ctx) */ | |
360 driver_sqlite_transaction_rollback(_ctx); | |
361 return -1; | |
362 } | |
363 | |
364 sql_exec(_ctx->db, "COMMIT"); | |
365 *error_r = sqlite3_errmsg(db->sqlite); | |
366 i_free(ctx); | |
367 return 0; | |
368 } | |
369 | |
370 static void | |
9360
4530228c8993
lib-sql: Added sql_update_get_rows().
Timo Sirainen <tss@iki.fi>
parents:
8102
diff
changeset
|
371 driver_sqlite_update(struct sql_transaction_context *_ctx, const char *query, |
4530228c8993
lib-sql: Added sql_update_get_rows().
Timo Sirainen <tss@iki.fi>
parents:
8102
diff
changeset
|
372 unsigned int *affected_rows) |
3923 | 373 { |
374 struct sqlite_transaction_context *ctx = | |
375 (struct sqlite_transaction_context *)_ctx; | |
376 struct sqlite_db *db = (struct sqlite_db *)ctx->ctx.db; | |
377 | |
378 if (ctx->failed) | |
379 return; | |
380 | |
381 sql_exec(_ctx->db, query); | |
382 if (db->rc != SQLITE_OK) | |
383 ctx->failed = TRUE; | |
9360
4530228c8993
lib-sql: Added sql_update_get_rows().
Timo Sirainen <tss@iki.fi>
parents:
8102
diff
changeset
|
384 else if (affected_rows != NULL) |
4530228c8993
lib-sql: Added sql_update_get_rows().
Timo Sirainen <tss@iki.fi>
parents:
8102
diff
changeset
|
385 *affected_rows = sqlite3_changes(db->sqlite); |
3923 | 386 } |
387 | |
388 struct sql_db driver_sqlite_db = { | |
389 "sqlite", | |
390 | |
6474
46c3e1ee196f
Added module_contexts to struct sql_db.
Timo Sirainen <tss@iki.fi>
parents:
6428
diff
changeset
|
391 MEMBER(v) { |
46c3e1ee196f
Added module_contexts to struct sql_db.
Timo Sirainen <tss@iki.fi>
parents:
6428
diff
changeset
|
392 driver_sqlite_init_v, |
46c3e1ee196f
Added module_contexts to struct sql_db.
Timo Sirainen <tss@iki.fi>
parents:
6428
diff
changeset
|
393 driver_sqlite_deinit_v, |
46c3e1ee196f
Added module_contexts to struct sql_db.
Timo Sirainen <tss@iki.fi>
parents:
6428
diff
changeset
|
394 driver_sqlite_get_flags, |
46c3e1ee196f
Added module_contexts to struct sql_db.
Timo Sirainen <tss@iki.fi>
parents:
6428
diff
changeset
|
395 driver_sqlite_connect, |
46c3e1ee196f
Added module_contexts to struct sql_db.
Timo Sirainen <tss@iki.fi>
parents:
6428
diff
changeset
|
396 driver_sqlite_escape_string, |
46c3e1ee196f
Added module_contexts to struct sql_db.
Timo Sirainen <tss@iki.fi>
parents:
6428
diff
changeset
|
397 driver_sqlite_exec, |
46c3e1ee196f
Added module_contexts to struct sql_db.
Timo Sirainen <tss@iki.fi>
parents:
6428
diff
changeset
|
398 driver_sqlite_query, |
46c3e1ee196f
Added module_contexts to struct sql_db.
Timo Sirainen <tss@iki.fi>
parents:
6428
diff
changeset
|
399 driver_sqlite_query_s, |
3923 | 400 |
6474
46c3e1ee196f
Added module_contexts to struct sql_db.
Timo Sirainen <tss@iki.fi>
parents:
6428
diff
changeset
|
401 driver_sqlite_transaction_begin, |
46c3e1ee196f
Added module_contexts to struct sql_db.
Timo Sirainen <tss@iki.fi>
parents:
6428
diff
changeset
|
402 driver_sqlite_transaction_commit, |
46c3e1ee196f
Added module_contexts to struct sql_db.
Timo Sirainen <tss@iki.fi>
parents:
6428
diff
changeset
|
403 driver_sqlite_transaction_commit_s, |
46c3e1ee196f
Added module_contexts to struct sql_db.
Timo Sirainen <tss@iki.fi>
parents:
6428
diff
changeset
|
404 driver_sqlite_transaction_rollback, |
46c3e1ee196f
Added module_contexts to struct sql_db.
Timo Sirainen <tss@iki.fi>
parents:
6428
diff
changeset
|
405 driver_sqlite_update |
46c3e1ee196f
Added module_contexts to struct sql_db.
Timo Sirainen <tss@iki.fi>
parents:
6428
diff
changeset
|
406 } |
3923 | 407 }; |
408 | |
409 struct sql_result driver_sqlite_result = { | |
5496
72ee0521dfaf
Added sql_result_setup_fetch() which makes it easier to fetch rows into
Timo Sirainen <tss@iki.fi>
parents:
4458
diff
changeset
|
410 MEMBER(v) { |
72ee0521dfaf
Added sql_result_setup_fetch() which makes it easier to fetch rows into
Timo Sirainen <tss@iki.fi>
parents:
4458
diff
changeset
|
411 driver_sqlite_result_free, |
72ee0521dfaf
Added sql_result_setup_fetch() which makes it easier to fetch rows into
Timo Sirainen <tss@iki.fi>
parents:
4458
diff
changeset
|
412 driver_sqlite_result_next_row, |
72ee0521dfaf
Added sql_result_setup_fetch() which makes it easier to fetch rows into
Timo Sirainen <tss@iki.fi>
parents:
4458
diff
changeset
|
413 driver_sqlite_result_get_fields_count, |
72ee0521dfaf
Added sql_result_setup_fetch() which makes it easier to fetch rows into
Timo Sirainen <tss@iki.fi>
parents:
4458
diff
changeset
|
414 driver_sqlite_result_get_field_name, |
72ee0521dfaf
Added sql_result_setup_fetch() which makes it easier to fetch rows into
Timo Sirainen <tss@iki.fi>
parents:
4458
diff
changeset
|
415 driver_sqlite_result_find_field, |
72ee0521dfaf
Added sql_result_setup_fetch() which makes it easier to fetch rows into
Timo Sirainen <tss@iki.fi>
parents:
4458
diff
changeset
|
416 driver_sqlite_result_get_field_value, |
72ee0521dfaf
Added sql_result_setup_fetch() which makes it easier to fetch rows into
Timo Sirainen <tss@iki.fi>
parents:
4458
diff
changeset
|
417 driver_sqlite_result_get_field_value_binary, |
72ee0521dfaf
Added sql_result_setup_fetch() which makes it easier to fetch rows into
Timo Sirainen <tss@iki.fi>
parents:
4458
diff
changeset
|
418 driver_sqlite_result_find_field_value, |
72ee0521dfaf
Added sql_result_setup_fetch() which makes it easier to fetch rows into
Timo Sirainen <tss@iki.fi>
parents:
4458
diff
changeset
|
419 driver_sqlite_result_get_values, |
72ee0521dfaf
Added sql_result_setup_fetch() which makes it easier to fetch rows into
Timo Sirainen <tss@iki.fi>
parents:
4458
diff
changeset
|
420 driver_sqlite_result_get_error |
72ee0521dfaf
Added sql_result_setup_fetch() which makes it easier to fetch rows into
Timo Sirainen <tss@iki.fi>
parents:
4458
diff
changeset
|
421 } |
3923 | 422 }; |
423 | |
424 static int | |
6411
6a64e64fa3a3
Renamed __attr_*__ to ATTR_*. Renamed __attrs_used__ to ATTRS_DEFINED.
Timo Sirainen <tss@iki.fi>
parents:
5496
diff
changeset
|
425 driver_sqlite_result_error_next_row(struct sql_result *result ATTR_UNUSED) |
3923 | 426 { |
427 return -1; | |
428 } | |
429 | |
430 struct sql_result driver_sqlite_error_result = { | |
5496
72ee0521dfaf
Added sql_result_setup_fetch() which makes it easier to fetch rows into
Timo Sirainen <tss@iki.fi>
parents:
4458
diff
changeset
|
431 MEMBER(v) { |
72ee0521dfaf
Added sql_result_setup_fetch() which makes it easier to fetch rows into
Timo Sirainen <tss@iki.fi>
parents:
4458
diff
changeset
|
432 driver_sqlite_result_free, |
72ee0521dfaf
Added sql_result_setup_fetch() which makes it easier to fetch rows into
Timo Sirainen <tss@iki.fi>
parents:
4458
diff
changeset
|
433 driver_sqlite_result_error_next_row, |
72ee0521dfaf
Added sql_result_setup_fetch() which makes it easier to fetch rows into
Timo Sirainen <tss@iki.fi>
parents:
4458
diff
changeset
|
434 NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
72ee0521dfaf
Added sql_result_setup_fetch() which makes it easier to fetch rows into
Timo Sirainen <tss@iki.fi>
parents:
4458
diff
changeset
|
435 driver_sqlite_result_get_error |
72ee0521dfaf
Added sql_result_setup_fetch() which makes it easier to fetch rows into
Timo Sirainen <tss@iki.fi>
parents:
4458
diff
changeset
|
436 } |
3923 | 437 }; |
438 | |
3943
cbe5c6772e0d
Added support for dynamically building SQL drivers.
Timo Sirainen <tss@iki.fi>
parents:
3936
diff
changeset
|
439 void driver_sqlite_init(void); |
cbe5c6772e0d
Added support for dynamically building SQL drivers.
Timo Sirainen <tss@iki.fi>
parents:
3936
diff
changeset
|
440 void driver_sqlite_deinit(void); |
cbe5c6772e0d
Added support for dynamically building SQL drivers.
Timo Sirainen <tss@iki.fi>
parents:
3936
diff
changeset
|
441 |
cbe5c6772e0d
Added support for dynamically building SQL drivers.
Timo Sirainen <tss@iki.fi>
parents:
3936
diff
changeset
|
442 void driver_sqlite_init(void) |
cbe5c6772e0d
Added support for dynamically building SQL drivers.
Timo Sirainen <tss@iki.fi>
parents:
3936
diff
changeset
|
443 { |
cbe5c6772e0d
Added support for dynamically building SQL drivers.
Timo Sirainen <tss@iki.fi>
parents:
3936
diff
changeset
|
444 sql_driver_register(&driver_sqlite_db); |
cbe5c6772e0d
Added support for dynamically building SQL drivers.
Timo Sirainen <tss@iki.fi>
parents:
3936
diff
changeset
|
445 } |
cbe5c6772e0d
Added support for dynamically building SQL drivers.
Timo Sirainen <tss@iki.fi>
parents:
3936
diff
changeset
|
446 |
cbe5c6772e0d
Added support for dynamically building SQL drivers.
Timo Sirainen <tss@iki.fi>
parents:
3936
diff
changeset
|
447 void driver_sqlite_deinit(void) |
cbe5c6772e0d
Added support for dynamically building SQL drivers.
Timo Sirainen <tss@iki.fi>
parents:
3936
diff
changeset
|
448 { |
cbe5c6772e0d
Added support for dynamically building SQL drivers.
Timo Sirainen <tss@iki.fi>
parents:
3936
diff
changeset
|
449 sql_driver_unregister(&driver_sqlite_db); |
cbe5c6772e0d
Added support for dynamically building SQL drivers.
Timo Sirainen <tss@iki.fi>
parents:
3936
diff
changeset
|
450 } |
cbe5c6772e0d
Added support for dynamically building SQL drivers.
Timo Sirainen <tss@iki.fi>
parents:
3936
diff
changeset
|
451 |
3923 | 452 #endif |