Skip to content

Commit

Permalink
Adapter#reset!
Browse files Browse the repository at this point in the history
  • Loading branch information
maiha committed Jan 27, 2019
1 parent a8b7fc6 commit 1d033a8
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 11 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ job.save # => true
def exec(sql) : Nil
def lastval : Int64
def scalar(*args)
def reset! : Nil
# CRUD
def insert(fields, params)
Expand Down Expand Up @@ -103,6 +104,7 @@ Pon.query_logging=(v : Bool) # writes queries into the logger or not
- [ ] escape
- [x] migrator
- Adapter Drivers
- [x] reset connections
- RDB
- [x] mysql
- [x] pg
Expand Down
13 changes: 10 additions & 3 deletions spec/adapter_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ end
{% for adapter in ADAPTERS %}
module {{adapter.upcase.id}}
describe "[{{adapter.upcase.id}}](ODBC)" do

describe "#databases" do
it "returns database names as Array(String)" do
Job.adapter.databases.should be_a(Array(String))
Expand All @@ -54,11 +53,9 @@ module {{adapter.upcase.id}}
Job.adapter.tables.should contain("jobs")
end
end

end

describe "[{{adapter.upcase.id}}](Trasaction)" do

describe "#transaction" do
{% if adapter == "mysql" %}
pending "ensures transaction" do
Expand All @@ -71,7 +68,17 @@ module {{adapter.upcase.id}}
end
end
end
end

describe "[{{adapter.upcase.id}}](Reset)" do
describe "#reset!" do
it "closes and re-builds connection" do
id1 = Job.adapter.database.object_id
Job.adapter.reset!
id2 = Job.adapter.database.object_id
id1.should_not eq(id2)
end
end
end
end
{% end %}
10 changes: 9 additions & 1 deletion src/pon/adapter.cr
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ abstract class Pon::Adapter
databases[setting.url] ||= build_database(setting)
end

private def self.build_database(setting) : DB::Database
# used from instances
def self.build_database(setting) : DB::Database
db = ::DB.open(setting.url)
db.setup_connection do |con|
if sql = setting.init_connect?
Expand All @@ -25,6 +26,13 @@ abstract class Pon::Adapter
end
return db
end

def self.reset!(setting : Setting) : Nil
if db = databases[setting.url]?
db.close
databases.delete(setting.url)
end
end
end

require "./adapter/rdb"
28 changes: 21 additions & 7 deletions src/pon/adapter/rdb.cr
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# base class for crystal-db
abstract class Pon::Adapter::RDB < Pon::Adapter
abstract def db : ::DB::Database
abstract def table_name : String
abstract def logger : Logger
abstract def exec(query : String, params = [] of String)
abstract def lastval : Int64
abstract def scalar(*args)
abstract def transaction(&block) : Nil
abstract def reset! : Nil

abstract def insert(fields, params)
abstract def all(fields : Array(String), as types : Tuple, limit = nil)
Expand All @@ -21,7 +21,7 @@ abstract class Pon::Adapter::RDB < Pon::Adapter
abstract def tables : Array(String)

delegate quote, to: self.class
delegate query_one?, query_all, scalar, to: db
delegate query_one?, query_all, scalar, to: database

enum BindType
Question = 1 # "?"
Expand All @@ -48,22 +48,36 @@ abstract class Pon::Adapter::RDB < Pon::Adapter
@qt : String # quoted table name
@qp : String # quoted primary name

getter db : ::DB::Database
getter table_name

def initialize(klass, @table_name : String, @primary_name : String, @setting : ::Pon::Setting = ::Pon::Setting.new, db : ::DB::Database? = nil)
def initialize(klass, @table_name : String, @primary_name : String, @setting : ::Pon::Setting = ::Pon::Setting.new, @db : ::DB::Database? = nil)
# bind class setting to default only if default is not set
if @setting.default? == nil
@setting.default = self.class.setting
end

@qt = quote(@table_name)
@qp = quote(@primary_name)
@db = db || Pon::Adapter.database(@setting)
end

### ODBC
# `database` abstracts unique connections and access to shared connections.
# Querying each time accessing without caching slightly degrades performance,
# but this mechanism is required when resetting shared connections.
def database : ::DB::Database
@db || Pon::Adapter.database(@setting)
end

def reset! : Nil
if db = @db
db.close
@db = Pon::Adapter.build_database(@setting)
else
Pon::Adapter.reset!(@setting)
end
end

### ODBC

def databases : Array(String)
query = @setting.query_show_databases
query_all query, as: String
Expand All @@ -78,7 +92,7 @@ abstract class Pon::Adapter::RDB < Pon::Adapter
def exec(query : String, params = [] of String)
query = underlying_prepared(query) if params.any?
query_log "#{query}: #{params}", "exec"
db.exec query, params
database.exec query, params
end

def transaction(&block) : Nil
Expand Down

0 comments on commit 1d033a8

Please sign in to comment.