Ruby¶
red-adbc is the Ruby binding for ADBC, built on top of ADBC GLib. It is distributed as the red-adbc gem on RubyGems.
Here we’ll briefly tour basic features of ADBC with Ruby using the SQLite driver.
Installation¶
red-adbc depends on the native Arrow GLib and ADBC GLib libraries. The
rubygems-requirements-system plugin installs
these system dependencies automatically using your system package manager, so
install it first.
With gem:
gem install rubygems-requirements-system
gem install red-adbc
Or, with Bundler, add the plugin and the gem to your Gemfile:
source "https://rubygems.org"
plugin "rubygems-requirements-system"
gem "red-adbc"
Installing Drivers¶
You also need a driver for the database you want to connect to. See Installing Drivers for instructions. For the example below, you could install dbc and then install the SQLite driver with:
dbc install sqlite
Creating a Connection¶
require "adbc"
ADBC::Database.open(driver: "sqlite",
uri: ":memory") do |database|
database.connect do |connection|
# Use connection
end
end
In application code, the database and connection must be closed after usage or
memory may leak. Both Database.open and database.connect accept blocks
to accomplish this automatically.
Executing a Query¶
We can execute a query and get the results as an Arrow table:
require "adbc"
ADBC::Database.open(driver: "sqlite",
uri: ":memory:") do |database|
database.connect do |connection|
table, = connection.query("SELECT 1, 2.0, 'Hello, world!'")
puts table
end
end
Output:
1 2.0 'Hello, world!'
(int64) (double) (utf8)
0 1 2.0 Hello, world!
Ingesting Bulk Data¶
We can insert a table of Arrow data into a new database table:
require "adbc"
ADBC::Database.open(driver: "sqlite",
uri: ":memory:") do |database|
database.connect do |connection|
# Create an Arrow table
table = Arrow::Table.new(
ints: Arrow::Int64Array.new([1, 2]),
strs: Arrow::StringArray.new(["a", nil])
)
# Ingest into database
connection.ingest("sample", table, mode: :create)
# Query the data
result, = connection.query("SELECT COUNT(DISTINCT ints) FROM sample")
puts result
end
end
We can also append to an existing table:
require "adbc"
ADBC::Database.open(driver: "sqlite",
uri: ":memory:") do |database|
database.connect do |connection|
# Create initial table
table = Arrow::Table.new(
ints: Arrow::Int64Array.new([1, 2]),
strs: Arrow::StringArray.new(["a", nil])
)
connection.ingest("sample", table, mode: :create)
# Append more data
table2 = Arrow::Table.new(
ints: Arrow::Int64Array.new([2, 3]),
strs: Arrow::StringArray.new([nil, "c"])
)
connection.ingest("sample", table2, mode: :append)
# Query the combined data
result, = connection.query("SELECT COUNT(DISTINCT ints) FROM sample")
puts result
end
end
The mode parameter can be:
:create- Create a new table (default):append- Append to an existing table:replace- Replace an existing table
Getting Database/Driver Metadata¶
We can get information about the driver and the database:
require "adbc"
ADBC::Database.open(driver: "sqlite",
uri: ":memory:") do |database|
database.connect do |connection|
info = connection.info
puts "Vendor: #{info[:vendor_name]}"
puts "Driver: #{info[:driver_name]}"
end
end
We can also query for tables and columns in the database. This gives a nested structure describing all the catalogs, schemas, tables, and columns:
require "adbc"
ADBC::Database.open(driver: "sqlite",
uri: ":memory:") do |database|
database.connect do |connection|
# Create a sample table first
connection.query("CREATE TEMPORARY TABLE sample (ints INTEGER, strs TEXT)")
# Get database objects
objects = connection.get_objects(depth: :all)
catalog = objects.raw_records[1]
schema = catalog[1][0]
tables = schema["db_schema_tables"]
puts "Table: #{tables[0]["table_name"]}"
columns = tables[0]["table_columns"]
puts "Columns: #{columns.map { |c| c["column_name"] }.join(", ")}"
end
end
Next Steps¶
See the drivers to see which databases are supported
Explore more examples in the adbc-quickstarts repository
Explore the Ruby source code for additional examples