activerecord 4.2.9 → 6.1.4.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 (374) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +964 -1382
  3. data/MIT-LICENSE +4 -2
  4. data/README.rdoc +15 -14
  5. data/examples/performance.rb +33 -32
  6. data/examples/simple.rb +5 -4
  7. data/lib/active_record/aggregations.rb +266 -251
  8. data/lib/active_record/association_relation.rb +40 -15
  9. data/lib/active_record/associations/alias_tracker.rb +40 -43
  10. data/lib/active_record/associations/association.rb +162 -69
  11. data/lib/active_record/associations/association_scope.rb +105 -130
  12. data/lib/active_record/associations/belongs_to_association.rb +83 -65
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +13 -12
  14. data/lib/active_record/associations/builder/association.rb +57 -43
  15. data/lib/active_record/associations/builder/belongs_to.rb +74 -57
  16. data/lib/active_record/associations/builder/collection_association.rb +15 -37
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +49 -66
  18. data/lib/active_record/associations/builder/has_many.rb +13 -5
  19. data/lib/active_record/associations/builder/has_one.rb +44 -6
  20. data/lib/active_record/associations/builder/singular_association.rb +16 -10
  21. data/lib/active_record/associations/collection_association.rb +148 -287
  22. data/lib/active_record/associations/collection_proxy.rb +252 -150
  23. data/lib/active_record/associations/foreign_association.rb +23 -1
  24. data/lib/active_record/associations/has_many_association.rb +56 -98
  25. data/lib/active_record/associations/has_many_through_association.rb +68 -89
  26. data/lib/active_record/associations/has_one_association.rb +73 -47
  27. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  28. data/lib/active_record/associations/join_dependency/join_association.rb +54 -81
  29. data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
  30. data/lib/active_record/associations/join_dependency/join_part.rb +14 -14
  31. data/lib/active_record/associations/join_dependency.rb +174 -169
  32. data/lib/active_record/associations/preloader/association.rb +108 -115
  33. data/lib/active_record/associations/preloader/through_association.rb +85 -65
  34. data/lib/active_record/associations/preloader.rb +97 -94
  35. data/lib/active_record/associations/singular_association.rb +18 -39
  36. data/lib/active_record/associations/through_association.rb +39 -19
  37. data/lib/active_record/associations.rb +1845 -1598
  38. data/lib/active_record/attribute_assignment.rb +59 -185
  39. data/lib/active_record/attribute_methods/before_type_cast.rb +18 -10
  40. data/lib/active_record/attribute_methods/dirty.rb +168 -148
  41. data/lib/active_record/attribute_methods/primary_key.rb +93 -83
  42. data/lib/active_record/attribute_methods/query.rb +8 -10
  43. data/lib/active_record/attribute_methods/read.rb +19 -79
  44. data/lib/active_record/attribute_methods/serialization.rb +49 -24
  45. data/lib/active_record/attribute_methods/time_zone_conversion.rb +55 -36
  46. data/lib/active_record/attribute_methods/write.rb +24 -55
  47. data/lib/active_record/attribute_methods.rb +149 -154
  48. data/lib/active_record/attributes.rb +234 -78
  49. data/lib/active_record/autosave_association.rb +133 -60
  50. data/lib/active_record/base.rb +46 -46
  51. data/lib/active_record/callbacks.rb +234 -79
  52. data/lib/active_record/coders/json.rb +3 -1
  53. data/lib/active_record/coders/yaml_column.rb +34 -13
  54. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +887 -323
  55. data/lib/active_record/connection_adapters/abstract/database_limits.rb +17 -41
  56. data/lib/active_record/connection_adapters/abstract/database_statements.rb +292 -124
  57. data/lib/active_record/connection_adapters/abstract/query_cache.rb +78 -24
  58. data/lib/active_record/connection_adapters/abstract/quoting.rb +177 -60
  59. data/lib/active_record/connection_adapters/abstract/savepoints.rb +8 -6
  60. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +157 -93
  61. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +473 -255
  62. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +79 -36
  63. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +869 -286
  64. data/lib/active_record/connection_adapters/abstract/transaction.rb +257 -91
  65. data/lib/active_record/connection_adapters/abstract_adapter.rb +483 -230
  66. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +557 -640
  67. data/lib/active_record/connection_adapters/column.rb +67 -40
  68. data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
  69. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +35 -0
  70. data/lib/active_record/connection_adapters/mysql/column.rb +27 -0
  71. data/lib/active_record/connection_adapters/mysql/database_statements.rb +194 -0
  72. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +71 -0
  73. data/lib/active_record/connection_adapters/mysql/quoting.rb +96 -0
  74. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +97 -0
  75. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +103 -0
  76. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +91 -0
  77. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +268 -0
  78. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +40 -0
  79. data/lib/active_record/connection_adapters/mysql2_adapter.rb +80 -192
  80. data/lib/active_record/connection_adapters/pool_config.rb +73 -0
  81. data/lib/active_record/connection_adapters/pool_manager.rb +47 -0
  82. data/lib/active_record/connection_adapters/postgresql/column.rb +44 -11
  83. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +75 -160
  84. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
  85. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +49 -58
  86. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +9 -8
  87. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +4 -2
  89. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +8 -6
  90. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +13 -1
  91. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +14 -19
  92. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  93. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -4
  94. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +31 -20
  95. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -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 +44 -0
  99. data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -9
  101. data/lib/active_record/connection_adapters/postgresql/oid/{infinity.rb → oid.rb} +5 -3
  102. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +32 -11
  103. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +70 -34
  104. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -5
  105. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +58 -54
  106. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +18 -4
  107. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +3 -1
  108. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +3 -1
  109. data/lib/active_record/connection_adapters/postgresql/oid.rb +25 -25
  110. data/lib/active_record/connection_adapters/postgresql/quoting.rb +145 -48
  111. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +27 -14
  112. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +80 -0
  113. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +178 -108
  114. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +49 -0
  115. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +496 -298
  116. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +44 -0
  117. data/lib/active_record/connection_adapters/postgresql/utils.rb +11 -8
  118. data/lib/active_record/connection_adapters/postgresql_adapter.rb +588 -375
  119. data/lib/active_record/connection_adapters/schema_cache.rb +167 -29
  120. data/lib/active_record/connection_adapters/sql_type_metadata.rb +45 -0
  121. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +144 -0
  122. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +21 -0
  123. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +102 -0
  124. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +21 -0
  125. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
  126. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
  127. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +170 -0
  128. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +322 -373
  129. data/lib/active_record/connection_adapters/statement_pool.rb +33 -13
  130. data/lib/active_record/connection_adapters.rb +52 -0
  131. data/lib/active_record/connection_handling.rb +314 -41
  132. data/lib/active_record/core.rb +458 -241
  133. data/lib/active_record/counter_cache.rb +70 -49
  134. data/lib/active_record/database_configurations/connection_url_resolver.rb +98 -0
  135. data/lib/active_record/database_configurations/database_config.rb +80 -0
  136. data/lib/active_record/database_configurations/hash_config.rb +96 -0
  137. data/lib/active_record/database_configurations/url_config.rb +53 -0
  138. data/lib/active_record/database_configurations.rb +272 -0
  139. data/lib/active_record/delegated_type.rb +209 -0
  140. data/lib/active_record/destroy_association_async_job.rb +36 -0
  141. data/lib/active_record/dynamic_matchers.rb +87 -106
  142. data/lib/active_record/enum.rb +211 -92
  143. data/lib/active_record/errors.rb +224 -54
  144. data/lib/active_record/explain.rb +27 -11
  145. data/lib/active_record/explain_registry.rb +4 -2
  146. data/lib/active_record/explain_subscriber.rb +10 -5
  147. data/lib/active_record/fixture_set/file.rb +33 -14
  148. data/lib/active_record/fixture_set/model_metadata.rb +32 -0
  149. data/lib/active_record/fixture_set/render_context.rb +17 -0
  150. data/lib/active_record/fixture_set/table_row.rb +152 -0
  151. data/lib/active_record/fixture_set/table_rows.rb +46 -0
  152. data/lib/active_record/fixtures.rb +275 -500
  153. data/lib/active_record/gem_version.rb +6 -4
  154. data/lib/active_record/inheritance.rb +175 -110
  155. data/lib/active_record/insert_all.rb +212 -0
  156. data/lib/active_record/integration.rb +121 -29
  157. data/lib/active_record/internal_metadata.rb +62 -0
  158. data/lib/active_record/legacy_yaml_adapter.rb +27 -5
  159. data/lib/active_record/locale/en.yml +3 -2
  160. data/lib/active_record/locking/optimistic.rb +98 -92
  161. data/lib/active_record/locking/pessimistic.rb +22 -6
  162. data/lib/active_record/log_subscriber.rb +93 -31
  163. data/lib/active_record/middleware/database_selector/resolver/session.rb +48 -0
  164. data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
  165. data/lib/active_record/middleware/database_selector.rb +77 -0
  166. data/lib/active_record/migration/command_recorder.rb +185 -90
  167. data/lib/active_record/migration/compatibility.rb +295 -0
  168. data/lib/active_record/migration/join_table.rb +8 -7
  169. data/lib/active_record/migration.rb +673 -325
  170. data/lib/active_record/model_schema.rb +418 -113
  171. data/lib/active_record/nested_attributes.rb +263 -224
  172. data/lib/active_record/no_touching.rb +15 -2
  173. data/lib/active_record/null_relation.rb +24 -38
  174. data/lib/active_record/persistence.rb +572 -136
  175. data/lib/active_record/query_cache.rb +29 -23
  176. data/lib/active_record/querying.rb +50 -31
  177. data/lib/active_record/railtie.rb +170 -51
  178. data/lib/active_record/railties/console_sandbox.rb +3 -3
  179. data/lib/active_record/railties/controller_runtime.rb +34 -33
  180. data/lib/active_record/railties/databases.rake +523 -199
  181. data/lib/active_record/readonly_attributes.rb +9 -4
  182. data/lib/active_record/reflection.rb +454 -291
  183. data/lib/active_record/relation/batches/batch_enumerator.rb +85 -0
  184. data/lib/active_record/relation/batches.rb +217 -59
  185. data/lib/active_record/relation/calculations.rb +324 -249
  186. data/lib/active_record/relation/delegation.rb +76 -84
  187. data/lib/active_record/relation/finder_methods.rb +316 -242
  188. data/lib/active_record/relation/from_clause.rb +30 -0
  189. data/lib/active_record/relation/merger.rb +95 -103
  190. data/lib/active_record/relation/predicate_builder/array_handler.rb +26 -26
  191. data/lib/active_record/relation/predicate_builder/association_query_value.rb +42 -0
  192. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +19 -0
  193. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +57 -0
  194. data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -0
  195. data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
  196. data/lib/active_record/relation/predicate_builder.rb +136 -122
  197. data/lib/active_record/relation/query_attribute.rb +50 -0
  198. data/lib/active_record/relation/query_methods.rb +757 -413
  199. data/lib/active_record/relation/record_fetch_warning.rb +51 -0
  200. data/lib/active_record/relation/spawn_methods.rb +18 -20
  201. data/lib/active_record/relation/where_clause.rb +239 -0
  202. data/lib/active_record/relation.rb +554 -343
  203. data/lib/active_record/result.rb +91 -47
  204. data/lib/active_record/runtime_registry.rb +6 -4
  205. data/lib/active_record/sanitization.rb +134 -122
  206. data/lib/active_record/schema.rb +21 -24
  207. data/lib/active_record/schema_dumper.rb +141 -92
  208. data/lib/active_record/schema_migration.rb +24 -23
  209. data/lib/active_record/scoping/default.rb +96 -83
  210. data/lib/active_record/scoping/named.rb +78 -36
  211. data/lib/active_record/scoping.rb +45 -27
  212. data/lib/active_record/secure_token.rb +48 -0
  213. data/lib/active_record/serialization.rb +8 -6
  214. data/lib/active_record/signed_id.rb +116 -0
  215. data/lib/active_record/statement_cache.rb +89 -36
  216. data/lib/active_record/store.rb +128 -43
  217. data/lib/active_record/suppressor.rb +61 -0
  218. data/lib/active_record/table_metadata.rb +81 -0
  219. data/lib/active_record/tasks/database_tasks.rb +364 -130
  220. data/lib/active_record/tasks/mysql_database_tasks.rb +67 -113
  221. data/lib/active_record/tasks/postgresql_database_tasks.rb +86 -49
  222. data/lib/active_record/tasks/sqlite_database_tasks.rb +44 -19
  223. data/lib/active_record/test_databases.rb +24 -0
  224. data/lib/active_record/test_fixtures.rb +287 -0
  225. data/lib/active_record/timestamp.rb +86 -43
  226. data/lib/active_record/touch_later.rb +65 -0
  227. data/lib/active_record/transactions.rb +182 -163
  228. data/lib/active_record/translation.rb +3 -1
  229. data/lib/active_record/type/adapter_specific_registry.rb +126 -0
  230. data/lib/active_record/type/date.rb +4 -45
  231. data/lib/active_record/type/date_time.rb +4 -49
  232. data/lib/active_record/type/decimal_without_scale.rb +6 -2
  233. data/lib/active_record/type/hash_lookup_type_map.rb +5 -4
  234. data/lib/active_record/type/internal/timezone.rb +17 -0
  235. data/lib/active_record/type/json.rb +30 -0
  236. data/lib/active_record/type/serialized.rb +27 -15
  237. data/lib/active_record/type/text.rb +2 -2
  238. data/lib/active_record/type/time.rb +21 -16
  239. data/lib/active_record/type/type_map.rb +16 -19
  240. data/lib/active_record/type/unsigned_integer.rb +9 -8
  241. data/lib/active_record/type.rb +84 -23
  242. data/lib/active_record/type_caster/connection.rb +33 -0
  243. data/lib/active_record/type_caster/map.rb +23 -0
  244. data/lib/active_record/type_caster.rb +9 -0
  245. data/lib/active_record/validations/absence.rb +25 -0
  246. data/lib/active_record/validations/associated.rb +12 -4
  247. data/lib/active_record/validations/length.rb +26 -0
  248. data/lib/active_record/validations/numericality.rb +35 -0
  249. data/lib/active_record/validations/presence.rb +14 -13
  250. data/lib/active_record/validations/uniqueness.rb +63 -56
  251. data/lib/active_record/validations.rb +39 -35
  252. data/lib/active_record/version.rb +3 -1
  253. data/lib/active_record.rb +42 -29
  254. data/lib/arel/alias_predication.rb +9 -0
  255. data/lib/arel/attributes/attribute.rb +41 -0
  256. data/lib/arel/collectors/bind.rb +29 -0
  257. data/lib/arel/collectors/composite.rb +39 -0
  258. data/lib/arel/collectors/plain_string.rb +20 -0
  259. data/lib/arel/collectors/sql_string.rb +27 -0
  260. data/lib/arel/collectors/substitute_binds.rb +35 -0
  261. data/lib/arel/crud.rb +42 -0
  262. data/lib/arel/delete_manager.rb +18 -0
  263. data/lib/arel/errors.rb +9 -0
  264. data/lib/arel/expressions.rb +29 -0
  265. data/lib/arel/factory_methods.rb +49 -0
  266. data/lib/arel/insert_manager.rb +49 -0
  267. data/lib/arel/math.rb +45 -0
  268. data/lib/arel/nodes/and.rb +32 -0
  269. data/lib/arel/nodes/ascending.rb +23 -0
  270. data/lib/arel/nodes/binary.rb +126 -0
  271. data/lib/arel/nodes/bind_param.rb +44 -0
  272. data/lib/arel/nodes/case.rb +55 -0
  273. data/lib/arel/nodes/casted.rb +62 -0
  274. data/lib/arel/nodes/comment.rb +29 -0
  275. data/lib/arel/nodes/count.rb +12 -0
  276. data/lib/arel/nodes/delete_statement.rb +45 -0
  277. data/lib/arel/nodes/descending.rb +23 -0
  278. data/lib/arel/nodes/equality.rb +15 -0
  279. data/lib/arel/nodes/extract.rb +24 -0
  280. data/lib/arel/nodes/false.rb +16 -0
  281. data/lib/arel/nodes/full_outer_join.rb +8 -0
  282. data/lib/arel/nodes/function.rb +44 -0
  283. data/lib/arel/nodes/grouping.rb +11 -0
  284. data/lib/arel/nodes/homogeneous_in.rb +76 -0
  285. data/lib/arel/nodes/in.rb +15 -0
  286. data/lib/arel/nodes/infix_operation.rb +92 -0
  287. data/lib/arel/nodes/inner_join.rb +8 -0
  288. data/lib/arel/nodes/insert_statement.rb +37 -0
  289. data/lib/arel/nodes/join_source.rb +20 -0
  290. data/lib/arel/nodes/matches.rb +18 -0
  291. data/lib/arel/nodes/named_function.rb +23 -0
  292. data/lib/arel/nodes/node.rb +51 -0
  293. data/lib/arel/nodes/node_expression.rb +13 -0
  294. data/lib/arel/nodes/ordering.rb +27 -0
  295. data/lib/arel/nodes/outer_join.rb +8 -0
  296. data/lib/arel/nodes/over.rb +15 -0
  297. data/lib/arel/nodes/regexp.rb +16 -0
  298. data/lib/arel/nodes/right_outer_join.rb +8 -0
  299. data/lib/arel/nodes/select_core.rb +67 -0
  300. data/lib/arel/nodes/select_statement.rb +41 -0
  301. data/lib/arel/nodes/sql_literal.rb +19 -0
  302. data/lib/arel/nodes/string_join.rb +11 -0
  303. data/lib/arel/nodes/table_alias.rb +31 -0
  304. data/lib/arel/nodes/terminal.rb +16 -0
  305. data/lib/arel/nodes/true.rb +16 -0
  306. data/lib/arel/nodes/unary.rb +44 -0
  307. data/lib/arel/nodes/unary_operation.rb +20 -0
  308. data/lib/arel/nodes/unqualified_column.rb +22 -0
  309. data/lib/arel/nodes/update_statement.rb +41 -0
  310. data/lib/arel/nodes/values_list.rb +9 -0
  311. data/lib/arel/nodes/window.rb +126 -0
  312. data/lib/arel/nodes/with.rb +11 -0
  313. data/lib/arel/nodes.rb +70 -0
  314. data/lib/arel/order_predications.rb +13 -0
  315. data/lib/arel/predications.rb +250 -0
  316. data/lib/arel/select_manager.rb +270 -0
  317. data/lib/arel/table.rb +118 -0
  318. data/lib/arel/tree_manager.rb +72 -0
  319. data/lib/arel/update_manager.rb +34 -0
  320. data/lib/arel/visitors/dot.rb +308 -0
  321. data/lib/arel/visitors/mysql.rb +93 -0
  322. data/lib/arel/visitors/postgresql.rb +120 -0
  323. data/lib/arel/visitors/sqlite.rb +38 -0
  324. data/lib/arel/visitors/to_sql.rb +899 -0
  325. data/lib/arel/visitors/visitor.rb +45 -0
  326. data/lib/arel/visitors.rb +13 -0
  327. data/lib/arel/window_predications.rb +9 -0
  328. data/lib/arel.rb +54 -0
  329. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +26 -0
  330. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +5 -0
  331. data/lib/rails/generators/active_record/migration/migration_generator.rb +43 -37
  332. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +26 -0
  333. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +13 -4
  334. data/lib/rails/generators/active_record/migration.rb +35 -1
  335. data/lib/rails/generators/active_record/model/model_generator.rb +55 -22
  336. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
  337. data/lib/rails/generators/active_record/model/templates/model.rb.tt +22 -0
  338. data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
  339. data/lib/rails/generators/active_record.rb +7 -5
  340. metadata +172 -65
  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_decorators.rb +0 -66
  350. data/lib/active_record/attribute_set/builder.rb +0 -106
  351. data/lib/active_record/attribute_set.rb +0 -81
  352. data/lib/active_record/connection_adapters/connection_specification.rb +0 -275
  353. data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -491
  354. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
  355. data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
  356. data/lib/active_record/connection_adapters/postgresql/oid/integer.rb +0 -11
  357. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -35
  358. data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
  359. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  360. data/lib/active_record/serializers/xml_serializer.rb +0 -193
  361. data/lib/active_record/type/big_integer.rb +0 -13
  362. data/lib/active_record/type/binary.rb +0 -50
  363. data/lib/active_record/type/boolean.rb +0 -31
  364. data/lib/active_record/type/decimal.rb +0 -64
  365. data/lib/active_record/type/decorator.rb +0 -14
  366. data/lib/active_record/type/float.rb +0 -19
  367. data/lib/active_record/type/integer.rb +0 -59
  368. data/lib/active_record/type/mutable.rb +0 -16
  369. data/lib/active_record/type/numeric.rb +0 -36
  370. data/lib/active_record/type/string.rb +0 -40
  371. data/lib/active_record/type/time_value.rb +0 -38
  372. data/lib/active_record/type/value.rb +0 -110
  373. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +0 -19
  374. data/lib/rails/generators/active_record/model/templates/model.rb +0 -10
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters # :nodoc:
3
5
  module DatabaseStatements
@@ -7,29 +9,67 @@ 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 = [], preparable = nil) # :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
+ collector = collector()
25
+
26
+ if prepared_statements
27
+ collector.preparable = true
28
+ sql, binds = visitor.compile(arel_or_sql_string.ast, collector)
29
+
30
+ if binds.length > bind_params_length
31
+ unprepared_statement do
32
+ return to_sql_and_binds(arel_or_sql_string)
33
+ end
34
+ end
35
+ preparable = collector.preparable
36
+ else
37
+ sql = visitor.compile(arel_or_sql_string.ast, collector)
38
+ end
39
+ [sql.freeze, binds, preparable]
14
40
  else
15
- arel
41
+ arel_or_sql_string = arel_or_sql_string.dup.freeze unless arel_or_sql_string.frozen?
42
+ [arel_or_sql_string, binds, preparable]
16
43
  end
17
44
  end
45
+ private :to_sql_and_binds
18
46
 
19
47
  # This is used in the StatementCache object. It returns an object that
20
48
  # can be used to query the database repeatedly.
21
- def cacheable_query(arel) # :nodoc:
49
+ def cacheable_query(klass, arel) # :nodoc:
22
50
  if prepared_statements
23
- ActiveRecord::StatementCache.query visitor, arel.ast
51
+ sql, binds = visitor.compile(arel.ast, collector)
52
+ query = klass.query(sql)
24
53
  else
25
- ActiveRecord::StatementCache.partial_query visitor, arel.ast, collector
54
+ collector = klass.partial_query_collector
55
+ parts, binds = visitor.compile(arel.ast, collector)
56
+ query = klass.partial_query(parts)
26
57
  end
58
+ [query, binds]
27
59
  end
28
60
 
29
61
  # Returns an ActiveRecord::Result instance.
30
- def select_all(arel, name = nil, binds = [])
31
- arel, binds = binds_from_relation arel, binds
32
- select(to_sql(arel, binds), name, binds)
62
+ def select_all(arel, name = nil, binds = [], preparable: nil)
63
+ arel = arel_from_relation(arel)
64
+ sql, binds, preparable = to_sql_and_binds(arel, binds, preparable)
65
+
66
+ if prepared_statements && preparable
67
+ select_prepared(sql, name, binds)
68
+ else
69
+ select(sql, name, binds)
70
+ end
71
+ rescue ::RangeError
72
+ ActiveRecord::Result.new([], [])
33
73
  end
34
74
 
35
75
  # Returns a record hash with the column names as keys and column values
@@ -40,89 +80,127 @@ module ActiveRecord
40
80
 
41
81
  # Returns a single value from a record
42
82
  def select_value(arel, name = nil, binds = [])
43
- if result = select_one(arel, name, binds)
44
- result.values.first
45
- end
83
+ single_value_from_rows(select_rows(arel, name, binds))
46
84
  end
47
85
 
48
86
  # Returns an array of the values of the first column in a select:
49
87
  # select_values("SELECT id FROM companies LIMIT 3") => [1,2,3]
50
- def select_values(arel, name = nil)
51
- arel, binds = binds_from_relation arel, []
52
- select_rows(to_sql(arel, binds), name, binds).map(&:first)
88
+ def select_values(arel, name = nil, binds = [])
89
+ select_rows(arel, name, binds).map(&:first)
53
90
  end
54
91
 
55
92
  # Returns an array of arrays containing the field values.
56
93
  # Order is the same as that returned by +columns+.
57
- def select_rows(sql, name = nil, binds = [])
94
+ def select_rows(arel, name = nil, binds = [])
95
+ select_all(arel, name, binds).rows
96
+ end
97
+
98
+ def query_value(sql, name = nil) # :nodoc:
99
+ single_value_from_rows(query(sql, name))
58
100
  end
59
- undef_method :select_rows
60
101
 
61
- # Executes the SQL statement in the context of this connection.
102
+ def query_values(sql, name = nil) # :nodoc:
103
+ query(sql, name).map(&:first)
104
+ end
105
+
106
+ def query(sql, name = nil) # :nodoc:
107
+ exec_query(sql, name).rows
108
+ end
109
+
110
+ # Determines whether the SQL statement is a write query.
111
+ def write_query?(sql)
112
+ raise NotImplementedError
113
+ end
114
+
115
+ # Executes the SQL statement in the context of this connection and returns
116
+ # the raw result from the connection adapter.
117
+ # Note: depending on your database connector, the result returned by this
118
+ # method may be manually memory managed. Consider using the exec_query
119
+ # wrapper instead.
62
120
  def execute(sql, name = nil)
121
+ raise NotImplementedError
63
122
  end
64
- undef_method :execute
65
123
 
66
124
  # Executes +sql+ statement in the context of this connection using
67
125
  # +binds+ as the bind substitutes. +name+ is logged along with
68
126
  # the executed +sql+ statement.
69
- def exec_query(sql, name = 'SQL', binds = [])
127
+ def exec_query(sql, name = "SQL", binds = [], prepare: false)
128
+ raise NotImplementedError
70
129
  end
71
130
 
72
131
  # Executes insert +sql+ statement in the context of this connection using
73
132
  # +binds+ as the bind substitutes. +name+ is logged along with
74
133
  # the executed +sql+ statement.
75
- def exec_insert(sql, name, binds, pk = nil, sequence_name = nil)
134
+ def exec_insert(sql, name = nil, binds = [], pk = nil, sequence_name = nil)
135
+ sql, binds = sql_for_insert(sql, pk, binds)
76
136
  exec_query(sql, name, binds)
77
137
  end
78
138
 
79
139
  # Executes delete +sql+ statement in the context of this connection using
80
140
  # +binds+ as the bind substitutes. +name+ is logged along with
81
141
  # the executed +sql+ statement.
82
- def exec_delete(sql, name, binds)
142
+ def exec_delete(sql, name = nil, binds = [])
83
143
  exec_query(sql, name, binds)
84
144
  end
85
145
 
86
- # Executes the truncate statement.
87
- def truncate(table_name, name = nil)
88
- raise NotImplementedError
89
- end
90
-
91
146
  # Executes update +sql+ statement in the context of this connection using
92
147
  # +binds+ as the bind substitutes. +name+ is logged along with
93
148
  # the executed +sql+ statement.
94
- def exec_update(sql, name, binds)
149
+ def exec_update(sql, name = nil, binds = [])
95
150
  exec_query(sql, name, binds)
96
151
  end
97
152
 
98
- # Returns the last auto-generated ID from the affected table.
153
+ def exec_insert_all(sql, name) # :nodoc:
154
+ exec_query(sql, name)
155
+ end
156
+
157
+ def explain(arel, binds = []) # :nodoc:
158
+ raise NotImplementedError
159
+ end
160
+
161
+ # Executes an INSERT query and returns the new record's ID
99
162
  #
100
- # +id_value+ will be returned unless the value is nil, in
163
+ # +id_value+ will be returned unless the value is +nil+, in
101
164
  # which case the database will attempt to calculate the last inserted
102
165
  # id and return that value.
103
166
  #
104
167
  # If the next id was calculated in advance (as in Oracle), it should be
105
168
  # passed in as +id_value+.
106
169
  def insert(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [])
107
- sql, binds = sql_for_insert(to_sql(arel, binds), pk, id_value, sequence_name, binds)
108
- value = exec_insert(sql, name, binds, pk, sequence_name)
170
+ sql, binds = to_sql_and_binds(arel, binds)
171
+ value = exec_insert(sql, name, binds, pk, sequence_name)
109
172
  id_value || last_inserted_id(value)
110
173
  end
174
+ alias create insert
111
175
 
112
176
  # Executes the update statement and returns the number of rows affected.
113
177
  def update(arel, name = nil, binds = [])
114
- exec_update(to_sql(arel, binds), name, binds)
178
+ sql, binds = to_sql_and_binds(arel, binds)
179
+ exec_update(sql, name, binds)
115
180
  end
116
181
 
117
182
  # Executes the delete statement and returns the number of rows affected.
118
183
  def delete(arel, name = nil, binds = [])
119
- exec_delete(to_sql(arel, binds), name, binds)
184
+ sql, binds = to_sql_and_binds(arel, binds)
185
+ exec_delete(sql, name, binds)
120
186
  end
121
187
 
122
- # Returns +true+ when the connection adapter supports prepared statement
123
- # caching, otherwise returns +false+
124
- def supports_statement_cache?
125
- false
188
+ # Executes the truncate statement.
189
+ def truncate(table_name, name = nil)
190
+ execute(build_truncate_statement(table_name), name)
191
+ end
192
+
193
+ def truncate_tables(*table_names) # :nodoc:
194
+ table_names -= [schema_migration.table_name, InternalMetadata.table_name]
195
+
196
+ return if table_names.empty?
197
+
198
+ with_multi_statements do
199
+ disable_referential_integrity do
200
+ statements = build_truncate_statements(table_names)
201
+ execute_batch(statements, "Truncate Tables")
202
+ end
203
+ end
126
204
  end
127
205
 
128
206
  # Runs the given block in a database transaction, and returns the result
@@ -130,15 +208,30 @@ module ActiveRecord
130
208
  #
131
209
  # == Nested transactions support
132
210
  #
211
+ # #transaction calls can be nested. By default, this makes all database
212
+ # statements in the nested transaction block become part of the parent
213
+ # transaction. For example, the following behavior may be surprising:
214
+ #
215
+ # ActiveRecord::Base.transaction do
216
+ # Post.create(title: 'first')
217
+ # ActiveRecord::Base.transaction do
218
+ # Post.create(title: 'second')
219
+ # raise ActiveRecord::Rollback
220
+ # end
221
+ # end
222
+ #
223
+ # This creates both "first" and "second" posts. Reason is the
224
+ # ActiveRecord::Rollback exception in the nested block does not issue a
225
+ # ROLLBACK. Since these exceptions are captured in transaction blocks,
226
+ # the parent block does not see it and the real transaction is committed.
227
+ #
133
228
  # Most databases don't support true nested transactions. At the time of
134
229
  # writing, the only database that supports true nested transactions that
135
230
  # we're aware of, is MS-SQL.
136
231
  #
137
232
  # In order to get around this problem, #transaction will emulate the effect
138
233
  # of nested transactions, by using savepoints:
139
- # http://dev.mysql.com/doc/refman/5.0/en/savepoint.html
140
- # Savepoints are supported by MySQL and PostgreSQL. SQLite3 version >= '3.6.8'
141
- # supports savepoints.
234
+ # https://dev.mysql.com/doc/refman/en/savepoint.html.
142
235
  #
143
236
  # It is safe to call this method if a database transaction is already open,
144
237
  # i.e. if #transaction is called within another #transaction block. In case
@@ -150,6 +243,24 @@ module ActiveRecord
150
243
  # - However, if +:requires_new+ is set, the block will be wrapped in a
151
244
  # database savepoint acting as a sub-transaction.
152
245
  #
246
+ # In order to get a ROLLBACK for the nested transaction you may ask for a
247
+ # real sub-transaction by passing <tt>requires_new: true</tt>.
248
+ # If anything goes wrong, the database rolls back to the beginning of
249
+ # the sub-transaction without rolling back the parent transaction.
250
+ # If we add it to the previous example:
251
+ #
252
+ # ActiveRecord::Base.transaction do
253
+ # Post.create(title: 'first')
254
+ # ActiveRecord::Base.transaction(requires_new: true) do
255
+ # Post.create(title: 'second')
256
+ # raise ActiveRecord::Rollback
257
+ # end
258
+ # end
259
+ #
260
+ # only post with title "first" is created.
261
+ #
262
+ # See ActiveRecord::Transactions to learn more.
263
+ #
153
264
  # === Caveats
154
265
  #
155
266
  # MySQL doesn't support DDL transactions. If you perform a DDL operation,
@@ -188,29 +299,25 @@ module ActiveRecord
188
299
  # You should consult the documentation for your database to understand the
189
300
  # semantics of these different levels:
190
301
  #
191
- # * http://www.postgresql.org/docs/9.1/static/transaction-iso.html
192
- # * https://dev.mysql.com/doc/refman/5.0/en/set-transaction.html
302
+ # * https://www.postgresql.org/docs/current/static/transaction-iso.html
303
+ # * https://dev.mysql.com/doc/refman/en/set-transaction.html
193
304
  #
194
- # An <tt>ActiveRecord::TransactionIsolationError</tt> will be raised if:
305
+ # An ActiveRecord::TransactionIsolationError will be raised if:
195
306
  #
196
307
  # * The adapter does not support setting the isolation level
197
308
  # * You are joining an existing open transaction
198
309
  # * You are creating a nested (savepoint) transaction
199
310
  #
200
- # The mysql, mysql2 and postgresql adapters support setting the transaction
201
- # isolation level. However, support is disabled for MySQL versions below 5,
202
- # because they are affected by a bug[http://bugs.mysql.com/bug.php?id=39170]
203
- # which means the isolation level gets persisted outside the transaction.
204
- def transaction(options = {})
205
- options.assert_valid_keys :requires_new, :joinable, :isolation
206
-
207
- if !options[:requires_new] && current_transaction.joinable?
208
- if options[:isolation]
311
+ # The mysql2 and postgresql adapters support setting the transaction
312
+ # isolation level.
313
+ def transaction(requires_new: nil, isolation: nil, joinable: true)
314
+ if !requires_new && current_transaction.joinable?
315
+ if isolation
209
316
  raise ActiveRecord::TransactionIsolationError, "cannot set isolation when joining a transaction"
210
317
  end
211
318
  yield
212
319
  else
213
- transaction_manager.within_new_transaction(options) { yield }
320
+ transaction_manager.within_new_transaction(isolation: isolation, joinable: joinable) { yield }
214
321
  end
215
322
  rescue ActiveRecord::Rollback
216
323
  # rollbacks are silently swallowed
@@ -218,24 +325,29 @@ module ActiveRecord
218
325
 
219
326
  attr_reader :transaction_manager #:nodoc:
220
327
 
221
- delegate :within_new_transaction, :open_transactions, :current_transaction, :begin_transaction, :commit_transaction, :rollback_transaction, to: :transaction_manager
328
+ delegate :within_new_transaction, :open_transactions, :current_transaction, :begin_transaction,
329
+ :commit_transaction, :rollback_transaction, :materialize_transactions,
330
+ :disable_lazy_transactions!, :enable_lazy_transactions!, to: :transaction_manager
331
+
332
+ def mark_transaction_written_if_write(sql) # :nodoc:
333
+ transaction = current_transaction
334
+ if transaction.open?
335
+ transaction.written ||= write_query?(sql)
336
+ end
337
+ end
222
338
 
223
339
  def transaction_open?
224
340
  current_transaction.open?
225
341
  end
226
342
 
227
343
  def reset_transaction #:nodoc:
228
- @transaction_manager = TransactionManager.new(self)
344
+ @transaction_manager = ConnectionAdapters::TransactionManager.new(self)
229
345
  end
230
346
 
231
347
  # Register a record with the current transaction so that its after_commit and after_rollback callbacks
232
348
  # can be called.
233
- def add_transaction_record(record)
234
- current_transaction.add_record(record)
235
- end
236
-
237
- def transaction_state
238
- current_transaction.state
349
+ def add_transaction_record(record, ensure_finalize = true)
350
+ current_transaction.add_record(record, ensure_finalize)
239
351
  end
240
352
 
241
353
  # Begins the transaction (and turns off auto-committing).
@@ -272,9 +384,6 @@ module ActiveRecord
272
384
  exec_rollback_to_savepoint(name)
273
385
  end
274
386
 
275
- def exec_rollback_to_savepoint(name = nil) #:nodoc:
276
- end
277
-
278
387
  def default_sequence_name(table, column)
279
388
  nil
280
389
  end
@@ -285,108 +394,167 @@ module ActiveRecord
285
394
  end
286
395
 
287
396
  # Inserts the given fixture into the table. Overridden in adapters that require
288
- # something beyond a simple insert (eg. Oracle).
397
+ # something beyond a simple insert (e.g. Oracle).
398
+ # Most of adapters should implement +insert_fixtures_set+ that leverages bulk SQL insert.
399
+ # We keep this method to provide fallback
400
+ # for databases like sqlite that do not support bulk inserts.
289
401
  def insert_fixture(fixture, table_name)
290
- fixture = fixture.stringify_keys
291
- columns = schema_cache.columns_hash(table_name)
292
-
293
- key_list = []
294
- value_list = fixture.map do |name, value|
295
- if column = columns[name]
296
- key_list << quote_column_name(name)
297
- quote(value, column)
298
- else
299
- raise Fixture::FixtureError, %(table "#{table_name}" has no column named #{name.inspect}.)
402
+ execute(build_fixture_sql(Array.wrap(fixture), table_name), "Fixture Insert")
403
+ end
404
+
405
+ def insert_fixtures_set(fixture_set, tables_to_delete = [])
406
+ fixture_inserts = build_fixture_statements(fixture_set)
407
+ table_deletes = tables_to_delete.map { |table| "DELETE FROM #{quote_table_name(table)}" }
408
+ statements = table_deletes + fixture_inserts
409
+
410
+ with_multi_statements do
411
+ disable_referential_integrity do
412
+ transaction(requires_new: true) do
413
+ execute_batch(statements, "Fixtures Load")
414
+ end
300
415
  end
301
416
  end
302
-
303
- execute "INSERT INTO #{quote_table_name(table_name)} (#{key_list.join(', ')}) VALUES (#{value_list.join(', ')})", 'Fixture Insert'
304
417
  end
305
418
 
306
- def empty_insert_statement_value
419
+ def empty_insert_statement_value(primary_key = nil)
307
420
  "DEFAULT VALUES"
308
421
  end
309
422
 
310
423
  # Sanitizes the given LIMIT parameter in order to prevent SQL injection.
311
424
  #
312
425
  # The +limit+ may be anything that can evaluate to a string via #to_s. It
313
- # should look like an integer, or a comma-delimited list of integers, or
314
- # an Arel SQL literal.
426
+ # should look like an integer, or an Arel SQL literal.
315
427
  #
316
428
  # Returns Integer and Arel::Nodes::SqlLiteral limits as is.
317
- # Returns the sanitized limit parameter, either as an integer, or as a
318
- # string which contains a comma-delimited list of integers.
319
429
  def sanitize_limit(limit)
320
430
  if limit.is_a?(Integer) || limit.is_a?(Arel::Nodes::SqlLiteral)
321
431
  limit
322
- elsif limit.to_s.include?(',')
323
- Arel.sql limit.to_s.split(',').map{ |i| Integer(i) }.join(',')
324
432
  else
325
433
  Integer(limit)
326
434
  end
327
435
  end
328
436
 
329
- # The default strategy for an UPDATE with joins is to use a subquery. This doesn't work
330
- # on MySQL (even when aliasing the tables), but MySQL allows using JOIN directly in
331
- # an UPDATE statement, so in the MySQL adapters we redefine this to do that.
332
- def join_to_update(update, select) #:nodoc:
333
- key = update.key
334
- subselect = subquery_for(key, select)
335
-
336
- update.where key.in(subselect)
437
+ # Fixture value is quoted by Arel, however scalar values
438
+ # are not quotable. In this case we want to convert
439
+ # the column value to YAML.
440
+ def with_yaml_fallback(value) # :nodoc:
441
+ if value.is_a?(Hash) || value.is_a?(Array)
442
+ YAML.dump(value)
443
+ else
444
+ value
445
+ end
337
446
  end
338
447
 
339
- def join_to_delete(delete, select, key) #:nodoc:
340
- subselect = subquery_for(key, select)
448
+ private
449
+ def execute_batch(statements, name = nil)
450
+ statements.each do |statement|
451
+ execute(statement, name)
452
+ end
453
+ end
454
+
455
+ DEFAULT_INSERT_VALUE = Arel.sql("DEFAULT").freeze
456
+ private_constant :DEFAULT_INSERT_VALUE
341
457
 
342
- delete.where key.in(subselect)
343
- end
458
+ def default_insert_value(column)
459
+ DEFAULT_INSERT_VALUE
460
+ end
344
461
 
345
- protected
462
+ def build_fixture_sql(fixtures, table_name)
463
+ columns = schema_cache.columns_hash(table_name)
464
+
465
+ values_list = fixtures.map do |fixture|
466
+ fixture = fixture.stringify_keys
467
+
468
+ unknown_columns = fixture.keys - columns.keys
469
+ if unknown_columns.any?
470
+ raise Fixture::FixtureError, %(table "#{table_name}" has no columns named #{unknown_columns.map(&:inspect).join(', ')}.)
471
+ end
472
+
473
+ columns.map do |name, column|
474
+ if fixture.key?(name)
475
+ type = lookup_cast_type_from_column(column)
476
+ with_yaml_fallback(type.serialize(fixture[name]))
477
+ else
478
+ default_insert_value(column)
479
+ end
480
+ end
481
+ end
346
482
 
347
- # Returns a subquery for the given key using the join information.
348
- def subquery_for(key, select)
349
- subselect = select.clone
350
- subselect.projections = [key]
351
- subselect
483
+ table = Arel::Table.new(table_name)
484
+ manager = Arel::InsertManager.new
485
+ manager.into(table)
486
+
487
+ if values_list.size == 1
488
+ values = values_list.shift
489
+ new_values = []
490
+ columns.each_key.with_index { |column, i|
491
+ unless values[i].equal?(DEFAULT_INSERT_VALUE)
492
+ new_values << values[i]
493
+ manager.columns << table[column]
494
+ end
495
+ }
496
+ values_list << new_values
497
+ else
498
+ columns.each_key { |column| manager.columns << table[column] }
499
+ end
500
+
501
+ manager.values = manager.create_values_list(values_list)
502
+ visitor.compile(manager.ast)
352
503
  end
353
504
 
354
- # Returns an ActiveRecord::Result instance.
355
- def select(sql, name = nil, binds = [])
356
- exec_query(sql, name, binds)
505
+ def build_fixture_statements(fixture_set)
506
+ fixture_set.map do |table_name, fixtures|
507
+ next if fixtures.empty?
508
+ build_fixture_sql(fixtures, table_name)
509
+ end.compact
510
+ end
511
+
512
+ def build_truncate_statement(table_name)
513
+ "TRUNCATE TABLE #{quote_table_name(table_name)}"
357
514
  end
358
515
 
516
+ def build_truncate_statements(table_names)
517
+ table_names.map do |table_name|
518
+ build_truncate_statement(table_name)
519
+ end
520
+ end
359
521
 
360
- # Returns the last auto-generated ID from the affected table.
361
- def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
362
- execute(sql, name)
363
- id_value
522
+ def with_multi_statements
523
+ yield
364
524
  end
365
525
 
366
- # Executes the update statement and returns the number of rows affected.
367
- def update_sql(sql, name = nil)
368
- execute(sql, name)
526
+ def combine_multi_statements(total_sql)
527
+ total_sql.join(";\n")
369
528
  end
370
529
 
371
- # Executes the delete statement and returns the number of rows affected.
372
- def delete_sql(sql, name = nil)
373
- update_sql(sql, name)
530
+ # Returns an ActiveRecord::Result instance.
531
+ def select(sql, name = nil, binds = [])
532
+ exec_query(sql, name, binds, prepare: false)
374
533
  end
375
534
 
376
- def sql_for_insert(sql, pk, id_value, sequence_name, binds)
535
+ def select_prepared(sql, name = nil, binds = [])
536
+ exec_query(sql, name, binds, prepare: true)
537
+ end
538
+
539
+ def sql_for_insert(sql, pk, binds)
377
540
  [sql, binds]
378
541
  end
379
542
 
380
543
  def last_inserted_id(result)
381
- row = result.rows.first
544
+ single_value_from_rows(result.rows)
545
+ end
546
+
547
+ def single_value_from_rows(rows)
548
+ row = rows.first
382
549
  row && row.first
383
550
  end
384
551
 
385
- def binds_from_relation(relation, binds)
386
- if relation.is_a?(Relation) && binds.empty?
387
- relation, binds = relation.arel, relation.bind_values
552
+ def arel_from_relation(relation)
553
+ if relation.is_a?(Relation)
554
+ relation.arel
555
+ else
556
+ relation
388
557
  end
389
- [relation, binds]
390
558
  end
391
559
  end
392
560
  end