diff --git a/spec/std/db/dummy_driver.cr b/spec/std/db/dummy_driver.cr index 35f0059..10d925d 100644 --- a/spec/std/db/dummy_driver.cr +++ b/spec/std/db/dummy_driver.cr @@ -21,7 +21,7 @@ class DummyDriver < DB::Driver @@connections.try &.clear end - def prepare(query) + def build_statement(query) DummyStatement.new(self, query) end @@ -30,6 +30,7 @@ class DummyDriver < DB::Driver end protected def do_close + super end end diff --git a/spec/std/db/statement_spec.cr b/spec/std/db/statement_spec.cr index c8cd6a4..a7f729c 100644 --- a/spec/std/db/statement_spec.cr +++ b/spec/std/db/statement_spec.cr @@ -80,4 +80,15 @@ describe DB::Statement do stmt.closed?.should be_false end end + + it "connection should cache statements by query" do + with_dummy do |db| + rs = db.query "1, ?", 2 + stmt = rs.statement + rs.close + + rs = db.query "1, ?", 4 + rs.statement.should be(stmt) + end + end end diff --git a/src/db/connection.cr b/src/db/connection.cr index 38e1707..08c19c7 100644 --- a/src/db/connection.cr +++ b/src/db/connection.cr @@ -9,17 +9,31 @@ module DB # # ### Note to implementors # - # The connection must be initialized in `#initialize` and closed in `#perform_close`. + # The connection must be initialized in `#initialize` and closed in `#do_close`. # - # To allow quering override `#prepare` method in order to return a prepared `Statement`. - # Also override `#last_insert_id` to allow safe access to the last inserted id through this connection. + # Override `#build_statement` method in order to return a prepared `Statement` to allow querying. + # See also `Statement` to define how the statements are executed. # abstract class Connection include Disposable + include QueryMethods + @statements_cache = {} of String => Statement # :nodoc: - abstract def prepare(query) : Statement + def prepare(query) : Statement + stmt = @statements_cache.fetch(query, nil) + if stmt.is_a?(Nil) + stmt = build_statement(query) + @statements_cache[query] = stmt + end - include QueryMethods + stmt + end + + abstract def build_statement(query) : Statement + + protected def do_close + @statements_cache.clear + end end end diff --git a/src/db/result_set.cr b/src/db/result_set.cr index 027efa5..1ad6f96 100644 --- a/src/db/result_set.cr +++ b/src/db/result_set.cr @@ -15,6 +15,7 @@ module DB abstract class ResultSet include Disposable + # :nodoc: getter statement def initialize(@statement : Statement) diff --git a/src/db/statement.cr b/src/db/statement.cr index ed39aba..3debd7d 100644 --- a/src/db/statement.cr +++ b/src/db/statement.cr @@ -12,6 +12,7 @@ module DB abstract class Statement include Disposable + # :nodoc: getter connection def initialize(@connection)