[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r5328 - in GNUnet/src: applications applications/datastore
From: |
gnunet |
Subject: |
[GNUnet-SVN] r5328 - in GNUnet/src: applications applications/datastore applications/fs/module applications/sqstore_mysql applications/sqstore_sqlite include |
Date: |
Sat, 21 Jul 2007 19:56:18 -0600 (MDT) |
Author: grothoff
Date: 2007-07-21 19:56:14 -0600 (Sat, 21 Jul 2007)
New Revision: 5328
Removed:
GNUnet/src/applications/sqstore_mysql_embedded/
Modified:
GNUnet/src/applications/Makefile.am
GNUnet/src/applications/datastore/datastore.c
GNUnet/src/applications/fs/module/dht_push.c
GNUnet/src/applications/sqstore_mysql/mysql.c
GNUnet/src/applications/sqstore_mysql/mysqltest.c
GNUnet/src/applications/sqstore_mysql/mysqltest2.c
GNUnet/src/applications/sqstore_mysql/mysqltest3.c
GNUnet/src/applications/sqstore_sqlite/sqlite.c
GNUnet/src/include/gnunet_datastore_service.h
GNUnet/src/include/gnunet_sqstore_service.h
Log:
starting new DB approach -- does not yet compile
Modified: GNUnet/src/applications/Makefile.am
===================================================================
--- GNUnet/src/applications/Makefile.am 2007-07-21 07:21:17 UTC (rev 5327)
+++ GNUnet/src/applications/Makefile.am 2007-07-22 01:56:14 UTC (rev 5328)
@@ -1,7 +1,3 @@
-if HAVE_MYSQLE
- MYSQLE_DIR = sqstore_mysql_embedded
-endif
-
if HAVE_MYSQL
MYSQL_DIR = sqstore_mysql
endif
@@ -33,7 +29,6 @@
pingpong \
session \
$(MYSQL_DIR) \
- $(MYSQLE_DIR) \
$(SQLITE_DIR) \
tbench \
template \
Modified: GNUnet/src/applications/datastore/datastore.c
===================================================================
--- GNUnet/src/applications/datastore/datastore.c 2007-07-21 07:21:17 UTC
(rev 5327)
+++ GNUnet/src/applications/datastore/datastore.c 2007-07-22 01:56:14 UTC
(rev 5328)
@@ -201,14 +201,16 @@
typedef struct
{
- int exists;
+ int exists;
const Datastore_Value *value;
- Datastore_Value *existing;
+ unsigned long long uid;
+ unsigned long long expiration;
} CE;
static int
checkExists (const HashCode512 * key,
- const Datastore_Value * value, void *cls)
+ const Datastore_Value * value, void *cls,
+ unsigned long long uid)
{
CE *ce = cls;
@@ -217,8 +219,8 @@
&ce->value[1],
ntohl (value->size) - sizeof (Datastore_Value))))
return OK; /* found another value, but different content!
*/
- ce->existing = MALLOC (ntohl (value->size));
- memcpy (ce->existing, value, ntohl (value->size));
+ ce->uid = uid;
+ ce->expiration = ntohll(value->expirationTime);
ce->exists = YES;
return SYSERR; /* abort iteration! */
}
@@ -251,16 +253,13 @@
{
if ((ntohl (value->prio) == 0) &&
(ntohll (value->expirationTime) <=
- ntohll (cls.existing->expirationTime)))
+ cls.expiration)))
{
- FREE (cls.existing);
return OK;
}
/* update prio */
- sq->update (key,
- cls.existing,
+ sq->update (cls.uid,
ntohl (value->prio), ntohll (value->expirationTime));
- FREE (cls.existing);
return OK;
}
#if DEBUG_DATASTORE
Modified: GNUnet/src/applications/fs/module/dht_push.c
===================================================================
--- GNUnet/src/applications/fs/module/dht_push.c 2007-07-21 07:21:17 UTC
(rev 5327)
+++ GNUnet/src/applications/fs/module/dht_push.c 2007-07-22 01:56:14 UTC
(rev 5328)
@@ -109,7 +109,7 @@
{
if (total == 0)
total = 1;
- total = sqstore->iterateNonAnonymous (0, YES, &push_callback, NULL);
+ total = sqstore->iterateNonAnonymous (0, &push_callback, NULL);
if ((dht != NULL) && (total == 0))
PTHREAD_SLEEP (15 * cronMINUTES);
}
Modified: GNUnet/src/applications/sqstore_mysql/mysql.c
===================================================================
--- GNUnet/src/applications/sqstore_mysql/mysql.c 2007-07-21 07:21:17 UTC
(rev 5327)
+++ GNUnet/src/applications/sqstore_mysql/mysql.c 2007-07-22 01:56:14 UTC
(rev 5328)
@@ -103,13 +103,10 @@
* - If you get odd SEGVs on gnunetd startup, it might be that the mysql
* databases have been corrupted.
* - The tables can be verified/fixed in two ways;
- * 1) by shutting down mysqld (mandatory!) and running
- * # myisamchk -r *.MYI
- * in /var/lib/mysql/gnunet/ (or wherever the tables are stored).
- * Another repair command is "mysqlcheck". The usable command
- * may depend on your mysql build/version. Or,
- * 2) by executing
- * mysql> REPAIR TABLE gn070;
+ * 1) by running mysqlcheck -A, or
+ * 2) by executing (inside of mysql using the GNUnet database):
+ * mysql> REPAIR TABLE gn071;
+ * mysql> REPAIR TABLE gn071;
*
* PROBLEMS?
*
@@ -129,8 +126,11 @@
#include <mysql/mysql.h>
#define DEBUG_MYSQL NO
+
#define DEBUG_TIME_MYSQL NO
+#define MAX_DATUM_SIZE 65536
+
/**
* Die with an error message that indicates
* a failure of the command 'cmd' with the message given
@@ -172,375 +172,580 @@
char *cnffile;
- int prepare;
-
int valid;
- MYSQL_STMT *insert;
+ /* stuff dealing with gn072 table */
+#define SELECT_VALUE "SELECT value FROM gn072 WHERE vkey=?"
+ MYSQL_STMT * select_value;
- MYSQL_BIND bind[7];
+#define DELETE_VALUE "DELETE FROM gn072 WHERE vkey=?"
+ MYSQL_STMT * delete_value;
- MYSQL_STMT *select;
+#define INSERT_VALUE "INSERT INTO gn072 (value) VALUES (?)"
+ MYSQL_STMT * insert_value;
- MYSQL_STMT *selectc;
+ /* stuff dealing with gn071 table */
+#define INSERT_ENTRY "INSERT INTO gn071
(size,type,prio,anonLevel,expire,hash,vkey) VALUES (?,?,?,?,?,?,?)"
+ MYSQL_STMT * insert_entry;
- MYSQL_STMT *selects;
+#define DELETE_ENTRY_BY_VKEY "DELETE FROM gn071 WHERE vkey=?"
+ MYSQL_STMT * delete_entry_by_vkey;
- MYSQL_STMT *selectsc;
+#define SELECT_ENTRY_BY_HASH "SELECT * FROM gn071 WHERE hash=? ORDER BY expire
DESC"
+ MYSQL_STMT * select_entry_by_hash;
- MYSQL_BIND sbind[2];
+#define SELECT_ENTRY_BY_HASH_AND_TYPE "SELECT * FROM gn071 WHERE hash=? AND
type=?"
+ MYSQL_STMT * select_entry_by_hash_and_type;
- MYSQL_STMT *deleteh;
+#define COUNT_ENTRY_BY_HASH "SELECT count(*) FROM gn071 WHERE hash=?"
+ MYSQL_STMT * count_entry_by_hash;
- MYSQL_STMT *deleteg;
+#define COUNT_ENTRY_BY_HASH_AND_TYPE "SELECT count(*) FROM gn071 WHERE hash=?
AND type=?"
+ MYSQL_STMT * count_entry_by_hash_and_type;
- MYSQL_BIND dbind[7];
+#define UPDATE_ENTRY "UPDATE gn071 SET
prio=prio+?,expire=IF(expire>=?,expire,?) WHERE hash=? AND vkey=?"
+ MYSQL_STMT * update_entry;
- MYSQL_STMT *update;
- MYSQL_BIND ubind[5];
-} mysqlHandle;
+#define SELECT_IT_LOW_PRIORITY "SELECT * FROM gn071 WHERE ( (prio = ? AND vkey
> ?) OR (prio > ?) )"\
+ "ORDER BY prio ASC,vkey ASC LIMIT 1"
+ MYSQL_STMT * ilow;
-#define SELECT_SIZE "SELECT sum(size) FROM gn070"
+#define SELECT_IT_NON_ANONYMOUS "SELECT * FROM gn071 WHERE ( (prio = ? AND
vkey > ?) OR (prio > ?) ) "\
+ "AND anonLevel=0 AND type != 0xFFFFFFFF "\
+ "ORDER BY prio DESC,vkey DESC LIMIT 1"
+ MYSQL_STMT * inon;
-#define INSERT_SAMPLE "INSERT INTO gn070
(size,type,prio,anonLevel,expire,hash,value) VALUES (?,?,?,?,?,?,?)"
+#define SELECT_IT_EXPIRATION_TIME "SELECT * FROM gn071 WHERE ( (expire = ? AND
vkey > ?) OR (expire > ?) ) "\
+ "ORDER BY expire ASC,vkey ASC LIMIT 1"
+ MYSQL_STMT * iexp;
-#define SELECT_SAMPLE "SELECT * FROM gn070 WHERE hash=? ORDER BY expire DESC"
+#define SELECT_IT_MIGRATION_ORDER "SELECT * FROM gn071 WHERE ( (expire = ? AND
vkey < ?) OR (expire > ?) ) "\
+ "AND expire > ? AND type!=3 "\
+ "ORDER BY expire DESC,vkey DESC LIMIT 1"
+ MYSQL_STMT * imig;
-#define SELECT_SAMPLE_COUNT "SELECT count(*) FROM gn070 WHERE hash=?"
+#define SELECT_ALL "SELECT * FROM gn071"
+ MYSQL_STMT * iall;
-#define SELECT_TYPE_SAMPLE "SELECT * FROM gn070 WHERE hash=? AND type=?"
+} mysqlHandle;
-#define SELECT_TYPE_SAMPLE_COUNT "SELECT count(*) FROM gn070 WHERE hash=? AND
type=?"
-/**
- * Select to prepare for key-based deletion.
- */
-#define SELECT_HASH_SAMPLE "SELECT * FROM gn070 WHERE hash=? ORDER BY prio ASC
LIMIT 1"
+#define SELECT_SIZE "SELECT sum(size) FROM gn070"
-#define DELETE_GENERIC_SAMPLE "DELETE FROM gn070 WHERE hash=? AND size=? AND
type=? AND prio=? AND anonLevel=? AND expire=? AND value=? ORDER BY prio ASC
LIMIT 1"
+static mysqlHandle * dbh;
-#define UPDATE_SAMPLE "UPDATE gn070 SET
prio=prio+?,expire=IF(expire>=?,expire,?) WHERE hash=? AND value=?"
-
-static mysqlHandle *dbh;
-
-
/**
- * Given a full (SELECT *) sql_row from gn070 table in database
- * order, assemble it into a Datastore_Datum representation.
- *
+ * Close the database connection.
*/
-static Datastore_Datum *
-assembleDatum (MYSQL_RES * res, MYSQL_ROW sql_row, mysqlHandle * dbhI)
+static int
+iclose ()
{
- Datastore_Datum *datum;
- int contentSize;
- unsigned long *lens;
- unsigned int type;
- unsigned int prio;
- unsigned int level;
- unsigned long long exp;
-
- contentSize = atol (sql_row[0]) - sizeof (Datastore_Value);
- if (contentSize < 0)
- return NULL; /* error */
-
- lens = mysql_fetch_lengths (res);
- if ((lens[5] != sizeof (HashCode512)) ||
- (lens[6] != contentSize) ||
- (sscanf (sql_row[1], "%u", &type) != 1) ||
- (sscanf (sql_row[2], "%u", &prio) != 1) ||
- (sscanf (sql_row[3], "%u", &level) != 1) ||
- (SSCANF (sql_row[4], "%llu", &exp) != 1))
- {
- mysql_free_result (res);
- if ((lens[5] != sizeof (HashCode512)) || (lens[6] != contentSize))
- {
- char scratch[512];
-
- GE_LOG (ectx,
- GE_WARNING | GE_BULK | GE_USER,
- _("Invalid data in %s. Trying to fix (by deletion).\n"),
- _("mysql datastore"));
- SNPRINTF (scratch,
- 512,
- "DELETE FROM gn070 WHERE NOT ((LENGTH(hash)=%u) AND
(size=%u + LENGTH(value)))",
- sizeof (HashCode512), sizeof (Datastore_Value));
- if (0 != mysql_query (dbhI->dbf, scratch))
- LOG_MYSQL (GE_ERROR | GE_ADMIN | GE_BULK, "mysql_query", dbhI);
- }
- else
- {
- GE_BREAK (ectx, 0); /* should really never happen */
- }
- return NULL;
- }
- datum = MALLOC (sizeof (Datastore_Datum) + contentSize);
- datum->value.size = htonl (contentSize + sizeof (Datastore_Value));
- datum->value.type = htonl (type);
- datum->value.prio = htonl (prio);
- datum->value.anonymityLevel = htonl (level);
- datum->value.expirationTime = htonll (exp);
- memcpy (&datum->key, sql_row[5], sizeof (HashCode512));
- memcpy (&datum[1], sql_row[6], contentSize);
- return datum;
+#define PEND(h) if (h != NULL) { mysql_stmt_close(h); h = NULL; } else {}
+ if (dbh->dbf == NULL)
+ return SYSERR;
+ PEND(dbh->select_value);
+ PEND(dbh->delete_value);
+ PEND(dbh->insert_value);
+ PEND(dbh->insert_entry);
+ PEND(dbh->delete_entry_by_vkey);
+ PEND(dbh->select_entry_by_hash);
+ PEND(dbh->select_entry_by_hash_and_type);
+ PEND(dbh->count_entry_by_hash);
+ PEND(dbh->count_entry_by_hash_and_type);
+ PEND(dbh->update_entry);
+ PEND(dbh->ilow);
+ PEND(dbh->inon);
+ PEND(dbh->iexp);
+ PEND(dbh->imig);
+ PEND(dbh->iall);
+ mysql_close (dbh->dbf);
+ dbh->dbf = NULL;
+ dbh->valid = NO;
+ return OK;
}
/**
- * Initiate the database connection.
- * Uses dbhI->cnffile for the configuration,
- * so that must be set already.
+ * Initiate the database connection. Uses dbh->cnffile for the
+ * configuration, so that must be set already.
*
- * @param prepare is this the main connection
- * (if YES, we create tables and initialize
- * prepared statements; if NO, we
- * use longer timeouts (for iteration)
- * and do not setup prepared statements)
* @return OK on success
*/
static int
-iopen (mysqlHandle * dbhI, int prepare)
+iopen ()
{
char *dbname;
my_bool reconnect = 0;
unsigned int timeout = 60; /* in seconds */
- cron_t start;
- if (dbhI->cnffile == NULL)
+ if (dbh->cnffile == NULL)
return SYSERR;
- dbhI->dbf = mysql_init (NULL);
- if (dbhI->dbf == NULL)
+ dbh->dbf = mysql_init (NULL);
+ if (dbh->dbf == NULL)
return SYSERR;
- mysql_options (dbhI->dbf, MYSQL_READ_DEFAULT_FILE, dbh->cnffile);
- mysql_options (dbhI->dbf, MYSQL_READ_DEFAULT_GROUP, "client");
- mysql_options (dbhI->dbf, MYSQL_OPT_RECONNECT, &reconnect);
- mysql_options (dbhI->dbf,
+ mysql_options (dbh->dbf, MYSQL_READ_DEFAULT_FILE, dbh->cnffile);
+ mysql_options (dbh->dbf, MYSQL_READ_DEFAULT_GROUP, "client");
+ mysql_options (dbh->dbf, MYSQL_OPT_RECONNECT, &reconnect);
+ mysql_options (dbh->dbf,
MYSQL_OPT_CONNECT_TIMEOUT, (const void *) &timeout);
- if (!prepare)
- timeout = 28800;
- mysql_options (dbhI->dbf, MYSQL_OPT_READ_TIMEOUT, (const void *) &timeout);
- mysql_options (dbhI->dbf, MYSQL_OPT_WRITE_TIMEOUT, (const void *) &timeout);
+ mysql_options (dbh->dbf, MYSQL_OPT_READ_TIMEOUT, (const void *) &timeout);
+ mysql_options (dbh->dbf, MYSQL_OPT_WRITE_TIMEOUT, (const void *) &timeout);
dbname = NULL;
GC_get_configuration_value_string (coreAPI->cfg,
"MYSQL", "DATABASE", "gnunet", &dbname);
GE_ASSERT (ectx, dbname != NULL);
- mysql_real_connect (dbhI->dbf, NULL, NULL, NULL, dbname, 0, NULL, 0);
+ mysql_real_connect (dbh->dbf, NULL, NULL, NULL, dbname, 0, NULL, 0);
FREE (dbname);
- if (mysql_error (dbhI->dbf)[0])
+ if (mysql_error (dbh->dbf)[0])
{
- LOG_MYSQL (GE_ERROR | GE_ADMIN | GE_BULK, "mysql_real_connect", dbhI);
- dbhI->dbf = NULL;
+ LOG_MYSQL (GE_ERROR | GE_ADMIN | GE_BULK, "mysql_real_connect", dbh);
+ iclose();
return SYSERR;
}
- if (prepare)
+ mysql_query (dbh->dbf,
+ "SET SESSION net_read_timeout=60, SESSION net_write_timeout=60");
+ if (mysql_error (dbh->dbf)[0])
{
- dbhI->prepare = YES;
- mysql_query (dbhI->dbf,
- "SET SESSION net_read_timeout=60, SESSION
net_write_timeout=60");
- if (mysql_error (dbhI->dbf)[0])
- {
- LOG_MYSQL (GE_ERROR | GE_ADMIN | GE_BULK, "mysql_query", dbhI);
- mysql_close (dbhI->dbf);
- dbhI->dbf = NULL;
- return SYSERR;
- }
- mysql_query (dbhI->dbf,
- "CREATE TABLE IF NOT EXISTS gn070 ("
- " size INT(11) UNSIGNED NOT NULL DEFAULT 0,"
- " type INT(11) UNSIGNED NOT NULL DEFAULT 0,"
- " prio INT(11) UNSIGNED NOT NULL DEFAULT 0,"
- " anonLevel INT(11) UNSIGNED NOT NULL DEFAULT 0,"
- " expire BIGINT UNSIGNED NOT NULL DEFAULT 0,"
- " hash TINYBLOB NOT NULL DEFAULT '',"
- " value BLOB NOT NULL DEFAULT '',"
- " INDEX (hash(64)),"
- " INDEX (prio),"
- " INDEX (expire),"
- " INDEX (expire,anonLevel,type)" ") TYPE=InnoDB");
- if (mysql_error (dbhI->dbf)[0])
- {
- LOG_MYSQL (GE_ERROR | GE_ADMIN | GE_BULK, "mysql_query", dbhI);
- mysql_close (dbhI->dbf);
- dbhI->dbf = NULL;
- return SYSERR;
- }
- mysql_query (dbhI->dbf, "SET AUTOCOMMIT = 1");
- if (mysql_error (dbhI->dbf)[0])
- {
- LOG_MYSQL (GE_ERROR | GE_ADMIN | GE_BULK, "mysql_query", dbhI);
- mysql_close (dbhI->dbf);
- dbhI->dbf = NULL;
- return SYSERR;
- }
- dbhI->insert = mysql_stmt_init (dbhI->dbf);
- dbhI->select = mysql_stmt_init (dbhI->dbf);
- dbhI->selectc = mysql_stmt_init (dbhI->dbf);
- dbhI->selects = mysql_stmt_init (dbhI->dbf);
- dbhI->selectsc = mysql_stmt_init (dbhI->dbf);
- dbhI->update = mysql_stmt_init (dbhI->dbf);
- dbhI->deleteh = mysql_stmt_init (dbhI->dbf);
- dbhI->deleteg = mysql_stmt_init (dbhI->dbf);
- if ((dbhI->insert == NULL) ||
- (dbhI->update == NULL) ||
- (dbhI->select == NULL) ||
- (dbhI->selectc == NULL) ||
- (dbhI->selects == NULL) ||
- (dbhI->selectsc == NULL) ||
- (dbhI->deleteh == NULL) || (dbhI->deleteg == NULL))
- {
- GE_BREAK (ectx, 0);
- if (dbhI->insert != NULL)
- mysql_stmt_close (dbhI->insert);
- if (dbhI->update != NULL)
- mysql_stmt_close (dbhI->update);
- if (dbhI->select != NULL)
- mysql_stmt_close (dbhI->select);
- if (dbhI->selectc != NULL)
- mysql_stmt_close (dbhI->selectc);
- if (dbhI->selects != NULL)
- mysql_stmt_close (dbhI->selects);
- if (dbhI->selectsc != NULL)
- mysql_stmt_close (dbhI->selectsc);
- mysql_close (dbhI->dbf);
- dbhI->dbf = NULL;
- return SYSERR;
- }
- start = get_time ();
- if (mysql_stmt_prepare (dbhI->insert,
- INSERT_SAMPLE,
- strlen (INSERT_SAMPLE)) ||
- mysql_stmt_prepare (dbhI->select,
- SELECT_SAMPLE,
- strlen (SELECT_SAMPLE)) ||
- mysql_stmt_prepare (dbhI->selectc,
- SELECT_SAMPLE_COUNT,
- strlen (SELECT_SAMPLE_COUNT)) ||
- mysql_stmt_prepare (dbhI->selects,
- SELECT_TYPE_SAMPLE,
- strlen (SELECT_TYPE_SAMPLE)) ||
- mysql_stmt_prepare (dbhI->selectsc,
- SELECT_TYPE_SAMPLE_COUNT,
- strlen (SELECT_TYPE_SAMPLE_COUNT)) ||
- mysql_stmt_prepare (dbhI->update,
- UPDATE_SAMPLE,
- strlen (UPDATE_SAMPLE)) ||
- mysql_stmt_prepare (dbhI->deleteh,
- SELECT_HASH_SAMPLE,
- strlen (SELECT_HASH_SAMPLE)) ||
- mysql_stmt_prepare (dbhI->deleteg,
- DELETE_GENERIC_SAMPLE,
- strlen (DELETE_GENERIC_SAMPLE)))
- {
- GE_LOG (ectx,
- GE_ERROR | GE_BULK | GE_USER,
- _
- ("`%s' failed at %s:%d with error: I/%s S/%s SC/%s SS/%s
SSC/%s U/%s D/%s DG/%s after %llums\n"),
- "mysql_stmt_prepare", __FILE__, __LINE__,
- mysql_stmt_error (dbhI->insert),
- mysql_stmt_error (dbhI->select),
- mysql_stmt_error (dbhI->selectc),
- mysql_stmt_error (dbhI->selects),
- mysql_stmt_error (dbhI->selectsc),
- mysql_stmt_error (dbhI->update),
- mysql_stmt_error (dbhI->deleteh),
- mysql_stmt_error (dbhI->deleteg), get_time () - start);
- mysql_stmt_close (dbhI->insert);
- mysql_stmt_close (dbhI->select);
- mysql_stmt_close (dbhI->selectc);
- mysql_stmt_close (dbhI->selects);
- mysql_stmt_close (dbhI->selectsc);
- mysql_stmt_close (dbhI->update);
- mysql_stmt_close (dbhI->deleteh);
- mysql_stmt_close (dbhI->deleteg);
- mysql_close (dbhI->dbf);
- dbhI->dbf = NULL;
- return SYSERR;
- }
- memset (dbhI->bind, 0, sizeof (dbhI->bind));
- dbhI->bind[0].buffer_type = MYSQL_TYPE_LONG; /* size */
- dbhI->bind[1].buffer_type = MYSQL_TYPE_LONG; /* type */
- dbhI->bind[2].buffer_type = MYSQL_TYPE_LONG; /* prio */
- dbhI->bind[3].buffer_type = MYSQL_TYPE_LONG; /* anon level */
- dbhI->bind[4].buffer_type = MYSQL_TYPE_LONGLONG; /* expiration */
- dbhI->bind[5].buffer_type = MYSQL_TYPE_TINY_BLOB; /* hash */
- dbhI->bind[6].buffer_type = MYSQL_TYPE_BLOB; /* value */
- memset (dbhI->sbind, 0, sizeof (dbhI->sbind));
- dbhI->sbind[0].buffer_type = MYSQL_TYPE_TINY_BLOB; /* hash */
- dbhI->sbind[1].buffer_type = MYSQL_TYPE_LONG; /* type */
- memset (dbhI->dbind, 0, sizeof (dbhI->dbind));
- dbhI->dbind[0].buffer_type = MYSQL_TYPE_TINY_BLOB; /* hash */
- dbhI->dbind[1].buffer_type = MYSQL_TYPE_LONG; /* size */
- dbhI->dbind[2].buffer_type = MYSQL_TYPE_LONG; /* type */
- dbhI->dbind[3].buffer_type = MYSQL_TYPE_LONG; /* prio */
- dbhI->dbind[4].buffer_type = MYSQL_TYPE_LONG; /* anon level */
- dbhI->dbind[5].buffer_type = MYSQL_TYPE_LONGLONG; /* expiration */
- dbhI->dbind[6].buffer_type = MYSQL_TYPE_BLOB; /* value */
- memset (dbhI->ubind, 0, sizeof (dbhI->ubind));
- dbhI->ubind[0].buffer_type = MYSQL_TYPE_LONG;
- dbhI->ubind[1].buffer_type = MYSQL_TYPE_LONG;
- dbhI->ubind[2].buffer_type = MYSQL_TYPE_LONG;
- dbhI->ubind[3].buffer_type = MYSQL_TYPE_BLOB;
- dbhI->ubind[4].buffer_type = MYSQL_TYPE_BLOB;
+ LOG_MYSQL (GE_ERROR | GE_ADMIN | GE_BULK, "mysql_query", dbh);
+ iclose();
+ return SYSERR;
}
+ mysql_query (dbh->dbf,
+ "CREATE TABLE IF NOT EXISTS gn071 ("
+ " size INT(11) UNSIGNED NOT NULL DEFAULT 0,"
+ " type INT(11) UNSIGNED NOT NULL DEFAULT 0,"
+ " prio INT(11) UNSIGNED NOT NULL DEFAULT 0,"
+ " anonLevel INT(11) UNSIGNED NOT NULL DEFAULT 0,"
+ " expire BIGINT UNSIGNED NOT NULL DEFAULT 0,"
+ " hash BINARY(64) NOT NULL DEFAULT '',"
+ " vkey BIGINT UNSIGNED NOT NULL DEFAULT 0,"
+ " INDEX (hash(64)),"
+ " INDEX (prio),"
+ " INDEX (expire,anonLevel,type)" ") ENGINE=MyISAM");
+ if (mysql_error (dbh->dbf)[0])
+ {
+ LOG_MYSQL (GE_ERROR | GE_ADMIN | GE_BULK, "mysql_query", dbh);
+ iclose();
+ return SYSERR;
+ }
+ mysql_query (dbh->dbf,
+ "CREATE TABLE IF NOT EXISTS gn072 ("
+ " vkey BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,"
+ " value BLOB NOT NULL DEFAULT '') ENGINE=MyISAM");
+ if (mysql_error (dbh->dbf)[0])
+ {
+ LOG_MYSQL (GE_ERROR | GE_ADMIN | GE_BULK, "mysql_query", dbh);
+ iclose();
+ return SYSERR;
+ }
+ mysql_query (dbh->dbf, "SET AUTOCOMMIT = 1");
+ if (mysql_error (dbh->dbf)[0])
+ {
+ LOG_MYSQL (GE_ERROR | GE_ADMIN | GE_BULK, "mysql_query", dbh);
+ iclose();
+ return SYSERR;
+ }
+#define PINIT(a,b) a = mysql_stmt_init(dbh->dbf); if (a == NULL) { iclose();
return SYSERR; } else { \
+ if (mysql_stmt_prepare (a, b, strlen(b))) { \
+ GE_LOG (ectx, GE_ERROR | GE_BULK | GE_USER, \
+ _("`%s' failed at %s:%d with error: %s"), "mysql_stmt_prepare",
__FILE__, __LINE__, \
+ mysql_stmt_error (a)); iclose(); return SYSERR; } }
+ PINIT(dbh->select_value, SELECT_VALUE);
+ PINIT(dbh->delete_value, DELETE_VALUE);
+ PINIT(dbh->insert_value, INSERT_VALUE);
+ PINIT(dbh->insert_entry, INSERT_ENTRY);
+ PINIT(dbh->delete_entry_by_vkey, DELETE_ENTRY_BY_VKEY);
+ PINIT(dbh->select_entry_by_hash, SELECT_ENTRY_BY_HASH);
+ PINIT(dbh->select_entry_by_hash_and_type, SELECT_ENTRY_BY_HASH_AND_TYPE);
+ PINIT(dbh->count_entry_by_hash, COUNT_ENTRY_BY_HASH);
+ PINIT(dbh->count_entry_by_hash_and_type, COUNT_ENTRY_BY_HASH_AND_TYPE);
+ PINIT(dbh->update_entry, UPDATE_ENTRY);
+ PINIT(dbh->ilow, SELECT_IT_LOW_PRIORITY);
+ PINIT(dbh->inon, SELECT_IT_NON_ANONYMOUS);
+ PINIT(dbh->iexp, SELECT_IT_EXPIRATION_TIME);
+ PINIT(dbh->imig, SELECT_IT_MIGRATION_ORDER);
+ PINIT(dbh->iall, SELECT_ALL);
+ dbh->valid = YES;
+ return OK;
+}
+
+/**
+ * Check if DBH handle is valid, return OK if it is.
+ * Also tries to re-connect to the DB if the connection
+ * is down.
+ */
+#define CHECK_DBH ((dbh->valid == NO) ? iopen(dbh, YES) : OK)
+
+
+/**
+ * Delete an value from the gn072 table.
+ *
+ * @param vkey vkey identifying the value to delete
+ * @return OK on success, NO if no such value exists, SYSERR on error
+ */
+static int delete_value(unsigned long long vkey) {
+ MYSQL_BIND qbind[1];
+ int ret;
+
+ memset(qbind, 0, sizeof(qbind));
+ qbind[0].is_unsigned = YES;
+ qbind[0].buffer_type = MYSQL_TYPE_LONGLONG;
+ qbind[0].buffer = &vkey;
+ GE_ASSERT (ectx,
+ mysql_stmt_param_count (dbh->delete_value) == 1);
+ if (mysql_stmt_bind_param(dbh->delete_value,
+ qbind)) {
+ GE_LOG (ectx,
+ GE_ERROR | GE_BULK | GE_USER,
+ _("`%s' failed at %s:%d with error: %s\n"),
+ "mysql_stmt_bind_param",
+ __FILE__, __LINE__, mysql_stmt_error (dbh->delete_value));
+ iclose ();
+ return SYSERR;
+ }
+ if (mysql_stmt_execute (dbh->delete_value))
+ {
+ GE_LOG (ectx,
+ GE_ERROR | GE_BULK | GE_USER,
+ _("`%s' failed at %s:%d with error: %s\n"),
+ "mysql_stmt_execute",
+ __FILE__, __LINE__, mysql_stmt_error (dbh->delete_value));
+ iclose ();
+ return SYSERR;
+ }
+ if (mysql_stmt_affected_rows(dbh->delete_value) == 0)
+ ret = NO;
else
+ ret = OK;
+ mysql_stmt_reset(dbh->delete_value);
+ return ret;
+}
+
+/**
+ * Insert a value into the gn072 table.
+ *
+ * @param value the value to insert
+ * @param size size of the value
+ * @param vkey vkey identifying the value henceforth (set)
+ * @return OK on success, SYSERR on error
+ */
+static int insert_value(const void * value,
+ unsigned int size,
+ unsigned long long * vkey) {
+ MYSQL_BIND qbind[1];
+ unsigned long length = size;
+
+ memset(qbind, 0, sizeof(qbind));
+ qbind[0].buffer_type = MYSQL_TYPE_BLOB;
+ qbind[0].buffer = (void*) value;
+ qbind[0].buffer_length = size;
+ qbind[0].length = &length;
+ GE_ASSERT (ectx,
+ mysql_stmt_param_count (dbh->insert_value) == 1);
+ if (mysql_stmt_bind_param(dbh->insert_value,
+ qbind)) {
+ GE_LOG (ectx,
+ GE_ERROR | GE_BULK | GE_USER,
+ _("`%s' failed at %s:%d with error: %s\n"),
+ "mysql_stmt_bind_param",
+ __FILE__, __LINE__, mysql_stmt_error (dbh->insert_value));
+ iclose ();
+ return SYSERR;
+ }
+ if (mysql_stmt_execute (dbh->insert_value))
{
- dbhI->prepare = NO;
- mysql_query (dbhI->dbf,
- "SET SESSION net_read_timeout=28800, SESSION
net_write_timeout=28800");
- if (mysql_error (dbhI->dbf)[0])
- {
- LOG_MYSQL (GE_ERROR | GE_ADMIN | GE_BULK, "mysql_query", dbhI);
- mysql_close (dbhI->dbf);
- dbhI->dbf = NULL;
- return SYSERR;
- }
+ GE_LOG (ectx,
+ GE_ERROR | GE_BULK | GE_USER,
+ _("`%s' failed at %s:%d with error: %s\n"),
+ "mysql_stmt_execute",
+ __FILE__, __LINE__, mysql_stmt_error (dbh->insert_value));
+ iclose ();
+ return SYSERR;
}
- dbhI->valid = YES;
+ *vkey = (unsigned long long) mysql_stmt_insert_id(dbh->insert_value);
+ mysql_stmt_reset(dbh->insert_value);
return OK;
}
/**
- * Close the database connection.
+ * Delete an entry from the gn071 table.
+ *
+ * @param vkey vkey identifying the entry to delete
+ * @return OK on success, NO if no such value exists, SYSERR on error
*/
+static int delete_entry_by_vkey(unsigned long long vkey) {
+ MYSQL_BIND qbind[1];
+ int ret;
+
+ memset(qbind, 0, sizeof(qbind));
+ qbind[0].is_unsigned = YES;
+ qbind[0].buffer_type = MYSQL_TYPE_LONGLONG;
+ qbind[0].buffer = &vkey;
+ GE_ASSERT (ectx,
+ mysql_stmt_param_count (dbh->delete_entry_by_vkey) == 1);
+ if (mysql_stmt_bind_param(dbh->delete_entry_by_vkey,
+ qbind)) {
+ GE_LOG (ectx,
+ GE_ERROR | GE_BULK | GE_USER,
+ _("`%s' failed at %s:%d with error: %s\n"),
+ "mysql_stmt_bind_param",
+ __FILE__, __LINE__, mysql_stmt_error (dbh->delete_entry_by_vkey));
+ iclose ();
+ return SYSERR;
+ }
+ if (mysql_stmt_execute (dbh->delete_entry_by_vkey))
+ {
+ GE_LOG (ectx,
+ GE_ERROR | GE_BULK | GE_USER,
+ _("`%s' failed at %s:%d with error: %s\n"),
+ "mysql_stmt_execute",
+ __FILE__, __LINE__, mysql_stmt_error
(dbh->delete_entry_by_vkey));
+ iclose ();
+ return SYSERR;
+ }
+ if (mysql_stmt_affected_rows(dbh->delete_entry_by_vkey) == 0)
+ ret = NO;
+ else
+ ret = OK;
+ mysql_stmt_reset(dbh->delete_entry_by_vkey);
+ return ret;
+}
+
+/**
+ * Given a full (SELECT *) result set from gn071 table,
+ * assemble it into a Datastore_Value representation.
+ *
+ * @param result location where mysql_stmt_fetch stored the results
+ * @return NULL on error
+ */
+static Datastore_Value *
+assembleDatum (MYSQL_BIND * result)
+{
+ Datastore_Value *datum;
+ unsigned int contentSize;
+ unsigned int type;
+ unsigned int prio;
+ unsigned int level;
+ unsigned long long exp;
+ unsigned long long vkey;
+ unsigned long length;
+ MYSQL_BIND qbind[1];
+ MYSQL_BIND rbind[1];
+
+ if ( (result[0].buffer_type != MYSQL_TYPE_LONG) ||
+ (! result[0].is_unsigned) ||
+ (result[1].buffer_type != MYSQL_TYPE_LONG) ||
+ (! result[1].is_unsigned) ||
+ (result[2].buffer_type != MYSQL_TYPE_LONG) ||
+ (! result[2].is_unsigned) ||
+ (result[3].buffer_type != MYSQL_TYPE_LONG) ||
+ (! result[3].is_unsigned) ||
+ (result[4].buffer_type != MYSQL_TYPE_LONGLONG) ||
+ (! result[4].is_unsigned) ||
+ (result[5].buffer_type != MYSQL_TYPE_STRING) ||
+ (result[5].buffer_length != sizeof(HashCode512)) ||
+ (*result[5].length != sizeof(HashCode512)) ||
+ (result[6].buffer_type != MYSQL_TYPE_LONGLONG) ||
+ (! result[6].is_unsigned) )
+ return NULL; /* error */
+
+ contentSize = * (unsigned int*) result[0].buffer;
+ if (contentSize < sizeof(Datastore_Value))
+ return NULL; /* error */
+ contentSize -= sizeof(Datastore_Value);
+ type = *(unsigned int*) result[1].buffer;
+ prio = *(unsigned int*) result[2].buffer;
+ level = *(unsigned int*) result[3].buffer;
+ exp = *(unsigned long long*) result[4].buffer;
+ vkey = *(unsigned long long*) result[6].buffer;
+ datum = MALLOC (sizeof (Datastore_Value) + contentSize);
+ datum->size = htonl (contentSize + sizeof (Datastore_Value));
+ datum->type = htonl (type);
+ datum->prio = htonl (prio);
+ datum->anonymityLevel = htonl (level);
+ datum->expirationTime = htonll (exp);
+
+ /* now do query on gn072 */
+ length = contentSize;
+ memset(qbind, 0, sizeof(qbind));
+ qbind[0].is_unsigned = YES;
+ qbind[0].buffer_type = MYSQL_TYPE_LONGLONG;
+ qbind[0].buffer = &vkey;
+ memset(rbind, 0, sizeof(rbind));
+ rbind[0].buffer_type = MYSQL_TYPE_BLOB;
+ rbind[0].buffer_length = contentSize;
+ rbind[0].length = &length;
+ rbind[0].buffer = &datum[1];
+ GE_ASSERT (ectx,
+ mysql_stmt_param_count (dbh->select_value) == 1);
+ if (mysql_stmt_bind_param(dbh->select_value,
+ qbind)) {
+ GE_LOG (ectx,
+ GE_ERROR | GE_BULK | GE_USER,
+ _("`%s' failed at %s:%d with error: %s\n"),
+ "mysql_stmt_bind_param",
+ __FILE__, __LINE__, mysql_stmt_error (dbh->select_value));
+ iclose ();
+ return NULL;
+ }
+ if (mysql_stmt_execute (dbh->select_value))
+ {
+ GE_LOG (ectx,
+ GE_ERROR | GE_BULK | GE_USER,
+ _("`%s' failed at %s:%d with error: %s\n"),
+ "mysql_stmt_execute",
+ __FILE__, __LINE__, mysql_stmt_error (dbh->select_value));
+ iclose ();
+ return NULL;
+ }
+ GE_ASSERT (ectx,
+ mysql_stmt_field_count (dbh->select_value) == 1);
+ if (mysql_stmt_bind_result(dbh->select_value,
+ rbind)) {
+ GE_LOG (ectx,
+ GE_ERROR | GE_BULK | GE_USER,
+ _("`%s' failed at %s:%d with error: %s\n"),
+ "mysql_stmt_bind_result",
+ __FILE__, __LINE__, mysql_stmt_error (dbh->select_value));
+ iclose ();
+ return NULL;
+ }
+ if ( (mysql_stmt_fetch(dbh->select_value)) ||
+ (rbind[0].buffer_length != contentSize) ||
+ (length != contentSize) ) {
+ mysql_stmt_reset(dbh->select_value);
+ GE_LOG (ectx,
+ GE_ERROR | GE_BULK | GE_USER,
+ _("`%s' failed at %s:%d with error: %s\n"),
+ "mysql_stmt_bind_result",
+ __FILE__, __LINE__, mysql_stmt_error (dbh->select_value));
+ delete_entry_by_vkey(vkey);
+ content_size -= ntohl(datum->size);
+ return NULL;
+ }
+ mysql_stmt_reset(dbh->select_value);
+ return datum;
+}
+
+/**
+ * Store an item in the datastore.
+ *
+ * @return OK on success, SYSERR on error
+ */
static int
-iclose (mysqlHandle * dbhI)
+put (const HashCode512 * key, const Datastore_Value * value)
{
- if (dbhI->dbf == NULL)
+ unsigned long contentSize;
+ unsigned long hashSize;
+ unsigned int size;
+ unsigned int type;
+ unsigned int prio;
+ unsigned int level;
+ unsigned long long expiration;
+ unsigned long long vkey;
+ MYSQL_BIND qbind[7];
+#if DEBUG_MYSQL
+ EncName enc;
+#endif
+
+ if ( ((ntohl (value->size) < sizeof (Datastore_Value))) ||
+ ((ntohl (value->size) - sizeof (Datastore_Value)) > MAX_DATUM_SIZE) )
+ {
+ GE_BREAK (ectx, 0);
+ return SYSERR;
+ }
+ MUTEX_LOCK (lock);
+ mysql_thread_init ();
+ if (OK != CHECK_DBH)
+ {
+ mysql_thread_end ();
+ MUTEX_UNLOCK (lock);
+ return SYSERR;
+ }
+ contentSize = ntohl (value->size) - sizeof (Datastore_Value);
+ if (OK != insert_value(&value[1],
+ contentSize,
+ &vkey)) {
+ mysql_thread_end ();
+ MUTEX_UNLOCK (lock);
return SYSERR;
- if (dbhI->prepare == YES)
+ }
+ hashSize = sizeof (HashCode512);
+ size = ntohl (value->size);
+ type = ntohl (value->type);
+ prio = ntohl (value->prio);
+ level = ntohl (value->anonymityLevel);
+ expiration = ntohll (value->expirationTime);
+#if DEBUG_MYSQL
+ IF_GELOG (ectx, GE_DEBUG | GE_REQUEST | GE_USER, hash2enc (key, &enc));
+ GE_LOG (ectx,
+ GE_DEBUG | GE_REQUEST | GE_USER,
+ "Storing in database block with type %u and key %s.\n", type, &enc);
+#endif
+ GE_ASSERT (ectx,
+ mysql_stmt_param_count (dbh->insert_entry) == 7);
+ memset(qbind, 0, sizeof (qbind));
+ qbind[0].buffer_type = MYSQL_TYPE_LONG; /* size */
+ qbind[0].buffer = &size;
+ qbind[0].is_unsigned = YES;
+ qbind[1].buffer_type = MYSQL_TYPE_LONG; /* type */
+ qbind[1].is_unsigned = YES;
+ qbind[1].buffer = &type;
+ qbind[2].buffer_type = MYSQL_TYPE_LONG; /* prio */
+ qbind[2].is_unsigned = YES;
+ qbind[2].buffer = &prio;
+ qbind[3].buffer_type = MYSQL_TYPE_LONG; /* anon level */
+ qbind[3].is_unsigned = YES;
+ qbind[3].buffer = &level;
+ qbind[4].buffer_type = MYSQL_TYPE_LONGLONG; /* expiration */
+ qbind[4].is_unsigned = YES;
+ qbind[4].buffer = &expiration;
+ qbind[5].buffer_type = MYSQL_TYPE_STRING; /* hash */
+ qbind[5].buffer = (void*) key;
+ qbind[5].length = &hashSize;
+ qbind[5].buffer_length = hashSize;
+ qbind[6].buffer_type = MYSQL_TYPE_LONGLONG; /* vkey */
+ qbind[6].is_unsigned = YES;
+ qbind[6].buffer = &vkey;
+
+ if (mysql_stmt_bind_param (dbh->insert_entry, qbind))
{
- mysql_stmt_free_result (dbhI->update);
- mysql_stmt_free_result (dbhI->insert);
- mysql_stmt_free_result (dbhI->select);
- mysql_stmt_free_result (dbhI->selectc);
- mysql_stmt_free_result (dbhI->selects);
- mysql_stmt_free_result (dbhI->selectsc);
- mysql_stmt_free_result (dbhI->deleteh);
- mysql_stmt_free_result (dbhI->deleteg);
- mysql_stmt_close (dbhI->update);
- mysql_stmt_close (dbhI->insert);
- mysql_stmt_close (dbhI->select);
- mysql_stmt_close (dbhI->selectc);
- mysql_stmt_close (dbhI->selects);
- mysql_stmt_close (dbhI->selectsc);
- mysql_stmt_close (dbhI->deleteh);
- mysql_stmt_close (dbhI->deleteg);
+ GE_LOG (ectx,
+ GE_ERROR | GE_BULK | GE_USER,
+ _("`%s' failed at %s:%d with error: %s\n"),
+ "mysql_stmt_bind_param",
+ __FILE__, __LINE__, mysql_stmt_error (dbh->insert_entry));
+ delete_value(vkey);
+ iclose ();
+ mysql_thread_end ();
+ MUTEX_UNLOCK (lock);
+ return SYSERR;
}
- mysql_close (dbhI->dbf);
- dbhI->dbf = NULL;
- dbhI->valid = NO;
+
+ if (mysql_stmt_execute (dbh->insert_entry))
+ {
+ GE_LOG (ectx,
+ GE_ERROR | GE_BULK | GE_USER,
+ _("`%s' failed at %s:%d with error: %s\n"),
+ "mysql_stmt_execute",
+ __FILE__, __LINE__, mysql_stmt_error (dbh->insert_entry));
+ delete_value(vkey);
+ iclose ();
+ mysql_thread_end ();
+ MUTEX_UNLOCK (lock);
+ return SYSERR;
+ }
+ mysql_thread_end ();
+ content_size += ntohl (value->size);
+ MUTEX_UNLOCK (lock);
return OK;
}
-/**
- * Check if DBH handle is valid, return OK if it is.
- * Also tries to re-connect to the DB if the connection
- * is down.
- */
-#define CHECK_DBH ((dbh->valid == NO) ? iopen(dbh, YES) : OK)
+
+
/**
* Iterate over the items in the datastore
* using the given query to select and order
@@ -549,85 +754,194 @@
* @param type entries of which type should be considered?
* Use 0 for any type.
* @param iter never NULL
+ * @param is_asc are we using ascending order?
+ * @param is_int is the extra ordering (other than vkey) an int?
* @return the number of results, SYSERR if the
* iter is non-NULL and aborted the iteration
*/
static int
iterateHelper (unsigned int type,
- const char *query, Datum_Iterator iter, void *closure)
+ int is_asc,
+ int is_int,
+ MYSQL_STMT * stmt, Datum_Iterator iter, void *closure)
{
- MYSQL_RES *sql_res;
- MYSQL_ROW sql_row;
- Datastore_Datum *datum;
- char *scratch;
- char typestr[32];
- int count = 0;
- mysqlHandle dbhI;
+ Datastore_Value * datum;
+ int count;
+ int ret;
+ int found;
+ unsigned int last_prio;
+ unsigned long long last_expire;
+ unsigned long long last_vkey;
+ unsigned int size;
+ unsigned int rtype;
+ unsigned int prio;
+ unsigned int level;
+ unsigned long long expiration;
+ unsigned long long vkey;
+ unsigned long hashSize;
+ HashCode512 key;
cron_t now;
+ MYSQL_BIND qbind[4];
+ MYSQL_BIND rbind[7];
- dbhI.cnffile = dbh->cnffile; /* shared */
- if (OK != iopen (&dbhI, NO))
- return SYSERR;
+ if (is_asc) {
+ last_prio = 0;
+ last_vkey = 0;
+ last_expire = 0;
+ } else {
+ last_prio = -1;
+ last_vkey = -1;
+ last_expire = -1;
+ }
+ if (is_int) {
+ qbind[0].buffer_type = MYSQL_TYPE_LONG;
+ qbind[0].buffer = &last_prio;
+ qbind[0].is_unsigned = YES;
+ qbind[2].buffer_type = MYSQL_TYPE_LONG;
+ qbind[2].buffer = &last_prio;
+ qbind[2].is_unsigned = YES;
+ } else {
+ qbind[0].buffer_type = MYSQL_TYPE_LONGLONG;
+ qbind[0].buffer = &last_expire;
+ qbind[0].is_unsigned = YES;
+ qbind[2].buffer_type = MYSQL_TYPE_LONGLONG;
+ qbind[2].buffer = &last_expire;
+ qbind[2].is_unsigned = YES;
+ }
+ qbind[1].buffer_type = MYSQL_TYPE_LONGLONG;
+ qbind[1].buffer = &last_vkey;
+ qbind[1].is_unsigned = YES;
+ qbind[3].buffer_type = MYSQL_TYPE_LONGLONG;
+ qbind[3].buffer = &now;
+ qbind[3].is_unsigned = YES;
+
+ hashSize = sizeof(HashCode512);
+ memset(rbind, 0, sizeof(rbind));
+ rbind[0].buffer_type = MYSQL_TYPE_LONG;
+ rbind[0].buffer = &size;
+ rbind[0].is_unsigned = YES;
+ rbind[1].buffer_type = MYSQL_TYPE_LONG;
+ rbind[1].buffer = &rtype;
+ rbind[1].is_unsigned = YES;
+ rbind[2].buffer_type = MYSQL_TYPE_LONG;
+ rbind[2].buffer = &prio;
+ rbind[2].is_unsigned = YES;
+ rbind[3].buffer_type = MYSQL_TYPE_LONG;
+ rbind[3].buffer = &level;
+ rbind[3].is_unsigned = YES;
+ rbind[4].buffer_type = MYSQL_TYPE_LONGLONG;
+ rbind[4].buffer = &expiration;
+ rbind[4].is_unsigned = YES;
+ rbind[5].buffer_type = MYSQL_TYPE_STRING;
+ rbind[5].buffer = &key;
+ rbind[5].buffer_length = hashSize;
+ rbind[5].length = &hashSize;
+ rbind[6].buffer_type = MYSQL_TYPE_LONGLONG;
+ rbind[6].buffer = &vkey;
+ rbind[6].is_unsigned = YES;
mysql_thread_init ();
- mysql_query (dbhI.dbf, "SET AUTOCOMMIT = 0");
- mysql_query (dbhI.dbf,
- "SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED");
- if (type == 0)
- {
- typestr[0] = '\0';
+ count = 0;
+ while (1) {
+ MUTEX_LOCK (lock);
+ if (OK != CHECK_DBH) {
+ MUTEX_UNLOCK (lock);
+ mysql_thread_end ();
+ return SYSERR;
}
- else
- {
- SNPRINTF (typestr, 32, "WHERE type=%u ", type);
- }
- now = get_time ();
- scratch = MALLOC (256);
- SNPRINTF (scratch, 256, query, typestr, now);
- mysql_query (dbhI.dbf, scratch);
- FREE (scratch);
- if (mysql_error (dbhI.dbf)[0])
- {
- LOG_MYSQL (GE_ERROR | GE_ADMIN | GE_BULK, "mysql_query", &dbhI);
+ now = get_time ();
+ GE_ASSERT (ectx, mysql_stmt_param_count (stmt) <= 4);
+ if (mysql_stmt_bind_param (stmt, qbind))
+ {
+ GE_LOG (ectx,
+ GE_ERROR | GE_BULK | GE_USER,
+ _("`%s' failed at %s:%d with error: %s\n"),
+ "mysql_stmt_bind_param",
+ __FILE__, __LINE__, mysql_stmt_error (stmt));
+ iclose ();
+ mysql_thread_end ();
+ MUTEX_UNLOCK (lock);
+ return SYSERR;
+ }
+ if (mysql_stmt_execute (stmt))
+ {
+ GE_LOG (ectx,
+ GE_ERROR | GE_BULK | GE_USER,
+ _("`%s' failed at %s:%d with error: %s\n"),
+ "mysql_stmt_execute",
+ __FILE__, __LINE__, mysql_stmt_error (stmt));
+ iclose ();
+ mysql_thread_end ();
+ MUTEX_UNLOCK (lock);
+ return SYSERR;
+ }
+ GE_ASSERT (ectx,
+ mysql_stmt_field_count (stmt) == 7);
+ if (mysql_stmt_bind_result(stmt,
+ rbind)) {
+ GE_LOG (ectx,
+ GE_ERROR | GE_BULK | GE_USER,
+ _("`%s' failed at %s:%d with error: %s\n"),
+ "mysql_stmt_bind_result",
+ __FILE__, __LINE__, mysql_stmt_error (stmt));
+ iclose ();
mysql_thread_end ();
- iclose (&dbhI);
+ MUTEX_UNLOCK (lock);
return SYSERR;
}
- if (!(sql_res = mysql_use_result (dbhI.dbf)))
- {
- iclose (&dbhI);
- return SYSERR;
- }
- while ((sql_row = mysql_fetch_row (sql_res)))
- {
- datum = assembleDatum (sql_res, sql_row, &dbhI);
- if (datum == NULL)
- {
- mysql_thread_end ();
- iclose (&dbhI);
- return count;
- }
- if ((iter != NULL) &&
- (SYSERR == iter (&datum->key, &datum->value, closure)))
- {
- count = SYSERR;
- FREE (datum);
- break;
- }
- FREE (datum);
+ found = NO;
+ datum = NULL;
+ while (mysql_stmt_fetch(stmt)) {
+ if (datum != NULL) {
+ if (iter == NULL)
+ ret = OK;
+ else
+ ret = iter(&key,
+ datum,
+ closure,
+ vkey);
+ FREE(datum);
+ datum = NULL;
+ if (ret == SYSERR)
+ break;
+ if (ret == NO) {
+ delete_value(vkey);
+ delete_entry_by_vkey(vkey);
+ content_size -= ntohl(datum->size);
+ }
+ }
+ found = YES;
count++;
+ datum = assembleDatum(rbind);
+ mysql_stmt_reset(stmt);
}
- if (mysql_error (dbhI.dbf)[0])
- {
- LOG_MYSQL (GE_ERROR | GE_ADMIN | GE_BULK, "mysql_query", &dbhI);
- mysql_free_result (sql_res);
- mysql_thread_end ();
- iclose (&dbhI);
- return SYSERR;
+ if (found == NO) {
+ mysql_stmt_reset(stmt);
+ MUTEX_UNLOCK (lock);
+ break;
}
- mysql_free_result (sql_res);
+ MUTEX_UNLOCK (lock);
+ if (datum == NULL)
+ continue;
+ ret = iter(&key,
+ datum,
+ closure,
+ vkey);
+ FREE(datum);
+ if (ret == SYSERR)
+ break;
+ if (ret == NO) {
+ MUTEX_LOCK (lock);
+ delete_value(vkey);
+ delete_entry_by_vkey(vkey);
+ content_size -= ntohl(datum->size);
+ MUTEX_UNLOCK (lock);
+ }
+ last_prio = prio;
+ last_vkey = vkey;
+ last_expire = expiration;
+ }
mysql_thread_end ();
- iclose (&dbhI);
return count;
}
@@ -645,8 +959,10 @@
iterateLowPriority (unsigned int type, Datum_Iterator iter, void *closure)
{
return iterateHelper (type,
- "SELECT SQL_NO_CACHE * FROM gn070"
- " %s" "ORDER BY prio ASC", iter, closure);
+ YES, YES,
+ dbh->ilow,
+ iter,
+ closure);
}
/**
@@ -661,21 +977,13 @@
*/
static int
iterateNonAnonymous (unsigned int type,
- int on_demand, Datum_Iterator iter, void *closure)
+ Datum_Iterator iter, void *closure)
{
- char limit[512];
-
- if (on_demand == YES)
- SNPRINTF (limit,
- 512,
- "SELECT SQL_NO_CACHE * FROM gn070"
- " %%s WHERE expire > %%llu AND anonLevel = 0 AND type != %d",
- ONDEMAND_BLOCK);
- else
- strcpy (limit,
- "SELECT SQL_NO_CACHE * FROM gn070"
- " %s WHERE expire > %llu AND anonLevel = 0");
- return iterateHelper (type, limit, iter, closure);
+ return iterateHelper (type,
+ NO, YES,
+ dbh->inon,
+ iter,
+ closure);
}
/**
@@ -692,8 +1000,10 @@
iterateExpirationTime (unsigned int type, Datum_Iterator iter, void *closure)
{
return iterateHelper (type,
- "SELECT SQL_NO_CACHE * FROM gn070"
- " %s" " ORDER BY expire ASC", iter, closure);
+ YES, NO,
+ dbh->iexp,
+ iter,
+ closure);
}
/**
@@ -708,9 +1018,11 @@
iterateMigrationOrder (Datum_Iterator iter, void *closure)
{
return iterateHelper (0,
- "SELECT SQL_NO_CACHE * FROM gn070"
- " %s WHERE expire > %llu AND type!=3"
- " ORDER BY expire DESC", iter, closure);
+ NO,
+ NO,
+ dbh->imig,
+ iter,
+ closure);
}
/**
@@ -724,11 +1036,13 @@
static int
iterateAllNow (Datum_Iterator iter, void *closure)
{
- return iterateHelper (0, "SELECT SQL_NO_CACHE * FROM gn070", iter, closure);
+ return iterateHelper (0,
+ NO,
+ NO,
+ dbh->iall,
+ iter, closure);
}
-#define MAX_DATUM_SIZE 65536
-
/**
* Iterate over the results for a particular key
* in the datastore.
@@ -744,19 +1058,20 @@
get (const HashCode512 * query,
unsigned int type, Datum_Iterator iter, void *closure)
{
- MYSQL_RES *sql_res;
int count;
- MYSQL_STMT *stmt;
+ int ret;
+ MYSQL_STMT * stmt;
unsigned int size;
unsigned int rtype;
unsigned int prio;
unsigned int level;
unsigned long long expiration;
- unsigned long datasize;
- unsigned long twenty;
- Datastore_Value *datum;
+ unsigned long long vkey;
+ Datastore_Value * datum;
HashCode512 key;
unsigned long hashSize;
+ MYSQL_BIND qbind[2];
+ MYSQL_BIND rbind[7];
#if DEBUG_MYSQL
EncName enc;
#endif
@@ -781,55 +1096,41 @@
if (type != 0)
{
if (iter == NULL)
- stmt = dbh->selectsc;
+ stmt = dbh->count_entry_by_hash_and_type;
else
- stmt = dbh->selects;
+ stmt = dbh->select_entry_by_hash_and_type;
}
else
{
if (iter == NULL)
- stmt = dbh->selectc;
+ stmt = dbh->count_entry_by_hash;
else
- stmt = dbh->select;
+ stmt = dbh->select_entry_by_hash;
}
+
hashSize = sizeof (HashCode512);
- dbh->sbind[0].buffer = (char *) query;
- dbh->sbind[1].buffer = (char *) &type;
- dbh->sbind[0].length = &hashSize;
+ memset(qbind, 0, sizeof(qbind));
+ qbind[0].buffer_type = MYSQL_TYPE_STRING;
+ qbind[0].buffer = (void*) query;
+ qbind[0].length = &hashSize;
+ qbind[0].buffer_length = hashSize;
+ qbind[1].buffer_type = MYSQL_TYPE_LONG;
+ qbind[1].buffer = &type;
GE_ASSERT (ectx, mysql_stmt_param_count (stmt) <= 2);
- sql_res = mysql_stmt_result_metadata (stmt);
- if (!sql_res)
+
+ if (mysql_stmt_bind_param (stmt, qbind))
{
GE_LOG (ectx,
GE_ERROR | GE_BULK | GE_USER,
_("`%s' failed at %s:%d with error: %s\n"),
- "mysql_stmt_result_metadata",
- __FILE__, __LINE__, mysql_stmt_error (stmt));
- iclose (dbh);
- mysql_thread_end ();
- MUTEX_UNLOCK (lock);
- return SYSERR;
- }
- if ((iter != NULL) && (7 != mysql_num_fields (sql_res)))
- {
- GE_BREAK (ectx, 0);
- iclose (dbh);
- mysql_thread_end ();
- MUTEX_UNLOCK (lock);
- return SYSERR;
- }
- if (mysql_stmt_bind_param (stmt, dbh->sbind))
- {
- GE_LOG (ectx,
- GE_ERROR | GE_BULK | GE_USER,
- _("`%s' failed at %s:%d with error: %s\n"),
"mysql_stmt_bind_param",
__FILE__, __LINE__, mysql_stmt_error (stmt));
- iclose (dbh);
+ iclose ();
mysql_thread_end ();
MUTEX_UNLOCK (lock);
return SYSERR;
}
+
if (mysql_stmt_execute (stmt))
{
GE_LOG (ectx,
@@ -837,11 +1138,12 @@
_("`%s' failed at %s:%d with error: %s\n"),
"mysql_stmt_execute",
__FILE__, __LINE__, mysql_stmt_error (stmt));
- iclose (dbh);
+ iclose ();
mysql_thread_end ();
MUTEX_UNLOCK (lock);
return SYSERR;
}
+
if (iter == NULL)
{
count = mysql_stmt_affected_rows (stmt);
@@ -849,473 +1151,80 @@
mysql_thread_end ();
MUTEX_UNLOCK (lock);
return count;
- }
- datum = MALLOC (sizeof (Datastore_Value) + MAX_DATUM_SIZE);
- twenty = sizeof (HashCode512);
- dbh->bind[0].buffer = (char *) &size;
- dbh->bind[1].buffer = (char *) &rtype;
- dbh->bind[2].buffer = (char *) &prio;
- dbh->bind[3].buffer = (char *) &level;
- dbh->bind[4].buffer = (char *) &expiration;
- dbh->bind[5].buffer = (char *) &key;
- dbh->bind[6].buffer = (char *) &datum[1];
- dbh->bind[5].length = &twenty;
- dbh->bind[6].length = &datasize;
- dbh->bind[5].buffer_length = sizeof (HashCode512);
- dbh->bind[6].buffer_length = MAX_DATUM_SIZE;
- if (mysql_stmt_bind_result (stmt, dbh->bind))
- {
- GE_LOG (ectx,
- GE_ERROR | GE_BULK | GE_USER,
- _("`%s' failed at %s:%d with error: %s\n"),
- "mysql_stmt_bind_result",
- __FILE__, __LINE__, mysql_stmt_error (stmt));
- iclose (dbh);
- mysql_thread_end ();
- MUTEX_UNLOCK (lock);
- FREE (datum);
- return SYSERR;
- }
- if (mysql_stmt_store_result (stmt))
- {
- GE_LOG (ectx,
- GE_ERROR | GE_BULK | GE_USER,
- _("`%s' failed at %s:%d with error: %s\n"),
- "mysql_stmt_store_result",
- __FILE__, __LINE__, mysql_stmt_error (stmt));
- iclose (dbh);
- mysql_thread_end ();
- MUTEX_UNLOCK (lock);
- FREE (datum);
- return SYSERR;
- }
- datasize = MAX_DATUM_SIZE;
+ }
+ GE_ASSERT (ectx,
+ mysql_stmt_field_count (stmt) == 7);
+ memset(rbind, 0, sizeof(rbind));
+ rbind[0].buffer_type = MYSQL_TYPE_LONG;
+ rbind[0].buffer = &size;
+ rbind[0].is_unsigned = YES;
+ rbind[1].buffer_type = MYSQL_TYPE_LONG;
+ rbind[1].buffer = &rtype;
+ rbind[1].is_unsigned = YES;
+ rbind[2].buffer_type = MYSQL_TYPE_LONG;
+ rbind[2].buffer = &prio;
+ rbind[2].is_unsigned = YES;
+ rbind[3].buffer_type = MYSQL_TYPE_LONG;
+ rbind[3].buffer = &level;
+ rbind[3].is_unsigned = YES;
+ rbind[4].buffer_type = MYSQL_TYPE_LONGLONG;
+ rbind[4].buffer = &expiration;
+ rbind[4].is_unsigned = YES;
+ rbind[5].buffer_type = MYSQL_TYPE_STRING;
+ rbind[5].buffer = &key;
+ rbind[5].buffer_length = hashSize;
+ rbind[5].length = &hashSize;
+ rbind[6].buffer_type = MYSQL_TYPE_LONGLONG;
+ rbind[6].buffer = &vkey;
+ rbind[6].is_unsigned = YES;
+ if (mysql_stmt_bind_result(dbh->select_value,
+ rbind)) {
+ GE_LOG (ectx,
+ GE_ERROR | GE_BULK | GE_USER,
+ _("`%s' failed at %s:%d with error: %s\n"),
+ "mysql_stmt_bind_result",
+ __FILE__, __LINE__, mysql_stmt_error (stmt));
+ iclose ();
+ mysql_thread_end ();
+ MUTEX_UNLOCK (lock);
+ return SYSERR;
+ }
count = 0;
- while (0 == mysql_stmt_fetch (stmt))
- {
- if ((twenty != sizeof (HashCode512)) ||
- (datasize != size - sizeof (Datastore_Value)))
- {
- char scratch[512];
-
- mysql_free_result (sql_res);
- GE_LOG (ectx,
- GE_WARNING | GE_BULK | GE_USER,
- _("Invalid data in %s. Trying to fix (by deletion).\n"),
- _("mysql datastore"));
- SNPRINTF (scratch,
- 512,
- "DELETE FROM gn070 WHERE NOT ((LENGTH(hash)=%u) AND
(size=%u + LENGTH(value)))",
- sizeof (HashCode512), sizeof (Datastore_Value));
- if (0 != mysql_query (dbh->dbf, scratch))
- LOG_MYSQL (GE_ERROR | GE_ADMIN | GE_BULK, "mysql_query", dbh);
-
- FREE (datum);
- iclose (dbh);
- mysql_thread_end ();
- MUTEX_UNLOCK (lock);
- return count;
- }
- count++;
- datum->size = htonl (size);
- datum->type = htonl (rtype);
- datum->prio = htonl (prio);
- datum->anonymityLevel = htonl (level);
- datum->expirationTime = htonll (expiration);
-#if DEBUG_MYSQL
- GE_LOG (ectx,
- GE_DEBUG | GE_REQUEST | GE_USER,
- "Found in database block with type %u.\n",
- ntohl (*(int *) &datum[1]));
-#endif
- if (SYSERR == iter (&key, datum, closure))
- {
- count = SYSERR;
- break;
- }
- datasize = MAX_DATUM_SIZE;
+ while (mysql_stmt_fetch(stmt)) {
+ datum = assembleDatum(rbind);
+ if (datum == NULL)
+ continue;
+ count++;
+ ret = iter(&key,
+ datum,
+ closure,
+ vkey);
+ FREE(datum);
+ if (ret == SYSERR)
+ break;
+ if (ret == NO) {
+ delete_value(vkey);
+ delete_entry_by_vkey(vkey);
+ content_size -= ntohl(datum->size);
}
- if (mysql_stmt_errno (stmt))
- {
- GE_LOG (ectx,
- GE_ERROR | GE_BULK | GE_USER,
- _("`%s' failed at %s:%d with error: %s\n"),
- "mysql_stmt_fetch",
- __FILE__, __LINE__, mysql_stmt_error (stmt));
- mysql_free_result (sql_res);
- FREE (datum);
- iclose (dbh);
- mysql_thread_end ();
- MUTEX_UNLOCK (lock);
- return SYSERR;
- }
- mysql_free_result (sql_res);
- FREE (datum);
+ }
+ mysql_stmt_reset(stmt);
mysql_thread_end ();
MUTEX_UNLOCK (lock);
-
-#if DEBUG_MYSQL
- IF_GELOG (ectx, GE_DEBUG | GE_REQUEST | GE_USER, hash2enc (query, &enc));
- if (count > 0)
- {
- GE_LOG (ectx,
- GE_DEBUG | GE_REQUEST | GE_USER,
- "MySQL found %d results for `%s' of type %u.\n",
- count, &enc, type);
- }
- else
- {
- GE_LOG (ectx,
- GE_DEBUG | GE_REQUEST | GE_USER,
- "MySQL iteration aborted looking for `%s' of type %u.\n",
- &enc, type);
- }
-#endif
return count;
}
/**
- * Store an item in the datastore.
- *
- * @return OK on success, SYSERR on error
- */
-static int
-put (const HashCode512 * key, const Datastore_Value * value)
-{
- unsigned long contentSize;
- unsigned long hashSize;
- unsigned int size;
- unsigned int type;
- unsigned int prio;
- unsigned int level;
- unsigned long long expiration;
-#if DEBUG_MYSQL
- EncName enc;
-#endif
-
- if ((ntohl (value->size) < sizeof (Datastore_Value)))
- {
- GE_BREAK (ectx, 0);
- return SYSERR;
- }
- MUTEX_LOCK (lock);
- mysql_thread_init ();
- if (OK != CHECK_DBH)
- {
- mysql_thread_end ();
- MUTEX_UNLOCK (lock);
- return SYSERR;
- }
- contentSize = ntohl (value->size) - sizeof (Datastore_Value);
- hashSize = sizeof (HashCode512);
- size = ntohl (value->size);
- type = ntohl (value->type);
- prio = ntohl (value->prio);
- level = ntohl (value->anonymityLevel);
- expiration = ntohll (value->expirationTime);
-#if DEBUG_MYSQL
- IF_GELOG (ectx, GE_DEBUG | GE_REQUEST | GE_USER, hash2enc (key, &enc));
- GE_LOG (ectx,
- GE_DEBUG | GE_REQUEST | GE_USER,
- "Storing in database block with type %u and key %s.\n", type, &enc);
-#endif
- dbh->bind[0].buffer = (char *) &size;
- dbh->bind[1].buffer = (char *) &type;
- dbh->bind[2].buffer = (char *) &prio;
- dbh->bind[3].buffer = (char *) &level;
- dbh->bind[4].buffer = (char *) &expiration;
- dbh->bind[5].buffer = (char *) key;
- dbh->bind[6].buffer = (char *) &value[1];
- dbh->bind[5].length = &hashSize;
- dbh->bind[6].length = &contentSize;
-
- if (mysql_stmt_bind_param (dbh->insert, dbh->bind))
- {
- GE_LOG (ectx,
- GE_ERROR | GE_BULK | GE_USER,
- _("`%s' failed at %s:%d with error: %s\n"),
- "mysql_stmt_bind_param",
- __FILE__, __LINE__, mysql_stmt_error (dbh->insert));
- iclose (dbh);
- mysql_thread_end ();
- MUTEX_UNLOCK (lock);
- return SYSERR;
- }
-
- if (mysql_stmt_execute (dbh->insert))
- {
- GE_LOG (ectx,
- GE_ERROR | GE_BULK | GE_USER,
- _("`%s' failed at %s:%d with error: %s\n"),
- "mysql_stmt_execute",
- __FILE__, __LINE__, mysql_stmt_error (dbh->insert));
- iclose (dbh);
- mysql_thread_end ();
- MUTEX_UNLOCK (lock);
- return SYSERR;
- }
- mysql_thread_end ();
- content_size += ntohl (value->size);
- MUTEX_UNLOCK (lock);
- return OK;
-}
-
-/**
- * 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 HashCode512 * key, const Datastore_Value * value)
-{
- int count;
- unsigned long twenty;
- MYSQL_STMT *stmt;
- unsigned int size;
- unsigned int type;
- unsigned int prio;
- unsigned int anon;
- unsigned long long expiration;
- unsigned long datasize;
- Datastore_Value *svalue;
- MYSQL_RES *sql_res;
- unsigned int rtype;
- unsigned int level;
- HashCode512 skey;
-#if DEBUG_MYSQL
- EncName enc;
-
- IF_GELOG (ectx, GE_DEBUG | GE_REQUEST | GE_USER, hash2enc (key, &enc));
- GE_LOG (ectx,
- GE_DEBUG | GE_REQUEST | GE_USER,
- "MySQL is executing deletion request for content of query `%s' and
type %u\n",
- &enc, value == NULL ? 0 : ntohl (value->type));
-#endif
- twenty = sizeof (HashCode512);
- svalue = NULL;
- MUTEX_LOCK (lock);
- mysql_thread_init ();
- if (OK != CHECK_DBH)
- {
- mysql_thread_end ();
- MUTEX_UNLOCK (lock);
- return SYSERR;
- }
- if (value == NULL)
- {
- stmt = dbh->deleteh;
- dbh->dbind[0].buffer = (char *) key;
- dbh->dbind[0].length = &twenty;
- GE_ASSERT (ectx, mysql_stmt_param_count (stmt) <= 1);
-
- sql_res = mysql_stmt_result_metadata (stmt);
- if (!sql_res)
- {
- GE_LOG (ectx,
- GE_ERROR | GE_BULK | GE_USER,
- _("`%s' failed at %s:%d with error: %s\n"),
- "mysql_stmt_result_metadata",
- __FILE__, __LINE__, mysql_stmt_error (stmt));
- iclose (dbh);
- mysql_thread_end ();
- MUTEX_UNLOCK (lock);
- return SYSERR;
- }
- if (7 != mysql_num_fields (sql_res))
- {
- GE_BREAK (ectx, 0);
- iclose (dbh);
- mysql_thread_end ();
- MUTEX_UNLOCK (lock);
- return SYSERR;
- }
- if (mysql_stmt_bind_param (stmt, dbh->dbind))
- {
- GE_LOG (ectx,
- GE_ERROR | GE_BULK | GE_USER,
- _("`%s' failed at %s:%d with error: %s\n"),
- "mysql_stmt_bind_param",
- __FILE__, __LINE__, mysql_stmt_error (stmt));
- iclose (dbh);
- mysql_thread_end ();
- MUTEX_UNLOCK (lock);
- return SYSERR;
- }
- if (mysql_stmt_execute (stmt))
- {
- GE_LOG (ectx,
- GE_ERROR | GE_BULK | GE_USER,
- _("`%s' failed at %s:%d with error: %s\n"),
- "mysql_stmt_execute",
- __FILE__, __LINE__, mysql_stmt_error (stmt));
- iclose (dbh);
- mysql_thread_end ();
- MUTEX_UNLOCK (lock);
- return SYSERR;
- }
- svalue = MALLOC (sizeof (Datastore_Value) + MAX_DATUM_SIZE);
- twenty = sizeof (HashCode512);
- dbh->bind[0].buffer = (char *) &size;
- dbh->bind[1].buffer = (char *) &rtype;
- dbh->bind[2].buffer = (char *) &prio;
- dbh->bind[3].buffer = (char *) &level;
- dbh->bind[4].buffer = (char *) &expiration;
- dbh->bind[5].buffer = (char *) &skey;
- dbh->bind[6].buffer = (char *) &svalue[1];
- dbh->bind[5].length = &twenty;
- dbh->bind[6].length = &datasize;
- dbh->bind[5].buffer_length = sizeof (HashCode512);
- dbh->bind[6].buffer_length = MAX_DATUM_SIZE;
- if (mysql_stmt_bind_result (stmt, dbh->bind))
- {
- GE_LOG (ectx,
- GE_ERROR | GE_BULK | GE_USER,
- _("`%s' failed at %s:%d with error: %s\n"),
- "mysql_stmt_bind_result",
- __FILE__, __LINE__, mysql_stmt_error (stmt));
- iclose (dbh);
- mysql_thread_end ();
- MUTEX_UNLOCK (lock);
- FREE (svalue);
- return SYSERR;
- }
- if (mysql_stmt_store_result (stmt))
- {
- GE_LOG (ectx,
- GE_ERROR | GE_BULK | GE_USER,
- _("`%s' failed at %s:%d with error: %s\n"),
- "mysql_stmt_store_result",
- __FILE__, __LINE__, mysql_stmt_error (stmt));
- iclose (dbh);
- mysql_thread_end ();
- MUTEX_UNLOCK (lock);
- FREE (svalue);
- return SYSERR;
- }
- datasize = MAX_DATUM_SIZE;
- if (0 != mysql_stmt_fetch (stmt))
- {
- GE_LOG (ectx,
- GE_ERROR | GE_BULK | GE_USER,
- _("`%s' failed at %s:%d with error: %s\n"),
- "mysql_stmt_fetch",
- __FILE__, __LINE__, mysql_stmt_error (stmt));
- iclose (dbh);
- mysql_thread_end ();
- MUTEX_UNLOCK (lock);
- FREE (svalue);
- return SYSERR;
- }
- if ((twenty != sizeof (HashCode512)) ||
- (datasize != size - sizeof (Datastore_Value)))
- {
- char scratch[512];
-
- mysql_free_result (sql_res);
- GE_LOG (ectx,
- GE_WARNING | GE_BULK | GE_USER,
- _("Invalid data in %s. Trying to fix (by deletion).\n"),
- _("mysql datastore"));
- SNPRINTF (scratch,
- 512,
- "DELETE FROM gn070 WHERE NOT ((LENGTH(hash)=%u) AND
(size=%u + LENGTH(value)))",
- sizeof (HashCode512), sizeof (Datastore_Value));
- if (0 != mysql_query (dbh->dbf, scratch))
- LOG_MYSQL (GE_ERROR | GE_ADMIN | GE_BULK, "mysql_query", dbh);
- FREE (svalue);
- iclose (dbh);
- mysql_thread_end ();
- MUTEX_UNLOCK (lock);
- return 1;
- }
- mysql_free_result (sql_res);
- svalue->size = htonl (size);
- svalue->type = htonl (rtype);
- svalue->prio = htonl (prio);
- svalue->anonymityLevel = htonl (level);
- svalue->expirationTime = htonll (expiration);
- value = svalue;
- }
-
- stmt = dbh->deleteg;
- type = ntohl (value->type);
- size = ntohl (value->size);
- prio = ntohl (value->prio);
- anon = ntohl (value->anonymityLevel);
- expiration = ntohll (value->expirationTime);
- datasize = ntohl (value->size) - sizeof (Datastore_Value);
- dbh->dbind[0].buffer = (char *) key;
- dbh->dbind[0].length = &twenty;
- dbh->dbind[1].buffer = (char *) &size;
- dbh->dbind[2].buffer = (char *) &type;
- dbh->dbind[3].buffer = (char *) &prio;
- dbh->dbind[4].buffer = (char *) &anon;
- dbh->dbind[5].buffer = (char *) &expiration;
- dbh->dbind[6].buffer = (char *) &value[1];
- dbh->dbind[6].length = &datasize;
-#if 0
- dbh->dbind[0].buffer_length = sizeof (HashCode512);
- dbh->dbind[6].buffer_length = size - sizeof (Datastore_Value);
-#endif
- GE_ASSERT (ectx, mysql_stmt_param_count (stmt) <= 7);
- if (mysql_stmt_bind_param (stmt, dbh->dbind))
- {
- GE_LOG (ectx,
- GE_ERROR | GE_BULK | GE_USER,
- _("`%s' failed at %s:%d with error: %s\n"),
- "mysql_stmt_bind_param",
- __FILE__, __LINE__, mysql_stmt_error (stmt));
- iclose (dbh);
- mysql_thread_end ();
- MUTEX_UNLOCK (lock);
- if (svalue != NULL)
- FREE (svalue);
- return SYSERR;
- }
- if (mysql_stmt_execute (stmt))
- {
- GE_LOG (ectx,
- GE_ERROR | GE_BULK | GE_USER,
- _("`%s' failed at %s:%d with error: %s\n"),
- "mysql_stmt_execute",
- __FILE__, __LINE__, mysql_stmt_error (stmt));
- iclose (dbh);
- mysql_thread_end ();
- MUTEX_UNLOCK (lock);
- if (svalue != NULL)
- FREE (svalue);
- return SYSERR;
- }
- count = mysql_stmt_affected_rows (stmt);
- mysql_thread_end ();
-#if DEBUG_MYSQL
- GE_LOG (ectx,
- GE_DEBUG | GE_REQUEST | GE_USER,
- "MySQL DELETE operation affected %d rows.\n", count);
-#endif
- content_size -= ntohl (value->size);
- MUTEX_UNLOCK (lock);
- if (svalue != NULL)
- FREE (svalue);
- return count;
-}
-
-/**
* Update the priority for a particular key
* in the datastore.
*/
static int
-update (const HashCode512 * key,
- const Datastore_Value * value, int delta, cron_t expire)
+update (unsigned long long vkey,
+ int delta, cron_t expire)
{
- unsigned long contentSize;
- unsigned long twenty;
cron_t start;
+ MYSQL_BIND qbind[4];
- twenty = sizeof (HashCode512);
MUTEX_LOCK (lock);
mysql_thread_init ();
if (OK != CHECK_DBH)
@@ -1324,23 +1233,27 @@
MUTEX_UNLOCK (lock);
return SYSERR;
}
- contentSize = ntohl (value->size) - sizeof (Datastore_Value);
- dbh->ubind[0].buffer = (char *) δ
- dbh->ubind[1].buffer = (char *) &expire;
- dbh->ubind[2].buffer = (char *) &expire;
- dbh->ubind[3].buffer = (char *) key;
- dbh->ubind[3].length = &twenty;
- dbh->ubind[4].buffer = (char *) &value[1];
- dbh->ubind[4].length = &contentSize;
- GE_ASSERT (ectx, mysql_stmt_param_count (dbh->update) <= 5);
- if (mysql_stmt_bind_param (dbh->update, dbh->ubind))
+ memset(qbind, 0, sizeof(qbind));
+ qbind[0].buffer_type = MYSQL_TYPE_LONG;
+ qbind[0].buffer = δ
+ qbind[1].buffer_type = MYSQL_TYPE_LONGLONG;
+ qbind[1].buffer = &expire;
+ qbind[1].is_unsigned = YES;
+ qbind[2].buffer_type = MYSQL_TYPE_LONGLONG;
+ qbind[2].is_unsigned = YES;
+ qbind[2].buffer = &expire;
+ qbind[3].buffer_type = MYSQL_TYPE_LONGLONG;
+ qbind[3].is_unsigned = YES;
+ qbind[3].buffer = &vkey;
+ GE_ASSERT (ectx, mysql_stmt_param_count (dbh->update_entry) == 4);
+ if (mysql_stmt_bind_param (dbh->update_entry, qbind))
{
GE_LOG (ectx,
GE_ERROR | GE_BULK | GE_USER,
_("`%s' failed at %s:%d with error: %s\n"),
"mysql_stmt_bind_param",
- __FILE__, __LINE__, mysql_stmt_error (dbh->update));
- iclose (dbh);
+ __FILE__, __LINE__, mysql_stmt_error (dbh->update_entry));
+ iclose ();
mysql_thread_end ();
MUTEX_UNLOCK (lock);
return SYSERR;
@@ -1351,24 +1264,26 @@
* at all in this context.)
*/
start = get_time ();
- if (mysql_stmt_execute (dbh->update))
+ if (mysql_stmt_execute (dbh->update_entry))
{
GE_LOG (ectx,
GE_ERROR | GE_BULK | GE_USER,
_("`%s' failed at %s:%d with error `%s' after %llums\n"),
"mysql_stmt_execute",
__FILE__, __LINE__,
- mysql_stmt_error (dbh->update), get_time () - start);
- iclose (dbh);
+ mysql_stmt_error (dbh->update_entry), get_time () - start);
+ iclose ();
mysql_thread_end ();
MUTEX_UNLOCK (lock);
return SYSERR;
}
+ mysql_stmt_reset(dbh->update_entry);
mysql_thread_end ();
MUTEX_UNLOCK (lock);
return OK;
}
+
/**
* Get the current on-disk size of the SQ store.
* Estimates are fine, if that's the only thing
@@ -1385,7 +1300,7 @@
if (stats)
stats->set (stat_size, ret);
MUTEX_UNLOCK (lock);
- return ret * 2; /* common overhead seems to be 100%! */
+ return ret * 2; /* FIXME: measure again! */
}
/**
@@ -1395,6 +1310,9 @@
static void
drop ()
{
+ int ok;
+
+ ok = YES;
MUTEX_LOCK (lock);
mysql_thread_init ();
if (OK != CHECK_DBH)
@@ -1403,16 +1321,21 @@
MUTEX_UNLOCK (lock);
return;
}
- mysql_query (dbh->dbf, "DROP TABLE gn070");
+ mysql_query (dbh->dbf, "DROP TABLE gn071");
if (mysql_error (dbh->dbf)[0])
{
LOG_MYSQL (GE_ERROR | GE_ADMIN | GE_BULK, "mysql_query", dbh);
- iclose (dbh);
+ ok = NO;
}
- else
+ mysql_query (dbh->dbf, "DROP TABLE gn072");
+ if (mysql_error (dbh->dbf)[0])
{
- content_size = 0;
+ LOG_MYSQL (GE_ERROR | GE_ADMIN | GE_BULK, "mysql_query", dbh);
+ ok = NO;
}
+ if (ok == YES)
+ content_size = 0;
+ iclose();
mysql_thread_end ();
MUTEX_UNLOCK (lock);
}
@@ -1473,8 +1396,9 @@
fclose (fp);
}
dbh = MALLOC (sizeof (mysqlHandle));
+ memset(dbh, 0, sizeof(mysqlHandle));
dbh->cnffile = cnffile;
- if (OK != iopen (dbh, YES))
+ if (OK != iopen ())
{
FREE (cnffile);
FREE (dbh);
@@ -1541,7 +1465,6 @@
api.iterateExpirationTime = &iterateExpirationTime;
api.iterateMigrationOrder = &iterateMigrationOrder;
api.iterateAllNow = &iterateAllNow;
- api.del = &del;
api.drop = &drop;
api.update = &update;
return &api;
@@ -1554,11 +1477,11 @@
release_module_sqstore_mysql ()
{
State_ServiceAPI *state;
+
iclose (dbh);
FREE (dbh->cnffile);
FREE (dbh);
dbh = NULL;
-
if (stats != NULL)
coreAPI->releaseService (stats);
MUTEX_DESTROY (lock);
Modified: GNUnet/src/applications/sqstore_mysql/mysqltest.c
===================================================================
--- GNUnet/src/applications/sqstore_mysql/mysqltest.c 2007-07-21 07:21:17 UTC
(rev 5327)
+++ GNUnet/src/applications/sqstore_mysql/mysqltest.c 2007-07-22 01:56:14 UTC
(rev 5328)
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet.
- (C) 2004, 2005, 2006 Christian Grothoff (and other contributing authors)
+ (C) 2004, 2005, 2006, 2007 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
@@ -52,7 +52,8 @@
static int
checkValue (const HashCode512 * key,
- const Datastore_Value * val, void *closure)
+ const Datastore_Value * val, void *closure,
+ unsigned long long uid)
{
int i;
int ret;
@@ -77,39 +78,49 @@
}
static int
-iterateUp (const HashCode512 * key, const Datastore_Value * val, int *closure)
+iterateUp (const HashCode512 * key, const Datastore_Value * val, int *closure,
+ unsigned long long uid)
{
int ret;
- ret = checkValue (key, val, closure);
+ ret = checkValue (key, val, closure, uid);
(*closure) += 2;
return ret;
}
static int
iterateDown (const HashCode512 * key,
- const Datastore_Value * val, int *closure)
+ const Datastore_Value * val, int *closure,
+ unsigned long long uid)
{
int ret;
(*closure) -= 2;
- ret = checkValue (key, val, closure);
+ ret = checkValue (key, val, closure, uid);
return ret;
}
static int
iterateDelete (const HashCode512 * key,
- const Datastore_Value * val, SQstore_ServiceAPI * api)
+ const Datastore_Value * val, void * closure,
+ unsigned long long uid)
{
- if (1 == api->del (key, val))
- return OK;
- else
- return SYSERR;
+ return NO;
}
static int
+iteratePriority (const HashCode512 * key,
+ const Datastore_Value * val, SQstore_ServiceAPI * api,
+ unsigned long long uid)
+{
+ api->update(uid, 4, 0);
+ return OK;
+}
+
+static int
priorityCheck (const HashCode512 * key,
- const Datastore_Value * val, int *closure)
+ const Datastore_Value * val, int *closure,
+ unsigned long long uid)
{
int id;
@@ -122,7 +133,8 @@
static int
multipleCheck (const HashCode512 * key,
- const Datastore_Value * val, Datastore_Value ** last)
+ const Datastore_Value * val, Datastore_Value ** last,
+ unsigned long long uid)
{
if (*last != NULL)
{
@@ -171,7 +183,7 @@
{
memset (&key, 256 - i, sizeof (HashCode512));
value = initValue (i);
- ASSERT (1 == api->del (&key, value));
+ ASSERT (1 == api->get (&key, 0, &iterateDelete, NULL));
FREE (value);
}
ASSERT (oldSize > api->getSize ());
@@ -197,7 +209,8 @@
ASSERT (1 == api->iterateExpirationTime (ANY_BLOCK,
(Datum_Iterator) & priorityCheck,
&i));
- api->update (&key, value, 4, 0);
+ ASSERT (1 == api->iterateAllNow((Datum_Iterator) & iteratePriority,
+ api));
i += 4;
ASSERT (1 == api->iterateExpirationTime (ANY_BLOCK,
(Datum_Iterator) & priorityCheck,
@@ -214,8 +227,8 @@
(Datum_Iterator) & multipleCheck,
&value));
FREE (value);
- api->del (&key, NULL);
- api->del (&key, NULL);
+ ASSERT (2 == api->iterateAllNow ((Datum_Iterator) & iterateDelete,
+ api));
ASSERT (0 == api->iterateExpirationTime (ANY_BLOCK, NULL, NULL));
api->drop ();
Modified: GNUnet/src/applications/sqstore_mysql/mysqltest2.c
===================================================================
--- GNUnet/src/applications/sqstore_mysql/mysqltest2.c 2007-07-21 07:21:17 UTC
(rev 5327)
+++ GNUnet/src/applications/sqstore_mysql/mysqltest2.c 2007-07-22 01:56:14 UTC
(rev 5328)
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet.
- (C) 2004, 2005, 2006 Christian Grothoff (and other contributing authors)
+ (C) 2004, 2005, 2006, 2007 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
@@ -166,7 +166,8 @@
static int
iterateDelete (const HashCode512 * key,
- const Datastore_Value * val, void *cls)
+ const Datastore_Value * val, void *cls,
+ unsigned long long uid)
{
SQstore_ServiceAPI *api = cls;
static int dc;
@@ -180,10 +181,9 @@
if (dc % REP_FREQ == 0)
fprintf (stderr, "D");
#endif
- GE_ASSERT (NULL, 1 == api->del (key, val));
stored_bytes -= ntohl (val->size);
stored_entries--;
- return OK;
+ return NO;
}
/**
Modified: GNUnet/src/applications/sqstore_mysql/mysqltest3.c
===================================================================
--- GNUnet/src/applications/sqstore_mysql/mysqltest3.c 2007-07-21 07:21:17 UTC
(rev 5327)
+++ GNUnet/src/applications/sqstore_mysql/mysqltest3.c 2007-07-22 01:56:14 UTC
(rev 5328)
@@ -70,6 +70,7 @@
size = size - (size & 7); /* always multiple of 8 */
/* generate random key */
+ key.bits[0] = (unsigned int) get_time();
hash (&key, sizeof (HashCode512), &key);
value = MALLOC (size);
value->size = htonl (size);
@@ -94,7 +95,8 @@
}
static int
-iterateDummy (const HashCode512 * key, const Datastore_Value * val, void *cls)
+iterateDummy (const HashCode512 * key, const Datastore_Value * val, void *cls,
+ unsigned long long uid)
{
if (GNUNET_SHUTDOWN_TEST () == YES)
return SYSERR;
@@ -137,17 +139,19 @@
if (GNUNET_SHUTDOWN_TEST () == YES)
break;
start = get_time ();
- api->iterateNonAnonymous (0, NO, &iterateDummy, api);
+ api->iterateNonAnonymous (0, &iterateDummy, api);
end = get_time ();
printf ("%3u non anonymou iteration took %20llums\n", i, end - start);
if (GNUNET_SHUTDOWN_TEST () == YES)
break;
+#if 1
start = get_time ();
- api->iterateNonAnonymous (0, YES, &iterateDummy, api);
+ api->iterateNonAnonymous (0, &iterateDummy, api);
end = get_time ();
printf ("%3u non anon YES iteration took %20llums\n", i, end - start);
if (GNUNET_SHUTDOWN_TEST () == YES)
break;
+#endif
start = get_time ();
api->iterateMigrationOrder (&iterateDummy, api);
end = get_time ();
@@ -161,7 +165,6 @@
if (GNUNET_SHUTDOWN_TEST () == YES)
break;
}
- api->drop ();
return OK;
}
Modified: GNUnet/src/applications/sqstore_sqlite/sqlite.c
===================================================================
--- GNUnet/src/applications/sqstore_sqlite/sqlite.c 2007-07-21 07:21:17 UTC
(rev 5327)
+++ GNUnet/src/applications/sqstore_sqlite/sqlite.c 2007-07-22 01:56:14 UTC
(rev 5328)
@@ -690,7 +690,7 @@
count++;
if (iter != NULL)
{
- if (SYSERR == iter (&datum->key, &datum->value, closure))
+ if (SYSERR == iter (&datum->key, &datum->value, closure, 0))
{
FREE (datum);
count = SYSERR;
@@ -743,18 +743,16 @@
*
* @param type limit the iteration to entries of this
* type. 0 for all entries.
- * @param on_demand limit the iteration to entries
- * that not on-demand?
- * @param iter the callback method
+ * @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
iterateNonAnonymous (unsigned int type,
- int on_demand, Datum_Iterator iter, void *closure)
+ Datum_Iterator iter, void *closure)
{
- return sqlite_iterate (0, iter, closure, NO, NO, NO, YES, on_demand);
+ return sqlite_iterate (0, iter, closure, NO, NO, NO, YES, YES);
}
/**
@@ -828,7 +826,7 @@
payload += getContentDatastoreSize (&datum->value);
if (iter != NULL)
{
- if (SYSERR == iter (&datum->key, &datum->value, closure))
+ if (SYSERR == iter (&datum->key, &datum->value, closure, 0))
{
FREE (datum);
count = SYSERR;
@@ -1009,7 +1007,7 @@
"Found in database block with type %u.\n",
ntohl (*(int *) &((&datum->value)[1])));
#endif
- if (SYSERR == iter (&datum->key, &datum->value, closure))
+ if (SYSERR == iter (&datum->key, &datum->value, closure, 0))
{
count = SYSERR;
@@ -1123,137 +1121,12 @@
}
/**
- * 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 HashCode512 * key, const Datastore_Value * value)
-{
- size_t n;
- sqlite3_stmt *stmt;
- int deleted;
- sqliteHandle *dbh;
- Datastore_Datum *dvalue;
- unsigned int size;
- unsigned int type;
- unsigned int prio;
- unsigned int anon;
- unsigned long long expir;
- unsigned long contentSize;
-#if DEBUG_SQLITE
- EncName enc;
-
- IF_GELOG (ectx, GE_DEBUG | GE_REQUEST | GE_USER, hash2enc (key, &enc));
- GE_LOG (ectx,
- GE_DEBUG | GE_REQUEST | GE_USER,
- "SQLite: deleting block with key `%s'\n", &enc);
-#endif
-
- dbh = getDBHandle ();
- if (db->lastSync > 1000)
- syncStats (dbh);
-
- if (NULL == value)
- {
- if (sq_prepare (dbh->dbh,
- "SELECT size, type, prio, anonLevel, expire, hash, value
"
- "FROM gn070 WHERE hash = ? ORDER BY prio ASC",
- &stmt) != SQLITE_OK)
- {
- LOG_SQLITE (dbh,
- GE_ERROR | GE_ADMIN | GE_USER | GE_BULK,
- "sqlite_query");
- return SYSERR;
- }
- sqlite3_bind_blob (stmt,
- 1, key, sizeof (HashCode512), SQLITE_TRANSIENT);
- if (sqlite3_step (stmt) != SQLITE_ROW)
- {
- sqlite3_finalize (stmt);
- return NO;
- }
- dvalue = assembleDatum (dbh, stmt);
- if (dvalue == NULL)
- {
- sqlite3_finalize (stmt);
- return SYSERR;
- }
- sqlite3_finalize (stmt);
- value = &dvalue->value;
- }
- else
- {
- dvalue = NULL;
- }
- contentSize = ntohl (value->size) - sizeof (Datastore_Value);
- n = sq_prepare (dbh->dbh, "DELETE FROM gn070 WHERE hash = ? and " "value = ?
AND size = ? AND type = ? AND prio = ? AND anonLevel = ? " "AND expire = ?",
/* ORDER BY prio ASC LIMIT 1" -- not available in sqlite */
- &stmt);
- if (n == SQLITE_OK)
- {
- size = ntohl (value->size);
- type = ntohl (value->type);
- prio = ntohl (value->prio);
- anon = ntohl (value->anonymityLevel);
- expir = ntohll (value->expirationTime);
-
- sqlite3_bind_blob (stmt, 1, key, sizeof (HashCode512),
- SQLITE_TRANSIENT);
- sqlite3_bind_blob (stmt, 2, &value[1], contentSize, SQLITE_TRANSIENT);
- sqlite3_bind_int (stmt, 3, size);
- sqlite3_bind_int (stmt, 4, type);
- sqlite3_bind_int (stmt, 5, prio);
- sqlite3_bind_int (stmt, 6, anon);
- sqlite3_bind_int64 (stmt, 7, expir);
- n = sqlite3_step (stmt);
- if ((n == SQLITE_DONE) || (n == SQLITE_ROW))
- db->payload -= getContentDatastoreSize (value);
- }
- else
- {
- LOG_SQLITE (dbh,
- GE_ERROR | GE_ADMIN | GE_USER | GE_BULK, "sqlite3_prepare");
- }
- FREENONNULL (dvalue);
- deleted = ((n == SQLITE_DONE)
- || (n == SQLITE_ROW)) ? sqlite3_changes (dbh->dbh) : SYSERR;
- sqlite3_finalize (stmt);
-
- if (n != SQLITE_DONE)
- {
- if (n != SQLITE_BUSY)
- {
- LOG_SQLITE (dbh,
- GE_ERROR | GE_ADMIN | GE_USER | GE_BULK,
- "sqlite_query");
- return SYSERR;
- }
- else
- {
- return NO;
- }
- }
- db->lastSync++;
-
-#if DEBUG_SQLITE
- GE_LOG (ectx,
- GE_DEBUG | GE_REQUEST | GE_USER,
- "SQLite: %d block(s) deleted\n", deleted);
-#endif
-
- return deleted;
-}
-
-/**
* Update the priority for a particular key
* in the datastore.
*/
static int
-update (const HashCode512 * key,
- const Datastore_Value * value, int delta, cron_t expire)
+update (unsigned long long uid,
+ int delta, cron_t expire)
{
int n;
unsigned long contentSize;
Modified: GNUnet/src/include/gnunet_datastore_service.h
===================================================================
--- GNUnet/src/include/gnunet_datastore_service.h 2007-07-21 07:21:17 UTC
(rev 5327)
+++ GNUnet/src/include/gnunet_datastore_service.h 2007-07-22 01:56:14 UTC
(rev 5328)
@@ -1,6 +1,6 @@
/*
This file is part of GNUnet
- (C) 2004, 2005, 2006 Christian Grothoff (and other contributing authors)
+ (C) 2004, 2005, 2006, 2007 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
@@ -84,33 +84,18 @@
} Datastore_Value;
/**
- * An entry (key-value pair) in the datastore.
- */
-typedef struct
-{
-
- /**
- * A key (not unique) that can be used to lookup this Datum in the
- * datastore.
- */
- HashCode512 key;
-
- /**
- * The value associated with the key.
- */
- Datastore_Value value;
-
-} Datastore_Datum;
-
-/**
* An iterator over a set of Datastore items.
*
* @param datum called with the next item
* @param closure user-defined extra argument
- * @return SYSERR to abort the iteration, OK to continue.
+ * @param uid unique identifier for the datum
+ *
+ * @return SYSERR to abort the iteration, OK to continue,
+ * NO to delete the item and continue (if supported)
*/
typedef int (*Datum_Iterator) (const HashCode512 * key,
- const Datastore_Value * value, void *closure);
+ const Datastore_Value * value, void *closure,
+ unsigned long long uid);
/**
@@ -200,16 +185,6 @@
HashCode512 * key,
Datastore_Value ** value, unsigned int type);
- /**
- * 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
- */
- int (*del) (const HashCode512 * key, const Datastore_Value * value);
-
} Datastore_ServiceAPI;
#if 0 /* keep Emacsens' auto-indent happy */
Modified: GNUnet/src/include/gnunet_sqstore_service.h
===================================================================
--- GNUnet/src/include/gnunet_sqstore_service.h 2007-07-21 07:21:17 UTC (rev
5327)
+++ GNUnet/src/include/gnunet_sqstore_service.h 2007-07-22 01:56:14 UTC (rev
5328)
@@ -91,10 +91,7 @@
* Note that it is possible for multiple values to match this put.
* In that case, all of the respective values are updated.
*
- * @param key never NULL
- * @param value the value to update (priority
- * maybe different than in DB, only match
- * on content and use other data as in DB!)
+ * @param uid unique identifier of the datum
* @param delta by how much should the priority
* change? If priority + delta < 0 the
* priority should be set to 0 (never go
@@ -105,8 +102,7 @@
* @return OK if a match was found and the update
* was successful, SYSERR on error
*/
- int (*update) (const HashCode512 * key,
- const Datastore_Value * value, int delta, cron_t expire);
+ int (*update) (unsigned long long uid, int delta, cron_t expire);
/**
* Iterate over the items in the datastore in ascending
@@ -126,14 +122,11 @@
*
* @param type entries of which type should be considered?
* Use 0 for any type.
- * @param on_demand limit the iteration to entries
- * that not on-demand?
* @param iter never NULL
* @return the number of results, SYSERR if the
* iter is non-NULL and aborted the iteration
*/
int (*iterateNonAnonymous) (unsigned int type,
- int on_demand,
Datum_Iterator iter, void *closure);
/**
@@ -173,32 +166,6 @@
int (*iterateAllNow) (Datum_Iterator iter, void *closure);
/**
- * Delete an item from the datastore.
- *
- * Note that it is possible for multiple values to match this del
- * (even if a value is given). In that case, only ONE of the
- * respective values is deleted, and it should be the one with an
- * expired expiration time or, if such an entry does not exist, the
- * lowest priority. (This is done such that if multiple files
- * contain the same data, the data has multiple replicas and all are
- * kept, avoiding unavaialbility if just one of the files is
- * removed).
- *
- * @param value maybe NULL, then all items under the
- * given key are deleted
- * @return the number of items deleted (if possible, the
- * database should delete only ONE matching item and
- * pick the one with the lowest priority [and then
- * lowest expiration time]; if the DB cannot do that,
- * deleting multiple entries will be 'tolerated' for now,
- * but the result is a slightly worse performance of the
- * peer; however, that there are multiple matches should
- * also be rare).
- * 0 if no matching items were found, SYSERR on errors
- */
- int (*del) (const HashCode512 * key, const Datastore_Value * value);
-
- /**
* Delete the database. The next operation is
* guaranteed to be unloading of the module.
*/
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r5328 - in GNUnet/src: applications applications/datastore applications/fs/module applications/sqstore_mysql applications/sqstore_sqlite include,
gnunet <=