activerecord 6.1.7 → 7.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (333) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +616 -1290
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +31 -31
  5. data/examples/performance.rb +2 -2
  6. data/lib/active_record/aggregations.rb +17 -14
  7. data/lib/active_record/association_relation.rb +2 -12
  8. data/lib/active_record/associations/alias_tracker.rb +25 -19
  9. data/lib/active_record/associations/association.rb +60 -21
  10. data/lib/active_record/associations/association_scope.rb +17 -12
  11. data/lib/active_record/associations/belongs_to_association.rb +37 -11
  12. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +13 -4
  13. data/lib/active_record/associations/builder/association.rb +11 -5
  14. data/lib/active_record/associations/builder/belongs_to.rb +41 -14
  15. data/lib/active_record/associations/builder/collection_association.rb +10 -3
  16. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +3 -7
  17. data/lib/active_record/associations/builder/has_many.rb +4 -4
  18. data/lib/active_record/associations/builder/has_one.rb +4 -4
  19. data/lib/active_record/associations/builder/singular_association.rb +6 -2
  20. data/lib/active_record/associations/collection_association.rb +46 -36
  21. data/lib/active_record/associations/collection_proxy.rb +44 -16
  22. data/lib/active_record/associations/disable_joins_association_scope.rb +59 -0
  23. data/lib/active_record/associations/errors.rb +265 -0
  24. data/lib/active_record/associations/foreign_association.rb +10 -3
  25. data/lib/active_record/associations/has_many_association.rb +29 -19
  26. data/lib/active_record/associations/has_many_through_association.rb +19 -8
  27. data/lib/active_record/associations/has_one_association.rb +20 -10
  28. data/lib/active_record/associations/has_one_through_association.rb +1 -1
  29. data/lib/active_record/associations/join_dependency/join_association.rb +30 -27
  30. data/lib/active_record/associations/join_dependency.rb +28 -20
  31. data/lib/active_record/associations/nested_error.rb +47 -0
  32. data/lib/active_record/associations/preloader/association.rb +212 -53
  33. data/lib/active_record/associations/preloader/batch.rb +48 -0
  34. data/lib/active_record/associations/preloader/branch.rb +153 -0
  35. data/lib/active_record/associations/preloader/through_association.rb +50 -16
  36. data/lib/active_record/associations/preloader.rb +50 -121
  37. data/lib/active_record/associations/singular_association.rb +15 -3
  38. data/lib/active_record/associations/through_association.rb +25 -14
  39. data/lib/active_record/associations.rb +429 -522
  40. data/lib/active_record/asynchronous_queries_tracker.rb +60 -0
  41. data/lib/active_record/attribute_assignment.rb +1 -5
  42. data/lib/active_record/attribute_methods/before_type_cast.rb +24 -2
  43. data/lib/active_record/attribute_methods/composite_primary_key.rb +84 -0
  44. data/lib/active_record/attribute_methods/dirty.rb +73 -22
  45. data/lib/active_record/attribute_methods/primary_key.rb +47 -27
  46. data/lib/active_record/attribute_methods/query.rb +31 -19
  47. data/lib/active_record/attribute_methods/read.rb +14 -11
  48. data/lib/active_record/attribute_methods/serialization.rb +174 -37
  49. data/lib/active_record/attribute_methods/time_zone_conversion.rb +15 -9
  50. data/lib/active_record/attribute_methods/write.rb +12 -15
  51. data/lib/active_record/attribute_methods.rb +164 -52
  52. data/lib/active_record/attributes.rb +57 -54
  53. data/lib/active_record/autosave_association.rb +74 -57
  54. data/lib/active_record/base.rb +27 -5
  55. data/lib/active_record/callbacks.rb +19 -35
  56. data/lib/active_record/coders/column_serializer.rb +61 -0
  57. data/lib/active_record/coders/json.rb +1 -1
  58. data/lib/active_record/coders/yaml_column.rb +70 -46
  59. data/lib/active_record/connection_adapters/abstract/connection_handler.rb +284 -0
  60. data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +211 -0
  61. data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +79 -0
  62. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +325 -604
  63. data/lib/active_record/connection_adapters/abstract/database_limits.rb +5 -17
  64. data/lib/active_record/connection_adapters/abstract/database_statements.rb +199 -60
  65. data/lib/active_record/connection_adapters/abstract/query_cache.rb +230 -64
  66. data/lib/active_record/connection_adapters/abstract/quoting.rb +119 -131
  67. data/lib/active_record/connection_adapters/abstract/savepoints.rb +4 -3
  68. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +21 -20
  69. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +186 -31
  70. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +14 -1
  71. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +378 -143
  72. data/lib/active_record/connection_adapters/abstract/transaction.rb +361 -76
  73. data/lib/active_record/connection_adapters/abstract_adapter.rb +624 -163
  74. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +348 -165
  75. data/lib/active_record/connection_adapters/column.rb +13 -0
  76. data/lib/active_record/connection_adapters/mysql/column.rb +1 -0
  77. data/lib/active_record/connection_adapters/mysql/database_statements.rb +29 -130
  78. data/lib/active_record/connection_adapters/mysql/quoting.rb +81 -55
  79. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +9 -0
  80. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +10 -1
  81. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +8 -2
  82. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +45 -14
  83. data/lib/active_record/connection_adapters/mysql2/database_statements.rb +152 -0
  84. data/lib/active_record/connection_adapters/mysql2_adapter.rb +107 -68
  85. data/lib/active_record/connection_adapters/pool_config.rb +26 -16
  86. data/lib/active_record/connection_adapters/pool_manager.rb +19 -9
  87. data/lib/active_record/connection_adapters/postgresql/column.rb +30 -1
  88. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +114 -54
  89. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
  90. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +6 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +8 -0
  92. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +5 -0
  93. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +53 -14
  94. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +1 -1
  95. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -2
  96. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +12 -3
  97. data/lib/active_record/connection_adapters/postgresql/oid/timestamp.rb +15 -0
  98. data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +30 -0
  99. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +18 -6
  100. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +14 -4
  101. data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
  102. data/lib/active_record/connection_adapters/postgresql/quoting.rb +137 -104
  103. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +28 -0
  104. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +92 -2
  105. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +173 -3
  106. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +78 -0
  107. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +403 -77
  108. data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -10
  109. data/lib/active_record/connection_adapters/postgresql_adapter.rb +520 -253
  110. data/lib/active_record/connection_adapters/schema_cache.rb +326 -102
  111. data/lib/active_record/connection_adapters/sqlite3/column.rb +62 -0
  112. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +78 -55
  113. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +68 -54
  114. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +22 -0
  115. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +20 -0
  116. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +16 -0
  117. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +66 -22
  118. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +372 -130
  119. data/lib/active_record/connection_adapters/statement_pool.rb +7 -0
  120. data/lib/active_record/connection_adapters/trilogy/database_statements.rb +99 -0
  121. data/lib/active_record/connection_adapters/trilogy_adapter.rb +229 -0
  122. data/lib/active_record/connection_adapters.rb +130 -6
  123. data/lib/active_record/connection_handling.rb +132 -146
  124. data/lib/active_record/core.rb +310 -253
  125. data/lib/active_record/counter_cache.rb +68 -34
  126. data/lib/active_record/database_configurations/connection_url_resolver.rb +10 -4
  127. data/lib/active_record/database_configurations/database_config.rb +34 -10
  128. data/lib/active_record/database_configurations/hash_config.rb +107 -31
  129. data/lib/active_record/database_configurations/url_config.rb +38 -13
  130. data/lib/active_record/database_configurations.rb +96 -60
  131. data/lib/active_record/delegated_type.rb +90 -20
  132. data/lib/active_record/deprecator.rb +7 -0
  133. data/lib/active_record/destroy_association_async_job.rb +4 -2
  134. data/lib/active_record/disable_joins_association_relation.rb +39 -0
  135. data/lib/active_record/dynamic_matchers.rb +3 -3
  136. data/lib/active_record/encryption/auto_filtered_parameters.rb +66 -0
  137. data/lib/active_record/encryption/cipher/aes256_gcm.rb +101 -0
  138. data/lib/active_record/encryption/cipher.rb +53 -0
  139. data/lib/active_record/encryption/config.rb +68 -0
  140. data/lib/active_record/encryption/configurable.rb +60 -0
  141. data/lib/active_record/encryption/context.rb +42 -0
  142. data/lib/active_record/encryption/contexts.rb +76 -0
  143. data/lib/active_record/encryption/derived_secret_key_provider.rb +18 -0
  144. data/lib/active_record/encryption/deterministic_key_provider.rb +14 -0
  145. data/lib/active_record/encryption/encryptable_record.rb +230 -0
  146. data/lib/active_record/encryption/encrypted_attribute_type.rb +175 -0
  147. data/lib/active_record/encryption/encrypted_fixtures.rb +38 -0
  148. data/lib/active_record/encryption/encrypting_only_encryptor.rb +12 -0
  149. data/lib/active_record/encryption/encryptor.rb +170 -0
  150. data/lib/active_record/encryption/envelope_encryption_key_provider.rb +55 -0
  151. data/lib/active_record/encryption/errors.rb +15 -0
  152. data/lib/active_record/encryption/extended_deterministic_queries.rb +157 -0
  153. data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +28 -0
  154. data/lib/active_record/encryption/key.rb +28 -0
  155. data/lib/active_record/encryption/key_generator.rb +53 -0
  156. data/lib/active_record/encryption/key_provider.rb +46 -0
  157. data/lib/active_record/encryption/message.rb +33 -0
  158. data/lib/active_record/encryption/message_pack_message_serializer.rb +76 -0
  159. data/lib/active_record/encryption/message_serializer.rb +96 -0
  160. data/lib/active_record/encryption/null_encryptor.rb +25 -0
  161. data/lib/active_record/encryption/properties.rb +76 -0
  162. data/lib/active_record/encryption/read_only_null_encryptor.rb +28 -0
  163. data/lib/active_record/encryption/scheme.rb +100 -0
  164. data/lib/active_record/encryption.rb +58 -0
  165. data/lib/active_record/enum.rb +170 -62
  166. data/lib/active_record/errors.rb +210 -27
  167. data/lib/active_record/explain.rb +21 -12
  168. data/lib/active_record/explain_registry.rb +11 -6
  169. data/lib/active_record/explain_subscriber.rb +1 -1
  170. data/lib/active_record/fixture_set/file.rb +15 -1
  171. data/lib/active_record/fixture_set/model_metadata.rb +14 -4
  172. data/lib/active_record/fixture_set/render_context.rb +2 -0
  173. data/lib/active_record/fixture_set/table_row.rb +70 -14
  174. data/lib/active_record/fixture_set/table_rows.rb +4 -4
  175. data/lib/active_record/fixtures.rb +179 -112
  176. data/lib/active_record/future_result.rb +178 -0
  177. data/lib/active_record/gem_version.rb +4 -4
  178. data/lib/active_record/inheritance.rb +85 -31
  179. data/lib/active_record/insert_all.rb +148 -32
  180. data/lib/active_record/integration.rb +14 -10
  181. data/lib/active_record/internal_metadata.rb +123 -23
  182. data/lib/active_record/legacy_yaml_adapter.rb +2 -39
  183. data/lib/active_record/locking/optimistic.rb +43 -27
  184. data/lib/active_record/locking/pessimistic.rb +15 -6
  185. data/lib/active_record/log_subscriber.rb +41 -29
  186. data/lib/active_record/marshalling.rb +59 -0
  187. data/lib/active_record/message_pack.rb +124 -0
  188. data/lib/active_record/middleware/database_selector/resolver.rb +10 -10
  189. data/lib/active_record/middleware/database_selector.rb +23 -13
  190. data/lib/active_record/middleware/shard_selector.rb +62 -0
  191. data/lib/active_record/migration/command_recorder.rb +113 -16
  192. data/lib/active_record/migration/compatibility.rb +235 -46
  193. data/lib/active_record/migration/default_strategy.rb +22 -0
  194. data/lib/active_record/migration/execution_strategy.rb +19 -0
  195. data/lib/active_record/migration/join_table.rb +1 -1
  196. data/lib/active_record/migration/pending_migration_connection.rb +21 -0
  197. data/lib/active_record/migration.rb +374 -177
  198. data/lib/active_record/model_schema.rb +145 -158
  199. data/lib/active_record/nested_attributes.rb +61 -23
  200. data/lib/active_record/no_touching.rb +3 -3
  201. data/lib/active_record/normalization.rb +163 -0
  202. data/lib/active_record/persistence.rb +282 -283
  203. data/lib/active_record/promise.rb +84 -0
  204. data/lib/active_record/query_cache.rb +18 -25
  205. data/lib/active_record/query_logs.rb +189 -0
  206. data/lib/active_record/query_logs_formatter.rb +41 -0
  207. data/lib/active_record/querying.rb +44 -9
  208. data/lib/active_record/railtie.rb +229 -71
  209. data/lib/active_record/railties/controller_runtime.rb +25 -11
  210. data/lib/active_record/railties/databases.rake +189 -256
  211. data/lib/active_record/railties/job_runtime.rb +23 -0
  212. data/lib/active_record/readonly_attributes.rb +41 -3
  213. data/lib/active_record/reflection.rb +332 -103
  214. data/lib/active_record/relation/batches/batch_enumerator.rb +38 -9
  215. data/lib/active_record/relation/batches.rb +200 -65
  216. data/lib/active_record/relation/calculations.rb +301 -112
  217. data/lib/active_record/relation/delegation.rb +33 -22
  218. data/lib/active_record/relation/finder_methods.rb +123 -52
  219. data/lib/active_record/relation/merger.rb +26 -19
  220. data/lib/active_record/relation/predicate_builder/array_handler.rb +2 -2
  221. data/lib/active_record/relation/predicate_builder/association_query_value.rb +38 -4
  222. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +10 -7
  223. data/lib/active_record/relation/predicate_builder/relation_handler.rb +5 -1
  224. data/lib/active_record/relation/predicate_builder.rb +29 -22
  225. data/lib/active_record/relation/query_attribute.rb +30 -12
  226. data/lib/active_record/relation/query_methods.rb +870 -163
  227. data/lib/active_record/relation/record_fetch_warning.rb +10 -9
  228. data/lib/active_record/relation/spawn_methods.rb +7 -6
  229. data/lib/active_record/relation/where_clause.rb +15 -36
  230. data/lib/active_record/relation.rb +736 -145
  231. data/lib/active_record/result.rb +67 -54
  232. data/lib/active_record/runtime_registry.rb +71 -13
  233. data/lib/active_record/sanitization.rb +84 -34
  234. data/lib/active_record/schema.rb +39 -23
  235. data/lib/active_record/schema_dumper.rb +90 -31
  236. data/lib/active_record/schema_migration.rb +74 -23
  237. data/lib/active_record/scoping/default.rb +72 -15
  238. data/lib/active_record/scoping/named.rb +6 -13
  239. data/lib/active_record/scoping.rb +65 -34
  240. data/lib/active_record/secure_password.rb +60 -0
  241. data/lib/active_record/secure_token.rb +21 -3
  242. data/lib/active_record/serialization.rb +6 -1
  243. data/lib/active_record/signed_id.rb +30 -9
  244. data/lib/active_record/statement_cache.rb +7 -7
  245. data/lib/active_record/store.rb +10 -10
  246. data/lib/active_record/suppressor.rb +13 -15
  247. data/lib/active_record/table_metadata.rb +7 -3
  248. data/lib/active_record/tasks/database_tasks.rb +288 -149
  249. data/lib/active_record/tasks/mysql_database_tasks.rb +16 -7
  250. data/lib/active_record/tasks/postgresql_database_tasks.rb +35 -26
  251. data/lib/active_record/tasks/sqlite_database_tasks.rb +16 -7
  252. data/lib/active_record/test_databases.rb +1 -1
  253. data/lib/active_record/test_fixtures.rb +173 -155
  254. data/lib/active_record/testing/query_assertions.rb +121 -0
  255. data/lib/active_record/timestamp.rb +32 -19
  256. data/lib/active_record/token_for.rb +123 -0
  257. data/lib/active_record/touch_later.rb +12 -7
  258. data/lib/active_record/transaction.rb +132 -0
  259. data/lib/active_record/transactions.rb +118 -41
  260. data/lib/active_record/translation.rb +3 -5
  261. data/lib/active_record/type/adapter_specific_registry.rb +32 -14
  262. data/lib/active_record/type/hash_lookup_type_map.rb +34 -1
  263. data/lib/active_record/type/internal/timezone.rb +7 -2
  264. data/lib/active_record/type/serialized.rb +9 -7
  265. data/lib/active_record/type/time.rb +4 -0
  266. data/lib/active_record/type/type_map.rb +17 -20
  267. data/lib/active_record/type.rb +1 -2
  268. data/lib/active_record/type_caster/connection.rb +4 -4
  269. data/lib/active_record/validations/absence.rb +1 -1
  270. data/lib/active_record/validations/associated.rb +13 -7
  271. data/lib/active_record/validations/numericality.rb +5 -4
  272. data/lib/active_record/validations/presence.rb +5 -28
  273. data/lib/active_record/validations/uniqueness.rb +65 -15
  274. data/lib/active_record/validations.rb +12 -5
  275. data/lib/active_record/version.rb +1 -1
  276. data/lib/active_record.rb +444 -32
  277. data/lib/arel/alias_predication.rb +1 -1
  278. data/lib/arel/attributes/attribute.rb +0 -8
  279. data/lib/arel/collectors/bind.rb +2 -0
  280. data/lib/arel/collectors/composite.rb +7 -0
  281. data/lib/arel/collectors/sql_string.rb +1 -1
  282. data/lib/arel/collectors/substitute_binds.rb +1 -1
  283. data/lib/arel/crud.rb +28 -22
  284. data/lib/arel/delete_manager.rb +18 -4
  285. data/lib/arel/errors.rb +10 -0
  286. data/lib/arel/factory_methods.rb +4 -0
  287. data/lib/arel/filter_predications.rb +9 -0
  288. data/lib/arel/insert_manager.rb +2 -3
  289. data/lib/arel/nodes/binary.rb +6 -7
  290. data/lib/arel/nodes/bound_sql_literal.rb +65 -0
  291. data/lib/arel/nodes/casted.rb +1 -1
  292. data/lib/arel/nodes/cte.rb +36 -0
  293. data/lib/arel/nodes/delete_statement.rb +12 -13
  294. data/lib/arel/nodes/filter.rb +10 -0
  295. data/lib/arel/nodes/fragments.rb +35 -0
  296. data/lib/arel/nodes/function.rb +1 -0
  297. data/lib/arel/nodes/homogeneous_in.rb +1 -9
  298. data/lib/arel/nodes/insert_statement.rb +2 -2
  299. data/lib/arel/nodes/leading_join.rb +8 -0
  300. data/lib/arel/nodes/{and.rb → nary.rb} +9 -2
  301. data/lib/arel/nodes/node.rb +115 -5
  302. data/lib/arel/nodes/select_core.rb +2 -2
  303. data/lib/arel/nodes/select_statement.rb +2 -2
  304. data/lib/arel/nodes/sql_literal.rb +13 -0
  305. data/lib/arel/nodes/table_alias.rb +4 -0
  306. data/lib/arel/nodes/update_statement.rb +8 -3
  307. data/lib/arel/nodes.rb +7 -2
  308. data/lib/arel/predications.rb +14 -4
  309. data/lib/arel/select_manager.rb +11 -5
  310. data/lib/arel/table.rb +9 -6
  311. data/lib/arel/tree_manager.rb +8 -15
  312. data/lib/arel/update_manager.rb +20 -5
  313. data/lib/arel/visitors/dot.rb +81 -90
  314. data/lib/arel/visitors/mysql.rb +23 -5
  315. data/lib/arel/visitors/postgresql.rb +1 -22
  316. data/lib/arel/visitors/sqlite.rb +25 -0
  317. data/lib/arel/visitors/to_sql.rb +170 -36
  318. data/lib/arel/visitors/visitor.rb +2 -2
  319. data/lib/arel.rb +23 -4
  320. data/lib/rails/generators/active_record/application_record/USAGE +8 -0
  321. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +1 -1
  322. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +4 -1
  323. data/lib/rails/generators/active_record/migration.rb +3 -1
  324. data/lib/rails/generators/active_record/model/USAGE +113 -0
  325. data/lib/rails/generators/active_record/model/model_generator.rb +15 -6
  326. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +1 -1
  327. data/lib/rails/generators/active_record/model/templates/model.rb.tt +1 -1
  328. data/lib/rails/generators/active_record/model/templates/module.rb.tt +2 -2
  329. data/lib/rails/generators/active_record/multi_db/multi_db_generator.rb +16 -0
  330. data/lib/rails/generators/active_record/multi_db/templates/multi_db.rb.tt +44 -0
  331. metadata +103 -17
  332. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +0 -35
  333. 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
+ pool = ActiveRecord::Tasks::DatabaseTasks.migration_connection_pool
13
+ raise ActiveRecord::EnvironmentStorageError unless pool.internal_metadata.enabled?
14
+
15
+ pool.internal_metadata.create_table_and_set_flags(pool.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 && db_configs.first.primary?
92
93
  ActiveRecord::Tasks::DatabaseTasks.migrate
94
+ else
95
+ mapped_versions = ActiveRecord::Tasks::DatabaseTasks.db_configs_with_versions
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_pool_for_each(env: Rails.env, name: name) do
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_pool.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_pool_for_each(env: Rails.env, name: name) do |pool|
203
+ ActiveRecord::Tasks::DatabaseTasks.check_target_version
204
+ pool.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_pool.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_pool_for_each(env: Rails.env, name: name) do |pool|
234
+ ActiveRecord::Tasks::DatabaseTasks.check_target_version
235
+ pool.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_pool_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_pool_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_pool_for_each(env: Rails.env, name: name) do |pool|
269
+ pool.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_pool.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_pool.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_pool_for_each(env: Rails.env) do |pool|
325
+ puts "\ndatabase: #{pool.db_config.database}\n"
326
+ puts "Current version: #{pool.migration_context.current_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_pool_for_each do |pool|
348
+ pending_migrations << pool.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_pool_for_each(env: Rails.env, name: name) do |pool|
369
+ pending_migrations = pool.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:'}"
340
373
 
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]
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.}
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
385
+ namespace :setup do
386
+ task all: ["db:create", :environment, "db:schema:load", :seed]
364
387
 
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
381
-
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
384
393
 
385
- ActiveRecord::Base.establish_connection
386
- ActiveRecord::Tasks::DatabaseTasks.load_seed if seed
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]
396
+
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_pool_for_each do |pool|
466
+ db_config = 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_pool_for_each(name: name) do |pool|
484
+ db_config = 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,37 +493,32 @@ 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_pool_for_each(name: name) do |pool|
499
+ db_config = 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_pool_for_each do |pool|
511
+ db_config = pool.db_config
512
+ filename = ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename(db_config)
513
+
514
+ ActiveRecord::Tasks::DatabaseTasks.dump_schema_cache(pool, 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
- filename = ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename(
515
- db_config.name,
516
- schema_cache_path: db_config.schema_cache_path,
517
- )
521
+ filename = ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename(db_config)
518
522
  ActiveRecord::Tasks::DatabaseTasks.clear_schema_cache(
519
523
  filename,
520
524
  )
@@ -523,92 +527,31 @@ db_namespace = namespace :db do
523
527
  end
524
528
  end
525
529
 
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
530
+ namespace :encryption do
531
+ desc "Generate a set of keys for configuring Active Record encryption in a given environment"
532
+ task :init do
533
+ puts <<~MSG
534
+ Add this entry to the credentials of the target environment:#{' '}
546
535
 
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.
536
+ active_record_encryption:
537
+ primary_key: #{SecureRandom.alphanumeric(32)}
538
+ deterministic_key: #{SecureRandom.alphanumeric(32)}
539
+ key_derivation_salt: #{SecureRandom.alphanumeric(32)}
551
540
  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
541
  end
581
542
  end
582
543
 
583
544
  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`)"
545
+ # 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
546
  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)
547
+ ActiveRecord::Tasks::DatabaseTasks.with_temporary_pool_for_each(env: "test") do |pool|
548
+ db_config = pool.db_config
549
+ ActiveRecord::Schema.verbose = false
550
+ schema_format = ENV.fetch("SCHEMA_FORMAT", ActiveRecord.schema_format).to_sym
551
+ ActiveRecord::Tasks::DatabaseTasks.load_schema(db_config, schema_format)
600
552
  end
601
553
  end
602
554
 
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
555
  # desc "Empty the test database"
613
556
  task purge: %w(load_config check_protected_environments) do
614
557
  ActiveRecord::Base.configurations.configs_for(env_name: "test").each do |db_config|
@@ -619,56 +562,37 @@ db_namespace = namespace :db do
619
562
  # desc 'Load the test schema'
620
563
  task prepare: :load_config do
621
564
  unless ActiveRecord::Base.configurations.blank?
622
- db_namespace["test:load"].invoke
565
+ db_namespace["test:load_schema"].invoke
623
566
  end
624
567
  end
625
568
 
626
569
  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
570
  # desc "Recreate the #{name} test database from an existent schema.rb file"
635
571
  namespace :load_schema do
636
572
  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)
573
+ ActiveRecord::Tasks::DatabaseTasks.with_temporary_pool_for_each(env: "test", name: name) do |pool|
574
+ db_config = pool.db_config
575
+ ActiveRecord::Schema.verbose = false
576
+ schema_format = ENV.fetch("SCHEMA_FORMAT", ActiveRecord.schema_format).to_sym
577
+ ActiveRecord::Tasks::DatabaseTasks.load_schema(db_config, schema_format)
645
578
  end
646
579
  end
647
580
  end
648
581
 
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
582
  # desc "Empty the #{name} test database"
661
583
  namespace :purge do
662
584
  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)
585
+ ActiveRecord::Tasks::DatabaseTasks.with_temporary_pool_for_each(env: "test", name: name) do |pool|
586
+ db_config = pool.db_config
587
+ ActiveRecord::Tasks::DatabaseTasks.purge(db_config)
588
+ end
665
589
  end
666
590
  end
667
591
 
668
592
  # desc 'Load the #{name} database test schema'
669
593
  namespace :prepare do
670
594
  task name => :load_config do
671
- db_namespace["test:load:#{name}"].invoke
595
+ db_namespace["test:load_schema:#{name}"].invoke
672
596
  end
673
597
  end
674
598
  end
@@ -677,7 +601,7 @@ end
677
601
 
678
602
  namespace :railties do
679
603
  namespace :install do
680
- # desc "Copies missing migrations from Railties (e.g. engines). You can specify Railties to use with FROM=railtie1,railtie2"
604
+ # 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
605
  task migrations: :'db:load_config' do
682
606
  to_load = ENV["FROM"].blank? ? :all : ENV["FROM"].split(",").map(&:strip)
683
607
  railties = {}
@@ -701,7 +625,16 @@ namespace :railties do
701
625
  puts "Copied migration #{migration.basename} from #{name}"
702
626
  end
703
627
 
704
- ActiveRecord::Migration.copy(ActiveRecord::Tasks::DatabaseTasks.migrations_paths.first, railties,
628
+ if ENV["DATABASE"].present? && ENV["DATABASE"] != "primary"
629
+ config = ActiveRecord::Base.configurations.configs_for(name: ENV["DATABASE"])
630
+ raise "Invalid DATABASE provided" if config.blank?
631
+ destination = config.migrations_paths
632
+ raise "#{ENV["DATABASE"]} does not have a custom migration path" if destination.blank?
633
+ else
634
+ destination = ActiveRecord::Tasks::DatabaseTasks.migrations_paths.first
635
+ end
636
+
637
+ ActiveRecord::Migration.copy(destination, railties,
705
638
  on_skip: on_skip, on_copy: on_copy)
706
639
  end
707
640
  end