activerecord 7.1.5.2 → 8.1.2.1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +567 -2443
- data/README.rdoc +16 -16
- data/examples/performance.rb +2 -2
- data/lib/active_record/association_relation.rb +3 -2
- data/lib/active_record/associations/alias_tracker.rb +31 -23
- data/lib/active_record/associations/association.rb +43 -12
- data/lib/active_record/associations/belongs_to_association.rb +31 -8
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +3 -2
- data/lib/active_record/associations/builder/association.rb +23 -11
- data/lib/active_record/associations/builder/belongs_to.rb +18 -4
- data/lib/active_record/associations/builder/collection_association.rb +7 -3
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +2 -2
- data/lib/active_record/associations/builder/has_many.rb +3 -4
- data/lib/active_record/associations/builder/has_one.rb +3 -4
- data/lib/active_record/associations/builder/singular_association.rb +33 -5
- data/lib/active_record/associations/collection_association.rb +17 -9
- data/lib/active_record/associations/collection_proxy.rb +36 -5
- data/lib/active_record/associations/deprecation.rb +88 -0
- data/lib/active_record/associations/disable_joins_association_scope.rb +1 -1
- data/lib/active_record/associations/errors.rb +268 -0
- data/lib/active_record/associations/has_many_association.rb +1 -1
- data/lib/active_record/associations/has_many_through_association.rb +10 -3
- data/lib/active_record/associations/join_dependency/join_association.rb +1 -1
- data/lib/active_record/associations/join_dependency.rb +4 -2
- data/lib/active_record/associations/nested_error.rb +47 -0
- data/lib/active_record/associations/preloader/association.rb +4 -3
- data/lib/active_record/associations/preloader/batch.rb +7 -1
- data/lib/active_record/associations/preloader/branch.rb +8 -1
- data/lib/active_record/associations/preloader/through_association.rb +1 -3
- data/lib/active_record/associations/singular_association.rb +14 -3
- data/lib/active_record/associations/through_association.rb +1 -1
- data/lib/active_record/associations.rb +250 -315
- data/lib/active_record/asynchronous_queries_tracker.rb +28 -24
- data/lib/active_record/attribute_assignment.rb +0 -2
- data/lib/active_record/attribute_methods/composite_primary_key.rb +84 -0
- data/lib/active_record/attribute_methods/primary_key.rb +25 -61
- data/lib/active_record/attribute_methods/query.rb +34 -0
- data/lib/active_record/attribute_methods/read.rb +1 -13
- data/lib/active_record/attribute_methods/serialization.rb +20 -27
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +19 -20
- data/lib/active_record/attribute_methods.rb +71 -75
- data/lib/active_record/attributes.rb +96 -68
- data/lib/active_record/autosave_association.rb +93 -58
- data/lib/active_record/base.rb +5 -7
- data/lib/active_record/callbacks.rb +1 -1
- data/lib/active_record/coders/json.rb +14 -5
- data/lib/active_record/connection_adapters/abstract/connection_handler.rb +50 -126
- data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +16 -4
- data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +52 -13
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +681 -135
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +165 -86
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +226 -78
- data/lib/active_record/connection_adapters/abstract/quoting.rb +79 -114
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +11 -7
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +37 -36
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +2 -1
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +136 -34
- data/lib/active_record/connection_adapters/abstract/transaction.rb +163 -68
- data/lib/active_record/connection_adapters/abstract_adapter.rb +197 -129
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +112 -63
- data/lib/active_record/connection_adapters/column.rb +17 -4
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +11 -3
- data/lib/active_record/connection_adapters/mysql/quoting.rb +50 -57
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +2 -0
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +41 -10
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +79 -46
- data/lib/active_record/connection_adapters/mysql2/database_statements.rb +97 -101
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +14 -33
- data/lib/active_record/connection_adapters/pool_config.rb +14 -13
- data/lib/active_record/connection_adapters/postgresql/column.rb +4 -0
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +98 -44
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +3 -3
- data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +10 -0
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +14 -4
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +79 -68
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +2 -4
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +9 -17
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +44 -41
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +69 -32
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +155 -75
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +104 -121
- data/lib/active_record/connection_adapters/schema_cache.rb +126 -133
- data/lib/active_record/connection_adapters/sqlite3/column.rb +14 -1
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +91 -95
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +57 -54
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +16 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +13 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +43 -2
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +38 -15
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +231 -111
- data/lib/active_record/connection_adapters/statement_pool.rb +4 -2
- data/lib/active_record/connection_adapters/trilogy/database_statements.rb +40 -69
- data/lib/active_record/connection_adapters/trilogy_adapter.rb +19 -65
- data/lib/active_record/connection_adapters.rb +66 -0
- data/lib/active_record/connection_handling.rb +88 -46
- data/lib/active_record/core.rb +142 -58
- data/lib/active_record/counter_cache.rb +52 -18
- data/lib/active_record/database_configurations/connection_url_resolver.rb +9 -2
- data/lib/active_record/database_configurations/database_config.rb +28 -5
- data/lib/active_record/database_configurations/hash_config.rb +103 -41
- data/lib/active_record/database_configurations/url_config.rb +30 -1
- data/lib/active_record/database_configurations.rb +8 -4
- data/lib/active_record/delegated_type.rb +43 -19
- data/lib/active_record/dynamic_matchers.rb +56 -71
- data/lib/active_record/encryption/config.rb +3 -1
- data/lib/active_record/encryption/encryptable_record.rb +12 -12
- data/lib/active_record/encryption/encrypted_attribute_type.rb +35 -6
- data/lib/active_record/encryption/encryptor.rb +58 -22
- data/lib/active_record/encryption/extended_deterministic_queries.rb +4 -2
- data/lib/active_record/encryption/key_provider.rb +1 -1
- data/lib/active_record/encryption/message_pack_message_serializer.rb +76 -0
- data/lib/active_record/encryption/message_serializer.rb +4 -0
- data/lib/active_record/encryption/null_encryptor.rb +4 -0
- data/lib/active_record/encryption/read_only_null_encryptor.rb +4 -0
- data/lib/active_record/encryption/scheme.rb +9 -2
- data/lib/active_record/enum.rb +57 -36
- data/lib/active_record/errors.rb +76 -26
- data/lib/active_record/explain.rb +14 -25
- data/lib/active_record/explain_registry.rb +51 -2
- data/lib/active_record/filter_attribute_handler.rb +73 -0
- data/lib/active_record/fixture_set/table_row.rb +19 -2
- data/lib/active_record/fixtures.rb +39 -35
- data/lib/active_record/future_result.rb +21 -13
- data/lib/active_record/gem_version.rb +3 -3
- data/lib/active_record/inheritance.rb +5 -3
- data/lib/active_record/insert_all.rb +28 -20
- data/lib/active_record/integration.rb +4 -1
- data/lib/active_record/internal_metadata.rb +48 -34
- data/lib/active_record/locking/optimistic.rb +15 -7
- data/lib/active_record/locking/pessimistic.rb +5 -0
- data/lib/active_record/log_subscriber.rb +3 -34
- data/lib/active_record/message_pack.rb +1 -1
- data/lib/active_record/middleware/shard_selector.rb +34 -17
- data/lib/active_record/migration/command_recorder.rb +46 -14
- data/lib/active_record/migration/compatibility.rb +40 -25
- data/lib/active_record/migration/default_schema_versions_formatter.rb +30 -0
- data/lib/active_record/migration/default_strategy.rb +4 -5
- data/lib/active_record/migration/pending_migration_connection.rb +2 -2
- data/lib/active_record/migration.rb +119 -103
- data/lib/active_record/model_schema.rb +66 -78
- data/lib/active_record/nested_attributes.rb +17 -9
- data/lib/active_record/persistence.rb +161 -454
- data/lib/active_record/query_cache.rb +33 -15
- data/lib/active_record/query_logs.rb +106 -39
- data/lib/active_record/query_logs_formatter.rb +17 -28
- data/lib/active_record/querying.rb +28 -16
- data/lib/active_record/railtie.rb +61 -74
- data/lib/active_record/railties/controller_runtime.rb +19 -5
- data/lib/active_record/railties/databases.rake +64 -78
- data/lib/active_record/railties/job_checkpoints.rb +15 -0
- data/lib/active_record/railties/job_runtime.rb +10 -11
- data/lib/active_record/reflection.rb +147 -53
- data/lib/active_record/relation/batches/batch_enumerator.rb +19 -5
- data/lib/active_record/relation/batches.rb +153 -73
- data/lib/active_record/relation/calculations.rb +146 -96
- data/lib/active_record/relation/delegation.rb +30 -23
- data/lib/active_record/relation/finder_methods.rb +64 -34
- data/lib/active_record/relation/merger.rb +12 -14
- data/lib/active_record/relation/predicate_builder/array_handler.rb +2 -2
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +19 -11
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +8 -8
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +4 -3
- data/lib/active_record/relation/predicate_builder.rb +25 -10
- data/lib/active_record/relation/query_attribute.rb +4 -2
- data/lib/active_record/relation/query_methods.rb +351 -124
- data/lib/active_record/relation/spawn_methods.rb +9 -25
- data/lib/active_record/relation/where_clause.rb +17 -30
- data/lib/active_record/relation.rb +590 -124
- data/lib/active_record/result.rb +131 -59
- data/lib/active_record/runtime_registry.rb +44 -21
- data/lib/active_record/sanitization.rb +33 -25
- data/lib/active_record/schema.rb +8 -6
- data/lib/active_record/schema_dumper.rb +66 -31
- data/lib/active_record/schema_migration.rb +31 -14
- data/lib/active_record/scoping/named.rb +6 -2
- data/lib/active_record/scoping.rb +0 -1
- data/lib/active_record/secure_token.rb +3 -3
- data/lib/active_record/signed_id.rb +68 -20
- data/lib/active_record/statement_cache.rb +29 -25
- data/lib/active_record/store.rb +51 -22
- data/lib/active_record/structured_event_subscriber.rb +85 -0
- data/lib/active_record/table_metadata.rb +7 -33
- data/lib/active_record/tasks/abstract_tasks.rb +76 -0
- data/lib/active_record/tasks/database_tasks.rb +118 -90
- data/lib/active_record/tasks/mysql_database_tasks.rb +3 -42
- data/lib/active_record/tasks/postgresql_database_tasks.rb +14 -40
- data/lib/active_record/tasks/sqlite_database_tasks.rb +17 -28
- data/lib/active_record/test_databases.rb +14 -4
- data/lib/active_record/test_fixtures.rb +123 -89
- data/lib/active_record/testing/query_assertions.rb +127 -0
- data/lib/active_record/timestamp.rb +6 -4
- data/lib/active_record/token_for.rb +22 -12
- data/lib/active_record/touch_later.rb +1 -1
- data/lib/active_record/transaction.rb +129 -0
- data/lib/active_record/transactions.rb +97 -18
- data/lib/active_record/translation.rb +0 -2
- data/lib/active_record/type/hash_lookup_type_map.rb +2 -1
- data/lib/active_record/type/internal/timezone.rb +7 -0
- data/lib/active_record/type/json.rb +15 -2
- data/lib/active_record/type/serialized.rb +12 -7
- data/lib/active_record/type/type_map.rb +1 -1
- data/lib/active_record/type_caster/connection.rb +5 -4
- data/lib/active_record/validations/associated.rb +10 -4
- data/lib/active_record/validations/uniqueness.rb +23 -18
- data/lib/active_record/validations.rb +4 -1
- data/lib/active_record.rb +203 -59
- data/lib/arel/alias_predication.rb +3 -1
- data/lib/arel/collectors/bind.rb +4 -2
- data/lib/arel/collectors/composite.rb +7 -0
- data/lib/arel/collectors/sql_string.rb +2 -2
- data/lib/arel/collectors/substitute_binds.rb +3 -3
- data/lib/arel/crud.rb +8 -11
- data/lib/arel/delete_manager.rb +5 -0
- data/lib/arel/nodes/binary.rb +1 -7
- data/lib/arel/nodes/bound_sql_literal.rb +9 -5
- data/lib/arel/nodes/count.rb +2 -2
- data/lib/arel/nodes/delete_statement.rb +4 -2
- data/lib/arel/nodes/function.rb +4 -10
- data/lib/arel/nodes/named_function.rb +2 -2
- data/lib/arel/nodes/{and.rb → nary.rb} +5 -2
- data/lib/arel/nodes/node.rb +6 -5
- data/lib/arel/nodes/sql_literal.rb +8 -1
- data/lib/arel/nodes/update_statement.rb +4 -2
- data/lib/arel/nodes.rb +2 -4
- data/lib/arel/predications.rb +1 -1
- data/lib/arel/select_manager.rb +14 -5
- data/lib/arel/table.rb +3 -7
- data/lib/arel/tree_manager.rb +3 -2
- data/lib/arel/update_manager.rb +7 -1
- data/lib/arel/visitors/dot.rb +3 -3
- data/lib/arel/visitors/mysql.rb +9 -4
- data/lib/arel/visitors/postgresql.rb +56 -12
- data/lib/arel/visitors/sqlite.rb +80 -8
- data/lib/arel/visitors/to_sql.rb +34 -37
- data/lib/arel.rb +10 -4
- data/lib/rails/generators/active_record/application_record/USAGE +1 -1
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +4 -1
- metadata +23 -14
- data/lib/active_record/explain_subscriber.rb +0 -34
- data/lib/active_record/normalization.rb +0 -167
- data/lib/active_record/relation/record_fetch_warning.rb +0 -49
|
@@ -45,7 +45,7 @@ module ActiveRecord
|
|
|
45
45
|
# Example:
|
|
46
46
|
# ActiveRecord::Tasks::DatabaseTasks.structure_dump_flags = {
|
|
47
47
|
# mysql2: ['--no-defaults', '--skip-add-drop-table'],
|
|
48
|
-
#
|
|
48
|
+
# postgresql: '--no-tablespaces'
|
|
49
49
|
# }
|
|
50
50
|
mattr_accessor :structure_dump_flags, instance_accessor: false
|
|
51
51
|
|
|
@@ -66,7 +66,7 @@ module ActiveRecord
|
|
|
66
66
|
return if ENV["DISABLE_DATABASE_ENVIRONMENT_CHECK"]
|
|
67
67
|
|
|
68
68
|
configs_for(env_name: environment).each do |db_config|
|
|
69
|
-
check_current_protected_environment!(db_config)
|
|
69
|
+
database_adapter_for(db_config).check_current_protected_environment!(db_config, migration_class)
|
|
70
70
|
end
|
|
71
71
|
end
|
|
72
72
|
|
|
@@ -125,11 +125,11 @@ module ActiveRecord
|
|
|
125
125
|
end
|
|
126
126
|
|
|
127
127
|
def create_all
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
128
|
+
db_config = migration_connection.pool.db_config
|
|
129
|
+
|
|
130
|
+
each_local_configuration { |db_config| create(db_config) }
|
|
131
|
+
|
|
132
|
+
migration_class.establish_connection(db_config)
|
|
133
133
|
end
|
|
134
134
|
|
|
135
135
|
def setup_initial_database_yaml # :nodoc:
|
|
@@ -147,8 +147,6 @@ module ActiveRecord
|
|
|
147
147
|
return if database_configs.count == 1
|
|
148
148
|
|
|
149
149
|
database_configs.each do |db_config|
|
|
150
|
-
next unless db_config.database_tasks?
|
|
151
|
-
|
|
152
150
|
yield db_config.name
|
|
153
151
|
end
|
|
154
152
|
end
|
|
@@ -178,22 +176,9 @@ module ActiveRecord
|
|
|
178
176
|
dump_db_configs = []
|
|
179
177
|
|
|
180
178
|
each_current_configuration(env) do |db_config|
|
|
181
|
-
|
|
182
|
-
begin
|
|
183
|
-
database_initialized = migration_connection.schema_migration.table_exists?
|
|
184
|
-
rescue ActiveRecord::NoDatabaseError
|
|
185
|
-
create(db_config)
|
|
186
|
-
retry
|
|
187
|
-
end
|
|
188
|
-
|
|
189
|
-
unless database_initialized
|
|
190
|
-
if File.exist?(schema_dump_path(db_config))
|
|
191
|
-
load_schema(db_config, ActiveRecord.schema_format, nil)
|
|
192
|
-
end
|
|
179
|
+
database_initialized = initialize_database(db_config)
|
|
193
180
|
|
|
194
|
-
|
|
195
|
-
end
|
|
196
|
-
end
|
|
181
|
+
seed = true if database_initialized && db_config.seeds?
|
|
197
182
|
end
|
|
198
183
|
|
|
199
184
|
each_current_environment(env) do |environment|
|
|
@@ -253,13 +238,34 @@ module ActiveRecord
|
|
|
253
238
|
end
|
|
254
239
|
end
|
|
255
240
|
|
|
256
|
-
def
|
|
241
|
+
def migrate_all
|
|
242
|
+
db_configs = ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env)
|
|
243
|
+
db_configs.each { |db_config| initialize_database(db_config) }
|
|
244
|
+
|
|
245
|
+
if db_configs.size == 1 && db_configs.first.primary?
|
|
246
|
+
ActiveRecord::Tasks::DatabaseTasks.migrate(skip_initialize: true)
|
|
247
|
+
else
|
|
248
|
+
mapped_versions = ActiveRecord::Tasks::DatabaseTasks.db_configs_with_versions
|
|
249
|
+
|
|
250
|
+
mapped_versions.sort.each do |version, db_configs|
|
|
251
|
+
db_configs.each do |db_config|
|
|
252
|
+
ActiveRecord::Tasks::DatabaseTasks.with_temporary_connection(db_config) do
|
|
253
|
+
ActiveRecord::Tasks::DatabaseTasks.migrate(version, skip_initialize: true)
|
|
254
|
+
end
|
|
255
|
+
end
|
|
256
|
+
end
|
|
257
|
+
end
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
def migrate(version = nil, skip_initialize: false)
|
|
257
261
|
scope = ENV["SCOPE"]
|
|
258
262
|
verbose_was, Migration.verbose = Migration.verbose, verbose?
|
|
259
263
|
|
|
260
264
|
check_target_version
|
|
261
265
|
|
|
262
|
-
|
|
266
|
+
initialize_database(migration_connection_pool.db_config) unless skip_initialize
|
|
267
|
+
|
|
268
|
+
migration_connection_pool.migration_context.migrate(target_version) do |migration|
|
|
263
269
|
if version.blank?
|
|
264
270
|
scope.blank? || scope == migration.scope
|
|
265
271
|
else
|
|
@@ -269,7 +275,7 @@ module ActiveRecord
|
|
|
269
275
|
Migration.write("No migrations ran. (using #{scope} scope)") if scope.present? && migrations_ran.empty?
|
|
270
276
|
end
|
|
271
277
|
|
|
272
|
-
|
|
278
|
+
migration_connection_pool.schema_cache.clear!
|
|
273
279
|
ensure
|
|
274
280
|
Migration.verbose = verbose_was
|
|
275
281
|
end
|
|
@@ -277,9 +283,9 @@ module ActiveRecord
|
|
|
277
283
|
def db_configs_with_versions(environment = env) # :nodoc:
|
|
278
284
|
db_configs_with_versions = Hash.new { |h, k| h[k] = [] }
|
|
279
285
|
|
|
280
|
-
|
|
281
|
-
db_config =
|
|
282
|
-
versions_to_run =
|
|
286
|
+
with_temporary_pool_for_each(env: environment) do |pool|
|
|
287
|
+
db_config = pool.db_config
|
|
288
|
+
versions_to_run = pool.migration_context.pending_migration_versions
|
|
283
289
|
target_version = ActiveRecord::Tasks::DatabaseTasks.target_version
|
|
284
290
|
|
|
285
291
|
versions_to_run.each do |version|
|
|
@@ -292,15 +298,15 @@ module ActiveRecord
|
|
|
292
298
|
end
|
|
293
299
|
|
|
294
300
|
def migrate_status
|
|
295
|
-
unless
|
|
301
|
+
unless migration_connection_pool.schema_migration.table_exists?
|
|
296
302
|
Kernel.abort "Schema migrations table does not exist yet."
|
|
297
303
|
end
|
|
298
304
|
|
|
299
305
|
# output
|
|
300
|
-
puts "\ndatabase: #{
|
|
306
|
+
puts "\ndatabase: #{migration_connection_pool.db_config.database}\n\n"
|
|
301
307
|
puts "#{'Status'.center(8)} #{'Migration ID'.ljust(14)} Migration Name"
|
|
302
308
|
puts "-" * 50
|
|
303
|
-
|
|
309
|
+
migration_connection_pool.migration_context.migrations_status.each do |status, version, name|
|
|
304
310
|
puts "#{status.center(8)} #{version.ljust(14)} #{name}"
|
|
305
311
|
end
|
|
306
312
|
puts
|
|
@@ -365,7 +371,8 @@ module ActiveRecord
|
|
|
365
371
|
database_adapter_for(db_config, *arguments).structure_load(filename, flags)
|
|
366
372
|
end
|
|
367
373
|
|
|
368
|
-
def load_schema(db_config, format =
|
|
374
|
+
def load_schema(db_config, format = db_config.schema_format, file = nil) # :nodoc:
|
|
375
|
+
format = format.to_sym
|
|
369
376
|
file ||= schema_dump_path(db_config, format)
|
|
370
377
|
return unless file
|
|
371
378
|
|
|
@@ -381,69 +388,87 @@ module ActiveRecord
|
|
|
381
388
|
raise ArgumentError, "unknown format #{format.inspect}"
|
|
382
389
|
end
|
|
383
390
|
|
|
384
|
-
|
|
391
|
+
migration_connection_pool.internal_metadata.create_table_and_set_flags(db_config.env_name, schema_sha1(file))
|
|
385
392
|
ensure
|
|
386
393
|
Migration.verbose = verbose_was
|
|
387
394
|
end
|
|
388
395
|
|
|
389
|
-
def schema_up_to_date?(configuration,
|
|
396
|
+
def schema_up_to_date?(configuration, _ = nil, file = nil)
|
|
390
397
|
db_config = resolve_configuration(configuration)
|
|
391
398
|
|
|
392
399
|
file ||= schema_dump_path(db_config)
|
|
393
400
|
|
|
394
401
|
return true unless file && File.exist?(file)
|
|
395
402
|
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
return false unless
|
|
403
|
+
with_temporary_pool(db_config) do |pool|
|
|
404
|
+
internal_metadata = pool.internal_metadata
|
|
405
|
+
return false unless internal_metadata.enabled?
|
|
406
|
+
return false unless internal_metadata.table_exists?
|
|
399
407
|
|
|
400
|
-
|
|
408
|
+
internal_metadata[:schema_sha1] == schema_sha1(file)
|
|
401
409
|
end
|
|
402
410
|
end
|
|
403
411
|
|
|
404
|
-
def reconstruct_from_schema(db_config,
|
|
405
|
-
file ||= schema_dump_path(db_config,
|
|
412
|
+
def reconstruct_from_schema(db_config, file = nil) # :nodoc:
|
|
413
|
+
file ||= schema_dump_path(db_config, db_config.schema_format)
|
|
406
414
|
|
|
407
415
|
check_schema_file(file) if file
|
|
408
416
|
|
|
409
417
|
with_temporary_pool(db_config, clobber: true) do
|
|
410
|
-
if schema_up_to_date?(db_config,
|
|
411
|
-
truncate_tables(db_config)
|
|
418
|
+
if schema_up_to_date?(db_config, nil, file)
|
|
419
|
+
truncate_tables(db_config) unless ENV["SKIP_TEST_DATABASE_TRUNCATE"]
|
|
412
420
|
else
|
|
413
421
|
purge(db_config)
|
|
414
|
-
load_schema(db_config,
|
|
422
|
+
load_schema(db_config, db_config.schema_format, file)
|
|
415
423
|
end
|
|
416
424
|
rescue ActiveRecord::NoDatabaseError
|
|
417
425
|
create(db_config)
|
|
418
|
-
load_schema(db_config,
|
|
426
|
+
load_schema(db_config, db_config.schema_format, file)
|
|
427
|
+
end
|
|
428
|
+
end
|
|
429
|
+
|
|
430
|
+
def dump_all
|
|
431
|
+
seen_schemas = []
|
|
432
|
+
|
|
433
|
+
ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
|
|
434
|
+
schema_path = schema_dump_path(db_config, ENV["SCHEMA_FORMAT"] || db_config.schema_format)
|
|
435
|
+
|
|
436
|
+
next if seen_schemas.include?(schema_path)
|
|
437
|
+
|
|
438
|
+
ActiveRecord::Tasks::DatabaseTasks.dump_schema(db_config, ENV["SCHEMA_FORMAT"] || db_config.schema_format)
|
|
439
|
+
seen_schemas << schema_path
|
|
419
440
|
end
|
|
420
441
|
end
|
|
421
442
|
|
|
422
|
-
def dump_schema(db_config, format =
|
|
443
|
+
def dump_schema(db_config, format = db_config.schema_format) # :nodoc:
|
|
423
444
|
return unless db_config.schema_dump
|
|
424
445
|
|
|
425
446
|
require "active_record/schema_dumper"
|
|
426
447
|
filename = schema_dump_path(db_config, format)
|
|
427
448
|
return unless filename
|
|
428
449
|
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
450
|
+
with_temporary_pool(db_config) do |pool|
|
|
451
|
+
FileUtils.mkdir_p(db_dir)
|
|
452
|
+
case format.to_sym
|
|
453
|
+
when :ruby
|
|
454
|
+
File.open(filename, "w:utf-8") do |file|
|
|
455
|
+
ActiveRecord::SchemaDumper.dump(pool, file)
|
|
456
|
+
end
|
|
457
|
+
when :sql
|
|
458
|
+
structure_dump(db_config, filename)
|
|
459
|
+
if pool.schema_migration.table_exists?
|
|
460
|
+
File.open(filename, "a") do |f|
|
|
461
|
+
pool.with_connection do |connection|
|
|
462
|
+
f.puts connection.dump_schema_versions
|
|
463
|
+
end
|
|
464
|
+
f.print "\n"
|
|
465
|
+
end
|
|
441
466
|
end
|
|
442
467
|
end
|
|
443
468
|
end
|
|
444
469
|
end
|
|
445
470
|
|
|
446
|
-
def schema_dump_path(db_config, format =
|
|
471
|
+
def schema_dump_path(db_config, format = db_config.schema_format)
|
|
447
472
|
return ENV["SCHEMA"] if ENV["SCHEMA"]
|
|
448
473
|
|
|
449
474
|
filename = db_config.schema_dump(format)
|
|
@@ -456,20 +481,16 @@ module ActiveRecord
|
|
|
456
481
|
end
|
|
457
482
|
end
|
|
458
483
|
|
|
459
|
-
def cache_dump_filename(
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
"#{db_config_name}_schema_cache.yml"
|
|
464
|
-
end
|
|
465
|
-
|
|
466
|
-
schema_cache_path || ENV["SCHEMA_CACHE"] || File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, filename)
|
|
484
|
+
def cache_dump_filename(db_config, schema_cache_path: nil)
|
|
485
|
+
schema_cache_path ||
|
|
486
|
+
db_config.schema_cache_path ||
|
|
487
|
+
db_config.default_schema_cache_path(ActiveRecord::Tasks::DatabaseTasks.db_dir)
|
|
467
488
|
end
|
|
468
489
|
|
|
469
|
-
def load_schema_current(format =
|
|
490
|
+
def load_schema_current(format = nil, file = nil, environment = env)
|
|
470
491
|
each_current_configuration(environment) do |db_config|
|
|
471
492
|
with_temporary_connection(db_config) do
|
|
472
|
-
load_schema(db_config, format, file)
|
|
493
|
+
load_schema(db_config, format || db_config.schema_format, file)
|
|
473
494
|
end
|
|
474
495
|
end
|
|
475
496
|
end
|
|
@@ -495,29 +516,29 @@ module ActiveRecord
|
|
|
495
516
|
# Dumps the schema cache in YAML format for the connection into the file
|
|
496
517
|
#
|
|
497
518
|
# ==== Examples
|
|
498
|
-
# ActiveRecord::Tasks::DatabaseTasks.dump_schema_cache(ActiveRecord::Base.
|
|
499
|
-
def dump_schema_cache(
|
|
500
|
-
|
|
519
|
+
# ActiveRecord::Tasks::DatabaseTasks.dump_schema_cache(ActiveRecord::Base.lease_connection, "tmp/schema_dump.yaml")
|
|
520
|
+
def dump_schema_cache(conn_or_pool, filename)
|
|
521
|
+
conn_or_pool.schema_cache.dump_to(filename)
|
|
501
522
|
end
|
|
502
523
|
|
|
503
524
|
def clear_schema_cache(filename)
|
|
504
525
|
FileUtils.rm_f filename, verbose: false
|
|
505
526
|
end
|
|
506
527
|
|
|
507
|
-
def
|
|
528
|
+
def with_temporary_pool_for_each(env: ActiveRecord::Tasks::DatabaseTasks.env, name: nil, clobber: false, &block) # :nodoc:
|
|
508
529
|
if name
|
|
509
530
|
db_config = ActiveRecord::Base.configurations.configs_for(env_name: env, name: name)
|
|
510
|
-
|
|
531
|
+
with_temporary_pool(db_config, clobber: clobber, &block)
|
|
511
532
|
else
|
|
512
533
|
ActiveRecord::Base.configurations.configs_for(env_name: env, name: name).each do |db_config|
|
|
513
|
-
|
|
534
|
+
with_temporary_pool(db_config, clobber: clobber, &block)
|
|
514
535
|
end
|
|
515
536
|
end
|
|
516
537
|
end
|
|
517
538
|
|
|
518
|
-
def with_temporary_connection(db_config, clobber: false) # :nodoc:
|
|
539
|
+
def with_temporary_connection(db_config, clobber: false, &block) # :nodoc:
|
|
519
540
|
with_temporary_pool(db_config, clobber: clobber) do |pool|
|
|
520
|
-
|
|
541
|
+
pool.with_connection(&block)
|
|
521
542
|
end
|
|
522
543
|
end
|
|
523
544
|
|
|
@@ -526,7 +547,11 @@ module ActiveRecord
|
|
|
526
547
|
end
|
|
527
548
|
|
|
528
549
|
def migration_connection # :nodoc:
|
|
529
|
-
migration_class.
|
|
550
|
+
migration_class.lease_connection
|
|
551
|
+
end
|
|
552
|
+
|
|
553
|
+
def migration_connection_pool # :nodoc:
|
|
554
|
+
migration_class.connection_pool
|
|
530
555
|
end
|
|
531
556
|
|
|
532
557
|
private
|
|
@@ -623,20 +648,23 @@ module ActiveRecord
|
|
|
623
648
|
end
|
|
624
649
|
end
|
|
625
650
|
|
|
626
|
-
def
|
|
627
|
-
with_temporary_pool(db_config) do
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
raise ActiveRecord::ProtectedEnvironmentError.new(stored)
|
|
651
|
+
def initialize_database(db_config)
|
|
652
|
+
with_temporary_pool(db_config) do
|
|
653
|
+
begin
|
|
654
|
+
database_already_initialized = migration_connection_pool.schema_migration.table_exists?
|
|
655
|
+
rescue ActiveRecord::NoDatabaseError
|
|
656
|
+
create(db_config)
|
|
657
|
+
retry
|
|
634
658
|
end
|
|
635
659
|
|
|
636
|
-
|
|
637
|
-
|
|
660
|
+
unless database_already_initialized
|
|
661
|
+
schema_dump_path = schema_dump_path(db_config)
|
|
662
|
+
if schema_dump_path && File.exist?(schema_dump_path)
|
|
663
|
+
load_schema(db_config)
|
|
664
|
+
end
|
|
638
665
|
end
|
|
639
|
-
|
|
666
|
+
|
|
667
|
+
!database_already_initialized
|
|
640
668
|
end
|
|
641
669
|
end
|
|
642
670
|
end
|
|
@@ -2,18 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module ActiveRecord
|
|
4
4
|
module Tasks # :nodoc:
|
|
5
|
-
class MySQLDatabaseTasks # :nodoc:
|
|
6
|
-
ER_DB_CREATE_EXISTS = 1007
|
|
7
|
-
|
|
8
|
-
def self.using_database_configurations?
|
|
9
|
-
true
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def initialize(db_config)
|
|
13
|
-
@db_config = db_config
|
|
14
|
-
@configuration_hash = db_config.configuration_hash
|
|
15
|
-
end
|
|
16
|
-
|
|
5
|
+
class MySQLDatabaseTasks < AbstractTasks # :nodoc:
|
|
17
6
|
def create
|
|
18
7
|
establish_connection(configuration_hash_without_database)
|
|
19
8
|
connection.create_database(db_config.database, creation_options)
|
|
@@ -35,10 +24,6 @@ module ActiveRecord
|
|
|
35
24
|
connection.charset
|
|
36
25
|
end
|
|
37
26
|
|
|
38
|
-
def collation
|
|
39
|
-
connection.collation
|
|
40
|
-
end
|
|
41
|
-
|
|
42
27
|
def structure_dump(filename, extra_flags)
|
|
43
28
|
args = prepare_command_options
|
|
44
29
|
args.concat(["--result-file", "#{filename}"])
|
|
@@ -55,7 +40,7 @@ module ActiveRecord
|
|
|
55
40
|
args.concat([db_config.database.to_s])
|
|
56
41
|
args.unshift(*extra_flags) if extra_flags
|
|
57
42
|
|
|
58
|
-
run_cmd("mysqldump", args
|
|
43
|
+
run_cmd("mysqldump", *args)
|
|
59
44
|
end
|
|
60
45
|
|
|
61
46
|
def structure_load(filename, extra_flags)
|
|
@@ -64,24 +49,10 @@ module ActiveRecord
|
|
|
64
49
|
args.concat(["--database", db_config.database.to_s])
|
|
65
50
|
args.unshift(*extra_flags) if extra_flags
|
|
66
51
|
|
|
67
|
-
run_cmd("mysql", args
|
|
52
|
+
run_cmd("mysql", *args)
|
|
68
53
|
end
|
|
69
54
|
|
|
70
55
|
private
|
|
71
|
-
attr_reader :db_config, :configuration_hash
|
|
72
|
-
|
|
73
|
-
def connection
|
|
74
|
-
ActiveRecord::Base.connection
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
def establish_connection(config = db_config)
|
|
78
|
-
ActiveRecord::Base.establish_connection(config)
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
def configuration_hash_without_database
|
|
82
|
-
configuration_hash.merge(database: nil)
|
|
83
|
-
end
|
|
84
|
-
|
|
85
56
|
def creation_options
|
|
86
57
|
Hash.new.tap do |options|
|
|
87
58
|
options[:charset] = configuration_hash[:encoding] if configuration_hash.include?(:encoding)
|
|
@@ -107,16 +78,6 @@ module ActiveRecord
|
|
|
107
78
|
|
|
108
79
|
args
|
|
109
80
|
end
|
|
110
|
-
|
|
111
|
-
def run_cmd(cmd, args, action)
|
|
112
|
-
fail run_cmd_error(cmd, args, action) unless Kernel.system(cmd, *args)
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
def run_cmd_error(cmd, args, action)
|
|
116
|
-
msg = +"failed to execute: `#{cmd}`\n"
|
|
117
|
-
msg << "Please check the output above for any errors and make sure that `#{cmd}` is installed in your PATH and has proper permissions.\n\n"
|
|
118
|
-
msg
|
|
119
|
-
end
|
|
120
81
|
end
|
|
121
82
|
end
|
|
122
83
|
end
|
|
@@ -4,20 +4,11 @@ require "tempfile"
|
|
|
4
4
|
|
|
5
5
|
module ActiveRecord
|
|
6
6
|
module Tasks # :nodoc:
|
|
7
|
-
class PostgreSQLDatabaseTasks # :nodoc:
|
|
7
|
+
class PostgreSQLDatabaseTasks < AbstractTasks # :nodoc:
|
|
8
8
|
DEFAULT_ENCODING = ENV["CHARSET"] || "utf8"
|
|
9
9
|
ON_ERROR_STOP_1 = "ON_ERROR_STOP=1"
|
|
10
10
|
SQL_COMMENT_BEGIN = "--"
|
|
11
11
|
|
|
12
|
-
def self.using_database_configurations?
|
|
13
|
-
true
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def initialize(db_config)
|
|
17
|
-
@db_config = db_config
|
|
18
|
-
@configuration_hash = db_config.configuration_hash
|
|
19
|
-
end
|
|
20
|
-
|
|
21
12
|
def create(connection_already_established = false)
|
|
22
13
|
establish_connection(public_schema_config) unless connection_already_established
|
|
23
14
|
connection.create_database(db_config.database, configuration_hash.merge(encoding: encoding))
|
|
@@ -29,14 +20,6 @@ module ActiveRecord
|
|
|
29
20
|
connection.drop_database(db_config.database)
|
|
30
21
|
end
|
|
31
22
|
|
|
32
|
-
def charset
|
|
33
|
-
connection.encoding
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def collation
|
|
37
|
-
connection.collation
|
|
38
|
-
end
|
|
39
|
-
|
|
40
23
|
def purge
|
|
41
24
|
ActiveRecord::Base.connection_handler.clear_active_connections!(:all)
|
|
42
25
|
drop
|
|
@@ -72,29 +55,20 @@ module ActiveRecord
|
|
|
72
55
|
end
|
|
73
56
|
|
|
74
57
|
args << db_config.database
|
|
75
|
-
run_cmd("pg_dump", args
|
|
58
|
+
run_cmd("pg_dump", *args)
|
|
76
59
|
remove_sql_header_comments(filename)
|
|
77
60
|
File.open(filename, "a") { |f| f << "SET search_path TO #{connection.schema_search_path};\n\n" }
|
|
78
61
|
end
|
|
79
62
|
|
|
80
63
|
def structure_load(filename, extra_flags)
|
|
81
|
-
args = ["--set", ON_ERROR_STOP_1, "--quiet", "--no-psqlrc", "--output", File::NULL
|
|
64
|
+
args = ["--set", ON_ERROR_STOP_1, "--quiet", "--no-psqlrc", "--output", File::NULL]
|
|
82
65
|
args.concat(Array(extra_flags)) if extra_flags
|
|
66
|
+
args.concat(["--file", filename])
|
|
83
67
|
args << db_config.database
|
|
84
|
-
run_cmd("psql", args
|
|
68
|
+
run_cmd("psql", *args)
|
|
85
69
|
end
|
|
86
70
|
|
|
87
71
|
private
|
|
88
|
-
attr_reader :db_config, :configuration_hash
|
|
89
|
-
|
|
90
|
-
def connection
|
|
91
|
-
ActiveRecord::Base.connection
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
def establish_connection(config = db_config)
|
|
95
|
-
ActiveRecord::Base.establish_connection(config)
|
|
96
|
-
end
|
|
97
|
-
|
|
98
72
|
def encoding
|
|
99
73
|
configuration_hash[:encoding] || DEFAULT_ENCODING
|
|
100
74
|
end
|
|
@@ -116,15 +90,8 @@ module ActiveRecord
|
|
|
116
90
|
end
|
|
117
91
|
end
|
|
118
92
|
|
|
119
|
-
def run_cmd(cmd, args,
|
|
120
|
-
fail run_cmd_error(cmd, args
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
def run_cmd_error(cmd, args, action)
|
|
124
|
-
msg = +"failed to execute:\n"
|
|
125
|
-
msg << "#{cmd} #{args.join(' ')}\n\n"
|
|
126
|
-
msg << "Please check the output above for any errors and make sure that `#{cmd}` is installed in your PATH and has proper permissions.\n\n"
|
|
127
|
-
msg
|
|
93
|
+
def run_cmd(cmd, *args, **opts)
|
|
94
|
+
fail run_cmd_error(cmd, args) unless Kernel.system(psql_env, cmd, *args, **opts)
|
|
128
95
|
end
|
|
129
96
|
|
|
130
97
|
def remove_sql_header_comments(filename)
|
|
@@ -132,6 +99,13 @@ module ActiveRecord
|
|
|
132
99
|
tempfile = Tempfile.open("uncommented_structure.sql")
|
|
133
100
|
begin
|
|
134
101
|
File.foreach(filename) do |line|
|
|
102
|
+
next if line.start_with?("\\restrict ")
|
|
103
|
+
|
|
104
|
+
if line.start_with?("\\unrestrict ")
|
|
105
|
+
removing_comments = true
|
|
106
|
+
next
|
|
107
|
+
end
|
|
108
|
+
|
|
135
109
|
unless removing_comments && (line.start_with?(SQL_COMMENT_BEGIN) || line.blank?)
|
|
136
110
|
tempfile << line
|
|
137
111
|
removing_comments = false
|
|
@@ -2,11 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module ActiveRecord
|
|
4
4
|
module Tasks # :nodoc:
|
|
5
|
-
class SQLiteDatabaseTasks # :nodoc:
|
|
6
|
-
def self.using_database_configurations?
|
|
7
|
-
true
|
|
8
|
-
end
|
|
9
|
-
|
|
5
|
+
class SQLiteDatabaseTasks < AbstractTasks # :nodoc:
|
|
10
6
|
def initialize(db_config, root = ActiveRecord::Tasks::DatabaseTasks.root)
|
|
11
7
|
@db_config = db_config
|
|
12
8
|
@root = root
|
|
@@ -37,10 +33,6 @@ module ActiveRecord
|
|
|
37
33
|
connection.reconnect!
|
|
38
34
|
end
|
|
39
35
|
|
|
40
|
-
def charset
|
|
41
|
-
connection.encoding
|
|
42
|
-
end
|
|
43
|
-
|
|
44
36
|
def structure_dump(filename, extra_flags)
|
|
45
37
|
args = []
|
|
46
38
|
args.concat(Array(extra_flags)) if extra_flags
|
|
@@ -50,11 +42,12 @@ module ActiveRecord
|
|
|
50
42
|
if ignore_tables.any?
|
|
51
43
|
ignore_tables = connection.data_sources.select { |table| ignore_tables.any? { |pattern| pattern === table } }
|
|
52
44
|
condition = ignore_tables.map { |table| connection.quote(table) }.join(", ")
|
|
53
|
-
args << "SELECT sql FROM sqlite_master WHERE tbl_name NOT IN (#{condition}) ORDER BY tbl_name, type DESC, name"
|
|
45
|
+
args << "SELECT sql || ';' FROM sqlite_master WHERE tbl_name NOT IN (#{condition}) ORDER BY tbl_name, type DESC, name"
|
|
54
46
|
else
|
|
55
|
-
args << ".schema"
|
|
47
|
+
args << ".schema --nosys"
|
|
56
48
|
end
|
|
57
|
-
|
|
49
|
+
|
|
50
|
+
run_cmd("sqlite3", *args, out: filename)
|
|
58
51
|
end
|
|
59
52
|
|
|
60
53
|
def structure_load(filename, extra_flags)
|
|
@@ -62,26 +55,22 @@ module ActiveRecord
|
|
|
62
55
|
`sqlite3 #{flags} #{db_config.database} < "#{filename}"`
|
|
63
56
|
end
|
|
64
57
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
58
|
+
def check_current_protected_environment!(db_config, migration_class)
|
|
59
|
+
super
|
|
60
|
+
rescue ActiveRecord::StatementInvalid => e
|
|
61
|
+
case e.cause
|
|
62
|
+
when SQLite3::ReadOnlyException
|
|
63
|
+
else
|
|
64
|
+
raise e
|
|
70
65
|
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
private
|
|
69
|
+
attr_reader :root
|
|
71
70
|
|
|
72
71
|
def establish_connection(config = db_config)
|
|
73
72
|
ActiveRecord::Base.establish_connection(config)
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
def run_cmd(cmd, args, out)
|
|
77
|
-
fail run_cmd_error(cmd, args) unless Kernel.system(cmd, *args, out: out)
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
def run_cmd_error(cmd, args)
|
|
81
|
-
msg = +"failed to execute:\n"
|
|
82
|
-
msg << "#{cmd} #{args.join(' ')}\n\n"
|
|
83
|
-
msg << "Please check the output above for any errors and make sure that `#{cmd}` is installed in your PATH and has proper permissions.\n\n"
|
|
84
|
-
msg
|
|
73
|
+
connection.connect!
|
|
85
74
|
end
|
|
86
75
|
end
|
|
87
76
|
end
|
|
@@ -4,17 +4,27 @@ require "active_support/testing/parallelization"
|
|
|
4
4
|
|
|
5
5
|
module ActiveRecord
|
|
6
6
|
module TestDatabases # :nodoc:
|
|
7
|
+
ActiveSupport::Testing::Parallelization.before_fork_hook do
|
|
8
|
+
if ActiveSupport.parallelize_test_databases
|
|
9
|
+
ActiveRecord::Base.connection_handler.clear_all_connections!
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
7
13
|
ActiveSupport::Testing::Parallelization.after_fork_hook do |i|
|
|
8
|
-
|
|
14
|
+
if ActiveSupport.parallelize_test_databases
|
|
15
|
+
create_and_load_schema(i, env_name: ActiveRecord::ConnectionHandling::DEFAULT_ENV.call)
|
|
16
|
+
end
|
|
9
17
|
end
|
|
10
18
|
|
|
11
19
|
def self.create_and_load_schema(i, env_name:)
|
|
12
20
|
old, ENV["VERBOSE"] = ENV["VERBOSE"], "false"
|
|
13
21
|
|
|
14
|
-
ActiveRecord::Base.configurations.configs_for(env_name: env_name).each do |db_config|
|
|
15
|
-
db_config._database = "#{db_config.database}
|
|
22
|
+
ActiveRecord::Base.configurations.configs_for(env_name: env_name, include_hidden: true).each do |db_config|
|
|
23
|
+
db_config._database = "#{db_config.database}_#{i}"
|
|
16
24
|
|
|
17
|
-
|
|
25
|
+
if db_config.database_tasks?
|
|
26
|
+
ActiveRecord::Tasks::DatabaseTasks.reconstruct_from_schema(db_config, nil)
|
|
27
|
+
end
|
|
18
28
|
end
|
|
19
29
|
ensure
|
|
20
30
|
ActiveRecord::Base.establish_connection
|