aboutsummaryrefslogtreecommitdiff
path: root/src/datacache/plugin_datacache_sqlite.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/datacache/plugin_datacache_sqlite.c')
-rw-r--r--src/datacache/plugin_datacache_sqlite.c449
1 files changed, 214 insertions, 235 deletions
diff --git a/src/datacache/plugin_datacache_sqlite.c b/src/datacache/plugin_datacache_sqlite.c
index fd451e2b4..5f534227f 100644
--- a/src/datacache/plugin_datacache_sqlite.c
+++ b/src/datacache/plugin_datacache_sqlite.c
@@ -39,7 +39,7 @@
39/** 39/**
40 * Context for all functions in this plugin. 40 * Context for all functions in this plugin.
41 */ 41 */
42struct Plugin 42struct Plugin
43{ 43{
44 /** 44 /**
45 * Our execution environment. 45 * Our execution environment.
@@ -53,7 +53,7 @@ struct Plugin
53 53
54 /** 54 /**
55 * Filename used for the DB. 55 * Filename used for the DB.
56 */ 56 */
57 char *fn; 57 char *fn;
58}; 58};
59 59
@@ -77,9 +77,9 @@ sq_prepare (sqlite3 * dbh, const char *zSql, /* SQL statement, UTF-8 encoded
77 sqlite3_stmt ** ppStmt) 77 sqlite3_stmt ** ppStmt)
78{ /* OUT: Statement handle */ 78{ /* OUT: Statement handle */
79 char *dummy; 79 char *dummy;
80
80 return sqlite3_prepare (dbh, 81 return sqlite3_prepare (dbh,
81 zSql, 82 zSql, strlen (zSql), ppStmt, (const char **) &dummy);
82 strlen (zSql), ppStmt, (const char **) &dummy);
83} 83}
84 84
85 85
@@ -94,13 +94,13 @@ sq_prepare (sqlite3 * dbh, const char *zSql, /* SQL statement, UTF-8 encoded
94 * @param discard_time when to discard the value in any case 94 * @param discard_time when to discard the value in any case
95 * @return 0 on error, number of bytes used otherwise 95 * @return 0 on error, number of bytes used otherwise
96 */ 96 */
97static size_t 97static size_t
98sqlite_plugin_put (void *cls, 98sqlite_plugin_put (void *cls,
99 const GNUNET_HashCode * key, 99 const GNUNET_HashCode * key,
100 size_t size, 100 size_t size,
101 const char *data, 101 const char *data,
102 enum GNUNET_BLOCK_Type type, 102 enum GNUNET_BLOCK_Type type,
103 struct GNUNET_TIME_Absolute discard_time) 103 struct GNUNET_TIME_Absolute discard_time)
104{ 104{
105 struct Plugin *plugin = cls; 105 struct Plugin *plugin = cls;
106 sqlite3_stmt *stmt; 106 sqlite3_stmt *stmt;
@@ -108,50 +108,50 @@ sqlite_plugin_put (void *cls,
108 108
109#if DEBUG_DATACACHE_SQLITE 109#if DEBUG_DATACACHE_SQLITE
110 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 110 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
111 "Processing `%s' of %u bytes with key `%4s' and expiration %llums\n", 111 "Processing `%s' of %u bytes with key `%4s' and expiration %llums\n",
112 "PUT", 112 "PUT",
113 (unsigned int) size, 113 (unsigned int) size,
114 GNUNET_h2s (key), 114 GNUNET_h2s (key),
115 (unsigned long long) GNUNET_TIME_absolute_get_remaining (discard_time).rel_value); 115 (unsigned long long)
116 GNUNET_TIME_absolute_get_remaining (discard_time).rel_value);
116#endif 117#endif
117 dval = (int64_t) discard_time.abs_value; 118 dval = (int64_t) discard_time.abs_value;
118 if (dval < 0) 119 if (dval < 0)
119 dval = INT64_MAX; 120 dval = INT64_MAX;
120 if (sq_prepare (plugin->dbh, 121 if (sq_prepare (plugin->dbh,
121 "INSERT INTO ds090 " 122 "INSERT INTO ds090 "
122 "(type, expire, key, value) " 123 "(type, expire, key, value) "
123 "VALUES (?, ?, ?, ?)", &stmt) != SQLITE_OK) 124 "VALUES (?, ?, ?, ?)", &stmt) != SQLITE_OK)
124 { 125 {
125 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 126 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
126 _("`%s' failed at %s:%d with error: %s\n"), 127 _("`%s' failed at %s:%d with error: %s\n"),
127 "sq_prepare", __FILE__, __LINE__, 128 "sq_prepare", __FILE__, __LINE__, sqlite3_errmsg (plugin->dbh));
128 sqlite3_errmsg (plugin->dbh)); 129 return 0;
129 return 0; 130 }
130 } 131 if ((SQLITE_OK != sqlite3_bind_int (stmt, 1, type)) ||
131 if ( (SQLITE_OK != sqlite3_bind_int (stmt, 1, type)) || 132 (SQLITE_OK != sqlite3_bind_int64 (stmt, 2, dval)) ||
132 (SQLITE_OK != sqlite3_bind_int64 (stmt, 2, dval)) || 133 (SQLITE_OK != sqlite3_bind_blob (stmt, 3, key, sizeof (GNUNET_HashCode),
133 (SQLITE_OK != sqlite3_bind_blob (stmt, 3, key, sizeof (GNUNET_HashCode), 134 SQLITE_TRANSIENT)) ||
134 SQLITE_TRANSIENT)) || 135 (SQLITE_OK != sqlite3_bind_blob (stmt, 4, data, size, SQLITE_TRANSIENT)))
135 (SQLITE_OK != sqlite3_bind_blob (stmt, 4, data, size, SQLITE_TRANSIENT))) 136 {
136 { 137 LOG_SQLITE (plugin->dbh,
137 LOG_SQLITE (plugin->dbh, 138 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
138 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 139 "sqlite3_bind_xxx");
139 "sqlite3_bind_xxx"); 140 sqlite3_finalize (stmt);
140 sqlite3_finalize (stmt); 141 return 0;
141 return 0; 142 }
142 }
143 if (SQLITE_DONE != sqlite3_step (stmt)) 143 if (SQLITE_DONE != sqlite3_step (stmt))
144 { 144 {
145 LOG_SQLITE (plugin->dbh, 145 LOG_SQLITE (plugin->dbh,
146 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 146 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
147 "sqlite3_step"); 147 "sqlite3_step");
148 sqlite3_finalize (stmt); 148 sqlite3_finalize (stmt);
149 return 0; 149 return 0;
150 } 150 }
151 if (SQLITE_OK != sqlite3_finalize (stmt)) 151 if (SQLITE_OK != sqlite3_finalize (stmt))
152 LOG_SQLITE (plugin->dbh, 152 LOG_SQLITE (plugin->dbh,
153 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 153 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
154 "sqlite3_finalize"); 154 "sqlite3_finalize");
155 return size + OVERHEAD; 155 return size + OVERHEAD;
156} 156}
157 157
@@ -167,12 +167,11 @@ sqlite_plugin_put (void *cls,
167 * @param iter_cls closure for iter 167 * @param iter_cls closure for iter
168 * @return the number of results found 168 * @return the number of results found
169 */ 169 */
170static unsigned int 170static unsigned int
171sqlite_plugin_get (void *cls, 171sqlite_plugin_get (void *cls,
172 const GNUNET_HashCode * key, 172 const GNUNET_HashCode * key,
173 enum GNUNET_BLOCK_Type type, 173 enum GNUNET_BLOCK_Type type,
174 GNUNET_DATACACHE_Iterator iter, 174 GNUNET_DATACACHE_Iterator iter, void *iter_cls)
175 void *iter_cls)
176{ 175{
177 struct Plugin *plugin = cls; 176 struct Plugin *plugin = cls;
178 sqlite3_stmt *stmt; 177 sqlite3_stmt *stmt;
@@ -189,102 +188,92 @@ sqlite_plugin_get (void *cls,
189 now = GNUNET_TIME_absolute_get (); 188 now = GNUNET_TIME_absolute_get ();
190#if DEBUG_DATACACHE_SQLITE 189#if DEBUG_DATACACHE_SQLITE
191 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 190 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
192 "Processing `%s' for key `%4s'\n", 191 "Processing `%s' for key `%4s'\n", "GET", GNUNET_h2s (key));
193 "GET",
194 GNUNET_h2s (key));
195#endif 192#endif
196 if (sq_prepare (plugin->dbh, 193 if (sq_prepare (plugin->dbh,
197 "SELECT count(*) FROM ds090 WHERE key=? AND type=? AND expire >= ?", 194 "SELECT count(*) FROM ds090 WHERE key=? AND type=? AND expire >= ?",
198 &stmt) != SQLITE_OK) 195 &stmt) != SQLITE_OK)
199 { 196 {
200 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 197 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
201 _("`%s' failed at %s:%d with error: %s\n"), 198 _("`%s' failed at %s:%d with error: %s\n"),
202 "sq_prepare", __FILE__, __LINE__, 199 "sq_prepare", __FILE__, __LINE__, sqlite3_errmsg (plugin->dbh));
203 sqlite3_errmsg (plugin->dbh)); 200 return 0;
204 return 0; 201 }
205 }
206 ntime = (int64_t) now.abs_value; 202 ntime = (int64_t) now.abs_value;
207 GNUNET_assert (ntime >= 0); 203 GNUNET_assert (ntime >= 0);
208 if ( (SQLITE_OK != 204 if ((SQLITE_OK !=
209 sqlite3_bind_blob (stmt, 1, key, sizeof (GNUNET_HashCode), 205 sqlite3_bind_blob (stmt, 1, key, sizeof (GNUNET_HashCode),
210 SQLITE_TRANSIENT)) || 206 SQLITE_TRANSIENT)) ||
211 (SQLITE_OK != 207 (SQLITE_OK !=
212 sqlite3_bind_int (stmt, 2, type)) || 208 sqlite3_bind_int (stmt, 2, type)) ||
213 (SQLITE_OK != 209 (SQLITE_OK != sqlite3_bind_int64 (stmt, 3, now.abs_value)))
214 sqlite3_bind_int64 (stmt, 3, now.abs_value)) ) 210 {
215 { 211 LOG_SQLITE (plugin->dbh,
216 LOG_SQLITE (plugin->dbh, 212 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
217 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 213 "sqlite3_bind_xxx");
218 "sqlite3_bind_xxx"); 214 sqlite3_finalize (stmt);
219 sqlite3_finalize (stmt); 215 return 0;
220 return 0; 216 }
221 }
222 217
223 if (SQLITE_ROW != sqlite3_step (stmt)) 218 if (SQLITE_ROW != sqlite3_step (stmt))
224 { 219 {
225 LOG_SQLITE (plugin->dbh, 220 LOG_SQLITE (plugin->dbh,
226 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 221 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
227 "sqlite_step"); 222 "sqlite_step");
228 sqlite3_finalize (stmt); 223 sqlite3_finalize (stmt);
229 return 0; 224 return 0;
230 } 225 }
231 total = sqlite3_column_int (stmt, 0); 226 total = sqlite3_column_int (stmt, 0);
232 sqlite3_finalize (stmt); 227 sqlite3_finalize (stmt);
233 if ( (total == 0) || (iter == NULL) ) 228 if ((total == 0) || (iter == NULL))
234 return total; 229 return total;
235 230
236 cnt = 0; 231 cnt = 0;
237 off = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, total); 232 off = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, total);
238 while (cnt < total) 233 while (cnt < total)
234 {
235 off = (off + 1) % total;
236 GNUNET_snprintf (scratch,
237 sizeof (scratch),
238 "SELECT value,expire FROM ds090 WHERE key=? AND type=? AND expire >= ? LIMIT 1 OFFSET %u",
239 off);
240 if (sq_prepare (plugin->dbh, scratch, &stmt) != SQLITE_OK)
241 {
242 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
243 _("`%s' failed at %s:%d with error: %s\n"),
244 "sq_prepare", __FILE__, __LINE__,
245 sqlite3_errmsg (plugin->dbh));
246 return cnt;
247 }
248 if ((SQLITE_OK !=
249 sqlite3_bind_blob (stmt, 1, key, sizeof (GNUNET_HashCode),
250 SQLITE_TRANSIENT)) ||
251 (SQLITE_OK !=
252 sqlite3_bind_int (stmt, 2, type)) ||
253 (SQLITE_OK != sqlite3_bind_int64 (stmt, 3, now.abs_value)))
254 {
255 LOG_SQLITE (plugin->dbh,
256 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
257 "sqlite3_bind_xxx");
258 sqlite3_finalize (stmt);
259 return cnt;
260 }
261 if (sqlite3_step (stmt) != SQLITE_ROW)
262 break;
263 size = sqlite3_column_bytes (stmt, 0);
264 dat = sqlite3_column_blob (stmt, 0);
265 exp.abs_value = sqlite3_column_int64 (stmt, 1);
266 ntime = (int64_t) exp.abs_value;
267 if (ntime == INT64_MAX)
268 exp = GNUNET_TIME_UNIT_FOREVER_ABS;
269 cnt++;
270 if (GNUNET_OK != iter (iter_cls, exp, key, size, dat, type))
239 { 271 {
240 off = (off + 1) % total;
241 GNUNET_snprintf (scratch,
242 sizeof(scratch),
243 "SELECT value,expire FROM ds090 WHERE key=? AND type=? AND expire >= ? LIMIT 1 OFFSET %u",
244 off);
245 if (sq_prepare (plugin->dbh, scratch, &stmt) != SQLITE_OK)
246 {
247 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
248 _("`%s' failed at %s:%d with error: %s\n"),
249 "sq_prepare", __FILE__, __LINE__,
250 sqlite3_errmsg (plugin->dbh));
251 return cnt;
252 }
253 if ( (SQLITE_OK !=
254 sqlite3_bind_blob (stmt, 1, key, sizeof (GNUNET_HashCode),
255 SQLITE_TRANSIENT)) ||
256 (SQLITE_OK !=
257 sqlite3_bind_int (stmt, 2, type)) ||
258 (SQLITE_OK !=
259 sqlite3_bind_int64 (stmt, 3, now.abs_value)) )
260 {
261 LOG_SQLITE (plugin->dbh,
262 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
263 "sqlite3_bind_xxx");
264 sqlite3_finalize (stmt);
265 return cnt;
266 }
267 if (sqlite3_step (stmt) != SQLITE_ROW)
268 break;
269 size = sqlite3_column_bytes (stmt, 0);
270 dat = sqlite3_column_blob (stmt, 0);
271 exp.abs_value = sqlite3_column_int64 (stmt, 1);
272 ntime = (int64_t) exp.abs_value;
273 if (ntime == INT64_MAX)
274 exp = GNUNET_TIME_UNIT_FOREVER_ABS;
275 cnt++;
276 if (GNUNET_OK != iter (iter_cls,
277 exp,
278 key,
279 size,
280 dat,
281 type))
282 {
283 sqlite3_finalize (stmt);
284 break;
285 }
286 sqlite3_finalize (stmt); 272 sqlite3_finalize (stmt);
273 break;
287 } 274 }
275 sqlite3_finalize (stmt);
276 }
288 return cnt; 277 return cnt;
289} 278}
290 279
@@ -295,8 +284,8 @@ sqlite_plugin_get (void *cls,
295 * 284 *
296 * @param cls closure (our "struct Plugin") 285 * @param cls closure (our "struct Plugin")
297 * @return GNUNET_OK on success, GNUNET_SYSERR on error 286 * @return GNUNET_OK on success, GNUNET_SYSERR on error
298 */ 287 */
299static int 288static int
300sqlite_plugin_del (void *cls) 289sqlite_plugin_del (void *cls)
301{ 290{
302 struct Plugin *plugin = cls; 291 struct Plugin *plugin = cls;
@@ -308,32 +297,30 @@ sqlite_plugin_del (void *cls)
308 GNUNET_HashCode hc; 297 GNUNET_HashCode hc;
309 298
310#if DEBUG_DATACACHE_SQLITE 299#if DEBUG_DATACACHE_SQLITE
311 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 300 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing `%s'\n", "DEL");
312 "Processing `%s'\n",
313 "DEL");
314#endif 301#endif
315 stmt = NULL; 302 stmt = NULL;
316 dstmt = NULL; 303 dstmt = NULL;
317 if (sq_prepare (plugin->dbh, 304 if (sq_prepare (plugin->dbh,
318 "SELECT type, key, value FROM ds090 ORDER BY expire ASC LIMIT 1", 305 "SELECT type, key, value FROM ds090 ORDER BY expire ASC LIMIT 1",
319 &stmt) != SQLITE_OK) 306 &stmt) != SQLITE_OK)
320 { 307 {
321 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 308 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
322 _("`%s' failed at %s:%d with error: %s\n"), 309 _("`%s' failed at %s:%d with error: %s\n"),
323 "sq_prepare", __FILE__, __LINE__, sqlite3_errmsg (plugin->dbh)); 310 "sq_prepare", __FILE__, __LINE__, sqlite3_errmsg (plugin->dbh));
324 if (stmt != NULL) 311 if (stmt != NULL)
325 (void) sqlite3_finalize (stmt);
326 return GNUNET_SYSERR;
327 }
328 if (SQLITE_ROW != sqlite3_step (stmt))
329 {
330 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
331 _("`%s' failed at %s:%d with error: %s\n"),
332 "sqlite3_step", __FILE__, __LINE__,
333 sqlite3_errmsg (plugin->dbh));
334 (void) sqlite3_finalize (stmt); 312 (void) sqlite3_finalize (stmt);
335 return GNUNET_SYSERR; 313 return GNUNET_SYSERR;
336 } 314 }
315 if (SQLITE_ROW != sqlite3_step (stmt))
316 {
317 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
318 _("`%s' failed at %s:%d with error: %s\n"),
319 "sqlite3_step", __FILE__, __LINE__,
320 sqlite3_errmsg (plugin->dbh));
321 (void) sqlite3_finalize (stmt);
322 return GNUNET_SYSERR;
323 }
337 dtype = sqlite3_column_int (stmt, 0); 324 dtype = sqlite3_column_int (stmt, 0);
338 GNUNET_break (sqlite3_column_bytes (stmt, 1) == sizeof (GNUNET_HashCode)); 325 GNUNET_break (sqlite3_column_bytes (stmt, 1) == sizeof (GNUNET_HashCode));
339 dsize = sqlite3_column_bytes (stmt, 2); 326 dsize = sqlite3_column_bytes (stmt, 2);
@@ -342,58 +329,54 @@ sqlite_plugin_del (void *cls)
342 memcpy (&hc, sqlite3_column_blob (stmt, 1), sizeof (GNUNET_HashCode)); 329 memcpy (&hc, sqlite3_column_blob (stmt, 1), sizeof (GNUNET_HashCode));
343 if (SQLITE_OK != sqlite3_finalize (stmt)) 330 if (SQLITE_OK != sqlite3_finalize (stmt))
344 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 331 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
345 _("`%s' failed at %s:%d with error: %s\n"), 332 _("`%s' failed at %s:%d with error: %s\n"),
346 "sqlite3_step", __FILE__, __LINE__, 333 "sqlite3_step", __FILE__, __LINE__,
347 sqlite3_errmsg (plugin->dbh)); 334 sqlite3_errmsg (plugin->dbh));
348 if (sq_prepare (plugin->dbh, 335 if (sq_prepare (plugin->dbh,
349 "DELETE FROM ds090 " 336 "DELETE FROM ds090 "
350 "WHERE key=? AND value=? AND type=?", 337 "WHERE key=? AND value=? AND type=?", &dstmt) != SQLITE_OK)
351 &dstmt) != SQLITE_OK) 338 {
352 { 339 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
353 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 340 _("`%s' failed at %s:%d with error: %s\n"),
354 _("`%s' failed at %s:%d with error: %s\n"), 341 "sq_prepare", __FILE__, __LINE__, sqlite3_errmsg (plugin->dbh));
355 "sq_prepare", __FILE__, __LINE__, sqlite3_errmsg (plugin->dbh)); 342 if (stmt != NULL)
356 if (stmt != NULL) 343 (void) sqlite3_finalize (stmt);
357 (void) sqlite3_finalize (stmt); 344 return GNUNET_SYSERR;
358 return GNUNET_SYSERR; 345 }
359 } 346 if ((SQLITE_OK !=
360 if ( (SQLITE_OK != 347 sqlite3_bind_blob (dstmt,
361 sqlite3_bind_blob (dstmt, 348 1, &hc,
362 1, &hc, 349 sizeof (GNUNET_HashCode),
363 sizeof (GNUNET_HashCode), 350 SQLITE_TRANSIENT)) ||
364 SQLITE_TRANSIENT)) || 351 (SQLITE_OK !=
365 (SQLITE_OK != 352 sqlite3_bind_blob (dstmt,
366 sqlite3_bind_blob (dstmt, 353 2, blob,
367 2, blob, 354 dsize,
368 dsize, 355 SQLITE_TRANSIENT)) ||
369 SQLITE_TRANSIENT)) || 356 (SQLITE_OK != sqlite3_bind_int (dstmt, 3, dtype)))
370 (SQLITE_OK != 357 {
371 sqlite3_bind_int (dstmt, 3, dtype)) ) 358 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
372 { 359 _("`%s' failed at %s:%d with error: %s\n"),
373 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 360 "sqlite3_bind", __FILE__, __LINE__,
374 _("`%s' failed at %s:%d with error: %s\n"), 361 sqlite3_errmsg (plugin->dbh));
375 "sqlite3_bind", __FILE__, __LINE__, 362 (void) sqlite3_finalize (dstmt);
376 sqlite3_errmsg (plugin->dbh)); 363 return GNUNET_SYSERR;
377 (void) sqlite3_finalize (dstmt); 364 }
378 return GNUNET_SYSERR;
379 }
380 if (sqlite3_step (dstmt) != SQLITE_DONE) 365 if (sqlite3_step (dstmt) != SQLITE_DONE)
381 { 366 {
382 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 367 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
383 _("`%s' failed at %s:%d with error: %s\n"), 368 _("`%s' failed at %s:%d with error: %s\n"),
384 "sqlite3_step", __FILE__, __LINE__, 369 "sqlite3_step", __FILE__, __LINE__,
385 sqlite3_errmsg (plugin->dbh)); 370 sqlite3_errmsg (plugin->dbh));
386 (void) sqlite3_finalize (dstmt); 371 (void) sqlite3_finalize (dstmt);
387 return GNUNET_SYSERR; 372 return GNUNET_SYSERR;
388 } 373 }
389 plugin->env->delete_notify (plugin->env->cls, 374 plugin->env->delete_notify (plugin->env->cls, &hc, dsize + OVERHEAD);
390 &hc,
391 dsize + OVERHEAD);
392 if (SQLITE_OK != sqlite3_finalize (dstmt)) 375 if (SQLITE_OK != sqlite3_finalize (dstmt))
393 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK, 376 GNUNET_log (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
394 _("`%s' failed at %s:%d with error: %s\n"), 377 _("`%s' failed at %s:%d with error: %s\n"),
395 "sqlite3_finalize", __FILE__, __LINE__, 378 "sqlite3_finalize", __FILE__, __LINE__,
396 sqlite3_errmsg (plugin->dbh)); 379 sqlite3_errmsg (plugin->dbh));
397 return GNUNET_OK; 380 return GNUNET_OK;
398} 381}
399 382
@@ -417,10 +400,10 @@ libgnunet_plugin_datacache_sqlite_init (void *cls)
417 400
418 fn = GNUNET_DISK_mktemp ("gnunet-datacache"); 401 fn = GNUNET_DISK_mktemp ("gnunet-datacache");
419 if (fn == NULL) 402 if (fn == NULL)
420 { 403 {
421 GNUNET_break (0); 404 GNUNET_break (0);
422 return NULL; 405 return NULL;
423 } 406 }
424#ifdef ENABLE_NLS 407#ifdef ENABLE_NLS
425 fn_utf8 = GNUNET_STRINGS_to_utf8 (fn, strlen (fn), nl_langinfo (CODESET)); 408 fn_utf8 = GNUNET_STRINGS_to_utf8 (fn, strlen (fn), nl_langinfo (CODESET));
426#else 409#else
@@ -428,11 +411,11 @@ libgnunet_plugin_datacache_sqlite_init (void *cls)
428 fn_utf8 = GNUNET_STRINGS_to_utf8 (fn, strlen (fn), "UTF-8"); 411 fn_utf8 = GNUNET_STRINGS_to_utf8 (fn, strlen (fn), "UTF-8");
429#endif 412#endif
430 if (SQLITE_OK != sqlite3_open (fn_utf8, &dbh)) 413 if (SQLITE_OK != sqlite3_open (fn_utf8, &dbh))
431 { 414 {
432 GNUNET_free (fn); 415 GNUNET_free (fn);
433 GNUNET_free (fn_utf8); 416 GNUNET_free (fn_utf8);
434 return NULL; 417 return NULL;
435 } 418 }
436 GNUNET_free (fn); 419 GNUNET_free (fn);
437 420
438 SQLITE3_EXEC (dbh, "PRAGMA temp_store=MEMORY"); 421 SQLITE3_EXEC (dbh, "PRAGMA temp_store=MEMORY");
@@ -461,6 +444,7 @@ libgnunet_plugin_datacache_sqlite_init (void *cls)
461 "sqlite", _("Sqlite datacache running\n")); 444 "sqlite", _("Sqlite datacache running\n"));
462 return api; 445 return api;
463} 446}
447
464// explain SELECT type FROM gn090 WHERE NOT EXISTS (SELECT 1 from gn090 WHERE expire < 42 LIMIT 1) OR expire < 42 ORDER BY repl DESC, Random() LIMIT 1; 448// explain SELECT type FROM gn090 WHERE NOT EXISTS (SELECT 1 from gn090 WHERE expire < 42 LIMIT 1) OR expire < 42 ORDER BY repl DESC, Random() LIMIT 1;
465 449
466 450
@@ -476,53 +460,49 @@ libgnunet_plugin_datacache_sqlite_done (void *cls)
476 struct GNUNET_DATACACHE_PluginFunctions *api = cls; 460 struct GNUNET_DATACACHE_PluginFunctions *api = cls;
477 struct Plugin *plugin = api->cls; 461 struct Plugin *plugin = api->cls;
478 int result; 462 int result;
463
479#if SQLITE_VERSION_NUMBER >= 3007000 464#if SQLITE_VERSION_NUMBER >= 3007000
480 sqlite3_stmt *stmt; 465 sqlite3_stmt *stmt;
481#endif 466#endif
482 467
483#if !WINDOWS || defined(__CYGWIN__) 468#if !WINDOWS || defined(__CYGWIN__)
484 if (0 != UNLINK (plugin->fn)) 469 if (0 != UNLINK (plugin->fn))
485 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, 470 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", plugin->fn);
486 "unlink",
487 plugin->fn);
488 GNUNET_free (plugin->fn); 471 GNUNET_free (plugin->fn);
489#endif 472#endif
490 result = sqlite3_close (plugin->dbh); 473 result = sqlite3_close (plugin->dbh);
491#if SQLITE_VERSION_NUMBER >= 3007000 474#if SQLITE_VERSION_NUMBER >= 3007000
492 if (result == SQLITE_BUSY) 475 if (result == SQLITE_BUSY)
476 {
477 GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING,
478 "sqlite",
479 _
480 ("Tried to close sqlite without finalizing all prepared statements.\n"));
481 stmt = sqlite3_next_stmt (plugin->dbh, NULL);
482 while (stmt != NULL)
493 { 483 {
494 GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING,
495 "sqlite",
496 _("Tried to close sqlite without finalizing all prepared statements.\n"));
497 stmt = sqlite3_next_stmt(plugin->dbh, NULL);
498 while (stmt != NULL)
499 {
500#if DEBUG_SQLITE 484#if DEBUG_SQLITE
501 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 485 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
502 "sqlite", "Closing statement %p\n", stmt); 486 "sqlite", "Closing statement %p\n", stmt);
503#endif 487#endif
504 result = sqlite3_finalize(stmt); 488 result = sqlite3_finalize (stmt);
505#if DEBUG_SQLITE 489#if DEBUG_SQLITE
506 if (result != SQLITE_OK) 490 if (result != SQLITE_OK)
507 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, 491 GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
508 "sqlite", 492 "sqlite",
509 "Failed to close statement %p: %d\n", stmt, result); 493 "Failed to close statement %p: %d\n", stmt, result);
510#endif 494#endif
511 stmt = sqlite3_next_stmt(plugin->dbh, NULL); 495 stmt = sqlite3_next_stmt (plugin->dbh, NULL);
512 }
513 result = sqlite3_close(plugin->dbh);
514 } 496 }
497 result = sqlite3_close (plugin->dbh);
498 }
515#endif 499#endif
516 if (SQLITE_OK != result) 500 if (SQLITE_OK != result)
517 LOG_SQLITE (plugin->dbh, 501 LOG_SQLITE (plugin->dbh, GNUNET_ERROR_TYPE_ERROR, "sqlite3_close");
518 GNUNET_ERROR_TYPE_ERROR,
519 "sqlite3_close");
520 502
521#if WINDOWS && !defined(__CYGWIN__) 503#if WINDOWS && !defined(__CYGWIN__)
522 if (0 != UNLINK (plugin->fn)) 504 if (0 != UNLINK (plugin->fn))
523 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, 505 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", plugin->fn);
524 "unlink",
525 plugin->fn);
526 GNUNET_free (plugin->fn); 506 GNUNET_free (plugin->fn);
527#endif 507#endif
528 GNUNET_free (plugin); 508 GNUNET_free (plugin);
@@ -533,4 +513,3 @@ libgnunet_plugin_datacache_sqlite_done (void *cls)
533 513
534 514
535/* end of plugin_datacache_sqlite.c */ 515/* end of plugin_datacache_sqlite.c */
536