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 0
end end
def perform_close protected def do_close
end end
end end
@ -57,6 +57,9 @@ class DummyDriver < DB::Driver
@params[index] = arg @params[index] = arg
end end
end end
protected def do_close
end
end end
class DummyResultSet < DB::ResultSet class DummyResultSet < DB::ResultSet
@ -69,6 +72,9 @@ class DummyDriver < DB::Driver
@@last_result_set = self @@last_result_set = self
end end
protected def do_close
end
def self.last_result_set def self.last_result_set
@@last_result_set.not_nil! @@last_result_set.not_nil!
end 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. # Also override `#last_insert_id` to allow safe access to the last inserted id through this connection.
# #
abstract class Connection abstract class Connection
@closed = false include Disposable
# 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
# :nodoc: # :nodoc:
abstract def prepare(query) : Statement abstract def prepare(query) : Statement
include QueryMethods include QueryMethods
protected abstract def perform_close # TODO do_close
end end
end end

View file

@ -99,6 +99,7 @@ module DB
end end
require "./query_methods" require "./query_methods"
require "./disposable"
require "./database" require "./database"
require "./driver" require "./driver"
require "./connection" 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`. # 4. Override `#column_count`, `#column_name`.
# 5. Override `#column_type`. It must return a type in `DB::TYPES`. # 5. Override `#column_type`. It must return a type in `DB::TYPES`.
abstract class ResultSet abstract class ResultSet
include Disposable
getter statement getter statement
def initialize(@statement : Statement) def initialize(@statement : Statement)
@ -27,26 +29,6 @@ module DB
end end
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. # Move the next row in the result.
# Return `false` if no more rows are available. # Return `false` if no more rows are available.
# See `#each` # See `#each`

View file

@ -10,13 +10,13 @@ module DB
# 4. `#perform_exec` executes a query that is expected to return an `ExecResult` # 4. `#perform_exec` executes a query that is expected to return an `ExecResult`
# 6. `#do_close` is called to release the statement resources. # 6. `#do_close` is called to release the statement resources.
abstract class Statement abstract class Statement
include Disposable
getter connection getter connection
def initialize(@connection) def initialize(@connection)
@closed = false
end end
# See `QueryMethods#exec` # See `QueryMethods#exec`
def exec def exec
perform_exec(Slice(Any).new(0)) # no overload matches ... with types Slice(NoReturn) 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)) perform_query(args.to_a.to_unsafe.to_slice(args.size))
end 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_query(args : Slice(Any)) : ResultSet
protected abstract def perform_exec(args : Slice(Any)) : ExecResult protected abstract def perform_exec(args : Slice(Any)) : ExecResult
protected def do_close
end
end end
end end