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