gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r278 - in GNUnet/src: applications applications/sqstore_sql


From: durner
Subject: [GNUnet-SVN] r278 - in GNUnet/src: applications applications/sqstore_sqlite include
Date: Wed, 16 Feb 2005 13:35:01 -0800 (PST)

Author: durner
Date: 2005-02-16 13:35:00 -0800 (Wed, 16 Feb 2005)
New Revision: 278

Modified:
   GNUnet/src/applications/Makefile.am
   GNUnet/src/applications/sqstore_sqlite/sqlite.c
   GNUnet/src/include/gnunet_protocols.h
Log:
First try (aka "compiles")

Modified: GNUnet/src/applications/Makefile.am
===================================================================
--- GNUnet/src/applications/Makefile.am 2005-02-16 21:28:06 UTC (rev 277)
+++ GNUnet/src/applications/Makefile.am 2005-02-16 21:35:00 UTC (rev 278)
@@ -2,6 +2,10 @@
  MYSQL_DIR = sqstore_mysql
 endif
 
+if HAVE_SQLITE
+ SQLITE_DIR = sqstore_sqlite
+endif
+
 if !MINGW
  TESTBED_DIR = testbed
 endif
@@ -21,6 +25,7 @@
  pingpong \
  session \
  $(MYSQL_DIR) \
+ $(SQLITE_DIR) \
  stats \
  tbench \
  template \

Modified: GNUnet/src/applications/sqstore_sqlite/sqlite.c
===================================================================
--- GNUnet/src/applications/sqstore_sqlite/sqlite.c     2005-02-16 21:28:06 UTC 
(rev 277)
+++ GNUnet/src/applications/sqstore_sqlite/sqlite.c     2005-02-16 21:35:00 UTC 
(rev 278)
@@ -1,6 +1,6 @@
 /*
      This file is part of GNUnet.
-     (C) 2001 - 2004 Christian Grothoff (and other contributing authors)
+     (C) 2001 - 2005 Christian Grothoff (and other contributing authors)
 
      GNUnet is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published
@@ -22,13 +22,16 @@
  * @file applications/sqstore_sqlite/sqlite.c
  * @brief SQLite based implementation of the sqstore service
  * @author Nils Durner
- *
+ * @todo Estimation of DB size
+ * @todo Apply fixes from MySQL module
+ * 
  * Database: SQLite
  */
 
 #include "platform.h"
 #include "gnunet_util.h"
 #include "gnunet_sqstore_service.h"
+#include "gnunet_protocols.h"
 #include <sqlite3.h>
 
 #define DEBUG_SQLITE NO
@@ -38,14 +41,14 @@
  * a failure of the command 'cmd' with the message given
  * by strerror(errno).
  */
-#define DIE_SQLITE(cmd, dbh) do { errexit(_("'%s' failed at %s:%d with error: 
%s\n"), cmd, __FILE__, __LINE__, sqlite3_errmsg(dbh->dbf)); } while(0);
+#define DIE_SQLITE(cmd) do { errexit(_("'%s' failed at %s:%d with error: 
%s\n"), cmd, __FILE__, __LINE__, sqlite3_errmsg(dbh->dbf)); } while(0);
 
 /**
  * Log an error message at log-level 'level' that indicates
  * a failure of the command 'cmd' on file 'filename'
  * with the message given by strerror(errno).
  */
-#define LOG_SQLITE(level, cmd, dbh) do { LOG(level, _("'%s' failed at %s:%d 
with error: %s\n"), cmd, __FILE__, __LINE__, sqlite3_errmsg(dbh->dbf)); } 
while(0);
+#define LOG_SQLITE(level, cmd) do { LOG(level, _("'%s' failed at %s:%d with 
error: %s\n"), cmd, __FILE__, __LINE__, sqlite3_errmsg(dbh->dbf)); } while(0);
 
 
 /**
@@ -53,24 +56,39 @@
  */
 typedef struct {
   sqlite3 *dbf; 
-  unsigned int i;          /* database index */
-  unsigned int n;          /* total number of databases */
   Mutex DATABASE_Lock_;
   char *fn;                /* filename of this bucket */
-  double count;            /* number of rows in the db */
   double payload;          /* bytes used */
-  double inserted;         /* inserted blocks */
-  double indexed;          /* indexed blocks */
   unsigned int lastSync;
   
   /* Precompiled SQL */
-  sqlite3_stmt *getContent, *writeContent, *updPrio, *getRndCont1,
-    *getRndCont2, *exists, *updContent;
+  sqlite3_stmt *exists, *countContent, *updPrio, *insertContent;
 } sqliteHandle;
 
-static sqliteHandle * dbh;
+static sqliteHandle *dbh;
 
 
+static Datastore_Datum * assembleDatum(sqlite3_stmt *stmt);
+static double getStat(char *key);
+static int setStat(char *key, double val);
+static SQstore_ServiceAPI *provide_module_sqstore_sqlite(
+       CoreAPIForApplication *capi);
+static void release_module_sqstore_sqlite();
+static int sqlite_iterate(unsigned int type, Datum_Iterator iter,
+       void *closure, int sort);
+static int iterateLowPriority(unsigned int type, Datum_Iterator iter,
+       void * closure);
+static int iterateExpirationTime(unsigned int type, Datum_Iterator iter,
+       void * closure);
+static int get(const HashCode160 * key, unsigned int type, Datum_Iterator iter,
+       void * closure);
+static int put(const HashCode160 * key, const Datastore_Value * value);
+static int del(const HashCode160 * key, const Datastore_Value * value);
+static int update(const HashCode160 * key, const Datastore_Value * value,
+       int delta);
+static unsigned long long getSize();
+static void drop();
+
 /**
  * @brief Encode a binary buffer "in" of size n bytes so that it contains
  *        no instances of characters '\'' or '\000'.  The output is
@@ -129,22 +147,91 @@
 }
 
 /**
+ * @brief Decode the string "in" into binary data and write it into "out".
+ * @param in input
+ * @param out output
+ * @param num size of the output buffer
+ * @return number of output bytes, -1 on error
+ */
+static int sqlite_decode_binary_n(const unsigned char *in, unsigned char *out,
+       unsigned int num){
+  char c;
+  unsigned char *start = out;
+  
+  while((c = *in) && (out - start < num)) {
+    if (c == 1) {
+      in++;
+      *out = *in - 1;
+    }
+    else
+      *out = c;
+    
+    in++;
+    out++;
+  }
+  
+  return (int) (out - start);
+}
+
+/**
+ * Given a full row from gn070 table 
(size,type,prio,anonLevel,expire,hash,value),
+ * assemble it into a Datastore_Datum representation.
+ */
+static Datastore_Datum * assembleDatum(sqlite3_stmt *stmt) {
+
+  Datastore_Datum * datum;
+  int contentSize;
+    
+  contentSize = sqlite3_column_int(stmt, 0) - sizeof(Datastore_Value);
+  
+  if (contentSize < 0)
+       return NULL; /* error */
+       
+  if (sqlite3_column_bytes(stmt, 5) > sizeof(HashCode160) * 2 + 1 ||
+               sqlite3_column_bytes(stmt, 6) > contentSize * 2 + 1) {
+                       
+               LOG(LOG_WARNING,
+                       _("SQL Database corrupt, ignoring result.\n"));
+               return NULL;
+  }
+
+  datum = MALLOC(sizeof(Datastore_Datum) + contentSize);
+  datum->value.size = htonl(contentSize + sizeof(Datastore_Value));
+  datum->value.type = htonl(sqlite3_column_int(stmt, 1));
+  datum->value.prio = htonl(sqlite3_column_int(stmt, 2));
+  datum->value.anonymityLevel = htonl(sqlite3_column_int(stmt, 3));
+  datum->value.expirationTime = htonll(sqlite3_column_int64(stmt, 4));
+       
+       if (sqlite_decode_binary_n(sqlite3_column_blob(stmt, 5), (char *) 
&datum->key,
+                               sizeof(HashCode160)) != sizeof(HashCode160) ||
+                       sqlite_decode_binary_n(sqlite3_column_blob(stmt, 6), 
(char *) &datum[1], 
+                               contentSize) != contentSize) {
+                       
+               LOG(LOG_WARNING,
+                       _("SQL Database corrupt, ignoring result.\n"));
+               return NULL;
+       }
+
+  return datum;
+}
+
+
+/**
  * @brief Get database statistics
- * @param dbh database
  * @param key kind of stat to retrieve
  * @return SYSERR on error, the value otherwise
  */
 static double getStat(char *key) {
   int i;
   sqlite3_stmt *stmt;
-  double ret;
+  double ret = SYSERR;
   char *dummy;
 
   i = sqlite3_prepare(dbh->dbf, 
-    "Select fileOffset from data where hash = ?", 42, &stmt,
+    "Select anonLevel from gn070 where hash = ?", 42, &stmt,
     (const char **) &dummy);
   if (i == SQLITE_OK) {
-    sqlite3_bind_blob(stmt, 1, key, strlen(key), SQLITE_STATIC);
+    sqlite3_bind_text(stmt, 1, key, strlen(key), SQLITE_STATIC);
     i = sqlite3_step(stmt);
     
     if (i == SQLITE_DONE) {
@@ -160,8 +247,7 @@
   
   if (i != SQLITE_OK) {
     LOG_SQLITE(LOG_ERROR, 
-        "sqlite_getStat",
-        dbh);
+        "sqlite_getStat");
     return SYSERR;
   }
   
@@ -170,7 +256,6 @@
 
 /**
  * @brief set database statistics
- * @param dbh database
  * @param key statistic to set
  * @param val value to set
  * @return SYSERR on error, OK otherwise
@@ -180,12 +265,13 @@
   char *dummy;
 
   if (sqlite3_prepare(dbh->dbf,
-        "REPLACE into data(hash, fileOffset) values (?, ?)", 49,
+        "REPLACE into gn070(hash, anonLevel, type) values (?, ?, ?)", 58,
         &stmt, (const char **) &dummy) == SQLITE_OK) {
-    sqlite3_bind_blob(stmt, 1, key, strlen(key), SQLITE_STATIC);
+    sqlite3_bind_text(stmt, 1, key, strlen(key), SQLITE_STATIC);
     sqlite3_bind_double(stmt, 2, val);
+    sqlite3_bind_int(stmt, 3, RESERVED_BLOCK);
     if (sqlite3_step(stmt) != SQLITE_DONE) {
-      LOG_SQLITE(LOG_ERROR, "sqlite_setStat", dbh);
+      LOG_SQLITE(LOG_ERROR, "sqlite_setStat");
 
       return SYSERR;
     }
@@ -201,124 +287,173 @@
  * @brief write all statistics to the db
  */
 static void syncStats() {
-  setStat(dbh, "PAYLOAD", dbh->payload);
-  setStat(dbh, "COUNT", dbh->count);
-  setStat(dbh, "INSERTED", dbh->inserted);
-  setStat(dbh, "INDEXED", dbh->indexed);
+  setStat("PAYLOAD", dbh->payload);
   
   dbh->lastSync = 0;
 }
 
-/**
- * Call a method for each key in the database and
- * call the callback method on it. 
- *
- * @param type limit the iteration to entries of this
- *   type. 0 for all entries.
- * @param iter the callback method
- * @param closure argument to all callback calls
- * @return the number of results, SYSERR if the
- *   iter is non-NULL and aborted the iteration
- */
-static int iterateLowPriority(unsigned int type,
-                             Datum_Iterator iter,
-                             void * closure) {
-  sqliteHandle *dbh = handle;
+SQstore_ServiceAPI *
+provide_module_sqstore_sqlite(CoreAPIForApplication * capi) {
+  static SQstore_ServiceAPI api;
+
+  char *dummy, *dir, *afsdir;
+  size_t nX;
   sqlite3_stmt *stmt;
-  ContentIndex ce;
-  void *result;
-  int count = 0;
-  int len;
-  char *dummy, *escapedCol6, *col6;
 
 #if DEBUG_SQLITE
-  LOG(LOG_DEBUG, "SQLite: iterating through the database\n");
+  LOG(LOG_DEBUG, "SQLite: initializing database\n");
 #endif 
 
-  MUTEX_LOCK(&dbh->DATABASE_Lock_);
+  dbh = MALLOC(sizeof(sqliteHandle));
+  
+  dbh->payload = 0;
+  dbh->lastSync = 0;
 
-  if (sqlite3_prepare(dbh->dbf, "SELECT content, type, priority, doubleHash, "
-           "fileOffset, fileIndex, hash FROM data where hash not in ('COUNT', "
-           "'PAYLOAD', 'INSERTED', 'INDEXED')", 142, &stmt,
-           (const char **) &dummy) != SQLITE_OK) {
-    LOG_SQLITE(LOG_ERROR, "sqlite_query", dbh);
-    MUTEX_UNLOCK(&dbh->DATABASE_Lock_);
-    return(SYSERR);
-  }
+  afsdir = getFileName("FS", "DIR",
+                                                _("Configuration file must 
specify directory for "
+                                                "storing FS data in section 
'%s' under '%s'.\n"));
+  dir = MALLOC(strlen(afsdir) + 8 + 2); /* 8 = "content/" */
+  strcpy(dir, afsdir);
+  strcat(dir, "/content/");
+  FREE(afsdir);
+  mkdirp(dir);
+  nX = strlen(dir) + 6 + 4 + 256;  /* 6 = "gnunet", 4 = ".dat" */
+  dbh->fn = MALLOC(strlen(dir) + 6 + 4 + 256);
+  SNPRINTF(dbh->fn, nX, "%s/gnunet.dat", dir);
 
-  while (sqlite3_step(stmt) == SQLITE_ROW) { 
-    char *escapedRes;
+  if (sqlite3_open(dbh->fn, &dbh->dbf) != SQLITE_OK) {
+    LOG(LOG_ERROR, 
+        _("Unable to initialize SQLite.\n"));
+    FREE(dbh->fn);
+    FREE(dbh);
+    return NULL;
+  }
+  
+  sqlite3_exec(dbh->dbf, "PRAGMA temp_store=MEMORY", NULL, NULL, NULL);
+  sqlite3_exec(dbh->dbf, "PRAGMA synchronous=OFF", NULL, NULL, NULL);
+  sqlite3_exec(dbh->dbf, "PRAGMA count_changes=OFF", NULL, NULL, NULL);
+  
+  sqlite3_prepare(dbh->dbf, "Select 1 from sqlite_master where tbl_name"
+    " = 'gn070'", 52, &stmt, (const char**) &dummy);
+  if (sqlite3_step(stmt) == SQLITE_DONE) {
+    if (sqlite3_exec(dbh->dbf, "CREATE TABLE gn070 ("
+           "  size integer NOT NULL default 0,"
+           "  type integer NOT NULL default 0,"
+           "  prio integer NOT NULL default 0,"
+           "  anonLevel integer NOT NULL default 0,"
+           "  expire integer NOT NULL default 0,"
+           "  hash text NOT NULL default '',"
+           "  value blob NOT NULL default '')", NULL, NULL,
+           NULL) != SQLITE_OK) {
+      LOG_SQLITE(LOG_ERROR, "sqlite_query");
+      FREE(dbh->fn);
+      FREE(dbh);
+      return NULL;
+    }    
+  }
+  sqlite3_finalize(stmt);
     
-    escapedRes = (char *) sqlite3_column_blob(stmt, 0);
-    if (strlen(escapedRes) > 0) {
-      result = MALLOC(strlen(escapedRes) + 1);
-      len = sqlite_decode_binary(escapedRes, result);
-    } else {
-      result = NULL;
-      len = 0;
-    }
+  sqlite3_exec(dbh->dbf, "CREATE INDEX idx_hash ON gn070 (hash)",
+       NULL, NULL, NULL);
+  sqlite3_exec(dbh->dbf, "CREATE INDEX idx_prio ON gn070 (prio)",
+       NULL, NULL, NULL);
+  sqlite3_exec(dbh->dbf, "CREATE INDEX idx_expire ON gn070 (expire)",
+       NULL, NULL, NULL);
 
-    escapedCol6 = (char *) sqlite3_column_blob(stmt, 6);
-    col6 = MALLOC(strlen(escapedCol6) + 1);
-    sqlite_decode_binary(escapedCol6, col6);
+  if (sqlite3_prepare(dbh->dbf, "SELECT count(*) FROM gn070 where hash=?", 39,
+         &dbh->countContent, (const char **) &dummy) != SQLITE_OK ||
+     
+      sqlite3_prepare(dbh->dbf, "SELECT length(hash), length(value), "
+         "from gn070 WHERE hash=?", 59,
+         &dbh->exists, (const char **) &dummy) != SQLITE_OK ||
 
-    ce.type = htons(sqlite3_column_int(stmt, 1));
-    ce.importance = htonl(sqlite3_column_int(stmt, 2));
-    if (ntohs(ce.type)==LOOKUP_TYPE_3HASH) {
-      char *escapedHash, *hash;
-      
-      escapedHash = (char *) sqlite3_column_blob(stmt, 3);
-      hash = MALLOC(strlen(escapedHash) + 1);
-      if (sqlite_decode_binary(escapedHash, hash) == sizeof(HashCode160))
-        memcpy(&ce.hash, 
-               hash,
-               sizeof(HashCode160));
-        FREE(hash);
-      } else {
-        memcpy(&ce.hash, col6, sizeof(HashCode160));
-    }
+      sqlite3_prepare(dbh->dbf, "UPDATE gn070 SET prio = prio + ? where "
+              "hash = ? and value = ? and prio + ? < ?", 78, &dbh->updPrio,
+              (const char **) &dummy) != SQLITE_OK ||
 
-    ce.fileOffset = htonl(sqlite3_column_int(stmt, 4));
-    ce.fileNameIndex = htons(sqlite3_column_int(stmt, 5));       
-    callback((HashCode160*) col6,
-       &ce,
-       result, /* freed by callback */
-       len,
-       data);
-    FREE(col6);
-    count++;
+      sqlite3_prepare(dbh->dbf, "insert into gn070 (size, type, prio, "
+              "anonLevel, expire, hash, value) values "
+              "(?, ?, ?, ?, ?, ?, ?)", 97, &dbh->insertContent,
+              (const char **) &dummy) != SQLITE_OK) {
+        
+      LOG_SQLITE(LOG_ERROR, "precompiling");
+      FREE(dbh->fn);
+      FREE(dbh);
+      return NULL;
   }
-    
-  sqlite3_finalize(stmt);
-  MUTEX_UNLOCK(&dbh->DATABASE_Lock_);
   
+  dbh->payload = getStat("PAYLOAD");
+  
+  if (dbh->payload == SYSERR) {
+    FREE(dbh->fn);
+    FREE(dbh);
+    return NULL;    
+  }
+    
+  MUTEX_CREATE_RECURSIVE(&dbh->DATABASE_Lock_);  
+
+  api.getSize = &getSize;
+  api.put = &put;
+  api.get = &get;
+  api.iterateLowPriority = &iterateLowPriority;
+  api.iterateExpirationTime = &iterateExpirationTime;
+  api.del = &del;
+  api.drop = &drop;
+  api.update = &update;
+  return &api;
+}
+
+static void sqlite_shutdown() {
 #if DEBUG_SQLITE
-  LOG(LOG_DEBUG, "SQLite: reached end of database\n");
-#endif 
+  LOG(LOG_DEBUG, "SQLite: closing database\n");
+#endif
+
+       if (! dbh)
+               return;
+
+  MUTEX_DESTROY(&dbh->DATABASE_Lock_);
+
+  sqlite3_finalize(dbh->countContent);
+  sqlite3_finalize(dbh->exists);
+  sqlite3_finalize(dbh->updPrio);
+  sqlite3_finalize(dbh->insertContent);
   
-  return count;
+  syncStats();
+
+  if (sqlite3_close(dbh->dbf) != SQLITE_OK)
+    LOG_SQLITE(LOG_ERROR, "sqlite_close");
+  
+  FREE(dbh->fn);
+  FREE(dbh);
+  dbh = NULL;
 }
 
+/**
+ * Shutdown the module.
+ */
+static void release_module_sqstore_sqlite() {
+       sqlite_shutdown();
+}
 
 /**
  * Call a method for each key in the database and
  * call the callback method on it. 
  *
- * @param handle the database
+ * @param type entries of which type should be considered?
+ *        Use 0 for any type.
  * @param callback the callback method
  * @param data second argument to all callback calls
+ * @param sort 0 to order by expiration, 1 to order by prio
  * @return the number of items stored in the content database
  */
-static int iterateExpirationTime(unsigned int type,
-                                Datum_Iterator iter,
-                                void * closure) {
-  sqliteHandle *dbh = handle;
+static int sqlite_iterate(unsigned int type, Datum_Iterator iter,
+       void *closure, int sort) {
+       
   sqlite3_stmt *stmt;
-  ContentIndex ce;
-  void *result;
   int count = 0;
-  int len;
-  char *dummy, *escapedCol6, *col6;
+  char *dummy;
+  char scratch[107];
+  Datastore_Datum * datum;
 
 #if DEBUG_SQLITE
   LOG(LOG_DEBUG, "SQLite: iterating through the database\n");
@@ -326,55 +461,36 @@
 
   MUTEX_LOCK(&dbh->DATABASE_Lock_);
 
-  if (sqlite3_prepare(dbh->dbf, "SELECT content, type, priority, doubleHash, "
-           "fileOffset, fileIndex, hash FROM data where hash not in ('COUNT', "
-           "'PAYLOAD', 'INSERTED', 'INDEXED')", 142, &stmt,
+       sprintf(scratch, "SELECT size, type, prio, anonLevel, expire, hash, 
value "
+                                        "FROM gn070 %s order by %s ASC",
+                                        type ? "where type = :1" : "", sort ? 
"prio" : "expire");
+
+  if (sqlite3_prepare(dbh->dbf, scratch, -1, &stmt,
            (const char **) &dummy) != SQLITE_OK) {
-    LOG_SQLITE(LOG_ERROR, "sqlite_query", dbh);
+    LOG_SQLITE(LOG_ERROR, "sqlite_query");
     MUTEX_UNLOCK(&dbh->DATABASE_Lock_);
     return(SYSERR);
   }
 
-  while (sqlite3_step(stmt) == SQLITE_ROW) { 
-    char *escapedRes;
-    
-    escapedRes = (char *) sqlite3_column_blob(stmt, 0);
-    if (strlen(escapedRes) > 0) {
-      result = MALLOC(strlen(escapedRes) + 1);
-      len = sqlite_decode_binary(escapedRes, result);
-    } else {
-      result = NULL;
-      len = 0;
+       if (type)
+               sqlite3_bind_int(stmt, 1, type);
+
+  while (sqlite3_step(stmt) == SQLITE_ROW) {
+               datum = assembleDatum(stmt);
+               
+    if (datum == NULL) {
+      LOG(LOG_WARNING,
+                       _("Invalid data in database.  Please verify 
integrity!\n"));
+      continue; 
     }
 
-    escapedCol6 = (char *) sqlite3_column_blob(stmt, 6);
-    col6 = MALLOC(strlen(escapedCol6) + 1);
-    sqlite_decode_binary(escapedCol6, col6);
-
-    ce.type = htons(sqlite3_column_int(stmt, 1));
-    ce.importance = htonl(sqlite3_column_int(stmt, 2));
-    if (ntohs(ce.type)==LOOKUP_TYPE_3HASH) {
-      char *escapedHash, *hash;
-      
-      escapedHash = (char *) sqlite3_column_blob(stmt, 3);
-      hash = MALLOC(strlen(escapedHash) + 1);
-      if (sqlite_decode_binary(escapedHash, hash) == sizeof(HashCode160))
-        memcpy(&ce.hash, 
-               hash,
-               sizeof(HashCode160));
-        FREE(hash);
-      } else {
-        memcpy(&ce.hash, col6, sizeof(HashCode160));
+    if( SYSERR == iter(&datum->key, &datum->value, closure) ) {
+      count = SYSERR;
+      FREE(datum);
+      break;
     }
+    FREE(datum);
 
-    ce.fileOffset = htonl(sqlite3_column_int(stmt, 4));
-    ce.fileNameIndex = htons(sqlite3_column_int(stmt, 5));       
-    callback((HashCode160*) col6,
-       &ce,
-       result, /* freed by callback */
-       len,
-       data);
-    FREE(col6);
     count++;
   }
     
@@ -383,12 +499,47 @@
   
 #if DEBUG_SQLITE
   LOG(LOG_DEBUG, "SQLite: reached end of database\n");
-#endif 
-  
+#endif
+
   return count;
 }
 
 /**
+ * Call a method for each key in the database and
+ * call the callback method on it. 
+ *
+ * @param type limit the iteration to entries of this
+ *   type. 0 for all entries.
+ * @param iter the callback method
+ * @param closure argument to all callback calls
+ * @return the number of results, SYSERR if the
+ *   iter is non-NULL and aborted the iteration
+ */
+static int iterateLowPriority(unsigned int type,
+                             Datum_Iterator iter,
+                             void * closure) {
+  
+  return sqlite_iterate(type, iter, closure, 1);
+}
+
+
+/**
+ * Call a method for each key in the database and
+ * call the callback method on it. 
+ *
+ * @param handle the database
+ * @param callback the callback method
+ * @param data second argument to all callback calls
+ * @return the number of items stored in the content database
+ */
+static int iterateExpirationTime(unsigned int type,
+                                Datum_Iterator iter,
+                                void * closure) {
+  return sqlite_iterate(type, iter, closure, 0);
+}
+
+
+/**
  * Iterate over all entries matching a particular key and
  * type.
  *
@@ -403,91 +554,117 @@
               unsigned int type,
               Datum_Iterator iter,
               void * closure) {
-  sqliteHandle *dbh = handle;
-  char *escapedHash, *escapedRes;
-  int len, ret;
+  char *escapedHash = NULL;
+  int len, ret, count = 0;
+  sqlite3_stmt *stmt;
+  char scratch[97], *dummy;
+  int bind = 1;
+  Datastore_Datum *datum;
 
 #if DEBUG_SQLITE
   {
     char block[33];
-    hash2enc(query, (EncName *) block);
-    LOG(LOG_DEBUG, "SQLite: read content %s\n", block);
+    hash2enc(query, (EncName *) key);
+    LOG(LOG_DEBUG, "SQLite: read content %s\n", key);
   }
 #endif 
 
   MUTEX_LOCK(&dbh->DATABASE_Lock_);
-  escapedHash = MALLOC(sizeof(HashCode160)*2 + 2);
-  len = sqlite_encode_binary((char *) query, sizeof(HashCode160), escapedHash);
-
-  ret = sqlite3_bind_blob(dbh->getContent, 1, escapedHash, len,
-    SQLITE_TRANSIENT);
-  if (ret == SQLITE_OK) {
-    if((ret = sqlite3_step(dbh->getContent)) == SQLITE_DONE) {
-#if DEBUG_SQLITE
-      LOG(LOG_DEBUG, "SQLite: not found\n");
-#endif
-      /* no error, just data not found */
-      sqlite3_reset(dbh->getContent);
-      FREE(escapedHash);
-      MUTEX_UNLOCK(&dbh->DATABASE_Lock_);
-      return SYSERR;
-    } else if (ret == SQLITE_ROW)
-        ret = SQLITE_OK;
+  
+  strcpy(scratch, "SELECT ");
+  
+  if (iter == NULL)
+       strcat(scratch, "count(*)");
+  else
+       strcat(scratch, "size, type, prio, anonLevel, expire, hash, value");
+  
+  strcat(scratch, " FROM gn070");
+  
+  if (type || key) {
+       strcat(scratch, " WHERE ");
+       
+       if (type) {
+               strcat(scratch, "type = :1");
+               
+               if (key)
+                       strcat(scratch, " and ");
+       }
+       
+       if (key)
+               strcat(scratch, "hash = :2");
   }
- 
-  if (ret != SQLITE_OK) {
-    LOG_SQLITE(LOG_ERROR, "sqlite_query", dbh);
-    FREE(escapedHash);
+  
+  if (sqlite3_prepare(dbh->dbf, scratch, -1, &stmt,
+           (const char **) &dummy) != SQLITE_OK) {
+    LOG_SQLITE(LOG_ERROR, "sqlite_query");
     MUTEX_UNLOCK(&dbh->DATABASE_Lock_);
-    return SYSERR;
-  }
+    return(SYSERR);
+  }  
   
-  escapedRes = (char *) sqlite3_column_blob(dbh->getContent, 0);
-  if (strlen(escapedRes) > 0) {
-    *result = MALLOC(strlen(escapedRes) + 1);
-    len = sqlite_decode_binary(escapedRes, *result);
-  } else {
-    *result = NULL;
-    len = 0;
+  if (type)
+       ret = sqlite3_bind_int(stmt, bind++, type);
+  else
+       ret = SQLITE_OK;
+       
+  if (key && ret == SQLITE_OK) {
+         escapedHash = MALLOC(sizeof(HashCode160)*2 + 2);
+         len = sqlite_encode_binary((char *) key, sizeof(HashCode160), 
escapedHash);
+       
+         ret = sqlite3_bind_blob(stmt, bind, escapedHash, len,
+           SQLITE_TRANSIENT);
   }
-  
-  ce->type = htons(sqlite3_column_int(dbh->getContent, 1));
-  ce->importance = htonl(sqlite3_column_int(dbh->getContent, 2));
-  if (ntohs(ce->type)==LOOKUP_TYPE_3HASH) {
-    char *doubleHashEsc, *doubleHash;
+
+  if (ret == SQLITE_OK) {
     
-    doubleHashEsc = (char *) sqlite3_column_blob(dbh->getContent, 3);
-    doubleHash = MALLOC(strlen(doubleHashEsc));
-    
-    if (sqlite_decode_binary(doubleHashEsc, doubleHash) == sizeof(HashCode160))
-      memcpy(&ce->hash, doubleHash, sizeof(HashCode160));
-    FREE(doubleHash);
-  } else {
-    memcpy(&ce->hash, query, sizeof(HashCode160));
-  }
+    while ((ret = sqlite3_step(stmt)) == SQLITE_ROW) {
+                       if (iter == NULL) {
+                               datum = assembleDatum(stmt);
+                               
+                   if (datum == NULL) {
+                     LOG(LOG_WARNING,
+                                       _("Invalid data in database.  Please 
verify integrity!\n"));
+                     continue; 
+                   }
+#if DEBUG_SQLITE
+                               LOG(LOG_DEBUG,
+                                       "Found in database block with type 
%u.\n",
+                                       ntohl(*(int*)&((&datum->value)[1])));
+#endif
+                               if( SYSERR == iter(&datum->key,
+                                                       &datum->value, 
+                                                       closure) ) {
 
-  ce->fileOffset = htonl(sqlite3_column_int(dbh->getContent, 4));
-  ce->fileNameIndex = htons(sqlite3_column_int(dbh->getContent, 5));
+                                       count = SYSERR;
+                     FREE(datum);
+                     break;
+                   }
+                   FREE(datum);                                                
                
+                         
+                         count++;
+                       }
+                       else
+                               count += sqlite3_column_int(stmt, 0);
+    }
 
-  sqlite3_reset(dbh->getContent);
+    FREENONNULL(escapedHash);
+    sqlite3_finalize(stmt);
 
-  if (prio != 0) {
-    sqlite3_bind_int(dbh->updPrio, 1, prio);
-    sqlite3_bind_blob(dbh->updPrio, 2, escapedHash, strlen(escapedHash),
-                      SQLITE_TRANSIENT);
-    if (sqlite3_step(dbh->updPrio) != SQLITE_DONE)
-      LOG_SQLITE(LOG_ERROR, "updating priority", dbh);
-    sqlite3_reset(dbh->updPrio);
+         if (ret != SQLITE_OK) {
+           LOG_SQLITE(LOG_ERROR, "sqlite_query");
+           MUTEX_UNLOCK(&dbh->DATABASE_Lock_);
+           return SYSERR;
+         }
   }
-
-  MUTEX_UNLOCK(&dbh->DATABASE_Lock_);
-  FREE(escapedHash);
+  else
+       LOG_SQLITE(LOG_ERROR, "sqlite_query");
   
+       MUTEX_UNLOCK(&dbh->DATABASE_Lock_);
+  
 #if DEBUG_SQLITE
   LOG(LOG_DEBUG, "SQLite: done reading content\n");
 #endif 
   
-  return len;
+  return count;
 }
 
 /**
@@ -498,22 +675,17 @@
  */
 static int put(const HashCode160 * key, 
               const Datastore_Value * value) {
-  sqliteHandle *dbh = handle;
-  HashCode160 tripleHash;
-  char *doubleHash;
   char *escapedBlock;
   char *escapedHash;
-  int n, blockLen, hashLen, dhashLen;
+  int n, hashLen, blockLen;
   sqlite3_stmt *stmt;
   unsigned long rowLen;
-
-#if DEBUG_SQLITE
-  {
-    char block[33];
-    hash2enc(&ce->hash, (EncName *) block);
-    LOG(LOG_DEBUG, "SQLite: write content %s\n", block);
+       unsigned int contentSize;
+       
+  if ( (ntohl(value->size) <= sizeof(Datastore_Value)) ) {
+    BREAK();
+    return SYSERR;
   }
-#endif 
 
   MUTEX_LOCK(&dbh->DATABASE_Lock_);
   
@@ -521,84 +693,40 @@
     syncStats(dbh);
   
   rowLen = 0;
+  contentSize = ntohl(value->size)-sizeof(Datastore_Value);
+ 
   escapedHash = MALLOC(2*sizeof(HashCode160)+1);
-  
-  if(ntohs(ce->type) == LOOKUP_TYPE_3HASH) {
-    hash(&ce->hash, 
-       sizeof(HashCode160),
-   &tripleHash);
-    sqlite_encode_binary((char *)&tripleHash, sizeof(HashCode160), 
escapedHash);
-    doubleHash = MALLOC(2*sizeof(HashCode160)+1);
-    sqlite_encode_binary((char *)&ce->hash, sizeof(HashCode160), doubleHash);
-  } else {
-    doubleHash = NULL;
-    sqlite_encode_binary((char *)&ce->hash, sizeof(HashCode160), escapedHash);
-  }
-  
-  escapedBlock = MALLOC(2 * len + 1);
-  sqlite_encode_binary((char *)block, len, escapedBlock);
-  
-  /* Do we have this content already? */
-  sqlite3_bind_blob(dbh->exists, 1, escapedHash, strlen(escapedHash),
-                    SQLITE_TRANSIENT);
-  n = sqlite3_step(dbh->exists);
-  if (n == SQLITE_DONE)
-    stmt = dbh->writeContent;
-  else if (n == SQLITE_ROW) {
-    rowLen -= sqlite3_column_int(dbh->exists, 1) - 
-      sqlite3_column_int(dbh->exists, 2) - sqlite3_column_int(dbh->exists, 3) -
-      4 * sizeof(int);
-    if (dbh->payload > rowLen)
-      dbh->payload -= rowLen;
-    else
-      dbh->payload = 0;
-    stmt = dbh->updContent;
-  }
-  else {
-    sqlite3_reset(dbh->exists);
-    LOG_SQLITE(LOG_ERROR, "sqlite_query", dbh);
-    FREE(escapedBlock);
-    FREE(escapedHash);
-    FREENONNULL(doubleHash);
-    MUTEX_UNLOCK(&dbh->DATABASE_Lock_);
-    return SYSERR;
-  }
-  sqlite3_reset(dbh->exists);
+  hashLen = sqlite_encode_binary((char *) key, sizeof(HashCode160), 
escapedHash);
+    
+  escapedBlock = MALLOC(2 * contentSize + 1);
+  blockLen = sqlite_encode_binary((char *) &value[1], contentSize, 
escapedBlock);
 
-  blockLen = strlen(escapedBlock);
-  hashLen = strlen(escapedHash);
-  dhashLen = doubleHash ? strlen(doubleHash) : 0;
+#if DEBUG_SQLITE
+  LOG(LOG_DEBUG,
+      "Storing in database block with type %u.\n",
+      ntohl(*(int*)&value[1]));
+#endif
 
-  sqlite3_bind_blob(stmt, 1, escapedBlock, blockLen,
-                    SQLITE_TRANSIENT);
-  sqlite3_bind_int(stmt, 2, ntohl(ce->importance));
-  sqlite3_bind_int(stmt, 3, ntohl(ce->fileOffset));
-  sqlite3_bind_int(stmt, 4, ntohs(ce->fileNameIndex));
-  sqlite3_bind_blob(stmt, 5, doubleHash, dhashLen, SQLITE_TRANSIENT);
-  sqlite3_bind_int(stmt, 6, ntohs(ce->type));
-  sqlite3_bind_blob(stmt, 7, escapedHash, hashLen,
-                    SQLITE_TRANSIENT);
+       stmt = dbh->insertContent;
+       sqlite3_bind_double(stmt, 1, ntohl(value->size));
+       sqlite3_bind_double(stmt, 2, ntohl(value->type));
+       sqlite3_bind_double(stmt, 3, ntohl(value->prio));
+       sqlite3_bind_double(stmt, 4, ntohl(value->anonymityLevel));
+       sqlite3_bind_double(stmt, 5, ntohll(value->expirationTime));
+       sqlite3_bind_blob(stmt, 6, escapedHash, hashLen, SQLITE_TRANSIENT);
+       sqlite3_bind_blob(stmt, 7, escapedBlock, blockLen, SQLITE_TRANSIENT);
+       
   n = sqlite3_step(stmt);
   FREE(escapedBlock);
   FREE(escapedHash);
-  FREENONNULL(doubleHash);
   sqlite3_reset(stmt);
   if(n != SQLITE_DONE) {
-    LOG_SQLITE(LOG_ERROR, "sqlite_query", dbh);
+    LOG_SQLITE(LOG_ERROR, "sqlite_query");
     MUTEX_UNLOCK(&dbh->DATABASE_Lock_);
     return SYSERR;
   }
-  rowLen = hashLen + dhashLen + blockLen + sizeof(int) * 4;
-  if (stmt == dbh->writeContent) {
-    dbh->count++;
-
-    if (len)
-      dbh->inserted++;
-    else
-      dbh->indexed++;
-    dbh->lastSync++;
-  }
-  dbh->payload += rowLen;
+  dbh->lastSync++;
+  dbh->payload += (hashLen + blockLen + sizeof(long long) * 5);
   MUTEX_UNLOCK(&dbh->DATABASE_Lock_);
  
 #if DEBUG_SQLITE
@@ -609,15 +737,20 @@
 }
 
 /**
- * Delete a particular block from the DB.
+ * Delete an item from the datastore.
+ *   
+ * @param value maybe NULL, then all items under the
+ *        given key are deleted
+ * @return the number of items deleted, 0 if
+ *        none were found, SYSERR on errors
  */
 static int del(const HashCode160 * key, 
               const Datastore_Value * value) {
-  sqliteHandle * dbh = handle;
   char *escapedHash, *dummy;
   size_t n;
   sqlite3_stmt *stmt;
   unsigned long rowLen;
+  int deleted, hashLen;
 
 #if DEBUG_SQLITE
   LOG(LOG_DEBUG, "SQLite: delete block\n");
@@ -629,84 +762,139 @@
     syncStats(dbh);
   
   escapedHash = MALLOC(2 * sizeof(HashCode160) + 1);
-  sqlite_encode_binary((char *)name, sizeof(HashCode160), escapedHash);
+  hashLen = sqlite_encode_binary((char *)key, sizeof(HashCode160), 
escapedHash);
 
-  sqlite3_bind_blob(dbh->exists, 1, escapedHash, strlen(escapedHash),
-                    SQLITE_TRANSIENT);
-  n = sqlite3_step(dbh->exists);
-  if (n == SQLITE_ROW) {
-    unsigned int contlen = sqlite3_column_int(dbh->exists, 3);
-  
-    rowLen = sqlite3_column_int(dbh->exists, 1) - 
-      sqlite3_column_int(dbh->exists, 2) - contlen - 4 * sizeof(int);
-    
-    if (dbh->payload > rowLen)
-      dbh->payload -= rowLen;
-    else
-      dbh->payload = 0;
-    
-    if (contlen) {
-      if (dbh->inserted > 0)
-        dbh->inserted--;
-    } else {
-      if (dbh->indexed > 0)
-        dbh->indexed--;
-    }
-    dbh->lastSync++;
-  }
-  sqlite3_reset(dbh->exists);
+       if (!value) {
+         sqlite3_bind_blob(dbh->exists, 1, escapedHash, hashLen,
+                           SQLITE_TRANSIENT);
+         while(sqlite3_step(dbh->exists) == SQLITE_ROW) {        
+           rowLen = sqlite3_column_int(dbh->exists, 0) + 
+             sqlite3_column_int(dbh->exists, 1) + 5 * sizeof(int);
+           
+           if (dbh->payload > rowLen)
+             dbh->payload -= rowLen;
+           else
+             dbh->payload = 0;
+           
+           dbh->lastSync++;
+         }
+         sqlite3_reset(dbh->exists);
 
-  n = sqlite3_prepare(dbh->dbf, "DELETE FROM data WHERE hash = ?", 31,
-      &stmt, (const char **) &dummy);
-  if (n == SQLITE_OK) {
-    sqlite3_bind_blob(stmt, 1, escapedHash, strlen(escapedHash),
-                      SQLITE_TRANSIENT);
-    n = sqlite3_step(stmt);
-  }
-  
+         n = sqlite3_prepare(dbh->dbf, "DELETE FROM gn070 WHERE hash = ?", 32, 
+               &stmt, (const char **) &dummy);
+         if (n == SQLITE_OK) {
+           sqlite3_bind_blob(stmt, 1, escapedHash, hashLen, SQLITE_TRANSIENT);
+           n = sqlite3_step(stmt);
+         }
+       }
+       else {
+               sqlite3_stmt *stmt;
+
+         n = sqlite3_prepare(dbh->dbf, "DELETE FROM gn070 WHERE hash = ? and "
+                               "value = ? and size = ? and type = ? and prio = 
? and anonLevel = ? "
+                               "expire = ?", 114, &stmt, (const char **) 
&dummy);
+         if (n == SQLITE_OK) {
+               char *escapedBlock;
+               int hashLen, blockLen;
+               
+               escapedBlock = MALLOC(2 * 
(ntohl(value->size)-sizeof(Datastore_Value)) + 1);
+               
+               hashLen = strlen(escapedHash);
+               blockLen = strlen(escapedBlock);
+               
+           sqlite3_bind_blob(stmt, 1, escapedHash, hashLen, SQLITE_TRANSIENT);
+           sqlite3_bind_blob(stmt, 2, escapedBlock, blockLen, 
SQLITE_TRANSIENT);
+                       sqlite3_bind_double(stmt, 3, ntohl(value->size));
+                       sqlite3_bind_double(stmt, 4, ntohl(value->type));
+                       sqlite3_bind_double(stmt, 5, ntohl(value->prio));
+                       sqlite3_bind_double(stmt, 6, 
ntohl(value->anonymityLevel));
+                       sqlite3_bind_double(stmt, 7, 
ntohll(value->expirationTime));
+
+           n = sqlite3_step(stmt);
+           
+           FREE(escapedBlock);
+           
+           if (n == SQLITE_OK)
+               dbh->payload -= (hashLen + blockLen + 5 * sizeof(long long));
+         }
+       }
+       
+  deleted = (n == SQLITE_OK) ? sqlite3_changes(dbh->dbf) : SYSERR;
+         
   FREE(escapedHash);
   sqlite3_finalize(stmt);
 
   if(n != SQLITE_DONE) {
-    LOG_SQLITE(LOG_ERROR, "sqlite_query", dbh);
+    LOG_SQLITE(LOG_ERROR, "sqlite_query");
     MUTEX_UNLOCK(&dbh->DATABASE_Lock_);
     return SYSERR;
   }
 
-  dbh->count--;
-
   MUTEX_UNLOCK(&dbh->DATABASE_Lock_);
   
 #if DEBUG_SQLITE
-  LOG(LOG_DEBUG, "SQLite: block deleted\n");
+  LOG(LOG_DEBUG, "SQLite: %i block(s) deleted\n", deleted);
 #endif 
   
-  return OK;
+  return deleted;
 }
 
 /**
- * Estimate how many blocks can be stored in the DB
- * before the quota is reached.
- *
- * @param handle the database
- * @param quota the number of kb available for the DB
- * @return number of blocks left
- */ 
+ * Update the priority for a particular key
+ * in the datastore.
+ */
+static int update(const HashCode160 * key,
+                 const Datastore_Value * value,
+                 int delta) {
+       char *escapedHash, *escapedBlock;
+       int hashLen, blockLen, n;
+  unsigned long contentSize;
+       
+  MUTEX_LOCK(&dbh->DATABASE_Lock_);
+  contentSize = ntohl(value->size)-sizeof(Datastore_Value);
+
+  escapedHash = MALLOC(2*sizeof(HashCode160)+1);
+       hashLen = sqlite_encode_binary((const char *) key, sizeof(HashCode160),
+    escapedHash);
+
+  escapedBlock = MALLOC(2*contentSize+1);
+       blockLen = sqlite_encode_binary((const char *) value, contentSize,
+    escapedBlock);
+       
+       sqlite3_bind_int(dbh->updPrio, 1, delta);
+  sqlite3_bind_blob(dbh->updPrio, 2, escapedHash, hashLen, SQLITE_TRANSIENT);
+  sqlite3_bind_blob(dbh->updPrio, 3, escapedBlock, blockLen, SQLITE_TRANSIENT);
+       sqlite3_bind_int(dbh->updPrio, 4, delta);
+       sqlite3_bind_int64(dbh->updPrio, 5, LLONG_MAX);
+       
+       n = sqlite3_step(dbh->updPrio);
+       sqlite3_reset(dbh->updPrio);
+  
+  FREE(escapedHash);
+  FREE(escapedBlock);
+
+  MUTEX_UNLOCK(&dbh->DATABASE_Lock_);
+
+  return n == SQLITE_OK ? OK : SYSERR;
+}
+
+/**
+ * Get the current on-disk size of the SQ store.
+ * Estimates are fine, if that's the only thing
+ * available.
+ * @return number of bytes used on disk
+ */
 static unsigned long long getSize() {       
-  sqliteHandle *dbh = handle;
+       double ret;
 
   MUTEX_LOCK(&dbh->DATABASE_Lock_);
-  ret = (dbh->payload + dbh->indexed * 59 + dbh->inserted * 132) / 1024;
+  ret = dbh->payload * 1.0; /* FIXME 0.7: Find magic factor */
   MUTEX_UNLOCK(&dbh->DATABASE_Lock_);
 
 #if DEBUG_SQLITE
   LOG(LOG_DEBUG,
-      "SQLite: kbytes used: %.0f, quota: %i, inserted: %.0f, "
-      "indexed: %.0f\n",
-      ret, 
-      quota,
-      dbh->inserted, 
-      dbh->indexed);
+      "SQLite: database size: %.0f\n",
+      ret);
 #endif
   
   return ret;
@@ -717,217 +905,11 @@
  * guaranteed to be unloading of the module.
  */
 static void drop() {
-}
-
-
-SQstore_ServiceAPI *
-provide_module_sqstore_sqlite(CoreAPIForApplication * capi) {
-  static SQstore_ServiceAPI api;
-
-  char *dummy, *dir, *afsdir;
-  size_t nX;
-  sqlite3_stmt *stmt;
-
-#if DEBUG_SQLITE
-  LOG(LOG_DEBUG, "SQLite: initializing database\n");
-#endif 
-
-  dbh = MALLOC(sizeof(sqliteHandle));
-  
-  dbh->n = n;
-  dbh->i = i;
-  dbh->count = 0;
-  dbh->payload = 0;
-  dbh->inserted = 0;
-  dbh->indexed = 0;
-  dbh->lastSync = 0;
-
-  afsdir = getFileName("FS",
-                      "DIR",
-                      _("Configuration file must specify directory for "
-                        "storing FS data in section '%s' under '%s'.\n"));
-  dir = MALLOC(strlen(afsdir) + strlen(CONTENTDIR) + 2);
-  strcpy(dir, afsdir);
-  strcat(dir, "/");
-  strcat(dir, CONTENTDIR);
-  FREE(afsdir);
-  mkdirp(dir);
-  nX = strlen(dir) + 6 + 4 + 256;  /* 6 = "bucket", 4 = ".dat" */
-  dbh->fn = MALLOC(strlen(dir) + 6 + 4 + 256);
-  SNPRINTF(dbh->fn, nX, "%s/bucket.%u.%u.dat", dir, n, i);
-
-  if (sqlite3_open(dbh->fn, &dbh->dbf) != SQLITE_OK) {
-    LOG(LOG_ERROR, 
-        _("Unable to initialize SQLite.\n"));
-    FREE(dbh->fn);
-    FREE(dbh);
-    return NULL;
-  }
-  
-  sqlite3_exec(dbh->dbf, "PRAGMA temp_store=MEMORY", NULL, NULL, NULL);
-  sqlite3_exec(dbh->dbf, "PRAGMA synchronous=OFF", NULL, NULL, NULL);
-  sqlite3_exec(dbh->dbf, "PRAGMA count_changes=OFF", NULL, NULL, NULL);
-  
-  sqlite3_prepare(dbh->dbf, "Select 1 from sqlite_master where tbl_name"
-    " = 'data'", 51, &stmt, (const char**) &dummy);
-  if (sqlite3_step(stmt) == SQLITE_DONE) {
-    if (sqlite3_exec(dbh->dbf, "CREATE TABLE data ("
-           "  hash blob default '' PRIMARY KEY,"
-           "  priority integer default 0,"
-           "  type integer default 0,"
-           "  fileIndex integer default 0,"
-           "  fileOffset integer default 0,"
-           "  doubleHash blob default '',"
-           "  content blob default '')", NULL, NULL,
-           NULL) != SQLITE_OK) {
-      LOG_SQLITE(LOG_ERROR, 
-          "sqlite_query",
-          dbh);
-      FREE(dbh->fn);
-      FREE(dbh);
-      return NULL;
-    }
-  }
-  sqlite3_finalize(stmt);
-    
-  sqlite3_exec(dbh->dbf,
-                "CREATE INDEX idx_key ON data (priority)",
-                NULL, NULL, NULL);
-                   
-  if (sqlite3_prepare(dbh->dbf, "SELECT content, type, priority, " \
-         "doubleHash, fileOffset, fileIndex FROM data WHERE hash=?", 83,
-         &dbh->getContent, (const char **) &dummy) != SQLITE_OK ||
-         
-      sqlite3_prepare(dbh->dbf, "UPDATE data SET priority = priority + ? 
WHERE" \
-         " hash = ?", 54, &dbh->updPrio, (const char **) &dummy) != SQLITE_OK 
||
-         
-      sqlite3_prepare(dbh->dbf, "REPLACE INTO data "
-         "(content, priority, fileOffset, fileIndex, doubleHash, type, hash)"
-         " VALUES (?, ?, ?, ?, ?, ?, ?)", 113, &dbh->writeContent,
-         (const char **) &dummy) != SQLITE_OK ||
-         
-      sqlite3_prepare(dbh->dbf, "SELECT hash, type, priority, fileOffset, "
-         "fileIndex, content FROM data WHERE hash >= ? "
-         "AND (type = ? OR type = ?) LIMIT 1", 111,
-         &dbh->getRndCont1, (const char **) &dummy) != SQLITE_OK ||
-                  
-      sqlite3_prepare(dbh->dbf, "SELECT hash, type, priority, fileOffset, "
-         "fileIndex, content FROM data WHERE hash NOTNULL "
-         "AND (type = ? OR type = ?) LIMIT 1", 114, &dbh->getRndCont2,
-         (const char **) &dummy) != SQLITE_OK ||
-     
-      sqlite3_prepare(dbh->dbf, "SELECT length(hash), length(doubleHash), "
-         "length(content) from data WHERE hash=?", 79,
-         &dbh->exists, (const char **) &dummy) != SQLITE_OK ||
-         
-      sqlite3_prepare(dbh->dbf, "UPDATE data Set content = ?, priority = ?, "
-         "fileOffset = ?, fileIndex = ?, doubleHash = ?, type = ? WHERE "
-         "hash = ?", 113, &dbh->updContent,
-         (const char **) &dummy) != SQLITE_OK) {
-        
-      LOG_SQLITE(LOG_ERROR, 
-          "precompiling",
-          dbh);
-      FREE(dbh->fn);
-      FREE(dbh);
-      return NULL;
-  }
-  
-  dbh->count = getStat(dbh, "COUNT");
-  dbh->payload = getStat(dbh, "PAYLOAD");
-  dbh->inserted = getStat(dbh, "INSERTED");
-  dbh->indexed = getStat(dbh, "INDEXED");
-  
-  if (dbh->count == SYSERR ||
-      dbh->payload == SYSERR ||
-      dbh->inserted == SYSERR ||
-      dbh->indexed == SYSERR) {
-    FREE(dbh->fn);
-    FREE(dbh);
-    return NULL;    
-  }
-  
-  if (! dbh->count) {
-    if (sqlite3_prepare(dbh->dbf, "SELECT count(*) from data where hash not "
-          "in ('COUNT', 'PAYLOAD', 'INSERTED', 'INDEXED')", 87, &stmt,
-         (const char **) &dummy) != SQLITE_OK ||
-        sqlite3_step(stmt) != SQLITE_ROW) {
-          LOG_SQLITE(LOG_ERROR, 
-            "sqlite_count",
-            dbh);
-    }
-  
-    dbh->count = sqlite3_column_double(stmt, 0);
-  
-    sqlite3_finalize(stmt);
-  }
-  
-  if (! dbh->indexed) {
-    if (sqlite3_prepare(dbh->dbf, "SELECT count(*) from data where hash not "
-          "in ('COUNT', 'PAYLOAD', 'INSERTED', 'INDEXED') and "
-          "length(content) = 0", 111, &stmt,
-          (const char **) &dummy) != SQLITE_OK ||
-        sqlite3_step(stmt) != SQLITE_ROW) {
-          LOG_SQLITE(LOG_ERROR, 
-            "sqlite_count",
-            dbh);
-    }
-  
-    dbh->indexed = sqlite3_column_double(stmt, 0); 
-    
-    sqlite3_finalize(stmt);    
-  }
-
-  if (! dbh->inserted) {
-    if (sqlite3_prepare(dbh->dbf, "SELECT count(*) from data where hash not "
-          "in ('COUNT', 'PAYLOAD', 'INSERTED', 'INDEXED') and "
-          "length(content) != 0",
-          111, &stmt, (const char **) &dummy) != SQLITE_OK ||
-        sqlite3_step(stmt) != SQLITE_ROW) {
-          LOG_SQLITE(LOG_ERROR, 
-            "sqlite_count",
-            dbh);
-    }
-  
-    dbh->inserted = sqlite3_column_double(stmt, 0); 
-
-    sqlite3_finalize(stmt);    
-  }
-    
-  MUTEX_CREATE_RECURSIVE(&dbh->DATABASE_Lock_);  
-
-
-  api.getSize = &getSize;
-  api.put = &put;
-  api.get = &get;
-  api.iterateLowPriority = &iterateLowPriority;
-  api.iterateExpirationTime = &iterateExpirationTime;
-  api.del = &del;
-  api.drop = &drop;
-  api.update = NULL; /* FIXME! */
-  return &api;
-}
-
-/**
- * Shutdown the module.
- */
-void release_module_sqstore_sqlite() {
-  MUTEX_DESTROY(&dbh->DATABASE_Lock_);
-
-  sqlite3_finalize(dbh->getContent);
-  sqlite3_finalize(dbh->writeContent);
-  sqlite3_finalize(dbh->updPrio);
-  sqlite3_finalize(dbh->getRndCont1);
-  sqlite3_finalize(dbh->getRndCont2);
-  sqlite3_finalize(dbh->exists);
-  sqlite3_finalize(dbh->updContent);
-
-  sqlite3_close(dbh->dbf);
-  UNLINK(dbh->fn);
-
-  FREE(dbh->fn);
-  FREE(dbh);
-  dbh = NULL;
-}
+       char *fn = STRDUP(dbh->fn);
+       
+       sqlite_shutdown();
+       
+       UNLINK(fn);
+}
  
 /* end of sqlite.c */

Modified: GNUnet/src/include/gnunet_protocols.h
===================================================================
--- GNUnet/src/include/gnunet_protocols.h       2005-02-16 21:28:06 UTC (rev 
277)
+++ GNUnet/src/include/gnunet_protocols.h       2005-02-16 21:35:00 UTC (rev 
278)
@@ -391,6 +391,11 @@
 #define DHT_STRING2STRING_BLOCK 7
 
 /**
+ * Reserved for internal usage
+ */
+#define RESERVED_BLOCK 0xFFFFFFFE
+
+/**
  * Type of OnDemand encoded blocks.
  */
 #define ONDEMAND_BLOCK 0xFFFFFFFF





reply via email to

[Prev in Thread] Current Thread [Next in Thread]