activerecord 4.2.11.2 → 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 +4 -4
  2. data/CHANGELOG.md +613 -1638
  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 +131 -287
  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 -86
  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 -243
  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 -635
  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 -180
  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 +6 -4
  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 +621 -303
  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 +312 -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 +143 -44
  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 +328 -185
  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 +307 -100
  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 -59
  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 -498
  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 -64
  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.6.0'
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
@@ -96,173 +116,31 @@ module ActiveRecord
96
116
  @connection.close
97
117
  end
98
118
 
99
- #--
100
- # DATABASE STATEMENTS ======================================
101
- #++
102
-
103
- def explain(arel, binds = [])
104
- sql = "EXPLAIN #{to_sql(arel, binds.dup)}"
105
- start = Time.now
106
- result = exec_query(sql, 'EXPLAIN', binds)
107
- elapsed = Time.now - start
108
-
109
- ExplainPrettyPrinter.new.pp(result, elapsed)
119
+ def discard! # :nodoc:
120
+ super
121
+ @connection.automatic_close = false
122
+ @connection = nil
110
123
  end
111
124
 
112
- class ExplainPrettyPrinter # :nodoc:
113
- # Pretty prints the result of a EXPLAIN in a way that resembles the output of the
114
- # MySQL shell:
115
- #
116
- # +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+
117
- # | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
118
- # +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+
119
- # | 1 | SIMPLE | users | const | PRIMARY | PRIMARY | 4 | const | 1 | |
120
- # | 1 | SIMPLE | posts | ALL | NULL | NULL | NULL | NULL | 1 | Using where |
121
- # +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+
122
- # 2 rows in set (0.00 sec)
123
- #
124
- # This is an exercise in Ruby hyperrealism :).
125
- def pp(result, elapsed)
126
- widths = compute_column_widths(result)
127
- separator = build_separator(widths)
128
-
129
- pp = []
130
-
131
- pp << separator
132
- pp << build_cells(result.columns, widths)
133
- pp << separator
134
-
135
- result.rows.each do |row|
136
- pp << build_cells(row, widths)
137
- end
138
-
139
- pp << separator
140
- pp << build_footer(result.rows.length, elapsed)
125
+ private
141
126
 
142
- pp.join("\n") + "\n"
127
+ def connect
128
+ @connection = Mysql2::Client.new(@config)
129
+ configure_connection
143
130
  end
144
131
 
145
- private
146
-
147
- def compute_column_widths(result)
148
- [].tap do |widths|
149
- result.columns.each_with_index do |column, i|
150
- cells_in_column = [column] + result.rows.map {|r| r[i].nil? ? 'NULL' : r[i].to_s}
151
- widths << cells_in_column.map(&:length).max
152
- end
153
- end
132
+ def configure_connection
133
+ @connection.query_options[:as] = :array
134
+ super
154
135
  end
155
136
 
156
- def build_separator(widths)
157
- padding = 1
158
- '+' + widths.map {|w| '-' * (w + (padding*2))}.join('+') + '+'
137
+ def full_version
138
+ schema_cache.database_version.full_version_string
159
139
  end
160
140
 
161
- def build_cells(items, widths)
162
- cells = []
163
- items.each_with_index do |item, i|
164
- item = 'NULL' if item.nil?
165
- justifier = item.is_a?(Numeric) ? 'rjust' : 'ljust'
166
- cells << item.to_s.send(justifier, widths[i])
167
- end
168
- '| ' + cells.join(' | ') + ' |'
141
+ def get_full_version
142
+ @connection.server_info[:version]
169
143
  end
170
-
171
- def build_footer(nrows, elapsed)
172
- rows_label = nrows == 1 ? 'row' : 'rows'
173
- "#{nrows} #{rows_label} in set (%.2f sec)" % elapsed
174
- end
175
- end
176
-
177
- # FIXME: re-enable the following once a "better" query_cache solution is in core
178
- #
179
- # The overrides below perform much better than the originals in AbstractAdapter
180
- # because we're able to take advantage of mysql2's lazy-loading capabilities
181
- #
182
- # # Returns a record hash with the column names as keys and column values
183
- # # as values.
184
- # def select_one(sql, name = nil)
185
- # result = execute(sql, name)
186
- # result.each(as: :hash) do |r|
187
- # return r
188
- # end
189
- # end
190
- #
191
- # # Returns a single value from a record
192
- # def select_value(sql, name = nil)
193
- # result = execute(sql, name)
194
- # if first = result.first
195
- # first.first
196
- # end
197
- # end
198
- #
199
- # # Returns an array of the values of the first column in a select:
200
- # # select_values("SELECT id FROM companies LIMIT 3") => [1,2,3]
201
- # def select_values(sql, name = nil)
202
- # execute(sql, name).map { |row| row.first }
203
- # end
204
-
205
- # Returns an array of arrays containing the field values.
206
- # Order is the same as that returned by +columns+.
207
- def select_rows(sql, name = nil, binds = [])
208
- execute(sql, name).to_a
209
- end
210
-
211
- # Executes the SQL statement in the context of this connection.
212
- def execute(sql, name = nil)
213
- # make sure we carry over any changes to ActiveRecord::Base.default_timezone that have been
214
- # made since we established the connection
215
- @connection.query_options[:database_timezone] = ActiveRecord::Base.default_timezone
216
-
217
- super
218
- end
219
-
220
- def exec_query(sql, name = 'SQL', binds = [])
221
- result = execute(sql, name)
222
- ActiveRecord::Result.new(result.fields, result.to_a)
223
- end
224
-
225
- alias exec_without_stmt exec_query
226
-
227
- def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
228
- super
229
- id_value || @connection.last_id
230
- end
231
- alias :create :insert_sql
232
-
233
- def exec_insert(sql, name, binds, pk = nil, sequence_name = nil)
234
- execute to_sql(sql, binds), name
235
- end
236
-
237
- def exec_delete(sql, name, binds)
238
- execute to_sql(sql, binds), name
239
- @connection.affected_rows
240
- end
241
- alias :exec_update :exec_delete
242
-
243
- def last_inserted_id(result)
244
- @connection.last_id
245
- end
246
-
247
- private
248
-
249
- def connect
250
- @connection = Mysql2::Client.new(@config)
251
- configure_connection
252
- end
253
-
254
- def configure_connection
255
- @connection.query_options.merge!(:as => :array)
256
- super
257
- end
258
-
259
- def full_version
260
- @full_version ||= @connection.server_info[:version]
261
- end
262
-
263
- def set_field_encoding field_name
264
- field_name
265
- end
266
144
  end
267
145
  end
268
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