activerecord 6.0.0 → 6.0.3

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 (150) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +185 -1
  3. data/README.rdoc +1 -1
  4. data/lib/active_record.rb +1 -0
  5. data/lib/active_record/advisory_lock_base.rb +18 -0
  6. data/lib/active_record/aggregations.rb +0 -1
  7. data/lib/active_record/association_relation.rb +10 -8
  8. data/lib/active_record/associations.rb +2 -2
  9. data/lib/active_record/associations/alias_tracker.rb +0 -1
  10. data/lib/active_record/associations/association.rb +5 -1
  11. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +0 -2
  12. data/lib/active_record/associations/collection_association.rb +6 -2
  13. data/lib/active_record/associations/collection_proxy.rb +1 -2
  14. data/lib/active_record/associations/has_many_association.rb +0 -1
  15. data/lib/active_record/associations/join_dependency.rb +13 -0
  16. data/lib/active_record/associations/join_dependency/join_association.rb +1 -1
  17. data/lib/active_record/associations/preloader.rb +2 -3
  18. data/lib/active_record/attribute_assignment.rb +0 -1
  19. data/lib/active_record/attribute_decorators.rb +0 -2
  20. data/lib/active_record/attribute_methods/before_type_cast.rb +0 -1
  21. data/lib/active_record/attribute_methods/dirty.rb +2 -2
  22. data/lib/active_record/attribute_methods/primary_key.rb +0 -2
  23. data/lib/active_record/attribute_methods/read.rb +0 -1
  24. data/lib/active_record/attribute_methods/serialization.rb +0 -1
  25. data/lib/active_record/attribute_methods/time_zone_conversion.rb +0 -2
  26. data/lib/active_record/attribute_methods/write.rb +0 -1
  27. data/lib/active_record/attributes.rb +0 -1
  28. data/lib/active_record/autosave_association.rb +8 -6
  29. data/lib/active_record/callbacks.rb +1 -2
  30. data/lib/active_record/coders/yaml_column.rb +0 -1
  31. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +14 -7
  32. data/lib/active_record/connection_adapters/abstract/database_statements.rb +21 -15
  33. data/lib/active_record/connection_adapters/abstract/query_cache.rb +2 -2
  34. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +1 -2
  35. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +27 -27
  36. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +47 -30
  37. data/lib/active_record/connection_adapters/abstract/transaction.rb +4 -5
  38. data/lib/active_record/connection_adapters/abstract_adapter.rb +23 -8
  39. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +25 -32
  40. data/lib/active_record/connection_adapters/connection_specification.rb +2 -3
  41. data/lib/active_record/connection_adapters/mysql/column.rb +1 -1
  42. data/lib/active_record/connection_adapters/mysql/database_statements.rb +8 -12
  43. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +0 -1
  44. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +1 -2
  45. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +8 -8
  46. data/lib/active_record/connection_adapters/mysql2_adapter.rb +0 -1
  47. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +9 -3
  48. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +0 -1
  49. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +0 -1
  50. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +0 -1
  51. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +0 -1
  52. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
  53. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +0 -1
  54. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +0 -1
  55. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
  56. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +0 -1
  57. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +1 -1
  58. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +2 -2
  59. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +1 -1
  60. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +0 -1
  61. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +15 -29
  62. data/lib/active_record/connection_adapters/postgresql/utils.rb +0 -1
  63. data/lib/active_record/connection_adapters/postgresql_adapter.rb +9 -2
  64. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +8 -7
  65. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +0 -1
  66. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +3 -3
  67. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +12 -7
  68. data/lib/active_record/connection_adapters/statement_pool.rb +0 -1
  69. data/lib/active_record/connection_handling.rb +13 -22
  70. data/lib/active_record/core.rb +8 -6
  71. data/lib/active_record/counter_cache.rb +4 -1
  72. data/lib/active_record/database_configurations/url_config.rb +0 -1
  73. data/lib/active_record/dynamic_matchers.rb +2 -3
  74. data/lib/active_record/explain.rb +0 -1
  75. data/lib/active_record/fixture_set/table_row.rb +0 -1
  76. data/lib/active_record/fixture_set/table_rows.rb +0 -1
  77. data/lib/active_record/fixtures.rb +0 -3
  78. data/lib/active_record/gem_version.rb +1 -1
  79. data/lib/active_record/inheritance.rb +0 -3
  80. data/lib/active_record/insert_all.rb +4 -4
  81. data/lib/active_record/internal_metadata.rb +1 -1
  82. data/lib/active_record/locking/optimistic.rb +0 -1
  83. data/lib/active_record/log_subscriber.rb +1 -1
  84. data/lib/active_record/middleware/database_selector.rb +0 -1
  85. data/lib/active_record/middleware/database_selector/resolver.rb +9 -14
  86. data/lib/active_record/migration.rb +4 -4
  87. data/lib/active_record/migration/command_recorder.rb +6 -18
  88. data/lib/active_record/migration/compatibility.rb +3 -3
  89. data/lib/active_record/migration/join_table.rb +0 -1
  90. data/lib/active_record/model_schema.rb +3 -2
  91. data/lib/active_record/nested_attributes.rb +0 -2
  92. data/lib/active_record/no_touching.rb +2 -2
  93. data/lib/active_record/null_relation.rb +0 -1
  94. data/lib/active_record/persistence.rb +4 -5
  95. data/lib/active_record/querying.rb +1 -1
  96. data/lib/active_record/railtie.rb +1 -1
  97. data/lib/active_record/railties/collection_cache_association_loading.rb +1 -1
  98. data/lib/active_record/railties/databases.rake +3 -0
  99. data/lib/active_record/reflection.rb +8 -8
  100. data/lib/active_record/relation.rb +13 -1
  101. data/lib/active_record/relation/batches.rb +0 -1
  102. data/lib/active_record/relation/calculations.rb +1 -1
  103. data/lib/active_record/relation/delegation.rb +7 -6
  104. data/lib/active_record/relation/finder_methods.rb +10 -2
  105. data/lib/active_record/relation/from_clause.rb +4 -0
  106. data/lib/active_record/relation/merger.rb +0 -1
  107. data/lib/active_record/relation/predicate_builder.rb +1 -5
  108. data/lib/active_record/relation/query_methods.rb +37 -12
  109. data/lib/active_record/relation/spawn_methods.rb +0 -1
  110. data/lib/active_record/relation/where_clause.rb +0 -1
  111. data/lib/active_record/result.rb +0 -1
  112. data/lib/active_record/schema_migration.rb +1 -1
  113. data/lib/active_record/scoping.rb +0 -1
  114. data/lib/active_record/scoping/default.rb +0 -1
  115. data/lib/active_record/scoping/named.rb +3 -3
  116. data/lib/active_record/store.rb +1 -1
  117. data/lib/active_record/suppressor.rb +2 -2
  118. data/lib/active_record/table_metadata.rb +16 -1
  119. data/lib/active_record/tasks/mysql_database_tasks.rb +0 -1
  120. data/lib/active_record/tasks/postgresql_database_tasks.rb +0 -1
  121. data/lib/active_record/tasks/sqlite_database_tasks.rb +0 -1
  122. data/lib/active_record/test_fixtures.rb +2 -1
  123. data/lib/active_record/timestamp.rb +0 -1
  124. data/lib/active_record/touch_later.rb +1 -2
  125. data/lib/active_record/transactions.rb +9 -9
  126. data/lib/active_record/type.rb +0 -1
  127. data/lib/active_record/type/adapter_specific_registry.rb +2 -5
  128. data/lib/active_record/type/hash_lookup_type_map.rb +0 -1
  129. data/lib/active_record/type/serialized.rb +0 -1
  130. data/lib/active_record/type/type_map.rb +0 -1
  131. data/lib/active_record/type/unsigned_integer.rb +0 -1
  132. data/lib/active_record/validations.rb +2 -3
  133. data/lib/active_record/validations/associated.rb +1 -2
  134. data/lib/arel.rb +17 -6
  135. data/lib/arel/predications.rb +5 -6
  136. data/lib/arel/visitors/depth_first.rb +0 -1
  137. data/lib/arel/visitors/dot.rb +0 -1
  138. data/lib/arel/visitors/mssql.rb +0 -1
  139. data/lib/arel/visitors/oracle.rb +1 -2
  140. data/lib/arel/visitors/oracle12.rb +0 -1
  141. data/lib/arel/visitors/postgresql.rb +0 -1
  142. data/lib/arel/visitors/sqlite.rb +0 -1
  143. data/lib/arel/visitors/to_sql.rb +0 -1
  144. data/lib/arel/visitors/visitor.rb +0 -1
  145. data/lib/arel/visitors/where_sql.rb +0 -1
  146. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +0 -1
  147. data/lib/rails/generators/active_record/migration.rb +0 -1
  148. data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +1 -1
  149. data/lib/rails/generators/active_record/model/model_generator.rb +0 -1
  150. metadata +13 -9
@@ -4,7 +4,9 @@ module ActiveRecord
4
4
  module ConnectionAdapters
5
5
  module SQLite3
6
6
  module DatabaseStatements
7
- READ_QUERY = ActiveRecord::ConnectionAdapters::AbstractAdapter.build_read_query_regexp(:begin, :commit, :explain, :select, :pragma, :release, :savepoint, :rollback) # :nodoc:
7
+ READ_QUERY = ActiveRecord::ConnectionAdapters::AbstractAdapter.build_read_query_regexp(
8
+ :begin, :commit, :explain, :select, :pragma, :release, :savepoint, :rollback, :with
9
+ ) # :nodoc:
8
10
  private_constant :READ_QUERY
9
11
 
10
12
  def write_query?(sql) # :nodoc:
@@ -81,7 +83,9 @@ module ActiveRecord
81
83
 
82
84
 
83
85
  private
84
- def execute_batch(sql, name = nil)
86
+ def execute_batch(statements, name = nil)
87
+ sql = combine_multi_statements(statements)
88
+
85
89
  if preventing_writes? && write_query?(sql)
86
90
  raise ActiveRecord::ReadOnlyError, "Write query attempted while in readonly mode: #{sql}"
87
91
  end
@@ -106,11 +110,8 @@ module ActiveRecord
106
110
  end.compact
107
111
  end
108
112
 
109
- def build_truncate_statements(*table_names)
110
- truncate_tables = table_names.map do |table_name|
111
- "DELETE FROM #{quote_table_name(table_name)}"
112
- end
113
- combine_multi_statements(truncate_tables)
113
+ def build_truncate_statement(table_name)
114
+ "DELETE FROM #{quote_table_name(table_name)}"
114
115
  end
115
116
  end
116
117
  end
@@ -82,7 +82,6 @@ module ActiveRecord
82
82
  private_constant :COLUMN_NAME, :COLUMN_NAME_WITH_ORDER
83
83
 
84
84
  private
85
-
86
85
  def _type_cast(value)
87
86
  case value
88
87
  when BigDecimal
@@ -55,7 +55,7 @@ module ActiveRecord
55
55
  def add_foreign_key(from_table, to_table, **options)
56
56
  alter_table(from_table) do |definition|
57
57
  to_table = strip_table_name_prefix_and_suffix(to_table)
58
- definition.foreign_key(to_table, options)
58
+ definition.foreign_key(to_table, **options)
59
59
  end
60
60
  end
61
61
 
@@ -87,8 +87,8 @@ module ActiveRecord
87
87
  SQLite3::SchemaCreation.new(self)
88
88
  end
89
89
 
90
- def create_table_definition(*args)
91
- SQLite3::TableDefinition.new(self, *args)
90
+ def create_table_definition(*args, **options)
91
+ SQLite3::TableDefinition.new(self, *args, **options)
92
92
  end
93
93
 
94
94
  def new_column_from_field(table_name, field)
@@ -101,7 +101,7 @@ module ActiveRecord
101
101
  def self.database_exists?(config)
102
102
  config = config.symbolize_keys
103
103
  if config[:database] == ":memory:"
104
- return true
104
+ true
105
105
  else
106
106
  database_file = defined?(Rails.root) ? File.expand_path(config[:database], Rails.root) : config[:database]
107
107
  File.exist?(database_file)
@@ -144,6 +144,10 @@ module ActiveRecord
144
144
  true
145
145
  end
146
146
 
147
+ def supports_common_table_expressions?
148
+ database_version >= "3.8.3"
149
+ end
150
+
147
151
  def supports_insert_on_conflict?
148
152
  database_version >= "3.24.0"
149
153
  end
@@ -240,17 +244,17 @@ module ActiveRecord
240
244
  rename_table_indexes(table_name, new_name)
241
245
  end
242
246
 
243
- def add_column(table_name, column_name, type, options = {}) #:nodoc:
247
+ def add_column(table_name, column_name, type, **options) #:nodoc:
244
248
  if invalid_alter_table_type?(type, options)
245
249
  alter_table(table_name) do |definition|
246
- definition.column(column_name, type, options)
250
+ definition.column(column_name, type, **options)
247
251
  end
248
252
  else
249
253
  super
250
254
  end
251
255
  end
252
256
 
253
- def remove_column(table_name, column_name, type = nil, options = {}) #:nodoc:
257
+ def remove_column(table_name, column_name, type = nil, **options) #:nodoc:
254
258
  alter_table(table_name) do |definition|
255
259
  definition.remove_column column_name
256
260
  definition.foreign_keys.delete_if do |_, fk_options|
@@ -359,7 +363,8 @@ module ActiveRecord
359
363
  # See: https://www.sqlite.org/lang_altertable.html
360
364
  # SQLite has an additional restriction on the ALTER TABLE statement
361
365
  def invalid_alter_table_type?(type, options)
362
- type.to_sym == :primary_key || options[:primary_key]
366
+ type.to_sym == :primary_key || options[:primary_key] ||
367
+ options[:null] == false && options[:default].nil?
363
368
  end
364
369
 
365
370
  def alter_table(table_name, foreign_keys = foreign_keys(table_name), **options)
@@ -372,7 +377,7 @@ module ActiveRecord
372
377
  fk.options[:column] = column
373
378
  end
374
379
  to_table = strip_table_name_prefix_and_suffix(fk.to_table)
375
- definition.foreign_key(to_table, fk.options)
380
+ definition.foreign_key(to_table, **fk.options)
376
381
  end
377
382
 
378
383
  yield definition if block_given?
@@ -394,7 +399,7 @@ module ActiveRecord
394
399
  def copy_table(from, to, options = {})
395
400
  from_primary_key = primary_key(from)
396
401
  options[:id] = false
397
- create_table(to, options) do |definition|
402
+ create_table(to, **options) do |definition|
398
403
  @definition = definition
399
404
  if from_primary_key.is_a?(Array)
400
405
  @definition.primary_keys from_primary_key
@@ -48,7 +48,6 @@ module ActiveRecord
48
48
  end
49
49
 
50
50
  private
51
-
52
51
  def cache
53
52
  @cache[Process.pid]
54
53
  end
@@ -96,25 +96,11 @@ module ActiveRecord
96
96
  # # raises exception due to non-existent role
97
97
  # end
98
98
  #
99
- # For cases where you may want to connect to a database outside of the model,
100
- # you can use +connected_to+ with a +database+ argument. The +database+ argument
101
- # expects a symbol that corresponds to the database key in your config.
99
+ # The `database` kwarg is deprecated in 6.1 and will be removed in 6.2
102
100
  #
103
- # ActiveRecord::Base.connected_to(database: :animals_slow_replica) do
104
- # Dog.run_a_long_query # runs a long query while connected to the +animals_slow_replica+
105
- # end
106
- #
107
- # This will connect to a new database for the queries inside the block. By
108
- # default the `:writing` role will be used since all connections must be assigned
109
- # a role. If you would like to use a different role you can pass a hash to database:
110
- #
111
- # ActiveRecord::Base.connected_to(database: { readonly_slow: :animals_slow_replica }) do
112
- # # runs a long query while connected to the +animals_slow_replica+ using the readonly_slow role.
113
- # Dog.run_a_long_query
114
- # end
115
- #
116
- # When using the database key a new connection will be established every time.
117
- def connected_to(database: nil, role: nil, &blk)
101
+ # It is not recommended for use as it re-establishes a connection every
102
+ # time it is called.
103
+ def connected_to(database: nil, role: nil, prevent_writes: false, &blk)
118
104
  if database && role
119
105
  raise ArgumentError, "connected_to can only accept a `database` or a `role` argument, but not both arguments."
120
106
  elsif database
@@ -130,7 +116,11 @@ module ActiveRecord
130
116
 
131
117
  with_handler(role, &blk)
132
118
  elsif role
133
- with_handler(role.to_sym, &blk)
119
+ prevent_writes = true if role == reading_role
120
+
121
+ with_handler(role.to_sym) do
122
+ connection_handler.while_preventing_writes(prevent_writes, &blk)
123
+ end
134
124
  else
135
125
  raise ArgumentError, "must provide a `database` or a `role`."
136
126
  end
@@ -204,7 +194,7 @@ module ActiveRecord
204
194
  # Return the specification name from the current class or its parent.
205
195
  def connection_specification_name
206
196
  if !defined?(@connection_specification_name) || @connection_specification_name.nil?
207
- return primary_class? ? "primary" : superclass.connection_specification_name
197
+ return self == Base ? "primary" : superclass.connection_specification_name
208
198
  end
209
199
  @connection_specification_name
210
200
  end
@@ -256,10 +246,11 @@ module ActiveRecord
256
246
  :clear_all_connections!, :flush_idle_connections!, to: :connection_handler
257
247
 
258
248
  private
259
-
260
249
  def swap_connection_handler(handler, &blk) # :nodoc:
261
250
  old_handler, ActiveRecord::Base.connection_handler = ActiveRecord::Base.connection_handler, handler
262
- yield
251
+ return_value = yield
252
+ return_value.load if return_value.is_a? ActiveRecord::Relation
253
+ return_value
263
254
  ensure
264
255
  ActiveRecord::Base.connection_handler = old_handler
265
256
  end
@@ -286,7 +286,6 @@ module ActiveRecord
286
286
  end
287
287
 
288
288
  private
289
-
290
289
  def cached_find_by_statement(key, &block)
291
290
  cache = @find_by_statement_cache[connection.prepared_statements]
292
291
  cache.compute_if_absent(key) { StatementCache.create(connection, &block) }
@@ -554,7 +553,6 @@ module ActiveRecord
554
553
  end
555
554
 
556
555
  private
557
-
558
556
  # +Array#flatten+ will call +#to_ary+ (recursively) on each of the elements of
559
557
  # the array, and then rescues from the possible +NoMethodError+. If those elements are
560
558
  # +ActiveRecord::Base+'s, then this triggers the various +method_missing+'s that we have,
@@ -586,12 +584,16 @@ module ActiveRecord
586
584
  self.class.instance_method(:inspect).owner != ActiveRecord::Base.instance_method(:inspect).owner
587
585
  end
588
586
 
587
+ class InspectionMask < DelegateClass(::String)
588
+ def pretty_print(pp)
589
+ pp.text __getobj__
590
+ end
591
+ end
592
+ private_constant :InspectionMask
593
+
589
594
  def inspection_filter
590
595
  @inspection_filter ||= begin
591
- mask = DelegateClass(::String).new(ActiveSupport::ParameterFilter::FILTERED)
592
- def mask.pretty_print(pp)
593
- pp.text __getobj__
594
- end
596
+ mask = InspectionMask.new(ActiveSupport::ParameterFilter::FILTERED)
595
597
  ActiveSupport::ParameterFilter.new(self.class.filter_attributes, mask: mask)
596
598
  end
597
599
  end
@@ -51,7 +51,10 @@ module ActiveRecord
51
51
 
52
52
  if touch
53
53
  names = touch if touch != true
54
- updates.merge!(touch_attributes_with_time(*names))
54
+ names = Array.wrap(names)
55
+ options = names.extract_options!
56
+ touch_updates = touch_attributes_with_time(*names, **options)
57
+ updates.merge!(touch_updates)
55
58
  end
56
59
 
57
60
  unscoped.where(primary_key => object.id).update_all(updates)
@@ -56,7 +56,6 @@ module ActiveRecord
56
56
  end
57
57
 
58
58
  private
59
-
60
59
  def build_url_hash(url)
61
60
  if url.nil? || /^jdbc:/.match?(url)
62
61
  { "url" => url }
@@ -49,9 +49,9 @@ module ActiveRecord
49
49
 
50
50
  attr_reader :model, :name, :attribute_names
51
51
 
52
- def initialize(model, name)
52
+ def initialize(model, method_name)
53
53
  @model = model
54
- @name = name.to_s
54
+ @name = method_name.to_s
55
55
  @attribute_names = @name.match(self.class.pattern)[1].split("_and_")
56
56
  @attribute_names.map! { |name| @model.attribute_aliases[name] || name }
57
57
  end
@@ -69,7 +69,6 @@ module ActiveRecord
69
69
  end
70
70
 
71
71
  private
72
-
73
72
  def body
74
73
  "#{finder}(#{attributes_hash})"
75
74
  end
@@ -36,7 +36,6 @@ module ActiveRecord
36
36
  end
37
37
 
38
38
  private
39
-
40
39
  def render_bind(attr)
41
40
  value = if attr.type.binary? && attr.value
42
41
  "<#{attr.value_for_database.to_s.bytesize} bytes of binary data>"
@@ -48,7 +48,6 @@ module ActiveRecord
48
48
  end
49
49
 
50
50
  private
51
-
52
51
  def model_metadata
53
52
  @table_rows.model_metadata
54
53
  end
@@ -29,7 +29,6 @@ module ActiveRecord
29
29
  end
30
30
 
31
31
  private
32
-
33
32
  def build_table_rows_from(table_name, fixtures, config)
34
33
  now = config.default_timezone == :utc ? Time.now.utc : Time.now
35
34
 
@@ -464,7 +464,6 @@ module ActiveRecord
464
464
  end
465
465
 
466
466
  private
467
-
468
467
  def insert_class(class_names, name, klass)
469
468
  # We only want to deal with AR objects.
470
469
  if klass && klass < ActiveRecord::Base
@@ -570,7 +569,6 @@ module ActiveRecord
570
569
  end
571
570
 
572
571
  private
573
-
574
572
  def read_and_insert(fixtures_directory, fixture_files, class_names, connection) # :nodoc:
575
573
  fixtures_map = {}
576
574
  fixture_sets = fixture_files.map do |fixture_set_name|
@@ -666,7 +664,6 @@ module ActiveRecord
666
664
  end
667
665
 
668
666
  private
669
-
670
667
  def model_class=(class_name)
671
668
  if class_name.is_a?(Class) # TODO: Should be an AR::Base type class, or any?
672
669
  @model_class = class_name
@@ -9,7 +9,7 @@ module ActiveRecord
9
9
  module VERSION
10
10
  MAJOR = 6
11
11
  MINOR = 0
12
- TINY = 0
12
+ TINY = 3
13
13
  PRE = nil
14
14
 
15
15
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
@@ -176,7 +176,6 @@ module ActiveRecord
176
176
  end
177
177
 
178
178
  protected
179
-
180
179
  # Returns the class type of the record using the current module as a prefix. So descendants of
181
180
  # MyApp::Business::Account would appear as MyApp::Business::AccountSubclass.
182
181
  def compute_type(type_name)
@@ -208,7 +207,6 @@ module ActiveRecord
208
207
  end
209
208
 
210
209
  private
211
-
212
210
  # Called by +instantiate+ to decide which class to use for a new
213
211
  # record instance. For single-table inheritance, we check the record
214
212
  # for a +type+ column and return the corresponding class.
@@ -272,7 +270,6 @@ module ActiveRecord
272
270
  end
273
271
 
274
272
  private
275
-
276
273
  def initialize_internals_callback
277
274
  super
278
275
  ensure_proper_type
@@ -24,7 +24,7 @@ module ActiveRecord
24
24
  message = +"#{model} "
25
25
  message << "Bulk " if inserts.many?
26
26
  message << (on_duplicate == :update ? "Upsert" : "Insert")
27
- connection.exec_query to_sql, message
27
+ connection.exec_insert_all to_sql, message
28
28
  end
29
29
 
30
30
  def updatable_columns
@@ -120,7 +120,7 @@ module ActiveRecord
120
120
  end
121
121
 
122
122
  def into
123
- "INTO #{model.quoted_table_name}(#{columns_list})"
123
+ "INTO #{model.quoted_table_name} (#{columns_list})"
124
124
  end
125
125
 
126
126
  def values_list
@@ -130,7 +130,7 @@ module ActiveRecord
130
130
  connection.with_yaml_fallback(types[key].serialize(value))
131
131
  end
132
132
 
133
- Arel::InsertManager.new.create_values_list(values_list).to_sql
133
+ connection.visitor.compile(Arel::Nodes::ValuesList.new(values_list))
134
134
  end
135
135
 
136
136
  def returning
@@ -164,7 +164,7 @@ module ActiveRecord
164
164
  unknown_column = (keys - columns.keys).first
165
165
  raise UnknownAttributeError.new(model.new, unknown_column) if unknown_column
166
166
 
167
- keys.map { |key| [ key, connection.lookup_cast_type_from_column(columns[key]) ] }.to_h
167
+ keys.index_with { |key| model.type_for_attribute(key) }
168
168
  end
169
169
 
170
170
  def format_columns(columns)
@@ -38,7 +38,7 @@ module ActiveRecord
38
38
  key_options = connection.internal_string_options_for_primary_key
39
39
 
40
40
  connection.create_table(table_name, id: false) do |t|
41
- t.string :key, key_options
41
+ t.string :key, **key_options
42
42
  t.string :value
43
43
  t.timestamps
44
44
  end
@@ -156,7 +156,6 @@ module ActiveRecord
156
156
  end
157
157
 
158
158
  private
159
-
160
159
  # We need to apply this decorator here, rather than on module inclusion. The closure
161
160
  # created by the matcher would otherwise evaluate for `ActiveRecord::Base`, not the
162
161
  # sub class being decorated. As such, changes to `lock_optimistically`, or
@@ -40,7 +40,7 @@ module ActiveRecord
40
40
  end
41
41
 
42
42
  name = colorize_payload_name(name, payload[:name])
43
- sql = color(sql, sql_color(sql), true)
43
+ sql = color(sql, sql_color(sql), true) if colorize_logging
44
44
 
45
45
  debug " #{name} #{sql}#{binds}"
46
46
  end
@@ -55,7 +55,6 @@ module ActiveRecord
55
55
  end
56
56
 
57
57
  private
58
-
59
58
  def select_database(request, &blk)
60
59
  context = context_klass.call(request)
61
60
  resolver = resolver_klass.call(context, options)
@@ -44,19 +44,16 @@ module ActiveRecord
44
44
  end
45
45
 
46
46
  private
47
-
48
47
  def read_from_primary(&blk)
49
- ActiveRecord::Base.connected_to(role: ActiveRecord::Base.writing_role) do
50
- ActiveRecord::Base.connection_handler.while_preventing_writes(true) do
51
- instrumenter.instrument("database_selector.active_record.read_from_primary") do
52
- yield
53
- end
48
+ ActiveRecord::Base.connected_to(role: ActiveRecord::Base.writing_role, prevent_writes: true) do
49
+ instrumenter.instrument("database_selector.active_record.read_from_primary") do
50
+ yield
54
51
  end
55
52
  end
56
53
  end
57
54
 
58
55
  def read_from_replica(&blk)
59
- ActiveRecord::Base.connected_to(role: ActiveRecord::Base.reading_role) do
56
+ ActiveRecord::Base.connected_to(role: ActiveRecord::Base.reading_role, prevent_writes: true) do
60
57
  instrumenter.instrument("database_selector.active_record.read_from_replica") do
61
58
  yield
62
59
  end
@@ -64,13 +61,11 @@ module ActiveRecord
64
61
  end
65
62
 
66
63
  def write_to_primary(&blk)
67
- ActiveRecord::Base.connected_to(role: ActiveRecord::Base.writing_role) do
68
- ActiveRecord::Base.connection_handler.while_preventing_writes(false) do
69
- instrumenter.instrument("database_selector.active_record.wrote_to_primary") do
70
- yield
71
- ensure
72
- context.update_last_write_timestamp
73
- end
64
+ ActiveRecord::Base.connected_to(role: ActiveRecord::Base.writing_role, prevent_writes: false) do
65
+ instrumenter.instrument("database_selector.active_record.wrote_to_primary") do
66
+ yield
67
+ ensure
68
+ context.update_last_write_timestamp
74
69
  end
75
70
  end
76
71
  end