omg-activerecord 8.0.0.alpha1

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 (412) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +355 -0
  3. data/MIT-LICENSE +22 -0
  4. data/README.rdoc +219 -0
  5. data/examples/performance.rb +185 -0
  6. data/examples/simple.rb +15 -0
  7. data/lib/active_record/aggregations.rb +287 -0
  8. data/lib/active_record/association_relation.rb +50 -0
  9. data/lib/active_record/associations/alias_tracker.rb +90 -0
  10. data/lib/active_record/associations/association.rb +417 -0
  11. data/lib/active_record/associations/association_scope.rb +175 -0
  12. data/lib/active_record/associations/belongs_to_association.rb +163 -0
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +50 -0
  14. data/lib/active_record/associations/builder/association.rb +170 -0
  15. data/lib/active_record/associations/builder/belongs_to.rb +160 -0
  16. data/lib/active_record/associations/builder/collection_association.rb +80 -0
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +107 -0
  18. data/lib/active_record/associations/builder/has_many.rb +23 -0
  19. data/lib/active_record/associations/builder/has_one.rb +61 -0
  20. data/lib/active_record/associations/builder/singular_association.rb +48 -0
  21. data/lib/active_record/associations/collection_association.rb +535 -0
  22. data/lib/active_record/associations/collection_proxy.rb +1163 -0
  23. data/lib/active_record/associations/disable_joins_association_scope.rb +59 -0
  24. data/lib/active_record/associations/errors.rb +265 -0
  25. data/lib/active_record/associations/foreign_association.rb +40 -0
  26. data/lib/active_record/associations/has_many_association.rb +167 -0
  27. data/lib/active_record/associations/has_many_through_association.rb +232 -0
  28. data/lib/active_record/associations/has_one_association.rb +142 -0
  29. data/lib/active_record/associations/has_one_through_association.rb +45 -0
  30. data/lib/active_record/associations/join_dependency/join_association.rb +106 -0
  31. data/lib/active_record/associations/join_dependency/join_base.rb +23 -0
  32. data/lib/active_record/associations/join_dependency/join_part.rb +71 -0
  33. data/lib/active_record/associations/join_dependency.rb +301 -0
  34. data/lib/active_record/associations/nested_error.rb +47 -0
  35. data/lib/active_record/associations/preloader/association.rb +316 -0
  36. data/lib/active_record/associations/preloader/batch.rb +48 -0
  37. data/lib/active_record/associations/preloader/branch.rb +153 -0
  38. data/lib/active_record/associations/preloader/through_association.rb +150 -0
  39. data/lib/active_record/associations/preloader.rb +135 -0
  40. data/lib/active_record/associations/singular_association.rb +76 -0
  41. data/lib/active_record/associations/through_association.rb +132 -0
  42. data/lib/active_record/associations.rb +1897 -0
  43. data/lib/active_record/asynchronous_queries_tracker.rb +64 -0
  44. data/lib/active_record/attribute_assignment.rb +82 -0
  45. data/lib/active_record/attribute_methods/before_type_cast.rb +106 -0
  46. data/lib/active_record/attribute_methods/composite_primary_key.rb +84 -0
  47. data/lib/active_record/attribute_methods/dirty.rb +262 -0
  48. data/lib/active_record/attribute_methods/primary_key.rb +158 -0
  49. data/lib/active_record/attribute_methods/query.rb +50 -0
  50. data/lib/active_record/attribute_methods/read.rb +46 -0
  51. data/lib/active_record/attribute_methods/serialization.rb +232 -0
  52. data/lib/active_record/attribute_methods/time_zone_conversion.rb +94 -0
  53. data/lib/active_record/attribute_methods/write.rb +49 -0
  54. data/lib/active_record/attribute_methods.rb +542 -0
  55. data/lib/active_record/attributes.rb +307 -0
  56. data/lib/active_record/autosave_association.rb +586 -0
  57. data/lib/active_record/base.rb +338 -0
  58. data/lib/active_record/callbacks.rb +452 -0
  59. data/lib/active_record/coders/column_serializer.rb +61 -0
  60. data/lib/active_record/coders/json.rb +15 -0
  61. data/lib/active_record/coders/yaml_column.rb +95 -0
  62. data/lib/active_record/connection_adapters/abstract/connection_handler.rb +290 -0
  63. data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +210 -0
  64. data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +78 -0
  65. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +923 -0
  66. data/lib/active_record/connection_adapters/abstract/database_limits.rb +31 -0
  67. data/lib/active_record/connection_adapters/abstract/database_statements.rb +747 -0
  68. data/lib/active_record/connection_adapters/abstract/query_cache.rb +319 -0
  69. data/lib/active_record/connection_adapters/abstract/quoting.rb +239 -0
  70. data/lib/active_record/connection_adapters/abstract/savepoints.rb +24 -0
  71. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +190 -0
  72. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +961 -0
  73. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +106 -0
  74. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +1883 -0
  75. data/lib/active_record/connection_adapters/abstract/transaction.rb +676 -0
  76. data/lib/active_record/connection_adapters/abstract_adapter.rb +1218 -0
  77. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +1016 -0
  78. data/lib/active_record/connection_adapters/column.rb +122 -0
  79. data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
  80. data/lib/active_record/connection_adapters/mysql/column.rb +28 -0
  81. data/lib/active_record/connection_adapters/mysql/database_statements.rb +95 -0
  82. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +71 -0
  83. data/lib/active_record/connection_adapters/mysql/quoting.rb +114 -0
  84. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +106 -0
  85. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +106 -0
  86. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +97 -0
  87. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +300 -0
  88. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +40 -0
  89. data/lib/active_record/connection_adapters/mysql2/database_statements.rb +96 -0
  90. data/lib/active_record/connection_adapters/mysql2_adapter.rb +196 -0
  91. data/lib/active_record/connection_adapters/pool_config.rb +83 -0
  92. data/lib/active_record/connection_adapters/pool_manager.rb +57 -0
  93. data/lib/active_record/connection_adapters/postgresql/column.rb +82 -0
  94. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +231 -0
  95. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +91 -0
  97. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +53 -0
  98. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +15 -0
  99. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +17 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +54 -0
  101. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +31 -0
  102. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +36 -0
  103. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +15 -0
  104. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +20 -0
  105. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +109 -0
  106. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +15 -0
  107. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
  108. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +15 -0
  109. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +44 -0
  110. data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
  111. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +42 -0
  112. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +15 -0
  113. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +74 -0
  114. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +124 -0
  115. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +18 -0
  116. data/lib/active_record/connection_adapters/postgresql/oid/timestamp.rb +15 -0
  117. data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +30 -0
  118. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +125 -0
  119. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +45 -0
  120. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +28 -0
  121. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +30 -0
  122. data/lib/active_record/connection_adapters/postgresql/oid.rb +38 -0
  123. data/lib/active_record/connection_adapters/postgresql/quoting.rb +238 -0
  124. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +71 -0
  125. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +169 -0
  126. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +392 -0
  127. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +127 -0
  128. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +1162 -0
  129. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +44 -0
  130. data/lib/active_record/connection_adapters/postgresql/utils.rb +79 -0
  131. data/lib/active_record/connection_adapters/postgresql_adapter.rb +1182 -0
  132. data/lib/active_record/connection_adapters/schema_cache.rb +478 -0
  133. data/lib/active_record/connection_adapters/sql_type_metadata.rb +45 -0
  134. data/lib/active_record/connection_adapters/sqlite3/column.rb +62 -0
  135. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +145 -0
  136. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +21 -0
  137. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +116 -0
  138. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +37 -0
  139. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +39 -0
  140. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +47 -0
  141. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +221 -0
  142. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +843 -0
  143. data/lib/active_record/connection_adapters/statement_pool.rb +67 -0
  144. data/lib/active_record/connection_adapters/trilogy/database_statements.rb +69 -0
  145. data/lib/active_record/connection_adapters/trilogy_adapter.rb +212 -0
  146. data/lib/active_record/connection_adapters.rb +176 -0
  147. data/lib/active_record/connection_handling.rb +413 -0
  148. data/lib/active_record/core.rb +836 -0
  149. data/lib/active_record/counter_cache.rb +230 -0
  150. data/lib/active_record/database_configurations/connection_url_resolver.rb +105 -0
  151. data/lib/active_record/database_configurations/database_config.rb +104 -0
  152. data/lib/active_record/database_configurations/hash_config.rb +172 -0
  153. data/lib/active_record/database_configurations/url_config.rb +78 -0
  154. data/lib/active_record/database_configurations.rb +309 -0
  155. data/lib/active_record/delegated_type.rb +289 -0
  156. data/lib/active_record/deprecator.rb +7 -0
  157. data/lib/active_record/destroy_association_async_job.rb +38 -0
  158. data/lib/active_record/disable_joins_association_relation.rb +39 -0
  159. data/lib/active_record/dynamic_matchers.rb +121 -0
  160. data/lib/active_record/encryption/auto_filtered_parameters.rb +66 -0
  161. data/lib/active_record/encryption/cipher/aes256_gcm.rb +101 -0
  162. data/lib/active_record/encryption/cipher.rb +53 -0
  163. data/lib/active_record/encryption/config.rb +70 -0
  164. data/lib/active_record/encryption/configurable.rb +60 -0
  165. data/lib/active_record/encryption/context.rb +42 -0
  166. data/lib/active_record/encryption/contexts.rb +76 -0
  167. data/lib/active_record/encryption/derived_secret_key_provider.rb +18 -0
  168. data/lib/active_record/encryption/deterministic_key_provider.rb +14 -0
  169. data/lib/active_record/encryption/encryptable_record.rb +230 -0
  170. data/lib/active_record/encryption/encrypted_attribute_type.rb +184 -0
  171. data/lib/active_record/encryption/encrypted_fixtures.rb +38 -0
  172. data/lib/active_record/encryption/encrypting_only_encryptor.rb +12 -0
  173. data/lib/active_record/encryption/encryptor.rb +177 -0
  174. data/lib/active_record/encryption/envelope_encryption_key_provider.rb +55 -0
  175. data/lib/active_record/encryption/errors.rb +15 -0
  176. data/lib/active_record/encryption/extended_deterministic_queries.rb +159 -0
  177. data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +28 -0
  178. data/lib/active_record/encryption/key.rb +28 -0
  179. data/lib/active_record/encryption/key_generator.rb +53 -0
  180. data/lib/active_record/encryption/key_provider.rb +46 -0
  181. data/lib/active_record/encryption/message.rb +33 -0
  182. data/lib/active_record/encryption/message_pack_message_serializer.rb +76 -0
  183. data/lib/active_record/encryption/message_serializer.rb +96 -0
  184. data/lib/active_record/encryption/null_encryptor.rb +25 -0
  185. data/lib/active_record/encryption/properties.rb +76 -0
  186. data/lib/active_record/encryption/read_only_null_encryptor.rb +28 -0
  187. data/lib/active_record/encryption/scheme.rb +107 -0
  188. data/lib/active_record/encryption.rb +58 -0
  189. data/lib/active_record/enum.rb +424 -0
  190. data/lib/active_record/errors.rb +614 -0
  191. data/lib/active_record/explain.rb +63 -0
  192. data/lib/active_record/explain_registry.rb +37 -0
  193. data/lib/active_record/explain_subscriber.rb +34 -0
  194. data/lib/active_record/fixture_set/file.rb +89 -0
  195. data/lib/active_record/fixture_set/model_metadata.rb +42 -0
  196. data/lib/active_record/fixture_set/render_context.rb +19 -0
  197. data/lib/active_record/fixture_set/table_row.rb +208 -0
  198. data/lib/active_record/fixture_set/table_rows.rb +46 -0
  199. data/lib/active_record/fixtures.rb +850 -0
  200. data/lib/active_record/future_result.rb +182 -0
  201. data/lib/active_record/gem_version.rb +17 -0
  202. data/lib/active_record/inheritance.rb +366 -0
  203. data/lib/active_record/insert_all.rb +328 -0
  204. data/lib/active_record/integration.rb +209 -0
  205. data/lib/active_record/internal_metadata.rb +164 -0
  206. data/lib/active_record/legacy_yaml_adapter.rb +15 -0
  207. data/lib/active_record/locale/en.yml +48 -0
  208. data/lib/active_record/locking/optimistic.rb +228 -0
  209. data/lib/active_record/locking/pessimistic.rb +102 -0
  210. data/lib/active_record/log_subscriber.rb +149 -0
  211. data/lib/active_record/marshalling.rb +56 -0
  212. data/lib/active_record/message_pack.rb +124 -0
  213. data/lib/active_record/middleware/database_selector/resolver/session.rb +48 -0
  214. data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
  215. data/lib/active_record/middleware/database_selector.rb +87 -0
  216. data/lib/active_record/middleware/shard_selector.rb +62 -0
  217. data/lib/active_record/migration/command_recorder.rb +406 -0
  218. data/lib/active_record/migration/compatibility.rb +490 -0
  219. data/lib/active_record/migration/default_strategy.rb +22 -0
  220. data/lib/active_record/migration/execution_strategy.rb +19 -0
  221. data/lib/active_record/migration/join_table.rb +16 -0
  222. data/lib/active_record/migration/pending_migration_connection.rb +21 -0
  223. data/lib/active_record/migration.rb +1626 -0
  224. data/lib/active_record/model_schema.rb +635 -0
  225. data/lib/active_record/nested_attributes.rb +633 -0
  226. data/lib/active_record/no_touching.rb +65 -0
  227. data/lib/active_record/normalization.rb +163 -0
  228. data/lib/active_record/persistence.rb +968 -0
  229. data/lib/active_record/promise.rb +84 -0
  230. data/lib/active_record/query_cache.rb +56 -0
  231. data/lib/active_record/query_logs.rb +247 -0
  232. data/lib/active_record/query_logs_formatter.rb +30 -0
  233. data/lib/active_record/querying.rb +122 -0
  234. data/lib/active_record/railtie.rb +440 -0
  235. data/lib/active_record/railties/console_sandbox.rb +5 -0
  236. data/lib/active_record/railties/controller_runtime.rb +65 -0
  237. data/lib/active_record/railties/databases.rake +641 -0
  238. data/lib/active_record/railties/job_runtime.rb +23 -0
  239. data/lib/active_record/readonly_attributes.rb +66 -0
  240. data/lib/active_record/reflection.rb +1287 -0
  241. data/lib/active_record/relation/batches/batch_enumerator.rb +115 -0
  242. data/lib/active_record/relation/batches.rb +491 -0
  243. data/lib/active_record/relation/calculations.rb +679 -0
  244. data/lib/active_record/relation/delegation.rb +154 -0
  245. data/lib/active_record/relation/finder_methods.rb +661 -0
  246. data/lib/active_record/relation/from_clause.rb +30 -0
  247. data/lib/active_record/relation/merger.rb +192 -0
  248. data/lib/active_record/relation/predicate_builder/array_handler.rb +48 -0
  249. data/lib/active_record/relation/predicate_builder/association_query_value.rb +76 -0
  250. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +19 -0
  251. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +60 -0
  252. data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -0
  253. data/lib/active_record/relation/predicate_builder/relation_handler.rb +24 -0
  254. data/lib/active_record/relation/predicate_builder.rb +181 -0
  255. data/lib/active_record/relation/query_attribute.rb +68 -0
  256. data/lib/active_record/relation/query_methods.rb +2235 -0
  257. data/lib/active_record/relation/record_fetch_warning.rb +52 -0
  258. data/lib/active_record/relation/spawn_methods.rb +78 -0
  259. data/lib/active_record/relation/where_clause.rb +218 -0
  260. data/lib/active_record/relation.rb +1495 -0
  261. data/lib/active_record/result.rb +249 -0
  262. data/lib/active_record/runtime_registry.rb +82 -0
  263. data/lib/active_record/sanitization.rb +254 -0
  264. data/lib/active_record/schema.rb +77 -0
  265. data/lib/active_record/schema_dumper.rb +364 -0
  266. data/lib/active_record/schema_migration.rb +106 -0
  267. data/lib/active_record/scoping/default.rb +205 -0
  268. data/lib/active_record/scoping/named.rb +202 -0
  269. data/lib/active_record/scoping.rb +136 -0
  270. data/lib/active_record/secure_password.rb +60 -0
  271. data/lib/active_record/secure_token.rb +66 -0
  272. data/lib/active_record/serialization.rb +29 -0
  273. data/lib/active_record/signed_id.rb +137 -0
  274. data/lib/active_record/statement_cache.rb +164 -0
  275. data/lib/active_record/store.rb +299 -0
  276. data/lib/active_record/suppressor.rb +59 -0
  277. data/lib/active_record/table_metadata.rb +85 -0
  278. data/lib/active_record/tasks/database_tasks.rb +681 -0
  279. data/lib/active_record/tasks/mysql_database_tasks.rb +120 -0
  280. data/lib/active_record/tasks/postgresql_database_tasks.rb +147 -0
  281. data/lib/active_record/tasks/sqlite_database_tasks.rb +89 -0
  282. data/lib/active_record/test_databases.rb +24 -0
  283. data/lib/active_record/test_fixtures.rb +321 -0
  284. data/lib/active_record/testing/query_assertions.rb +121 -0
  285. data/lib/active_record/timestamp.rb +177 -0
  286. data/lib/active_record/token_for.rb +123 -0
  287. data/lib/active_record/touch_later.rb +70 -0
  288. data/lib/active_record/transaction.rb +132 -0
  289. data/lib/active_record/transactions.rb +523 -0
  290. data/lib/active_record/translation.rb +22 -0
  291. data/lib/active_record/type/adapter_specific_registry.rb +144 -0
  292. data/lib/active_record/type/date.rb +9 -0
  293. data/lib/active_record/type/date_time.rb +9 -0
  294. data/lib/active_record/type/decimal_without_scale.rb +15 -0
  295. data/lib/active_record/type/hash_lookup_type_map.rb +57 -0
  296. data/lib/active_record/type/internal/timezone.rb +22 -0
  297. data/lib/active_record/type/json.rb +30 -0
  298. data/lib/active_record/type/serialized.rb +76 -0
  299. data/lib/active_record/type/text.rb +11 -0
  300. data/lib/active_record/type/time.rb +35 -0
  301. data/lib/active_record/type/type_map.rb +58 -0
  302. data/lib/active_record/type/unsigned_integer.rb +16 -0
  303. data/lib/active_record/type.rb +83 -0
  304. data/lib/active_record/type_caster/connection.rb +33 -0
  305. data/lib/active_record/type_caster/map.rb +23 -0
  306. data/lib/active_record/type_caster.rb +9 -0
  307. data/lib/active_record/validations/absence.rb +25 -0
  308. data/lib/active_record/validations/associated.rb +65 -0
  309. data/lib/active_record/validations/length.rb +26 -0
  310. data/lib/active_record/validations/numericality.rb +36 -0
  311. data/lib/active_record/validations/presence.rb +45 -0
  312. data/lib/active_record/validations/uniqueness.rb +295 -0
  313. data/lib/active_record/validations.rb +101 -0
  314. data/lib/active_record/version.rb +10 -0
  315. data/lib/active_record.rb +616 -0
  316. data/lib/arel/alias_predication.rb +9 -0
  317. data/lib/arel/attributes/attribute.rb +33 -0
  318. data/lib/arel/collectors/bind.rb +31 -0
  319. data/lib/arel/collectors/composite.rb +46 -0
  320. data/lib/arel/collectors/plain_string.rb +20 -0
  321. data/lib/arel/collectors/sql_string.rb +27 -0
  322. data/lib/arel/collectors/substitute_binds.rb +35 -0
  323. data/lib/arel/crud.rb +48 -0
  324. data/lib/arel/delete_manager.rb +32 -0
  325. data/lib/arel/errors.rb +19 -0
  326. data/lib/arel/expressions.rb +29 -0
  327. data/lib/arel/factory_methods.rb +53 -0
  328. data/lib/arel/filter_predications.rb +9 -0
  329. data/lib/arel/insert_manager.rb +48 -0
  330. data/lib/arel/math.rb +45 -0
  331. data/lib/arel/nodes/ascending.rb +23 -0
  332. data/lib/arel/nodes/binary.rb +125 -0
  333. data/lib/arel/nodes/bind_param.rb +44 -0
  334. data/lib/arel/nodes/bound_sql_literal.rb +65 -0
  335. data/lib/arel/nodes/case.rb +55 -0
  336. data/lib/arel/nodes/casted.rb +62 -0
  337. data/lib/arel/nodes/comment.rb +29 -0
  338. data/lib/arel/nodes/count.rb +12 -0
  339. data/lib/arel/nodes/cte.rb +36 -0
  340. data/lib/arel/nodes/delete_statement.rb +44 -0
  341. data/lib/arel/nodes/descending.rb +23 -0
  342. data/lib/arel/nodes/equality.rb +15 -0
  343. data/lib/arel/nodes/extract.rb +24 -0
  344. data/lib/arel/nodes/false.rb +16 -0
  345. data/lib/arel/nodes/filter.rb +10 -0
  346. data/lib/arel/nodes/fragments.rb +35 -0
  347. data/lib/arel/nodes/full_outer_join.rb +8 -0
  348. data/lib/arel/nodes/function.rb +45 -0
  349. data/lib/arel/nodes/grouping.rb +11 -0
  350. data/lib/arel/nodes/homogeneous_in.rb +68 -0
  351. data/lib/arel/nodes/in.rb +15 -0
  352. data/lib/arel/nodes/infix_operation.rb +92 -0
  353. data/lib/arel/nodes/inner_join.rb +8 -0
  354. data/lib/arel/nodes/insert_statement.rb +37 -0
  355. data/lib/arel/nodes/join_source.rb +20 -0
  356. data/lib/arel/nodes/leading_join.rb +8 -0
  357. data/lib/arel/nodes/matches.rb +18 -0
  358. data/lib/arel/nodes/named_function.rb +23 -0
  359. data/lib/arel/nodes/nary.rb +39 -0
  360. data/lib/arel/nodes/node.rb +161 -0
  361. data/lib/arel/nodes/node_expression.rb +13 -0
  362. data/lib/arel/nodes/ordering.rb +27 -0
  363. data/lib/arel/nodes/outer_join.rb +8 -0
  364. data/lib/arel/nodes/over.rb +15 -0
  365. data/lib/arel/nodes/regexp.rb +16 -0
  366. data/lib/arel/nodes/right_outer_join.rb +8 -0
  367. data/lib/arel/nodes/select_core.rb +67 -0
  368. data/lib/arel/nodes/select_statement.rb +41 -0
  369. data/lib/arel/nodes/sql_literal.rb +32 -0
  370. data/lib/arel/nodes/string_join.rb +11 -0
  371. data/lib/arel/nodes/table_alias.rb +35 -0
  372. data/lib/arel/nodes/terminal.rb +16 -0
  373. data/lib/arel/nodes/true.rb +16 -0
  374. data/lib/arel/nodes/unary.rb +44 -0
  375. data/lib/arel/nodes/unary_operation.rb +20 -0
  376. data/lib/arel/nodes/unqualified_column.rb +22 -0
  377. data/lib/arel/nodes/update_statement.rb +46 -0
  378. data/lib/arel/nodes/values_list.rb +9 -0
  379. data/lib/arel/nodes/window.rb +126 -0
  380. data/lib/arel/nodes/with.rb +11 -0
  381. data/lib/arel/nodes.rb +75 -0
  382. data/lib/arel/order_predications.rb +13 -0
  383. data/lib/arel/predications.rb +260 -0
  384. data/lib/arel/select_manager.rb +276 -0
  385. data/lib/arel/table.rb +121 -0
  386. data/lib/arel/tree_manager.rb +65 -0
  387. data/lib/arel/update_manager.rb +49 -0
  388. data/lib/arel/visitors/dot.rb +299 -0
  389. data/lib/arel/visitors/mysql.rb +111 -0
  390. data/lib/arel/visitors/postgresql.rb +99 -0
  391. data/lib/arel/visitors/sqlite.rb +38 -0
  392. data/lib/arel/visitors/to_sql.rb +1033 -0
  393. data/lib/arel/visitors/visitor.rb +45 -0
  394. data/lib/arel/visitors.rb +13 -0
  395. data/lib/arel/window_predications.rb +9 -0
  396. data/lib/arel.rb +73 -0
  397. data/lib/rails/generators/active_record/application_record/USAGE +8 -0
  398. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +26 -0
  399. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +5 -0
  400. data/lib/rails/generators/active_record/migration/migration_generator.rb +76 -0
  401. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +29 -0
  402. data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +48 -0
  403. data/lib/rails/generators/active_record/migration.rb +54 -0
  404. data/lib/rails/generators/active_record/model/USAGE +113 -0
  405. data/lib/rails/generators/active_record/model/model_generator.rb +94 -0
  406. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
  407. data/lib/rails/generators/active_record/model/templates/model.rb.tt +22 -0
  408. data/lib/rails/generators/active_record/model/templates/module.rb.tt +7 -0
  409. data/lib/rails/generators/active_record/multi_db/multi_db_generator.rb +16 -0
  410. data/lib/rails/generators/active_record/multi_db/templates/multi_db.rb.tt +44 -0
  411. data/lib/rails/generators/active_record.rb +19 -0
  412. metadata +505 -0
@@ -0,0 +1,681 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_record/database_configurations"
4
+
5
+ module ActiveRecord
6
+ module Tasks # :nodoc:
7
+ class DatabaseNotSupported < StandardError; end # :nodoc:
8
+
9
+ # = Active Record \DatabaseTasks
10
+ #
11
+ # ActiveRecord::Tasks::DatabaseTasks is a utility class, which encapsulates
12
+ # logic behind common tasks used to manage database and migrations.
13
+ #
14
+ # The tasks defined here are used with \Rails commands provided by Active Record.
15
+ #
16
+ # In order to use DatabaseTasks, a few config values need to be set. All the needed
17
+ # config values are set by \Rails already, so it's necessary to do it only if you
18
+ # want to change the defaults or when you want to use Active Record outside of \Rails
19
+ # (in such case after configuring the database tasks, you can also use the rake tasks
20
+ # defined in Active Record).
21
+ #
22
+ # The possible config values are:
23
+ #
24
+ # * +env+: current environment (like Rails.env).
25
+ # * +database_configuration+: configuration of your databases (as in +config/database.yml+).
26
+ # * +db_dir+: your +db+ directory.
27
+ # * +fixtures_path+: a path to fixtures directory.
28
+ # * +migrations_paths+: a list of paths to directories with migrations.
29
+ # * +seed_loader+: an object which will load seeds, it needs to respond to the +load_seed+ method.
30
+ # * +root+: a path to the root of the application.
31
+ #
32
+ # Example usage of DatabaseTasks outside \Rails could look as such:
33
+ #
34
+ # include ActiveRecord::Tasks
35
+ # DatabaseTasks.database_configuration = YAML.load_file('my_database_config.yml')
36
+ # DatabaseTasks.db_dir = 'db'
37
+ # # other settings...
38
+ #
39
+ # DatabaseTasks.create_current('production')
40
+ module DatabaseTasks
41
+ ##
42
+ # :singleton-method:
43
+ # Extra flags passed to database CLI tool (mysqldump/pg_dump) when calling db:schema:dump
44
+ # It can be used as a string/array (the typical case) or a hash (when you use multiple adapters)
45
+ # Example:
46
+ # ActiveRecord::Tasks::DatabaseTasks.structure_dump_flags = {
47
+ # mysql2: ['--no-defaults', '--skip-add-drop-table'],
48
+ # postgres: '--no-tablespaces'
49
+ # }
50
+ mattr_accessor :structure_dump_flags, instance_accessor: false
51
+
52
+ ##
53
+ # :singleton-method:
54
+ # Extra flags passed to database CLI tool when calling db:schema:load
55
+ # It can be used as a string/array (the typical case) or a hash (when you use multiple adapters)
56
+ mattr_accessor :structure_load_flags, instance_accessor: false
57
+
58
+ extend self
59
+
60
+ attr_writer :db_dir, :migrations_paths, :fixtures_path, :root, :env, :seed_loader
61
+ attr_accessor :database_configuration
62
+
63
+ LOCAL_HOSTS = ["127.0.0.1", "localhost"]
64
+
65
+ def check_protected_environments!(environment = env)
66
+ return if ENV["DISABLE_DATABASE_ENVIRONMENT_CHECK"]
67
+
68
+ configs_for(env_name: environment).each do |db_config|
69
+ check_current_protected_environment!(db_config)
70
+ end
71
+ end
72
+
73
+ def register_task(pattern, task)
74
+ @tasks ||= {}
75
+ @tasks[pattern] = task
76
+ end
77
+
78
+ register_task(/mysql/, "ActiveRecord::Tasks::MySQLDatabaseTasks")
79
+ register_task(/trilogy/, "ActiveRecord::Tasks::MySQLDatabaseTasks")
80
+ register_task(/postgresql/, "ActiveRecord::Tasks::PostgreSQLDatabaseTasks")
81
+ register_task(/sqlite/, "ActiveRecord::Tasks::SQLiteDatabaseTasks")
82
+
83
+ def db_dir
84
+ @db_dir ||= Rails.application.config.paths["db"].first
85
+ end
86
+
87
+ def migrations_paths
88
+ @migrations_paths ||= Rails.application.paths["db/migrate"].to_a
89
+ end
90
+
91
+ def fixtures_path
92
+ @fixtures_path ||= if ENV["FIXTURES_PATH"]
93
+ File.join(root, ENV["FIXTURES_PATH"])
94
+ else
95
+ File.join(root, "test", "fixtures")
96
+ end
97
+ end
98
+
99
+ def root
100
+ @root ||= Rails.root
101
+ end
102
+
103
+ def env
104
+ @env ||= Rails.env
105
+ end
106
+
107
+ def name
108
+ @name ||= "primary"
109
+ end
110
+
111
+ def seed_loader
112
+ @seed_loader ||= Rails.application
113
+ end
114
+
115
+ def create(configuration, *arguments)
116
+ db_config = resolve_configuration(configuration)
117
+ database_adapter_for(db_config, *arguments).create
118
+ $stdout.puts "Created database '#{db_config.database}'" if verbose?
119
+ rescue DatabaseAlreadyExists
120
+ $stderr.puts "Database '#{db_config.database}' already exists" if verbose?
121
+ rescue Exception => error
122
+ $stderr.puts error
123
+ $stderr.puts "Couldn't create '#{db_config.database}' database. Please check your configuration."
124
+ raise
125
+ end
126
+
127
+ def create_all
128
+ db_config = migration_connection.pool.db_config
129
+
130
+ each_local_configuration { |db_config| create(db_config) }
131
+
132
+ migration_class.establish_connection(db_config)
133
+ end
134
+
135
+ def setup_initial_database_yaml # :nodoc:
136
+ return {} unless defined?(Rails)
137
+
138
+ Rails.application.config.load_database_yaml
139
+ end
140
+
141
+ def for_each(databases) # :nodoc:
142
+ return {} unless defined?(Rails)
143
+
144
+ database_configs = ActiveRecord::DatabaseConfigurations.new(databases).configs_for(env_name: Rails.env)
145
+
146
+ # if this is a single database application we don't want tasks for each primary database
147
+ return if database_configs.count == 1
148
+
149
+ database_configs.each do |db_config|
150
+ next unless db_config.database_tasks?
151
+
152
+ yield db_config.name
153
+ end
154
+ end
155
+
156
+ def raise_for_multi_db(environment = env, command:) # :nodoc:
157
+ db_configs = configs_for(env_name: environment)
158
+
159
+ if db_configs.count > 1
160
+ dbs_list = []
161
+
162
+ db_configs.each do |db|
163
+ dbs_list << "#{command}:#{db.name}"
164
+ end
165
+
166
+ raise "You're using a multiple database application. To use `#{command}` you must run the namespaced task with a VERSION. Available tasks are #{dbs_list.to_sentence}."
167
+ end
168
+ end
169
+
170
+ def create_current(environment = env, name = nil)
171
+ each_current_configuration(environment, name) { |db_config| create(db_config) }
172
+
173
+ migration_class.establish_connection(environment.to_sym)
174
+ end
175
+
176
+ def prepare_all
177
+ seed = false
178
+ dump_db_configs = []
179
+
180
+ each_current_configuration(env) do |db_config|
181
+ database_initialized = initialize_database(db_config)
182
+
183
+ seed = true if database_initialized
184
+ end
185
+
186
+ each_current_environment(env) do |environment|
187
+ db_configs_with_versions(environment).sort.each do |version, db_configs|
188
+ dump_db_configs |= db_configs
189
+
190
+ db_configs.each do |db_config|
191
+ with_temporary_pool(db_config) do
192
+ migrate(version)
193
+ end
194
+ end
195
+ end
196
+ end
197
+
198
+ # Dump schema for databases that were migrated.
199
+ if ActiveRecord.dump_schema_after_migration
200
+ dump_db_configs.each do |db_config|
201
+ with_temporary_pool(db_config) do
202
+ dump_schema(db_config)
203
+ end
204
+ end
205
+ end
206
+
207
+ load_seed if seed
208
+ end
209
+
210
+ def drop(configuration, *arguments)
211
+ db_config = resolve_configuration(configuration)
212
+ database_adapter_for(db_config, *arguments).drop
213
+ $stdout.puts "Dropped database '#{db_config.database}'" if verbose?
214
+ rescue ActiveRecord::NoDatabaseError
215
+ $stderr.puts "Database '#{db_config.database}' does not exist"
216
+ rescue Exception => error
217
+ $stderr.puts error
218
+ $stderr.puts "Couldn't drop database '#{db_config.database}'"
219
+ raise
220
+ end
221
+
222
+ def drop_all
223
+ each_local_configuration { |db_config| drop(db_config) }
224
+ end
225
+
226
+ def drop_current(environment = env)
227
+ each_current_configuration(environment) { |db_config| drop(db_config) }
228
+ end
229
+
230
+ def truncate_tables(db_config)
231
+ with_temporary_connection(db_config) do |conn|
232
+ conn.truncate_tables(*conn.tables)
233
+ end
234
+ end
235
+ private :truncate_tables
236
+
237
+ def truncate_all(environment = env)
238
+ configs_for(env_name: environment).each do |db_config|
239
+ truncate_tables(db_config)
240
+ end
241
+ end
242
+
243
+ def migrate(version = nil)
244
+ scope = ENV["SCOPE"]
245
+ verbose_was, Migration.verbose = Migration.verbose, verbose?
246
+
247
+ check_target_version
248
+
249
+ initialize_database(migration_connection_pool.db_config)
250
+
251
+ migration_connection_pool.migration_context.migrate(target_version) do |migration|
252
+ if version.blank?
253
+ scope.blank? || scope == migration.scope
254
+ else
255
+ migration.version == version
256
+ end
257
+ end.tap do |migrations_ran|
258
+ Migration.write("No migrations ran. (using #{scope} scope)") if scope.present? && migrations_ran.empty?
259
+ end
260
+
261
+ migration_connection_pool.schema_cache.clear!
262
+ ensure
263
+ Migration.verbose = verbose_was
264
+ end
265
+
266
+ def db_configs_with_versions(environment = env) # :nodoc:
267
+ db_configs_with_versions = Hash.new { |h, k| h[k] = [] }
268
+
269
+ with_temporary_pool_for_each(env: environment) do |pool|
270
+ db_config = pool.db_config
271
+ versions_to_run = pool.migration_context.pending_migration_versions
272
+ target_version = ActiveRecord::Tasks::DatabaseTasks.target_version
273
+
274
+ versions_to_run.each do |version|
275
+ next if target_version && target_version != version
276
+ db_configs_with_versions[version] << db_config
277
+ end
278
+ end
279
+
280
+ db_configs_with_versions
281
+ end
282
+
283
+ def migrate_status
284
+ unless migration_connection_pool.schema_migration.table_exists?
285
+ Kernel.abort "Schema migrations table does not exist yet."
286
+ end
287
+
288
+ # output
289
+ puts "\ndatabase: #{migration_connection_pool.db_config.database}\n\n"
290
+ puts "#{'Status'.center(8)} #{'Migration ID'.ljust(14)} Migration Name"
291
+ puts "-" * 50
292
+ migration_connection_pool.migration_context.migrations_status.each do |status, version, name|
293
+ puts "#{status.center(8)} #{version.ljust(14)} #{name}"
294
+ end
295
+ puts
296
+ end
297
+
298
+ def check_target_version
299
+ if target_version && !Migration.valid_version_format?(ENV["VERSION"])
300
+ raise "Invalid format of target version: `VERSION=#{ENV['VERSION']}`"
301
+ end
302
+ end
303
+
304
+ def target_version
305
+ ENV["VERSION"].to_i if ENV["VERSION"] && !ENV["VERSION"].empty?
306
+ end
307
+
308
+ def charset_current(env_name = env, db_name = name)
309
+ db_config = configs_for(env_name: env_name, name: db_name)
310
+ charset(db_config)
311
+ end
312
+
313
+ def charset(configuration, *arguments)
314
+ db_config = resolve_configuration(configuration)
315
+ database_adapter_for(db_config, *arguments).charset
316
+ end
317
+
318
+ def collation_current(env_name = env, db_name = name)
319
+ db_config = configs_for(env_name: env_name, name: db_name)
320
+ collation(db_config)
321
+ end
322
+
323
+ def collation(configuration, *arguments)
324
+ db_config = resolve_configuration(configuration)
325
+ database_adapter_for(db_config, *arguments).collation
326
+ end
327
+
328
+ def purge(configuration)
329
+ db_config = resolve_configuration(configuration)
330
+ database_adapter_for(db_config).purge
331
+ end
332
+
333
+ def purge_all
334
+ each_local_configuration { |db_config| purge(db_config) }
335
+ end
336
+
337
+ def purge_current(environment = env)
338
+ each_current_configuration(environment) { |db_config| purge(db_config) }
339
+
340
+ migration_class.establish_connection(environment.to_sym)
341
+ end
342
+
343
+ def structure_dump(configuration, *arguments)
344
+ db_config = resolve_configuration(configuration)
345
+ filename = arguments.delete_at(0)
346
+ flags = structure_dump_flags_for(db_config.adapter)
347
+ database_adapter_for(db_config, *arguments).structure_dump(filename, flags)
348
+ end
349
+
350
+ def structure_load(configuration, *arguments)
351
+ db_config = resolve_configuration(configuration)
352
+ filename = arguments.delete_at(0)
353
+ flags = structure_load_flags_for(db_config.adapter)
354
+ database_adapter_for(db_config, *arguments).structure_load(filename, flags)
355
+ end
356
+
357
+ def load_schema(db_config, format = ActiveRecord.schema_format, file = nil) # :nodoc:
358
+ file ||= schema_dump_path(db_config, format)
359
+ return unless file
360
+
361
+ verbose_was, Migration.verbose = Migration.verbose, verbose? && ENV["VERBOSE"]
362
+ check_schema_file(file)
363
+
364
+ case format
365
+ when :ruby
366
+ load(file)
367
+ when :sql
368
+ structure_load(db_config, file)
369
+ else
370
+ raise ArgumentError, "unknown format #{format.inspect}"
371
+ end
372
+
373
+ migration_connection_pool.internal_metadata.create_table_and_set_flags(db_config.env_name, schema_sha1(file))
374
+ ensure
375
+ Migration.verbose = verbose_was
376
+ end
377
+
378
+ def schema_up_to_date?(configuration, format = ActiveRecord.schema_format, file = nil)
379
+ db_config = resolve_configuration(configuration)
380
+
381
+ file ||= schema_dump_path(db_config)
382
+
383
+ return true unless file && File.exist?(file)
384
+
385
+ with_temporary_pool(db_config) do |pool|
386
+ internal_metadata = pool.internal_metadata
387
+ return false unless internal_metadata.enabled?
388
+ return false unless internal_metadata.table_exists?
389
+
390
+ internal_metadata[:schema_sha1] == schema_sha1(file)
391
+ end
392
+ end
393
+
394
+ def reconstruct_from_schema(db_config, format = ActiveRecord.schema_format, file = nil) # :nodoc:
395
+ file ||= schema_dump_path(db_config, format)
396
+
397
+ check_schema_file(file) if file
398
+
399
+ with_temporary_pool(db_config, clobber: true) do
400
+ if schema_up_to_date?(db_config, format, file)
401
+ truncate_tables(db_config) unless ENV["SKIP_TEST_DATABASE_TRUNCATE"]
402
+ else
403
+ purge(db_config)
404
+ load_schema(db_config, format, file)
405
+ end
406
+ rescue ActiveRecord::NoDatabaseError
407
+ create(db_config)
408
+ load_schema(db_config, format, file)
409
+ end
410
+ end
411
+
412
+ def dump_schema(db_config, format = ActiveRecord.schema_format) # :nodoc:
413
+ return unless db_config.schema_dump
414
+
415
+ require "active_record/schema_dumper"
416
+ filename = schema_dump_path(db_config, format)
417
+ return unless filename
418
+
419
+ FileUtils.mkdir_p(db_dir)
420
+ case format
421
+ when :ruby
422
+ File.open(filename, "w:utf-8") do |file|
423
+ ActiveRecord::SchemaDumper.dump(migration_connection_pool, file)
424
+ end
425
+ when :sql
426
+ structure_dump(db_config, filename)
427
+ if migration_connection_pool.schema_migration.table_exists?
428
+ File.open(filename, "a") do |f|
429
+ f.puts migration_connection.dump_schema_information
430
+ f.print "\n"
431
+ end
432
+ end
433
+ end
434
+ end
435
+
436
+ def schema_dump_path(db_config, format = ActiveRecord.schema_format)
437
+ return ENV["SCHEMA"] if ENV["SCHEMA"]
438
+
439
+ filename = db_config.schema_dump(format)
440
+ return unless filename
441
+
442
+ if File.dirname(filename) == ActiveRecord::Tasks::DatabaseTasks.db_dir
443
+ filename
444
+ else
445
+ File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, filename)
446
+ end
447
+ end
448
+
449
+ def cache_dump_filename(db_config_or_name, schema_cache_path: nil)
450
+ if db_config_or_name.is_a?(DatabaseConfigurations::DatabaseConfig)
451
+ schema_cache_path ||
452
+ db_config_or_name.schema_cache_path ||
453
+ schema_cache_env ||
454
+ db_config_or_name.default_schema_cache_path(ActiveRecord::Tasks::DatabaseTasks.db_dir)
455
+ else
456
+ ActiveRecord.deprecator.warn(<<~MSG.squish)
457
+ Passing a database name to `cache_dump_filename` is deprecated and will be removed in Rails 8.0. Pass a
458
+ `ActiveRecord::DatabaseConfigurations::DatabaseConfig` object instead.
459
+ MSG
460
+
461
+ filename = if ActiveRecord::Base.configurations.primary?(db_config_or_name)
462
+ "schema_cache.yml"
463
+ else
464
+ "#{db_config_or_name}_schema_cache.yml"
465
+ end
466
+
467
+ schema_cache_path || schema_cache_env || File.join(ActiveRecord::Tasks::DatabaseTasks.db_dir, filename)
468
+ end
469
+ end
470
+
471
+ def load_schema_current(format = ActiveRecord.schema_format, file = nil, environment = env)
472
+ each_current_configuration(environment) do |db_config|
473
+ with_temporary_connection(db_config) do
474
+ load_schema(db_config, format, file)
475
+ end
476
+ end
477
+ end
478
+
479
+ def check_schema_file(filename)
480
+ unless File.exist?(filename)
481
+ message = +%{#{filename} doesn't exist yet. Run `bin/rails db:migrate` to create it, then try again.}
482
+ message << %{ If you do not intend to use a database, you should instead alter #{Rails.root}/config/application.rb to limit the frameworks that will be loaded.} if defined?(::Rails.root)
483
+ Kernel.abort message
484
+ end
485
+ end
486
+
487
+ def load_seed
488
+ if seed_loader
489
+ seed_loader.load_seed
490
+ else
491
+ raise "You tried to load seed data, but no seed loader is specified. Please specify seed " \
492
+ "loader with ActiveRecord::Tasks::DatabaseTasks.seed_loader = your_seed_loader\n" \
493
+ "Seed loader should respond to load_seed method"
494
+ end
495
+ end
496
+
497
+ # Dumps the schema cache in YAML format for the connection into the file
498
+ #
499
+ # ==== Examples
500
+ # ActiveRecord::Tasks::DatabaseTasks.dump_schema_cache(ActiveRecord::Base.lease_connection, "tmp/schema_dump.yaml")
501
+ def dump_schema_cache(conn_or_pool, filename)
502
+ conn_or_pool.schema_cache.dump_to(filename)
503
+ end
504
+
505
+ def clear_schema_cache(filename)
506
+ FileUtils.rm_f filename, verbose: false
507
+ end
508
+
509
+ def with_temporary_pool_for_each(env: ActiveRecord::Tasks::DatabaseTasks.env, name: nil, clobber: false, &block) # :nodoc:
510
+ if name
511
+ db_config = ActiveRecord::Base.configurations.configs_for(env_name: env, name: name)
512
+ with_temporary_pool(db_config, clobber: clobber, &block)
513
+ else
514
+ ActiveRecord::Base.configurations.configs_for(env_name: env, name: name).each do |db_config|
515
+ with_temporary_pool(db_config, clobber: clobber, &block)
516
+ end
517
+ end
518
+ end
519
+
520
+ def with_temporary_connection(db_config, clobber: false, &block) # :nodoc:
521
+ with_temporary_pool(db_config, clobber: clobber) do |pool|
522
+ pool.with_connection(&block)
523
+ end
524
+ end
525
+
526
+ def migration_class # :nodoc:
527
+ ActiveRecord::Base
528
+ end
529
+
530
+ def migration_connection # :nodoc:
531
+ migration_class.lease_connection
532
+ end
533
+
534
+ def migration_connection_pool # :nodoc:
535
+ migration_class.connection_pool
536
+ end
537
+
538
+ private
539
+ def schema_cache_env
540
+ if ENV["SCHEMA_CACHE"]
541
+ ActiveRecord.deprecator.warn(<<~MSG.squish)
542
+ Setting `ENV["SCHEMA_CACHE"]` is deprecated and will be removed in Rails 8.0.
543
+ Configure the `:schema_cache_path` in the database configuration instead.
544
+ MSG
545
+
546
+ nil
547
+ end
548
+ end
549
+
550
+ def with_temporary_pool(db_config, clobber: false)
551
+ original_db_config = migration_class.connection_db_config
552
+ pool = migration_class.connection_handler.establish_connection(db_config, clobber: clobber)
553
+
554
+ yield pool
555
+ ensure
556
+ migration_class.connection_handler.establish_connection(original_db_config, clobber: clobber)
557
+ end
558
+
559
+ def configs_for(**options)
560
+ Base.configurations.configs_for(**options)
561
+ end
562
+
563
+ def resolve_configuration(configuration)
564
+ Base.configurations.resolve(configuration)
565
+ end
566
+
567
+ def verbose?
568
+ ENV["VERBOSE"] ? ENV["VERBOSE"] != "false" : true
569
+ end
570
+
571
+ # Create a new instance for the specified db configuration object
572
+ # For classes that have been converted to use db_config objects, pass a
573
+ # `DatabaseConfig`, otherwise pass a `Hash`
574
+ def database_adapter_for(db_config, *arguments)
575
+ klass = class_for_adapter(db_config.adapter)
576
+ converted = klass.respond_to?(:using_database_configurations?) && klass.using_database_configurations?
577
+
578
+ config = converted ? db_config : db_config.configuration_hash
579
+ klass.new(config, *arguments)
580
+ end
581
+
582
+ def class_for_adapter(adapter)
583
+ _key, task = @tasks.reverse_each.detect { |pattern, _task| adapter[pattern] }
584
+ unless task
585
+ raise DatabaseNotSupported, "Rake tasks not supported by '#{adapter}' adapter"
586
+ end
587
+ task.is_a?(String) ? task.constantize : task
588
+ end
589
+
590
+ def each_current_configuration(environment, name = nil)
591
+ each_current_environment(environment) do |env|
592
+ configs_for(env_name: env).each do |db_config|
593
+ next if name && name != db_config.name
594
+
595
+ yield db_config
596
+ end
597
+ end
598
+ end
599
+
600
+ def each_current_environment(environment, &block)
601
+ environments = [environment]
602
+ environments << "test" if environment == "development" && !ENV["SKIP_TEST_DATABASE"] && !ENV["DATABASE_URL"]
603
+ environments.each(&block)
604
+ end
605
+
606
+ def each_local_configuration
607
+ configs_for.each do |db_config|
608
+ next unless db_config.database
609
+
610
+ if local_database?(db_config)
611
+ yield db_config
612
+ else
613
+ $stderr.puts "This task only modifies local databases. #{db_config.database} is on a remote host."
614
+ end
615
+ end
616
+ end
617
+
618
+ def local_database?(db_config)
619
+ host = db_config.host
620
+ host.blank? || LOCAL_HOSTS.include?(host)
621
+ end
622
+
623
+ def schema_sha1(file)
624
+ OpenSSL::Digest::SHA1.hexdigest(File.read(file))
625
+ end
626
+
627
+ def structure_dump_flags_for(adapter)
628
+ if structure_dump_flags.is_a?(Hash)
629
+ structure_dump_flags[adapter.to_sym]
630
+ else
631
+ structure_dump_flags
632
+ end
633
+ end
634
+
635
+ def structure_load_flags_for(adapter)
636
+ if structure_load_flags.is_a?(Hash)
637
+ structure_load_flags[adapter.to_sym]
638
+ else
639
+ structure_load_flags
640
+ end
641
+ end
642
+
643
+ def check_current_protected_environment!(db_config)
644
+ with_temporary_pool(db_config) do |pool|
645
+ migration_context = pool.migration_context
646
+ current = migration_context.current_environment
647
+ stored = migration_context.last_stored_environment
648
+
649
+ if migration_context.protected_environment?
650
+ raise ActiveRecord::ProtectedEnvironmentError.new(stored)
651
+ end
652
+
653
+ if stored && stored != current
654
+ raise ActiveRecord::EnvironmentMismatchError.new(current: current, stored: stored)
655
+ end
656
+ rescue ActiveRecord::NoDatabaseError
657
+ end
658
+ end
659
+
660
+ def initialize_database(db_config)
661
+ with_temporary_pool(db_config) do
662
+ begin
663
+ database_already_initialized = migration_connection_pool.schema_migration.table_exists?
664
+ rescue ActiveRecord::NoDatabaseError
665
+ create(db_config)
666
+ retry
667
+ end
668
+
669
+ unless database_already_initialized
670
+ schema_dump_path = schema_dump_path(db_config)
671
+ if schema_dump_path && File.exist?(schema_dump_path)
672
+ load_schema(db_config, ActiveRecord.schema_format, nil)
673
+ end
674
+ end
675
+
676
+ !database_already_initialized
677
+ end
678
+ end
679
+ end
680
+ end
681
+ end