activerecord 6.1.6 → 7.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (309) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1627 -983
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +18 -18
  5. data/lib/active_record/aggregations.rb +17 -14
  6. data/lib/active_record/association_relation.rb +1 -11
  7. data/lib/active_record/associations/association.rb +50 -19
  8. data/lib/active_record/associations/association_scope.rb +17 -12
  9. data/lib/active_record/associations/belongs_to_association.rb +28 -9
  10. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +10 -2
  11. data/lib/active_record/associations/builder/association.rb +11 -5
  12. data/lib/active_record/associations/builder/belongs_to.rb +40 -14
  13. data/lib/active_record/associations/builder/collection_association.rb +10 -3
  14. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +1 -5
  15. data/lib/active_record/associations/builder/has_many.rb +3 -2
  16. data/lib/active_record/associations/builder/has_one.rb +2 -1
  17. data/lib/active_record/associations/builder/singular_association.rb +6 -2
  18. data/lib/active_record/associations/collection_association.rb +35 -31
  19. data/lib/active_record/associations/collection_proxy.rb +30 -15
  20. data/lib/active_record/associations/disable_joins_association_scope.rb +59 -0
  21. data/lib/active_record/associations/foreign_association.rb +10 -3
  22. data/lib/active_record/associations/has_many_association.rb +28 -18
  23. data/lib/active_record/associations/has_many_through_association.rb +12 -7
  24. data/lib/active_record/associations/has_one_association.rb +20 -10
  25. data/lib/active_record/associations/has_one_through_association.rb +1 -1
  26. data/lib/active_record/associations/join_dependency.rb +26 -16
  27. data/lib/active_record/associations/preloader/association.rb +207 -52
  28. data/lib/active_record/associations/preloader/batch.rb +48 -0
  29. data/lib/active_record/associations/preloader/branch.rb +147 -0
  30. data/lib/active_record/associations/preloader/through_association.rb +50 -14
  31. data/lib/active_record/associations/preloader.rb +50 -121
  32. data/lib/active_record/associations/singular_association.rb +9 -3
  33. data/lib/active_record/associations/through_association.rb +25 -14
  34. data/lib/active_record/associations.rb +439 -305
  35. data/lib/active_record/asynchronous_queries_tracker.rb +60 -0
  36. data/lib/active_record/attribute_assignment.rb +1 -3
  37. data/lib/active_record/attribute_methods/before_type_cast.rb +24 -2
  38. data/lib/active_record/attribute_methods/dirty.rb +73 -22
  39. data/lib/active_record/attribute_methods/primary_key.rb +78 -26
  40. data/lib/active_record/attribute_methods/query.rb +31 -19
  41. data/lib/active_record/attribute_methods/read.rb +25 -10
  42. data/lib/active_record/attribute_methods/serialization.rb +194 -37
  43. data/lib/active_record/attribute_methods/time_zone_conversion.rb +4 -3
  44. data/lib/active_record/attribute_methods/write.rb +10 -13
  45. data/lib/active_record/attribute_methods.rb +121 -40
  46. data/lib/active_record/attributes.rb +27 -38
  47. data/lib/active_record/autosave_association.rb +61 -30
  48. data/lib/active_record/base.rb +25 -2
  49. data/lib/active_record/callbacks.rb +18 -34
  50. data/lib/active_record/coders/column_serializer.rb +61 -0
  51. data/lib/active_record/coders/json.rb +1 -1
  52. data/lib/active_record/coders/yaml_column.rb +70 -34
  53. data/lib/active_record/connection_adapters/abstract/connection_handler.rb +367 -0
  54. data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +211 -0
  55. data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +78 -0
  56. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +96 -590
  57. data/lib/active_record/connection_adapters/abstract/database_limits.rb +5 -17
  58. data/lib/active_record/connection_adapters/abstract/database_statements.rb +172 -50
  59. data/lib/active_record/connection_adapters/abstract/query_cache.rb +77 -27
  60. data/lib/active_record/connection_adapters/abstract/quoting.rb +87 -73
  61. data/lib/active_record/connection_adapters/abstract/savepoints.rb +4 -3
  62. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +21 -20
  63. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +186 -31
  64. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +14 -1
  65. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +360 -138
  66. data/lib/active_record/connection_adapters/abstract/transaction.rb +281 -59
  67. data/lib/active_record/connection_adapters/abstract_adapter.rb +631 -149
  68. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +285 -156
  69. data/lib/active_record/connection_adapters/column.rb +13 -0
  70. data/lib/active_record/connection_adapters/mysql/column.rb +1 -0
  71. data/lib/active_record/connection_adapters/mysql/database_statements.rb +25 -134
  72. data/lib/active_record/connection_adapters/mysql/quoting.rb +56 -25
  73. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +9 -0
  74. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +10 -1
  75. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +8 -2
  76. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +38 -14
  77. data/lib/active_record/connection_adapters/mysql2/database_statements.rb +151 -0
  78. data/lib/active_record/connection_adapters/mysql2_adapter.rb +104 -53
  79. data/lib/active_record/connection_adapters/pool_config.rb +20 -11
  80. data/lib/active_record/connection_adapters/pool_manager.rb +19 -9
  81. data/lib/active_record/connection_adapters/postgresql/column.rb +30 -1
  82. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +89 -52
  83. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
  84. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +8 -0
  85. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +5 -0
  86. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +53 -14
  87. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -2
  88. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +12 -3
  89. data/lib/active_record/connection_adapters/postgresql/oid/timestamp.rb +15 -0
  90. data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +30 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +18 -6
  92. data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
  93. data/lib/active_record/connection_adapters/postgresql/quoting.rb +89 -56
  94. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +28 -0
  95. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +92 -2
  96. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +153 -3
  97. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +78 -0
  98. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +394 -74
  99. data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -10
  100. data/lib/active_record/connection_adapters/postgresql_adapter.rb +509 -247
  101. data/lib/active_record/connection_adapters/schema_cache.rb +319 -90
  102. data/lib/active_record/connection_adapters/sqlite3/column.rb +49 -0
  103. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +72 -53
  104. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +37 -21
  105. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +7 -0
  106. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +43 -22
  107. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +294 -102
  108. data/lib/active_record/connection_adapters/statement_pool.rb +7 -0
  109. data/lib/active_record/connection_adapters/trilogy/database_statements.rb +99 -0
  110. data/lib/active_record/connection_adapters/trilogy_adapter.rb +254 -0
  111. data/lib/active_record/connection_adapters.rb +9 -6
  112. data/lib/active_record/connection_handling.rb +107 -136
  113. data/lib/active_record/core.rb +202 -223
  114. data/lib/active_record/counter_cache.rb +46 -25
  115. data/lib/active_record/database_configurations/connection_url_resolver.rb +2 -1
  116. data/lib/active_record/database_configurations/database_config.rb +21 -12
  117. data/lib/active_record/database_configurations/hash_config.rb +84 -16
  118. data/lib/active_record/database_configurations/url_config.rb +18 -12
  119. data/lib/active_record/database_configurations.rb +95 -59
  120. data/lib/active_record/delegated_type.rb +61 -15
  121. data/lib/active_record/deprecator.rb +7 -0
  122. data/lib/active_record/destroy_association_async_job.rb +3 -1
  123. data/lib/active_record/disable_joins_association_relation.rb +39 -0
  124. data/lib/active_record/dynamic_matchers.rb +1 -1
  125. data/lib/active_record/encryption/auto_filtered_parameters.rb +66 -0
  126. data/lib/active_record/encryption/cipher/aes256_gcm.rb +101 -0
  127. data/lib/active_record/encryption/cipher.rb +53 -0
  128. data/lib/active_record/encryption/config.rb +68 -0
  129. data/lib/active_record/encryption/configurable.rb +60 -0
  130. data/lib/active_record/encryption/context.rb +42 -0
  131. data/lib/active_record/encryption/contexts.rb +76 -0
  132. data/lib/active_record/encryption/derived_secret_key_provider.rb +18 -0
  133. data/lib/active_record/encryption/deterministic_key_provider.rb +14 -0
  134. data/lib/active_record/encryption/encryptable_record.rb +224 -0
  135. data/lib/active_record/encryption/encrypted_attribute_type.rb +151 -0
  136. data/lib/active_record/encryption/encrypted_fixtures.rb +38 -0
  137. data/lib/active_record/encryption/encrypting_only_encryptor.rb +12 -0
  138. data/lib/active_record/encryption/encryptor.rb +155 -0
  139. data/lib/active_record/encryption/envelope_encryption_key_provider.rb +55 -0
  140. data/lib/active_record/encryption/errors.rb +15 -0
  141. data/lib/active_record/encryption/extended_deterministic_queries.rb +157 -0
  142. data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +28 -0
  143. data/lib/active_record/encryption/key.rb +28 -0
  144. data/lib/active_record/encryption/key_generator.rb +53 -0
  145. data/lib/active_record/encryption/key_provider.rb +46 -0
  146. data/lib/active_record/encryption/message.rb +33 -0
  147. data/lib/active_record/encryption/message_serializer.rb +92 -0
  148. data/lib/active_record/encryption/null_encryptor.rb +21 -0
  149. data/lib/active_record/encryption/properties.rb +76 -0
  150. data/lib/active_record/encryption/read_only_null_encryptor.rb +24 -0
  151. data/lib/active_record/encryption/scheme.rb +96 -0
  152. data/lib/active_record/encryption.rb +56 -0
  153. data/lib/active_record/enum.rb +154 -63
  154. data/lib/active_record/errors.rb +171 -15
  155. data/lib/active_record/explain.rb +23 -3
  156. data/lib/active_record/explain_registry.rb +11 -6
  157. data/lib/active_record/explain_subscriber.rb +1 -1
  158. data/lib/active_record/fixture_set/file.rb +15 -1
  159. data/lib/active_record/fixture_set/model_metadata.rb +14 -4
  160. data/lib/active_record/fixture_set/render_context.rb +2 -0
  161. data/lib/active_record/fixture_set/table_row.rb +70 -14
  162. data/lib/active_record/fixture_set/table_rows.rb +4 -4
  163. data/lib/active_record/fixtures.rb +131 -86
  164. data/lib/active_record/future_result.rb +164 -0
  165. data/lib/active_record/gem_version.rb +3 -3
  166. data/lib/active_record/inheritance.rb +81 -29
  167. data/lib/active_record/insert_all.rb +135 -22
  168. data/lib/active_record/integration.rb +11 -10
  169. data/lib/active_record/internal_metadata.rb +119 -33
  170. data/lib/active_record/legacy_yaml_adapter.rb +2 -39
  171. data/lib/active_record/locking/optimistic.rb +36 -21
  172. data/lib/active_record/locking/pessimistic.rb +15 -6
  173. data/lib/active_record/log_subscriber.rb +52 -19
  174. data/lib/active_record/marshalling.rb +56 -0
  175. data/lib/active_record/message_pack.rb +124 -0
  176. data/lib/active_record/middleware/database_selector/resolver.rb +10 -10
  177. data/lib/active_record/middleware/database_selector.rb +23 -13
  178. data/lib/active_record/middleware/shard_selector.rb +62 -0
  179. data/lib/active_record/migration/command_recorder.rb +112 -14
  180. data/lib/active_record/migration/compatibility.rb +221 -48
  181. data/lib/active_record/migration/default_strategy.rb +23 -0
  182. data/lib/active_record/migration/execution_strategy.rb +19 -0
  183. data/lib/active_record/migration/join_table.rb +1 -1
  184. data/lib/active_record/migration/pending_migration_connection.rb +21 -0
  185. data/lib/active_record/migration.rb +358 -171
  186. data/lib/active_record/model_schema.rb +120 -101
  187. data/lib/active_record/nested_attributes.rb +37 -18
  188. data/lib/active_record/no_touching.rb +3 -3
  189. data/lib/active_record/normalization.rb +167 -0
  190. data/lib/active_record/persistence.rb +405 -85
  191. data/lib/active_record/promise.rb +84 -0
  192. data/lib/active_record/query_cache.rb +3 -21
  193. data/lib/active_record/query_logs.rb +174 -0
  194. data/lib/active_record/query_logs_formatter.rb +41 -0
  195. data/lib/active_record/querying.rb +29 -6
  196. data/lib/active_record/railtie.rb +219 -43
  197. data/lib/active_record/railties/controller_runtime.rb +13 -9
  198. data/lib/active_record/railties/databases.rake +188 -252
  199. data/lib/active_record/railties/job_runtime.rb +23 -0
  200. data/lib/active_record/readonly_attributes.rb +41 -3
  201. data/lib/active_record/reflection.rb +241 -80
  202. data/lib/active_record/relation/batches/batch_enumerator.rb +23 -7
  203. data/lib/active_record/relation/batches.rb +192 -63
  204. data/lib/active_record/relation/calculations.rb +219 -90
  205. data/lib/active_record/relation/delegation.rb +27 -13
  206. data/lib/active_record/relation/finder_methods.rb +108 -51
  207. data/lib/active_record/relation/merger.rb +22 -13
  208. data/lib/active_record/relation/predicate_builder/association_query_value.rb +31 -3
  209. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +4 -6
  210. data/lib/active_record/relation/predicate_builder/relation_handler.rb +5 -1
  211. data/lib/active_record/relation/predicate_builder.rb +27 -20
  212. data/lib/active_record/relation/query_attribute.rb +30 -12
  213. data/lib/active_record/relation/query_methods.rb +654 -127
  214. data/lib/active_record/relation/record_fetch_warning.rb +7 -9
  215. data/lib/active_record/relation/spawn_methods.rb +20 -3
  216. data/lib/active_record/relation/where_clause.rb +10 -19
  217. data/lib/active_record/relation.rb +262 -120
  218. data/lib/active_record/result.rb +37 -11
  219. data/lib/active_record/runtime_registry.rb +18 -13
  220. data/lib/active_record/sanitization.rb +65 -20
  221. data/lib/active_record/schema.rb +36 -22
  222. data/lib/active_record/schema_dumper.rb +73 -24
  223. data/lib/active_record/schema_migration.rb +68 -33
  224. data/lib/active_record/scoping/default.rb +72 -15
  225. data/lib/active_record/scoping/named.rb +5 -13
  226. data/lib/active_record/scoping.rb +65 -34
  227. data/lib/active_record/secure_password.rb +60 -0
  228. data/lib/active_record/secure_token.rb +21 -3
  229. data/lib/active_record/serialization.rb +6 -1
  230. data/lib/active_record/signed_id.rb +10 -8
  231. data/lib/active_record/store.rb +16 -11
  232. data/lib/active_record/suppressor.rb +13 -15
  233. data/lib/active_record/table_metadata.rb +16 -3
  234. data/lib/active_record/tasks/database_tasks.rb +225 -136
  235. data/lib/active_record/tasks/mysql_database_tasks.rb +16 -7
  236. data/lib/active_record/tasks/postgresql_database_tasks.rb +35 -26
  237. data/lib/active_record/tasks/sqlite_database_tasks.rb +15 -7
  238. data/lib/active_record/test_databases.rb +1 -1
  239. data/lib/active_record/test_fixtures.rb +123 -99
  240. data/lib/active_record/timestamp.rb +29 -18
  241. data/lib/active_record/token_for.rb +113 -0
  242. data/lib/active_record/touch_later.rb +11 -6
  243. data/lib/active_record/transactions.rb +48 -27
  244. data/lib/active_record/translation.rb +3 -3
  245. data/lib/active_record/type/adapter_specific_registry.rb +32 -14
  246. data/lib/active_record/type/hash_lookup_type_map.rb +34 -1
  247. data/lib/active_record/type/internal/timezone.rb +7 -2
  248. data/lib/active_record/type/serialized.rb +9 -5
  249. data/lib/active_record/type/time.rb +4 -0
  250. data/lib/active_record/type/type_map.rb +17 -20
  251. data/lib/active_record/type.rb +1 -2
  252. data/lib/active_record/validations/absence.rb +1 -1
  253. data/lib/active_record/validations/associated.rb +4 -4
  254. data/lib/active_record/validations/numericality.rb +5 -4
  255. data/lib/active_record/validations/presence.rb +5 -28
  256. data/lib/active_record/validations/uniqueness.rb +51 -6
  257. data/lib/active_record/validations.rb +8 -4
  258. data/lib/active_record/version.rb +1 -1
  259. data/lib/active_record.rb +335 -32
  260. data/lib/arel/attributes/attribute.rb +0 -8
  261. data/lib/arel/crud.rb +28 -22
  262. data/lib/arel/delete_manager.rb +18 -4
  263. data/lib/arel/errors.rb +10 -0
  264. data/lib/arel/factory_methods.rb +4 -0
  265. data/lib/arel/filter_predications.rb +9 -0
  266. data/lib/arel/insert_manager.rb +2 -3
  267. data/lib/arel/nodes/and.rb +4 -0
  268. data/lib/arel/nodes/binary.rb +6 -1
  269. data/lib/arel/nodes/bound_sql_literal.rb +61 -0
  270. data/lib/arel/nodes/casted.rb +1 -1
  271. data/lib/arel/nodes/cte.rb +36 -0
  272. data/lib/arel/nodes/delete_statement.rb +12 -13
  273. data/lib/arel/nodes/filter.rb +10 -0
  274. data/lib/arel/nodes/fragments.rb +35 -0
  275. data/lib/arel/nodes/function.rb +1 -0
  276. data/lib/arel/nodes/homogeneous_in.rb +1 -9
  277. data/lib/arel/nodes/insert_statement.rb +2 -2
  278. data/lib/arel/nodes/leading_join.rb +8 -0
  279. data/lib/arel/nodes/node.rb +111 -2
  280. data/lib/arel/nodes/select_core.rb +2 -2
  281. data/lib/arel/nodes/select_statement.rb +2 -2
  282. data/lib/arel/nodes/sql_literal.rb +6 -0
  283. data/lib/arel/nodes/table_alias.rb +4 -0
  284. data/lib/arel/nodes/update_statement.rb +8 -3
  285. data/lib/arel/nodes.rb +5 -0
  286. data/lib/arel/predications.rb +13 -3
  287. data/lib/arel/select_manager.rb +10 -4
  288. data/lib/arel/table.rb +9 -6
  289. data/lib/arel/tree_manager.rb +0 -12
  290. data/lib/arel/update_manager.rb +18 -4
  291. data/lib/arel/visitors/dot.rb +80 -90
  292. data/lib/arel/visitors/mysql.rb +16 -3
  293. data/lib/arel/visitors/postgresql.rb +0 -10
  294. data/lib/arel/visitors/to_sql.rb +139 -19
  295. data/lib/arel/visitors/visitor.rb +2 -2
  296. data/lib/arel.rb +18 -3
  297. data/lib/rails/generators/active_record/application_record/USAGE +8 -0
  298. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +1 -1
  299. data/lib/rails/generators/active_record/migration.rb +3 -1
  300. data/lib/rails/generators/active_record/model/USAGE +113 -0
  301. data/lib/rails/generators/active_record/model/model_generator.rb +15 -6
  302. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +1 -1
  303. data/lib/rails/generators/active_record/model/templates/model.rb.tt +1 -1
  304. data/lib/rails/generators/active_record/model/templates/module.rb.tt +2 -2
  305. data/lib/rails/generators/active_record/multi_db/multi_db_generator.rb +16 -0
  306. data/lib/rails/generators/active_record/multi_db/templates/multi_db.rb.tt +44 -0
  307. metadata +93 -13
  308. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +0 -35
  309. data/lib/active_record/null_relation.rb +0 -67
@@ -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
@@ -86,19 +87,28 @@ db_namespace = namespace :db do
86
87
 
87
88
  desc "Migrate the database (options: VERSION=x, VERBOSE=false, SCOPE=blog)."
88
89
  task migrate: :load_config do
89
- original_db_config = ActiveRecord::Base.connection_db_config
90
- ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
91
- ActiveRecord::Base.establish_connection(db_config)
90
+ db_configs = ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env)
91
+
92
+ if db_configs.size == 1
92
93
  ActiveRecord::Tasks::DatabaseTasks.migrate
94
+ else
95
+ mapped_versions = ActiveRecord::Tasks::DatabaseTasks.db_configs_with_versions(db_configs)
96
+
97
+ mapped_versions.sort.each do |version, db_configs|
98
+ db_configs.each do |db_config|
99
+ ActiveRecord::Tasks::DatabaseTasks.with_temporary_connection(db_config) do
100
+ ActiveRecord::Tasks::DatabaseTasks.migrate(version)
101
+ end
102
+ end
103
+ end
93
104
  end
105
+
94
106
  db_namespace["_dump"].invoke
95
- ensure
96
- ActiveRecord::Base.establish_connection(original_db_config)
97
107
  end
98
108
 
99
- # IMPORTANT: This task won't dump the schema if ActiveRecord::Base.dump_schema_after_migration is set to false
109
+ # IMPORTANT: This task won't dump the schema if ActiveRecord.dump_schema_after_migration is set to false
100
110
  task :_dump do
101
- if ActiveRecord::Base.dump_schema_after_migration
111
+ if ActiveRecord.dump_schema_after_migration
102
112
  db_namespace["schema:dump"].invoke
103
113
  end
104
114
  # Allow this task to be called as many times as required. An example is the
@@ -108,11 +118,12 @@ db_namespace = namespace :db do
108
118
 
109
119
  namespace :_dump do
110
120
  ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
111
- # IMPORTANT: This task won't dump the schema if ActiveRecord::Base.dump_schema_after_migration is set to false
121
+ # IMPORTANT: This task won't dump the schema if ActiveRecord.dump_schema_after_migration is set to false
112
122
  task name do
113
- if ActiveRecord::Base.dump_schema_after_migration
123
+ if ActiveRecord.dump_schema_after_migration
114
124
  db_namespace["schema:dump:#{name}"].invoke
115
125
  end
126
+
116
127
  # Allow this task to be called as many times as required. An example is the
117
128
  # migrate:redo task, which calls other two internally that depend on this one.
118
129
  db_namespace["_dump:#{name}"].reenable
@@ -124,17 +135,15 @@ db_namespace = namespace :db do
124
135
  ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
125
136
  desc "Migrate #{name} database for current environment"
126
137
  task name => :load_config do
127
- original_db_config = ActiveRecord::Base.connection_db_config
128
- db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, name: name)
129
- ActiveRecord::Base.establish_connection(db_config)
130
- 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
+
131
142
  db_namespace["_dump:#{name}"].invoke
132
- ensure
133
- ActiveRecord::Base.establish_connection(original_db_config)
134
143
  end
135
144
  end
136
145
 
137
- 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)."
138
147
  task redo: :load_config do
139
148
  ActiveRecord::Tasks::DatabaseTasks.raise_for_multi_db(command: "db:migrate:redo")
140
149
 
@@ -151,7 +160,7 @@ db_namespace = namespace :db do
151
160
 
152
161
  namespace :redo do
153
162
  ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
154
- 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)."
155
164
  task name => :load_config do
156
165
  raise "Empty VERSION provided" if ENV["VERSION"] && ENV["VERSION"].empty?
157
166
 
@@ -169,7 +178,7 @@ db_namespace = namespace :db do
169
178
  # desc 'Resets your database using your migrations for the current environment'
170
179
  task reset: ["db:drop", "db:create", "db:migrate"]
171
180
 
172
- desc 'Runs the "up" for a given migration VERSION.'
181
+ desc 'Run the "up" for a given migration VERSION.'
173
182
  task up: :load_config do
174
183
  ActiveRecord::Tasks::DatabaseTasks.raise_for_multi_db(command: "db:migrate:up")
175
184
 
@@ -177,7 +186,7 @@ db_namespace = namespace :db do
177
186
 
178
187
  ActiveRecord::Tasks::DatabaseTasks.check_target_version
179
188
 
180
- ActiveRecord::Base.connection.migration_context.run(
189
+ ActiveRecord::Tasks::DatabaseTasks.migration_connection.migration_context.run(
181
190
  :up,
182
191
  ActiveRecord::Tasks::DatabaseTasks.target_version
183
192
  )
@@ -186,24 +195,21 @@ db_namespace = namespace :db do
186
195
 
187
196
  namespace :up do
188
197
  ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
198
+ desc "Run the \"up\" on #{name} database for a given migration VERSION."
189
199
  task name => :load_config do
190
200
  raise "VERSION is required" if !ENV["VERSION"] || ENV["VERSION"].empty?
191
201
 
192
- db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, name: name)
193
-
194
- ActiveRecord::Base.establish_connection(db_config)
195
- ActiveRecord::Tasks::DatabaseTasks.check_target_version
196
- ActiveRecord::Base.connection.migration_context.run(
197
- :up,
198
- ActiveRecord::Tasks::DatabaseTasks.target_version
199
- )
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
200
206
 
201
- db_namespace["_dump"].invoke
207
+ db_namespace["_dump:#{name}"].invoke
202
208
  end
203
209
  end
204
210
  end
205
211
 
206
- desc 'Runs the "down" for a given migration VERSION.'
212
+ desc 'Run the "down" for a given migration VERSION.'
207
213
  task down: :load_config do
208
214
  ActiveRecord::Tasks::DatabaseTasks.raise_for_multi_db(command: "db:migrate:down")
209
215
 
@@ -211,7 +217,7 @@ db_namespace = namespace :db do
211
217
 
212
218
  ActiveRecord::Tasks::DatabaseTasks.check_target_version
213
219
 
214
- ActiveRecord::Base.connection.migration_context.run(
220
+ ActiveRecord::Tasks::DatabaseTasks.migration_connection.migration_context.run(
215
221
  :down,
216
222
  ActiveRecord::Tasks::DatabaseTasks.target_version
217
223
  )
@@ -220,27 +226,23 @@ db_namespace = namespace :db do
220
226
 
221
227
  namespace :down do
222
228
  ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
229
+ desc "Run the \"down\" on #{name} database for a given migration VERSION."
223
230
  task name => :load_config do
224
231
  raise "VERSION is required" if !ENV["VERSION"] || ENV["VERSION"].empty?
225
232
 
226
- db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, name: name)
227
-
228
- ActiveRecord::Base.establish_connection(db_config)
229
- ActiveRecord::Tasks::DatabaseTasks.check_target_version
230
- ActiveRecord::Base.connection.migration_context.run(
231
- :down,
232
- ActiveRecord::Tasks::DatabaseTasks.target_version
233
- )
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
234
237
 
235
- db_namespace["_dump"].invoke
238
+ db_namespace["_dump:#{name}"].invoke
236
239
  end
237
240
  end
238
241
  end
239
242
 
240
243
  desc "Display status of migrations"
241
244
  task status: :load_config do
242
- ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
243
- ActiveRecord::Base.establish_connection(db_config)
245
+ ActiveRecord::Tasks::DatabaseTasks.with_temporary_connection_for_each do
244
246
  ActiveRecord::Tasks::DatabaseTasks.migrate_status
245
247
  end
246
248
  end
@@ -249,9 +251,9 @@ db_namespace = namespace :db do
249
251
  ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
250
252
  desc "Display status of migrations for #{name} database"
251
253
  task name => :load_config do
252
- db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, name: name)
253
- ActiveRecord::Base.establish_connection(db_config)
254
- 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
255
257
  end
256
258
  end
257
259
  end
@@ -262,23 +264,24 @@ db_namespace = namespace :db do
262
264
  desc "Rollback #{name} database for current environment (specify steps w/ STEP=n)."
263
265
  task name => :load_config do
264
266
  step = ENV["STEP"] ? ENV["STEP"].to_i : 1
265
- db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, name: name)
266
267
 
267
- ActiveRecord::Base.establish_connection(db_config)
268
- 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
269
271
 
270
- db_namespace["_dump"].invoke
272
+ db_namespace["_dump:#{name}"].invoke
271
273
  end
272
274
  end
273
275
  end
274
276
 
275
- 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)."
276
278
  task rollback: :load_config do
277
279
  ActiveRecord::Tasks::DatabaseTasks.raise_for_multi_db(command: "db:rollback")
280
+ raise "VERSION is not supported - To rollback a specific version, use db:migrate:down" if ENV["VERSION"]
278
281
 
279
282
  step = ENV["STEP"] ? ENV["STEP"].to_i : 1
280
283
 
281
- ActiveRecord::Base.connection.migration_context.rollback(step)
284
+ ActiveRecord::Tasks::DatabaseTasks.migration_connection.migration_context.rollback(step)
282
285
 
283
286
  db_namespace["_dump"].invoke
284
287
  end
@@ -286,119 +289,129 @@ db_namespace = namespace :db do
286
289
  # desc 'Pushes the schema to the next version (specify steps w/ STEP=n).'
287
290
  task forward: :load_config do
288
291
  step = ENV["STEP"] ? ENV["STEP"].to_i : 1
289
- ActiveRecord::Base.connection.migration_context.forward(step)
292
+
293
+ ActiveRecord::Tasks::DatabaseTasks.migration_connection.migration_context.forward(step)
294
+
290
295
  db_namespace["_dump"].invoke
291
296
  end
292
297
 
293
- desc "Drops and recreates the database from db/schema.rb for the current environment and loads the seeds."
298
+ namespace :reset do
299
+ task all: ["db:drop", "db:setup"]
300
+
301
+ ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
302
+ desc "Drop and recreate the #{name} database from its schema for the current environment and load the seeds."
303
+ task name => ["db:drop:#{name}", "db:setup:#{name}"]
304
+ end
305
+ end
306
+
307
+ desc "Drop and recreate all databases from their schema for the current environment and load the seeds."
294
308
  task reset: [ "db:drop", "db:setup" ]
295
309
 
296
- # desc "Retrieves the charset for the current environment's database"
310
+ # desc "Retrieve the charset for the current environment's database"
297
311
  task charset: :load_config do
298
312
  puts ActiveRecord::Tasks::DatabaseTasks.charset_current
299
313
  end
300
314
 
301
- # desc "Retrieves the collation for the current environment's database"
315
+ # desc "Retrieve the collation for the current environment's database"
302
316
  task collation: :load_config do
303
317
  puts ActiveRecord::Tasks::DatabaseTasks.collation_current
304
318
  rescue NoMethodError
305
319
  $stderr.puts "Sorry, your database adapter is not supported yet. Feel free to submit a patch."
306
320
  end
307
321
 
308
- desc "Retrieves the current schema version number"
322
+ desc "Retrieve the current schema version number"
309
323
  task version: :load_config do
310
- puts "Current version: #{ActiveRecord::Base.connection.migration_context.current_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
311
341
  end
312
342
 
313
343
  # desc "Raises an error if there are pending migrations"
314
344
  task abort_if_pending_migrations: :load_config do
315
- pending_migrations = ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).flat_map do |db_config|
316
- ActiveRecord::Base.establish_connection(db_config)
345
+ pending_migrations = []
317
346
 
318
- 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
319
349
  end
320
350
 
351
+ pending_migrations = pending_migrations.flatten!
352
+
321
353
  if pending_migrations.any?
322
354
  puts "You have #{pending_migrations.size} pending #{pending_migrations.size > 1 ? 'migrations:' : 'migration:'}"
355
+
323
356
  pending_migrations.each do |pending_migration|
324
357
  puts " %4d %s" % [pending_migration.version, pending_migration.name]
325
358
  end
359
+
326
360
  abort %{Run `bin/rails db:migrate` to update your database then try again.}
327
361
  end
328
- ensure
329
- ActiveRecord::Base.establish_connection(ActiveRecord::Tasks::DatabaseTasks.env.to_sym)
330
362
  end
331
363
 
332
364
  namespace :abort_if_pending_migrations do
333
365
  ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
334
- # 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"
335
367
  task name => :load_config do
336
- db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, name: name)
337
- 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
338
370
 
339
- 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:'}"
373
+
374
+ pending_migrations.each do |pending_migration|
375
+ puts " %4d %s" % [pending_migration.version, pending_migration.name]
376
+ end
340
377
 
341
- if pending_migrations.any?
342
- puts "You have #{pending_migrations.size} pending #{pending_migrations.size > 1 ? 'migrations:' : 'migration:'}"
343
- pending_migrations.each do |pending_migration|
344
- puts " %4d %s" % [pending_migration.version, pending_migration.name]
378
+ abort %{Run `bin/rails db:migrate:#{name}` to update your database then try again.}
345
379
  end
346
- abort %{Run `bin/rails db:migrate:#{name}` to update your database then try again.}
347
380
  end
348
381
  end
349
382
  end
350
383
  end
351
384
 
352
- desc "Creates the database, loads the schema, and initializes with the seed data (use db:reset to also drop the database first)"
353
- task setup: ["db:create", :environment, "db:schema:load", :seed]
354
-
355
- desc "Runs setup if database does not exist, or runs migrations if it does"
356
- task prepare: :load_config do
357
- seed = false
358
-
359
- ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
360
- ActiveRecord::Base.establish_connection(db_config)
361
-
362
- # Skipped when no database
363
- ActiveRecord::Tasks::DatabaseTasks.migrate
364
-
365
- if ActiveRecord::Base.dump_schema_after_migration
366
- ActiveRecord::Tasks::DatabaseTasks.dump_schema(db_config, ActiveRecord::Base.schema_format)
367
- end
368
- rescue ActiveRecord::NoDatabaseError
369
- config_name = db_config.name
370
- ActiveRecord::Tasks::DatabaseTasks.create_current(db_config.env_name, config_name)
371
-
372
- if File.exist?(ActiveRecord::Tasks::DatabaseTasks.dump_filename(config_name))
373
- ActiveRecord::Tasks::DatabaseTasks.load_schema(
374
- db_config,
375
- ActiveRecord::Base.schema_format,
376
- nil
377
- )
378
- else
379
- ActiveRecord::Tasks::DatabaseTasks.migrate
380
- end
385
+ namespace :setup do
386
+ task all: ["db:create", :environment, "db:schema:load", :seed]
381
387
 
382
- seed = true
388
+ ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
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)"
390
+ task name => ["db:create:#{name}", :environment, "db:schema:load:#{name}", "db:seed"]
383
391
  end
392
+ end
393
+
394
+ desc "Create all databases, load all schemas, and initialize with the seed data (use db:reset to also drop all databases first)"
395
+ task setup: ["db:create", :environment, "db:schema:load", :seed]
384
396
 
385
- ActiveRecord::Base.establish_connection
386
- ActiveRecord::Tasks::DatabaseTasks.load_seed if seed
397
+ desc "Run setup if database does not exist, or run migrations if it does"
398
+ task prepare: :load_config do
399
+ ActiveRecord::Tasks::DatabaseTasks.prepare_all
387
400
  end
388
401
 
389
- desc "Loads the seed data from db/seeds.rb"
402
+ desc "Load the seed data from db/seeds.rb"
390
403
  task seed: :load_config do
391
404
  db_namespace["abort_if_pending_migrations"].invoke
392
405
  ActiveRecord::Tasks::DatabaseTasks.load_seed
393
406
  end
394
407
 
395
408
  namespace :seed do
396
- 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"
397
410
  task replant: [:load_config, :truncate_all, :seed]
398
411
  end
399
412
 
400
413
  namespace :fixtures do
401
- 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."
402
415
  task load: :load_config do
403
416
  require "active_record/fixtures"
404
417
 
@@ -447,36 +460,32 @@ db_namespace = namespace :db do
447
460
  end
448
461
 
449
462
  namespace :schema do
450
- 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`)"
451
464
  task dump: :load_config do
452
- ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
453
- ActiveRecord::Base.establish_connection(db_config)
454
- ActiveRecord::Tasks::DatabaseTasks.dump_schema(db_config)
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)
455
469
  end
456
470
 
457
471
  db_namespace["schema:dump"].reenable
458
472
  end
459
473
 
460
- 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"
461
475
  task load: [:load_config, :check_protected_environments] do
462
- ActiveRecord::Tasks::DatabaseTasks.load_schema_current(ActiveRecord::Base.schema_format, ENV["SCHEMA"])
463
- end
464
-
465
- task load_if_ruby: ["db:create", :environment] do
466
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
467
- Using `bin/rails db:schema:load_if_ruby` is deprecated and will be removed in Rails 7.0.
468
- Configure the format using `config.active_record.schema_format = :ruby` to use `schema.rb` and run `bin/rails db:schema:load` instead.
469
- MSG
470
- db_namespace["schema:load"].invoke if ActiveRecord::Base.schema_format == :ruby
476
+ ActiveRecord::Tasks::DatabaseTasks.load_schema_current(ActiveRecord.schema_format, ENV["SCHEMA"])
471
477
  end
472
478
 
473
479
  namespace :dump do
474
480
  ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
475
- 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"
476
482
  task name => :load_config do
477
- db_config = ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env, name: name)
478
- ActiveRecord::Base.establish_connection(db_config)
479
- 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
+
480
489
  db_namespace["schema:dump:#{name}"].reenable
481
490
  end
482
491
  end
@@ -484,31 +493,29 @@ db_namespace = namespace :db do
484
493
 
485
494
  namespace :load do
486
495
  ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
487
- 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"
488
- task name => :load_config do
489
- db_config = ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env, name: name)
490
- ActiveRecord::Tasks::DatabaseTasks.load_schema(db_config, ActiveRecord::Base.schema_format, ENV["SCHEMA"])
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
491
503
  end
492
504
  end
493
505
  end
494
506
 
495
507
  namespace :cache do
496
- desc "Creates a db/schema_cache.yml file."
508
+ desc "Create a db/schema_cache.yml file."
497
509
  task dump: :load_config do
498
- ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
499
- ActiveRecord::Base.establish_connection(db_config)
500
- filename = ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename(
501
- db_config.name,
502
- schema_cache_path: db_config.schema_cache_path,
503
- )
504
- ActiveRecord::Tasks::DatabaseTasks.dump_schema_cache(
505
- ActiveRecord::Base.connection,
506
- filename,
507
- )
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)
508
515
  end
509
516
  end
510
517
 
511
- desc "Clears a db/schema_cache.yml file."
518
+ desc "Clear a db/schema_cache.yml file."
512
519
  task clear: :load_config do
513
520
  ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
514
521
  filename = ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename(
@@ -523,92 +530,31 @@ db_namespace = namespace :db do
523
530
  end
524
531
  end
525
532
 
526
- namespace :structure do
527
- desc "Dumps the database structure to db/structure.sql. Specify another file with SCHEMA=db/my_structure.sql"
528
- task dump: :load_config do
529
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
530
- Using `bin/rails db:structure:dump` is deprecated and will be removed in Rails 7.0.
531
- Configure the format using `config.active_record.schema_format = :sql` to use `structure.sql` and run `bin/rails db:schema:dump` instead.
532
- MSG
533
-
534
- db_namespace["schema:dump"].invoke
535
- db_namespace["structure:dump"].reenable
536
- end
537
-
538
- desc "Recreates the databases from the structure.sql file"
539
- task load: [:load_config, :check_protected_environments] do
540
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
541
- Using `bin/rails db:structure:load` is deprecated and will be removed in Rails 7.0.
542
- Configure the format using `config.active_record.schema_format = :sql` to use `structure.sql` and run `bin/rails db:schema:load` instead.
543
- MSG
544
- db_namespace["schema:load"].invoke
545
- end
533
+ namespace :encryption do
534
+ desc "Generate a set of keys for configuring Active Record encryption in a given environment"
535
+ task :init do
536
+ puts <<~MSG
537
+ Add this entry to the credentials of the target environment:#{' '}
546
538
 
547
- task load_if_sql: ["db:create", :environment] do
548
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
549
- Using `bin/rails db:structure:load_if_sql` is deprecated and will be removed in Rails 7.0.
550
- Configure the format using `config.active_record.schema_format = :sql` to use `structure.sql` and run `bin/rails db:schema:load` instead.
539
+ active_record_encryption:
540
+ primary_key: #{SecureRandom.alphanumeric(32)}
541
+ deterministic_key: #{SecureRandom.alphanumeric(32)}
542
+ key_derivation_salt: #{SecureRandom.alphanumeric(32)}
551
543
  MSG
552
- db_namespace["schema:load"].invoke if ActiveRecord::Base.schema_format == :sql
553
- end
554
-
555
- namespace :dump do
556
- ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
557
- desc "Dumps the #{name} database structure to db/structure.sql. Specify another file with SCHEMA=db/my_structure.sql"
558
- task name => :load_config do
559
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
560
- Using `bin/rails db:structure:dump:#{name}` is deprecated and will be removed in Rails 7.0.
561
- Configure the format using `config.active_record.schema_format = :sql` to use `structure.sql` and run `bin/rails db:schema:dump:#{name}` instead.
562
- MSG
563
- db_namespace["schema:dump:#{name}"].invoke
564
- db_namespace["structure:dump:#{name}"].reenable
565
- end
566
- end
567
- end
568
-
569
- namespace :load do
570
- ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
571
- desc "Recreates the #{name} database from the structure.sql file"
572
- task name => :load_config do
573
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
574
- Using `bin/rails db:structure:load:#{name}` is deprecated and will be removed in Rails 7.0.
575
- Configure the format using `config.active_record.schema_format = :sql` to use `structure.sql` and run `bin/rails db:schema:load:#{name}` instead.
576
- MSG
577
- db_namespace["schema:load:#{name}"].invoke
578
- end
579
- end
580
544
  end
581
545
  end
582
546
 
583
547
  namespace :test do
584
- # desc "Recreate the test database from the current schema"
585
- task load: %w(db:test:purge) do
586
- db_namespace["test:load_schema"].invoke
587
- end
588
-
589
- # 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`)"
590
549
  task load_schema: %w(db:test:purge) do
591
- should_reconnect = ActiveRecord::Base.connection_pool.active_connection?
592
- ActiveRecord::Schema.verbose = false
593
- ActiveRecord::Base.configurations.configs_for(env_name: "test").each do |db_config|
594
- filename = ActiveRecord::Tasks::DatabaseTasks.dump_filename(db_config.name)
595
- ActiveRecord::Tasks::DatabaseTasks.load_schema(db_config, ActiveRecord::Base.schema_format, filename)
596
- end
597
- ensure
598
- if should_reconnect
599
- 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)
600
555
  end
601
556
  end
602
557
 
603
- # desc "Recreate the test database from an existent structure.sql file"
604
- task load_structure: %w(db:test:purge) do
605
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
606
- Using `bin/rails db:test:load_structure` is deprecated and will be removed in Rails 7.0.
607
- Configure the format using `config.active_record.schema_format = :sql` to use `structure.sql` and run `bin/rails db:test:load_schema` instead.
608
- MSG
609
- db_namespace["test:load_schema"].invoke
610
- end
611
-
612
558
  # desc "Empty the test database"
613
559
  task purge: %w(load_config check_protected_environments) do
614
560
  ActiveRecord::Base.configurations.configs_for(env_name: "test").each do |db_config|
@@ -619,56 +565,37 @@ db_namespace = namespace :db do
619
565
  # desc 'Load the test schema'
620
566
  task prepare: :load_config do
621
567
  unless ActiveRecord::Base.configurations.blank?
622
- db_namespace["test:load"].invoke
568
+ db_namespace["test:load_schema"].invoke
623
569
  end
624
570
  end
625
571
 
626
572
  ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
627
- # desc "Recreate the #{name} test database"
628
- namespace :load do
629
- task name => "db:test:purge:#{name}" do
630
- db_namespace["test:load_schema:#{name}"].invoke
631
- end
632
- end
633
-
634
573
  # desc "Recreate the #{name} test database from an existent schema.rb file"
635
574
  namespace :load_schema do
636
575
  task name => "db:test:purge:#{name}" do
637
- should_reconnect = ActiveRecord::Base.connection_pool.active_connection?
638
- ActiveRecord::Schema.verbose = false
639
- filename = ActiveRecord::Tasks::DatabaseTasks.dump_filename(name)
640
- db_config = ActiveRecord::Base.configurations.configs_for(env_name: "test", name: name)
641
- ActiveRecord::Tasks::DatabaseTasks.load_schema(db_config, ActiveRecord::Base.schema_format, filename)
642
- ensure
643
- if should_reconnect
644
- 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)
645
581
  end
646
582
  end
647
583
  end
648
584
 
649
- # desc "Recreate the #{name} test database from an existent structure.sql file"
650
- namespace :load_structure do
651
- task name => "db:test:purge:#{name}" do
652
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
653
- Using `bin/rails db:test:load_structure:#{name}` is deprecated and will be removed in Rails 7.0.
654
- Configure the format using `config.active_record.schema_format = :sql` to use `structure.sql` and run `bin/rails db:test:load_structure:#{name}` instead.
655
- MSG
656
- db_namespace["test:load_schema:#{name}"].invoke
657
- end
658
- end
659
-
660
585
  # desc "Empty the #{name} test database"
661
586
  namespace :purge do
662
587
  task name => %w(load_config check_protected_environments) do
663
- db_config = ActiveRecord::Base.configurations.configs_for(env_name: "test", name: name)
664
- 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
665
592
  end
666
593
  end
667
594
 
668
595
  # desc 'Load the #{name} database test schema'
669
596
  namespace :prepare do
670
597
  task name => :load_config do
671
- db_namespace["test:load:#{name}"].invoke
598
+ db_namespace["test:load_schema:#{name}"].invoke
672
599
  end
673
600
  end
674
601
  end
@@ -677,7 +604,7 @@ end
677
604
 
678
605
  namespace :railties do
679
606
  namespace :install do
680
- # 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."
681
608
  task migrations: :'db:load_config' do
682
609
  to_load = ENV["FROM"].blank? ? :all : ENV["FROM"].split(",").map(&:strip)
683
610
  railties = {}
@@ -701,7 +628,16 @@ namespace :railties do
701
628
  puts "Copied migration #{migration.basename} from #{name}"
702
629
  end
703
630
 
704
- 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,
705
641
  on_skip: on_skip, on_copy: on_copy)
706
642
  end
707
643
  end