switchman 2.0.13 → 3.0.0

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.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +10 -2
  3. data/app/models/switchman/shard.rb +234 -271
  4. data/app/models/switchman/unsharded_record.rb +7 -0
  5. data/db/migrate/20130328212039_create_switchman_shards.rb +1 -1
  6. data/db/migrate/20130328224244_create_default_shard.rb +5 -5
  7. data/db/migrate/20161206323434_add_back_default_string_limits_switchman.rb +1 -0
  8. data/db/migrate/20180828183945_add_default_shard_index.rb +2 -2
  9. data/db/migrate/20180828192111_add_timestamps_to_shards.rb +7 -5
  10. data/db/migrate/20190114212900_add_unique_name_indexes.rb +5 -3
  11. data/lib/switchman.rb +3 -5
  12. data/lib/switchman/action_controller/caching.rb +2 -2
  13. data/lib/switchman/active_record/abstract_adapter.rb +1 -0
  14. data/lib/switchman/active_record/association.rb +78 -89
  15. data/lib/switchman/active_record/attribute_methods.rb +58 -52
  16. data/lib/switchman/active_record/base.rb +58 -59
  17. data/lib/switchman/active_record/calculations.rb +74 -67
  18. data/lib/switchman/active_record/connection_pool.rb +14 -41
  19. data/lib/switchman/active_record/database_configurations.rb +34 -0
  20. data/lib/switchman/active_record/database_configurations/database_config.rb +13 -0
  21. data/lib/switchman/active_record/finder_methods.rb +11 -16
  22. data/lib/switchman/active_record/log_subscriber.rb +4 -8
  23. data/lib/switchman/active_record/migration.rb +6 -47
  24. data/lib/switchman/active_record/model_schema.rb +1 -1
  25. data/lib/switchman/active_record/persistence.rb +4 -6
  26. data/lib/switchman/active_record/postgresql_adapter.rb +124 -168
  27. data/lib/switchman/active_record/predicate_builder.rb +2 -2
  28. data/lib/switchman/active_record/query_cache.rb +18 -19
  29. data/lib/switchman/active_record/query_methods.rb +172 -197
  30. data/lib/switchman/active_record/reflection.rb +6 -10
  31. data/lib/switchman/active_record/relation.rb +30 -78
  32. data/lib/switchman/active_record/spawn_methods.rb +27 -29
  33. data/lib/switchman/active_record/statement_cache.rb +18 -35
  34. data/lib/switchman/active_record/tasks/database_tasks.rb +16 -0
  35. data/lib/switchman/active_support/cache.rb +3 -5
  36. data/lib/switchman/arel.rb +13 -8
  37. data/lib/switchman/database_server.rb +121 -142
  38. data/lib/switchman/default_shard.rb +52 -16
  39. data/lib/switchman/engine.rb +61 -58
  40. data/lib/switchman/environment.rb +4 -8
  41. data/lib/switchman/errors.rb +1 -0
  42. data/lib/switchman/guard_rail.rb +6 -19
  43. data/lib/switchman/guard_rail/relation.rb +5 -7
  44. data/lib/switchman/r_spec_helper.rb +29 -37
  45. data/lib/switchman/rails.rb +14 -12
  46. data/lib/switchman/schema_cache.rb +1 -9
  47. data/lib/switchman/sharded_instrumenter.rb +1 -1
  48. data/lib/switchman/standard_error.rb +15 -3
  49. data/lib/switchman/test_helper.rb +7 -11
  50. data/lib/switchman/version.rb +1 -1
  51. data/lib/tasks/switchman.rake +54 -69
  52. metadata +87 -45
  53. data/lib/switchman/active_record/batches.rb +0 -11
  54. data/lib/switchman/active_record/connection_handler.rb +0 -172
  55. data/lib/switchman/active_record/where_clause_factory.rb +0 -36
  56. data/lib/switchman/connection_pool_proxy.rb +0 -173
@@ -1,18 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Switchman::Rails
4
- module ClassMethods
5
- def self.prepended(klass)
6
- # in Rails 4+, the Rails.cache= method was used during bootstrap to set
7
- # Rails.cache(_without_sharding) to the value from the config file. but now
8
- # that that's done (the bootstrap happened before this module is included
9
- # into Rails), we want to make sure no one tries to assign to Rails.cache,
10
- # because it would be wrong w.r.t. sharding.
11
- klass.send(:remove_method, :cache=)
12
- end
3
+ module Switchman
4
+ module Rails
5
+ module ClassMethods
6
+ def self.prepended(klass)
7
+ # in Rails 4+, the Rails.cache= method was used during bootstrap to set
8
+ # Rails.cache(_without_sharding) to the value from the config file. but now
9
+ # that that's done (the bootstrap happened before this module is included
10
+ # into Rails), we want to make sure no one tries to assign to Rails.cache,
11
+ # because it would be wrong w.r.t. sharding.
12
+ klass.send(:remove_method, :cache=)
13
+ end
13
14
 
14
- def cache
15
- Switchman::Shard.current.database_server.cache_store
15
+ def cache
16
+ Switchman::Shard.current.database_server.cache_store
17
+ end
16
18
  end
17
19
  end
18
20
  end
@@ -5,22 +5,14 @@ module Switchman
5
5
  delegate :connection, to: :pool
6
6
  attr_reader :pool
7
7
 
8
- SHARED_IVS = %i{@columns @columns_hash @primary_keys @data_sources @indexes}.freeze
9
-
10
8
  def initialize(pool)
11
9
  @pool = pool
12
10
  super(nil)
13
11
  end
14
12
 
15
13
  def copy_values(other_cache)
16
- SHARED_IVS.each do |iv|
17
- instance_variable_get(iv).replace(other_cache.instance_variable_get(iv))
18
- end
19
- end
20
-
21
- def copy_references(other_cache)
22
14
  # use the same cached values but still fall back to the correct pool
23
- SHARED_IVS.each do |iv|
15
+ %i[@columns @columns_hash @primary_keys @data_sources].each do |iv|
24
16
  instance_variable_set(iv, other_cache.instance_variable_get(iv))
25
17
  end
26
18
  end
@@ -7,7 +7,7 @@ module Switchman
7
7
  @shard_host = shard_host
8
8
  end
9
9
 
10
- def instrument(name, payload={})
10
+ def instrument(name, payload = {})
11
11
  shard = @shard_host&.shard
12
12
  # attribute_methods_generated? will be false during a reload -
13
13
  # when we might be doing a query while defining attribute methods,
@@ -3,12 +3,24 @@
3
3
  module Switchman
4
4
  module StandardError
5
5
  def initialize(*args)
6
- @active_shards = Shard.send(:active_shards).dup
6
+ # Shard.current can throw this when switchman isn't working right; if we try to
7
+ # do our stuff here, it'll cause a SystemStackError, which is a pain to deal with
8
+ if is_a?(::ActiveRecord::ConnectionNotEstablished)
9
+ super
10
+ return
11
+ end
12
+
13
+ if defined?(Shard)
14
+ @active_shards = Shard.sharded_models.map do |klass|
15
+ [klass, Shard.current(klass)]
16
+ end.compact.to_h
17
+ end
18
+
7
19
  super
8
20
  end
9
21
 
10
- def current_shard(category = :primary)
11
- @active_shards&.[](category) || Shard.default
22
+ def current_shard(klass = ::ActiveRecord::Base)
23
+ @active_shards&.[](klass) || Shard.default
12
24
  end
13
25
  end
14
26
  end
@@ -11,20 +11,15 @@ module Switchman
11
11
  Shard.create!(default: true)
12
12
  rescue
13
13
  raise unless dont_create
14
+
14
15
  # database doesn't exist yet, presumably cause we're creating it right now
15
16
  return [nil, nil]
16
17
  end
17
18
  Shard.default(reload: true)
18
19
  end
19
20
 
20
- # can't auto-create a new shard on the default shard's db server if the
21
- # default shard is split across multiple db servers
22
- if ::ActiveRecord::Base.connection_handler.connection_pool_list.length > 1
23
- server1 = DatabaseServer.create(Shard.default.database_server.config)
24
- else
25
- server1 = Shard.default.database_server
26
- end
27
- server2 = DatabaseServer.create(Shard.default.database_server.config.merge(server2: true))
21
+ server1 = Shard.default.database_server
22
+ server2 = DatabaseServer.create(Shard.default.database_server.config)
28
23
 
29
24
  if server1 == Shard.default.database_server && server1.config[:shard1] && server1.config[:shard2]
30
25
  # look for the shards in the db already
@@ -55,8 +50,8 @@ module Switchman
55
50
  shard1.destroy
56
51
  shard2.drop_database rescue nil
57
52
  shard2.destroy
58
- shard1 = server1.create_new_shard(:name => server1.config[:shard1])
59
- shard2 = server2.create_new_shard(:name => server1.config[:shard2])
53
+ shard1 = server1.create_new_shard(name: server1.config[:shard1])
54
+ shard2 = server2.create_new_shard(name: server1.config[:shard2])
60
55
  end
61
56
  [shard1, shard2]
62
57
  else
@@ -65,11 +60,12 @@ module Switchman
65
60
  end
66
61
 
67
62
  private
63
+
68
64
  def find_existing_test_shard(server, name)
69
65
  if server == Shard.default.database_server
70
66
  server.shards.where(name: name).first
71
67
  else
72
- shard = Shard.where("database_server_id IS NOT NULL AND name=?", name).first
68
+ shard = Shard.where('database_server_id IS NOT NULL AND name=?', name).first
73
69
  # if somehow databases got created in a different order, change the shard to match
74
70
  shard.database_server = server if shard
75
71
  shard
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Switchman
4
- VERSION = "2.0.13"
4
+ VERSION = '3.0.0'
5
5
  end
@@ -1,20 +1,22 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Switchman
2
4
  module Rake
3
5
  def self.filter_database_servers(&block)
4
6
  chain = filter_database_servers_chain # use a local variable so that the current chain is closed over in the following lambda
5
- @filter_database_servers_chain = lambda { |servers| block.call(servers, chain) }
7
+ @filter_database_servers_chain = ->(servers) { block.call(servers, chain) }
6
8
  end
7
9
 
8
10
  def self.scope(base_scope = Shard,
9
- database_server: ENV['DATABASE_SERVER'],
10
- shard: ENV['SHARD'])
11
+ database_server: ENV['DATABASE_SERVER'],
12
+ shard: ENV['SHARD'])
11
13
  servers = DatabaseServer.all
12
14
 
13
15
  if database_server
14
16
  servers = database_server
15
17
  if servers.first == '-'
16
18
  negative = true
17
- servers = servers[1..-1]
19
+ servers = servers[1..]
18
20
  end
19
21
  servers = servers.split(',')
20
22
  open = servers.delete('open')
@@ -31,16 +33,14 @@ module Switchman
31
33
 
32
34
  servers = filter_database_servers_chain.call(servers)
33
35
 
34
- scope = base_scope.order(::Arel.sql("database_server_id IS NOT NULL, database_server_id, id"))
36
+ scope = base_scope.order(::Arel.sql('database_server_id IS NOT NULL, database_server_id, id'))
35
37
  if servers != DatabaseServer.all
36
- conditions = ["database_server_id IN (?)", servers.map(&:id)]
37
- conditions.first << " OR database_server_id IS NULL" if servers.include?(Shard.default.database_server)
38
+ conditions = ['database_server_id IN (?)', servers.map(&:id)]
39
+ conditions.first << ' OR database_server_id IS NULL' if servers.include?(Shard.default.database_server)
38
40
  scope = scope.where(conditions)
39
41
  end
40
42
 
41
- if shard
42
- scope = shard_scope(scope, shard)
43
- end
43
+ scope = shard_scope(scope, shard) if shard
44
44
 
45
45
  scope
46
46
  end
@@ -49,11 +49,11 @@ module Switchman
49
49
  { parallel: ENV['PARALLEL'].to_i, max_procs: ENV['MAX_PARALLEL_PROCS'] }
50
50
  end
51
51
 
52
- # categories - an array or proc, to activate as the current shard during the
52
+ # classes - an array or proc, to activate as the current shard during the
53
53
  # task. tasks which modify the schema may want to pass all categories in
54
54
  # so that schema updates for non-default tables happen against all shards.
55
55
  # this is handled automatically for the default migration tasks, below.
56
- def self.shardify_task(task_name, categories: [:primary])
56
+ def self.shardify_task(task_name, classes: [::ActiveRecord::Base])
57
57
  old_task = ::Rake::Task[task_name]
58
58
  old_actions = old_task.actions.dup
59
59
  old_task.actions.clear
@@ -66,43 +66,30 @@ module Switchman
66
66
 
67
67
  ::GuardRail.activate(:deploy) do
68
68
  Shard.default.database_server.unguard do
69
- begin
70
- categories = categories.call if categories.respond_to?(:call)
71
- Shard.with_each_shard(scope, categories, options) do
72
- shard = Shard.current
73
- puts "#{shard.id}: #{shard.description}"
74
- ::ActiveRecord::Base.connection_pool.spec.config[:shard_name] = Shard.current.name
75
- if ::Rails.version < '6.0'
76
- ::ActiveRecord::Base.configurations[::Rails.env] = ::ActiveRecord::Base.connection_pool.spec.config.stringify_keys
77
- else
78
- # Adopted from the deprecated code that currently lives in rails proper
79
- remaining_configs = ::ActiveRecord::Base.configurations.configurations.reject { |db_config| db_config.env_name == ::Rails.env }
80
- new_config = ::ActiveRecord::DatabaseConfigurations.new(::Rails.env =>
81
- ::ActiveRecord::Base.connection_pool.spec.config.stringify_keys).configurations
82
- new_configs = remaining_configs + new_config
83
-
84
- ::ActiveRecord::Base.configurations = new_configs
85
- end
86
- shard.database_server.unguard do
87
- old_actions.each { |action| action.call(*task_args) }
88
- end
89
- nil
69
+ classes = classes.call if classes.respond_to?(:call)
70
+ Shard.with_each_shard(scope, classes, **options) do
71
+ shard = Shard.current
72
+ puts "#{shard.id}: #{shard.description}"
73
+
74
+ shard.database_server.unguard do
75
+ old_actions.each { |action| action.call(*task_args) }
90
76
  end
91
- rescue => e
92
- puts "Exception from #{e.current_shard.id}: #{e.current_shard.description}" if options[:parallel] != 0
93
- raise
77
+ nil
94
78
  end
79
+ rescue => e
80
+ puts "Exception from #{e.current_shard.id}: #{e.current_shard.description}" if options[:parallel] != 0
81
+ raise
82
+
83
+ #::ActiveRecord::Base.configurations = old_configurations
95
84
  end
96
85
  end
97
86
  end
98
87
  end
99
88
 
100
- %w{db:migrate db:migrate:up db:migrate:down db:rollback}.each do |task_name|
101
- shardify_task(task_name, categories: ->{ Shard.categories })
89
+ %w[db:migrate db:migrate:up db:migrate:down db:rollback].each do |task_name|
90
+ shardify_task(task_name, classes: -> { Shard.sharded_models })
102
91
  end
103
92
 
104
- private
105
-
106
93
  def self.shard_scope(scope, raw_shard_ids)
107
94
  raw_shard_ids = raw_shard_ids.split(',')
108
95
 
@@ -125,6 +112,7 @@ module Switchman
125
112
  when /^(-?)(\d+)?\.\.(\.)?(\d+)?$/
126
113
  negative, start, open, finish = $1.present?, $2, $3.present?, $4
127
114
  raise "Invalid shard id or range: #{id}" unless start || finish
115
+
128
116
  range = []
129
117
  range << "id>=#{start}" if start
130
118
  range << "id<#{'=' unless open}#{finish}" if finish
@@ -136,12 +124,12 @@ module Switchman
136
124
  when %r{^(-?\d+)/(\d+)$}
137
125
  numerator = $1.to_i
138
126
  denominator = $2.to_i
139
- if numerator == 0 || numerator.abs > denominator
140
- raise "Invalid fractional chunk: #{id}"
141
- end
127
+ raise "Invalid fractional chunk: #{id}" if numerator.zero? || numerator.abs > denominator
128
+
142
129
  # one chunk means everything
143
130
  if denominator == 1
144
131
  next if numerator == 1
132
+
145
133
  return scope.none
146
134
  end
147
135
 
@@ -156,24 +144,25 @@ module Switchman
156
144
  select = []
157
145
  if index != 1
158
146
  subscope = subscope.offset(per_chunk * (index - 1))
159
- select << "MIN(id) AS min_id"
147
+ select << 'MIN(id) AS min_id'
160
148
  end
161
149
  if index != denominator
162
150
  subscope = subscope.limit(per_chunk)
163
- select << "MAX(id) AS max_id"
164
- end
165
-
166
- result = Shard.from(subscope).select(select.join(", ")).to_a.first
167
- if index == 1
168
- range = "id<=#{result['max_id']}"
169
- elsif index == denominator
170
- range = "id>=#{result['min_id']}"
171
- else
172
- range = "(id>=#{result['min_id']} AND id<=#{result['max_id']})"
151
+ select << 'MAX(id) AS max_id'
173
152
  end
174
153
 
175
- (numerator < 0 ? negative_ranges : ranges) << range
176
- else
154
+ result = Shard.from(subscope).select(select.join(', ')).to_a.first
155
+ range = case index
156
+ when 1
157
+ "id<=#{result['max_id']}"
158
+ when denominator
159
+ "id>=#{result['min_id']}"
160
+ else
161
+ "(id>=#{result['min_id']} AND id<=#{result['max_id']})"
162
+ end
163
+
164
+ (numerator.negative? ? negative_ranges : ranges) << range
165
+ else
177
166
  raise "Invalid shard id or range: #{id}"
178
167
  end
179
168
  end
@@ -182,27 +171,24 @@ module Switchman
182
171
  negative_shard_ids.uniq!
183
172
  unless shard_ids.empty?
184
173
  shard_ids -= negative_shard_ids
185
- if shard_ids.empty? && ranges.empty?
186
- return scope.none
187
- end
174
+ return scope.none if shard_ids.empty? && ranges.empty?
175
+
188
176
  # we already trimmed them all out; no need to make the server do it as well
189
177
  negative_shard_ids = [] if ranges.empty?
190
178
  end
191
179
 
192
180
  conditions = []
193
181
  positive_queries = []
194
- unless ranges.empty?
195
- positive_queries << ranges.join(" OR ")
196
- end
182
+ positive_queries << ranges.join(' OR ') unless ranges.empty?
197
183
  unless shard_ids.empty?
198
- positive_queries << "id IN (?)"
184
+ positive_queries << 'id IN (?)'
199
185
  conditions << shard_ids
200
186
  end
201
- positive_query = positive_queries.join(" OR ")
187
+ positive_query = positive_queries.join(' OR ')
202
188
  scope = scope.where(positive_query, *conditions) unless positive_queries.empty?
203
189
 
204
- scope = scope.where("NOT (#{negative_ranges.join(" OR")})") unless negative_ranges.empty?
205
- scope = scope.where("id NOT IN (?)", negative_shard_ids) unless negative_shard_ids.empty?
190
+ scope = scope.where("NOT (#{negative_ranges.join(' OR')})") unless negative_ranges.empty?
191
+ scope = scope.where('id NOT IN (?)', negative_shard_ids) unless negative_shard_ids.empty?
206
192
  scope
207
193
  end
208
194
 
@@ -213,18 +199,17 @@ module Switchman
213
199
 
214
200
  module ActiveRecord
215
201
  module PostgreSQLDatabaseTasks
216
- def structure_dump(filename, extra_flags=nil)
202
+ def structure_dump(filename, extra_flags = nil)
217
203
  set_psql_env
218
204
  args = ['-s', '-x', '-O', '-f', filename]
219
205
  args.concat(Array(extra_flags)) if extra_flags
220
- search_path = configuration['schema_search_path']
221
206
  shard = Shard.current.name
222
207
  serialized_search_path = shard
223
208
  args << "--schema=#{Shellwords.escape(shard)}"
224
209
 
225
210
  args << configuration['database']
226
211
  run_cmd('pg_dump', args, 'dumping')
227
- File.open(filename, "a") { |f| f << "SET search_path TO #{serialized_search_path};\n\n" }
212
+ File.open(filename, 'a') { |f| f << "SET search_path TO #{serialized_search_path};\n\n" }
228
213
  end
229
214
  end
230
215
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: switchman
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.13
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cody Cutrer
@@ -10,76 +10,76 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2021-06-11 00:00:00.000000000 Z
13
+ date: 2021-03-17 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
- name: railties
16
+ name: activerecord
17
17
  requirement: !ruby/object:Gem::Requirement
18
18
  requirements:
19
19
  - - ">="
20
20
  - !ruby/object:Gem::Version
21
- version: '5.1'
21
+ version: '6.1'
22
22
  - - "<"
23
23
  - !ruby/object:Gem::Version
24
- version: '6.1'
24
+ version: '6.2'
25
25
  type: :runtime
26
26
  prerelease: false
27
27
  version_requirements: !ruby/object:Gem::Requirement
28
28
  requirements:
29
29
  - - ">="
30
30
  - !ruby/object:Gem::Version
31
- version: '5.1'
31
+ version: '6.1'
32
32
  - - "<"
33
33
  - !ruby/object:Gem::Version
34
- version: '6.1'
34
+ version: '6.2'
35
35
  - !ruby/object:Gem::Dependency
36
- name: activerecord
36
+ name: guardrail
37
37
  requirement: !ruby/object:Gem::Requirement
38
38
  requirements:
39
- - - ">="
40
- - !ruby/object:Gem::Version
41
- version: '5.1'
42
- - - "<"
39
+ - - "~>"
43
40
  - !ruby/object:Gem::Version
44
- version: '6.1'
41
+ version: 3.0.0
45
42
  type: :runtime
46
43
  prerelease: false
47
44
  version_requirements: !ruby/object:Gem::Requirement
48
45
  requirements:
49
- - - ">="
50
- - !ruby/object:Gem::Version
51
- version: '5.1'
52
- - - "<"
46
+ - - "~>"
53
47
  - !ruby/object:Gem::Version
54
- version: '6.1'
48
+ version: 3.0.0
55
49
  - !ruby/object:Gem::Dependency
56
- name: guardrail
50
+ name: open4
57
51
  requirement: !ruby/object:Gem::Requirement
58
52
  requirements:
59
53
  - - "~>"
60
54
  - !ruby/object:Gem::Version
61
- version: 2.0.0
55
+ version: 1.3.0
62
56
  type: :runtime
63
57
  prerelease: false
64
58
  version_requirements: !ruby/object:Gem::Requirement
65
59
  requirements:
66
60
  - - "~>"
67
61
  - !ruby/object:Gem::Version
68
- version: 2.0.0
62
+ version: 1.3.0
69
63
  - !ruby/object:Gem::Dependency
70
- name: open4
64
+ name: railties
71
65
  requirement: !ruby/object:Gem::Requirement
72
66
  requirements:
73
- - - "~>"
67
+ - - ">="
74
68
  - !ruby/object:Gem::Version
75
- version: 1.3.0
69
+ version: '6.1'
70
+ - - "<"
71
+ - !ruby/object:Gem::Version
72
+ version: '6.2'
76
73
  type: :runtime
77
74
  prerelease: false
78
75
  version_requirements: !ruby/object:Gem::Requirement
79
76
  requirements:
80
- - - "~>"
77
+ - - ">="
81
78
  - !ruby/object:Gem::Version
82
- version: 1.3.0
79
+ version: '6.1'
80
+ - - "<"
81
+ - !ruby/object:Gem::Version
82
+ version: '6.2'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: appraisal
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -108,6 +108,20 @@ dependencies:
108
108
  - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: pg
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '1.2'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '1.2'
111
125
  - !ruby/object:Gem::Dependency
112
126
  name: pry
113
127
  requirement: !ruby/object:Gem::Requirement
@@ -123,21 +137,21 @@ dependencies:
123
137
  - !ruby/object:Gem::Version
124
138
  version: '0'
125
139
  - !ruby/object:Gem::Dependency
126
- name: pg
140
+ name: rake
127
141
  requirement: !ruby/object:Gem::Requirement
128
142
  requirements:
129
143
  - - "~>"
130
144
  - !ruby/object:Gem::Version
131
- version: '0'
145
+ version: '13.0'
132
146
  type: :development
133
147
  prerelease: false
134
148
  version_requirements: !ruby/object:Gem::Requirement
135
149
  requirements:
136
150
  - - "~>"
137
151
  - !ruby/object:Gem::Version
138
- version: '0'
152
+ version: '13.0'
139
153
  - !ruby/object:Gem::Dependency
140
- name: rspec-rails
154
+ name: rspec-mocks
141
155
  requirement: !ruby/object:Gem::Requirement
142
156
  requirements:
143
157
  - - "~>"
@@ -151,47 +165,75 @@ dependencies:
151
165
  - !ruby/object:Gem::Version
152
166
  version: '3.5'
153
167
  - !ruby/object:Gem::Dependency
154
- name: rspec-mocks
168
+ name: rspec-rails
155
169
  requirement: !ruby/object:Gem::Requirement
156
170
  requirements:
157
171
  - - "~>"
158
172
  - !ruby/object:Gem::Version
159
- version: '3.5'
173
+ version: '4.0'
160
174
  type: :development
161
175
  prerelease: false
162
176
  version_requirements: !ruby/object:Gem::Requirement
163
177
  requirements:
164
178
  - - "~>"
165
179
  - !ruby/object:Gem::Version
166
- version: '3.5'
180
+ version: '4.0'
167
181
  - !ruby/object:Gem::Dependency
168
- name: simplecov
182
+ name: rubocop
169
183
  requirement: !ruby/object:Gem::Requirement
170
184
  requirements:
171
185
  - - "~>"
172
186
  - !ruby/object:Gem::Version
173
- version: '0.15'
187
+ version: '1.10'
174
188
  type: :development
175
189
  prerelease: false
176
190
  version_requirements: !ruby/object:Gem::Requirement
177
191
  requirements:
178
192
  - - "~>"
179
193
  - !ruby/object:Gem::Version
180
- version: '0.15'
194
+ version: '1.10'
181
195
  - !ruby/object:Gem::Dependency
182
- name: rake
196
+ name: rubocop-rake
183
197
  requirement: !ruby/object:Gem::Requirement
184
198
  requirements:
185
199
  - - "~>"
186
200
  - !ruby/object:Gem::Version
187
- version: '12.0'
201
+ version: '0.5'
188
202
  type: :development
189
203
  prerelease: false
190
204
  version_requirements: !ruby/object:Gem::Requirement
191
205
  requirements:
192
206
  - - "~>"
193
207
  - !ruby/object:Gem::Version
194
- version: '12.0'
208
+ version: '0.5'
209
+ - !ruby/object:Gem::Dependency
210
+ name: rubocop-rspec
211
+ requirement: !ruby/object:Gem::Requirement
212
+ requirements:
213
+ - - "~>"
214
+ - !ruby/object:Gem::Version
215
+ version: '2.2'
216
+ type: :development
217
+ prerelease: false
218
+ version_requirements: !ruby/object:Gem::Requirement
219
+ requirements:
220
+ - - "~>"
221
+ - !ruby/object:Gem::Version
222
+ version: '2.2'
223
+ - !ruby/object:Gem::Dependency
224
+ name: simplecov
225
+ requirement: !ruby/object:Gem::Requirement
226
+ requirements:
227
+ - - "~>"
228
+ - !ruby/object:Gem::Version
229
+ version: '0.15'
230
+ type: :development
231
+ prerelease: false
232
+ version_requirements: !ruby/object:Gem::Requirement
233
+ requirements:
234
+ - - "~>"
235
+ - !ruby/object:Gem::Version
236
+ version: '0.15'
195
237
  description: Sharding
196
238
  email:
197
239
  - cody@instructure.com
@@ -201,6 +243,7 @@ extra_rdoc_files: []
201
243
  files:
202
244
  - Rakefile
203
245
  - app/models/switchman/shard.rb
246
+ - app/models/switchman/unsharded_record.rb
204
247
  - db/migrate/20130328212039_create_switchman_shards.rb
205
248
  - db/migrate/20130328224244_create_default_shard.rb
206
249
  - db/migrate/20161206323434_add_back_default_string_limits_switchman.rb
@@ -213,10 +256,10 @@ files:
213
256
  - lib/switchman/active_record/association.rb
214
257
  - lib/switchman/active_record/attribute_methods.rb
215
258
  - lib/switchman/active_record/base.rb
216
- - lib/switchman/active_record/batches.rb
217
259
  - lib/switchman/active_record/calculations.rb
218
- - lib/switchman/active_record/connection_handler.rb
219
260
  - lib/switchman/active_record/connection_pool.rb
261
+ - lib/switchman/active_record/database_configurations.rb
262
+ - lib/switchman/active_record/database_configurations/database_config.rb
220
263
  - lib/switchman/active_record/finder_methods.rb
221
264
  - lib/switchman/active_record/log_subscriber.rb
222
265
  - lib/switchman/active_record/migration.rb
@@ -231,12 +274,11 @@ files:
231
274
  - lib/switchman/active_record/spawn_methods.rb
232
275
  - lib/switchman/active_record/statement_cache.rb
233
276
  - lib/switchman/active_record/table_definition.rb
277
+ - lib/switchman/active_record/tasks/database_tasks.rb
234
278
  - lib/switchman/active_record/type_caster.rb
235
- - lib/switchman/active_record/where_clause_factory.rb
236
279
  - lib/switchman/active_support/cache.rb
237
280
  - lib/switchman/arel.rb
238
281
  - lib/switchman/call_super.rb
239
- - lib/switchman/connection_pool_proxy.rb
240
282
  - lib/switchman/database_server.rb
241
283
  - lib/switchman/default_shard.rb
242
284
  - lib/switchman/engine.rb
@@ -265,14 +307,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
265
307
  requirements:
266
308
  - - ">="
267
309
  - !ruby/object:Gem::Version
268
- version: '2.5'
310
+ version: '2.6'
269
311
  required_rubygems_version: !ruby/object:Gem::Requirement
270
312
  requirements:
271
313
  - - ">="
272
314
  - !ruby/object:Gem::Version
273
315
  version: '0'
274
316
  requirements: []
275
- rubygems_version: 3.2.15
317
+ rubygems_version: 3.1.4
276
318
  signing_key:
277
319
  specification_version: 4
278
320
  summary: Rails sharding magic