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 784d913b feat(glib): Add Apache Arrow GLib integration library (#1459)
784d913b is described below

commit 784d913bdc237cfde18704fb39dcb757b86770fd
Author: Sutou Kouhei <[email protected]>
AuthorDate: Tue Jan 23 07:04:03 2024 +0900

    feat(glib): Add Apache Arrow GLib integration library (#1459)
    
    Fixes #1280.
    
    We can use
    `GArrowRecordBatch`/`GArrowSchema`/`GArrowRecordBatchReader` instead of
    C data API with this library.
---
 ci/linux-packages/debian/control                   |  55 +++++++
 .../debian/gir1.2-adbc-arrow-1.0.install           |   1 +
 .../debian/libadbc-arrow-glib-dev.install          |   6 +
 .../debian/libadbc-arrow-glib-doc.install          |   1 +
 .../debian/libadbc-arrow-glib0.install             |   1 +
 ci/linux-packages/debian/libadbc-glib-dev.install  |   2 +-
 ci/linux-packages/yum/almalinux-8/Dockerfile       |   1 +
 ci/linux-packages/yum/almalinux-9/Dockerfile       |   1 +
 ci/linux-packages/yum/apache-arrow-adbc.spec.in    |  57 ++++++-
 ci/scripts/glib_test.sh                            |   1 +
 dev/release/verify-apt.sh                          |   8 +
 dev/release/verify-yum.sh                          |  10 +-
 glib/adbc-arrow-glib/adbc-arrow-glib.h             |  24 +++
 glib/adbc-arrow-glib/meson.build                   | 115 ++++++++++++++
 glib/adbc-arrow-glib/statement.c                   | 146 ++++++++++++++++++
 glib/adbc-arrow-glib/statement.h                   |  52 +++++++
 glib/adbc-arrow-glib/version.h.in                  | 171 +++++++++++++++++++++
 glib/adbc-glib/statement.c                         |  49 ++++--
 glib/adbc-glib/statement.h                         |   4 +
 glib/adbc-glib/version.h.in                        |  23 +++
 glib/example/vala/meson.build                      |   3 +-
 glib/example/vala/sqlite.vala                      |  15 +-
 glib/meson.build                                   |   9 ++
 glib/test/run.rb                                   |   5 +
 glib/test/run.sh                                   |   1 +
 .../{test-statement.rb => test-arrow-statement.rb} |  63 +++-----
 glib/test/test-statement.rb                        |   2 -
 ruby/dependency-check/Rakefile                     |   6 +-
 ruby/lib/adbc.rb                                   |  12 +-
 ruby/lib/adbc/arrow-statement.rb                   |  65 ++++++++
 ruby/lib/adbc/loader.rb                            |  19 +++
 ruby/lib/{adbc.rb => adbc/statement-openable.rb}   |  22 +--
 ruby/lib/{adbc.rb => adbc/statement-operations.rb} |  22 +--
 ruby/lib/adbc/statement.rb                         |  39 +----
 34 files changed, 885 insertions(+), 126 deletions(-)

diff --git a/ci/linux-packages/debian/control b/ci/linux-packages/debian/control
index 3643c337..2572edba 100644
--- a/ci/linux-packages/debian/control
+++ b/ci/linux-packages/debian/control
@@ -24,6 +24,7 @@ Build-Depends:
   debhelper-compat (= 12),
   gobject-introspection,
   golang | golang-1.20,
+  libarrow-glib-dev,
   libgirepository1.0-dev,
   libpq-dev,
   libsqlite3-dev,
@@ -197,3 +198,57 @@ Recommends:
 Description: Apache Arrow Database Connectivity (ADBC) driver manager
  .
  This package provides documentations.
+
+Package: libadbc-arrow-glib0
+Section: libs
+Architecture: any
+Multi-Arch: same
+Pre-Depends: ${misc:Pre-Depends}
+Depends:
+  ${misc:Depends},
+  ${shlibs:Depends},
+  libadbc-glib0 (= ${binary:Version})
+Description: Apache Arrow Database Connectivity (ADBC) driver manager
+ .
+ This package provides library files for Apache Arrow GLib integration.
+
+Package: gir1.2-adbc-arrow-1.0
+Section: introspection
+Architecture: any
+Multi-Arch: same
+Depends:
+  ${gir:Depends},
+  ${misc:Depends},
+  gir1.2-adbc-1.0 (= ${binary:Version})
+Description: Apache Arrow Database Connectivity (ADBC) driver manager
+ .
+ This package provides GObject Introspection typelib files for Apache
+ Arrow GLib integration.
+
+Package: libadbc-arrow-glib-dev
+Section: libdevel
+Architecture: any
+Multi-Arch: same
+Depends:
+  ${misc:Depends},
+  gir1.2-adbc-arrow-1.0 (= ${binary:Version}),
+  libadbc-glib-dev (= ${binary:Version})
+Description: Apache Arrow Database Connectivity (ADBC) driver manager
+ .
+ This package provides header files for Apache Arrow GLib
+ integration.
+
+Package: libadbc-arrow-glib-doc
+Section: doc
+Architecture: all
+Multi-Arch: foreign
+Depends:
+  ${misc:Depends}
+Recommends:
+  libglib2.0-doc,
+  libadbc-glib-doc,
+  libarrow-glib-doc
+Description: Apache Arrow Database Connectivity (ADBC) driver manager
+ .
+ This package provides documentations for Apache Arrow GLib
+ integration.
diff --git a/ci/linux-packages/debian/gir1.2-adbc-arrow-1.0.install 
b/ci/linux-packages/debian/gir1.2-adbc-arrow-1.0.install
new file mode 100644
index 00000000..800739d5
--- /dev/null
+++ b/ci/linux-packages/debian/gir1.2-adbc-arrow-1.0.install
@@ -0,0 +1 @@
+usr/lib/*/girepository-1.0/ADBCArrow-*.typelib
diff --git a/ci/linux-packages/debian/libadbc-arrow-glib-dev.install 
b/ci/linux-packages/debian/libadbc-arrow-glib-dev.install
new file mode 100644
index 00000000..84f304c4
--- /dev/null
+++ b/ci/linux-packages/debian/libadbc-arrow-glib-dev.install
@@ -0,0 +1,6 @@
+usr/include/adbc-arrow-glib/
+usr/lib/*/libadbc-arrow-glib.so
+usr/lib/*/pkgconfig/adbc-arrow-glib.pc
+usr/share/adbc-arrow-glib/example/
+usr/share/gir-1.0/ADBCArrow-*.gir
+usr/share/vala/vapi/adbc-arrow-glib.*
diff --git a/ci/linux-packages/debian/libadbc-arrow-glib-doc.install 
b/ci/linux-packages/debian/libadbc-arrow-glib-doc.install
new file mode 100644
index 00000000..b5f85b4d
--- /dev/null
+++ b/ci/linux-packages/debian/libadbc-arrow-glib-doc.install
@@ -0,0 +1 @@
+usr/share/doc/adbc-arrow-glib/
diff --git a/ci/linux-packages/debian/libadbc-arrow-glib0.install 
b/ci/linux-packages/debian/libadbc-arrow-glib0.install
new file mode 100644
index 00000000..b7d8187f
--- /dev/null
+++ b/ci/linux-packages/debian/libadbc-arrow-glib0.install
@@ -0,0 +1 @@
+usr/lib/*/libadbc-arrow-glib.so.*
diff --git a/ci/linux-packages/debian/libadbc-glib-dev.install 
b/ci/linux-packages/debian/libadbc-glib-dev.install
index 7e5f0d8d..9ff7ea31 100644
--- a/ci/linux-packages/debian/libadbc-glib-dev.install
+++ b/ci/linux-packages/debian/libadbc-glib-dev.install
@@ -3,4 +3,4 @@ usr/lib/*/libadbc-glib.so
 usr/lib/*/pkgconfig/adbc-glib.pc
 usr/share/adbc-glib/example/
 usr/share/gir-1.0/ADBC-*.gir
-usr/share/vala/vapi/*
+usr/share/vala/vapi/adbc-glib.*
diff --git a/ci/linux-packages/yum/almalinux-8/Dockerfile 
b/ci/linux-packages/yum/almalinux-8/Dockerfile
index dfd10dd4..8768d9ff 100644
--- a/ci/linux-packages/yum/almalinux-8/Dockerfile
+++ b/ci/linux-packages/yum/almalinux-8/Dockerfile
@@ -25,6 +25,7 @@ RUN \
   yum install -y ${quiet} epel-release && \
   yum install -y https://apache.jfrog.io/artifactory/arrow/almalinux/$(cut -d: 
-f5 /etc/system-release-cpe | cut -d. -f1)/apache-arrow-release-latest.rpm && \
   yum install --enablerepo=powertools -y ${quiet} \
+    arrow-glib-devel \
     ccache \
     cmake \
     gcc-c++ \
diff --git a/ci/linux-packages/yum/almalinux-9/Dockerfile 
b/ci/linux-packages/yum/almalinux-9/Dockerfile
index 213590e8..7d1929e4 100644
--- a/ci/linux-packages/yum/almalinux-9/Dockerfile
+++ b/ci/linux-packages/yum/almalinux-9/Dockerfile
@@ -25,6 +25,7 @@ RUN \
   dnf install -y ${quiet} epel-release && \
   dnf install -y https://apache.jfrog.io/artifactory/arrow/almalinux/$(cut -d: 
-f5 /etc/system-release-cpe | cut -d. -f1)/apache-arrow-release-latest.rpm && \
   dnf install --enablerepo=crb -y ${quiet} \
+    arrow-glib-devel \
     ccache \
     cmake \
     gcc-c++ \
diff --git a/ci/linux-packages/yum/apache-arrow-adbc.spec.in 
b/ci/linux-packages/yum/apache-arrow-adbc.spec.in
index 7a50a1fe..d1ba2d6a 100644
--- a/ci/linux-packages/yum/apache-arrow-adbc.spec.in
+++ b/ci/linux-packages/yum/apache-arrow-adbc.spec.in
@@ -40,6 +40,7 @@ License:      Apache-2.0
 URL:           https://arrow.apache.org/adbc/
 Source0:       
https://www.apache.org/dyn/closer.lua?action=download&path=/arrow/arrow-adbc-%{version}/apache-arrow-adbc-%{version}.tar.gz
 
+BuildRequires: arrow-glib-devel
 BuildRequires: cmake
 BuildRequires: gcc-c++
 BuildRequires: gobject-introspection-devel
@@ -260,7 +261,7 @@ This package contains the libraries for ADBC GLib.
 %defattr(-,root,root,-)
 %doc README.md
 %license LICENSE.txt NOTICE.txt
-%{_libdir}/girepository-1.0/
+%{_libdir}/girepository-1.0/ADBC-*.typelib
 %{_libdir}/libadbc-glib.so.*
 
 %package glib-devel
@@ -278,8 +279,8 @@ Libraries and header files for ADBC GLib.
 %defattr(-,root,root,-)
 %doc README.md
 %license LICENSE.txt NOTICE.txt
-%{_datadir}/gir-1.0/
-%{_datadir}/vala/vapi/
+%{_datadir}/gir-1.0/ADBC-*.gir
+%{_datadir}/vala/vapi/adbc-glib.*
 %{_includedir}/adbc-glib/
 %{_libdir}/libadbc-glib.a
 %{_libdir}/libadbc-glib.so
@@ -299,6 +300,56 @@ Documentation for ADBC GLib.
 %{_datadir}/adbc-glib/example/
 %{_docdir}/adbc-glib/
 
+%package arrow-glib%{major_version}-libs
+Summary:       Runtime libraries for Apache Arrow GLib integration
+License:       Apache-2.0
+Requires:      %{name}-glib%{major_version}-libs = %{version}-%{release}
+
+%description arrow-glib%{major_version}-libs
+This package contains the libraries for Apache Arrow GLib integration.
+
+%files arrow-glib%{major_version}-libs
+%defattr(-,root,root,-)
+%doc README.md
+%license LICENSE.txt NOTICE.txt
+%{_libdir}/girepository-1.0/ADBCArrow-*.typelib
+%{_libdir}/libadbc-arrow-glib.so.*
+
+%package arrow-glib-devel
+Summary:       Libraries and header files for Apache Arrow GLib integration
+License:       Apache-2.0
+Requires:      %{name}-arrow-glib%{major_version}-libs = %{version}-%{release}
+Requires:      %{name}-glib-devel = %{version}-%{release}
+Requires:      arrow-glib-devel
+
+%description arrow-glib-devel
+Libraries and header files for Apache Arrow GLib integration
+
+%files arrow-glib-devel
+%defattr(-,root,root,-)
+%doc README.md
+%license LICENSE.txt NOTICE.txt
+%{_datadir}/gir-1.0/ADBCArrow-*.gir
+%{_datadir}/vala/vapi/adbc-arrow-glib.*
+%{_includedir}/adbc-arrow-glib/
+%{_libdir}/libadbc-arrow-glib.a
+%{_libdir}/libadbc-arrow-glib.so
+%{_libdir}/pkgconfig/adbc-arrow-glib.pc
+
+%package arrow-glib-doc
+Summary:       Documentation for Apache Arrow GLib integration
+License:       Apache-2.0
+
+%description arrow-glib-doc
+Documentation for Apache Arrow GLib integration.
+
+%files arrow-glib-doc
+%defattr(-,root,root,-)
+%doc README.md
+%license LICENSE.txt NOTICE.txt
+%{_datadir}/adbc-arrow-glib/example/
+%{_docdir}/adbc-arrow-glib/
+
 %changelog
 * Thu Apr 27 2023 Matt Topol <[email protected]> - 0.4.0-1
 - Add snowflake driver
diff --git a/ci/scripts/glib_test.sh b/ci/scripts/glib_test.sh
index ad29d47b..f2b3d1c2 100755
--- a/ci/scripts/glib_test.sh
+++ b/ci/scripts/glib_test.sh
@@ -28,6 +28,7 @@ test_subproject() {
 
     export 
DYLD_LIBRARY_PATH="${install_dir}/lib${DYLD_LIBRARY_PATH:+:${DYLD_LIBRARY_PATH}}"
     export 
GI_TYPELIB_PATH="${build_dir}/glib/adbc-glib${GI_TYPELIB_PATH:+:${GI_TYPELIB_PATH}}"
+    export 
GI_TYPELIB_PATH="${build_dir}/glib/adbc-arrow-glib:${GI_TYPELIB_PATH}"
     export 
LD_LIBRARY_PATH="${install_dir}/lib${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}"
     export 
PKG_CONFIG_PATH="${install_dir}/lib/pkgconfig${PKG_CONFIG_PATH:+:${PKG_CONFIG_PATH}}"
     if [[ -n "${CONDA_PREFIX}" ]]; then
diff --git a/dev/release/verify-apt.sh b/dev/release/verify-apt.sh
index c5bd4818..0f6f935b 100755
--- a/dev/release/verify-apt.sh
+++ b/dev/release/verify-apt.sh
@@ -197,3 +197,11 @@ ${APT_INSTALL} ruby-dev rubygems-integration
 gem install gobject-introspection
 ruby -r gi -e "p GI.load('ADBC')"
 echo "::endgroup::"
+
+echo "::group::Test ADBC Arrow GLib"
+
+${APT_INSTALL} libadbc-arrow-glib-dev=${package_version}
+${APT_INSTALL} libadbc-arrow-glib-doc=${package_version}
+
+ruby -r gi -e "p GI.load('ADBCArrow')"
+echo "::endgroup::"
diff --git a/dev/release/verify-yum.sh b/dev/release/verify-yum.sh
index 244fed45..f7f02361 100755
--- a/dev/release/verify-yum.sh
+++ b/dev/release/verify-yum.sh
@@ -157,7 +157,7 @@ echo "::group::Test ADBC Snowflake Driver"
 ${install_command} --enablerepo=epel 
adbc-driver-snowflake-devel-${package_version}
 echo "::endgroup::"
 
-echo "::group::Test Apache Arrow GLib"
+echo "::group::Test ADBC GLib"
 export G_DEBUG=fatal-warnings
 
 ${install_command} --enablerepo=epel adbc-glib-devel-${package_version}
@@ -167,3 +167,11 @@ ${install_command} "${ruby_devel_packages[@]}"
 gem install gobject-introspection
 ruby -r gi -e "p GI.load('ADBC')"
 echo "::endgroup::"
+
+echo "::group::Test ADBC Arrow GLib"
+
+${install_command} --enablerepo=epel adbc-arrow-glib-devel-${package_version}
+${install_command} --enablerepo=epel adbc-arrow-glib-doc-${package_version}
+
+ruby -r gi -e "p GI.load('ADBCArrow')"
+echo "::endgroup::"
diff --git a/glib/adbc-arrow-glib/adbc-arrow-glib.h 
b/glib/adbc-arrow-glib/adbc-arrow-glib.h
new file mode 100644
index 00000000..d9b485f3
--- /dev/null
+++ b/glib/adbc-arrow-glib/adbc-arrow-glib.h
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#pragma once
+
+#include <adbc-arrow-glib/version.h>
+
+#include <adbc-arrow-glib/statement.h>
diff --git a/glib/adbc-arrow-glib/meson.build b/glib/adbc-arrow-glib/meson.build
new file mode 100644
index 00000000..65103693
--- /dev/null
+++ b/glib/adbc-arrow-glib/meson.build
@@ -0,0 +1,115 @@
+# -*- indent-tabs-mode: nil -*-
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+sources = files(
+  'statement.c',
+)
+
+definition_headers = files(
+  'statement.h',
+)
+
+headers = definition_headers
+headers += files(
+  'adbc-arrow-glib.h',
+)
+
+version_h_conf = configuration_data()
+version_h_conf.set('GADBC_ARROW_VERSION', meson.project_version())
+version_h_conf.set('GADBC_ARROW_VERSION_MAJOR', version_major)
+version_h_conf.set('GADBC_ARROW_VERSION_MINOR', version_minor)
+version_h_conf.set('GADBC_ARROW_VERSION_MICRO', version_micro)
+version_h = configure_file(input: 'version.h.in',
+                           output: 'version.h',
+                           configuration: version_h_conf)
+headers += version_h
+
+enums = gnome.mkenums_simple('enum-types',
+                             identifier_prefix: 'GADBCArrow',
+                             sources: definition_headers,
+                             symbol_prefix: 'gadbc_arrow')
+enums_header = enums[1]
+
+install_headers(headers, subdir: 'adbc-arrow-glib')
+
+
+dependencies = [
+  adbc_glib,
+  arrow_glib,
+]
+libadbc_arrow_glib = library('adbc-arrow-glib',
+                             c_args: '-DG_LOG_DOMAIN="ADBC-Arrow"',
+                             sources: sources + enums,
+                             install: true,
+                             dependencies: dependencies,
+                             include_directories: base_include_directories,
+                             soversion: so_version,
+                             version: library_version)
+adbc_arrow_glib = \
+  declare_dependency(link_with: libadbc_arrow_glib,
+                     include_directories: base_include_directories,
+                     dependencies: dependencies,
+                     sources: enums_header)
+
+pkgconfig.generate(libadbc_arrow_glib,
+                   description: 'Arrow GLib integration API for ADBC GLib',
+                   filebase: 'adbc-arrow-glib',
+                   name: 'ADBC Arrow GLib',
+                   requires: ['adbc-glib', 'arrow-glib'],
+                   variables: pkgconfig_variables,
+                   version: meson.project_version())
+
+adbc_arrow_glib_gir = \
+  gnome.generate_gir(libadbc_arrow_glib,
+                     dependencies: [
+                       declare_dependency(sources: adbc_glib_gir),
+                       arrow_glib,
+                     ],
+                     export_packages: 'adbc-arrow-glib',
+                     extra_args: [
+                       '--warn-all',
+                     ],
+                     fatal_warnings: gi_fatal_warnings,
+                     header: 'adbc-arrow-glib/adbc-arrow-glib.h',
+                     identifier_prefix: 'GADBCArrow',
+                     includes: [
+                       'ADBC-1.0',
+                       'Arrow-1.0',
+                     ],
+                     install: true,
+                     namespace: 'ADBCArrow',
+                     nsversion: api_version,
+                     sources: sources + definition_headers + enums,
+                     symbol_prefix: 'gadbc_arrow')
+if generate_vapi
+  adbc_arrow_glib_vapi = \
+    gnome.generate_vapi('adbc-arrow-glib',
+                        gir_dirs: [
+                          arrow_glib.get_variable('girdir'),
+                        ],
+                        install: true,
+                        packages: [
+                          adbc_glib_vapi,
+                          'arrow-glib',
+                        ],
+                        sources: [adbc_arrow_glib_gir[0]],
+                        vapi_dirs: [
+                          arrow_glib.get_variable('vapidir'),
+                        ])
+endif
diff --git a/glib/adbc-arrow-glib/statement.c b/glib/adbc-arrow-glib/statement.c
new file mode 100644
index 00000000..8f9352f8
--- /dev/null
+++ b/glib/adbc-arrow-glib/statement.c
@@ -0,0 +1,146 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <adbc-arrow-glib/statement.h>
+
+/**
+ * SECTION: statement
+ * @title: GADBCArrowStatement
+ * @include: adbc-arrow-glib/adbc-arrow-glib.h
+ *
+ * #GADBCArrowStatement is a class for Arrow GLib integrated
+    statement.
+ */
+
+G_DEFINE_TYPE(GADBCArrowStatement, gadbc_arrow_statement, GADBC_TYPE_STATEMENT)
+
+static void gadbc_arrow_statement_init(GADBCArrowStatement* statement) {}
+
+static void gadbc_arrow_statement_class_init(GADBCArrowStatementClass* klass) 
{}
+
+/**
+ * gadbc_arrow_statement_new:
+ * @connection: A #GADBCConnection.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Returns: A newly created #GADBCArrowStatement for @connection on
+ * success, %NULL otherwise.
+ *
+ * Since: 0.10.0
+ */
+GADBCArrowStatement* gadbc_arrow_statement_new(GADBCConnection* connection,
+                                               GError** error) {
+  GADBCArrowStatement* statement = g_object_new(GADBC_ARROW_TYPE_STATEMENT, 
NULL);
+  if (gadbc_statement_initialize(GADBC_STATEMENT(statement), connection,
+                                 "[adbc-arrow][statement][new]", error)) {
+    return statement;
+  } else {
+    g_object_unref(statement);
+    return NULL;
+  }
+}
+
+/**
+ * gadbc_arrow_statement_bind:
+ * @statement: A #GADBCArrowStatement.
+ * @record_batch: A #GArrowRecordBatch.
+ * @error: (out) (optional): Return location for a #GError or %NULL.
+ *
+ * Bind Arrow data. This can be used for bulk inserts or prepared
+ * statements.
+ *
+ * Returns: %TRUE if binding is done successfully, %FALSE
+ *   otherwise.
+ *
+ * Since: 0.10.0
+ */
+gboolean gadbc_arrow_statement_bind(GADBCArrowStatement* statement,
+                                    GArrowRecordBatch* record_batch, GError** 
error) {
+  gpointer c_abi_array = NULL;
+  gpointer c_abi_schema = NULL;
+  if (!garrow_record_batch_export(record_batch, &c_abi_array, &c_abi_schema, 
error)) {
+    return FALSE;
+  }
+  gboolean success =
+      gadbc_statement_bind(GADBC_STATEMENT(statement), c_abi_array, 
c_abi_schema, error);
+  g_free(c_abi_array);
+  g_free(c_abi_schema);
+  return success;
+}
+
+/**
+ * gadbc_arrow_statement_bind_stream:
+ * @statement: A #GADBCArrowStatement.
+ * @reader: A #GArrowRecordBatchReader.
+ * @error: (out) (optional): Return location for a #GError or %NULL.
+ *
+ * Bind Arrow data stream. This can be used for bulk inserts or prepared
+ * statements.
+ *
+ * Returns: %TRUE if binding is done successfully, %FALSE
+ *   otherwise.
+ *
+ * Since: 0.10.0
+ */
+gboolean gadbc_arrow_statement_bind_stream(GADBCArrowStatement* statement,
+                                           GArrowRecordBatchReader* reader,
+                                           GError** error) {
+  gpointer c_abi_array_stream = garrow_record_batch_reader_export(reader, 
error);
+  if (!c_abi_array_stream) {
+    return FALSE;
+  }
+  gboolean success =
+      gadbc_statement_bind_stream(GADBC_STATEMENT(statement), 
c_abi_array_stream, error);
+  g_free(c_abi_array_stream);
+  return success;
+}
+
+/**
+ * gadbc_arrow_statement_execute:
+ * @statement: A #GADBCStatement.
+ * @need_result: Whether the results are received by @reader or not.
+ * @reader: (out) (optional): Return location for the execution.
+ * @n_rows_affected: (out) (optional): Return location for the number of rows
+ *   affected if known.
+ * @error: (out) (optional): Return location for a #GError or %NULL.
+ *
+ * Execute a statement and get the results.
+ *
+ * This invalidates any prior result sets.
+ *
+ * Returns: %TRUE if execution is done successfully, %FALSE otherwise.
+ *
+ * Since: 0.10.0
+ */
+gboolean gadbc_arrow_statement_execute(GADBCArrowStatement* statement,
+                                       gboolean need_result,
+                                       GArrowRecordBatchReader** reader,
+                                       gint64* n_rows_affected, GError** 
error) {
+  gpointer c_abi_array_stream = NULL;
+  if (!gadbc_statement_execute(GADBC_STATEMENT(statement), need_result,
+                               reader ? &c_abi_array_stream : NULL, 
n_rows_affected,
+                               error)) {
+    return FALSE;
+  }
+  if (need_result && reader) {
+    *reader = garrow_record_batch_reader_import(c_abi_array_stream, error);
+    g_free(c_abi_array_stream);
+  }
+  return TRUE;
+}
diff --git a/glib/adbc-arrow-glib/statement.h b/glib/adbc-arrow-glib/statement.h
new file mode 100644
index 00000000..ee020064
--- /dev/null
+++ b/glib/adbc-arrow-glib/statement.h
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#pragma once
+
+#include <adbc-glib/adbc-glib.h>
+#include <arrow-glib/arrow-glib.h>
+
+#include <adbc-arrow-glib/version.h>
+
+G_BEGIN_DECLS
+
+#define GADBC_ARROW_TYPE_STATEMENT (gadbc_arrow_statement_get_type())
+G_DECLARE_DERIVABLE_TYPE(GADBCArrowStatement, gadbc_arrow_statement, 
GADBCArrow,
+                         STATEMENT, GADBCStatement)
+struct _GADBCArrowStatementClass {
+  GADBCStatementClass parent_class;
+};
+
+GADBC_ARROW_AVAILABLE_IN_0_10
+GADBCArrowStatement* gadbc_arrow_statement_new(GADBCConnection* connection,
+                                               GError** error);
+GADBC_ARROW_AVAILABLE_IN_0_10
+gboolean gadbc_arrow_statement_bind(GADBCArrowStatement* statement,
+                                    GArrowRecordBatch* record_batch, GError** 
error);
+GADBC_ARROW_AVAILABLE_IN_0_10
+gboolean gadbc_arrow_statement_bind_stream(GADBCArrowStatement* statement,
+                                           GArrowRecordBatchReader* reader,
+                                           GError** error);
+GADBC_ARROW_AVAILABLE_IN_0_10
+gboolean gadbc_arrow_statement_execute(GADBCArrowStatement* statement,
+                                       gboolean need_result,
+                                       GArrowRecordBatchReader** reader,
+                                       gint64* n_rows_affected, GError** 
error);
+
+G_END_DECLS
diff --git a/glib/adbc-arrow-glib/version.h.in 
b/glib/adbc-arrow-glib/version.h.in
new file mode 100644
index 00000000..6fd00688
--- /dev/null
+++ b/glib/adbc-arrow-glib/version.h.in
@@ -0,0 +1,171 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#pragma once
+
+#include <glib.h>
+
+/**
+ * SECTION: version
+ * @section_id: version-macros
+ * @title: Version related macros
+ * @include: adbc-arrow-glib/adbc-arrow-glib.h
+ *
+ * ADBC Arrow GLib provides macros that can be used by C pre-processor.
+ * They are useful to check version related things at compile time.
+ */
+
+/**
+ * GADBC_ARROW_VERSION_MAJOR:
+ *
+ * The major version.
+ *
+ * Since: 0.10.0
+ */
+#define GADBC_ARROW_VERSION_MAJOR (@GADBC_ARROW_VERSION_MAJOR@)
+
+/**
+ * GADBC_ARROW_VERSION_MINOR:
+ *
+ * The minor version.
+ *
+ * Since: 0.10.0
+ */
+#define GADBC_ARROW_VERSION_MINOR (@GADBC_ARROW_VERSION_MINOR@)
+
+/**
+ * GADBC_ARROW_VERSION_MICRO:
+ *
+ * The micro version.
+ *
+ * Since: 0.10.0
+ */
+#define GADBC_ARROW_VERSION_MICRO (@GADBC_ARROW_VERSION_MICRO@)
+
+/**
+ * GADBC_ARROW_VERSION_CHECK:
+ * @major: A major version to check for.
+ * @minor: A minor version to check for.
+ * @micro: A micro version to check for.
+ *
+ * You can use this macro in C pre-processor.
+ *
+ * Returns: %TRUE if the compile time ADBC Arrow GLib version is the
+ *   same as or newer than the passed version, %FALSE otherwise.
+ *
+ * Since: 0.10.0
+ */
+#define GADBC_ARROW_VERSION_CHECK(major, minor, micro)  \
+  (GADBC_ARROW_VERSION_MAJOR > (major) ||               \
+   (GADBC_ARROW_VERSION_MAJOR == (major) &&             \
+    GADBC_ARROW_VERSION_MINOR > (minor)) ||             \
+   (GADBC_ARROW_VERSION_MAJOR == (major) &&             \
+    GADBC_ARROW_VERSION_MINOR == (minor) &&             \
+    GADBC_ARROW_VERSION_MICRO >= (micro)))
+
+/**
+ * GADBC_ARROW_DISABLE_DEPRECATION_WARNINGS:
+ *
+ * If this macro is defined, no deprecated warnings are produced.
+ *
+ * You must define this macro before including the
+ * adbc-arrow-glib/adbc-arrow-glib.h header.
+ *
+ * Since: 0.10.0
+ */
+
+#ifdef GADBC_ARROW_DISABLE_DEPRECATION_WARNINGS
+#  define GADBC_ARROW_DEPRECATED
+#  define GADBC_ARROW_DEPRECATED_FOR(function)
+#  define GADBC_ARROW_UNAVAILABLE(major, minor)
+#else
+#  define GADBC_ARROW_DEPRECATED G_DEPRECATED
+#  define GADBC_ARROW_DEPRECATED_FOR(function) G_DEPRECATED_FOR(function)
+#  define GADBC_ARROW_UNAVAILABLE(major, minor) G_UNAVAILABLE(major, minor)
+#endif
+
+/**
+ * GADBC_ARROW_VERSION_0_10:
+ *
+ * You can use this macro value for compile time API version check.
+ *
+ * Since: 0.10.0
+ */
+#define GADBC_ARROW_VERSION_0_10 G_ENCODE_VERSION(0, 10)
+
+/**
+ * GADBC_ARROW_VERSION_MIN_REQUIRED:
+ *
+ * You can use this macro for compile time API version check.
+ *
+ * This macro value must be one of the predefined version macros such
+ * as %GADBC_ARROW_VERSION_0_10.
+ *
+ * If you use any functions that is defined by newer version than
+ * %GADBC_ARROW_VERSION_MIN_REQUIRED, deprecated warnings are produced at
+ * compile time.
+ *
+ * You must define this macro before including the
+ * adbc-glib/adbc-glib.h header.
+ *
+ * Since: 0.10.0
+ */
+#ifndef GADBC_ARROW_VERSION_MIN_REQUIRED
+#  define GADBC_ARROW_VERSION_MIN_REQUIRED                              \
+  G_ENCODE_VERSION(GADBC_ARROW_VERSION_MAJOR, GADBC_ARROW_VERSION_MINOR)
+#endif
+
+/**
+ * GADBC_ARROW_VERSION_MAX_ALLOWED:
+ *
+ * You can use this macro for compile time API version check.
+ *
+ * This macro value must be one of the predefined version macros such
+ * as %GADBC_ARROW_VERSION_0_10.
+ *
+ * If you use any functions that is defined by newer version than
+ * %GADBC_ARROW_VERSION_MAX_ALLOWED, deprecated warnings are produced at
+ * compile time.
+ *
+ * You must define this macro before including the
+ * adbc-arrow-glib/adbc-arrow-glib.h header.
+ *
+ * Since: 0.10.0
+ */
+#ifndef GADBC_ARROW_VERSION_MAX_ALLOWED
+#  define GADBC_ARROW_VERSION_MAX_ALLOWED                               \
+  G_ENCODE_VERSION(GADBC_ARROW_VERSION_MAJOR, GADBC_ARROW_VERSION_MINOR)
+#endif
+
+
+#define GADBC_ARROW_AVAILABLE_IN_ALL
+
+#if GADBC_ARROW_VERSION_MIN_REQUIRED >= GADBC_ARROW_VERSION_0_10
+#  define GADBC_ARROW_DEPRECATED_IN_0_10                GADBC_ARROW_DEPRECATED
+#  define GADBC_ARROW_DEPRECATED_IN_0_10_FOR(function)  
GADBC_ARROW_DEPRECATED_FOR(function)
+#else
+#  define GADBC_ARROW_DEPRECATED_IN_0_10
+#  define GADBC_ARROW_DEPRECATED_IN_0_10_FOR(function)
+#endif
+
+#if GADBC_ARROW_VERSION_MAX_ALLOWED < GADBC_ARROW_VERSION_0_10
+#  define GADBC_ARROW_AVAILABLE_IN_0_10 GADBC_ARROW_UNAVAILABLE(0, 10)
+#else
+#  define GADBC_ARROW_AVAILABLE_IN_0_10
+#endif
diff --git a/glib/adbc-glib/statement.c b/glib/adbc-glib/statement.c
index 36734a69..cb17eb3c 100644
--- a/glib/adbc-glib/statement.c
+++ b/glib/adbc-glib/statement.c
@@ -65,35 +65,62 @@ static void gadbc_statement_class_init(GADBCStatementClass* 
klass) {
 }
 
 /**
- * gadbc_statement_new:
+ * gadbc_statement_initialize: (skip)
+ * @statement: A #GADBCStatement.
  * @connection: A #GADBCConnection.
+ * @context: A context for error message.
  * @error: (nullable): Return location for a #GError or %NULL.
  *
- * Returns: A newly created #GADBCStatement for @connection on success,
- *   %NULL otherwise.
+ * This is only for implementing subclass of #GADBCStatement. In
+ * general, users should use gadbc_statement_new().
  *
- * Since: 0.1.0
+ * Initializes an empty #GADBCStatement with the given
+ * #GADBCConnection.
+ *
+ * Returns: %TRUE if initialization is done successfully, %FALSE otherwise.
+ *
+ * Since: 0.10.0
  */
-GADBCStatement* gadbc_statement_new(GADBCConnection* connection, GError** 
error) {
-  const gchar* context = "[adbc][statement][new]";
+gboolean gadbc_statement_initialize(GADBCStatement* statement,
+                                    GADBCConnection* connection, const char* 
context,
+                                    GError** error) {
   struct AdbcConnection* adbc_connection =
       gadbc_connection_get_raw(connection, context, error);
   if (!adbc_connection) {
-    return NULL;
+    return FALSE;
   }
-  GADBCStatement* statement = g_object_new(GADBC_TYPE_STATEMENT, NULL);
   GADBCStatementPrivate* priv = 
gadbc_statement_get_instance_private(statement);
   struct AdbcError adbc_error = {};
   AdbcStatusCode status_code =
       AdbcStatementNew(adbc_connection, &(priv->adbc_statement), &adbc_error);
   priv->initialized = gadbc_error_check(error, status_code, &adbc_error, 
context);
   if (!priv->initialized) {
-    g_object_unref(statement);
-    return NULL;
+    return FALSE;
   }
   priv->connection = connection;
   g_object_ref(priv->connection);
-  return statement;
+  return TRUE;
+}
+
+/**
+ * gadbc_statement_new:
+ * @connection: A #GADBCConnection.
+ * @error: (nullable): Return location for a #GError or %NULL.
+ *
+ * Returns: A newly created #GADBCStatement for @connection on success,
+ *   %NULL otherwise.
+ *
+ * Since: 0.1.0
+ */
+GADBCStatement* gadbc_statement_new(GADBCConnection* connection, GError** 
error) {
+  GADBCStatement* statement = g_object_new(GADBC_TYPE_STATEMENT, NULL);
+  if (gadbc_statement_initialize(statement, connection, 
"[adbc][statement][new]",
+                                 error)) {
+    return statement;
+  } else {
+    g_object_unref(statement);
+    return NULL;
+  }
 }
 
 /**
diff --git a/glib/adbc-glib/statement.h b/glib/adbc-glib/statement.h
index cf6a3d5b..07f6ade8 100644
--- a/glib/adbc-glib/statement.h
+++ b/glib/adbc-glib/statement.h
@@ -47,6 +47,10 @@ struct _GADBCStatementClass {
   GObjectClass parent_class;
 };
 
+GADBC_AVAILABLE_IN_0_10
+gboolean gadbc_statement_initialize(GADBCStatement* statement,
+                                    GADBCConnection* connection, const gchar* 
context,
+                                    GError** error);
 GADBC_AVAILABLE_IN_0_1
 GADBCStatement* gadbc_statement_new(GADBCConnection* connection, GError** 
error);
 GADBC_AVAILABLE_IN_0_1
diff --git a/glib/adbc-glib/version.h.in b/glib/adbc-glib/version.h.in
index bf75cfc4..a7a88379 100644
--- a/glib/adbc-glib/version.h.in
+++ b/glib/adbc-glib/version.h.in
@@ -100,6 +100,15 @@
 #  define GADBC_UNAVAILABLE(major, minor) G_UNAVAILABLE(major, minor)
 #endif
 
+/**
+ * GADBC_VERSION_0_10:
+ *
+ * You can use this macro value for compile time API version check.
+ *
+ * Since: 0.10.0
+ */
+#define GADBC_VERSION_0_10 G_ENCODE_VERSION(0, 10)
+
 /**
  * GADBC_VERSION_0_4:
  *
@@ -165,6 +174,20 @@
 
 #define GADBC_AVAILABLE_IN_ALL
 
+#if GADBC_VERSION_MIN_REQUIRED >= GADBC_VERSION_0_10
+#  define GADBC_DEPRECATED_IN_0_10                GADBC_DEPRECATED
+#  define GADBC_DEPRECATED_IN_0_10_FOR(function)  
GADBC_DEPRECATED_FOR(function)
+#else
+#  define GADBC_DEPRECATED_IN_0_10
+#  define GADBC_DEPRECATED_IN_0_10_FOR(function)
+#endif
+
+#if GADBC_VERSION_MAX_ALLOWED < GADBC_VERSION_0_10
+#  define GADBC_AVAILABLE_IN_0_10 GADBC_UNAVAILABLE(0, 10)
+#else
+#  define GADBC_AVAILABLE_IN_0_10
+#endif
+
 #if GADBC_VERSION_MIN_REQUIRED >= GADBC_VERSION_0_4
 #  define GADBC_DEPRECATED_IN_0_4                GADBC_DEPRECATED
 #  define GADBC_DEPRECATED_IN_0_4_FOR(function)  GADBC_DEPRECATED_FOR(function)
diff --git a/glib/example/vala/meson.build b/glib/example/vala/meson.build
index 3486a8c9..26022bcc 100644
--- a/glib/example/vala/meson.build
+++ b/glib/example/vala/meson.build
@@ -25,6 +25,7 @@ if build_example and generate_vapi
     ],
     'dependencies': [
       adbc_glib_vapi,
+      adbc_arrow_glib_vapi,
       arrow_glib,
       dependency('gobject-2.0'),
     ],
@@ -43,6 +44,6 @@ files = [
 ]
 install_data(files,
              install_dir: join_paths(data_dir,
-                                     meson.project_name(),
+                                     'adbc-arrow-glib',
                                      'example',
                                      'vala'))
diff --git a/glib/example/vala/sqlite.vala b/glib/example/vala/sqlite.vala
index 76183539..c184bb51 100644
--- a/glib/example/vala/sqlite.vala
+++ b/glib/example/vala/sqlite.vala
@@ -27,20 +27,15 @@ int main (string[] args) {
             var connection = new GADBC.Connection ();
             connection.init (database);
             try {
-                var statement = new GADBC.Statement (connection);
+                var statement = new GADBCArrow.Statement (connection);
                 string sql = "SELECT sqlite_version() AS version";
                 statement.set_sql_query (sql);
                 try {
-                    void *c_abi_array_stream = null;
+                    GArrow.RecordBatchReader reader;
                     int64 n_rows_affected;
-                    statement.execute (true, out c_abi_array_stream, out 
n_rows_affected);
-                    try {
-                        var reader = GArrow.RecordBatchReader.import 
(c_abi_array_stream);
-                        var table = reader.read_all ();
-                        stdout.printf ("Result:\n%s", table.to_string ());
-                    } finally {
-                        GLib.free (c_abi_array_stream);
-                    }
+                    statement.execute (true, out reader, out n_rows_affected);
+                    var table = reader.read_all ();
+                    stdout.printf ("Result:\n%s", table.to_string ());
                     exit_code = Posix.EXIT_SUCCESS;
                 } catch (GLib.Error error) {
                     GLib.error ("Failed to execute a statement: %s", 
error.message);
diff --git a/glib/meson.build b/glib/meson.build
index f95563f2..dca66094 100644
--- a/glib/meson.build
+++ b/glib/meson.build
@@ -78,11 +78,20 @@ if generate_vapi
 endif
 
 subdir('adbc-glib')
+arrow_glib = dependency('arrow-glib', required: generate_vapi)
+if arrow_glib.found()
+  subdir('adbc-arrow-glib')
+endif
 subdir('example')
 
 install_data('../LICENSE.txt',
              'README.md',
              install_dir: data_dir / 'doc' / meson.project_name())
+if arrow_glib.found()
+  install_data('../LICENSE.txt',
+               'README.md',
+               install_dir: data_dir / 'doc' / 'adbc-arrow-glib')
+endif
 
 ruby = find_program('ruby', required: false)
 if ruby.found()
diff --git a/glib/test/run.rb b/glib/test/run.rb
index 352c34fa..2685a1ad 100755
--- a/glib/test/run.rb
+++ b/glib/test/run.rb
@@ -30,6 +30,11 @@ test_dir = base_dir + "test"
 require "gi"
 
 ADBC = GI.load("ADBC")
+begin
+  ADBCArrow = GI.load("ADBCArrow")
+rescue GObjectIntrospection::RepositoryError => error
+  puts("ADBCArrow isn't found: #{error}")
+end
 
 require_relative "helper"
 
diff --git a/glib/test/run.sh b/glib/test/run.sh
index 96fd6261..7a6dfc47 100755
--- a/glib/test/run.sh
+++ b/glib/test/run.sh
@@ -22,6 +22,7 @@ build_dir="$(cd .; pwd)"
 
 modules=(
   adbc-glib
+  adbc-arrow-glib
 )
 
 for module in "${modules[@]}"; do
diff --git a/glib/test/test-statement.rb b/glib/test/test-arrow-statement.rb
similarity index 56%
copy from glib/test/test-statement.rb
copy to glib/test/test-arrow-statement.rb
index b1b72dae..97f9807f 100644
--- a/glib/test/test-statement.rb
+++ b/glib/test/test-arrow-statement.rb
@@ -15,85 +15,66 @@
 # specific language governing permissions and limitations
 # under the License.
 
-class StatementTest < Test::Unit::TestCase
+class ArrowStatementTest < Test::Unit::TestCase
   include Helper
 
   def setup
+    omit("adbc-arrow-glib isn't built") unless defined?(ADBCArrow)
+
     @database = ADBC::Database.new
     @database.set_option("driver", "adbc_driver_sqlite")
     @database.set_option("uri", ":memory:")
     @database.init
     @connection = ADBC::Connection.new
     @connection.init(@database)
-    @statement = ADBC::Statement.new(@connection)
+    @statement = ADBCArrow::Statement.new(@connection)
   end
 
   def teardown
-    @statement.release
+    @statement&.release
   end
 
   def test_execute
     @statement.set_sql_query("SELECT 1")
-    execute_statement(@statement) do |table, _n_rows_affected|
-      assert_equal(Arrow::Table.new("1" => Arrow::Int64Array.new([1])),
-                   table)
-    end
+    _, reader, _ = @statement.execute(true)
+    assert_equal(Arrow::Table.new("1" => Arrow::Int64Array.new([1])),
+                 reader.read_all)
   end
 
   def test_bind
     @statement.set_sql_query("CREATE TABLE data (number int)")
-    execute_statement(@statement, need_result: false)
+    @statement.execute(false)
 
     record_batch =
       Arrow::RecordBatch.new(number: Arrow::Int64Array.new([10, 20, 30]))
-    @statement.set_sql_query("INSERT INTO data VALUES (?)")
     @statement.ingest_target_table = "data"
     @statement.ingest_mode = :append
-    _, c_abi_array, c_abi_schema = record_batch.export
-    begin
-      @statement.bind(c_abi_array, c_abi_schema)
-      execute_statement(@statement, need_result: false) do |n_rows_affected|
-        assert_equal(3, n_rows_affected)
-      end
-    ensure
-      begin
-        GLib.free(c_abi_array)
-      ensure
-        GLib.free(c_abi_schema)
-      end
-    end
+    @statement.bind(record_batch)
+    _, _, n_rows_affected = @statement.execute(false)
+    assert_equal(3, n_rows_affected)
 
     @statement.set_sql_query("SELECT * FROM data")
-    execute_statement(@statement) do |table, _n_rows_affected|
-      assert_equal(record_batch.to_table,
-                   table)
-    end
+    _, reader, _ = @statement.execute(true)
+    assert_equal(record_batch.to_table,
+                 reader.read_all)
   end
 
   def test_bind_stream
     @statement.set_sql_query("CREATE TABLE data (number int)")
-    execute_statement(@statement, need_result: false)
+    @statement.execute(false)
 
     record_batch =
       Arrow::RecordBatch.new(number: Arrow::Int64Array.new([10, 20, 30]))
-    @statement.set_sql_query("INSERT INTO data VALUES (?)")
     @statement.ingest_target_table = "data"
     @statement.ingest_mode = :append
     reader = Arrow::RecordBatchReader.new([record_batch])
-    c_abi_array_stream = reader.export
-    begin
-      @statement.bind_stream(c_abi_array_stream)
-      execute_statement(@statement, need_result: false) do |n_rows_affected|
-        assert_equal(3, n_rows_affected)
-      end
-    ensure
-      GLib.free(c_abi_array_stream)
-    end
+    @statement.bind_stream(reader)
+    _, _, n_rows_affected = @statement.execute(false)
+    assert_equal(3, n_rows_affected)
 
     @statement.set_sql_query("SELECT * FROM data")
-    execute_statement(@statement) do |table, _n_rows_affected|
-      assert_equal(record_batch.to_table,
-                   table)
-    end
+    _, reader, _ = @statement.execute(true)
+    assert_equal(record_batch.to_table,
+                 reader.read_all)
   end
 end
diff --git a/glib/test/test-statement.rb b/glib/test/test-statement.rb
index b1b72dae..9f565158 100644
--- a/glib/test/test-statement.rb
+++ b/glib/test/test-statement.rb
@@ -46,7 +46,6 @@ class StatementTest < Test::Unit::TestCase
 
     record_batch =
       Arrow::RecordBatch.new(number: Arrow::Int64Array.new([10, 20, 30]))
-    @statement.set_sql_query("INSERT INTO data VALUES (?)")
     @statement.ingest_target_table = "data"
     @statement.ingest_mode = :append
     _, c_abi_array, c_abi_schema = record_batch.export
@@ -76,7 +75,6 @@ class StatementTest < Test::Unit::TestCase
 
     record_batch =
       Arrow::RecordBatch.new(number: Arrow::Int64Array.new([10, 20, 30]))
-    @statement.set_sql_query("INSERT INTO data VALUES (?)")
     @statement.ingest_target_table = "data"
     @statement.ingest_mode = :append
     reader = Arrow::RecordBatchReader.new([record_batch])
diff --git a/ruby/dependency-check/Rakefile b/ruby/dependency-check/Rakefile
index 05ae3ee7..a083e09c 100644
--- a/ruby/dependency-check/Rakefile
+++ b/ruby/dependency-check/Rakefile
@@ -34,12 +34,12 @@ end
 namespace :dependency do
   desc "Check dependency"
   task :check do
-    unless PKGConfig.check_version?("adbc-glib",
+    unless PKGConfig.check_version?("adbc-arrow-glib",
                                     ADBC::Version::MAJOR,
                                     ADBC::Version::MINOR,
                                     ADBC::Version::MICRO)
-      unless NativePackageInstaller.install(debian: "libadbc-glib-dev",
-                                            redhat: "adbc-glib-devel")
+      unless NativePackageInstaller.install(debian: "libadbc-arrow-glib-dev",
+                                            redhat: "adbc-arrow-glib-devel")
         exit(false)
       end
     end
diff --git a/ruby/lib/adbc.rb b/ruby/lib/adbc.rb
index 5dfe18f7..f2482bfb 100644
--- a/ruby/lib/adbc.rb
+++ b/ruby/lib/adbc.rb
@@ -24,6 +24,16 @@ require "adbc/loader"
 module ADBC
   class Error < StandardError
   end
+end
 
-  Loader.load
+ADBC::Loader.load
+begin
+  ADBCArrow::Loader.load
+rescue GObjectIntrospection::RepositoryError
+else
+  module ADBC
+    RawStatement = Statement
+    remove_const(:Statement)
+    Statement = ADBCArrow::Statement
+  end
 end
diff --git a/ruby/lib/adbc/arrow-statement.rb b/ruby/lib/adbc/arrow-statement.rb
new file mode 100644
index 00000000..821ca637
--- /dev/null
+++ b/ruby/lib/adbc/arrow-statement.rb
@@ -0,0 +1,65 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+module ADBCArrow
+  class Statement
+    extend ADBC::StatementOpenable
+    include ADBC::StatementOperations
+
+    alias_method :execute_raw, :execute
+    def execute(need_result: true)
+      _, reader, n_rows_affected = execute_raw(need_result)
+      if need_result
+        begin
+          if block_given?
+            yield(reader, n_rows_affected)
+          else
+            [reader.read_all, n_rows_affected]
+          end
+        end
+      else
+        if block_given?
+          yield(n_rows_affected)
+        else
+          n_rows_affected
+        end
+      end
+    end
+
+    alias_method :bind_raw, :bind
+    def bind(*args)
+      n_args = args.size
+      if block_given?
+        message = "wrong number of arguments (given #{n_args}, expected 1 with 
block)"
+        raise ArgumentError, message unless n_args == 1
+        values = args[0]
+        if values.is_a?(Arrow::Table)
+          values = Arrow::TableBatchReader.new(values)
+        end
+        if values.is_a?(Arrow::RecordBatchReader)
+          bind_stream(values)
+          yield
+        else
+          bind_raw(values)
+          yield
+        end
+      else
+        bind_raw(*args)
+      end
+    end
+  end
+end
diff --git a/ruby/lib/adbc/loader.rb b/ruby/lib/adbc/loader.rb
index db776cf2..0e6468b2 100644
--- a/ruby/lib/adbc/loader.rb
+++ b/ruby/lib/adbc/loader.rb
@@ -43,3 +43,22 @@ module ADBC
     end
   end
 end
+
+module ADBCArrow
+  class Loader < GObjectIntrospection::Loader
+    class << self
+      def load
+        super("ADBCArrow", ADBCArrow)
+      end
+    end
+
+    private
+    def post_load(repository, namespace)
+      require_libraries
+    end
+
+    def require_libraries
+      require_relative "arrow-statement"
+    end
+  end
+end
diff --git a/ruby/lib/adbc.rb b/ruby/lib/adbc/statement-openable.rb
similarity index 76%
copy from ruby/lib/adbc.rb
copy to ruby/lib/adbc/statement-openable.rb
index 5dfe18f7..b805b33d 100644
--- a/ruby/lib/adbc.rb
+++ b/ruby/lib/adbc/statement-openable.rb
@@ -15,15 +15,19 @@
 # specific language governing permissions and limitations
 # under the License.
 
-require "arrow"
-
-require "adbc/version"
-
-require "adbc/loader"
-
 module ADBC
-  class Error < StandardError
+  module StatementOpenable
+    def open(connection)
+      statement = new(connection)
+      if block_given?
+        begin
+          yield(statement)
+        ensure
+          statement.release
+        end
+      else
+        statement
+      end
+    end
   end
-
-  Loader.load
 end
diff --git a/ruby/lib/adbc.rb b/ruby/lib/adbc/statement-operations.rb
similarity index 72%
copy from ruby/lib/adbc.rb
copy to ruby/lib/adbc/statement-operations.rb
index 5dfe18f7..79dd106b 100644
--- a/ruby/lib/adbc.rb
+++ b/ruby/lib/adbc/statement-operations.rb
@@ -15,15 +15,19 @@
 # specific language governing permissions and limitations
 # under the License.
 
-require "arrow"
-
-require "adbc/version"
-
-require "adbc/loader"
-
 module ADBC
-  class Error < StandardError
-  end
+  module StatementOperations
+    def ingest(table_name, values, mode: :create)
+      self.ingest_target_table = table_name
+      self.ingest_mode = mode
+      bind(values) do
+        execute(need_result: false)
+      end
+    end
 
-  Loader.load
+    def query(sql, &block)
+      self.sql_query = sql
+      execute(&block)
+    end
+  end
 end
diff --git a/ruby/lib/adbc/statement.rb b/ruby/lib/adbc/statement.rb
index d89ea0d0..f093be48 100644
--- a/ruby/lib/adbc/statement.rb
+++ b/ruby/lib/adbc/statement.rb
@@ -15,22 +15,13 @@
 # specific language governing permissions and limitations
 # under the License.
 
+require_relative "statement-openable"
+require_relative "statement-operations"
+
 module ADBC
   class Statement
-    class << self
-      def open(connection)
-        statement = new(connection)
-        if block_given?
-          begin
-            yield(statement)
-          ensure
-            statement.release
-          end
-        else
-          statement
-        end
-      end
-    end
+    extend StatementOpenable
+    include StatementOperations
 
     alias_method :execute_raw, :execute
     def execute(need_result: true)
@@ -94,25 +85,5 @@ module ADBC
         bind_raw(*args)
       end
     end
-
-    def ingest(table_name, values, mode: :create)
-      insert = "INSERT INTO #{table_name} (" # TODO escape
-      fields = values.schema.fields
-      insert << fields.collect(&:name).join(", ")
-      insert << ") VALUES ("
-      insert << (["?"] * fields.size).join(", ")
-      insert << ")"
-      self.sql_query = insert
-      self.ingest_target_table = table_name
-      self.ingest_mode = mode
-      bind(values) do
-        execute(need_result: false)
-      end
-    end
-
-    def query(sql, &block)
-      self.sql_query = sql
-      execute(&block)
-    end
   end
 end

Reply via email to