active_record_shards 2.8.0 → 3.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/active_record_shards/arel_engine.rb +13 -0
- data/lib/active_record_shards/connection_handler.rb +11 -0
- data/lib/active_record_shards/connection_pool.rb +27 -50
- data/lib/active_record_shards/connection_specification.rb +7 -3
- data/lib/active_record_shards/connection_switcher.rb +14 -4
- data/lib/active_record_shards/default_slave_patches.rb +46 -35
- data/lib/active_record_shards.rb +25 -4
- data/test/connection_switching_test.rb +16 -22
- data/test/models.rb +0 -2
- data/test/schema.rb +0 -5
- metadata +12 -15
@@ -0,0 +1,13 @@
|
|
1
|
+
if ActiveRecord::VERSION::MAJOR == 3 && ActiveRecord::VERSION::MINOR == 0
|
2
|
+
class ActiveRecord::Base
|
3
|
+
def self.arel_engine
|
4
|
+
@arel_engine ||= begin
|
5
|
+
if self == ActiveRecord::Base
|
6
|
+
Arel::Table.engine
|
7
|
+
else
|
8
|
+
connection_handler.connection_pools[connection_pool_name] ? self : superclass.arel_engine
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
ActiveRecord::ConnectionAdapters::ConnectionHandler.class_eval do
|
2
|
+
if ActiveRecord::VERSION::MAJOR >= 4
|
3
|
+
def retrieve_connection_pool(klass)
|
4
|
+
class_to_pool[klass.connection_pool_name] ||= pool_for(klass)
|
5
|
+
end
|
6
|
+
else
|
7
|
+
def retrieve_connection_pool(klass)
|
8
|
+
(@class_to_pool || @connection_pools)[klass.connection_pool_name]
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -1,55 +1,32 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
# instead of klass.name as the pool key
|
4
|
-
def retrieve_connection_pool(klass)
|
5
|
-
pool = (@class_to_pool || @connection_pools)[klass.connection_pool_name]
|
6
|
-
return pool if pool
|
7
|
-
return nil if ActiveRecord::Base == klass
|
8
|
-
retrieve_connection_pool klass.superclass
|
9
|
-
end
|
10
|
-
|
11
|
-
def remove_connection(klass)
|
12
|
-
# rails 2: @connection_pools is a hash of klass.name => pool
|
13
|
-
# rails 3: @connection_pools is a hash of pool.spec => pool
|
14
|
-
# @class_to_pool is a hash of klass.name => pool
|
15
|
-
#
|
16
|
-
if @class_to_pool
|
17
|
-
pool = @class_to_pool.delete(klass.connection_pool_name)
|
18
|
-
@connection_pools.delete(pool.spec) if pool
|
19
|
-
else
|
20
|
-
pool = @connection_pools.delete(klass.connection_pool_name)
|
21
|
-
@connection_pools.delete_if { |key, value| value == pool }
|
22
|
-
end
|
23
|
-
|
24
|
-
return nil unless pool
|
25
|
-
|
26
|
-
pool.disconnect! if pool
|
27
|
-
pool.spec.config if pool
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
ActiveRecord::Base.singleton_class.class_eval do
|
32
|
-
def establish_connection_with_connection_pool_name(spec = nil)
|
33
|
-
case spec
|
34
|
-
when ActiveRecord::Base::ConnectionSpecification
|
35
|
-
connection_handler.establish_connection(connection_pool_name, spec)
|
36
|
-
else
|
37
|
-
establish_connection_without_connection_pool_name(spec)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
alias_method_chain :establish_connection, :connection_pool_name
|
41
|
-
end
|
1
|
+
module ActiveRecordShards
|
2
|
+
ConnectionPoolNameDecorator = Struct.new(:name)
|
42
3
|
|
43
|
-
#
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
4
|
+
# It overrides given connection handler methods (they differ depend on
|
5
|
+
# Rails version).
|
6
|
+
#
|
7
|
+
# It takes the first argument, ActiveRecord::Base object or
|
8
|
+
# String (connection_pool_name), converts it in Struct object and
|
9
|
+
# passes to the original method.
|
10
|
+
#
|
11
|
+
# Example:
|
12
|
+
# methods_to_override = [:establish_connection, :remove_connection]
|
13
|
+
# ActiveRecordShards.override_connection_handler_methods(methods_to_override)
|
14
|
+
#
|
15
|
+
def self.override_connection_handler_methods(method_names)
|
16
|
+
method_names.each do |method_name|
|
17
|
+
ActiveRecord::ConnectionAdapters::ConnectionHandler.class_eval do
|
18
|
+
define_method("#{method_name}_with_connection_pool_name") do |*args|
|
19
|
+
unless args[0].is_a? ConnectionPoolNameDecorator
|
20
|
+
name = if args[0].is_a? String
|
21
|
+
args[0]
|
22
|
+
else
|
23
|
+
args[0].connection_pool_name
|
24
|
+
end
|
25
|
+
args[0] = ConnectionPoolNameDecorator.new(name)
|
26
|
+
end
|
27
|
+
send("#{method_name}_without_connection_pool_name", *args)
|
52
28
|
end
|
29
|
+
alias_method_chain method_name, :connection_pool_name
|
53
30
|
end
|
54
31
|
end
|
55
32
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
class ActiveRecord::Base
|
2
|
-
|
3
2
|
def self.establish_connection(spec = ENV["DATABASE_URL"])
|
4
|
-
resolver = ConnectionSpecification::Resolver.new spec, configurations
|
3
|
+
resolver = ActiveRecordShards::ConnectionSpecification::Resolver.new spec, configurations
|
5
4
|
spec = resolver.spec
|
6
5
|
|
7
6
|
unless respond_to?(spec.adapter_method)
|
@@ -10,6 +9,11 @@ class ActiveRecord::Base
|
|
10
9
|
|
11
10
|
remove_connection
|
12
11
|
specification_cache[connection_pool_name] = spec
|
13
|
-
|
12
|
+
|
13
|
+
if ActiveRecord::VERSION::STRING >= "4.0.0"
|
14
|
+
connection_handler.establish_connection self, spec
|
15
|
+
else
|
16
|
+
connection_handler.establish_connection connection_pool_name, spec
|
17
|
+
end
|
14
18
|
end
|
15
19
|
end
|
@@ -95,7 +95,11 @@ module ActiveRecordShards
|
|
95
95
|
if self == ActiveRecord::Base || !switch_to_slave || options[:construct_ro_scope] == false
|
96
96
|
yield
|
97
97
|
else
|
98
|
-
|
98
|
+
if ActiveRecord::VERSION::MAJOR == 2
|
99
|
+
with_scope({:find => {:readonly => true}}, &block)
|
100
|
+
else
|
101
|
+
readonly.scoping(&block)
|
102
|
+
end
|
99
103
|
end
|
100
104
|
ensure
|
101
105
|
@disallow_slave -= 1 if which == :master
|
@@ -174,11 +178,11 @@ module ActiveRecordShards
|
|
174
178
|
# connection adapter ourselves.
|
175
179
|
specification_cache[name] ||= begin
|
176
180
|
if ActiveRecord::VERSION::STRING >= "3.2.0"
|
177
|
-
resolver =
|
181
|
+
resolver = ActiveRecordShards::ConnectionSpecification::Resolver.new spec, configurations
|
178
182
|
resolver.spec
|
179
183
|
else
|
180
184
|
autoload_adapter(spec['adapter'])
|
181
|
-
|
185
|
+
ActiveRecordShards::ConnectionSpecification.new(spec, "#{spec['adapter']}_connection")
|
182
186
|
end
|
183
187
|
end
|
184
188
|
|
@@ -198,7 +202,13 @@ module ActiveRecordShards
|
|
198
202
|
end
|
199
203
|
|
200
204
|
def connected_to_shard?
|
201
|
-
|
205
|
+
if ActiveRecord::VERSION::MAJOR == 4
|
206
|
+
specs_to_pools = Hash[connection_handler.connection_pool_list.map { |pool| [pool.spec, pool] }]
|
207
|
+
else
|
208
|
+
specs_to_pools = connection_handler.connection_pools
|
209
|
+
end
|
210
|
+
|
211
|
+
specs_to_pools.has_key?(connection_pool_key)
|
202
212
|
end
|
203
213
|
|
204
214
|
def columns_with_default_shard
|
@@ -1,32 +1,23 @@
|
|
1
1
|
module ActiveRecordShards
|
2
2
|
module DefaultSlavePatches
|
3
|
-
|
3
|
+
CLASS_SLAVE_METHODS = [ :find_by_sql, :count_by_sql, :calculate, :find_one, :find_some, :find_every, :quote_value, :sanitize_sql_hash_for_conditions, :exists? ]
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
def #{method}_with_default_slave#{punctuation}(*args, &block)
|
16
|
-
on_slave_unless_tx do
|
17
|
-
#{method}_without_default_slave#{punctuation}(*args, &block)
|
5
|
+
def self.extended(base)
|
6
|
+
base_methods = (base.methods | base.private_methods).map(&:to_sym)
|
7
|
+
(CLASS_SLAVE_METHODS & base_methods).each do |slave_method|
|
8
|
+
_, slave_method, punctuation = slave_method.to_s.match(/^(.*?)([\?\!]?)$/).to_a
|
9
|
+
base.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
10
|
+
class << self
|
11
|
+
def #{slave_method}_with_default_slave#{punctuation}(*args, &block)
|
12
|
+
on_slave_unless_tx do
|
13
|
+
#{slave_method}_without_default_slave#{punctuation}(*args, &block)
|
14
|
+
end
|
18
15
|
end
|
19
|
-
end
|
20
|
-
|
21
|
-
alias_method_chain :#{method}#{punctuation}, :default_slave
|
22
|
-
#{class_method ? "end" : ""}
|
23
|
-
RUBY
|
24
|
-
end
|
25
16
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
17
|
+
alias_method_chain :#{slave_method}#{punctuation}, :default_slave
|
18
|
+
end
|
19
|
+
RUBY
|
20
|
+
end
|
30
21
|
|
31
22
|
base.class_eval do
|
32
23
|
# fix ActiveRecord to do the right thing, and use our aliased quote_value
|
@@ -67,10 +58,33 @@ module ActiveRecordShards
|
|
67
58
|
end
|
68
59
|
|
69
60
|
alias_method_chain :transaction, :slave_off
|
61
|
+
|
62
|
+
|
63
|
+
def table_exists_with_default_slave?(*args)
|
64
|
+
on_slave_unless_tx(*args) { table_exists_without_default_slave?(*args) }
|
65
|
+
end
|
66
|
+
|
67
|
+
alias_method_chain :table_exists?, :default_slave
|
70
68
|
end
|
71
69
|
end
|
72
|
-
|
73
|
-
|
70
|
+
|
71
|
+
|
72
|
+
ActiveRecord::Associations::HasAndBelongsToManyAssociation.class_eval do
|
73
|
+
def construct_sql_with_default_slave(*args, &block)
|
74
|
+
on_slave_unless_tx do
|
75
|
+
construct_sql_without_default_slave(*args, &block)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def construct_find_options_with_default_slave!(*args, &block)
|
80
|
+
on_slave_unless_tx do
|
81
|
+
construct_find_options_without_default_slave!(*args, &block)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
alias_method_chain :construct_sql, :default_slave if respond_to?(:construct_sql)
|
86
|
+
alias_method_chain :construct_find_options!, :default_slave if respond_to?(:construct_find_options!)
|
87
|
+
end
|
74
88
|
end
|
75
89
|
|
76
90
|
def on_slave_unless_tx(&block)
|
@@ -83,23 +97,20 @@ module ActiveRecordShards
|
|
83
97
|
|
84
98
|
module ActiveRelationPatches
|
85
99
|
def self.included(base)
|
86
|
-
|
87
|
-
|
88
|
-
ActiveRecordShards::DefaultSlavePatches.wrap_method_in_on_slave(false, base, :pluck)
|
100
|
+
base.send :alias_method_chain, :calculate, :default_slave
|
101
|
+
base.send :alias_method_chain, :exists?, :default_slave
|
89
102
|
end
|
90
103
|
|
91
104
|
def on_slave_unless_tx
|
92
105
|
@klass.on_slave_unless_tx { yield }
|
93
106
|
end
|
94
|
-
end
|
95
107
|
|
96
|
-
|
97
|
-
|
98
|
-
ActiveRecordShards::DefaultSlavePatches.wrap_method_in_on_slave(false, base, :records_for) rescue nil
|
108
|
+
def calculate_with_default_slave(*args, &block)
|
109
|
+
on_slave_unless_tx { calculate_without_default_slave(*args, &block) }
|
99
110
|
end
|
100
111
|
|
101
|
-
def
|
102
|
-
|
112
|
+
def exists_with_default_slave?(*args, &block)
|
113
|
+
on_slave_unless_tx { exists_without_default_slave?(*args, &block) }
|
103
114
|
end
|
104
115
|
end
|
105
116
|
end
|
data/lib/active_record_shards.rb
CHANGED
@@ -8,11 +8,24 @@ require 'active_record_shards/association_collection_connection_selection'
|
|
8
8
|
require 'active_record_shards/connection_pool'
|
9
9
|
require 'active_record_shards/migration'
|
10
10
|
require 'active_record_shards/default_slave_patches'
|
11
|
+
require 'active_record_shards/arel_engine'
|
12
|
+
require 'active_record_shards/connection_handler'
|
11
13
|
|
12
14
|
if ActiveRecord::VERSION::STRING >= "3.2.0"
|
13
15
|
require 'active_record_shards/connection_specification'
|
14
16
|
end
|
15
17
|
|
18
|
+
if ActiveRecord::VERSION::STRING >= "4.0.0"
|
19
|
+
methods_to_override = [:establish_connection, :remove_connection, :pool_for,
|
20
|
+
:pool_from_any_process_for]
|
21
|
+
ActiveRecordShards::ConnectionSpecification = ActiveRecord::ConnectionAdapters::ConnectionSpecification
|
22
|
+
else
|
23
|
+
methods_to_override = [:remove_connection]
|
24
|
+
ActiveRecordShards::ConnectionSpecification = ActiveRecord::Base::ConnectionSpecification
|
25
|
+
end
|
26
|
+
|
27
|
+
ActiveRecordShards.override_connection_handler_methods(methods_to_override)
|
28
|
+
|
16
29
|
ActiveRecord::Base.extend(ActiveRecordShards::ConfigurationParser)
|
17
30
|
ActiveRecord::Base.extend(ActiveRecordShards::Model)
|
18
31
|
ActiveRecord::Base.extend(ActiveRecordShards::ConnectionSwitcher)
|
@@ -22,10 +35,6 @@ if ActiveRecord.const_defined?(:Relation)
|
|
22
35
|
ActiveRecord::Relation.send(:include, ActiveRecordShards::DefaultSlavePatches::ActiveRelationPatches)
|
23
36
|
end
|
24
37
|
|
25
|
-
if ActiveRecord::Associations.const_defined?(:Preloader)
|
26
|
-
ActiveRecord::Associations::Preloader::HasAndBelongsToMany.send(:include, ActiveRecordShards::DefaultSlavePatches::HasAndBelongsToManyPreloaderPatches)
|
27
|
-
end
|
28
|
-
|
29
38
|
if ActiveRecord::VERSION::STRING >= "3.1.0"
|
30
39
|
ActiveRecord::Associations::CollectionProxy.send(:include, ActiveRecordShards::AssociationCollectionConnectionSelection)
|
31
40
|
else
|
@@ -39,3 +48,15 @@ module ActiveRecordShards
|
|
39
48
|
env ||= ENV['RAILS_ENV']
|
40
49
|
end
|
41
50
|
end
|
51
|
+
|
52
|
+
ActiveRecord::Base.singleton_class.class_eval do
|
53
|
+
def establish_connection_with_connection_pool_name(spec = nil)
|
54
|
+
case spec
|
55
|
+
when ActiveRecordShards::ConnectionSpecification
|
56
|
+
connection_handler.establish_connection(connection_pool_name, spec)
|
57
|
+
else
|
58
|
+
establish_connection_without_connection_pool_name(spec)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
alias_method_chain :establish_connection, :connection_pool_name
|
62
|
+
end
|
@@ -233,7 +233,6 @@ describe "connection switching" do
|
|
233
233
|
end
|
234
234
|
|
235
235
|
it "execute the block on all shard masters" do
|
236
|
-
@database_names
|
237
236
|
assert_equal([ActiveRecord::Base.connection.select_value("SELECT DATABASE()")], @database_names)
|
238
237
|
end
|
239
238
|
end
|
@@ -244,7 +243,11 @@ describe "connection switching" do
|
|
244
243
|
|
245
244
|
before do
|
246
245
|
ActiveRecord::Base.configurations.delete('test_slave')
|
247
|
-
ActiveRecord::
|
246
|
+
if ActiveRecord::VERSION::MAJOR == 4
|
247
|
+
ActiveRecord::Base.connection_handler.connection_pool_list.clear
|
248
|
+
else
|
249
|
+
ActiveRecord::Base.connection_handler.connection_pools.clear
|
250
|
+
end
|
248
251
|
ActiveRecord::Base.establish_connection('test')
|
249
252
|
end
|
250
253
|
|
@@ -380,19 +383,13 @@ describe "connection switching" do
|
|
380
383
|
end
|
381
384
|
end
|
382
385
|
|
386
|
+
# TODO: make all this stuff rails 3 compatible.
|
383
387
|
describe "with finds routed to the slave by default" do
|
384
388
|
before do
|
385
389
|
Account.on_slave_by_default = true
|
386
|
-
Person.on_slave_by_default = true
|
387
390
|
Account.connection.execute("INSERT INTO accounts (id, name, created_at, updated_at) VALUES(1000, 'master_name', '2009-12-04 20:18:48', '2009-12-04 20:18:48')")
|
388
391
|
Account.on_slave.connection.execute("INSERT INTO accounts (id, name, created_at, updated_at) VALUES(1000, 'slave_name', '2009-12-04 20:18:48', '2009-12-04 20:18:48')")
|
389
392
|
Account.on_slave.connection.execute("INSERT INTO accounts (id, name, created_at, updated_at) VALUES(1001, 'slave_name2', '2009-12-04 20:18:48', '2009-12-04 20:18:48')")
|
390
|
-
|
391
|
-
Person.connection.execute("REPLACE INTO people(id, name) VALUES(10, 'master person')")
|
392
|
-
Person.on_slave.connection.execute("REPLACE INTO people(id, name) VALUES(20, 'slave person')")
|
393
|
-
|
394
|
-
Account.connection.execute("INSERT INTO account_people(account_id, person_id) VALUES(1000, 10)")
|
395
|
-
Account.on_slave.connection.execute("INSERT INTO account_people(account_id, person_id) VALUES(1001, 20)")
|
396
393
|
end
|
397
394
|
|
398
395
|
it "find() by default on the slave" do
|
@@ -451,21 +448,8 @@ describe "connection switching" do
|
|
451
448
|
assert AccountInherited.on_slave_by_default?
|
452
449
|
end
|
453
450
|
|
454
|
-
it "will :include things via has_and_belongs associations correctly" do
|
455
|
-
a = Account.first(:conditions => "id = 1001", :include => :people)
|
456
|
-
assert a.people.size > 0
|
457
|
-
assert_equal 'slave person', a.people.first.name
|
458
|
-
end
|
459
|
-
|
460
|
-
if ActiveRecord::VERSION::MAJOR >= 3 && ActiveRecord::VERSION::MINOR >= 2
|
461
|
-
it "supports .pluck" do
|
462
|
-
assert_equal ["slave_name", "slave_name2"], Account.pluck(:name)
|
463
|
-
end
|
464
|
-
end
|
465
|
-
|
466
451
|
after do
|
467
452
|
Account.on_slave_by_default = false
|
468
|
-
Person.on_slave_by_default = false
|
469
453
|
end
|
470
454
|
end
|
471
455
|
end
|
@@ -518,4 +502,14 @@ describe "connection switching" do
|
|
518
502
|
assert_using_database('ars_test_alternative', Email)
|
519
503
|
end
|
520
504
|
end
|
505
|
+
|
506
|
+
it "raises an exception if a connection is not found" do
|
507
|
+
ActiveRecord::Base.on_shard(0) do
|
508
|
+
ActiveRecord::Base.connection_handler.remove_connection(Ticket)
|
509
|
+
assert_raises(ActiveRecord::ConnectionNotEstablished) do
|
510
|
+
ActiveRecord::Base.connection_handler.retrieve_connection_pool(Ticket)
|
511
|
+
assert_using_database('ars_test_shard0', Ticket)
|
512
|
+
end
|
513
|
+
end
|
514
|
+
end
|
521
515
|
end
|
data/test/models.rb
CHANGED
@@ -4,7 +4,6 @@ class Account < ActiveRecord::Base
|
|
4
4
|
|
5
5
|
has_many :tickets
|
6
6
|
has_many :account_things
|
7
|
-
has_and_belongs_to_many :people, :join_table => 'account_people'
|
8
7
|
end
|
9
8
|
|
10
9
|
class AccountThing < ActiveRecord::Base
|
@@ -37,4 +36,3 @@ end
|
|
37
36
|
class User < Person
|
38
37
|
end
|
39
38
|
|
40
|
-
|
data/test/schema.rb
CHANGED
@@ -12,11 +12,6 @@ ActiveRecord::Schema.define(:version => 1) do
|
|
12
12
|
t.boolean "enabled", :default => true
|
13
13
|
end
|
14
14
|
|
15
|
-
create_table "account_people", :force => true, :id => false do |t|
|
16
|
-
t.integer "account_id"
|
17
|
-
t.integer "person_id"
|
18
|
-
end
|
19
|
-
|
20
15
|
create_table "emails", :force => true do |t|
|
21
16
|
t.string "from"
|
22
17
|
t.string "to"
|
metadata
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_record_shards
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
5
|
-
prerelease:
|
4
|
+
version: 3.0.0.beta1
|
5
|
+
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Mick Staugaard
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2013-11-
|
14
|
+
date: 2013-11-06 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: activerecord
|
@@ -21,9 +21,9 @@ dependencies:
|
|
21
21
|
- - ! '>='
|
22
22
|
- !ruby/object:Gem::Version
|
23
23
|
version: 2.3.5
|
24
|
-
- -
|
24
|
+
- - <=
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '4.1'
|
27
27
|
type: :runtime
|
28
28
|
prerelease: false
|
29
29
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -32,9 +32,9 @@ dependencies:
|
|
32
32
|
- - ! '>='
|
33
33
|
- !ruby/object:Gem::Version
|
34
34
|
version: 2.3.5
|
35
|
-
- -
|
35
|
+
- - <=
|
36
36
|
- !ruby/object:Gem::Version
|
37
|
-
version: '
|
37
|
+
version: '4.1'
|
38
38
|
description: Easily run queries on shard and slave databases.
|
39
39
|
email:
|
40
40
|
- mick@staugaard.com
|
@@ -44,8 +44,10 @@ executables: []
|
|
44
44
|
extensions: []
|
45
45
|
extra_rdoc_files: []
|
46
46
|
files:
|
47
|
+
- lib/active_record_shards/arel_engine.rb
|
47
48
|
- lib/active_record_shards/association_collection_connection_selection.rb
|
48
49
|
- lib/active_record_shards/configuration_parser.rb
|
50
|
+
- lib/active_record_shards/connection_handler.rb
|
49
51
|
- lib/active_record_shards/connection_pool.rb
|
50
52
|
- lib/active_record_shards/connection_specification.rb
|
51
53
|
- lib/active_record_shards/connection_switcher.rb
|
@@ -81,18 +83,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
81
83
|
- - ! '>='
|
82
84
|
- !ruby/object:Gem::Version
|
83
85
|
version: '0'
|
84
|
-
segments:
|
85
|
-
- 0
|
86
|
-
hash: -479183148352030802
|
87
86
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
88
87
|
none: false
|
89
88
|
requirements:
|
90
|
-
- - ! '
|
89
|
+
- - ! '>'
|
91
90
|
- !ruby/object:Gem::Version
|
92
|
-
version:
|
93
|
-
segments:
|
94
|
-
- 0
|
95
|
-
hash: -479183148352030802
|
91
|
+
version: 1.3.1
|
96
92
|
requirements: []
|
97
93
|
rubyforge_project:
|
98
94
|
rubygems_version: 1.8.25
|
@@ -112,3 +108,4 @@ test_files:
|
|
112
108
|
- test/migrator_test.rb
|
113
109
|
- test/models.rb
|
114
110
|
- test/schema.rb
|
111
|
+
has_rdoc:
|