activerecord 7.0.0 → 7.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (249) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1607 -1040
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +17 -18
  5. data/lib/active_record/aggregations.rb +16 -13
  6. data/lib/active_record/association_relation.rb +1 -1
  7. data/lib/active_record/associations/association.rb +18 -3
  8. data/lib/active_record/associations/association_scope.rb +16 -9
  9. data/lib/active_record/associations/belongs_to_association.rb +14 -6
  10. data/lib/active_record/associations/builder/association.rb +3 -3
  11. data/lib/active_record/associations/builder/belongs_to.rb +21 -8
  12. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +1 -5
  13. data/lib/active_record/associations/builder/singular_association.rb +4 -0
  14. data/lib/active_record/associations/collection_association.rb +17 -12
  15. data/lib/active_record/associations/collection_proxy.rb +22 -12
  16. data/lib/active_record/associations/foreign_association.rb +10 -3
  17. data/lib/active_record/associations/has_many_association.rb +27 -17
  18. data/lib/active_record/associations/has_many_through_association.rb +10 -6
  19. data/lib/active_record/associations/has_one_association.rb +10 -3
  20. data/lib/active_record/associations/join_dependency.rb +20 -14
  21. data/lib/active_record/associations/preloader/association.rb +27 -6
  22. data/lib/active_record/associations/preloader/through_association.rb +1 -1
  23. data/lib/active_record/associations/preloader.rb +13 -10
  24. data/lib/active_record/associations/singular_association.rb +1 -1
  25. data/lib/active_record/associations/through_association.rb +22 -11
  26. data/lib/active_record/associations.rb +345 -219
  27. data/lib/active_record/attribute_assignment.rb +0 -2
  28. data/lib/active_record/attribute_methods/before_type_cast.rb +17 -0
  29. data/lib/active_record/attribute_methods/dirty.rb +40 -26
  30. data/lib/active_record/attribute_methods/primary_key.rb +76 -24
  31. data/lib/active_record/attribute_methods/query.rb +28 -16
  32. data/lib/active_record/attribute_methods/read.rb +18 -5
  33. data/lib/active_record/attribute_methods/serialization.rb +172 -69
  34. data/lib/active_record/attribute_methods/write.rb +3 -3
  35. data/lib/active_record/attribute_methods.rb +110 -28
  36. data/lib/active_record/attributes.rb +3 -3
  37. data/lib/active_record/autosave_association.rb +56 -10
  38. data/lib/active_record/base.rb +10 -5
  39. data/lib/active_record/callbacks.rb +16 -32
  40. data/lib/active_record/coders/column_serializer.rb +61 -0
  41. data/lib/active_record/coders/json.rb +1 -1
  42. data/lib/active_record/coders/yaml_column.rb +70 -34
  43. data/lib/active_record/connection_adapters/abstract/connection_handler.rb +164 -89
  44. data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +2 -0
  45. data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +3 -1
  46. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +63 -43
  47. data/lib/active_record/connection_adapters/abstract/database_limits.rb +5 -0
  48. data/lib/active_record/connection_adapters/abstract/database_statements.rb +128 -32
  49. data/lib/active_record/connection_adapters/abstract/query_cache.rb +60 -22
  50. data/lib/active_record/connection_adapters/abstract/quoting.rb +52 -8
  51. data/lib/active_record/connection_adapters/abstract/savepoints.rb +4 -3
  52. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +18 -4
  53. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +163 -29
  54. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +14 -1
  55. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +302 -129
  56. data/lib/active_record/connection_adapters/abstract/transaction.rb +287 -58
  57. data/lib/active_record/connection_adapters/abstract_adapter.rb +504 -106
  58. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +217 -104
  59. data/lib/active_record/connection_adapters/column.rb +9 -0
  60. data/lib/active_record/connection_adapters/mysql/column.rb +1 -0
  61. data/lib/active_record/connection_adapters/mysql/database_statements.rb +23 -144
  62. data/lib/active_record/connection_adapters/mysql/quoting.rb +29 -12
  63. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +9 -0
  64. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +10 -1
  65. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +8 -2
  66. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +38 -14
  67. data/lib/active_record/connection_adapters/mysql2/database_statements.rb +148 -0
  68. data/lib/active_record/connection_adapters/mysql2_adapter.rb +98 -53
  69. data/lib/active_record/connection_adapters/pool_config.rb +14 -5
  70. data/lib/active_record/connection_adapters/pool_manager.rb +19 -9
  71. data/lib/active_record/connection_adapters/postgresql/column.rb +3 -2
  72. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +72 -45
  73. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
  74. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +2 -2
  75. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +11 -2
  76. data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +3 -1
  77. data/lib/active_record/connection_adapters/postgresql/quoting.rb +41 -8
  78. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +6 -10
  79. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -6
  80. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +131 -2
  81. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +53 -0
  82. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +358 -57
  83. data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -10
  84. data/lib/active_record/connection_adapters/postgresql_adapter.rb +343 -181
  85. data/lib/active_record/connection_adapters/schema_cache.rb +287 -59
  86. data/lib/active_record/connection_adapters/sqlite3/column.rb +49 -0
  87. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +45 -39
  88. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +22 -5
  89. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +7 -0
  90. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +41 -22
  91. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +242 -81
  92. data/lib/active_record/connection_adapters/statement_pool.rb +7 -0
  93. data/lib/active_record/connection_adapters/trilogy/database_statements.rb +98 -0
  94. data/lib/active_record/connection_adapters/trilogy_adapter.rb +254 -0
  95. data/lib/active_record/connection_adapters.rb +3 -1
  96. data/lib/active_record/connection_handling.rb +73 -96
  97. data/lib/active_record/core.rb +136 -148
  98. data/lib/active_record/counter_cache.rb +46 -25
  99. data/lib/active_record/database_configurations/connection_url_resolver.rb +1 -0
  100. data/lib/active_record/database_configurations/database_config.rb +9 -3
  101. data/lib/active_record/database_configurations/hash_config.rb +22 -12
  102. data/lib/active_record/database_configurations/url_config.rb +17 -11
  103. data/lib/active_record/database_configurations.rb +87 -34
  104. data/lib/active_record/delegated_type.rb +9 -4
  105. data/lib/active_record/deprecator.rb +7 -0
  106. data/lib/active_record/destroy_association_async_job.rb +2 -0
  107. data/lib/active_record/disable_joins_association_relation.rb +1 -1
  108. data/lib/active_record/encryption/auto_filtered_parameters.rb +66 -0
  109. data/lib/active_record/encryption/cipher/aes256_gcm.rb +4 -1
  110. data/lib/active_record/encryption/config.rb +25 -1
  111. data/lib/active_record/encryption/configurable.rb +13 -14
  112. data/lib/active_record/encryption/context.rb +10 -3
  113. data/lib/active_record/encryption/contexts.rb +8 -4
  114. data/lib/active_record/encryption/derived_secret_key_provider.rb +9 -3
  115. data/lib/active_record/encryption/deterministic_key_provider.rb +1 -1
  116. data/lib/active_record/encryption/encryptable_record.rb +38 -22
  117. data/lib/active_record/encryption/encrypted_attribute_type.rb +19 -8
  118. data/lib/active_record/encryption/encryptor.rb +7 -7
  119. data/lib/active_record/encryption/envelope_encryption_key_provider.rb +3 -3
  120. data/lib/active_record/encryption/extended_deterministic_queries.rb +83 -71
  121. data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +3 -3
  122. data/lib/active_record/encryption/key_generator.rb +12 -1
  123. data/lib/active_record/encryption/message.rb +1 -1
  124. data/lib/active_record/encryption/message_serializer.rb +2 -0
  125. data/lib/active_record/encryption/properties.rb +4 -4
  126. data/lib/active_record/encryption/scheme.rb +20 -23
  127. data/lib/active_record/encryption.rb +1 -0
  128. data/lib/active_record/enum.rb +114 -27
  129. data/lib/active_record/errors.rb +108 -15
  130. data/lib/active_record/explain.rb +23 -3
  131. data/lib/active_record/explain_subscriber.rb +1 -1
  132. data/lib/active_record/fixture_set/model_metadata.rb +14 -4
  133. data/lib/active_record/fixture_set/render_context.rb +2 -0
  134. data/lib/active_record/fixture_set/table_row.rb +29 -8
  135. data/lib/active_record/fixtures.rb +121 -73
  136. data/lib/active_record/future_result.rb +30 -5
  137. data/lib/active_record/gem_version.rb +2 -2
  138. data/lib/active_record/inheritance.rb +30 -16
  139. data/lib/active_record/insert_all.rb +55 -8
  140. data/lib/active_record/integration.rb +10 -10
  141. data/lib/active_record/internal_metadata.rb +118 -30
  142. data/lib/active_record/locking/optimistic.rb +32 -18
  143. data/lib/active_record/locking/pessimistic.rb +8 -5
  144. data/lib/active_record/log_subscriber.rb +39 -17
  145. data/lib/active_record/marshalling.rb +56 -0
  146. data/lib/active_record/message_pack.rb +124 -0
  147. data/lib/active_record/middleware/database_selector/resolver.rb +4 -0
  148. data/lib/active_record/middleware/database_selector.rb +18 -13
  149. data/lib/active_record/middleware/shard_selector.rb +7 -5
  150. data/lib/active_record/migration/command_recorder.rb +104 -9
  151. data/lib/active_record/migration/compatibility.rb +158 -64
  152. data/lib/active_record/migration/default_strategy.rb +23 -0
  153. data/lib/active_record/migration/execution_strategy.rb +19 -0
  154. data/lib/active_record/migration.rb +271 -117
  155. data/lib/active_record/model_schema.rb +82 -50
  156. data/lib/active_record/nested_attributes.rb +23 -3
  157. data/lib/active_record/normalization.rb +159 -0
  158. data/lib/active_record/persistence.rb +200 -47
  159. data/lib/active_record/promise.rb +84 -0
  160. data/lib/active_record/query_cache.rb +3 -21
  161. data/lib/active_record/query_logs.rb +87 -51
  162. data/lib/active_record/query_logs_formatter.rb +41 -0
  163. data/lib/active_record/querying.rb +16 -3
  164. data/lib/active_record/railtie.rb +127 -61
  165. data/lib/active_record/railties/controller_runtime.rb +12 -8
  166. data/lib/active_record/railties/databases.rake +142 -143
  167. data/lib/active_record/railties/job_runtime.rb +23 -0
  168. data/lib/active_record/readonly_attributes.rb +32 -5
  169. data/lib/active_record/reflection.rb +177 -45
  170. data/lib/active_record/relation/batches/batch_enumerator.rb +5 -3
  171. data/lib/active_record/relation/batches.rb +190 -61
  172. data/lib/active_record/relation/calculations.rb +200 -83
  173. data/lib/active_record/relation/delegation.rb +23 -9
  174. data/lib/active_record/relation/finder_methods.rb +77 -16
  175. data/lib/active_record/relation/merger.rb +2 -0
  176. data/lib/active_record/relation/predicate_builder/association_query_value.rb +31 -3
  177. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +4 -6
  178. data/lib/active_record/relation/predicate_builder/relation_handler.rb +5 -1
  179. data/lib/active_record/relation/predicate_builder.rb +26 -14
  180. data/lib/active_record/relation/query_attribute.rb +25 -1
  181. data/lib/active_record/relation/query_methods.rb +429 -76
  182. data/lib/active_record/relation/spawn_methods.rb +18 -1
  183. data/lib/active_record/relation.rb +98 -41
  184. data/lib/active_record/result.rb +25 -9
  185. data/lib/active_record/runtime_registry.rb +10 -1
  186. data/lib/active_record/sanitization.rb +57 -16
  187. data/lib/active_record/schema.rb +36 -22
  188. data/lib/active_record/schema_dumper.rb +65 -23
  189. data/lib/active_record/schema_migration.rb +68 -33
  190. data/lib/active_record/scoping/default.rb +20 -12
  191. data/lib/active_record/scoping/named.rb +2 -2
  192. data/lib/active_record/scoping.rb +2 -1
  193. data/lib/active_record/secure_password.rb +60 -0
  194. data/lib/active_record/secure_token.rb +21 -3
  195. data/lib/active_record/serialization.rb +5 -0
  196. data/lib/active_record/signed_id.rb +9 -7
  197. data/lib/active_record/store.rb +16 -11
  198. data/lib/active_record/suppressor.rb +3 -1
  199. data/lib/active_record/table_metadata.rb +16 -3
  200. data/lib/active_record/tasks/database_tasks.rb +138 -107
  201. data/lib/active_record/tasks/mysql_database_tasks.rb +15 -6
  202. data/lib/active_record/tasks/postgresql_database_tasks.rb +17 -15
  203. data/lib/active_record/tasks/sqlite_database_tasks.rb +15 -7
  204. data/lib/active_record/test_fixtures.rb +123 -99
  205. data/lib/active_record/timestamp.rb +26 -14
  206. data/lib/active_record/token_for.rb +113 -0
  207. data/lib/active_record/touch_later.rb +11 -6
  208. data/lib/active_record/transactions.rb +39 -13
  209. data/lib/active_record/translation.rb +1 -1
  210. data/lib/active_record/type/adapter_specific_registry.rb +1 -8
  211. data/lib/active_record/type/internal/timezone.rb +7 -2
  212. data/lib/active_record/type/serialized.rb +8 -4
  213. data/lib/active_record/type/time.rb +4 -0
  214. data/lib/active_record/validations/absence.rb +1 -1
  215. data/lib/active_record/validations/associated.rb +3 -3
  216. data/lib/active_record/validations/numericality.rb +5 -4
  217. data/lib/active_record/validations/presence.rb +5 -28
  218. data/lib/active_record/validations/uniqueness.rb +50 -5
  219. data/lib/active_record/validations.rb +8 -4
  220. data/lib/active_record/version.rb +1 -1
  221. data/lib/active_record.rb +143 -16
  222. data/lib/arel/errors.rb +10 -0
  223. data/lib/arel/factory_methods.rb +4 -0
  224. data/lib/arel/filter_predications.rb +1 -1
  225. data/lib/arel/nodes/and.rb +4 -0
  226. data/lib/arel/nodes/binary.rb +6 -1
  227. data/lib/arel/nodes/bound_sql_literal.rb +61 -0
  228. data/lib/arel/nodes/cte.rb +36 -0
  229. data/lib/arel/nodes/filter.rb +1 -1
  230. data/lib/arel/nodes/fragments.rb +35 -0
  231. data/lib/arel/nodes/homogeneous_in.rb +0 -8
  232. data/lib/arel/nodes/leading_join.rb +8 -0
  233. data/lib/arel/nodes/node.rb +111 -2
  234. data/lib/arel/nodes/sql_literal.rb +6 -0
  235. data/lib/arel/nodes/table_alias.rb +4 -0
  236. data/lib/arel/nodes.rb +4 -0
  237. data/lib/arel/predications.rb +2 -0
  238. data/lib/arel/table.rb +9 -5
  239. data/lib/arel/visitors/mysql.rb +8 -1
  240. data/lib/arel/visitors/to_sql.rb +81 -17
  241. data/lib/arel/visitors/visitor.rb +2 -2
  242. data/lib/arel.rb +16 -2
  243. data/lib/rails/generators/active_record/application_record/USAGE +8 -0
  244. data/lib/rails/generators/active_record/migration.rb +3 -1
  245. data/lib/rails/generators/active_record/model/USAGE +113 -0
  246. data/lib/rails/generators/active_record/model/model_generator.rb +15 -6
  247. metadata +50 -15
  248. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +0 -35
  249. data/lib/active_record/null_relation.rb +0 -63
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "active_support/core_ext/module/attr_internal"
4
- require "active_record/log_subscriber"
4
+ require "active_record/runtime_registry"
5
5
 
6
6
  module ActiveRecord
7
7
  module Railties # :nodoc:
@@ -16,6 +16,11 @@ module ActiveRecord
16
16
  end
17
17
  end
18
18
 
19
+ def initialize(...) # :nodoc:
20
+ super
21
+ self.db_runtime = nil
22
+ end
23
+
19
24
  private
20
25
  attr_internal :db_runtime
21
26
 
@@ -23,16 +28,16 @@ module ActiveRecord
23
28
  # We also need to reset the runtime before each action
24
29
  # because of queries in middleware or in cases we are streaming
25
30
  # and it won't be cleaned up by the method below.
26
- ActiveRecord::LogSubscriber.reset_runtime
31
+ ActiveRecord::RuntimeRegistry.reset
27
32
  super
28
33
  end
29
34
 
30
35
  def cleanup_view_runtime
31
- if logger && logger.info? && ActiveRecord::Base.connected?
32
- db_rt_before_render = ActiveRecord::LogSubscriber.reset_runtime
36
+ if logger && logger.info?
37
+ db_rt_before_render = ActiveRecord::RuntimeRegistry.reset
33
38
  self.db_runtime = (db_runtime || 0) + db_rt_before_render
34
39
  runtime = super
35
- db_rt_after_render = ActiveRecord::LogSubscriber.reset_runtime
40
+ db_rt_after_render = ActiveRecord::RuntimeRegistry.reset
36
41
  self.db_runtime += db_rt_after_render
37
42
  runtime - db_rt_after_render
38
43
  else
@@ -42,9 +47,8 @@ module ActiveRecord
42
47
 
43
48
  def append_info_to_payload(payload)
44
49
  super
45
- if ActiveRecord::Base.connected?
46
- payload[:db_runtime] = (db_runtime || 0) + ActiveRecord::LogSubscriber.reset_runtime
47
- end
50
+
51
+ payload[:db_runtime] = (db_runtime || 0) + ActiveRecord::RuntimeRegistry.reset
48
52
  end
49
53
  end
50
54
  end
@@ -9,9 +9,10 @@ databases = ActiveRecord::Tasks::DatabaseTasks.setup_initial_database_yaml
9
9
  db_namespace = namespace :db do
10
10
  desc "Set the environment value for the database"
11
11
  task "environment:set" => :load_config do
12
- raise ActiveRecord::EnvironmentStorageError unless ActiveRecord::InternalMetadata.enabled?
13
- ActiveRecord::InternalMetadata.create_table
14
- ActiveRecord::InternalMetadata[:environment] = ActiveRecord::Base.connection.migration_context.current_environment
12
+ connection = ActiveRecord::Tasks::DatabaseTasks.migration_connection
13
+ raise ActiveRecord::EnvironmentStorageError unless connection.internal_metadata.enabled?
14
+
15
+ connection.internal_metadata.create_table_and_set_flags(connection.migration_context.current_environment)
15
16
  end
16
17
 
17
18
  task check_protected_environments: :load_config do
@@ -40,7 +41,7 @@ db_namespace = namespace :db do
40
41
  end
41
42
  end
42
43
 
43
- desc "Creates the database from DATABASE_URL or config/database.yml for the current RAILS_ENV (use db:create:all to create all databases in the config). Without RAILS_ENV or when RAILS_ENV is development, it defaults to creating the development and test databases, except when DATABASE_URL is present."
44
+ desc "Create the database from DATABASE_URL or config/database.yml for the current RAILS_ENV (use db:create:all to create all databases in the config). Without RAILS_ENV or when RAILS_ENV is development, it defaults to creating the development and test databases, except when DATABASE_URL is present."
44
45
  task create: [:load_config] do
45
46
  ActiveRecord::Tasks::DatabaseTasks.create_current
46
47
  end
@@ -59,7 +60,7 @@ db_namespace = namespace :db do
59
60
  end
60
61
  end
61
62
 
62
- desc "Drops the database from DATABASE_URL or config/database.yml for the current RAILS_ENV (use db:drop:all to drop all databases in the config). Without RAILS_ENV or when RAILS_ENV is development, it defaults to dropping the development and test databases, except when DATABASE_URL is present."
63
+ desc "Drop the database from DATABASE_URL or config/database.yml for the current RAILS_ENV (use db:drop:all to drop all databases in the config). Without RAILS_ENV or when RAILS_ENV is development, it defaults to dropping the development and test databases, except when DATABASE_URL is present."
63
64
  task drop: [:load_config, :check_protected_environments] do
64
65
  db_namespace["drop:_unsafe"].invoke
65
66
  end
@@ -91,20 +92,18 @@ db_namespace = namespace :db do
91
92
  if db_configs.size == 1
92
93
  ActiveRecord::Tasks::DatabaseTasks.migrate
93
94
  else
94
- original_db_config = ActiveRecord::Base.connection_db_config
95
95
  mapped_versions = ActiveRecord::Tasks::DatabaseTasks.db_configs_with_versions(db_configs)
96
96
 
97
97
  mapped_versions.sort.each do |version, db_configs|
98
98
  db_configs.each do |db_config|
99
- ActiveRecord::Base.establish_connection(db_config)
100
- ActiveRecord::Tasks::DatabaseTasks.migrate(version)
99
+ ActiveRecord::Tasks::DatabaseTasks.with_temporary_connection(db_config) do
100
+ ActiveRecord::Tasks::DatabaseTasks.migrate(version)
101
+ end
101
102
  end
102
103
  end
103
104
  end
104
105
 
105
106
  db_namespace["_dump"].invoke
106
- ensure
107
- ActiveRecord::Base.establish_connection(original_db_config) if original_db_config
108
107
  end
109
108
 
110
109
  # IMPORTANT: This task won't dump the schema if ActiveRecord.dump_schema_after_migration is set to false
@@ -121,10 +120,7 @@ db_namespace = namespace :db do
121
120
  ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
122
121
  # IMPORTANT: This task won't dump the schema if ActiveRecord.dump_schema_after_migration is set to false
123
122
  task name do
124
- db_config = ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env, name: name)
125
-
126
- if ActiveRecord.dump_schema_after_migration && db_config.schema_dump
127
- ActiveRecord::Base.establish_connection(db_config)
123
+ if ActiveRecord.dump_schema_after_migration
128
124
  db_namespace["schema:dump:#{name}"].invoke
129
125
  end
130
126
 
@@ -139,17 +135,15 @@ db_namespace = namespace :db do
139
135
  ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
140
136
  desc "Migrate #{name} database for current environment"
141
137
  task name => :load_config do
142
- original_db_config = ActiveRecord::Base.connection_db_config
143
- db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, name: name)
144
- ActiveRecord::Base.establish_connection(db_config)
145
- ActiveRecord::Tasks::DatabaseTasks.migrate
138
+ ActiveRecord::Tasks::DatabaseTasks.with_temporary_connection_for_each(env: Rails.env, name: name) do |conn|
139
+ ActiveRecord::Tasks::DatabaseTasks.migrate
140
+ end
141
+
146
142
  db_namespace["_dump:#{name}"].invoke
147
- ensure
148
- ActiveRecord::Base.establish_connection(original_db_config)
149
143
  end
150
144
  end
151
145
 
152
- desc "Rolls back the database one migration and re-migrates up (options: STEP=x, VERSION=x)."
146
+ desc "Roll back the database one migration and re-migrate up (options: STEP=x, VERSION=x)."
153
147
  task redo: :load_config do
154
148
  ActiveRecord::Tasks::DatabaseTasks.raise_for_multi_db(command: "db:migrate:redo")
155
149
 
@@ -166,7 +160,7 @@ db_namespace = namespace :db do
166
160
 
167
161
  namespace :redo do
168
162
  ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
169
- desc "Rolls back #{name} database one migration and re-migrates up (options: STEP=x, VERSION=x)."
163
+ desc "Roll back #{name} database one migration and re-migrate up (options: STEP=x, VERSION=x)."
170
164
  task name => :load_config do
171
165
  raise "Empty VERSION provided" if ENV["VERSION"] && ENV["VERSION"].empty?
172
166
 
@@ -184,7 +178,7 @@ db_namespace = namespace :db do
184
178
  # desc 'Resets your database using your migrations for the current environment'
185
179
  task reset: ["db:drop", "db:create", "db:migrate"]
186
180
 
187
- desc 'Runs the "up" for a given migration VERSION.'
181
+ desc 'Run the "up" for a given migration VERSION.'
188
182
  task up: :load_config do
189
183
  ActiveRecord::Tasks::DatabaseTasks.raise_for_multi_db(command: "db:migrate:up")
190
184
 
@@ -192,7 +186,7 @@ db_namespace = namespace :db do
192
186
 
193
187
  ActiveRecord::Tasks::DatabaseTasks.check_target_version
194
188
 
195
- ActiveRecord::Base.connection.migration_context.run(
189
+ ActiveRecord::Tasks::DatabaseTasks.migration_connection.migration_context.run(
196
190
  :up,
197
191
  ActiveRecord::Tasks::DatabaseTasks.target_version
198
192
  )
@@ -201,24 +195,21 @@ db_namespace = namespace :db do
201
195
 
202
196
  namespace :up do
203
197
  ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
198
+ desc 'Run the "up" on #{name} database for a given migration VERSION.'
204
199
  task name => :load_config do
205
200
  raise "VERSION is required" if !ENV["VERSION"] || ENV["VERSION"].empty?
206
201
 
207
- db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, name: name)
208
-
209
- ActiveRecord::Base.establish_connection(db_config)
210
- ActiveRecord::Tasks::DatabaseTasks.check_target_version
211
- ActiveRecord::Base.connection.migration_context.run(
212
- :up,
213
- ActiveRecord::Tasks::DatabaseTasks.target_version
214
- )
202
+ ActiveRecord::Tasks::DatabaseTasks.with_temporary_connection_for_each(env: Rails.env, name: name) do |conn|
203
+ ActiveRecord::Tasks::DatabaseTasks.check_target_version
204
+ conn.migration_context.run(:up, ActiveRecord::Tasks::DatabaseTasks.target_version)
205
+ end
215
206
 
216
207
  db_namespace["_dump"].invoke
217
208
  end
218
209
  end
219
210
  end
220
211
 
221
- desc 'Runs the "down" for a given migration VERSION.'
212
+ desc 'Run the "down" for a given migration VERSION.'
222
213
  task down: :load_config do
223
214
  ActiveRecord::Tasks::DatabaseTasks.raise_for_multi_db(command: "db:migrate:down")
224
215
 
@@ -226,7 +217,7 @@ db_namespace = namespace :db do
226
217
 
227
218
  ActiveRecord::Tasks::DatabaseTasks.check_target_version
228
219
 
229
- ActiveRecord::Base.connection.migration_context.run(
220
+ ActiveRecord::Tasks::DatabaseTasks.migration_connection.migration_context.run(
230
221
  :down,
231
222
  ActiveRecord::Tasks::DatabaseTasks.target_version
232
223
  )
@@ -235,17 +226,14 @@ db_namespace = namespace :db do
235
226
 
236
227
  namespace :down do
237
228
  ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
229
+ desc 'Run the "down" on #{name} database for a given migration VERSION.'
238
230
  task name => :load_config do
239
231
  raise "VERSION is required" if !ENV["VERSION"] || ENV["VERSION"].empty?
240
232
 
241
- db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, name: name)
242
-
243
- ActiveRecord::Base.establish_connection(db_config)
244
- ActiveRecord::Tasks::DatabaseTasks.check_target_version
245
- ActiveRecord::Base.connection.migration_context.run(
246
- :down,
247
- ActiveRecord::Tasks::DatabaseTasks.target_version
248
- )
233
+ ActiveRecord::Tasks::DatabaseTasks.with_temporary_connection_for_each(env: Rails.env, name: name) do |conn|
234
+ ActiveRecord::Tasks::DatabaseTasks.check_target_version
235
+ conn.migration_context.run(:down, ActiveRecord::Tasks::DatabaseTasks.target_version)
236
+ end
249
237
 
250
238
  db_namespace["_dump"].invoke
251
239
  end
@@ -254,8 +242,7 @@ db_namespace = namespace :db do
254
242
 
255
243
  desc "Display status of migrations"
256
244
  task status: :load_config do
257
- ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
258
- ActiveRecord::Base.establish_connection(db_config)
245
+ ActiveRecord::Tasks::DatabaseTasks.with_temporary_connection_for_each do
259
246
  ActiveRecord::Tasks::DatabaseTasks.migrate_status
260
247
  end
261
248
  end
@@ -264,9 +251,9 @@ db_namespace = namespace :db do
264
251
  ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
265
252
  desc "Display status of migrations for #{name} database"
266
253
  task name => :load_config do
267
- db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, name: name)
268
- ActiveRecord::Base.establish_connection(db_config)
269
- ActiveRecord::Tasks::DatabaseTasks.migrate_status
254
+ ActiveRecord::Tasks::DatabaseTasks.with_temporary_connection_for_each(env: Rails.env, name: name) do
255
+ ActiveRecord::Tasks::DatabaseTasks.migrate_status
256
+ end
270
257
  end
271
258
  end
272
259
  end
@@ -277,24 +264,24 @@ db_namespace = namespace :db do
277
264
  desc "Rollback #{name} database for current environment (specify steps w/ STEP=n)."
278
265
  task name => :load_config do
279
266
  step = ENV["STEP"] ? ENV["STEP"].to_i : 1
280
- db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, name: name)
281
267
 
282
- ActiveRecord::Base.establish_connection(db_config)
283
- ActiveRecord::Base.connection.migration_context.rollback(step)
268
+ ActiveRecord::Tasks::DatabaseTasks.with_temporary_connection_for_each(env: Rails.env, name: name) do |conn|
269
+ conn.migration_context.rollback(step)
270
+ end
284
271
 
285
272
  db_namespace["_dump"].invoke
286
273
  end
287
274
  end
288
275
  end
289
276
 
290
- desc "Rolls the schema back to the previous version (specify steps w/ STEP=n)."
277
+ desc "Roll the schema back to the previous version (specify steps w/ STEP=n)."
291
278
  task rollback: :load_config do
292
279
  ActiveRecord::Tasks::DatabaseTasks.raise_for_multi_db(command: "db:rollback")
293
280
  raise "VERSION is not supported - To rollback a specific version, use db:migrate:down" if ENV["VERSION"]
294
281
 
295
282
  step = ENV["STEP"] ? ENV["STEP"].to_i : 1
296
283
 
297
- ActiveRecord::Base.connection.migration_context.rollback(step)
284
+ ActiveRecord::Tasks::DatabaseTasks.migration_connection.migration_context.rollback(step)
298
285
 
299
286
  db_namespace["_dump"].invoke
300
287
  end
@@ -302,7 +289,9 @@ db_namespace = namespace :db do
302
289
  # desc 'Pushes the schema to the next version (specify steps w/ STEP=n).'
303
290
  task forward: :load_config do
304
291
  step = ENV["STEP"] ? ENV["STEP"].to_i : 1
305
- ActiveRecord::Base.connection.migration_context.forward(step)
292
+
293
+ ActiveRecord::Tasks::DatabaseTasks.migration_connection.migration_context.forward(step)
294
+
306
295
  db_namespace["_dump"].invoke
307
296
  end
308
297
 
@@ -310,65 +299,84 @@ db_namespace = namespace :db do
310
299
  task all: ["db:drop", "db:setup"]
311
300
 
312
301
  ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
313
- desc "Drops and recreates the #{name} database from its schema for the current environment and loads the seeds."
302
+ desc "Drop and recreate the #{name} database from its schema for the current environment and load the seeds."
314
303
  task name => ["db:drop:#{name}", "db:setup:#{name}"]
315
304
  end
316
305
  end
317
306
 
318
- desc "Drops and recreates all databases from their schema for the current environment and loads the seeds."
307
+ desc "Drop and recreate all databases from their schema for the current environment and load the seeds."
319
308
  task reset: [ "db:drop", "db:setup" ]
320
309
 
321
- # desc "Retrieves the charset for the current environment's database"
310
+ # desc "Retrieve the charset for the current environment's database"
322
311
  task charset: :load_config do
323
312
  puts ActiveRecord::Tasks::DatabaseTasks.charset_current
324
313
  end
325
314
 
326
- # desc "Retrieves the collation for the current environment's database"
315
+ # desc "Retrieve the collation for the current environment's database"
327
316
  task collation: :load_config do
328
317
  puts ActiveRecord::Tasks::DatabaseTasks.collation_current
329
318
  rescue NoMethodError
330
319
  $stderr.puts "Sorry, your database adapter is not supported yet. Feel free to submit a patch."
331
320
  end
332
321
 
333
- desc "Retrieves the current schema version number"
322
+ desc "Retrieve the current schema version number"
334
323
  task version: :load_config do
335
- puts "Current version: #{ActiveRecord::Base.connection.schema_version}"
324
+ ActiveRecord::Tasks::DatabaseTasks.with_temporary_connection_for_each(env: Rails.env) do |connection|
325
+ puts "\ndatabase: #{connection.pool.db_config.database}\n"
326
+ puts "Current version: #{connection.schema_version}"
327
+ puts
328
+ end
329
+ end
330
+
331
+ namespace :version do
332
+ ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
333
+ desc "Retrieve the current schema version number for #{name} database"
334
+ task name => :load_config do
335
+ db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, name: name)
336
+ ActiveRecord::Tasks::DatabaseTasks.with_temporary_connection(db_config) do |connection|
337
+ puts "Current version: #{connection.schema_version}"
338
+ end
339
+ end
340
+ end
336
341
  end
337
342
 
338
343
  # desc "Raises an error if there are pending migrations"
339
344
  task abort_if_pending_migrations: :load_config do
340
- pending_migrations = ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).flat_map do |db_config|
341
- ActiveRecord::Base.establish_connection(db_config)
345
+ pending_migrations = []
342
346
 
343
- ActiveRecord::Base.connection.migration_context.open.pending_migrations
347
+ ActiveRecord::Tasks::DatabaseTasks.with_temporary_connection_for_each do |conn|
348
+ pending_migrations << conn.migration_context.open.pending_migrations
344
349
  end
345
350
 
351
+ pending_migrations = pending_migrations.flatten!
352
+
346
353
  if pending_migrations.any?
347
354
  puts "You have #{pending_migrations.size} pending #{pending_migrations.size > 1 ? 'migrations:' : 'migration:'}"
355
+
348
356
  pending_migrations.each do |pending_migration|
349
357
  puts " %4d %s" % [pending_migration.version, pending_migration.name]
350
358
  end
359
+
351
360
  abort %{Run `bin/rails db:migrate` to update your database then try again.}
352
361
  end
353
- ensure
354
- ActiveRecord::Base.establish_connection(ActiveRecord::Tasks::DatabaseTasks.env.to_sym)
355
362
  end
356
363
 
357
364
  namespace :abort_if_pending_migrations do
358
365
  ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
359
- # desc "Raises an error if there are pending migrations for #{name} database"
366
+ # desc "Raise an error if there are pending migrations for #{name} database"
360
367
  task name => :load_config do
361
- db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, name: name)
362
- ActiveRecord::Base.establish_connection(db_config)
368
+ ActiveRecord::Tasks::DatabaseTasks.with_temporary_connection_for_each(env: Rails.env, name: name) do |conn|
369
+ pending_migrations = conn.migration_context.open.pending_migrations
363
370
 
364
- pending_migrations = ActiveRecord::Base.connection.migration_context.open.pending_migrations
371
+ if pending_migrations.any?
372
+ puts "You have #{pending_migrations.size} pending #{pending_migrations.size > 1 ? 'migrations:' : 'migration:'}"
365
373
 
366
- if pending_migrations.any?
367
- puts "You have #{pending_migrations.size} pending #{pending_migrations.size > 1 ? 'migrations:' : 'migration:'}"
368
- pending_migrations.each do |pending_migration|
369
- puts " %4d %s" % [pending_migration.version, pending_migration.name]
374
+ pending_migrations.each do |pending_migration|
375
+ puts " %4d %s" % [pending_migration.version, pending_migration.name]
376
+ end
377
+
378
+ abort %{Run `bin/rails db:migrate:#{name}` to update your database then try again.}
370
379
  end
371
- abort %{Run `bin/rails db:migrate:#{name}` to update your database then try again.}
372
380
  end
373
381
  end
374
382
  end
@@ -378,32 +386,32 @@ db_namespace = namespace :db do
378
386
  task all: ["db:create", :environment, "db:schema:load", :seed]
379
387
 
380
388
  ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
381
- desc "Creates the #{name} database, loads the schema, and initializes with the seed data (use db:reset:#{name} to also drop the database first)"
389
+ desc "Create the #{name} database, load the schema, and initialize with the seed data (use db:reset:#{name} to also drop the database first)"
382
390
  task name => ["db:create:#{name}", :environment, "db:schema:load:#{name}", "db:seed"]
383
391
  end
384
392
  end
385
393
 
386
- desc "Creates all databases, loads all schemas, and initializes with the seed data (use db:reset to also drop all databases first)"
394
+ desc "Create all databases, load all schemas, and initialize with the seed data (use db:reset to also drop all databases first)"
387
395
  task setup: ["db:create", :environment, "db:schema:load", :seed]
388
396
 
389
- desc "Runs setup if database does not exist, or runs migrations if it does"
397
+ desc "Run setup if database does not exist, or run migrations if it does"
390
398
  task prepare: :load_config do
391
399
  ActiveRecord::Tasks::DatabaseTasks.prepare_all
392
400
  end
393
401
 
394
- desc "Loads the seed data from db/seeds.rb"
402
+ desc "Load the seed data from db/seeds.rb"
395
403
  task seed: :load_config do
396
404
  db_namespace["abort_if_pending_migrations"].invoke
397
405
  ActiveRecord::Tasks::DatabaseTasks.load_seed
398
406
  end
399
407
 
400
408
  namespace :seed do
401
- desc "Truncates tables of each database for current environment and loads the seeds"
409
+ desc "Truncate tables of each database for current environment and load the seeds"
402
410
  task replant: [:load_config, :truncate_all, :seed]
403
411
  end
404
412
 
405
413
  namespace :fixtures do
406
- desc "Loads fixtures into the current environment's database. Load specific fixtures using FIXTURES=x,y. Load from subdirectory in test/fixtures using FIXTURES_DIR=z. Specify an alternative path (e.g. spec/fixtures) using FIXTURES_PATH=spec/fixtures."
414
+ desc "Load fixtures into the current environment's database. To load specific fixtures, use FIXTURES=x,y. To load from subdirectory in test/fixtures, use FIXTURES_DIR=z. To specify an alternative path (e.g. spec/fixtures), use FIXTURES_PATH=spec/fixtures."
407
415
  task load: :load_config do
408
416
  require "active_record/fixtures"
409
417
 
@@ -452,30 +460,32 @@ db_namespace = namespace :db do
452
460
  end
453
461
 
454
462
  namespace :schema do
455
- desc "Creates a database schema file (either db/schema.rb or db/structure.sql, depending on `config.active_record.schema_format`)"
463
+ desc "Create a database schema file (either db/schema.rb or db/structure.sql, depending on `ENV['SCHEMA_FORMAT']` or `config.active_record.schema_format`)"
456
464
  task dump: :load_config do
457
- ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
458
- if db_config.schema_dump
459
- ActiveRecord::Base.establish_connection(db_config)
460
- ActiveRecord::Tasks::DatabaseTasks.dump_schema(db_config)
461
- end
465
+ ActiveRecord::Tasks::DatabaseTasks.with_temporary_connection_for_each do |conn|
466
+ db_config = conn.pool.db_config
467
+ schema_format = ENV.fetch("SCHEMA_FORMAT", ActiveRecord.schema_format).to_sym
468
+ ActiveRecord::Tasks::DatabaseTasks.dump_schema(db_config, schema_format)
462
469
  end
463
470
 
464
471
  db_namespace["schema:dump"].reenable
465
472
  end
466
473
 
467
- desc "Loads a database schema file (either db/schema.rb or db/structure.sql, depending on `config.active_record.schema_format`) into the database"
474
+ desc "Load a database schema file (either db/schema.rb or db/structure.sql, depending on `ENV['SCHEMA_FORMAT']` or `config.active_record.schema_format`) into the database"
468
475
  task load: [:load_config, :check_protected_environments] do
469
476
  ActiveRecord::Tasks::DatabaseTasks.load_schema_current(ActiveRecord.schema_format, ENV["SCHEMA"])
470
477
  end
471
478
 
472
479
  namespace :dump do
473
480
  ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
474
- desc "Creates a database schema file (either db/schema.rb or db/structure.sql, depending on `config.active_record.schema_format`) for #{name} database"
481
+ desc "Create a database schema file (either db/schema.rb or db/structure.sql, depending on `ENV['SCHEMA_FORMAT']` or `config.active_record.schema_format`) for #{name} database"
475
482
  task name => :load_config do
476
- db_config = ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env, name: name)
477
- ActiveRecord::Base.establish_connection(db_config)
478
- ActiveRecord::Tasks::DatabaseTasks.dump_schema(db_config)
483
+ ActiveRecord::Tasks::DatabaseTasks.with_temporary_connection_for_each(name: name) do |conn|
484
+ db_config = conn.pool.db_config
485
+ schema_format = ENV.fetch("SCHEMA_FORMAT", ActiveRecord.schema_format).to_sym
486
+ ActiveRecord::Tasks::DatabaseTasks.dump_schema(db_config, schema_format)
487
+ end
488
+
479
489
  db_namespace["schema:dump:#{name}"].reenable
480
490
  end
481
491
  end
@@ -483,34 +493,29 @@ db_namespace = namespace :db do
483
493
 
484
494
  namespace :load do
485
495
  ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
486
- desc "Loads a database schema file (either db/schema.rb or db/structure.sql, depending on `config.active_record.schema_format`) into the #{name} database"
487
- task name => :load_config do
488
- original_db_config = ActiveRecord::Base.connection_db_config
489
- db_config = ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env, name: name)
490
- ActiveRecord::Tasks::DatabaseTasks.load_schema(db_config)
491
- ensure
492
- ActiveRecord::Base.establish_connection(original_db_config) if original_db_config
496
+ desc "Load a database schema file (either db/schema.rb or db/structure.sql, depending on `ENV['SCHEMA_FORMAT']` or `config.active_record.schema_format`) into the #{name} database"
497
+ task name => "db:test:purge:#{name}" do
498
+ ActiveRecord::Tasks::DatabaseTasks.with_temporary_connection_for_each(name: name) do |conn|
499
+ db_config = conn.pool.db_config
500
+ schema_format = ENV.fetch("SCHEMA_FORMAT", ActiveRecord.schema_format).to_sym
501
+ ActiveRecord::Tasks::DatabaseTasks.load_schema(db_config, schema_format)
502
+ end
493
503
  end
494
504
  end
495
505
  end
496
506
 
497
507
  namespace :cache do
498
- desc "Creates a db/schema_cache.yml file."
508
+ desc "Create a db/schema_cache.yml file."
499
509
  task dump: :load_config do
500
- ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
501
- ActiveRecord::Base.establish_connection(db_config)
502
- filename = ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename(
503
- db_config.name,
504
- schema_cache_path: db_config.schema_cache_path,
505
- )
506
- ActiveRecord::Tasks::DatabaseTasks.dump_schema_cache(
507
- ActiveRecord::Base.connection,
508
- filename,
509
- )
510
+ ActiveRecord::Tasks::DatabaseTasks.with_temporary_connection_for_each do |conn|
511
+ db_config = conn.pool.db_config
512
+ filename = ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename(db_config.name, schema_cache_path: db_config.schema_cache_path)
513
+
514
+ ActiveRecord::Tasks::DatabaseTasks.dump_schema_cache(conn, filename)
510
515
  end
511
516
  end
512
517
 
513
- desc "Clears a db/schema_cache.yml file."
518
+ desc "Clear a db/schema_cache.yml file."
514
519
  task clear: :load_config do
515
520
  ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
516
521
  filename = ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename(
@@ -540,21 +545,13 @@ db_namespace = namespace :db do
540
545
  end
541
546
 
542
547
  namespace :test do
543
- # desc "Recreate the test database from the current schema"
544
- task load: %w(db:test:purge) do
545
- db_namespace["test:load_schema"].invoke
546
- end
547
-
548
- # desc "Recreate the test database from an existent schema file (schema.rb or structure.sql, depending on `config.active_record.schema_format`)"
548
+ # desc "Recreate the test database from an existent schema file (schema.rb or structure.sql, depending on `ENV['SCHEMA_FORMAT']` or `config.active_record.schema_format`)"
549
549
  task load_schema: %w(db:test:purge) do
550
- should_reconnect = ActiveRecord::Base.connection_pool.active_connection?
551
- ActiveRecord::Schema.verbose = false
552
- ActiveRecord::Base.configurations.configs_for(env_name: "test").each do |db_config|
553
- ActiveRecord::Tasks::DatabaseTasks.load_schema(db_config)
554
- end
555
- ensure
556
- if should_reconnect
557
- ActiveRecord::Base.establish_connection(ActiveRecord::Tasks::DatabaseTasks.env.to_sym)
550
+ ActiveRecord::Tasks::DatabaseTasks.with_temporary_connection_for_each(env: "test") do |conn|
551
+ db_config = conn.pool.db_config
552
+ ActiveRecord::Schema.verbose = false
553
+ schema_format = ENV.fetch("SCHEMA_FORMAT", ActiveRecord.schema_format).to_sym
554
+ ActiveRecord::Tasks::DatabaseTasks.load_schema(db_config, schema_format)
558
555
  end
559
556
  end
560
557
 
@@ -568,28 +565,19 @@ db_namespace = namespace :db do
568
565
  # desc 'Load the test schema'
569
566
  task prepare: :load_config do
570
567
  unless ActiveRecord::Base.configurations.blank?
571
- db_namespace["test:load"].invoke
568
+ db_namespace["test:load_schema"].invoke
572
569
  end
573
570
  end
574
571
 
575
572
  ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
576
- # desc "Recreate the #{name} test database"
577
- namespace :load do
578
- task name => "db:test:purge:#{name}" do
579
- db_namespace["test:load_schema:#{name}"].invoke
580
- end
581
- end
582
-
583
573
  # desc "Recreate the #{name} test database from an existent schema.rb file"
584
574
  namespace :load_schema do
585
575
  task name => "db:test:purge:#{name}" do
586
- should_reconnect = ActiveRecord::Base.connection_pool.active_connection?
587
- ActiveRecord::Schema.verbose = false
588
- db_config = ActiveRecord::Base.configurations.configs_for(env_name: "test", name: name)
589
- ActiveRecord::Tasks::DatabaseTasks.load_schema(db_config)
590
- ensure
591
- if should_reconnect
592
- ActiveRecord::Base.establish_connection(ActiveRecord::Tasks::DatabaseTasks.env.to_sym)
576
+ ActiveRecord::Tasks::DatabaseTasks.with_temporary_connection_for_each(env: "test", name: name) do |conn|
577
+ db_config = conn.pool.db_config
578
+ ActiveRecord::Schema.verbose = false
579
+ schema_format = ENV.fetch("SCHEMA_FORMAT", ActiveRecord.schema_format).to_sym
580
+ ActiveRecord::Tasks::DatabaseTasks.load_schema(db_config, schema_format)
593
581
  end
594
582
  end
595
583
  end
@@ -597,15 +585,17 @@ db_namespace = namespace :db do
597
585
  # desc "Empty the #{name} test database"
598
586
  namespace :purge do
599
587
  task name => %w(load_config check_protected_environments) do
600
- db_config = ActiveRecord::Base.configurations.configs_for(env_name: "test", name: name)
601
- ActiveRecord::Tasks::DatabaseTasks.purge(db_config)
588
+ ActiveRecord::Tasks::DatabaseTasks.with_temporary_connection_for_each(env: "test", name: name) do |conn|
589
+ db_config = conn.pool.db_config
590
+ ActiveRecord::Tasks::DatabaseTasks.purge(db_config)
591
+ end
602
592
  end
603
593
  end
604
594
 
605
595
  # desc 'Load the #{name} database test schema'
606
596
  namespace :prepare do
607
597
  task name => :load_config do
608
- db_namespace["test:load:#{name}"].invoke
598
+ db_namespace["test:load_schema:#{name}"].invoke
609
599
  end
610
600
  end
611
601
  end
@@ -614,7 +604,7 @@ end
614
604
 
615
605
  namespace :railties do
616
606
  namespace :install do
617
- # desc "Copies missing migrations from Railties (e.g. engines). You can specify Railties to use with FROM=railtie1,railtie2"
607
+ # desc "Copy missing migrations from Railties (e.g. engines). You can specify Railties to use with FROM=railtie1,railtie2 and database to copy to with DATABASE=database."
618
608
  task migrations: :'db:load_config' do
619
609
  to_load = ENV["FROM"].blank? ? :all : ENV["FROM"].split(",").map(&:strip)
620
610
  railties = {}
@@ -638,7 +628,16 @@ namespace :railties do
638
628
  puts "Copied migration #{migration.basename} from #{name}"
639
629
  end
640
630
 
641
- ActiveRecord::Migration.copy(ActiveRecord::Tasks::DatabaseTasks.migrations_paths.first, railties,
631
+ if ENV["DATABASE"].present? && ENV["DATABASE"] != "primary"
632
+ config = ActiveRecord::Base.configurations.configs_for(name: ENV["DATABASE"])
633
+ raise "Invalid DATABASE provided" if config.blank?
634
+ destination = config.migrations_paths
635
+ raise "#{ENV["DATABASE"]} does not have a custom migration path" if destination.blank?
636
+ else
637
+ destination = ActiveRecord::Tasks::DatabaseTasks.migrations_paths.first
638
+ end
639
+
640
+ ActiveRecord::Migration.copy(destination, railties,
642
641
  on_skip: on_skip, on_copy: on_copy)
643
642
  end
644
643
  end