From 325fa9d4aec5184e97347eabedd7a07fe42702c0 Mon Sep 17 00:00:00 2001 From: "Brian J. Cardiff" Date: Mon, 29 Aug 2016 01:23:20 -0300 Subject: [PATCH] ensure the connection is released after exec avoid releasing connection twice on exec. avoid releasing connection when QueryMethod#query is blockless called. --- spec/dummy_driver.cr | 1 + spec/dummy_driver_spec.cr | 8 ++++++++ spec/statement_spec.cr | 9 +++++++++ src/db/query_methods.cr | 16 +++------------- src/db/statement.cr | 4 ++-- 5 files changed, 23 insertions(+), 15 deletions(-) diff --git a/spec/dummy_driver.cr b/spec/dummy_driver.cr index aa05f83..ceaf38e 100644 --- a/spec/dummy_driver.cr +++ b/spec/dummy_driver.cr @@ -49,6 +49,7 @@ class DummyDriver < DB::Driver protected def perform_exec(args : Enumerable) set_params args + raise "forced exception due to query" if @query == "raise" DB::ExecResult.new 0i64, 0_i64 end diff --git a/spec/dummy_driver_spec.cr b/spec/dummy_driver_spec.cr index 97a47da..e24af78 100644 --- a/spec/dummy_driver_spec.cr +++ b/spec/dummy_driver_spec.cr @@ -237,6 +237,14 @@ describe DummyDriver do end end + it "should raise executing raise query" do + with_dummy do |db| + expect_raises do + db.exec "raise" + end + end + end + {% for value in [1, 1_i64, "hello", 1.5, 1.5_f32] %} it "should set positional arguments for {{value.id}}" do with_dummy do |db| diff --git a/spec/statement_spec.cr b/spec/statement_spec.cr index 9621ed5..196c2ed 100644 --- a/spec/statement_spec.cr +++ b/spec/statement_spec.cr @@ -118,4 +118,13 @@ describe DB::Statement do rs.statement.should be(stmt) end end + + it "connection should be released if error occurs during exec" do + with_dummy do |db| + expect_raises do + db.exec "raise" + end + db.@in_pool.should be_true + end + end end diff --git a/src/db/query_methods.cr b/src/db/query_methods.cr index 572ff20..f41596b 100644 --- a/src/db/query_methods.cr +++ b/src/db/query_methods.cr @@ -35,7 +35,7 @@ module DB # end # ``` def query(query, *args) - prepare query, &.query(*args) + prepare(query).query(*args) end # Executes a *query* and yields a `ResultSet` with the results. @@ -200,23 +200,13 @@ module DB # Performs the `query` and returns an `ExecResult` def exec(query, *args) - prepare query, &.exec(*args) + prepare(query).exec(*args) end # Performs the `query` and returns a single scalar value # puts db.scalar("SELECT MAX(name)").as(String) # => (a String) def scalar(query, *args) - prepare query, &.scalar(*args) - end - - private def prepare(query) - stm = prepare(query) - begin - yield stm - rescue ex - stm.release_connection - raise ex - end + prepare(query).scalar(*args) end end end diff --git a/src/db/statement.cr b/src/db/statement.cr index 55120b4..45a6997 100644 --- a/src/db/statement.cr +++ b/src/db/statement.cr @@ -74,9 +74,9 @@ module DB end private def perform_exec_and_release(args : Enumerable) : ExecResult - res = perform_exec(args) + return perform_exec(args) + ensure release_connection - res end protected abstract def perform_query(args : Enumerable) : ResultSet