- ttl is deprecated, don't warn
[oweals/gnunet.git] / src / datastore / plugin_datastore_sqlite.c
1  /*
2   * This file is part of GNUnet
3   * Copyright (C) 2009, 2011 Christian Grothoff (and other contributing authors)
4   *
5   * GNUnet is free software; you can redistribute it and/or modify
6   * it under the terms of the GNU General Public License as published
7   * by the Free Software Foundation; either version 3, or (at your
8   * option) any later version.
9   *
10   * GNUnet is distributed in the hope that it will be useful, but
11   * WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13   * General Public License for more details.
14   *
15   * You should have received a copy of the GNU General Public License
16   * along with GNUnet; see the file COPYING.  If not, write to the
17   * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18   * Boston, MA 02111-1307, USA.
19   */
20
21 /**
22  * @file datastore/plugin_datastore_sqlite.c
23  * @brief sqlite-based datastore backend
24  * @author Christian Grothoff
25  */
26
27 #include "platform.h"
28 #include "gnunet_datastore_plugin.h"
29 #include <sqlite3.h>
30
31
32 /**
33  * We allocate items on the stack at times.  To prevent a stack
34  * overflow, we impose a limit on the maximum size for the data per
35  * item.  64k should be enough.
36  */
37 #define MAX_ITEM_SIZE 65536
38
39 /**
40  * After how many ms "busy" should a DB operation fail for good?
41  * A low value makes sure that we are more responsive to requests
42  * (especially PUTs).  A high value guarantees a higher success
43  * rate (SELECTs in iterate can take several seconds despite LIMIT=1).
44  *
45  * The default value of 250ms should ensure that users do not experience
46  * huge latencies while at the same time allowing operations to succeed
47  * with reasonable probability.
48  */
49 #define BUSY_TIMEOUT_MS 250
50
51
52 /**
53  * Log an error message at log-level 'level' that indicates
54  * a failure of the command 'cmd' on file 'filename'
55  * with the message given by strerror(errno).
56  */
57 #define LOG_SQLITE(db, msg, level, cmd) do { GNUNET_log_from (level, "sqlite", _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, sqlite3_errmsg(db->dbh)); if (msg != NULL) GNUNET_asprintf(msg, _("`%s' failed at %s:%u with error: %s"), cmd, __FILE__, __LINE__, sqlite3_errmsg(db->dbh)); } while(0)
58
59
60
61 /**
62  * Context for all functions in this plugin.
63  */
64 struct Plugin
65 {
66   /**
67    * Our execution environment.
68    */
69   struct GNUNET_DATASTORE_PluginEnvironment *env;
70
71   /**
72    * Database filename.
73    */
74   char *fn;
75
76   /**
77    * Native SQLite database handle.
78    */
79   sqlite3 *dbh;
80
81   /**
82    * Precompiled SQL for deletion.
83    */
84   sqlite3_stmt *delRow;
85
86   /**
87    * Precompiled SQL for update.
88    */
89   sqlite3_stmt *updPrio;
90
91   /**
92    * Get maximum repl value in database.
93    */
94   sqlite3_stmt *maxRepl;
95
96   /**
97    * Precompiled SQL for replication decrement.
98    */
99   sqlite3_stmt *updRepl;
100
101   /**
102    * Precompiled SQL for replication selection.
103    */
104   sqlite3_stmt *selRepl;
105
106   /**
107    * Precompiled SQL for expiration selection.
108    */
109   sqlite3_stmt *selExpi;
110
111   /**
112    * Precompiled SQL for expiration selection.
113    */
114   sqlite3_stmt *selZeroAnon;
115
116   /**
117    * Precompiled SQL for insertion.
118    */
119   sqlite3_stmt *insertContent;
120
121   /**
122    * Should the database be dropped on shutdown?
123    */
124   int drop_on_shutdown;
125
126 };
127
128
129 /**
130  * @brief Prepare a SQL statement
131  *
132  * @param dbh handle to the database
133  * @param zSql SQL statement, UTF-8 encoded
134  * @param ppStmt set to the prepared statement
135  * @return 0 on success
136  */
137 static int
138 sq_prepare (sqlite3 *dbh,
139             const char *zSql,
140             sqlite3_stmt **ppStmt)
141 {
142   char *dummy;
143   int result;
144
145   result =
146       sqlite3_prepare_v2 (dbh, zSql, strlen (zSql), ppStmt,
147                           (const char **) &dummy);
148   GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite",
149                    "Prepared `%s' / %p: %d\n", zSql, *ppStmt, result);
150   return result;
151 }
152
153
154 /**
155  * Create our database indices.
156  *
157  * @param dbh handle to the database
158  */
159 static void
160 create_indices (sqlite3 * dbh)
161 {
162   /* create indices */
163   if ((SQLITE_OK !=
164        sqlite3_exec (dbh, "CREATE INDEX IF NOT EXISTS idx_hash ON gn090 (hash)",
165                      NULL, NULL, NULL)) ||
166       (SQLITE_OK !=
167        sqlite3_exec (dbh,
168                      "CREATE INDEX IF NOT EXISTS idx_hash_vhash ON gn090 (hash,vhash)",
169                      NULL, NULL, NULL)) ||
170       (SQLITE_OK !=
171        sqlite3_exec (dbh,
172                      "CREATE INDEX IF NOT EXISTS idx_expire_repl ON gn090 (expire ASC,repl DESC)",
173                      NULL, NULL, NULL)) ||
174       (SQLITE_OK !=
175        sqlite3_exec (dbh,
176                      "CREATE INDEX IF NOT EXISTS idx_comb ON gn090 (anonLevel ASC,expire ASC,prio,type,hash)",
177                      NULL, NULL, NULL)) ||
178       (SQLITE_OK !=
179        sqlite3_exec (dbh,
180                      "CREATE INDEX IF NOT EXISTS idx_anon_type_hash ON gn090 (anonLevel ASC,type,hash)",
181                      NULL, NULL, NULL)) ||
182       (SQLITE_OK !=
183        sqlite3_exec (dbh,
184                      "CREATE INDEX IF NOT EXISTS idx_expire ON gn090 (expire ASC)",
185                      NULL, NULL, NULL)) ||
186       (SQLITE_OK !=
187        sqlite3_exec (dbh,
188                      "CREATE INDEX IF NOT EXISTS idx_repl_rvalue ON gn090 (repl,rvalue)",
189                      NULL, NULL, NULL)) ||
190       (SQLITE_OK !=
191        sqlite3_exec (dbh,
192                      "CREATE INDEX IF NOT EXISTS idx_repl ON gn090 (repl DESC)",
193                      NULL, NULL, NULL)))
194     GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "sqlite",
195                      "Failed to create indices: %s\n", sqlite3_errmsg (dbh));
196 }
197
198
199 #if 0
200 #define CHECK(a) GNUNET_break(a)
201 #define ENULL NULL
202 #else
203 #define ENULL &e
204 #define ENULL_DEFINED 1
205 #define CHECK(a) if (! a) { GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "%s\n", e); sqlite3_free(e); }
206 #endif
207
208
209 /**
210  * Initialize the database connections and associated
211  * data structures (create tables and indices
212  * as needed as well).
213  *
214  * @param cfg our configuration
215  * @param plugin the plugin context (state for this module)
216  * @return #GNUNET_OK on success
217  */
218 static int
219 database_setup (const struct GNUNET_CONFIGURATION_Handle *cfg,
220                 struct Plugin *plugin)
221 {
222   sqlite3_stmt *stmt;
223   char *afsdir;
224
225 #if ENULL_DEFINED
226   char *e;
227 #endif
228
229   if (GNUNET_OK !=
230       GNUNET_CONFIGURATION_get_value_filename (cfg, "datastore-sqlite",
231                                                "FILENAME", &afsdir))
232   {
233     GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
234                                "datastore-sqlite", "FILENAME");
235     return GNUNET_SYSERR;
236   }
237   if (GNUNET_OK != GNUNET_DISK_file_test (afsdir))
238   {
239     if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (afsdir))
240     {
241       GNUNET_break (0);
242       GNUNET_free (afsdir);
243       return GNUNET_SYSERR;
244     }
245     /* database is new or got deleted, reset payload to zero! */
246     plugin->env->duc (plugin->env->cls, 0);
247   }
248   /* afsdir should be UTF-8-encoded. If it isn't, it's a bug */
249   plugin->fn = afsdir;
250
251   /* Open database and precompile statements */
252   if (sqlite3_open (plugin->fn, &plugin->dbh) != SQLITE_OK)
253   {
254     GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "sqlite",
255                      _("Unable to initialize SQLite: %s.\n"),
256                      sqlite3_errmsg (plugin->dbh));
257     return GNUNET_SYSERR;
258   }
259   CHECK (SQLITE_OK ==
260          sqlite3_exec (plugin->dbh, "PRAGMA temp_store=MEMORY", NULL, NULL,
261                        ENULL));
262   CHECK (SQLITE_OK ==
263          sqlite3_exec (plugin->dbh, "PRAGMA synchronous=OFF", NULL, NULL,
264                        ENULL));
265   CHECK (SQLITE_OK ==
266          sqlite3_exec (plugin->dbh, "PRAGMA legacy_file_format=OFF", NULL, NULL,
267                        ENULL));
268   CHECK (SQLITE_OK ==
269          sqlite3_exec (plugin->dbh, "PRAGMA auto_vacuum=INCREMENTAL", NULL,
270                        NULL, ENULL));
271   CHECK (SQLITE_OK ==
272          sqlite3_exec (plugin->dbh, "PRAGMA locking_mode=EXCLUSIVE", NULL, NULL,
273                        ENULL));
274   CHECK (SQLITE_OK ==
275          sqlite3_exec (plugin->dbh, "PRAGMA page_size=4092", NULL, NULL,
276                        ENULL));
277
278   CHECK (SQLITE_OK == sqlite3_busy_timeout (plugin->dbh, BUSY_TIMEOUT_MS));
279
280
281   /* We have to do it here, because otherwise precompiling SQL might fail */
282   CHECK (SQLITE_OK ==
283          sq_prepare (plugin->dbh,
284                      "SELECT 1 FROM sqlite_master WHERE tbl_name = 'gn090'",
285                      &stmt));
286   if ((sqlite3_step (stmt) == SQLITE_DONE) &&
287       (sqlite3_exec
288        (plugin->dbh,
289         "CREATE TABLE gn090 (" "  repl INT4 NOT NULL DEFAULT 0,"
290         "  type INT4 NOT NULL DEFAULT 0," "  prio INT4 NOT NULL DEFAULT 0,"
291         "  anonLevel INT4 NOT NULL DEFAULT 0,"
292         "  expire INT8 NOT NULL DEFAULT 0," "  rvalue INT8 NOT NULL,"
293         "  hash TEXT NOT NULL DEFAULT ''," "  vhash TEXT NOT NULL DEFAULT '',"
294         "  value BLOB NOT NULL DEFAULT '')", NULL, NULL, NULL) != SQLITE_OK))
295   {
296     LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR, "sqlite3_exec");
297     sqlite3_finalize (stmt);
298     return GNUNET_SYSERR;
299   }
300   sqlite3_finalize (stmt);
301   create_indices (plugin->dbh);
302
303   if ((sq_prepare
304        (plugin->dbh,
305         "UPDATE gn090 "
306         "SET prio = prio + ?, expire = MAX(expire,?) WHERE _ROWID_ = ?",
307         &plugin->updPrio) != SQLITE_OK) ||
308       (sq_prepare
309        (plugin->dbh,
310         "UPDATE gn090 " "SET repl = MAX (0, repl - 1) WHERE _ROWID_ = ?",
311         &plugin->updRepl) != SQLITE_OK) ||
312       (sq_prepare
313        (plugin->dbh,
314         "SELECT type,prio,anonLevel,expire,hash,value,_ROWID_ " "FROM gn090 "
315 #if SQLITE_VERSION_NUMBER >= 3007000
316         "INDEXED BY idx_repl_rvalue "
317 #endif
318         "WHERE repl=?2 AND " " (rvalue>=?1 OR "
319         "  NOT EXISTS (SELECT 1 FROM gn090 "
320 #if SQLITE_VERSION_NUMBER >= 3007000
321         "INDEXED BY idx_repl_rvalue "
322 #endif
323         "WHERE repl=?2 AND rvalue>=?1 LIMIT 1) ) "
324         "ORDER BY rvalue ASC LIMIT 1", &plugin->selRepl) != SQLITE_OK) ||
325       (sq_prepare (plugin->dbh, "SELECT MAX(repl) FROM gn090"
326 #if SQLITE_VERSION_NUMBER >= 3007000
327                    " INDEXED BY idx_repl_rvalue"
328 #endif
329                    "", &plugin->maxRepl) != SQLITE_OK) ||
330       (sq_prepare
331        (plugin->dbh,
332         "SELECT type,prio,anonLevel,expire,hash,value,_ROWID_ " "FROM gn090 "
333 #if SQLITE_VERSION_NUMBER >= 3007000
334         "INDEXED BY idx_expire "
335 #endif
336         "WHERE NOT EXISTS (SELECT 1 FROM gn090 WHERE expire < ?1 LIMIT 1) OR (expire < ?1) "
337         "ORDER BY expire ASC LIMIT 1", &plugin->selExpi) != SQLITE_OK) ||
338       (sq_prepare
339        (plugin->dbh,
340         "SELECT type,prio,anonLevel,expire,hash,value,_ROWID_ " "FROM gn090 "
341 #if SQLITE_VERSION_NUMBER >= 3007000
342         "INDEXED BY idx_anon_type_hash "
343 #endif
344         "WHERE (anonLevel = 0 AND type=?1) "
345         "ORDER BY hash DESC LIMIT 1 OFFSET ?2",
346         &plugin->selZeroAnon) != SQLITE_OK) ||
347       (sq_prepare
348        (plugin->dbh,
349         "INSERT INTO gn090 (repl, type, prio, anonLevel, expire, rvalue, hash, vhash, value) "
350         "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
351         &plugin->insertContent) != SQLITE_OK) ||
352       (sq_prepare
353        (plugin->dbh, "DELETE FROM gn090 WHERE _ROWID_ = ?",
354         &plugin->delRow) != SQLITE_OK))
355   {
356     LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR, "precompiling");
357     return GNUNET_SYSERR;
358   }
359
360   return GNUNET_OK;
361 }
362
363
364 /**
365  * Shutdown database connection and associate data
366  * structures.
367  *
368  * @param plugin the plugin context (state for this module)
369  */
370 static void
371 database_shutdown (struct Plugin *plugin)
372 {
373   int result;
374
375 #if SQLITE_VERSION_NUMBER >= 3007000
376   sqlite3_stmt *stmt;
377 #endif
378
379   if (plugin->delRow != NULL)
380     sqlite3_finalize (plugin->delRow);
381   if (plugin->updPrio != NULL)
382     sqlite3_finalize (plugin->updPrio);
383   if (plugin->updRepl != NULL)
384     sqlite3_finalize (plugin->updRepl);
385   if (plugin->selRepl != NULL)
386     sqlite3_finalize (plugin->selRepl);
387   if (plugin->maxRepl != NULL)
388     sqlite3_finalize (plugin->maxRepl);
389   if (plugin->selExpi != NULL)
390     sqlite3_finalize (plugin->selExpi);
391   if (plugin->selZeroAnon != NULL)
392     sqlite3_finalize (plugin->selZeroAnon);
393   if (plugin->insertContent != NULL)
394     sqlite3_finalize (plugin->insertContent);
395   result = sqlite3_close (plugin->dbh);
396 #if SQLITE_VERSION_NUMBER >= 3007000
397   if (result == SQLITE_BUSY)
398   {
399     GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, "sqlite",
400                      _
401                      ("Tried to close sqlite without finalizing all prepared statements.\n"));
402     stmt = sqlite3_next_stmt (plugin->dbh, NULL);
403     while (stmt != NULL)
404     {
405       GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite",
406                        "Closing statement %p\n", stmt);
407       result = sqlite3_finalize (stmt);
408       if (result != SQLITE_OK)
409         GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, "sqlite",
410                          "Failed to close statement %p: %d\n", stmt, result);
411       stmt = sqlite3_next_stmt (plugin->dbh, NULL);
412     }
413     result = sqlite3_close (plugin->dbh);
414   }
415 #endif
416   if (SQLITE_OK != result)
417     LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR, "sqlite3_close");
418
419   GNUNET_free_non_null (plugin->fn);
420 }
421
422
423 /**
424  * Delete the database entry with the given
425  * row identifier.
426  *
427  * @param plugin the plugin context (state for this module)
428  * @param rid the ID of the row to delete
429  */
430 static int
431 delete_by_rowid (struct Plugin *plugin,
432                  unsigned long long rid)
433 {
434   if (SQLITE_OK != sqlite3_bind_int64 (plugin->delRow, 1, rid))
435   {
436     LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
437                 "sqlite3_bind_XXXX");
438     if (SQLITE_OK != sqlite3_reset (plugin->delRow))
439       LOG_SQLITE (plugin, NULL,
440                   GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
441                   "sqlite3_reset");
442     return GNUNET_SYSERR;
443   }
444   if (SQLITE_DONE != sqlite3_step (plugin->delRow))
445   {
446     LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
447                 "sqlite3_step");
448     if (SQLITE_OK != sqlite3_reset (plugin->delRow))
449       LOG_SQLITE (plugin, NULL,
450                   GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
451                   "sqlite3_reset");
452     return GNUNET_SYSERR;
453   }
454   if (SQLITE_OK != sqlite3_reset (plugin->delRow))
455     LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
456                 "sqlite3_reset");
457   return GNUNET_OK;
458 }
459
460
461 /**
462  * Store an item in the datastore.
463  *
464  * @param cls closure
465  * @param key key for the item
466  * @param size number of bytes in @a data
467  * @param data content stored
468  * @param type type of the content
469  * @param priority priority of the content
470  * @param anonymity anonymity-level for the content
471  * @param replication replication-level for the content
472  * @param expiration expiration time for the content
473  * @param cont continuation called with success or failure status
474  * @param cont_cls continuation closure
475  */
476 static void
477 sqlite_plugin_put (void *cls,
478                    const struct GNUNET_HashCode *key,
479                    uint32_t size,
480                    const void *data,
481                    enum GNUNET_BLOCK_Type type,
482                    uint32_t priority,
483                    uint32_t anonymity,
484                    uint32_t replication,
485                    struct GNUNET_TIME_Absolute expiration,
486                    PluginPutCont cont,
487                    void *cont_cls)
488 {
489   struct Plugin *plugin = cls;
490   int n;
491   int ret;
492   sqlite3_stmt *stmt;
493   struct GNUNET_HashCode vhash;
494   uint64_t rvalue;
495   char *msg = NULL;
496
497   if (size > MAX_ITEM_SIZE)
498   {
499     cont (cont_cls, key, size, GNUNET_SYSERR, _("Data too large"));
500     return;
501   }
502   GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite",
503                    "Storing in database block with type %u/key `%s'/priority %u/expiration in %s (%s).\n",
504                    type,
505                    GNUNET_h2s (key),
506                    priority,
507                    GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_remaining (expiration),
508                                                            GNUNET_YES),
509                    GNUNET_STRINGS_absolute_time_to_string (expiration));
510   GNUNET_CRYPTO_hash (data, size, &vhash);
511   stmt = plugin->insertContent;
512   rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX);
513   if ((SQLITE_OK != sqlite3_bind_int (stmt, 1, replication)) ||
514       (SQLITE_OK != sqlite3_bind_int (stmt, 2, type)) ||
515       (SQLITE_OK != sqlite3_bind_int (stmt, 3, priority)) ||
516       (SQLITE_OK != sqlite3_bind_int (stmt, 4, anonymity)) ||
517       (SQLITE_OK != sqlite3_bind_int64 (stmt, 5, expiration.abs_value_us)) ||
518       (SQLITE_OK != sqlite3_bind_int64 (stmt, 6, rvalue)) ||
519       (SQLITE_OK !=
520        sqlite3_bind_blob (stmt, 7, key, sizeof (struct GNUNET_HashCode),
521                           SQLITE_TRANSIENT)) ||
522       (SQLITE_OK !=
523        sqlite3_bind_blob (stmt, 8, &vhash, sizeof (struct GNUNET_HashCode),
524                           SQLITE_TRANSIENT)) ||
525       (SQLITE_OK != sqlite3_bind_blob (stmt, 9, data, size, SQLITE_TRANSIENT)))
526   {
527     LOG_SQLITE (plugin, &msg, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
528                 "sqlite3_bind_XXXX");
529     if (SQLITE_OK != sqlite3_reset (stmt))
530       LOG_SQLITE (plugin, NULL,
531                   GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
532                   "sqlite3_reset");
533     cont (cont_cls, key, size, GNUNET_SYSERR, msg);
534     GNUNET_free_non_null(msg);
535     return;
536   }
537   n = sqlite3_step (stmt);
538   switch (n)
539   {
540   case SQLITE_DONE:
541     plugin->env->duc (plugin->env->cls, size + GNUNET_DATASTORE_ENTRY_OVERHEAD);
542     GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite",
543                      "Stored new entry (%u bytes)\n",
544                      size + GNUNET_DATASTORE_ENTRY_OVERHEAD);
545     ret = GNUNET_OK;
546     break;
547   case SQLITE_BUSY:
548     GNUNET_break (0);
549     LOG_SQLITE (plugin, &msg, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
550                 "sqlite3_step");
551     ret = GNUNET_SYSERR;
552     break;
553   default:
554     LOG_SQLITE (plugin, &msg, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
555                 "sqlite3_step");
556     if (SQLITE_OK != sqlite3_reset (stmt))
557       LOG_SQLITE (plugin, NULL,
558                   GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
559                   "sqlite3_reset");
560     database_shutdown (plugin);
561     database_setup (plugin->env->cfg, plugin);
562     cont (cont_cls, key, size, GNUNET_SYSERR, msg);
563     GNUNET_free_non_null(msg);
564     return;
565   }
566   if (SQLITE_OK != sqlite3_reset (stmt))
567     LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
568                 "sqlite3_reset");
569   cont (cont_cls, key, size, ret, msg);
570   GNUNET_free_non_null(msg);
571 }
572
573
574 /**
575  * Update the priority for a particular key in the datastore.  If
576  * the expiration time in value is different than the time found in
577  * the datastore, the higher value should be kept.  For the
578  * anonymity level, the lower value is to be used.  The specified
579  * priority should be added to the existing priority, ignoring the
580  * priority in value.
581  *
582  * Note that it is possible for multiple values to match this put.
583  * In that case, all of the respective values are updated.
584  *
585  * @param cls the plugin context (state for this module)
586  * @param uid unique identifier of the datum
587  * @param delta by how much should the priority
588  *     change?  If priority + delta < 0 the
589  *     priority should be set to 0 (never go
590  *     negative).
591  * @param expire new expiration time should be the
592  *     MAX of any existing expiration time and
593  *     this value
594  * @param cont continuation called with success or failure status
595  * @param cons_cls continuation closure
596  */
597 static void
598 sqlite_plugin_update (void *cls,
599                       uint64_t uid,
600                       int delta,
601                       struct GNUNET_TIME_Absolute expire,
602                       PluginUpdateCont cont,
603                       void *cont_cls)
604 {
605   struct Plugin *plugin = cls;
606   int n;
607   char *msg = NULL;
608
609   if ((SQLITE_OK != sqlite3_bind_int (plugin->updPrio, 1, delta)) ||
610       (SQLITE_OK != sqlite3_bind_int64 (plugin->updPrio, 2, expire.abs_value_us))
611       || (SQLITE_OK != sqlite3_bind_int64 (plugin->updPrio, 3, uid)))
612   {
613     LOG_SQLITE (plugin, &msg, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
614                 "sqlite3_bind_XXXX");
615     if (SQLITE_OK != sqlite3_reset (plugin->updPrio))
616       LOG_SQLITE (plugin, NULL,
617                   GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
618                   "sqlite3_reset");
619     cont (cont_cls, GNUNET_SYSERR, msg);
620     GNUNET_free_non_null(msg);
621     return;
622   }
623   n = sqlite3_step (plugin->updPrio);
624   if (SQLITE_OK != sqlite3_reset (plugin->updPrio))
625     LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
626                 "sqlite3_reset");
627   switch (n)
628   {
629   case SQLITE_DONE:
630     GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "Block updated\n");
631     cont (cont_cls, GNUNET_OK, NULL);
632     return;
633   case SQLITE_BUSY:
634     LOG_SQLITE (plugin, &msg,
635                 GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK,
636                 "sqlite3_step");
637     cont (cont_cls, GNUNET_NO, msg);
638     GNUNET_free_non_null(msg);
639     return;
640   default:
641     LOG_SQLITE (plugin, &msg, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
642                 "sqlite3_step");
643     cont (cont_cls, GNUNET_SYSERR, msg);
644     GNUNET_free_non_null(msg);
645     return;
646   }
647 }
648
649
650 /**
651  * Execute statement that gets a row and call the callback
652  * with the result.  Resets the statement afterwards.
653  *
654  * @param plugin the plugin
655  * @param stmt the statement
656  * @param proc processor to call
657  * @param proc_cls closure for @a proc
658  */
659 static void
660 execute_get (struct Plugin *plugin,
661              sqlite3_stmt *stmt,
662              PluginDatumProcessor proc,
663              void *proc_cls)
664 {
665   int n;
666   struct GNUNET_TIME_Absolute expiration;
667   unsigned long long rowid;
668   unsigned int size;
669   int ret;
670
671   n = sqlite3_step (stmt);
672   switch (n)
673   {
674   case SQLITE_ROW:
675     size = sqlite3_column_bytes (stmt, 5);
676     rowid = sqlite3_column_int64 (stmt, 6);
677     if (sqlite3_column_bytes (stmt, 4) != sizeof (struct GNUNET_HashCode))
678     {
679       GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, "sqlite",
680                        _("Invalid data in database.  Trying to fix (by deletion).\n"));
681       if (SQLITE_OK != sqlite3_reset (stmt))
682         LOG_SQLITE (plugin, NULL,
683                     GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
684                     "sqlite3_reset");
685       if (GNUNET_OK == delete_by_rowid (plugin, rowid))
686         plugin->env->duc (plugin->env->cls,
687                           -(size + GNUNET_DATASTORE_ENTRY_OVERHEAD));
688       break;
689     }
690     expiration.abs_value_us = sqlite3_column_int64 (stmt, 3);
691     GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite",
692                      "Found reply in database with expiration %s\n",
693                      GNUNET_STRINGS_absolute_time_to_string (expiration));
694     ret = proc (proc_cls, sqlite3_column_blob (stmt, 4) /* key */ ,
695                 size, sqlite3_column_blob (stmt, 5) /* data */ ,
696                 sqlite3_column_int (stmt, 0) /* type */ ,
697                 sqlite3_column_int (stmt, 1) /* priority */ ,
698                 sqlite3_column_int (stmt, 2) /* anonymity */ ,
699                 expiration, rowid);
700     if (SQLITE_OK != sqlite3_reset (stmt))
701       LOG_SQLITE (plugin, NULL,
702                   GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
703                   "sqlite3_reset");
704     if ((GNUNET_NO == ret) && (GNUNET_OK == delete_by_rowid (plugin, rowid)))
705       plugin->env->duc (plugin->env->cls,
706                         -(size + GNUNET_DATASTORE_ENTRY_OVERHEAD));
707     return;
708   case SQLITE_DONE:
709     /* database must be empty */
710     if (SQLITE_OK != sqlite3_reset (stmt))
711       LOG_SQLITE (plugin, NULL,
712                   GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
713                   "sqlite3_reset");
714     break;
715   case SQLITE_BUSY:
716   case SQLITE_ERROR:
717   case SQLITE_MISUSE:
718   default:
719     LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
720                 "sqlite3_step");
721     if (SQLITE_OK != sqlite3_reset (stmt))
722       LOG_SQLITE (plugin, NULL,
723                   GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
724                   "sqlite3_reset");
725     GNUNET_break (0);
726     database_shutdown (plugin);
727     database_setup (plugin->env->cfg, plugin);
728     break;
729   }
730   if (SQLITE_OK != sqlite3_reset (stmt))
731     LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
732                 "sqlite3_reset");
733   proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
734 }
735
736
737 /**
738  * Select a subset of the items in the datastore and call
739  * the given processor for the item.
740  *
741  * @param cls our plugin context
742  * @param offset offset of the result (modulo num-results);
743  *               specific ordering does not matter for the offset
744  * @param type entries of which type should be considered?
745  *        Use 0 for any type.
746  * @param proc function to call on each matching value;
747  *        will be called once with a NULL value at the end
748  * @param proc_cls closure for @a proc
749  */
750 static void
751 sqlite_plugin_get_zero_anonymity (void *cls, uint64_t offset,
752                                   enum GNUNET_BLOCK_Type type,
753                                   PluginDatumProcessor proc, void *proc_cls)
754 {
755   struct Plugin *plugin = cls;
756   sqlite3_stmt *stmt;
757
758   GNUNET_assert (type != GNUNET_BLOCK_TYPE_ANY);
759   stmt = plugin->selZeroAnon;
760   if ((SQLITE_OK != sqlite3_bind_int (stmt, 1, type)) ||
761       (SQLITE_OK != sqlite3_bind_int64 (stmt, 2, offset)))
762   {
763     LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
764                 "sqlite3_bind_XXXX");
765     if (SQLITE_OK != sqlite3_reset (stmt))
766       LOG_SQLITE (plugin, NULL,
767                   GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
768                   "sqlite3_reset");
769     proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
770     return;
771   }
772   execute_get (plugin, stmt, proc, proc_cls);
773 }
774
775
776 /**
777  * Get results for a particular key in the datastore.
778  *
779  * @param cls closure
780  * @param offset offset (mod count).
781  * @param key key to match, never NULL
782  * @param vhash hash of the value, maybe NULL (to
783  *        match all values that have the right key).
784  *        Note that for DBlocks there is no difference
785  *        betwen key and vhash, but for other blocks
786  *        there may be!
787  * @param type entries of which type are relevant?
788  *     Use 0 for any type.
789  * @param proc function to call on each matching value;
790  *        will be called once with a NULL value at the end
791  * @param proc_cls closure for @a proc
792  */
793 static void
794 sqlite_plugin_get_key (void *cls,
795                        uint64_t offset,
796                        const struct GNUNET_HashCode *key,
797                        const struct GNUNET_HashCode *vhash,
798                        enum GNUNET_BLOCK_Type type,
799                        PluginDatumProcessor proc,
800                        void *proc_cls)
801 {
802   struct Plugin *plugin = cls;
803   int ret;
804   int total;
805   int limit_off;
806   unsigned int sqoff;
807   sqlite3_stmt *stmt;
808   char scratch[256];
809
810   GNUNET_assert (proc != NULL);
811   GNUNET_assert (key != NULL);
812   GNUNET_snprintf (scratch, sizeof (scratch),
813                    "SELECT count(*) FROM gn090 WHERE hash=?%s%s",
814                    vhash == NULL ? "" : " AND vhash=?",
815                    type == 0 ? "" : " AND type=?");
816   if (sq_prepare (plugin->dbh, scratch, &stmt) != SQLITE_OK)
817   {
818     LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
819                 "sqlite_prepare");
820     proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
821     return;
822   }
823   sqoff = 1;
824   ret =
825       sqlite3_bind_blob (stmt, sqoff++, key, sizeof (struct GNUNET_HashCode),
826                          SQLITE_TRANSIENT);
827   if ((vhash != NULL) && (ret == SQLITE_OK))
828     ret =
829         sqlite3_bind_blob (stmt, sqoff++, vhash, sizeof (struct GNUNET_HashCode),
830                            SQLITE_TRANSIENT);
831   if ((type != 0) && (ret == SQLITE_OK))
832     ret = sqlite3_bind_int (stmt, sqoff++, type);
833   if (SQLITE_OK != ret)
834   {
835     LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR, "sqlite_bind");
836     sqlite3_finalize (stmt);
837     proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
838     return;
839   }
840   ret = sqlite3_step (stmt);
841   if (ret != SQLITE_ROW)
842   {
843     LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
844                 "sqlite_step");
845     sqlite3_finalize (stmt);
846     proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
847     return;
848   }
849   total = sqlite3_column_int (stmt, 0);
850   sqlite3_finalize (stmt);
851   if (0 == total)
852   {
853     proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
854     return;
855   }
856   limit_off = (int) (offset % total);
857   if (limit_off < 0)
858     limit_off += total;
859   GNUNET_snprintf (scratch, sizeof (scratch),
860                    "SELECT type, prio, anonLevel, expire, hash, value, _ROWID_ "
861                    "FROM gn090 WHERE hash=?%s%s "
862                    "ORDER BY _ROWID_ ASC LIMIT 1 OFFSET ?",
863                    vhash == NULL ? "" : " AND vhash=?",
864                    type == 0 ? "" : " AND type=?");
865   if (sq_prepare (plugin->dbh, scratch, &stmt) != SQLITE_OK)
866   {
867     LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
868                 "sqlite_prepare");
869     proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
870     return;
871   }
872   sqoff = 1;
873   ret = sqlite3_bind_blob (stmt, sqoff++, key,
874                            sizeof (struct GNUNET_HashCode),
875                            SQLITE_TRANSIENT);
876   if ((vhash != NULL) && (ret == SQLITE_OK))
877     ret = sqlite3_bind_blob (stmt, sqoff++, vhash,
878                              sizeof (struct GNUNET_HashCode),
879                              SQLITE_TRANSIENT);
880   if ((type != 0) && (ret == SQLITE_OK))
881     ret = sqlite3_bind_int (stmt, sqoff++, type);
882   if (ret == SQLITE_OK)
883     ret = sqlite3_bind_int64 (stmt, sqoff++, limit_off);
884   if (ret != SQLITE_OK)
885   {
886     LOG_SQLITE (plugin, NULL,
887                 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
888                 "sqlite_bind");
889     proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
890     return;
891   }
892   execute_get (plugin, stmt, proc, proc_cls);
893   sqlite3_finalize (stmt);
894 }
895
896
897 /**
898  * Context for #repl_proc() function.
899  */
900 struct ReplCtx
901 {
902
903   /**
904    * Function to call for the result (or the NULL).
905    */
906   PluginDatumProcessor proc;
907
908   /**
909    * Closure for @e proc.
910    */
911   void *proc_cls;
912
913   /**
914    * UID to use.
915    */
916   uint64_t uid;
917
918   /**
919    * Yes if UID was set.
920    */
921   int have_uid;
922 };
923
924
925 /**
926  * Wrapper for the processor for #sqlite_plugin_get_replication().
927  * Decrements the replication counter and calls the original
928  * processor.
929  *
930  * @param cls closure
931  * @param key key for the content
932  * @param size number of bytes in @a data
933  * @param data content stored
934  * @param type type of the content
935  * @param priority priority of the content
936  * @param anonymity anonymity-level for the content
937  * @param expiration expiration time for the content
938  * @param uid unique identifier for the datum;
939  *        maybe 0 if no unique identifier is available
940  * @return #GNUNET_OK for normal return,
941  *         #GNUNET_NO to delete the item
942  */
943 static int
944 repl_proc (void *cls,
945            const struct GNUNET_HashCode *key,
946            uint32_t size,
947            const void *data,
948            enum GNUNET_BLOCK_Type type,
949            uint32_t priority,
950            uint32_t anonymity,
951            struct GNUNET_TIME_Absolute expiration,
952            uint64_t uid)
953 {
954   struct ReplCtx *rc = cls;
955   int ret;
956
957   ret = rc->proc (rc->proc_cls,
958                   key,
959                   size, data,
960                   type,
961                   priority,
962                   anonymity,
963                   expiration, uid);
964   if (NULL != key)
965   {
966     rc->uid = uid;
967     rc->have_uid = GNUNET_YES;
968   }
969   return ret;
970 }
971
972
973 /**
974  * Get a random item for replication.  Returns a single random item
975  * from those with the highest replication counters.  The item's
976  * replication counter is decremented by one IF it was positive before.
977  * Call @a proc with all values ZERO or NULL if the datastore is empty.
978  *
979  * @param cls closure
980  * @param proc function to call the value (once only).
981  * @param proc_cls closure for @a proc
982  */
983 static void
984 sqlite_plugin_get_replication (void *cls, PluginDatumProcessor proc,
985                                void *proc_cls)
986 {
987   struct Plugin *plugin = cls;
988   struct ReplCtx rc;
989   uint64_t rvalue;
990   uint32_t repl;
991   sqlite3_stmt *stmt;
992
993   GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite",
994                    "Getting random block based on replication order.\n");
995   rc.have_uid = GNUNET_NO;
996   rc.proc = proc;
997   rc.proc_cls = proc_cls;
998   stmt = plugin->maxRepl;
999   if (SQLITE_ROW != sqlite3_step (stmt))
1000   {
1001     if (SQLITE_OK != sqlite3_reset (stmt))
1002       LOG_SQLITE (plugin, NULL,
1003                   GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
1004                   "sqlite3_reset");
1005     /* DB empty */
1006     proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
1007     return;
1008   }
1009   repl = sqlite3_column_int (stmt, 0);
1010   if (SQLITE_OK != sqlite3_reset (stmt))
1011     LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
1012                 "sqlite3_reset");
1013   stmt = plugin->selRepl;
1014   rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX);
1015   if (SQLITE_OK != sqlite3_bind_int64 (stmt, 1, rvalue))
1016   {
1017     LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
1018                 "sqlite3_bind_XXXX");
1019     if (SQLITE_OK != sqlite3_reset (stmt))
1020       LOG_SQLITE (plugin, NULL,
1021                   GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
1022                   "sqlite3_reset");
1023     proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
1024     return;
1025   }
1026   if (SQLITE_OK != sqlite3_bind_int (stmt, 2, repl))
1027   {
1028     LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
1029                 "sqlite3_bind_XXXX");
1030     if (SQLITE_OK != sqlite3_reset (stmt))
1031       LOG_SQLITE (plugin, NULL,
1032                   GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
1033                   "sqlite3_reset");
1034     proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
1035     return;
1036   }
1037   execute_get (plugin, stmt, &repl_proc, &rc);
1038   if (GNUNET_YES == rc.have_uid)
1039   {
1040     if (SQLITE_OK != sqlite3_bind_int64 (plugin->updRepl, 1, rc.uid))
1041     {
1042       LOG_SQLITE (plugin, NULL,
1043                   GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
1044                   "sqlite3_bind_XXXX");
1045       if (SQLITE_OK != sqlite3_reset (plugin->updRepl))
1046         LOG_SQLITE (plugin, NULL,
1047                     GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
1048                     "sqlite3_reset");
1049       return;
1050     }
1051     if (SQLITE_DONE != sqlite3_step (plugin->updRepl))
1052       LOG_SQLITE (plugin, NULL,
1053                   GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
1054                   "sqlite3_step");
1055     if (SQLITE_OK != sqlite3_reset (plugin->updRepl))
1056       LOG_SQLITE (plugin, NULL,
1057                   GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
1058                   "sqlite3_reset");
1059   }
1060 }
1061
1062
1063 /**
1064  * Get a random item that has expired or has low priority.
1065  * Call @a proc with all values ZERO or NULL if the datastore is empty.
1066  *
1067  * @param cls closure
1068  * @param proc function to call the value (once only).
1069  * @param proc_cls closure for @a proc
1070  */
1071 static void
1072 sqlite_plugin_get_expiration (void *cls, PluginDatumProcessor proc,
1073                               void *proc_cls)
1074 {
1075   struct Plugin *plugin = cls;
1076   sqlite3_stmt *stmt;
1077   struct GNUNET_TIME_Absolute now;
1078
1079   GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite",
1080                    "Getting random block based on expiration and priority order.\n");
1081   now = GNUNET_TIME_absolute_get ();
1082   stmt = plugin->selExpi;
1083   if (SQLITE_OK != sqlite3_bind_int64 (stmt, 1, now.abs_value_us))
1084   {
1085     LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
1086                 "sqlite3_bind_XXXX");
1087     if (SQLITE_OK != sqlite3_reset (stmt))
1088       LOG_SQLITE (plugin, NULL,
1089                   GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
1090                   "sqlite3_reset");
1091     proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
1092     return;
1093   }
1094   execute_get (plugin, stmt, proc, proc_cls);
1095 }
1096
1097
1098 /**
1099  * Get all of the keys in the datastore.
1100  *
1101  * @param cls closure
1102  * @param proc function to call on each key
1103  * @param proc_cls closure for @a proc
1104  */
1105 static void
1106 sqlite_plugin_get_keys (void *cls,
1107                         PluginKeyProcessor proc,
1108                         void *proc_cls)
1109 {
1110   struct Plugin *plugin = cls;
1111   const struct GNUNET_HashCode *key;
1112   sqlite3_stmt *stmt;
1113   int ret;
1114
1115   GNUNET_assert (proc != NULL);
1116   if (sq_prepare (plugin->dbh, "SELECT hash FROM gn090", &stmt) != SQLITE_OK)
1117   {
1118     LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
1119                 "sqlite_prepare");
1120     proc (proc_cls, NULL, 0);
1121     return;
1122   }
1123   while (SQLITE_ROW == (ret = sqlite3_step (stmt)))
1124   {
1125     key = sqlite3_column_blob (stmt, 0);
1126     if (sizeof (struct GNUNET_HashCode) == sqlite3_column_bytes (stmt, 0))
1127       proc (proc_cls, key, 1);
1128     else
1129       GNUNET_break (0);
1130   }
1131   if (SQLITE_DONE != ret)
1132     LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR, "sqlite_step");
1133   sqlite3_finalize (stmt);
1134   proc (proc_cls, NULL, 0);
1135 }
1136
1137
1138 /**
1139  * Drop database.
1140  *
1141  * @param cls our plugin context
1142  */
1143 static void
1144 sqlite_plugin_drop (void *cls)
1145 {
1146   struct Plugin *plugin = cls;
1147
1148   plugin->drop_on_shutdown = GNUNET_YES;
1149 }
1150
1151
1152 /**
1153  * Get an estimate of how much space the database is
1154  * currently using.
1155  *
1156  * @param cls the `struct Plugin`
1157  * @return the size of the database on disk (estimate)
1158  */
1159 static void
1160 sqlite_plugin_estimate_size (void *cls, unsigned long long *estimate)
1161 {
1162   struct Plugin *plugin = cls;
1163   sqlite3_stmt *stmt;
1164   uint64_t pages;
1165   uint64_t page_size;
1166
1167 #if ENULL_DEFINED
1168   char *e;
1169 #endif
1170
1171   if (NULL == estimate)
1172     return;
1173   if (SQLITE_VERSION_NUMBER < 3006000)
1174   {
1175     GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, "datastore-sqlite",
1176                      _
1177                      ("sqlite version to old to determine size, assuming zero\n"));
1178     *estimate = 0;
1179     return;
1180   }
1181   CHECK (SQLITE_OK == sqlite3_exec (plugin->dbh, "VACUUM", NULL, NULL, ENULL));
1182   CHECK (SQLITE_OK ==
1183          sqlite3_exec (plugin->dbh, "PRAGMA auto_vacuum=INCREMENTAL", NULL,
1184                        NULL, ENULL));
1185   CHECK (SQLITE_OK == sq_prepare (plugin->dbh, "PRAGMA page_count", &stmt));
1186   if (SQLITE_ROW == sqlite3_step (stmt))
1187     pages = sqlite3_column_int64 (stmt, 0);
1188   else
1189     pages = 0;
1190   sqlite3_finalize (stmt);
1191   CHECK (SQLITE_OK == sq_prepare (plugin->dbh, "PRAGMA page_size", &stmt));
1192   CHECK (SQLITE_ROW == sqlite3_step (stmt));
1193   page_size = sqlite3_column_int64 (stmt, 0);
1194   sqlite3_finalize (stmt);
1195   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1196               _
1197               ("Using sqlite page utilization to estimate payload (%llu pages of size %llu bytes)\n"),
1198               (unsigned long long) pages, (unsigned long long) page_size);
1199   *estimate = pages * page_size;
1200 }
1201
1202
1203 /**
1204  * Entry point for the plugin.
1205  *
1206  * @param cls the `struct GNUNET_DATASTORE_PluginEnvironment *`
1207  * @return NULL on error, othrewise the plugin context
1208  */
1209 void *
1210 libgnunet_plugin_datastore_sqlite_init (void *cls)
1211 {
1212   static struct Plugin plugin;
1213   struct GNUNET_DATASTORE_PluginEnvironment *env = cls;
1214   struct GNUNET_DATASTORE_PluginFunctions *api;
1215
1216   if (plugin.env != NULL)
1217     return NULL;                /* can only initialize once! */
1218   memset (&plugin, 0, sizeof (struct Plugin));
1219   plugin.env = env;
1220   if (GNUNET_OK != database_setup (env->cfg, &plugin))
1221   {
1222     database_shutdown (&plugin);
1223     return NULL;
1224   }
1225   api = GNUNET_new (struct GNUNET_DATASTORE_PluginFunctions);
1226   api->cls = &plugin;
1227   api->estimate_size = &sqlite_plugin_estimate_size;
1228   api->put = &sqlite_plugin_put;
1229   api->update = &sqlite_plugin_update;
1230   api->get_key = &sqlite_plugin_get_key;
1231   api->get_replication = &sqlite_plugin_get_replication;
1232   api->get_expiration = &sqlite_plugin_get_expiration;
1233   api->get_zero_anonymity = &sqlite_plugin_get_zero_anonymity;
1234   api->get_keys = &sqlite_plugin_get_keys;
1235   api->drop = &sqlite_plugin_drop;
1236   GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "sqlite",
1237                    _("Sqlite database running\n"));
1238   return api;
1239 }
1240
1241
1242 /**
1243  * Exit point from the plugin.
1244  *
1245  * @param cls the plugin context (as returned by "init")
1246  * @return always NULL
1247  */
1248 void *
1249 libgnunet_plugin_datastore_sqlite_done (void *cls)
1250 {
1251   char *fn;
1252   struct GNUNET_DATASTORE_PluginFunctions *api = cls;
1253   struct Plugin *plugin = api->cls;
1254
1255   GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite",
1256                    "sqlite plugin is done\n");
1257   fn = NULL;
1258   if (plugin->drop_on_shutdown)
1259     fn = GNUNET_strdup (plugin->fn);
1260   GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite",
1261                    "Shutting down database\n");
1262   database_shutdown (plugin);
1263   plugin->env = NULL;
1264   GNUNET_free (api);
1265   if (fn != NULL)
1266   {
1267     if (0 != UNLINK (fn))
1268       GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", fn);
1269     GNUNET_free (fn);
1270   }
1271   GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite",
1272                    "sqlite plugin is finished\n");
1273   return NULL;
1274 }
1275
1276 /* end of plugin_datastore_sqlite.c */