ar-multidb 0.1.12 → 0.4.2
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 +5 -5
- data/.gitignore +4 -1
- data/.rubocop.yml +62 -0
- data/.travis.yml +15 -3
- data/CHANGELOG.md +16 -0
- data/Gemfile +7 -4
- data/README.markdown +41 -19
- data/Rakefile +10 -9
- data/ar-multidb.gemspec +19 -16
- data/gemfiles/activerecord51.gemfile +7 -0
- data/gemfiles/activerecord52.gemfile +7 -0
- data/lib/ar-multidb.rb +2 -0
- data/lib/multidb.rb +4 -0
- data/lib/multidb/balancer.rb +69 -67
- data/lib/multidb/candidate.rb +33 -0
- data/lib/multidb/configuration.rb +17 -36
- data/lib/multidb/log_subscriber.rb +23 -0
- data/lib/multidb/model_extensions.rb +18 -13
- data/lib/multidb/version.rb +4 -2
- data/spec/balancer_spec.rb +74 -30
- data/spec/helpers.rb +21 -18
- data/spec/spec_helper.rb +6 -3
- metadata +79 -34
- data/Gemfile.lock +0 -54
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 3ecd6501582114326efd8452ffe712c79b5667d1ce54a181eff6efeaf40d1897
|
4
|
+
data.tar.gz: 85c3e8b3dc155374ef7d7caed121bf5a140cf64030b760bb6cdcdb3123e8cddc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e2eefe25c89d914367afecce5ebc07f4be668985097969f5a1c9acb563a22c448778b4128caf64e5dd6029437e28b13188097d6c66c111f4b5911543858f50b1
|
7
|
+
data.tar.gz: c83c08a921575803b15ebf473e125ad6da3619b321208766e9f8d058bb8226154cd21255d14aa77be260bfd17da29926be8aa3bdeda547fed0c6f46624370283
|
data/.gitignore
CHANGED
data/.rubocop.yml
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
AllCops:
|
2
|
+
TargetRubyVersion: 2.4
|
3
|
+
Exclude:
|
4
|
+
- '**/vendor/**/*'
|
5
|
+
|
6
|
+
Layout/EmptyLinesAroundAttributeAccessor:
|
7
|
+
Enabled: true
|
8
|
+
Layout/SpaceAroundMethodCallOperator:
|
9
|
+
Enabled: true
|
10
|
+
Layout/LineLength:
|
11
|
+
Exclude:
|
12
|
+
- 'ar-multidb.gemspec'
|
13
|
+
Lint/DeprecatedOpenSSLConstant:
|
14
|
+
Enabled: true
|
15
|
+
Lint/DuplicateElsifCondition:
|
16
|
+
Enabled: true
|
17
|
+
Lint/MixedRegexpCaptureTypes:
|
18
|
+
Enabled: true
|
19
|
+
Lint/RaiseException:
|
20
|
+
Enabled: true
|
21
|
+
Lint/StructNewOverride:
|
22
|
+
Enabled: true
|
23
|
+
Naming/FileName:
|
24
|
+
Exclude:
|
25
|
+
- 'lib/ar-multidb.rb'
|
26
|
+
Metrics:
|
27
|
+
Enabled: false
|
28
|
+
Style/AccessorGrouping:
|
29
|
+
Enabled: true
|
30
|
+
Style/ArrayCoercion:
|
31
|
+
Enabled: true
|
32
|
+
Style/BisectedAttrAccessor:
|
33
|
+
Enabled: true
|
34
|
+
Style/CaseLikeIf:
|
35
|
+
Enabled: true
|
36
|
+
Style/Documentation:
|
37
|
+
Enabled: false
|
38
|
+
Style/ExponentialNotation:
|
39
|
+
Enabled: true
|
40
|
+
Style/HashAsLastArrayItem:
|
41
|
+
Enabled: true
|
42
|
+
Style/HashEachMethods:
|
43
|
+
Enabled: true
|
44
|
+
Style/HashLikeCase:
|
45
|
+
Enabled: true
|
46
|
+
Style/HashTransformKeys:
|
47
|
+
Enabled: true
|
48
|
+
Style/HashTransformValues:
|
49
|
+
Enabled: true
|
50
|
+
Style/RedundantAssignment:
|
51
|
+
Enabled: true
|
52
|
+
Style/RedundantFetchBlock:
|
53
|
+
Enabled: true
|
54
|
+
Style/RedundantFileExtensionInRequire:
|
55
|
+
Enabled: true
|
56
|
+
Style/RedundantRegexpCharacterClass:
|
57
|
+
Enabled: true
|
58
|
+
Style/RedundantRegexpEscape:
|
59
|
+
Enabled: true
|
60
|
+
Style/SlicingWithRange:
|
61
|
+
Enabled: true
|
62
|
+
|
data/.travis.yml
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
sudo: false
|
2
|
+
language: ruby
|
3
|
+
cache: bundler
|
4
|
+
|
5
|
+
script:
|
6
|
+
- bundle exec rubocop
|
7
|
+
- bundle exec rspec
|
8
|
+
|
9
|
+
matrix:
|
10
|
+
fast_finish: true
|
11
|
+
include:
|
12
|
+
- rvm: 2.5
|
13
|
+
gemfile: gemfiles/activerecord51.gemfile
|
14
|
+
- rvm: 2.5
|
15
|
+
gemfile: gemfiles/activerecord52.gemfile
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# Changelog
|
2
|
+
All notable changes to this project will be documented in this file.
|
3
|
+
|
4
|
+
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
5
|
+
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html)
|
6
|
+
|
7
|
+
## [0.4.2]
|
8
|
+
### Changed
|
9
|
+
- adjust rails restriction to exclude untested rails 6
|
10
|
+
- adjust minimum ruby version to 2.4
|
11
|
+
- add rubocop
|
12
|
+
|
13
|
+
## [0.4.1]
|
14
|
+
### Added
|
15
|
+
- Added support for database aliases ( PR #26 )
|
16
|
+
|
data/Gemfile
CHANGED
@@ -1,9 +1,12 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
source 'http://rubygems.org'
|
2
4
|
|
3
5
|
# Specify your gem's dependencies in ar-multidb.gemspec
|
4
6
|
gemspec
|
5
7
|
|
6
|
-
|
7
|
-
|
8
|
-
|
8
|
+
local_gemfile = 'Gemfile.local'
|
9
|
+
|
10
|
+
if File.exist?(local_gemfile)
|
11
|
+
eval(File.read(local_gemfile)) # rubocop:disable Security/Eval
|
9
12
|
end
|
data/README.markdown
CHANGED
@@ -2,9 +2,9 @@
|
|
2
2
|
|
3
3
|
# Multidb
|
4
4
|
|
5
|
-
A simple, no-nonsense ActiveRecord extension which allows the application to switch between multiple database connections, such as in a
|
5
|
+
A simple, no-nonsense ActiveRecord extension which allows the application to switch between multiple database connections, such as in a primary/replica environment. For example:
|
6
6
|
|
7
|
-
Multidb.use(:
|
7
|
+
Multidb.use(:replica) do
|
8
8
|
@posts = Post.all
|
9
9
|
end
|
10
10
|
|
@@ -14,8 +14,13 @@ Randomized balancing of multiple connections within a group is supported. In the
|
|
14
14
|
|
15
15
|
## Requirements
|
16
16
|
|
17
|
-
* Ruby
|
18
|
-
* ActiveRecord
|
17
|
+
* Ruby 2.4 or later.
|
18
|
+
* ActiveRecord 5.1 or later.
|
19
|
+
|
20
|
+
## Older releases
|
21
|
+
For ActiveRecord 4. through 5.0 use version 0.3
|
22
|
+
For ActiveRecord older than 4.0 use the gem version 0.1.13
|
23
|
+
For ActiveRecord older than 3.0 use 0.1.10
|
19
24
|
|
20
25
|
## Comparison to other ActiveRecord extensions
|
21
26
|
|
@@ -27,10 +32,10 @@ Compared to other, more full-featured extensions such as Octopus and Seamless Da
|
|
27
32
|
|
28
33
|
**Orthogonal**. Unlike Octopus, for example, connections follow context:
|
29
34
|
|
30
|
-
Multidb.use(:
|
35
|
+
Multidb.use(:primary) do
|
31
36
|
@post = Post.find(1)
|
32
|
-
Multidb.use(:
|
33
|
-
@post.authors # This will use the
|
37
|
+
Multidb.use(:replica) do
|
38
|
+
@post.authors # This will use the replica
|
34
39
|
end
|
35
40
|
end
|
36
41
|
|
@@ -55,8 +60,8 @@ All that is needed is to set up your `database.yml` file:
|
|
55
60
|
host: db1
|
56
61
|
multidb:
|
57
62
|
databases:
|
58
|
-
|
59
|
-
host: db-
|
63
|
+
replica:
|
64
|
+
host: db-replica
|
60
65
|
|
61
66
|
Each database entry may be a hash or an array. So this also works:
|
62
67
|
|
@@ -68,24 +73,41 @@ Each database entry may be a hash or an array. So this also works:
|
|
68
73
|
host: db1
|
69
74
|
multidb:
|
70
75
|
databases:
|
71
|
-
|
72
|
-
- host: db-
|
73
|
-
- host: db-
|
76
|
+
replica:
|
77
|
+
- host: db-replica1
|
78
|
+
- host: db-replica2
|
74
79
|
|
75
80
|
If multiple elements are specified, Multidb will use the list to pick a random candidate connection.
|
76
81
|
|
77
82
|
The database hashes follow the same format as the top-level adapter configuration. In other words, each database connection may override the adapter, database name, username and so on.
|
78
83
|
|
84
|
+
You may also add an "alias" record to the configuration to support more than one name for a given database configuration.
|
85
|
+
|
86
|
+
production:
|
87
|
+
adapter: postgresql
|
88
|
+
database: myapp_production
|
89
|
+
username: ohoh
|
90
|
+
password: mymy
|
91
|
+
host: db1
|
92
|
+
multidb:
|
93
|
+
databases:
|
94
|
+
main_db:
|
95
|
+
host: db1-a
|
96
|
+
secondary_db:
|
97
|
+
alias: main_db
|
98
|
+
|
99
|
+
With the above, `Multidb.use(:main_db)` and `Multidb.use(:secondary_db)` will work identically. This can be useful to support naming scheme migrations transparently: once your application is updated to use `secondary_db` where necessary, you can swap out the configuration.
|
100
|
+
|
79
101
|
To use the connection, modify your code by wrapping database access logic in blocks:
|
80
102
|
|
81
|
-
Multidb.use(:
|
103
|
+
Multidb.use(:replica) do
|
82
104
|
@posts = Post.all
|
83
105
|
end
|
84
106
|
|
85
107
|
To wrap entire controller requests, for example:
|
86
108
|
|
87
109
|
class PostsController < ApplicationController
|
88
|
-
around_filter :
|
110
|
+
around_filter :run_using_replica, only: [:index]
|
89
111
|
|
90
112
|
def index
|
91
113
|
@posts = Post.all
|
@@ -95,22 +117,22 @@ To wrap entire controller requests, for example:
|
|
95
117
|
# Won't be wrapped
|
96
118
|
end
|
97
119
|
|
98
|
-
def
|
99
|
-
Multidb.use(:
|
120
|
+
def run_using_replica(&block)
|
121
|
+
Multidb.use(:replica, &block)
|
100
122
|
end
|
101
123
|
end
|
102
124
|
|
103
125
|
You can also set the current connection for the remainder of the thread's execution:
|
104
126
|
|
105
|
-
Multidb.use(:
|
127
|
+
Multidb.use(:replica)
|
106
128
|
# Do work
|
107
|
-
Multidb.use(:
|
129
|
+
Multidb.use(:primary)
|
108
130
|
|
109
131
|
Note that the symbol `:default` will (unless you override it) refer to the default top-level ActiveRecord configuration.
|
110
132
|
|
111
133
|
## Development mode
|
112
134
|
|
113
|
-
In development you will typically want `Multidb.use(:
|
135
|
+
In development you will typically want `Multidb.use(:replica)` to still work, but you probably don't want to run multiple databases on your development box. To make `use` silently fall back to using the default connection, Multidb can run in fallback mode.
|
114
136
|
|
115
137
|
If you are using Rails, this will be automatically enabled in `development` and `test` environments. Otherwise, simply set `fallback: true` in `database.yml`:
|
116
138
|
|
data/Rakefile
CHANGED
@@ -1,26 +1,27 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'bundler/gem_tasks'
|
2
4
|
require 'rspec/core/rake_task'
|
3
5
|
|
4
6
|
RSpec::Core::RakeTask.new
|
5
7
|
|
6
|
-
task :
|
8
|
+
task default: :spec
|
7
9
|
|
8
10
|
desc 'Bump version'
|
9
11
|
task :bump do
|
10
|
-
if `git status -uno -s --porcelain | wc -l`.to_i
|
11
|
-
|
12
|
-
end
|
12
|
+
abort 'You have uncommitted changed.' if `git status -uno -s --porcelain | wc -l`.to_i.positive?
|
13
|
+
|
13
14
|
text = File.read('lib/multidb/version.rb')
|
14
15
|
if text =~ /VERSION = '(.*)'/
|
15
|
-
old_version =
|
16
|
+
old_version = Regexp.last_match(1)
|
16
17
|
version_parts = old_version.split('.')
|
17
18
|
version_parts[-1] = version_parts[-1].to_i + 1
|
18
19
|
new_version = version_parts.join('.')
|
19
20
|
text.gsub!(/VERSION = '(.*)'/, "VERSION = '#{new_version}'")
|
20
21
|
File.open('lib/multidb/version.rb', 'w') { |f| f << text }
|
21
|
-
(system(
|
22
|
-
system("git commit -m 'Bump to #{new_version}.'"))
|
22
|
+
(system('git add lib/multidb/version.rb') &&
|
23
|
+
system("git commit -m 'Bump to #{new_version}.'")) || abort('Failed to commit.')
|
23
24
|
else
|
24
|
-
abort
|
25
|
+
abort 'Could not find version number'
|
25
26
|
end
|
26
27
|
end
|
data/ar-multidb.gemspec
CHANGED
@@ -1,25 +1,28 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
$LOAD_PATH.push File.expand_path('lib', __dir__)
|
4
|
+
require 'multidb/version'
|
4
5
|
|
5
6
|
Gem::Specification.new do |s|
|
6
|
-
s.name =
|
7
|
+
s.name = 'ar-multidb'
|
7
8
|
s.version = Multidb::VERSION
|
8
|
-
s.authors = [
|
9
|
-
s.email = [
|
10
|
-
s.homepage =
|
11
|
-
s.summary = s.description =
|
12
|
-
|
13
|
-
s.rubyforge_project = "ar-multidb"
|
9
|
+
s.authors = ['Alexander Staubo', 'Edward Rudd']
|
10
|
+
s.email = ['alex@bengler.no', 'urkle@outoforder.cc']
|
11
|
+
s.homepage = ''
|
12
|
+
s.summary = s.description = 'Multidb is an ActiveRecord extension for switching between multiple database connections, such as primary/replica setups.'
|
14
13
|
|
15
14
|
s.files = `git ls-files`.split("\n")
|
16
15
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
17
|
-
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
|
-
s.require_paths = [
|
16
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
17
|
+
s.require_paths = ['lib']
|
18
|
+
|
19
|
+
s.required_ruby_version = '>= 2.4.0'
|
19
20
|
|
20
|
-
s.add_runtime_dependency '
|
21
|
-
s.add_runtime_dependency '
|
21
|
+
s.add_runtime_dependency 'activerecord', '>= 5.1', '< 6.0'
|
22
|
+
s.add_runtime_dependency 'activesupport', '>= 5.1', '< 6.0'
|
22
23
|
|
23
|
-
s.add_development_dependency '
|
24
|
-
s.add_development_dependency '
|
24
|
+
s.add_development_dependency 'rake', '~> 12.0'
|
25
|
+
s.add_development_dependency 'rspec', '~> 3.8'
|
26
|
+
s.add_development_dependency 'rubocop', '~> 0.88.0'
|
27
|
+
s.add_development_dependency 'sqlite3', '~> 1.3'
|
25
28
|
end
|
data/lib/ar-multidb.rb
CHANGED
data/lib/multidb.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'active_record'
|
2
4
|
|
3
5
|
require 'active_support/core_ext/module/delegation'
|
@@ -6,5 +8,7 @@ require 'active_support/core_ext/module/aliasing'
|
|
6
8
|
|
7
9
|
require_relative 'multidb/configuration'
|
8
10
|
require_relative 'multidb/model_extensions'
|
11
|
+
require_relative 'multidb/log_subscriber'
|
12
|
+
require_relative 'multidb/candidate'
|
9
13
|
require_relative 'multidb/balancer'
|
10
14
|
require_relative 'multidb/version'
|
data/lib/multidb/balancer.rb
CHANGED
@@ -1,107 +1,107 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Multidb
|
4
|
+
class Balancer
|
5
|
+
attr_accessor :fallback
|
2
6
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
adapter = target[:adapter]
|
7
|
-
begin
|
8
|
-
require "active_record/connection_adapters/#{adapter}_adapter"
|
9
|
-
rescue LoadError
|
10
|
-
raise "Please install the #{adapter} adapter: `gem install activerecord-#{adapter}-adapter` (#{$!})"
|
11
|
-
end
|
12
|
-
if defined?(ActiveRecord::ConnectionAdapters::ConnectionSpecification)
|
13
|
-
spec_class = ActiveRecord::ConnectionAdapters::ConnectionSpecification
|
14
|
-
else
|
15
|
-
spec_class = ActiveRecord::Base::ConnectionSpecification
|
16
|
-
end
|
17
|
-
@connection_pool = ActiveRecord::ConnectionAdapters::ConnectionPool.new(
|
18
|
-
spec_class.new(target, "#{adapter}_connection"))
|
19
|
-
else
|
20
|
-
@connection_pool = target
|
21
|
-
end
|
22
|
-
end
|
7
|
+
def initialize(configuration)
|
8
|
+
@candidates = {}.with_indifferent_access
|
9
|
+
@default_configuration = configuration
|
23
10
|
|
24
|
-
|
25
|
-
if block_given?
|
26
|
-
@connection_pool.with_connection(&block)
|
27
|
-
else
|
28
|
-
@connection_pool.connection
|
29
|
-
end
|
30
|
-
end
|
11
|
+
return unless @default_configuration
|
31
12
|
|
32
|
-
|
33
|
-
end
|
13
|
+
append(@default_configuration.raw_configuration[:databases] || {})
|
34
14
|
|
35
|
-
|
15
|
+
@fallback = if @default_configuration.raw_configuration.include?(:fallback)
|
16
|
+
@default_configuration.raw_configuration[:fallback]
|
17
|
+
elsif defined?(Rails)
|
18
|
+
%w[development test].include?(Rails.env)
|
19
|
+
else
|
20
|
+
false
|
21
|
+
end
|
36
22
|
|
37
|
-
|
38
|
-
|
39
|
-
@
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
23
|
+
@default_candidate = Candidate.new('default', @default_configuration.default_handler)
|
24
|
+
|
25
|
+
@candidates[:default] = [@default_candidate] unless @candidates.include?(:default)
|
26
|
+
end
|
27
|
+
|
28
|
+
def append(databases)
|
29
|
+
databases.each_pair do |name, config|
|
30
|
+
configs = config.is_a?(Array) ? config : [config]
|
31
|
+
configs.each do |cfg|
|
32
|
+
if cfg['alias']
|
33
|
+
@candidates[name] = @candidates[cfg['alias']]
|
34
|
+
next
|
47
35
|
end
|
48
|
-
|
49
|
-
|
50
|
-
@
|
51
|
-
|
52
|
-
@fallback = %w(development test).include?(Rails.env)
|
53
|
-
else
|
54
|
-
@fallback = false
|
55
|
-
end
|
56
|
-
@default_candidate = Candidate.new(@configuration.default_pool)
|
57
|
-
unless @candidates.include?(:default)
|
58
|
-
@candidates[:default] = [@default_candidate]
|
36
|
+
|
37
|
+
candidate = Candidate.new(name, @default_configuration.default_adapter.merge(cfg))
|
38
|
+
@candidates[name] ||= []
|
39
|
+
@candidates[name].push(candidate)
|
59
40
|
end
|
60
41
|
end
|
61
42
|
end
|
62
43
|
|
63
44
|
def disconnect!
|
64
|
-
@candidates.values.flatten.each
|
65
|
-
candidate.connection_pool.disconnect!
|
66
|
-
end
|
45
|
+
@candidates.values.flatten.each(&:disconnect!)
|
67
46
|
end
|
68
47
|
|
69
|
-
def get(name, &
|
48
|
+
def get(name, &_block)
|
70
49
|
candidates = @candidates[name]
|
71
50
|
candidates ||= @fallback ? @candidates[:default] : []
|
51
|
+
|
72
52
|
raise ArgumentError, "No such database connection '#{name}'" if candidates.empty?
|
73
|
-
|
74
|
-
|
53
|
+
|
54
|
+
candidate = candidates.respond_to?(:sample) ? candidates.sample : candidates[rand(candidates.length)]
|
55
|
+
|
75
56
|
block_given? ? yield(candidate) : candidate
|
76
57
|
end
|
77
58
|
|
78
|
-
def use(name, &
|
59
|
+
def use(name, &_block)
|
79
60
|
result = nil
|
80
61
|
get(name) do |candidate|
|
81
62
|
if block_given?
|
82
63
|
candidate.connection do |connection|
|
83
|
-
|
84
|
-
|
64
|
+
previous_configuration = Thread.current[:multidb]
|
65
|
+
Thread.current[:multidb] = {
|
66
|
+
connection: connection,
|
67
|
+
connection_name: name
|
68
|
+
}
|
85
69
|
begin
|
86
70
|
result = yield
|
71
|
+
result = result.to_a if result.is_a?(ActiveRecord::Relation)
|
87
72
|
ensure
|
88
|
-
Thread.current[:
|
73
|
+
Thread.current[:multidb] = previous_configuration
|
89
74
|
end
|
90
75
|
result
|
91
76
|
end
|
92
77
|
else
|
93
|
-
|
78
|
+
Thread.current[:multidb] = {
|
79
|
+
connection: candidate.connection,
|
80
|
+
connection_name: name
|
81
|
+
}
|
82
|
+
result = candidate.connection
|
94
83
|
end
|
95
84
|
end
|
96
85
|
result
|
97
86
|
end
|
98
87
|
|
99
88
|
def current_connection
|
100
|
-
Thread.current[:
|
89
|
+
if Thread.current[:multidb]
|
90
|
+
Thread.current[:multidb][:connection]
|
91
|
+
else
|
92
|
+
@default_candidate.connection
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def current_connection_name
|
97
|
+
if Thread.current[:multidb]
|
98
|
+
Thread.current[:multidb][:connection_name]
|
99
|
+
else
|
100
|
+
:default
|
101
|
+
end
|
101
102
|
end
|
102
103
|
|
103
104
|
class << self
|
104
|
-
delegate :use, :current_connection, :disconnect!, to: :balancer
|
105
105
|
def use(name, &block)
|
106
106
|
Multidb.balancer.use(name, &block)
|
107
107
|
end
|
@@ -110,11 +110,13 @@ module Multidb
|
|
110
110
|
Multidb.balancer.current_connection
|
111
111
|
end
|
112
112
|
|
113
|
+
def current_connection_name
|
114
|
+
Multidb.balancer.current_connection_name
|
115
|
+
end
|
116
|
+
|
113
117
|
def disconnect!
|
114
118
|
Multidb.balancer.disconnect!
|
115
119
|
end
|
116
120
|
end
|
117
|
-
|
118
121
|
end
|
119
|
-
|
120
|
-
end
|
122
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Multidb
|
4
|
+
class Candidate
|
5
|
+
def initialize(name, target)
|
6
|
+
@name = name
|
7
|
+
|
8
|
+
case target
|
9
|
+
when Hash
|
10
|
+
@connection_handler = ActiveRecord::ConnectionAdapters::ConnectionHandler.new
|
11
|
+
@connection_handler.establish_connection(target.merge(name: 'primary'))
|
12
|
+
when ActiveRecord::ConnectionAdapters::ConnectionHandler
|
13
|
+
@connection_handler = target
|
14
|
+
else
|
15
|
+
raise ArgumentError, 'Connection handler not passed to target'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def connection(&block)
|
20
|
+
if block_given?
|
21
|
+
@connection_handler.retrieve_connection_pool('primary').with_connection(&block)
|
22
|
+
else
|
23
|
+
@connection_handler.retrieve_connection('primary')
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def disconnect!
|
28
|
+
@connection_handler.clear_all_connections!
|
29
|
+
end
|
30
|
+
|
31
|
+
attr_reader :name
|
32
|
+
end
|
33
|
+
end
|
@@ -1,54 +1,35 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
mattr_reader :configuration
|
1
|
+
# frozen_string_literal: true
|
4
2
|
|
3
|
+
module Multidb
|
5
4
|
class << self
|
6
5
|
delegate :use, :get, :disconnect!, to: :balancer
|
7
6
|
end
|
8
7
|
|
8
|
+
def self.init(config)
|
9
|
+
activerecord_config = config.dup.with_indifferent_access
|
10
|
+
default_adapter = activerecord_config
|
11
|
+
configuration_hash = activerecord_config.delete(:multidb)
|
12
|
+
|
13
|
+
@balancer = Balancer.new(Configuration.new(default_adapter, configuration_hash || {}))
|
14
|
+
end
|
15
|
+
|
9
16
|
def self.balancer
|
10
|
-
@balancer
|
17
|
+
@balancer || raise(NotInitializedError, 'Balancer not initialized. You need to run Multidb.init first')
|
11
18
|
end
|
12
19
|
|
13
20
|
def self.reset!
|
14
|
-
@balancer
|
21
|
+
@balancer = nil
|
15
22
|
end
|
16
23
|
|
24
|
+
class NotInitializedError < StandardError; end
|
25
|
+
|
17
26
|
class Configuration
|
18
27
|
def initialize(default_adapter, configuration_hash)
|
19
|
-
@
|
28
|
+
@default_handler = ActiveRecord::Base.connection_handler
|
20
29
|
@default_adapter = default_adapter
|
21
30
|
@raw_configuration = configuration_hash
|
22
31
|
end
|
23
32
|
|
24
|
-
attr_reader :
|
25
|
-
attr_reader :default_adapter
|
26
|
-
attr_reader :raw_configuration
|
33
|
+
attr_reader :default_handler, :default_adapter, :raw_configuration
|
27
34
|
end
|
28
|
-
|
29
|
-
private
|
30
|
-
|
31
|
-
def self.create_balancer
|
32
|
-
unless @configuration
|
33
|
-
begin
|
34
|
-
connection_pool = ActiveRecord::Base.connection_pool
|
35
|
-
rescue ActiveRecord::ConnectionNotEstablished
|
36
|
-
# Ignore
|
37
|
-
else
|
38
|
-
connection = connection_pool.connection
|
39
|
-
|
40
|
-
# FIXME: This is hacky, but apparently the only way to get at
|
41
|
-
# the internal configuration hash.
|
42
|
-
activerecord_config = connection.instance_variable_get(:@config).dup.with_indifferent_access
|
43
|
-
|
44
|
-
default_adapter, configuration_hash = activerecord_config, activerecord_config.delete(:multidb)
|
45
|
-
|
46
|
-
@configuration = Configuration.new(default_adapter, configuration_hash || {})
|
47
|
-
end
|
48
|
-
end
|
49
|
-
if @configuration
|
50
|
-
Balancer.new(@configuration)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
end
|
35
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Multidb
|
4
|
+
module LogSubscriberExtension
|
5
|
+
def sql(event)
|
6
|
+
name = Multidb.balancer.current_connection_name
|
7
|
+
event.payload[:db_name] = name if name
|
8
|
+
super
|
9
|
+
end
|
10
|
+
|
11
|
+
def debug(msg)
|
12
|
+
name = Multidb.balancer.current_connection_name
|
13
|
+
if name
|
14
|
+
db = color("[DB: #{name}]", ActiveSupport::LogSubscriber::GREEN, true)
|
15
|
+
super(db + msg)
|
16
|
+
else
|
17
|
+
super
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
ActiveRecord::LogSubscriber.prepend(Multidb::LogSubscriberExtension)
|
@@ -1,24 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_record/base'
|
4
|
+
|
1
5
|
module Multidb
|
2
|
-
module
|
6
|
+
module Connection
|
7
|
+
def establish_connection(spec = nil)
|
8
|
+
super(spec)
|
9
|
+
Multidb.init(connection_pool.spec.config)
|
10
|
+
end
|
11
|
+
|
12
|
+
def connection
|
13
|
+
Multidb.balancer.current_connection
|
14
|
+
rescue Multidb::NotInitializedError
|
15
|
+
super
|
16
|
+
end
|
17
|
+
end
|
3
18
|
|
19
|
+
module ModelExtensions
|
4
20
|
extend ActiveSupport::Concern
|
5
21
|
|
6
22
|
included do
|
7
23
|
class << self
|
8
|
-
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
module ClassMethods
|
13
|
-
def connection_with_multidb
|
14
|
-
if (balancer = Multidb.balancer)
|
15
|
-
balancer.current_connection
|
16
|
-
else
|
17
|
-
connection_without_multidb
|
18
|
-
end
|
24
|
+
prepend Multidb::Connection
|
19
25
|
end
|
20
26
|
end
|
21
|
-
|
22
27
|
end
|
23
28
|
end
|
24
29
|
|
data/lib/multidb/version.rb
CHANGED
data/spec/balancer_spec.rb
CHANGED
@@ -1,16 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative 'spec_helper'
|
2
4
|
|
3
5
|
describe 'Multidb.balancer' do
|
4
|
-
|
5
6
|
context 'with no configuration' do
|
6
|
-
it '
|
7
|
-
Multidb.balancer.should
|
7
|
+
it 'raises exception' do
|
8
|
+
-> { Multidb.balancer }.should raise_error(Multidb::NotInitializedError)
|
8
9
|
end
|
9
10
|
end
|
10
11
|
|
11
12
|
context 'with configuration' do
|
12
13
|
before do
|
13
|
-
ActiveRecord::Base.establish_connection(
|
14
|
+
ActiveRecord::Base.establish_connection(configuration_with_replicas)
|
14
15
|
end
|
15
16
|
|
16
17
|
it 'returns balancer' do
|
@@ -26,25 +27,54 @@ describe 'Multidb.balancer' do
|
|
26
27
|
|
27
28
|
Multidb.balancer.current_connection.should eq conn
|
28
29
|
end
|
29
|
-
end
|
30
30
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
31
|
+
it 'returns default connection name for default connection' do
|
32
|
+
ActiveRecord::Base.connection
|
33
|
+
|
34
|
+
Multidb.balancer.current_connection_name.should eq :default
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'with additional configurations' do
|
38
|
+
before do
|
39
|
+
additional_configuration = { replica4: { database: 'spec/test-replica4.sqlite' } }
|
40
|
+
Multidb.balancer.append(additional_configuration)
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'makes the new database available' do
|
44
|
+
Multidb.use(:replica4) do
|
45
|
+
conn = ActiveRecord::Base.connection
|
46
|
+
conn.should eq Multidb.balancer.current_connection
|
47
|
+
list = conn.execute('pragma database_list')
|
48
|
+
list.length.should eq 1
|
49
|
+
File.basename(list[0]['file']).should eq 'test-replica4.sqlite'
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'returns the connection name' do
|
54
|
+
Multidb.use(:replica4) do
|
55
|
+
Multidb.balancer.current_connection_name.should eq :replica4
|
56
|
+
end
|
38
57
|
end
|
39
58
|
end
|
59
|
+
end
|
40
60
|
|
61
|
+
describe '#use' do
|
41
62
|
context 'with configuration' do
|
42
63
|
before do
|
43
|
-
ActiveRecord::Base.establish_connection(
|
64
|
+
ActiveRecord::Base.establish_connection(configuration_with_replicas)
|
65
|
+
end
|
66
|
+
|
67
|
+
context 'undefined connection' do
|
68
|
+
it 'raises exception' do
|
69
|
+
lambda {
|
70
|
+
Multidb.use(:something) do
|
71
|
+
end
|
72
|
+
}.should raise_error(ArgumentError)
|
73
|
+
end
|
44
74
|
end
|
45
75
|
|
46
76
|
it 'returns default connection on :default' do
|
47
|
-
|
77
|
+
ActiveRecord::Base.connection
|
48
78
|
Multidb.use(:default) do
|
49
79
|
conn2 = ActiveRecord::Base.connection
|
50
80
|
conn2.should eq Multidb.balancer.current_connection
|
@@ -55,61 +85,75 @@ describe 'Multidb.balancer' do
|
|
55
85
|
end
|
56
86
|
end
|
57
87
|
|
58
|
-
it 'returns
|
59
|
-
Multidb.use(:
|
88
|
+
it 'returns replica connection' do
|
89
|
+
Multidb.use(:replica1) do
|
60
90
|
conn = ActiveRecord::Base.connection
|
61
91
|
conn.should eq Multidb.balancer.current_connection
|
62
92
|
list = conn.execute('pragma database_list')
|
63
93
|
list.length.should eq 1
|
64
|
-
File.basename(list[0]['file']).should eq 'test-
|
94
|
+
File.basename(list[0]['file']).should eq 'test-replica1.sqlite'
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'returns results instead of relation' do
|
99
|
+
class FooBar < ActiveRecord::Base; end
|
100
|
+
res = Multidb.use(:replica1) do
|
101
|
+
ActiveRecord::Migration.verbose = false
|
102
|
+
ActiveRecord::Schema.define(version: 1) { create_table :foo_bars }
|
103
|
+
FooBar.where(id: 42)
|
65
104
|
end
|
105
|
+
res.should eq []
|
66
106
|
end
|
67
107
|
|
68
|
-
it 'returns supports nested
|
69
|
-
Multidb.use(:
|
70
|
-
Multidb.use(:
|
108
|
+
it 'returns supports nested replica connection' do
|
109
|
+
Multidb.use(:replica1) do
|
110
|
+
Multidb.use(:replica2) do
|
71
111
|
conn = ActiveRecord::Base.connection
|
72
112
|
conn.should eq Multidb.balancer.current_connection
|
73
113
|
list = conn.execute('pragma database_list')
|
74
114
|
list.length.should eq 1
|
75
|
-
File.basename(list[0]['file']).should eq 'test-
|
115
|
+
File.basename(list[0]['file']).should eq 'test-replica2.sqlite'
|
76
116
|
end
|
77
117
|
end
|
78
118
|
end
|
79
119
|
|
80
120
|
it 'returns preserves state when nesting' do
|
81
|
-
Multidb.use(:
|
82
|
-
Multidb.use(:
|
121
|
+
Multidb.use(:replica1) do
|
122
|
+
Multidb.use(:replica2) do
|
83
123
|
conn = ActiveRecord::Base.connection
|
84
124
|
conn.should eq Multidb.balancer.current_connection
|
85
125
|
list = conn.execute('pragma database_list')
|
86
126
|
list.length.should eq 1
|
87
|
-
File.basename(list[0]['file']).should eq 'test-
|
127
|
+
File.basename(list[0]['file']).should eq 'test-replica2.sqlite'
|
88
128
|
end
|
89
129
|
|
90
130
|
conn = ActiveRecord::Base.connection
|
91
131
|
conn.should eq Multidb.balancer.current_connection
|
92
132
|
list = conn.execute('pragma database_list')
|
93
133
|
list.length.should eq 1
|
94
|
-
File.basename(list[0]['file']).should eq 'test-
|
134
|
+
File.basename(list[0]['file']).should eq 'test-replica1.sqlite'
|
95
135
|
end
|
96
136
|
end
|
97
137
|
|
138
|
+
it 'returns the parent connection for aliases' do
|
139
|
+
Multidb.use(:replica1).should_not eq Multidb.use(:replica_alias)
|
140
|
+
Multidb.use(:replica2).should eq Multidb.use(:replica_alias)
|
141
|
+
end
|
142
|
+
|
98
143
|
it 'returns random candidate' do
|
99
144
|
names = []
|
100
145
|
100.times do
|
101
|
-
Multidb.use(:
|
146
|
+
Multidb.use(:replica3) do
|
102
147
|
list = ActiveRecord::Base.connection.execute('pragma database_list')
|
103
148
|
list.length.should eq 1
|
104
149
|
names.push(File.basename(list[0]['file']))
|
105
150
|
end
|
106
151
|
end
|
107
152
|
names.sort.uniq.should eq [
|
108
|
-
'test-
|
109
|
-
'test-
|
153
|
+
'test-replica3-1.sqlite',
|
154
|
+
'test-replica3-2.sqlite'
|
110
155
|
]
|
111
156
|
end
|
112
157
|
end
|
113
158
|
end
|
114
|
-
|
115
|
-
end
|
159
|
+
end
|
data/spec/helpers.rb
CHANGED
@@ -1,20 +1,23 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
3
|
+
module Helpers
|
4
|
+
def configuration_with_replicas
|
5
|
+
YAML.safe_load(<<~YAML)
|
6
|
+
adapter: sqlite3
|
7
|
+
database: spec/test.sqlite
|
8
|
+
encoding: utf-8
|
9
|
+
multidb:
|
10
|
+
databases:
|
11
|
+
replica1:
|
12
|
+
database: spec/test-replica1.sqlite
|
13
|
+
replica2:
|
14
|
+
database: spec/test-replica2.sqlite
|
15
|
+
replica3:
|
16
|
+
- database: spec/test-replica3-1.sqlite
|
17
|
+
- database: spec/test-replica3-2.sqlite
|
18
|
+
replica_alias:
|
19
|
+
database: spec/test-replica2.sqlite
|
20
|
+
alias: replica2
|
21
|
+
YAML
|
18
22
|
end
|
19
|
-
|
20
|
-
end
|
23
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,23 +1,26 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
ENV['RACK_ENV'] ||= 'test'
|
2
4
|
|
3
5
|
require 'rspec'
|
4
6
|
require 'yaml'
|
5
7
|
require 'active_record'
|
6
8
|
require 'fileutils'
|
7
9
|
|
8
|
-
$LOAD_PATH.unshift(File.expand_path('
|
10
|
+
$LOAD_PATH.unshift(File.expand_path('lib', __dir__))
|
9
11
|
require 'multidb'
|
10
12
|
|
11
13
|
require_relative 'helpers'
|
12
14
|
|
13
15
|
RSpec.configure do |config|
|
14
16
|
config.include Helpers
|
17
|
+
config.expect_with(:rspec) { |c| c.syntax = :should }
|
15
18
|
config.before :each do
|
16
19
|
ActiveRecord::Base.clear_all_connections!
|
17
20
|
Multidb.reset!
|
18
21
|
end
|
19
22
|
config.after :each do
|
20
|
-
Dir.glob(File.expand_path('
|
23
|
+
Dir.glob(File.expand_path('test*.sqlite', __dir__)).each do |f|
|
21
24
|
FileUtils.rm(f)
|
22
25
|
end
|
23
26
|
end
|
metadata
CHANGED
@@ -1,91 +1,138 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ar-multidb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alexander Staubo
|
8
|
-
|
8
|
+
- Edward Rudd
|
9
|
+
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date:
|
12
|
+
date: 2020-07-20 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
15
|
+
name: activerecord
|
15
16
|
requirement: !ruby/object:Gem::Requirement
|
16
17
|
requirements:
|
17
|
-
- -
|
18
|
+
- - ">="
|
18
19
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
20
|
+
version: '5.1'
|
21
|
+
- - "<"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: '6.0'
|
20
24
|
type: :runtime
|
21
25
|
prerelease: false
|
22
26
|
version_requirements: !ruby/object:Gem::Requirement
|
23
27
|
requirements:
|
24
|
-
- -
|
28
|
+
- - ">="
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
version: '5.1'
|
31
|
+
- - "<"
|
25
32
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
33
|
+
version: '6.0'
|
27
34
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
35
|
+
name: activesupport
|
29
36
|
requirement: !ruby/object:Gem::Requirement
|
30
37
|
requirements:
|
31
|
-
- -
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '5.1'
|
41
|
+
- - "<"
|
32
42
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
43
|
+
version: '6.0'
|
34
44
|
type: :runtime
|
35
45
|
prerelease: false
|
36
46
|
version_requirements: !ruby/object:Gem::Requirement
|
37
47
|
requirements:
|
38
|
-
- -
|
48
|
+
- - ">="
|
39
49
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
50
|
+
version: '5.1'
|
51
|
+
- - "<"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '6.0'
|
54
|
+
- !ruby/object:Gem::Dependency
|
55
|
+
name: rake
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '12.0'
|
61
|
+
type: :development
|
62
|
+
prerelease: false
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - "~>"
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '12.0'
|
41
68
|
- !ruby/object:Gem::Dependency
|
42
69
|
name: rspec
|
43
70
|
requirement: !ruby/object:Gem::Requirement
|
44
71
|
requirements:
|
45
|
-
- -
|
72
|
+
- - "~>"
|
46
73
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
74
|
+
version: '3.8'
|
48
75
|
type: :development
|
49
76
|
prerelease: false
|
50
77
|
version_requirements: !ruby/object:Gem::Requirement
|
51
78
|
requirements:
|
52
|
-
- -
|
79
|
+
- - "~>"
|
53
80
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
81
|
+
version: '3.8'
|
82
|
+
- !ruby/object:Gem::Dependency
|
83
|
+
name: rubocop
|
84
|
+
requirement: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - "~>"
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: 0.88.0
|
89
|
+
type: :development
|
90
|
+
prerelease: false
|
91
|
+
version_requirements: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - "~>"
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: 0.88.0
|
55
96
|
- !ruby/object:Gem::Dependency
|
56
97
|
name: sqlite3
|
57
98
|
requirement: !ruby/object:Gem::Requirement
|
58
99
|
requirements:
|
59
|
-
- -
|
100
|
+
- - "~>"
|
60
101
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
102
|
+
version: '1.3'
|
62
103
|
type: :development
|
63
104
|
prerelease: false
|
64
105
|
version_requirements: !ruby/object:Gem::Requirement
|
65
106
|
requirements:
|
66
|
-
- -
|
107
|
+
- - "~>"
|
67
108
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
109
|
+
version: '1.3'
|
69
110
|
description: Multidb is an ActiveRecord extension for switching between multiple database
|
70
|
-
connections, such as
|
111
|
+
connections, such as primary/replica setups.
|
71
112
|
email:
|
72
113
|
- alex@bengler.no
|
114
|
+
- urkle@outoforder.cc
|
73
115
|
executables: []
|
74
116
|
extensions: []
|
75
117
|
extra_rdoc_files: []
|
76
118
|
files:
|
77
|
-
- .gitignore
|
78
|
-
- .
|
119
|
+
- ".gitignore"
|
120
|
+
- ".rubocop.yml"
|
121
|
+
- ".travis.yml"
|
122
|
+
- CHANGELOG.md
|
79
123
|
- Gemfile
|
80
|
-
- Gemfile.lock
|
81
124
|
- LICENSE
|
82
125
|
- README.markdown
|
83
126
|
- Rakefile
|
84
127
|
- ar-multidb.gemspec
|
128
|
+
- gemfiles/activerecord51.gemfile
|
129
|
+
- gemfiles/activerecord52.gemfile
|
85
130
|
- lib/ar-multidb.rb
|
86
131
|
- lib/multidb.rb
|
87
132
|
- lib/multidb/balancer.rb
|
133
|
+
- lib/multidb/candidate.rb
|
88
134
|
- lib/multidb/configuration.rb
|
135
|
+
- lib/multidb/log_subscriber.rb
|
89
136
|
- lib/multidb/model_extensions.rb
|
90
137
|
- lib/multidb/version.rb
|
91
138
|
- spec/balancer_spec.rb
|
@@ -94,29 +141,27 @@ files:
|
|
94
141
|
homepage: ''
|
95
142
|
licenses: []
|
96
143
|
metadata: {}
|
97
|
-
post_install_message:
|
144
|
+
post_install_message:
|
98
145
|
rdoc_options: []
|
99
146
|
require_paths:
|
100
147
|
- lib
|
101
148
|
required_ruby_version: !ruby/object:Gem::Requirement
|
102
149
|
requirements:
|
103
|
-
- -
|
150
|
+
- - ">="
|
104
151
|
- !ruby/object:Gem::Version
|
105
|
-
version:
|
152
|
+
version: 2.4.0
|
106
153
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
107
154
|
requirements:
|
108
|
-
- -
|
155
|
+
- - ">="
|
109
156
|
- !ruby/object:Gem::Version
|
110
157
|
version: '0'
|
111
158
|
requirements: []
|
112
|
-
|
113
|
-
|
114
|
-
signing_key:
|
159
|
+
rubygems_version: 3.0.6
|
160
|
+
signing_key:
|
115
161
|
specification_version: 4
|
116
162
|
summary: Multidb is an ActiveRecord extension for switching between multiple database
|
117
|
-
connections, such as
|
163
|
+
connections, such as primary/replica setups.
|
118
164
|
test_files:
|
119
165
|
- spec/balancer_spec.rb
|
120
166
|
- spec/helpers.rb
|
121
167
|
- spec/spec_helper.rb
|
122
|
-
has_rdoc:
|
data/Gemfile.lock
DELETED
@@ -1,54 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
ar-multidb (0.1.11)
|
5
|
-
activerecord (>= 3.0)
|
6
|
-
activesupport (>= 3.0)
|
7
|
-
|
8
|
-
GEM
|
9
|
-
remote: http://rubygems.org/
|
10
|
-
specs:
|
11
|
-
activemodel (4.0.2)
|
12
|
-
activesupport (= 4.0.2)
|
13
|
-
builder (~> 3.1.0)
|
14
|
-
activerecord (4.0.2)
|
15
|
-
activemodel (= 4.0.2)
|
16
|
-
activerecord-deprecated_finders (~> 1.0.2)
|
17
|
-
activesupport (= 4.0.2)
|
18
|
-
arel (~> 4.0.0)
|
19
|
-
activerecord-deprecated_finders (1.0.3)
|
20
|
-
activesupport (4.0.2)
|
21
|
-
i18n (~> 0.6, >= 0.6.4)
|
22
|
-
minitest (~> 4.2)
|
23
|
-
multi_json (~> 1.3)
|
24
|
-
thread_safe (~> 0.1)
|
25
|
-
tzinfo (~> 0.3.37)
|
26
|
-
arel (4.0.1)
|
27
|
-
atomic (1.1.14)
|
28
|
-
builder (3.1.4)
|
29
|
-
diff-lcs (1.2.5)
|
30
|
-
i18n (0.6.9)
|
31
|
-
minitest (4.7.5)
|
32
|
-
multi_json (1.8.4)
|
33
|
-
rake (10.1.1)
|
34
|
-
rspec (2.14.1)
|
35
|
-
rspec-core (~> 2.14.0)
|
36
|
-
rspec-expectations (~> 2.14.0)
|
37
|
-
rspec-mocks (~> 2.14.0)
|
38
|
-
rspec-core (2.14.7)
|
39
|
-
rspec-expectations (2.14.5)
|
40
|
-
diff-lcs (>= 1.1.3, < 2.0)
|
41
|
-
rspec-mocks (2.14.5)
|
42
|
-
sqlite3 (1.3.8)
|
43
|
-
thread_safe (0.1.3)
|
44
|
-
atomic
|
45
|
-
tzinfo (0.3.38)
|
46
|
-
|
47
|
-
PLATFORMS
|
48
|
-
ruby
|
49
|
-
|
50
|
-
DEPENDENCIES
|
51
|
-
ar-multidb!
|
52
|
-
rake
|
53
|
-
rspec
|
54
|
-
sqlite3
|