activerecord 4.2.8 → 6.0.0

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 (372) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +612 -1583
  3. data/MIT-LICENSE +4 -2
  4. data/README.rdoc +13 -12
  5. data/examples/performance.rb +33 -32
  6. data/examples/simple.rb +5 -4
  7. data/lib/active_record.rb +41 -22
  8. data/lib/active_record/aggregations.rb +267 -251
  9. data/lib/active_record/association_relation.rb +11 -6
  10. data/lib/active_record/associations.rb +1737 -1597
  11. data/lib/active_record/associations/alias_tracker.rb +29 -35
  12. data/lib/active_record/associations/association.rb +125 -58
  13. data/lib/active_record/associations/association_scope.rb +103 -132
  14. data/lib/active_record/associations/belongs_to_association.rb +65 -60
  15. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -12
  16. data/lib/active_record/associations/builder/association.rb +27 -40
  17. data/lib/active_record/associations/builder/belongs_to.rb +69 -55
  18. data/lib/active_record/associations/builder/collection_association.rb +10 -33
  19. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +52 -66
  20. data/lib/active_record/associations/builder/has_many.rb +8 -4
  21. data/lib/active_record/associations/builder/has_one.rb +46 -5
  22. data/lib/active_record/associations/builder/singular_association.rb +16 -10
  23. data/lib/active_record/associations/collection_association.rb +134 -286
  24. data/lib/active_record/associations/collection_proxy.rb +241 -146
  25. data/lib/active_record/associations/foreign_association.rb +10 -1
  26. data/lib/active_record/associations/has_many_association.rb +34 -97
  27. data/lib/active_record/associations/has_many_through_association.rb +60 -87
  28. data/lib/active_record/associations/has_one_association.rb +61 -49
  29. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  30. data/lib/active_record/associations/join_dependency.rb +137 -167
  31. data/lib/active_record/associations/join_dependency/join_association.rb +38 -88
  32. data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
  33. data/lib/active_record/associations/join_dependency/join_part.rb +14 -14
  34. data/lib/active_record/associations/preloader.rb +90 -92
  35. data/lib/active_record/associations/preloader/association.rb +90 -123
  36. data/lib/active_record/associations/preloader/through_association.rb +85 -65
  37. data/lib/active_record/associations/singular_association.rb +18 -39
  38. data/lib/active_record/associations/through_association.rb +38 -18
  39. data/lib/active_record/attribute_assignment.rb +56 -183
  40. data/lib/active_record/attribute_decorators.rb +39 -15
  41. data/lib/active_record/attribute_methods.rb +120 -135
  42. data/lib/active_record/attribute_methods/before_type_cast.rb +13 -8
  43. data/lib/active_record/attribute_methods/dirty.rb +174 -144
  44. data/lib/active_record/attribute_methods/primary_key.rb +91 -83
  45. data/lib/active_record/attribute_methods/query.rb +6 -5
  46. data/lib/active_record/attribute_methods/read.rb +20 -76
  47. data/lib/active_record/attribute_methods/serialization.rb +40 -20
  48. data/lib/active_record/attribute_methods/time_zone_conversion.rb +58 -36
  49. data/lib/active_record/attribute_methods/write.rb +32 -54
  50. data/lib/active_record/attributes.rb +214 -82
  51. data/lib/active_record/autosave_association.rb +91 -37
  52. data/lib/active_record/base.rb +57 -45
  53. data/lib/active_record/callbacks.rb +100 -74
  54. data/lib/active_record/coders/json.rb +3 -1
  55. data/lib/active_record/coders/yaml_column.rb +24 -12
  56. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +796 -296
  57. data/lib/active_record/connection_adapters/abstract/database_limits.rb +26 -8
  58. data/lib/active_record/connection_adapters/abstract/database_statements.rb +234 -115
  59. data/lib/active_record/connection_adapters/abstract/query_cache.rb +82 -23
  60. data/lib/active_record/connection_adapters/abstract/quoting.rb +170 -53
  61. data/lib/active_record/connection_adapters/abstract/savepoints.rb +5 -3
  62. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +74 -46
  63. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +356 -227
  64. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +79 -36
  65. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +664 -244
  66. data/lib/active_record/connection_adapters/abstract/transaction.rb +191 -83
  67. data/lib/active_record/connection_adapters/abstract_adapter.rb +460 -204
  68. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +510 -627
  69. data/lib/active_record/connection_adapters/column.rb +56 -43
  70. data/lib/active_record/connection_adapters/connection_specification.rb +174 -152
  71. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +29 -0
  72. data/lib/active_record/connection_adapters/mysql/column.rb +27 -0
  73. data/lib/active_record/connection_adapters/mysql/database_statements.rb +200 -0
  74. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +72 -0
  75. data/lib/active_record/connection_adapters/mysql/quoting.rb +81 -0
  76. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +72 -0
  77. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +95 -0
  78. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +88 -0
  79. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +264 -0
  80. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +31 -0
  81. data/lib/active_record/connection_adapters/mysql2_adapter.rb +58 -188
  82. data/lib/active_record/connection_adapters/postgresql/column.rb +21 -11
  83. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +64 -114
  84. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
  85. data/lib/active_record/connection_adapters/postgresql/oid.rb +23 -25
  86. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +50 -58
  87. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +9 -8
  88. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  89. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +4 -2
  90. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +5 -1
  91. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +13 -1
  92. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +9 -22
  93. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  94. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -3
  95. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +31 -19
  96. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  97. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
  98. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +45 -0
  99. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -9
  100. data/lib/active_record/connection_adapters/postgresql/oid/{integer.rb → oid.rb} +6 -2
  101. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +33 -11
  102. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +52 -34
  103. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -5
  104. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +58 -54
  105. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +10 -5
  106. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +3 -1
  107. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +3 -1
  108. data/lib/active_record/connection_adapters/postgresql/quoting.rb +144 -47
  109. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +27 -14
  110. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -0
  111. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +178 -108
  112. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +50 -0
  113. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +470 -290
  114. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +36 -0
  115. data/lib/active_record/connection_adapters/postgresql/utils.rb +12 -8
  116. data/lib/active_record/connection_adapters/postgresql_adapter.rb +551 -356
  117. data/lib/active_record/connection_adapters/schema_cache.rb +72 -25
  118. data/lib/active_record/connection_adapters/sql_type_metadata.rb +37 -0
  119. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +118 -0
  120. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +21 -0
  121. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +103 -0
  122. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +17 -0
  123. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
  124. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
  125. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +137 -0
  126. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +290 -345
  127. data/lib/active_record/connection_adapters/statement_pool.rb +34 -13
  128. data/lib/active_record/connection_handling.rb +176 -41
  129. data/lib/active_record/core.rb +251 -231
  130. data/lib/active_record/counter_cache.rb +67 -49
  131. data/lib/active_record/database_configurations.rb +233 -0
  132. data/lib/active_record/database_configurations/database_config.rb +37 -0
  133. data/lib/active_record/database_configurations/hash_config.rb +50 -0
  134. data/lib/active_record/database_configurations/url_config.rb +79 -0
  135. data/lib/active_record/define_callbacks.rb +22 -0
  136. data/lib/active_record/dynamic_matchers.rb +87 -105
  137. data/lib/active_record/enum.rb +163 -86
  138. data/lib/active_record/errors.rb +188 -53
  139. data/lib/active_record/explain.rb +23 -11
  140. data/lib/active_record/explain_registry.rb +4 -2
  141. data/lib/active_record/explain_subscriber.rb +10 -5
  142. data/lib/active_record/fixture_set/file.rb +35 -9
  143. data/lib/active_record/fixture_set/model_metadata.rb +33 -0
  144. data/lib/active_record/fixture_set/render_context.rb +17 -0
  145. data/lib/active_record/fixture_set/table_row.rb +153 -0
  146. data/lib/active_record/fixture_set/table_rows.rb +47 -0
  147. data/lib/active_record/fixtures.rb +228 -499
  148. data/lib/active_record/gem_version.rb +5 -3
  149. data/lib/active_record/inheritance.rb +158 -112
  150. data/lib/active_record/insert_all.rb +179 -0
  151. data/lib/active_record/integration.rb +123 -29
  152. data/lib/active_record/internal_metadata.rb +53 -0
  153. data/lib/active_record/legacy_yaml_adapter.rb +21 -3
  154. data/lib/active_record/locale/en.yml +3 -2
  155. data/lib/active_record/locking/optimistic.rb +87 -96
  156. data/lib/active_record/locking/pessimistic.rb +18 -6
  157. data/lib/active_record/log_subscriber.rb +76 -33
  158. data/lib/active_record/middleware/database_selector.rb +75 -0
  159. data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
  160. data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
  161. data/lib/active_record/migration.rb +626 -283
  162. data/lib/active_record/migration/command_recorder.rb +177 -90
  163. data/lib/active_record/migration/compatibility.rb +244 -0
  164. data/lib/active_record/migration/join_table.rb +8 -6
  165. data/lib/active_record/model_schema.rb +314 -112
  166. data/lib/active_record/nested_attributes.rb +264 -222
  167. data/lib/active_record/no_touching.rb +14 -1
  168. data/lib/active_record/null_relation.rb +24 -37
  169. data/lib/active_record/persistence.rb +557 -125
  170. data/lib/active_record/query_cache.rb +19 -23
  171. data/lib/active_record/querying.rb +43 -29
  172. data/lib/active_record/railtie.rb +147 -46
  173. data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
  174. data/lib/active_record/railties/console_sandbox.rb +2 -0
  175. data/lib/active_record/railties/controller_runtime.rb +34 -33
  176. data/lib/active_record/railties/databases.rake +330 -197
  177. data/lib/active_record/readonly_attributes.rb +5 -4
  178. data/lib/active_record/reflection.rb +428 -279
  179. data/lib/active_record/relation.rb +518 -341
  180. data/lib/active_record/relation/batches.rb +207 -55
  181. data/lib/active_record/relation/batches/batch_enumerator.rb +69 -0
  182. data/lib/active_record/relation/calculations.rb +267 -253
  183. data/lib/active_record/relation/delegation.rb +70 -80
  184. data/lib/active_record/relation/finder_methods.rb +277 -241
  185. data/lib/active_record/relation/from_clause.rb +26 -0
  186. data/lib/active_record/relation/merger.rb +78 -87
  187. data/lib/active_record/relation/predicate_builder.rb +114 -119
  188. data/lib/active_record/relation/predicate_builder/array_handler.rb +27 -26
  189. data/lib/active_record/relation/predicate_builder/association_query_value.rb +43 -0
  190. data/lib/active_record/relation/predicate_builder/base_handler.rb +18 -0
  191. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +19 -0
  192. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +53 -0
  193. data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -0
  194. data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
  195. data/lib/active_record/relation/query_attribute.rb +50 -0
  196. data/lib/active_record/relation/query_methods.rb +575 -394
  197. data/lib/active_record/relation/record_fetch_warning.rb +51 -0
  198. data/lib/active_record/relation/spawn_methods.rb +11 -13
  199. data/lib/active_record/relation/where_clause.rb +190 -0
  200. data/lib/active_record/relation/where_clause_factory.rb +33 -0
  201. data/lib/active_record/result.rb +79 -42
  202. data/lib/active_record/runtime_registry.rb +6 -4
  203. data/lib/active_record/sanitization.rb +144 -121
  204. data/lib/active_record/schema.rb +21 -24
  205. data/lib/active_record/schema_dumper.rb +112 -93
  206. data/lib/active_record/schema_migration.rb +24 -17
  207. data/lib/active_record/scoping.rb +45 -26
  208. data/lib/active_record/scoping/default.rb +101 -85
  209. data/lib/active_record/scoping/named.rb +86 -33
  210. data/lib/active_record/secure_token.rb +40 -0
  211. data/lib/active_record/serialization.rb +5 -5
  212. data/lib/active_record/statement_cache.rb +73 -36
  213. data/lib/active_record/store.rb +127 -42
  214. data/lib/active_record/suppressor.rb +61 -0
  215. data/lib/active_record/table_metadata.rb +75 -0
  216. data/lib/active_record/tasks/database_tasks.rb +308 -99
  217. data/lib/active_record/tasks/mysql_database_tasks.rb +55 -99
  218. data/lib/active_record/tasks/postgresql_database_tasks.rb +81 -41
  219. data/lib/active_record/tasks/sqlite_database_tasks.rb +38 -16
  220. data/lib/active_record/test_databases.rb +23 -0
  221. data/lib/active_record/test_fixtures.rb +224 -0
  222. data/lib/active_record/timestamp.rb +86 -40
  223. data/lib/active_record/touch_later.rb +66 -0
  224. data/lib/active_record/transactions.rb +216 -150
  225. data/lib/active_record/translation.rb +3 -1
  226. data/lib/active_record/type.rb +78 -23
  227. data/lib/active_record/type/adapter_specific_registry.rb +129 -0
  228. data/lib/active_record/type/date.rb +4 -45
  229. data/lib/active_record/type/date_time.rb +4 -49
  230. data/lib/active_record/type/decimal_without_scale.rb +6 -2
  231. data/lib/active_record/type/hash_lookup_type_map.rb +5 -3
  232. data/lib/active_record/type/internal/timezone.rb +17 -0
  233. data/lib/active_record/type/json.rb +30 -0
  234. data/lib/active_record/type/serialized.rb +24 -15
  235. data/lib/active_record/type/text.rb +2 -2
  236. data/lib/active_record/type/time.rb +11 -16
  237. data/lib/active_record/type/type_map.rb +15 -17
  238. data/lib/active_record/type/unsigned_integer.rb +9 -7
  239. data/lib/active_record/type_caster.rb +9 -0
  240. data/lib/active_record/type_caster/connection.rb +34 -0
  241. data/lib/active_record/type_caster/map.rb +20 -0
  242. data/lib/active_record/validations.rb +39 -35
  243. data/lib/active_record/validations/absence.rb +25 -0
  244. data/lib/active_record/validations/associated.rb +13 -4
  245. data/lib/active_record/validations/length.rb +26 -0
  246. data/lib/active_record/validations/presence.rb +14 -13
  247. data/lib/active_record/validations/uniqueness.rb +42 -55
  248. data/lib/active_record/version.rb +3 -1
  249. data/lib/arel.rb +51 -0
  250. data/lib/arel/alias_predication.rb +9 -0
  251. data/lib/arel/attributes.rb +22 -0
  252. data/lib/arel/attributes/attribute.rb +37 -0
  253. data/lib/arel/collectors/bind.rb +24 -0
  254. data/lib/arel/collectors/composite.rb +31 -0
  255. data/lib/arel/collectors/plain_string.rb +20 -0
  256. data/lib/arel/collectors/sql_string.rb +20 -0
  257. data/lib/arel/collectors/substitute_binds.rb +28 -0
  258. data/lib/arel/crud.rb +42 -0
  259. data/lib/arel/delete_manager.rb +18 -0
  260. data/lib/arel/errors.rb +9 -0
  261. data/lib/arel/expressions.rb +29 -0
  262. data/lib/arel/factory_methods.rb +49 -0
  263. data/lib/arel/insert_manager.rb +49 -0
  264. data/lib/arel/math.rb +45 -0
  265. data/lib/arel/nodes.rb +68 -0
  266. data/lib/arel/nodes/and.rb +32 -0
  267. data/lib/arel/nodes/ascending.rb +23 -0
  268. data/lib/arel/nodes/binary.rb +52 -0
  269. data/lib/arel/nodes/bind_param.rb +36 -0
  270. data/lib/arel/nodes/case.rb +55 -0
  271. data/lib/arel/nodes/casted.rb +50 -0
  272. data/lib/arel/nodes/comment.rb +29 -0
  273. data/lib/arel/nodes/count.rb +12 -0
  274. data/lib/arel/nodes/delete_statement.rb +45 -0
  275. data/lib/arel/nodes/descending.rb +23 -0
  276. data/lib/arel/nodes/equality.rb +18 -0
  277. data/lib/arel/nodes/extract.rb +24 -0
  278. data/lib/arel/nodes/false.rb +16 -0
  279. data/lib/arel/nodes/full_outer_join.rb +8 -0
  280. data/lib/arel/nodes/function.rb +44 -0
  281. data/lib/arel/nodes/grouping.rb +8 -0
  282. data/lib/arel/nodes/in.rb +8 -0
  283. data/lib/arel/nodes/infix_operation.rb +80 -0
  284. data/lib/arel/nodes/inner_join.rb +8 -0
  285. data/lib/arel/nodes/insert_statement.rb +37 -0
  286. data/lib/arel/nodes/join_source.rb +20 -0
  287. data/lib/arel/nodes/matches.rb +18 -0
  288. data/lib/arel/nodes/named_function.rb +23 -0
  289. data/lib/arel/nodes/node.rb +50 -0
  290. data/lib/arel/nodes/node_expression.rb +13 -0
  291. data/lib/arel/nodes/outer_join.rb +8 -0
  292. data/lib/arel/nodes/over.rb +15 -0
  293. data/lib/arel/nodes/regexp.rb +16 -0
  294. data/lib/arel/nodes/right_outer_join.rb +8 -0
  295. data/lib/arel/nodes/select_core.rb +67 -0
  296. data/lib/arel/nodes/select_statement.rb +41 -0
  297. data/lib/arel/nodes/sql_literal.rb +16 -0
  298. data/lib/arel/nodes/string_join.rb +11 -0
  299. data/lib/arel/nodes/table_alias.rb +27 -0
  300. data/lib/arel/nodes/terminal.rb +16 -0
  301. data/lib/arel/nodes/true.rb +16 -0
  302. data/lib/arel/nodes/unary.rb +45 -0
  303. data/lib/arel/nodes/unary_operation.rb +20 -0
  304. data/lib/arel/nodes/unqualified_column.rb +22 -0
  305. data/lib/arel/nodes/update_statement.rb +41 -0
  306. data/lib/arel/nodes/values_list.rb +9 -0
  307. data/lib/arel/nodes/window.rb +126 -0
  308. data/lib/arel/nodes/with.rb +11 -0
  309. data/lib/arel/order_predications.rb +13 -0
  310. data/lib/arel/predications.rb +257 -0
  311. data/lib/arel/select_manager.rb +271 -0
  312. data/lib/arel/table.rb +110 -0
  313. data/lib/arel/tree_manager.rb +72 -0
  314. data/lib/arel/update_manager.rb +34 -0
  315. data/lib/arel/visitors.rb +20 -0
  316. data/lib/arel/visitors/depth_first.rb +204 -0
  317. data/lib/arel/visitors/dot.rb +297 -0
  318. data/lib/arel/visitors/ibm_db.rb +34 -0
  319. data/lib/arel/visitors/informix.rb +62 -0
  320. data/lib/arel/visitors/mssql.rb +157 -0
  321. data/lib/arel/visitors/mysql.rb +83 -0
  322. data/lib/arel/visitors/oracle.rb +159 -0
  323. data/lib/arel/visitors/oracle12.rb +66 -0
  324. data/lib/arel/visitors/postgresql.rb +110 -0
  325. data/lib/arel/visitors/sqlite.rb +39 -0
  326. data/lib/arel/visitors/to_sql.rb +889 -0
  327. data/lib/arel/visitors/visitor.rb +46 -0
  328. data/lib/arel/visitors/where_sql.rb +23 -0
  329. data/lib/arel/window_predications.rb +9 -0
  330. data/lib/rails/generators/active_record.rb +7 -5
  331. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
  332. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +5 -0
  333. data/lib/rails/generators/active_record/migration.rb +31 -1
  334. data/lib/rails/generators/active_record/migration/migration_generator.rb +42 -37
  335. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +24 -0
  336. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +11 -2
  337. data/lib/rails/generators/active_record/model/model_generator.rb +19 -22
  338. data/lib/rails/generators/active_record/model/templates/model.rb.tt +22 -0
  339. data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
  340. metadata +164 -60
  341. data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
  342. data/lib/active_record/associations/preloader/collection_association.rb +0 -24
  343. data/lib/active_record/associations/preloader/has_many.rb +0 -17
  344. data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
  345. data/lib/active_record/associations/preloader/has_one.rb +0 -23
  346. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  347. data/lib/active_record/associations/preloader/singular_association.rb +0 -21
  348. data/lib/active_record/attribute.rb +0 -163
  349. data/lib/active_record/attribute_set.rb +0 -81
  350. data/lib/active_record/attribute_set/builder.rb +0 -106
  351. data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -491
  352. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
  353. data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
  354. data/lib/active_record/connection_adapters/postgresql/oid/infinity.rb +0 -13
  355. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -35
  356. data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
  357. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  358. data/lib/active_record/serializers/xml_serializer.rb +0 -193
  359. data/lib/active_record/type/big_integer.rb +0 -13
  360. data/lib/active_record/type/binary.rb +0 -50
  361. data/lib/active_record/type/boolean.rb +0 -31
  362. data/lib/active_record/type/decimal.rb +0 -58
  363. data/lib/active_record/type/decorator.rb +0 -14
  364. data/lib/active_record/type/float.rb +0 -19
  365. data/lib/active_record/type/integer.rb +0 -59
  366. data/lib/active_record/type/mutable.rb +0 -16
  367. data/lib/active_record/type/numeric.rb +0 -36
  368. data/lib/active_record/type/string.rb +0 -40
  369. data/lib/active_record/type/time_value.rb +0 -38
  370. data/lib/active_record/type/value.rb +0 -110
  371. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +0 -19
  372. data/lib/rails/generators/active_record/model/templates/model.rb +0 -10
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ class Relation
5
+ module RecordFetchWarning
6
+ # When this module is prepended to ActiveRecord::Relation and
7
+ # +config.active_record.warn_on_records_fetched_greater_than+ is
8
+ # set to an integer, if the number of records a query returns is
9
+ # greater than the value of +warn_on_records_fetched_greater_than+,
10
+ # a warning is logged. This allows for the detection of queries that
11
+ # return a large number of records, which could cause memory bloat.
12
+ #
13
+ # In most cases, fetching large number of records can be performed
14
+ # efficiently using the ActiveRecord::Batches methods.
15
+ # See ActiveRecord::Batches for more information.
16
+ def exec_queries
17
+ QueryRegistry.reset
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(";")}"
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ # :stopdoc:
29
+ ActiveSupport::Notifications.subscribe("sql.active_record") do |*, payload|
30
+ QueryRegistry.queries << payload[:sql]
31
+ end
32
+ # :startdoc:
33
+
34
+ class QueryRegistry # :nodoc:
35
+ extend ActiveSupport::PerThreadRegistry
36
+
37
+ attr_reader :queries
38
+
39
+ def initialize
40
+ @queries = []
41
+ end
42
+
43
+ def reset
44
+ @queries.clear
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+
51
+ ActiveRecord::Relation.prepend ActiveRecord::Relation::RecordFetchWarning
@@ -1,16 +1,17 @@
1
- require 'active_support/core_ext/hash/except'
2
- require 'active_support/core_ext/hash/slice'
3
- require 'active_record/relation/merger'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/hash/except"
4
+ require "active_support/core_ext/hash/slice"
5
+ require "active_record/relation/merger"
4
6
 
5
7
  module ActiveRecord
6
8
  module SpawnMethods
7
-
8
9
  # This is overridden by Associations::CollectionProxy
9
10
  def spawn #:nodoc:
10
- clone
11
+ already_in_scope? ? klass.all : clone
11
12
  end
12
13
 
13
- # Merges in the conditions from <tt>other</tt>, if <tt>other</tt> is an <tt>ActiveRecord::Relation</tt>.
14
+ # Merges in the conditions from <tt>other</tt>, if <tt>other</tt> is an ActiveRecord::Relation.
14
15
  # Returns an array representing the intersection of the resulting records with <tt>other</tt>, if <tt>other</tt> is an array.
15
16
  #
16
17
  # Post.where(published: true).joins(:comments).merge( Comment.where(spam: false) )
@@ -29,11 +30,11 @@ module ActiveRecord
29
30
  # This is mainly intended for sharing common conditions between multiple associations.
30
31
  def merge(other)
31
32
  if other.is_a?(Array)
32
- to_a & other
33
+ records & other
33
34
  elsif other
34
35
  spawn.merge!(other)
35
36
  else
36
- self
37
+ raise ArgumentError, "invalid argument: #{other.inspect}."
37
38
  end
38
39
  end
39
40
 
@@ -62,16 +63,13 @@ module ActiveRecord
62
63
  # Post.order('id asc').only(:where) # discards the order condition
63
64
  # Post.order('id asc').only(:where, :order) # uses the specified order
64
65
  def only(*onlies)
65
- if onlies.any? { |o| o == :where }
66
- onlies << :bind
67
- end
68
66
  relation_with values.slice(*onlies)
69
67
  end
70
68
 
71
69
  private
72
70
 
73
- def relation_with(values) # :nodoc:
74
- result = Relation.create(klass, table, values)
71
+ def relation_with(values)
72
+ result = Relation.create(klass, values: values)
75
73
  result.extend(*extending_values) if extending_values.any?
76
74
  result
77
75
  end
@@ -0,0 +1,190 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ class Relation
5
+ class WhereClause # :nodoc:
6
+ delegate :any?, :empty?, to: :predicates
7
+
8
+ def initialize(predicates)
9
+ @predicates = predicates
10
+ end
11
+
12
+ def +(other)
13
+ WhereClause.new(
14
+ predicates + other.predicates,
15
+ )
16
+ end
17
+
18
+ def -(other)
19
+ WhereClause.new(
20
+ predicates - other.predicates,
21
+ )
22
+ end
23
+
24
+ def merge(other)
25
+ WhereClause.new(
26
+ predicates_unreferenced_by(other) + other.predicates,
27
+ )
28
+ end
29
+
30
+ def except(*columns)
31
+ WhereClause.new(except_predicates(columns))
32
+ end
33
+
34
+ def or(other)
35
+ left = self - other
36
+ common = self - left
37
+ right = other - common
38
+
39
+ if left.empty? || right.empty?
40
+ common
41
+ else
42
+ or_clause = WhereClause.new(
43
+ [left.ast.or(right.ast)],
44
+ )
45
+ common + or_clause
46
+ end
47
+ end
48
+
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
55
+ end
56
+
57
+ equalities.map { |node|
58
+ name = node.left.name.to_s
59
+ value = extract_node_value(node.right)
60
+ [name, value]
61
+ }.to_h
62
+ end
63
+
64
+ def ast
65
+ Arel::Nodes::And.new(predicates_with_wrapped_sql_literals)
66
+ end
67
+
68
+ def ==(other)
69
+ other.is_a?(WhereClause) &&
70
+ predicates == other.predicates
71
+ end
72
+
73
+ def invert(as = :nand)
74
+ if predicates.size == 1
75
+ inverted_predicates = [ invert_predicate(predicates.first) ]
76
+ elsif as == :nor
77
+ inverted_predicates = predicates.map { |node| invert_predicate(node) }
78
+ else
79
+ inverted_predicates = [ Arel::Nodes::Not.new(ast) ]
80
+ end
81
+
82
+ WhereClause.new(inverted_predicates)
83
+ end
84
+
85
+ def self.empty
86
+ @empty ||= new([])
87
+ end
88
+
89
+ protected
90
+
91
+ attr_reader :predicates
92
+
93
+ def referenced_columns
94
+ @referenced_columns ||= begin
95
+ equality_nodes = predicates.select { |n| equality_node?(n) }
96
+ Set.new(equality_nodes, &:left)
97
+ end
98
+ end
99
+
100
+ private
101
+ def equalities(predicates)
102
+ equalities = []
103
+
104
+ predicates.each do |node|
105
+ case node
106
+ when Arel::Nodes::Equality
107
+ equalities << node
108
+ when Arel::Nodes::And
109
+ equalities.concat equalities(node.children)
110
+ end
111
+ end
112
+
113
+ equalities
114
+ end
115
+
116
+ def predicates_unreferenced_by(other)
117
+ predicates.reject do |n|
118
+ equality_node?(n) && other.referenced_columns.include?(n.left)
119
+ end
120
+ end
121
+
122
+ def equality_node?(node)
123
+ node.respond_to?(:operator) && node.operator == :==
124
+ end
125
+
126
+ def invert_predicate(node)
127
+ case node
128
+ when NilClass
129
+ raise ArgumentError, "Invalid argument for .where.not(), got nil."
130
+ when Arel::Nodes::In
131
+ Arel::Nodes::NotIn.new(node.left, node.right)
132
+ when Arel::Nodes::IsNotDistinctFrom
133
+ Arel::Nodes::IsDistinctFrom.new(node.left, node.right)
134
+ when Arel::Nodes::IsDistinctFrom
135
+ Arel::Nodes::IsNotDistinctFrom.new(node.left, node.right)
136
+ when Arel::Nodes::Equality
137
+ Arel::Nodes::NotEqual.new(node.left, node.right)
138
+ when String
139
+ Arel::Nodes::Not.new(Arel::Nodes::SqlLiteral.new(node))
140
+ else
141
+ Arel::Nodes::Not.new(node)
142
+ end
143
+ end
144
+
145
+ def except_predicates(columns)
146
+ predicates.reject do |node|
147
+ Arel.fetch_attribute(node) { |attr| columns.include?(attr.name.to_s) }
148
+ end
149
+ end
150
+
151
+ def predicates_with_wrapped_sql_literals
152
+ non_empty_predicates.map do |node|
153
+ case node
154
+ when Arel::Nodes::SqlLiteral, ::String
155
+ wrap_sql_literal(node)
156
+ else node
157
+ end
158
+ end
159
+ end
160
+
161
+ ARRAY_WITH_EMPTY_STRING = [""]
162
+ def non_empty_predicates
163
+ predicates - ARRAY_WITH_EMPTY_STRING
164
+ end
165
+
166
+ def wrap_sql_literal(node)
167
+ if ::String === node
168
+ node = Arel.sql(node)
169
+ end
170
+ Arel::Nodes::Grouping.new(node)
171
+ end
172
+
173
+ def extract_node_value(node)
174
+ case node
175
+ when Array
176
+ node.map { |v| extract_node_value(v) }
177
+ when Arel::Nodes::Casted, Arel::Nodes::Quoted
178
+ node.val
179
+ when Arel::Nodes::BindParam
180
+ value = node.value
181
+ if value.respond_to?(:value_before_type_cast)
182
+ value.value_before_type_cast
183
+ else
184
+ value
185
+ end
186
+ end
187
+ end
188
+ end
189
+ end
190
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ class Relation
5
+ class WhereClauseFactory # :nodoc:
6
+ def initialize(klass, predicate_builder)
7
+ @klass = klass
8
+ @predicate_builder = predicate_builder
9
+ end
10
+
11
+ def build(opts, other)
12
+ case opts
13
+ when String, Array
14
+ parts = [klass.sanitize_sql(other.empty? ? opts : ([opts] + other))]
15
+ when Hash
16
+ attributes = predicate_builder.resolve_column_aliases(opts)
17
+ attributes.stringify_keys!
18
+
19
+ parts = predicate_builder.build_from_hash(attributes)
20
+ when Arel::Nodes::Node
21
+ parts = [opts]
22
+ else
23
+ raise ArgumentError, "Unsupported argument type: #{opts} (#{opts.class})"
24
+ end
25
+
26
+ WhereClause.new(parts)
27
+ end
28
+
29
+ private
30
+ attr_reader :klass, :predicate_builder
31
+ end
32
+ end
33
+ end
@@ -1,7 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  ###
3
- # This class encapsulates a Result returned from calling +exec_query+ on any
4
- # database connection adapter. For example:
5
+ # This class encapsulates a result returned from calling
6
+ # {#exec_query}[rdoc-ref:ConnectionAdapters::DatabaseStatements#exec_query]
7
+ # on any database connection adapter. For example:
5
8
  #
6
9
  # result = ActiveRecord::Base.connection.exec_query('SELECT id, title, body FROM posts')
7
10
  # result # => #<ActiveRecord::Result:0xdeadbeef>
@@ -18,7 +21,7 @@ module ActiveRecord
18
21
  # ]
19
22
  #
20
23
  # # Get an array of hashes representing the result (column => value):
21
- # result.to_hash
24
+ # result.to_a
22
25
  # # => [{"id" => 1, "title" => "title_1", "body" => "body_1"},
23
26
  # {"id" => 2, "title" => "title_2", "body" => "body_2"},
24
27
  # ...
@@ -31,8 +34,6 @@ module ActiveRecord
31
34
  class Result
32
35
  include Enumerable
33
36
 
34
- IDENTITY_TYPE = Type::Value.new # :nodoc:
35
-
36
37
  attr_reader :columns, :rows, :column_types
37
38
 
38
39
  def initialize(columns, rows, column_types = {})
@@ -42,10 +43,20 @@ module ActiveRecord
42
43
  @column_types = column_types
43
44
  end
44
45
 
46
+ # Returns true if this result set includes the column named +name+
47
+ def includes_column?(name)
48
+ @columns.include? name
49
+ end
50
+
51
+ # Returns the number of elements in the rows array.
45
52
  def length
46
53
  @rows.length
47
54
  end
48
55
 
56
+ # Calls the given block once for each element in row collection, passing
57
+ # row as parameter.
58
+ #
59
+ # Returns an +Enumerator+ if no block is given.
49
60
  def each
50
61
  if block_given?
51
62
  hash_rows.each { |row| yield row }
@@ -55,36 +66,62 @@ module ActiveRecord
55
66
  end
56
67
 
57
68
  def to_hash
58
- hash_rows
69
+ ActiveSupport::Deprecation.warn(<<-MSG.squish)
70
+ `ActiveRecord::Result#to_hash` has been renamed to `to_a`.
71
+ `to_hash` is deprecated and will be removed in Rails 6.1.
72
+ MSG
73
+ to_a
59
74
  end
60
75
 
61
76
  alias :map! :map
62
77
  alias :collect! :map
63
78
 
64
- # Returns true if there are no records.
79
+ # Returns true if there are no records, otherwise false.
65
80
  def empty?
66
81
  rows.empty?
67
82
  end
68
83
 
84
+ # Returns an array of hashes representing each row record.
69
85
  def to_ary
70
86
  hash_rows
71
87
  end
72
88
 
89
+ alias :to_a :to_ary
90
+
73
91
  def [](idx)
74
92
  hash_rows[idx]
75
93
  end
76
94
 
95
+ # Returns the first record from the rows collection.
96
+ # If the rows collection is empty, returns +nil+.
97
+ def first
98
+ return nil if @rows.empty?
99
+ Hash[@columns.zip(@rows.first)]
100
+ end
101
+
102
+ # Returns the last record from the rows collection.
103
+ # If the rows collection is empty, returns +nil+.
77
104
  def last
78
- hash_rows.last
105
+ return nil if @rows.empty?
106
+ Hash[@columns.zip(@rows.last)]
79
107
  end
80
108
 
81
109
  def cast_values(type_overrides = {}) # :nodoc:
82
- types = columns.map { |name| column_type(name, type_overrides) }
83
- result = rows.map do |values|
84
- types.zip(values).map { |type, value| type.type_cast_from_database(value) }
85
- end
110
+ if columns.one?
111
+ # Separated to avoid allocating an array per row
112
+
113
+ type = column_type(columns.first, type_overrides)
86
114
 
87
- columns.one? ? result.map!(&:first) : result
115
+ rows.map do |(value)|
116
+ type.deserialize(value)
117
+ end
118
+ else
119
+ types = columns.map { |name| column_type(name, type_overrides) }
120
+
121
+ rows.map do |values|
122
+ Array.new(values.size) { |i| types[i].deserialize(values[i]) }
123
+ end
124
+ end
88
125
  end
89
126
 
90
127
  def initialize_copy(other)
@@ -96,36 +133,36 @@ module ActiveRecord
96
133
 
97
134
  private
98
135
 
99
- def column_type(name, type_overrides = {})
100
- type_overrides.fetch(name) do
101
- column_types.fetch(name, IDENTITY_TYPE)
136
+ def column_type(name, type_overrides = {})
137
+ type_overrides.fetch(name) do
138
+ column_types.fetch(name, Type.default_value)
139
+ end
102
140
  end
103
- end
104
141
 
105
- def hash_rows
106
- @hash_rows ||=
107
- begin
108
- # We freeze the strings to prevent them getting duped when
109
- # used as keys in ActiveRecord::Base's @attributes hash
110
- columns = @columns.map { |c| c.dup.freeze }
111
- @rows.map { |row|
112
- # In the past we used Hash[columns.zip(row)]
113
- # though elegant, the verbose way is much more efficient
114
- # both time and memory wise cause it avoids a big array allocation
115
- # this method is called a lot and needs to be micro optimised
116
- hash = {}
117
-
118
- index = 0
119
- length = columns.length
120
-
121
- while index < length
122
- hash[columns[index]] = row[index]
123
- index += 1
124
- end
125
-
126
- hash
127
- }
128
- end
129
- end
142
+ def hash_rows
143
+ @hash_rows ||=
144
+ begin
145
+ # We freeze the strings to prevent them getting duped when
146
+ # used as keys in ActiveRecord::Base's @attributes hash
147
+ columns = @columns.map(&:-@)
148
+ length = columns.length
149
+
150
+ @rows.map { |row|
151
+ # In the past we used Hash[columns.zip(row)]
152
+ # though elegant, the verbose way is much more efficient
153
+ # both time and memory wise cause it avoids a big array allocation
154
+ # this method is called a lot and needs to be micro optimised
155
+ hash = {}
156
+
157
+ index = 0
158
+ while index < length
159
+ hash[columns[index]] = row[index]
160
+ index += 1
161
+ end
162
+
163
+ hash
164
+ }
165
+ end
166
+ end
130
167
  end
131
168
  end