activerecord 5.2.8 → 7.0.2

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

Potentially problematic release.


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

Files changed (364) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1393 -587
  3. data/MIT-LICENSE +3 -1
  4. data/README.rdoc +7 -5
  5. data/examples/performance.rb +1 -1
  6. data/lib/active_record/aggregations.rb +10 -9
  7. data/lib/active_record/association_relation.rb +22 -12
  8. data/lib/active_record/associations/alias_tracker.rb +19 -16
  9. data/lib/active_record/associations/association.rb +122 -47
  10. data/lib/active_record/associations/association_scope.rb +24 -24
  11. data/lib/active_record/associations/belongs_to_association.rb +67 -49
  12. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +16 -7
  13. data/lib/active_record/associations/builder/association.rb +52 -23
  14. data/lib/active_record/associations/builder/belongs_to.rb +44 -61
  15. data/lib/active_record/associations/builder/collection_association.rb +17 -19
  16. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +17 -41
  17. data/lib/active_record/associations/builder/has_many.rb +10 -3
  18. data/lib/active_record/associations/builder/has_one.rb +35 -3
  19. data/lib/active_record/associations/builder/singular_association.rb +5 -3
  20. data/lib/active_record/associations/collection_association.rb +59 -50
  21. data/lib/active_record/associations/collection_proxy.rb +32 -23
  22. data/lib/active_record/associations/disable_joins_association_scope.rb +59 -0
  23. data/lib/active_record/associations/foreign_association.rb +20 -0
  24. data/lib/active_record/associations/has_many_association.rb +27 -14
  25. data/lib/active_record/associations/has_many_through_association.rb +26 -19
  26. data/lib/active_record/associations/has_one_association.rb +52 -37
  27. data/lib/active_record/associations/has_one_through_association.rb +6 -6
  28. data/lib/active_record/associations/join_dependency/join_association.rb +44 -22
  29. data/lib/active_record/associations/join_dependency/join_part.rb +5 -5
  30. data/lib/active_record/associations/join_dependency.rb +97 -62
  31. data/lib/active_record/associations/preloader/association.rb +220 -60
  32. data/lib/active_record/associations/preloader/batch.rb +48 -0
  33. data/lib/active_record/associations/preloader/branch.rb +147 -0
  34. data/lib/active_record/associations/preloader/through_association.rb +85 -40
  35. data/lib/active_record/associations/preloader.rb +44 -105
  36. data/lib/active_record/associations/singular_association.rb +9 -17
  37. data/lib/active_record/associations/through_association.rb +4 -4
  38. data/lib/active_record/associations.rb +207 -66
  39. data/lib/active_record/asynchronous_queries_tracker.rb +60 -0
  40. data/lib/active_record/attribute_assignment.rb +17 -19
  41. data/lib/active_record/attribute_methods/before_type_cast.rb +19 -8
  42. data/lib/active_record/attribute_methods/dirty.rb +141 -47
  43. data/lib/active_record/attribute_methods/primary_key.rb +22 -27
  44. data/lib/active_record/attribute_methods/query.rb +6 -10
  45. data/lib/active_record/attribute_methods/read.rb +15 -55
  46. data/lib/active_record/attribute_methods/serialization.rb +77 -18
  47. data/lib/active_record/attribute_methods/time_zone_conversion.rb +16 -18
  48. data/lib/active_record/attribute_methods/write.rb +18 -37
  49. data/lib/active_record/attribute_methods.rb +90 -153
  50. data/lib/active_record/attributes.rb +38 -12
  51. data/lib/active_record/autosave_association.rb +50 -50
  52. data/lib/active_record/base.rb +23 -18
  53. data/lib/active_record/callbacks.rb +159 -44
  54. data/lib/active_record/coders/yaml_column.rb +12 -3
  55. data/lib/active_record/connection_adapters/abstract/connection_handler.rb +292 -0
  56. data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +209 -0
  57. data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +76 -0
  58. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +92 -464
  59. data/lib/active_record/connection_adapters/abstract/database_limits.rb +5 -51
  60. data/lib/active_record/connection_adapters/abstract/database_statements.rb +209 -164
  61. data/lib/active_record/connection_adapters/abstract/query_cache.rb +38 -22
  62. data/lib/active_record/connection_adapters/abstract/quoting.rb +103 -82
  63. data/lib/active_record/connection_adapters/abstract/savepoints.rb +3 -3
  64. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +140 -110
  65. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +236 -94
  66. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +16 -5
  67. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +456 -159
  68. data/lib/active_record/connection_adapters/abstract/transaction.rb +169 -78
  69. data/lib/active_record/connection_adapters/abstract_adapter.rb +367 -162
  70. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +311 -327
  71. data/lib/active_record/connection_adapters/column.rb +33 -11
  72. data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
  73. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +35 -0
  74. data/lib/active_record/connection_adapters/mysql/column.rb +1 -1
  75. data/lib/active_record/connection_adapters/mysql/database_statements.rb +113 -45
  76. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +1 -2
  77. data/lib/active_record/connection_adapters/mysql/quoting.rb +71 -5
  78. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +34 -10
  79. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +48 -32
  80. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +25 -8
  81. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +143 -19
  82. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +14 -9
  83. data/lib/active_record/connection_adapters/mysql2_adapter.rb +63 -22
  84. data/lib/active_record/connection_adapters/pool_config.rb +73 -0
  85. data/lib/active_record/connection_adapters/pool_manager.rb +47 -0
  86. data/lib/active_record/connection_adapters/postgresql/column.rb +53 -28
  87. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +56 -63
  88. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -2
  89. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +1 -4
  90. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -5
  91. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +10 -2
  92. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +15 -2
  93. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +0 -1
  94. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +54 -16
  95. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +3 -4
  97. data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
  98. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
  99. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +3 -4
  100. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +25 -7
  101. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
  102. data/lib/active_record/connection_adapters/postgresql/oid/timestamp.rb +15 -0
  103. data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +30 -0
  104. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +26 -12
  105. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +15 -3
  106. data/lib/active_record/connection_adapters/postgresql/oid.rb +4 -0
  107. data/lib/active_record/connection_adapters/postgresql/quoting.rb +89 -52
  108. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +34 -2
  109. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +39 -4
  110. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +128 -91
  111. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +25 -1
  112. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +149 -113
  113. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +31 -26
  114. data/lib/active_record/connection_adapters/postgresql/utils.rb +0 -1
  115. data/lib/active_record/connection_adapters/postgresql_adapter.rb +386 -182
  116. data/lib/active_record/connection_adapters/schema_cache.rb +161 -22
  117. data/lib/active_record/connection_adapters/sql_type_metadata.rb +17 -6
  118. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +152 -0
  119. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +65 -18
  120. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -1
  121. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +92 -26
  122. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +251 -204
  123. data/lib/active_record/connection_adapters/statement_pool.rb +0 -1
  124. data/lib/active_record/connection_adapters.rb +53 -0
  125. data/lib/active_record/connection_handling.rb +292 -38
  126. data/lib/active_record/core.rb +385 -158
  127. data/lib/active_record/counter_cache.rb +8 -30
  128. data/lib/active_record/database_configurations/connection_url_resolver.rb +100 -0
  129. data/lib/active_record/database_configurations/database_config.rb +83 -0
  130. data/lib/active_record/database_configurations/hash_config.rb +154 -0
  131. data/lib/active_record/database_configurations/url_config.rb +53 -0
  132. data/lib/active_record/database_configurations.rb +256 -0
  133. data/lib/active_record/delegated_type.rb +250 -0
  134. data/lib/active_record/destroy_association_async_job.rb +36 -0
  135. data/lib/active_record/disable_joins_association_relation.rb +39 -0
  136. data/lib/active_record/dynamic_matchers.rb +4 -5
  137. data/lib/active_record/encryption/cipher/aes256_gcm.rb +98 -0
  138. data/lib/active_record/encryption/cipher.rb +53 -0
  139. data/lib/active_record/encryption/config.rb +44 -0
  140. data/lib/active_record/encryption/configurable.rb +61 -0
  141. data/lib/active_record/encryption/context.rb +35 -0
  142. data/lib/active_record/encryption/contexts.rb +72 -0
  143. data/lib/active_record/encryption/derived_secret_key_provider.rb +12 -0
  144. data/lib/active_record/encryption/deterministic_key_provider.rb +14 -0
  145. data/lib/active_record/encryption/encryptable_record.rb +208 -0
  146. data/lib/active_record/encryption/encrypted_attribute_type.rb +140 -0
  147. data/lib/active_record/encryption/encrypted_fixtures.rb +38 -0
  148. data/lib/active_record/encryption/encrypting_only_encryptor.rb +12 -0
  149. data/lib/active_record/encryption/encryptor.rb +155 -0
  150. data/lib/active_record/encryption/envelope_encryption_key_provider.rb +55 -0
  151. data/lib/active_record/encryption/errors.rb +15 -0
  152. data/lib/active_record/encryption/extended_deterministic_queries.rb +160 -0
  153. data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +28 -0
  154. data/lib/active_record/encryption/key.rb +28 -0
  155. data/lib/active_record/encryption/key_generator.rb +42 -0
  156. data/lib/active_record/encryption/key_provider.rb +46 -0
  157. data/lib/active_record/encryption/message.rb +33 -0
  158. data/lib/active_record/encryption/message_serializer.rb +90 -0
  159. data/lib/active_record/encryption/null_encryptor.rb +21 -0
  160. data/lib/active_record/encryption/properties.rb +76 -0
  161. data/lib/active_record/encryption/read_only_null_encryptor.rb +24 -0
  162. data/lib/active_record/encryption/scheme.rb +99 -0
  163. data/lib/active_record/encryption.rb +55 -0
  164. data/lib/active_record/enum.rb +130 -51
  165. data/lib/active_record/errors.rb +129 -23
  166. data/lib/active_record/explain.rb +10 -6
  167. data/lib/active_record/explain_registry.rb +11 -6
  168. data/lib/active_record/explain_subscriber.rb +1 -1
  169. data/lib/active_record/fixture_set/file.rb +22 -15
  170. data/lib/active_record/fixture_set/model_metadata.rb +32 -0
  171. data/lib/active_record/fixture_set/render_context.rb +17 -0
  172. data/lib/active_record/fixture_set/table_row.rb +187 -0
  173. data/lib/active_record/fixture_set/table_rows.rb +46 -0
  174. data/lib/active_record/fixtures.rb +206 -490
  175. data/lib/active_record/future_result.rb +139 -0
  176. data/lib/active_record/gem_version.rb +3 -3
  177. data/lib/active_record/inheritance.rb +104 -37
  178. data/lib/active_record/insert_all.rb +278 -0
  179. data/lib/active_record/integration.rb +69 -18
  180. data/lib/active_record/internal_metadata.rb +24 -9
  181. data/lib/active_record/legacy_yaml_adapter.rb +3 -36
  182. data/lib/active_record/locking/optimistic.rb +41 -26
  183. data/lib/active_record/locking/pessimistic.rb +18 -8
  184. data/lib/active_record/log_subscriber.rb +46 -35
  185. data/lib/active_record/middleware/database_selector/resolver/session.rb +48 -0
  186. data/lib/active_record/middleware/database_selector/resolver.rb +88 -0
  187. data/lib/active_record/middleware/database_selector.rb +82 -0
  188. data/lib/active_record/middleware/shard_selector.rb +60 -0
  189. data/lib/active_record/migration/command_recorder.rb +96 -44
  190. data/lib/active_record/migration/compatibility.rb +246 -64
  191. data/lib/active_record/migration/join_table.rb +1 -2
  192. data/lib/active_record/migration.rb +266 -187
  193. data/lib/active_record/model_schema.rb +165 -52
  194. data/lib/active_record/nested_attributes.rb +17 -19
  195. data/lib/active_record/no_touching.rb +11 -4
  196. data/lib/active_record/null_relation.rb +2 -7
  197. data/lib/active_record/persistence.rb +467 -92
  198. data/lib/active_record/query_cache.rb +21 -4
  199. data/lib/active_record/query_logs.rb +138 -0
  200. data/lib/active_record/querying.rb +51 -24
  201. data/lib/active_record/railtie.rb +224 -57
  202. data/lib/active_record/railties/console_sandbox.rb +2 -4
  203. data/lib/active_record/railties/controller_runtime.rb +31 -36
  204. data/lib/active_record/railties/databases.rake +369 -101
  205. data/lib/active_record/readonly_attributes.rb +15 -0
  206. data/lib/active_record/reflection.rb +170 -137
  207. data/lib/active_record/relation/batches/batch_enumerator.rb +44 -14
  208. data/lib/active_record/relation/batches.rb +46 -37
  209. data/lib/active_record/relation/calculations.rb +168 -96
  210. data/lib/active_record/relation/delegation.rb +37 -52
  211. data/lib/active_record/relation/finder_methods.rb +79 -58
  212. data/lib/active_record/relation/from_clause.rb +5 -1
  213. data/lib/active_record/relation/merger.rb +50 -51
  214. data/lib/active_record/relation/predicate_builder/array_handler.rb +13 -13
  215. data/lib/active_record/relation/predicate_builder/association_query_value.rb +5 -9
  216. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +1 -2
  217. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +11 -10
  218. data/lib/active_record/relation/predicate_builder/range_handler.rb +3 -23
  219. data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
  220. data/lib/active_record/relation/predicate_builder.rb +58 -46
  221. data/lib/active_record/relation/query_attribute.rb +9 -10
  222. data/lib/active_record/relation/query_methods.rb +685 -208
  223. data/lib/active_record/relation/record_fetch_warning.rb +9 -11
  224. data/lib/active_record/relation/spawn_methods.rb +10 -10
  225. data/lib/active_record/relation/where_clause.rb +108 -64
  226. data/lib/active_record/relation.rb +515 -151
  227. data/lib/active_record/result.rb +78 -42
  228. data/lib/active_record/runtime_registry.rb +9 -13
  229. data/lib/active_record/sanitization.rb +29 -44
  230. data/lib/active_record/schema.rb +37 -31
  231. data/lib/active_record/schema_dumper.rb +74 -23
  232. data/lib/active_record/schema_migration.rb +7 -9
  233. data/lib/active_record/scoping/default.rb +62 -17
  234. data/lib/active_record/scoping/named.rb +17 -32
  235. data/lib/active_record/scoping.rb +70 -41
  236. data/lib/active_record/secure_token.rb +16 -8
  237. data/lib/active_record/serialization.rb +6 -4
  238. data/lib/active_record/signed_id.rb +116 -0
  239. data/lib/active_record/statement_cache.rb +49 -6
  240. data/lib/active_record/store.rb +88 -9
  241. data/lib/active_record/suppressor.rb +13 -17
  242. data/lib/active_record/table_metadata.rb +42 -43
  243. data/lib/active_record/tasks/database_tasks.rb +352 -94
  244. data/lib/active_record/tasks/mysql_database_tasks.rb +37 -39
  245. data/lib/active_record/tasks/postgresql_database_tasks.rb +41 -39
  246. data/lib/active_record/tasks/sqlite_database_tasks.rb +14 -17
  247. data/lib/active_record/test_databases.rb +24 -0
  248. data/lib/active_record/test_fixtures.rb +287 -0
  249. data/lib/active_record/timestamp.rb +44 -34
  250. data/lib/active_record/touch_later.rb +23 -22
  251. data/lib/active_record/transactions.rb +67 -128
  252. data/lib/active_record/translation.rb +3 -3
  253. data/lib/active_record/type/adapter_specific_registry.rb +34 -19
  254. data/lib/active_record/type/hash_lookup_type_map.rb +34 -2
  255. data/lib/active_record/type/internal/timezone.rb +2 -2
  256. data/lib/active_record/type/serialized.rb +7 -4
  257. data/lib/active_record/type/time.rb +10 -0
  258. data/lib/active_record/type/type_map.rb +17 -21
  259. data/lib/active_record/type/unsigned_integer.rb +0 -1
  260. data/lib/active_record/type.rb +9 -5
  261. data/lib/active_record/type_caster/connection.rb +15 -15
  262. data/lib/active_record/type_caster/map.rb +8 -8
  263. data/lib/active_record/validations/associated.rb +2 -3
  264. data/lib/active_record/validations/numericality.rb +35 -0
  265. data/lib/active_record/validations/uniqueness.rb +39 -31
  266. data/lib/active_record/validations.rb +4 -3
  267. data/lib/active_record.rb +209 -32
  268. data/lib/arel/alias_predication.rb +9 -0
  269. data/lib/arel/attributes/attribute.rb +33 -0
  270. data/lib/arel/collectors/bind.rb +29 -0
  271. data/lib/arel/collectors/composite.rb +39 -0
  272. data/lib/arel/collectors/plain_string.rb +20 -0
  273. data/lib/arel/collectors/sql_string.rb +27 -0
  274. data/lib/arel/collectors/substitute_binds.rb +35 -0
  275. data/lib/arel/crud.rb +48 -0
  276. data/lib/arel/delete_manager.rb +32 -0
  277. data/lib/arel/errors.rb +9 -0
  278. data/lib/arel/expressions.rb +29 -0
  279. data/lib/arel/factory_methods.rb +49 -0
  280. data/lib/arel/filter_predications.rb +9 -0
  281. data/lib/arel/insert_manager.rb +48 -0
  282. data/lib/arel/math.rb +45 -0
  283. data/lib/arel/nodes/and.rb +32 -0
  284. data/lib/arel/nodes/ascending.rb +23 -0
  285. data/lib/arel/nodes/binary.rb +126 -0
  286. data/lib/arel/nodes/bind_param.rb +44 -0
  287. data/lib/arel/nodes/case.rb +55 -0
  288. data/lib/arel/nodes/casted.rb +62 -0
  289. data/lib/arel/nodes/comment.rb +29 -0
  290. data/lib/arel/nodes/count.rb +12 -0
  291. data/lib/arel/nodes/delete_statement.rb +44 -0
  292. data/lib/arel/nodes/descending.rb +23 -0
  293. data/lib/arel/nodes/equality.rb +15 -0
  294. data/lib/arel/nodes/extract.rb +24 -0
  295. data/lib/arel/nodes/false.rb +16 -0
  296. data/lib/arel/nodes/filter.rb +10 -0
  297. data/lib/arel/nodes/full_outer_join.rb +8 -0
  298. data/lib/arel/nodes/function.rb +45 -0
  299. data/lib/arel/nodes/grouping.rb +11 -0
  300. data/lib/arel/nodes/homogeneous_in.rb +76 -0
  301. data/lib/arel/nodes/in.rb +15 -0
  302. data/lib/arel/nodes/infix_operation.rb +92 -0
  303. data/lib/arel/nodes/inner_join.rb +8 -0
  304. data/lib/arel/nodes/insert_statement.rb +37 -0
  305. data/lib/arel/nodes/join_source.rb +20 -0
  306. data/lib/arel/nodes/matches.rb +18 -0
  307. data/lib/arel/nodes/named_function.rb +23 -0
  308. data/lib/arel/nodes/node.rb +51 -0
  309. data/lib/arel/nodes/node_expression.rb +13 -0
  310. data/lib/arel/nodes/ordering.rb +27 -0
  311. data/lib/arel/nodes/outer_join.rb +8 -0
  312. data/lib/arel/nodes/over.rb +15 -0
  313. data/lib/arel/nodes/regexp.rb +16 -0
  314. data/lib/arel/nodes/right_outer_join.rb +8 -0
  315. data/lib/arel/nodes/select_core.rb +67 -0
  316. data/lib/arel/nodes/select_statement.rb +41 -0
  317. data/lib/arel/nodes/sql_literal.rb +19 -0
  318. data/lib/arel/nodes/string_join.rb +11 -0
  319. data/lib/arel/nodes/table_alias.rb +31 -0
  320. data/lib/arel/nodes/terminal.rb +16 -0
  321. data/lib/arel/nodes/true.rb +16 -0
  322. data/lib/arel/nodes/unary.rb +44 -0
  323. data/lib/arel/nodes/unary_operation.rb +20 -0
  324. data/lib/arel/nodes/unqualified_column.rb +22 -0
  325. data/lib/arel/nodes/update_statement.rb +46 -0
  326. data/lib/arel/nodes/values_list.rb +9 -0
  327. data/lib/arel/nodes/window.rb +126 -0
  328. data/lib/arel/nodes/with.rb +11 -0
  329. data/lib/arel/nodes.rb +71 -0
  330. data/lib/arel/order_predications.rb +13 -0
  331. data/lib/arel/predications.rb +258 -0
  332. data/lib/arel/select_manager.rb +276 -0
  333. data/lib/arel/table.rb +117 -0
  334. data/lib/arel/tree_manager.rb +60 -0
  335. data/lib/arel/update_manager.rb +48 -0
  336. data/lib/arel/visitors/dot.rb +298 -0
  337. data/lib/arel/visitors/mysql.rb +99 -0
  338. data/lib/arel/visitors/postgresql.rb +110 -0
  339. data/lib/arel/visitors/sqlite.rb +38 -0
  340. data/lib/arel/visitors/to_sql.rb +955 -0
  341. data/lib/arel/visitors/visitor.rb +45 -0
  342. data/lib/arel/visitors.rb +13 -0
  343. data/lib/arel/window_predications.rb +9 -0
  344. data/lib/arel.rb +55 -0
  345. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +0 -1
  346. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +1 -1
  347. data/lib/rails/generators/active_record/migration/migration_generator.rb +3 -5
  348. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +3 -1
  349. data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +7 -5
  350. data/lib/rails/generators/active_record/migration.rb +19 -2
  351. data/lib/rails/generators/active_record/model/model_generator.rb +39 -2
  352. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
  353. data/lib/rails/generators/active_record/model/templates/model.rb.tt +10 -1
  354. data/lib/rails/generators/active_record/model/templates/module.rb.tt +2 -2
  355. data/lib/rails/generators/active_record/multi_db/multi_db_generator.rb +16 -0
  356. data/lib/rails/generators/active_record/multi_db/templates/multi_db.rb.tt +44 -0
  357. metadata +162 -32
  358. data/lib/active_record/attribute_decorators.rb +0 -90
  359. data/lib/active_record/collection_cache_key.rb +0 -53
  360. data/lib/active_record/connection_adapters/connection_specification.rb +0 -287
  361. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -33
  362. data/lib/active_record/define_callbacks.rb +0 -22
  363. data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -19
  364. data/lib/active_record/relation/where_clause_factory.rb +0 -34
@@ -16,10 +16,10 @@ module ActiveRecord
16
16
  def exec_queries
17
17
  QueryRegistry.reset
18
18
 
19
- super.tap do
20
- if logger && warn_on_records_fetched_greater_than
21
- if @records.length > warn_on_records_fetched_greater_than
22
- logger.warn "Query fetched #{@records.size} #{@klass} records: #{QueryRegistry.queries.join(";")}"
19
+ super.tap do |records|
20
+ if logger && ActiveRecord.warn_on_records_fetched_greater_than
21
+ if records.length > ActiveRecord.warn_on_records_fetched_greater_than
22
+ logger.warn "Query fetched #{records.size} #{@klass} records: #{QueryRegistry.queries.join(";")}"
23
23
  end
24
24
  end
25
25
  end
@@ -31,17 +31,15 @@ module ActiveRecord
31
31
  end
32
32
  # :startdoc:
33
33
 
34
- class QueryRegistry # :nodoc:
35
- extend ActiveSupport::PerThreadRegistry
34
+ module QueryRegistry # :nodoc:
35
+ extend self
36
36
 
37
- attr_reader :queries
38
-
39
- def initialize
40
- @queries = []
37
+ def queries
38
+ ActiveSupport::IsolatedExecutionState[:active_record_query_registry] ||= []
41
39
  end
42
40
 
43
41
  def reset
44
- @queries.clear
42
+ queries.clear
45
43
  end
46
44
  end
47
45
  end
@@ -7,8 +7,8 @@ require "active_record/relation/merger"
7
7
  module ActiveRecord
8
8
  module SpawnMethods
9
9
  # This is overridden by Associations::CollectionProxy
10
- def spawn #:nodoc:
11
- @delegate_to_klass ? klass.all : clone
10
+ def spawn # :nodoc:
11
+ already_in_scope?(klass.scope_registry) ? klass.all : clone
12
12
  end
13
13
 
14
14
  # Merges in the conditions from <tt>other</tt>, if <tt>other</tt> is an ActiveRecord::Relation.
@@ -28,21 +28,22 @@ module ActiveRecord
28
28
  # # => Post.where(published: true).joins(:comments)
29
29
  #
30
30
  # This is mainly intended for sharing common conditions between multiple associations.
31
- def merge(other)
31
+ def merge(other, *rest)
32
32
  if other.is_a?(Array)
33
33
  records & other
34
34
  elsif other
35
- spawn.merge!(other)
35
+ spawn.merge!(other, *rest)
36
36
  else
37
37
  raise ArgumentError, "invalid argument: #{other.inspect}."
38
38
  end
39
39
  end
40
40
 
41
- def merge!(other) # :nodoc:
41
+ def merge!(other, *rest) # :nodoc:
42
+ options = rest.extract_options!
42
43
  if other.is_a?(Hash)
43
- Relation::HashMerger.new(self, other).merge
44
+ Relation::HashMerger.new(self, other, options[:rewhere]).merge
44
45
  elsif other.is_a?(Relation)
45
- Relation::Merger.new(self, other).merge
46
+ Relation::Merger.new(self, other, options[:rewhere]).merge
46
47
  elsif other.respond_to?(:to_proc)
47
48
  instance_exec(&other)
48
49
  else
@@ -67,10 +68,9 @@ module ActiveRecord
67
68
  end
68
69
 
69
70
  private
70
-
71
71
  def relation_with(values)
72
- result = Relation.create(klass, values: values)
73
- result.extend(*extending_values) if extending_values.any?
72
+ result = spawn
73
+ result.instance_variable_set(:@values, values)
74
74
  result
75
75
  end
76
76
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "active_support/core_ext/array/extract"
4
+
3
5
  module ActiveRecord
4
6
  class Relation
5
7
  class WhereClause # :nodoc:
@@ -10,21 +12,25 @@ module ActiveRecord
10
12
  end
11
13
 
12
14
  def +(other)
13
- WhereClause.new(
14
- predicates + other.predicates,
15
- )
15
+ WhereClause.new(predicates + other.predicates)
16
16
  end
17
17
 
18
18
  def -(other)
19
- WhereClause.new(
20
- predicates - other.predicates,
21
- )
19
+ WhereClause.new(predicates - other.predicates)
22
20
  end
23
21
 
24
- def merge(other)
25
- WhereClause.new(
26
- predicates_unreferenced_by(other) + other.predicates,
27
- )
22
+ def |(other)
23
+ WhereClause.new(predicates | other.predicates)
24
+ end
25
+
26
+ def merge(other, rewhere = nil)
27
+ predicates = if rewhere
28
+ except_predicates(other.extract_attributes)
29
+ else
30
+ predicates_unreferenced_by(other)
31
+ end
32
+
33
+ WhereClause.new(predicates | other.predicates)
28
34
  end
29
35
 
30
36
  def except(*columns)
@@ -39,66 +45,111 @@ module ActiveRecord
39
45
  if left.empty? || right.empty?
40
46
  common
41
47
  else
42
- or_clause = WhereClause.new(
43
- [left.ast.or(right.ast)],
44
- )
45
- common + or_clause
46
- end
47
- end
48
+ left = left.ast
49
+ left = left.expr if left.is_a?(Arel::Nodes::Grouping)
48
50
 
49
- def to_h(table_name = nil)
50
- equalities = equalities(predicates)
51
- if table_name
52
- equalities = equalities.select do |node|
53
- node.left.relation.name == table_name
54
- end
51
+ right = right.ast
52
+ right = right.expr if right.is_a?(Arel::Nodes::Grouping)
53
+
54
+ or_clause = Arel::Nodes::Or.new(left, right)
55
+
56
+ common.predicates << Arel::Nodes::Grouping.new(or_clause)
57
+ common
55
58
  end
59
+ end
56
60
 
57
- equalities.map { |node|
61
+ def to_h(table_name = nil, equality_only: false)
62
+ equalities(predicates, equality_only).each_with_object({}) do |node, hash|
63
+ next if table_name&.!= node.left.relation.name
58
64
  name = node.left.name.to_s
59
65
  value = extract_node_value(node.right)
60
- [name, value]
61
- }.to_h
66
+ hash[name] = value
67
+ end
62
68
  end
63
69
 
64
70
  def ast
65
- Arel::Nodes::And.new(predicates_with_wrapped_sql_literals)
71
+ predicates = predicates_with_wrapped_sql_literals
72
+ predicates.one? ? predicates.first : Arel::Nodes::And.new(predicates)
66
73
  end
67
74
 
68
75
  def ==(other)
69
76
  other.is_a?(WhereClause) &&
70
77
  predicates == other.predicates
71
78
  end
79
+ alias :eql? :==
80
+
81
+ def hash
82
+ [self.class, predicates].hash
83
+ end
72
84
 
73
85
  def invert
86
+ if predicates.size == 1
87
+ inverted_predicates = [ invert_predicate(predicates.first) ]
88
+ else
89
+ inverted_predicates = [ Arel::Nodes::Not.new(ast) ]
90
+ end
91
+
74
92
  WhereClause.new(inverted_predicates)
75
93
  end
76
94
 
77
95
  def self.empty
78
- @empty ||= new([])
96
+ @empty ||= new([]).freeze
79
97
  end
80
98
 
81
- protected
99
+ def contradiction?
100
+ predicates.any? do |x|
101
+ case x
102
+ when Arel::Nodes::In
103
+ Array === x.right && x.right.empty?
104
+ when Arel::Nodes::Equality
105
+ x.right.respond_to?(:unboundable?) && x.right.unboundable?
106
+ end
107
+ end
108
+ end
82
109
 
110
+ def extract_attributes
111
+ attrs = []
112
+ each_attributes { |attr, _| attrs << attr }
113
+ attrs
114
+ end
115
+
116
+ protected
83
117
  attr_reader :predicates
84
118
 
85
119
  def referenced_columns
86
- @referenced_columns ||= begin
87
- equality_nodes = predicates.select { |n| equality_node?(n) }
88
- Set.new(equality_nodes, &:left)
89
- end
120
+ hash = {}
121
+ each_attributes { |attr, node| hash[attr] = node }
122
+ hash
90
123
  end
91
124
 
92
125
  private
93
- def equalities(predicates)
126
+ def each_attributes
127
+ predicates.each do |node|
128
+ attr = extract_attribute(node) || begin
129
+ node.left if equality_node?(node) && node.left.is_a?(Arel::Predications)
130
+ end
131
+
132
+ yield attr, node if attr
133
+ end
134
+ end
135
+
136
+ def extract_attribute(node)
137
+ attr_node = nil
138
+ Arel.fetch_attribute(node) do |attr|
139
+ return if attr_node&.!= attr # all attr nodes should be the same
140
+ attr_node = attr
141
+ end
142
+ attr_node
143
+ end
144
+
145
+ def equalities(predicates, equality_only)
94
146
  equalities = []
95
147
 
96
148
  predicates.each do |node|
97
- case node
98
- when Arel::Nodes::Equality
149
+ if equality_only ? Arel::Nodes::Equality === node : equality_node?(node)
99
150
  equalities << node
100
- when Arel::Nodes::And
101
- equalities.concat equalities(node.children)
151
+ elsif node.is_a?(Arel::Nodes::And)
152
+ equalities.concat equalities(node.children, equality_only)
102
153
  end
103
154
  end
104
155
 
@@ -106,40 +157,41 @@ module ActiveRecord
106
157
  end
107
158
 
108
159
  def predicates_unreferenced_by(other)
109
- predicates.reject do |n|
110
- equality_node?(n) && other.referenced_columns.include?(n.left)
160
+ referenced_columns = other.referenced_columns
161
+
162
+ predicates.reject do |node|
163
+ attr = extract_attribute(node) || begin
164
+ node.left if equality_node?(node) && node.left.is_a?(Arel::Predications)
165
+ end
166
+
167
+ attr && referenced_columns[attr]
111
168
  end
112
169
  end
113
170
 
114
171
  def equality_node?(node)
115
- node.respond_to?(:operator) && node.operator == :==
116
- end
117
-
118
- def inverted_predicates
119
- predicates.map { |node| invert_predicate(node) }
172
+ !node.is_a?(String) && node.equality?
120
173
  end
121
174
 
122
175
  def invert_predicate(node)
123
176
  case node
124
177
  when NilClass
125
178
  raise ArgumentError, "Invalid argument for .where.not(), got nil."
126
- when Arel::Nodes::In
127
- Arel::Nodes::NotIn.new(node.left, node.right)
128
- when Arel::Nodes::Equality
129
- Arel::Nodes::NotEqual.new(node.left, node.right)
130
179
  when String
131
180
  Arel::Nodes::Not.new(Arel::Nodes::SqlLiteral.new(node))
132
181
  else
133
- Arel::Nodes::Not.new(node)
182
+ node.invert
134
183
  end
135
184
  end
136
185
 
137
186
  def except_predicates(columns)
187
+ attrs = columns.extract! { |node| node.is_a?(Arel::Attribute) }
188
+ non_attrs = columns.extract! { |node| node.is_a?(Arel::Predications) }
189
+
138
190
  predicates.reject do |node|
139
- case node
140
- when Arel::Nodes::Between, Arel::Nodes::In, Arel::Nodes::NotIn, Arel::Nodes::Equality, Arel::Nodes::NotEqual, Arel::Nodes::LessThan, Arel::Nodes::LessThanOrEqual, Arel::Nodes::GreaterThan, Arel::Nodes::GreaterThanOrEqual
141
- subrelation = (node.left.kind_of?(Arel::Attributes::Attribute) ? node.left : node.right)
142
- columns.include?(subrelation.name.to_s)
191
+ if !non_attrs.empty? && node.equality? && node.left.is_a?(Arel::Predications)
192
+ non_attrs.include?(node.left)
193
+ end || Arel.fetch_attribute(node) do |attr|
194
+ attrs.include?(attr) || columns.include?(attr.name.to_s)
143
195
  end
144
196
  end
145
197
  end
@@ -167,18 +219,10 @@ module ActiveRecord
167
219
  end
168
220
 
169
221
  def extract_node_value(node)
170
- case node
171
- when Array
222
+ if node.respond_to?(:value_before_type_cast)
223
+ node.value_before_type_cast
224
+ elsif Array === node
172
225
  node.map { |v| extract_node_value(v) }
173
- when Arel::Nodes::Casted, Arel::Nodes::Quoted
174
- node.val
175
- when Arel::Nodes::BindParam
176
- value = node.value
177
- if value.respond_to?(:value_before_type_cast)
178
- value.value_before_type_cast
179
- else
180
- value
181
- end
182
226
  end
183
227
  end
184
228
  end