simple-sql 0.5.18 → 0.5.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/simple/sql.rb +4 -9
- data/lib/simple/sql/connection.rb +32 -61
- data/lib/simple/sql/connection_manager.rb +50 -0
- data/lib/simple/sql/logging.rb +1 -6
- data/lib/simple/sql/version.rb +1 -1
- data/spec/simple/sql/connect_spec.rb +43 -55
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8f07bda4a766c4847fdb1b6ff5b2ffbb46aadf64e57ae72ae0e033027aba2d13
|
4
|
+
data.tar.gz: 8637da9a4e8de6f7a57c8003db0fb27e0d479005730e88e14476f3c5e7edc6ca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 35b8dec9461128d4c1250c6ab3451431aa6defc442afb03cbbeb2fdb5247b9b4258aebcfb86014cf4d6bcad8313320ae028d6d65519a66cddd3dbb35524feb9c
|
7
|
+
data.tar.gz: b087a97ff95ec6f848bde598625ceaf4fd3864cfb3e37a17d7001edab4eabaffcaf5b124e7b401108fbd5622f25bc02eb019bb428d071f7d4bcbb37345cc1cb4
|
data/lib/simple/sql.rb
CHANGED
@@ -59,11 +59,9 @@ module Simple
|
|
59
59
|
|
60
60
|
# -- default connection ---------------------------------------------------
|
61
61
|
|
62
|
-
DEFAULT_CONNECTION_KEY = :"Simple::SQL.default_connection"
|
63
|
-
|
64
62
|
# returns the default connection.
|
65
63
|
def default_connection
|
66
|
-
|
64
|
+
@default_connection ||= connect(:auto)
|
67
65
|
end
|
68
66
|
|
69
67
|
# connects to the database specified via the url parameter, and sets
|
@@ -72,16 +70,13 @@ module Simple
|
|
72
70
|
# \see connect, default_connection
|
73
71
|
def connect!(database_url = :auto)
|
74
72
|
disconnect!
|
75
|
-
|
73
|
+
@default_connection = connect(database_url)
|
76
74
|
end
|
77
75
|
|
78
76
|
# disconnects the current default connection.
|
79
77
|
def disconnect!
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
connection.disconnect!
|
84
|
-
Thread.current[DEFAULT_CONNECTION_KEY] = nil
|
78
|
+
::Simple::SQL::ConnectionManager.disconnect_all!
|
79
|
+
@default_connection = nil
|
85
80
|
end
|
86
81
|
end
|
87
82
|
end
|
@@ -4,6 +4,8 @@ end
|
|
4
4
|
require "pg"
|
5
5
|
require "active_record"
|
6
6
|
|
7
|
+
require_relative "connection_manager"
|
8
|
+
|
7
9
|
require_relative "connection/base"
|
8
10
|
require_relative "connection/lock"
|
9
11
|
require_relative "connection/scope"
|
@@ -17,80 +19,49 @@ require_relative "connection/type_info"
|
|
17
19
|
# It Method.includes the ConnectionAdapter, which implements ask, all, + friends
|
18
20
|
#
|
19
21
|
class Simple::SQL::Connection
|
22
|
+
ConnectionManager = ::Simple::SQL::ConnectionManager
|
23
|
+
|
20
24
|
def self.create(database_url = :auto)
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
25
|
+
expect! database_url => [nil, :auto, String]
|
26
|
+
new connection_class(database_url)
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.connection_class(database_url)
|
30
|
+
if database_url.nil?
|
31
|
+
::ActiveRecord::Base
|
32
|
+
elsif database_url.is_a?(String)
|
33
|
+
ConnectionManager.connection_class(database_url)
|
34
|
+
elsif ::ActiveRecord::Base.connected?
|
35
|
+
# database_url is :auto, and we are connected. This happens, for example,
|
36
|
+
# within a rails controller. IT IS IMPORTANT NOT TO CONNECT AGAINST THE
|
37
|
+
# ::Simple::SQL::Config.determine_url! Only so we can make sure that
|
38
|
+
# simple-sql and ActiveRecord can be mixed freely together, i.e. they are
|
39
|
+
# sharing the same connection.
|
40
|
+
::ActiveRecord::Base
|
30
41
|
else
|
31
|
-
|
42
|
+
ConnectionManager.connection_class(::Simple::SQL::Config.determine_url)
|
32
43
|
end
|
33
44
|
end
|
34
45
|
|
35
|
-
def initialize(
|
36
|
-
@
|
46
|
+
def initialize(connection_class)
|
47
|
+
@connection_class = connection_class
|
37
48
|
end
|
38
49
|
|
39
50
|
def raw_connection
|
40
|
-
@
|
51
|
+
@connection_class.connection.raw_connection
|
41
52
|
end
|
42
53
|
|
43
54
|
def transaction(&block)
|
44
|
-
@
|
55
|
+
@connection_class.connection.transaction(&block)
|
45
56
|
end
|
46
57
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
# -- specific connection classes --------------------------------------------
|
51
|
-
|
52
|
-
class DefaultConnection < self
|
53
|
-
def initialize
|
54
|
-
@active_record_class = ::ActiveRecord::Base
|
55
|
-
end
|
56
|
-
|
57
|
-
def disconnect!; end
|
58
|
+
def disconnect!
|
59
|
+
return unless @connection_class && @connection_class != ::ActiveRecord::Base
|
60
|
+
@connection_class.remove_connection
|
58
61
|
end
|
59
62
|
|
60
|
-
|
61
|
-
|
62
|
-
super create_active_record_class(url)
|
63
|
-
end
|
64
|
-
|
65
|
-
def disconnect!
|
66
|
-
return unless @active_record_class
|
67
|
-
|
68
|
-
@active_record_class.remove_connection
|
69
|
-
end
|
70
|
-
|
71
|
-
private
|
72
|
-
|
73
|
-
# ActiveRecord needs a class name in order to connect.
|
74
|
-
module WritableClassName
|
75
|
-
attr_accessor :name
|
76
|
-
end
|
77
|
-
|
78
|
-
# create_active_record_class builds a ActiveRecord::Base class, whose
|
79
|
-
# ConnectionPool we are going to use for this connection.
|
80
|
-
def create_active_record_class(url)
|
81
|
-
Class.new(ActiveRecord::Base).tap do |klass|
|
82
|
-
klass.extend WritableClassName
|
83
|
-
klass.name = "Simple::SQL::Connection::ExplicitConnection::Adapter"
|
84
|
-
klass.establish_connection url
|
85
|
-
|
86
|
-
connection_pool = klass.connection_pool
|
87
|
-
connection_pool_stats = {
|
88
|
-
size: connection_pool.size,
|
89
|
-
automatic_reconnect: connection_pool.automatic_reconnect,
|
90
|
-
checkout_timeout: connection_pool.checkout_timeout
|
91
|
-
}
|
92
|
-
::Simple::SQL.logger.info "#{url}: connected to connection pool w/#{connection_pool_stats.inspect}"
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|
63
|
+
extend Forwardable
|
64
|
+
delegate [:wait_for_notify] => :raw_connection
|
96
65
|
end
|
66
|
+
|
67
|
+
# TODO disconnect! reconnect!
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# The ConnectionManager manages a pool of ActiveRecord::Base classes.
|
2
|
+
#
|
3
|
+
# ActiveRecord assigns a connection_pool to a class. If you want to connect to
|
4
|
+
# multiple detabases you must inherit from ActiveRecord::Base. This is what
|
5
|
+
# we do dynamically in this ConnectionManager.
|
6
|
+
#
|
7
|
+
# Note that connections to the same database are always shared within a single
|
8
|
+
# ConnectionPool.
|
9
|
+
module Simple::SQL
|
10
|
+
module ConnectionManager
|
11
|
+
extend self
|
12
|
+
|
13
|
+
def disconnect_all!
|
14
|
+
ActiveRecord::Base.connection_pool.disconnect!
|
15
|
+
connection_classes.values.map(&:connection_pool).each(&:disconnect!)
|
16
|
+
connection_classes.clear
|
17
|
+
end
|
18
|
+
|
19
|
+
def connection_class(url)
|
20
|
+
connection_classes[url] ||= create_connection_class(url)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def connection_classes
|
26
|
+
@connection_classes ||= {}
|
27
|
+
end
|
28
|
+
|
29
|
+
# ActiveRecord needs a class name in order to connect.
|
30
|
+
module WritableClassName
|
31
|
+
attr_accessor :name
|
32
|
+
end
|
33
|
+
|
34
|
+
def create_connection_class(url)
|
35
|
+
Class.new(ActiveRecord::Base).tap do |klass|
|
36
|
+
klass.extend WritableClassName
|
37
|
+
klass.name = "Simple::SQL::Connection::ExplicitConnection::Adapter/#{url}"
|
38
|
+
|
39
|
+
klass.establish_connection url
|
40
|
+
connection_pool = klass.connection_pool
|
41
|
+
connection_pool_stats = {
|
42
|
+
size: connection_pool.size,
|
43
|
+
automatic_reconnect: connection_pool.automatic_reconnect,
|
44
|
+
checkout_timeout: connection_pool.checkout_timeout
|
45
|
+
}
|
46
|
+
::Simple::SQL.logger.info "#{url}: connected to connection pool w/#{connection_pool_stats.inspect}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
data/lib/simple/sql/logging.rb
CHANGED
@@ -24,12 +24,7 @@ module Simple
|
|
24
24
|
|
25
25
|
def default_logger
|
26
26
|
# return the ActiveRecord logger, if it exists.
|
27
|
-
|
28
|
-
logger = ActiveRecord::Base.logger
|
29
|
-
return logger if logger
|
30
|
-
end
|
31
|
-
|
32
|
-
stderr_logger
|
27
|
+
::ActiveRecord::Base.logger || stderr_logger
|
33
28
|
end
|
34
29
|
|
35
30
|
def stderr_logger
|
data/lib/simple/sql/version.rb
CHANGED
@@ -1,78 +1,66 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
|
-
describe "
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
end
|
10
|
-
|
11
|
-
context 'without an argument' do
|
12
|
-
let(:params) { [] }
|
13
|
-
|
14
|
-
it 'is reusing the existing ActiveRecord connection' do
|
15
|
-
Simple::SQL.with_connection(*params) do |db|
|
16
|
-
expect(default_pg_backend_pid).to eq(db.ask("SELECT pg_backend_pid()"))
|
17
|
-
expect(db).not_to be_a(Simple::SQL::Connection::ExplicitConnection)
|
18
|
-
end
|
3
|
+
describe "Connections" do
|
4
|
+
describe "Simple::SQL.connect" do
|
5
|
+
before do
|
6
|
+
org = create(:organization)
|
7
|
+
2.times { create(:user, organization_id: org.id) }
|
8
|
+
end
|
19
9
|
|
20
|
-
|
10
|
+
after do
|
11
|
+
expect(User.count).to eq(2)
|
21
12
|
end
|
22
13
|
|
23
|
-
|
24
|
-
|
14
|
+
describe 'automatic connections' do
|
15
|
+
let(:db) { Simple::SQL.connect }
|
25
16
|
|
26
|
-
Simple::SQL
|
27
|
-
|
28
|
-
|
29
|
-
|
17
|
+
it 'can mix Simple::SQL inside ActiveRecord' do
|
18
|
+
User.transaction do
|
19
|
+
User.delete_all
|
20
|
+
expect(db.ask("SELECT count(*) FROM users")).to eq(0)
|
30
21
|
|
31
|
-
|
32
|
-
|
33
|
-
|
22
|
+
raise ActiveRecord::Rollback
|
23
|
+
end
|
24
|
+
|
25
|
+
db.transaction do
|
26
|
+
db.ask("DELETE FROM users")
|
34
27
|
|
35
|
-
|
36
|
-
let(:params) { [:auto] }
|
28
|
+
expect(User.count).to eq(0)
|
37
29
|
|
38
|
-
|
39
|
-
|
40
|
-
expect(default_pg_backend_pid).to eq(db.ask("SELECT pg_backend_pid()"))
|
41
|
-
expect(db).not_to be_a(Simple::SQL::Connection::ExplicitConnection)
|
30
|
+
raise ActiveRecord::Rollback
|
31
|
+
end
|
42
32
|
end
|
43
33
|
end
|
44
34
|
|
45
|
-
|
46
|
-
|
35
|
+
describe 'explizit connections' do
|
36
|
+
let(:db) { Simple::SQL.connect(::Simple::SQL::Config.determine_url) }
|
47
37
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
38
|
+
it 'runs in separate transactions' do
|
39
|
+
User.transaction do
|
40
|
+
User.delete_all
|
41
|
+
expect(db.ask("SELECT count(*) FROM users")).to eq(2)
|
52
42
|
|
53
|
-
|
54
|
-
|
55
|
-
|
43
|
+
raise ActiveRecord::Rollback
|
44
|
+
end
|
45
|
+
|
46
|
+
db.transaction do
|
47
|
+
db.ask("DELETE FROM users")
|
56
48
|
|
57
|
-
|
58
|
-
let(:params) { [Simple::SQL::Config.determine_url] }
|
49
|
+
expect(User.count).to eq(2)
|
59
50
|
|
60
|
-
|
61
|
-
|
62
|
-
expect(default_pg_backend_pid).not_to eq(db.ask("SELECT pg_backend_pid()"))
|
63
|
-
expect(db).to be_a(Simple::SQL::Connection::ExplicitConnection)
|
51
|
+
raise ActiveRecord::Rollback
|
52
|
+
end
|
64
53
|
end
|
65
54
|
end
|
55
|
+
end
|
66
56
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
Simple::SQL.with_connection(*params) do |db|
|
71
|
-
db.ask("SELECT 1")
|
72
|
-
expect(connection_count).to be > initial_connection_count
|
73
|
-
end
|
57
|
+
describe "Simple::SQL.disconnect!" do
|
58
|
+
let(:default_db) { Simple::SQL.connect }
|
59
|
+
let(:db) { Simple::SQL.connect(::Simple::SQL::Config.determine_url) }
|
74
60
|
|
75
|
-
|
61
|
+
it 'disconnects everything' do
|
62
|
+
Simple::SQL.disconnect!
|
63
|
+
expect(ActiveRecord::Base.connection_pool.connections.length).to eq(0)
|
76
64
|
end
|
77
65
|
end
|
78
66
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: simple-sql
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.19
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- radiospiel
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2019-07-
|
12
|
+
date: 2019-07-09 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: pg_array_parser
|
@@ -203,6 +203,7 @@ files:
|
|
203
203
|
- lib/simple/sql/connection/scope/pagination.rb
|
204
204
|
- lib/simple/sql/connection/scope/shorthand.rb
|
205
205
|
- lib/simple/sql/connection/type_info.rb
|
206
|
+
- lib/simple/sql/connection_manager.rb
|
206
207
|
- lib/simple/sql/formatting.rb
|
207
208
|
- lib/simple/sql/fragment.rb
|
208
209
|
- lib/simple/sql/helpers.rb
|
@@ -268,7 +269,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
268
269
|
- !ruby/object:Gem::Version
|
269
270
|
version: '0'
|
270
271
|
requirements: []
|
271
|
-
rubygems_version: 3.0.
|
272
|
+
rubygems_version: 3.0.4
|
272
273
|
signing_key:
|
273
274
|
specification_version: 4
|
274
275
|
summary: SQL with a simple interface
|