activerecord 4.2.8 → 6.0.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activerecord might be problematic. Click here for more details.

Files changed (372) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +612 -1583
  3. data/MIT-LICENSE +4 -2
  4. data/README.rdoc +13 -12
  5. data/examples/performance.rb +33 -32
  6. data/examples/simple.rb +5 -4
  7. data/lib/active_record.rb +41 -22
  8. data/lib/active_record/aggregations.rb +267 -251
  9. data/lib/active_record/association_relation.rb +11 -6
  10. data/lib/active_record/associations.rb +1737 -1597
  11. data/lib/active_record/associations/alias_tracker.rb +29 -35
  12. data/lib/active_record/associations/association.rb +125 -58
  13. data/lib/active_record/associations/association_scope.rb +103 -132
  14. data/lib/active_record/associations/belongs_to_association.rb +65 -60
  15. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -12
  16. data/lib/active_record/associations/builder/association.rb +27 -40
  17. data/lib/active_record/associations/builder/belongs_to.rb +69 -55
  18. data/lib/active_record/associations/builder/collection_association.rb +10 -33
  19. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +52 -66
  20. data/lib/active_record/associations/builder/has_many.rb +8 -4
  21. data/lib/active_record/associations/builder/has_one.rb +46 -5
  22. data/lib/active_record/associations/builder/singular_association.rb +16 -10
  23. data/lib/active_record/associations/collection_association.rb +134 -286
  24. data/lib/active_record/associations/collection_proxy.rb +241 -146
  25. data/lib/active_record/associations/foreign_association.rb +10 -1
  26. data/lib/active_record/associations/has_many_association.rb +34 -97
  27. data/lib/active_record/associations/has_many_through_association.rb +60 -87
  28. data/lib/active_record/associations/has_one_association.rb +61 -49
  29. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  30. data/lib/active_record/associations/join_dependency.rb +137 -167
  31. data/lib/active_record/associations/join_dependency/join_association.rb +38 -88
  32. data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
  33. data/lib/active_record/associations/join_dependency/join_part.rb +14 -14
  34. data/lib/active_record/associations/preloader.rb +90 -92
  35. data/lib/active_record/associations/preloader/association.rb +90 -123
  36. data/lib/active_record/associations/preloader/through_association.rb +85 -65
  37. data/lib/active_record/associations/singular_association.rb +18 -39
  38. data/lib/active_record/associations/through_association.rb +38 -18
  39. data/lib/active_record/attribute_assignment.rb +56 -183
  40. data/lib/active_record/attribute_decorators.rb +39 -15
  41. data/lib/active_record/attribute_methods.rb +120 -135
  42. data/lib/active_record/attribute_methods/before_type_cast.rb +13 -8
  43. data/lib/active_record/attribute_methods/dirty.rb +174 -144
  44. data/lib/active_record/attribute_methods/primary_key.rb +91 -83
  45. data/lib/active_record/attribute_methods/query.rb +6 -5
  46. data/lib/active_record/attribute_methods/read.rb +20 -76
  47. data/lib/active_record/attribute_methods/serialization.rb +40 -20
  48. data/lib/active_record/attribute_methods/time_zone_conversion.rb +58 -36
  49. data/lib/active_record/attribute_methods/write.rb +32 -54
  50. data/lib/active_record/attributes.rb +214 -82
  51. data/lib/active_record/autosave_association.rb +91 -37
  52. data/lib/active_record/base.rb +57 -45
  53. data/lib/active_record/callbacks.rb +100 -74
  54. data/lib/active_record/coders/json.rb +3 -1
  55. data/lib/active_record/coders/yaml_column.rb +24 -12
  56. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +796 -296
  57. data/lib/active_record/connection_adapters/abstract/database_limits.rb +26 -8
  58. data/lib/active_record/connection_adapters/abstract/database_statements.rb +234 -115
  59. data/lib/active_record/connection_adapters/abstract/query_cache.rb +82 -23
  60. data/lib/active_record/connection_adapters/abstract/quoting.rb +170 -53
  61. data/lib/active_record/connection_adapters/abstract/savepoints.rb +5 -3
  62. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +74 -46
  63. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +356 -227
  64. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +79 -36
  65. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +664 -244
  66. data/lib/active_record/connection_adapters/abstract/transaction.rb +191 -83
  67. data/lib/active_record/connection_adapters/abstract_adapter.rb +460 -204
  68. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +510 -627
  69. data/lib/active_record/connection_adapters/column.rb +56 -43
  70. data/lib/active_record/connection_adapters/connection_specification.rb +174 -152
  71. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +29 -0
  72. data/lib/active_record/connection_adapters/mysql/column.rb +27 -0
  73. data/lib/active_record/connection_adapters/mysql/database_statements.rb +200 -0
  74. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +72 -0
  75. data/lib/active_record/connection_adapters/mysql/quoting.rb +81 -0
  76. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +72 -0
  77. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +95 -0
  78. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +88 -0
  79. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +264 -0
  80. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +31 -0
  81. data/lib/active_record/connection_adapters/mysql2_adapter.rb +58 -188
  82. data/lib/active_record/connection_adapters/postgresql/column.rb +21 -11
  83. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +64 -114
  84. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
  85. data/lib/active_record/connection_adapters/postgresql/oid.rb +23 -25
  86. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +50 -58
  87. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +9 -8
  88. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  89. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +4 -2
  90. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +5 -1
  91. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +13 -1
  92. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +9 -22
  93. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  94. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +5 -3
  95. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +31 -19
  96. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  97. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
  98. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +45 -0
  99. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -9
  100. data/lib/active_record/connection_adapters/postgresql/oid/{integer.rb → oid.rb} +6 -2
  101. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +33 -11
  102. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +52 -34
  103. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -5
  104. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +58 -54
  105. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +10 -5
  106. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +3 -1
  107. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +3 -1
  108. data/lib/active_record/connection_adapters/postgresql/quoting.rb +144 -47
  109. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +27 -14
  110. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -0
  111. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +178 -108
  112. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +50 -0
  113. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +470 -290
  114. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +36 -0
  115. data/lib/active_record/connection_adapters/postgresql/utils.rb +12 -8
  116. data/lib/active_record/connection_adapters/postgresql_adapter.rb +551 -356
  117. data/lib/active_record/connection_adapters/schema_cache.rb +72 -25
  118. data/lib/active_record/connection_adapters/sql_type_metadata.rb +37 -0
  119. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +118 -0
  120. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +21 -0
  121. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +103 -0
  122. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +17 -0
  123. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
  124. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
  125. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +137 -0
  126. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +290 -345
  127. data/lib/active_record/connection_adapters/statement_pool.rb +34 -13
  128. data/lib/active_record/connection_handling.rb +176 -41
  129. data/lib/active_record/core.rb +251 -231
  130. data/lib/active_record/counter_cache.rb +67 -49
  131. data/lib/active_record/database_configurations.rb +233 -0
  132. data/lib/active_record/database_configurations/database_config.rb +37 -0
  133. data/lib/active_record/database_configurations/hash_config.rb +50 -0
  134. data/lib/active_record/database_configurations/url_config.rb +79 -0
  135. data/lib/active_record/define_callbacks.rb +22 -0
  136. data/lib/active_record/dynamic_matchers.rb +87 -105
  137. data/lib/active_record/enum.rb +163 -86
  138. data/lib/active_record/errors.rb +188 -53
  139. data/lib/active_record/explain.rb +23 -11
  140. data/lib/active_record/explain_registry.rb +4 -2
  141. data/lib/active_record/explain_subscriber.rb +10 -5
  142. data/lib/active_record/fixture_set/file.rb +35 -9
  143. data/lib/active_record/fixture_set/model_metadata.rb +33 -0
  144. data/lib/active_record/fixture_set/render_context.rb +17 -0
  145. data/lib/active_record/fixture_set/table_row.rb +153 -0
  146. data/lib/active_record/fixture_set/table_rows.rb +47 -0
  147. data/lib/active_record/fixtures.rb +228 -499
  148. data/lib/active_record/gem_version.rb +5 -3
  149. data/lib/active_record/inheritance.rb +158 -112
  150. data/lib/active_record/insert_all.rb +179 -0
  151. data/lib/active_record/integration.rb +123 -29
  152. data/lib/active_record/internal_metadata.rb +53 -0
  153. data/lib/active_record/legacy_yaml_adapter.rb +21 -3
  154. data/lib/active_record/locale/en.yml +3 -2
  155. data/lib/active_record/locking/optimistic.rb +87 -96
  156. data/lib/active_record/locking/pessimistic.rb +18 -6
  157. data/lib/active_record/log_subscriber.rb +76 -33
  158. data/lib/active_record/middleware/database_selector.rb +75 -0
  159. data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
  160. data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
  161. data/lib/active_record/migration.rb +626 -283
  162. data/lib/active_record/migration/command_recorder.rb +177 -90
  163. data/lib/active_record/migration/compatibility.rb +244 -0
  164. data/lib/active_record/migration/join_table.rb +8 -6
  165. data/lib/active_record/model_schema.rb +314 -112
  166. data/lib/active_record/nested_attributes.rb +264 -222
  167. data/lib/active_record/no_touching.rb +14 -1
  168. data/lib/active_record/null_relation.rb +24 -37
  169. data/lib/active_record/persistence.rb +557 -125
  170. data/lib/active_record/query_cache.rb +19 -23
  171. data/lib/active_record/querying.rb +43 -29
  172. data/lib/active_record/railtie.rb +147 -46
  173. data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
  174. data/lib/active_record/railties/console_sandbox.rb +2 -0
  175. data/lib/active_record/railties/controller_runtime.rb +34 -33
  176. data/lib/active_record/railties/databases.rake +330 -197
  177. data/lib/active_record/readonly_attributes.rb +5 -4
  178. data/lib/active_record/reflection.rb +428 -279
  179. data/lib/active_record/relation.rb +518 -341
  180. data/lib/active_record/relation/batches.rb +207 -55
  181. data/lib/active_record/relation/batches/batch_enumerator.rb +69 -0
  182. data/lib/active_record/relation/calculations.rb +267 -253
  183. data/lib/active_record/relation/delegation.rb +70 -80
  184. data/lib/active_record/relation/finder_methods.rb +277 -241
  185. data/lib/active_record/relation/from_clause.rb +26 -0
  186. data/lib/active_record/relation/merger.rb +78 -87
  187. data/lib/active_record/relation/predicate_builder.rb +114 -119
  188. data/lib/active_record/relation/predicate_builder/array_handler.rb +27 -26
  189. data/lib/active_record/relation/predicate_builder/association_query_value.rb +43 -0
  190. data/lib/active_record/relation/predicate_builder/base_handler.rb +18 -0
  191. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +19 -0
  192. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +53 -0
  193. data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -0
  194. data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
  195. data/lib/active_record/relation/query_attribute.rb +50 -0
  196. data/lib/active_record/relation/query_methods.rb +575 -394
  197. data/lib/active_record/relation/record_fetch_warning.rb +51 -0
  198. data/lib/active_record/relation/spawn_methods.rb +11 -13
  199. data/lib/active_record/relation/where_clause.rb +190 -0
  200. data/lib/active_record/relation/where_clause_factory.rb +33 -0
  201. data/lib/active_record/result.rb +79 -42
  202. data/lib/active_record/runtime_registry.rb +6 -4
  203. data/lib/active_record/sanitization.rb +144 -121
  204. data/lib/active_record/schema.rb +21 -24
  205. data/lib/active_record/schema_dumper.rb +112 -93
  206. data/lib/active_record/schema_migration.rb +24 -17
  207. data/lib/active_record/scoping.rb +45 -26
  208. data/lib/active_record/scoping/default.rb +101 -85
  209. data/lib/active_record/scoping/named.rb +86 -33
  210. data/lib/active_record/secure_token.rb +40 -0
  211. data/lib/active_record/serialization.rb +5 -5
  212. data/lib/active_record/statement_cache.rb +73 -36
  213. data/lib/active_record/store.rb +127 -42
  214. data/lib/active_record/suppressor.rb +61 -0
  215. data/lib/active_record/table_metadata.rb +75 -0
  216. data/lib/active_record/tasks/database_tasks.rb +308 -99
  217. data/lib/active_record/tasks/mysql_database_tasks.rb +55 -99
  218. data/lib/active_record/tasks/postgresql_database_tasks.rb +81 -41
  219. data/lib/active_record/tasks/sqlite_database_tasks.rb +38 -16
  220. data/lib/active_record/test_databases.rb +23 -0
  221. data/lib/active_record/test_fixtures.rb +224 -0
  222. data/lib/active_record/timestamp.rb +86 -40
  223. data/lib/active_record/touch_later.rb +66 -0
  224. data/lib/active_record/transactions.rb +216 -150
  225. data/lib/active_record/translation.rb +3 -1
  226. data/lib/active_record/type.rb +78 -23
  227. data/lib/active_record/type/adapter_specific_registry.rb +129 -0
  228. data/lib/active_record/type/date.rb +4 -45
  229. data/lib/active_record/type/date_time.rb +4 -49
  230. data/lib/active_record/type/decimal_without_scale.rb +6 -2
  231. data/lib/active_record/type/hash_lookup_type_map.rb +5 -3
  232. data/lib/active_record/type/internal/timezone.rb +17 -0
  233. data/lib/active_record/type/json.rb +30 -0
  234. data/lib/active_record/type/serialized.rb +24 -15
  235. data/lib/active_record/type/text.rb +2 -2
  236. data/lib/active_record/type/time.rb +11 -16
  237. data/lib/active_record/type/type_map.rb +15 -17
  238. data/lib/active_record/type/unsigned_integer.rb +9 -7
  239. data/lib/active_record/type_caster.rb +9 -0
  240. data/lib/active_record/type_caster/connection.rb +34 -0
  241. data/lib/active_record/type_caster/map.rb +20 -0
  242. data/lib/active_record/validations.rb +39 -35
  243. data/lib/active_record/validations/absence.rb +25 -0
  244. data/lib/active_record/validations/associated.rb +13 -4
  245. data/lib/active_record/validations/length.rb +26 -0
  246. data/lib/active_record/validations/presence.rb +14 -13
  247. data/lib/active_record/validations/uniqueness.rb +42 -55
  248. data/lib/active_record/version.rb +3 -1
  249. data/lib/arel.rb +51 -0
  250. data/lib/arel/alias_predication.rb +9 -0
  251. data/lib/arel/attributes.rb +22 -0
  252. data/lib/arel/attributes/attribute.rb +37 -0
  253. data/lib/arel/collectors/bind.rb +24 -0
  254. data/lib/arel/collectors/composite.rb +31 -0
  255. data/lib/arel/collectors/plain_string.rb +20 -0
  256. data/lib/arel/collectors/sql_string.rb +20 -0
  257. data/lib/arel/collectors/substitute_binds.rb +28 -0
  258. data/lib/arel/crud.rb +42 -0
  259. data/lib/arel/delete_manager.rb +18 -0
  260. data/lib/arel/errors.rb +9 -0
  261. data/lib/arel/expressions.rb +29 -0
  262. data/lib/arel/factory_methods.rb +49 -0
  263. data/lib/arel/insert_manager.rb +49 -0
  264. data/lib/arel/math.rb +45 -0
  265. data/lib/arel/nodes.rb +68 -0
  266. data/lib/arel/nodes/and.rb +32 -0
  267. data/lib/arel/nodes/ascending.rb +23 -0
  268. data/lib/arel/nodes/binary.rb +52 -0
  269. data/lib/arel/nodes/bind_param.rb +36 -0
  270. data/lib/arel/nodes/case.rb +55 -0
  271. data/lib/arel/nodes/casted.rb +50 -0
  272. data/lib/arel/nodes/comment.rb +29 -0
  273. data/lib/arel/nodes/count.rb +12 -0
  274. data/lib/arel/nodes/delete_statement.rb +45 -0
  275. data/lib/arel/nodes/descending.rb +23 -0
  276. data/lib/arel/nodes/equality.rb +18 -0
  277. data/lib/arel/nodes/extract.rb +24 -0
  278. data/lib/arel/nodes/false.rb +16 -0
  279. data/lib/arel/nodes/full_outer_join.rb +8 -0
  280. data/lib/arel/nodes/function.rb +44 -0
  281. data/lib/arel/nodes/grouping.rb +8 -0
  282. data/lib/arel/nodes/in.rb +8 -0
  283. data/lib/arel/nodes/infix_operation.rb +80 -0
  284. data/lib/arel/nodes/inner_join.rb +8 -0
  285. data/lib/arel/nodes/insert_statement.rb +37 -0
  286. data/lib/arel/nodes/join_source.rb +20 -0
  287. data/lib/arel/nodes/matches.rb +18 -0
  288. data/lib/arel/nodes/named_function.rb +23 -0
  289. data/lib/arel/nodes/node.rb +50 -0
  290. data/lib/arel/nodes/node_expression.rb +13 -0
  291. data/lib/arel/nodes/outer_join.rb +8 -0
  292. data/lib/arel/nodes/over.rb +15 -0
  293. data/lib/arel/nodes/regexp.rb +16 -0
  294. data/lib/arel/nodes/right_outer_join.rb +8 -0
  295. data/lib/arel/nodes/select_core.rb +67 -0
  296. data/lib/arel/nodes/select_statement.rb +41 -0
  297. data/lib/arel/nodes/sql_literal.rb +16 -0
  298. data/lib/arel/nodes/string_join.rb +11 -0
  299. data/lib/arel/nodes/table_alias.rb +27 -0
  300. data/lib/arel/nodes/terminal.rb +16 -0
  301. data/lib/arel/nodes/true.rb +16 -0
  302. data/lib/arel/nodes/unary.rb +45 -0
  303. data/lib/arel/nodes/unary_operation.rb +20 -0
  304. data/lib/arel/nodes/unqualified_column.rb +22 -0
  305. data/lib/arel/nodes/update_statement.rb +41 -0
  306. data/lib/arel/nodes/values_list.rb +9 -0
  307. data/lib/arel/nodes/window.rb +126 -0
  308. data/lib/arel/nodes/with.rb +11 -0
  309. data/lib/arel/order_predications.rb +13 -0
  310. data/lib/arel/predications.rb +257 -0
  311. data/lib/arel/select_manager.rb +271 -0
  312. data/lib/arel/table.rb +110 -0
  313. data/lib/arel/tree_manager.rb +72 -0
  314. data/lib/arel/update_manager.rb +34 -0
  315. data/lib/arel/visitors.rb +20 -0
  316. data/lib/arel/visitors/depth_first.rb +204 -0
  317. data/lib/arel/visitors/dot.rb +297 -0
  318. data/lib/arel/visitors/ibm_db.rb +34 -0
  319. data/lib/arel/visitors/informix.rb +62 -0
  320. data/lib/arel/visitors/mssql.rb +157 -0
  321. data/lib/arel/visitors/mysql.rb +83 -0
  322. data/lib/arel/visitors/oracle.rb +159 -0
  323. data/lib/arel/visitors/oracle12.rb +66 -0
  324. data/lib/arel/visitors/postgresql.rb +110 -0
  325. data/lib/arel/visitors/sqlite.rb +39 -0
  326. data/lib/arel/visitors/to_sql.rb +889 -0
  327. data/lib/arel/visitors/visitor.rb +46 -0
  328. data/lib/arel/visitors/where_sql.rb +23 -0
  329. data/lib/arel/window_predications.rb +9 -0
  330. data/lib/rails/generators/active_record.rb +7 -5
  331. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
  332. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +5 -0
  333. data/lib/rails/generators/active_record/migration.rb +31 -1
  334. data/lib/rails/generators/active_record/migration/migration_generator.rb +42 -37
  335. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +24 -0
  336. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +11 -2
  337. data/lib/rails/generators/active_record/model/model_generator.rb +19 -22
  338. data/lib/rails/generators/active_record/model/templates/model.rb.tt +22 -0
  339. data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
  340. metadata +164 -60
  341. data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
  342. data/lib/active_record/associations/preloader/collection_association.rb +0 -24
  343. data/lib/active_record/associations/preloader/has_many.rb +0 -17
  344. data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
  345. data/lib/active_record/associations/preloader/has_one.rb +0 -23
  346. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  347. data/lib/active_record/associations/preloader/singular_association.rb +0 -21
  348. data/lib/active_record/attribute.rb +0 -163
  349. data/lib/active_record/attribute_set.rb +0 -81
  350. data/lib/active_record/attribute_set/builder.rb +0 -106
  351. data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -491
  352. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
  353. data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
  354. data/lib/active_record/connection_adapters/postgresql/oid/infinity.rb +0 -13
  355. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -35
  356. data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
  357. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  358. data/lib/active_record/serializers/xml_serializer.rb +0 -193
  359. data/lib/active_record/type/big_integer.rb +0 -13
  360. data/lib/active_record/type/binary.rb +0 -50
  361. data/lib/active_record/type/boolean.rb +0 -31
  362. data/lib/active_record/type/decimal.rb +0 -58
  363. data/lib/active_record/type/decorator.rb +0 -14
  364. data/lib/active_record/type/float.rb +0 -19
  365. data/lib/active_record/type/integer.rb +0 -59
  366. data/lib/active_record/type/mutable.rb +0 -16
  367. data/lib/active_record/type/numeric.rb +0 -36
  368. data/lib/active_record/type/string.rb +0 -40
  369. data/lib/active_record/type/time_value.rb +0 -38
  370. data/lib/active_record/type/value.rb +0 -110
  371. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +0 -19
  372. data/lib/rails/generators/active_record/model/templates/model.rb +0 -10
@@ -1,26 +1,31 @@
1
- require 'active_record/connection_adapters/abstract_mysql_adapter'
1
+ # frozen_string_literal: true
2
2
 
3
- gem 'mysql2', '>= 0.3.13', '< 0.5'
4
- require 'mysql2'
3
+ require "active_record/connection_adapters/abstract_mysql_adapter"
4
+ require "active_record/connection_adapters/mysql/database_statements"
5
+
6
+ gem "mysql2", ">= 0.4.4"
7
+ require "mysql2"
5
8
 
6
9
  module ActiveRecord
7
10
  module ConnectionHandling # :nodoc:
11
+ ER_BAD_DB_ERROR = 1049
12
+
8
13
  # Establishes a connection to the database that's used by all Active Record objects.
9
14
  def mysql2_connection(config)
10
15
  config = config.symbolize_keys
16
+ config[:flags] ||= 0
11
17
 
12
- config[:username] = 'root' if config[:username].nil?
13
-
14
- if Mysql2::Client.const_defined? :FOUND_ROWS
15
- config[:flags] = Mysql2::Client::FOUND_ROWS
18
+ if config[:flags].kind_of? Array
19
+ config[:flags].push "FOUND_ROWS"
20
+ else
21
+ config[:flags] |= Mysql2::Client::FOUND_ROWS
16
22
  end
17
23
 
18
24
  client = Mysql2::Client.new(config)
19
- options = [config[:host], config[:username], config[:password], config[:database], config[:port], config[:socket], 0]
20
- ConnectionAdapters::Mysql2Adapter.new(client, logger, options, config)
25
+ ConnectionAdapters::Mysql2Adapter.new(client, logger, nil, config)
21
26
  rescue Mysql2::Error => error
22
- if error.message.include?("Unknown database")
23
- raise ActiveRecord::NoDatabaseError.new(error.message, error)
27
+ if error.error_number == ER_BAD_DB_ERROR
28
+ raise ActiveRecord::NoDatabaseError
24
29
  else
25
30
  raise
26
31
  end
@@ -29,24 +34,39 @@ module ActiveRecord
29
34
 
30
35
  module ConnectionAdapters
31
36
  class Mysql2Adapter < AbstractMysqlAdapter
32
- ADAPTER_NAME = 'Mysql2'.freeze
37
+ ADAPTER_NAME = "Mysql2"
38
+
39
+ include MySQL::DatabaseStatements
33
40
 
34
41
  def initialize(connection, logger, connection_options, config)
35
- super
36
- @prepared_statements = false
42
+ superclass_config = config.reverse_merge(prepared_statements: false)
43
+ super(connection, logger, connection_options, superclass_config)
37
44
  configure_connection
38
45
  end
39
46
 
40
- MAX_INDEX_LENGTH_FOR_UTF8MB4 = 191
41
- def initialize_schema_migrations_table
42
- if charset == 'utf8mb4'
43
- ActiveRecord::SchemaMigration.create_table(MAX_INDEX_LENGTH_FOR_UTF8MB4)
44
- else
45
- ActiveRecord::SchemaMigration.create_table
46
- end
47
+ def self.database_exists?(config)
48
+ !!ActiveRecord::Base.mysql2_connection(config)
49
+ rescue ActiveRecord::NoDatabaseError
50
+ false
51
+ end
52
+
53
+ def supports_json?
54
+ !mariadb? && database_version >= "5.7.8"
55
+ end
56
+
57
+ def supports_comments?
58
+ true
59
+ end
60
+
61
+ def supports_comments_in_create?
62
+ true
63
+ end
64
+
65
+ def supports_savepoints?
66
+ true
47
67
  end
48
68
 
49
- def supports_explain?
69
+ def supports_lazy_transactions?
50
70
  true
51
71
  end
52
72
 
@@ -54,7 +74,7 @@ module ActiveRecord
54
74
 
55
75
  def each_hash(result) # :nodoc:
56
76
  if block_given?
57
- result.each(:as => :hash, :symbolize_keys => true) do |row|
77
+ result.each(as: :hash, symbolize_keys: true) do |row|
58
78
  yield row
59
79
  end
60
80
  else
@@ -74,14 +94,6 @@ module ActiveRecord
74
94
  @connection.escape(string)
75
95
  end
76
96
 
77
- def quoted_date(value)
78
- if supports_datetime_with_precision? && value.acts_like?(:time) && value.respond_to?(:usec)
79
- "#{super}.#{sprintf("%06d", value.usec)}"
80
- else
81
- super
82
- end
83
- end
84
-
85
97
  #--
86
98
  # CONNECTION MANAGEMENT ====================================
87
99
  #++
@@ -104,173 +116,31 @@ module ActiveRecord
104
116
  @connection.close
105
117
  end
106
118
 
107
- #--
108
- # DATABASE STATEMENTS ======================================
109
- #++
110
-
111
- def explain(arel, binds = [])
112
- sql = "EXPLAIN #{to_sql(arel, binds.dup)}"
113
- start = Time.now
114
- result = exec_query(sql, 'EXPLAIN', binds)
115
- elapsed = Time.now - start
116
-
117
- ExplainPrettyPrinter.new.pp(result, elapsed)
119
+ def discard! # :nodoc:
120
+ super
121
+ @connection.automatic_close = false
122
+ @connection = nil
118
123
  end
119
124
 
120
- class ExplainPrettyPrinter # :nodoc:
121
- # Pretty prints the result of a EXPLAIN in a way that resembles the output of the
122
- # MySQL shell:
123
- #
124
- # +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+
125
- # | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
126
- # +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+
127
- # | 1 | SIMPLE | users | const | PRIMARY | PRIMARY | 4 | const | 1 | |
128
- # | 1 | SIMPLE | posts | ALL | NULL | NULL | NULL | NULL | 1 | Using where |
129
- # +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+
130
- # 2 rows in set (0.00 sec)
131
- #
132
- # This is an exercise in Ruby hyperrealism :).
133
- def pp(result, elapsed)
134
- widths = compute_column_widths(result)
135
- separator = build_separator(widths)
136
-
137
- pp = []
138
-
139
- pp << separator
140
- pp << build_cells(result.columns, widths)
141
- pp << separator
142
-
143
- result.rows.each do |row|
144
- pp << build_cells(row, widths)
145
- end
146
-
147
- pp << separator
148
- pp << build_footer(result.rows.length, elapsed)
149
-
150
- pp.join("\n") + "\n"
151
- end
152
-
153
- private
125
+ private
154
126
 
155
- def compute_column_widths(result)
156
- [].tap do |widths|
157
- result.columns.each_with_index do |column, i|
158
- cells_in_column = [column] + result.rows.map {|r| r[i].nil? ? 'NULL' : r[i].to_s}
159
- widths << cells_in_column.map(&:length).max
160
- end
161
- end
127
+ def connect
128
+ @connection = Mysql2::Client.new(@config)
129
+ configure_connection
162
130
  end
163
131
 
164
- def build_separator(widths)
165
- padding = 1
166
- '+' + widths.map {|w| '-' * (w + (padding*2))}.join('+') + '+'
132
+ def configure_connection
133
+ @connection.query_options[:as] = :array
134
+ super
167
135
  end
168
136
 
169
- def build_cells(items, widths)
170
- cells = []
171
- items.each_with_index do |item, i|
172
- item = 'NULL' if item.nil?
173
- justifier = item.is_a?(Numeric) ? 'rjust' : 'ljust'
174
- cells << item.to_s.send(justifier, widths[i])
175
- end
176
- '| ' + cells.join(' | ') + ' |'
137
+ def full_version
138
+ schema_cache.database_version.full_version_string
177
139
  end
178
140
 
179
- def build_footer(nrows, elapsed)
180
- rows_label = nrows == 1 ? 'row' : 'rows'
181
- "#{nrows} #{rows_label} in set (%.2f sec)" % elapsed
141
+ def get_full_version
142
+ @connection.server_info[:version]
182
143
  end
183
- end
184
-
185
- # FIXME: re-enable the following once a "better" query_cache solution is in core
186
- #
187
- # The overrides below perform much better than the originals in AbstractAdapter
188
- # because we're able to take advantage of mysql2's lazy-loading capabilities
189
- #
190
- # # Returns a record hash with the column names as keys and column values
191
- # # as values.
192
- # def select_one(sql, name = nil)
193
- # result = execute(sql, name)
194
- # result.each(as: :hash) do |r|
195
- # return r
196
- # end
197
- # end
198
- #
199
- # # Returns a single value from a record
200
- # def select_value(sql, name = nil)
201
- # result = execute(sql, name)
202
- # if first = result.first
203
- # first.first
204
- # end
205
- # end
206
- #
207
- # # Returns an array of the values of the first column in a select:
208
- # # select_values("SELECT id FROM companies LIMIT 3") => [1,2,3]
209
- # def select_values(sql, name = nil)
210
- # execute(sql, name).map { |row| row.first }
211
- # end
212
-
213
- # Returns an array of arrays containing the field values.
214
- # Order is the same as that returned by +columns+.
215
- def select_rows(sql, name = nil, binds = [])
216
- execute(sql, name).to_a
217
- end
218
-
219
- # Executes the SQL statement in the context of this connection.
220
- def execute(sql, name = nil)
221
- # make sure we carry over any changes to ActiveRecord::Base.default_timezone that have been
222
- # made since we established the connection
223
- @connection.query_options[:database_timezone] = ActiveRecord::Base.default_timezone
224
-
225
- super
226
- end
227
-
228
- def exec_query(sql, name = 'SQL', binds = [])
229
- result = execute(sql, name)
230
- ActiveRecord::Result.new(result.fields, result.to_a)
231
- end
232
-
233
- alias exec_without_stmt exec_query
234
-
235
- def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
236
- super
237
- id_value || @connection.last_id
238
- end
239
- alias :create :insert_sql
240
-
241
- def exec_insert(sql, name, binds, pk = nil, sequence_name = nil)
242
- execute to_sql(sql, binds), name
243
- end
244
-
245
- def exec_delete(sql, name, binds)
246
- execute to_sql(sql, binds), name
247
- @connection.affected_rows
248
- end
249
- alias :exec_update :exec_delete
250
-
251
- def last_inserted_id(result)
252
- @connection.last_id
253
- end
254
-
255
- private
256
-
257
- def connect
258
- @connection = Mysql2::Client.new(@config)
259
- configure_connection
260
- end
261
-
262
- def configure_connection
263
- @connection.query_options.merge!(:as => :array)
264
- super
265
- end
266
-
267
- def full_version
268
- @full_version ||= @connection.server_info[:version]
269
- end
270
-
271
- def set_field_encoding field_name
272
- field_name
273
- end
274
144
  end
275
145
  end
276
146
  end
@@ -1,20 +1,30 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
- # PostgreSQL-specific extensions to column definitions in a table.
4
- class PostgreSQLColumn < Column #:nodoc:
5
- attr_accessor :array
5
+ module PostgreSQL
6
+ class Column < ConnectionAdapters::Column # :nodoc:
7
+ delegate :oid, :fmod, to: :sql_type_metadata
8
+
9
+ def initialize(*, serial: nil, **)
10
+ super
11
+ @serial = serial
12
+ end
6
13
 
7
- def initialize(name, default, cast_type, sql_type = nil, null = true, default_function = nil)
8
- if sql_type =~ /\[\]$/
9
- @array = true
10
- super(name, default, cast_type, sql_type[0..sql_type.length - 3], null)
11
- else
12
- @array = false
13
- super(name, default, cast_type, sql_type, null)
14
+ def serial?
15
+ @serial
14
16
  end
15
17
 
16
- @default_function = default_function
18
+ def array
19
+ sql_type_metadata.sql_type.end_with?("[]")
20
+ end
21
+ alias :array? :array
22
+
23
+ def sql_type
24
+ super.sub(/\[\]\z/, "")
25
+ end
17
26
  end
18
27
  end
28
+ PostgreSQLColumn = PostgreSQL::Column # :nodoc:
19
29
  end
20
30
  end
@@ -1,97 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module ConnectionAdapters
3
5
  module PostgreSQL
4
6
  module DatabaseStatements
5
7
  def explain(arel, binds = [])
6
8
  sql = "EXPLAIN #{to_sql(arel, binds)}"
7
- ExplainPrettyPrinter.new.pp(exec_query(sql, 'EXPLAIN', binds))
8
- end
9
-
10
- class ExplainPrettyPrinter # :nodoc:
11
- # Pretty prints the result of a EXPLAIN in a way that resembles the output of the
12
- # PostgreSQL shell:
13
- #
14
- # QUERY PLAN
15
- # ------------------------------------------------------------------------------
16
- # Nested Loop Left Join (cost=0.00..37.24 rows=8 width=0)
17
- # Join Filter: (posts.user_id = users.id)
18
- # -> Index Scan using users_pkey on users (cost=0.00..8.27 rows=1 width=4)
19
- # Index Cond: (id = 1)
20
- # -> Seq Scan on posts (cost=0.00..28.88 rows=8 width=4)
21
- # Filter: (posts.user_id = 1)
22
- # (6 rows)
23
- #
24
- def pp(result)
25
- header = result.columns.first
26
- lines = result.rows.map(&:first)
27
-
28
- # We add 2 because there's one char of padding at both sides, note
29
- # the extra hyphens in the example above.
30
- width = [header, *lines].map(&:length).max + 2
31
-
32
- pp = []
33
-
34
- pp << header.center(width).rstrip
35
- pp << '-' * width
36
-
37
- pp += lines.map {|line| " #{line}"}
38
-
39
- nrows = result.rows.length
40
- rows_label = nrows == 1 ? 'row' : 'rows'
41
- pp << "(#{nrows} #{rows_label})"
42
-
43
- pp.join("\n") + "\n"
44
- end
45
- end
46
-
47
- def select_value(arel, name = nil, binds = [])
48
- arel, binds = binds_from_relation arel, binds
49
- sql = to_sql(arel, binds)
50
- execute_and_clear(sql, name, binds) do |result|
51
- result.getvalue(0, 0) if result.ntuples > 0 && result.nfields > 0
52
- end
53
- end
54
-
55
- def select_values(arel, name = nil)
56
- arel, binds = binds_from_relation arel, []
57
- sql = to_sql(arel, binds)
58
- execute_and_clear(sql, name, binds) do |result|
59
- if result.nfields > 0
60
- result.column_values(0)
61
- else
62
- []
63
- end
64
- end
65
- end
66
-
67
- # Executes a SELECT query and returns an array of rows. Each row is an
68
- # array of field values.
69
- def select_rows(sql, name = nil, binds = [])
70
- execute_and_clear(sql, name, binds) do |result|
71
- result.values
72
- end
73
- end
74
-
75
- # Executes an INSERT query and returns the new record's ID
76
- def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
77
- unless pk
78
- # Extract the table from the insert sql. Yuck.
79
- table_ref = extract_table_ref_from_insert_sql(sql)
80
- pk = primary_key(table_ref) if table_ref
81
- end
82
-
83
- if pk && use_insert_returning?
84
- select_value("#{sql} RETURNING #{quote_column_name(pk)}")
85
- elsif pk
86
- super
87
- last_insert_id_value(sequence_name || default_sequence_name(table_ref, pk))
88
- else
89
- super
90
- end
91
- end
92
-
93
- def create
94
- super.insert
9
+ PostgreSQL::ExplainPrettyPrinter.new.pp(exec_query(sql, "EXPLAIN", binds))
95
10
  end
96
11
 
97
12
  # The internal PostgreSQL identifier of the money data type.
@@ -133,9 +48,9 @@ module ActiveRecord
133
48
  # (2) $12.345.678,12
134
49
  case data
135
50
  when /^-?\D+[\d,]+\.\d{2}$/ # (1)
136
- data.gsub!(/[^-\d.]/, '')
51
+ data.gsub!(/[^-\d.]/, "")
137
52
  when /^-?\D+[\d.]+,\d{2}$/ # (2)
138
- data.gsub!(/[^-\d,]/, '').sub!(/,/, '.')
53
+ data.gsub!(/[^-\d,]/, "").sub!(/,/, ".")
139
54
  end
140
55
  end
141
56
  end
@@ -143,21 +58,42 @@ module ActiveRecord
143
58
 
144
59
  # Queries the database and returns the results in an Array-like object
145
60
  def query(sql, name = nil) #:nodoc:
61
+ materialize_transactions
62
+
146
63
  log(sql, name) do
147
- result_as_array @connection.async_exec(sql)
64
+ ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
65
+ result_as_array @connection.async_exec(sql)
66
+ end
148
67
  end
149
68
  end
150
69
 
151
- # Executes an SQL statement, returning a PGresult object on success
152
- # or raising a PGError exception otherwise.
70
+ READ_QUERY = ActiveRecord::ConnectionAdapters::AbstractAdapter.build_read_query_regexp(:begin, :commit, :explain, :select, :set, :show, :release, :savepoint, :rollback) # :nodoc:
71
+ private_constant :READ_QUERY
72
+
73
+ def write_query?(sql) # :nodoc:
74
+ !READ_QUERY.match?(sql)
75
+ end
76
+
77
+ # Executes an SQL statement, returning a PG::Result object on success
78
+ # or raising a PG::Error exception otherwise.
79
+ # Note: the PG::Result object is manually memory managed; if you don't
80
+ # need it specifically, you may want consider the <tt>exec_query</tt> wrapper.
153
81
  def execute(sql, name = nil)
82
+ if preventing_writes? && write_query?(sql)
83
+ raise ActiveRecord::ReadOnlyError, "Write query attempted while in readonly mode: #{sql}"
84
+ end
85
+
86
+ materialize_transactions
87
+
154
88
  log(sql, name) do
155
- @connection.async_exec(sql)
89
+ ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
90
+ @connection.async_exec(sql)
91
+ end
156
92
  end
157
93
  end
158
94
 
159
- def exec_query(sql, name = 'SQL', binds = [])
160
- execute_and_clear(sql, name, binds) do |result|
95
+ def exec_query(sql, name = "SQL", binds = [], prepare: false)
96
+ execute_and_clear(sql, name, binds, prepare: prepare) do |result|
161
97
  types = {}
162
98
  fields = result.fields
163
99
  fields.each_with_index do |fname, i|
@@ -169,44 +105,44 @@ module ActiveRecord
169
105
  end
170
106
  end
171
107
 
172
- def exec_delete(sql, name = 'SQL', binds = [])
173
- execute_and_clear(sql, name, binds) {|result| result.cmd_tuples }
108
+ def exec_delete(sql, name = nil, binds = [])
109
+ execute_and_clear(sql, name, binds) { |result| result.cmd_tuples }
174
110
  end
175
111
  alias :exec_update :exec_delete
176
112
 
177
- def sql_for_insert(sql, pk, id_value, sequence_name, binds)
178
- unless pk
113
+ def sql_for_insert(sql, pk, binds) # :nodoc:
114
+ if pk.nil?
179
115
  # Extract the table from the insert sql. Yuck.
180
116
  table_ref = extract_table_ref_from_insert_sql(sql)
181
117
  pk = primary_key(table_ref) if table_ref
182
118
  end
183
119
 
184
- if pk && use_insert_returning?
120
+ if pk = suppress_composite_primary_key(pk)
185
121
  sql = "#{sql} RETURNING #{quote_column_name(pk)}"
186
122
  end
187
123
 
188
- [sql, binds]
124
+ super
189
125
  end
126
+ private :sql_for_insert
190
127
 
191
- def exec_insert(sql, name, binds, pk = nil, sequence_name = nil)
192
- val = exec_query(sql, name, binds)
193
- if !use_insert_returning? && pk
128
+ def exec_insert(sql, name = nil, binds = [], pk = nil, sequence_name = nil)
129
+ if use_insert_returning? || pk == false
130
+ super
131
+ else
132
+ result = exec_query(sql, name, binds)
194
133
  unless sequence_name
195
134
  table_ref = extract_table_ref_from_insert_sql(sql)
196
- sequence_name = default_sequence_name(table_ref, pk)
197
- return val unless sequence_name
135
+ if table_ref
136
+ pk = primary_key(table_ref) if pk.nil?
137
+ pk = suppress_composite_primary_key(pk)
138
+ sequence_name = default_sequence_name(table_ref, pk)
139
+ end
140
+ return result unless sequence_name
198
141
  end
199
142
  last_insert_id_result(sequence_name)
200
- else
201
- val
202
143
  end
203
144
  end
204
145
 
205
- # Executes an UPDATE query and returns the number of affected tuples.
206
- def update_sql(sql, name = nil)
207
- super.cmd_tuples
208
- end
209
-
210
146
  # Begins a transaction.
211
147
  def begin_db_transaction
212
148
  execute "BEGIN"
@@ -226,6 +162,20 @@ module ActiveRecord
226
162
  def exec_rollback_db_transaction
227
163
  execute "ROLLBACK"
228
164
  end
165
+
166
+ private
167
+ def build_truncate_statements(*table_names)
168
+ "TRUNCATE TABLE #{table_names.map(&method(:quote_table_name)).join(", ")}"
169
+ end
170
+
171
+ # Returns the current ID of a table's sequence.
172
+ def last_insert_id_result(sequence_name)
173
+ exec_query("SELECT currval(#{quote(sequence_name)})", "SQL")
174
+ end
175
+
176
+ def suppress_composite_primary_key(pk)
177
+ pk unless pk.is_a?(Array)
178
+ end
229
179
  end
230
180
  end
231
181
  end