activerecord 6.1.4.6 → 7.0.2.3

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activerecord might be problematic. Click here for more details.

Files changed (240) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1188 -932
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +1 -1
  5. data/lib/active_record/aggregations.rb +1 -1
  6. data/lib/active_record/association_relation.rb +0 -10
  7. data/lib/active_record/associations/association.rb +33 -17
  8. data/lib/active_record/associations/association_scope.rb +1 -3
  9. data/lib/active_record/associations/belongs_to_association.rb +15 -4
  10. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +10 -2
  11. data/lib/active_record/associations/builder/association.rb +8 -2
  12. data/lib/active_record/associations/builder/belongs_to.rb +19 -6
  13. data/lib/active_record/associations/builder/collection_association.rb +10 -3
  14. data/lib/active_record/associations/builder/has_many.rb +3 -2
  15. data/lib/active_record/associations/builder/has_one.rb +2 -1
  16. data/lib/active_record/associations/builder/singular_association.rb +2 -2
  17. data/lib/active_record/associations/collection_association.rb +34 -27
  18. data/lib/active_record/associations/collection_proxy.rb +8 -3
  19. data/lib/active_record/associations/disable_joins_association_scope.rb +59 -0
  20. data/lib/active_record/associations/has_many_association.rb +1 -1
  21. data/lib/active_record/associations/has_many_through_association.rb +2 -1
  22. data/lib/active_record/associations/has_one_association.rb +10 -7
  23. data/lib/active_record/associations/has_one_through_association.rb +1 -1
  24. data/lib/active_record/associations/join_dependency.rb +6 -2
  25. data/lib/active_record/associations/preloader/association.rb +187 -55
  26. data/lib/active_record/associations/preloader/batch.rb +48 -0
  27. data/lib/active_record/associations/preloader/branch.rb +147 -0
  28. data/lib/active_record/associations/preloader/through_association.rb +49 -13
  29. data/lib/active_record/associations/preloader.rb +39 -113
  30. data/lib/active_record/associations/singular_association.rb +8 -2
  31. data/lib/active_record/associations/through_association.rb +3 -3
  32. data/lib/active_record/associations.rb +119 -90
  33. data/lib/active_record/asynchronous_queries_tracker.rb +60 -0
  34. data/lib/active_record/attribute_assignment.rb +1 -1
  35. data/lib/active_record/attribute_methods/before_type_cast.rb +7 -2
  36. data/lib/active_record/attribute_methods/dirty.rb +49 -16
  37. data/lib/active_record/attribute_methods/primary_key.rb +2 -2
  38. data/lib/active_record/attribute_methods/query.rb +2 -2
  39. data/lib/active_record/attribute_methods/read.rb +7 -5
  40. data/lib/active_record/attribute_methods/serialization.rb +66 -12
  41. data/lib/active_record/attribute_methods/time_zone_conversion.rb +4 -3
  42. data/lib/active_record/attribute_methods/write.rb +7 -10
  43. data/lib/active_record/attribute_methods.rb +13 -14
  44. data/lib/active_record/attributes.rb +24 -35
  45. data/lib/active_record/autosave_association.rb +8 -23
  46. data/lib/active_record/base.rb +19 -1
  47. data/lib/active_record/callbacks.rb +2 -2
  48. data/lib/active_record/connection_adapters/abstract/connection_handler.rb +292 -0
  49. data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +209 -0
  50. data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +76 -0
  51. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +47 -561
  52. data/lib/active_record/connection_adapters/abstract/database_limits.rb +0 -17
  53. data/lib/active_record/connection_adapters/abstract/database_statements.rb +46 -22
  54. data/lib/active_record/connection_adapters/abstract/query_cache.rb +24 -12
  55. data/lib/active_record/connection_adapters/abstract/quoting.rb +42 -72
  56. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +4 -17
  57. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +38 -13
  58. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +14 -1
  59. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +78 -22
  60. data/lib/active_record/connection_adapters/abstract/transaction.rb +15 -22
  61. data/lib/active_record/connection_adapters/abstract_adapter.rb +149 -74
  62. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +97 -81
  63. data/lib/active_record/connection_adapters/column.rb +4 -0
  64. data/lib/active_record/connection_adapters/mysql/database_statements.rb +38 -24
  65. data/lib/active_record/connection_adapters/mysql/quoting.rb +35 -21
  66. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +7 -1
  67. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +5 -1
  68. data/lib/active_record/connection_adapters/mysql2_adapter.rb +12 -6
  69. data/lib/active_record/connection_adapters/pool_config.rb +7 -7
  70. data/lib/active_record/connection_adapters/postgresql/column.rb +17 -1
  71. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +21 -12
  72. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +8 -0
  73. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +5 -0
  74. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +53 -14
  75. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +1 -1
  76. data/lib/active_record/connection_adapters/postgresql/oid/timestamp.rb +15 -0
  77. data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +30 -0
  78. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +18 -6
  79. data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
  80. data/lib/active_record/connection_adapters/postgresql/quoting.rb +50 -50
  81. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +32 -0
  82. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +21 -1
  83. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +22 -1
  84. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +25 -0
  85. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +35 -19
  86. data/lib/active_record/connection_adapters/postgresql_adapter.rb +207 -107
  87. data/lib/active_record/connection_adapters/schema_cache.rb +29 -4
  88. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +27 -19
  89. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +28 -16
  90. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +16 -14
  91. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +89 -30
  92. data/lib/active_record/connection_adapters.rb +6 -5
  93. data/lib/active_record/connection_handling.rb +47 -53
  94. data/lib/active_record/core.rb +122 -132
  95. data/lib/active_record/database_configurations/connection_url_resolver.rb +3 -1
  96. data/lib/active_record/database_configurations/database_config.rb +12 -9
  97. data/lib/active_record/database_configurations/hash_config.rb +63 -5
  98. data/lib/active_record/database_configurations/url_config.rb +2 -2
  99. data/lib/active_record/database_configurations.rb +16 -32
  100. data/lib/active_record/delegated_type.rb +52 -11
  101. data/lib/active_record/destroy_association_async_job.rb +1 -1
  102. data/lib/active_record/disable_joins_association_relation.rb +39 -0
  103. data/lib/active_record/dynamic_matchers.rb +1 -1
  104. data/lib/active_record/encryption/cipher/aes256_gcm.rb +98 -0
  105. data/lib/active_record/encryption/cipher.rb +53 -0
  106. data/lib/active_record/encryption/config.rb +44 -0
  107. data/lib/active_record/encryption/configurable.rb +61 -0
  108. data/lib/active_record/encryption/context.rb +35 -0
  109. data/lib/active_record/encryption/contexts.rb +72 -0
  110. data/lib/active_record/encryption/derived_secret_key_provider.rb +12 -0
  111. data/lib/active_record/encryption/deterministic_key_provider.rb +14 -0
  112. data/lib/active_record/encryption/encryptable_record.rb +208 -0
  113. data/lib/active_record/encryption/encrypted_attribute_type.rb +140 -0
  114. data/lib/active_record/encryption/encrypted_fixtures.rb +38 -0
  115. data/lib/active_record/encryption/encrypting_only_encryptor.rb +12 -0
  116. data/lib/active_record/encryption/encryptor.rb +155 -0
  117. data/lib/active_record/encryption/envelope_encryption_key_provider.rb +55 -0
  118. data/lib/active_record/encryption/errors.rb +15 -0
  119. data/lib/active_record/encryption/extended_deterministic_queries.rb +160 -0
  120. data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +28 -0
  121. data/lib/active_record/encryption/key.rb +28 -0
  122. data/lib/active_record/encryption/key_generator.rb +42 -0
  123. data/lib/active_record/encryption/key_provider.rb +46 -0
  124. data/lib/active_record/encryption/message.rb +33 -0
  125. data/lib/active_record/encryption/message_serializer.rb +90 -0
  126. data/lib/active_record/encryption/null_encryptor.rb +21 -0
  127. data/lib/active_record/encryption/properties.rb +76 -0
  128. data/lib/active_record/encryption/read_only_null_encryptor.rb +24 -0
  129. data/lib/active_record/encryption/scheme.rb +99 -0
  130. data/lib/active_record/encryption.rb +55 -0
  131. data/lib/active_record/enum.rb +49 -42
  132. data/lib/active_record/errors.rb +67 -4
  133. data/lib/active_record/explain_registry.rb +11 -6
  134. data/lib/active_record/fixture_set/file.rb +15 -1
  135. data/lib/active_record/fixture_set/table_row.rb +41 -6
  136. data/lib/active_record/fixture_set/table_rows.rb +4 -4
  137. data/lib/active_record/fixtures.rb +17 -20
  138. data/lib/active_record/future_result.rb +139 -0
  139. data/lib/active_record/gem_version.rb +4 -4
  140. data/lib/active_record/inheritance.rb +55 -17
  141. data/lib/active_record/insert_all.rb +80 -14
  142. data/lib/active_record/integration.rb +4 -3
  143. data/lib/active_record/internal_metadata.rb +3 -5
  144. data/lib/active_record/legacy_yaml_adapter.rb +2 -39
  145. data/lib/active_record/locking/optimistic.rb +10 -9
  146. data/lib/active_record/locking/pessimistic.rb +9 -3
  147. data/lib/active_record/log_subscriber.rb +14 -3
  148. data/lib/active_record/middleware/database_selector/resolver.rb +6 -10
  149. data/lib/active_record/middleware/database_selector.rb +8 -3
  150. data/lib/active_record/middleware/shard_selector.rb +60 -0
  151. data/lib/active_record/migration/command_recorder.rb +4 -4
  152. data/lib/active_record/migration/compatibility.rb +107 -3
  153. data/lib/active_record/migration/join_table.rb +1 -1
  154. data/lib/active_record/migration.rb +109 -79
  155. data/lib/active_record/model_schema.rb +45 -58
  156. data/lib/active_record/nested_attributes.rb +13 -12
  157. data/lib/active_record/no_touching.rb +3 -3
  158. data/lib/active_record/null_relation.rb +2 -6
  159. data/lib/active_record/persistence.rb +219 -52
  160. data/lib/active_record/query_cache.rb +2 -2
  161. data/lib/active_record/query_logs.rb +138 -0
  162. data/lib/active_record/querying.rb +15 -5
  163. data/lib/active_record/railtie.rb +127 -17
  164. data/lib/active_record/railties/controller_runtime.rb +1 -1
  165. data/lib/active_record/railties/databases.rake +66 -129
  166. data/lib/active_record/readonly_attributes.rb +11 -0
  167. data/lib/active_record/reflection.rb +67 -50
  168. data/lib/active_record/relation/batches/batch_enumerator.rb +19 -5
  169. data/lib/active_record/relation/batches.rb +3 -3
  170. data/lib/active_record/relation/calculations.rb +43 -38
  171. data/lib/active_record/relation/delegation.rb +7 -7
  172. data/lib/active_record/relation/finder_methods.rb +31 -35
  173. data/lib/active_record/relation/merger.rb +20 -13
  174. data/lib/active_record/relation/predicate_builder.rb +1 -6
  175. data/lib/active_record/relation/query_attribute.rb +5 -11
  176. data/lib/active_record/relation/query_methods.rb +249 -61
  177. data/lib/active_record/relation/record_fetch_warning.rb +7 -9
  178. data/lib/active_record/relation/spawn_methods.rb +2 -2
  179. data/lib/active_record/relation/where_clause.rb +10 -19
  180. data/lib/active_record/relation.rb +184 -84
  181. data/lib/active_record/result.rb +17 -7
  182. data/lib/active_record/runtime_registry.rb +9 -13
  183. data/lib/active_record/sanitization.rb +11 -7
  184. data/lib/active_record/schema.rb +38 -23
  185. data/lib/active_record/schema_dumper.rb +25 -19
  186. data/lib/active_record/schema_migration.rb +4 -4
  187. data/lib/active_record/scoping/default.rb +61 -12
  188. data/lib/active_record/scoping/named.rb +3 -11
  189. data/lib/active_record/scoping.rb +64 -34
  190. data/lib/active_record/serialization.rb +1 -1
  191. data/lib/active_record/signed_id.rb +1 -1
  192. data/lib/active_record/suppressor.rb +11 -15
  193. data/lib/active_record/tasks/database_tasks.rb +120 -58
  194. data/lib/active_record/tasks/mysql_database_tasks.rb +1 -1
  195. data/lib/active_record/tasks/postgresql_database_tasks.rb +19 -12
  196. data/lib/active_record/test_databases.rb +1 -1
  197. data/lib/active_record/test_fixtures.rb +4 -4
  198. data/lib/active_record/timestamp.rb +3 -4
  199. data/lib/active_record/transactions.rb +9 -14
  200. data/lib/active_record/translation.rb +2 -2
  201. data/lib/active_record/type/adapter_specific_registry.rb +32 -7
  202. data/lib/active_record/type/hash_lookup_type_map.rb +34 -1
  203. data/lib/active_record/type/internal/timezone.rb +2 -2
  204. data/lib/active_record/type/serialized.rb +1 -1
  205. data/lib/active_record/type/type_map.rb +17 -20
  206. data/lib/active_record/type.rb +1 -2
  207. data/lib/active_record/validations/associated.rb +1 -1
  208. data/lib/active_record/validations/uniqueness.rb +1 -1
  209. data/lib/active_record.rb +204 -28
  210. data/lib/arel/attributes/attribute.rb +0 -8
  211. data/lib/arel/crud.rb +28 -22
  212. data/lib/arel/delete_manager.rb +18 -4
  213. data/lib/arel/filter_predications.rb +9 -0
  214. data/lib/arel/insert_manager.rb +2 -3
  215. data/lib/arel/nodes/casted.rb +1 -1
  216. data/lib/arel/nodes/delete_statement.rb +12 -13
  217. data/lib/arel/nodes/filter.rb +10 -0
  218. data/lib/arel/nodes/function.rb +1 -0
  219. data/lib/arel/nodes/insert_statement.rb +2 -2
  220. data/lib/arel/nodes/select_core.rb +2 -2
  221. data/lib/arel/nodes/select_statement.rb +2 -2
  222. data/lib/arel/nodes/update_statement.rb +8 -3
  223. data/lib/arel/nodes.rb +1 -0
  224. data/lib/arel/predications.rb +11 -3
  225. data/lib/arel/select_manager.rb +10 -4
  226. data/lib/arel/table.rb +0 -1
  227. data/lib/arel/tree_manager.rb +0 -12
  228. data/lib/arel/update_manager.rb +18 -4
  229. data/lib/arel/visitors/dot.rb +80 -90
  230. data/lib/arel/visitors/mysql.rb +8 -2
  231. data/lib/arel/visitors/postgresql.rb +0 -10
  232. data/lib/arel/visitors/to_sql.rb +58 -2
  233. data/lib/arel.rb +2 -1
  234. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +1 -1
  235. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +1 -1
  236. data/lib/rails/generators/active_record/model/templates/model.rb.tt +1 -1
  237. data/lib/rails/generators/active_record/model/templates/module.rb.tt +2 -2
  238. data/lib/rails/generators/active_record/multi_db/multi_db_generator.rb +16 -0
  239. data/lib/rails/generators/active_record/multi_db/templates/multi_db.rb.tt +44 -0
  240. metadata +56 -11
@@ -39,17 +39,23 @@ module ActiveRecord
39
39
  ##
40
40
  # :singleton-method:
41
41
  # Extra flags passed to database CLI tool (mysqldump/pg_dump) when calling db:schema:dump
42
+ # It can be used as a string/array (the typical case) or a hash (when you use multiple adapters)
43
+ # Example:
44
+ # ActiveRecord::Tasks::DatabaseTasks.structure_dump_flags = {
45
+ # mysql2: ['--no-defaults', '--skip-add-drop-table'],
46
+ # postgres: '--no-tablespaces'
47
+ # }
42
48
  mattr_accessor :structure_dump_flags, instance_accessor: false
43
49
 
44
50
  ##
45
51
  # :singleton-method:
46
52
  # Extra flags passed to database CLI tool when calling db:schema:load
53
+ # It can be used as a string/array (the typical case) or a hash (when you use multiple adapters)
47
54
  mattr_accessor :structure_load_flags, instance_accessor: false
48
55
 
49
56
  extend self
50
57
 
51
- attr_writer :current_config, :db_dir, :migrations_paths, :fixtures_path, :root, :env, :seed_loader
52
- deprecate :current_config=
58
+ attr_writer :db_dir, :migrations_paths, :fixtures_path, :root, :env, :seed_loader
53
59
  attr_accessor :database_configuration
54
60
 
55
61
  LOCAL_HOSTS = ["127.0.0.1", "localhost"]
@@ -103,11 +109,6 @@ module ActiveRecord
103
109
  @env ||= Rails.env
104
110
  end
105
111
 
106
- def spec
107
- @spec ||= "primary"
108
- end
109
- deprecate spec: "please use name instead"
110
-
111
112
  def name
112
113
  @name ||= "primary"
113
114
  end
@@ -116,18 +117,6 @@ module ActiveRecord
116
117
  @seed_loader ||= Rails.application
117
118
  end
118
119
 
119
- def current_config(options = {})
120
- if options.has_key?(:config)
121
- @current_config = options[:config]
122
- else
123
- env_name = options[:env] || env
124
- name = options[:spec] || "primary"
125
-
126
- @current_config ||= ActiveRecord::Base.configurations.configs_for(env_name: env_name, name: name)&.configuration_hash
127
- end
128
- end
129
- deprecate :current_config
130
-
131
120
  def create(configuration, *arguments)
132
121
  db_config = resolve_configuration(configuration)
133
122
  database_adapter_for(db_config, *arguments).create
@@ -154,7 +143,7 @@ module ActiveRecord
154
143
  begin
155
144
  Rails.application.config.load_database_yaml
156
145
  rescue
157
- unless ActiveRecord::Base.suppress_multiple_database_warning
146
+ unless ActiveRecord.suppress_multiple_database_warning
158
147
  $stderr.puts "Rails couldn't infer whether you are using multiple databases from your database.yml and can't generate the tasks for the non-primary databases. If you'd like to use this feature, please simplify your ERB."
159
148
  end
160
149
 
@@ -171,12 +160,14 @@ module ActiveRecord
171
160
  return if database_configs.count == 1
172
161
 
173
162
  database_configs.each do |db_config|
163
+ next unless db_config.database_tasks?
164
+
174
165
  yield db_config.name
175
166
  end
176
167
  end
177
168
 
178
169
  def raise_for_multi_db(environment = env, command:)
179
- db_configs = ActiveRecord::Base.configurations.configs_for(env_name: environment)
170
+ db_configs = configs_for(env_name: environment)
180
171
 
181
172
  if db_configs.count > 1
182
173
  dbs_list = []
@@ -194,6 +185,38 @@ module ActiveRecord
194
185
  ActiveRecord::Base.establish_connection(environment.to_sym)
195
186
  end
196
187
 
188
+ def prepare_all
189
+ seed = false
190
+
191
+ configs_for(env_name: env).each do |db_config|
192
+ ActiveRecord::Base.establish_connection(db_config)
193
+
194
+ # Skipped when no database
195
+ migrate
196
+
197
+ if ActiveRecord.dump_schema_after_migration
198
+ dump_schema(db_config, ActiveRecord.schema_format)
199
+ end
200
+ rescue ActiveRecord::NoDatabaseError
201
+ create_current(db_config.env_name, db_config.name)
202
+
203
+ if File.exist?(schema_dump_path(db_config))
204
+ load_schema(
205
+ db_config,
206
+ ActiveRecord.schema_format,
207
+ nil
208
+ )
209
+ else
210
+ migrate
211
+ end
212
+
213
+ seed = true
214
+ end
215
+
216
+ ActiveRecord::Base.establish_connection
217
+ load_seed if seed
218
+ end
219
+
197
220
  def drop(configuration, *arguments)
198
221
  db_config = resolve_configuration(configuration)
199
222
  database_adapter_for(db_config, *arguments).drop
@@ -223,19 +246,25 @@ module ActiveRecord
223
246
  private :truncate_tables
224
247
 
225
248
  def truncate_all(environment = env)
226
- ActiveRecord::Base.configurations.configs_for(env_name: environment).each do |db_config|
249
+ configs_for(env_name: environment).each do |db_config|
227
250
  truncate_tables(db_config)
228
251
  end
229
252
  end
230
253
 
231
- def migrate
254
+ def migrate(version = nil)
232
255
  check_target_version
233
256
 
234
257
  scope = ENV["SCOPE"]
235
258
  verbose_was, Migration.verbose = Migration.verbose, verbose?
236
259
 
237
260
  Base.connection.migration_context.migrate(target_version) do |migration|
238
- scope.blank? || scope == migration.scope
261
+ if version.blank?
262
+ scope.blank? || scope == migration.scope
263
+ else
264
+ migration.version == version
265
+ end
266
+ end.tap do |migrations_ran|
267
+ Migration.write("No migrations ran. (using #{scope} scope)") if scope.present? && migrations_ran.empty?
239
268
  end
240
269
 
241
270
  ActiveRecord::Base.clear_cache!
@@ -243,6 +272,23 @@ module ActiveRecord
243
272
  Migration.verbose = verbose_was
244
273
  end
245
274
 
275
+ def db_configs_with_versions(db_configs) # :nodoc:
276
+ db_configs_with_versions = Hash.new { |h, k| h[k] = [] }
277
+
278
+ db_configs.each do |db_config|
279
+ ActiveRecord::Base.establish_connection(db_config)
280
+ versions_to_run = ActiveRecord::Base.connection.migration_context.pending_migration_versions
281
+ target_version = ActiveRecord::Tasks::DatabaseTasks.target_version
282
+
283
+ versions_to_run.each do |version|
284
+ next if target_version && target_version != version
285
+ db_configs_with_versions[version] << db_config
286
+ end
287
+ end
288
+
289
+ db_configs_with_versions
290
+ end
291
+
246
292
  def migrate_status
247
293
  unless ActiveRecord::Base.connection.schema_migration.table_exists?
248
294
  Kernel.abort "Schema migrations table does not exist yet."
@@ -269,7 +315,7 @@ module ActiveRecord
269
315
  end
270
316
 
271
317
  def charset_current(env_name = env, db_name = name)
272
- db_config = ActiveRecord::Base.configurations.configs_for(env_name: env_name, name: db_name)
318
+ db_config = configs_for(env_name: env_name, name: db_name)
273
319
  charset(db_config)
274
320
  end
275
321
 
@@ -279,7 +325,7 @@ module ActiveRecord
279
325
  end
280
326
 
281
327
  def collation_current(env_name = env, db_name = name)
282
- db_config = ActiveRecord::Base.configurations.configs_for(env_name: env_name, name: db_name)
328
+ db_config = configs_for(env_name: env_name, name: db_name)
283
329
  collation(db_config)
284
330
  end
285
331
 
@@ -305,17 +351,19 @@ module ActiveRecord
305
351
  def structure_dump(configuration, *arguments)
306
352
  db_config = resolve_configuration(configuration)
307
353
  filename = arguments.delete_at(0)
308
- database_adapter_for(db_config, *arguments).structure_dump(filename, structure_dump_flags)
354
+ flags = structure_dump_flags_for(db_config.adapter)
355
+ database_adapter_for(db_config, *arguments).structure_dump(filename, flags)
309
356
  end
310
357
 
311
358
  def structure_load(configuration, *arguments)
312
359
  db_config = resolve_configuration(configuration)
313
360
  filename = arguments.delete_at(0)
314
- database_adapter_for(db_config, *arguments).structure_load(filename, structure_load_flags)
361
+ flags = structure_load_flags_for(db_config.adapter)
362
+ database_adapter_for(db_config, *arguments).structure_load(filename, flags)
315
363
  end
316
364
 
317
- def load_schema(db_config, format = ActiveRecord::Base.schema_format, file = nil) # :nodoc:
318
- file ||= dump_filename(db_config.name, format)
365
+ def load_schema(db_config, format = ActiveRecord.schema_format, file = nil) # :nodoc:
366
+ file ||= schema_dump_path(db_config, format)
319
367
 
320
368
  verbose_was, Migration.verbose = Migration.verbose, verbose? && ENV["VERBOSE"]
321
369
  check_schema_file(file)
@@ -336,16 +384,10 @@ module ActiveRecord
336
384
  Migration.verbose = verbose_was
337
385
  end
338
386
 
339
- def schema_up_to_date?(configuration, format = ActiveRecord::Base.schema_format, file = nil, environment = nil, name = nil)
387
+ def schema_up_to_date?(configuration, format = ActiveRecord.schema_format, file = nil)
340
388
  db_config = resolve_configuration(configuration)
341
389
 
342
- if environment || name
343
- ActiveSupport::Deprecation.warn("`environment` and `name` will be removed as parameters in 6.2.0, you may now pass an ActiveRecord::DatabaseConfigurations::DatabaseConfig as `configuration` instead.")
344
- end
345
-
346
- name ||= db_config.name
347
-
348
- file ||= dump_filename(name, format)
390
+ file ||= schema_dump_path(db_config)
349
391
 
350
392
  return true unless File.exist?(file)
351
393
 
@@ -357,8 +399,8 @@ module ActiveRecord
357
399
  ActiveRecord::InternalMetadata[:schema_sha1] == schema_sha1(file)
358
400
  end
359
401
 
360
- def reconstruct_from_schema(db_config, format = ActiveRecord::Base.schema_format, file = nil) # :nodoc:
361
- file ||= dump_filename(db_config.name, format)
402
+ def reconstruct_from_schema(db_config, format = ActiveRecord.schema_format, file = nil) # :nodoc:
403
+ file ||= schema_dump_path(db_config, format)
362
404
 
363
405
  check_schema_file(file)
364
406
 
@@ -375,9 +417,9 @@ module ActiveRecord
375
417
  load_schema(db_config, format, file)
376
418
  end
377
419
 
378
- def dump_schema(db_config, format = ActiveRecord::Base.schema_format) # :nodoc:
420
+ def dump_schema(db_config, format = ActiveRecord.schema_format) # :nodoc:
379
421
  require "active_record/schema_dumper"
380
- filename = dump_filename(db_config.name, format)
422
+ filename = schema_dump_path(db_config, format)
381
423
  connection = ActiveRecord::Base.connection
382
424
 
383
425
  FileUtils.mkdir_p(db_dir)
@@ -397,11 +439,7 @@ module ActiveRecord
397
439
  end
398
440
  end
399
441
 
400
- def schema_file(format = ActiveRecord::Base.schema_format)
401
- File.join(db_dir, schema_file_type(format))
402
- end
403
-
404
- def schema_file_type(format = ActiveRecord::Base.schema_format)
442
+ def schema_file_type(format = ActiveRecord.schema_format)
405
443
  case format
406
444
  when :ruby
407
445
  "schema.rb"
@@ -409,15 +447,19 @@ module ActiveRecord
409
447
  "structure.sql"
410
448
  end
411
449
  end
450
+ deprecate :schema_file_type
412
451
 
413
- def dump_filename(db_config_name, format = ActiveRecord::Base.schema_format)
414
- filename = if ActiveRecord::Base.configurations.primary?(db_config_name)
415
- schema_file_type(format)
452
+ def schema_dump_path(db_config, format = ActiveRecord.schema_format)
453
+ return ENV["SCHEMA"] if ENV["SCHEMA"]
454
+
455
+ filename = db_config.schema_dump(format)
456
+ return unless filename
457
+
458
+ if File.dirname(filename) == ActiveRecord::Tasks::DatabaseTasks.db_dir
459
+ filename
416
460
  else
417
- "#{db_config_name}_#{schema_file_type(format)}"
461
+ File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, filename)
418
462
  end
419
-
420
- ENV["SCHEMA"] || File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, filename)
421
463
  end
422
464
 
423
465
  def cache_dump_filename(db_config_name, schema_cache_path: nil)
@@ -430,7 +472,7 @@ module ActiveRecord
430
472
  schema_cache_path || ENV["SCHEMA_CACHE"] || File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, filename)
431
473
  end
432
474
 
433
- def load_schema_current(format = ActiveRecord::Base.schema_format, file = nil, environment = env)
475
+ def load_schema_current(format = ActiveRecord.schema_format, file = nil, environment = env)
434
476
  each_current_configuration(environment) do |db_config|
435
477
  load_schema(db_config, format, file)
436
478
  end
@@ -468,6 +510,10 @@ module ActiveRecord
468
510
  end
469
511
 
470
512
  private
513
+ def configs_for(**options)
514
+ Base.configurations.configs_for(**options)
515
+ end
516
+
471
517
  def resolve_configuration(configuration)
472
518
  Base.configurations.resolve(configuration)
473
519
  end
@@ -488,7 +534,7 @@ module ActiveRecord
488
534
  end
489
535
 
490
536
  def class_for_adapter(adapter)
491
- _key, task = @tasks.each_pair.detect { |pattern, _task| adapter[pattern] }
537
+ _key, task = @tasks.reverse_each.detect { |pattern, _task| adapter[pattern] }
492
538
  unless task
493
539
  raise DatabaseNotSupported, "Rake tasks not supported by '#{adapter}' adapter"
494
540
  end
@@ -500,7 +546,7 @@ module ActiveRecord
500
546
  environments << "test" if environment == "development" && !ENV["SKIP_TEST_DATABASE"] && !ENV["DATABASE_URL"]
501
547
 
502
548
  environments.each do |env|
503
- ActiveRecord::Base.configurations.configs_for(env_name: env).each do |db_config|
549
+ configs_for(env_name: env).each do |db_config|
504
550
  next if name && name != db_config.name
505
551
 
506
552
  yield db_config
@@ -509,7 +555,7 @@ module ActiveRecord
509
555
  end
510
556
 
511
557
  def each_local_configuration
512
- ActiveRecord::Base.configurations.configs_for.each do |db_config|
558
+ configs_for.each do |db_config|
513
559
  next unless db_config.database
514
560
 
515
561
  if local_database?(db_config)
@@ -526,7 +572,23 @@ module ActiveRecord
526
572
  end
527
573
 
528
574
  def schema_sha1(file)
529
- Digest::SHA1.hexdigest(File.read(file))
575
+ OpenSSL::Digest::SHA1.hexdigest(File.read(file))
576
+ end
577
+
578
+ def structure_dump_flags_for(adapter)
579
+ if structure_dump_flags.is_a?(Hash)
580
+ structure_dump_flags[adapter.to_sym]
581
+ else
582
+ structure_dump_flags
583
+ end
584
+ end
585
+
586
+ def structure_load_flags_for(adapter)
587
+ if structure_load_flags.is_a?(Hash)
588
+ structure_load_flags[adapter.to_sym]
589
+ else
590
+ structure_load_flags
591
+ end
530
592
  end
531
593
  end
532
594
  end
@@ -94,7 +94,7 @@ module ActiveRecord
94
94
  sslcapath: "--ssl-capath",
95
95
  sslcipher: "--ssl-cipher",
96
96
  sslkey: "--ssl-key"
97
- }.map { |opt, arg| "#{arg}=#{configuration_hash[opt]}" if configuration_hash[opt] }.compact
97
+ }.filter_map { |opt, arg| "#{arg}=#{configuration_hash[opt]}" if configuration_hash[opt] }
98
98
 
99
99
  args
100
100
  end
@@ -47,20 +47,22 @@ module ActiveRecord
47
47
  end
48
48
 
49
49
  def structure_dump(filename, extra_flags)
50
- set_psql_env
51
-
52
50
  search_path = \
53
- case ActiveRecord::Base.dump_schemas
51
+ case ActiveRecord.dump_schemas
54
52
  when :schema_search_path
55
53
  configuration_hash[:schema_search_path]
56
54
  when :all
57
55
  nil
58
56
  when String
59
- ActiveRecord::Base.dump_schemas
57
+ ActiveRecord.dump_schemas
60
58
  end
61
59
 
62
- args = ["--schema-only", "--no-privileges", "--no-owner", "--file", filename]
60
+ args = ["--schema-only", "--no-privileges", "--no-owner"]
61
+ args << "--no-comments" if connection.database_version >= 110_000
62
+ args.concat(["--file", filename])
63
+
63
64
  args.concat(Array(extra_flags)) if extra_flags
65
+
64
66
  unless search_path.blank?
65
67
  args += search_path.split(",").map do |part|
66
68
  "--schema=#{part.strip}"
@@ -79,7 +81,6 @@ module ActiveRecord
79
81
  end
80
82
 
81
83
  def structure_load(filename, extra_flags)
82
- set_psql_env
83
84
  args = ["--set", ON_ERROR_STOP_1, "--quiet", "--no-psqlrc", "--file", filename]
84
85
  args.concat(Array(extra_flags)) if extra_flags
85
86
  args << db_config.database
@@ -100,15 +101,21 @@ module ActiveRecord
100
101
  )
101
102
  end
102
103
 
103
- def set_psql_env
104
- ENV["PGHOST"] = db_config.host if db_config.host
105
- ENV["PGPORT"] = configuration_hash[:port].to_s if configuration_hash[:port]
106
- ENV["PGPASSWORD"] = configuration_hash[:password].to_s if configuration_hash[:password]
107
- ENV["PGUSER"] = configuration_hash[:username].to_s if configuration_hash[:username]
104
+ def psql_env
105
+ {}.tap do |env|
106
+ env["PGHOST"] = db_config.host if db_config.host
107
+ env["PGPORT"] = configuration_hash[:port].to_s if configuration_hash[:port]
108
+ env["PGPASSWORD"] = configuration_hash[:password].to_s if configuration_hash[:password]
109
+ env["PGUSER"] = configuration_hash[:username].to_s if configuration_hash[:username]
110
+ env["PGSSLMODE"] = configuration_hash[:sslmode].to_s if configuration_hash[:sslmode]
111
+ env["PGSSLCERT"] = configuration_hash[:sslcert].to_s if configuration_hash[:sslcert]
112
+ env["PGSSLKEY"] = configuration_hash[:sslkey].to_s if configuration_hash[:sslkey]
113
+ env["PGSSLROOTCERT"] = configuration_hash[:sslrootcert].to_s if configuration_hash[:sslrootcert]
114
+ end
108
115
  end
109
116
 
110
117
  def run_cmd(cmd, args, action)
111
- fail run_cmd_error(cmd, args, action) unless Kernel.system(cmd, *args)
118
+ fail run_cmd_error(cmd, args, action) unless Kernel.system(psql_env, cmd, *args)
112
119
  end
113
120
 
114
121
  def run_cmd_error(cmd, args, action)
@@ -14,7 +14,7 @@ module ActiveRecord
14
14
  ActiveRecord::Base.configurations.configs_for(env_name: env_name).each do |db_config|
15
15
  db_config._database = "#{db_config.database}-#{i}"
16
16
 
17
- ActiveRecord::Tasks::DatabaseTasks.reconstruct_from_schema(db_config, ActiveRecord::Base.schema_format, nil)
17
+ ActiveRecord::Tasks::DatabaseTasks.reconstruct_from_schema(db_config, ActiveRecord.schema_format, nil)
18
18
  end
19
19
  ensure
20
20
  ActiveRecord::Base.establish_connection
@@ -193,8 +193,8 @@ module ActiveRecord
193
193
  # need to share a connection pool so that the reading connection
194
194
  # can see data in the open transaction on the writing connection.
195
195
  def setup_shared_connection_pool
196
- if ActiveRecord::Base.legacy_connection_handling
197
- writing_handler = ActiveRecord::Base.connection_handlers[ActiveRecord::Base.writing_role]
196
+ if ActiveRecord.legacy_connection_handling
197
+ writing_handler = ActiveRecord::Base.connection_handlers[ActiveRecord.writing_role]
198
198
 
199
199
  ActiveRecord::Base.connection_handlers.values.each do |handler|
200
200
  if handler != writing_handler
@@ -221,7 +221,7 @@ module ActiveRecord
221
221
  handler.connection_pool_names.each do |name|
222
222
  pool_manager = handler.send(:owner_to_pool_manager)[name]
223
223
  pool_manager.shard_names.each do |shard_name|
224
- writing_pool_config = pool_manager.get_pool_config(ActiveRecord::Base.writing_role, shard_name)
224
+ writing_pool_config = pool_manager.get_pool_config(ActiveRecord.writing_role, shard_name)
225
225
  @saved_pool_configs[name][shard_name] ||= {}
226
226
  pool_manager.role_names.each do |role|
227
227
  next unless pool_config = pool_manager.get_pool_config(role, shard_name)
@@ -236,7 +236,7 @@ module ActiveRecord
236
236
  end
237
237
 
238
238
  def teardown_shared_connection_pool
239
- if ActiveRecord::Base.legacy_connection_handling
239
+ if ActiveRecord.legacy_connection_handling
240
240
  @legacy_saved_pool_configs.each_pair do |handler, names|
241
241
  names.each_pair do |name, shards|
242
242
  shards.each_pair do |shard_name, pool_config|
@@ -75,7 +75,7 @@ module ActiveRecord
75
75
  end
76
76
 
77
77
  def current_time_from_proper_timezone
78
- default_timezone == :utc ? Time.now.utc : Time.now
78
+ ActiveRecord.default_timezone == :utc ? Time.now.utc : Time.now
79
79
  end
80
80
 
81
81
  private
@@ -127,7 +127,7 @@ module ActiveRecord
127
127
  end
128
128
 
129
129
  def should_record_timestamps?
130
- record_timestamps && (!partial_writes? || has_changes_to_save?)
130
+ record_timestamps && (!partial_updates? || has_changes_to_save?)
131
131
  end
132
132
 
133
133
  def timestamp_attributes_for_create_in_model
@@ -148,8 +148,7 @@ module ActiveRecord
148
148
 
149
149
  def max_updated_column_timestamp
150
150
  timestamp_attributes_for_update_in_model
151
- .map { |attr| self[attr]&.to_time }
152
- .compact
151
+ .filter_map { |attr| self[attr]&.to_time }
153
152
  .max
154
153
  end
155
154
 
@@ -4,7 +4,7 @@ module ActiveRecord
4
4
  # See ActiveRecord::Transactions::ClassMethods for documentation.
5
5
  module Transactions
6
6
  extend ActiveSupport::Concern
7
- #:nodoc:
7
+ # :nodoc:
8
8
  ACTIONS = [:create, :destroy, :update]
9
9
 
10
10
  included do
@@ -290,19 +290,19 @@ module ActiveRecord
290
290
  self.class.transaction(**options, &block)
291
291
  end
292
292
 
293
- def destroy #:nodoc:
293
+ def destroy # :nodoc:
294
294
  with_transaction_returning_status { super }
295
295
  end
296
296
 
297
- def save(**) #:nodoc:
297
+ def save(**) # :nodoc:
298
298
  with_transaction_returning_status { super }
299
299
  end
300
300
 
301
- def save!(**) #:nodoc:
301
+ def save!(**) # :nodoc:
302
302
  with_transaction_returning_status { super }
303
303
  end
304
304
 
305
- def touch(*, **) #:nodoc:
305
+ def touch(*, **) # :nodoc:
306
306
  with_transaction_returning_status { super }
307
307
  end
308
308
 
@@ -314,8 +314,8 @@ module ActiveRecord
314
314
  #
315
315
  # Ensure that it is not called if the object was never persisted (failed create),
316
316
  # but call it after the commit of a destroyed object.
317
- def committed!(should_run_callbacks: true) #:nodoc:
318
- force_clear_transaction_record_state
317
+ def committed!(should_run_callbacks: true) # :nodoc:
318
+ @_start_transaction_state = nil
319
319
  if should_run_callbacks
320
320
  @_committed_already_called = true
321
321
  _run_commit_callbacks
@@ -326,7 +326,7 @@ module ActiveRecord
326
326
 
327
327
  # Call the #after_rollback callbacks. The +force_restore_state+ argument indicates if the record
328
328
  # state should be rolled back to the beginning or just to the last savepoint.
329
- def rolledback!(force_restore_state: false, should_run_callbacks: true) #:nodoc:
329
+ def rolledback!(force_restore_state: false, should_run_callbacks: true) # :nodoc:
330
330
  if should_run_callbacks
331
331
  _run_rollback_callbacks
332
332
  end
@@ -389,12 +389,7 @@ module ActiveRecord
389
389
  def clear_transaction_record_state
390
390
  return unless @_start_transaction_state
391
391
  @_start_transaction_state[:level] -= 1
392
- force_clear_transaction_record_state if @_start_transaction_state[:level] < 1
393
- end
394
-
395
- # Force to clear the transaction record state.
396
- def force_clear_transaction_record_state
397
- @_start_transaction_state = nil
392
+ @_start_transaction_state = nil if @_start_transaction_state[:level] < 1
398
393
  end
399
394
 
400
395
  # Restore the new record state and id of a record that was previously saved by a call to save_record_state.
@@ -5,7 +5,7 @@ module ActiveRecord
5
5
  include ActiveModel::Translation
6
6
 
7
7
  # Set the lookup ancestors for ActiveModel.
8
- def lookup_ancestors #:nodoc:
8
+ def lookup_ancestors # :nodoc:
9
9
  klass = self
10
10
  classes = [klass]
11
11
  return classes if klass == ActiveRecord::Base
@@ -17,7 +17,7 @@ module ActiveRecord
17
17
  end
18
18
 
19
19
  # Set the i18n scope to overwrite ActiveModel.
20
- def i18n_scope #:nodoc:
20
+ def i18n_scope # :nodoc:
21
21
  :activerecord
22
22
  end
23
23
  end
@@ -5,15 +5,40 @@ require "active_model/type/registry"
5
5
  module ActiveRecord
6
6
  # :stopdoc:
7
7
  module Type
8
- class AdapterSpecificRegistry < ActiveModel::Type::Registry
8
+ class AdapterSpecificRegistry # :nodoc:
9
+ def initialize
10
+ @registrations = []
11
+ end
12
+
13
+ def initialize_copy(other)
14
+ @registrations = @registrations.dup
15
+ super
16
+ end
17
+
9
18
  def add_modifier(options, klass, **args)
10
19
  registrations << DecorationRegistration.new(options, klass, **args)
11
20
  end
12
21
 
13
- private
14
- def registration_klass
15
- Registration
22
+ def register(type_name, klass = nil, **options, &block)
23
+ unless block_given?
24
+ block = proc { |_, *args| klass.new(*args) }
25
+ block.ruby2_keywords if block.respond_to?(:ruby2_keywords)
16
26
  end
27
+ registrations << Registration.new(type_name, block, **options)
28
+ end
29
+
30
+ def lookup(symbol, *args, **kwargs)
31
+ registration = find_registration(symbol, *args, **kwargs)
32
+
33
+ if registration
34
+ registration.call(self, symbol, *args, **kwargs)
35
+ else
36
+ raise ArgumentError, "Unknown type #{symbol.inspect}"
37
+ end
38
+ end
39
+
40
+ private
41
+ attr_reader :registrations
17
42
 
18
43
  def find_registration(symbol, *args, **kwargs)
19
44
  registrations
@@ -22,7 +47,7 @@ module ActiveRecord
22
47
  end
23
48
  end
24
49
 
25
- class Registration
50
+ class Registration # :nodoc:
26
51
  def initialize(name, block, adapter: nil, override: nil)
27
52
  @name = name
28
53
  @block = block
@@ -89,7 +114,7 @@ module ActiveRecord
89
114
  end
90
115
  end
91
116
 
92
- class DecorationRegistration < Registration
117
+ class DecorationRegistration < Registration # :nodoc:
93
118
  def initialize(options, klass, adapter: nil)
94
119
  @options = options
95
120
  @klass = klass
@@ -120,7 +145,7 @@ module ActiveRecord
120
145
  end
121
146
  end
122
147
 
123
- class TypeConflictError < StandardError
148
+ class TypeConflictError < StandardError # :nodoc:
124
149
  end
125
150
  # :startdoc:
126
151
  end