activerecord 4.2.0 → 6.1.7.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (374) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +1221 -796
  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 +267 -249
  8. data/lib/active_record/association_relation.rb +45 -7
  9. data/lib/active_record/associations/alias_tracker.rb +40 -43
  10. data/lib/active_record/associations/association.rb +172 -67
  11. data/lib/active_record/associations/association_scope.rb +105 -129
  12. data/lib/active_record/associations/belongs_to_association.rb +85 -59
  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 -33
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +57 -70
  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 +168 -279
  22. data/lib/active_record/associations/collection_proxy.rb +263 -155
  23. data/lib/active_record/associations/foreign_association.rb +33 -0
  24. data/lib/active_record/associations/has_many_association.rb +57 -84
  25. data/lib/active_record/associations/has_many_through_association.rb +70 -82
  26. data/lib/active_record/associations/has_one_association.rb +74 -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 -73
  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 +175 -164
  32. data/lib/active_record/associations/preloader/association.rb +107 -112
  33. data/lib/active_record/associations/preloader/through_association.rb +85 -65
  34. data/lib/active_record/associations/preloader.rb +99 -96
  35. data/lib/active_record/associations/singular_association.rb +18 -45
  36. data/lib/active_record/associations/through_association.rb +49 -24
  37. data/lib/active_record/associations.rb +1845 -1597
  38. data/lib/active_record/attribute_assignment.rb +59 -185
  39. data/lib/active_record/attribute_methods/before_type_cast.rb +20 -7
  40. data/lib/active_record/attribute_methods/dirty.rb +168 -138
  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 +59 -36
  46. data/lib/active_record/attribute_methods/write.rb +25 -56
  47. data/lib/active_record/attribute_methods.rb +153 -162
  48. data/lib/active_record/attributes.rb +234 -70
  49. data/lib/active_record/autosave_association.rb +157 -69
  50. data/lib/active_record/base.rb +49 -50
  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 +46 -13
  54. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +887 -317
  55. data/lib/active_record/connection_adapters/abstract/database_limits.rb +17 -41
  56. data/lib/active_record/connection_adapters/abstract/database_statements.rb +301 -113
  57. data/lib/active_record/connection_adapters/abstract/query_cache.rb +78 -24
  58. data/lib/active_record/connection_adapters/abstract/quoting.rb +187 -60
  59. data/lib/active_record/connection_adapters/abstract/savepoints.rb +9 -7
  60. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +157 -93
  61. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +485 -253
  62. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +79 -36
  63. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +909 -263
  64. data/lib/active_record/connection_adapters/abstract/transaction.rb +254 -92
  65. data/lib/active_record/connection_adapters/abstract_adapter.rb +492 -221
  66. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +580 -608
  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 +196 -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 +271 -0
  78. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +40 -0
  79. data/lib/active_record/connection_adapters/mysql2_adapter.rb +81 -199
  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 +78 -161
  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 -57
  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 +5 -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 +17 -13
  92. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  93. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +6 -3
  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 -1
  105. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +67 -51
  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 +171 -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 +499 -293
  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 +595 -382
  119. data/lib/active_record/connection_adapters/schema_cache.rb +191 -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 +146 -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 -389
  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 +488 -243
  133. data/lib/active_record/counter_cache.rb +71 -50
  134. data/lib/active_record/database_configurations/connection_url_resolver.rb +99 -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 +273 -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 +212 -94
  143. data/lib/active_record/errors.rb +225 -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 +11 -6
  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 +273 -496
  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 +64 -0
  158. data/lib/active_record/legacy_yaml_adapter.rb +52 -0
  159. data/lib/active_record/locale/en.yml +3 -2
  160. data/lib/active_record/locking/optimistic.rb +103 -95
  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 +298 -0
  168. data/lib/active_record/migration/join_table.rb +8 -7
  169. data/lib/active_record/migration.rb +685 -309
  170. data/lib/active_record/model_schema.rb +420 -113
  171. data/lib/active_record/nested_attributes.rb +265 -216
  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 +574 -135
  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 +175 -54
  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 +533 -216
  181. data/lib/active_record/readonly_attributes.rb +9 -4
  182. data/lib/active_record/reflection.rb +485 -310
  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 +326 -244
  186. data/lib/active_record/relation/delegation.rb +76 -84
  187. data/lib/active_record/relation/finder_methods.rb +318 -256
  188. data/lib/active_record/relation/from_clause.rb +30 -0
  189. data/lib/active_record/relation/merger.rb +99 -84
  190. data/lib/active_record/relation/predicate_builder/array_handler.rb +26 -25
  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 +139 -96
  197. data/lib/active_record/relation/query_attribute.rb +50 -0
  198. data/lib/active_record/relation/query_methods.rb +757 -409
  199. data/lib/active_record/relation/record_fetch_warning.rb +51 -0
  200. data/lib/active_record/relation/spawn_methods.rb +23 -21
  201. data/lib/active_record/relation/where_clause.rb +239 -0
  202. data/lib/active_record/relation.rb +554 -342
  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 -26
  209. data/lib/active_record/scoping/default.rb +96 -82
  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 +133 -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 +366 -129
  220. data/lib/active_record/tasks/mysql_database_tasks.rb +68 -100
  221. data/lib/active_record/tasks/postgresql_database_tasks.rb +87 -39
  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 +291 -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 +181 -152
  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 -41
  231. data/lib/active_record/type/date_time.rb +4 -38
  232. data/lib/active_record/type/decimal_without_scale.rb +6 -2
  233. data/lib/active_record/type/hash_lookup_type_map.rb +12 -5
  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 +33 -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 +65 -48
  251. data/lib/active_record/validations.rb +39 -35
  252. data/lib/active_record/version.rb +3 -1
  253. data/lib/active_record.rb +44 -28
  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 -10
  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.rb +7 -5
  339. metadata +175 -65
  340. data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
  341. data/lib/active_record/associations/preloader/collection_association.rb +0 -24
  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 -23
  345. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  346. data/lib/active_record/associations/preloader/singular_association.rb +0 -21
  347. data/lib/active_record/attribute.rb +0 -149
  348. data/lib/active_record/attribute_decorators.rb +0 -66
  349. data/lib/active_record/attribute_set/builder.rb +0 -86
  350. data/lib/active_record/attribute_set.rb +0 -77
  351. data/lib/active_record/connection_adapters/connection_specification.rb +0 -275
  352. data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -491
  353. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
  354. data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
  355. data/lib/active_record/connection_adapters/postgresql/oid/integer.rb +0 -11
  356. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -35
  357. data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
  358. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  359. data/lib/active_record/serializers/xml_serializer.rb +0 -193
  360. data/lib/active_record/type/big_integer.rb +0 -13
  361. data/lib/active_record/type/binary.rb +0 -50
  362. data/lib/active_record/type/boolean.rb +0 -30
  363. data/lib/active_record/type/decimal.rb +0 -40
  364. data/lib/active_record/type/decorator.rb +0 -14
  365. data/lib/active_record/type/float.rb +0 -19
  366. data/lib/active_record/type/integer.rb +0 -55
  367. data/lib/active_record/type/mutable.rb +0 -16
  368. data/lib/active_record/type/numeric.rb +0 -36
  369. data/lib/active_record/type/string.rb +0 -36
  370. data/lib/active_record/type/time_value.rb +0 -38
  371. data/lib/active_record/type/value.rb +0 -101
  372. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +0 -22
  373. data/lib/rails/generators/active_record/model/templates/model.rb +0 -10
  374. /data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
@@ -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,20 +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)
349
+ def add_transaction_record(record, ensure_finalize = true)
350
+ current_transaction.add_record(record, ensure_finalize)
235
351
  end
236
352
 
237
353
  # Begins the transaction (and turns off auto-committing).
@@ -258,7 +374,15 @@ module ActiveRecord
258
374
 
259
375
  # Rolls back the transaction (and turns on auto-committing). Must be
260
376
  # done if the transaction block raises an exception or returns false.
261
- def rollback_db_transaction() end
377
+ def rollback_db_transaction
378
+ exec_rollback_db_transaction
379
+ end
380
+
381
+ def exec_rollback_db_transaction() end #:nodoc:
382
+
383
+ def rollback_to_savepoint(name = nil)
384
+ exec_rollback_to_savepoint(name)
385
+ end
262
386
 
263
387
  def default_sequence_name(table, column)
264
388
  nil
@@ -270,103 +394,167 @@ module ActiveRecord
270
394
  end
271
395
 
272
396
  # Inserts the given fixture into the table. Overridden in adapters that require
273
- # 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.
274
401
  def insert_fixture(fixture, table_name)
275
- columns = schema_cache.columns_hash(table_name)
402
+ execute(build_fixture_sql(Array.wrap(fixture), table_name), "Fixture Insert")
403
+ end
276
404
 
277
- key_list = []
278
- value_list = fixture.map do |name, value|
279
- key_list << quote_column_name(name)
280
- quote(value, columns[name])
281
- end
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
282
409
 
283
- execute "INSERT INTO #{quote_table_name(table_name)} (#{key_list.join(', ')}) VALUES (#{value_list.join(', ')})", 'Fixture Insert'
410
+ with_multi_statements do
411
+ disable_referential_integrity do
412
+ transaction(requires_new: true) do
413
+ execute_batch(statements, "Fixtures Load")
414
+ end
415
+ end
416
+ end
284
417
  end
285
418
 
286
- def empty_insert_statement_value
419
+ def empty_insert_statement_value(primary_key = nil)
287
420
  "DEFAULT VALUES"
288
421
  end
289
422
 
290
423
  # Sanitizes the given LIMIT parameter in order to prevent SQL injection.
291
424
  #
292
425
  # The +limit+ may be anything that can evaluate to a string via #to_s. It
293
- # should look like an integer, or a comma-delimited list of integers, or
294
- # an Arel SQL literal.
426
+ # should look like an integer, or an Arel SQL literal.
295
427
  #
296
428
  # Returns Integer and Arel::Nodes::SqlLiteral limits as is.
297
- # Returns the sanitized limit parameter, either as an integer, or as a
298
- # string which contains a comma-delimited list of integers.
299
429
  def sanitize_limit(limit)
300
430
  if limit.is_a?(Integer) || limit.is_a?(Arel::Nodes::SqlLiteral)
301
431
  limit
302
- elsif limit.to_s.include?(',')
303
- Arel.sql limit.to_s.split(',').map{ |i| Integer(i) }.join(',')
304
432
  else
305
433
  Integer(limit)
306
434
  end
307
435
  end
308
436
 
309
- # The default strategy for an UPDATE with joins is to use a subquery. This doesn't work
310
- # on MySQL (even when aliasing the tables), but MySQL allows using JOIN directly in
311
- # an UPDATE statement, so in the MySQL adapters we redefine this to do that.
312
- def join_to_update(update, select) #:nodoc:
313
- key = update.key
314
- subselect = subquery_for(key, select)
315
-
316
- 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
317
446
  end
318
447
 
319
- def join_to_delete(delete, select, key) #:nodoc:
320
- 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
321
454
 
322
- delete.where key.in(subselect)
323
- end
455
+ DEFAULT_INSERT_VALUE = Arel.sql("DEFAULT").freeze
456
+ private_constant :DEFAULT_INSERT_VALUE
324
457
 
325
- protected
458
+ def default_insert_value(column)
459
+ DEFAULT_INSERT_VALUE
460
+ end
461
+
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
326
482
 
327
- # Returns a subquery for the given key using the join information.
328
- def subquery_for(key, select)
329
- subselect = select.clone
330
- subselect.projections = [key]
331
- 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)
332
503
  end
333
504
 
334
- # Returns an ActiveRecord::Result instance.
335
- def select(sql, name = nil, binds = [])
336
- 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
337
510
  end
338
511
 
512
+ def build_truncate_statement(table_name)
513
+ "TRUNCATE TABLE #{quote_table_name(table_name)}"
514
+ end
339
515
 
340
- # Returns the last auto-generated ID from the affected table.
341
- def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
342
- execute(sql, name)
343
- id_value
516
+ def build_truncate_statements(table_names)
517
+ table_names.map do |table_name|
518
+ build_truncate_statement(table_name)
519
+ end
520
+ end
521
+
522
+ def with_multi_statements
523
+ yield
524
+ end
525
+
526
+ def combine_multi_statements(total_sql)
527
+ total_sql.join(";\n")
344
528
  end
345
529
 
346
- # Executes the update statement and returns the number of rows affected.
347
- def update_sql(sql, name = nil)
348
- execute(sql, name)
530
+ # Returns an ActiveRecord::Result instance.
531
+ def select(sql, name = nil, binds = [])
532
+ exec_query(sql, name, binds, prepare: false)
349
533
  end
350
534
 
351
- # Executes the delete statement and returns the number of rows affected.
352
- def delete_sql(sql, name = nil)
353
- update_sql(sql, name)
535
+ def select_prepared(sql, name = nil, binds = [])
536
+ exec_query(sql, name, binds, prepare: true)
354
537
  end
355
538
 
356
- def sql_for_insert(sql, pk, id_value, sequence_name, binds)
539
+ def sql_for_insert(sql, pk, binds)
357
540
  [sql, binds]
358
541
  end
359
542
 
360
543
  def last_inserted_id(result)
361
- 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
362
549
  row && row.first
363
550
  end
364
551
 
365
- def binds_from_relation(relation, binds)
366
- if relation.is_a?(Relation) && binds.empty?
367
- 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
368
557
  end
369
- [relation, binds]
370
558
  end
371
559
  end
372
560
  end