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
@@ -0,0 +1,276 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arel # :nodoc: all
4
+ class SelectManager < Arel::TreeManager
5
+ include Arel::Crud
6
+
7
+ STRING_OR_SYMBOL_CLASS = [Symbol, String]
8
+
9
+ def initialize(table = nil)
10
+ @ast = Nodes::SelectStatement.new(table)
11
+ @ctx = @ast.cores.last
12
+ end
13
+
14
+ def initialize_copy(other)
15
+ super
16
+ @ctx = @ast.cores.last
17
+ end
18
+
19
+ def limit
20
+ @ast.limit && @ast.limit.expr
21
+ end
22
+ alias :taken :limit
23
+
24
+ def constraints
25
+ @ctx.wheres
26
+ end
27
+
28
+ def offset
29
+ @ast.offset && @ast.offset.expr
30
+ end
31
+
32
+ def skip(amount)
33
+ if amount
34
+ @ast.offset = Nodes::Offset.new(amount)
35
+ else
36
+ @ast.offset = nil
37
+ end
38
+ self
39
+ end
40
+ alias :offset= :skip
41
+
42
+ ###
43
+ # Produces an Arel::Nodes::Exists node
44
+ def exists
45
+ Arel::Nodes::Exists.new @ast
46
+ end
47
+
48
+ def as(other)
49
+ create_table_alias grouping(@ast), Nodes::SqlLiteral.new(other)
50
+ end
51
+
52
+ def lock(locking = Arel.sql("FOR UPDATE"))
53
+ case locking
54
+ when true
55
+ locking = Arel.sql("FOR UPDATE")
56
+ when Arel::Nodes::SqlLiteral
57
+ when String
58
+ locking = Arel.sql locking
59
+ end
60
+
61
+ @ast.lock = Nodes::Lock.new(locking)
62
+ self
63
+ end
64
+
65
+ def locked
66
+ @ast.lock
67
+ end
68
+
69
+ def on(*exprs)
70
+ @ctx.source.right.last.right = Nodes::On.new(collapse(exprs))
71
+ self
72
+ end
73
+
74
+ def group(*columns)
75
+ columns.each do |column|
76
+ # FIXME: backwards compat
77
+ column = Nodes::SqlLiteral.new(column) if String === column
78
+ column = Nodes::SqlLiteral.new(column.to_s) if Symbol === column
79
+
80
+ @ctx.groups.push Nodes::Group.new column
81
+ end
82
+ self
83
+ end
84
+
85
+ def from(table)
86
+ table = Nodes::SqlLiteral.new(table) if String === table
87
+
88
+ case table
89
+ when Nodes::Join
90
+ @ctx.source.right << table
91
+ else
92
+ @ctx.source.left = table
93
+ end
94
+
95
+ self
96
+ end
97
+
98
+ def froms
99
+ @ast.cores.filter_map { |x| x.from }
100
+ end
101
+
102
+ def join(relation, klass = Nodes::InnerJoin)
103
+ return self unless relation
104
+
105
+ case relation
106
+ when String, Nodes::SqlLiteral
107
+ raise EmptyJoinError if relation.empty?
108
+ klass = Nodes::StringJoin
109
+ end
110
+
111
+ @ctx.source.right << create_join(relation, nil, klass)
112
+ self
113
+ end
114
+
115
+ def outer_join(relation)
116
+ join(relation, Nodes::OuterJoin)
117
+ end
118
+
119
+ def having(expr)
120
+ @ctx.havings << expr
121
+ self
122
+ end
123
+
124
+ def window(name)
125
+ window = Nodes::NamedWindow.new(name)
126
+ @ctx.windows.push window
127
+ window
128
+ end
129
+
130
+ def project(*projections)
131
+ # FIXME: converting these to SQLLiterals is probably not good, but
132
+ # rails tests require it.
133
+ @ctx.projections.concat projections.map { |x|
134
+ STRING_OR_SYMBOL_CLASS.include?(x.class) ? Nodes::SqlLiteral.new(x.to_s) : x
135
+ }
136
+ self
137
+ end
138
+
139
+ def projections
140
+ @ctx.projections
141
+ end
142
+
143
+ def projections=(projections)
144
+ @ctx.projections = projections
145
+ end
146
+
147
+ def optimizer_hints(*hints)
148
+ unless hints.empty?
149
+ @ctx.optimizer_hints = Arel::Nodes::OptimizerHints.new(hints)
150
+ end
151
+ self
152
+ end
153
+
154
+ def distinct(value = true)
155
+ if value
156
+ @ctx.set_quantifier = Arel::Nodes::Distinct.new
157
+ else
158
+ @ctx.set_quantifier = nil
159
+ end
160
+ self
161
+ end
162
+
163
+ def distinct_on(value)
164
+ if value
165
+ @ctx.set_quantifier = Arel::Nodes::DistinctOn.new(value)
166
+ else
167
+ @ctx.set_quantifier = nil
168
+ end
169
+ self
170
+ end
171
+
172
+ def order(*expr)
173
+ # FIXME: We SHOULD NOT be converting these to SqlLiteral automatically
174
+ @ast.orders.concat expr.map { |x|
175
+ STRING_OR_SYMBOL_CLASS.include?(x.class) ? Nodes::SqlLiteral.new(x.to_s) : x
176
+ }
177
+ self
178
+ end
179
+
180
+ def orders
181
+ @ast.orders
182
+ end
183
+
184
+ def where(expr)
185
+ if Arel::TreeManager === expr
186
+ expr = expr.ast
187
+ end
188
+ @ctx.wheres << expr
189
+ self
190
+ end
191
+
192
+ def where_sql(engine = Table.engine)
193
+ return if @ctx.wheres.empty?
194
+
195
+ Nodes::SqlLiteral.new("WHERE #{Nodes::And.new(@ctx.wheres).to_sql(engine)}")
196
+ end
197
+
198
+ def union(operation, other = nil)
199
+ if other
200
+ node_class = Nodes.const_get("Union#{operation.to_s.capitalize}")
201
+ else
202
+ other = operation
203
+ node_class = Nodes::Union
204
+ end
205
+
206
+ node_class.new self.ast, other.ast
207
+ end
208
+
209
+ def intersect(other)
210
+ Nodes::Intersect.new ast, other.ast
211
+ end
212
+
213
+ def except(other)
214
+ Nodes::Except.new ast, other.ast
215
+ end
216
+ alias :minus :except
217
+
218
+ def lateral(table_name = nil)
219
+ base = table_name.nil? ? ast : as(table_name)
220
+ Nodes::Lateral.new(base)
221
+ end
222
+
223
+ def with(*subqueries)
224
+ if subqueries.first.is_a? Symbol
225
+ node_class = Nodes.const_get("With#{subqueries.shift.to_s.capitalize}")
226
+ else
227
+ node_class = Nodes::With
228
+ end
229
+ @ast.with = node_class.new(subqueries.flatten)
230
+
231
+ self
232
+ end
233
+
234
+ def take(limit)
235
+ if limit
236
+ @ast.limit = Nodes::Limit.new(limit)
237
+ else
238
+ @ast.limit = nil
239
+ end
240
+ self
241
+ end
242
+ alias limit= take
243
+
244
+ def join_sources
245
+ @ctx.source.right
246
+ end
247
+
248
+ def source
249
+ @ctx.source
250
+ end
251
+
252
+ def comment(*values)
253
+ @ctx.comment = Nodes::Comment.new(values)
254
+ self
255
+ end
256
+
257
+ private
258
+ def collapse(exprs)
259
+ exprs = exprs.compact
260
+ exprs.map! { |expr|
261
+ if String === expr
262
+ # FIXME: Don't do this automatically
263
+ Arel.sql(expr)
264
+ else
265
+ expr
266
+ end
267
+ }
268
+
269
+ if exprs.length == 1
270
+ exprs.first
271
+ else
272
+ create_and exprs
273
+ end
274
+ end
275
+ end
276
+ end
data/lib/arel/table.rb ADDED
@@ -0,0 +1,117 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arel # :nodoc: all
4
+ class Table
5
+ include Arel::FactoryMethods
6
+ include Arel::AliasPredication
7
+
8
+ @engine = nil
9
+ class << self; attr_accessor :engine; end
10
+
11
+ attr_accessor :name, :table_alias
12
+
13
+ # TableAlias and Table both have a #table_name which is the name of the underlying table
14
+ alias :table_name :name
15
+
16
+ def initialize(name, as: nil, klass: nil, type_caster: klass&.type_caster)
17
+ @name = name.to_s
18
+ @klass = klass
19
+ @type_caster = type_caster
20
+
21
+ # Sometime AR sends an :as parameter to table, to let the table know
22
+ # that it is an Alias. We may want to override new, and return a
23
+ # TableAlias node?
24
+ if as.to_s == @name
25
+ as = nil
26
+ end
27
+ @table_alias = as
28
+ end
29
+
30
+ def alias(name = "#{self.name}_2")
31
+ Nodes::TableAlias.new(self, name)
32
+ end
33
+
34
+ def from
35
+ SelectManager.new(self)
36
+ end
37
+
38
+ def join(relation, klass = Nodes::InnerJoin)
39
+ return from unless relation
40
+
41
+ case relation
42
+ when String, Nodes::SqlLiteral
43
+ raise EmptyJoinError if relation.empty?
44
+ klass = Nodes::StringJoin
45
+ end
46
+
47
+ from.join(relation, klass)
48
+ end
49
+
50
+ def outer_join(relation)
51
+ join(relation, Nodes::OuterJoin)
52
+ end
53
+
54
+ def group(*columns)
55
+ from.group(*columns)
56
+ end
57
+
58
+ def order(*expr)
59
+ from.order(*expr)
60
+ end
61
+
62
+ def where(condition)
63
+ from.where condition
64
+ end
65
+
66
+ def project(*things)
67
+ from.project(*things)
68
+ end
69
+
70
+ def take(amount)
71
+ from.take amount
72
+ end
73
+
74
+ def skip(amount)
75
+ from.skip amount
76
+ end
77
+
78
+ def having(expr)
79
+ from.having expr
80
+ end
81
+
82
+ def [](name, table = self)
83
+ name = name.to_s if name.is_a?(Symbol)
84
+ name = @klass.attribute_aliases[name] || name if @klass
85
+ Attribute.new(table, name)
86
+ end
87
+
88
+ def hash
89
+ # Perf note: aliases and table alias is excluded from the hash
90
+ # aliases can have a loop back to this table breaking hashes in parent
91
+ # relations, for the vast majority of cases @name is unique to a query
92
+ @name.hash
93
+ end
94
+
95
+ def eql?(other)
96
+ self.class == other.class &&
97
+ self.name == other.name &&
98
+ self.table_alias == other.table_alias
99
+ end
100
+ alias :== :eql?
101
+
102
+ def type_cast_for_database(attr_name, value)
103
+ type_caster.type_cast_for_database(attr_name, value)
104
+ end
105
+
106
+ def type_for_attribute(name)
107
+ type_caster.type_for_attribute(name)
108
+ end
109
+
110
+ def able_to_type_cast?
111
+ !type_caster.nil?
112
+ end
113
+
114
+ private
115
+ attr_reader :type_caster
116
+ end
117
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arel # :nodoc: all
4
+ class TreeManager
5
+ include Arel::FactoryMethods
6
+
7
+ module StatementMethods
8
+ def take(limit)
9
+ @ast.limit = Nodes::Limit.new(Nodes.build_quoted(limit)) if limit
10
+ self
11
+ end
12
+
13
+ def offset(offset)
14
+ @ast.offset = Nodes::Offset.new(Nodes.build_quoted(offset)) if offset
15
+ self
16
+ end
17
+
18
+ def order(*expr)
19
+ @ast.orders = expr
20
+ self
21
+ end
22
+
23
+ def key=(key)
24
+ @ast.key = Nodes.build_quoted(key)
25
+ end
26
+
27
+ def key
28
+ @ast.key
29
+ end
30
+
31
+ def wheres=(exprs)
32
+ @ast.wheres = exprs
33
+ end
34
+
35
+ def where(expr)
36
+ @ast.wheres << expr
37
+ self
38
+ end
39
+ end
40
+
41
+ attr_reader :ast
42
+
43
+ def to_dot
44
+ collector = Arel::Collectors::PlainString.new
45
+ collector = Visitors::Dot.new.accept @ast, collector
46
+ collector.value
47
+ end
48
+
49
+ def to_sql(engine = Table.engine)
50
+ collector = Arel::Collectors::SQLString.new
51
+ collector = engine.connection.visitor.accept @ast, collector
52
+ collector.value
53
+ end
54
+
55
+ def initialize_copy(other)
56
+ super
57
+ @ast = @ast.clone
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arel # :nodoc: all
4
+ class UpdateManager < Arel::TreeManager
5
+ include TreeManager::StatementMethods
6
+
7
+ def initialize(table = nil)
8
+ @ast = Nodes::UpdateStatement.new(table)
9
+ end
10
+
11
+ ###
12
+ # UPDATE +table+
13
+ def table(table)
14
+ @ast.relation = table
15
+ self
16
+ end
17
+
18
+ def set(values)
19
+ if String === values
20
+ @ast.values = [values]
21
+ else
22
+ @ast.values = values.map { |column, value|
23
+ Nodes::Assignment.new(
24
+ Nodes::UnqualifiedColumn.new(column),
25
+ value
26
+ )
27
+ }
28
+ end
29
+ self
30
+ end
31
+
32
+ def group(columns)
33
+ columns.each do |column|
34
+ column = Nodes::SqlLiteral.new(column) if String === column
35
+ column = Nodes::SqlLiteral.new(column.to_s) if Symbol === column
36
+
37
+ @ast.groups.push Nodes::Group.new column
38
+ end
39
+
40
+ self
41
+ end
42
+
43
+ def having(expr)
44
+ @ast.havings << expr
45
+ self
46
+ end
47
+ end
48
+ end