- fix #3364, establish a new connection to a peer when a core connection becomes...
[oweals/gnunet.git] / src / datastore / plugin_datastore_sqlite.c
1  /*
2   * This file is part of GNUnet
3   * (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 count_changes=OFF", NULL, NULL,
276                        ENULL));
277   CHECK (SQLITE_OK ==
278          sqlite3_exec (plugin->dbh, "PRAGMA page_size=4092", NULL, NULL,
279                        ENULL));
280
281   CHECK (SQLITE_OK == sqlite3_busy_timeout (plugin->dbh, BUSY_TIMEOUT_MS));
282
283
284   /* We have to do it here, because otherwise precompiling SQL might fail */
285   CHECK (SQLITE_OK ==
286          sq_prepare (plugin->dbh,
287                      "SELECT 1 FROM sqlite_master WHERE tbl_name = 'gn090'",
288                      &stmt));
289   if ((sqlite3_step (stmt) == SQLITE_DONE) &&
290       (sqlite3_exec
291        (plugin->dbh,
292         "CREATE TABLE gn090 (" "  repl INT4 NOT NULL DEFAULT 0,"
293         "  type INT4 NOT NULL DEFAULT 0," "  prio INT4 NOT NULL DEFAULT 0,"
294         "  anonLevel INT4 NOT NULL DEFAULT 0,"
295         "  expire INT8 NOT NULL DEFAULT 0," "  rvalue INT8 NOT NULL,"
296         "  hash TEXT NOT NULL DEFAULT ''," "  vhash TEXT NOT NULL DEFAULT '',"
297         "  value BLOB NOT NULL DEFAULT '')", NULL, NULL, NULL) != SQLITE_OK))
298   {
299     LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR, "sqlite3_exec");
300     sqlite3_finalize (stmt);
301     return GNUNET_SYSERR;
302   }
303   sqlite3_finalize (stmt);
304   create_indices (plugin->dbh);
305
306   if ((sq_prepare
307        (plugin->dbh,
308         "UPDATE gn090 "
309         "SET prio = prio + ?, expire = MAX(expire,?) WHERE _ROWID_ = ?",
310         &plugin->updPrio) != SQLITE_OK) ||
311       (sq_prepare
312        (plugin->dbh,
313         "UPDATE gn090 " "SET repl = MAX (0, repl - 1) WHERE _ROWID_ = ?",
314         &plugin->updRepl) != SQLITE_OK) ||
315       (sq_prepare
316        (plugin->dbh,
317         "SELECT type,prio,anonLevel,expire,hash,value,_ROWID_ " "FROM gn090 "
318 #if SQLITE_VERSION_NUMBER >= 3007000
319         "INDEXED BY idx_repl_rvalue "
320 #endif
321         "WHERE repl=?2 AND " " (rvalue>=?1 OR "
322         "  NOT EXISTS (SELECT 1 FROM gn090 "
323 #if SQLITE_VERSION_NUMBER >= 3007000
324         "INDEXED BY idx_repl_rvalue "
325 #endif
326         "WHERE repl=?2 AND rvalue>=?1 LIMIT 1) ) "
327         "ORDER BY rvalue ASC LIMIT 1", &plugin->selRepl) != SQLITE_OK) ||
328       (sq_prepare (plugin->dbh, "SELECT MAX(repl) FROM gn090"
329 #if SQLITE_VERSION_NUMBER >= 3007000
330                    " INDEXED BY idx_repl_rvalue"
331 #endif
332                    "", &plugin->maxRepl) != SQLITE_OK) ||
333       (sq_prepare
334        (plugin->dbh,
335         "SELECT type,prio,anonLevel,expire,hash,value,_ROWID_ " "FROM gn090 "
336 #if SQLITE_VERSION_NUMBER >= 3007000
337         "INDEXED BY idx_expire "
338 #endif
339         "WHERE NOT EXISTS (SELECT 1 FROM gn090 WHERE expire < ?1 LIMIT 1) OR (expire < ?1) "
340         "ORDER BY expire ASC LIMIT 1", &plugin->selExpi) != SQLITE_OK) ||
341       (sq_prepare
342        (plugin->dbh,
343         "SELECT type,prio,anonLevel,expire,hash,value,_ROWID_ " "FROM gn090 "
344 #if SQLITE_VERSION_NUMBER >= 3007000
345         "INDEXED BY idx_anon_type_hash "
346 #endif
347         "WHERE (anonLevel = 0 AND type=?1) "
348         "ORDER BY hash DESC LIMIT 1 OFFSET ?2",
349         &plugin->selZeroAnon) != SQLITE_OK) ||
350       (sq_prepare
351        (plugin->dbh,
352         "INSERT INTO gn090 (repl, type, prio, anonLevel, expire, rvalue, hash, vhash, value) "
353         "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
354         &plugin->insertContent) != SQLITE_OK) ||
355       (sq_prepare
356        (plugin->dbh, "DELETE FROM gn090 WHERE _ROWID_ = ?",
357         &plugin->delRow) != SQLITE_OK))
358   {
359     LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR, "precompiling");
360     return GNUNET_SYSERR;
361   }
362
363   return GNUNET_OK;
364 }
365
366
367 /**
368  * Shutdown database connection and associate data
369  * structures.
370  *
371  * @param plugin the plugin context (state for this module)
372  */
373 static void
374 database_shutdown (struct Plugin *plugin)
375 {
376   int result;
377
378 #if SQLITE_VERSION_NUMBER >= 3007000
379   sqlite3_stmt *stmt;
380 #endif
381
382   if (plugin->delRow != NULL)
383     sqlite3_finalize (plugin->delRow);
384   if (plugin->updPrio != NULL)
385     sqlite3_finalize (plugin->updPrio);
386   if (plugin->updRepl != NULL)
387     sqlite3_finalize (plugin->updRepl);
388   if (plugin->selRepl != NULL)
389     sqlite3_finalize (plugin->selRepl);
390   if (plugin->maxRepl != NULL)
391     sqlite3_finalize (plugin->maxRepl);
392   if (plugin->selExpi != NULL)
393     sqlite3_finalize (plugin->selExpi);
394   if (plugin->selZeroAnon != NULL)
395     sqlite3_finalize (plugin->selZeroAnon);
396   if (plugin->insertContent != NULL)
397     sqlite3_finalize (plugin->insertContent);
398   result = sqlite3_close (plugin->dbh);
399 #if SQLITE_VERSION_NUMBER >= 3007000
400   if (result == SQLITE_BUSY)
401   {
402     GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, "sqlite",
403                      _
404                      ("Tried to close sqlite without finalizing all prepared statements.\n"));
405     stmt = sqlite3_next_stmt (plugin->dbh, NULL);
406     while (stmt != NULL)
407     {
408       GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite",
409                        "Closing statement %p\n", stmt);
410       result = sqlite3_finalize (stmt);
411       if (result != SQLITE_OK)
412         GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, "sqlite",
413                          "Failed to close statement %p: %d\n", stmt, result);
414       stmt = sqlite3_next_stmt (plugin->dbh, NULL);
415     }
416     result = sqlite3_close (plugin->dbh);
417   }
418 #endif
419   if (SQLITE_OK != result)
420     LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR, "sqlite3_close");
421
422   GNUNET_free_non_null (plugin->fn);
423 }
424
425
426 /**
427  * Delete the database entry with the given
428  * row identifier.
429  *
430  * @param plugin the plugin context (state for this module)
431  * @param rid the ID of the row to delete
432  */
433 static int
434 delete_by_rowid (struct Plugin *plugin,
435                  unsigned long long rid)
436 {
437   if (SQLITE_OK != sqlite3_bind_int64 (plugin->delRow, 1, rid))
438   {
439     LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
440                 "sqlite3_bind_XXXX");
441     if (SQLITE_OK != sqlite3_reset (plugin->delRow))
442       LOG_SQLITE (plugin, NULL,
443                   GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
444                   "sqlite3_reset");
445     return GNUNET_SYSERR;
446   }
447   if (SQLITE_DONE != sqlite3_step (plugin->delRow))
448   {
449     LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
450                 "sqlite3_step");
451     if (SQLITE_OK != sqlite3_reset (plugin->delRow))
452       LOG_SQLITE (plugin, NULL,
453                   GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
454                   "sqlite3_reset");
455     return GNUNET_SYSERR;
456   }
457   if (SQLITE_OK != sqlite3_reset (plugin->delRow))
458     LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
459                 "sqlite3_reset");
460   return GNUNET_OK;
461 }
462
463
464 /**
465  * Store an item in the datastore.
466  *
467  * @param cls closure
468  * @param key key for the item
469  * @param size number of bytes in @a data
470  * @param data content stored
471  * @param type type of the content
472  * @param priority priority of the content
473  * @param anonymity anonymity-level for the content
474  * @param replication replication-level for the content
475  * @param expiration expiration time for the content
476  * @param msg set to an error message
477  * @return #GNUNET_OK on success
478  */
479 static int
480 sqlite_plugin_put (void *cls,
481                    const struct GNUNET_HashCode *key,
482                    uint32_t size,
483                    const void *data,
484                    enum GNUNET_BLOCK_Type type,
485                    uint32_t priority,
486                    uint32_t anonymity,
487                    uint32_t replication,
488                    struct GNUNET_TIME_Absolute expiration,
489                    char **msg)
490 {
491   struct Plugin *plugin = cls;
492   int n;
493   int ret;
494   sqlite3_stmt *stmt;
495   struct GNUNET_HashCode vhash;
496   uint64_t rvalue;
497
498   if (size > MAX_ITEM_SIZE)
499     return GNUNET_SYSERR;
500   GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite",
501                    "Storing in database block with type %u/key `%s'/priority %u/expiration in %s (%s).\n",
502                    type, GNUNET_h2s (key), priority,
503                    (unsigned long long)
504                    GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_remaining (expiration),
505                                                            GNUNET_YES),
506                    GNUNET_STRINGS_absolute_time_to_string (expiration));
507   GNUNET_CRYPTO_hash (data, size, &vhash);
508   stmt = plugin->insertContent;
509   rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX);
510   if ((SQLITE_OK != sqlite3_bind_int (stmt, 1, replication)) ||
511       (SQLITE_OK != sqlite3_bind_int (stmt, 2, type)) ||
512       (SQLITE_OK != sqlite3_bind_int (stmt, 3, priority)) ||
513       (SQLITE_OK != sqlite3_bind_int (stmt, 4, anonymity)) ||
514       (SQLITE_OK != sqlite3_bind_int64 (stmt, 5, expiration.abs_value_us)) ||
515       (SQLITE_OK != sqlite3_bind_int64 (stmt, 6, rvalue)) ||
516       (SQLITE_OK !=
517        sqlite3_bind_blob (stmt, 7, key, sizeof (struct GNUNET_HashCode),
518                           SQLITE_TRANSIENT)) ||
519       (SQLITE_OK !=
520        sqlite3_bind_blob (stmt, 8, &vhash, sizeof (struct GNUNET_HashCode),
521                           SQLITE_TRANSIENT)) ||
522       (SQLITE_OK != sqlite3_bind_blob (stmt, 9, data, size, SQLITE_TRANSIENT)))
523   {
524     LOG_SQLITE (plugin, msg, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
525                 "sqlite3_bind_XXXX");
526     if (SQLITE_OK != sqlite3_reset (stmt))
527       LOG_SQLITE (plugin, NULL,
528                   GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
529                   "sqlite3_reset");
530     return GNUNET_SYSERR;
531   }
532   n = sqlite3_step (stmt);
533   switch (n)
534   {
535   case SQLITE_DONE:
536     plugin->env->duc (plugin->env->cls, size + GNUNET_DATASTORE_ENTRY_OVERHEAD);
537     GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite",
538                      "Stored new entry (%u bytes)\n",
539                      size + GNUNET_DATASTORE_ENTRY_OVERHEAD);
540     ret = GNUNET_OK;
541     break;
542   case SQLITE_BUSY:
543     GNUNET_break (0);
544     LOG_SQLITE (plugin, msg, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
545                 "sqlite3_step");
546     ret = GNUNET_SYSERR;
547     break;
548   default:
549     LOG_SQLITE (plugin, msg, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
550                 "sqlite3_step");
551     if (SQLITE_OK != sqlite3_reset (stmt))
552       LOG_SQLITE (plugin, NULL,
553                   GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
554                   "sqlite3_reset");
555     database_shutdown (plugin);
556     database_setup (plugin->env->cfg, plugin);
557     return GNUNET_SYSERR;
558   }
559   if (SQLITE_OK != sqlite3_reset (stmt))
560     LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
561                 "sqlite3_reset");
562   return ret;
563 }
564
565
566 /**
567  * Update the priority for a particular key in the datastore.  If
568  * the expiration time in value is different than the time found in
569  * the datastore, the higher value should be kept.  For the
570  * anonymity level, the lower value is to be used.  The specified
571  * priority should be added to the existing priority, ignoring the
572  * priority in value.
573  *
574  * Note that it is possible for multiple values to match this put.
575  * In that case, all of the respective values are updated.
576  *
577  * @param cls the plugin context (state for this module)
578  * @param uid unique identifier of the datum
579  * @param delta by how much should the priority
580  *     change?  If priority + delta < 0 the
581  *     priority should be set to 0 (never go
582  *     negative).
583  * @param expire new expiration time should be the
584  *     MAX of any existing expiration time and
585  *     this value
586  * @param msg set to an error message
587  * @return #GNUNET_OK on success
588  */
589 static int
590 sqlite_plugin_update (void *cls,
591                       uint64_t uid,
592                       int delta,
593                       struct GNUNET_TIME_Absolute expire,
594                       char **msg)
595 {
596   struct Plugin *plugin = cls;
597   int n;
598
599   if ((SQLITE_OK != sqlite3_bind_int (plugin->updPrio, 1, delta)) ||
600       (SQLITE_OK != sqlite3_bind_int64 (plugin->updPrio, 2, expire.abs_value_us))
601       || (SQLITE_OK != sqlite3_bind_int64 (plugin->updPrio, 3, uid)))
602   {
603     LOG_SQLITE (plugin, msg, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
604                 "sqlite3_bind_XXXX");
605     if (SQLITE_OK != sqlite3_reset (plugin->updPrio))
606       LOG_SQLITE (plugin, NULL,
607                   GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
608                   "sqlite3_reset");
609     return GNUNET_SYSERR;
610
611   }
612   n = sqlite3_step (plugin->updPrio);
613   if (SQLITE_OK != sqlite3_reset (plugin->updPrio))
614     LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
615                 "sqlite3_reset");
616   switch (n)
617   {
618   case SQLITE_DONE:
619     GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite", "Block updated\n");
620     return GNUNET_OK;
621   case SQLITE_BUSY:
622     LOG_SQLITE (plugin, msg, GNUNET_ERROR_TYPE_WARNING | GNUNET_ERROR_TYPE_BULK,
623                 "sqlite3_step");
624     return GNUNET_NO;
625   default:
626     LOG_SQLITE (plugin, msg, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
627                 "sqlite3_step");
628     return GNUNET_SYSERR;
629   }
630 }
631
632
633 /**
634  * Execute statement that gets a row and call the callback
635  * with the result.  Resets the statement afterwards.
636  *
637  * @param plugin the plugin
638  * @param stmt the statement
639  * @param proc processor to call
640  * @param proc_cls closure for @a proc
641  */
642 static void
643 execute_get (struct Plugin *plugin,
644              sqlite3_stmt *stmt,
645              PluginDatumProcessor proc,
646              void *proc_cls)
647 {
648   int n;
649   struct GNUNET_TIME_Absolute expiration;
650   unsigned long long rowid;
651   unsigned int size;
652   int ret;
653
654   n = sqlite3_step (stmt);
655   switch (n)
656   {
657   case SQLITE_ROW:
658     size = sqlite3_column_bytes (stmt, 5);
659     rowid = sqlite3_column_int64 (stmt, 6);
660     if (sqlite3_column_bytes (stmt, 4) != sizeof (struct GNUNET_HashCode))
661     {
662       GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, "sqlite",
663                        _("Invalid data in database.  Trying to fix (by deletion).\n"));
664       if (SQLITE_OK != sqlite3_reset (stmt))
665         LOG_SQLITE (plugin, NULL,
666                     GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
667                     "sqlite3_reset");
668       if (GNUNET_OK == delete_by_rowid (plugin, rowid))
669         plugin->env->duc (plugin->env->cls,
670                           -(size + GNUNET_DATASTORE_ENTRY_OVERHEAD));
671       break;
672     }
673     expiration.abs_value_us = sqlite3_column_int64 (stmt, 3);
674     GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite",
675                      "Found reply in database with expiration %s\n",
676                      GNUNET_STRINGS_absolute_time_to_string (expiration));
677     ret = proc (proc_cls, sqlite3_column_blob (stmt, 4) /* key */ ,
678                 size, sqlite3_column_blob (stmt, 5) /* data */ ,
679                 sqlite3_column_int (stmt, 0) /* type */ ,
680                 sqlite3_column_int (stmt, 1) /* priority */ ,
681                 sqlite3_column_int (stmt, 2) /* anonymity */ ,
682                 expiration, rowid);
683     if (SQLITE_OK != sqlite3_reset (stmt))
684       LOG_SQLITE (plugin, NULL,
685                   GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
686                   "sqlite3_reset");
687     if ((GNUNET_NO == ret) && (GNUNET_OK == delete_by_rowid (plugin, rowid)))
688       plugin->env->duc (plugin->env->cls,
689                         -(size + GNUNET_DATASTORE_ENTRY_OVERHEAD));
690     return;
691   case SQLITE_DONE:
692     /* database must be empty */
693     if (SQLITE_OK != sqlite3_reset (stmt))
694       LOG_SQLITE (plugin, NULL,
695                   GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
696                   "sqlite3_reset");
697     break;
698   case SQLITE_BUSY:
699   case SQLITE_ERROR:
700   case SQLITE_MISUSE:
701   default:
702     LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
703                 "sqlite3_step");
704     if (SQLITE_OK != sqlite3_reset (stmt))
705       LOG_SQLITE (plugin, NULL,
706                   GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
707                   "sqlite3_reset");
708     GNUNET_break (0);
709     database_shutdown (plugin);
710     database_setup (plugin->env->cfg, plugin);
711     break;
712   }
713   if (SQLITE_OK != sqlite3_reset (stmt))
714     LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
715                 "sqlite3_reset");
716   proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
717 }
718
719
720 /**
721  * Select a subset of the items in the datastore and call
722  * the given processor for the item.
723  *
724  * @param cls our plugin context
725  * @param offset offset of the result (modulo num-results);
726  *               specific ordering does not matter for the offset
727  * @param type entries of which type should be considered?
728  *        Use 0 for any type.
729  * @param proc function to call on each matching value;
730  *        will be called once with a NULL value at the end
731  * @param proc_cls closure for @a proc
732  */
733 static void
734 sqlite_plugin_get_zero_anonymity (void *cls, uint64_t offset,
735                                   enum GNUNET_BLOCK_Type type,
736                                   PluginDatumProcessor proc, void *proc_cls)
737 {
738   struct Plugin *plugin = cls;
739   sqlite3_stmt *stmt;
740
741   GNUNET_assert (type != GNUNET_BLOCK_TYPE_ANY);
742   stmt = plugin->selZeroAnon;
743   if ((SQLITE_OK != sqlite3_bind_int (stmt, 1, type)) ||
744       (SQLITE_OK != sqlite3_bind_int64 (stmt, 2, offset)))
745   {
746     LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
747                 "sqlite3_bind_XXXX");
748     if (SQLITE_OK != sqlite3_reset (stmt))
749       LOG_SQLITE (plugin, NULL,
750                   GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
751                   "sqlite3_reset");
752     proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
753     return;
754   }
755   execute_get (plugin, stmt, proc, proc_cls);
756 }
757
758
759 /**
760  * Get results for a particular key in the datastore.
761  *
762  * @param cls closure
763  * @param offset offset (mod count).
764  * @param key key to match, never NULL
765  * @param vhash hash of the value, maybe NULL (to
766  *        match all values that have the right key).
767  *        Note that for DBlocks there is no difference
768  *        betwen key and vhash, but for other blocks
769  *        there may be!
770  * @param type entries of which type are relevant?
771  *     Use 0 for any type.
772  * @param proc function to call on each matching value;
773  *        will be called once with a NULL value at the end
774  * @param proc_cls closure for @a proc
775  */
776 static void
777 sqlite_plugin_get_key (void *cls,
778                        uint64_t offset,
779                        const struct GNUNET_HashCode *key,
780                        const struct GNUNET_HashCode *vhash,
781                        enum GNUNET_BLOCK_Type type,
782                        PluginDatumProcessor proc,
783                        void *proc_cls)
784 {
785   struct Plugin *plugin = cls;
786   int ret;
787   int total;
788   int limit_off;
789   unsigned int sqoff;
790   sqlite3_stmt *stmt;
791   char scratch[256];
792
793   GNUNET_assert (proc != NULL);
794   GNUNET_assert (key != NULL);
795   GNUNET_snprintf (scratch, sizeof (scratch),
796                    "SELECT count(*) FROM gn090 WHERE hash=?%s%s",
797                    vhash == NULL ? "" : " AND vhash=?",
798                    type == 0 ? "" : " AND type=?");
799   if (sq_prepare (plugin->dbh, scratch, &stmt) != SQLITE_OK)
800   {
801     LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
802                 "sqlite_prepare");
803     proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
804     return;
805   }
806   sqoff = 1;
807   ret =
808       sqlite3_bind_blob (stmt, sqoff++, key, sizeof (struct GNUNET_HashCode),
809                          SQLITE_TRANSIENT);
810   if ((vhash != NULL) && (ret == SQLITE_OK))
811     ret =
812         sqlite3_bind_blob (stmt, sqoff++, vhash, sizeof (struct GNUNET_HashCode),
813                            SQLITE_TRANSIENT);
814   if ((type != 0) && (ret == SQLITE_OK))
815     ret = sqlite3_bind_int (stmt, sqoff++, type);
816   if (SQLITE_OK != ret)
817   {
818     LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR, "sqlite_bind");
819     sqlite3_finalize (stmt);
820     proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
821     return;
822   }
823   ret = sqlite3_step (stmt);
824   if (ret != SQLITE_ROW)
825   {
826     LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
827                 "sqlite_step");
828     sqlite3_finalize (stmt);
829     proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
830     return;
831   }
832   total = sqlite3_column_int (stmt, 0);
833   sqlite3_finalize (stmt);
834   if (0 == total)
835   {
836     proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
837     return;
838   }
839   limit_off = (int) (offset % total);
840   if (limit_off < 0)
841     limit_off += total;
842   GNUNET_snprintf (scratch, sizeof (scratch),
843                    "SELECT type, prio, anonLevel, expire, hash, value, _ROWID_ "
844                    "FROM gn090 WHERE hash=?%s%s "
845                    "ORDER BY _ROWID_ ASC LIMIT 1 OFFSET ?",
846                    vhash == NULL ? "" : " AND vhash=?",
847                    type == 0 ? "" : " AND type=?");
848   if (sq_prepare (plugin->dbh, scratch, &stmt) != SQLITE_OK)
849   {
850     LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
851                 "sqlite_prepare");
852     proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
853     return;
854   }
855   sqoff = 1;
856   ret = sqlite3_bind_blob (stmt, sqoff++, key,
857                            sizeof (struct GNUNET_HashCode),
858                            SQLITE_TRANSIENT);
859   if ((vhash != NULL) && (ret == SQLITE_OK))
860     ret = sqlite3_bind_blob (stmt, sqoff++, vhash,
861                              sizeof (struct GNUNET_HashCode),
862                              SQLITE_TRANSIENT);
863   if ((type != 0) && (ret == SQLITE_OK))
864     ret = sqlite3_bind_int (stmt, sqoff++, type);
865   if (ret == SQLITE_OK)
866     ret = sqlite3_bind_int64 (stmt, sqoff++, limit_off);
867   if (ret != SQLITE_OK)
868   {
869     LOG_SQLITE (plugin, NULL,
870                 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
871                 "sqlite_bind");
872     proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
873     return;
874   }
875   execute_get (plugin, stmt, proc, proc_cls);
876   sqlite3_finalize (stmt);
877 }
878
879
880 /**
881  * Context for #repl_proc() function.
882  */
883 struct ReplCtx
884 {
885
886   /**
887    * Function to call for the result (or the NULL).
888    */
889   PluginDatumProcessor proc;
890
891   /**
892    * Closure for @e proc.
893    */
894   void *proc_cls;
895
896   /**
897    * UID to use.
898    */
899   uint64_t uid;
900
901   /**
902    * Yes if UID was set.
903    */
904   int have_uid;
905 };
906
907
908 /**
909  * Wrapper for the processor for #sqlite_plugin_replication_get().
910  * Decrements the replication counter and calls the original
911  * processor.
912  *
913  * @param cls closure
914  * @param key key for the content
915  * @param size number of bytes in @a data
916  * @param data content stored
917  * @param type type of the content
918  * @param priority priority of the content
919  * @param anonymity anonymity-level for the content
920  * @param expiration expiration time for the content
921  * @param uid unique identifier for the datum;
922  *        maybe 0 if no unique identifier is available
923  * @return #GNUNET_OK for normal return,
924  *         #GNUNET_NO to delete the item
925  */
926 static int
927 repl_proc (void *cls,
928            const struct GNUNET_HashCode *key,
929            uint32_t size,
930            const void *data,
931            enum GNUNET_BLOCK_Type type,
932            uint32_t priority,
933            uint32_t anonymity,
934            struct GNUNET_TIME_Absolute expiration,
935            uint64_t uid)
936 {
937   struct ReplCtx *rc = cls;
938   int ret;
939
940   ret = rc->proc (rc->proc_cls,
941                   key,
942                   size, data,
943                   type,
944                   priority,
945                   anonymity,
946                   expiration, uid);
947   if (NULL != key)
948   {
949     rc->uid = uid;
950     rc->have_uid = GNUNET_YES;
951   }
952   return ret;
953 }
954
955
956 /**
957  * Get a random item for replication.  Returns a single random item
958  * from those with the highest replication counters.  The item's
959  * replication counter is decremented by one IF it was positive before.
960  * Call @a proc with all values ZERO or NULL if the datastore is empty.
961  *
962  * @param cls closure
963  * @param proc function to call the value (once only).
964  * @param proc_cls closure for @a proc
965  */
966 static void
967 sqlite_plugin_get_replication (void *cls, PluginDatumProcessor proc,
968                                void *proc_cls)
969 {
970   struct Plugin *plugin = cls;
971   struct ReplCtx rc;
972   uint64_t rvalue;
973   uint32_t repl;
974   sqlite3_stmt *stmt;
975
976   GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite",
977                    "Getting random block based on replication order.\n");
978   rc.have_uid = GNUNET_NO;
979   rc.proc = proc;
980   rc.proc_cls = proc_cls;
981   stmt = plugin->maxRepl;
982   if (SQLITE_ROW != sqlite3_step (stmt))
983   {
984     if (SQLITE_OK != sqlite3_reset (stmt))
985       LOG_SQLITE (plugin, NULL,
986                   GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
987                   "sqlite3_reset");
988     /* DB empty */
989     proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
990     return;
991   }
992   repl = sqlite3_column_int (stmt, 0);
993   if (SQLITE_OK != sqlite3_reset (stmt))
994     LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
995                 "sqlite3_reset");
996   stmt = plugin->selRepl;
997   rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX);
998   if (SQLITE_OK != sqlite3_bind_int64 (stmt, 1, rvalue))
999   {
1000     LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
1001                 "sqlite3_bind_XXXX");
1002     if (SQLITE_OK != sqlite3_reset (stmt))
1003       LOG_SQLITE (plugin, NULL,
1004                   GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
1005                   "sqlite3_reset");
1006     proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
1007     return;
1008   }
1009   if (SQLITE_OK != sqlite3_bind_int (stmt, 2, repl))
1010   {
1011     LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
1012                 "sqlite3_bind_XXXX");
1013     if (SQLITE_OK != sqlite3_reset (stmt))
1014       LOG_SQLITE (plugin, NULL,
1015                   GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
1016                   "sqlite3_reset");
1017     proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
1018     return;
1019   }
1020   execute_get (plugin, stmt, &repl_proc, &rc);
1021   if (GNUNET_YES == rc.have_uid)
1022   {
1023     if (SQLITE_OK != sqlite3_bind_int64 (plugin->updRepl, 1, rc.uid))
1024     {
1025       LOG_SQLITE (plugin, NULL,
1026                   GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
1027                   "sqlite3_bind_XXXX");
1028       if (SQLITE_OK != sqlite3_reset (plugin->updRepl))
1029         LOG_SQLITE (plugin, NULL,
1030                     GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
1031                     "sqlite3_reset");
1032       return;
1033     }
1034     if (SQLITE_DONE != sqlite3_step (plugin->updRepl))
1035       LOG_SQLITE (plugin, NULL,
1036                   GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
1037                   "sqlite3_step");
1038     if (SQLITE_OK != sqlite3_reset (plugin->updRepl))
1039       LOG_SQLITE (plugin, NULL,
1040                   GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
1041                   "sqlite3_reset");
1042   }
1043 }
1044
1045
1046 /**
1047  * Get a random item that has expired or has low priority.
1048  * Call @a proc with all values ZERO or NULL if the datastore is empty.
1049  *
1050  * @param cls closure
1051  * @param proc function to call the value (once only).
1052  * @param proc_cls closure for @a proc
1053  */
1054 static void
1055 sqlite_plugin_get_expiration (void *cls, PluginDatumProcessor proc,
1056                               void *proc_cls)
1057 {
1058   struct Plugin *plugin = cls;
1059   sqlite3_stmt *stmt;
1060   struct GNUNET_TIME_Absolute now;
1061
1062   GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite",
1063                    "Getting random block based on expiration and priority order.\n");
1064   now = GNUNET_TIME_absolute_get ();
1065   stmt = plugin->selExpi;
1066   if (SQLITE_OK != sqlite3_bind_int64 (stmt, 1, now.abs_value_us))
1067   {
1068     LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
1069                 "sqlite3_bind_XXXX");
1070     if (SQLITE_OK != sqlite3_reset (stmt))
1071       LOG_SQLITE (plugin, NULL,
1072                   GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
1073                   "sqlite3_reset");
1074     proc (proc_cls, NULL, 0, NULL, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
1075     return;
1076   }
1077   execute_get (plugin, stmt, proc, proc_cls);
1078 }
1079
1080
1081 /**
1082  * Get all of the keys in the datastore.
1083  *
1084  * @param cls closure
1085  * @param proc function to call on each key
1086  * @param proc_cls closure for @a proc
1087  */
1088 static void
1089 sqlite_plugin_get_keys (void *cls,
1090                         PluginKeyProcessor proc,
1091                         void *proc_cls)
1092 {
1093   struct Plugin *plugin = cls;
1094   const struct GNUNET_HashCode *key;
1095   sqlite3_stmt *stmt;
1096   int ret;
1097
1098   GNUNET_assert (proc != NULL);
1099   if (sq_prepare (plugin->dbh, "SELECT hash FROM gn090", &stmt) != SQLITE_OK)
1100   {
1101     LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
1102                 "sqlite_prepare");
1103     return;
1104   }
1105   while (SQLITE_ROW == (ret = sqlite3_step (stmt)))
1106   {
1107     key = sqlite3_column_blob (stmt, 0);
1108     if (sizeof (struct GNUNET_HashCode) == sqlite3_column_bytes (stmt, 0))
1109       proc (proc_cls, key, 1);
1110     else
1111       GNUNET_break (0);
1112   }
1113   if (SQLITE_DONE != ret)
1114     LOG_SQLITE (plugin, NULL, GNUNET_ERROR_TYPE_ERROR, "sqlite_step");
1115   sqlite3_finalize (stmt);
1116 }
1117
1118
1119 /**
1120  * Drop database.
1121  *
1122  * @param cls our plugin context
1123  */
1124 static void
1125 sqlite_plugin_drop (void *cls)
1126 {
1127   struct Plugin *plugin = cls;
1128
1129   plugin->drop_on_shutdown = GNUNET_YES;
1130 }
1131
1132
1133 /**
1134  * Get an estimate of how much space the database is
1135  * currently using.
1136  *
1137  * @param cls the `struct Plugin`
1138  * @return the size of the database on disk (estimate)
1139  */
1140 static unsigned long long
1141 sqlite_plugin_estimate_size (void *cls)
1142 {
1143   struct Plugin *plugin = cls;
1144   sqlite3_stmt *stmt;
1145   uint64_t pages;
1146   uint64_t page_size;
1147
1148 #if ENULL_DEFINED
1149   char *e;
1150 #endif
1151
1152   if (SQLITE_VERSION_NUMBER < 3006000)
1153   {
1154     GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, "datastore-sqlite",
1155                      _
1156                      ("sqlite version to old to determine size, assuming zero\n"));
1157     return 0;
1158   }
1159   CHECK (SQLITE_OK == sqlite3_exec (plugin->dbh, "VACUUM", NULL, NULL, ENULL));
1160   CHECK (SQLITE_OK ==
1161          sqlite3_exec (plugin->dbh, "PRAGMA auto_vacuum=INCREMENTAL", NULL,
1162                        NULL, ENULL));
1163   CHECK (SQLITE_OK == sq_prepare (plugin->dbh, "PRAGMA page_count", &stmt));
1164   if (SQLITE_ROW == sqlite3_step (stmt))
1165     pages = sqlite3_column_int64 (stmt, 0);
1166   else
1167     pages = 0;
1168   sqlite3_finalize (stmt);
1169   CHECK (SQLITE_OK == sq_prepare (plugin->dbh, "PRAGMA page_size", &stmt));
1170   CHECK (SQLITE_ROW == sqlite3_step (stmt));
1171   page_size = sqlite3_column_int64 (stmt, 0);
1172   sqlite3_finalize (stmt);
1173   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
1174               _
1175               ("Using sqlite page utilization to estimate payload (%llu pages of size %llu bytes)\n"),
1176               (unsigned long long) pages, (unsigned long long) page_size);
1177   return pages * page_size;
1178 }
1179
1180
1181 /**
1182  * Entry point for the plugin.
1183  *
1184  * @param cls the `struct GNUNET_DATASTORE_PluginEnvironment *`
1185  * @return NULL on error, othrewise the plugin context
1186  */
1187 void *
1188 libgnunet_plugin_datastore_sqlite_init (void *cls)
1189 {
1190   static struct Plugin plugin;
1191   struct GNUNET_DATASTORE_PluginEnvironment *env = cls;
1192   struct GNUNET_DATASTORE_PluginFunctions *api;
1193
1194   if (plugin.env != NULL)
1195     return NULL;                /* can only initialize once! */
1196   memset (&plugin, 0, sizeof (struct Plugin));
1197   plugin.env = env;
1198   if (GNUNET_OK != database_setup (env->cfg, &plugin))
1199   {
1200     database_shutdown (&plugin);
1201     return NULL;
1202   }
1203   api = GNUNET_new (struct GNUNET_DATASTORE_PluginFunctions);
1204   api->cls = &plugin;
1205   api->estimate_size = &sqlite_plugin_estimate_size;
1206   api->put = &sqlite_plugin_put;
1207   api->update = &sqlite_plugin_update;
1208   api->get_key = &sqlite_plugin_get_key;
1209   api->get_replication = &sqlite_plugin_get_replication;
1210   api->get_expiration = &sqlite_plugin_get_expiration;
1211   api->get_zero_anonymity = &sqlite_plugin_get_zero_anonymity;
1212   api->get_keys = &sqlite_plugin_get_keys;
1213   api->drop = &sqlite_plugin_drop;
1214   GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, "sqlite",
1215                    _("Sqlite database running\n"));
1216   return api;
1217 }
1218
1219
1220 /**
1221  * Exit point from the plugin.
1222  *
1223  * @param cls the plugin context (as returned by "init")
1224  * @return always NULL
1225  */
1226 void *
1227 libgnunet_plugin_datastore_sqlite_done (void *cls)
1228 {
1229   char *fn;
1230   struct GNUNET_DATASTORE_PluginFunctions *api = cls;
1231   struct Plugin *plugin = api->cls;
1232
1233   GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite",
1234                    "sqlite plugin is done\n");
1235   fn = NULL;
1236   if (plugin->drop_on_shutdown)
1237     fn = GNUNET_strdup (plugin->fn);
1238   GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite",
1239                    "Shutting down database\n");
1240   database_shutdown (plugin);
1241   plugin->env = NULL;
1242   GNUNET_free (api);
1243   if (fn != NULL)
1244   {
1245     if (0 != UNLINK (fn))
1246       GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", fn);
1247     GNUNET_free (fn);
1248   }
1249   GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite",
1250                    "sqlite plugin is finished\n");
1251   return NULL;
1252 }
1253
1254 /* end of plugin_datastore_sqlite.c */