From aba20e11bc083c1ecc8f88a683f09a8dab2e06ef Mon Sep 17 00:00:00 2001 From: Steven Blowers Date: Thu, 24 Aug 2017 08:59:09 +0100 Subject: [PATCH 1/4] update db_connection dep --- mix.exs | 2 +- mix.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mix.exs b/mix.exs index 8ad26e8..ea0711b 100644 --- a/mix.exs +++ b/mix.exs @@ -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}, diff --git a/mix.lock b/mix.lock index 7ebdd50..f8cbdf2 100644 --- a/mix.lock +++ b/mix.lock @@ -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]}]}, From ada1eb7f72c2ec842a676f3ec1b635e9f5e8b185 Mon Sep 17 00:00:00 2001 From: Steven Blowers Date: Thu, 24 Aug 2017 09:05:19 +0100 Subject: [PATCH 2/4] update typespec for handle funcs --- lib/mssqlex/protocol.ex | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/mssqlex/protocol.ex b/lib/mssqlex/protocol.ex index c5ba59c..99af910 100644 --- a/lib/mssqlex/protocol.ex +++ b/lib/mssqlex/protocol.ex @@ -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) @@ -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 @@ -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 From 2bfc31cefc44df2d59be39b75ff66d3f6fd57c92 Mon Sep 17 00:00:00 2001 From: Steven Blowers Date: Thu, 24 Aug 2017 09:16:19 +0100 Subject: [PATCH 3/4] doing update for transactions --- lib/mssqlex/protocol.ex | 49 +++++++++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 12 deletions(-) diff --git a/lib/mssqlex/protocol.ex b/lib/mssqlex/protocol.ex index 99af910..43bbd4c 100644 --- a/lib/mssqlex/protocol.ex +++ b/lib/mssqlex/protocol.ex @@ -143,25 +143,50 @@ 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 From 9cee8944fa38f92cc2e000048fff232b8f5a1f75 Mon Sep 17 00:00:00 2001 From: Steven Blowers Date: Thu, 24 Aug 2017 09:27:20 +0100 Subject: [PATCH 4/4] doing update for savepoints --- lib/mssqlex/protocol.ex | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/lib/mssqlex/protocol.ex b/lib/mssqlex/protocol.ex index 43bbd4c..eaaad64 100644 --- a/lib/mssqlex/protocol.ex +++ b/lib/mssqlex/protocol.ex @@ -191,23 +191,34 @@ defmodule Mssqlex.Protocol do 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