Merge branch 'master' of ssh://gnunet.org/gnunet
[oweals/gnunet.git] / src / datastore / plugin_datastore_sqlite.c
index 710f1e0df1abb81fec07f53847c43925a67f0bf8..9ab50714faf014f8025af4532755c450c588551a 100644 (file)
@@ -1,6 +1,6 @@
  /*
   * This file is part of GNUnet
-  * Copyright (C) 2009, 2011 Christian Grothoff (and other contributing authors)
+  * Copyright (C) 2009, 2011 GNUnet e.V.
   *
   * GNUnet is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published
@@ -14,8 +14,8 @@
   *
   * You should have received a copy of the GNU General Public License
   * along with GNUnet; see the file COPYING.  If not, write to the
-  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-  * Boston, MA 02111-1307, USA.
+  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+  * Boston, MA 02110-1301, USA.
   */
 
 /**
@@ -210,7 +210,7 @@ create_indices (sqlite3 * dbh)
 #else
 #define ENULL &e
 #define ENULL_DEFINED 1
-#define CHECK(a) if (! a) { GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "%s\n", e); sqlite3_free(e); }
+#define CHECK(a) if (! (a)) { GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "%s\n", e); sqlite3_free(e); }
 #endif
 
 
@@ -229,35 +229,41 @@ database_setup (const struct GNUNET_CONFIGURATION_Handle *cfg,
 {
   sqlite3_stmt *stmt;
   char *afsdir;
-
 #if ENULL_DEFINED
   char *e;
 #endif
 
   if (GNUNET_OK !=
-      GNUNET_CONFIGURATION_get_value_filename (cfg, "datastore-sqlite",
-                                               "FILENAME", &afsdir))
+      GNUNET_CONFIGURATION_get_value_filename (cfg,
+                                               "datastore-sqlite",
+                                               "FILENAME",
+                                               &afsdir))
   {
     GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
-                              "datastore-sqlite", "FILENAME");
+                              "datastore-sqlite",
+                               "FILENAME");
     return GNUNET_SYSERR;
   }
   if (GNUNET_OK != GNUNET_DISK_file_test (afsdir))
   {
-    if (GNUNET_OK != GNUNET_DISK_directory_create_for_file (afsdir))
+    if (GNUNET_OK !=
+        GNUNET_DISK_directory_create_for_file (afsdir))
     {
       GNUNET_break (0);
       GNUNET_free (afsdir);
       return GNUNET_SYSERR;
     }
     /* database is new or got deleted, reset payload to zero! */
-    plugin->env->duc (plugin->env->cls, 0);
+    if (NULL != plugin->env->duc)
+      plugin->env->duc (plugin->env->cls,
+                        0);
   }
   /* afsdir should be UTF-8-encoded. If it isn't, it's a bug */
   plugin->fn = afsdir;
 
   /* Open database and precompile statements */
-  if (sqlite3_open (plugin->fn, &plugin->dbh) != SQLITE_OK)
+  if (SQLITE_OK !=
+      sqlite3_open (plugin->fn, &plugin->dbh))
   {
     GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "sqlite",
                      _("Unable to initialize SQLite: %s.\n"),
@@ -265,25 +271,32 @@ database_setup (const struct GNUNET_CONFIGURATION_Handle *cfg,
     return GNUNET_SYSERR;
   }
   CHECK (SQLITE_OK ==
-         sqlite3_exec (plugin->dbh, "PRAGMA temp_store=MEMORY", NULL, NULL,
+         sqlite3_exec (plugin->dbh,
+                       "PRAGMA temp_store=MEMORY", NULL, NULL,
                        ENULL));
   CHECK (SQLITE_OK ==
-         sqlite3_exec (plugin->dbh, "PRAGMA synchronous=OFF", NULL, NULL,
+         sqlite3_exec (plugin->dbh,
+                       "PRAGMA synchronous=OFF", NULL, NULL,
                        ENULL));
   CHECK (SQLITE_OK ==
-         sqlite3_exec (plugin->dbh, "PRAGMA legacy_file_format=OFF", NULL, NULL,
+         sqlite3_exec (plugin->dbh,
+                       "PRAGMA legacy_file_format=OFF", NULL, NULL,
                        ENULL));
   CHECK (SQLITE_OK ==
-         sqlite3_exec (plugin->dbh, "PRAGMA auto_vacuum=INCREMENTAL", NULL,
+         sqlite3_exec (plugin->dbh,
+                       "PRAGMA auto_vacuum=INCREMENTAL", NULL,
                        NULL, ENULL));
   CHECK (SQLITE_OK ==
-         sqlite3_exec (plugin->dbh, "PRAGMA locking_mode=EXCLUSIVE", NULL, NULL,
+         sqlite3_exec (plugin->dbh,
+                       "PRAGMA locking_mode=EXCLUSIVE", NULL, NULL,
                        ENULL));
   CHECK (SQLITE_OK ==
-         sqlite3_exec (plugin->dbh, "PRAGMA page_size=4092", NULL, NULL,
+         sqlite3_exec (plugin->dbh,
+                       "PRAGMA page_size=4092", NULL, NULL,
                        ENULL));
 
-  CHECK (SQLITE_OK == sqlite3_busy_timeout (plugin->dbh, BUSY_TIMEOUT_MS));
+  CHECK (SQLITE_OK ==
+         sqlite3_busy_timeout (plugin->dbh, BUSY_TIMEOUT_MS));
 
 
   /* We have to do it here, because otherwise precompiling SQL might fail */
@@ -291,6 +304,12 @@ database_setup (const struct GNUNET_CONFIGURATION_Handle *cfg,
          sq_prepare (plugin->dbh,
                      "SELECT 1 FROM sqlite_master WHERE tbl_name = 'gn090'",
                      &stmt));
+
+  /* FIXME: SQLite does not have unsigned integers! This is ok for the type column because
+   * we only test equality on it and can cast it to/from uint32_t. For repl, prio, and anonLevel
+   * we do math or inequality tests, so we can't handle the entire range of uint32_t.
+   * This will also cause problems for expiration times after 294247-01-10-04:00:54 UTC.
+   */
   if ((sqlite3_step (stmt) == SQLITE_DONE) &&
       (sqlite3_exec
        (plugin->dbh,
@@ -546,7 +565,9 @@ sqlite_plugin_put (void *cls,
   switch (n)
   {
   case SQLITE_DONE:
-    plugin->env->duc (plugin->env->cls, size + GNUNET_DATASTORE_ENTRY_OVERHEAD);
+    if (NULL != plugin->env->duc)
+      plugin->env->duc (plugin->env->cls,
+                        size + GNUNET_DATASTORE_ENTRY_OVERHEAD);
     GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "sqlite",
                      "Stored new entry (%u bytes)\n",
                      size + GNUNET_DATASTORE_ENTRY_OVERHEAD);
@@ -593,9 +614,7 @@ sqlite_plugin_put (void *cls,
  * @param cls the plugin context (state for this module)
  * @param uid unique identifier of the datum
  * @param delta by how much should the priority
- *     change?  If priority + delta < 0 the
- *     priority should be set to 0 (never go
- *     negative).
+ *     change?
  * @param expire new expiration time should be the
  *     MAX of any existing expiration time and
  *     this value
@@ -605,7 +624,7 @@ sqlite_plugin_put (void *cls,
 static void
 sqlite_plugin_update (void *cls,
                       uint64_t uid,
-                      int delta,
+                      uint32_t delta,
                       struct GNUNET_TIME_Absolute expire,
                       PluginUpdateCont cont,
                       void *cont_cls)
@@ -690,7 +709,8 @@ execute_get (struct Plugin *plugin,
         LOG_SQLITE (plugin,
                     GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
                     "sqlite3_reset");
-      if (GNUNET_OK == delete_by_rowid (plugin, rowid))
+      if ( (GNUNET_OK == delete_by_rowid (plugin, rowid)) &&
+           (NULL != plugin->env->duc) )
         plugin->env->duc (plugin->env->cls,
                           -(size + GNUNET_DATASTORE_ENTRY_OVERHEAD));
       break;
@@ -709,7 +729,9 @@ execute_get (struct Plugin *plugin,
       LOG_SQLITE (plugin,
                   GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
                   "sqlite3_reset");
-    if ((GNUNET_NO == ret) && (GNUNET_OK == delete_by_rowid (plugin, rowid)))
+    if ( (GNUNET_NO == ret) &&
+         (GNUNET_OK == delete_by_rowid (plugin, rowid)) &&
+         (NULL != plugin->env->duc) )
       plugin->env->duc (plugin->env->cls,
                         -(size + GNUNET_DATASTORE_ENTRY_OVERHEAD));
     return;