elixir-explorer / adbc

Apache Arrow ADBC bindings for Elixir
https://arrow.apache.org/adbc/
Apache License 2.0
50 stars 16 forks source link

expose more APIs #64

Closed cocoa-xu closed 6 months ago

cocoa-xu commented 6 months ago

Based on the design of ADBC, we probably have to expose more APIs, in particular these {get,set}_option functions. This PR added the following functions

Adbc.Database.get_option/2
Adbc.Database.set_option/3
Adbc.Connection.get_option/2
Adbc.Connection.set_option/3
Adbc.Connection.query_with_options/4
Adbc.Connection.query_with_options!/4

Adbc.Connection.query_with_options/4 will call Adbc.Nif.adbc_statement_set_option/3 in create_statement. Users can now send query with statement options using:

db = start_supervised!({Adbc.Database, driver: :some_driver})
conn = start_supervised!({Connection, database: db})

# with parameters
query_result = Connection.query_with_options(conn, 
  "SOME SQL STATEMENT BIND WITH ?", 
  ["PARAMETERS"],
  statement_option_a: "value for a",
  statement_option_b: "value for b",
)

# without parameters
query_result = Connection.query_with_options(conn, 
  "SOME SQL STATEMENT",
  statement_option_a: "value for a",
  statement_option_b: "value for b",
)
josevalim commented 6 months ago

Looks great to me I would just nitpick on the function names:

get_string_option
get_float_option
get_integer_option
get_binary_option

Similar for set. Those would align with Elixir naming and conventions. :) Thank you!

cocoa-xu commented 6 months ago

Looks great to me I would just nitpick on the function names:

get_string_option
get_float_option
get_integer_option
get_binary_option

Similar for set. Those would align with Elixir naming and conventions. :) Thank you!

No problem, I'll update these names and fix the test in test/adbc_connection_test.exs:96, and we should be ready to merge it!

cocoa-xu commented 6 months ago

I've done renaming these functions, but I'm not sure if we should leave Adbc.{Database,Connection}.set_option/3 because we can pattern match the value in Adbc.Helper.set_option/4.

It could be convenient maybe... What do you think?

josevalim commented 6 months ago

I've done renaming these functions, but I'm not sure if we should leave Adbc.{Database,Connection}.set_option/3 because we can pattern match the value in Adbc.Helper.set_option/4.

Actually, please ignore both of my comments above (I have deleted them).

I think keeping only set_option would be nice, and we use {:binary ...} (similar to what you did) to handle binaries. This keeps the API surface smaller and also works nicely with our existing keyword API that we already have today (when starting the connection/database).

However, I don't think we can apply this to get_option, can we? In that case, my suggestion for now would be:

cocoa-xu commented 6 months ago

Got it :) I also thought that this would be the better way (although the user may have to explicitly use {:binary, data} if they want to set a bytes type option).

cocoa-xu commented 6 months ago

I refactored it a bit so we now have less repetition in both Elixir and C++.

cocoa-xu commented 6 months ago

I tested it with explorer, and it seems that we're okay! (Although we will need to add statement options to Explorer.DataFrame.from_query)