refactor db disposables

This commit is contained in:
Brian J. Cardiff 2016-02-03 17:10:03 -03:00
parent 782a2ee0e2
commit b92d08bf74
6 changed files with 41 additions and 63 deletions

View File

@ -29,7 +29,7 @@ class DummyDriver < DB::Driver
0
end
def perform_close
protected def do_close
end
end
@ -57,6 +57,9 @@ class DummyDriver < DB::Driver
@params[index] = arg
end
end
protected def do_close
end
end
class DummyResultSet < DB::ResultSet
@ -69,6 +72,9 @@ class DummyDriver < DB::Driver
@@last_result_set = self
end
protected def do_close
end
def self.last_result_set
@@last_result_set.not_nil!
end

View File

@ -15,30 +15,11 @@ module DB
# Also override `#last_insert_id` to allow safe access to the last inserted id through this connection.
#
abstract class Connection
@closed = false
# Closes this connection.
def close
return if @closed
@closed = true
perform_close
end
# Returns `true` if this connection is closed. See `#close`.
def closed?
@closed
end
# :nodoc:
def finalize
close unless closed?
end
include Disposable
# :nodoc:
abstract def prepare(query) : Statement
include QueryMethods
protected abstract def perform_close # TODO do_close
end
end

View File

@ -99,6 +99,7 @@ module DB
end
require "./query_methods"
require "./disposable"
require "./database"
require "./driver"
require "./connection"

28
src/db/disposable.cr Normal file
View File

@ -0,0 +1,28 @@
module DB
# Generic module to encapsulate disposable db resources.
module Disposable
macro included
@closed = false
end
# Closes this object.
def close
return if @closed
@closed = true
do_close
end
# Returns `true` if this object is closed. See `#close`.
def closed?
@closed
end
# :nodoc:
def finalize
close
end
# Implementors overrides this method to perform resource cleanup
protected abstract def do_close
end
end

View File

@ -13,6 +13,8 @@ module DB
# 4. Override `#column_count`, `#column_name`.
# 5. Override `#column_type`. It must return a type in `DB::TYPES`.
abstract class ResultSet
include Disposable
getter statement
def initialize(@statement : Statement)
@ -27,26 +29,6 @@ module DB
end
end
# Closes this result set.
def close
return if @closed
@closed = true
do_close
end
# Returns `true` if this result set is closed. See `#close`.
def closed?
@closed
end
# :nodoc:
def finalize
close
end
protected def do_close
end
# Move the next row in the result.
# Return `false` if no more rows are available.
# See `#each`

View File

@ -10,13 +10,13 @@ module DB
# 4. `#perform_exec` executes a query that is expected to return an `ExecResult`
# 6. `#do_close` is called to release the statement resources.
abstract class Statement
include Disposable
getter connection
def initialize(@connection)
@closed = false
end
# See `QueryMethods#exec`
def exec
perform_exec(Slice(Any).new(0)) # no overload matches ... with types Slice(NoReturn)
@ -82,27 +82,7 @@ module DB
perform_query(args.to_a.to_unsafe.to_slice(args.size))
end
# Closes this statement.
def close
return if @closed
@closed = true
do_close
end
# Returns `true` if this statement is closed. See `#close`.
def closed?
@closed
end
# :nodoc:
def finalize
close
end
protected abstract def perform_query(args : Slice(Any)) : ResultSet
protected abstract def perform_exec(args : Slice(Any)) : ExecResult
protected def do_close
end
end
end