From 0ea8066f0f059486fe61248cda933b968bb99ff7 Mon Sep 17 00:00:00 2001 From: tautQD Date: Thu, 10 Oct 2024 16:45:15 +0200 Subject: [PATCH] Adding appender/3 with conn, schema_name, table_name --- c_src/nif.cpp | 46 +++++++++++++++++++++++++++++++------- lib/nif.ex | 3 +++ test/nif/appender_test.exs | 28 +++++++++++++++++++++++ 3 files changed, 69 insertions(+), 8 deletions(-) diff --git a/c_src/nif.cpp b/c_src/nif.cpp index 17b0538..c7c1514 100644 --- a/c_src/nif.cpp +++ b/c_src/nif.cpp @@ -346,21 +346,50 @@ fetch_all(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { static ERL_NIF_TERM appender(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { + if (argc < 2 || argc > 3) { + return enif_make_badarg(env); + } + erlang_resource* connres = nullptr; - if(!enif_get_resource(env, argv[0], connection_nif_type, (void**)&connres)) + if (!enif_get_resource(env, argv[0], connection_nif_type, (void**)&connres)) { return enif_make_badarg(env); + } ErlNifBinary binary_table_name; - if (!enif_inspect_binary(env, argv[1], &binary_table_name)) - return enif_make_badarg(env); + if (argc == 2) { + // Only table name is provided + if (!enif_inspect_binary(env, argv[1], &binary_table_name)) { + return enif_make_badarg(env); + } - std::string table_name((const char*)binary_table_name.data, binary_table_name.size); + std::string table_name((const char*)binary_table_name.data, binary_table_name.size); - if (!connres->data->TableInfo(table_name)) - return nif::make_error_tuple(env, "Table '" + table_name + "' could not be found"); + if (!connres->data->TableInfo(table_name)) + return nif::make_error_tuple(env, "Table '" + table_name + "' could not be found"); - ErlangResourceBuilder resource_builder(appender_nif_type, *connres->data, table_name); - return nif::make_ok_tuple(env, resource_builder.make_and_release_resource(env)); + ErlangResourceBuilder resource_builder(appender_nif_type, *connres->data, table_name); + return nif::make_ok_tuple(env, resource_builder.make_and_release_resource(env)); + } else { + ErlNifBinary binary_schema_name; + + // Schema name and table name are provided + if (!enif_inspect_binary(env, argv[1], &binary_schema_name)) { + return enif_make_badarg(env); + } + if (!enif_inspect_binary(env, argv[2], &binary_table_name)) { + return enif_make_badarg(env); + } + + std::string schema_name((const char*)binary_schema_name.data, binary_schema_name.size); + std::string table_name((const char*)binary_table_name.data, binary_table_name.size); + + if (!connres->data->TableInfo(schema_name, table_name)) { + return nif::make_error_tuple(env, "Table '" + schema_name + "." + table_name + "' could not be found"); + } + + ErlangResourceBuilder resource_builder(appender_nif_type, *connres->data, schema_name, table_name); + return nif::make_ok_tuple(env, resource_builder.make_and_release_resource(env)); + } } static ERL_NIF_TERM @@ -599,6 +628,7 @@ static ErlNifFunc nif_funcs[] = { {"fetch_chunk", 1, fetch_chunk, ERL_NIF_DIRTY_JOB_IO_BOUND}, {"fetch_all", 1, fetch_all, ERL_NIF_DIRTY_JOB_IO_BOUND}, {"appender", 2, appender, ERL_NIF_DIRTY_JOB_IO_BOUND}, + {"appender", 3, appender, ERL_NIF_DIRTY_JOB_IO_BOUND}, {"appender_add_row", 2, appender_add_row, ERL_NIF_DIRTY_JOB_IO_BOUND}, {"appender_add_rows", 2, appender_add_rows, ERL_NIF_DIRTY_JOB_IO_BOUND}, {"appender_flush", 1, appender_flush, ERL_NIF_DIRTY_JOB_IO_BOUND}, diff --git a/lib/nif.ex b/lib/nif.ex index f765145..1e2ebe7 100644 --- a/lib/nif.ex +++ b/lib/nif.ex @@ -46,6 +46,9 @@ defmodule Duckdbex.NIF do @spec appender(connection(), binary()) :: {:ok, appender()} | {:error, reason()} def appender(_connection, _table_name), do: :erlang.nif_error(:not_loaded) + @spec appender(connection(), binary(), binary()) :: {:ok, appender()} | {:error, reason()} + def appender(_connection, _schema_name, _table_name), do: :erlang.nif_error(:not_loaded) + @spec appender_add_row(appender(), list()) :: :ok | {:error, reason()} def appender_add_row(_appender, _row), do: :erlang.nif_error(:not_loaded) diff --git a/test/nif/appender_test.exs b/test/nif/appender_test.exs index db6a368..2b4608a 100644 --- a/test/nif/appender_test.exs +++ b/test/nif/appender_test.exs @@ -380,4 +380,32 @@ defmodule Duckdbex.Nif.AppenderTest do assert ^result = Duckdbex.NIF.fetch_all(r) end + + test "appender schema table", %{conn: conn} do + {:ok, _} = + Duckdbex.NIF.query(conn, """ + create schema schema_1; + """) + + {:ok, _} = + Duckdbex.NIF.query(conn, """ + CREATE TABLE schema_1.appender_test_1( + bigint BIGINT, + ); + """) + + assert {:ok, appender} = Duckdbex.NIF.appender(conn, "schema_1", "appender_test_1") + + assert :ok = + Duckdbex.NIF.appender_add_row(appender, [ + 123, + ]) + + assert :ok = Duckdbex.NIF.appender_flush(appender) + + {:ok, r} = Duckdbex.NIF.query(conn, "SELECT * FROM schema_1.appender_test_1;") + + assert [[123]] = + Duckdbex.NIF.fetch_all(r) + end end