gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r2465 - in GNUnet/src: applications/sqstore_sqlite include


From: durner
Subject: [GNUnet-SVN] r2465 - in GNUnet/src: applications/sqstore_sqlite include
Date: Wed, 22 Feb 2006 10:21:47 -0800 (PST)

Author: durner
Date: 2006-02-22 10:21:26 -0800 (Wed, 22 Feb 2006)
New Revision: 2465

Modified:
   GNUnet/src/applications/sqstore_sqlite/sqlite.c
   GNUnet/src/applications/sqstore_sqlite/sqlitetest.c
   GNUnet/src/include/gnunet_datastore_service.h
   GNUnet/src/include/gnunet_sqstore_service.h
Log:
Key/Value-Tables

Modified: GNUnet/src/applications/sqstore_sqlite/sqlite.c
===================================================================
--- GNUnet/src/applications/sqstore_sqlite/sqlite.c     2006-02-19 01:31:25 UTC 
(rev 2464)
+++ GNUnet/src/applications/sqstore_sqlite/sqlite.c     2006-02-22 18:21:26 UTC 
(rev 2465)
@@ -1010,7 +1010,284 @@
   return n == SQLITE_OK ? OK : SYSERR;
 }
 
+/**
+ * @brief Open a Key/Value-Table
+ * @param table the name of the Key/Value-Table
+ * @return a handle
+ */
+KVHandle *kvGetTable(const char *table)
+{
+  sqlite3_stmt *stmt;
+  unsigned int len;
+  KVHandle *ret;
+  sqliteHandle *dbh;
+  
+  dbh = getDBHandle();
+  MUTEX_LOCK(&db->DATABASE_Lock_);
+  
+  sq_prepare("Select 1 from sqlite_master where tbl_name = ?",
+       &stmt);
+  len = strlen(table);
+  sqlite3_bind_text(stmt, 1, table, len, SQLITE_STATIC);
+  if (sqlite3_step(stmt) == SQLITE_DONE)
+  {
+    char *create = malloc(len + 58);
+    
+    sprintf(create, "CREATE TABLE %s (gn_key BLOB, gn_val BLOB, gn_age 
BIGINT)", table);
+    
+    if (sqlite3_exec(dbh->dbh, create, NULL, NULL, NULL) != SQLITE_OK)
+    {
+      LOG_SQLITE(LOG_ERROR, "sqlite_create");
+      sqlite3_finalize(stmt);
+      free(create);
+      MUTEX_UNLOCK(&db->DATABASE_Lock_);
+      return NULL;
+    }
+    
+    free(create);
+  }
+  sqlite3_finalize(stmt);  
+  
+  MUTEX_UNLOCK(&db->DATABASE_Lock_);
 
+  ret = malloc(sizeof(KVHandle));
+  ret->table = strdup(table);
+  
+  return ret;
+}
+
+/**
+ * @brief Get data from a Key/Value-Table
+ * @param kv handle to the table
+ * @param key the key to retrieve
+ * @param keylen length of the key
+ * @param sort 0 = dont, sort, 1 = random, 2 = sort by age
+ * @param limit limit result set to n rows
+ * @param handler callback function to be called for every result (may be NULL)
+ * @param closure optional parameter for handler
+ */
+void *kvGet(KVHandle *kv, void *key, int keylen, unsigned int sort,
+  unsigned int limit, KVCallback handler, void *closure)
+{
+  unsigned int len;
+  char *sel, *order, *where, limit_spec[30];
+  sqlite3_stmt *stmt;
+  void *ret;
+  sqliteHandle *dbh;
+  
+  ret = NULL;
+ 
+  len = strlen(kv->table); 
+  sel = malloc(len + 45);
+  
+  if (key)
+    where = "WHERE gn_key = ?";
+  else
+    where = "";
+  
+  switch(sort)
+  {
+    case 1:
+      order = "BY RANDOM()";
+      break;
+    case 2:
+      order = "BY gn_age desc";
+      break;
+    default:
+      order = "";
+      break;
+  }
+  
+  if (limit != 0)
+    sprintf(limit_spec, "LIMIT %u", limit);
+  else
+    *limit_spec = 0;
+  
+  sprintf(sel, "SELECT gn_val FROM %s %s %s %s", where, order, limit_spec);
+  
+  dbh = getDBHandle();
+  MUTEX_LOCK(&db->DATABASE_Lock_);
+
+  sq_prepare(sel, &stmt);
+  sqlite3_bind_blob(stmt, 1, &key, keylen, SQLITE_STATIC);
+  while(sqlite3_step(stmt) == SQLITE_ROW)
+  {
+    ret = (void *) sqlite3_column_blob(stmt, 0);
+    if (handler)
+      if (handler(closure, ret) != OK)
+      {
+        free(sel);
+        MUTEX_UNLOCK(&db->DATABASE_Lock_);
+        sqlite3_finalize(stmt);
+        
+        return ret;      
+      }
+  }
+  
+  sqlite3_finalize(stmt);
+
+  MUTEX_UNLOCK(&db->DATABASE_Lock_);
+  
+  free(sel);
+  
+  return ret;
+}
+
+/**
+ * @brief Store Key/Value-Pair in a table
+ * @param kv handle to the table
+ * @param key key of the pair
+ * @param keylen length of the key (int because of SQLite!)
+ * @param val value of the pair
+ * @param vallen length of the value (int because of SQLite!)
+ * @param optional creation time
+ * @return OK on success, SYSERR otherwise
+ */
+int kvPut(KVHandle *kv, void *key, int keylen, void *val, int vallen,
+  unsigned long long age)
+{
+  unsigned int len;
+  char *ins;
+  sqlite3_stmt *stmt;
+  sqliteHandle *dbh;
+ 
+  len = strlen(kv->table); 
+  ins = malloc(len + 61);
+  
+  sprintf(ins, "INSERT INTO %s(gn_key, gn_value, gn_age) (?, ?, ?)", 
kv->table);
+  
+  dbh = getDBHandle();
+  MUTEX_LOCK(&db->DATABASE_Lock_);
+
+  sq_prepare(ins, &stmt);
+  sqlite3_bind_blob(stmt, 1, &key, keylen, SQLITE_STATIC);
+  sqlite3_bind_blob(stmt, 2, &val, vallen, SQLITE_STATIC);
+  sqlite3_bind_int64(stmt, 3, age);
+  if (sqlite3_step(stmt) != SQLITE_OK)
+  {
+    free(ins);
+    MUTEX_UNLOCK(&db->DATABASE_Lock_);
+    sqlite3_finalize(stmt);
+    
+    return SYSERR;      
+  }
+  
+  sqlite3_finalize(stmt);
+
+  MUTEX_UNLOCK(&db->DATABASE_Lock_);
+  
+  free(ins);
+  
+  return OK;  
+}
+
+/**
+ * @brief Delete values from a Key/Value-Table
+ * @param key key to delete (may be NULL)
+ * @param keylen length of the key
+ * @param age age of the items to delete (may be 0)
+ * @return OK on success, SYSERR otherwise
+ */
+int kvDel(KVHandle *kv, void *key, int keylen, unsigned long long age)
+{
+  unsigned int len;
+  char *del, *key_where, *age_where;
+  sqlite3_stmt *stmt;
+  int bind;
+  sqliteHandle *dbh;
+ 
+  len = strlen(kv->table); 
+  del = malloc(len + 52);
+  bind = 1;
+  
+  if (key)
+    key_where = "gn_key = ?";
+  else
+    key_where = "";
+  
+  if (age)
+    age_where = "gn_age = ?";
+  else
+    age_where = "";
+  
+  sprintf(del, "DELETE from %s where %s %s %s", kv->table, key_where, key ? 
"or" : "", age_where);
+  
+  dbh = getDBHandle();
+  MUTEX_LOCK(&db->DATABASE_Lock_);
+
+  sq_prepare(del, &stmt);
+  if (key)
+  {
+    sqlite3_bind_blob(stmt, 1, &key, keylen, SQLITE_STATIC);
+    bind++;
+  }
+  
+  if (age)
+    sqlite3_bind_int64(stmt, bind, age);
+
+  if (sqlite3_step(stmt) != SQLITE_OK)
+  {
+    free(del);
+    MUTEX_UNLOCK(&db->DATABASE_Lock_);
+    sqlite3_finalize(stmt);
+    
+    return SYSERR;      
+  }
+  
+  sqlite3_finalize(stmt);
+
+  MUTEX_UNLOCK(&db->DATABASE_Lock_);
+  
+  free(del);
+  
+  return OK;  
+}
+
+/**
+ * @brief Close a handle to a Key/Value-Table
+ * @param kv the handle to close
+ */
+void kvClose(KVHandle *kv)
+{
+  free(kv->table);
+}
+
+/**
+ * @brief Drop a Key/Value-Table
+ * @param the handle to the table
+ * @return OK on success, SYSERR otherwise
+ */
+int kvDropTable(KVHandle *kv)
+{
+  sqlite3_stmt *stmt;
+  sqliteHandle *dbh;
+
+  char *drop = (void *) malloc(11 + strlen(kv->table));
+  
+  sprintf(drop, "DROP TABLE %s", kv->table);
+  dbh = getDBHandle();
+  MUTEX_LOCK(&db->DATABASE_Lock_);
+
+  sq_prepare(drop, &stmt);
+
+  if (sqlite3_step(stmt) != SQLITE_OK)
+  {
+    free(drop);
+    MUTEX_UNLOCK(&db->DATABASE_Lock_);
+    sqlite3_finalize(stmt);
+    
+    return SYSERR;      
+  }
+  
+  sqlite3_finalize(stmt);
+
+  MUTEX_UNLOCK(&db->DATABASE_Lock_);
+
+  free(drop);
+
+  return OK;
+}
+
 SQstore_ServiceAPI *
 provide_module_sqstore_sqlite(CoreAPIForApplication * capi) {
   static SQstore_ServiceAPI api;
@@ -1079,6 +1356,11 @@
   api.del = &del;
   api.drop = &drop;
   api.update = &update;
+  api.kvClose = &kvClose;
+  api.kvDel = &kvDel;
+  api.kvGet = &kvGet;
+  api.kvGetTable = &kvGetTable;
+  api.kvPut = &kvPut;
   return &api;
 }
 

Modified: GNUnet/src/applications/sqstore_sqlite/sqlitetest.c
===================================================================
--- GNUnet/src/applications/sqstore_sqlite/sqlitetest.c 2006-02-19 01:31:25 UTC 
(rev 2464)
+++ GNUnet/src/applications/sqstore_sqlite/sqlitetest.c 2006-02-22 18:21:26 UTC 
(rev 2465)
@@ -140,6 +140,10 @@
   HashCode512 key;
   unsigned long long oldSize;
   int i;
+  KVHandle *kv;
+  HashCode512 k, v;
+  HashCode512 *r;
+  cron_t timeStmp;
 
   now = 1000000;
   oldSize = api->getSize();
@@ -219,7 +223,29 @@
                                         NULL,
                                         NULL));
   api->drop();
+  
+  /* test Key/Value-Tables */
+  kv = api->kvGetTable("KVTEST");
+  ASSERT(kv != NULL);
+  
+  hash("Some key", 9, &k);
+  hash("Some value", 11, &v);
+  cronTime(&timeStmp);
+  ASSERT(api->kvPut(kv, (void *) &k, sizeof(k), (void *) &v, sizeof(v),
+    timeStmp) == OK);
+  
+  r = api->kvGet(kv, (void *) &k, sizeof(k), 0, 0, NULL, NULL);
+  ASSERT(memcmp(&v, r, sizeof(v)) == 0);
+  free(r);
+  
+  ASSERT(api->kvDel(kv, (void *) &k, sizeof(k), 0) == 0);
+  
+  ASSERT(api->kvGet(kv, (void *) &k, sizeof(k), 0, 0, NULL, NULL) == NULL);
+  
+  ASSERT(api->kvDropTable(kv) == OK);
+
   return OK;
+  
  FAILURE:
   api->drop();
   return SYSERR;

Modified: GNUnet/src/include/gnunet_datastore_service.h
===================================================================
--- GNUnet/src/include/gnunet_datastore_service.h       2006-02-19 01:31:25 UTC 
(rev 2464)
+++ GNUnet/src/include/gnunet_datastore_service.h       2006-02-22 18:21:26 UTC 
(rev 2465)
@@ -33,6 +33,22 @@
 #include "gnunet_core.h"
 
 /**
+ * @brief Handle to a Key/Value-Table
+ */
+typedef struct
+{
+  char *table;
+} KVHandle;
+
+/**
+ * @brief Callback for multiple results from Key/Value-Tables
+ * @param closure optional parameter
+ * @param val the value retrieved
+ * @return OK on success
+ */
+typedef int (*KVCallback)(void *closure, void *val);
+
+/**
  * A value in the datastore.
  */
 typedef struct {
@@ -200,6 +216,63 @@
   int (*del)(const HashCode512 * key,
             const Datastore_Value * value);
 
+  /* *** Key/Value-Table support *** */
+  
+  /**
+   * @brief Open a Key/Value-Table
+   * @param table the name of the Key/Value-Table
+   * @return a handle
+   */
+  KVHandle *(*kvGetTable)(const char *table);
+
+  /**
+   * @brief Get data from a Key/Value-Table
+   * @param kv handle to the table
+   * @param key the key to retrieve
+   * @param keylen length of the key
+   * @param sort 0 = dont, sort, 1 = random, 2 = sort by age
+   * @param limit limit result set to n rows
+   * @param handler callback function to be called for every result (may be 
NULL)
+   * @param closure optional parameter for handler
+   */
+  void * (*kvGet)(KVHandle *kv, void *key, int keylen, unsigned int sort,
+    unsigned int limit, KVCallback handler, void *closure);
+
+  /**
+   * @brief Store Key/Value-Pair in a table
+   * @param kv handle to the table
+   * @param key key of the pair
+   * @param keylen length of the key (int because of SQLite!)
+   * @param val value of the pair
+   * @param vallen length of the value (int because of SQLite!)
+   * @param optional creation time
+   * @return OK on success, SYSERR otherwise
+   */
+  int (* kvPut)(KVHandle *kv, void *key, int keylen, void *val, int vallen,
+    unsigned long long age);
+  
+  /**
+   * @brief Delete values from a Key/Value-Table
+   * @param key key to delete (may be NULL)
+   * @param keylen length of the key
+   * @param age age of the items to delete (may be 0)
+   * @return OK on success, SYSERR otherwise
+   */
+  int (* kvDel)(KVHandle *kv, void *key, int keylen, unsigned long long age);
+  
+  /**
+   * @brief Close a handle to a Key/Value-Table
+   * @param kv the handle to close
+   */
+  void (* kvClose)(KVHandle *kv);
+
+  /**
+   * @brief Drop a Key/Value-Table
+   * @param the handle to the table
+   * @return OK on success, SYSERR otherwise
+   */
+  int (*kvDropTable) (KVHandle *kv);
+
 } Datastore_ServiceAPI;
 
 

Modified: GNUnet/src/include/gnunet_sqstore_service.h
===================================================================
--- GNUnet/src/include/gnunet_sqstore_service.h 2006-02-19 01:31:25 UTC (rev 
2464)
+++ GNUnet/src/include/gnunet_sqstore_service.h 2006-02-22 18:21:26 UTC (rev 
2465)
@@ -159,7 +159,63 @@
    * guaranteed to be unloading of the module.
    */
   void (*drop)(void);
+  
+  /* *** Key/Value-Table support *** */
+  
+  /**
+   * @brief Open a Key/Value-Table
+   * @param table the name of the Key/Value-Table
+   * @return a handle
+   */
+  KVHandle *(*kvGetTable)(const char *table);
 
+  /**
+   * @brief Get data from a Key/Value-Table
+   * @param kv handle to the table
+   * @param key the key to retrieve
+   * @param keylen length of the key
+   * @param sort 0 = dont, sort, 1 = random, 2 = sort by age
+   * @param limit limit result set to n rows
+   * @param handler callback function to be called for every result (may be 
NULL)
+   * @param closure optional parameter for handler
+   */
+  void * (*kvGet)(KVHandle *kv, void *key, int keylen, unsigned int sort,
+    unsigned int limit, KVCallback handler, void *closure);
+
+  /**
+   * @brief Store Key/Value-Pair in a table
+   * @param kv handle to the table
+   * @param key key of the pair
+   * @param keylen length of the key (int because of SQLite!)
+   * @param val value of the pair
+   * @param vallen length of the value (int because of SQLite!)
+   * @param optional creation time
+   * @return OK on success, SYSERR otherwise
+   */
+  int (* kvPut)(KVHandle *kv, void *key, int keylen, void *val, int vallen,
+    unsigned long long age);
+  
+  /**
+   * @brief Delete values from a Key/Value-Table
+   * @param key key to delete (may be NULL)
+   * @param keylen length of the key
+   * @param age age of the items to delete (may be 0)
+   * @return OK on success, SYSERR otherwise
+   */
+  int (* kvDel)(KVHandle *kv, void *key, int keylen, unsigned long long age);
+  
+  /**
+   * @brief Close a handle to a Key/Value-Table
+   * @param kv the handle to close
+   */
+  void (* kvClose)(KVHandle *kv);
+
+  /**
+   * @brief Drop a Key/Value-Table
+   * @param the handle to the table
+   * @return OK on success, SYSERR otherwise
+   */
+  int (* kvDropTable)(KVHandle *kv);
 } SQstore_ServiceAPI;
 
 





reply via email to

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