Skip to content
New issue

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

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

Already on GitHub? # to your account

Dbconnection update #16

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 65 additions & 26 deletions lib/mssqlex/protocol.ex
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,9 @@ defmodule Mssqlex.Protocol do

@doc false
@spec handle_begin(opts :: Keyword.t, state) ::
{:ok, result, state}
| {:error | :disconnect, Exception.t, state}
{:ok, result, state} |
{DBConnection.status, state} |
{:error | :disconnect, Exception.t, state}
def handle_begin(opts, state) do
case Keyword.get(opts, :mode, :transaction) do
:transaction -> handle_transaction(:begin, opts, state)
Expand All @@ -119,6 +120,7 @@ defmodule Mssqlex.Protocol do
@doc false
@spec handle_commit(opts :: Keyword.t, state) ::
{:ok, result, state} |
{DBConnection.status, state} |
{:error | :disconnect, Exception.t, state}
def handle_commit(opts, state) do
case Keyword.get(opts, :mode, :transaction) do
Expand All @@ -130,6 +132,7 @@ defmodule Mssqlex.Protocol do
@doc false
@spec handle_rollback(opts :: Keyword.t, state) ::
{:ok, result, state} |
{DBConnection.status, state} |
{:error | :disconnect, Exception.t, state}
def handle_rollback(opts, state) do
case Keyword.get(opts, :mode, :transaction) do
Expand All @@ -140,46 +143,82 @@ defmodule Mssqlex.Protocol do

defp handle_transaction(:begin, _opts, state) do
case state.mssql do
:idle -> {:ok, %Result{num_rows: 0}, %{state | mssql: :transaction}}
:transaction -> {:error,
%Mssqlex.Error{message: "Already in transaction"},
state}
:auto_commit -> {:error,
%Mssqlex.Error{message: "Transactions not allowed in autocommit mode"},
state}
:idle ->
{:ok, %Result{num_rows: 0}, %{state | mssql: :transaction}}
:transaction ->
{:transaction, state}
:auto_commit ->
{:error, %Mssqlex.Error{message: "Transactions not allowed in autocommit mode"}, state}
end
end
defp handle_transaction(:commit, _opts, state) do
case ODBC.commit(state.pid) do
:ok -> {:ok, %Result{}, %{state | mssql: :idle}}
{:error, reason} -> {:error, reason, state}
case state.mssql do
:idle ->
commit_transaction(state) # Because everything is a transaction with ODBC
:transaction ->
commit_transaction(state)
:auto_commit ->
{:error, %Mssqlex.Error{message: "Transactions not allowed in autocommit mode"}, state}
end
end
defp handle_transaction(:rollback, _opts, state) do
case state.mssql do
:idle ->
{:idle, state}
:transaction ->
rollback_transaction(state)
:auto_commit ->
{:error, %Mssqlex.Error{message: "Transactions not allowed in autocommit mode"}, state}
end
end

defp commit_transaction(state) do
case ODBC.commit(state.pid) do
:ok ->
{:ok, %Result{}, %{state | mssql: :idle}}
{:error, reason} ->
{:error, reason, state}
end
end

defp rollback_transaction(state) do
case ODBC.rollback(state.pid) do
:ok -> {:ok, %Result{}, %{state | mssql: :idle}}
{:error, reason} -> {:disconnect, reason, state}
:ok ->
{:ok, %Result{}, %{state | mssql: :idle}}
{:error, reason} ->
{:disconnect, reason, state}
end
end

defp handle_savepoint(:begin, opts, state) do
if state.mssql == :autocommit do
{:error,
%Mssqlex.Error{message: "savepoint not allowed in autocommit mode"},
state}
else
handle_execute(
%Mssqlex.Query{name: "", statement: "SAVE TRANSACTION mssqlex_savepoint"},
[], opts, state)
case state.mssql do
:idle ->
handle_execute(%Mssqlex.Query{name: "", statement: "SAVE TRANSACTION mssqlex_savepoint"}, [], opts, state) # Because everything is a transaction with ODBC
:transaction ->
handle_execute(%Mssqlex.Query{name: "", statement: "SAVE TRANSACTION mssqlex_savepoint"}, [], opts, state)
:autocommit ->
{:error, %Mssqlex.Error{message: "savepoint not allowed in autocommit mode"}, state}
end
end
defp handle_savepoint(:commit, _opts, state) do
{:ok, %Result{}, state}
case state.mssql do
:idle ->
{:ok, %Result{}, state}
:transaction ->
{:ok, %Result{}, state}
:autocommit ->
{:error, %Mssqlex.Error{message: "savepoint not allowed in autocommit mode"}, state}
end
end
defp handle_savepoint(:rollback, opts, state) do
handle_execute(
%Mssqlex.Query{name: "", statement: "ROLLBACK TRANSACTION mssqlex_savepoint"},
[], opts, state)
case state.mssql do
:idle ->
handle_execute(%Mssqlex.Query{name: "", statement: "ROLLBACK TRANSACTION mssqlex_savepoint"}, [], opts, state) # Because everything is a transaction with ODBC
:transaction ->
handle_execute(%Mssqlex.Query{name: "", statement: "ROLLBACK TRANSACTION mssqlex_savepoint"}, [], opts, state)
:autocommit ->
{:error, %Mssqlex.Error{message: "savepoint not allowed in autocommit mode"}, state}
end
end

@doc false
Expand Down
2 changes: 1 addition & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ defmodule Mssqlex.Mixfile do
end

defp deps do
[{:db_connection, "~> 1.1"},
[{:db_connection, "~> 1.1", github: "elixir-ecto/db_connection", ref: "f2619f720e1fd377a02aacbbeb98cabe23642331"},
{:decimal, "~> 1.0"},
{:ex_doc, "~> 0.15", only: :dev, runtime: false},
{:excoveralls, "~> 0.6", only: :test},
Expand Down
2 changes: 1 addition & 1 deletion mix.lock
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
%{"certifi": {:hex, :certifi, "1.0.0", "1c787a85b1855ba354f0b8920392c19aa1d06b0ee1362f9141279620a5be2039", [:rebar3], []},
"connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], []},
"db_connection": {:hex, :db_connection, "1.1.1", "f9d246e8f65b9490945cf7360875eee18fcec9a0115207603215eb1fd94c39ef", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, optional: false]}, {:poolboy, "~> 1.5", [hex: :poolboy, optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, optional: true]}]},
"db_connection": {:git, "https://github.com/elixir-ecto/db_connection.git", "f2619f720e1fd377a02aacbbeb98cabe23642331", [ref: "f2619f720e1fd377a02aacbbeb98cabe23642331"]},
"decimal": {:hex, :decimal, "1.3.1", "157b3cedb2bfcb5359372a7766dd7a41091ad34578296e951f58a946fcab49c6", [:mix], []},
"earmark": {:hex, :earmark, "1.1.1", "433136b7f2e99cde88b745b3a0cfc3fbc81fe58b918a09b40fce7f00db4d8187", [:mix], []},
"ex_doc": {:hex, :ex_doc, "0.15.0", "e73333785eef3488cf9144a6e847d3d647e67d02bd6fdac500687854dd5c599f", [:mix], [{:earmark, "~> 1.1", [hex: :earmark, optional: false]}]},
Expand Down