[Top][All Lists]
[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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r278 - in GNUnet/src: applications applications/sqstore_sqlite include,
durner <=