/
adbc.ex
138 lines (95 loc) · 4.11 KB
/
adbc.ex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
defmodule Adbc do
@moduledoc """
Bindings for Arrow Database Connectivity (ADBC).
Adbc provides a standard database interface using the
Apache Arrow format.
## Installation
First, add `:adbc` as a dependency in your `mix.exs`:
{:adbc, "~> 0.1"}
Now, in your config/config.exs, configure the drivers you
are going to use:
config :adbc, :drivers, [:sqlite]
If you are using a notebook or scripting, you can also use
`Adbc.download_driver!/1` to dynamically download one.
Then start the database and the relevant connection processes
in your supervision tree:
children = [
{Adbc.Database,
driver: :sqlite,
process_options: [name: MyApp.DB]},
{Adbc.Connection,
database: MyApp.DB,
process_options: [name: MyApp.Conn]}
]
Supervisor.start_link(children, strategy: :one_for_one)
In a notebook, the above would look like this:
db = Kino.start_child!({Adbc.Database, driver: :sqlite})
conn = Kino.start_child!({Adbc.Connection, database: db})
And now you can make queries with:
# For named connections
{:ok, _} = Adbc.Connection.query(MyApp.Conn, "SELECT 123")
# When using the conn PID directly
{:ok, _} = Adbc.Connection.query(conn, "SELECT 123")
## Supported drivers
Below we list all drivers supported out of the box. You may also
give the full path to a driver in the `:driver` option to load other
existing drivers.
### DuckDB
The DuckDB driver provides access to in-memory DuckDB databases.
#### Examples
{Adbc.Database, driver: :duckdb}
### PostgreSQL
The PostgreSQL driver provides access to any database that supports
the PostgreSQL wire format. It is implemented as a wrapper around
`libpq`.
#### Examples
{Adbc.Database, driver: :postgresql, uri: "postgresql://postgres@localhost"}
You must pass the `:uri` option using Postgres'
[connection URI](https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING):
### Sqlite
The SQLite driver provides access to SQLite databases.
#### Examples
{Adbc.Database, driver: :sqlite, uri: ":memory:"}
{Adbc.Database, driver: :sqlite, uri: "./db/my.db"}
{Adbc.Database, driver: :sqlite, uri: "file:/path/to/file/in/disk.db"}
The `:uri` option should be, ":memory:", a filename or
[URI filename](https://www.sqlite.org/c3ref/open.html#urifilenamesinsqlite3open).
If omitted, it will default to an in-memory database, but
one that is shared across all connections.
### Snowflake
The Snowflake driver provides access to Snowflake Database Warehouses.
#### Examples
{Adbc.Database, driver: :snowflake, uri: "..."}
The Snowflake URI should be of one of the following formats:
user[:password]@account/database/schema[?param1=value1¶mN=valueN]
user[:password]@account/database[?param1=value1¶mN=valueN]
user[:password]@host:port/database/schema?account=user_account[¶m1=value1¶mN=valueN]
host:port/database/schema?account=user_account[¶m1=value1¶mN=valueN]
The first two are the most recommended formats. The schema, database and parameters are optional.
See [Account identifiers](https://docs.snowflake.com/en/user-guide/admin-account-identifier) for more information.
"""
@doc """
Downloads a driver.
See `Adbc` module doc for all supports drivers.
It returns `:ok` or `{:error, binary}`.
"""
@spec download_driver(atom, keyword) :: :ok | {:error, binary}
def download_driver(driver, opts \\ []) when is_atom(driver) and is_list(opts) do
Adbc.Driver.download(driver, opts)
end
@doc """
Downloads a driver and raises in case of errors.
See `Adbc` module doc for all supports drivers.
It returns `:ok`.
"""
@spec download_driver!(atom, keyword) :: :ok
def download_driver!(driver, opts \\ []) when is_atom(driver) and is_list(opts) do
case download_driver(driver, opts) do
:ok -> :ok
{:error, reason} -> raise "could not download Adbc driver for #{driver}: " <> reason
end
end
end
for driver <- Application.compile_env(:adbc, :drivers, []) do
Adbc.download_driver!(driver)
end