gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r298 - GNUnet/src/applications/sqstore_sqlite


From: grothoff
Subject: [GNUnet-SVN] r298 - GNUnet/src/applications/sqstore_sqlite
Date: Thu, 24 Feb 2005 18:21:59 -0800 (PST)

Author: grothoff
Date: 2005-02-24 18:21:58 -0800 (Thu, 24 Feb 2005)
New Revision: 298

Modified:
   GNUnet/src/applications/sqstore_sqlite/sqlite.c
   GNUnet/src/applications/sqstore_sqlite/sqlitetest.c
Log:
extensive SQLITE bugfixes and code refactoring - almost there

Modified: GNUnet/src/applications/sqstore_sqlite/sqlite.c
===================================================================
--- GNUnet/src/applications/sqstore_sqlite/sqlite.c     2005-02-24 21:02:10 UTC 
(rev 297)
+++ GNUnet/src/applications/sqstore_sqlite/sqlite.c     2005-02-25 02:21:58 UTC 
(rev 298)
@@ -57,41 +57,54 @@
 typedef struct {
   sqlite3 *dbf; 
   Mutex DATABASE_Lock_;
-  char *fn;                /* filename of this bucket */
-  double payload;          /* bytes used */
+  /** filename of this bucket */
+  char *fn;        
+  /** bytes used */
+  double payload;          
   unsigned int lastSync;
   
-  /* Precompiled SQL */
+  /** Precompiled SQL */
   sqlite3_stmt *exists, *countContent, *updPrio, *insertContent, *migr;
   
-  /* Last migrated block */
+  /** Last migrated block */
   cron_t lastExp;
   unsigned int lastPrio;
 } sqliteHandle;
 
 static sqliteHandle *dbh;
 
+static int sq_prepare(const char *zSql,       /* SQL statement, UTF-8 encoded 
*/
+                     sqlite3_stmt **ppStmt) {  /* OUT: Statement handle */
+  char * dummy;
+  return sqlite3_prepare(dbh->dbf,
+                        zSql,
+                        strlen(zSql),
+                        ppStmt,
+                        (const char**) &dummy);
+}
 
-static Datastore_Datum * assembleDatum(sqlite3_stmt *stmt);
-static double getStat(char *key);
-static int setStat(char *key, double val);
-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();
-static void suspendMigration();
 
 /**
+ * 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() {       
+  double ret;
+
+  MUTEX_LOCK(&dbh->DATABASE_Lock_);
+  ret = dbh->payload * 1.0; /* FIXME 0.7: Find magic factor */
+  MUTEX_UNLOCK(&dbh->DATABASE_Lock_);
+#if DEBUG_SQLITE
+  LOG(LOG_DEBUG,
+      "SQLite: database size: %.0f\n",
+      ret);
+#endif 
+  return ret;
+}
+
+/**
  * @brief Encode a binary buffer "in" of size n bytes so that it contains
  *        no instances of characters '\'' or '\000'.  The output is
  *        null-terminated and can be used as a string value in an INSERT
@@ -100,7 +113,9 @@
  * @param n size of in
  * @param out output
  */
-static int sqlite_encode_binary(const unsigned char *in, int n, unsigned char 
*out){
+static int sqlite_encode_binary(const unsigned char *in, 
+                               int n, 
+                               unsigned char *out){
   char c;
   unsigned char *start = out;
   
@@ -130,8 +145,9 @@
  * @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){
+static int sqlite_decode_binary_n(const unsigned char *in, 
+                                 unsigned char *out,
+                                 unsigned int num){
   char c;
   unsigned char *start = out;
   
@@ -139,14 +155,11 @@
     if (c == 1) {
       in++;
       *out = *in - 1;
-    }
-    else
-      *out = c;
-    
+    } else
+      *out = c;    
     in++;
     out++;
-  }
-  
+  } 
   return (int) (out - start);
 }
 
@@ -165,21 +178,20 @@
  * 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 */
-       
+    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;
+      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);
@@ -188,17 +200,18 @@
   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;
-       }
-
+  
+  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;
 }
 
@@ -208,19 +221,21 @@
  * @param key kind of stat to retrieve
  * @return SYSERR on error, the value otherwise
  */
-static double getStat(char *key) {
+static double getStat(const char * key) {
   int i;
   sqlite3_stmt *stmt;
   double ret = SYSERR;
-  char *dummy;
   
   suspendMigration();
 
-  i = sqlite3_prepare(dbh->dbf, 
-    "Select anonLevel from gn070 where hash = ?", 42, &stmt,
-    (const char **) &dummy);
+  i = sq_prepare("Select anonLevel from gn070 where hash = ?",
+                &stmt);
   if (i == SQLITE_OK) {
-    sqlite3_bind_text(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) {
@@ -236,7 +251,7 @@
   
   if (i != SQLITE_OK) {
     LOG_SQLITE(LOG_ERROR, 
-        "sqlite_getStat");
+              "sqlite_getStat");
     return SYSERR;
   }
   
@@ -249,28 +264,34 @@
  * @param val value to set
  * @return SYSERR on error, OK otherwise
  */
-static int setStat(char *key, double val) {
+static int setStat(const char *key, 
+                  double val) {
   sqlite3_stmt *stmt;
-  char *dummy;
   
   suspendMigration();
 
-  if (sqlite3_prepare(dbh->dbf,
-        "REPLACE into gn070(hash, anonLevel, type) values (?, ?, ?)", 58,
-        &stmt, (const char **) &dummy) == SQLITE_OK) {
-    sqlite3_bind_text(stmt, 1, key, strlen(key), SQLITE_STATIC);
-    sqlite3_bind_double(stmt, 2, val);
-    sqlite3_bind_int(stmt, 3, RESERVED_BLOCK);
+  if (sq_prepare("REPLACE into gn070(hash, anonLevel, type) values (?, ?, ?)",
+                &stmt) == SQLITE_OK) {
+    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");
-
+      LOG_SQLITE(LOG_ERROR, 
+                "sqlite_setStat");
       return SYSERR;
     }
     sqlite3_finalize(stmt);
-
+    
     return OK;    
-  }
-  else
+  } else
     return SYSERR;
 }
 
@@ -278,160 +299,12 @@
  * @brief write all statistics to the db
  */
 static void syncStats() {
-  setStat("PAYLOAD", dbh->payload);
-  
+  setStat("PAYLOAD", 
+         dbh->payload);  
   dbh->lastSync = 0;
 }
 
-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->payload = 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) + 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);
-
-  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);
-    
-  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);
-
-  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 ||
-
-      sqlite3_prepare(dbh->dbf, "UPDATE gn070 SET prio = prio + ? where "
-              "hash = ? and value = ? and prio + ? < ?", 78, &dbh->updPrio,
-              (const char **) &dummy) != SQLITE_OK ||
-
-      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;
-  }
-  
-  dbh->payload = getStat("PAYLOAD");
-  
-  dbh->migr = NULL;
-  dbh->lastPrio = 0;
-  dbh->lastExp = 0;
-  
-  if (dbh->payload == SYSERR) {
-    FREE(dbh->fn);
-    FREE(dbh);
-    return NULL;    
-  }
-    
-  MUTEX_CREATE(&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: 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);
-  suspendMigration();
-  
-  syncStats();
-
-  if (sqlite3_close(dbh->dbf) != SQLITE_OK)
-    LOG_SQLITE(LOG_ERROR, "sqlite_close");
-  
-  FREE(dbh->fn);
-  FREE(dbh);
-  dbh = NULL;
-}
-
 /**
- * Shutdown the module.
- */
-void release_module_sqstore_sqlite() {
-  sqlite_shutdown();  
-}
-
-/**
  * Call a method for each key in the database and
  * call the callback method on it. 
  *
@@ -442,12 +315,13 @@
  * @param sort 0 to order by expiration, 1 to order by prio
  * @return the number of items stored in the content database
  */
-static int sqlite_iterate(unsigned int type, Datum_Iterator iter,
-       void *closure, int sort) {
+static int sqlite_iterate(unsigned int type, 
+                         Datum_Iterator iter,
+                         void *closure, 
+                         int sort) {
        
   sqlite3_stmt *stmt;
   int count = 0;
-  char *dummy;
   char scratch[200], *ptr;
   Datastore_Datum * datum;
   int bind;
@@ -459,19 +333,18 @@
   MUTEX_LOCK(&dbh->DATABASE_Lock_);
   
   if ((sort == 0 && !dbh->migr) || sort != 0) {
-    strcpy(scratch, "SELECT size, type, prio, anonLevel, expire, hash, value "
-             "FROM gn070 ");
+    strcpy(scratch, 
+          "SELECT size, type, prio, anonLevel, expire, hash, value "
+          "FROM gn070 ");
     ptr = scratch + 67;
     
     if (type) {
       strcpy(ptr, "where type = :1 ");
       ptr += 16;
-    }
-    
+    }    
     if (sort) {
       strcpy(ptr, "order by prio ASC");
-    }
-    else {
+    } else {
       if (!type) {
         strcpy(ptr, "where ");
         ptr += 6;
@@ -479,38 +352,42 @@
       strcpy(ptr, "expire > :2 and prio >= :3 order by expire ASC, prio ASC");
     }
   
-    if (sqlite3_prepare(dbh->dbf, scratch, -1, &stmt,
-             (const char **) &dummy) != SQLITE_OK) {
+    if (sq_prepare(scratch, 
+                  &stmt) != SQLITE_OK) {
       LOG_SQLITE(LOG_ERROR, "sqlite_query");
       MUTEX_UNLOCK(&dbh->DATABASE_Lock_);
       return(SYSERR);
     }
     
     dbh->migr = stmt;
-  }
-  else
+  } else
     if (sort == 0)
       stmt = dbh->migr;
   
   bind = 1;
   
-       if (type)
-               sqlite3_bind_int(stmt, bind++, type);
+  if (type)
+    sqlite3_bind_int(stmt, 
+                    bind++,
+                    type);
     
   if (!sort) {
-    sqlite3_bind_int(stmt, bind++, dbh->lastExp);
-    sqlite3_bind_int(stmt, bind, dbh->lastPrio);
+    sqlite3_bind_int(stmt,
+                    bind++,
+                    dbh->lastExp);
+    sqlite3_bind_int(stmt, 
+                    bind, 
+                    dbh->lastPrio);
   }
 
   while (sqlite3_step(stmt) == SQLITE_ROW) {
-               datum = assembleDatum(stmt);
-               
+    datum = assembleDatum(stmt);
+    
     if (datum == NULL) {
       LOG(LOG_WARNING,
-                       _("Invalid data in database.  Please verify 
integrity!\n"));
+         _("Invalid data in database.  Please verify integrity!\n"));
       continue; 
-    }
-    
+    }    
     MUTEX_UNLOCK(&dbh->DATABASE_Lock_);
 
     if( SYSERR == iter(&datum->key, &datum->value, closure) ) {
@@ -535,12 +412,14 @@
   MUTEX_UNLOCK(&dbh->DATABASE_Lock_);
   
 #if DEBUG_SQLITE
-  LOG(LOG_DEBUG, "SQLite: reached end of database\n");
+  LOG(LOG_DEBUG,
+      "SQLite: reached end of database\n");
 #endif
 
   return count;
 }
 
+
 /**
  * Call a method for each key in the database and
  * call the callback method on it. 
@@ -554,12 +433,10 @@
  */
 static int iterateLowPriority(unsigned int type,
                              Datum_Iterator iter,
-                             void * closure) {
-  
+                             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. 
@@ -575,8 +452,41 @@
   return sqlite_iterate(type, iter, closure, 0);
 }
 
+static void sqlite_shutdown() {
+#if DEBUG_SQLITE
+  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);
+  suspendMigration();  
+  syncStats();
+  if (sqlite3_close(dbh->dbf) != SQLITE_OK)
+    LOG_SQLITE(LOG_ERROR, "sqlite_close");
+  
+  FREE(dbh->fn);
+  FREE(dbh);
+  dbh = NULL;
+}
+
 /**
+ * Delete the database.  The next operation is
+ * guaranteed to be unloading of the module.
+ */
+static void drop() {
+  char *fn = STRDUP(dbh->fn);  
+  sqlite_shutdown();  
+  UNLINK(fn);
+}
+
+
+/**
  * Iterate over all entries matching a particular key and
  * type.
  *
@@ -594,7 +504,7 @@
   char *escapedHash = NULL;
   int len, ret, count = 0;
   sqlite3_stmt *stmt;
-  char scratch[97], *dummy;
+  char scratch[97];
   int bind = 1;
   Datastore_Datum *datum;
 
@@ -606,100 +516,96 @@
   }
 #endif 
 
-  MUTEX_LOCK(&dbh->DATABASE_Lock_);
-  
+  MUTEX_LOCK(&dbh->DATABASE_Lock_); 
   suspendMigration();
   
   strcpy(scratch, "SELECT ");
   
   if (iter == NULL)
-       strcat(scratch, "count(*)");
+    strcat(scratch, "count(*)");
   else
-       strcat(scratch, "size, type, prio, anonLevel, expire, hash, value");
-  
+    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");
+    strcat(scratch, " WHERE ");    
+    if (type) {
+      strcat(scratch, "type = :1");      
+      if (key)
+       strcat(scratch, " and ");
+    }    
+    if (key)
+      strcat(scratch, "hash = :2");
   }
   
-  if (sqlite3_prepare(dbh->dbf, scratch, -1, &stmt,
-           (const char **) &dummy) != SQLITE_OK) {
+  if (sq_prepare(scratch, 
+                &stmt) != SQLITE_OK) {
     LOG_SQLITE(LOG_ERROR, "sqlite_query");
     MUTEX_UNLOCK(&dbh->DATABASE_Lock_);
-    return(SYSERR);
+    return SYSERR;
   }  
   
   if (type)
-       ret = sqlite3_bind_int(stmt, bind++, type);
+    ret = sqlite3_bind_int(stmt,
+                          bind++,
+                          type);
   else
-       ret = SQLITE_OK;
+    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);
+  if (key && (ret == SQLITE_OK)) {
+    escapedHash = MALLOC(sizeof(HashCode160)*2 + 2);
+    len = sqlite_encode_binary((const char *) key, 
+                              sizeof(HashCode160), 
+                              escapedHash);    
+    ret = sqlite3_bind_blob(stmt,
+                           bind,
+                           escapedHash, 
+                           len,
+                           SQLITE_TRANSIENT);
   }
 
-  if (ret == SQLITE_OK) {
-    
+  if (ret == SQLITE_OK) {    
     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 (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])));
+       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) ) {
-
-                                       count = SYSERR;
-                     FREE(datum);
-                     break;
-                   }
-                   FREE(datum);                                                
                
-                         
-                         count++;
-                       }
-                       else
-                               count += sqlite3_column_int(stmt, 0);
-    }
-
+       if (SYSERR == iter(&datum->key,
+                          &datum->value, 
+                          closure) ) {
+         
+         count = SYSERR;
+         FREE(datum);
+         ret = SQLITE_DONE;
+         break;
+       }
+       FREE(datum);
+       count++;
+      } else
+       count += sqlite3_column_int(stmt, 0);
+    } 
     FREENONNULL(escapedHash);
-
-         if (ret != SQLITE_OK) {
-           LOG_SQLITE(LOG_ERROR, "sqlite_query");
+    if (ret != SQLITE_DONE) {
+      LOG_SQLITE(LOG_ERROR, "sqlite_query");
       sqlite3_finalize(stmt);
-           MUTEX_UNLOCK(&dbh->DATABASE_Lock_);
-           return SYSERR;
-         }
+      MUTEX_UNLOCK(&dbh->DATABASE_Lock_);
+      return SYSERR;
+    }
 
     sqlite3_finalize(stmt);
-  }
-  else
-       LOG_SQLITE(LOG_ERROR, "sqlite_query");
+  } else
+    LOG_SQLITE(LOG_ERROR, "sqlite_query");
   
-       MUTEX_UNLOCK(&dbh->DATABASE_Lock_);
+  MUTEX_UNLOCK(&dbh->DATABASE_Lock_);
   
 #if DEBUG_SQLITE
   LOG(LOG_DEBUG, "SQLite: done reading content\n");
@@ -721,13 +627,12 @@
   int n, hashLen, blockLen;
   sqlite3_stmt *stmt;
   unsigned long rowLen;
-       unsigned int contentSize;
+  unsigned int contentSize;
        
-  if ( (ntohl(value->size) <= sizeof(Datastore_Value)) ) {
+  if ( (ntohl(value->size) < sizeof(Datastore_Value)) ) {
     BREAK();
     return SYSERR;
   }
-
 #if DEBUG_SQLITE
   LOG(LOG_DEBUG,
       "Storing in database block with type %u.\n",
@@ -745,26 +650,31 @@
   contentSize = ntohl(value->size)-sizeof(Datastore_Value);
  
   escapedHash = MALLOC(2*sizeof(HashCode160)+1);
-  hashLen = sqlite_encode_binary((char *) key, sizeof(HashCode160), 
escapedHash);
+  hashLen = sqlite_encode_binary((const char *) key, 
+                                sizeof(HashCode160),
+                                escapedHash);
     
   escapedBlock = MALLOC(2 * contentSize + 1);
-  blockLen = sqlite_encode_binary((char *) &value[1], contentSize, 
escapedBlock);
-
-       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);
-       
+  blockLen = sqlite_encode_binary((const char *) &value[1],
+                                 contentSize, 
+                                 escapedBlock);
+  
+  stmt = dbh->insertContent;
+  sqlite3_bind_int(stmt, 1, ntohl(value->size));
+  sqlite3_bind_int(stmt, 2, ntohl(value->type));
+  sqlite3_bind_int(stmt, 3, ntohl(value->prio));
+  sqlite3_bind_int(stmt, 4, ntohl(value->anonymityLevel));
+  sqlite3_bind_int64(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);
   sqlite3_reset(stmt);
   if(n != SQLITE_DONE) {
-    LOG_SQLITE(LOG_ERROR, "sqlite_query");
+    LOG_SQLITE(LOG_ERROR, 
+              "sqlite_query");
     MUTEX_UNLOCK(&dbh->DATABASE_Lock_);
     return SYSERR;
   }
@@ -773,7 +683,8 @@
   MUTEX_UNLOCK(&dbh->DATABASE_Lock_);
  
 #if DEBUG_SQLITE
-  LOG(LOG_DEBUG, "SQLite: done writing content\n");
+  LOG(LOG_DEBUG,
+      "SQLite: done writing content\n");
 #endif 
 
   return OK;
@@ -789,83 +700,87 @@
  */
 static int del(const HashCode160 * key, 
               const Datastore_Value * value) {
-  char *escapedHash, *dummy;
+  char *escapedHash;
   size_t n;
   sqlite3_stmt *stmt;
   unsigned long rowLen;
   int deleted, hashLen;
+  char * escapedBlock;
+  int blockLen;
+  unsigned long contentSize;
 
 #if DEBUG_SQLITE
   LOG(LOG_DEBUG, "SQLite: delete block\n");
 #endif 
 
-  MUTEX_LOCK(&dbh->DATABASE_Lock_);
-  
+  MUTEX_LOCK(&dbh->DATABASE_Lock_); 
   suspendMigration();
   
   if (dbh->lastSync > 1000)
     syncStats(dbh);
   
   escapedHash = MALLOC(2 * sizeof(HashCode160) + 1);
-  hashLen = sqlite_encode_binary((char *)key, sizeof(HashCode160), 
escapedHash);
-
-       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 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;
-         
+  hashLen = sqlite_encode_binary((const char *)key,
+                                sizeof(HashCode160),
+                                escapedHash);
+  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 = sq_prepare("DELETE FROM gn070 WHERE hash = ?", 
+                  &stmt);
+    if (n == SQLITE_OK) {
+      sqlite3_bind_blob(stmt, 
+                       1, 
+                       escapedHash, 
+                       hashLen,
+                       SQLITE_TRANSIENT);
+      n = sqlite3_step(stmt);
+    }
+  } else {    
+    n = sq_prepare("DELETE FROM gn070 WHERE hash = ? and "
+                  "value = ? and size = ? and type = ? and prio = ? and 
anonLevel = ? "
+                  "and expire = ?", 
+                  &stmt);
+    if (n == SQLITE_OK) {      
+      escapedBlock = MALLOC(2 * (ntohl(value->size)-sizeof(Datastore_Value)) + 
1);      
+  
+      contentSize = ntohl(value->size)-sizeof(Datastore_Value);
+      blockLen = sqlite_encode_binary((const char *) &value[1], 
+                                     contentSize,
+                                     escapedBlock);
+      sqlite3_bind_blob(stmt, 1, escapedHash, hashLen, SQLITE_TRANSIENT);
+      sqlite3_bind_blob(stmt, 2, escapedBlock, blockLen, SQLITE_TRANSIENT);
+      sqlite3_bind_int(stmt, 3, ntohl(value->size));
+      sqlite3_bind_int(stmt, 4, ntohl(value->type));
+      sqlite3_bind_int(stmt, 5, ntohl(value->prio));
+      sqlite3_bind_int(stmt, 6, ntohl(value->anonymityLevel));
+      sqlite3_bind_int64(stmt, 7, ntohll(value->expirationTime));     
+      n = sqlite3_step(stmt);      
+      FREE(escapedBlock);      
+      if ( (n == SQLITE_DONE) || (n == SQLITE_ROW) )
+       dbh->payload -= (hashLen + blockLen + 5 * sizeof(long long));
+    } else {
+      LOG_SQLITE(LOG_ERROR, "sqlite3_prepare");
+    }
+  }
+  deleted = ( (n == SQLITE_DONE) || (n == SQLITE_ROW) ) ? 
sqlite3_changes(dbh->dbf) : SYSERR;
+  
   FREE(escapedHash);
   sqlite3_finalize(stmt);
 
@@ -878,7 +793,9 @@
   MUTEX_UNLOCK(&dbh->DATABASE_Lock_);
   
 #if DEBUG_SQLITE
-  LOG(LOG_DEBUG, "SQLite: %i block(s) deleted\n", deleted);
+  LOG(LOG_DEBUG, 
+      "SQLite: %d block(s) deleted\n", 
+      deleted);
 #endif 
   
   return deleted;
@@ -896,7 +813,8 @@
   unsigned long contentSize;
 
 #if DEBUG_SQLITE
-  LOG(LOG_DEBUG, "SQLite: update block\n");
+  LOG(LOG_DEBUG, 
+      "SQLite: update block\n");
 #endif 
 
   MUTEX_LOCK(&dbh->DATABASE_Lock_);
@@ -910,7 +828,7 @@
                                 sizeof(HashCode160),
                                 escapedHash);  
   escapedBlock = MALLOC(2*contentSize+1);
-  blockLen = sqlite_encode_binary((const char *) value, 
+  blockLen = sqlite_encode_binary((const char *) &value[1], 
                                  contentSize,
                                  escapedBlock);
   sqlite3_bind_int(dbh->updPrio,
@@ -948,36 +866,125 @@
   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() {       
-       double ret;
 
-  MUTEX_LOCK(&dbh->DATABASE_Lock_);
-  ret = dbh->payload * 1.0; /* FIXME 0.7: Find magic factor */
-  MUTEX_UNLOCK(&dbh->DATABASE_Lock_);
+SQstore_ServiceAPI *
+provide_module_sqstore_sqlite(CoreAPIForApplication * capi) {
+  static SQstore_ServiceAPI api;
 
+  char *dir, *afsdir;
+  size_t nX;
+  sqlite3_stmt *stmt;
+
 #if DEBUG_SQLITE
-  LOG(LOG_DEBUG,
-      "SQLite: database size: %.0f\n",
-      ret);
-#endif
+  LOG(LOG_DEBUG, "SQLite: initializing database\n");
+#endif 
+
+  dbh = MALLOC(sizeof(sqliteHandle));
   
-  return ret;
+  dbh->payload = 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) + 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);
+
+  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);
+  
+  sq_prepare("Select 1 from sqlite_master where tbl_name = 'gn070'", 
+            &stmt);
+  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);
+    
+  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);
+  
+  if ( (sq_prepare("SELECT count(*) FROM gn070 where hash=?", 
+                  &dbh->countContent) != SQLITE_OK) ||     
+       (sq_prepare("SELECT length(hash), length(value) "
+                  "from gn070 WHERE hash=?",
+                  &dbh->exists) != SQLITE_OK) ||                               
           
+       (sq_prepare("UPDATE gn070 SET prio = prio + ? where "
+                  "hash = ? and value = ? and prio + ? < ?", 
+                  &dbh->updPrio) != SQLITE_OK) ||
+       (sq_prepare("insert into gn070 (size, type, prio, "
+                  "anonLevel, expire, hash, value) values "
+                  "(?, ?, ?, ?, ?, ?, ?)",
+                  &dbh->insertContent) != SQLITE_OK) ) {    
+    LOG_SQLITE(LOG_ERROR, 
+              "precompiling");    
+    FREE(dbh->fn);
+    FREE(dbh);
+    return NULL;
+  }
+  
+  dbh->payload = getStat("PAYLOAD");
+  
+  dbh->migr = NULL;
+  dbh->lastPrio = 0;
+  dbh->lastExp = 0;
+  
+  if (dbh->payload == SYSERR) {
+    FREE(dbh->fn);
+    FREE(dbh);
+    return NULL;    
+  }
+    
+  MUTEX_CREATE(&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;
 }
 
 /**
- * Delete the database.  The next operation is
- * guaranteed to be unloading of the module.
+ * Shutdown the module.
  */
-static void drop() {
-  char *fn = STRDUP(dbh->fn);  
+void release_module_sqstore_sqlite() {
   sqlite_shutdown();  
-  UNLINK(fn);
 }
- 
+
 /* end of sqlite.c */

Modified: GNUnet/src/applications/sqstore_sqlite/sqlitetest.c
===================================================================
--- GNUnet/src/applications/sqstore_sqlite/sqlitetest.c 2005-02-24 21:02:10 UTC 
(rev 297)
+++ GNUnet/src/applications/sqstore_sqlite/sqlitetest.c 2005-02-25 02:21:58 UTC 
(rev 298)
@@ -10,7 +10,7 @@
 #include "gnunet_sqstore_service.h"
 #include "core.h"
 
-#define ASSERT(x) do { if (! (x)) goto FAILURE; } while (0)
+#define ASSERT(x) do { if (! (x)) { printf("Error at %s:%d\n", __FILE__, 
__LINE__); goto FAILURE;} } while (0)
 
 static cron_t now;
 
@@ -62,6 +62,7 @@
                       int * closure) {
   int ret;
 
+  printf("IDOWN: %u\n", *closure);
   (*closure) -= 2;  
   ret = checkValue(key, val, closure);
   return ret;





reply via email to

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