From caf2676aad25fb3a6e516fa6daaafdc376e38c79 Mon Sep 17 00:00:00 2001 From: "Brian J. Cardiff" Date: Fri, 29 Jan 2016 21:57:00 -0300 Subject: [PATCH] column_count and column_names close result_set and statements main entry points for exec_non_query and exec_query closing them when ready --- spec/std/db/dummy_driver.cr | 8 ++++++++ src/db/database.cr | 23 +++++++++++++++++++++++ src/db/result_set.cr | 9 +++++++++ src/db/statement.cr | 16 ++++++++++++++++ 4 files changed, 56 insertions(+) diff --git a/spec/std/db/dummy_driver.cr b/spec/std/db/dummy_driver.cr index 9b9b5d9..24b76c0 100644 --- a/spec/std/db/dummy_driver.cr +++ b/spec/std/db/dummy_driver.cr @@ -40,6 +40,14 @@ class DummyDriver < DB::Driver end end + def column_count + 2 + end + + def column_name(index) + "c#{index}" + end + private def read? : DB::Any? n = @values.not_nil!.next raise "end of row" if n.is_a?(Iterator::Stop) diff --git a/src/db/database.cr b/src/db/database.cr index 25a171f..3d8641d 100644 --- a/src/db/database.cr +++ b/src/db/database.cr @@ -9,12 +9,35 @@ module DB @driver = @driver_class.new(@options) end + # :nodoc: def prepare(query) @driver.prepare(query) end + # :nodoc: def exec(query, *args) prepare(query).exec(*args) end + + def exec_non_query(query, *args) + exec_query(query) do |result_set| + result_set.move_next + end + end + + # :nodoc: + def exec_query(query, *args) + result_set = exec(query, *args) + yield result_set + result_set.close + end + + def exec_query_each(query, *args) + exec_query(query) do |result_set| + result_set.each do + yield result_set + end + end + end end end diff --git a/src/db/result_set.cr b/src/db/result_set.cr index ed396c5..4958fc7 100644 --- a/src/db/result_set.cr +++ b/src/db/result_set.cr @@ -11,8 +11,17 @@ module DB end end + def close + @statement.close + end + abstract def move_next : Bool + abstract def column_count : Int32 + abstract def column_name(index : Int32) : String + + # abstract def column_type(index : Int32) + # list datatypes that must be supported form the driver # users will call read(String) or read?(String) for nillables {% for t in DB::TYPES %} diff --git a/src/db/statement.cr b/src/db/statement.cr index 30f2440..a5e58ca 100644 --- a/src/db/statement.cr +++ b/src/db/statement.cr @@ -3,6 +3,7 @@ module DB getter driver def initialize(@driver) + @closed = false end def exec(*args) : ResultSet @@ -32,9 +33,24 @@ module DB protected def before_execute end + # Closes this statement. + def close + raise "Statement already closed" if @closed + @closed = true + on_close + end + + # Returns `true` if this statement is closed. See `#close`. + def closed? + @closed + end + # 1-based positional arguments protected abstract def add_parameter(index : Int32, value) protected abstract def add_parameter(name : String, value) + protected abstract def execute : ResultSet + protected def on_close + end end end