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,298 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arel # :nodoc: all
4
+ module Visitors
5
+ class Dot < Arel::Visitors::Visitor
6
+ class Node # :nodoc:
7
+ attr_accessor :name, :id, :fields
8
+
9
+ def initialize(name, id, fields = [])
10
+ @name = name
11
+ @id = id
12
+ @fields = fields
13
+ end
14
+ end
15
+
16
+ class Edge < Struct.new :name, :from, :to # :nodoc:
17
+ end
18
+
19
+ def initialize
20
+ super()
21
+ @nodes = []
22
+ @edges = []
23
+ @node_stack = []
24
+ @edge_stack = []
25
+ @seen = {}
26
+ end
27
+
28
+ def accept(object, collector)
29
+ visit object
30
+ collector << to_dot
31
+ end
32
+
33
+ private
34
+ def visit_Arel_Nodes_Function(o)
35
+ visit_edge o, "expressions"
36
+ visit_edge o, "distinct"
37
+ visit_edge o, "alias"
38
+ end
39
+
40
+ def visit_Arel_Nodes_Unary(o)
41
+ visit_edge o, "expr"
42
+ end
43
+
44
+ def visit_Arel_Nodes_Binary(o)
45
+ visit_edge o, "left"
46
+ visit_edge o, "right"
47
+ end
48
+
49
+ def visit_Arel_Nodes_UnaryOperation(o)
50
+ visit_edge o, "operator"
51
+ visit_edge o, "expr"
52
+ end
53
+
54
+ def visit_Arel_Nodes_InfixOperation(o)
55
+ visit_edge o, "operator"
56
+ visit_edge o, "left"
57
+ visit_edge o, "right"
58
+ end
59
+
60
+ def visit__regexp(o)
61
+ visit_edge o, "left"
62
+ visit_edge o, "right"
63
+ visit_edge o, "case_sensitive"
64
+ end
65
+ alias :visit_Arel_Nodes_Regexp :visit__regexp
66
+ alias :visit_Arel_Nodes_NotRegexp :visit__regexp
67
+
68
+ def visit_Arel_Nodes_Ordering(o)
69
+ visit_edge o, "expr"
70
+ end
71
+
72
+ def visit_Arel_Nodes_TableAlias(o)
73
+ visit_edge o, "name"
74
+ visit_edge o, "relation"
75
+ end
76
+
77
+ def visit_Arel_Nodes_Count(o)
78
+ visit_edge o, "expressions"
79
+ visit_edge o, "distinct"
80
+ end
81
+
82
+ def visit_Arel_Nodes_ValuesList(o)
83
+ visit_edge o, "rows"
84
+ end
85
+
86
+ def visit_Arel_Nodes_StringJoin(o)
87
+ visit_edge o, "left"
88
+ end
89
+
90
+ def visit_Arel_Nodes_Window(o)
91
+ visit_edge o, "partitions"
92
+ visit_edge o, "orders"
93
+ visit_edge o, "framing"
94
+ end
95
+
96
+ def visit_Arel_Nodes_NamedWindow(o)
97
+ visit_edge o, "partitions"
98
+ visit_edge o, "orders"
99
+ visit_edge o, "framing"
100
+ visit_edge o, "name"
101
+ end
102
+
103
+ def visit__no_edges(o)
104
+ # intentionally left blank
105
+ end
106
+ alias :visit_Arel_Nodes_CurrentRow :visit__no_edges
107
+ alias :visit_Arel_Nodes_Distinct :visit__no_edges
108
+
109
+ def visit_Arel_Nodes_Extract(o)
110
+ visit_edge o, "expressions"
111
+ visit_edge o, "alias"
112
+ end
113
+
114
+ def visit_Arel_Nodes_NamedFunction(o)
115
+ visit_edge o, "name"
116
+ visit_edge o, "expressions"
117
+ visit_edge o, "distinct"
118
+ visit_edge o, "alias"
119
+ end
120
+
121
+ def visit_Arel_Nodes_InsertStatement(o)
122
+ visit_edge o, "relation"
123
+ visit_edge o, "columns"
124
+ visit_edge o, "values"
125
+ visit_edge o, "select"
126
+ end
127
+
128
+ def visit_Arel_Nodes_SelectCore(o)
129
+ visit_edge o, "source"
130
+ visit_edge o, "projections"
131
+ visit_edge o, "wheres"
132
+ visit_edge o, "windows"
133
+ visit_edge o, "groups"
134
+ visit_edge o, "comment"
135
+ visit_edge o, "havings"
136
+ visit_edge o, "set_quantifier"
137
+ visit_edge o, "optimizer_hints"
138
+ end
139
+
140
+ def visit_Arel_Nodes_SelectStatement(o)
141
+ visit_edge o, "cores"
142
+ visit_edge o, "limit"
143
+ visit_edge o, "orders"
144
+ visit_edge o, "offset"
145
+ visit_edge o, "lock"
146
+ visit_edge o, "with"
147
+ end
148
+
149
+ def visit_Arel_Nodes_UpdateStatement(o)
150
+ visit_edge o, "relation"
151
+ visit_edge o, "wheres"
152
+ visit_edge o, "values"
153
+ visit_edge o, "orders"
154
+ visit_edge o, "limit"
155
+ visit_edge o, "offset"
156
+ visit_edge o, "key"
157
+ end
158
+
159
+ def visit_Arel_Nodes_DeleteStatement(o)
160
+ visit_edge o, "relation"
161
+ visit_edge o, "wheres"
162
+ visit_edge o, "orders"
163
+ visit_edge o, "limit"
164
+ visit_edge o, "offset"
165
+ visit_edge o, "key"
166
+ end
167
+
168
+ def visit_Arel_Table(o)
169
+ visit_edge o, "name"
170
+ end
171
+
172
+ def visit_Arel_Nodes_Casted(o)
173
+ visit_edge o, "value"
174
+ visit_edge o, "attribute"
175
+ end
176
+
177
+ def visit_Arel_Nodes_HomogeneousIn(o)
178
+ visit_edge o, "values"
179
+ visit_edge o, "type"
180
+ visit_edge o, "attribute"
181
+ end
182
+
183
+ def visit_Arel_Attributes_Attribute(o)
184
+ visit_edge o, "relation"
185
+ visit_edge o, "name"
186
+ end
187
+
188
+ def visit__children(o)
189
+ o.children.each_with_index do |child, i|
190
+ edge(i) { visit child }
191
+ end
192
+ end
193
+ alias :visit_Arel_Nodes_And :visit__children
194
+ alias :visit_Arel_Nodes_With :visit__children
195
+
196
+ def visit_String(o)
197
+ @node_stack.last.fields << o
198
+ end
199
+ alias :visit_Time :visit_String
200
+ alias :visit_Date :visit_String
201
+ alias :visit_DateTime :visit_String
202
+ alias :visit_NilClass :visit_String
203
+ alias :visit_TrueClass :visit_String
204
+ alias :visit_FalseClass :visit_String
205
+ alias :visit_Integer :visit_String
206
+ alias :visit_BigDecimal :visit_String
207
+ alias :visit_Float :visit_String
208
+ alias :visit_Symbol :visit_String
209
+ alias :visit_Arel_Nodes_SqlLiteral :visit_String
210
+
211
+ def visit_Arel_Nodes_BindParam(o)
212
+ visit_edge(o, "value")
213
+ end
214
+
215
+ def visit_ActiveModel_Attribute(o)
216
+ visit_edge(o, "value_before_type_cast")
217
+ end
218
+
219
+ def visit_Hash(o)
220
+ o.each_with_index do |pair, i|
221
+ edge("pair_#{i}") { visit pair }
222
+ end
223
+ end
224
+
225
+ def visit_Array(o)
226
+ o.each_with_index do |member, i|
227
+ edge(i) { visit member }
228
+ end
229
+ end
230
+ alias :visit_Set :visit_Array
231
+
232
+ def visit_Arel_Nodes_Comment(o)
233
+ visit_edge(o, "values")
234
+ end
235
+
236
+ def visit_Arel_Nodes_Case(o)
237
+ visit_edge(o, "case")
238
+ visit_edge(o, "conditions")
239
+ visit_edge(o, "default")
240
+ end
241
+
242
+ def visit_edge(o, method)
243
+ edge(method) { visit o.send(method) }
244
+ end
245
+
246
+ def visit(o)
247
+ if node = @seen[o.object_id]
248
+ @edge_stack.last.to = node
249
+ return
250
+ end
251
+
252
+ node = Node.new(o.class.name, o.object_id)
253
+ @seen[node.id] = node
254
+ @nodes << node
255
+ with_node node do
256
+ super
257
+ end
258
+ end
259
+
260
+ def edge(name)
261
+ edge = Edge.new(name, @node_stack.last)
262
+ @edge_stack.push edge
263
+ @edges << edge
264
+ yield
265
+ @edge_stack.pop
266
+ end
267
+
268
+ def with_node(node)
269
+ if edge = @edge_stack.last
270
+ edge.to = node
271
+ end
272
+
273
+ @node_stack.push node
274
+ yield
275
+ @node_stack.pop
276
+ end
277
+
278
+ def quote(string)
279
+ string.to_s.gsub('"', '\"')
280
+ end
281
+
282
+ def to_dot
283
+ "digraph \"Arel\" {\nnode [width=0.375,height=0.25,shape=record];\n" +
284
+ @nodes.map { |node|
285
+ label = "<f0>#{node.name}"
286
+
287
+ node.fields.each_with_index do |field, i|
288
+ label += "|<f#{i + 1}>#{quote field}"
289
+ end
290
+
291
+ "#{node.id} [label=\"#{label}\"];"
292
+ }.join("\n") + "\n" + @edges.map { |edge|
293
+ "#{edge.from.id} -> #{edge.to.id} [label=\"#{edge.name}\"];"
294
+ }.join("\n") + "\n}"
295
+ end
296
+ end
297
+ end
298
+ end
@@ -0,0 +1,99 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arel # :nodoc: all
4
+ module Visitors
5
+ class MySQL < Arel::Visitors::ToSql
6
+ private
7
+ def visit_Arel_Nodes_Bin(o, collector)
8
+ collector << "BINARY "
9
+ visit o.expr, collector
10
+ end
11
+
12
+ def visit_Arel_Nodes_UnqualifiedColumn(o, collector)
13
+ visit o.expr, collector
14
+ end
15
+
16
+ ###
17
+ # :'(
18
+ # To retrieve all rows from a certain offset up to the end of the result set,
19
+ # you can use some large number for the second parameter.
20
+ # https://dev.mysql.com/doc/refman/en/select.html
21
+ def visit_Arel_Nodes_SelectStatement(o, collector)
22
+ if o.offset && !o.limit
23
+ o.limit = Arel::Nodes::Limit.new(18446744073709551615)
24
+ end
25
+ super
26
+ end
27
+
28
+ def visit_Arel_Nodes_SelectCore(o, collector)
29
+ o.froms ||= Arel.sql("DUAL")
30
+ super
31
+ end
32
+
33
+ def visit_Arel_Nodes_Concat(o, collector)
34
+ collector << " CONCAT("
35
+ visit o.left, collector
36
+ collector << ", "
37
+ visit o.right, collector
38
+ collector << ") "
39
+ collector
40
+ end
41
+
42
+ def visit_Arel_Nodes_IsNotDistinctFrom(o, collector)
43
+ collector = visit o.left, collector
44
+ collector << " <=> "
45
+ visit o.right, collector
46
+ end
47
+
48
+ def visit_Arel_Nodes_IsDistinctFrom(o, collector)
49
+ collector << "NOT "
50
+ visit_Arel_Nodes_IsNotDistinctFrom o, collector
51
+ end
52
+
53
+ def visit_Arel_Nodes_Regexp(o, collector)
54
+ infix_value o, collector, " REGEXP "
55
+ end
56
+
57
+ def visit_Arel_Nodes_NotRegexp(o, collector)
58
+ infix_value o, collector, " NOT REGEXP "
59
+ end
60
+
61
+ # no-op
62
+ def visit_Arel_Nodes_NullsFirst(o, collector)
63
+ visit o.expr, collector
64
+ end
65
+
66
+ # In the simple case, MySQL allows us to place JOINs directly into the UPDATE
67
+ # query. However, this does not allow for LIMIT, OFFSET and ORDER. To support
68
+ # these, we must use a subquery.
69
+ def prepare_update_statement(o)
70
+ if o.offset || has_group_by_and_having?(o) ||
71
+ has_join_sources?(o) && has_limit_or_offset_or_orders?(o)
72
+ super
73
+ else
74
+ o
75
+ end
76
+ end
77
+ alias :prepare_delete_statement :prepare_update_statement
78
+
79
+ # MySQL doesn't automatically create a temporary table for use subquery, so we have
80
+ # to give it some prompting in the form of a subsubquery.
81
+ def build_subselect(key, o)
82
+ subselect = super
83
+
84
+ # Materialize subquery by adding distinct
85
+ # to work with MySQL 5.7.6 which sets optimizer_switch='derived_merge=on'
86
+ unless has_limit_or_offset_or_orders?(subselect)
87
+ core = subselect.cores.last
88
+ core.set_quantifier = Arel::Nodes::Distinct.new
89
+ end
90
+
91
+ Nodes::SelectStatement.new.tap do |stmt|
92
+ core = stmt.cores.last
93
+ core.froms = Nodes::Grouping.new(subselect).as("__active_record_temp")
94
+ core.projections = [Arel.sql(quote_column_name(key.name))]
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,110 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arel # :nodoc: all
4
+ module Visitors
5
+ class PostgreSQL < Arel::Visitors::ToSql
6
+ private
7
+ def visit_Arel_Nodes_Matches(o, collector)
8
+ op = o.case_sensitive ? " LIKE " : " ILIKE "
9
+ collector = infix_value o, collector, op
10
+ if o.escape
11
+ collector << " ESCAPE "
12
+ visit o.escape, collector
13
+ else
14
+ collector
15
+ end
16
+ end
17
+
18
+ def visit_Arel_Nodes_DoesNotMatch(o, collector)
19
+ op = o.case_sensitive ? " NOT LIKE " : " NOT ILIKE "
20
+ collector = infix_value o, collector, op
21
+ if o.escape
22
+ collector << " ESCAPE "
23
+ visit o.escape, collector
24
+ else
25
+ collector
26
+ end
27
+ end
28
+
29
+ def visit_Arel_Nodes_Regexp(o, collector)
30
+ op = o.case_sensitive ? " ~ " : " ~* "
31
+ infix_value o, collector, op
32
+ end
33
+
34
+ def visit_Arel_Nodes_NotRegexp(o, collector)
35
+ op = o.case_sensitive ? " !~ " : " !~* "
36
+ infix_value o, collector, op
37
+ end
38
+
39
+ def visit_Arel_Nodes_DistinctOn(o, collector)
40
+ collector << "DISTINCT ON ( "
41
+ visit(o.expr, collector) << " )"
42
+ end
43
+
44
+ def visit_Arel_Nodes_GroupingElement(o, collector)
45
+ collector << "( "
46
+ visit(o.expr, collector) << " )"
47
+ end
48
+
49
+ def visit_Arel_Nodes_Cube(o, collector)
50
+ collector << "CUBE"
51
+ grouping_array_or_grouping_element o, collector
52
+ end
53
+
54
+ def visit_Arel_Nodes_RollUp(o, collector)
55
+ collector << "ROLLUP"
56
+ grouping_array_or_grouping_element o, collector
57
+ end
58
+
59
+ def visit_Arel_Nodes_GroupingSet(o, collector)
60
+ collector << "GROUPING SETS"
61
+ grouping_array_or_grouping_element o, collector
62
+ end
63
+
64
+ def visit_Arel_Nodes_Lateral(o, collector)
65
+ collector << "LATERAL "
66
+ grouping_parentheses o, collector
67
+ end
68
+
69
+ def visit_Arel_Nodes_IsNotDistinctFrom(o, collector)
70
+ collector = visit o.left, collector
71
+ collector << " IS NOT DISTINCT FROM "
72
+ visit o.right, collector
73
+ end
74
+
75
+ def visit_Arel_Nodes_IsDistinctFrom(o, collector)
76
+ collector = visit o.left, collector
77
+ collector << " IS DISTINCT FROM "
78
+ visit o.right, collector
79
+ end
80
+
81
+ BIND_BLOCK = proc { |i| "$#{i}" }
82
+ private_constant :BIND_BLOCK
83
+
84
+ def bind_block; BIND_BLOCK; end
85
+
86
+ # Used by Lateral visitor to enclose select queries in parentheses
87
+ def grouping_parentheses(o, collector)
88
+ if o.expr.is_a? Nodes::SelectStatement
89
+ collector << "("
90
+ visit o.expr, collector
91
+ collector << ")"
92
+ else
93
+ visit o.expr, collector
94
+ end
95
+ end
96
+
97
+ # Utilized by GroupingSet, Cube & RollUp visitors to
98
+ # handle grouping aggregation semantics
99
+ def grouping_array_or_grouping_element(o, collector)
100
+ if o.expr.is_a? Array
101
+ collector << "( "
102
+ visit o.expr, collector
103
+ collector << " )"
104
+ else
105
+ visit o.expr, collector
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arel # :nodoc: all
4
+ module Visitors
5
+ class SQLite < Arel::Visitors::ToSql
6
+ private
7
+ # Locks are not supported in SQLite
8
+ def visit_Arel_Nodes_Lock(o, collector)
9
+ collector
10
+ end
11
+
12
+ def visit_Arel_Nodes_SelectStatement(o, collector)
13
+ o.limit = Arel::Nodes::Limit.new(-1) if o.offset && !o.limit
14
+ super
15
+ end
16
+
17
+ def visit_Arel_Nodes_True(o, collector)
18
+ collector << "1"
19
+ end
20
+
21
+ def visit_Arel_Nodes_False(o, collector)
22
+ collector << "0"
23
+ end
24
+
25
+ def visit_Arel_Nodes_IsNotDistinctFrom(o, collector)
26
+ collector = visit o.left, collector
27
+ collector << " IS "
28
+ visit o.right, collector
29
+ end
30
+
31
+ def visit_Arel_Nodes_IsDistinctFrom(o, collector)
32
+ collector = visit o.left, collector
33
+ collector << " IS NOT "
34
+ visit o.right, collector
35
+ end
36
+ end
37
+ end
38
+ end