diff --git a/lib/adbc_arrow_array_stream.ex b/lib/adbc_arrow_array_stream.ex deleted file mode 100644 index 05ecb97..0000000 --- a/lib/adbc_arrow_array_stream.ex +++ /dev/null @@ -1,32 +0,0 @@ -defmodule Adbc.ArrowArrayStream do - @moduledoc """ - Documentation for `Adbc.ArrowArrayStream`. - """ - - @typedoc """ - - **reference**: `reference`. - - The underlying erlang resource variable. - - """ - @type t :: %__MODULE__{ - reference: reference() - } - defstruct [:reference] - alias __MODULE__, as: T - - @spec get_pointer(Adbc.ArrowArrayStream.t()) :: non_neg_integer() - def get_pointer(self = %T{}) do - Adbc.Nif.adbc_arrow_array_stream_get_pointer(self.reference) - end - - @spec next(Adbc.ArrowArrayStream.t()) :: term() | {:error, String.t()} - def next(self = %T{}) do - Adbc.Nif.adbc_arrow_array_stream_next(self.reference) - end - - @spec release(Adbc.ArrowArrayStream.t()) :: :ok | {:error, String.t()} - def release(self = %T{}) do - Adbc.Nif.adbc_arrow_array_stream_release(self.reference) - end -end diff --git a/lib/adbc_connection.ex b/lib/adbc_connection.ex index a665933..a445ebe 100644 --- a/lib/adbc_connection.ex +++ b/lib/adbc_connection.ex @@ -3,6 +3,8 @@ defmodule Adbc.Connection do Documentation for `Adbc.Connection`. """ + # TODO: Add prepared queries + @type t :: GenServer.server() @type result_set :: map @@ -242,6 +244,7 @@ defmodule Adbc.Connection do fun.(stream_ref) after # TODO: force release the arrow array stream on the server + # Adbc.Nif.adbc_arrow_array_stream_release(stream_ref) GenServer.cast(conn, {:unlock, unlock_ref}) end diff --git a/lib/adbc_statement.ex b/lib/adbc_statement.ex deleted file mode 100644 index f9eb369..0000000 --- a/lib/adbc_statement.ex +++ /dev/null @@ -1,160 +0,0 @@ -defmodule Adbc.Statement do - @typedoc """ - - **reference**: `reference`. - - The underlying erlang resource variable. - - """ - @type t :: %__MODULE__{ - reference: reference() - } - defstruct [:reference] - alias __MODULE__, as: T - alias Adbc.ArrowArrayStream - - @doc """ - Create a new statement for a given connection. - """ - @doc group: :adbc_statement - @spec new(Adbc.Connection.t()) :: {:ok, Adbc.Statement.t()} | Adbc.Error.adbc_error() - def new(connection) do - case Adbc.Nif.adbc_statement_new(connection.reference) do - {:ok, ref} -> - {:ok, %T{reference: ref}} - - {:error, {reason, code, sql_state}} -> - {:error, {reason, code, sql_state}} - end - end - - @doc """ - Destroy a statement. - - ##### Positional Parameter - - - `self`: `Adbc.Statement.t()` - - The statement to release. - - """ - @doc group: :adbc_statement - @spec release(Adbc.Statement.t()) :: :ok | Adbc.Error.adbc_error() - def release(self = %T{}) do - Adbc.Nif.adbc_statement_release(self.reference) - end - - @doc """ - Execute a statement and get the results. - - This invalidates any prior result sets. - - ##### Positional Parameter - - - `self`: `Adbc.Statement.t()` - - The statement to execute. - """ - @doc group: :adbc_statement - @spec execute_query(Adbc.Statement.t()) :: - {:ok, Adbc.ArrowArrayStream.t(), integer()} | Adbc.Error.adbc_error() - def execute_query(self = %T{}) do - case Adbc.Nif.adbc_statement_execute_query(self.reference) do - {:ok, array_stream_ref, rows_affected} -> - {:ok, %ArrowArrayStream{reference: array_stream_ref}, rows_affected} - - {:error, {reason, code, sql_state}} -> - {:error, {reason, code, sql_state}} - end - end - - @doc """ - Turn this statement into a prepared statement to be - executed multiple times. - - This invalidates any prior result sets. - - ##### Positional Parameter - - - `self`: `Adbc.Statement.t()` - - A valid `Adbc.Statement.t()` - """ - @doc group: :adbc_statement - @spec prepare(Adbc.Statement.t()) :: :ok | Adbc.Error.adbc_error() - def prepare(self = %T{}) do - Adbc.Nif.adbc_statement_prepare(self.reference) - end - - @doc """ - Set the SQL query to execute. - - The query can then be executed with `Adbc.Statement.execute/1`. For - queries expected to be executed repeatedly, `Adbc.Statement.prepare/1` - the statement first. - - ##### Positional Parameter - - - `self`: `Adbc.Statement.t()` - - The statement. - - - `query`: `String.t()` - - The query to execute. - - """ - @doc group: :adbc_statement_sql - @spec set_sql_query(Adbc.Statement.t(), String.t()) :: :ok | Adbc.Error.adbc_error() - def set_sql_query(self = %T{}, query) when is_binary(query) do - Adbc.Nif.adbc_statement_set_sql_query(self.reference, query) - end - - @doc """ - Bind Arrow data. This can be used for bulk inserts or prepared statements. - - ##### Positional Parameter - - - `self`: `Adbc.Statement.t()` - - The statement. - - - `values`: `Adbc.ArrowArray.t()` - - The values to bind. The driver will call the release callback itself, - although it may not do this until the statement is released. - - - `schema`: `Adbc.ArrowSchema.t()` - - The schema of the values to bind. - - """ - @doc group: :adbc_statement - @spec bind(Adbc.Statement.t(), [integer() | float() | String.t() | nil | boolean()]) :: - :ok | Adbc.Error.adbc_error() - def bind(self = %T{}, values) when is_list(values) do - Adbc.Nif.adbc_statement_bind(self.reference, values) - end - - @doc """ - Bind Arrow data. This can be used for bulk inserts or prepared statements. - - ##### Positional Parameter - - - `self`: `Adbc.Statement.t()` - - The statement. - - - `stream`: `Adbc.ArrowArrayStream.t()` - - The values to bind. The driver will call the - release callback itself, although it may not do this until the - statement is released. - - """ - @doc group: :adbc_statement - @spec bind_stream(Adbc.Statement.t(), Adbc.ArrowArrayStream.t()) :: - :ok | Adbc.Error.adbc_error() - def bind_stream(self = %T{}, stream = %ArrowArrayStream{}) do - Adbc.Nif.adbc_statement_bind_stream(self.reference, stream.reference) - end -end diff --git a/test/adbc_connection_test.exs b/test/adbc_connection_test.exs index 393c1fb..6be5b9f 100644 --- a/test/adbc_connection_test.exs +++ b/test/adbc_connection_test.exs @@ -2,7 +2,6 @@ defmodule Adbc.Connection.Test do use ExUnit.Case doctest Adbc.Connection - alias Adbc.ArrowArrayStream alias Adbc.Connection setup do diff --git a/test/adbc_statement_test.exs b/test/adbc_statement_test.exs deleted file mode 100644 index 7f92134..0000000 --- a/test/adbc_statement_test.exs +++ /dev/null @@ -1,119 +0,0 @@ -defmodule Adbc.Statement.Test do - use ExUnit.Case - doctest Adbc.Statement - - alias Adbc.Statement - alias Adbc.ArrowArrayStream - - setup do - db = start_supervised!({Adbc.Database, driver: :sqlite}) - conn = %{reference: :sys.get_state(start_supervised!({Adbc.Connection, database: db})).conn} - %{db: db, conn: conn} - end - - test "new statement and release it", %{conn: conn} do - {:ok, %Statement{} = statement} = Statement.new(conn) - assert is_reference(statement.reference) - assert :ok == Statement.release(statement) - end - - test "release a statement twice should raise an ArgumentError", %{conn: conn} do - {:ok, %Statement{} = statement} = Statement.new(conn) - assert is_reference(statement.reference) - assert :ok == Statement.release(statement) - assert {:error, "invalid state"} == Statement.release(statement) - end - - test "execute statements", %{conn: conn, test: test} do - {:ok, %Statement{} = statement} = Statement.new(conn) - assert is_reference(statement.reference) - assert :ok == Statement.set_sql_query(statement, "CREATE TABLE \"#{test}\" (col)") - {:ok, _stream, row_affected} = Statement.execute_query(statement) - assert row_affected == -1 - - assert :ok == Statement.set_sql_query(statement, "INSERT INTO \"#{test}\" VALUES (42)") - {:ok, _stream, row_affected} = Statement.execute_query(statement) - assert row_affected == -1 - - assert :ok == Statement.set_sql_query(statement, "INSERT INTO \"#{test}\" VALUES (43)") - assert :ok == Statement.prepare(statement) - {:ok, _stream, row_affected} = Statement.execute_query(statement) - assert row_affected == -1 - end - - test "bind statement", %{conn: conn, test: test} do - {:ok, %Statement{} = statement} = Statement.new(conn) - assert is_reference(statement.reference) - assert :ok == Statement.set_sql_query(statement, "CREATE TABLE \"#{test}\" (col)") - {:ok, _stream, row_affected} = Statement.execute_query(statement) - assert row_affected == -1 - - assert :ok == Statement.set_sql_query(statement, "INSERT INTO \"#{test}\" VALUES (?)") - assert :ok == Statement.bind(statement, [42]) - {:ok, _stream, row_affected} = Statement.execute_query(statement) - assert row_affected == -1 - - assert :ok == Statement.set_sql_query(statement, "INSERT INTO \"#{test}\" VALUES (?)") - assert :ok == Statement.bind(statement, [43]) - assert :ok == Statement.prepare(statement) - {:ok, _stream, row_affected} = Statement.execute_query(statement) - assert row_affected == -1 - end - - test "query values", %{conn: conn, test: test} do - {:ok, %Statement{} = statement} = Statement.new(conn) - assert is_reference(statement.reference) - - assert :ok == - Statement.set_sql_query( - statement, - "CREATE TABLE \"#{test}\" (i64 INT, f64 REAL, str TEXT)" - ) - - {:ok, _stream, row_affected} = Statement.execute_query(statement) - assert row_affected == -1 - - assert :ok == Statement.set_sql_query(statement, "INSERT INTO \"#{test}\" VALUES (?,?,?)") - assert :ok == Statement.bind(statement, [42, 42.0, "value = 42"]) - {:ok, _stream, row_affected} = Statement.execute_query(statement) - assert row_affected == -1 - - assert :ok == Statement.set_sql_query(statement, "INSERT INTO \"#{test}\" VALUES (?,?,?)") - assert :ok == Statement.bind(statement, [43, 43.0, "value = 43"]) - # assert :ok == Statement.prepare(statement) - {:ok, _stream, row_affected} = Statement.execute_query(statement) - assert row_affected == -1 - - assert :ok == Statement.set_sql_query(statement, "INSERT INTO \"#{test}\" VALUES (?,?,?)") - assert :ok == Statement.bind(statement, [44, 44.0, "value = 44"]) - # assert :ok == Statement.prepare(statement) - {:ok, _stream, row_affected} = Statement.execute_query(statement) - assert row_affected == -1 - - {:ok, %Statement{} = statement} = Statement.new(conn) - assert :ok == Statement.set_sql_query(statement, "SELECT * FROM \"#{test}\" WHERE i64 > 42") - {:ok, stream, row_affected} = Statement.execute_query(statement) - assert row_affected == -1 - {:ok, next} = ArrowArrayStream.next(stream) - - assert [ - {"i64", [43, 44]}, - {"f64", [43.0, 44.0]}, - {"str", ["value = 43", "value = 44"]} - ] == next - - assert :ok == Statement.set_sql_query(statement, "SELECT * FROM \"#{test}\" WHERE i64 = ?") - assert :ok == Statement.bind(statement, [42]) - {:ok, stream, row_affected} = Statement.execute_query(statement) - assert row_affected == -1 - {:ok, next} = ArrowArrayStream.next(stream) - - assert [ - {"i64", [42]}, - {"f64", [42.0]}, - {"str", ["value = 42"]} - ] == next - - Statement.release(statement) - end -end