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,232 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module Associations
5
+ # = Active Record Has Many Through Association
6
+ class HasManyThroughAssociation < HasManyAssociation # :nodoc:
7
+ include ThroughAssociation
8
+
9
+ def initialize(owner, reflection)
10
+ super
11
+ @through_records = {}.compare_by_identity
12
+ end
13
+
14
+ def concat(*records)
15
+ unless owner.new_record?
16
+ records.flatten.each do |record|
17
+ raise_on_type_mismatch!(record)
18
+ end
19
+ end
20
+
21
+ super
22
+ end
23
+
24
+ def insert_record(record, validate = true, raise = false)
25
+ ensure_not_nested
26
+
27
+ if record.new_record? || record.has_changes_to_save?
28
+ return unless super
29
+ end
30
+
31
+ save_through_record(record)
32
+
33
+ record
34
+ end
35
+
36
+ private
37
+ def concat_records(records)
38
+ ensure_not_nested
39
+
40
+ records = super(records, true)
41
+
42
+ if owner.new_record? && records
43
+ records.flatten.each do |record|
44
+ build_through_record(record)
45
+ end
46
+ end
47
+
48
+ records
49
+ end
50
+
51
+ # The through record (built with build_record) is temporarily cached
52
+ # so that it may be reused if insert_record is subsequently called.
53
+ #
54
+ # However, after insert_record has been called, the cache is cleared in
55
+ # order to allow multiple instances of the same record in an association.
56
+ def build_through_record(record)
57
+ @through_records[record] ||= begin
58
+ ensure_mutable
59
+
60
+ attributes = through_scope_attributes
61
+ attributes[source_reflection.name] = record
62
+
63
+ through_association.build(attributes).tap do |new_record|
64
+ new_record.send("#{source_reflection.foreign_type}=", options[:source_type]) if options[:source_type]
65
+ end
66
+ end
67
+ end
68
+
69
+ attr_reader :through_scope
70
+
71
+ def through_scope_attributes
72
+ scope = through_scope || self.scope
73
+ attributes = scope.where_values_hash(through_association.reflection.klass.table_name)
74
+ except_keys = [
75
+ *Array(through_association.reflection.foreign_key),
76
+ through_association.reflection.klass.inheritance_column
77
+ ]
78
+ attributes.except!(*except_keys)
79
+ end
80
+
81
+ def save_through_record(record)
82
+ association = build_through_record(record)
83
+ if association.changed?
84
+ association.save!
85
+ end
86
+ ensure
87
+ @through_records.delete(record)
88
+ end
89
+
90
+ def build_record(attributes)
91
+ ensure_not_nested
92
+
93
+ @through_scope = scope
94
+ record = super
95
+
96
+ inverse = source_reflection.inverse_of
97
+ if inverse
98
+ if inverse.collection?
99
+ record.send(inverse.name) << build_through_record(record)
100
+ elsif inverse.has_one?
101
+ record.send("#{inverse.name}=", build_through_record(record))
102
+ end
103
+ end
104
+
105
+ record
106
+ ensure
107
+ @through_scope = nil
108
+ end
109
+
110
+ def remove_records(existing_records, records, method)
111
+ super
112
+ delete_through_records(records)
113
+ end
114
+
115
+ def target_reflection_has_associated_record?
116
+ !(through_reflection.belongs_to? && Array(through_reflection.foreign_key).all? { |foreign_key_column| owner[foreign_key_column].blank? })
117
+ end
118
+
119
+ def update_through_counter?(method)
120
+ case method
121
+ when :destroy
122
+ !through_reflection.inverse_updates_counter_cache?
123
+ when :nullify
124
+ false
125
+ else
126
+ true
127
+ end
128
+ end
129
+
130
+ def delete_or_nullify_all_records(method)
131
+ delete_records(load_target, method)
132
+ end
133
+
134
+ def delete_records(records, method)
135
+ ensure_not_nested
136
+
137
+ scope = through_association.scope
138
+ scope.where! construct_join_attributes(*records)
139
+ scope = scope.where(through_scope_attributes)
140
+
141
+ case method
142
+ when :destroy
143
+ if scope.model.primary_key
144
+ count = scope.destroy_all.count(&:destroyed?)
145
+ else
146
+ scope.each(&:_run_destroy_callbacks)
147
+ count = scope.delete_all
148
+ end
149
+ when :nullify
150
+ count = scope.update_all(source_reflection.foreign_key => nil)
151
+ else
152
+ count = scope.delete_all
153
+ end
154
+
155
+ delete_through_records(records)
156
+
157
+ if source_reflection.options[:counter_cache] && method != :destroy
158
+ counter = source_reflection.counter_cache_column
159
+ klass.decrement_counter counter, records.map(&:id)
160
+ end
161
+
162
+ if through_reflection.collection? && update_through_counter?(method)
163
+ update_counter(-count, through_reflection)
164
+ else
165
+ update_counter(-count)
166
+ end
167
+
168
+ count
169
+ end
170
+
171
+ def difference(a, b)
172
+ distribution = distribution(b)
173
+
174
+ a.reject { |record| mark_occurrence(distribution, record) }
175
+ end
176
+
177
+ def intersection(a, b)
178
+ distribution = distribution(b)
179
+
180
+ a.select { |record| mark_occurrence(distribution, record) }
181
+ end
182
+
183
+ def mark_occurrence(distribution, record)
184
+ distribution[record] > 0 && distribution[record] -= 1
185
+ end
186
+
187
+ def distribution(array)
188
+ array.each_with_object(Hash.new(0)) do |record, distribution|
189
+ distribution[record] += 1
190
+ end
191
+ end
192
+
193
+ def through_records_for(record)
194
+ attributes = construct_join_attributes(record)
195
+ candidates = Array.wrap(through_association.target)
196
+ candidates.find_all do |c|
197
+ attributes.all? do |key, value|
198
+ c.public_send(key) == value
199
+ end
200
+ end
201
+ end
202
+
203
+ def delete_through_records(records)
204
+ records.each do |record|
205
+ through_records = through_records_for(record)
206
+
207
+ if through_reflection.collection?
208
+ through_records.each { |r| through_association.target.delete(r) }
209
+ else
210
+ if through_records.include?(through_association.target)
211
+ through_association.target = nil
212
+ end
213
+ end
214
+
215
+ @through_records.delete(record)
216
+ end
217
+ end
218
+
219
+ def find_target(async: false)
220
+ raise NotImplementedError, "No async loading for HasManyThroughAssociation yet" if async
221
+ return [] unless target_reflection_has_associated_record?
222
+ return scope.to_a if disable_joins
223
+ super
224
+ end
225
+
226
+ # NOTE - not sure that we can actually cope with inverses here
227
+ def invertible_for?(record)
228
+ false
229
+ end
230
+ end
231
+ end
232
+ end
@@ -0,0 +1,142 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module Associations
5
+ # = Active Record Has One Association
6
+ class HasOneAssociation < SingularAssociation # :nodoc:
7
+ include ForeignAssociation
8
+
9
+ def handle_dependency
10
+ case options[:dependent]
11
+ when :restrict_with_exception
12
+ raise ActiveRecord::DeleteRestrictionError.new(reflection.name) if load_target
13
+
14
+ when :restrict_with_error
15
+ if load_target
16
+ record = owner.class.human_attribute_name(reflection.name).downcase
17
+ owner.errors.add(:base, :'restrict_dependent_destroy.has_one', record: record)
18
+ throw(:abort)
19
+ end
20
+
21
+ else
22
+ delete
23
+ end
24
+ end
25
+
26
+ def delete(method = options[:dependent])
27
+ if load_target
28
+ case method
29
+ when :delete
30
+ target.delete
31
+ when :destroy
32
+ target.destroyed_by_association = reflection
33
+ target.destroy
34
+ throw(:abort) unless target.destroyed?
35
+ when :destroy_async
36
+ if target.class.query_constraints_list
37
+ primary_key_column = target.class.query_constraints_list
38
+ id = primary_key_column.map { |col| target.public_send(col) }
39
+ else
40
+ primary_key_column = target.class.primary_key
41
+ id = target.public_send(primary_key_column)
42
+ end
43
+
44
+ enqueue_destroy_association(
45
+ owner_model_name: owner.class.to_s,
46
+ owner_id: owner.id,
47
+ association_class: reflection.klass.to_s,
48
+ association_ids: [id],
49
+ association_primary_key_column: primary_key_column,
50
+ ensuring_owner_was_method: options.fetch(:ensuring_owner_was, nil)
51
+ )
52
+ when :nullify
53
+ target.update_columns(nullified_owner_attributes) if target.persisted?
54
+ end
55
+ end
56
+ end
57
+
58
+ private
59
+ def replace(record, save = true)
60
+ raise_on_type_mismatch!(record) if record
61
+
62
+ return target unless load_target || record
63
+
64
+ assigning_another_record = target != record
65
+ if assigning_another_record || record.has_changes_to_save?
66
+ save &&= owner.persisted?
67
+
68
+ transaction_if(save) do
69
+ remove_target!(options[:dependent]) if target && !target.destroyed? && assigning_another_record
70
+
71
+ if record
72
+ set_owner_attributes(record)
73
+ set_inverse_instance(record)
74
+
75
+ if save && !record.save
76
+ nullify_owner_attributes(record)
77
+ set_owner_attributes(target) if target
78
+ raise RecordNotSaved.new("Failed to save the new associated #{reflection.name}.", record)
79
+ end
80
+ end
81
+ end
82
+ end
83
+
84
+ self.target = record
85
+ end
86
+
87
+ # The reason that the save param for replace is false, if for create (not just build),
88
+ # is because the setting of the foreign keys is actually handled by the scoping when
89
+ # the record is instantiated, and so they are set straight away and do not need to be
90
+ # updated within replace.
91
+ def set_new_record(record)
92
+ replace(record, false)
93
+ end
94
+
95
+ def remove_target!(method)
96
+ case method
97
+ when :delete
98
+ target.delete
99
+ when :destroy
100
+ target.destroyed_by_association = reflection
101
+ if target.persisted?
102
+ target.destroy
103
+ end
104
+ else
105
+ nullify_owner_attributes(target)
106
+ remove_inverse_instance(target)
107
+
108
+ if target.persisted? && owner.persisted? && !target.save
109
+ set_owner_attributes(target)
110
+ raise RecordNotSaved.new(
111
+ "Failed to remove the existing associated #{reflection.name}. " \
112
+ "The record failed to save after its foreign key was set to nil.",
113
+ target
114
+ )
115
+ end
116
+ end
117
+ end
118
+
119
+ def nullify_owner_attributes(record)
120
+ Array(reflection.foreign_key).each do |foreign_key_column|
121
+ record[foreign_key_column] = nil unless foreign_key_column.in?(Array(record.class.primary_key))
122
+ end
123
+ end
124
+
125
+ def transaction_if(value, &block)
126
+ if value
127
+ reflection.klass.transaction(&block)
128
+ else
129
+ yield
130
+ end
131
+ end
132
+
133
+ def _create_record(attributes, raise_error = false, &block)
134
+ unless owner.persisted?
135
+ raise ActiveRecord::RecordNotSaved.new("You cannot call create unless the parent is saved", owner)
136
+ end
137
+
138
+ super
139
+ end
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module Associations
5
+ # = Active Record Has One Through Association
6
+ class HasOneThroughAssociation < HasOneAssociation # :nodoc:
7
+ include ThroughAssociation
8
+
9
+ private
10
+ def replace(record, save = true)
11
+ create_through_record(record, save)
12
+ self.target = record
13
+ end
14
+
15
+ def create_through_record(record, save)
16
+ ensure_not_nested
17
+
18
+ through_proxy = through_association
19
+ through_record = through_proxy.load_target
20
+
21
+ if through_record && !record
22
+ through_record.destroy
23
+ elsif record
24
+ attributes = construct_join_attributes(record)
25
+
26
+ if through_record && through_record.destroyed?
27
+ through_record = through_proxy.tap(&:reload).target
28
+ end
29
+
30
+ if through_record
31
+ if through_record.new_record?
32
+ through_record.assign_attributes(attributes)
33
+ else
34
+ through_record.update(attributes)
35
+ end
36
+ elsif owner.new_record? || !save
37
+ through_proxy.build(attributes)
38
+ else
39
+ through_proxy.create(attributes)
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,106 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_record/associations/join_dependency/join_part"
4
+ require "active_support/core_ext/array/extract"
5
+
6
+ module ActiveRecord
7
+ module Associations
8
+ class JoinDependency # :nodoc:
9
+ class JoinAssociation < JoinPart # :nodoc:
10
+ attr_reader :reflection, :tables
11
+ attr_accessor :table
12
+
13
+ def initialize(reflection, children)
14
+ super(reflection.klass, children)
15
+
16
+ @reflection = reflection
17
+ end
18
+
19
+ def match?(other)
20
+ return true if self == other
21
+ super && reflection == other.reflection
22
+ end
23
+
24
+ def join_constraints(foreign_table, foreign_klass, join_type, alias_tracker)
25
+ joins = []
26
+ chain = []
27
+
28
+ reflection_chain = reflection.chain
29
+ reflection_chain.each_with_index do |reflection, index|
30
+ table, terminated = yield reflection, reflection_chain[index..]
31
+ @table ||= table
32
+
33
+ if terminated
34
+ foreign_table, foreign_klass = table, reflection.klass
35
+ break
36
+ end
37
+
38
+ chain << [reflection, table]
39
+ end
40
+
41
+ base_klass.with_connection do |connection|
42
+ # The chain starts with the target table, but we want to end with it here (makes
43
+ # more sense in this context), so we reverse
44
+ chain.reverse_each do |reflection, table|
45
+ klass = reflection.klass
46
+
47
+ scope = reflection.join_scope(table, foreign_table, foreign_klass)
48
+
49
+ unless scope.references_values.empty?
50
+ associations = scope.eager_load_values | scope.includes_values
51
+
52
+ unless associations.empty?
53
+ scope.joins! scope.construct_join_dependency(associations, Arel::Nodes::OuterJoin)
54
+ end
55
+ end
56
+
57
+ arel = scope.arel(alias_tracker.aliases)
58
+ nodes = arel.constraints.first
59
+
60
+ if nodes.is_a?(Arel::Nodes::And)
61
+ others = nodes.children.extract! do |node|
62
+ !Arel.fetch_attribute(node) { |attr| attr.relation.name == table.name }
63
+ end
64
+ end
65
+
66
+ joins << join_type.new(table, Arel::Nodes::On.new(nodes))
67
+
68
+ if others && !others.empty?
69
+ joins.concat arel.join_sources
70
+ append_constraints(connection, joins.last, others)
71
+ end
72
+
73
+ # The current table in this iteration becomes the foreign table in the next
74
+ foreign_table, foreign_klass = table, klass
75
+ end
76
+ end
77
+
78
+ joins
79
+ end
80
+
81
+ def readonly?
82
+ return @readonly if defined?(@readonly)
83
+
84
+ @readonly = reflection.scope && reflection.scope_for(base_klass.unscoped).readonly_value
85
+ end
86
+
87
+ def strict_loading?
88
+ return @strict_loading if defined?(@strict_loading)
89
+
90
+ @strict_loading = reflection.scope && reflection.scope_for(base_klass.unscoped).strict_loading_value
91
+ end
92
+
93
+ private
94
+ def append_constraints(connection, join, constraints)
95
+ if join.is_a?(Arel::Nodes::StringJoin)
96
+ join_string = Arel::Nodes::And.new(constraints.unshift join.left)
97
+ join.left = Arel.sql(connection.visitor.compile(join_string))
98
+ else
99
+ right = join.right
100
+ right.expr = Arel::Nodes::And.new(constraints.unshift right.expr)
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_record/associations/join_dependency/join_part"
4
+
5
+ module ActiveRecord
6
+ module Associations
7
+ class JoinDependency # :nodoc:
8
+ class JoinBase < JoinPart # :nodoc:
9
+ attr_reader :table
10
+
11
+ def initialize(base_klass, table, children)
12
+ super(base_klass, children)
13
+ @table = table
14
+ end
15
+
16
+ def match?(other)
17
+ return true if self == other
18
+ super && base_klass == other.base_klass
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module Associations
5
+ class JoinDependency # :nodoc:
6
+ # A JoinPart represents a part of a JoinDependency. It is inherited
7
+ # by JoinBase and JoinAssociation. A JoinBase represents the Active Record which
8
+ # everything else is being joined onto. A JoinAssociation represents an association which
9
+ # is joining to the base. A JoinAssociation may result in more than one actual join
10
+ # operations (for example a has_and_belongs_to_many JoinAssociation would result in
11
+ # two; one for the join table and one for the target table).
12
+ class JoinPart # :nodoc:
13
+ include Enumerable
14
+
15
+ # The Active Record class which this join part is associated 'about'; for a JoinBase
16
+ # this is the actual base model, for a JoinAssociation this is the target model of the
17
+ # association.
18
+ attr_reader :base_klass, :children
19
+
20
+ delegate :table_name, :column_names, :primary_key, :attribute_types, to: :base_klass
21
+
22
+ def initialize(base_klass, children)
23
+ @base_klass = base_klass
24
+ @children = children
25
+ end
26
+
27
+ def match?(other)
28
+ self.class == other.class
29
+ end
30
+
31
+ def each(&block)
32
+ yield self
33
+ children.each { |child| child.each(&block) }
34
+ end
35
+
36
+ def each_children(&block)
37
+ children.each do |child|
38
+ yield self, child
39
+ child.each_children(&block)
40
+ end
41
+ end
42
+
43
+ # An Arel::Table for the active_record
44
+ def table
45
+ raise NotImplementedError
46
+ end
47
+
48
+ def extract_record(row, column_names_with_alias)
49
+ # This code is performance critical as it is called per row.
50
+ # see: https://github.com/rails/rails/pull/12185
51
+ hash = {}
52
+
53
+ index = 0
54
+ length = column_names_with_alias.length
55
+
56
+ while index < length
57
+ column = column_names_with_alias[index]
58
+ hash[column.name] = row[column.alias]
59
+ index += 1
60
+ end
61
+
62
+ hash
63
+ end
64
+
65
+ def instantiate(row, aliases, column_types = {}, &block)
66
+ base_klass.instantiate(extract_record(row, aliases), column_types, &block)
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end