active_record_shards 3.5.0.pre.alpha → 3.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +6 -7
- data/lib/active_record_shards.rb +14 -13
- data/lib/active_record_shards/configuration_parser.rb +6 -7
- data/lib/active_record_shards/connection_pool.rb +11 -12
- data/lib/active_record_shards/connection_specification.rb +1 -1
- data/lib/active_record_shards/connection_switcher.rb +22 -21
- data/lib/active_record_shards/default_slave_patches.rb +48 -61
- data/lib/active_record_shards/migration.rb +20 -16
- metadata +11 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9adfc3476e718a0178c8781868e0ef96fc77bc85
|
4
|
+
data.tar.gz: 678e2b636c88a52d427236523c417b67d32bc3e1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 84e2df24248d209b3dcca3a6942064a84cbfabc2b2ef4afdbad24e4350b5ceca876d84e8ceec00b6821cca4c939e7aad2313fda4e06e39df0164c1dc997c188f
|
7
|
+
data.tar.gz: 678577457e7212e8b36c5498c0c5416a781fa0bffc31d49cd36085b0f6f4a1d7d9b09f592a13944a2df815b06578ae00d14827c704f8529cf7961267e926fb03
|
data/README.md
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
ActiveRecord Shards is an extension for ActiveRecord that provides support for sharded database and slaves. Basically it is just a nice way to
|
4
4
|
switch between database connections. We've made the implementation very small, and have tried not to reinvent any wheels already present in ActiveRecord.
|
5
5
|
|
6
|
-
ActiveRecord Shards has used and tested on Rails 3.
|
6
|
+
ActiveRecord Shards has used and tested on Rails 3.2.x, 4.0.x, 4.1.x and 4.2.x and has in some form or another been used in production on a large rails app for
|
7
7
|
more than a year.
|
8
8
|
|
9
9
|
## Installation
|
@@ -47,10 +47,10 @@ All the models that live on the shared database must be marked as not\_sharded:
|
|
47
47
|
|
48
48
|
class Account < ActiveRecord::Base
|
49
49
|
not_sharded
|
50
|
-
|
50
|
+
|
51
51
|
has_many :projects
|
52
52
|
end
|
53
|
-
|
53
|
+
|
54
54
|
class Project < ActiveRecord::Base
|
55
55
|
belongs_to :account
|
56
56
|
end
|
@@ -62,10 +62,10 @@ in a rack middleware and switch to the right shard:
|
|
62
62
|
def initialize(app)
|
63
63
|
@app = app
|
64
64
|
end
|
65
|
-
|
65
|
+
|
66
66
|
def call(env)
|
67
67
|
account = lookup_account(env)
|
68
|
-
|
68
|
+
|
69
69
|
if account
|
70
70
|
ActiveRecord::Base.on_shard(account.shard_id) do
|
71
71
|
@app.call(env)
|
@@ -74,7 +74,7 @@ in a rack middleware and switch to the right shard:
|
|
74
74
|
@app.call(env)
|
75
75
|
end
|
76
76
|
end
|
77
|
-
|
77
|
+
|
78
78
|
def lookup_account(env)
|
79
79
|
...
|
80
80
|
end
|
@@ -98,4 +98,3 @@ Copyright (c) 2011 Zendesk. See LICENSE for details.
|
|
98
98
|
Mick Staugaard, Eric Chapweske
|
99
99
|
|
100
100
|
[![Build Status](https://secure.travis-ci.org/osheroff/active_record_shards.png)](http://travis-ci.org/osheroff/active_record_shards)
|
101
|
-
|
data/lib/active_record_shards.rb
CHANGED
@@ -33,16 +33,16 @@ if ActiveRecord.const_defined?(:Relation)
|
|
33
33
|
end
|
34
34
|
|
35
35
|
if ActiveRecord::Associations.const_defined?(:Preloader) && ActiveRecord::Associations::Preloader.const_defined?(:HasAndBelongsToMany)
|
36
|
-
ActiveRecord::Associations::Preloader::HasAndBelongsToMany.send(:
|
36
|
+
ActiveRecord::Associations::Preloader::HasAndBelongsToMany.send(:prepend, ActiveRecordShards::DefaultSlavePatches::HasAndBelongsToManyPreloaderPatches)
|
37
37
|
end
|
38
38
|
|
39
|
-
if ActiveRecord::VERSION::
|
40
|
-
ActiveRecord::Associations::Builder::HasAndBelongsToMany.send(:
|
39
|
+
if ActiveRecord::VERSION::STRING >= '4.1.0'
|
40
|
+
ActiveRecord::Associations::Builder::HasAndBelongsToMany.send(:prepend, ActiveRecordShards::DefaultSlavePatches::Rails41HasAndBelongsToManyBuilderExtension)
|
41
41
|
end
|
42
42
|
|
43
43
|
ActiveRecord::Associations::CollectionProxy.send(:include, ActiveRecordShards::AssociationCollectionConnectionSelection)
|
44
44
|
|
45
|
-
if ActiveRecord::VERSION::MAJOR >= 4
|
45
|
+
if ActiveRecord::VERSION::MAJOR >= 4
|
46
46
|
ActiveRecord::SchemaDumper.send(:prepend, ActiveRecordShards::SchemaDumperExtension)
|
47
47
|
end
|
48
48
|
|
@@ -53,16 +53,17 @@ module ActiveRecordShards
|
|
53
53
|
env ||= ENV['RAILS_ENV']
|
54
54
|
env ||= 'development'
|
55
55
|
end
|
56
|
-
end
|
57
56
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
57
|
+
module ActiveRecordConnectionPoolName
|
58
|
+
def establish_connection(spec = nil)
|
59
|
+
case spec
|
60
|
+
when ActiveRecordShards::ConnectionSpecification
|
61
|
+
connection_handler.establish_connection(connection_pool_name, spec)
|
62
|
+
else
|
63
|
+
super
|
64
|
+
end
|
65
65
|
end
|
66
66
|
end
|
67
|
-
alias_method_chain :establish_connection, :connection_pool_name
|
68
67
|
end
|
68
|
+
|
69
|
+
ActiveRecord::Base.singleton_class.send(:prepend, ActiveRecordShards::ActiveRecordConnectionPoolName)
|
@@ -35,16 +35,15 @@ module ActiveRecordShards
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
-
|
39
|
-
|
38
|
+
module PrependMethods
|
39
|
+
def configurations=(conf)
|
40
|
+
super(explode(conf))
|
41
|
+
end
|
40
42
|
end
|
41
43
|
|
42
44
|
def ConfigurationParser.extended(klass)
|
43
|
-
klass.singleton_class.
|
44
|
-
|
45
|
-
if !klass.configurations.nil? && !klass.configurations.empty?
|
46
|
-
klass.configurations = klass.configurations
|
47
|
-
end
|
45
|
+
klass.singleton_class.send(:prepend, PrependMethods)
|
46
|
+
klass.configurations = klass.configurations if klass.configurations.present?
|
48
47
|
end
|
49
48
|
end
|
50
49
|
end
|
@@ -13,21 +13,20 @@ module ActiveRecordShards
|
|
13
13
|
# ActiveRecordShards.override_connection_handler_methods(methods_to_override)
|
14
14
|
#
|
15
15
|
def self.override_connection_handler_methods(method_names)
|
16
|
+
injected_module = Module.new
|
16
17
|
method_names.each do |method_name|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
args[0] = ConnectionPoolNameDecorator.new(name)
|
26
|
-
end
|
27
|
-
send("#{method_name}_without_connection_pool_name", *args)
|
18
|
+
injected_module.send(:define_method, method_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)
|
28
26
|
end
|
29
|
-
|
27
|
+
super(*args)
|
30
28
|
end
|
31
29
|
end
|
30
|
+
ActiveRecord::ConnectionAdapters::ConnectionHandler.send(:prepend, injected_module)
|
32
31
|
end
|
33
32
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
class ActiveRecord::Base
|
2
2
|
def self.establish_connection(spec = ENV["DATABASE_URL"])
|
3
|
-
if ActiveRecord::VERSION::
|
3
|
+
if ActiveRecord::VERSION::STRING >= '4.1.0'
|
4
4
|
spec ||= ActiveRecord::ConnectionHandling::DEFAULT_ENV.call
|
5
5
|
spec = spec.to_sym if spec.is_a?(String)
|
6
6
|
resolver = ActiveRecordShards::ConnectionSpecification::Resolver.new configurations
|
@@ -4,9 +4,28 @@ module ActiveRecordShards
|
|
4
4
|
module ConnectionSwitcher
|
5
5
|
SHARD_NAMES_CONFIG_KEY = 'shard_names'.freeze
|
6
6
|
|
7
|
+
module PrependMethods
|
8
|
+
def columns
|
9
|
+
if is_sharded? && current_shard_id.nil? && table_name != ActiveRecord::Migrator.schema_migrations_table_name
|
10
|
+
on_first_shard { super }
|
11
|
+
else
|
12
|
+
super
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def table_exists?
|
17
|
+
result = super()
|
18
|
+
|
19
|
+
if !result && is_sharded? && (shard_name = shard_names.first)
|
20
|
+
result = on_shard(shard_name) { super }
|
21
|
+
end
|
22
|
+
|
23
|
+
result
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
7
27
|
def self.extended(klass)
|
8
|
-
klass.singleton_class.
|
9
|
-
klass.singleton_class.alias_method_chain :table_exists?, :default_shard
|
28
|
+
klass.singleton_class.send(:prepend, ActiveRecordShards::ConnectionSwitcher::PrependMethods)
|
10
29
|
end
|
11
30
|
|
12
31
|
def default_shard=(new_default_shard)
|
@@ -181,7 +200,7 @@ module ActiveRecordShards
|
|
181
200
|
# note that since we're subverting the standard establish_connection path, we have to handle the funky autoloading of the
|
182
201
|
# connection adapter ourselves.
|
183
202
|
specification_cache[name] ||= begin
|
184
|
-
if ActiveRecord::VERSION::
|
203
|
+
if ActiveRecord::VERSION::STRING >= '4.1.0'
|
185
204
|
resolver = ActiveRecordShards::ConnectionSpecification::Resolver.new configurations
|
186
205
|
resolver.spec(spec)
|
187
206
|
else
|
@@ -215,24 +234,6 @@ module ActiveRecordShards
|
|
215
234
|
specs_to_pools.has_key?(connection_pool_key)
|
216
235
|
end
|
217
236
|
|
218
|
-
def columns_with_default_shard
|
219
|
-
if is_sharded? && current_shard_id.nil? && table_name != ActiveRecord::Migrator.schema_migrations_table_name
|
220
|
-
on_first_shard { columns_without_default_shard }
|
221
|
-
else
|
222
|
-
columns_without_default_shard
|
223
|
-
end
|
224
|
-
end
|
225
|
-
|
226
|
-
def table_exists_with_default_shard?
|
227
|
-
result = table_exists_without_default_shard?
|
228
|
-
|
229
|
-
if !result && is_sharded? && (shard_name = shard_names.first)
|
230
|
-
result = on_shard(shard_name) { table_exists_without_default_shard? }
|
231
|
-
end
|
232
|
-
|
233
|
-
result
|
234
|
-
end
|
235
|
-
|
236
237
|
def autoload_adapter(adapter_name)
|
237
238
|
begin
|
238
239
|
require 'rubygems'
|
@@ -9,66 +9,59 @@ module ActiveRecordShards
|
|
9
9
|
end
|
10
10
|
|
11
11
|
return unless base_methods.include?(method)
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
end
|
20
|
-
|
21
|
-
alias_method_chain :#{method}#{punctuation}, :default_slave
|
22
|
-
#{class_method ? "end" : ""}
|
23
|
-
RUBY
|
12
|
+
injected_module = Module.new
|
13
|
+
injected_module.send(:define_method, method) do |*args, &block|
|
14
|
+
on_slave_unless_tx do
|
15
|
+
super(*args, &block)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
(class_method ? base.singleton_class : base).send(:prepend, injected_module)
|
24
19
|
end
|
25
20
|
|
26
21
|
CLASS_SLAVE_METHODS = [ :find_by_sql, :count_by_sql, :calculate, :find_one, :find_some, :find_every, :quote_value, :sanitize_sql_hash_for_conditions, :exists?, :table_exists? ]
|
27
22
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
self.class.quote_value(*args, &block)
|
23
|
+
module PrependClassMethods
|
24
|
+
def columns
|
25
|
+
if on_slave_by_default? && !Thread.current[:_active_record_shards_slave_off]
|
26
|
+
read_columns_from = :slave
|
27
|
+
else
|
28
|
+
read_columns_form = :master
|
35
29
|
end
|
36
30
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
if on_slave_by_default? && !Thread.current[:_active_record_shards_slave_off]
|
45
|
-
read_columns_from = :slave
|
46
|
-
else
|
47
|
-
read_columns_form = :master
|
48
|
-
end
|
49
|
-
|
50
|
-
on_cx_switch_block(read_columns_from, :construct_ro_scope => false) { columns_without_default_slave(*args, &block) }
|
51
|
-
end
|
52
|
-
alias_method_chain :columns, :default_slave
|
31
|
+
on_cx_switch_block(read_columns_from, construct_ro_scope: false) { super }
|
32
|
+
end
|
33
|
+
|
34
|
+
def transaction(*args, &block)
|
35
|
+
if on_slave_by_default?
|
36
|
+
old_val = Thread.current[:_active_record_shards_slave_off]
|
37
|
+
Thread.current[:_active_record_shards_slave_off] = true
|
53
38
|
end
|
54
39
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
Thread.current[:_active_record_shards_slave_off] = true
|
60
|
-
end
|
61
|
-
|
62
|
-
transaction_without_slave_off(*args, &block)
|
63
|
-
ensure
|
64
|
-
if on_slave_by_default?
|
65
|
-
Thread.current[:_active_record_shards_slave_off] = old_val
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
alias_method_chain :transaction, :slave_off
|
40
|
+
super(*args, &block)
|
41
|
+
ensure
|
42
|
+
if on_slave_by_default?
|
43
|
+
Thread.current[:_active_record_shards_slave_off] = old_val
|
70
44
|
end
|
71
45
|
end
|
46
|
+
end
|
47
|
+
|
48
|
+
module PrependMethods
|
49
|
+
# fix ActiveRecord to do the right thing, and use our aliased quote_value
|
50
|
+
def quote_value(*args, &block)
|
51
|
+
self.class.quote_value(*args, &block)
|
52
|
+
end
|
53
|
+
|
54
|
+
def reload(*args, &block)
|
55
|
+
self.class.on_master { super(*args, &block) }
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.extended(base)
|
60
|
+
base.send(:prepend, PrependMethods)
|
61
|
+
base.singleton_class.send(:prepend, PrependClassMethods)
|
62
|
+
|
63
|
+
CLASS_SLAVE_METHODS.each { |m| ActiveRecordShards::DefaultSlavePatches.wrap_method_in_on_slave(true, base, m) }
|
64
|
+
|
72
65
|
if ActiveRecord::Associations.const_defined?(:HasAndBelongsToManyAssociation)
|
73
66
|
ActiveRecordShards::DefaultSlavePatches.wrap_method_in_on_slave(false, ActiveRecord::Associations::HasAndBelongsToManyAssociation, :construct_sql)
|
74
67
|
ActiveRecordShards::DefaultSlavePatches.wrap_method_in_on_slave(false, ActiveRecord::Associations::HasAndBelongsToManyAssociation, :construct_find_options!)
|
@@ -96,7 +89,7 @@ module ActiveRecordShards
|
|
96
89
|
end
|
97
90
|
|
98
91
|
module HasAndBelongsToManyPreloaderPatches
|
99
|
-
def self.
|
92
|
+
def self.prepended(base)
|
100
93
|
ActiveRecordShards::DefaultSlavePatches.wrap_method_in_on_slave(false, base, :records_for) rescue nil
|
101
94
|
end
|
102
95
|
|
@@ -104,8 +97,8 @@ module ActiveRecordShards
|
|
104
97
|
klass.on_slave_unless_tx { yield }
|
105
98
|
end
|
106
99
|
|
107
|
-
def
|
108
|
-
on_slave_unless_tx {
|
100
|
+
def exists?(*args, &block)
|
101
|
+
on_slave_unless_tx { super(*args, &block) }
|
109
102
|
end
|
110
103
|
end
|
111
104
|
|
@@ -113,14 +106,8 @@ module ActiveRecordShards
|
|
113
106
|
# this simplifies the hell out of our existence, because all we have to do is inerit on-slave-by-default
|
114
107
|
# down from the parent now.
|
115
108
|
module Rails41HasAndBelongsToManyBuilderExtension
|
116
|
-
def
|
117
|
-
|
118
|
-
alias_method_chain :through_model, :inherit_default_slave_from_lhs
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
|
-
def through_model_with_inherit_default_slave_from_lhs
|
123
|
-
model = through_model_without_inherit_default_slave_from_lhs
|
109
|
+
def through_model
|
110
|
+
model = super
|
124
111
|
def model.on_slave_by_default?
|
125
112
|
left_reflection.klass.on_slave_by_default?
|
126
113
|
end
|
@@ -1,18 +1,23 @@
|
|
1
|
-
module
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
self.send("#{m}_without_sharding", *args)
|
11
|
-
end
|
1
|
+
module ActiveRecordShards
|
2
|
+
module Migrator
|
3
|
+
[:up, :down, :run].each do |m|
|
4
|
+
define_method(m) do |*args|
|
5
|
+
ActiveRecord::Base.on_shard(nil) do
|
6
|
+
super(*args)
|
7
|
+
end
|
8
|
+
ActiveRecord::Base.on_all_shards do
|
9
|
+
super(*args)
|
12
10
|
end
|
13
|
-
alias_method_chain m.to_sym, :sharding
|
14
11
|
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
15
|
|
16
|
+
ActiveRecord::Migrator.singleton_class.send(:prepend, ActiveRecordShards::Migrator)
|
17
|
+
|
18
|
+
module ActiveRecord
|
19
|
+
class Migrator
|
20
|
+
class << self
|
16
21
|
def bootstrap_migrations_from_nil_shard(migrations_path, this_migration=nil)
|
17
22
|
migrations = nil
|
18
23
|
ActiveRecord::Base.on_shard(nil) do
|
@@ -83,7 +88,7 @@ module ActiveRecordShards
|
|
83
88
|
# migration, where it should have been. But this makes our monkey patch incompatible.
|
84
89
|
# So we're forced to *either* include or extend this.
|
85
90
|
module ActualMigrationExtension
|
86
|
-
def
|
91
|
+
def migrate(direction)
|
87
92
|
if migration_shard.blank?
|
88
93
|
raise RuntimeError, "#{self.name}: Can't run migrations without a shard spec: this may be :all, :none,
|
89
94
|
or a specific shard (for data-fixups). please call shard(arg) in your migration."
|
@@ -98,7 +103,7 @@ module ActiveRecordShards
|
|
98
103
|
return if migration_shard != :all && migration_shard.to_s != shard.to_s
|
99
104
|
end
|
100
105
|
|
101
|
-
|
106
|
+
super
|
102
107
|
end
|
103
108
|
end
|
104
109
|
end
|
@@ -106,11 +111,10 @@ end
|
|
106
111
|
ActiveRecord::Migration.class_eval do
|
107
112
|
extend ActiveRecordShards::MigrationClassExtension
|
108
113
|
|
109
|
-
|
114
|
+
prepend ActiveRecordShards::ActualMigrationExtension
|
110
115
|
define_method :migration_shard do
|
111
116
|
self.class.migration_shard
|
112
117
|
end
|
113
|
-
alias_method_chain :migrate, :forced_shard
|
114
118
|
end
|
115
119
|
|
116
120
|
ActiveRecord::MigrationProxy.delegate :migration_shard, :to => :migration
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_record_shards
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mick Staugaard
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2015-
|
13
|
+
date: 2015-12-23 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activerecord
|
@@ -21,7 +21,7 @@ dependencies:
|
|
21
21
|
version: 3.2.16
|
22
22
|
- - "<"
|
23
23
|
- !ruby/object:Gem::Version
|
24
|
-
version: '5.
|
24
|
+
version: '5.1'
|
25
25
|
type: :runtime
|
26
26
|
prerelease: false
|
27
27
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -31,7 +31,7 @@ dependencies:
|
|
31
31
|
version: 3.2.16
|
32
32
|
- - "<"
|
33
33
|
- !ruby/object:Gem::Version
|
34
|
-
version: '5.
|
34
|
+
version: '5.1'
|
35
35
|
- !ruby/object:Gem::Dependency
|
36
36
|
name: activesupport
|
37
37
|
requirement: !ruby/object:Gem::Requirement
|
@@ -41,7 +41,7 @@ dependencies:
|
|
41
41
|
version: 3.2.16
|
42
42
|
- - "<"
|
43
43
|
- !ruby/object:Gem::Version
|
44
|
-
version: '5.
|
44
|
+
version: '5.1'
|
45
45
|
type: :runtime
|
46
46
|
prerelease: false
|
47
47
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -51,7 +51,7 @@ dependencies:
|
|
51
51
|
version: 3.2.16
|
52
52
|
- - "<"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '5.
|
54
|
+
version: '5.1'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: wwtd
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -184,17 +184,17 @@ require_paths:
|
|
184
184
|
- lib
|
185
185
|
required_ruby_version: !ruby/object:Gem::Requirement
|
186
186
|
requirements:
|
187
|
-
- - "
|
187
|
+
- - "~>"
|
188
188
|
- !ruby/object:Gem::Version
|
189
|
-
version: '0'
|
189
|
+
version: '2.0'
|
190
190
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
191
191
|
requirements:
|
192
|
-
- - "
|
192
|
+
- - ">="
|
193
193
|
- !ruby/object:Gem::Version
|
194
|
-
version:
|
194
|
+
version: '0'
|
195
195
|
requirements: []
|
196
196
|
rubyforge_project:
|
197
|
-
rubygems_version: 2.
|
197
|
+
rubygems_version: 2.5.0
|
198
198
|
signing_key:
|
199
199
|
specification_version: 4
|
200
200
|
summary: Simple database switching for ActiveRecord.
|