gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r33248 - in gnunet/src: include peerstore


From: gnunet
Subject: [GNUnet-SVN] r33248 - in gnunet/src: include peerstore
Date: Mon, 12 May 2014 19:01:59 +0200

Author: otarabai
Date: 2014-05-12 19:01:59 +0200 (Mon, 12 May 2014)
New Revision: 33248

Modified:
   gnunet/src/include/gnunet_peerstore_plugin.h
   gnunet/src/peerstore/plugin_peerstore_sqlite.c
Log:
towards PEERSTORE iterate


Modified: gnunet/src/include/gnunet_peerstore_plugin.h
===================================================================
--- gnunet/src/include/gnunet_peerstore_plugin.h        2014-05-12 16:47:50 UTC 
(rev 33247)
+++ gnunet/src/include/gnunet_peerstore_plugin.h        2014-05-12 17:01:59 UTC 
(rev 33248)
@@ -39,6 +39,21 @@
 
 
 /**
+ * Function called by for each matching record.
+ *
+ * @param cls closure
+ * @param peer peer identity
+ * @param sub_system name of the GNUnet sub system responsible
+ * @param value stored value
+ * @param size size of stored value
+ */
+typedef void (*GNUNET_PEERSTORE_RecordIterator) (void *cls,
+    const struct GNUNET_PeerIdentity *peer,
+    const char *sub_system,
+    const void *value,
+    size_t size);
+
+/**
  * @brief struct returned by the initialization function of the plugin
  */
 struct GNUNET_PEERSTORE_PluginFunctions
@@ -68,6 +83,23 @@
       const void *value,
       size_t size);
 
+  /**
+   * Iterate over the records given an optional peer id
+   * and/or sub system.
+   *
+   * @param cls closure (internal context for the plugin)
+   * @param peer Peer identity (can be NULL)
+   * @param sub_system name of sub system (can be NULL)
+   * @param iter function to call with the result
+   * @param iter_cls closure for @a iter
+   * @return #GNUNET_OK on success, #GNUNET_NO if there were no results, 
#GNUNET_SYSERR on error
+   */
+  int
+  (*iterate_records) (void *cls,
+      const struct GNUNET_PeerIdentity *peer,
+      const char *sub_system,
+      GNUNET_PEERSTORE_RecordIterator iter, void *iter_cls);
+
 };
 
 

Modified: gnunet/src/peerstore/plugin_peerstore_sqlite.c
===================================================================
--- gnunet/src/peerstore/plugin_peerstore_sqlite.c      2014-05-12 16:47:50 UTC 
(rev 33247)
+++ gnunet/src/peerstore/plugin_peerstore_sqlite.c      2014-05-12 17:01:59 UTC 
(rev 33248)
@@ -77,9 +77,130 @@
    */
   sqlite3_stmt *insert_peerstoredata;
 
+  /**
+   * Precompiled SQL for selecting from peerstoredata
+   */
+  sqlite3_stmt *select_peerstoredata;
+
+  /**
+   * Precompiled SQL for selecting from peerstoredata
+   */
+  sqlite3_stmt *select_peerstoredata_by_pid;
+
+  /**
+   * Precompiled SQL for selecting from peerstoredata
+   */
+  sqlite3_stmt *select_peerstoredata_by_ss;
+
+  /**
+   * Precompiled SQL for selecting from peerstoredata
+   */
+  sqlite3_stmt *select_peerstoredata_by_both;
+
 };
 
 /**
+ * The given 'sqlite' statement has been prepared to be run.
+ * It will return a record which should be given to the iterator.
+ * Runs the statement and parses the returned record.
+ *
+ * @param plugin plugin context
+ * @param stmt to run (and then clean up)
+ * @param iter iterator to call with the result
+ * @param iter_cls closure for @a iter
+ * @return #GNUNET_OK on success, #GNUNET_NO if there were no results, 
#GNUNET_SYSERR on error
+ */
+static int
+get_record_and_call_iterator (struct Plugin *plugin,
+            sqlite3_stmt *stmt,
+            GNUNET_PEERSTORE_RecordIterator iter, void *iter_cls)
+{
+  int ret;
+  int sret;
+  struct GNUNET_PeerIdentity *pid;
+  char *sub_system;
+  void *value;
+  size_t value_size;
+
+  ret = GNUNET_NO;
+  if (SQLITE_ROW == (sret = sqlite3_step (stmt)))
+  {
+    pid = sqlite3_column_blob(stmt, 0);
+    sub_system = sqlite3_column_text(stmt, 1);
+    value = sqlite3_column_blob(stmt, 2);
+    value_size = sqlite3_column_bytes(stmt, 2);
+    if (NULL != iter)
+      iter (iter_cls, pid, sub_system, value, value_size);
+    ret = GNUNET_YES;
+  }
+  else
+  {
+    if (SQLITE_DONE != sret)
+      LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR, "sqlite_step");
+  }
+  if (SQLITE_OK != sqlite3_reset (stmt))
+    LOG_SQLITE (plugin,
+    GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+    "sqlite3_reset");
+  return ret;
+
+}
+
+/**
+ * Iterate over the records given an optional peer id
+ * and/or sub system.
+ *
+ * @param cls closure (internal context for the plugin)
+ * @param peer Peer identity (can be NULL)
+ * @param sub_system name of sub system (can be NULL)
+ * @param iter function to call with the result
+ * @param iter_cls closure for @a iter
+ * @return #GNUNET_OK on success, #GNUNET_NO if there were no results, 
#GNUNET_SYSERR on error
+ */
+static int
+peerstore_sqlite_iterate_records (void *cls,
+    const struct GNUNET_PeerIdentity *peer,
+    const char *sub_system,
+    GNUNET_PEERSTORE_RecordIterator iter, void *iter_cls)
+{
+  struct Plugin *plugin = cls;
+  sqlite3_stmt *stmt;
+  int err;
+
+  if(NULL == sub_system && NULL == peer)
+    stmt = plugin->select_peerstoredata;
+  else if(NULL == sub_system)
+  {
+    stmt = plugin->select_peerstoredata_by_pid;
+    err = (SQLITE_OK != sqlite3_bind_blob(stmt, 1, peer, sizeof(struct 
GNUNET_PeerIdentity), SQLITE_STATIC));
+  }
+  else if(NULL == peer)
+  {
+    stmt = plugin->select_peerstoredata_by_ss;
+    err = (SQLITE_OK != sqlite3_bind_text(stmt, 1, sub_system, 
strlen(sub_system) + 1, SQLITE_STATIC));
+  }
+  else
+  {
+    stmt = plugin->select_peerstoredata_by_both;
+    err =
+        (SQLITE_OK != sqlite3_bind_blob(stmt, 1, peer, sizeof(struct 
GNUNET_PeerIdentity), SQLITE_STATIC))
+        || (SQLITE_OK != sqlite3_bind_text(stmt, 2, sub_system, 
strlen(sub_system) + 1, SQLITE_STATIC));
+  }
+
+  if (err)
+  {
+    LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+    "sqlite3_bind_XXXX");
+    if (SQLITE_OK != sqlite3_reset (stmt))
+      LOG_SQLITE (plugin,
+      GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
+      "sqlite3_reset");
+    return GNUNET_SYSERR;
+  }
+  return get_record_and_call_iterator (plugin, stmt, iter, iter_cls);
+}
+
+/**
  * Store a record in the peerstore.
  * Key is the combination of sub system and peer identity.
  * One key can store multiple values.
@@ -103,8 +224,8 @@
 
   //FIXME: check if value exists with the same key first
 
-  if(SQLITE_OK != sqlite3_bind_blob(stmt, 2, peer, sizeof(struct 
GNUNET_PeerIdentity), SQLITE_STATIC)
-      || SQLITE_OK != sqlite3_bind_text(stmt, 1, sub_system, 
strlen(sub_system) + 1, SQLITE_STATIC)
+  if(SQLITE_OK != sqlite3_bind_blob(stmt, 1, peer, sizeof(struct 
GNUNET_PeerIdentity), SQLITE_STATIC)
+      || SQLITE_OK != sqlite3_bind_text(stmt, 2, sub_system, 
strlen(sub_system) + 1, SQLITE_STATIC)
       || SQLITE_OK != sqlite3_bind_blob(stmt, 3, value, size, SQLITE_STATIC))
     LOG_SQLITE (plugin, GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
                     "sqlite3_bind");
@@ -235,8 +356,20 @@
   /* Prepare statements */
 
   sql_prepare (plugin->dbh,
-               "INSERT INTO peerstoredata (peer_id, sub_system, value) VALUES 
(?,?,?);",
-               &plugin->insert_peerstoredata);
+      "INSERT INTO peerstoredata (peer_id, sub_system, value) VALUES (?,?,?);",
+      &plugin->insert_peerstoredata);
+  sql_prepare(plugin->dbh,
+      "SELECT peer_id, sub_system, value FROM peerstoredata",
+      &plugin->select_peerstoredata);
+  sql_prepare(plugin->dbh,
+      "SELECT peer_id, sub_system, value FROM peerstoredata WHERE peer_id = ?",
+      &plugin->select_peerstoredata_by_pid);
+  sql_prepare(plugin->dbh,
+      "SELECT peer_id, sub_system, value FROM peerstoredata WHERE sub_system = 
?",
+      &plugin->select_peerstoredata_by_ss);
+  sql_prepare(plugin->dbh,
+      "SELECT peer_id, sub_system, value FROM peerstoredata WHERE peer_id = ? 
AND sub_system = ?",
+      &plugin->select_peerstoredata_by_both);
 
   return GNUNET_OK;
 }
@@ -289,6 +422,7 @@
   api = GNUNET_new (struct GNUNET_PEERSTORE_PluginFunctions);
   api->cls = &plugin;
   api->store_record = &peerstore_sqlite_store_record;
+  api->iterate_records = &peerstore_sqlite_iterate_records;
   LOG(GNUNET_ERROR_TYPE_DEBUG, "Sqlite plugin is running\n");
   return api;
 }




reply via email to

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