This is an automated email from the ASF dual-hosted git repository.

kou pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-adbc.git


The following commit(s) were added to refs/heads/main by this push:
     new d47b54d  feat(glib): add transaction related connection bindings (#579)
d47b54d is described below

commit d47b54d5ae25beae22efd23671ff880103bf6277
Author: Sutou Kouhei <[email protected]>
AuthorDate: Wed Apr 12 14:24:03 2023 +0900

    feat(glib): add transaction related connection bindings (#579)
    
    Fixes #551.
    
    New APIs:
    
    * `gadbc_connection_set_auto_commit()`
    * `gadbc_connection_commit()`
    * `gadbc_connection_rollback()`
---
 glib/adbc-glib/connection.c  |  69 +++++++++++++++++++++++++++++
 glib/adbc-glib/connection.h  |   7 +++
 glib/test/helper.rb          |   2 +
 glib/test/test-connection.rb | 100 ++++++++++++++++++++++++++++++++++++++++---
 4 files changed, 172 insertions(+), 6 deletions(-)

diff --git a/glib/adbc-glib/connection.c b/glib/adbc-glib/connection.c
index 6500cc3..ade4007 100644
--- a/glib/adbc-glib/connection.c
+++ b/glib/adbc-glib/connection.c
@@ -32,6 +32,9 @@
  * #GADBCConnection is a class for connection.
  */
 
+#define BOOLEAN_TO_OPTION_VALUE(boolean) \
+  ((boolean) ? ADBC_OPTION_VALUE_ENABLED : ADBC_OPTION_VALUE_DISABLED)
+
 typedef struct {
   gboolean initialized;
   struct AdbcConnection adbc_connection;
@@ -147,6 +150,22 @@ gboolean gadbc_connection_set_option(GADBCConnection* 
connection, const gchar* k
   return gadbc_error_check(error, status_code, &adbc_error, context);
 }
 
+/**
+ * gadbc_connection_set_auto_commit:
+ * @connection: A #GADBCConnection.
+ * @auto_commit: Whether auto commit is enabled or not.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Returns: %TRUE if this is set successfully, %FALSE otherwise.
+ *
+ * Since: 0.4.0
+ */
+gboolean gadbc_connection_set_auto_commit(GADBCConnection* connection,
+                                          gboolean auto_commit, GError** 
error) {
+  return gadbc_connection_set_option(connection, 
ADBC_CONNECTION_OPTION_AUTOCOMMIT,
+                                     BOOLEAN_TO_OPTION_VALUE(auto_commit), 
error);
+}
+
 /**
  * gadbc_connection_init:
  * @connection: A #GADBCConnection.
@@ -317,6 +336,56 @@ gpointer gadbc_connection_get_table_types(GADBCConnection* 
connection, GError**
   }
 }
 
+/**
+ * gadbc_connection_commit:
+ * @connection: A #GADBCConnection.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Commit any pending transactions. Only used if auto commit is
+ * disabled.
+ *
+ * Behavior is undefined if this is mixed with SQL transaction
+ * statements.
+ *
+ * Returns: %TRUE if the commit is done successfully, %FALSE
+ *   otherwise.
+ *
+ * Since: 0.4.0
+ */
+gboolean gadbc_connection_commit(GADBCConnection* connection, GError** error) {
+  const gchar* context = "[adbc][connection][commit]";
+  struct AdbcConnection* adbc_connection =
+      gadbc_connection_get_raw(connection, context, error);
+  struct AdbcError adbc_error = {};
+  return gadbc_error_check(error, AdbcConnectionCommit(adbc_connection, 
&adbc_error),
+                           &adbc_error, context);
+}
+
+/**
+ * gadbc_connection_rollback:
+ * @connection: A #GADBCConnection.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Rollback any pending transactions. Only used if auto commit is
+ * disabled.
+ *
+ * Behavior is undefined if this is mixed with SQL transaction
+ * statements.
+ *
+ * Returns: %TRUE if the rollback is done successfully, %FALSE
+ *   otherwise.
+ *
+ * Since: 0.4.0
+ */
+gboolean gadbc_connection_rollback(GADBCConnection* connection, GError** 
error) {
+  const gchar* context = "[adbc][connection][rollback]";
+  struct AdbcConnection* adbc_connection =
+      gadbc_connection_get_raw(connection, context, error);
+  struct AdbcError adbc_error = {};
+  return gadbc_error_check(error, AdbcConnectionRollback(adbc_connection, 
&adbc_error),
+                           &adbc_error, context);
+}
+
 /**
  * gadbc_connection_get_raw:
  * @connection: A #GADBCConnection.
diff --git a/glib/adbc-glib/connection.h b/glib/adbc-glib/connection.h
index f8b9105..971321c 100644
--- a/glib/adbc-glib/connection.h
+++ b/glib/adbc-glib/connection.h
@@ -64,6 +64,9 @@ gboolean gadbc_connection_release(GADBCConnection* 
connection, GError** error);
 GADBC_AVAILABLE_IN_0_1
 gboolean gadbc_connection_set_option(GADBCConnection* connection, const gchar* 
key,
                                      const gchar* value, GError** error);
+GADBC_AVAILABLE_IN_0_4
+gboolean gadbc_connection_set_auto_commit(GADBCConnection* connection,
+                                          gboolean auto_commit, GError** 
error);
 GADBC_AVAILABLE_IN_0_1
 gboolean gadbc_connection_init(GADBCConnection* connection, GADBCDatabase* 
database,
                                GError** error);
@@ -77,5 +80,9 @@ gpointer gadbc_connection_get_table_schema(GADBCConnection* 
connection,
                                            const gchar* table_name, GError** 
error);
 GADBC_AVAILABLE_IN_0_4
 gpointer gadbc_connection_get_table_types(GADBCConnection* connection, 
GError** error);
+GADBC_AVAILABLE_IN_0_4
+gboolean gadbc_connection_commit(GADBCConnection* connection, GError** error);
+GADBC_AVAILABLE_IN_0_4
+gboolean gadbc_connection_rollback(GADBCConnection* connection, GError** 
error);
 
 G_END_DECLS
diff --git a/glib/test/helper.rb b/glib/test/helper.rb
index f207060..6a8e9ab 100644
--- a/glib/test/helper.rb
+++ b/glib/test/helper.rb
@@ -15,6 +15,8 @@
 # specific language governing permissions and limitations
 # under the License.
 
+require "tmpdir"
+
 require "arrow"
 
 module Helper
diff --git a/glib/test/test-connection.rb b/glib/test/test-connection.rb
index cea32c9..9ed3692 100644
--- a/glib/test/test-connection.rb
+++ b/glib/test/test-connection.rb
@@ -21,14 +21,24 @@ class ConnectionTest < Test::Unit::TestCase
   def setup
     @database = ADBC::Database.new
     @database.set_option("driver", "adbc_driver_sqlite")
-    @database.set_option("uri", ":memory:")
-    @database.init
-    @connection = ADBC::Connection.new
+    Dir.mktmpdir do |tmp_dir|
+      database = File.join(tmp_dir, "test.sqlite3")
+      @database.set_option("uri", database)
+      @database.init
+      open_connection do |connection|
+        @connection = connection
+        yield
+      end
+    end
+  end
+
+  def open_connection
+    connection = ADBC::Connection.new
     begin
-      @connection.init(@database)
-      yield
+      connection.init(@database)
+      yield(connection)
     ensure
-      @connection.release
+      connection.release
     end
   end
 
@@ -123,4 +133,82 @@ class ConnectionTest < Test::Unit::TestCase
       GLib.free(c_abi_array_stream)
     end
   end
+
+  def test_commit
+    open_connection do |connection|
+      execute_sql(connection,
+                  "CREATE TABLE data (number int, string text)",
+                  need_result: false)
+      execute_sql(connection,
+                  "INSERT INTO data VALUES (1, 'hello')",
+                  need_result: false)
+    end
+
+    open_connection do |connection|
+      connection.auto_commit = false
+      execute_sql(connection,
+                  "INSERT INTO data VALUES (2, 'world')",
+                  need_result: false)
+      open_connection do |other_connection|
+        execute_sql(other_connection, "SELECT * FROM data") do |table,|
+          expected = {
+            number: Arrow::Int64Array.new([1]),
+            string: Arrow::StringArray.new(["hello"]),
+          }
+          assert_equal(Arrow::Table.new(expected),
+                       table)
+        end
+      end
+      connection.commit
+      open_connection do |other_connection|
+        execute_sql(other_connection, "SELECT * FROM data") do |table,|
+          expected = {
+            number: Arrow::Int64Array.new([1, 2]),
+            string: Arrow::StringArray.new(["hello", "world"]),
+          }
+          assert_equal(Arrow::Table.new(expected),
+                       table)
+        end
+      end
+    end
+  end
+
+  def test_rollback
+    open_connection do |connection|
+      execute_sql(connection,
+                  "CREATE TABLE data (number int, string text)",
+                  need_result: false)
+      execute_sql(connection,
+                  "INSERT INTO data VALUES (1, 'hello')",
+                  need_result: false)
+    end
+
+    open_connection do |connection|
+      connection.auto_commit = false
+      execute_sql(connection,
+                  "INSERT INTO data VALUES (2, 'world')",
+                  need_result: false)
+      open_connection do |other_connection|
+        execute_sql(other_connection, "SELECT * FROM data") do |table,|
+          expected = {
+            number: Arrow::Int64Array.new([1]),
+            string: Arrow::StringArray.new(["hello"]),
+          }
+          assert_equal(Arrow::Table.new(expected),
+                       table)
+        end
+      end
+      connection.rollback
+      open_connection do |other_connection|
+        execute_sql(other_connection, "SELECT * FROM data") do |table,|
+          expected = {
+            number: Arrow::Int64Array.new([1]),
+            string: Arrow::StringArray.new(["hello"]),
+          }
+          assert_equal(Arrow::Table.new(expected),
+                       table)
+        end
+      end
+    end
+  end
 end

Reply via email to