activerecord 4.2.0 → 6.0.5.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 (373) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +852 -801
  3. data/MIT-LICENSE +4 -2
  4. data/README.rdoc +14 -13
  5. data/examples/performance.rb +33 -32
  6. data/examples/simple.rb +5 -4
  7. data/lib/active_record/advisory_lock_base.rb +18 -0
  8. data/lib/active_record/aggregations.rb +267 -249
  9. data/lib/active_record/association_relation.rb +26 -6
  10. data/lib/active_record/associations/alias_tracker.rb +29 -36
  11. data/lib/active_record/associations/association.rb +137 -55
  12. data/lib/active_record/associations/association_scope.rb +110 -132
  13. data/lib/active_record/associations/belongs_to_association.rb +67 -54
  14. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -12
  15. data/lib/active_record/associations/builder/association.rb +27 -40
  16. data/lib/active_record/associations/builder/belongs_to.rb +69 -55
  17. data/lib/active_record/associations/builder/collection_association.rb +10 -29
  18. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +58 -70
  19. data/lib/active_record/associations/builder/has_many.rb +8 -4
  20. data/lib/active_record/associations/builder/has_one.rb +46 -5
  21. data/lib/active_record/associations/builder/singular_association.rb +16 -10
  22. data/lib/active_record/associations/collection_association.rb +150 -275
  23. data/lib/active_record/associations/collection_proxy.rb +253 -152
  24. data/lib/active_record/associations/foreign_association.rb +20 -0
  25. data/lib/active_record/associations/has_many_association.rb +35 -84
  26. data/lib/active_record/associations/has_many_through_association.rb +62 -80
  27. data/lib/active_record/associations/has_one_association.rb +62 -49
  28. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  29. data/lib/active_record/associations/join_dependency/join_association.rb +43 -78
  30. data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
  31. data/lib/active_record/associations/join_dependency/join_part.rb +14 -14
  32. data/lib/active_record/associations/join_dependency.rb +159 -162
  33. data/lib/active_record/associations/preloader/association.rb +102 -113
  34. data/lib/active_record/associations/preloader/through_association.rb +85 -65
  35. data/lib/active_record/associations/preloader.rb +96 -95
  36. data/lib/active_record/associations/singular_association.rb +18 -45
  37. data/lib/active_record/associations/through_association.rb +49 -24
  38. data/lib/active_record/associations.rb +1737 -1596
  39. data/lib/active_record/attribute_assignment.rb +57 -185
  40. data/lib/active_record/attribute_decorators.rb +39 -17
  41. data/lib/active_record/attribute_methods/before_type_cast.rb +14 -5
  42. data/lib/active_record/attribute_methods/dirty.rb +174 -134
  43. data/lib/active_record/attribute_methods/primary_key.rb +90 -84
  44. data/lib/active_record/attribute_methods/query.rb +6 -5
  45. data/lib/active_record/attribute_methods/read.rb +20 -77
  46. data/lib/active_record/attribute_methods/serialization.rb +40 -21
  47. data/lib/active_record/attribute_methods/time_zone_conversion.rb +61 -37
  48. data/lib/active_record/attribute_methods/write.rb +33 -56
  49. data/lib/active_record/attribute_methods.rb +124 -143
  50. data/lib/active_record/attributes.rb +213 -74
  51. data/lib/active_record/autosave_association.rb +125 -54
  52. data/lib/active_record/base.rb +60 -49
  53. data/lib/active_record/callbacks.rb +101 -76
  54. data/lib/active_record/coders/json.rb +3 -1
  55. data/lib/active_record/coders/yaml_column.rb +36 -13
  56. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +810 -291
  57. data/lib/active_record/connection_adapters/abstract/database_limits.rb +26 -8
  58. data/lib/active_record/connection_adapters/abstract/database_statements.rb +253 -108
  59. data/lib/active_record/connection_adapters/abstract/query_cache.rb +83 -24
  60. data/lib/active_record/connection_adapters/abstract/quoting.rb +171 -53
  61. data/lib/active_record/connection_adapters/abstract/savepoints.rb +6 -4
  62. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +74 -47
  63. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +383 -239
  64. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +79 -36
  65. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +736 -235
  66. data/lib/active_record/connection_adapters/abstract/transaction.rb +190 -87
  67. data/lib/active_record/connection_adapters/abstract_adapter.rb +487 -192
  68. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +536 -600
  69. data/lib/active_record/connection_adapters/column.rb +56 -43
  70. data/lib/active_record/connection_adapters/connection_specification.rb +174 -153
  71. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +29 -0
  72. data/lib/active_record/connection_adapters/mysql/column.rb +27 -0
  73. data/lib/active_record/connection_adapters/mysql/database_statements.rb +196 -0
  74. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +71 -0
  75. data/lib/active_record/connection_adapters/mysql/quoting.rb +81 -0
  76. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +71 -0
  77. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +95 -0
  78. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +88 -0
  79. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +268 -0
  80. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +31 -0
  81. data/lib/active_record/connection_adapters/mysql2_adapter.rb +59 -196
  82. data/lib/active_record/connection_adapters/postgresql/column.rb +21 -11
  83. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +71 -115
  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 +5 -1
  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/jsonb.rb +3 -11
  97. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +44 -0
  98. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -9
  99. data/lib/active_record/connection_adapters/postgresql/oid/{infinity.rb → oid.rb} +5 -3
  100. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +32 -11
  101. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +70 -34
  102. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -1
  103. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +67 -51
  104. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +9 -5
  105. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +3 -1
  106. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +3 -1
  107. data/lib/active_record/connection_adapters/postgresql/oid.rb +23 -25
  108. data/lib/active_record/connection_adapters/postgresql/quoting.rb +144 -47
  109. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +27 -14
  110. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -0
  111. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +178 -108
  112. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +49 -0
  113. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +465 -291
  114. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +36 -0
  115. data/lib/active_record/connection_adapters/postgresql/utils.rb +11 -8
  116. data/lib/active_record/connection_adapters/postgresql_adapter.rb +565 -363
  117. data/lib/active_record/connection_adapters/schema_cache.rb +72 -25
  118. data/lib/active_record/connection_adapters/sql_type_metadata.rb +37 -0
  119. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +119 -0
  120. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +21 -0
  121. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +102 -0
  122. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +17 -0
  123. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
  124. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
  125. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +137 -0
  126. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +299 -364
  127. data/lib/active_record/connection_adapters/statement_pool.rb +33 -13
  128. data/lib/active_record/connection_handling.rb +167 -41
  129. data/lib/active_record/core.rb +277 -233
  130. data/lib/active_record/counter_cache.rb +71 -50
  131. data/lib/active_record/database_configurations/database_config.rb +37 -0
  132. data/lib/active_record/database_configurations/hash_config.rb +50 -0
  133. data/lib/active_record/database_configurations/url_config.rb +78 -0
  134. data/lib/active_record/database_configurations.rb +233 -0
  135. data/lib/active_record/define_callbacks.rb +22 -0
  136. data/lib/active_record/dynamic_matchers.rb +87 -106
  137. data/lib/active_record/enum.rb +172 -89
  138. data/lib/active_record/errors.rb +189 -53
  139. data/lib/active_record/explain.rb +22 -11
  140. data/lib/active_record/explain_registry.rb +4 -2
  141. data/lib/active_record/explain_subscriber.rb +11 -6
  142. data/lib/active_record/fixture_set/file.rb +35 -9
  143. data/lib/active_record/fixture_set/model_metadata.rb +33 -0
  144. data/lib/active_record/fixture_set/render_context.rb +17 -0
  145. data/lib/active_record/fixture_set/table_row.rb +152 -0
  146. data/lib/active_record/fixture_set/table_rows.rb +46 -0
  147. data/lib/active_record/fixtures.rb +225 -497
  148. data/lib/active_record/gem_version.rb +6 -4
  149. data/lib/active_record/inheritance.rb +158 -115
  150. data/lib/active_record/insert_all.rb +179 -0
  151. data/lib/active_record/integration.rb +123 -29
  152. data/lib/active_record/internal_metadata.rb +53 -0
  153. data/lib/active_record/legacy_yaml_adapter.rb +48 -0
  154. data/lib/active_record/locale/en.yml +3 -2
  155. data/lib/active_record/locking/optimistic.rb +99 -98
  156. data/lib/active_record/locking/pessimistic.rb +18 -6
  157. data/lib/active_record/log_subscriber.rb +76 -33
  158. data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
  159. data/lib/active_record/middleware/database_selector/resolver.rb +87 -0
  160. data/lib/active_record/middleware/database_selector.rb +74 -0
  161. data/lib/active_record/migration/command_recorder.rb +166 -91
  162. data/lib/active_record/migration/compatibility.rb +244 -0
  163. data/lib/active_record/migration/join_table.rb +8 -7
  164. data/lib/active_record/migration.rb +636 -290
  165. data/lib/active_record/model_schema.rb +344 -112
  166. data/lib/active_record/nested_attributes.rb +265 -215
  167. data/lib/active_record/no_touching.rb +15 -2
  168. data/lib/active_record/null_relation.rb +24 -38
  169. data/lib/active_record/persistence.rb +559 -125
  170. data/lib/active_record/query_cache.rb +19 -23
  171. data/lib/active_record/querying.rb +44 -30
  172. data/lib/active_record/railtie.rb +166 -47
  173. data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
  174. data/lib/active_record/railties/console_sandbox.rb +2 -0
  175. data/lib/active_record/railties/controller_runtime.rb +34 -33
  176. data/lib/active_record/railties/databases.rake +341 -202
  177. data/lib/active_record/readonly_attributes.rb +5 -4
  178. data/lib/active_record/reflection.rb +461 -302
  179. data/lib/active_record/relation/batches/batch_enumerator.rb +69 -0
  180. data/lib/active_record/relation/batches.rb +206 -55
  181. data/lib/active_record/relation/calculations.rb +270 -249
  182. data/lib/active_record/relation/delegation.rb +76 -84
  183. data/lib/active_record/relation/finder_methods.rb +287 -255
  184. data/lib/active_record/relation/from_clause.rb +30 -0
  185. data/lib/active_record/relation/merger.rb +86 -68
  186. data/lib/active_record/relation/predicate_builder/array_handler.rb +27 -25
  187. data/lib/active_record/relation/predicate_builder/association_query_value.rb +43 -0
  188. data/lib/active_record/relation/predicate_builder/base_handler.rb +18 -0
  189. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +19 -0
  190. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +53 -0
  191. data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -0
  192. data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
  193. data/lib/active_record/relation/predicate_builder.rb +112 -92
  194. data/lib/active_record/relation/query_attribute.rb +50 -0
  195. data/lib/active_record/relation/query_methods.rb +612 -392
  196. data/lib/active_record/relation/record_fetch_warning.rb +51 -0
  197. data/lib/active_record/relation/spawn_methods.rb +18 -17
  198. data/lib/active_record/relation/where_clause.rb +189 -0
  199. data/lib/active_record/relation/where_clause_factory.rb +33 -0
  200. data/lib/active_record/relation.rb +533 -340
  201. data/lib/active_record/result.rb +79 -43
  202. data/lib/active_record/runtime_registry.rb +6 -4
  203. data/lib/active_record/sanitization.rb +144 -121
  204. data/lib/active_record/schema.rb +21 -24
  205. data/lib/active_record/schema_dumper.rb +112 -93
  206. data/lib/active_record/schema_migration.rb +24 -20
  207. data/lib/active_record/scoping/default.rb +98 -82
  208. data/lib/active_record/scoping/named.rb +91 -33
  209. data/lib/active_record/scoping.rb +45 -27
  210. data/lib/active_record/secure_token.rb +40 -0
  211. data/lib/active_record/serialization.rb +5 -5
  212. data/lib/active_record/statement_cache.rb +73 -36
  213. data/lib/active_record/store.rb +127 -42
  214. data/lib/active_record/suppressor.rb +61 -0
  215. data/lib/active_record/table_metadata.rb +90 -0
  216. data/lib/active_record/tasks/database_tasks.rb +309 -99
  217. data/lib/active_record/tasks/mysql_database_tasks.rb +58 -89
  218. data/lib/active_record/tasks/postgresql_database_tasks.rb +81 -31
  219. data/lib/active_record/tasks/sqlite_database_tasks.rb +37 -16
  220. data/lib/active_record/test_databases.rb +23 -0
  221. data/lib/active_record/test_fixtures.rb +243 -0
  222. data/lib/active_record/timestamp.rb +86 -41
  223. data/lib/active_record/touch_later.rb +65 -0
  224. data/lib/active_record/transactions.rb +222 -146
  225. data/lib/active_record/translation.rb +3 -1
  226. data/lib/active_record/type/adapter_specific_registry.rb +126 -0
  227. data/lib/active_record/type/date.rb +4 -41
  228. data/lib/active_record/type/date_time.rb +4 -38
  229. data/lib/active_record/type/decimal_without_scale.rb +6 -2
  230. data/lib/active_record/type/hash_lookup_type_map.rb +12 -5
  231. data/lib/active_record/type/internal/timezone.rb +17 -0
  232. data/lib/active_record/type/json.rb +30 -0
  233. data/lib/active_record/type/serialized.rb +29 -15
  234. data/lib/active_record/type/text.rb +2 -2
  235. data/lib/active_record/type/time.rb +21 -16
  236. data/lib/active_record/type/type_map.rb +16 -19
  237. data/lib/active_record/type/unsigned_integer.rb +9 -8
  238. data/lib/active_record/type.rb +77 -23
  239. data/lib/active_record/type_caster/connection.rb +34 -0
  240. data/lib/active_record/type_caster/map.rb +20 -0
  241. data/lib/active_record/type_caster.rb +9 -0
  242. data/lib/active_record/validations/absence.rb +25 -0
  243. data/lib/active_record/validations/associated.rb +12 -4
  244. data/lib/active_record/validations/length.rb +26 -0
  245. data/lib/active_record/validations/presence.rb +14 -13
  246. data/lib/active_record/validations/uniqueness.rb +43 -46
  247. data/lib/active_record/validations.rb +38 -35
  248. data/lib/active_record/version.rb +3 -1
  249. data/lib/active_record.rb +44 -21
  250. data/lib/arel/alias_predication.rb +9 -0
  251. data/lib/arel/attributes/attribute.rb +37 -0
  252. data/lib/arel/attributes.rb +22 -0
  253. data/lib/arel/collectors/bind.rb +24 -0
  254. data/lib/arel/collectors/composite.rb +31 -0
  255. data/lib/arel/collectors/plain_string.rb +20 -0
  256. data/lib/arel/collectors/sql_string.rb +20 -0
  257. data/lib/arel/collectors/substitute_binds.rb +28 -0
  258. data/lib/arel/crud.rb +42 -0
  259. data/lib/arel/delete_manager.rb +18 -0
  260. data/lib/arel/errors.rb +9 -0
  261. data/lib/arel/expressions.rb +29 -0
  262. data/lib/arel/factory_methods.rb +49 -0
  263. data/lib/arel/insert_manager.rb +49 -0
  264. data/lib/arel/math.rb +45 -0
  265. data/lib/arel/nodes/and.rb +32 -0
  266. data/lib/arel/nodes/ascending.rb +23 -0
  267. data/lib/arel/nodes/binary.rb +52 -0
  268. data/lib/arel/nodes/bind_param.rb +36 -0
  269. data/lib/arel/nodes/case.rb +55 -0
  270. data/lib/arel/nodes/casted.rb +50 -0
  271. data/lib/arel/nodes/comment.rb +29 -0
  272. data/lib/arel/nodes/count.rb +12 -0
  273. data/lib/arel/nodes/delete_statement.rb +45 -0
  274. data/lib/arel/nodes/descending.rb +23 -0
  275. data/lib/arel/nodes/equality.rb +18 -0
  276. data/lib/arel/nodes/extract.rb +24 -0
  277. data/lib/arel/nodes/false.rb +16 -0
  278. data/lib/arel/nodes/full_outer_join.rb +8 -0
  279. data/lib/arel/nodes/function.rb +44 -0
  280. data/lib/arel/nodes/grouping.rb +8 -0
  281. data/lib/arel/nodes/in.rb +8 -0
  282. data/lib/arel/nodes/infix_operation.rb +80 -0
  283. data/lib/arel/nodes/inner_join.rb +8 -0
  284. data/lib/arel/nodes/insert_statement.rb +37 -0
  285. data/lib/arel/nodes/join_source.rb +20 -0
  286. data/lib/arel/nodes/matches.rb +18 -0
  287. data/lib/arel/nodes/named_function.rb +23 -0
  288. data/lib/arel/nodes/node.rb +50 -0
  289. data/lib/arel/nodes/node_expression.rb +13 -0
  290. data/lib/arel/nodes/outer_join.rb +8 -0
  291. data/lib/arel/nodes/over.rb +15 -0
  292. data/lib/arel/nodes/regexp.rb +16 -0
  293. data/lib/arel/nodes/right_outer_join.rb +8 -0
  294. data/lib/arel/nodes/select_core.rb +67 -0
  295. data/lib/arel/nodes/select_statement.rb +41 -0
  296. data/lib/arel/nodes/sql_literal.rb +16 -0
  297. data/lib/arel/nodes/string_join.rb +11 -0
  298. data/lib/arel/nodes/table_alias.rb +27 -0
  299. data/lib/arel/nodes/terminal.rb +16 -0
  300. data/lib/arel/nodes/true.rb +16 -0
  301. data/lib/arel/nodes/unary.rb +45 -0
  302. data/lib/arel/nodes/unary_operation.rb +20 -0
  303. data/lib/arel/nodes/unqualified_column.rb +22 -0
  304. data/lib/arel/nodes/update_statement.rb +41 -0
  305. data/lib/arel/nodes/values_list.rb +9 -0
  306. data/lib/arel/nodes/window.rb +126 -0
  307. data/lib/arel/nodes/with.rb +11 -0
  308. data/lib/arel/nodes.rb +68 -0
  309. data/lib/arel/order_predications.rb +13 -0
  310. data/lib/arel/predications.rb +256 -0
  311. data/lib/arel/select_manager.rb +271 -0
  312. data/lib/arel/table.rb +110 -0
  313. data/lib/arel/tree_manager.rb +72 -0
  314. data/lib/arel/update_manager.rb +34 -0
  315. data/lib/arel/visitors/depth_first.rb +203 -0
  316. data/lib/arel/visitors/dot.rb +296 -0
  317. data/lib/arel/visitors/ibm_db.rb +34 -0
  318. data/lib/arel/visitors/informix.rb +62 -0
  319. data/lib/arel/visitors/mssql.rb +156 -0
  320. data/lib/arel/visitors/mysql.rb +83 -0
  321. data/lib/arel/visitors/oracle.rb +158 -0
  322. data/lib/arel/visitors/oracle12.rb +65 -0
  323. data/lib/arel/visitors/postgresql.rb +109 -0
  324. data/lib/arel/visitors/sqlite.rb +38 -0
  325. data/lib/arel/visitors/to_sql.rb +888 -0
  326. data/lib/arel/visitors/visitor.rb +45 -0
  327. data/lib/arel/visitors/where_sql.rb +22 -0
  328. data/lib/arel/visitors.rb +20 -0
  329. data/lib/arel/window_predications.rb +9 -0
  330. data/lib/arel.rb +62 -0
  331. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +26 -0
  332. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +5 -0
  333. data/lib/rails/generators/active_record/migration/migration_generator.rb +42 -37
  334. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +24 -0
  335. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +11 -8
  336. data/lib/rails/generators/active_record/migration.rb +30 -1
  337. data/lib/rails/generators/active_record/model/model_generator.rb +18 -22
  338. data/lib/rails/generators/active_record/model/templates/model.rb.tt +22 -0
  339. data/lib/rails/generators/active_record.rb +7 -5
  340. metadata +174 -63
  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 -149
  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/mysql_adapter.rb +0 -491
  352. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
  353. data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
  354. data/lib/active_record/connection_adapters/postgresql/oid/integer.rb +0 -11
  355. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -35
  356. data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
  357. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  358. data/lib/active_record/serializers/xml_serializer.rb +0 -193
  359. data/lib/active_record/type/big_integer.rb +0 -13
  360. data/lib/active_record/type/binary.rb +0 -50
  361. data/lib/active_record/type/boolean.rb +0 -30
  362. data/lib/active_record/type/decimal.rb +0 -40
  363. data/lib/active_record/type/decorator.rb +0 -14
  364. data/lib/active_record/type/float.rb +0 -19
  365. data/lib/active_record/type/integer.rb +0 -55
  366. data/lib/active_record/type/mutable.rb +0 -16
  367. data/lib/active_record/type/numeric.rb +0 -36
  368. data/lib/active_record/type/string.rb +0 -36
  369. data/lib/active_record/type/time_value.rb +0 -38
  370. data/lib/active_record/type/value.rb +0 -101
  371. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +0 -22
  372. data/lib/rails/generators/active_record/model/templates/model.rb +0 -10
  373. /data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
@@ -1,7 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  ###
3
- # This class encapsulates a Result returned from calling +exec_query+ on any
4
- # database connection adapter. For example:
5
+ # This class encapsulates a result returned from calling
6
+ # {#exec_query}[rdoc-ref:ConnectionAdapters::DatabaseStatements#exec_query]
7
+ # on any database connection adapter. For example:
5
8
  #
6
9
  # result = ActiveRecord::Base.connection.exec_query('SELECT id, title, body FROM posts')
7
10
  # result # => #<ActiveRecord::Result:0xdeadbeef>
@@ -18,7 +21,7 @@ module ActiveRecord
18
21
  # ]
19
22
  #
20
23
  # # Get an array of hashes representing the result (column => value):
21
- # result.to_hash
24
+ # result.to_a
22
25
  # # => [{"id" => 1, "title" => "title_1", "body" => "body_1"},
23
26
  # {"id" => 2, "title" => "title_2", "body" => "body_2"},
24
27
  # ...
@@ -31,8 +34,6 @@ module ActiveRecord
31
34
  class Result
32
35
  include Enumerable
33
36
 
34
- IDENTITY_TYPE = Type::Value.new # :nodoc:
35
-
36
37
  attr_reader :columns, :rows, :column_types
37
38
 
38
39
  def initialize(columns, rows, column_types = {})
@@ -42,10 +43,20 @@ module ActiveRecord
42
43
  @column_types = column_types
43
44
  end
44
45
 
46
+ # Returns true if this result set includes the column named +name+
47
+ def includes_column?(name)
48
+ @columns.include? name
49
+ end
50
+
51
+ # Returns the number of elements in the rows array.
45
52
  def length
46
53
  @rows.length
47
54
  end
48
55
 
56
+ # Calls the given block once for each element in row collection, passing
57
+ # row as parameter.
58
+ #
59
+ # Returns an +Enumerator+ if no block is given.
49
60
  def each
50
61
  if block_given?
51
62
  hash_rows.each { |row| yield row }
@@ -55,36 +66,62 @@ module ActiveRecord
55
66
  end
56
67
 
57
68
  def to_hash
58
- hash_rows
69
+ ActiveSupport::Deprecation.warn(<<-MSG.squish)
70
+ `ActiveRecord::Result#to_hash` has been renamed to `to_a`.
71
+ `to_hash` is deprecated and will be removed in Rails 6.1.
72
+ MSG
73
+ to_a
59
74
  end
60
75
 
61
76
  alias :map! :map
62
77
  alias :collect! :map
63
78
 
64
- # Returns true if there are no records.
79
+ # Returns true if there are no records, otherwise false.
65
80
  def empty?
66
81
  rows.empty?
67
82
  end
68
83
 
84
+ # Returns an array of hashes representing each row record.
69
85
  def to_ary
70
86
  hash_rows
71
87
  end
72
88
 
89
+ alias :to_a :to_ary
90
+
73
91
  def [](idx)
74
92
  hash_rows[idx]
75
93
  end
76
94
 
95
+ # Returns the first record from the rows collection.
96
+ # If the rows collection is empty, returns +nil+.
97
+ def first
98
+ return nil if @rows.empty?
99
+ Hash[@columns.zip(@rows.first)]
100
+ end
101
+
102
+ # Returns the last record from the rows collection.
103
+ # If the rows collection is empty, returns +nil+.
77
104
  def last
78
- hash_rows.last
105
+ return nil if @rows.empty?
106
+ Hash[@columns.zip(@rows.last)]
79
107
  end
80
108
 
81
109
  def cast_values(type_overrides = {}) # :nodoc:
82
- types = columns.map { |name| column_type(name, type_overrides) }
83
- result = rows.map do |values|
84
- types.zip(values).map { |type, value| type.type_cast_from_database(value) }
85
- end
110
+ if columns.one?
111
+ # Separated to avoid allocating an array per row
86
112
 
87
- columns.one? ? result.map!(&:first) : result
113
+ type = column_type(columns.first, type_overrides)
114
+
115
+ rows.map do |(value)|
116
+ type.deserialize(value)
117
+ end
118
+ else
119
+ types = columns.map { |name| column_type(name, type_overrides) }
120
+
121
+ rows.map do |values|
122
+ Array.new(values.size) { |i| types[i].deserialize(values[i]) }
123
+ end
124
+ end
88
125
  end
89
126
 
90
127
  def initialize_copy(other)
@@ -95,37 +132,36 @@ module ActiveRecord
95
132
  end
96
133
 
97
134
  private
98
-
99
- def column_type(name, type_overrides = {})
100
- type_overrides.fetch(name) do
101
- column_types.fetch(name, IDENTITY_TYPE)
135
+ def column_type(name, type_overrides = {})
136
+ type_overrides.fetch(name) do
137
+ column_types.fetch(name, Type.default_value)
138
+ end
102
139
  end
103
- end
104
140
 
105
- def hash_rows
106
- @hash_rows ||=
107
- begin
108
- # We freeze the strings to prevent them getting duped when
109
- # used as keys in ActiveRecord::Base's @attributes hash
110
- columns = @columns.map { |c| c.dup.freeze }
111
- @rows.map { |row|
112
- # In the past we used Hash[columns.zip(row)]
113
- # though elegant, the verbose way is much more efficient
114
- # both time and memory wise cause it avoids a big array allocation
115
- # this method is called a lot and needs to be micro optimised
116
- hash = {}
117
-
118
- index = 0
119
- length = columns.length
120
-
121
- while index < length
122
- hash[columns[index]] = row[index]
123
- index += 1
124
- end
125
-
126
- hash
127
- }
128
- end
129
- end
141
+ def hash_rows
142
+ @hash_rows ||=
143
+ begin
144
+ # We freeze the strings to prevent them getting duped when
145
+ # used as keys in ActiveRecord::Base's @attributes hash
146
+ columns = @columns.map(&:-@)
147
+ length = columns.length
148
+
149
+ @rows.map { |row|
150
+ # In the past we used Hash[columns.zip(row)]
151
+ # though elegant, the verbose way is much more efficient
152
+ # both time and memory wise cause it avoids a big array allocation
153
+ # this method is called a lot and needs to be micro optimised
154
+ hash = {}
155
+
156
+ index = 0
157
+ while index < length
158
+ hash[columns[index]] = row[index]
159
+ index += 1
160
+ end
161
+
162
+ hash
163
+ }
164
+ end
165
+ end
130
166
  end
131
167
  end
@@ -1,4 +1,6 @@
1
- require 'active_support/per_thread_registry'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/per_thread_registry"
2
4
 
3
5
  module ActiveRecord
4
6
  # This is a thread locals registry for Active Record. For example:
@@ -7,14 +9,14 @@ module ActiveRecord
7
9
  #
8
10
  # returns the connection handler local to the current thread.
9
11
  #
10
- # See the documentation of <tt>ActiveSupport::PerThreadRegistry</tt>
12
+ # See the documentation of ActiveSupport::PerThreadRegistry
11
13
  # for further details.
12
14
  class RuntimeRegistry # :nodoc:
13
15
  extend ActiveSupport::PerThreadRegistry
14
16
 
15
- attr_accessor :connection_handler, :sql_runtime, :connection_id
17
+ attr_accessor :connection_handler, :sql_runtime
16
18
 
17
- [:connection_handler, :sql_runtime, :connection_id].each do |val|
19
+ [:connection_handler, :sql_runtime].each do |val|
18
20
  class_eval %{ def self.#{val}; instance.#{val}; end }, __FILE__, __LINE__
19
21
  class_eval %{ def self.#{val}=(x); instance.#{val}=x; end }, __FILE__, __LINE__
20
22
  end
@@ -1,40 +1,49 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module Sanitization
3
5
  extend ActiveSupport::Concern
4
6
 
5
7
  module ClassMethods
6
- def quote_value(value, column) #:nodoc:
7
- connection.quote(value, column)
8
- end
9
-
10
- # Used to sanitize objects before they're used in an SQL SELECT statement. Delegates to <tt>connection.quote</tt>.
11
- def sanitize(object) #:nodoc:
12
- connection.quote(object)
13
- end
14
-
15
- protected
16
-
17
- # Accepts an array, hash, or string of SQL conditions and sanitizes
8
+ # Accepts an array or string of SQL conditions and sanitizes
18
9
  # them into a valid SQL fragment for a WHERE clause.
19
- # ["name='%s' and group_id='%s'", "foo'bar", 4] returns "name='foo''bar' and group_id='4'"
20
- # { name: "foo'bar", group_id: 4 } returns "name='foo''bar' and group_id='4'"
21
- # "name='foo''bar' and group_id='4'" returns "name='foo''bar' and group_id='4'"
22
- def sanitize_sql_for_conditions(condition, table_name = self.table_name)
10
+ #
11
+ # sanitize_sql_for_conditions(["name=? and group_id=?", "foo'bar", 4])
12
+ # # => "name='foo''bar' and group_id=4"
13
+ #
14
+ # sanitize_sql_for_conditions(["name=:name and group_id=:group_id", name: "foo'bar", group_id: 4])
15
+ # # => "name='foo''bar' and group_id='4'"
16
+ #
17
+ # sanitize_sql_for_conditions(["name='%s' and group_id='%s'", "foo'bar", 4])
18
+ # # => "name='foo''bar' and group_id='4'"
19
+ #
20
+ # sanitize_sql_for_conditions("name='foo''bar' and group_id='4'")
21
+ # # => "name='foo''bar' and group_id='4'"
22
+ def sanitize_sql_for_conditions(condition)
23
23
  return nil if condition.blank?
24
24
 
25
25
  case condition
26
26
  when Array; sanitize_sql_array(condition)
27
- when Hash; sanitize_sql_hash_for_conditions(condition, table_name)
28
27
  else condition
29
28
  end
30
29
  end
31
- alias_method :sanitize_sql, :sanitize_sql_for_conditions
32
- alias_method :sanitize_conditions, :sanitize_sql
30
+ alias :sanitize_sql :sanitize_sql_for_conditions
33
31
 
34
32
  # Accepts an array, hash, or string of SQL conditions and sanitizes
35
33
  # them into a valid SQL fragment for a SET clause.
36
- # { name: nil, group_id: 4 } returns "name = NULL , group_id='4'"
37
- def sanitize_sql_for_assignment(assignments, default_table_name = self.table_name)
34
+ #
35
+ # sanitize_sql_for_assignment(["name=? and group_id=?", nil, 4])
36
+ # # => "name=NULL and group_id=4"
37
+ #
38
+ # sanitize_sql_for_assignment(["name=:name and group_id=:group_id", name: nil, group_id: 4])
39
+ # # => "name=NULL and group_id=4"
40
+ #
41
+ # Post.sanitize_sql_for_assignment({ name: nil, group_id: 4 })
42
+ # # => "`posts`.`name` = NULL, `posts`.`group_id` = 4"
43
+ #
44
+ # sanitize_sql_for_assignment("name=NULL and group_id='4'")
45
+ # # => "name=NULL and group_id='4'"
46
+ def sanitize_sql_for_assignment(assignments, default_table_name = table_name)
38
47
  case assignments
39
48
  when Array; sanitize_sql_array(assignments)
40
49
  when Hash; sanitize_sql_hash_for_assignment(assignments, default_table_name)
@@ -42,76 +51,60 @@ module ActiveRecord
42
51
  end
43
52
  end
44
53
 
45
- # Accepts a hash of SQL conditions and replaces those attributes
46
- # that correspond to a +composed_of+ relationship with their expanded
47
- # aggregate attribute values.
48
- # Given:
49
- # class Person < ActiveRecord::Base
50
- # composed_of :address, class_name: "Address",
51
- # mapping: [%w(address_street street), %w(address_city city)]
52
- # end
53
- # Then:
54
- # { address: Address.new("813 abc st.", "chicago") }
55
- # # => { address_street: "813 abc st.", address_city: "chicago" }
56
- def expand_hash_conditions_for_aggregates(attrs)
57
- expanded_attrs = {}
58
- attrs.each do |attr, value|
59
- if aggregation = reflect_on_aggregation(attr.to_sym)
60
- mapping = aggregation.mapping
61
- mapping.each do |field_attr, aggregate_attr|
62
- if mapping.size == 1 && !value.respond_to?(aggregate_attr)
63
- expanded_attrs[field_attr] = value
64
- else
65
- expanded_attrs[field_attr] = value.send(aggregate_attr)
66
- end
67
- end
68
- else
69
- expanded_attrs[attr] = value
54
+ # Accepts an array, or string of SQL conditions and sanitizes
55
+ # them into a valid SQL fragment for an ORDER clause.
56
+ #
57
+ # sanitize_sql_for_order(["field(id, ?)", [1,3,2]])
58
+ # # => "field(id, 1,3,2)"
59
+ #
60
+ # sanitize_sql_for_order("id ASC")
61
+ # # => "id ASC"
62
+ def sanitize_sql_for_order(condition)
63
+ if condition.is_a?(Array) && condition.first.to_s.include?("?")
64
+ disallow_raw_sql!(
65
+ [condition.first],
66
+ permit: connection.column_name_with_order_matcher
67
+ )
68
+
69
+ # Ensure we aren't dealing with a subclass of String that might
70
+ # override methods we use (eg. Arel::Nodes::SqlLiteral).
71
+ if condition.first.kind_of?(String) && !condition.first.instance_of?(String)
72
+ condition = [String.new(condition.first), *condition[1..-1]]
70
73
  end
71
- end
72
- expanded_attrs
73
- end
74
74
 
75
- # Sanitizes a hash of attribute/value pairs into SQL conditions for a WHERE clause.
76
- # { name: "foo'bar", group_id: 4 }
77
- # # => "name='foo''bar' and group_id= 4"
78
- # { status: nil, group_id: [1,2,3] }
79
- # # => "status IS NULL and group_id IN (1,2,3)"
80
- # { age: 13..18 }
81
- # # => "age BETWEEN 13 AND 18"
82
- # { 'other_records.id' => 7 }
83
- # # => "`other_records`.`id` = 7"
84
- # { other_records: { id: 7 } }
85
- # # => "`other_records`.`id` = 7"
86
- # And for value objects on a composed_of relationship:
87
- # { address: Address.new("123 abc st.", "chicago") }
88
- # # => "address_street='123 abc st.' and address_city='chicago'"
89
- def sanitize_sql_hash_for_conditions(attrs, default_table_name = self.table_name)
90
- ActiveSupport::Deprecation.warn(<<-EOWARN)
91
- sanitize_sql_hash_for_conditions is deprecated, and will be removed in Rails 5.0
92
- EOWARN
93
- attrs = PredicateBuilder.resolve_column_aliases self, attrs
94
- attrs = expand_hash_conditions_for_aggregates(attrs)
95
-
96
- table = Arel::Table.new(table_name, arel_engine).alias(default_table_name)
97
- PredicateBuilder.build_from_hash(self, attrs, table).map { |b|
98
- connection.visitor.compile b
99
- }.join(' AND ')
75
+ Arel.sql(sanitize_sql_array(condition))
76
+ else
77
+ condition
78
+ end
100
79
  end
101
- alias_method :sanitize_sql_hash, :sanitize_sql_hash_for_conditions
102
80
 
103
81
  # Sanitizes a hash of attribute/value pairs into SQL conditions for a SET clause.
104
- # { status: nil, group_id: 1 }
105
- # # => "status = NULL , group_id = 1"
82
+ #
83
+ # sanitize_sql_hash_for_assignment({ status: nil, group_id: 1 }, "posts")
84
+ # # => "`posts`.`status` = NULL, `posts`.`group_id` = 1"
106
85
  def sanitize_sql_hash_for_assignment(attrs, table)
107
86
  c = connection
108
87
  attrs.map do |attr, value|
109
- "#{c.quote_table_name_for_assignment(table, attr)} = #{quote_bound_value(value, c, columns_hash[attr.to_s])}"
110
- end.join(', ')
88
+ type = type_for_attribute(attr)
89
+ value = type.serialize(type.cast(value))
90
+ "#{c.quote_table_name_for_assignment(table, attr)} = #{c.quote(value)}"
91
+ end.join(", ")
111
92
  end
112
93
 
113
94
  # Sanitizes a +string+ so that it is safe to use within an SQL
114
- # LIKE statement. This method uses +escape_character+ to escape all occurrences of "\", "_" and "%"
95
+ # LIKE statement. This method uses +escape_character+ to escape all occurrences of "\", "_" and "%".
96
+ #
97
+ # sanitize_sql_like("100%")
98
+ # # => "100\\%"
99
+ #
100
+ # sanitize_sql_like("snake_cased_string")
101
+ # # => "snake\\_cased\\_string"
102
+ #
103
+ # sanitize_sql_like("100%", "!")
104
+ # # => "100!%"
105
+ #
106
+ # sanitize_sql_like("snake_cased_string", "!")
107
+ # # => "snake!_cased!_string"
115
108
  def sanitize_sql_like(string, escape_character = "\\")
116
109
  pattern = Regexp.union(escape_character, "%", "_")
117
110
  string.gsub(pattern) { |x| [escape_character, x].join }
@@ -119,12 +112,20 @@ sanitize_sql_hash_for_conditions is deprecated, and will be removed in Rails 5.0
119
112
 
120
113
  # Accepts an array of conditions. The array has each value
121
114
  # sanitized and interpolated into the SQL statement.
122
- # ["name='%s' and group_id='%s'", "foo'bar", 4] returns "name='foo''bar' and group_id='4'"
115
+ #
116
+ # sanitize_sql_array(["name=? and group_id=?", "foo'bar", 4])
117
+ # # => "name='foo''bar' and group_id=4"
118
+ #
119
+ # sanitize_sql_array(["name=:name and group_id=:group_id", name: "foo'bar", group_id: 4])
120
+ # # => "name='foo''bar' and group_id=4"
121
+ #
122
+ # sanitize_sql_array(["name='%s' and group_id='%s'", "foo'bar", 4])
123
+ # # => "name='foo''bar' and group_id='4'"
123
124
  def sanitize_sql_array(ary)
124
125
  statement, *values = ary
125
- if values.first.is_a?(Hash) && statement =~ /:\w+/
126
+ if values.first.is_a?(Hash) && /:\w+/.match?(statement)
126
127
  replace_named_bind_variables(statement, values.first)
127
- elsif statement.include?('?')
128
+ elsif statement.include?("?")
128
129
  replace_bind_variables(statement, values)
129
130
  elsif statement.blank?
130
131
  statement
@@ -133,59 +134,81 @@ sanitize_sql_hash_for_conditions is deprecated, and will be removed in Rails 5.0
133
134
  end
134
135
  end
135
136
 
136
- def replace_bind_variables(statement, values) #:nodoc:
137
- raise_if_bind_arity_mismatch(statement, statement.count('?'), values.size)
138
- bound = values.dup
139
- c = connection
140
- statement.gsub(/\?/) do
141
- replace_bind_variable(bound.shift, c)
137
+ def disallow_raw_sql!(args, permit: connection.column_name_matcher) # :nodoc:
138
+ unexpected = nil
139
+ args.each do |arg|
140
+ next if arg.is_a?(Symbol) || Arel.arel_node?(arg) || permit.match?(arg.to_s)
141
+ (unexpected ||= []) << arg
142
142
  end
143
- end
144
143
 
145
- def replace_bind_variable(value, c = connection) #:nodoc:
146
- if ActiveRecord::Relation === value
147
- value.to_sql
144
+ return unless unexpected
145
+
146
+ if allow_unsafe_raw_sql == :deprecated
147
+ ActiveSupport::Deprecation.warn(
148
+ "Dangerous query method (method whose arguments are used as raw " \
149
+ "SQL) called with non-attribute argument(s): " \
150
+ "#{unexpected.map(&:inspect).join(", ")}. Non-attribute " \
151
+ "arguments will be disallowed in Rails 6.1. This method should " \
152
+ "not be called with user-provided values, such as request " \
153
+ "parameters or model attributes. Known-safe values can be passed " \
154
+ "by wrapping them in Arel.sql()."
155
+ )
148
156
  else
149
- quote_bound_value(value, c)
157
+ raise(ActiveRecord::UnknownAttributeReference,
158
+ "Query method called with non-attribute argument(s): " +
159
+ unexpected.map(&:inspect).join(", ")
160
+ )
150
161
  end
151
162
  end
152
163
 
153
- def replace_named_bind_variables(statement, bind_vars) #:nodoc:
154
- statement.gsub(/(:?):([a-zA-Z]\w*)/) do
155
- if $1 == ':' # skip postgresql casts
156
- $& # return the whole match
157
- elsif bind_vars.include?(match = $2.to_sym)
158
- replace_bind_variable(bind_vars[match])
159
- else
160
- raise PreparedStatementInvalid, "missing value for :#{match} in #{statement}"
164
+ private
165
+ def replace_bind_variables(statement, values)
166
+ raise_if_bind_arity_mismatch(statement, statement.count("?"), values.size)
167
+ bound = values.dup
168
+ c = connection
169
+ statement.gsub(/\?/) do
170
+ replace_bind_variable(bound.shift, c)
161
171
  end
162
172
  end
163
- end
164
173
 
165
- def quote_bound_value(value, c = connection, column = nil) #:nodoc:
166
- if column
167
- c.quote(value, column)
168
- elsif value.respond_to?(:map) && !value.acts_like?(:string)
169
- if value.respond_to?(:empty?) && value.empty?
170
- c.quote(nil)
174
+ def replace_bind_variable(value, c = connection)
175
+ if ActiveRecord::Relation === value
176
+ value.to_sql
171
177
  else
172
- value.map { |v| c.quote(v) }.join(',')
178
+ quote_bound_value(value, c)
173
179
  end
174
- else
175
- c.quote(value)
176
180
  end
177
- end
178
181
 
179
- def raise_if_bind_arity_mismatch(statement, expected, provided) #:nodoc:
180
- unless expected == provided
181
- raise PreparedStatementInvalid, "wrong number of bind variables (#{provided} for #{expected}) in: #{statement}"
182
+ def replace_named_bind_variables(statement, bind_vars)
183
+ statement.gsub(/(:?):([a-zA-Z]\w*)/) do |match|
184
+ if $1 == ":" # skip postgresql casts
185
+ match # return the whole match
186
+ elsif bind_vars.include?(match = $2.to_sym)
187
+ replace_bind_variable(bind_vars[match])
188
+ else
189
+ raise PreparedStatementInvalid, "missing value for :#{match} in #{statement}"
190
+ end
191
+ end
182
192
  end
183
- end
184
- end
185
193
 
186
- # TODO: Deprecate this
187
- def quoted_id
188
- self.class.quote_value(id, column_for_attribute(self.class.primary_key))
194
+ def quote_bound_value(value, c = connection)
195
+ if value.respond_to?(:map) && !value.acts_like?(:string)
196
+ quoted = value.map { |v| c.quote(v) }
197
+ if quoted.empty?
198
+ c.quote(nil)
199
+ else
200
+ quoted.join(",")
201
+ end
202
+ else
203
+ c.quote(value)
204
+ end
205
+ end
206
+
207
+ def raise_if_bind_arity_mismatch(statement, expected, provided)
208
+ unless expected == provided
209
+ raise PreparedStatementInvalid, "wrong number of bind variables (#{provided} for #{expected}) in: #{statement}"
210
+ end
211
+ end
189
212
  end
190
213
  end
191
214
  end
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
- # = Active Record Schema
4
+ # = Active Record \Schema
3
5
  #
4
6
  # Allows programmers to programmatically define a schema in a portable
5
7
  # DSL. This means you can define tables, indexes, etc. without using SQL
@@ -27,38 +29,33 @@ module ActiveRecord
27
29
  #
28
30
  # ActiveRecord::Schema is only supported by database adapters that also
29
31
  # support migrations, the two features being very similar.
30
- class Schema < Migration
31
-
32
- # Returns the migrations paths.
33
- #
34
- # ActiveRecord::Schema.new.migrations_paths
35
- # # => ["db/migrate"] # Rails migration path by default.
36
- def migrations_paths
37
- ActiveRecord::Migrator.migrations_paths
38
- end
39
-
40
- def define(info, &block) # :nodoc:
41
- instance_eval(&block)
42
-
43
- unless info[:version].blank?
44
- initialize_schema_migrations_table
45
- connection.assume_migrated_upto_version(info[:version], migrations_paths)
46
- end
47
- end
48
-
32
+ class Schema < Migration::Current
49
33
  # Eval the given block. All methods available to the current connection
50
34
  # adapter are available within the block, so you can easily use the
51
- # database definition DSL to build up your schema (+create_table+,
52
- # +add_index+, etc.).
35
+ # database definition DSL to build up your schema (
36
+ # {create_table}[rdoc-ref:ConnectionAdapters::SchemaStatements#create_table],
37
+ # {add_index}[rdoc-ref:ConnectionAdapters::SchemaStatements#add_index], etc.).
53
38
  #
54
39
  # The +info+ hash is optional, and if given is used to define metadata
55
40
  # about the current schema (currently, only the schema's version):
56
41
  #
57
- # ActiveRecord::Schema.define(version: 20380119000001) do
42
+ # ActiveRecord::Schema.define(version: 2038_01_19_000001) do
58
43
  # ...
59
44
  # end
60
- def self.define(info={}, &block)
45
+ def self.define(info = {}, &block)
61
46
  new.define(info, &block)
62
47
  end
48
+
49
+ def define(info, &block) # :nodoc:
50
+ instance_eval(&block)
51
+
52
+ if info[:version].present?
53
+ connection.schema_migration.create_table
54
+ connection.assume_migrated_upto_version(info[:version])
55
+ end
56
+
57
+ ActiveRecord::InternalMetadata.create_table
58
+ ActiveRecord::InternalMetadata[:environment] = connection.migration_context.current_environment
59
+ end
63
60
  end
64
61
  end