expose database in connection

get/return from pool while result set is been used. still single connection pool
This commit is contained in:
Brian J. Cardiff 2016-02-03 19:30:51 -03:00
parent fa111fd698
commit d45427dfdd
8 changed files with 59 additions and 31 deletions

View File

@ -13,20 +13,18 @@ describe DB do
it "should instantiate driver with connection uri" do
db = DB.open "dummy://localhost:1027"
db.driver_class.should eq(DummyDriver)
db.driver.should be_a(DummyDriver)
db.uri.scheme.should eq("dummy")
db.uri.host.should eq("localhost")
db.uri.port.should eq(1027)
end
it "should create a connection and close it" do
cnn = nil
DummyDriver::DummyConnection.clear_connections
DB.open "dummy://localhost" do |db|
cnn = db.connection
end
cnn.should be_a(DummyDriver::DummyConnection)
cnn.not_nil!.closed?.should be_true
connections.size.should eq(1)
connections.first.closed?.should be_true
end
it "query should close result_set" do
@ -61,4 +59,14 @@ describe DB do
end
connections.first.closed?.should be_true
end
it "should raise if the sole connection is been used" do
with_dummy do |db|
db.query "1" do |rs|
expect_raises Exception, /DB Pool Exhausted/ do
db.scalar "2"
end
end
end
end
end

View File

@ -1,14 +1,13 @@
require "spec"
class DummyDriver < DB::Driver
def build_connection
DummyConnection.new(uri)
def build_connection(db : DB::Database) : DB::Connection
DummyConnection.new(db)
end
class DummyConnection < DB::Connection
getter uri
def initialize(@uri)
def initialize(db)
super(db)
@@connections ||= [] of DummyConnection
@@connections.not_nil! << self
end
@ -60,6 +59,7 @@ class DummyDriver < DB::Driver
end
protected def do_close
super
end
end
@ -74,6 +74,7 @@ class DummyDriver < DB::Driver
end
protected def do_close
super
end
def self.last_result_set

View File

@ -17,8 +17,14 @@ module DB
abstract class Connection
include Disposable
include QueryMethods
# :nodoc:
getter database
@statements_cache = {} of String => Statement
def initialize(@database : Database)
end
# :nodoc:
def prepare(query) : Statement
stmt = @statements_cache.fetch(query, nil)

View File

@ -8,30 +8,37 @@ module DB
# Refer to `QueryMethods` for documentation about querying the database.
class Database
# :nodoc:
getter driver_class
getter driver
# Connection configuration to the database.
# Returns the uri with the connection settings to the database
getter uri
# :nodoc:
def initialize(@driver_class, @uri)
@driver = @driver_class.new(@uri)
@connection = @driver.build_connection
def initialize(@driver, @uri)
@in_pool = true
@connection = @driver.build_connection(self)
end
# Closes all connection to the database.
def close
@connection.close
end
# :nodoc:
def connection
@connection
@connection.try &.close
end
# :nodoc:
def prepare(query)
connection.prepare(query)
get_from_pool.prepare(query)
end
# :nodoc:
def get_from_pool
raise "DB Pool Exhausted" unless @in_pool
@in_pool = false
@connection.not_nil!
end
# :nodoc:
def return_to_pool(connection)
@in_pool = true
end
include QueryMethods

View File

@ -105,7 +105,7 @@ module DB
end
private def self.build_database(uri : URI)
Database.new(driver_class(uri.scheme), uri)
Database.new(driver_class(uri.scheme).new, uri)
end
end

View File

@ -7,8 +7,8 @@ module DB
# require "db"
#
# class FakeDriver < Driver
# def build_connection
# FakeConnection.new uri
# def build_connection(db)
# FakeConnection.new db
# end
# end
#
@ -18,7 +18,7 @@ module DB
# Access to this fake datbase will be available with
#
# ```
# DB.open "fake", "..." do |db|
# DB.open "fake://..." do |db|
# # ... use db ...
# end
# ```
@ -26,11 +26,9 @@ module DB
# Refer to `Connection`, `Statement` and `ResultSet` for further
# driver implementation instructions.
abstract class Driver
getter uri
def initialize(@uri : URI)
def initialize
end
abstract def build_connection : Connection
abstract def build_connection(db : Database) : Connection
end
end

View File

@ -21,6 +21,11 @@ module DB
def initialize(@statement : Statement)
end
protected def do_close
cnn = statement.connection
cnn.database.return_to_pool(cnn)
end
# TODO add_next_result_set : Bool
# Iterates over all the rows

View File

@ -18,6 +18,9 @@ module DB
def initialize(@connection)
end
protected def do_close
end
# See `QueryMethods#exec`
def exec
perform_exec(Slice(Any).new(0)) # no overload matches ... with types Slice(NoReturn)