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