activerecord 4.2.0 → 6.1.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (374) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +1221 -796
  3. data/MIT-LICENSE +4 -2
  4. data/README.rdoc +15 -14
  5. data/examples/performance.rb +33 -32
  6. data/examples/simple.rb +5 -4
  7. data/lib/active_record/aggregations.rb +267 -249
  8. data/lib/active_record/association_relation.rb +45 -7
  9. data/lib/active_record/associations/alias_tracker.rb +40 -43
  10. data/lib/active_record/associations/association.rb +172 -67
  11. data/lib/active_record/associations/association_scope.rb +105 -129
  12. data/lib/active_record/associations/belongs_to_association.rb +85 -59
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +13 -12
  14. data/lib/active_record/associations/builder/association.rb +57 -43
  15. data/lib/active_record/associations/builder/belongs_to.rb +74 -57
  16. data/lib/active_record/associations/builder/collection_association.rb +15 -33
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +57 -70
  18. data/lib/active_record/associations/builder/has_many.rb +13 -5
  19. data/lib/active_record/associations/builder/has_one.rb +44 -6
  20. data/lib/active_record/associations/builder/singular_association.rb +16 -10
  21. data/lib/active_record/associations/collection_association.rb +168 -279
  22. data/lib/active_record/associations/collection_proxy.rb +263 -155
  23. data/lib/active_record/associations/foreign_association.rb +33 -0
  24. data/lib/active_record/associations/has_many_association.rb +57 -84
  25. data/lib/active_record/associations/has_many_through_association.rb +70 -82
  26. data/lib/active_record/associations/has_one_association.rb +74 -47
  27. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  28. data/lib/active_record/associations/join_dependency/join_association.rb +54 -73
  29. data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
  30. data/lib/active_record/associations/join_dependency/join_part.rb +14 -14
  31. data/lib/active_record/associations/join_dependency.rb +175 -164
  32. data/lib/active_record/associations/preloader/association.rb +107 -112
  33. data/lib/active_record/associations/preloader/through_association.rb +85 -65
  34. data/lib/active_record/associations/preloader.rb +99 -96
  35. data/lib/active_record/associations/singular_association.rb +18 -45
  36. data/lib/active_record/associations/through_association.rb +49 -24
  37. data/lib/active_record/associations.rb +1845 -1597
  38. data/lib/active_record/attribute_assignment.rb +59 -185
  39. data/lib/active_record/attribute_methods/before_type_cast.rb +20 -7
  40. data/lib/active_record/attribute_methods/dirty.rb +168 -138
  41. data/lib/active_record/attribute_methods/primary_key.rb +93 -83
  42. data/lib/active_record/attribute_methods/query.rb +8 -10
  43. data/lib/active_record/attribute_methods/read.rb +19 -79
  44. data/lib/active_record/attribute_methods/serialization.rb +49 -24
  45. data/lib/active_record/attribute_methods/time_zone_conversion.rb +59 -36
  46. data/lib/active_record/attribute_methods/write.rb +25 -56
  47. data/lib/active_record/attribute_methods.rb +153 -162
  48. data/lib/active_record/attributes.rb +234 -70
  49. data/lib/active_record/autosave_association.rb +157 -69
  50. data/lib/active_record/base.rb +49 -50
  51. data/lib/active_record/callbacks.rb +234 -79
  52. data/lib/active_record/coders/json.rb +3 -1
  53. data/lib/active_record/coders/yaml_column.rb +46 -13
  54. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +887 -317
  55. data/lib/active_record/connection_adapters/abstract/database_limits.rb +17 -41
  56. data/lib/active_record/connection_adapters/abstract/database_statements.rb +301 -113
  57. data/lib/active_record/connection_adapters/abstract/query_cache.rb +78 -24
  58. data/lib/active_record/connection_adapters/abstract/quoting.rb +187 -60
  59. data/lib/active_record/connection_adapters/abstract/savepoints.rb +9 -7
  60. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +157 -93
  61. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +485 -253
  62. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +79 -36
  63. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +909 -263
  64. data/lib/active_record/connection_adapters/abstract/transaction.rb +254 -92
  65. data/lib/active_record/connection_adapters/abstract_adapter.rb +492 -221
  66. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +580 -608
  67. data/lib/active_record/connection_adapters/column.rb +67 -40
  68. data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
  69. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +35 -0
  70. data/lib/active_record/connection_adapters/mysql/column.rb +27 -0
  71. data/lib/active_record/connection_adapters/mysql/database_statements.rb +196 -0
  72. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +71 -0
  73. data/lib/active_record/connection_adapters/mysql/quoting.rb +96 -0
  74. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +97 -0
  75. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +103 -0
  76. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +91 -0
  77. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +271 -0
  78. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +40 -0
  79. data/lib/active_record/connection_adapters/mysql2_adapter.rb +81 -199
  80. data/lib/active_record/connection_adapters/pool_config.rb +73 -0
  81. data/lib/active_record/connection_adapters/pool_manager.rb +47 -0
  82. data/lib/active_record/connection_adapters/postgresql/column.rb +44 -11
  83. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +78 -161
  84. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
  85. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +49 -57
  86. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +9 -8
  87. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  88. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +5 -2
  89. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +8 -6
  90. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +13 -1
  91. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +17 -13
  92. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  93. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +6 -3
  94. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +31 -20
  95. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  96. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
  97. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
  98. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +44 -0
  99. data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
  100. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -9
  101. data/lib/active_record/connection_adapters/postgresql/oid/{infinity.rb → oid.rb} +5 -3
  102. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +32 -11
  103. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +70 -34
  104. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -1
  105. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +67 -51
  106. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +18 -4
  107. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +3 -1
  108. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +3 -1
  109. data/lib/active_record/connection_adapters/postgresql/oid.rb +25 -25
  110. data/lib/active_record/connection_adapters/postgresql/quoting.rb +171 -48
  111. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +27 -14
  112. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +80 -0
  113. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +178 -108
  114. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +49 -0
  115. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +499 -293
  116. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +44 -0
  117. data/lib/active_record/connection_adapters/postgresql/utils.rb +11 -8
  118. data/lib/active_record/connection_adapters/postgresql_adapter.rb +595 -382
  119. data/lib/active_record/connection_adapters/schema_cache.rb +191 -29
  120. data/lib/active_record/connection_adapters/sql_type_metadata.rb +45 -0
  121. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +146 -0
  122. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +21 -0
  123. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +102 -0
  124. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +21 -0
  125. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
  126. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
  127. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +170 -0
  128. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +322 -389
  129. data/lib/active_record/connection_adapters/statement_pool.rb +33 -13
  130. data/lib/active_record/connection_adapters.rb +52 -0
  131. data/lib/active_record/connection_handling.rb +314 -41
  132. data/lib/active_record/core.rb +488 -243
  133. data/lib/active_record/counter_cache.rb +71 -50
  134. data/lib/active_record/database_configurations/connection_url_resolver.rb +99 -0
  135. data/lib/active_record/database_configurations/database_config.rb +80 -0
  136. data/lib/active_record/database_configurations/hash_config.rb +96 -0
  137. data/lib/active_record/database_configurations/url_config.rb +53 -0
  138. data/lib/active_record/database_configurations.rb +273 -0
  139. data/lib/active_record/delegated_type.rb +209 -0
  140. data/lib/active_record/destroy_association_async_job.rb +36 -0
  141. data/lib/active_record/dynamic_matchers.rb +87 -106
  142. data/lib/active_record/enum.rb +212 -94
  143. data/lib/active_record/errors.rb +225 -54
  144. data/lib/active_record/explain.rb +27 -11
  145. data/lib/active_record/explain_registry.rb +4 -2
  146. data/lib/active_record/explain_subscriber.rb +11 -6
  147. data/lib/active_record/fixture_set/file.rb +33 -14
  148. data/lib/active_record/fixture_set/model_metadata.rb +32 -0
  149. data/lib/active_record/fixture_set/render_context.rb +17 -0
  150. data/lib/active_record/fixture_set/table_row.rb +152 -0
  151. data/lib/active_record/fixture_set/table_rows.rb +46 -0
  152. data/lib/active_record/fixtures.rb +273 -496
  153. data/lib/active_record/gem_version.rb +6 -4
  154. data/lib/active_record/inheritance.rb +175 -110
  155. data/lib/active_record/insert_all.rb +212 -0
  156. data/lib/active_record/integration.rb +121 -29
  157. data/lib/active_record/internal_metadata.rb +64 -0
  158. data/lib/active_record/legacy_yaml_adapter.rb +52 -0
  159. data/lib/active_record/locale/en.yml +3 -2
  160. data/lib/active_record/locking/optimistic.rb +103 -95
  161. data/lib/active_record/locking/pessimistic.rb +22 -6
  162. data/lib/active_record/log_subscriber.rb +93 -31
  163. data/lib/active_record/middleware/database_selector/resolver/session.rb +48 -0
  164. data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
  165. data/lib/active_record/middleware/database_selector.rb +77 -0
  166. data/lib/active_record/migration/command_recorder.rb +185 -90
  167. data/lib/active_record/migration/compatibility.rb +298 -0
  168. data/lib/active_record/migration/join_table.rb +8 -7
  169. data/lib/active_record/migration.rb +685 -309
  170. data/lib/active_record/model_schema.rb +420 -113
  171. data/lib/active_record/nested_attributes.rb +265 -216
  172. data/lib/active_record/no_touching.rb +15 -2
  173. data/lib/active_record/null_relation.rb +24 -38
  174. data/lib/active_record/persistence.rb +574 -135
  175. data/lib/active_record/query_cache.rb +29 -23
  176. data/lib/active_record/querying.rb +50 -31
  177. data/lib/active_record/railtie.rb +175 -54
  178. data/lib/active_record/railties/console_sandbox.rb +3 -3
  179. data/lib/active_record/railties/controller_runtime.rb +34 -33
  180. data/lib/active_record/railties/databases.rake +533 -216
  181. data/lib/active_record/readonly_attributes.rb +9 -4
  182. data/lib/active_record/reflection.rb +485 -310
  183. data/lib/active_record/relation/batches/batch_enumerator.rb +85 -0
  184. data/lib/active_record/relation/batches.rb +217 -59
  185. data/lib/active_record/relation/calculations.rb +326 -244
  186. data/lib/active_record/relation/delegation.rb +76 -84
  187. data/lib/active_record/relation/finder_methods.rb +318 -256
  188. data/lib/active_record/relation/from_clause.rb +30 -0
  189. data/lib/active_record/relation/merger.rb +99 -84
  190. data/lib/active_record/relation/predicate_builder/array_handler.rb +26 -25
  191. data/lib/active_record/relation/predicate_builder/association_query_value.rb +42 -0
  192. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +19 -0
  193. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +57 -0
  194. data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -0
  195. data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
  196. data/lib/active_record/relation/predicate_builder.rb +139 -96
  197. data/lib/active_record/relation/query_attribute.rb +50 -0
  198. data/lib/active_record/relation/query_methods.rb +757 -409
  199. data/lib/active_record/relation/record_fetch_warning.rb +51 -0
  200. data/lib/active_record/relation/spawn_methods.rb +23 -21
  201. data/lib/active_record/relation/where_clause.rb +239 -0
  202. data/lib/active_record/relation.rb +554 -342
  203. data/lib/active_record/result.rb +91 -47
  204. data/lib/active_record/runtime_registry.rb +6 -4
  205. data/lib/active_record/sanitization.rb +134 -122
  206. data/lib/active_record/schema.rb +21 -24
  207. data/lib/active_record/schema_dumper.rb +141 -92
  208. data/lib/active_record/schema_migration.rb +24 -26
  209. data/lib/active_record/scoping/default.rb +96 -82
  210. data/lib/active_record/scoping/named.rb +78 -36
  211. data/lib/active_record/scoping.rb +45 -27
  212. data/lib/active_record/secure_token.rb +48 -0
  213. data/lib/active_record/serialization.rb +8 -6
  214. data/lib/active_record/signed_id.rb +116 -0
  215. data/lib/active_record/statement_cache.rb +89 -36
  216. data/lib/active_record/store.rb +133 -43
  217. data/lib/active_record/suppressor.rb +61 -0
  218. data/lib/active_record/table_metadata.rb +81 -0
  219. data/lib/active_record/tasks/database_tasks.rb +366 -129
  220. data/lib/active_record/tasks/mysql_database_tasks.rb +68 -100
  221. data/lib/active_record/tasks/postgresql_database_tasks.rb +87 -39
  222. data/lib/active_record/tasks/sqlite_database_tasks.rb +44 -19
  223. data/lib/active_record/test_databases.rb +24 -0
  224. data/lib/active_record/test_fixtures.rb +291 -0
  225. data/lib/active_record/timestamp.rb +86 -43
  226. data/lib/active_record/touch_later.rb +65 -0
  227. data/lib/active_record/transactions.rb +181 -152
  228. data/lib/active_record/translation.rb +3 -1
  229. data/lib/active_record/type/adapter_specific_registry.rb +126 -0
  230. data/lib/active_record/type/date.rb +4 -41
  231. data/lib/active_record/type/date_time.rb +4 -38
  232. data/lib/active_record/type/decimal_without_scale.rb +6 -2
  233. data/lib/active_record/type/hash_lookup_type_map.rb +12 -5
  234. data/lib/active_record/type/internal/timezone.rb +17 -0
  235. data/lib/active_record/type/json.rb +30 -0
  236. data/lib/active_record/type/serialized.rb +33 -15
  237. data/lib/active_record/type/text.rb +2 -2
  238. data/lib/active_record/type/time.rb +21 -16
  239. data/lib/active_record/type/type_map.rb +16 -19
  240. data/lib/active_record/type/unsigned_integer.rb +9 -8
  241. data/lib/active_record/type.rb +84 -23
  242. data/lib/active_record/type_caster/connection.rb +33 -0
  243. data/lib/active_record/type_caster/map.rb +23 -0
  244. data/lib/active_record/type_caster.rb +9 -0
  245. data/lib/active_record/validations/absence.rb +25 -0
  246. data/lib/active_record/validations/associated.rb +12 -4
  247. data/lib/active_record/validations/length.rb +26 -0
  248. data/lib/active_record/validations/numericality.rb +35 -0
  249. data/lib/active_record/validations/presence.rb +14 -13
  250. data/lib/active_record/validations/uniqueness.rb +65 -48
  251. data/lib/active_record/validations.rb +39 -35
  252. data/lib/active_record/version.rb +3 -1
  253. data/lib/active_record.rb +44 -28
  254. data/lib/arel/alias_predication.rb +9 -0
  255. data/lib/arel/attributes/attribute.rb +41 -0
  256. data/lib/arel/collectors/bind.rb +29 -0
  257. data/lib/arel/collectors/composite.rb +39 -0
  258. data/lib/arel/collectors/plain_string.rb +20 -0
  259. data/lib/arel/collectors/sql_string.rb +27 -0
  260. data/lib/arel/collectors/substitute_binds.rb +35 -0
  261. data/lib/arel/crud.rb +42 -0
  262. data/lib/arel/delete_manager.rb +18 -0
  263. data/lib/arel/errors.rb +9 -0
  264. data/lib/arel/expressions.rb +29 -0
  265. data/lib/arel/factory_methods.rb +49 -0
  266. data/lib/arel/insert_manager.rb +49 -0
  267. data/lib/arel/math.rb +45 -0
  268. data/lib/arel/nodes/and.rb +32 -0
  269. data/lib/arel/nodes/ascending.rb +23 -0
  270. data/lib/arel/nodes/binary.rb +126 -0
  271. data/lib/arel/nodes/bind_param.rb +44 -0
  272. data/lib/arel/nodes/case.rb +55 -0
  273. data/lib/arel/nodes/casted.rb +62 -0
  274. data/lib/arel/nodes/comment.rb +29 -0
  275. data/lib/arel/nodes/count.rb +12 -0
  276. data/lib/arel/nodes/delete_statement.rb +45 -0
  277. data/lib/arel/nodes/descending.rb +23 -0
  278. data/lib/arel/nodes/equality.rb +15 -0
  279. data/lib/arel/nodes/extract.rb +24 -0
  280. data/lib/arel/nodes/false.rb +16 -0
  281. data/lib/arel/nodes/full_outer_join.rb +8 -0
  282. data/lib/arel/nodes/function.rb +44 -0
  283. data/lib/arel/nodes/grouping.rb +11 -0
  284. data/lib/arel/nodes/homogeneous_in.rb +76 -0
  285. data/lib/arel/nodes/in.rb +15 -0
  286. data/lib/arel/nodes/infix_operation.rb +92 -0
  287. data/lib/arel/nodes/inner_join.rb +8 -0
  288. data/lib/arel/nodes/insert_statement.rb +37 -0
  289. data/lib/arel/nodes/join_source.rb +20 -0
  290. data/lib/arel/nodes/matches.rb +18 -0
  291. data/lib/arel/nodes/named_function.rb +23 -0
  292. data/lib/arel/nodes/node.rb +51 -0
  293. data/lib/arel/nodes/node_expression.rb +13 -0
  294. data/lib/arel/nodes/ordering.rb +27 -0
  295. data/lib/arel/nodes/outer_join.rb +8 -0
  296. data/lib/arel/nodes/over.rb +15 -0
  297. data/lib/arel/nodes/regexp.rb +16 -0
  298. data/lib/arel/nodes/right_outer_join.rb +8 -0
  299. data/lib/arel/nodes/select_core.rb +67 -0
  300. data/lib/arel/nodes/select_statement.rb +41 -0
  301. data/lib/arel/nodes/sql_literal.rb +19 -0
  302. data/lib/arel/nodes/string_join.rb +11 -0
  303. data/lib/arel/nodes/table_alias.rb +31 -0
  304. data/lib/arel/nodes/terminal.rb +16 -0
  305. data/lib/arel/nodes/true.rb +16 -0
  306. data/lib/arel/nodes/unary.rb +44 -0
  307. data/lib/arel/nodes/unary_operation.rb +20 -0
  308. data/lib/arel/nodes/unqualified_column.rb +22 -0
  309. data/lib/arel/nodes/update_statement.rb +41 -0
  310. data/lib/arel/nodes/values_list.rb +9 -0
  311. data/lib/arel/nodes/window.rb +126 -0
  312. data/lib/arel/nodes/with.rb +11 -0
  313. data/lib/arel/nodes.rb +70 -0
  314. data/lib/arel/order_predications.rb +13 -0
  315. data/lib/arel/predications.rb +250 -0
  316. data/lib/arel/select_manager.rb +270 -0
  317. data/lib/arel/table.rb +118 -0
  318. data/lib/arel/tree_manager.rb +72 -0
  319. data/lib/arel/update_manager.rb +34 -0
  320. data/lib/arel/visitors/dot.rb +308 -0
  321. data/lib/arel/visitors/mysql.rb +93 -0
  322. data/lib/arel/visitors/postgresql.rb +120 -0
  323. data/lib/arel/visitors/sqlite.rb +38 -0
  324. data/lib/arel/visitors/to_sql.rb +899 -0
  325. data/lib/arel/visitors/visitor.rb +45 -0
  326. data/lib/arel/visitors.rb +13 -0
  327. data/lib/arel/window_predications.rb +9 -0
  328. data/lib/arel.rb +54 -0
  329. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +26 -0
  330. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +5 -0
  331. data/lib/rails/generators/active_record/migration/migration_generator.rb +43 -37
  332. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +26 -0
  333. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +13 -10
  334. data/lib/rails/generators/active_record/migration.rb +35 -1
  335. data/lib/rails/generators/active_record/model/model_generator.rb +55 -22
  336. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
  337. data/lib/rails/generators/active_record/model/templates/model.rb.tt +22 -0
  338. data/lib/rails/generators/active_record.rb +7 -5
  339. metadata +175 -65
  340. data/lib/active_record/associations/preloader/belongs_to.rb +0 -17
  341. data/lib/active_record/associations/preloader/collection_association.rb +0 -24
  342. data/lib/active_record/associations/preloader/has_many.rb +0 -17
  343. data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
  344. data/lib/active_record/associations/preloader/has_one.rb +0 -23
  345. data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
  346. data/lib/active_record/associations/preloader/singular_association.rb +0 -21
  347. data/lib/active_record/attribute.rb +0 -149
  348. data/lib/active_record/attribute_decorators.rb +0 -66
  349. data/lib/active_record/attribute_set/builder.rb +0 -86
  350. data/lib/active_record/attribute_set.rb +0 -77
  351. data/lib/active_record/connection_adapters/connection_specification.rb +0 -275
  352. data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -491
  353. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
  354. data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
  355. data/lib/active_record/connection_adapters/postgresql/oid/integer.rb +0 -11
  356. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -35
  357. data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
  358. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  359. data/lib/active_record/serializers/xml_serializer.rb +0 -193
  360. data/lib/active_record/type/big_integer.rb +0 -13
  361. data/lib/active_record/type/binary.rb +0 -50
  362. data/lib/active_record/type/boolean.rb +0 -30
  363. data/lib/active_record/type/decimal.rb +0 -40
  364. data/lib/active_record/type/decorator.rb +0 -14
  365. data/lib/active_record/type/float.rb +0 -19
  366. data/lib/active_record/type/integer.rb +0 -55
  367. data/lib/active_record/type/mutable.rb +0 -16
  368. data/lib/active_record/type/numeric.rb +0 -36
  369. data/lib/active_record/type/string.rb +0 -36
  370. data/lib/active_record/type/time_value.rb +0 -38
  371. data/lib/active_record/type/value.rb +0 -101
  372. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +0 -22
  373. data/lib/rails/generators/active_record/model/templates/model.rb +0 -10
  374. /data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
@@ -1,52 +1,81 @@
1
- require 'active_record/connection_adapters/abstract_mysql_adapter'
1
+ # frozen_string_literal: true
2
2
 
3
- gem 'mysql2', '~> 0.3.13'
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.5"
7
+ require "mysql2"
5
8
 
6
9
  module ActiveRecord
7
10
  module ConnectionHandling # :nodoc:
8
11
  # Establishes a connection to the database that's used by all Active Record objects.
9
12
  def mysql2_connection(config)
10
13
  config = config.symbolize_keys
14
+ config[:flags] ||= 0
11
15
 
12
- config[:username] = 'root' if config[:username].nil?
13
-
14
- if Mysql2::Client.const_defined? :FOUND_ROWS
15
- config[:flags] = Mysql2::Client::FOUND_ROWS
16
- end
17
-
18
- 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)
21
- rescue Mysql2::Error => error
22
- if error.message.include?("Unknown database")
23
- raise ActiveRecord::NoDatabaseError.new(error.message, error)
16
+ if config[:flags].kind_of? Array
17
+ config[:flags].push "FOUND_ROWS"
24
18
  else
25
- raise
19
+ config[:flags] |= Mysql2::Client::FOUND_ROWS
26
20
  end
21
+
22
+ ConnectionAdapters::Mysql2Adapter.new(
23
+ ConnectionAdapters::Mysql2Adapter.new_client(config),
24
+ logger,
25
+ nil,
26
+ config,
27
+ )
27
28
  end
28
29
  end
29
30
 
30
31
  module ConnectionAdapters
31
32
  class Mysql2Adapter < AbstractMysqlAdapter
32
- ADAPTER_NAME = 'Mysql2'.freeze
33
+ ER_BAD_DB_ERROR = 1049
34
+ ADAPTER_NAME = "Mysql2"
35
+
36
+ include MySQL::DatabaseStatements
37
+
38
+ class << self
39
+ def new_client(config)
40
+ Mysql2::Client.new(config)
41
+ rescue Mysql2::Error => error
42
+ if error.error_number == ConnectionAdapters::Mysql2Adapter::ER_BAD_DB_ERROR
43
+ raise ActiveRecord::NoDatabaseError
44
+ else
45
+ raise ActiveRecord::ConnectionNotEstablished, error.message
46
+ end
47
+ end
48
+ end
33
49
 
34
50
  def initialize(connection, logger, connection_options, config)
35
- super
36
- @prepared_statements = false
51
+ superclass_config = config.reverse_merge(prepared_statements: false)
52
+ super(connection, logger, connection_options, superclass_config)
37
53
  configure_connection
38
54
  end
39
55
 
40
- MAX_INDEX_LENGTH_FOR_UTF8MB4 = 191
41
- def initialize_schema_migrations_table
42
- if @config[:encoding] == 'utf8mb4'
43
- ActiveRecord::SchemaMigration.create_table(MAX_INDEX_LENGTH_FOR_UTF8MB4)
44
- else
45
- ActiveRecord::SchemaMigration.create_table
46
- end
56
+ def self.database_exists?(config)
57
+ !!ActiveRecord::Base.mysql2_connection(config)
58
+ rescue ActiveRecord::NoDatabaseError
59
+ false
60
+ end
61
+
62
+ def supports_json?
63
+ !mariadb? && database_version >= "5.7.8"
64
+ end
65
+
66
+ def supports_comments?
67
+ true
47
68
  end
48
69
 
49
- def supports_explain?
70
+ def supports_comments_in_create?
71
+ true
72
+ end
73
+
74
+ def supports_savepoints?
75
+ true
76
+ end
77
+
78
+ def supports_lazy_transactions?
50
79
  true
51
80
  end
52
81
 
@@ -54,7 +83,7 @@ module ActiveRecord
54
83
 
55
84
  def each_hash(result) # :nodoc:
56
85
  if block_given?
57
- result.each(:as => :hash, :symbolize_keys => true) do |row|
86
+ result.each(as: :hash, symbolize_keys: true) do |row|
58
87
  yield row
59
88
  end
60
89
  else
@@ -72,14 +101,8 @@ module ActiveRecord
72
101
 
73
102
  def quote_string(string)
74
103
  @connection.escape(string)
75
- end
76
-
77
- def quoted_date(value)
78
- if value.acts_like?(:time) && value.respond_to?(:usec)
79
- "#{super}.#{sprintf("%06d", value.usec)}"
80
- else
81
- super
82
- end
104
+ rescue Mysql2::Error => error
105
+ raise translate_exception(error, message: error.message, sql: "<escape>", binds: [])
83
106
  end
84
107
 
85
108
  #--
@@ -87,7 +110,6 @@ module ActiveRecord
87
110
  #++
88
111
 
89
112
  def active?
90
- return false unless @connection
91
113
  @connection.ping
92
114
  end
93
115
 
@@ -102,181 +124,41 @@ module ActiveRecord
102
124
  # Otherwise, this method does nothing.
103
125
  def disconnect!
104
126
  super
105
- unless @connection.nil?
106
- @connection.close
107
- @connection = nil
108
- end
127
+ @connection.close
109
128
  end
110
129
 
111
- #--
112
- # DATABASE STATEMENTS ======================================
113
- #++
114
-
115
- def explain(arel, binds = [])
116
- sql = "EXPLAIN #{to_sql(arel, binds.dup)}"
117
- start = Time.now
118
- result = exec_query(sql, 'EXPLAIN', binds)
119
- elapsed = Time.now - start
120
-
121
- ExplainPrettyPrinter.new.pp(result, elapsed)
130
+ def discard! # :nodoc:
131
+ super
132
+ @connection.automatic_close = false
133
+ @connection = nil
122
134
  end
123
135
 
124
- class ExplainPrettyPrinter # :nodoc:
125
- # Pretty prints the result of a EXPLAIN in a way that resembles the output of the
126
- # MySQL shell:
127
- #
128
- # +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+
129
- # | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
130
- # +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+
131
- # | 1 | SIMPLE | users | const | PRIMARY | PRIMARY | 4 | const | 1 | |
132
- # | 1 | SIMPLE | posts | ALL | NULL | NULL | NULL | NULL | 1 | Using where |
133
- # +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+
134
- # 2 rows in set (0.00 sec)
135
- #
136
- # This is an exercise in Ruby hyperrealism :).
137
- def pp(result, elapsed)
138
- widths = compute_column_widths(result)
139
- separator = build_separator(widths)
140
-
141
- pp = []
142
-
143
- pp << separator
144
- pp << build_cells(result.columns, widths)
145
- pp << separator
146
-
147
- result.rows.each do |row|
148
- pp << build_cells(row, widths)
149
- end
150
-
151
- pp << separator
152
- pp << build_footer(result.rows.length, elapsed)
153
-
154
- pp.join("\n") + "\n"
155
- end
156
-
157
- private
158
-
159
- def compute_column_widths(result)
160
- [].tap do |widths|
161
- result.columns.each_with_index do |column, i|
162
- cells_in_column = [column] + result.rows.map {|r| r[i].nil? ? 'NULL' : r[i].to_s}
163
- widths << cells_in_column.map(&:length).max
164
- end
165
- end
136
+ private
137
+ def connect
138
+ @connection = self.class.new_client(@config)
139
+ configure_connection
166
140
  end
167
141
 
168
- def build_separator(widths)
169
- padding = 1
170
- '+' + widths.map {|w| '-' * (w + (padding*2))}.join('+') + '+'
142
+ def configure_connection
143
+ @connection.query_options[:as] = :array
144
+ super
171
145
  end
172
146
 
173
- def build_cells(items, widths)
174
- cells = []
175
- items.each_with_index do |item, i|
176
- item = 'NULL' if item.nil?
177
- justifier = item.is_a?(Numeric) ? 'rjust' : 'ljust'
178
- cells << item.to_s.send(justifier, widths[i])
179
- end
180
- '| ' + cells.join(' | ') + ' |'
147
+ def full_version
148
+ schema_cache.database_version.full_version_string
181
149
  end
182
150
 
183
- def build_footer(nrows, elapsed)
184
- rows_label = nrows == 1 ? 'row' : 'rows'
185
- "#{nrows} #{rows_label} in set (%.2f sec)" % elapsed
151
+ def get_full_version
152
+ @connection.server_info[:version]
186
153
  end
187
- end
188
-
189
- # FIXME: re-enable the following once a "better" query_cache solution is in core
190
- #
191
- # The overrides below perform much better than the originals in AbstractAdapter
192
- # because we're able to take advantage of mysql2's lazy-loading capabilities
193
- #
194
- # # Returns a record hash with the column names as keys and column values
195
- # # as values.
196
- # def select_one(sql, name = nil)
197
- # result = execute(sql, name)
198
- # result.each(as: :hash) do |r|
199
- # return r
200
- # end
201
- # end
202
- #
203
- # # Returns a single value from a record
204
- # def select_value(sql, name = nil)
205
- # result = execute(sql, name)
206
- # if first = result.first
207
- # first.first
208
- # end
209
- # end
210
- #
211
- # # Returns an array of the values of the first column in a select:
212
- # # select_values("SELECT id FROM companies LIMIT 3") => [1,2,3]
213
- # def select_values(sql, name = nil)
214
- # execute(sql, name).map { |row| row.first }
215
- # end
216
-
217
- # Returns an array of arrays containing the field values.
218
- # Order is the same as that returned by +columns+.
219
- def select_rows(sql, name = nil, binds = [])
220
- execute(sql, name).to_a
221
- end
222
154
 
223
- # Executes the SQL statement in the context of this connection.
224
- def execute(sql, name = nil)
225
- if @connection
226
- # make sure we carry over any changes to ActiveRecord::Base.default_timezone that have been
227
- # made since we established the connection
228
- @connection.query_options[:database_timezone] = ActiveRecord::Base.default_timezone
155
+ def translate_exception(exception, message:, sql:, binds:)
156
+ if exception.is_a?(Mysql2::Error::TimeoutError) && !exception.error_number
157
+ ActiveRecord::AdapterTimeout.new(message, sql: sql, binds: binds)
158
+ else
159
+ super
160
+ end
229
161
  end
230
-
231
- super
232
- end
233
-
234
- def exec_query(sql, name = 'SQL', binds = [])
235
- result = execute(sql, name)
236
- ActiveRecord::Result.new(result.fields, result.to_a)
237
- end
238
-
239
- alias exec_without_stmt exec_query
240
-
241
- def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
242
- super
243
- id_value || @connection.last_id
244
- end
245
- alias :create :insert_sql
246
-
247
- def exec_insert(sql, name, binds, pk = nil, sequence_name = nil)
248
- execute to_sql(sql, binds), name
249
- end
250
-
251
- def exec_delete(sql, name, binds)
252
- execute to_sql(sql, binds), name
253
- @connection.affected_rows
254
- end
255
- alias :exec_update :exec_delete
256
-
257
- def last_inserted_id(result)
258
- @connection.last_id
259
- end
260
-
261
- private
262
-
263
- def connect
264
- @connection = Mysql2::Client.new(@config)
265
- configure_connection
266
- end
267
-
268
- def configure_connection
269
- @connection.query_options.merge!(:as => :array)
270
- super
271
- end
272
-
273
- def full_version
274
- @full_version ||= @connection.info[:version]
275
- end
276
-
277
- def set_field_encoding field_name
278
- field_name
279
- end
280
162
  end
281
163
  end
282
164
  end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module ConnectionAdapters
5
+ class PoolConfig # :nodoc:
6
+ include Mutex_m
7
+
8
+ attr_reader :db_config, :connection_klass
9
+ attr_accessor :schema_cache
10
+
11
+ INSTANCES = ObjectSpace::WeakMap.new
12
+ private_constant :INSTANCES
13
+
14
+ class << self
15
+ def discard_pools!
16
+ INSTANCES.each_key(&:discard_pool!)
17
+ end
18
+ end
19
+
20
+ def initialize(connection_klass, db_config)
21
+ super()
22
+ @connection_klass = connection_klass
23
+ @db_config = db_config
24
+ @pool = nil
25
+ INSTANCES[self] = self
26
+ end
27
+
28
+ def connection_specification_name
29
+ if connection_klass.is_a?(String)
30
+ connection_klass
31
+ elsif connection_klass.primary_class?
32
+ "ActiveRecord::Base"
33
+ else
34
+ connection_klass.name
35
+ end
36
+ end
37
+
38
+ def disconnect!
39
+ ActiveSupport::ForkTracker.check!
40
+
41
+ return unless @pool
42
+
43
+ synchronize do
44
+ return unless @pool
45
+
46
+ @pool.automatic_reconnect = false
47
+ @pool.disconnect!
48
+ end
49
+
50
+ nil
51
+ end
52
+
53
+ def pool
54
+ ActiveSupport::ForkTracker.check!
55
+
56
+ @pool || synchronize { @pool ||= ConnectionAdapters::ConnectionPool.new(self) }
57
+ end
58
+
59
+ def discard_pool!
60
+ return unless @pool
61
+
62
+ synchronize do
63
+ return unless @pool
64
+
65
+ @pool.discard!
66
+ @pool = nil
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+
73
+ ActiveSupport::ForkTracker.after_fork { ActiveRecord::ConnectionAdapters::PoolConfig.discard_pools! }
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module ConnectionAdapters
5
+ class PoolManager # :nodoc:
6
+ def initialize
7
+ @name_to_role_mapping = Hash.new { |h, k| h[k] = {} }
8
+ end
9
+
10
+ def shard_names
11
+ @name_to_role_mapping.values.flat_map { |shard_map| shard_map.keys }
12
+ end
13
+
14
+ def role_names
15
+ @name_to_role_mapping.keys
16
+ end
17
+
18
+ def pool_configs(role = nil)
19
+ if role
20
+ @name_to_role_mapping[role].values
21
+ else
22
+ @name_to_role_mapping.flat_map { |_, shard_map| shard_map.values }
23
+ end
24
+ end
25
+
26
+ def remove_role(role)
27
+ @name_to_role_mapping.delete(role)
28
+ end
29
+
30
+ def remove_pool_config(role, shard)
31
+ @name_to_role_mapping[role].delete(shard)
32
+ end
33
+
34
+ def get_pool_config(role, shard)
35
+ @name_to_role_mapping[role][shard]
36
+ end
37
+
38
+ def set_pool_config(role, shard, pool_config)
39
+ if pool_config
40
+ @name_to_role_mapping[role][shard] = pool_config
41
+ else
42
+ raise ArgumentError, "The `pool_config` for the :#{role} role and :#{shard} shard was `nil`. Please check your configuration. If you want your writing role to be something other than `:writing` set `config.active_record.writing_role` in your application configuration. The same setting should be applied for the `reading_role` if applicable."
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -1,20 +1,53 @@
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
13
+
14
+ def serial?
15
+ @serial
16
+ end
17
+
18
+ def array
19
+ sql_type_metadata.sql_type.end_with?("[]")
20
+ end
21
+ alias :array? :array
6
22
 
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)
23
+ def sql_type
24
+ super.delete_suffix("[]")
14
25
  end
15
26
 
16
- @default_function = default_function
27
+ def init_with(coder)
28
+ @serial = coder["serial"]
29
+ super
30
+ end
31
+
32
+ def encode_with(coder)
33
+ coder["serial"] = @serial
34
+ super
35
+ end
36
+
37
+ def ==(other)
38
+ other.is_a?(Column) &&
39
+ super &&
40
+ serial? == other.serial?
41
+ end
42
+ alias :eql? :==
43
+
44
+ def hash
45
+ Column.hash ^
46
+ super.hash ^
47
+ serial?.hash
48
+ end
17
49
  end
18
50
  end
51
+ PostgreSQLColumn = PostgreSQL::Column # :nodoc:
19
52
  end
20
53
  end