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