Skip to content

Commit

Permalink
Handle insert/update/delete responses in query_many (#194)
Browse files Browse the repository at this point in the history
  • Loading branch information
greg-rychlewski authored Aug 20, 2024
1 parent 1f370f7 commit 128f350
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 69 deletions.
122 changes: 53 additions & 69 deletions lib/myxql/connection.ex
Original file line number Diff line number Diff line change
Expand Up @@ -275,80 +275,25 @@ defmodule MyXQL.Connection do

## Internals

defp result(
{:ok,
ok_packet(
last_insert_id: last_insert_id,
affected_rows: affected_rows,
status_flags: status_flags,
num_warnings: num_warnings
)},
query,
state
) do
result = %Result{
connection_id: state.client.connection_id,
last_insert_id: last_insert_id,
num_rows: affected_rows,
num_warnings: num_warnings
}

{:ok, query, result, put_status(state, status_flags)}
defp result({:ok, ok_packet(status_flags: status_flags) = result}, query, state) do
{:ok, query, format_result(result, state), put_status(state, status_flags)}
end

defp result(
{:ok,
resultset(
column_defs: column_defs,
num_rows: num_rows,
rows: rows,
status_flags: status_flags,
num_warnings: num_warnings
)},
query,
state
) do
columns = Enum.map(column_defs, &elem(&1, 1))

result = %Result{
connection_id: state.client.connection_id,
columns: columns,
num_rows: num_rows,
rows: rows,
num_warnings: num_warnings
}

{:ok, query, result, put_status(state, status_flags)}
defp result({:ok, resultset(status_flags: status_flags) = result}, query, state) do
{:ok, query, format_result(result, state), put_status(state, status_flags)}
end

defp result({:ok, resultsets}, query, state) when is_list(resultsets) do
defp result({:ok, results}, query, state) when is_list(results) do
{results, status_flags} =
Enum.reduce(resultsets, {[], nil}, fn resultset, {results, newest_status_flags} ->
resultset(
column_defs: column_defs,
num_rows: num_rows,
rows: rows,
status_flags: status_flags,
num_warnings: num_warnings
) = resultset

columns = Enum.map(column_defs, &elem(&1, 1))

result = %Result{
connection_id: state.client.connection_id,
columns: columns,
num_rows: num_rows,
rows: rows,
num_warnings: num_warnings
}

# Keep status flags from the last query. The resultsets
# are given to this function in reverse order, so it is the first one.
if newest_status_flags do
{[result | results], newest_status_flags}
else
{[result | results], status_flags}
end
Enum.reduce(results, {[], nil}, fn
result, {results, latest_status_flags} ->
# Keep status flags from the last query. The results are given
# to this function in reverse order, so it is the first one.
if latest_status_flags do
{[format_result(result, state) | results], latest_status_flags}
else
{[format_result(result, state) | results], status_flags(result)}
end
end)

{:ok, query, results, put_status(state, status_flags)}
Expand Down Expand Up @@ -377,6 +322,45 @@ defmodule MyXQL.Connection do
{:error, %DBConnection.ConnectionError{message: message}}
end

defp format_result(
ok_packet(
last_insert_id: last_insert_id,
affected_rows: affected_rows,
num_warnings: num_warnings
),
state
) do
%Result{
connection_id: state.client.connection_id,
last_insert_id: last_insert_id,
num_rows: affected_rows,
num_warnings: num_warnings
}
end

defp format_result(
resultset(
column_defs: column_defs,
num_rows: num_rows,
rows: rows,
num_warnings: num_warnings
),
state
) do
columns = Enum.map(column_defs, &column_def(&1, :name))

%Result{
connection_id: state.client.connection_id,
columns: columns,
num_rows: num_rows,
rows: rows,
num_warnings: num_warnings
}
end

defp status_flags(ok_packet(status_flags: status_flags)), do: status_flags
defp status_flags(resultset(status_flags: status_flags)), do: status_flags

defp error(reason, %{statement: statement}, state) do
error(reason, statement, state)
end
Expand Down
13 changes: 13 additions & 0 deletions test/myxql_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,19 @@ defmodule MyXQLTest do

assert {:ok, [%MyXQL.Result{rows: [[1]]}]} =
MyXQL.query_many(c.conn, "SELECT 1;", [], query_type: :text)

assert {:ok, [%MyXQL.Result{num_rows: 1, columns: nil}]} =
MyXQL.query_many(c.conn, "INSERT INTO integers VALUES (1);", [], query_type: :text)

assert {:ok, [%MyXQL.Result{num_rows: 0, columns: nil}]} =
MyXQL.query_many(c.conn, "UPDATE integers SET x = x + 1 WHERE x = 0;", [],
query_type: :text
)

assert {:ok, [%MyXQL.Result{num_rows: 1, columns: nil}]} =
MyXQL.query_many(c.conn, "DELETE FROM integers WHERE x = 1;", [],
query_type: :text
)
end

test "query_many!/4 with text", c do
Expand Down

0 comments on commit 128f350

Please sign in to comment.