activerecord 5.2.8 → 7.0.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activerecord might be problematic. Click here for more details.

Files changed (364) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1393 -587
  3. data/MIT-LICENSE +3 -1
  4. data/README.rdoc +7 -5
  5. data/examples/performance.rb +1 -1
  6. data/lib/active_record/aggregations.rb +10 -9
  7. data/lib/active_record/association_relation.rb +22 -12
  8. data/lib/active_record/associations/alias_tracker.rb +19 -16
  9. data/lib/active_record/associations/association.rb +122 -47
  10. data/lib/active_record/associations/association_scope.rb +24 -24
  11. data/lib/active_record/associations/belongs_to_association.rb +67 -49
  12. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +16 -7
  13. data/lib/active_record/associations/builder/association.rb +52 -23
  14. data/lib/active_record/associations/builder/belongs_to.rb +44 -61
  15. data/lib/active_record/associations/builder/collection_association.rb +17 -19
  16. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +17 -41
  17. data/lib/active_record/associations/builder/has_many.rb +10 -3
  18. data/lib/active_record/associations/builder/has_one.rb +35 -3
  19. data/lib/active_record/associations/builder/singular_association.rb +5 -3
  20. data/lib/active_record/associations/collection_association.rb +59 -50
  21. data/lib/active_record/associations/collection_proxy.rb +32 -23
  22. data/lib/active_record/associations/disable_joins_association_scope.rb +59 -0
  23. data/lib/active_record/associations/foreign_association.rb +20 -0
  24. data/lib/active_record/associations/has_many_association.rb +27 -14
  25. data/lib/active_record/associations/has_many_through_association.rb +26 -19
  26. data/lib/active_record/associations/has_one_association.rb +52 -37
  27. data/lib/active_record/associations/has_one_through_association.rb +6 -6
  28. data/lib/active_record/associations/join_dependency/join_association.rb +44 -22
  29. data/lib/active_record/associations/join_dependency/join_part.rb +5 -5
  30. data/lib/active_record/associations/join_dependency.rb +97 -62
  31. data/lib/active_record/associations/preloader/association.rb +220 -60
  32. data/lib/active_record/associations/preloader/batch.rb +48 -0
  33. data/lib/active_record/associations/preloader/branch.rb +147 -0
  34. data/lib/active_record/associations/preloader/through_association.rb +85 -40
  35. data/lib/active_record/associations/preloader.rb +44 -105
  36. data/lib/active_record/associations/singular_association.rb +9 -17
  37. data/lib/active_record/associations/through_association.rb +4 -4
  38. data/lib/active_record/associations.rb +207 -66
  39. data/lib/active_record/asynchronous_queries_tracker.rb +60 -0
  40. data/lib/active_record/attribute_assignment.rb +17 -19
  41. data/lib/active_record/attribute_methods/before_type_cast.rb +19 -8
  42. data/lib/active_record/attribute_methods/dirty.rb +141 -47
  43. data/lib/active_record/attribute_methods/primary_key.rb +22 -27
  44. data/lib/active_record/attribute_methods/query.rb +6 -10
  45. data/lib/active_record/attribute_methods/read.rb +15 -55
  46. data/lib/active_record/attribute_methods/serialization.rb +77 -18
  47. data/lib/active_record/attribute_methods/time_zone_conversion.rb +16 -18
  48. data/lib/active_record/attribute_methods/write.rb +18 -37
  49. data/lib/active_record/attribute_methods.rb +90 -153
  50. data/lib/active_record/attributes.rb +38 -12
  51. data/lib/active_record/autosave_association.rb +50 -50
  52. data/lib/active_record/base.rb +23 -18
  53. data/lib/active_record/callbacks.rb +159 -44
  54. data/lib/active_record/coders/yaml_column.rb +12 -3
  55. data/lib/active_record/connection_adapters/abstract/connection_handler.rb +292 -0
  56. data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +209 -0
  57. data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +76 -0
  58. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +92 -464
  59. data/lib/active_record/connection_adapters/abstract/database_limits.rb +5 -51
  60. data/lib/active_record/connection_adapters/abstract/database_statements.rb +209 -164
  61. data/lib/active_record/connection_adapters/abstract/query_cache.rb +38 -22
  62. data/lib/active_record/connection_adapters/abstract/quoting.rb +103 -82
  63. data/lib/active_record/connection_adapters/abstract/savepoints.rb +3 -3
  64. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +140 -110
  65. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +236 -94
  66. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +16 -5
  67. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +456 -159
  68. data/lib/active_record/connection_adapters/abstract/transaction.rb +169 -78
  69. data/lib/active_record/connection_adapters/abstract_adapter.rb +367 -162
  70. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +311 -327
  71. data/lib/active_record/connection_adapters/column.rb +33 -11
  72. data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
  73. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +35 -0
  74. data/lib/active_record/connection_adapters/mysql/column.rb +1 -1
  75. data/lib/active_record/connection_adapters/mysql/database_statements.rb +113 -45
  76. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +1 -2
  77. data/lib/active_record/connection_adapters/mysql/quoting.rb +71 -5
  78. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +34 -10
  79. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +48 -32
  80. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +25 -8
  81. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +143 -19
  82. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +14 -9
  83. data/lib/active_record/connection_adapters/mysql2_adapter.rb +63 -22
  84. data/lib/active_record/connection_adapters/pool_config.rb +73 -0
  85. data/lib/active_record/connection_adapters/pool_manager.rb +47 -0
  86. data/lib/active_record/connection_adapters/postgresql/column.rb +53 -28
  87. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +56 -63
  88. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -2
  89. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +1 -4
  90. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -5
  91. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +10 -2
  92. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +15 -2
  93. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +0 -1
  94. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +54 -16
  95. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +3 -4
  97. data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
  98. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
  99. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +3 -4
  100. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +25 -7
  101. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
  102. data/lib/active_record/connection_adapters/postgresql/oid/timestamp.rb +15 -0
  103. data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +30 -0
  104. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +26 -12
  105. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +15 -3
  106. data/lib/active_record/connection_adapters/postgresql/oid.rb +4 -0
  107. data/lib/active_record/connection_adapters/postgresql/quoting.rb +89 -52
  108. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +34 -2
  109. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +39 -4
  110. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +128 -91
  111. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +25 -1
  112. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +149 -113
  113. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +31 -26
  114. data/lib/active_record/connection_adapters/postgresql/utils.rb +0 -1
  115. data/lib/active_record/connection_adapters/postgresql_adapter.rb +386 -182
  116. data/lib/active_record/connection_adapters/schema_cache.rb +161 -22
  117. data/lib/active_record/connection_adapters/sql_type_metadata.rb +17 -6
  118. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +152 -0
  119. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +65 -18
  120. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -1
  121. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +92 -26
  122. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +251 -204
  123. data/lib/active_record/connection_adapters/statement_pool.rb +0 -1
  124. data/lib/active_record/connection_adapters.rb +53 -0
  125. data/lib/active_record/connection_handling.rb +292 -38
  126. data/lib/active_record/core.rb +385 -158
  127. data/lib/active_record/counter_cache.rb +8 -30
  128. data/lib/active_record/database_configurations/connection_url_resolver.rb +100 -0
  129. data/lib/active_record/database_configurations/database_config.rb +83 -0
  130. data/lib/active_record/database_configurations/hash_config.rb +154 -0
  131. data/lib/active_record/database_configurations/url_config.rb +53 -0
  132. data/lib/active_record/database_configurations.rb +256 -0
  133. data/lib/active_record/delegated_type.rb +250 -0
  134. data/lib/active_record/destroy_association_async_job.rb +36 -0
  135. data/lib/active_record/disable_joins_association_relation.rb +39 -0
  136. data/lib/active_record/dynamic_matchers.rb +4 -5
  137. data/lib/active_record/encryption/cipher/aes256_gcm.rb +98 -0
  138. data/lib/active_record/encryption/cipher.rb +53 -0
  139. data/lib/active_record/encryption/config.rb +44 -0
  140. data/lib/active_record/encryption/configurable.rb +61 -0
  141. data/lib/active_record/encryption/context.rb +35 -0
  142. data/lib/active_record/encryption/contexts.rb +72 -0
  143. data/lib/active_record/encryption/derived_secret_key_provider.rb +12 -0
  144. data/lib/active_record/encryption/deterministic_key_provider.rb +14 -0
  145. data/lib/active_record/encryption/encryptable_record.rb +208 -0
  146. data/lib/active_record/encryption/encrypted_attribute_type.rb +140 -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 +155 -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 +160 -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 +42 -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_serializer.rb +90 -0
  159. data/lib/active_record/encryption/null_encryptor.rb +21 -0
  160. data/lib/active_record/encryption/properties.rb +76 -0
  161. data/lib/active_record/encryption/read_only_null_encryptor.rb +24 -0
  162. data/lib/active_record/encryption/scheme.rb +99 -0
  163. data/lib/active_record/encryption.rb +55 -0
  164. data/lib/active_record/enum.rb +130 -51
  165. data/lib/active_record/errors.rb +129 -23
  166. data/lib/active_record/explain.rb +10 -6
  167. data/lib/active_record/explain_registry.rb +11 -6
  168. data/lib/active_record/explain_subscriber.rb +1 -1
  169. data/lib/active_record/fixture_set/file.rb +22 -15
  170. data/lib/active_record/fixture_set/model_metadata.rb +32 -0
  171. data/lib/active_record/fixture_set/render_context.rb +17 -0
  172. data/lib/active_record/fixture_set/table_row.rb +187 -0
  173. data/lib/active_record/fixture_set/table_rows.rb +46 -0
  174. data/lib/active_record/fixtures.rb +206 -490
  175. data/lib/active_record/future_result.rb +139 -0
  176. data/lib/active_record/gem_version.rb +3 -3
  177. data/lib/active_record/inheritance.rb +104 -37
  178. data/lib/active_record/insert_all.rb +278 -0
  179. data/lib/active_record/integration.rb +69 -18
  180. data/lib/active_record/internal_metadata.rb +24 -9
  181. data/lib/active_record/legacy_yaml_adapter.rb +3 -36
  182. data/lib/active_record/locking/optimistic.rb +41 -26
  183. data/lib/active_record/locking/pessimistic.rb +18 -8
  184. data/lib/active_record/log_subscriber.rb +46 -35
  185. data/lib/active_record/middleware/database_selector/resolver/session.rb +48 -0
  186. data/lib/active_record/middleware/database_selector/resolver.rb +88 -0
  187. data/lib/active_record/middleware/database_selector.rb +82 -0
  188. data/lib/active_record/middleware/shard_selector.rb +60 -0
  189. data/lib/active_record/migration/command_recorder.rb +96 -44
  190. data/lib/active_record/migration/compatibility.rb +246 -64
  191. data/lib/active_record/migration/join_table.rb +1 -2
  192. data/lib/active_record/migration.rb +266 -187
  193. data/lib/active_record/model_schema.rb +165 -52
  194. data/lib/active_record/nested_attributes.rb +17 -19
  195. data/lib/active_record/no_touching.rb +11 -4
  196. data/lib/active_record/null_relation.rb +2 -7
  197. data/lib/active_record/persistence.rb +467 -92
  198. data/lib/active_record/query_cache.rb +21 -4
  199. data/lib/active_record/query_logs.rb +138 -0
  200. data/lib/active_record/querying.rb +51 -24
  201. data/lib/active_record/railtie.rb +224 -57
  202. data/lib/active_record/railties/console_sandbox.rb +2 -4
  203. data/lib/active_record/railties/controller_runtime.rb +31 -36
  204. data/lib/active_record/railties/databases.rake +369 -101
  205. data/lib/active_record/readonly_attributes.rb +15 -0
  206. data/lib/active_record/reflection.rb +170 -137
  207. data/lib/active_record/relation/batches/batch_enumerator.rb +44 -14
  208. data/lib/active_record/relation/batches.rb +46 -37
  209. data/lib/active_record/relation/calculations.rb +168 -96
  210. data/lib/active_record/relation/delegation.rb +37 -52
  211. data/lib/active_record/relation/finder_methods.rb +79 -58
  212. data/lib/active_record/relation/from_clause.rb +5 -1
  213. data/lib/active_record/relation/merger.rb +50 -51
  214. data/lib/active_record/relation/predicate_builder/array_handler.rb +13 -13
  215. data/lib/active_record/relation/predicate_builder/association_query_value.rb +5 -9
  216. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +1 -2
  217. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +11 -10
  218. data/lib/active_record/relation/predicate_builder/range_handler.rb +3 -23
  219. data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
  220. data/lib/active_record/relation/predicate_builder.rb +58 -46
  221. data/lib/active_record/relation/query_attribute.rb +9 -10
  222. data/lib/active_record/relation/query_methods.rb +685 -208
  223. data/lib/active_record/relation/record_fetch_warning.rb +9 -11
  224. data/lib/active_record/relation/spawn_methods.rb +10 -10
  225. data/lib/active_record/relation/where_clause.rb +108 -64
  226. data/lib/active_record/relation.rb +515 -151
  227. data/lib/active_record/result.rb +78 -42
  228. data/lib/active_record/runtime_registry.rb +9 -13
  229. data/lib/active_record/sanitization.rb +29 -44
  230. data/lib/active_record/schema.rb +37 -31
  231. data/lib/active_record/schema_dumper.rb +74 -23
  232. data/lib/active_record/schema_migration.rb +7 -9
  233. data/lib/active_record/scoping/default.rb +62 -17
  234. data/lib/active_record/scoping/named.rb +17 -32
  235. data/lib/active_record/scoping.rb +70 -41
  236. data/lib/active_record/secure_token.rb +16 -8
  237. data/lib/active_record/serialization.rb +6 -4
  238. data/lib/active_record/signed_id.rb +116 -0
  239. data/lib/active_record/statement_cache.rb +49 -6
  240. data/lib/active_record/store.rb +88 -9
  241. data/lib/active_record/suppressor.rb +13 -17
  242. data/lib/active_record/table_metadata.rb +42 -43
  243. data/lib/active_record/tasks/database_tasks.rb +352 -94
  244. data/lib/active_record/tasks/mysql_database_tasks.rb +37 -39
  245. data/lib/active_record/tasks/postgresql_database_tasks.rb +41 -39
  246. data/lib/active_record/tasks/sqlite_database_tasks.rb +14 -17
  247. data/lib/active_record/test_databases.rb +24 -0
  248. data/lib/active_record/test_fixtures.rb +287 -0
  249. data/lib/active_record/timestamp.rb +44 -34
  250. data/lib/active_record/touch_later.rb +23 -22
  251. data/lib/active_record/transactions.rb +67 -128
  252. data/lib/active_record/translation.rb +3 -3
  253. data/lib/active_record/type/adapter_specific_registry.rb +34 -19
  254. data/lib/active_record/type/hash_lookup_type_map.rb +34 -2
  255. data/lib/active_record/type/internal/timezone.rb +2 -2
  256. data/lib/active_record/type/serialized.rb +7 -4
  257. data/lib/active_record/type/time.rb +10 -0
  258. data/lib/active_record/type/type_map.rb +17 -21
  259. data/lib/active_record/type/unsigned_integer.rb +0 -1
  260. data/lib/active_record/type.rb +9 -5
  261. data/lib/active_record/type_caster/connection.rb +15 -15
  262. data/lib/active_record/type_caster/map.rb +8 -8
  263. data/lib/active_record/validations/associated.rb +2 -3
  264. data/lib/active_record/validations/numericality.rb +35 -0
  265. data/lib/active_record/validations/uniqueness.rb +39 -31
  266. data/lib/active_record/validations.rb +4 -3
  267. data/lib/active_record.rb +209 -32
  268. data/lib/arel/alias_predication.rb +9 -0
  269. data/lib/arel/attributes/attribute.rb +33 -0
  270. data/lib/arel/collectors/bind.rb +29 -0
  271. data/lib/arel/collectors/composite.rb +39 -0
  272. data/lib/arel/collectors/plain_string.rb +20 -0
  273. data/lib/arel/collectors/sql_string.rb +27 -0
  274. data/lib/arel/collectors/substitute_binds.rb +35 -0
  275. data/lib/arel/crud.rb +48 -0
  276. data/lib/arel/delete_manager.rb +32 -0
  277. data/lib/arel/errors.rb +9 -0
  278. data/lib/arel/expressions.rb +29 -0
  279. data/lib/arel/factory_methods.rb +49 -0
  280. data/lib/arel/filter_predications.rb +9 -0
  281. data/lib/arel/insert_manager.rb +48 -0
  282. data/lib/arel/math.rb +45 -0
  283. data/lib/arel/nodes/and.rb +32 -0
  284. data/lib/arel/nodes/ascending.rb +23 -0
  285. data/lib/arel/nodes/binary.rb +126 -0
  286. data/lib/arel/nodes/bind_param.rb +44 -0
  287. data/lib/arel/nodes/case.rb +55 -0
  288. data/lib/arel/nodes/casted.rb +62 -0
  289. data/lib/arel/nodes/comment.rb +29 -0
  290. data/lib/arel/nodes/count.rb +12 -0
  291. data/lib/arel/nodes/delete_statement.rb +44 -0
  292. data/lib/arel/nodes/descending.rb +23 -0
  293. data/lib/arel/nodes/equality.rb +15 -0
  294. data/lib/arel/nodes/extract.rb +24 -0
  295. data/lib/arel/nodes/false.rb +16 -0
  296. data/lib/arel/nodes/filter.rb +10 -0
  297. data/lib/arel/nodes/full_outer_join.rb +8 -0
  298. data/lib/arel/nodes/function.rb +45 -0
  299. data/lib/arel/nodes/grouping.rb +11 -0
  300. data/lib/arel/nodes/homogeneous_in.rb +76 -0
  301. data/lib/arel/nodes/in.rb +15 -0
  302. data/lib/arel/nodes/infix_operation.rb +92 -0
  303. data/lib/arel/nodes/inner_join.rb +8 -0
  304. data/lib/arel/nodes/insert_statement.rb +37 -0
  305. data/lib/arel/nodes/join_source.rb +20 -0
  306. data/lib/arel/nodes/matches.rb +18 -0
  307. data/lib/arel/nodes/named_function.rb +23 -0
  308. data/lib/arel/nodes/node.rb +51 -0
  309. data/lib/arel/nodes/node_expression.rb +13 -0
  310. data/lib/arel/nodes/ordering.rb +27 -0
  311. data/lib/arel/nodes/outer_join.rb +8 -0
  312. data/lib/arel/nodes/over.rb +15 -0
  313. data/lib/arel/nodes/regexp.rb +16 -0
  314. data/lib/arel/nodes/right_outer_join.rb +8 -0
  315. data/lib/arel/nodes/select_core.rb +67 -0
  316. data/lib/arel/nodes/select_statement.rb +41 -0
  317. data/lib/arel/nodes/sql_literal.rb +19 -0
  318. data/lib/arel/nodes/string_join.rb +11 -0
  319. data/lib/arel/nodes/table_alias.rb +31 -0
  320. data/lib/arel/nodes/terminal.rb +16 -0
  321. data/lib/arel/nodes/true.rb +16 -0
  322. data/lib/arel/nodes/unary.rb +44 -0
  323. data/lib/arel/nodes/unary_operation.rb +20 -0
  324. data/lib/arel/nodes/unqualified_column.rb +22 -0
  325. data/lib/arel/nodes/update_statement.rb +46 -0
  326. data/lib/arel/nodes/values_list.rb +9 -0
  327. data/lib/arel/nodes/window.rb +126 -0
  328. data/lib/arel/nodes/with.rb +11 -0
  329. data/lib/arel/nodes.rb +71 -0
  330. data/lib/arel/order_predications.rb +13 -0
  331. data/lib/arel/predications.rb +258 -0
  332. data/lib/arel/select_manager.rb +276 -0
  333. data/lib/arel/table.rb +117 -0
  334. data/lib/arel/tree_manager.rb +60 -0
  335. data/lib/arel/update_manager.rb +48 -0
  336. data/lib/arel/visitors/dot.rb +298 -0
  337. data/lib/arel/visitors/mysql.rb +99 -0
  338. data/lib/arel/visitors/postgresql.rb +110 -0
  339. data/lib/arel/visitors/sqlite.rb +38 -0
  340. data/lib/arel/visitors/to_sql.rb +955 -0
  341. data/lib/arel/visitors/visitor.rb +45 -0
  342. data/lib/arel/visitors.rb +13 -0
  343. data/lib/arel/window_predications.rb +9 -0
  344. data/lib/arel.rb +55 -0
  345. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +0 -1
  346. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +1 -1
  347. data/lib/rails/generators/active_record/migration/migration_generator.rb +3 -5
  348. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +3 -1
  349. data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +7 -5
  350. data/lib/rails/generators/active_record/migration.rb +19 -2
  351. data/lib/rails/generators/active_record/model/model_generator.rb +39 -2
  352. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
  353. data/lib/rails/generators/active_record/model/templates/model.rb.tt +10 -1
  354. data/lib/rails/generators/active_record/model/templates/module.rb.tt +2 -2
  355. data/lib/rails/generators/active_record/multi_db/multi_db_generator.rb +16 -0
  356. data/lib/rails/generators/active_record/multi_db/templates/multi_db.rb.tt +44 -0
  357. metadata +162 -32
  358. data/lib/active_record/attribute_decorators.rb +0 -90
  359. data/lib/active_record/collection_cache_key.rb +0 -53
  360. data/lib/active_record/connection_adapters/connection_specification.rb +0 -287
  361. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -33
  362. data/lib/active_record/define_callbacks.rb +0 -22
  363. data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -19
  364. data/lib/active_record/relation/where_clause_factory.rb +0 -34
@@ -1,10 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "active_record"
4
+ require "active_support/configuration_file"
5
+ require "active_support/deprecation"
6
+
7
+ databases = ActiveRecord::Tasks::DatabaseTasks.setup_initial_database_yaml
4
8
 
5
9
  db_namespace = namespace :db do
6
10
  desc "Set the environment value for the database"
7
11
  task "environment:set" => :load_config do
12
+ raise ActiveRecord::EnvironmentStorageError unless ActiveRecord::InternalMetadata.enabled?
8
13
  ActiveRecord::InternalMetadata.create_table
9
14
  ActiveRecord::InternalMetadata[:environment] = ActiveRecord::Base.connection.migration_context.current_environment
10
15
  end
@@ -14,7 +19,10 @@ db_namespace = namespace :db do
14
19
  end
15
20
 
16
21
  task load_config: :environment do
17
- ActiveRecord::Base.configurations = ActiveRecord::Tasks::DatabaseTasks.database_configuration || {}
22
+ if ActiveRecord::Base.configurations.empty?
23
+ ActiveRecord::Base.configurations = ActiveRecord::Tasks::DatabaseTasks.database_configuration
24
+ end
25
+
18
26
  ActiveRecord::Migrator.migrations_paths = ActiveRecord::Tasks::DatabaseTasks.migrations_paths
19
27
  end
20
28
 
@@ -22,9 +30,17 @@ db_namespace = namespace :db do
22
30
  task all: :load_config do
23
31
  ActiveRecord::Tasks::DatabaseTasks.create_all
24
32
  end
33
+
34
+ ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
35
+ desc "Create #{name} database for current environment"
36
+ task name => :load_config do
37
+ db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, name: name)
38
+ ActiveRecord::Tasks::DatabaseTasks.create(db_config)
39
+ end
40
+ end
25
41
  end
26
42
 
27
- 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."
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."
28
44
  task create: [:load_config] do
29
45
  ActiveRecord::Tasks::DatabaseTasks.create_current
30
46
  end
@@ -33,9 +49,17 @@ db_namespace = namespace :db do
33
49
  task all: [:load_config, :check_protected_environments] do
34
50
  ActiveRecord::Tasks::DatabaseTasks.drop_all
35
51
  end
52
+
53
+ ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
54
+ desc "Drop #{name} database for current environment"
55
+ task name => [:load_config, :check_protected_environments] do
56
+ db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, name: name)
57
+ ActiveRecord::Tasks::DatabaseTasks.drop(db_config)
58
+ end
59
+ end
36
60
  end
37
61
 
38
- 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."
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."
39
63
  task drop: [:load_config, :check_protected_environments] do
40
64
  db_namespace["drop:_unsafe"].invoke
41
65
  end
@@ -50,35 +74,85 @@ db_namespace = namespace :db do
50
74
  end
51
75
  end
52
76
 
53
- # desc "Empty the database from DATABASE_URL or config/database.yml for the current RAILS_ENV (use db:purge:all to purge all databases in the config). Without RAILS_ENV it defaults to purging the development and test databases."
77
+ # desc "Truncates tables of each database for current environment"
78
+ task truncate_all: [:load_config, :check_protected_environments] do
79
+ ActiveRecord::Tasks::DatabaseTasks.truncate_all
80
+ end
81
+
82
+ # desc "Empty the database from DATABASE_URL or config/database.yml for the current RAILS_ENV (use db:purge:all to purge all databases in the config). Without RAILS_ENV it defaults to purging the development and test databases, except when DATABASE_URL is present."
54
83
  task purge: [:load_config, :check_protected_environments] do
55
84
  ActiveRecord::Tasks::DatabaseTasks.purge_current
56
85
  end
57
86
 
58
87
  desc "Migrate the database (options: VERSION=x, VERBOSE=false, SCOPE=blog)."
59
88
  task migrate: :load_config do
60
- ActiveRecord::Tasks::DatabaseTasks.migrate
89
+ db_configs = ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env)
90
+
91
+ if db_configs.size == 1
92
+ ActiveRecord::Tasks::DatabaseTasks.migrate
93
+ else
94
+ original_db_config = ActiveRecord::Base.connection_db_config
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::Base.establish_connection(db_config)
100
+ ActiveRecord::Tasks::DatabaseTasks.migrate(version)
101
+ end
102
+ end
103
+ end
104
+
61
105
  db_namespace["_dump"].invoke
106
+ ensure
107
+ ActiveRecord::Base.establish_connection(original_db_config) if original_db_config
62
108
  end
63
109
 
64
- # IMPORTANT: This task won't dump the schema if ActiveRecord::Base.dump_schema_after_migration is set to false
110
+ # IMPORTANT: This task won't dump the schema if ActiveRecord.dump_schema_after_migration is set to false
65
111
  task :_dump do
66
- if ActiveRecord::Base.dump_schema_after_migration
67
- case ActiveRecord::Base.schema_format
68
- when :ruby then db_namespace["schema:dump"].invoke
69
- when :sql then db_namespace["structure:dump"].invoke
70
- else
71
- raise "unknown schema format #{ActiveRecord::Base.schema_format}"
72
- end
112
+ if ActiveRecord.dump_schema_after_migration
113
+ db_namespace["schema:dump"].invoke
73
114
  end
74
115
  # Allow this task to be called as many times as required. An example is the
75
116
  # migrate:redo task, which calls other two internally that depend on this one.
76
117
  db_namespace["_dump"].reenable
77
118
  end
78
119
 
120
+ namespace :_dump do
121
+ ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
122
+ # IMPORTANT: This task won't dump the schema if ActiveRecord.dump_schema_after_migration is set to false
123
+ task name do
124
+ db_config = ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env, name: name)
125
+
126
+ if ActiveRecord.dump_schema_after_migration && db_config.schema_dump
127
+ ActiveRecord::Base.establish_connection(db_config)
128
+ db_namespace["schema:dump:#{name}"].invoke
129
+ end
130
+
131
+ # Allow this task to be called as many times as required. An example is the
132
+ # migrate:redo task, which calls other two internally that depend on this one.
133
+ db_namespace["_dump:#{name}"].reenable
134
+ end
135
+ end
136
+ end
137
+
79
138
  namespace :migrate do
80
- # desc 'Rollbacks the database one migration and re migrate up (options: STEP=x, VERSION=x).'
139
+ ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
140
+ desc "Migrate #{name} database for current environment"
141
+ task name => :load_config do
142
+ original_db_config = ActiveRecord::Base.connection_db_config
143
+ db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, name: name)
144
+ ActiveRecord::Base.establish_connection(db_config)
145
+ ActiveRecord::Tasks::DatabaseTasks.migrate
146
+ db_namespace["_dump:#{name}"].invoke
147
+ ensure
148
+ ActiveRecord::Base.establish_connection(original_db_config)
149
+ end
150
+ end
151
+
152
+ desc "Rolls back the database one migration and re-migrates up (options: STEP=x, VERSION=x)."
81
153
  task redo: :load_config do
154
+ ActiveRecord::Tasks::DatabaseTasks.raise_for_multi_db(command: "db:migrate:redo")
155
+
82
156
  raise "Empty VERSION provided" if ENV["VERSION"] && ENV["VERSION"].empty?
83
157
 
84
158
  if ENV["VERSION"]
@@ -90,11 +164,30 @@ db_namespace = namespace :db do
90
164
  end
91
165
  end
92
166
 
167
+ namespace :redo do
168
+ ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
169
+ desc "Rolls back #{name} database one migration and re-migrates up (options: STEP=x, VERSION=x)."
170
+ task name => :load_config do
171
+ raise "Empty VERSION provided" if ENV["VERSION"] && ENV["VERSION"].empty?
172
+
173
+ if ENV["VERSION"]
174
+ db_namespace["migrate:down:#{name}"].invoke
175
+ db_namespace["migrate:up:#{name}"].invoke
176
+ else
177
+ db_namespace["rollback:#{name}"].invoke
178
+ db_namespace["migrate:#{name}"].invoke
179
+ end
180
+ end
181
+ end
182
+ end
183
+
93
184
  # desc 'Resets your database using your migrations for the current environment'
94
185
  task reset: ["db:drop", "db:create", "db:migrate"]
95
186
 
96
- # desc 'Runs the "up" for a given migration VERSION.'
187
+ desc 'Runs the "up" for a given migration VERSION.'
97
188
  task up: :load_config do
189
+ ActiveRecord::Tasks::DatabaseTasks.raise_for_multi_db(command: "db:migrate:up")
190
+
98
191
  raise "VERSION is required" if !ENV["VERSION"] || ENV["VERSION"].empty?
99
192
 
100
193
  ActiveRecord::Tasks::DatabaseTasks.check_target_version
@@ -106,8 +199,29 @@ db_namespace = namespace :db do
106
199
  db_namespace["_dump"].invoke
107
200
  end
108
201
 
109
- # desc 'Runs the "down" for a given migration VERSION.'
202
+ namespace :up do
203
+ ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
204
+ task name => :load_config do
205
+ raise "VERSION is required" if !ENV["VERSION"] || ENV["VERSION"].empty?
206
+
207
+ db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, name: name)
208
+
209
+ ActiveRecord::Base.establish_connection(db_config)
210
+ ActiveRecord::Tasks::DatabaseTasks.check_target_version
211
+ ActiveRecord::Base.connection.migration_context.run(
212
+ :up,
213
+ ActiveRecord::Tasks::DatabaseTasks.target_version
214
+ )
215
+
216
+ db_namespace["_dump"].invoke
217
+ end
218
+ end
219
+ end
220
+
221
+ desc 'Runs the "down" for a given migration VERSION.'
110
222
  task down: :load_config do
223
+ ActiveRecord::Tasks::DatabaseTasks.raise_for_multi_db(command: "db:migrate:down")
224
+
111
225
  raise "VERSION is required - To go down one migration, use db:rollback" if !ENV["VERSION"] || ENV["VERSION"].empty?
112
226
 
113
227
  ActiveRecord::Tasks::DatabaseTasks.check_target_version
@@ -119,27 +233,69 @@ db_namespace = namespace :db do
119
233
  db_namespace["_dump"].invoke
120
234
  end
121
235
 
236
+ namespace :down do
237
+ ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
238
+ task name => :load_config do
239
+ raise "VERSION is required" if !ENV["VERSION"] || ENV["VERSION"].empty?
240
+
241
+ db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, name: name)
242
+
243
+ ActiveRecord::Base.establish_connection(db_config)
244
+ ActiveRecord::Tasks::DatabaseTasks.check_target_version
245
+ ActiveRecord::Base.connection.migration_context.run(
246
+ :down,
247
+ ActiveRecord::Tasks::DatabaseTasks.target_version
248
+ )
249
+
250
+ db_namespace["_dump"].invoke
251
+ end
252
+ end
253
+ end
254
+
122
255
  desc "Display status of migrations"
123
256
  task status: :load_config do
124
- unless ActiveRecord::SchemaMigration.table_exists?
125
- abort "Schema migrations table does not exist yet."
257
+ ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
258
+ ActiveRecord::Base.establish_connection(db_config)
259
+ ActiveRecord::Tasks::DatabaseTasks.migrate_status
126
260
  end
261
+ end
127
262
 
128
- # output
129
- puts "\ndatabase: #{ActiveRecord::Base.connection_config[:database]}\n\n"
130
- puts "#{'Status'.center(8)} #{'Migration ID'.ljust(14)} Migration Name"
131
- puts "-" * 50
132
- ActiveRecord::Base.connection.migration_context.migrations_status.each do |status, version, name|
133
- puts "#{status.center(8)} #{version.ljust(14)} #{name}"
263
+ namespace :status do
264
+ ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
265
+ desc "Display status of migrations for #{name} database"
266
+ task name => :load_config do
267
+ db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, name: name)
268
+ ActiveRecord::Base.establish_connection(db_config)
269
+ ActiveRecord::Tasks::DatabaseTasks.migrate_status
270
+ end
271
+ end
272
+ end
273
+ end
274
+
275
+ namespace :rollback do
276
+ ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
277
+ desc "Rollback #{name} database for current environment (specify steps w/ STEP=n)."
278
+ task name => :load_config do
279
+ step = ENV["STEP"] ? ENV["STEP"].to_i : 1
280
+ db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, name: name)
281
+
282
+ ActiveRecord::Base.establish_connection(db_config)
283
+ ActiveRecord::Base.connection.migration_context.rollback(step)
284
+
285
+ db_namespace["_dump"].invoke
134
286
  end
135
- puts
136
287
  end
137
288
  end
138
289
 
139
290
  desc "Rolls the schema back to the previous version (specify steps w/ STEP=n)."
140
291
  task rollback: :load_config do
292
+ ActiveRecord::Tasks::DatabaseTasks.raise_for_multi_db(command: "db:rollback")
293
+ raise "VERSION is not supported - To rollback a specific version, use db:migrate:down" if ENV["VERSION"]
294
+
141
295
  step = ENV["STEP"] ? ENV["STEP"].to_i : 1
296
+
142
297
  ActiveRecord::Base.connection.migration_context.rollback(step)
298
+
143
299
  db_namespace["_dump"].invoke
144
300
  end
145
301
 
@@ -150,7 +306,16 @@ db_namespace = namespace :db do
150
306
  db_namespace["_dump"].invoke
151
307
  end
152
308
 
153
- # desc 'Drops and recreates the database from db/schema.rb for the current environment and loads the seeds.'
309
+ namespace :reset do
310
+ task all: ["db:drop", "db:setup"]
311
+
312
+ ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
313
+ desc "Drops and recreates the #{name} database from its schema for the current environment and loads the seeds."
314
+ task name => ["db:drop:#{name}", "db:setup:#{name}"]
315
+ end
316
+ end
317
+
318
+ desc "Drops and recreates all databases from their schema for the current environment and loads the seeds."
154
319
  task reset: [ "db:drop", "db:setup" ]
155
320
 
156
321
  # desc "Retrieves the charset for the current environment's database"
@@ -160,42 +325,85 @@ db_namespace = namespace :db do
160
325
 
161
326
  # desc "Retrieves the collation for the current environment's database"
162
327
  task collation: :load_config do
163
- begin
164
- puts ActiveRecord::Tasks::DatabaseTasks.collation_current
165
- rescue NoMethodError
166
- $stderr.puts "Sorry, your database adapter is not supported yet. Feel free to submit a patch."
167
- end
328
+ puts ActiveRecord::Tasks::DatabaseTasks.collation_current
329
+ rescue NoMethodError
330
+ $stderr.puts "Sorry, your database adapter is not supported yet. Feel free to submit a patch."
168
331
  end
169
332
 
170
333
  desc "Retrieves the current schema version number"
171
334
  task version: :load_config do
172
- puts "Current version: #{ActiveRecord::Base.connection.migration_context.current_version}"
335
+ puts "Current version: #{ActiveRecord::Base.connection.schema_version}"
173
336
  end
174
337
 
175
338
  # desc "Raises an error if there are pending migrations"
176
339
  task abort_if_pending_migrations: :load_config do
177
- pending_migrations = ActiveRecord::Base.connection.migration_context.open.pending_migrations
340
+ pending_migrations = ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).flat_map do |db_config|
341
+ ActiveRecord::Base.establish_connection(db_config)
342
+
343
+ ActiveRecord::Base.connection.migration_context.open.pending_migrations
344
+ end
178
345
 
179
346
  if pending_migrations.any?
180
347
  puts "You have #{pending_migrations.size} pending #{pending_migrations.size > 1 ? 'migrations:' : 'migration:'}"
181
348
  pending_migrations.each do |pending_migration|
182
349
  puts " %4d %s" % [pending_migration.version, pending_migration.name]
183
350
  end
184
- abort %{Run `rails db:migrate` to update your database then try again.}
351
+ abort %{Run `bin/rails db:migrate` to update your database then try again.}
352
+ end
353
+ ensure
354
+ ActiveRecord::Base.establish_connection(ActiveRecord::Tasks::DatabaseTasks.env.to_sym)
355
+ end
356
+
357
+ namespace :abort_if_pending_migrations do
358
+ ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
359
+ # desc "Raises an error if there are pending migrations for #{name} database"
360
+ task name => :load_config do
361
+ db_config = ActiveRecord::Base.configurations.configs_for(env_name: Rails.env, name: name)
362
+ ActiveRecord::Base.establish_connection(db_config)
363
+
364
+ pending_migrations = ActiveRecord::Base.connection.migration_context.open.pending_migrations
365
+
366
+ if pending_migrations.any?
367
+ puts "You have #{pending_migrations.size} pending #{pending_migrations.size > 1 ? 'migrations:' : 'migration:'}"
368
+ pending_migrations.each do |pending_migration|
369
+ puts " %4d %s" % [pending_migration.version, pending_migration.name]
370
+ end
371
+ abort %{Run `bin/rails db:migrate:#{name}` to update your database then try again.}
372
+ end
373
+ end
374
+ end
375
+ end
376
+
377
+ namespace :setup do
378
+ task all: ["db:create", :environment, "db:schema:load", :seed]
379
+
380
+ ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
381
+ desc "Creates the #{name} database, loads the schema, and initializes with the seed data (use db:reset:#{name} to also drop the database first)"
382
+ task name => ["db:create:#{name}", :environment, "db:schema:load:#{name}", "db:seed"]
185
383
  end
186
384
  end
187
385
 
188
- desc "Creates the database, loads the schema, and initializes with the seed data (use db:reset to also drop the database first)"
189
- task setup: ["db:schema:load_if_ruby", "db:structure:load_if_sql", :seed]
386
+ desc "Creates all databases, loads all schemas, and initializes with the seed data (use db:reset to also drop all databases first)"
387
+ task setup: ["db:create", :environment, "db:schema:load", :seed]
388
+
389
+ desc "Runs setup if database does not exist, or runs migrations if it does"
390
+ task prepare: :load_config do
391
+ ActiveRecord::Tasks::DatabaseTasks.prepare_all
392
+ end
190
393
 
191
394
  desc "Loads the seed data from db/seeds.rb"
192
- task :seed do
395
+ task seed: :load_config do
193
396
  db_namespace["abort_if_pending_migrations"].invoke
194
397
  ActiveRecord::Tasks::DatabaseTasks.load_seed
195
398
  end
196
399
 
400
+ namespace :seed do
401
+ desc "Truncates tables of each database for current environment and loads the seeds"
402
+ task replant: [:load_config, :truncate_all, :seed]
403
+ end
404
+
197
405
  namespace :fixtures do
198
- 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 (eg. spec/fixtures) using FIXTURES_PATH=spec/fixtures."
406
+ desc "Loads fixtures into the current environment's database. Load specific fixtures using FIXTURES=x,y. Load from subdirectory in test/fixtures using FIXTURES_DIR=z. Specify an alternative path (e.g. spec/fixtures) using FIXTURES_PATH=spec/fixtures."
199
407
  task load: :load_config do
200
408
  require "active_record/fixtures"
201
409
 
@@ -210,14 +418,15 @@ db_namespace = namespace :db do
210
418
  fixture_files = if ENV["FIXTURES"]
211
419
  ENV["FIXTURES"].split(",")
212
420
  else
213
- # The use of String#[] here is to support namespaced fixtures.
214
- Dir["#{fixtures_dir}/**/*.yml"].map { |f| f[(fixtures_dir.size + 1)..-5] }
421
+ files = Dir[File.join(fixtures_dir, "**/*.{yml}")]
422
+ files.reject! { |f| f.start_with?(File.join(fixtures_dir, "files")) }
423
+ files.map! { |f| f[fixtures_dir.to_s.size..-5].delete_prefix("/") }
215
424
  end
216
425
 
217
426
  ActiveRecord::FixtureSet.create_fixtures(fixtures_dir, fixture_files)
218
427
  end
219
428
 
220
- # desc "Search for a fixture given a LABEL or ID. Specify an alternative path (eg. spec/fixtures) using FIXTURES_PATH=spec/fixtures."
429
+ # desc "Search for a fixture given a LABEL or ID. Specify an alternative path (e.g. spec/fixtures) using FIXTURES_PATH=spec/fixtures."
221
430
  task identify: :load_config do
222
431
  require "active_record/fixtures"
223
432
 
@@ -229,7 +438,7 @@ db_namespace = namespace :db do
229
438
  base_dir = ActiveRecord::Tasks::DatabaseTasks.fixtures_path
230
439
 
231
440
  Dir["#{base_dir}/**/*.yml"].each do |file|
232
- if data = YAML.load(ERB.new(IO.read(file)).result)
441
+ if data = ActiveSupport::ConfigurationFile.parse(file)
233
442
  data.each_key do |key|
234
443
  key_id = ActiveRecord::FixtureSet.identify(key)
235
444
 
@@ -243,100 +452,117 @@ db_namespace = namespace :db do
243
452
  end
244
453
 
245
454
  namespace :schema do
246
- desc "Creates a db/schema.rb file that is portable against any DB supported by Active Record"
455
+ desc "Creates a database schema file (either db/schema.rb or db/structure.sql, depending on `config.active_record.schema_format`)"
247
456
  task dump: :load_config do
248
- require "active_record/schema_dumper"
249
- filename = ENV["SCHEMA"] || File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, "schema.rb")
250
- File.open(filename, "w:utf-8") do |file|
251
- ActiveRecord::SchemaDumper.dump(ActiveRecord::Base.connection, file)
457
+ ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
458
+ if db_config.schema_dump
459
+ ActiveRecord::Base.establish_connection(db_config)
460
+ ActiveRecord::Tasks::DatabaseTasks.dump_schema(db_config)
461
+ end
252
462
  end
463
+
253
464
  db_namespace["schema:dump"].reenable
254
465
  end
255
466
 
256
- desc "Loads a schema.rb file into the database"
467
+ desc "Loads a database schema file (either db/schema.rb or db/structure.sql, depending on `config.active_record.schema_format`) into the database"
257
468
  task load: [:load_config, :check_protected_environments] do
258
- ActiveRecord::Tasks::DatabaseTasks.load_schema_current(:ruby, ENV["SCHEMA"])
469
+ ActiveRecord::Tasks::DatabaseTasks.load_schema_current(ActiveRecord.schema_format, ENV["SCHEMA"])
470
+ end
471
+
472
+ namespace :dump do
473
+ ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
474
+ desc "Creates a database schema file (either db/schema.rb or db/structure.sql, depending on `config.active_record.schema_format`) for #{name} database"
475
+ task name => :load_config do
476
+ db_config = ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env, name: name)
477
+ ActiveRecord::Base.establish_connection(db_config)
478
+ ActiveRecord::Tasks::DatabaseTasks.dump_schema(db_config)
479
+ db_namespace["schema:dump:#{name}"].reenable
480
+ end
481
+ end
259
482
  end
260
483
 
261
- task load_if_ruby: ["db:create", :environment] do
262
- db_namespace["schema:load"].invoke if ActiveRecord::Base.schema_format == :ruby
484
+ namespace :load do
485
+ ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
486
+ desc "Loads a database schema file (either db/schema.rb or db/structure.sql, depending on `config.active_record.schema_format`) into the #{name} database"
487
+ task name => :load_config do
488
+ original_db_config = ActiveRecord::Base.connection_db_config
489
+ db_config = ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env, name: name)
490
+ ActiveRecord::Tasks::DatabaseTasks.load_schema(db_config)
491
+ ensure
492
+ ActiveRecord::Base.establish_connection(original_db_config) if original_db_config
493
+ end
494
+ end
263
495
  end
264
496
 
265
497
  namespace :cache do
266
498
  desc "Creates a db/schema_cache.yml file."
267
499
  task dump: :load_config do
268
- conn = ActiveRecord::Base.connection
269
- filename = File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, "schema_cache.yml")
270
- ActiveRecord::Tasks::DatabaseTasks.dump_schema_cache(conn, filename)
500
+ ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
501
+ ActiveRecord::Base.establish_connection(db_config)
502
+ filename = ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename(
503
+ db_config.name,
504
+ schema_cache_path: db_config.schema_cache_path,
505
+ )
506
+ ActiveRecord::Tasks::DatabaseTasks.dump_schema_cache(
507
+ ActiveRecord::Base.connection,
508
+ filename,
509
+ )
510
+ end
271
511
  end
272
512
 
273
513
  desc "Clears a db/schema_cache.yml file."
274
514
  task clear: :load_config do
275
- filename = File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, "schema_cache.yml")
276
- rm_f filename, verbose: false
277
- end
278
- end
279
-
280
- end
281
-
282
- namespace :structure do
283
- desc "Dumps the database structure to db/structure.sql. Specify another file with SCHEMA=db/my_structure.sql"
284
- task dump: :load_config do
285
- filename = ENV["SCHEMA"] || File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, "structure.sql")
286
- current_config = ActiveRecord::Tasks::DatabaseTasks.current_config
287
- ActiveRecord::Tasks::DatabaseTasks.structure_dump(current_config, filename)
288
-
289
- if ActiveRecord::SchemaMigration.table_exists?
290
- File.open(filename, "a") do |f|
291
- f.puts ActiveRecord::Base.connection.dump_schema_information
292
- f.print "\n"
515
+ ActiveRecord::Base.configurations.configs_for(env_name: ActiveRecord::Tasks::DatabaseTasks.env).each do |db_config|
516
+ filename = ActiveRecord::Tasks::DatabaseTasks.cache_dump_filename(
517
+ db_config.name,
518
+ schema_cache_path: db_config.schema_cache_path,
519
+ )
520
+ ActiveRecord::Tasks::DatabaseTasks.clear_schema_cache(
521
+ filename,
522
+ )
293
523
  end
294
524
  end
295
- db_namespace["structure:dump"].reenable
296
- end
297
-
298
- desc "Recreates the databases from the structure.sql file"
299
- task load: [:load_config, :check_protected_environments] do
300
- ActiveRecord::Tasks::DatabaseTasks.load_schema_current(:sql, ENV["SCHEMA"])
301
525
  end
526
+ end
302
527
 
303
- task load_if_sql: ["db:create", :environment] do
304
- db_namespace["structure:load"].invoke if ActiveRecord::Base.schema_format == :sql
528
+ namespace :encryption do
529
+ desc "Generate a set of keys for configuring Active Record encryption in a given environment"
530
+ task :init do
531
+ puts <<~MSG
532
+ Add this entry to the credentials of the target environment:#{' '}
533
+
534
+ active_record_encryption:
535
+ primary_key: #{SecureRandom.alphanumeric(32)}
536
+ deterministic_key: #{SecureRandom.alphanumeric(32)}
537
+ key_derivation_salt: #{SecureRandom.alphanumeric(32)}
538
+ MSG
305
539
  end
306
540
  end
307
541
 
308
542
  namespace :test do
309
543
  # desc "Recreate the test database from the current schema"
310
544
  task load: %w(db:test:purge) do
311
- case ActiveRecord::Base.schema_format
312
- when :ruby
313
- db_namespace["test:load_schema"].invoke
314
- when :sql
315
- db_namespace["test:load_structure"].invoke
316
- end
545
+ db_namespace["test:load_schema"].invoke
317
546
  end
318
547
 
319
- # desc "Recreate the test database from an existent schema.rb file"
548
+ # desc "Recreate the test database from an existent schema file (schema.rb or structure.sql, depending on `config.active_record.schema_format`)"
320
549
  task load_schema: %w(db:test:purge) do
321
- begin
322
- should_reconnect = ActiveRecord::Base.connection_pool.active_connection?
323
- ActiveRecord::Schema.verbose = false
324
- ActiveRecord::Tasks::DatabaseTasks.load_schema ActiveRecord::Base.configurations["test"], :ruby, ENV["SCHEMA"], "test"
325
- ensure
326
- if should_reconnect
327
- ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations[ActiveRecord::Tasks::DatabaseTasks.env])
328
- end
550
+ should_reconnect = ActiveRecord::Base.connection_pool.active_connection?
551
+ ActiveRecord::Schema.verbose = false
552
+ ActiveRecord::Base.configurations.configs_for(env_name: "test").each do |db_config|
553
+ ActiveRecord::Tasks::DatabaseTasks.load_schema(db_config)
554
+ end
555
+ ensure
556
+ if should_reconnect
557
+ ActiveRecord::Base.establish_connection(ActiveRecord::Tasks::DatabaseTasks.env.to_sym)
329
558
  end
330
- end
331
-
332
- # desc "Recreate the test database from an existent structure.sql file"
333
- task load_structure: %w(db:test:purge) do
334
- ActiveRecord::Tasks::DatabaseTasks.load_schema ActiveRecord::Base.configurations["test"], :sql, ENV["SCHEMA"], "test"
335
559
  end
336
560
 
337
561
  # desc "Empty the test database"
338
562
  task purge: %w(load_config check_protected_environments) do
339
- ActiveRecord::Tasks::DatabaseTasks.purge ActiveRecord::Base.configurations["test"]
563
+ ActiveRecord::Base.configurations.configs_for(env_name: "test").each do |db_config|
564
+ ActiveRecord::Tasks::DatabaseTasks.purge(db_config)
565
+ end
340
566
  end
341
567
 
342
568
  # desc 'Load the test schema'
@@ -345,6 +571,44 @@ db_namespace = namespace :db do
345
571
  db_namespace["test:load"].invoke
346
572
  end
347
573
  end
574
+
575
+ ActiveRecord::Tasks::DatabaseTasks.for_each(databases) do |name|
576
+ # desc "Recreate the #{name} test database"
577
+ namespace :load do
578
+ task name => "db:test:purge:#{name}" do
579
+ db_namespace["test:load_schema:#{name}"].invoke
580
+ end
581
+ end
582
+
583
+ # desc "Recreate the #{name} test database from an existent schema.rb file"
584
+ namespace :load_schema do
585
+ task name => "db:test:purge:#{name}" do
586
+ should_reconnect = ActiveRecord::Base.connection_pool.active_connection?
587
+ ActiveRecord::Schema.verbose = false
588
+ db_config = ActiveRecord::Base.configurations.configs_for(env_name: "test", name: name)
589
+ ActiveRecord::Tasks::DatabaseTasks.load_schema(db_config)
590
+ ensure
591
+ if should_reconnect
592
+ ActiveRecord::Base.establish_connection(ActiveRecord::Tasks::DatabaseTasks.env.to_sym)
593
+ end
594
+ end
595
+ end
596
+
597
+ # desc "Empty the #{name} test database"
598
+ namespace :purge do
599
+ task name => %w(load_config check_protected_environments) do
600
+ db_config = ActiveRecord::Base.configurations.configs_for(env_name: "test", name: name)
601
+ ActiveRecord::Tasks::DatabaseTasks.purge(db_config)
602
+ end
603
+ end
604
+
605
+ # desc 'Load the #{name} database test schema'
606
+ namespace :prepare do
607
+ task name => :load_config do
608
+ db_namespace["test:load:#{name}"].invoke
609
+ end
610
+ end
611
+ end
348
612
  end
349
613
  end
350
614
 
@@ -360,6 +624,10 @@ namespace :railties do
360
624
  if railtie.respond_to?(:paths) && (path = railtie.paths["db/migrate"].first)
361
625
  railties[railtie.railtie_name] = path
362
626
  end
627
+
628
+ unless ENV["MIGRATIONS_PATH"].blank?
629
+ railties[railtie.railtie_name] = railtie.root + ENV["MIGRATIONS_PATH"]
630
+ end
363
631
  end
364
632
 
365
633
  on_skip = Proc.new do |name, migration|