Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[AUTO-3289] General improvements, add DBConnection adapter #32

Merged
merged 10 commits into from
Jan 18, 2022

Conversation

pggalaviz
Copy link
Contributor

@pggalaviz pggalaviz commented Nov 16, 2021

This is the first attempt to add DBConnection support.

I tried to keep functionality the same, except for adding an extra function process_result/2 which will return results as current implementation instead of an {:ok, %Result{}} tuple.

See config/test.exs for an example of configuration required, specially pool_size option.

lib/snowflex/db_connection.ex Outdated Show resolved Hide resolved
lib/snowflex/db_connection/protocol.ex Outdated Show resolved Hide resolved

def to_string(%{statement: statement}) do
case statement do
statement when is_binary(statement) -> IO.iodata_to_binary(statement)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it's already a binary, it should be OK to pass through directly.

Suggested change
statement when is_binary(statement) -> IO.iodata_to_binary(statement)
statement when is_binary(statement) -> statement

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In Result.t(), statement is typed as String.t() | nil. If it can be iodata(), I would update the typespec to indicate that. A Query.t() typespec would also be a nice addition here.

columns: Enum.map(columns, &to_string(&1)),
rows: rows,
num_rows: Enum.count(rows)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You'll probably want to set success and statement on the result (ignore if you were already planning to do this 🙂).

lib/snowflex/db_connection/server.ex Show resolved Hide resolved
def disconnect(_err, %{pid: pid}), do: Server.disconnect(pid)

@impl DBConnection
def checkout(state), do: {:ok, state}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if there should be any sort of limit on the maximum number of connections that can be checked out at once? Maybe it doesn't matter 🤷

Copy link
Collaborator

@nickolaich nickolaich left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we only want to use own DbConnection implementation. Was there a plan/discussion about using own Adapter module for Snowflex?

Comment on lines 39 to 43
opts =
Keyword.merge(config,
timeout: @timeout,
connection: connection
)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isn't always override timeout from config with a compile-time @timeout ?

@timeout timeout
@name __MODULE__

def child_spec(_) do
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we ignore child spec input options?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

opts should be provided statically when configuring your connection module with use Snowflake.DBConnection, opt1: _, opt2: _, .... Ignoring the opts in child_spec/1 ensures that the static config in the use macro is always correct, and not accidentally overridden in the supervision tree. I like this approach 👍

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gotcha, thanks

@pggalaviz pggalaviz marked this pull request as ready for review January 12, 2022 20:34
Copy link
Contributor

@superhawk610 superhawk610 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! Just a few small comments, nothing blocking.

end

defp parse_result(columns, rows) do
%Result{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should %Result structs always include statement? If not, it'd be nice to add something to the docs describing when it will/won't be set.

Comment on lines 128 to 142
case worker.param_query(state.pid, query.statement, params, opts) do
{:ok, {:selected, columns, rows}} ->
result = parse_result(columns, rows)
{:ok, query, result, state}

{:ok, {:selected, columns, rows, _}} ->
result = parse_result(columns, rows)
{:ok, query, result, state}

{:ok, result} ->
{:ok, query, result, state}

{:error, reason} ->
{:error, reason, state}
end
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could pull this case out into its own function so you don't have to duplicate it between sql_query and param_query.

Comment on lines 15 to 16
def decode(_query, [], _opts), do: []
def decode(_query, result, _opts), do: result
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These can be combined

Suggested change
def decode(_query, [], _opts), do: []
def decode(_query, result, _opts), do: result
def decode(_query, result, _opts), do: result


def to_string(%{statement: statement}) do
case statement do
statement when is_binary(statement) -> IO.iodata_to_binary(statement)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In Result.t(), statement is typed as String.t() | nil. If it can be iodata(), I would update the typespec to indicate that. A Query.t() typespec would also be a nice addition here.

@Ch4s3 Ch4s3 mentioned this pull request Jan 14, 2022
@Ch4s3 Ch4s3 changed the title [AUTO-3289] WIP - General improvements, add DBConnection adapter [AUTO-3289] General improvements, add DBConnection adapter Jan 18, 2022
@Ch4s3 Ch4s3 merged commit 193c505 into master Jan 18, 2022
@Ch4s3 Ch4s3 deleted the AUTO-3289-general-improvements branch January 18, 2022 16:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants