add transactions to namestore plugin API
authorChristian Grothoff <christian@grothoff.org>
Sun, 15 Apr 2018 18:45:44 +0000 (20:45 +0200)
committerChristian Grothoff <christian@grothoff.org>
Sun, 15 Apr 2018 18:45:44 +0000 (20:45 +0200)
src/include/gnunet_namestore_plugin.h
src/namestore/plugin_namestore_flat.c
src/namestore/plugin_namestore_postgres.c
src/namestore/plugin_namestore_sqlite.c
src/pq/pq_exec.c

index 11f16b97a17f9651a738c812f461fae4dba63a90..d1c68cd23969604f4518673df7844518cffe2143 100644 (file)
@@ -88,7 +88,7 @@ struct GNUNET_NAMESTORE_PluginFunctions
                    const char *label,
                    unsigned int rd_count,
                    const struct GNUNET_GNSRECORD_Data *rd);
-  
+
   /**
    * Lookup records in the datastore for which we are the authority.
    *
@@ -145,6 +145,35 @@ struct GNUNET_NAMESTORE_PluginFunctions
                   void *iter_cls);
 
 
+  /**
+   * Start a transaction.
+   *
+   * @param cls closure
+   * @return #GNUNET_OK on success, #GNUNET_NO if transactions are not supported,
+   *         #GNUNET_SYSERR on internal errors
+   */
+  int
+  (*begin_transaction) (void *cls);
+
+
+  /**
+   * Try to commit a transaction.
+   *
+   * @param cls closure
+   * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
+   */
+  int
+  (*commit_transaction) (void *cls);
+
+
+  /**
+   * Rollback a transaction.
+   *
+   * @param cls closure
+   */
+  void
+  (*rollback_transaction) (void *cls);
+
 };
 
 
index 024fc34f27da58882a327abcb8c4010faf9101a4..170adb49e12a30cc5372f52c72272429bf91a57b 100644 (file)
@@ -383,7 +383,7 @@ static void
 database_shutdown (struct Plugin *plugin)
 {
   struct GNUNET_DISK_FileHandle *fh;
-  
+
   fh = GNUNET_DISK_file_open (plugin->fn,
                               GNUNET_DISK_OPEN_CREATE |
                               GNUNET_DISK_OPEN_TRUNCATE |
@@ -418,11 +418,11 @@ database_shutdown (struct Plugin *plugin)
  * @return #GNUNET_OK on success, else #GNUNET_SYSERR
  */
 static int
-namestore_store_records (void *cls,
-                         const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
-                         const char *label,
-                         unsigned int rd_count,
-                         const struct GNUNET_GNSRECORD_Data *rd)
+namestore_flat_store_records (void *cls,
+                              const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
+                              const char *label,
+                              unsigned int rd_count,
+                              const struct GNUNET_GNSRECORD_Data *rd)
 {
   struct Plugin *plugin = cls;
   uint64_t rvalue;
@@ -488,11 +488,11 @@ namestore_store_records (void *cls,
  * @return #GNUNET_OK on success, else #GNUNET_SYSERR
  */
 static int
-namestore_lookup_records (void *cls,
-                          const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
-                          const char *label,
-                          GNUNET_NAMESTORE_RecordIterator iter,
-                          void *iter_cls)
+namestore_flat_lookup_records (void *cls,
+                               const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
+                               const char *label,
+                               GNUNET_NAMESTORE_RecordIterator iter,
+                               void *iter_cls)
 {
   struct Plugin *plugin = cls;
   struct FlatFileEntry *entry;
@@ -571,11 +571,11 @@ iterate_zones (void *cls,
  * @return #GNUNET_OK on success, #GNUNET_NO if there were no results, #GNUNET_SYSERR on error
  */
 static int
-namestore_iterate_records (void *cls,
-                           const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
-                           uint64_t offset,
-                           GNUNET_NAMESTORE_RecordIterator iter,
-                          void *iter_cls)
+namestore_flat_iterate_records (void *cls,
+                                const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
+                                uint64_t offset,
+                                GNUNET_NAMESTORE_RecordIterator iter,
+                                void *iter_cls)
 {
   struct Plugin *plugin = cls;
 
@@ -641,11 +641,11 @@ zone_to_name (void *cls,
  * @return #GNUNET_OK on success, #GNUNET_NO if there were no results, #GNUNET_SYSERR on error
  */
 static int
-namestore_zone_to_name (void *cls,
-                        const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
-                        const struct GNUNET_CRYPTO_EcdsaPublicKey *value_zone,
-                        GNUNET_NAMESTORE_RecordIterator iter,
-                       void *iter_cls)
+namestore_flat_zone_to_name (void *cls,
+                             const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone,
+                             const struct GNUNET_CRYPTO_EcdsaPublicKey *value_zone,
+                             GNUNET_NAMESTORE_RecordIterator iter,
+                             void *iter_cls)
 {
   struct Plugin *plugin = cls;
 
@@ -666,6 +666,46 @@ namestore_zone_to_name (void *cls,
 }
 
 
+/**
+ * Start a transaction.
+ *
+ * @param cls closure
+ * @return #GNUNET_OK on success, #GNUNET_NO if transactions are not supported,
+ *         #GNUNET_SYSERR on internal errors
+ */
+static int
+namestore_flat_begin_transaction (void *cls)
+{
+  return GNUNET_NO;
+}
+
+
+/**
+ * Try to commit a transaction.
+ *
+ * @param cls closure
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
+ */
+static int
+namestore_flat_commit_transaction (void *cls)
+{
+  GNUNET_break (0);
+  return GNUNET_SYSERR;
+}
+
+
+/**
+ * Rollback a transaction.
+ *
+ * @param cls closure
+ */
+static void
+namestore_flat_rollback_transaction (void *cls)
+{
+  GNUNET_break (0);
+}
+
+
 /**
  * Entry point for the plugin.
  *
@@ -692,10 +732,13 @@ libgnunet_plugin_namestore_flat_init (void *cls)
   }
   api = GNUNET_new (struct GNUNET_NAMESTORE_PluginFunctions);
   api->cls = &plugin;
-  api->store_records = &namestore_store_records;
-  api->iterate_records = &namestore_iterate_records;
-  api->zone_to_name = &namestore_zone_to_name;
-  api->lookup_records = &namestore_lookup_records;
+  api->store_records = &namestore_flat_store_records;
+  api->iterate_records = &namestore_flat_iterate_records;
+  api->zone_to_name = &namestore_flat_zone_to_name;
+  api->lookup_records = &namestore_flat_lookup_records;
+  api->begin_transaction = &namestore_flat_begin_transaction;
+  api->commit_transaction = &namestore_flat_commit_transaction;
+  api->rollback_transaction = &namestore_flat_rollback_transaction;
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
               _("flat file database running\n"));
   return api;
index 4828cb190d8f7eb3c1791979a854aaedd870c81d..378a88f51ead1edbcd19c6a85daf4583ef289391 100644 (file)
@@ -243,7 +243,7 @@ namestore_postgres_store_records (void *cls,
                                              data_size,
                                              data);
     if ( (ret < 0) ||
-        (data_size != (size_t) ret) )        
+        (data_size != (size_t) ret) )
     {
       GNUNET_break (0);
       return GNUNET_SYSERR;
@@ -517,6 +517,80 @@ database_shutdown (struct Plugin *plugin)
 }
 
 
+/**
+ * Start a transaction.
+ *
+ * @param cls closure
+ * @return #GNUNET_OK on success, #GNUNET_NO if transactions are not supported,
+ *         #GNUNET_SYSERR on internal errors
+ */
+static int
+namestore_postgres_begin_transaction (void *cls)
+{
+  struct Plugin *plugin = cls;
+  PGresult *result;
+  ExecStatusType ex;
+
+  result = PQexec (plugin->dbh,
+                   "START TRANSACTION ISOLATION LEVEL SERIALIZABLE");
+  if (PGRES_COMMAND_OK !=
+      (ex = PQresultStatus (result)))
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Failed to start transaction (%s): %s\n",
+                PQresStatus (ex),
+                PQerrorMessage (plugin->dbh));
+    GNUNET_break (0);
+    PQclear (result);
+    return GNUNET_SYSERR;
+  }
+  PQclear (result);
+  return GNUNET_OK;
+}
+
+
+/**
+ * Try to commit a transaction.
+ *
+ * @param cls closure
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
+ */
+static int
+namestore_postgres_commit_transaction (void *cls)
+{
+  struct Plugin *plugin = cls;
+  PGresult *result;
+  ExecStatusType status;
+  int ret;
+
+  result = PQexec (plugin->dbh,
+                   "COMMIT");
+  status = PQresultStatus (result);
+  ret = (PGRES_COMMAND_OK == status) ? GNUNET_OK : GNUNET_SYSERR;
+  PQclear (result);
+  return ret;
+}
+
+
+/**
+ * Rollback a transaction.
+ *
+ * @param cls closure
+ */
+static void
+namestore_postgres_rollback_transaction (void *cls)
+{
+  struct Plugin *plugin = cls;
+  PGresult *result;
+
+  result = PQexec (plugin->dbh,
+                   "ROLLBACK");
+  GNUNET_break (PGRES_COMMAND_OK ==
+                PQresultStatus (result));
+  PQclear (result);
+}
+
+
 /**
  * Entry point for the plugin.
  *
@@ -545,6 +619,9 @@ libgnunet_plugin_namestore_postgres_init (void *cls)
   api->iterate_records = &namestore_postgres_iterate_records;
   api->zone_to_name = &namestore_postgres_zone_to_name;
   api->lookup_records = &namestore_postgres_lookup_records;
+  api->begin_transaction = &namestore_postgres_begin_transaction;
+  api->commit_transaction = &namestore_postgres_commit_transaction;
+  api->rollback_transaction = &namestore_postgres_rollback_transaction;
   LOG (GNUNET_ERROR_TYPE_INFO,
        "Postgres namestore plugin running\n");
   return api;
index 5ad84688c66b4719a32df8fc593172964c5ef2ee..1ebb6bfc70d1e5814eccbc2acc5062cc851939eb 100644 (file)
@@ -772,6 +772,47 @@ namestore_sqlite_zone_to_name (void *cls,
 }
 
 
+/**
+ * Start a transaction.
+ *
+ * @param cls closure
+ * @return #GNUNET_OK on success, #GNUNET_NO if transactions are not supported,
+ *         #GNUNET_SYSERR on internal errors
+ */
+static int
+namestore_sqlite_begin_transaction (void *cls)
+{
+  return GNUNET_NO;
+}
+
+
+/**
+ * Try to commit a transaction.
+ *
+ * @param cls closure
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR on failure
+ */
+static int
+namestore_sqlite_commit_transaction (void *cls)
+{
+  GNUNET_break (0);
+  return GNUNET_SYSERR;
+}
+
+
+/**
+ * Rollback a transaction.
+ *
+ * @param cls closure
+ */
+static void
+namestore_sqlite_rollback_transaction (void *cls)
+{
+  GNUNET_break (0);
+}
+
+
+
 /**
  * Entry point for the plugin.
  *
@@ -800,6 +841,9 @@ libgnunet_plugin_namestore_sqlite_init (void *cls)
   api->iterate_records = &namestore_sqlite_iterate_records;
   api->zone_to_name = &namestore_sqlite_zone_to_name;
   api->lookup_records = &namestore_sqlite_lookup_records;
+  api->begin_transaction = &namestore_sqlite_begin_transaction;
+  api->commit_transaction = &namestore_sqlite_commit_transaction;
+  api->rollback_transaction = &namestore_sqlite_rollback_transaction;
   LOG (GNUNET_ERROR_TYPE_INFO,
        _("Sqlite database running\n"));
   return api;
index 1e5e4eb76e8df2dc84af9880906f58fd6fca09a4..eacc1f2b3c06252f836446536bf13d115f5610ca 100644 (file)
@@ -79,7 +79,6 @@ GNUNET_PQ_exec_statements (PGconn *connection,
 
     result = PQexec (connection,
                      es[i].sql);
-
     if ( (GNUNET_NO == es[i].ignore_errors) &&
          (PGRES_COMMAND_OK != PQresultStatus (result)) )
     {