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