diff --git a/spec/database_spec.cr b/spec/database_spec.cr index 2071d27..51a53a3 100644 --- a/spec/database_spec.cr +++ b/spec/database_spec.cr @@ -149,6 +149,28 @@ describe DB::Database do end end + it "should return connection to the pool if prepared statement is unable to be built" do + connection = uninitialized DB::Connection + with_dummy "dummy://localhost:1027?initial_pool_size=1" do |db| + connection = DummyDriver::DummyConnection.connections.first + expect_raises do + db.prepared.exec("syntax error") + end + db.pool.is_available?(connection).should be_true + end + end + + it "should return connection to the pool if unprepared statement is unable to be built" do + connection = uninitialized DB::Connection + with_dummy "dummy://localhost:1027?initial_pool_size=1" do |db| + connection = DummyDriver::DummyConnection.connections.first + expect_raises do + db.unprepared.exec("syntax error") + end + db.pool.is_available?(connection).should be_true + end + end + describe "prepared_statements connection option" do it "defaults to true" do with_dummy "dummy://localhost:1027" do |db| diff --git a/spec/dummy_driver.cr b/spec/dummy_driver.cr index cda056e..b0dcf42 100644 --- a/spec/dummy_driver.cr +++ b/spec/dummy_driver.cr @@ -99,6 +99,7 @@ class DummyDriver < DB::Driver def initialize(connection, @query : String, @prepared : Bool) @params = Hash(Int32 | String, DB::Any).new super(connection) + raise query if query == "syntax error" end protected def perform_query(args : Enumerable) diff --git a/src/db/pool_prepared_statement.cr b/src/db/pool_prepared_statement.cr index d50b240..5a65910 100644 --- a/src/db/pool_prepared_statement.cr +++ b/src/db/pool_prepared_statement.cr @@ -29,12 +29,18 @@ module DB end # builds a statement over a real connection - # the conneciton is registered in `@connections` + # the connection is registered in `@connections` private def build_statement clean_connections conn, existing = @db.checkout_some(@connections) + begin + stmt = conn.prepared.build(@query) + rescue ex + conn.release + raise ex + end @connections << WeakRef.new(conn) unless existing - conn.prepared.build(@query) + stmt end private def clean_connections diff --git a/src/db/pool_unprepared_statement.cr b/src/db/pool_unprepared_statement.cr index 1a120e5..b597e6a 100644 --- a/src/db/pool_unprepared_statement.cr +++ b/src/db/pool_unprepared_statement.cr @@ -15,7 +15,13 @@ module DB # builds a statement over a real connection private def build_statement - @db.pool.checkout.unprepared.build(@query) + conn = @db.pool.checkout + begin + conn.unprepared.build(@query) + rescue ex + conn.release + raise ex + end end end end