first step to remove plibc
[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 #if ENULL_DEFINED
276   char *e;
277 #endif
278
279   if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_filename (cfg,
280                                                             "datastore-sqlite",
281                                                             "FILENAME",
282                                                             &afsdir))
283   {
284     GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
285                                "datastore-sqlite",
286                                "FILENAME");
287     return GNUNET_SYSERR;
288   }
289   if (GNUNET_OK != GNUNET_DISK_file_test (afsdir))
290   {
291     if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (afsdir))
292     {
293       GNUNET_break (0);
294       GNUNET_free (afsdir);
295       return GNUNET_SYSERR;
296     }
297     /* database is new or got deleted, reset payload to zero! */
298     if (NULL != plugin->env->duc)
299       plugin->env->duc (plugin->env->cls, 0);
300   }
301   /* afsdir should be UTF-8-encoded. If it isn't, it's a bug */
302   plugin->fn = afsdir;
303
304   /* Open database and precompile statements */
305   if (SQLITE_OK != sqlite3_open (plugin->fn, &plugin->dbh))
306   {
307     GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR,
308                      "sqlite",
309                      _ ("Unable to initialize SQLite: %s.\n"),
310                      sqlite3_errmsg (plugin->dbh));
311     return GNUNET_SYSERR;
312   }
313   CHECK (
314     SQLITE_OK ==
315     sqlite3_exec (plugin->dbh, "PRAGMA temp_store=MEMORY", NULL, NULL, ENULL));
316   CHECK (
317     SQLITE_OK ==
318     sqlite3_exec (plugin->dbh, "PRAGMA synchronous=OFF", NULL, NULL, ENULL));
319   CHECK (SQLITE_OK == sqlite3_exec (plugin->dbh,
320                                     "PRAGMA legacy_file_format=OFF",
321                                     NULL,
322                                     NULL,
323                                     ENULL));
324   CHECK (SQLITE_OK == sqlite3_exec (plugin->dbh,
325                                     "PRAGMA auto_vacuum=INCREMENTAL",
326                                     NULL,
327                                     NULL,
328                                     ENULL));
329   CHECK (SQLITE_OK == sqlite3_exec (plugin->dbh,
330                                     "PRAGMA locking_mode=EXCLUSIVE",
331                                     NULL,
332                                     NULL,
333                                     ENULL));
334   CHECK (
335     SQLITE_OK ==
336     sqlite3_exec (plugin->dbh, "PRAGMA page_size=4096", NULL, NULL, ENULL));
337
338   CHECK (SQLITE_OK == sqlite3_busy_timeout (plugin->dbh, BUSY_TIMEOUT_MS));
339
340
341   /* We have to do it here, because otherwise precompiling SQL might fail */
342   CHECK (SQLITE_OK ==
343          sq_prepare (plugin->dbh,
344                      "SELECT 1 FROM sqlite_master WHERE tbl_name = 'gn091'",
345                      &stmt));
346
347   /* FIXME: SQLite does not have unsigned integers! This is ok for the type column because
348    * we only test equality on it and can cast it to/from uint32_t. For repl, prio, and anonLevel
349    * we do math or inequality tests, so we can't handle the entire range of uint32_t.
350    * This will also cause problems for expiration times after 294247-01-10-04:00:54 UTC.
351    */
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 #if SQLITE_VERSION_NUMBER >= 3007000
498   sqlite3_stmt *stmt;
499 #endif
500
501   if (NULL != plugin->remove)
502     sqlite3_finalize (plugin->remove);
503   if (NULL != plugin->delRow)
504     sqlite3_finalize (plugin->delRow);
505   if (NULL != plugin->update)
506     sqlite3_finalize (plugin->update);
507   if (NULL != plugin->updRepl)
508     sqlite3_finalize (plugin->updRepl);
509   if (NULL != plugin->selRepl)
510     sqlite3_finalize (plugin->selRepl);
511   if (NULL != plugin->maxRepl)
512     sqlite3_finalize (plugin->maxRepl);
513   if (NULL != plugin->selExpi)
514     sqlite3_finalize (plugin->selExpi);
515   if (NULL != plugin->selZeroAnon)
516     sqlite3_finalize (plugin->selZeroAnon);
517   if (NULL != plugin->insertContent)
518     sqlite3_finalize (plugin->insertContent);
519   for (int i = 0; i < 8; ++i)
520     if (NULL != plugin->get[i])
521       sqlite3_finalize (plugin->get[i]);
522   result = sqlite3_close (plugin->dbh);
523 #if SQLITE_VERSION_NUMBER >= 3007000
524   if (result == SQLITE_BUSY)
525   {
526     GNUNET_log_from (
527       GNUNET_ERROR_TYPE_WARNING,
528       "sqlite",
529       _ (
530         "Tried to close sqlite without finalizing all prepared statements.\n"));
531     stmt = sqlite3_next_stmt (plugin->dbh, NULL);
532     while (NULL != stmt)
533     {
534       GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
535                        "sqlite",
536                        "Closing statement %p\n",
537                        stmt);
538       result = sqlite3_finalize (stmt);
539       if (result != SQLITE_OK)
540         GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING,
541                          "sqlite",
542                          "Failed to close statement %p: %d\n",
543                          stmt,
544                          result);
545       stmt = sqlite3_next_stmt (plugin->dbh, NULL);
546     }
547     result = sqlite3_close (plugin->dbh);
548   }
549 #endif
550   if (SQLITE_OK != result)
551     LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite3_close");
552   GNUNET_free_non_null (plugin->fn);
553 }
554
555
556 /**
557  * Delete the database entry with the given
558  * row identifier.
559  *
560  * @param plugin the plugin context (state for this module)
561  * @param rid the ID of the row to delete
562  */
563 static int
564 delete_by_rowid (struct Plugin *plugin, uint64_t rid)
565 {
566   struct GNUNET_SQ_QueryParam params[] = {GNUNET_SQ_query_param_uint64 (&rid),
567                                           GNUNET_SQ_query_param_end};
568
569   if (GNUNET_OK != GNUNET_SQ_bind (plugin->delRow, params))
570     return GNUNET_SYSERR;
571   if (SQLITE_DONE != sqlite3_step (plugin->delRow))
572   {
573     LOG_SQLITE (plugin,
574                 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
575                 "sqlite3_step");
576     GNUNET_SQ_reset (plugin->dbh, plugin->delRow);
577     return GNUNET_SYSERR;
578   }
579   GNUNET_SQ_reset (plugin->dbh, plugin->delRow);
580   return GNUNET_OK;
581 }
582
583
584 /**
585  * Store an item in the datastore.
586  *
587  * @param cls closure
588  * @param key key for the item
589  * @param absent true if the key was not found in the bloom filter
590  * @param size number of bytes in @a data
591  * @param data content stored
592  * @param type type of the content
593  * @param priority priority of the content
594  * @param anonymity anonymity-level for the content
595  * @param replication replication-level for the content
596  * @param expiration expiration time for the content
597  * @param cont continuation called with success or failure status
598  * @param cont_cls continuation closure
599  */
600 static void
601 sqlite_plugin_put (void *cls,
602                    const struct GNUNET_HashCode *key,
603                    bool absent,
604                    uint32_t size,
605                    const void *data,
606                    enum GNUNET_BLOCK_Type type,
607                    uint32_t priority,
608                    uint32_t anonymity,
609                    uint32_t replication,
610                    struct GNUNET_TIME_Absolute expiration,
611                    PluginPutCont cont,
612                    void *cont_cls)
613 {
614   struct Plugin *plugin = cls;
615   struct GNUNET_HashCode vhash;
616   char *msg = NULL;
617
618   GNUNET_CRYPTO_hash (data, size, &vhash);
619
620   if (! absent)
621   {
622     struct GNUNET_SQ_QueryParam params[] =
623       {GNUNET_SQ_query_param_uint32 (&priority),
624        GNUNET_SQ_query_param_uint32 (&replication),
625        GNUNET_SQ_query_param_absolute_time (&expiration),
626        GNUNET_SQ_query_param_auto_from_type (key),
627        GNUNET_SQ_query_param_auto_from_type (&vhash),
628        GNUNET_SQ_query_param_end};
629
630     if (GNUNET_OK != GNUNET_SQ_bind (plugin->update, params))
631     {
632       cont (cont_cls, key, size, GNUNET_SYSERR, _ ("sqlite bind failure"));
633       return;
634     }
635     if (SQLITE_DONE != sqlite3_step (plugin->update))
636     {
637       LOG_SQLITE_MSG (plugin,
638                       &msg,
639                       GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
640                       "sqlite3_step");
641       cont (cont_cls, key, size, GNUNET_SYSERR, msg);
642       GNUNET_free_non_null (msg);
643       return;
644     }
645     int changes = sqlite3_changes (plugin->dbh);
646     GNUNET_SQ_reset (plugin->dbh, plugin->update);
647     if (0 != changes)
648     {
649       cont (cont_cls, key, size, GNUNET_NO, NULL);
650       return;
651     }
652   }
653
654   uint64_t rvalue;
655   uint32_t type32 = (uint32_t) type;
656   struct GNUNET_SQ_QueryParam params[] =
657     {GNUNET_SQ_query_param_uint32 (&replication),
658      GNUNET_SQ_query_param_uint32 (&type32),
659      GNUNET_SQ_query_param_uint32 (&priority),
660      GNUNET_SQ_query_param_uint32 (&anonymity),
661      GNUNET_SQ_query_param_absolute_time (&expiration),
662      GNUNET_SQ_query_param_uint64 (&rvalue),
663      GNUNET_SQ_query_param_auto_from_type (key),
664      GNUNET_SQ_query_param_auto_from_type (&vhash),
665      GNUNET_SQ_query_param_fixed_size (data, size),
666      GNUNET_SQ_query_param_end};
667   int n;
668   int ret;
669   sqlite3_stmt *stmt;
670
671   if (size > MAX_ITEM_SIZE)
672   {
673     cont (cont_cls, key, size, GNUNET_SYSERR, _ ("Data too large"));
674     return;
675   }
676   GNUNET_log_from (
677     GNUNET_ERROR_TYPE_DEBUG,
678     "sqlite",
679     "Storing in database block with type %u/key `%s'/priority %u/expiration in %s (%s).\n",
680     type,
681     GNUNET_h2s (key),
682     priority,
683     GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_remaining (
684                                               expiration),
685                                             GNUNET_YES),
686     GNUNET_STRINGS_absolute_time_to_string (expiration));
687   stmt = plugin->insertContent;
688   rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX);
689   if (GNUNET_OK != GNUNET_SQ_bind (stmt, params))
690   {
691     cont (cont_cls, key, size, GNUNET_SYSERR, NULL);
692     return;
693   }
694   n = sqlite3_step (stmt);
695   switch (n)
696   {
697   case SQLITE_DONE:
698     if (NULL != plugin->env->duc)
699       plugin->env->duc (plugin->env->cls,
700                         size + GNUNET_DATASTORE_ENTRY_OVERHEAD);
701     GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
702                      "sqlite",
703                      "Stored new entry (%u bytes)\n",
704                      size + GNUNET_DATASTORE_ENTRY_OVERHEAD);
705     ret = GNUNET_OK;
706     break;
707   case SQLITE_BUSY:
708     GNUNET_break (0);
709     LOG_SQLITE_MSG (plugin,
710                     &msg,
711                     GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
712                     "sqlite3_step");
713     ret = GNUNET_SYSERR;
714     break;
715   default:
716     LOG_SQLITE_MSG (plugin,
717                     &msg,
718                     GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
719                     "sqlite3_step");
720     GNUNET_SQ_reset (plugin->dbh, stmt);
721     database_shutdown (plugin);
722     database_setup (plugin->env->cfg, plugin);
723     cont (cont_cls, key, size, GNUNET_SYSERR, msg);
724     GNUNET_free_non_null (msg);
725     return;
726   }
727   GNUNET_SQ_reset (plugin->dbh, stmt);
728   cont (cont_cls, key, size, ret, msg);
729   GNUNET_free_non_null (msg);
730 }
731
732
733 /**
734  * Execute statement that gets a row and call the callback
735  * with the result.  Resets the statement afterwards.
736  *
737  * @param plugin the plugin
738  * @param stmt the statement
739  * @param proc processor to call
740  * @param proc_cls closure for @a proc
741  */
742 static void
743 execute_get (struct Plugin *plugin,
744              sqlite3_stmt *stmt,
745              PluginDatumProcessor proc,
746              void *proc_cls)
747 {
748   int n;
749   struct GNUNET_TIME_Absolute expiration;
750   uint32_t replication;
751   uint32_t type;
752   uint32_t priority;
753   uint32_t anonymity;
754   uint64_t rowid;
755   void *value;
756   size_t value_size;
757   struct GNUNET_HashCode key;
758   int ret;
759   struct GNUNET_SQ_ResultSpec rs[] =
760     {GNUNET_SQ_result_spec_uint32 (&replication),
761      GNUNET_SQ_result_spec_uint32 (&type),
762      GNUNET_SQ_result_spec_uint32 (&priority),
763      GNUNET_SQ_result_spec_uint32 (&anonymity),
764      GNUNET_SQ_result_spec_absolute_time (&expiration),
765      GNUNET_SQ_result_spec_auto_from_type (&key),
766      GNUNET_SQ_result_spec_variable_size (&value, &value_size),
767      GNUNET_SQ_result_spec_uint64 (&rowid),
768      GNUNET_SQ_result_spec_end};
769
770   n = sqlite3_step (stmt);
771   switch (n)
772   {
773   case SQLITE_ROW:
774     if (GNUNET_OK != GNUNET_SQ_extract_result (stmt, rs))
775     {
776       GNUNET_break (0);
777       break;
778     }
779     GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
780                      "sqlite",
781                      "Found reply in database with expiration %s\n",
782                      GNUNET_STRINGS_absolute_time_to_string (expiration));
783     ret = proc (proc_cls,
784                 &key,
785                 value_size,
786                 value,
787                 type,
788                 priority,
789                 anonymity,
790                 replication,
791                 expiration,
792                 rowid);
793     GNUNET_SQ_cleanup_result (rs);
794     GNUNET_SQ_reset (plugin->dbh, stmt);
795     if ((GNUNET_NO == ret) && (GNUNET_OK == delete_by_rowid (plugin, rowid)) &&
796         (NULL != plugin->env->duc))
797       plugin->env->duc (plugin->env->cls,
798                         -(value_size + GNUNET_DATASTORE_ENTRY_OVERHEAD));
799     return;
800   case SQLITE_DONE:
801     /* database must be empty */
802     break;
803   case SQLITE_BUSY:
804   case SQLITE_ERROR:
805   case SQLITE_MISUSE:
806   default:
807     LOG_SQLITE (plugin,
808                 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
809                 "sqlite3_step");
810     if (SQLITE_OK != sqlite3_reset (stmt))
811       LOG_SQLITE (plugin,
812                   GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
813                   "sqlite3_reset");
814     GNUNET_break (0);
815     proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
816     database_shutdown (plugin);
817     database_setup (plugin->env->cfg, plugin);
818     return;
819   }
820   GNUNET_SQ_reset (plugin->dbh, stmt);
821   proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
822 }
823
824
825 /**
826  * Select a subset of the items in the datastore and call
827  * the given processor for the item.
828  *
829  * @param cls our plugin context
830  * @param next_uid return the result with lowest uid >= next_uid
831  * @param type entries of which type should be considered?
832  *        Must not be zero (ANY).
833  * @param proc function to call on the matching value;
834  *        will be called with NULL if no value matches
835  * @param proc_cls closure for @a proc
836  */
837 static void
838 sqlite_plugin_get_zero_anonymity (void *cls,
839                                   uint64_t next_uid,
840                                   enum GNUNET_BLOCK_Type type,
841                                   PluginDatumProcessor proc,
842                                   void *proc_cls)
843 {
844   struct Plugin *plugin = cls;
845   uint32_t type32 = type;
846   struct GNUNET_SQ_QueryParam params[] = {GNUNET_SQ_query_param_uint64 (
847                                             &next_uid),
848                                           GNUNET_SQ_query_param_uint32 (
849                                             &type32),
850                                           GNUNET_SQ_query_param_end};
851
852   GNUNET_assert (type != GNUNET_BLOCK_TYPE_ANY);
853   if (GNUNET_OK != GNUNET_SQ_bind (plugin->selZeroAnon, params))
854   {
855     proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
856     return;
857   }
858   execute_get (plugin, plugin->selZeroAnon, proc, proc_cls);
859 }
860
861
862 /**
863  * Get results for a particular key in the datastore.
864  *
865  * @param cls closure
866  * @param next_uid return the result with lowest uid >= next_uid
867  * @param random if true, return a random result instead of using next_uid
868  * @param key maybe NULL (to match all entries)
869  * @param type entries of which type are relevant?
870  *     Use 0 for any type.
871  * @param proc function to call on the matching value;
872  *        will be called with NULL if nothing matches
873  * @param proc_cls closure for @a proc
874  */
875 static void
876 sqlite_plugin_get_key (void *cls,
877                        uint64_t next_uid,
878                        bool random,
879                        const struct GNUNET_HashCode *key,
880                        enum GNUNET_BLOCK_Type type,
881                        PluginDatumProcessor proc,
882                        void *proc_cls)
883 {
884   struct Plugin *plugin = cls;
885   uint64_t rvalue;
886   int use_rvalue = random;
887   uint32_t type32 = (uint32_t) type;
888   int use_type = GNUNET_BLOCK_TYPE_ANY != type;
889   int use_key = NULL != key;
890   sqlite3_stmt *stmt = plugin->get[use_rvalue * 4 + use_key * 2 + use_type];
891   struct GNUNET_SQ_QueryParam params[] =
892     {GNUNET_SQ_query_param_uint64 (&next_uid),
893      GNUNET_SQ_query_param_uint64 (&rvalue),
894      GNUNET_SQ_query_param_auto_from_type (key),
895      GNUNET_SQ_query_param_uint32 (&type32),
896      GNUNET_SQ_query_param_end};
897
898   /* SQLite doesn't like it when you try to bind a parameter greater than the
899    * last numbered parameter, but unused parameters in the middle are OK.
900    */
901   if (! use_type)
902   {
903     params[3] = (struct GNUNET_SQ_QueryParam) GNUNET_SQ_query_param_end;
904     if (! use_key)
905     {
906       params[2] = (struct GNUNET_SQ_QueryParam) GNUNET_SQ_query_param_end;
907       if (! use_rvalue)
908         params[1] = (struct GNUNET_SQ_QueryParam) GNUNET_SQ_query_param_end;
909     }
910   }
911   if (random)
912   {
913     rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX);
914     next_uid = 0;
915   }
916   else
917     rvalue = 0;
918
919   if (GNUNET_OK != GNUNET_SQ_bind (stmt, params))
920   {
921     proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
922     return;
923   }
924   execute_get (plugin, stmt, proc, proc_cls);
925 }
926
927
928 /**
929  * Context for #repl_proc() function.
930  */
931 struct ReplCtx
932 {
933
934   /**
935    * Function to call for the result (or the NULL).
936    */
937   PluginDatumProcessor proc;
938
939   /**
940    * Closure for @e proc.
941    */
942   void *proc_cls;
943
944   /**
945    * UID to use.
946    */
947   uint64_t uid;
948
949   /**
950    * Yes if UID was set.
951    */
952   int have_uid;
953 };
954
955
956 /**
957  * Wrapper for the processor for #sqlite_plugin_get_replication().
958  * Decrements the replication counter and calls the original
959  * processor.
960  *
961  * @param cls closure
962  * @param key key for the content
963  * @param size number of bytes in @a data
964  * @param data content stored
965  * @param type type of the content
966  * @param priority priority of the content
967  * @param anonymity anonymity-level for the content
968  * @param replication replication-level for the content
969  * @param expiration expiration time for the content
970  * @param uid unique identifier for the datum;
971  *        maybe 0 if no unique identifier is available
972  * @return #GNUNET_OK for normal return,
973  *         #GNUNET_NO to delete the item
974  */
975 static int
976 repl_proc (void *cls,
977            const struct GNUNET_HashCode *key,
978            uint32_t size,
979            const void *data,
980            enum GNUNET_BLOCK_Type type,
981            uint32_t priority,
982            uint32_t anonymity,
983            uint32_t replication,
984            struct GNUNET_TIME_Absolute expiration,
985            uint64_t uid)
986 {
987   struct ReplCtx *rc = cls;
988   int ret;
989
990   if (GNUNET_SYSERR == rc->have_uid)
991     rc->have_uid = GNUNET_NO;
992   ret = rc->proc (rc->proc_cls,
993                   key,
994                   size,
995                   data,
996                   type,
997                   priority,
998                   anonymity,
999                   replication,
1000                   expiration,
1001                   uid);
1002   if (NULL != key)
1003   {
1004     rc->uid = uid;
1005     rc->have_uid = GNUNET_YES;
1006   }
1007   return ret;
1008 }
1009
1010
1011 /**
1012  * Get a random item for replication.  Returns a single random item
1013  * from those with the highest replication counters.  The item's
1014  * replication counter is decremented by one IF it was positive before.
1015  * Call @a proc with all values ZERO or NULL if the datastore is empty.
1016  *
1017  * @param cls closure
1018  * @param proc function to call the value (once only).
1019  * @param proc_cls closure for @a proc
1020  */
1021 static void
1022 sqlite_plugin_get_replication (void *cls,
1023                                PluginDatumProcessor proc,
1024                                void *proc_cls)
1025 {
1026   struct Plugin *plugin = cls;
1027   struct ReplCtx rc;
1028   uint64_t rvalue;
1029   uint32_t repl;
1030   struct GNUNET_SQ_QueryParam params_sel_repl[] =
1031     {GNUNET_SQ_query_param_uint64 (&rvalue),
1032      GNUNET_SQ_query_param_uint32 (&repl),
1033      GNUNET_SQ_query_param_end};
1034   struct GNUNET_SQ_QueryParam params_upd_repl[] =
1035     {GNUNET_SQ_query_param_uint64 (&rc.uid), GNUNET_SQ_query_param_end};
1036
1037   GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
1038                    "datastore-sqlite",
1039                    "Getting random block based on replication order.\n");
1040   if (SQLITE_ROW != sqlite3_step (plugin->maxRepl))
1041   {
1042     GNUNET_SQ_reset (plugin->dbh, plugin->maxRepl);
1043     /* DB empty */
1044     proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
1045     return;
1046   }
1047   repl = sqlite3_column_int (plugin->maxRepl, 0);
1048   GNUNET_SQ_reset (plugin->dbh, plugin->maxRepl);
1049   rvalue = GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX);
1050   if (GNUNET_OK != GNUNET_SQ_bind (plugin->selRepl, params_sel_repl))
1051   {
1052     proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
1053     return;
1054   }
1055   rc.have_uid = GNUNET_SYSERR;
1056   rc.proc = proc;
1057   rc.proc_cls = proc_cls;
1058   execute_get (plugin, plugin->selRepl, &repl_proc, &rc);
1059   if (GNUNET_YES == rc.have_uid)
1060   {
1061     if (GNUNET_OK != GNUNET_SQ_bind (plugin->updRepl, params_upd_repl))
1062     {
1063       proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
1064       return;
1065     }
1066     if (SQLITE_DONE != sqlite3_step (plugin->updRepl))
1067       LOG_SQLITE (plugin,
1068                   GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
1069                   "sqlite3_step");
1070     GNUNET_SQ_reset (plugin->dbh, plugin->updRepl);
1071   }
1072   if (GNUNET_SYSERR == rc.have_uid)
1073   {
1074     /* proc was not called at all so far, do it now. */
1075     proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
1076   }
1077 }
1078
1079
1080 /**
1081  * Get a random item that has expired or has low priority.
1082  * Call @a proc with all values ZERO or NULL if the datastore is empty.
1083  *
1084  * @param cls closure
1085  * @param proc function to call the value (once only).
1086  * @param proc_cls closure for @a proc
1087  */
1088 static void
1089 sqlite_plugin_get_expiration (void *cls,
1090                               PluginDatumProcessor proc,
1091                               void *proc_cls)
1092 {
1093   struct Plugin *plugin = cls;
1094   sqlite3_stmt *stmt;
1095   struct GNUNET_TIME_Absolute now;
1096   struct GNUNET_SQ_QueryParam params[] = {GNUNET_SQ_query_param_absolute_time (
1097                                             &now),
1098                                           GNUNET_SQ_query_param_end};
1099
1100   GNUNET_log_from (
1101     GNUNET_ERROR_TYPE_DEBUG,
1102     "sqlite",
1103     "Getting random block based on expiration and priority order.\n");
1104   now = GNUNET_TIME_absolute_get ();
1105   stmt = plugin->selExpi;
1106   if (GNUNET_OK != GNUNET_SQ_bind (stmt, params))
1107   {
1108     proc (proc_cls, NULL, 0, NULL, 0, 0, 0, 0, GNUNET_TIME_UNIT_ZERO_ABS, 0);
1109     return;
1110   }
1111   execute_get (plugin, stmt, proc, proc_cls);
1112 }
1113
1114
1115 /**
1116  * Get all of the keys in the datastore.
1117  *
1118  * @param cls closure
1119  * @param proc function to call on each key
1120  * @param proc_cls closure for @a proc
1121  */
1122 static void
1123 sqlite_plugin_get_keys (void *cls, PluginKeyProcessor proc, void *proc_cls)
1124 {
1125   struct Plugin *plugin = cls;
1126   struct GNUNET_HashCode key;
1127   struct GNUNET_SQ_ResultSpec results[] =
1128     {GNUNET_SQ_result_spec_auto_from_type (&key), GNUNET_SQ_result_spec_end};
1129   sqlite3_stmt *stmt;
1130   int ret;
1131
1132   GNUNET_assert (NULL != proc);
1133   if (SQLITE_OK != sq_prepare (plugin->dbh, "SELECT hash FROM gn091", &stmt))
1134   {
1135     LOG_SQLITE (plugin,
1136                 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
1137                 "sqlite_prepare");
1138     proc (proc_cls, NULL, 0);
1139     return;
1140   }
1141   while (SQLITE_ROW == (ret = sqlite3_step (stmt)))
1142   {
1143     if (GNUNET_OK == GNUNET_SQ_extract_result (stmt, results))
1144       proc (proc_cls, &key, 1);
1145     else
1146       GNUNET_break (0);
1147   }
1148   if (SQLITE_DONE != ret)
1149     LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite_step");
1150   sqlite3_finalize (stmt);
1151   proc (proc_cls, NULL, 0);
1152 }
1153
1154
1155 /**
1156  * Drop database.
1157  *
1158  * @param cls our plugin context
1159  */
1160 static void
1161 sqlite_plugin_drop (void *cls)
1162 {
1163   struct Plugin *plugin = cls;
1164
1165   plugin->drop_on_shutdown = GNUNET_YES;
1166 }
1167
1168
1169 /**
1170  * Remove a particular key in the datastore.
1171  *
1172  * @param cls closure
1173  * @param key key for the content
1174  * @param size number of bytes in data
1175  * @param data content stored
1176  * @param cont continuation called with success or failure status
1177  * @param cont_cls continuation closure for @a cont
1178  */
1179 static void
1180 sqlite_plugin_remove_key (void *cls,
1181                           const struct GNUNET_HashCode *key,
1182                           uint32_t size,
1183                           const void *data,
1184                           PluginRemoveCont cont,
1185                           void *cont_cls)
1186 {
1187   struct Plugin *plugin = cls;
1188   struct GNUNET_SQ_QueryParam params[] =
1189     {GNUNET_SQ_query_param_auto_from_type (key),
1190      GNUNET_SQ_query_param_fixed_size (data, size),
1191      GNUNET_SQ_query_param_end};
1192
1193   if (GNUNET_OK != GNUNET_SQ_bind (plugin->remove, params))
1194   {
1195     cont (cont_cls, key, size, GNUNET_SYSERR, "bind failed");
1196     return;
1197   }
1198   if (SQLITE_DONE != sqlite3_step (plugin->remove))
1199   {
1200     LOG_SQLITE (plugin,
1201                 GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
1202                 "sqlite3_step");
1203     GNUNET_SQ_reset (plugin->dbh, plugin->remove);
1204     cont (cont_cls, key, size, GNUNET_SYSERR, "sqlite3_step failed");
1205     return;
1206   }
1207   int changes = sqlite3_changes (plugin->dbh);
1208   GNUNET_SQ_reset (plugin->dbh, plugin->remove);
1209   if (0 == changes)
1210   {
1211     cont (cont_cls, key, size, GNUNET_NO, NULL);
1212     return;
1213   }
1214   if (NULL != plugin->env->duc)
1215     plugin->env->duc (plugin->env->cls,
1216                       -(size + GNUNET_DATASTORE_ENTRY_OVERHEAD));
1217   cont (cont_cls, key, size, GNUNET_OK, NULL);
1218 }
1219
1220
1221 /**
1222  * Get an estimate of how much space the database is
1223  * currently using.
1224  *
1225  * @param cls the `struct Plugin`
1226  * @return the size of the database on disk (estimate)
1227  */
1228 static void
1229 sqlite_plugin_estimate_size (void *cls, unsigned long long *estimate)
1230 {
1231   struct Plugin *plugin = cls;
1232   sqlite3_stmt *stmt;
1233   uint64_t pages;
1234   uint64_t page_size;
1235
1236 #if ENULL_DEFINED
1237   char *e;
1238 #endif
1239
1240   if (NULL == estimate)
1241     return;
1242   if (SQLITE_VERSION_NUMBER < 3006000)
1243   {
1244     GNUNET_log_from (
1245       GNUNET_ERROR_TYPE_WARNING,
1246       "datastore-sqlite",
1247       _ ("sqlite version to old to determine size, assuming zero\n"));
1248     *estimate = 0;
1249     return;
1250   }
1251   CHECK (SQLITE_OK == sqlite3_exec (plugin->dbh, "VACUUM", NULL, NULL, ENULL));
1252   CHECK (SQLITE_OK == sqlite3_exec (plugin->dbh,
1253                                     "PRAGMA auto_vacuum=INCREMENTAL",
1254                                     NULL,
1255                                     NULL,
1256                                     ENULL));
1257   CHECK (SQLITE_OK == sq_prepare (plugin->dbh, "PRAGMA page_count", &stmt));
1258   if (SQLITE_ROW == sqlite3_step (stmt))
1259     pages = sqlite3_column_int64 (stmt, 0);
1260   else
1261     pages = 0;
1262   sqlite3_finalize (stmt);
1263   CHECK (SQLITE_OK == sq_prepare (plugin->dbh, "PRAGMA page_size", &stmt));
1264   CHECK (SQLITE_ROW == sqlite3_step (stmt));
1265   page_size = sqlite3_column_int64 (stmt, 0);
1266   sqlite3_finalize (stmt);
1267   GNUNET_log (
1268     GNUNET_ERROR_TYPE_INFO,
1269     _ (
1270       "Using sqlite page utilization to estimate payload (%llu pages of size %llu bytes)\n"),
1271     (unsigned long long) pages,
1272     (unsigned long long) page_size);
1273   *estimate = pages * page_size;
1274 }
1275
1276
1277 /**
1278  * Entry point for the plugin.
1279  *
1280  * @param cls the `struct GNUNET_DATASTORE_PluginEnvironment *`
1281  * @return NULL on error, othrewise the plugin context
1282  */
1283 void *
1284 libgnunet_plugin_datastore_sqlite_init (void *cls)
1285 {
1286   static struct Plugin plugin;
1287   struct GNUNET_DATASTORE_PluginEnvironment *env = cls;
1288   struct GNUNET_DATASTORE_PluginFunctions *api;
1289
1290   if (NULL != plugin.env)
1291     return NULL; /* can only initialize once! */
1292   memset (&plugin, 0, sizeof (struct Plugin));
1293   plugin.env = env;
1294   if (GNUNET_OK != database_setup (env->cfg, &plugin))
1295   {
1296     database_shutdown (&plugin);
1297     return NULL;
1298   }
1299   api = GNUNET_new (struct GNUNET_DATASTORE_PluginFunctions);
1300   api->cls = &plugin;
1301   api->estimate_size = &sqlite_plugin_estimate_size;
1302   api->put = &sqlite_plugin_put;
1303   api->get_key = &sqlite_plugin_get_key;
1304   api->get_replication = &sqlite_plugin_get_replication;
1305   api->get_expiration = &sqlite_plugin_get_expiration;
1306   api->get_zero_anonymity = &sqlite_plugin_get_zero_anonymity;
1307   api->get_keys = &sqlite_plugin_get_keys;
1308   api->drop = &sqlite_plugin_drop;
1309   api->remove_key = &sqlite_plugin_remove_key;
1310   GNUNET_log_from (GNUNET_ERROR_TYPE_INFO,
1311                    "sqlite",
1312                    _ ("Sqlite database running\n"));
1313   return api;
1314 }
1315
1316
1317 /**
1318  * Exit point from the plugin.
1319  *
1320  * @param cls the plugin context (as returned by "init")
1321  * @return always NULL
1322  */
1323 void *
1324 libgnunet_plugin_datastore_sqlite_done (void *cls)
1325 {
1326   char *fn;
1327   struct GNUNET_DATASTORE_PluginFunctions *api = cls;
1328   struct Plugin *plugin = api->cls;
1329
1330   GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG,
1331                    "sqlite",
1332                    "sqlite plugin is done\n");
1333   fn = NULL;
1334   if (plugin->drop_on_shutdown)
1335     fn = GNUNET_strdup (plugin->fn);
1336   database_shutdown (plugin);
1337   plugin->env = NULL;
1338   GNUNET_free (api);
1339   if (NULL != fn)
1340   {
1341     if (0 != unlink (fn))
1342       GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING, "unlink", fn);
1343     GNUNET_free (fn);
1344   }
1345   return NULL;
1346 }
1347
1348 /* end of plugin_datastore_sqlite.c */