activerecord 5.0.6 → 6.0.1

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 (358) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +638 -2023
  3. data/MIT-LICENSE +3 -1
  4. data/README.rdoc +8 -6
  5. data/examples/performance.rb +31 -29
  6. data/examples/simple.rb +5 -3
  7. data/lib/active_record/aggregations.rb +249 -246
  8. data/lib/active_record/association_relation.rb +24 -13
  9. data/lib/active_record/associations/alias_tracker.rb +24 -33
  10. data/lib/active_record/associations/association.rb +119 -56
  11. data/lib/active_record/associations/association_scope.rb +94 -94
  12. data/lib/active_record/associations/belongs_to_association.rb +58 -42
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -12
  14. data/lib/active_record/associations/builder/association.rb +18 -25
  15. data/lib/active_record/associations/builder/belongs_to.rb +43 -54
  16. data/lib/active_record/associations/builder/collection_association.rb +7 -18
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +42 -61
  18. data/lib/active_record/associations/builder/has_many.rb +4 -0
  19. data/lib/active_record/associations/builder/has_one.rb +37 -1
  20. data/lib/active_record/associations/builder/singular_association.rb +4 -0
  21. data/lib/active_record/associations/collection_association.rb +80 -252
  22. data/lib/active_record/associations/collection_proxy.rb +158 -121
  23. data/lib/active_record/associations/foreign_association.rb +9 -0
  24. data/lib/active_record/associations/has_many_association.rb +23 -29
  25. data/lib/active_record/associations/has_many_through_association.rb +58 -44
  26. data/lib/active_record/associations/has_one_association.rb +59 -54
  27. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  28. data/lib/active_record/associations/join_dependency/join_association.rb +38 -90
  29. data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
  30. data/lib/active_record/associations/join_dependency/join_part.rb +12 -12
  31. data/lib/active_record/associations/join_dependency.rb +134 -176
  32. data/lib/active_record/associations/preloader/association.rb +84 -125
  33. data/lib/active_record/associations/preloader/through_association.rb +82 -75
  34. data/lib/active_record/associations/preloader.rb +90 -102
  35. data/lib/active_record/associations/singular_association.rb +12 -45
  36. data/lib/active_record/associations/through_association.rb +26 -14
  37. data/lib/active_record/associations.rb +1603 -1592
  38. data/lib/active_record/attribute_assignment.rb +54 -60
  39. data/lib/active_record/attribute_decorators.rb +38 -15
  40. data/lib/active_record/attribute_methods/before_type_cast.rb +12 -7
  41. data/lib/active_record/attribute_methods/dirty.rb +179 -109
  42. data/lib/active_record/attribute_methods/primary_key.rb +86 -91
  43. data/lib/active_record/attribute_methods/query.rb +4 -3
  44. data/lib/active_record/attribute_methods/read.rb +21 -49
  45. data/lib/active_record/attribute_methods/serialization.rb +30 -7
  46. data/lib/active_record/attribute_methods/time_zone_conversion.rb +39 -64
  47. data/lib/active_record/attribute_methods/write.rb +35 -33
  48. data/lib/active_record/attribute_methods.rb +66 -106
  49. data/lib/active_record/attributes.rb +38 -24
  50. data/lib/active_record/autosave_association.rb +53 -32
  51. data/lib/active_record/base.rb +27 -24
  52. data/lib/active_record/callbacks.rb +63 -33
  53. data/lib/active_record/coders/json.rb +2 -0
  54. data/lib/active_record/coders/yaml_column.rb +11 -11
  55. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +553 -321
  56. data/lib/active_record/connection_adapters/abstract/database_limits.rb +23 -5
  57. data/lib/active_record/connection_adapters/abstract/database_statements.rb +213 -94
  58. data/lib/active_record/connection_adapters/abstract/query_cache.rb +59 -28
  59. data/lib/active_record/connection_adapters/abstract/quoting.rb +119 -75
  60. data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
  61. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +33 -27
  62. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +207 -126
  63. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +68 -80
  64. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +369 -199
  65. data/lib/active_record/connection_adapters/abstract/transaction.rb +169 -78
  66. data/lib/active_record/connection_adapters/abstract_adapter.rb +363 -202
  67. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +405 -551
  68. data/lib/active_record/connection_adapters/column.rb +41 -13
  69. data/lib/active_record/connection_adapters/connection_specification.rb +172 -138
  70. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +11 -4
  71. data/lib/active_record/connection_adapters/mysql/column.rb +8 -31
  72. data/lib/active_record/connection_adapters/mysql/database_statements.rb +143 -49
  73. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +24 -22
  74. data/lib/active_record/connection_adapters/mysql/quoting.rb +50 -20
  75. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +50 -45
  76. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +58 -56
  77. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +70 -36
  78. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +264 -0
  79. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +12 -13
  80. data/lib/active_record/connection_adapters/mysql2_adapter.rb +49 -30
  81. data/lib/active_record/connection_adapters/postgresql/column.rb +22 -7
  82. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +60 -54
  83. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +5 -3
  84. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +22 -10
  85. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +6 -5
  86. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  87. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -1
  89. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
  90. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +4 -2
  91. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  92. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -3
  93. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +19 -17
  94. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  95. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
  96. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +45 -0
  97. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -5
  98. data/lib/active_record/connection_adapters/postgresql/oid/{json.rb → oid.rb} +6 -1
  99. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +31 -9
  100. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +34 -30
  101. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -1
  102. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +58 -54
  103. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +9 -4
  104. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
  105. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
  106. data/lib/active_record/connection_adapters/postgresql/oid.rb +24 -21
  107. data/lib/active_record/connection_adapters/postgresql/quoting.rb +95 -35
  108. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +19 -25
  109. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -0
  110. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +147 -105
  111. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +35 -32
  112. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +380 -300
  113. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +26 -25
  114. data/lib/active_record/connection_adapters/postgresql/utils.rb +10 -6
  115. data/lib/active_record/connection_adapters/postgresql_adapter.rb +382 -275
  116. data/lib/active_record/connection_adapters/schema_cache.rb +46 -12
  117. data/lib/active_record/connection_adapters/sql_type_metadata.rb +13 -8
  118. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +120 -0
  119. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +3 -1
  120. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +74 -19
  121. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +3 -8
  122. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
  123. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
  124. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +137 -0
  125. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +254 -262
  126. data/lib/active_record/connection_adapters/statement_pool.rb +9 -7
  127. data/lib/active_record/connection_handling.rb +159 -40
  128. data/lib/active_record/core.rb +202 -162
  129. data/lib/active_record/counter_cache.rb +57 -28
  130. data/lib/active_record/database_configurations/database_config.rb +37 -0
  131. data/lib/active_record/database_configurations/hash_config.rb +50 -0
  132. data/lib/active_record/database_configurations/url_config.rb +79 -0
  133. data/lib/active_record/database_configurations.rb +233 -0
  134. data/lib/active_record/define_callbacks.rb +22 -0
  135. data/lib/active_record/dynamic_matchers.rb +87 -86
  136. data/lib/active_record/enum.rb +60 -23
  137. data/lib/active_record/errors.rb +114 -18
  138. data/lib/active_record/explain.rb +4 -3
  139. data/lib/active_record/explain_registry.rb +3 -1
  140. data/lib/active_record/explain_subscriber.rb +9 -4
  141. data/lib/active_record/fixture_set/file.rb +13 -8
  142. data/lib/active_record/fixture_set/model_metadata.rb +33 -0
  143. data/lib/active_record/fixture_set/render_context.rb +17 -0
  144. data/lib/active_record/fixture_set/table_row.rb +153 -0
  145. data/lib/active_record/fixture_set/table_rows.rb +47 -0
  146. data/lib/active_record/fixtures.rb +195 -502
  147. data/lib/active_record/gem_version.rb +4 -2
  148. data/lib/active_record/inheritance.rb +151 -97
  149. data/lib/active_record/insert_all.rb +179 -0
  150. data/lib/active_record/integration.rb +116 -25
  151. data/lib/active_record/internal_metadata.rb +15 -18
  152. data/lib/active_record/legacy_yaml_adapter.rb +4 -2
  153. data/lib/active_record/locking/optimistic.rb +78 -87
  154. data/lib/active_record/locking/pessimistic.rb +18 -6
  155. data/lib/active_record/log_subscriber.rb +48 -29
  156. data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
  157. data/lib/active_record/middleware/database_selector/resolver.rb +88 -0
  158. data/lib/active_record/middleware/database_selector.rb +75 -0
  159. data/lib/active_record/migration/command_recorder.rb +143 -97
  160. data/lib/active_record/migration/compatibility.rb +174 -56
  161. data/lib/active_record/migration/join_table.rb +8 -6
  162. data/lib/active_record/migration.rb +367 -300
  163. data/lib/active_record/model_schema.rb +145 -139
  164. data/lib/active_record/nested_attributes.rb +214 -201
  165. data/lib/active_record/no_touching.rb +10 -1
  166. data/lib/active_record/null_relation.rb +13 -34
  167. data/lib/active_record/persistence.rb +442 -72
  168. data/lib/active_record/query_cache.rb +15 -14
  169. data/lib/active_record/querying.rb +36 -23
  170. data/lib/active_record/railtie.rb +128 -36
  171. data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
  172. data/lib/active_record/railties/console_sandbox.rb +2 -0
  173. data/lib/active_record/railties/controller_runtime.rb +34 -33
  174. data/lib/active_record/railties/databases.rake +309 -177
  175. data/lib/active_record/readonly_attributes.rb +5 -4
  176. data/lib/active_record/reflection.rb +211 -249
  177. data/lib/active_record/relation/batches/batch_enumerator.rb +3 -1
  178. data/lib/active_record/relation/batches.rb +99 -52
  179. data/lib/active_record/relation/calculations.rb +211 -172
  180. data/lib/active_record/relation/delegation.rb +67 -65
  181. data/lib/active_record/relation/finder_methods.rb +208 -247
  182. data/lib/active_record/relation/from_clause.rb +2 -8
  183. data/lib/active_record/relation/merger.rb +78 -61
  184. data/lib/active_record/relation/predicate_builder/array_handler.rb +20 -14
  185. data/lib/active_record/relation/predicate_builder/association_query_value.rb +43 -0
  186. data/lib/active_record/relation/predicate_builder/base_handler.rb +4 -3
  187. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +6 -4
  188. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +53 -0
  189. data/lib/active_record/relation/predicate_builder/range_handler.rb +7 -18
  190. data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
  191. data/lib/active_record/relation/predicate_builder.rb +86 -104
  192. data/lib/active_record/relation/query_attribute.rb +33 -2
  193. data/lib/active_record/relation/query_methods.rb +458 -329
  194. data/lib/active_record/relation/record_fetch_warning.rb +5 -3
  195. data/lib/active_record/relation/spawn_methods.rb +8 -7
  196. data/lib/active_record/relation/where_clause.rb +111 -95
  197. data/lib/active_record/relation/where_clause_factory.rb +6 -11
  198. data/lib/active_record/relation.rb +429 -318
  199. data/lib/active_record/result.rb +69 -39
  200. data/lib/active_record/runtime_registry.rb +5 -3
  201. data/lib/active_record/sanitization.rb +83 -99
  202. data/lib/active_record/schema.rb +7 -14
  203. data/lib/active_record/schema_dumper.rb +71 -69
  204. data/lib/active_record/schema_migration.rb +15 -5
  205. data/lib/active_record/scoping/default.rb +93 -95
  206. data/lib/active_record/scoping/named.rb +45 -25
  207. data/lib/active_record/scoping.rb +20 -19
  208. data/lib/active_record/secure_token.rb +4 -2
  209. data/lib/active_record/serialization.rb +2 -0
  210. data/lib/active_record/statement_cache.rb +63 -28
  211. data/lib/active_record/store.rb +121 -41
  212. data/lib/active_record/suppressor.rb +4 -1
  213. data/lib/active_record/table_metadata.rb +26 -20
  214. data/lib/active_record/tasks/database_tasks.rb +276 -85
  215. data/lib/active_record/tasks/mysql_database_tasks.rb +54 -90
  216. data/lib/active_record/tasks/postgresql_database_tasks.rb +78 -47
  217. data/lib/active_record/tasks/sqlite_database_tasks.rb +34 -16
  218. data/lib/active_record/test_databases.rb +23 -0
  219. data/lib/active_record/test_fixtures.rb +224 -0
  220. data/lib/active_record/timestamp.rb +70 -35
  221. data/lib/active_record/touch_later.rb +7 -4
  222. data/lib/active_record/transactions.rb +133 -149
  223. data/lib/active_record/translation.rb +3 -1
  224. data/lib/active_record/type/adapter_specific_registry.rb +44 -45
  225. data/lib/active_record/type/date.rb +2 -0
  226. data/lib/active_record/type/date_time.rb +2 -0
  227. data/lib/active_record/type/decimal_without_scale.rb +15 -0
  228. data/lib/active_record/type/hash_lookup_type_map.rb +5 -3
  229. data/lib/active_record/type/internal/timezone.rb +2 -0
  230. data/lib/active_record/type/json.rb +30 -0
  231. data/lib/active_record/type/serialized.rb +16 -8
  232. data/lib/active_record/type/text.rb +11 -0
  233. data/lib/active_record/type/time.rb +2 -1
  234. data/lib/active_record/type/type_map.rb +13 -15
  235. data/lib/active_record/type/unsigned_integer.rb +17 -0
  236. data/lib/active_record/type.rb +23 -17
  237. data/lib/active_record/type_caster/connection.rb +17 -12
  238. data/lib/active_record/type_caster/map.rb +5 -4
  239. data/lib/active_record/type_caster.rb +4 -2
  240. data/lib/active_record/validations/absence.rb +2 -0
  241. data/lib/active_record/validations/associated.rb +3 -1
  242. data/lib/active_record/validations/length.rb +2 -0
  243. data/lib/active_record/validations/presence.rb +4 -2
  244. data/lib/active_record/validations/uniqueness.rb +29 -42
  245. data/lib/active_record/validations.rb +7 -4
  246. data/lib/active_record/version.rb +3 -1
  247. data/lib/active_record.rb +36 -22
  248. data/lib/arel/alias_predication.rb +9 -0
  249. data/lib/arel/attributes/attribute.rb +37 -0
  250. data/lib/arel/attributes.rb +22 -0
  251. data/lib/arel/collectors/bind.rb +24 -0
  252. data/lib/arel/collectors/composite.rb +31 -0
  253. data/lib/arel/collectors/plain_string.rb +20 -0
  254. data/lib/arel/collectors/sql_string.rb +20 -0
  255. data/lib/arel/collectors/substitute_binds.rb +28 -0
  256. data/lib/arel/crud.rb +42 -0
  257. data/lib/arel/delete_manager.rb +18 -0
  258. data/lib/arel/errors.rb +9 -0
  259. data/lib/arel/expressions.rb +29 -0
  260. data/lib/arel/factory_methods.rb +49 -0
  261. data/lib/arel/insert_manager.rb +49 -0
  262. data/lib/arel/math.rb +45 -0
  263. data/lib/arel/nodes/and.rb +32 -0
  264. data/lib/arel/nodes/ascending.rb +23 -0
  265. data/lib/arel/nodes/binary.rb +52 -0
  266. data/lib/arel/nodes/bind_param.rb +36 -0
  267. data/lib/arel/nodes/case.rb +55 -0
  268. data/lib/arel/nodes/casted.rb +50 -0
  269. data/lib/arel/nodes/comment.rb +29 -0
  270. data/lib/arel/nodes/count.rb +12 -0
  271. data/lib/arel/nodes/delete_statement.rb +45 -0
  272. data/lib/arel/nodes/descending.rb +23 -0
  273. data/lib/arel/nodes/equality.rb +18 -0
  274. data/lib/arel/nodes/extract.rb +24 -0
  275. data/lib/arel/nodes/false.rb +16 -0
  276. data/lib/arel/nodes/full_outer_join.rb +8 -0
  277. data/lib/arel/nodes/function.rb +44 -0
  278. data/lib/arel/nodes/grouping.rb +8 -0
  279. data/lib/arel/nodes/in.rb +8 -0
  280. data/lib/arel/nodes/infix_operation.rb +80 -0
  281. data/lib/arel/nodes/inner_join.rb +8 -0
  282. data/lib/arel/nodes/insert_statement.rb +37 -0
  283. data/lib/arel/nodes/join_source.rb +20 -0
  284. data/lib/arel/nodes/matches.rb +18 -0
  285. data/lib/arel/nodes/named_function.rb +23 -0
  286. data/lib/arel/nodes/node.rb +50 -0
  287. data/lib/arel/nodes/node_expression.rb +13 -0
  288. data/lib/arel/nodes/outer_join.rb +8 -0
  289. data/lib/arel/nodes/over.rb +15 -0
  290. data/lib/arel/nodes/regexp.rb +16 -0
  291. data/lib/arel/nodes/right_outer_join.rb +8 -0
  292. data/lib/arel/nodes/select_core.rb +67 -0
  293. data/lib/arel/nodes/select_statement.rb +41 -0
  294. data/lib/arel/nodes/sql_literal.rb +16 -0
  295. data/lib/arel/nodes/string_join.rb +11 -0
  296. data/lib/arel/nodes/table_alias.rb +27 -0
  297. data/lib/arel/nodes/terminal.rb +16 -0
  298. data/lib/arel/nodes/true.rb +16 -0
  299. data/lib/arel/nodes/unary.rb +45 -0
  300. data/lib/arel/nodes/unary_operation.rb +20 -0
  301. data/lib/arel/nodes/unqualified_column.rb +22 -0
  302. data/lib/arel/nodes/update_statement.rb +41 -0
  303. data/lib/arel/nodes/values_list.rb +9 -0
  304. data/lib/arel/nodes/window.rb +126 -0
  305. data/lib/arel/nodes/with.rb +11 -0
  306. data/lib/arel/nodes.rb +68 -0
  307. data/lib/arel/order_predications.rb +13 -0
  308. data/lib/arel/predications.rb +257 -0
  309. data/lib/arel/select_manager.rb +271 -0
  310. data/lib/arel/table.rb +110 -0
  311. data/lib/arel/tree_manager.rb +72 -0
  312. data/lib/arel/update_manager.rb +34 -0
  313. data/lib/arel/visitors/depth_first.rb +204 -0
  314. data/lib/arel/visitors/dot.rb +297 -0
  315. data/lib/arel/visitors/ibm_db.rb +34 -0
  316. data/lib/arel/visitors/informix.rb +62 -0
  317. data/lib/arel/visitors/mssql.rb +157 -0
  318. data/lib/arel/visitors/mysql.rb +83 -0
  319. data/lib/arel/visitors/oracle.rb +159 -0
  320. data/lib/arel/visitors/oracle12.rb +66 -0
  321. data/lib/arel/visitors/postgresql.rb +110 -0
  322. data/lib/arel/visitors/sqlite.rb +39 -0
  323. data/lib/arel/visitors/to_sql.rb +889 -0
  324. data/lib/arel/visitors/visitor.rb +46 -0
  325. data/lib/arel/visitors/where_sql.rb +23 -0
  326. data/lib/arel/visitors.rb +20 -0
  327. data/lib/arel/window_predications.rb +9 -0
  328. data/lib/arel.rb +58 -0
  329. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
  330. data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
  331. data/lib/rails/generators/active_record/migration/migration_generator.rb +37 -35
  332. data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +1 -1
  333. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +4 -2
  334. data/lib/rails/generators/active_record/migration.rb +17 -2
  335. data/lib/rails/generators/active_record/model/model_generator.rb +9 -29
  336. data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +10 -1
  337. data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
  338. data/lib/rails/generators/active_record.rb +7 -5
  339. metadata +133 -50
  340. data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
  341. data/lib/active_record/associations/preloader/collection_association.rb +0 -17
  342. data/lib/active_record/associations/preloader/has_many.rb +0 -17
  343. data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
  344. data/lib/active_record/associations/preloader/has_one.rb +0 -15
  345. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  346. data/lib/active_record/associations/preloader/singular_association.rb +0 -20
  347. data/lib/active_record/attribute/user_provided_default.rb +0 -28
  348. data/lib/active_record/attribute.rb +0 -213
  349. data/lib/active_record/attribute_mutation_tracker.rb +0 -70
  350. data/lib/active_record/attribute_set/builder.rb +0 -130
  351. data/lib/active_record/attribute_set.rb +0 -110
  352. data/lib/active_record/collection_cache_key.rb +0 -50
  353. data/lib/active_record/connection_adapters/postgresql/oid/rails_5_1_point.rb +0 -50
  354. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  355. data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
  356. data/lib/active_record/relation/predicate_builder/class_handler.rb +0 -27
  357. data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -57
  358. data/lib/active_record/type/internal/abstract_json.rb +0 -33
@@ -1,21 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/deprecation"
4
+
1
5
  module ActiveRecord
2
6
  module ConnectionAdapters # :nodoc:
3
7
  module DatabaseLimits
8
+ def max_identifier_length # :nodoc:
9
+ 64
10
+ end
4
11
 
5
12
  # Returns the maximum length of a table alias.
6
13
  def table_alias_length
7
- 255
14
+ max_identifier_length
8
15
  end
9
16
 
10
17
  # Returns the maximum length of a column name.
11
18
  def column_name_length
12
- 64
19
+ max_identifier_length
13
20
  end
21
+ deprecate :column_name_length
14
22
 
15
23
  # Returns the maximum length of a table name.
16
24
  def table_name_length
17
- 64
25
+ max_identifier_length
18
26
  end
27
+ deprecate :table_name_length
19
28
 
20
29
  # Returns the maximum allowed length for an index name. This
21
30
  # limit is enforced by \Rails and is less than or equal to
@@ -28,26 +37,29 @@ module ActiveRecord
28
37
 
29
38
  # Returns the maximum length of an index name.
30
39
  def index_name_length
31
- 64
40
+ max_identifier_length
32
41
  end
33
42
 
34
43
  # Returns the maximum number of columns per table.
35
44
  def columns_per_table
36
45
  1024
37
46
  end
47
+ deprecate :columns_per_table
38
48
 
39
49
  # Returns the maximum number of indexes per table.
40
50
  def indexes_per_table
41
51
  16
42
52
  end
53
+ deprecate :indexes_per_table
43
54
 
44
55
  # Returns the maximum number of columns in a multicolumn index.
45
56
  def columns_per_multicolumn_index
46
57
  16
47
58
  end
59
+ deprecate :columns_per_multicolumn_index
48
60
 
49
61
  # Returns the maximum number of elements in an IN (x,y,z) clause.
50
- # nil means no limit.
62
+ # +nil+ means no limit.
51
63
  def in_clause_length
52
64
  nil
53
65
  end
@@ -56,12 +68,18 @@ module ActiveRecord
56
68
  def sql_query_length
57
69
  1048575
58
70
  end
71
+ deprecate :sql_query_length
59
72
 
60
73
  # Returns maximum number of joins in a single query.
61
74
  def joins_per_query
62
75
  256
63
76
  end
77
+ deprecate :joins_per_query
64
78
 
79
+ private
80
+ def bind_params_length
81
+ 65535
82
+ end
65
83
  end
66
84
  end
67
85
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters # :nodoc:
3
5
  module DatabaseStatements
@@ -7,34 +9,61 @@ module ActiveRecord
7
9
  end
8
10
 
9
11
  # Converts an arel AST to SQL
10
- def to_sql(arel, binds = [])
11
- if arel.respond_to?(:ast)
12
- collected = visitor.accept(arel.ast, collector)
13
- collected.compile(binds.dup, self)
12
+ def to_sql(arel_or_sql_string, binds = [])
13
+ sql, _ = to_sql_and_binds(arel_or_sql_string, binds)
14
+ sql
15
+ end
16
+
17
+ def to_sql_and_binds(arel_or_sql_string, binds = []) # :nodoc:
18
+ if arel_or_sql_string.respond_to?(:ast)
19
+ unless binds.empty?
20
+ raise "Passing bind parameters with an arel AST is forbidden. " \
21
+ "The values must be stored on the AST directly"
22
+ end
23
+
24
+ if prepared_statements
25
+ sql, binds = visitor.compile(arel_or_sql_string.ast, collector)
26
+
27
+ if binds.length > bind_params_length
28
+ unprepared_statement do
29
+ sql, binds = to_sql_and_binds(arel_or_sql_string)
30
+ visitor.preparable = false
31
+ end
32
+ end
33
+ else
34
+ sql = visitor.compile(arel_or_sql_string.ast, collector)
35
+ end
36
+ [sql.freeze, binds]
14
37
  else
15
- arel
38
+ visitor.preparable = false if prepared_statements
39
+ [arel_or_sql_string.dup.freeze, binds]
16
40
  end
17
41
  end
42
+ private :to_sql_and_binds
18
43
 
19
44
  # This is used in the StatementCache object. It returns an object that
20
45
  # can be used to query the database repeatedly.
21
- def cacheable_query(arel) # :nodoc:
46
+ def cacheable_query(klass, arel) # :nodoc:
22
47
  if prepared_statements
23
- ActiveRecord::StatementCache.query visitor, arel.ast
48
+ sql, binds = visitor.compile(arel.ast, collector)
49
+ query = klass.query(sql)
24
50
  else
25
- ActiveRecord::StatementCache.partial_query visitor, arel.ast, collector
51
+ collector = klass.partial_query_collector
52
+ parts, binds = visitor.compile(arel.ast, collector)
53
+ query = klass.partial_query(parts)
26
54
  end
55
+ [query, binds]
27
56
  end
28
57
 
29
58
  # Returns an ActiveRecord::Result instance.
30
59
  def select_all(arel, name = nil, binds = [], preparable: nil)
31
- arel, binds = binds_from_relation arel, binds
32
- sql = to_sql(arel, binds)
33
- if !prepared_statements || (arel.is_a?(String) && preparable.nil?)
34
- preparable = false
35
- else
36
- preparable = visitor.preparable
60
+ arel = arel_from_relation(arel)
61
+ sql, binds = to_sql_and_binds(arel, binds)
62
+
63
+ if preparable.nil?
64
+ preparable = prepared_statements ? visitor.preparable : false
37
65
  end
66
+
38
67
  if prepared_statements && preparable
39
68
  select_prepared(sql, name, binds)
40
69
  else
@@ -50,23 +79,36 @@ module ActiveRecord
50
79
 
51
80
  # Returns a single value from a record
52
81
  def select_value(arel, name = nil, binds = [])
53
- arel, binds = binds_from_relation arel, binds
54
- if result = select_rows(to_sql(arel, binds), name, binds).first
55
- result.first
56
- end
82
+ single_value_from_rows(select_rows(arel, name, binds))
57
83
  end
58
84
 
59
85
  # Returns an array of the values of the first column in a select:
60
86
  # select_values("SELECT id FROM companies LIMIT 3") => [1,2,3]
61
87
  def select_values(arel, name = nil, binds = [])
62
- arel, binds = binds_from_relation arel, binds
63
- select_rows(to_sql(arel, binds), name, binds).map(&:first)
88
+ select_rows(arel, name, binds).map(&:first)
64
89
  end
65
90
 
66
91
  # Returns an array of arrays containing the field values.
67
92
  # Order is the same as that returned by +columns+.
68
- def select_rows(sql, name = nil, binds = [])
69
- exec_query(sql, name, binds).rows
93
+ def select_rows(arel, name = nil, binds = [])
94
+ select_all(arel, name, binds).rows
95
+ end
96
+
97
+ def query_value(sql, name = nil) # :nodoc:
98
+ single_value_from_rows(query(sql, name))
99
+ end
100
+
101
+ def query_values(sql, name = nil) # :nodoc:
102
+ query(sql, name).map(&:first)
103
+ end
104
+
105
+ def query(sql, name = nil) # :nodoc:
106
+ exec_query(sql, name).rows
107
+ end
108
+
109
+ # Determines whether the SQL statement is a write query.
110
+ def write_query?(sql)
111
+ raise NotImplementedError
70
112
  end
71
113
 
72
114
  # Executes the SQL statement in the context of this connection and returns
@@ -81,71 +123,78 @@ module ActiveRecord
81
123
  # Executes +sql+ statement in the context of this connection using
82
124
  # +binds+ as the bind substitutes. +name+ is logged along with
83
125
  # the executed +sql+ statement.
84
- def exec_query(sql, name = 'SQL', binds = [], prepare: false)
126
+ def exec_query(sql, name = "SQL", binds = [], prepare: false)
85
127
  raise NotImplementedError
86
128
  end
87
129
 
88
130
  # Executes insert +sql+ statement in the context of this connection using
89
131
  # +binds+ as the bind substitutes. +name+ is logged along with
90
132
  # the executed +sql+ statement.
91
- def exec_insert(sql, name, binds, pk = nil, sequence_name = nil)
133
+ def exec_insert(sql, name = nil, binds = [], pk = nil, sequence_name = nil)
134
+ sql, binds = sql_for_insert(sql, pk, binds)
92
135
  exec_query(sql, name, binds)
93
136
  end
94
137
 
95
138
  # Executes delete +sql+ statement in the context of this connection using
96
139
  # +binds+ as the bind substitutes. +name+ is logged along with
97
140
  # the executed +sql+ statement.
98
- def exec_delete(sql, name, binds)
141
+ def exec_delete(sql, name = nil, binds = [])
99
142
  exec_query(sql, name, binds)
100
143
  end
101
144
 
102
- # Executes the truncate statement.
103
- def truncate(table_name, name = nil)
104
- raise NotImplementedError
105
- end
106
-
107
145
  # Executes update +sql+ statement in the context of this connection using
108
146
  # +binds+ as the bind substitutes. +name+ is logged along with
109
147
  # the executed +sql+ statement.
110
- def exec_update(sql, name, binds)
148
+ def exec_update(sql, name = nil, binds = [])
111
149
  exec_query(sql, name, binds)
112
150
  end
113
151
 
152
+ def exec_insert_all(sql, name) # :nodoc:
153
+ exec_query(sql, name)
154
+ end
155
+
114
156
  # Executes an INSERT query and returns the new record's ID
115
157
  #
116
- # +id_value+ will be returned unless the value is nil, in
158
+ # +id_value+ will be returned unless the value is +nil+, in
117
159
  # which case the database will attempt to calculate the last inserted
118
160
  # id and return that value.
119
161
  #
120
162
  # If the next id was calculated in advance (as in Oracle), it should be
121
163
  # passed in as +id_value+.
122
164
  def insert(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [])
123
- sql, binds, pk, sequence_name = sql_for_insert(to_sql(arel, binds), pk, id_value, sequence_name, binds)
165
+ sql, binds = to_sql_and_binds(arel, binds)
124
166
  value = exec_insert(sql, name, binds, pk, sequence_name)
125
167
  id_value || last_inserted_id(value)
126
168
  end
127
169
  alias create insert
128
- alias insert_sql insert
129
- deprecate insert_sql: :insert
130
170
 
131
171
  # Executes the update statement and returns the number of rows affected.
132
172
  def update(arel, name = nil, binds = [])
133
- exec_update(to_sql(arel, binds), name, binds)
173
+ sql, binds = to_sql_and_binds(arel, binds)
174
+ exec_update(sql, name, binds)
134
175
  end
135
- alias update_sql update
136
- deprecate update_sql: :update
137
176
 
138
177
  # Executes the delete statement and returns the number of rows affected.
139
178
  def delete(arel, name = nil, binds = [])
140
- exec_delete(to_sql(arel, binds), name, binds)
179
+ sql, binds = to_sql_and_binds(arel, binds)
180
+ exec_delete(sql, name, binds)
181
+ end
182
+
183
+ # Executes the truncate statement.
184
+ def truncate(table_name, name = nil)
185
+ execute(build_truncate_statements(table_name), name)
141
186
  end
142
- alias delete_sql delete
143
- deprecate delete_sql: :delete
144
187
 
145
- # Returns +true+ when the connection adapter supports prepared statement
146
- # caching, otherwise returns +false+
147
- def supports_statement_cache?
148
- false
188
+ def truncate_tables(*table_names) # :nodoc:
189
+ return if table_names.empty?
190
+
191
+ with_multi_statements do
192
+ disable_referential_integrity do
193
+ Array(build_truncate_statements(*table_names)).each do |sql|
194
+ execute_batch(sql, "Truncate Tables")
195
+ end
196
+ end
197
+ end
149
198
  end
150
199
 
151
200
  # Runs the given block in a database transaction, and returns the result
@@ -159,7 +208,7 @@ module ActiveRecord
159
208
  #
160
209
  # In order to get around this problem, #transaction will emulate the effect
161
210
  # of nested transactions, by using savepoints:
162
- # http://dev.mysql.com/doc/refman/5.7/en/savepoint.html
211
+ # https://dev.mysql.com/doc/refman/5.7/en/savepoint.html
163
212
  # Savepoints are supported by MySQL and PostgreSQL. SQLite3 version >= '3.6.8'
164
213
  # supports savepoints.
165
214
  #
@@ -211,7 +260,7 @@ module ActiveRecord
211
260
  # You should consult the documentation for your database to understand the
212
261
  # semantics of these different levels:
213
262
  #
214
- # * http://www.postgresql.org/docs/current/static/transaction-iso.html
263
+ # * https://www.postgresql.org/docs/current/static/transaction-iso.html
215
264
  # * https://dev.mysql.com/doc/refman/5.7/en/set-transaction.html
216
265
  #
217
266
  # An ActiveRecord::TransactionIsolationError will be raised if:
@@ -237,7 +286,9 @@ module ActiveRecord
237
286
 
238
287
  attr_reader :transaction_manager #:nodoc:
239
288
 
240
- delegate :within_new_transaction, :open_transactions, :current_transaction, :begin_transaction, :commit_transaction, :rollback_transaction, to: :transaction_manager
289
+ delegate :within_new_transaction, :open_transactions, :current_transaction, :begin_transaction,
290
+ :commit_transaction, :rollback_transaction, :materialize_transactions,
291
+ :disable_lazy_transactions!, :enable_lazy_transactions!, to: :transaction_manager
241
292
 
242
293
  def transaction_open?
243
294
  current_transaction.open?
@@ -302,70 +353,133 @@ module ActiveRecord
302
353
 
303
354
  # Inserts the given fixture into the table. Overridden in adapters that require
304
355
  # something beyond a simple insert (eg. Oracle).
356
+ # Most of adapters should implement `insert_fixtures_set` that leverages bulk SQL insert.
357
+ # We keep this method to provide fallback
358
+ # for databases like sqlite that do not support bulk inserts.
305
359
  def insert_fixture(fixture, table_name)
306
- fixture = fixture.stringify_keys
360
+ execute(build_fixture_sql(Array.wrap(fixture), table_name), "Fixture Insert")
361
+ end
307
362
 
308
- columns = schema_cache.columns_hash(table_name)
309
- binds = fixture.map do |name, value|
310
- if column = columns[name]
311
- type = lookup_cast_type_from_column(column)
312
- Relation::QueryAttribute.new(name, value, type)
313
- else
314
- raise Fixture::FixtureError, %(table "#{table_name}" has no column named #{name.inspect}.)
315
- end
316
- end
317
- key_list = fixture.keys.map { |name| quote_column_name(name) }
318
- value_list = prepare_binds_for_database(binds).map do |value|
319
- begin
320
- quote(value)
321
- rescue TypeError
322
- quote(YAML.dump(value))
363
+ def insert_fixtures_set(fixture_set, tables_to_delete = [])
364
+ fixture_inserts = build_fixture_statements(fixture_set)
365
+ table_deletes = tables_to_delete.map { |table| "DELETE FROM #{quote_table_name(table)}" }
366
+ total_sql = Array(combine_multi_statements(table_deletes + fixture_inserts))
367
+
368
+ with_multi_statements do
369
+ disable_referential_integrity do
370
+ transaction(requires_new: true) do
371
+ total_sql.each do |sql|
372
+ execute_batch(sql, "Fixtures Load")
373
+ end
374
+ end
323
375
  end
324
376
  end
325
-
326
- execute "INSERT INTO #{quote_table_name(table_name)} (#{key_list.join(', ')}) VALUES (#{value_list.join(', ')})", 'Fixture Insert'
327
377
  end
328
378
 
329
- def empty_insert_statement_value
379
+ def empty_insert_statement_value(primary_key = nil)
330
380
  "DEFAULT VALUES"
331
381
  end
332
382
 
333
383
  # Sanitizes the given LIMIT parameter in order to prevent SQL injection.
334
384
  #
335
385
  # The +limit+ may be anything that can evaluate to a string via #to_s. It
336
- # should look like an integer, or a comma-delimited list of integers, or
337
- # an Arel SQL literal.
386
+ # should look like an integer, or an Arel SQL literal.
338
387
  #
339
388
  # Returns Integer and Arel::Nodes::SqlLiteral limits as is.
340
- # Returns the sanitized limit parameter, either as an integer, or as a
341
- # string which contains a comma-delimited list of integers.
342
389
  def sanitize_limit(limit)
343
390
  if limit.is_a?(Integer) || limit.is_a?(Arel::Nodes::SqlLiteral)
344
391
  limit
345
- elsif limit.to_s.include?(',')
346
- Arel.sql limit.to_s.split(',').map{ |i| Integer(i) }.join(',')
347
392
  else
348
393
  Integer(limit)
349
394
  end
350
395
  end
351
396
 
352
- # The default strategy for an UPDATE with joins is to use a subquery. This doesn't work
353
- # on MySQL (even when aliasing the tables), but MySQL allows using JOIN directly in
354
- # an UPDATE statement, so in the MySQL adapters we redefine this to do that.
355
- def join_to_update(update, select, key) # :nodoc:
356
- subselect = subquery_for(key, select)
357
-
358
- update.where key.in(subselect)
397
+ # Fixture value is quoted by Arel, however scalar values
398
+ # are not quotable. In this case we want to convert
399
+ # the column value to YAML.
400
+ def with_yaml_fallback(value) # :nodoc:
401
+ if value.is_a?(Hash) || value.is_a?(Array)
402
+ YAML.dump(value)
403
+ else
404
+ value
405
+ end
359
406
  end
360
- alias join_to_delete join_to_update
361
407
 
362
- protected
408
+ private
409
+ def execute_batch(sql, name = nil)
410
+ execute(sql, name)
411
+ end
412
+
413
+ DEFAULT_INSERT_VALUE = Arel.sql("DEFAULT").freeze
414
+ private_constant :DEFAULT_INSERT_VALUE
363
415
 
364
- # Returns a subquery for the given key using the join information.
365
- def subquery_for(key, select)
366
- subselect = select.clone
367
- subselect.projections = [key]
368
- subselect
416
+ def default_insert_value(column)
417
+ DEFAULT_INSERT_VALUE
418
+ end
419
+
420
+ def build_fixture_sql(fixtures, table_name)
421
+ columns = schema_cache.columns_hash(table_name)
422
+
423
+ values_list = fixtures.map do |fixture|
424
+ fixture = fixture.stringify_keys
425
+
426
+ unknown_columns = fixture.keys - columns.keys
427
+ if unknown_columns.any?
428
+ raise Fixture::FixtureError, %(table "#{table_name}" has no columns named #{unknown_columns.map(&:inspect).join(', ')}.)
429
+ end
430
+
431
+ columns.map do |name, column|
432
+ if fixture.key?(name)
433
+ type = lookup_cast_type_from_column(column)
434
+ with_yaml_fallback(type.serialize(fixture[name]))
435
+ else
436
+ default_insert_value(column)
437
+ end
438
+ end
439
+ end
440
+
441
+ table = Arel::Table.new(table_name)
442
+ manager = Arel::InsertManager.new
443
+ manager.into(table)
444
+
445
+ if values_list.size == 1
446
+ values = values_list.shift
447
+ new_values = []
448
+ columns.each_key.with_index { |column, i|
449
+ unless values[i].equal?(DEFAULT_INSERT_VALUE)
450
+ new_values << values[i]
451
+ manager.columns << table[column]
452
+ end
453
+ }
454
+ values_list << new_values
455
+ else
456
+ columns.each_key { |column| manager.columns << table[column] }
457
+ end
458
+
459
+ manager.values = manager.create_values_list(values_list)
460
+ manager.to_sql
461
+ end
462
+
463
+ def build_fixture_statements(fixture_set)
464
+ fixture_set.map do |table_name, fixtures|
465
+ next if fixtures.empty?
466
+ build_fixture_sql(fixtures, table_name)
467
+ end.compact
468
+ end
469
+
470
+ def build_truncate_statements(*table_names)
471
+ truncate_tables = table_names.map do |table_name|
472
+ "TRUNCATE TABLE #{quote_table_name(table_name)}"
473
+ end
474
+ combine_multi_statements(truncate_tables)
475
+ end
476
+
477
+ def with_multi_statements
478
+ yield
479
+ end
480
+
481
+ def combine_multi_statements(total_sql)
482
+ total_sql.join(";\n")
369
483
  end
370
484
 
371
485
  # Returns an ActiveRecord::Result instance.
@@ -377,20 +491,25 @@ module ActiveRecord
377
491
  exec_query(sql, name, binds, prepare: true)
378
492
  end
379
493
 
380
- def sql_for_insert(sql, pk, id_value, sequence_name, binds)
381
- [sql, binds, pk, sequence_name]
494
+ def sql_for_insert(sql, pk, binds)
495
+ [sql, binds]
382
496
  end
383
497
 
384
498
  def last_inserted_id(result)
385
- row = result.rows.first
499
+ single_value_from_rows(result.rows)
500
+ end
501
+
502
+ def single_value_from_rows(rows)
503
+ row = rows.first
386
504
  row && row.first
387
505
  end
388
506
 
389
- def binds_from_relation(relation, binds)
390
- if relation.is_a?(Relation) && binds.empty?
391
- relation, binds = relation.arel, relation.bound_attributes
507
+ def arel_from_relation(relation)
508
+ if relation.is_a?(Relation)
509
+ relation.arel
510
+ else
511
+ relation
392
512
  end
393
- [relation, binds]
394
513
  end
395
514
  end
396
515
  end