activerecord 6.1.7.4 → 7.0.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1055 -1170
- data/MIT-LICENSE +1 -1
- data/README.rdoc +1 -1
- data/lib/active_record/aggregations.rb +1 -1
- data/lib/active_record/association_relation.rb +0 -10
- data/lib/active_record/associations/association.rb +33 -17
- data/lib/active_record/associations/association_scope.rb +1 -3
- data/lib/active_record/associations/belongs_to_association.rb +15 -4
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +10 -2
- data/lib/active_record/associations/builder/association.rb +8 -2
- data/lib/active_record/associations/builder/belongs_to.rb +19 -6
- data/lib/active_record/associations/builder/collection_association.rb +10 -3
- data/lib/active_record/associations/builder/has_many.rb +3 -2
- data/lib/active_record/associations/builder/has_one.rb +2 -1
- data/lib/active_record/associations/builder/singular_association.rb +2 -2
- data/lib/active_record/associations/collection_association.rb +18 -19
- data/lib/active_record/associations/collection_proxy.rb +8 -3
- data/lib/active_record/associations/disable_joins_association_scope.rb +59 -0
- data/lib/active_record/associations/has_many_association.rb +1 -1
- data/lib/active_record/associations/has_many_through_association.rb +2 -1
- data/lib/active_record/associations/has_one_association.rb +10 -7
- data/lib/active_record/associations/has_one_through_association.rb +1 -1
- data/lib/active_record/associations/join_dependency.rb +6 -2
- data/lib/active_record/associations/preloader/association.rb +186 -52
- data/lib/active_record/associations/preloader/batch.rb +48 -0
- data/lib/active_record/associations/preloader/branch.rb +147 -0
- data/lib/active_record/associations/preloader/through_association.rb +49 -13
- data/lib/active_record/associations/preloader.rb +39 -113
- data/lib/active_record/associations/singular_association.rb +8 -2
- data/lib/active_record/associations/through_association.rb +3 -3
- data/lib/active_record/associations.rb +90 -82
- data/lib/active_record/asynchronous_queries_tracker.rb +60 -0
- data/lib/active_record/attribute_assignment.rb +1 -1
- data/lib/active_record/attribute_methods/before_type_cast.rb +7 -2
- data/lib/active_record/attribute_methods/dirty.rb +49 -16
- data/lib/active_record/attribute_methods/primary_key.rb +2 -2
- data/lib/active_record/attribute_methods/query.rb +2 -2
- data/lib/active_record/attribute_methods/read.rb +7 -5
- data/lib/active_record/attribute_methods/serialization.rb +66 -12
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +4 -3
- data/lib/active_record/attribute_methods/write.rb +7 -10
- data/lib/active_record/attribute_methods.rb +13 -14
- data/lib/active_record/attributes.rb +24 -35
- data/lib/active_record/autosave_association.rb +6 -21
- data/lib/active_record/base.rb +19 -1
- data/lib/active_record/callbacks.rb +2 -2
- data/lib/active_record/coders/yaml_column.rb +2 -14
- data/lib/active_record/connection_adapters/abstract/connection_handler.rb +292 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +209 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +76 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +47 -561
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +0 -17
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +46 -22
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +24 -12
- data/lib/active_record/connection_adapters/abstract/quoting.rb +43 -82
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +4 -17
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +34 -13
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +69 -18
- data/lib/active_record/connection_adapters/abstract/transaction.rb +15 -22
- data/lib/active_record/connection_adapters/abstract_adapter.rb +149 -74
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +97 -81
- data/lib/active_record/connection_adapters/column.rb +4 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +35 -23
- data/lib/active_record/connection_adapters/mysql/quoting.rb +35 -21
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +12 -6
- data/lib/active_record/connection_adapters/pool_config.rb +7 -7
- data/lib/active_record/connection_adapters/postgresql/column.rb +17 -1
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +19 -12
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +8 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +5 -0
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +53 -14
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/timestamp.rb +15 -0
- data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +28 -0
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +18 -6
- data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +50 -76
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +32 -0
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +21 -1
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +22 -1
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +25 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +27 -16
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +207 -107
- data/lib/active_record/connection_adapters/schema_cache.rb +39 -38
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +25 -19
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +15 -16
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +4 -2
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +61 -30
- data/lib/active_record/connection_adapters.rb +6 -5
- data/lib/active_record/connection_handling.rb +47 -53
- data/lib/active_record/core.rb +121 -146
- data/lib/active_record/database_configurations/connection_url_resolver.rb +1 -1
- data/lib/active_record/database_configurations/database_config.rb +12 -9
- data/lib/active_record/database_configurations/hash_config.rb +63 -5
- data/lib/active_record/database_configurations/url_config.rb +2 -2
- data/lib/active_record/database_configurations.rb +15 -32
- data/lib/active_record/delegated_type.rb +52 -11
- data/lib/active_record/destroy_association_async_job.rb +1 -1
- data/lib/active_record/disable_joins_association_relation.rb +39 -0
- data/lib/active_record/dynamic_matchers.rb +1 -1
- data/lib/active_record/encryption/cipher/aes256_gcm.rb +98 -0
- data/lib/active_record/encryption/cipher.rb +53 -0
- data/lib/active_record/encryption/config.rb +44 -0
- data/lib/active_record/encryption/configurable.rb +61 -0
- data/lib/active_record/encryption/context.rb +35 -0
- data/lib/active_record/encryption/contexts.rb +72 -0
- data/lib/active_record/encryption/derived_secret_key_provider.rb +12 -0
- data/lib/active_record/encryption/deterministic_key_provider.rb +14 -0
- data/lib/active_record/encryption/encryptable_record.rb +208 -0
- data/lib/active_record/encryption/encrypted_attribute_type.rb +140 -0
- data/lib/active_record/encryption/encrypted_fixtures.rb +38 -0
- data/lib/active_record/encryption/encrypting_only_encryptor.rb +12 -0
- data/lib/active_record/encryption/encryptor.rb +155 -0
- data/lib/active_record/encryption/envelope_encryption_key_provider.rb +55 -0
- data/lib/active_record/encryption/errors.rb +15 -0
- data/lib/active_record/encryption/extended_deterministic_queries.rb +160 -0
- data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +28 -0
- data/lib/active_record/encryption/key.rb +28 -0
- data/lib/active_record/encryption/key_generator.rb +42 -0
- data/lib/active_record/encryption/key_provider.rb +46 -0
- data/lib/active_record/encryption/message.rb +33 -0
- data/lib/active_record/encryption/message_serializer.rb +90 -0
- data/lib/active_record/encryption/null_encryptor.rb +21 -0
- data/lib/active_record/encryption/properties.rb +76 -0
- data/lib/active_record/encryption/read_only_null_encryptor.rb +24 -0
- data/lib/active_record/encryption/scheme.rb +99 -0
- data/lib/active_record/encryption.rb +55 -0
- data/lib/active_record/enum.rb +49 -42
- data/lib/active_record/errors.rb +67 -4
- data/lib/active_record/explain_registry.rb +11 -6
- data/lib/active_record/fixture_set/file.rb +15 -1
- data/lib/active_record/fixture_set/table_row.rb +41 -6
- data/lib/active_record/fixture_set/table_rows.rb +4 -4
- data/lib/active_record/fixtures.rb +17 -20
- data/lib/active_record/future_result.rb +139 -0
- data/lib/active_record/gem_version.rb +4 -4
- data/lib/active_record/inheritance.rb +55 -17
- data/lib/active_record/insert_all.rb +80 -14
- data/lib/active_record/integration.rb +4 -3
- data/lib/active_record/internal_metadata.rb +1 -5
- data/lib/active_record/legacy_yaml_adapter.rb +2 -39
- data/lib/active_record/locking/optimistic.rb +10 -9
- data/lib/active_record/locking/pessimistic.rb +9 -3
- data/lib/active_record/log_subscriber.rb +14 -3
- data/lib/active_record/middleware/database_selector/resolver.rb +6 -10
- data/lib/active_record/middleware/database_selector.rb +8 -3
- data/lib/active_record/middleware/shard_selector.rb +60 -0
- data/lib/active_record/migration/command_recorder.rb +4 -4
- data/lib/active_record/migration/compatibility.rb +89 -10
- data/lib/active_record/migration/join_table.rb +1 -1
- data/lib/active_record/migration.rb +110 -80
- data/lib/active_record/model_schema.rb +45 -58
- data/lib/active_record/nested_attributes.rb +13 -12
- data/lib/active_record/no_touching.rb +3 -3
- data/lib/active_record/null_relation.rb +2 -6
- data/lib/active_record/persistence.rb +219 -52
- data/lib/active_record/query_cache.rb +2 -2
- data/lib/active_record/query_logs.rb +138 -0
- data/lib/active_record/querying.rb +15 -5
- data/lib/active_record/railtie.rb +127 -17
- data/lib/active_record/railties/controller_runtime.rb +1 -1
- data/lib/active_record/railties/databases.rake +66 -129
- data/lib/active_record/readonly_attributes.rb +11 -0
- data/lib/active_record/reflection.rb +67 -50
- data/lib/active_record/relation/batches/batch_enumerator.rb +19 -5
- data/lib/active_record/relation/batches.rb +3 -3
- data/lib/active_record/relation/calculations.rb +40 -36
- data/lib/active_record/relation/delegation.rb +6 -6
- data/lib/active_record/relation/finder_methods.rb +31 -35
- data/lib/active_record/relation/merger.rb +20 -13
- data/lib/active_record/relation/predicate_builder.rb +1 -6
- data/lib/active_record/relation/query_attribute.rb +5 -11
- data/lib/active_record/relation/query_methods.rb +235 -63
- data/lib/active_record/relation/record_fetch_warning.rb +7 -9
- data/lib/active_record/relation/spawn_methods.rb +2 -2
- data/lib/active_record/relation/where_clause.rb +10 -19
- data/lib/active_record/relation.rb +169 -84
- data/lib/active_record/result.rb +17 -7
- data/lib/active_record/runtime_registry.rb +9 -13
- data/lib/active_record/sanitization.rb +11 -7
- data/lib/active_record/schema_dumper.rb +10 -3
- data/lib/active_record/schema_migration.rb +4 -4
- data/lib/active_record/scoping/default.rb +61 -12
- data/lib/active_record/scoping/named.rb +3 -11
- data/lib/active_record/scoping.rb +64 -34
- data/lib/active_record/serialization.rb +1 -1
- data/lib/active_record/signed_id.rb +1 -1
- data/lib/active_record/store.rb +1 -6
- data/lib/active_record/suppressor.rb +11 -15
- data/lib/active_record/tasks/database_tasks.rb +116 -58
- data/lib/active_record/tasks/mysql_database_tasks.rb +1 -1
- data/lib/active_record/tasks/postgresql_database_tasks.rb +19 -12
- data/lib/active_record/test_databases.rb +1 -1
- data/lib/active_record/test_fixtures.rb +9 -13
- data/lib/active_record/timestamp.rb +3 -4
- data/lib/active_record/transactions.rb +9 -14
- data/lib/active_record/translation.rb +2 -2
- data/lib/active_record/type/adapter_specific_registry.rb +32 -7
- data/lib/active_record/type/hash_lookup_type_map.rb +34 -1
- data/lib/active_record/type/internal/timezone.rb +2 -2
- data/lib/active_record/type/serialized.rb +1 -1
- data/lib/active_record/type/type_map.rb +17 -20
- data/lib/active_record/type.rb +1 -2
- data/lib/active_record/validations/associated.rb +1 -1
- data/lib/active_record/validations/uniqueness.rb +1 -1
- data/lib/active_record.rb +204 -28
- data/lib/arel/attributes/attribute.rb +0 -8
- data/lib/arel/crud.rb +28 -22
- data/lib/arel/delete_manager.rb +18 -4
- data/lib/arel/filter_predications.rb +9 -0
- data/lib/arel/insert_manager.rb +2 -3
- data/lib/arel/nodes/casted.rb +1 -1
- data/lib/arel/nodes/delete_statement.rb +12 -13
- data/lib/arel/nodes/filter.rb +10 -0
- data/lib/arel/nodes/function.rb +1 -0
- data/lib/arel/nodes/insert_statement.rb +2 -2
- data/lib/arel/nodes/select_core.rb +2 -2
- data/lib/arel/nodes/select_statement.rb +2 -2
- data/lib/arel/nodes/update_statement.rb +8 -3
- data/lib/arel/nodes.rb +1 -0
- data/lib/arel/predications.rb +11 -3
- data/lib/arel/select_manager.rb +10 -4
- data/lib/arel/table.rb +0 -1
- data/lib/arel/tree_manager.rb +0 -12
- data/lib/arel/update_manager.rb +18 -4
- data/lib/arel/visitors/dot.rb +80 -90
- data/lib/arel/visitors/mysql.rb +8 -2
- data/lib/arel/visitors/postgresql.rb +0 -10
- data/lib/arel/visitors/to_sql.rb +58 -2
- data/lib/arel.rb +2 -1
- data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +1 -1
- data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +1 -1
- data/lib/rails/generators/active_record/model/templates/model.rb.tt +1 -1
- data/lib/rails/generators/active_record/model/templates/module.rb.tt +2 -2
- data/lib/rails/generators/active_record/multi_db/multi_db_generator.rb +16 -0
- data/lib/rails/generators/active_record/multi_db/templates/multi_db.rb.tt +44 -0
- metadata +58 -14
@@ -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 :
|
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
|
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 =
|
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,21 @@ module ActiveRecord
|
|
223
246
|
private :truncate_tables
|
224
247
|
|
225
248
|
def truncate_all(environment = env)
|
226
|
-
|
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
|
-
Base.connection.migration_context.migrate(target_version) do |migration|
|
260
|
+
Base.connection.migration_context.migrate(target_version || version) do |migration|
|
238
261
|
scope.blank? || scope == migration.scope
|
262
|
+
end.tap do |migrations_ran|
|
263
|
+
Migration.write("No migrations ran. (using #{scope} scope)") if scope.present? && migrations_ran.empty?
|
239
264
|
end
|
240
265
|
|
241
266
|
ActiveRecord::Base.clear_cache!
|
@@ -243,6 +268,23 @@ module ActiveRecord
|
|
243
268
|
Migration.verbose = verbose_was
|
244
269
|
end
|
245
270
|
|
271
|
+
def db_configs_with_versions(db_configs) # :nodoc:
|
272
|
+
db_configs_with_versions = Hash.new { |h, k| h[k] = [] }
|
273
|
+
|
274
|
+
db_configs.each do |db_config|
|
275
|
+
ActiveRecord::Base.establish_connection(db_config)
|
276
|
+
versions_to_run = ActiveRecord::Base.connection.migration_context.pending_migration_versions
|
277
|
+
target_version = ActiveRecord::Tasks::DatabaseTasks.target_version
|
278
|
+
|
279
|
+
versions_to_run.each do |version|
|
280
|
+
next if target_version && target_version != version
|
281
|
+
db_configs_with_versions[version] << db_config
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
db_configs_with_versions
|
286
|
+
end
|
287
|
+
|
246
288
|
def migrate_status
|
247
289
|
unless ActiveRecord::Base.connection.schema_migration.table_exists?
|
248
290
|
Kernel.abort "Schema migrations table does not exist yet."
|
@@ -269,7 +311,7 @@ module ActiveRecord
|
|
269
311
|
end
|
270
312
|
|
271
313
|
def charset_current(env_name = env, db_name = name)
|
272
|
-
db_config =
|
314
|
+
db_config = configs_for(env_name: env_name, name: db_name)
|
273
315
|
charset(db_config)
|
274
316
|
end
|
275
317
|
|
@@ -279,7 +321,7 @@ module ActiveRecord
|
|
279
321
|
end
|
280
322
|
|
281
323
|
def collation_current(env_name = env, db_name = name)
|
282
|
-
db_config =
|
324
|
+
db_config = configs_for(env_name: env_name, name: db_name)
|
283
325
|
collation(db_config)
|
284
326
|
end
|
285
327
|
|
@@ -305,17 +347,19 @@ module ActiveRecord
|
|
305
347
|
def structure_dump(configuration, *arguments)
|
306
348
|
db_config = resolve_configuration(configuration)
|
307
349
|
filename = arguments.delete_at(0)
|
308
|
-
|
350
|
+
flags = structure_dump_flags_for(db_config.adapter)
|
351
|
+
database_adapter_for(db_config, *arguments).structure_dump(filename, flags)
|
309
352
|
end
|
310
353
|
|
311
354
|
def structure_load(configuration, *arguments)
|
312
355
|
db_config = resolve_configuration(configuration)
|
313
356
|
filename = arguments.delete_at(0)
|
314
|
-
|
357
|
+
flags = structure_load_flags_for(db_config.adapter)
|
358
|
+
database_adapter_for(db_config, *arguments).structure_load(filename, flags)
|
315
359
|
end
|
316
360
|
|
317
|
-
def load_schema(db_config, format = ActiveRecord
|
318
|
-
file ||=
|
361
|
+
def load_schema(db_config, format = ActiveRecord.schema_format, file = nil) # :nodoc:
|
362
|
+
file ||= schema_dump_path(db_config, format)
|
319
363
|
|
320
364
|
verbose_was, Migration.verbose = Migration.verbose, verbose? && ENV["VERBOSE"]
|
321
365
|
check_schema_file(file)
|
@@ -336,16 +380,10 @@ module ActiveRecord
|
|
336
380
|
Migration.verbose = verbose_was
|
337
381
|
end
|
338
382
|
|
339
|
-
def schema_up_to_date?(configuration, format = ActiveRecord
|
383
|
+
def schema_up_to_date?(configuration, format = ActiveRecord.schema_format, file = nil)
|
340
384
|
db_config = resolve_configuration(configuration)
|
341
385
|
|
342
|
-
|
343
|
-
ActiveSupport::Deprecation.warn("`environment` and `name` will be removed as parameters in 7.0.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)
|
386
|
+
file ||= schema_dump_path(db_config)
|
349
387
|
|
350
388
|
return true unless File.exist?(file)
|
351
389
|
|
@@ -357,8 +395,8 @@ module ActiveRecord
|
|
357
395
|
ActiveRecord::InternalMetadata[:schema_sha1] == schema_sha1(file)
|
358
396
|
end
|
359
397
|
|
360
|
-
def reconstruct_from_schema(db_config, format = ActiveRecord
|
361
|
-
file ||=
|
398
|
+
def reconstruct_from_schema(db_config, format = ActiveRecord.schema_format, file = nil) # :nodoc:
|
399
|
+
file ||= schema_dump_path(db_config, format)
|
362
400
|
|
363
401
|
check_schema_file(file)
|
364
402
|
|
@@ -375,9 +413,9 @@ module ActiveRecord
|
|
375
413
|
load_schema(db_config, format, file)
|
376
414
|
end
|
377
415
|
|
378
|
-
def dump_schema(db_config, format = ActiveRecord
|
416
|
+
def dump_schema(db_config, format = ActiveRecord.schema_format) # :nodoc:
|
379
417
|
require "active_record/schema_dumper"
|
380
|
-
filename =
|
418
|
+
filename = schema_dump_path(db_config, format)
|
381
419
|
connection = ActiveRecord::Base.connection
|
382
420
|
|
383
421
|
FileUtils.mkdir_p(db_dir)
|
@@ -397,11 +435,7 @@ module ActiveRecord
|
|
397
435
|
end
|
398
436
|
end
|
399
437
|
|
400
|
-
def
|
401
|
-
File.join(db_dir, schema_file_type(format))
|
402
|
-
end
|
403
|
-
|
404
|
-
def schema_file_type(format = ActiveRecord::Base.schema_format)
|
438
|
+
def schema_file_type(format = ActiveRecord.schema_format)
|
405
439
|
case format
|
406
440
|
when :ruby
|
407
441
|
"schema.rb"
|
@@ -409,15 +443,19 @@ module ActiveRecord
|
|
409
443
|
"structure.sql"
|
410
444
|
end
|
411
445
|
end
|
446
|
+
deprecate :schema_file_type
|
412
447
|
|
413
|
-
def
|
414
|
-
|
415
|
-
|
448
|
+
def schema_dump_path(db_config, format = ActiveRecord.schema_format)
|
449
|
+
return ENV["SCHEMA"] if ENV["SCHEMA"]
|
450
|
+
|
451
|
+
filename = db_config.schema_dump(format)
|
452
|
+
return unless filename
|
453
|
+
|
454
|
+
if File.dirname(filename) == ActiveRecord::Tasks::DatabaseTasks.db_dir
|
455
|
+
filename
|
416
456
|
else
|
417
|
-
|
457
|
+
File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, filename)
|
418
458
|
end
|
419
|
-
|
420
|
-
ENV["SCHEMA"] || File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, filename)
|
421
459
|
end
|
422
460
|
|
423
461
|
def cache_dump_filename(db_config_name, schema_cache_path: nil)
|
@@ -430,7 +468,7 @@ module ActiveRecord
|
|
430
468
|
schema_cache_path || ENV["SCHEMA_CACHE"] || File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, filename)
|
431
469
|
end
|
432
470
|
|
433
|
-
def load_schema_current(format = ActiveRecord
|
471
|
+
def load_schema_current(format = ActiveRecord.schema_format, file = nil, environment = env)
|
434
472
|
each_current_configuration(environment) do |db_config|
|
435
473
|
load_schema(db_config, format, file)
|
436
474
|
end
|
@@ -468,6 +506,10 @@ module ActiveRecord
|
|
468
506
|
end
|
469
507
|
|
470
508
|
private
|
509
|
+
def configs_for(**options)
|
510
|
+
Base.configurations.configs_for(**options)
|
511
|
+
end
|
512
|
+
|
471
513
|
def resolve_configuration(configuration)
|
472
514
|
Base.configurations.resolve(configuration)
|
473
515
|
end
|
@@ -488,7 +530,7 @@ module ActiveRecord
|
|
488
530
|
end
|
489
531
|
|
490
532
|
def class_for_adapter(adapter)
|
491
|
-
_key, task = @tasks.
|
533
|
+
_key, task = @tasks.reverse_each.detect { |pattern, _task| adapter[pattern] }
|
492
534
|
unless task
|
493
535
|
raise DatabaseNotSupported, "Rake tasks not supported by '#{adapter}' adapter"
|
494
536
|
end
|
@@ -500,7 +542,7 @@ module ActiveRecord
|
|
500
542
|
environments << "test" if environment == "development" && !ENV["SKIP_TEST_DATABASE"] && !ENV["DATABASE_URL"]
|
501
543
|
|
502
544
|
environments.each do |env|
|
503
|
-
|
545
|
+
configs_for(env_name: env).each do |db_config|
|
504
546
|
next if name && name != db_config.name
|
505
547
|
|
506
548
|
yield db_config
|
@@ -509,7 +551,7 @@ module ActiveRecord
|
|
509
551
|
end
|
510
552
|
|
511
553
|
def each_local_configuration
|
512
|
-
|
554
|
+
configs_for.each do |db_config|
|
513
555
|
next unless db_config.database
|
514
556
|
|
515
557
|
if local_database?(db_config)
|
@@ -526,7 +568,23 @@ module ActiveRecord
|
|
526
568
|
end
|
527
569
|
|
528
570
|
def schema_sha1(file)
|
529
|
-
Digest::SHA1.hexdigest(File.read(file))
|
571
|
+
OpenSSL::Digest::SHA1.hexdigest(File.read(file))
|
572
|
+
end
|
573
|
+
|
574
|
+
def structure_dump_flags_for(adapter)
|
575
|
+
if structure_dump_flags.is_a?(Hash)
|
576
|
+
structure_dump_flags[adapter.to_sym]
|
577
|
+
else
|
578
|
+
structure_dump_flags
|
579
|
+
end
|
580
|
+
end
|
581
|
+
|
582
|
+
def structure_load_flags_for(adapter)
|
583
|
+
if structure_load_flags.is_a?(Hash)
|
584
|
+
structure_load_flags[adapter.to_sym]
|
585
|
+
else
|
586
|
+
structure_load_flags
|
587
|
+
end
|
530
588
|
end
|
531
589
|
end
|
532
590
|
end
|
@@ -94,7 +94,7 @@ module ActiveRecord
|
|
94
94
|
sslcapath: "--ssl-capath",
|
95
95
|
sslcipher: "--ssl-cipher",
|
96
96
|
sslkey: "--ssl-key"
|
97
|
-
}.
|
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
|
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
|
57
|
+
ActiveRecord.dump_schemas
|
60
58
|
end
|
61
59
|
|
62
|
-
args = ["--schema-only", "--no-privileges", "--no-owner"
|
60
|
+
args = ["--schema-only", "--no-privileges", "--no-owner"]
|
61
|
+
args << "--no-comment" 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
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
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
|
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
|
@@ -134,7 +134,7 @@ module ActiveRecord
|
|
134
134
|
@connection_subscriber = ActiveSupport::Notifications.subscribe("!connection.active_record") do |_, _, _, _, payload|
|
135
135
|
spec_name = payload[:spec_name] if payload.key?(:spec_name)
|
136
136
|
shard = payload[:shard] if payload.key?(:shard)
|
137
|
-
setup_shared_connection_pool
|
137
|
+
setup_shared_connection_pool
|
138
138
|
|
139
139
|
if spec_name
|
140
140
|
begin
|
@@ -143,14 +143,10 @@ module ActiveRecord
|
|
143
143
|
connection = nil
|
144
144
|
end
|
145
145
|
|
146
|
-
if connection
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
connection.begin_transaction joinable: false, _lazy: false
|
151
|
-
connection.pool.lock_thread = true if lock_threads
|
152
|
-
@fixture_connections << connection
|
153
|
-
end
|
146
|
+
if connection && !@fixture_connections.include?(connection)
|
147
|
+
connection.begin_transaction joinable: false, _lazy: false
|
148
|
+
connection.pool.lock_thread = true if lock_threads
|
149
|
+
@fixture_connections << connection
|
154
150
|
end
|
155
151
|
end
|
156
152
|
end
|
@@ -197,8 +193,8 @@ module ActiveRecord
|
|
197
193
|
# need to share a connection pool so that the reading connection
|
198
194
|
# can see data in the open transaction on the writing connection.
|
199
195
|
def setup_shared_connection_pool
|
200
|
-
if ActiveRecord
|
201
|
-
writing_handler = ActiveRecord::Base.connection_handlers[ActiveRecord
|
196
|
+
if ActiveRecord.legacy_connection_handling
|
197
|
+
writing_handler = ActiveRecord::Base.connection_handlers[ActiveRecord.writing_role]
|
202
198
|
|
203
199
|
ActiveRecord::Base.connection_handlers.values.each do |handler|
|
204
200
|
if handler != writing_handler
|
@@ -225,7 +221,7 @@ module ActiveRecord
|
|
225
221
|
handler.connection_pool_names.each do |name|
|
226
222
|
pool_manager = handler.send(:owner_to_pool_manager)[name]
|
227
223
|
pool_manager.shard_names.each do |shard_name|
|
228
|
-
writing_pool_config = pool_manager.get_pool_config(ActiveRecord
|
224
|
+
writing_pool_config = pool_manager.get_pool_config(ActiveRecord.writing_role, shard_name)
|
229
225
|
@saved_pool_configs[name][shard_name] ||= {}
|
230
226
|
pool_manager.role_names.each do |role|
|
231
227
|
next unless pool_config = pool_manager.get_pool_config(role, shard_name)
|
@@ -240,7 +236,7 @@ module ActiveRecord
|
|
240
236
|
end
|
241
237
|
|
242
238
|
def teardown_shared_connection_pool
|
243
|
-
if ActiveRecord
|
239
|
+
if ActiveRecord.legacy_connection_handling
|
244
240
|
@legacy_saved_pool_configs.each_pair do |handler, names|
|
245
241
|
names.each_pair do |name, shards|
|
246
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 && (!
|
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
|
-
.
|
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
|
-
|
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
|
293
|
+
def destroy # :nodoc:
|
294
294
|
with_transaction_returning_status { super }
|
295
295
|
end
|
296
296
|
|
297
|
-
def save(**)
|
297
|
+
def save(**) # :nodoc:
|
298
298
|
with_transaction_returning_status { super }
|
299
299
|
end
|
300
300
|
|
301
|
-
def save!(**)
|
301
|
+
def save!(**) # :nodoc:
|
302
302
|
with_transaction_returning_status { super }
|
303
303
|
end
|
304
304
|
|
305
|
-
def touch(*, **)
|
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)
|
318
|
-
|
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)
|
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
|
-
|
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
|
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
|
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
|
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
|
-
|
14
|
-
|
15
|
-
|
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
|