switchman 2.1.0 → 3.0.6

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 (57) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +10 -2
  3. data/app/models/switchman/shard.rb +270 -343
  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 +8 -6
  10. data/db/migrate/20190114212900_add_unique_name_indexes.rb +5 -3
  11. data/lib/switchman/action_controller/caching.rb +2 -2
  12. data/lib/switchman/active_record/abstract_adapter.rb +0 -8
  13. data/lib/switchman/active_record/association.rb +78 -89
  14. data/lib/switchman/active_record/attribute_methods.rb +127 -52
  15. data/lib/switchman/active_record/base.rb +83 -67
  16. data/lib/switchman/active_record/calculations.rb +73 -66
  17. data/lib/switchman/active_record/connection_pool.rb +12 -59
  18. data/lib/switchman/active_record/database_configurations/database_config.rb +13 -0
  19. data/lib/switchman/active_record/database_configurations.rb +34 -0
  20. data/lib/switchman/active_record/finder_methods.rb +11 -16
  21. data/lib/switchman/active_record/log_subscriber.rb +4 -8
  22. data/lib/switchman/active_record/migration.rb +19 -45
  23. data/lib/switchman/active_record/model_schema.rb +1 -1
  24. data/lib/switchman/active_record/persistence.rb +11 -6
  25. data/lib/switchman/active_record/postgresql_adapter.rb +33 -161
  26. data/lib/switchman/active_record/predicate_builder.rb +1 -1
  27. data/lib/switchman/active_record/query_cache.rb +18 -19
  28. data/lib/switchman/active_record/query_methods.rb +178 -193
  29. data/lib/switchman/active_record/reflection.rb +7 -22
  30. data/lib/switchman/active_record/relation.rb +32 -29
  31. data/lib/switchman/active_record/spawn_methods.rb +27 -29
  32. data/lib/switchman/active_record/statement_cache.rb +18 -35
  33. data/lib/switchman/active_record/tasks/database_tasks.rb +16 -0
  34. data/lib/switchman/active_record/test_fixtures.rb +43 -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 +130 -154
  38. data/lib/switchman/default_shard.rb +52 -16
  39. data/lib/switchman/engine.rb +65 -58
  40. data/lib/switchman/environment.rb +4 -8
  41. data/lib/switchman/errors.rb +1 -0
  42. data/lib/switchman/guard_rail/relation.rb +5 -7
  43. data/lib/switchman/guard_rail.rb +6 -19
  44. data/lib/switchman/r_spec_helper.rb +29 -57
  45. data/lib/switchman/rails.rb +14 -12
  46. data/lib/switchman/sharded_instrumenter.rb +1 -1
  47. data/lib/switchman/standard_error.rb +15 -3
  48. data/lib/switchman/test_helper.rb +5 -3
  49. data/lib/switchman/version.rb +1 -1
  50. data/lib/switchman.rb +3 -3
  51. data/lib/tasks/switchman.rake +61 -72
  52. metadata +90 -48
  53. data/lib/switchman/active_record/batches.rb +0 -11
  54. data/lib/switchman/active_record/connection_handler.rb +0 -190
  55. data/lib/switchman/active_record/where_clause_factory.rb +0 -36
  56. data/lib/switchman/connection_pool_proxy.rb +0 -173
  57. data/lib/switchman/schema_cache.rb +0 -28
@@ -7,19 +7,18 @@ module Switchman
7
7
  return super(id) unless klass.integral_id?
8
8
 
9
9
  if shard_source_value != :implicit
10
- current_shard = Shard.current(klass.shard_category)
11
- result = self.activate do |relation, shard|
10
+ current_shard = Shard.current(klass.connection_classes)
11
+ result = activate do |relation, shard|
12
12
  current_id = Shard.relative_id_for(id, current_shard, shard)
13
13
  # current_id will be nil for non-integral id
14
14
  next unless current_id
15
15
  # skip the shard if the object can't be on it. unless we're only looking at one shard;
16
16
  # we might be expecting a shadow object
17
- next if current_id > Shard::IDS_PER_SHARD && self.all_shards.length > 1
17
+ next if current_id > Shard::IDS_PER_SHARD && all_shards.length > 1
18
+
18
19
  relation.call_super(:find_one, FinderMethods, current_id)
19
20
  end
20
- if result.is_a?(Array)
21
- result = result.first
22
- end
21
+ result = result.first if result.is_a?(Array)
23
22
  # we may have skipped all shards
24
23
  raise_record_not_found_exception!(id, 0, 1) unless result
25
24
  return result
@@ -34,8 +33,8 @@ module Switchman
34
33
  end
35
34
 
36
35
  def find_some_ordered(ids)
37
- current_shard = Shard.current(klass.shard_category)
38
- ids = ids.map{|id| Shard.relative_id_for(id, current_shard, current_shard)}
36
+ current_shard = Shard.current(klass.connection_classes)
37
+ ids = ids.map { |id| Shard.relative_id_for(id, current_shard, current_shard) }
39
38
  super(ids)
40
39
  end
41
40
 
@@ -45,14 +44,12 @@ module Switchman
45
44
 
46
45
  def exists?(conditions = :none)
47
46
  conditions = conditions.id if ::ActiveRecord::Base === conditions
48
- return false if !conditions
47
+ return false unless conditions
49
48
 
50
- relation = ::Rails.version >= "5.2" ?
51
- apply_join_dependency(eager_loading: false) :
52
- apply_join_dependency(self, construct_join_dependency)
49
+ relation = apply_join_dependency(eager_loading: false)
53
50
  return false if ::ActiveRecord::NullRelation === relation
54
51
 
55
- relation = relation.except(:select, :order).select("1 AS one").limit(1)
52
+ relation = relation.except(:select, :order).select('1 AS one').limit(1)
56
53
 
57
54
  case conditions
58
55
  when Array, Hash
@@ -62,9 +59,7 @@ module Switchman
62
59
  end
63
60
 
64
61
  relation.activate do |shard_rel|
65
- return true if ::Rails.version >= "5.2" ?
66
- connection.select_value(shard_rel.arel, "#{name} Exists") :
67
- connection.select_value(shard_rel, "#{name} Exists", shard_rel.bound_attributes)
62
+ return true if connection.select_value(shard_rel.arel, "#{name} Exists")
68
63
  end
69
64
  false
70
65
  end
@@ -14,20 +14,16 @@ module Switchman
14
14
 
15
15
  name = "#{payload[:name]} (#{event.duration.round(1)}ms)"
16
16
  name = "CACHE #{name}" if payload[:cached]
17
- sql = payload[:sql].squeeze(' '.freeze)
17
+ sql = payload[:sql].squeeze(' ')
18
18
  binds = nil
19
19
  shard = payload[:shard]
20
20
  shard = " [#{shard[:database_server_id]}:#{shard[:id]} #{shard[:env]}]" if shard
21
21
 
22
22
  unless (payload[:binds] || []).empty?
23
- use_old_format = (::Rails.version < '5.1.5')
24
- args = use_old_format ?
25
- [payload[:binds], payload[:type_casted_binds]] :
26
- [payload[:type_casted_binds]]
27
- casted_params = type_casted_binds(*args)
28
- binds = " " + payload[:binds].zip(casted_params).map { |attr, value|
23
+ casted_params = type_casted_binds(payload[:type_casted_binds])
24
+ binds = ' ' + payload[:binds].zip(casted_params).map do |attr, value|
29
25
  render_bind(attr, value)
30
- }.inspect
26
+ end.inspect
31
27
  end
32
28
 
33
29
  name = colorize_payload_name(name, payload[:name])
@@ -4,73 +4,47 @@ module Switchman
4
4
  module ActiveRecord
5
5
  module Migration
6
6
  module Compatibility
7
- module V5_0
7
+ module V5_0 # rubocop:disable Naming/ClassAndModuleCamelCase
8
8
  def create_table(*args, **options)
9
- unless options.key?(:id)
10
- options[:id] = :bigserial
11
- end
12
- if block_given?
13
- super do |td|
14
- yield td
15
- end
16
- else
17
- super
18
- end
9
+ options[:id] = :bigserial unless options.key?(:id)
10
+ super
19
11
  end
20
12
  end
21
13
  end
22
14
 
23
15
  def connection
24
16
  conn = super
25
- if conn.shard != ::ActiveRecord::Base.connection_pool.current_pool.shard
26
- ::ActiveRecord::Base.connection_pool.current_pool.switch_database(conn)
27
- end
17
+ ::ActiveRecord::Base.connection_pool.switch_database(conn) if conn.shard != ::ActiveRecord::Base.current_switchman_shard
28
18
  conn
29
19
  end
30
20
  end
31
21
 
32
22
  module Migrator
33
- # significant change: hash shard id, not database name
23
+ # significant change: just return MIGRATOR_SALT directly
24
+ # especially if you're going through pgbouncer, the database
25
+ # name you're accessing may not be consistent. it is NOT allowed
26
+ # to run migrations against multiple shards in the same database
27
+ # concurrently
34
28
  def generate_migrator_advisory_lock_id
35
- shard_name_hash = Zlib.crc32(Shard.current.name)
36
- ::ActiveRecord::Migrator::MIGRATOR_SALT * shard_name_hash
29
+ ::ActiveRecord::Migrator::MIGRATOR_SALT
37
30
  end
38
31
 
39
- if ::Rails.version >= '6.0'
40
- # copy/paste from Rails 6.1
41
- def with_advisory_lock
42
- lock_id = generate_migrator_advisory_lock_id
43
-
44
- with_advisory_lock_connection do |connection|
45
- got_lock = connection.get_advisory_lock(lock_id)
46
- raise ::ActiveRecord::ConcurrentMigrationError unless got_lock
47
- load_migrated # reload schema_migrations to be sure it wasn't changed by another process before we got the lock
48
- yield
49
- ensure
50
- if got_lock && !connection.release_advisory_lock(lock_id)
51
- raise ::ActiveRecord::ConcurrentMigrationError.new(
52
- ::ActiveRecord::ConcurrentMigrationError::RELEASE_LOCK_FAILED_MESSAGE
53
- )
54
- end
55
- end
56
- end
32
+ # significant change: strip out prefer_secondary from config
33
+ def with_advisory_lock_connection
34
+ pool = ::ActiveRecord::ConnectionAdapters::ConnectionHandler.new.establish_connection(
35
+ ::ActiveRecord::Base.connection_db_config.configuration_hash.except(:prefer_secondary)
36
+ )
57
37
 
58
- # significant change: strip out prefer_secondary from config
59
- def with_advisory_lock_connection
60
- pool = ::ActiveRecord::ConnectionAdapters::ConnectionHandler.new.establish_connection(
61
- ::ActiveRecord::Base.connection_config.except(:prefer_secondary)
62
- )
63
-
64
- pool.with_connection { |connection| yield(connection) }
65
- ensure
66
- pool&.disconnect!
67
- end
38
+ pool.with_connection { |connection| yield(connection) } # rubocop:disable Style/ExplicitBlockArgument
39
+ ensure
40
+ pool&.disconnect!
68
41
  end
69
42
  end
70
43
 
71
44
  module MigrationContext
72
45
  def migrations
73
46
  return @migrations if instance_variable_defined?(:@migrations)
47
+
74
48
  migrations_cache = Thread.current[:migrations_cache] ||= {}
75
49
  key = Digest::MD5.hexdigest(migration_files.sort.join(','))
76
50
  @migrations = migrations_cache[key] ||= super
@@ -6,7 +6,7 @@ module Switchman
6
6
  module ClassMethods
7
7
  def quoted_table_name
8
8
  @quoted_table_name ||= {}
9
- @quoted_table_name[Shard.current(shard_category).id] ||= connection.quote_table_name(table_name)
9
+ @quoted_table_name[Shard.current(connection_classes).id] ||= connection.quote_table_name(table_name)
10
10
  end
11
11
  end
12
12
  end
@@ -5,14 +5,19 @@ module Switchman
5
5
  module Persistence
6
6
  # touch reads the id attribute directly, so it's not relative to the current shard
7
7
  def touch(*, **)
8
- shard.activate(self.class.shard_category) { super }
8
+ shard.activate(self.class.connection_classes) { super }
9
9
  end
10
10
 
11
- if ::Rails.version >= '5.2'
12
- def update_columns(*)
13
- shard.activate(self.class.shard_category) { super }
14
- end
11
+ def update_columns(*)
12
+ shard.activate(self.class.connection_classes) { super }
13
+ end
14
+
15
+ def delete
16
+ db = shard.database_server
17
+ return db.unguard { super } unless ::GuardRail.environment == db.guard_rail_environment
18
+
19
+ super
15
20
  end
16
21
  end
17
22
  end
18
- end
23
+ end
@@ -9,22 +9,22 @@ module Switchman
9
9
 
10
10
  option_string = options.sum do |key, value|
11
11
  case key
12
- when :owner
13
- " OWNER = \"#{value}\""
14
- when :template
15
- " TEMPLATE = \"#{value}\""
16
- when :encoding
17
- " ENCODING = '#{value}'"
18
- when :collation
19
- " LC_COLLATE = '#{value}'"
20
- when :ctype
21
- " LC_CTYPE = '#{value}'"
22
- when :tablespace
23
- " TABLESPACE = \"#{value}\""
24
- when :connection_limit
25
- " CONNECTION LIMIT = #{value}"
26
- else
27
- ""
12
+ when :owner
13
+ " OWNER = \"#{value}\""
14
+ when :template
15
+ " TEMPLATE = \"#{value}\""
16
+ when :encoding
17
+ " ENCODING = '#{value}'"
18
+ when :collation
19
+ " LC_COLLATE = '#{value}'"
20
+ when :ctype
21
+ " LC_CTYPE = '#{value}'"
22
+ when :tablespace
23
+ " TABLESPACE = \"#{value}\""
24
+ when :connection_limit
25
+ " CONNECTION LIMIT = #{value}"
26
+ else
27
+ ''
28
28
  end
29
29
  end
30
30
 
@@ -32,19 +32,17 @@ module Switchman
32
32
  end
33
33
 
34
34
  # copy/paste; use quote_local_table_name
35
- def drop_database(name) #:nodoc:
35
+ def drop_database(name) # :nodoc:
36
36
  execute "DROP DATABASE IF EXISTS #{quote_local_table_name(name)}"
37
37
  end
38
38
 
39
39
  def current_schemas
40
- select_values("SELECT * FROM unnest(current_schemas(false))")
40
+ select_values('SELECT * FROM unnest(current_schemas(false))')
41
41
  end
42
42
 
43
43
  def extract_schema_qualified_name(string)
44
44
  name = ::ActiveRecord::ConnectionAdapters::PostgreSQL::Utils.extract_schema_qualified_name(string.to_s)
45
- if string && !name.schema
46
- name.instance_variable_set(:@schema, shard.name)
47
- end
45
+ name.instance_variable_set(:@schema, shard.name) if string && !name.schema
48
46
  [name.schema, name.identifier]
49
47
  end
50
48
 
@@ -52,12 +50,12 @@ module Switchman
52
50
  def quoted_scope(name = nil, type: nil)
53
51
  schema, name = extract_schema_qualified_name(name)
54
52
  type = \
55
- case type
56
- when "BASE TABLE"
53
+ case type # rubocop:disable Style/HashLikeCase
54
+ when 'BASE TABLE'
57
55
  "'r','p'"
58
- when "VIEW"
56
+ when 'VIEW'
59
57
  "'v','m'"
60
- when "FOREIGN TABLE"
58
+ when 'FOREIGN TABLE'
61
59
  "'f'"
62
60
  end
63
61
  scope = {}
@@ -67,135 +65,10 @@ module Switchman
67
65
  scope
68
66
  end
69
67
 
70
- if ::Rails.version < '6.0'
71
- def tables(name = nil)
72
- query(<<-SQL, 'SCHEMA').map { |row| row[0] }
73
- SELECT tablename
74
- FROM pg_tables
75
- WHERE schemaname = '#{shard.name}'
76
- SQL
77
- end
78
-
79
- def view_exists?(name)
80
- name = ::ActiveRecord::ConnectionAdapters::PostgreSQL::Utils.extract_schema_qualified_name(name.to_s)
81
- return false unless name.identifier
82
- if !name.schema
83
- name.instance_variable_set(:@schema, shard.name)
84
- end
85
-
86
- select_values(<<-SQL, 'SCHEMA').any?
87
- SELECT c.relname
88
- FROM pg_class c
89
- LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
90
- WHERE c.relkind IN ('v','m') -- (v)iew, (m)aterialized view
91
- AND c.relname = '#{name.identifier}'
92
- AND n.nspname = '#{shard.name}'
93
- SQL
94
- end
95
-
96
- def indexes(table_name)
97
- result = query(<<-SQL, 'SCHEMA')
98
- SELECT distinct i.relname, d.indisunique, d.indkey, pg_get_indexdef(d.indexrelid), t.oid
99
- FROM pg_class t
100
- INNER JOIN pg_index d ON t.oid = d.indrelid
101
- INNER JOIN pg_class i ON d.indexrelid = i.oid
102
- WHERE i.relkind = 'i'
103
- AND d.indisprimary = 'f'
104
- AND t.relname = '#{table_name}'
105
- AND i.relnamespace IN (SELECT oid FROM pg_namespace WHERE nspname = '#{shard.name}' )
106
- ORDER BY i.relname
107
- SQL
108
-
109
-
110
- result.map do |row|
111
- index_name = row[0]
112
- unique = row[1] == true || row[1] == 't'
113
- indkey = row[2].split(" ")
114
- inddef = row[3]
115
- oid = row[4]
116
-
117
- columns = Hash[query(<<-SQL, "SCHEMA")]
118
- SELECT a.attnum, a.attname
119
- FROM pg_attribute a
120
- WHERE a.attrelid = #{oid}
121
- AND a.attnum IN (#{indkey.join(",")})
122
- SQL
123
-
124
- column_names = columns.stringify_keys.values_at(*indkey).compact
125
-
126
- unless column_names.empty?
127
- # add info on sort order for columns (only desc order is explicitly specified, asc is the default)
128
- desc_order_columns = inddef.scan(/(\w+) DESC/).flatten
129
- orders = desc_order_columns.any? ? Hash[desc_order_columns.map {|order_column| [order_column, :desc]}] : {}
130
- where = inddef.scan(/WHERE (.+)$/).flatten[0]
131
- using = inddef.scan(/USING (.+?) /).flatten[0].to_sym
132
-
133
- if ::Rails.version >= "5.2"
134
- ::ActiveRecord::ConnectionAdapters::IndexDefinition.new(table_name, index_name, unique, column_names, orders: orders, where: where, using: using)
135
- else
136
- ::ActiveRecord::ConnectionAdapters::IndexDefinition.new(table_name, index_name, unique, column_names, [], orders, where, nil, using)
137
- end
138
- end
139
- end.compact
140
- end
141
-
142
- def index_name_exists?(table_name, index_name, _default = nil)
143
- exec_query(<<-SQL, 'SCHEMA').rows.first[0].to_i > 0
144
- SELECT COUNT(*)
145
- FROM pg_class t
146
- INNER JOIN pg_index d ON t.oid = d.indrelid
147
- INNER JOIN pg_class i ON d.indexrelid = i.oid
148
- WHERE i.relkind = 'i'
149
- AND i.relname = '#{index_name}'
150
- AND t.relname = '#{table_name}'
151
- AND i.relnamespace IN (SELECT oid FROM pg_namespace WHERE nspname = '#{shard.name}' )
152
- SQL
153
- end
154
-
155
- def foreign_keys(table_name)
156
- # mostly copy-pasted from AR - only change is to the nspname condition for qualified names support
157
- fk_info = select_all <<-SQL.strip_heredoc
158
- SELECT t2.oid::regclass::text AS to_table, a1.attname AS column, a2.attname AS primary_key, c.conname AS name, c.confupdtype AS on_update, c.confdeltype AS on_delete
159
- FROM pg_constraint c
160
- JOIN pg_class t1 ON c.conrelid = t1.oid
161
- JOIN pg_class t2 ON c.confrelid = t2.oid
162
- JOIN pg_attribute a1 ON a1.attnum = c.conkey[1] AND a1.attrelid = t1.oid
163
- JOIN pg_attribute a2 ON a2.attnum = c.confkey[1] AND a2.attrelid = t2.oid
164
- JOIN pg_namespace t3 ON c.connamespace = t3.oid
165
- WHERE c.contype = 'f'
166
- AND t1.relname = #{quote(table_name)}
167
- AND t3.nspname = '#{shard.name}'
168
- ORDER BY c.conname
169
- SQL
170
-
171
- fk_info.map do |row|
172
- options = {
173
- column: row['column'],
174
- name: row['name'],
175
- primary_key: row['primary_key']
176
- }
177
-
178
- options[:on_delete] = extract_foreign_key_action(row['on_delete'])
179
- options[:on_update] = extract_foreign_key_action(row['on_update'])
180
-
181
- # strip the schema name from to_table if it matches
182
- to_table = row['to_table']
183
- to_table_qualified_name = ::ActiveRecord::ConnectionAdapters::PostgreSQL::Utils.extract_schema_qualified_name(to_table)
184
- if to_table_qualified_name.schema == shard.name
185
- to_table = to_table_qualified_name.identifier
186
- end
187
-
188
- ::ActiveRecord::ConnectionAdapters::ForeignKeyDefinition.new(table_name, to_table, options)
189
- end
190
- end
191
- else
192
- def foreign_keys(table_name)
193
- super.each do |fk|
194
- to_table_qualified_name = ::ActiveRecord::ConnectionAdapters::PostgreSQL::Utils.extract_schema_qualified_name(fk.to_table)
195
- if to_table_qualified_name.schema == shard.name
196
- fk.to_table = to_table_qualified_name.identifier
197
- end
198
- end
68
+ def foreign_keys(table_name)
69
+ super.each do |fk|
70
+ to_table_qualified_name = ::ActiveRecord::ConnectionAdapters::PostgreSQL::Utils.extract_schema_qualified_name(fk.to_table)
71
+ fk.to_table = to_table_qualified_name.identifier if to_table_qualified_name.schema == shard.name
199
72
  end
200
73
  end
201
74
 
@@ -208,10 +81,9 @@ module Switchman
208
81
 
209
82
  def quote_table_name(name)
210
83
  return quote_local_table_name(name) if @use_local_table_name
84
+
211
85
  name = ::ActiveRecord::ConnectionAdapters::PostgreSQL::Utils.extract_schema_qualified_name(name.to_s)
212
- if !name.schema
213
- name.instance_variable_set(:@schema, shard.name)
214
- end
86
+ name.instance_variable_set(:@schema, shard.name) unless name.schema
215
87
  name.quoted
216
88
  end
217
89
 
@@ -219,7 +91,7 @@ module Switchman
219
91
  with_local_table_name(false, &block)
220
92
  end
221
93
 
222
- def with_local_table_name(enable = true)
94
+ def with_local_table_name(enable = true) # rubocop:disable Style/OptionalBooleanParameter
223
95
  old_value = @use_local_table_name
224
96
  @use_local_table_name = enable
225
97
  yield
@@ -228,9 +100,9 @@ module Switchman
228
100
  end
229
101
 
230
102
  def add_index_options(_table_name, _column_name, **)
231
- index_name, index_type, index_columns, index_options, algorithm, using = super
232
- algorithm = nil if DatabaseServer.creating_new_shard && algorithm == "CONCURRENTLY"
233
- [index_name, index_type, index_columns, index_options, algorithm, using]
103
+ index, algorithm, if_not_exists = super
104
+ algorithm = nil if DatabaseServer.creating_new_shard && algorithm == 'CONCURRENTLY'
105
+ [index, algorithm, if_not_exists]
234
106
  end
235
107
 
236
108
  def rename_table(table_name, new_name)
@@ -23,4 +23,4 @@ module Switchman
23
23
  end
24
24
  end
25
25
  end
26
- end
26
+ end
@@ -3,31 +3,30 @@
3
3
  module Switchman
4
4
  module ActiveRecord
5
5
  module QueryCache
6
-
7
6
  private
8
7
 
9
8
  def cache_sql(sql, name, binds)
10
9
  # have to include the shard id in the cache key because of switching dbs on the same connection
11
- sql = "#{self.shard.id}::#{sql}"
10
+ sql = "#{shard.id}::#{sql}"
12
11
  @lock.synchronize do
13
12
  result =
14
- if query_cache[sql].key?(binds)
15
- args = {
16
- sql: sql,
17
- binds: binds,
18
- name: name,
19
- connection_id: object_id,
20
- cached: true
21
- }
22
- args[:type_casted_binds] = -> { type_casted_binds(binds) } if ::Rails.version >= '5.1.5'
23
- ::ActiveSupport::Notifications.instrument(
24
- "sql.active_record",
25
- args
26
- )
27
- query_cache[sql][binds]
28
- else
29
- query_cache[sql][binds] = yield
30
- end
13
+ if query_cache[sql].key?(binds)
14
+ args = {
15
+ sql: sql,
16
+ binds: binds,
17
+ name: name,
18
+ connection_id: object_id,
19
+ cached: true,
20
+ type_casted_binds: -> { type_casted_binds(binds) }
21
+ }
22
+ ::ActiveSupport::Notifications.instrument(
23
+ 'sql.active_record',
24
+ args
25
+ )
26
+ query_cache[sql][binds]
27
+ else
28
+ query_cache[sql][binds] = yield
29
+ end
31
30
  result.dup
32
31
  end
33
32
  end