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,230 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ # = Active Record Counter Cache
5
+ module CounterCache
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ class_attribute :_counter_cache_columns, instance_accessor: false, default: []
10
+ class_attribute :counter_cached_association_names, instance_writer: false, default: []
11
+ end
12
+
13
+ module ClassMethods
14
+ # Resets one or more counter caches to their correct value using an SQL
15
+ # count query. This is useful when adding new counter caches, or if the
16
+ # counter has been corrupted or modified directly by SQL.
17
+ #
18
+ # ==== Parameters
19
+ #
20
+ # * +id+ - The id of the object you wish to reset a counter on.
21
+ # * +counters+ - One or more association counters to reset. Association name or counter name can be given.
22
+ # * <tt>:touch</tt> - Touch timestamp columns when updating.
23
+ # Pass +true+ to touch +updated_at+ and/or +updated_on+. Pass a symbol to
24
+ # touch that column or an array of symbols to touch just those ones.
25
+ #
26
+ # ==== Examples
27
+ #
28
+ # # For the Post with id #1, reset the comments_count
29
+ # Post.reset_counters(1, :comments)
30
+ #
31
+ # # Like above, but also touch the +updated_at+ and/or +updated_on+
32
+ # # attributes.
33
+ # Post.reset_counters(1, :comments, touch: true)
34
+ def reset_counters(id, *counters, touch: nil)
35
+ object = find(id)
36
+
37
+ updates = {}
38
+ counters.each do |counter_association|
39
+ has_many_association = _reflect_on_association(counter_association)
40
+ unless has_many_association
41
+ has_many = reflect_on_all_associations(:has_many)
42
+ has_many_association = has_many.find { |association| association.counter_cache_column && association.counter_cache_column.to_sym == counter_association.to_sym }
43
+ counter_association = has_many_association.plural_name if has_many_association
44
+ end
45
+ raise ArgumentError, "'#{name}' has no association called '#{counter_association}'" unless has_many_association
46
+
47
+ if has_many_association.is_a? ActiveRecord::Reflection::ThroughReflection
48
+ has_many_association = has_many_association.through_reflection
49
+ end
50
+
51
+ foreign_key = has_many_association.foreign_key.to_s
52
+ child_class = has_many_association.klass
53
+ reflection = child_class._reflections.values.find { |e| e.belongs_to? && e.foreign_key.to_s == foreign_key && e.options[:counter_cache].present? }
54
+ counter_name = reflection.counter_cache_column
55
+
56
+ count_was = object.send(counter_name)
57
+ count = object.send(counter_association).count(:all)
58
+ updates[counter_name] = count if count != count_was
59
+ end
60
+
61
+ if touch
62
+ names = touch if touch != true
63
+ names = Array.wrap(names)
64
+ options = names.extract_options!
65
+ touch_updates = touch_attributes_with_time(*names, **options)
66
+ updates.merge!(touch_updates)
67
+ end
68
+
69
+ unscoped.where(primary_key => [object.id]).update_all(updates) if updates.any?
70
+
71
+ true
72
+ end
73
+
74
+ # A generic "counter updater" implementation, intended primarily to be
75
+ # used by #increment_counter and #decrement_counter, but which may also
76
+ # be useful on its own. It simply does a direct SQL update for the record
77
+ # with the given ID, altering the given hash of counters by the amount
78
+ # given by the corresponding value:
79
+ #
80
+ # ==== Parameters
81
+ #
82
+ # * +id+ - The id of the object you wish to update a counter on or an array of ids.
83
+ # * +counters+ - A Hash containing the names of the fields
84
+ # to update as keys and the amount to update the field by as values.
85
+ # * <tt>:touch</tt> option - Touch timestamp columns when updating.
86
+ # If attribute names are passed, they are updated along with updated_at/on
87
+ # attributes.
88
+ #
89
+ # ==== Examples
90
+ #
91
+ # # For the Post with id of 5, decrement the comments_count by 1, and
92
+ # # increment the actions_count by 1
93
+ # Post.update_counters 5, comments_count: -1, actions_count: 1
94
+ # # Executes the following SQL:
95
+ # # UPDATE posts
96
+ # # SET comments_count = COALESCE(comments_count, 0) - 1,
97
+ # # actions_count = COALESCE(actions_count, 0) + 1
98
+ # # WHERE id = 5
99
+ #
100
+ # # For the Posts with id of 10 and 15, increment the comments_count by 1
101
+ # Post.update_counters [10, 15], comments_count: 1
102
+ # # Executes the following SQL:
103
+ # # UPDATE posts
104
+ # # SET comments_count = COALESCE(comments_count, 0) + 1
105
+ # # WHERE id IN (10, 15)
106
+ #
107
+ # # For the Posts with id of 10 and 15, increment the comments_count by 1
108
+ # # and update the updated_at value for each counter.
109
+ # Post.update_counters [10, 15], comments_count: 1, touch: true
110
+ # # Executes the following SQL:
111
+ # # UPDATE posts
112
+ # # SET comments_count = COALESCE(comments_count, 0) + 1,
113
+ # # `updated_at` = '2016-10-13T09:59:23-05:00'
114
+ # # WHERE id IN (10, 15)
115
+ def update_counters(id, counters)
116
+ id = [id] if composite_primary_key? && id.is_a?(Array) && !id[0].is_a?(Array)
117
+ unscoped.where!(primary_key => id).update_counters(counters)
118
+ end
119
+
120
+ # Increment a numeric field by one, via a direct SQL update.
121
+ #
122
+ # This method is used primarily for maintaining counter_cache columns that are
123
+ # used to store aggregate values. For example, a +DiscussionBoard+ may cache
124
+ # posts_count and comments_count to avoid running an SQL query to calculate the
125
+ # number of posts and comments there are, each time it is displayed.
126
+ #
127
+ # ==== Parameters
128
+ #
129
+ # * +counter_name+ - The name of the field that should be incremented.
130
+ # * +id+ - The id of the object that should be incremented or an array of ids.
131
+ # * <tt>:by</tt> - The amount by which to increment the value. Defaults to +1+.
132
+ # * <tt>:touch</tt> - Touch timestamp columns when updating.
133
+ # Pass +true+ to touch +updated_at+ and/or +updated_on+. Pass a symbol to
134
+ # touch that column or an array of symbols to touch just those ones.
135
+ #
136
+ # ==== Examples
137
+ #
138
+ # # Increment the posts_count column for the record with an id of 5
139
+ # DiscussionBoard.increment_counter(:posts_count, 5)
140
+ #
141
+ # # Increment the posts_count column for the record with an id of 5
142
+ # # by a specific amount.
143
+ # DiscussionBoard.increment_counter(:posts_count, 5, by: 3)
144
+ #
145
+ # # Increment the posts_count column for the record with an id of 5
146
+ # # and update the updated_at value.
147
+ # DiscussionBoard.increment_counter(:posts_count, 5, touch: true)
148
+ def increment_counter(counter_name, id, by: 1, touch: nil)
149
+ update_counters(id, counter_name => by, touch: touch)
150
+ end
151
+
152
+ # Decrement a numeric field by one, via a direct SQL update.
153
+ #
154
+ # This works the same as #increment_counter but reduces the column value by
155
+ # 1 instead of increasing it.
156
+ #
157
+ # ==== Parameters
158
+ #
159
+ # * +counter_name+ - The name of the field that should be decremented.
160
+ # * +id+ - The id of the object that should be decremented or an array of ids.
161
+ # * <tt>:by</tt> - The amount by which to decrement the value. Defaults to +1+.
162
+ # * <tt>:touch</tt> - Touch timestamp columns when updating.
163
+ # Pass +true+ to touch +updated_at+ and/or +updated_on+. Pass a symbol to
164
+ # touch that column or an array of symbols to touch just those ones.
165
+ #
166
+ # ==== Examples
167
+ #
168
+ # # Decrement the posts_count column for the record with an id of 5
169
+ # DiscussionBoard.decrement_counter(:posts_count, 5)
170
+ #
171
+ # # Decrement the posts_count column for the record with an id of 5
172
+ # by a specific amount.
173
+ # DiscussionBoard.decrement_counter(:posts_count, 5, by: 3)
174
+ #
175
+ # # Decrement the posts_count column for the record with an id of 5
176
+ # # and update the updated_at value.
177
+ # DiscussionBoard.decrement_counter(:posts_count, 5, touch: true)
178
+ def decrement_counter(counter_name, id, by: 1, touch: nil)
179
+ update_counters(id, counter_name => -by, touch: touch)
180
+ end
181
+
182
+ def counter_cache_column?(name) # :nodoc:
183
+ _counter_cache_columns.include?(name)
184
+ end
185
+
186
+ def load_schema! # :nodoc:
187
+ super
188
+
189
+ association_names = _reflections.filter_map do |name, reflection|
190
+ next unless reflection.belongs_to? && reflection.counter_cache_column
191
+
192
+ name.to_sym
193
+ end
194
+
195
+ self.counter_cached_association_names |= association_names
196
+ end
197
+ end
198
+
199
+ private
200
+ def _create_record(attribute_names = self.attribute_names)
201
+ id = super
202
+
203
+ counter_cached_association_names.each do |association_name|
204
+ association(association_name).increment_counters
205
+ end
206
+
207
+ id
208
+ end
209
+
210
+ def destroy_row
211
+ affected_rows = super
212
+
213
+ if affected_rows > 0
214
+ counter_cached_association_names.each do |association_name|
215
+ association = association(association_name)
216
+
217
+ unless destroyed_by_association && _foreign_keys_equal?(destroyed_by_association.foreign_key, association.reflection.foreign_key)
218
+ association.decrement_counters
219
+ end
220
+ end
221
+ end
222
+
223
+ affected_rows
224
+ end
225
+
226
+ def _foreign_keys_equal?(fkey1, fkey2)
227
+ fkey1 == fkey2 || Array(fkey1).map(&:to_sym) == Array(fkey2).map(&:to_sym)
228
+ end
229
+ end
230
+ end
@@ -0,0 +1,105 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "uri"
4
+ require "active_support/core_ext/enumerable"
5
+ require "active_support/core_ext/hash/reverse_merge"
6
+
7
+ module ActiveRecord
8
+ class DatabaseConfigurations
9
+ # Expands a connection string into a hash.
10
+ class ConnectionUrlResolver # :nodoc:
11
+ # == Example
12
+ #
13
+ # url = "postgresql://foo:bar@localhost:9000/foo_test?pool=5&timeout=3000"
14
+ # ConnectionUrlResolver.new(url).to_hash
15
+ # # => {
16
+ # adapter: "postgresql",
17
+ # host: "localhost",
18
+ # port: 9000,
19
+ # database: "foo_test",
20
+ # username: "foo",
21
+ # password: "bar",
22
+ # pool: "5",
23
+ # timeout: "3000"
24
+ # }
25
+ def initialize(url)
26
+ raise "Database URL cannot be empty" if url.blank?
27
+ @uri = uri_parser.parse(url)
28
+ @adapter = resolved_adapter
29
+
30
+ if @uri.opaque
31
+ @uri.opaque, @query = @uri.opaque.split("?", 2)
32
+ else
33
+ @query = @uri.query
34
+ end
35
+ end
36
+
37
+ # Converts the given URL to a full connection hash.
38
+ def to_hash
39
+ config = raw_config.compact_blank
40
+ config.map { |key, value| config[key] = uri_parser.unescape(value) if value.is_a? String }
41
+ config
42
+ end
43
+
44
+ private
45
+ attr_reader :uri
46
+
47
+ def uri_parser
48
+ @uri_parser ||= URI::RFC2396_Parser.new
49
+ end
50
+
51
+ # Converts the query parameters of the URI into a hash.
52
+ #
53
+ # "localhost?pool=5&reaping_frequency=2"
54
+ # # => { pool: "5", reaping_frequency: "2" }
55
+ #
56
+ # returns empty hash if no query present.
57
+ #
58
+ # "localhost"
59
+ # # => {}
60
+ def query_hash
61
+ Hash[(@query || "").split("&").map { |pair| pair.split("=", 2) }].symbolize_keys
62
+ end
63
+
64
+ def raw_config
65
+ if uri.opaque
66
+ query_hash.merge(
67
+ adapter: @adapter,
68
+ database: uri.opaque
69
+ )
70
+ else
71
+ query_hash.reverse_merge(
72
+ adapter: @adapter,
73
+ username: uri.user,
74
+ password: uri.password,
75
+ port: uri.port,
76
+ database: database_from_path,
77
+ host: uri.hostname
78
+ )
79
+ end
80
+ end
81
+
82
+ def resolved_adapter
83
+ adapter = uri.scheme && @uri.scheme.tr("-", "_")
84
+ adapter = ActiveRecord.protocol_adapters[adapter] || adapter
85
+ adapter
86
+ end
87
+
88
+ # Returns name of the database.
89
+ def database_from_path
90
+ if @adapter == "sqlite3"
91
+ # 'sqlite3:/foo' is absolute, because that makes sense. The
92
+ # corresponding relative version, 'sqlite3:foo', is handled
93
+ # elsewhere, as an "opaque".
94
+
95
+ uri.path
96
+ else
97
+ # Only SQLite uses a filename as the "database" name; for
98
+ # anything else, a leading slash would be silly.
99
+
100
+ uri.path.delete_prefix("/")
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ class DatabaseConfigurations
5
+ # ActiveRecord::Base.configurations will return either a HashConfig or
6
+ # UrlConfig respectively. It will never return a +DatabaseConfig+ object,
7
+ # as this is the parent class for the types of database configuration objects.
8
+ class DatabaseConfig # :nodoc:
9
+ attr_reader :env_name, :name
10
+
11
+ def initialize(env_name, name)
12
+ @env_name = env_name
13
+ @name = name
14
+ @adapter_class = nil
15
+ end
16
+
17
+ def adapter_class
18
+ @adapter_class ||= ActiveRecord::ConnectionAdapters.resolve(adapter)
19
+ end
20
+
21
+ def inspect # :nodoc:
22
+ "#<#{self.class.name} env_name=#{@env_name} name=#{@name} adapter_class=#{adapter_class}>"
23
+ end
24
+
25
+ def new_connection
26
+ adapter_class.new(configuration_hash)
27
+ end
28
+
29
+ def validate!
30
+ adapter_class if adapter
31
+
32
+ true
33
+ end
34
+
35
+ def host
36
+ raise NotImplementedError
37
+ end
38
+
39
+ def database
40
+ raise NotImplementedError
41
+ end
42
+
43
+ def _database=(database)
44
+ raise NotImplementedError
45
+ end
46
+
47
+ def adapter
48
+ raise NotImplementedError
49
+ end
50
+
51
+ def pool
52
+ raise NotImplementedError
53
+ end
54
+
55
+ def min_threads
56
+ raise NotImplementedError
57
+ end
58
+
59
+ def max_threads
60
+ raise NotImplementedError
61
+ end
62
+
63
+ def max_queue
64
+ raise NotImplementedError
65
+ end
66
+
67
+ def query_cache
68
+ raise NotImplementedError
69
+ end
70
+
71
+ def checkout_timeout
72
+ raise NotImplementedError
73
+ end
74
+
75
+ def reaping_frequency
76
+ raise NotImplementedError
77
+ end
78
+
79
+ def idle_timeout
80
+ raise NotImplementedError
81
+ end
82
+
83
+ def replica?
84
+ raise NotImplementedError
85
+ end
86
+
87
+ def migrations_paths
88
+ raise NotImplementedError
89
+ end
90
+
91
+ def for_current_env?
92
+ env_name == ActiveRecord::ConnectionHandling::DEFAULT_ENV.call
93
+ end
94
+
95
+ def schema_cache_path
96
+ raise NotImplementedError
97
+ end
98
+
99
+ def use_metadata_table?
100
+ raise NotImplementedError
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,172 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :markup: markdown
4
+
5
+ module ActiveRecord
6
+ class DatabaseConfigurations
7
+ # # Active Record Database Hash Config
8
+ #
9
+ # A `HashConfig` object is created for each database configuration entry that is
10
+ # created from a hash.
11
+ #
12
+ # A hash config:
13
+ #
14
+ # { "development" => { "database" => "db_name" } }
15
+ #
16
+ # Becomes:
17
+ #
18
+ # #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd1acbded10
19
+ # @env_name="development", @name="primary", @config={database: "db_name"}>
20
+ #
21
+ # See ActiveRecord::DatabaseConfigurations for more info.
22
+ class HashConfig < DatabaseConfig
23
+ attr_reader :configuration_hash
24
+
25
+ # Initialize a new `HashConfig` object
26
+ #
27
+ # #### Parameters
28
+ #
29
+ # * `env_name` - The Rails environment, i.e. "development".
30
+ # * `name` - The db config name. In a standard two-tier database configuration
31
+ # this will default to "primary". In a multiple database three-tier database
32
+ # configuration this corresponds to the name used in the second tier, for
33
+ # example "primary_readonly".
34
+ # * `configuration_hash` - The config hash. This is the hash that contains the
35
+ # database adapter, name, and other important information for database
36
+ # connections.
37
+ #
38
+ def initialize(env_name, name, configuration_hash)
39
+ super(env_name, name)
40
+ @configuration_hash = configuration_hash.symbolize_keys.freeze
41
+ end
42
+
43
+ # Determines whether a database configuration is for a replica / readonly
44
+ # connection. If the `replica` key is present in the config, `replica?` will
45
+ # return `true`.
46
+ def replica?
47
+ configuration_hash[:replica]
48
+ end
49
+
50
+ # The migrations paths for a database configuration. If the `migrations_paths`
51
+ # key is present in the config, `migrations_paths` will return its value.
52
+ def migrations_paths
53
+ configuration_hash[:migrations_paths]
54
+ end
55
+
56
+ def host
57
+ configuration_hash[:host]
58
+ end
59
+
60
+ def socket # :nodoc:
61
+ configuration_hash[:socket]
62
+ end
63
+
64
+ def database
65
+ configuration_hash[:database]
66
+ end
67
+
68
+ def _database=(database) # :nodoc:
69
+ @configuration_hash = configuration_hash.merge(database: database).freeze
70
+ end
71
+
72
+ def pool
73
+ (configuration_hash[:pool] || 5).to_i
74
+ end
75
+
76
+ def min_threads
77
+ (configuration_hash[:min_threads] || 0).to_i
78
+ end
79
+
80
+ def max_threads
81
+ (configuration_hash[:max_threads] || pool).to_i
82
+ end
83
+
84
+ def query_cache
85
+ configuration_hash[:query_cache]
86
+ end
87
+
88
+ def max_queue
89
+ max_threads * 4
90
+ end
91
+
92
+ def checkout_timeout
93
+ (configuration_hash[:checkout_timeout] || 5).to_f
94
+ end
95
+
96
+ # `reaping_frequency` is configurable mostly for historical reasons, but it
97
+ # could also be useful if someone wants a very low `idle_timeout`.
98
+ def reaping_frequency
99
+ configuration_hash.fetch(:reaping_frequency, 60)&.to_f
100
+ end
101
+
102
+ def idle_timeout
103
+ timeout = configuration_hash.fetch(:idle_timeout, 300).to_f
104
+ timeout if timeout > 0
105
+ end
106
+
107
+ def adapter
108
+ configuration_hash[:adapter]&.to_s
109
+ end
110
+
111
+ # The path to the schema cache dump file for a database. If omitted, the
112
+ # filename will be read from ENV or a default will be derived.
113
+ def schema_cache_path
114
+ configuration_hash[:schema_cache_path]
115
+ end
116
+
117
+ def default_schema_cache_path(db_dir = "db")
118
+ if primary?
119
+ File.join(db_dir, "schema_cache.yml")
120
+ else
121
+ File.join(db_dir, "#{name}_schema_cache.yml")
122
+ end
123
+ end
124
+
125
+ def lazy_schema_cache_path
126
+ schema_cache_path || default_schema_cache_path
127
+ end
128
+
129
+ def primary? # :nodoc:
130
+ Base.configurations.primary?(name)
131
+ end
132
+
133
+ # Determines whether to dump the schema/structure files and the filename that
134
+ # should be used.
135
+ #
136
+ # If `configuration_hash[:schema_dump]` is set to `false` or `nil` the schema
137
+ # will not be dumped.
138
+ #
139
+ # If the config option is set that will be used. Otherwise Rails will generate
140
+ # the filename from the database config name.
141
+ def schema_dump(format = ActiveRecord.schema_format)
142
+ if configuration_hash.key?(:schema_dump)
143
+ if config = configuration_hash[:schema_dump]
144
+ config
145
+ end
146
+ elsif primary?
147
+ schema_file_type(format)
148
+ else
149
+ "#{name}_#{schema_file_type(format)}"
150
+ end
151
+ end
152
+
153
+ def database_tasks? # :nodoc:
154
+ !replica? && !!configuration_hash.fetch(:database_tasks, true)
155
+ end
156
+
157
+ def use_metadata_table? # :nodoc:
158
+ configuration_hash.fetch(:use_metadata_table, true)
159
+ end
160
+
161
+ private
162
+ def schema_file_type(format)
163
+ case format
164
+ when :ruby
165
+ "schema.rb"
166
+ when :sql
167
+ "structure.sql"
168
+ end
169
+ end
170
+ end
171
+ end
172
+ end
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ class DatabaseConfigurations
5
+ # = Active Record Database Url Config
6
+ #
7
+ # A +UrlConfig+ object is created for each database configuration
8
+ # entry that is created from a URL. This can either be a URL string
9
+ # or a hash with a URL in place of the config hash.
10
+ #
11
+ # A URL config:
12
+ #
13
+ # postgres://localhost/foo
14
+ #
15
+ # Becomes:
16
+ #
17
+ # #<ActiveRecord::DatabaseConfigurations::UrlConfig:0x00007fdc3238f340
18
+ # @env_name="default_env", @name="primary",
19
+ # @config={adapter: "postgresql", database: "foo", host: "localhost"},
20
+ # @url="postgres://localhost/foo">
21
+ #
22
+ # See ActiveRecord::DatabaseConfigurations for more info.
23
+ #
24
+ class UrlConfig < HashConfig
25
+ attr_reader :url
26
+
27
+ # Initialize a new +UrlConfig+ object
28
+ #
29
+ # ==== Options
30
+ #
31
+ # * <tt>:env_name</tt> - The \Rails environment, i.e. "development".
32
+ # * <tt>:name</tt> - The db config name. In a standard two-tier
33
+ # database configuration this will default to "primary". In a multiple
34
+ # database three-tier database configuration this corresponds to the name
35
+ # used in the second tier, for example "primary_readonly".
36
+ # * <tt>:url</tt> - The database URL.
37
+ # * <tt>:config</tt> - The config hash. This is the hash that contains the
38
+ # database adapter, name, and other important information for database
39
+ # connections.
40
+ def initialize(env_name, name, url, configuration_hash = {})
41
+ super(env_name, name, configuration_hash)
42
+
43
+ @url = url
44
+ @configuration_hash = @configuration_hash.merge(build_url_hash)
45
+
46
+ if @configuration_hash[:schema_dump] == "false"
47
+ @configuration_hash[:schema_dump] = false
48
+ end
49
+
50
+ if @configuration_hash[:query_cache] == "false"
51
+ @configuration_hash[:query_cache] = false
52
+ end
53
+
54
+ to_boolean!(@configuration_hash, :replica)
55
+ to_boolean!(@configuration_hash, :database_tasks)
56
+
57
+ @configuration_hash.freeze
58
+ end
59
+
60
+ private
61
+ def to_boolean!(configuration_hash, key)
62
+ if configuration_hash[key].is_a?(String)
63
+ configuration_hash[key] = configuration_hash[key] != "false"
64
+ end
65
+ end
66
+
67
+ # Return a Hash that can be merged into the main config that represents
68
+ # the passed in url
69
+ def build_url_hash
70
+ if url.nil? || url.start_with?("jdbc:", "http:", "https:")
71
+ { url: url }
72
+ else
73
+ ConnectionUrlResolver.new(url).to_hash
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end