Skip to content

Commit

Permalink
Merge 9cee894 into 2aa5e2e
Browse files Browse the repository at this point in the history
  • Loading branch information
Steven Blowers committed Aug 24, 2017
2 parents 2aa5e2e + 9cee894 commit 33c3071
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 28 deletions.
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

0 comments on commit 33c3071

Please sign in to comment.