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,46 +1,36 @@
1
- require 'set'
1
+ # frozen_string_literal: true
2
2
 
3
3
  module ActiveRecord
4
4
  # :stopdoc:
5
5
  module ConnectionAdapters
6
6
  # An abstract definition of a column in a table.
7
7
  class Column
8
- TRUE_VALUES = [true, 1, '1', 't', 'T', 'true', 'TRUE', 'on', 'ON'].to_set
9
- FALSE_VALUES = [false, 0, '0', 'f', 'F', 'false', 'FALSE', 'off', 'OFF'].to_set
8
+ attr_reader :name, :default, :sql_type_metadata, :null, :default_function, :collation, :comment
10
9
 
11
- module Format
12
- ISO_DATE = /\A(\d{4})-(\d\d)-(\d\d)\z/
13
- ISO_DATETIME = /\A(\d{4})-(\d\d)-(\d\d) (\d\d):(\d\d):(\d\d)(\.\d+)?\z/
14
- end
15
-
16
- attr_reader :name, :cast_type, :null, :sql_type, :default, :default_function
17
-
18
- delegate :type, :precision, :scale, :limit, :klass, :accessor,
19
- :text?, :number?, :binary?, :changed?,
20
- :type_cast_from_user, :type_cast_from_database, :type_cast_for_database,
21
- :type_cast_for_schema,
22
- to: :cast_type
10
+ delegate :precision, :scale, :limit, :type, :sql_type, to: :sql_type_metadata, allow_nil: true
23
11
 
24
12
  # Instantiates a new column in the table.
25
13
  #
26
- # +name+ is the column's name, such as <tt>supplier_id</tt> in <tt>supplier_id int(11)</tt>.
14
+ # +name+ is the column's name, such as <tt>supplier_id</tt> in <tt>supplier_id bigint</tt>.
27
15
  # +default+ is the type-casted default value, such as +new+ in <tt>sales_stage varchar(20) default 'new'</tt>.
28
- # +cast_type+ is the object used for type casting and type information.
29
- # +sql_type+ is used to extract the column's length, if necessary. For example +60+ in
30
- # <tt>company_name varchar(60)</tt>.
31
- # It will be mapped to one of the standard Rails SQL types in the <tt>type</tt> attribute.
16
+ # +sql_type_metadata+ is various information about the type of the column
32
17
  # +null+ determines if this column allows +NULL+ values.
33
- def initialize(name, default, cast_type, sql_type = nil, null = true)
34
- @name = name.freeze
35
- @cast_type = cast_type
36
- @sql_type = sql_type
37
- @null = null
38
- @default = default
39
- @default_function = nil
18
+ def initialize(name, default, sql_type_metadata = nil, null = true, default_function = nil, collation: nil, comment: nil, **)
19
+ @name = name.freeze
20
+ @sql_type_metadata = sql_type_metadata
21
+ @null = null
22
+ @default = default
23
+ @default_function = default_function
24
+ @collation = collation
25
+ @comment = comment
40
26
  end
41
27
 
42
28
  def has_default?
43
- !default.nil?
29
+ !default.nil? || default_function
30
+ end
31
+
32
+ def bigint?
33
+ /\Abigint\b/.match?(sql_type)
44
34
  end
45
35
 
46
36
  # Returns the human name of the column name.
@@ -51,30 +41,53 @@ module ActiveRecord
51
41
  Base.human_attribute_name(@name)
52
42
  end
53
43
 
54
- def with_type(type)
55
- dup.tap do |clone|
56
- clone.instance_variable_set('@cast_type', type)
57
- end
44
+ def init_with(coder)
45
+ @name = coder["name"]
46
+ @sql_type_metadata = coder["sql_type_metadata"]
47
+ @null = coder["null"]
48
+ @default = coder["default"]
49
+ @default_function = coder["default_function"]
50
+ @collation = coder["collation"]
51
+ @comment = coder["comment"]
52
+ end
53
+
54
+ def encode_with(coder)
55
+ coder["name"] = @name
56
+ coder["sql_type_metadata"] = @sql_type_metadata
57
+ coder["null"] = @null
58
+ coder["default"] = @default
59
+ coder["default_function"] = @default_function
60
+ coder["collation"] = @collation
61
+ coder["comment"] = @comment
58
62
  end
59
63
 
60
64
  def ==(other)
61
- other.name == name &&
62
- other.default == default &&
63
- other.cast_type == cast_type &&
64
- other.sql_type == sql_type &&
65
- other.null == null &&
66
- other.default_function == default_function
65
+ other.is_a?(Column) &&
66
+ name == other.name &&
67
+ default == other.default &&
68
+ sql_type_metadata == other.sql_type_metadata &&
69
+ null == other.null &&
70
+ default_function == other.default_function &&
71
+ collation == other.collation &&
72
+ comment == other.comment
67
73
  end
68
74
  alias :eql? :==
69
75
 
70
76
  def hash
71
- attributes_for_hash.hash
77
+ Column.hash ^
78
+ name.hash ^
79
+ default.hash ^
80
+ sql_type_metadata.hash ^
81
+ null.hash ^
82
+ default_function.hash ^
83
+ collation.hash ^
84
+ comment.hash
72
85
  end
86
+ end
73
87
 
74
- private
75
-
76
- def attributes_for_hash
77
- [self.class, name, default, cast_type, sql_type, null, default_function]
88
+ class NullColumn < Column
89
+ def initialize(name)
90
+ super(name, nil)
78
91
  end
79
92
  end
80
93
  end
@@ -1,22 +1,26 @@
1
- require 'uri'
2
- require 'active_support/core_ext/string/filters'
1
+ # frozen_string_literal: true
2
+
3
+ require "uri"
3
4
 
4
5
  module ActiveRecord
5
6
  module ConnectionAdapters
6
7
  class ConnectionSpecification #:nodoc:
7
- attr_reader :config, :adapter_method
8
+ attr_reader :name, :config, :adapter_method
8
9
 
9
- def initialize(config, adapter_method)
10
- @config, @adapter_method = config, adapter_method
10
+ def initialize(name, config, adapter_method)
11
+ @name, @config, @adapter_method = name, config, adapter_method
11
12
  end
12
13
 
13
14
  def initialize_dup(original)
14
15
  @config = original.config.dup
15
16
  end
16
17
 
18
+ def to_hash
19
+ @config.merge(name: @name)
20
+ end
21
+
17
22
  # Expands a connection string into a hash.
18
23
  class ConnectionUrlResolver # :nodoc:
19
-
20
24
  # == Example
21
25
  #
22
26
  # url = "postgresql://foo:bar@localhost:9000/foo_test?pool=5&timeout=3000"
@@ -34,11 +38,11 @@ module ActiveRecord
34
38
  def initialize(url)
35
39
  raise "Database URL cannot be empty" if url.blank?
36
40
  @uri = uri_parser.parse(url)
37
- @adapter = @uri.scheme.tr('-', '_')
41
+ @adapter = @uri.scheme && @uri.scheme.tr("-", "_")
38
42
  @adapter = "postgresql" if @adapter == "postgres"
39
43
 
40
44
  if @uri.opaque
41
- @uri.opaque, @query = @uri.opaque.split('?', 2)
45
+ @uri.opaque, @query = @uri.opaque.split("?", 2)
42
46
  else
43
47
  @query = @uri.query
44
48
  end
@@ -46,65 +50,63 @@ module ActiveRecord
46
50
 
47
51
  # Converts the given URL to a full connection hash.
48
52
  def to_hash
49
- config = raw_config.reject { |_,value| value.blank? }
50
- config.map { |key,value| config[key] = uri_parser.unescape(value) if value.is_a? String }
53
+ config = raw_config.reject { |_, value| value.blank? }
54
+ config.map { |key, value| config[key] = uri_parser.unescape(value) if value.is_a? String }
51
55
  config
52
56
  end
53
57
 
54
58
  private
55
59
 
56
- def uri
57
- @uri
58
- end
60
+ attr_reader :uri
59
61
 
60
- def uri_parser
61
- @uri_parser ||= URI::Parser.new
62
- end
62
+ def uri_parser
63
+ @uri_parser ||= URI::Parser.new
64
+ end
63
65
 
64
- # Converts the query parameters of the URI into a hash.
65
- #
66
- # "localhost?pool=5&reaping_frequency=2"
67
- # # => { "pool" => "5", "reaping_frequency" => "2" }
68
- #
69
- # returns empty hash if no query present.
70
- #
71
- # "localhost"
72
- # # => {}
73
- def query_hash
74
- Hash[(@query || '').split("&").map { |pair| pair.split("=") }]
75
- end
66
+ # Converts the query parameters of the URI into a hash.
67
+ #
68
+ # "localhost?pool=5&reaping_frequency=2"
69
+ # # => { "pool" => "5", "reaping_frequency" => "2" }
70
+ #
71
+ # returns empty hash if no query present.
72
+ #
73
+ # "localhost"
74
+ # # => {}
75
+ def query_hash
76
+ Hash[(@query || "").split("&").map { |pair| pair.split("=") }]
77
+ end
76
78
 
77
- def raw_config
78
- if uri.opaque
79
- query_hash.merge({
80
- "adapter" => @adapter,
81
- "database" => uri.opaque })
82
- else
83
- query_hash.merge({
84
- "adapter" => @adapter,
85
- "username" => uri.user,
86
- "password" => uri.password,
87
- "port" => uri.port,
88
- "database" => database_from_path,
89
- "host" => uri.hostname })
79
+ def raw_config
80
+ if uri.opaque
81
+ query_hash.merge(
82
+ "adapter" => @adapter,
83
+ "database" => uri.opaque)
84
+ else
85
+ query_hash.merge(
86
+ "adapter" => @adapter,
87
+ "username" => uri.user,
88
+ "password" => uri.password,
89
+ "port" => uri.port,
90
+ "database" => database_from_path,
91
+ "host" => uri.hostname)
92
+ end
90
93
  end
91
- end
92
94
 
93
- # Returns name of the database.
94
- def database_from_path
95
- if @adapter == 'sqlite3'
96
- # 'sqlite3:/foo' is absolute, because that makes sense. The
97
- # corresponding relative version, 'sqlite3:foo', is handled
98
- # elsewhere, as an "opaque".
95
+ # Returns name of the database.
96
+ def database_from_path
97
+ if @adapter == "sqlite3"
98
+ # 'sqlite3:/foo' is absolute, because that makes sense. The
99
+ # corresponding relative version, 'sqlite3:foo', is handled
100
+ # elsewhere, as an "opaque".
99
101
 
100
- uri.path
101
- else
102
- # Only SQLite uses a filename as the "database" name; for
103
- # anything else, a leading slash would be silly.
102
+ uri.path
103
+ else
104
+ # Only SQLite uses a filename as the "database" name; for
105
+ # anything else, a leading slash would be silly.
104
106
 
105
- uri.path.sub(%r{^/}, "")
107
+ uri.path.sub(%r{^/}, "")
108
+ end
106
109
  end
107
- end
108
110
  end
109
111
 
110
112
  ##
@@ -112,8 +114,7 @@ module ActiveRecord
112
114
  class Resolver # :nodoc:
113
115
  attr_reader :configurations
114
116
 
115
- # Accepts a hash two layers deep, keys on the first layer represent
116
- # environments such as "production". Keys must be strings.
117
+ # Accepts a list of db config objects.
117
118
  def initialize(configurations)
118
119
  @configurations = configurations
119
120
  end
@@ -134,25 +135,14 @@ module ActiveRecord
134
135
  # Resolver.new(configurations).resolve(:production)
135
136
  # # => { "host" => "localhost", "database" => "foo", "adapter" => "postgresql" }
136
137
  #
137
- def resolve(config)
138
- if config
139
- resolve_connection config
140
- elsif env = ActiveRecord::ConnectionHandling::RAILS_ENV.call
141
- resolve_symbol_connection env.to_sym
138
+ def resolve(config_or_env, pool_name = nil)
139
+ if config_or_env
140
+ resolve_connection config_or_env, pool_name
142
141
  else
143
142
  raise AdapterNotSpecified
144
143
  end
145
144
  end
146
145
 
147
- # Expands each key in @configurations hash into fully resolved hash
148
- def resolve_all
149
- config = configurations.dup
150
- config.each do |key, value|
151
- config[key] = resolve(value) if value
152
- end
153
- config
154
- end
155
-
156
146
  # Returns an instance of ConnectionSpecification for a given adapter.
157
147
  # Accepts a hash one layer deep that contains all connection information.
158
148
  #
@@ -166,109 +156,141 @@ module ActiveRecord
166
156
  # # => { "host" => "localhost", "database" => "foo", "adapter" => "sqlite3" }
167
157
  #
168
158
  def spec(config)
169
- spec = resolve(config).symbolize_keys
159
+ pool_name = config if config.is_a?(Symbol)
160
+
161
+ spec = resolve(config, pool_name).symbolize_keys
170
162
 
171
163
  raise(AdapterNotSpecified, "database configuration does not specify adapter") unless spec.key?(:adapter)
172
164
 
165
+ # Require the adapter itself and give useful feedback about
166
+ # 1. Missing adapter gems and
167
+ # 2. Adapter gems' missing dependencies.
173
168
  path_to_adapter = "active_record/connection_adapters/#{spec[:adapter]}_adapter"
174
169
  begin
175
170
  require path_to_adapter
176
- rescue Gem::LoadError => e
177
- raise Gem::LoadError, "Specified '#{spec[:adapter]}' for database adapter, but the gem is not loaded. Add `gem '#{e.name}'` to your Gemfile (and ensure its version is at the minimum required by ActiveRecord)."
178
171
  rescue LoadError => e
179
- raise LoadError, "Could not load '#{path_to_adapter}'. Make sure that the adapter in config/database.yml is valid. If you use an adapter other than 'mysql', 'mysql2', 'postgresql' or 'sqlite3' add the necessary adapter gem to the Gemfile.", e.backtrace
172
+ # We couldn't require the adapter itself. Raise an exception that
173
+ # points out config typos and missing gems.
174
+ if e.path == path_to_adapter
175
+ # We can assume that a non-builtin adapter was specified, so it's
176
+ # either misspelled or missing from Gemfile.
177
+ raise LoadError, "Could not load the '#{spec[:adapter]}' Active Record adapter. Ensure that the adapter is spelled correctly in config/database.yml and that you've added the necessary adapter gem to your Gemfile.", e.backtrace
178
+
179
+ # Bubbled up from the adapter require. Prefix the exception message
180
+ # with some guidance about how to address it and reraise.
181
+ else
182
+ raise LoadError, "Error loading the '#{spec[:adapter]}' Active Record adapter. Missing a gem it depends on? #{e.message}", e.backtrace
183
+ end
180
184
  end
181
185
 
182
186
  adapter_method = "#{spec[:adapter]}_connection"
183
- ConnectionSpecification.new(spec, adapter_method)
187
+
188
+ unless ActiveRecord::Base.respond_to?(adapter_method)
189
+ raise AdapterNotFound, "database configuration specifies nonexistent #{spec.config[:adapter]} adapter"
190
+ end
191
+
192
+ ConnectionSpecification.new(spec.delete(:name) || "primary", spec, adapter_method)
184
193
  end
185
194
 
186
195
  private
187
-
188
- # Returns fully resolved connection, accepts hash, string or symbol.
189
- # Always returns a hash.
190
- #
191
- # == Examples
192
- #
193
- # Symbol representing current environment.
194
- #
195
- # Resolver.new("production" => {}).resolve_connection(:production)
196
- # # => {}
197
- #
198
- # One layer deep hash of connection values.
199
- #
200
- # Resolver.new({}).resolve_connection("adapter" => "sqlite3")
201
- # # => { "adapter" => "sqlite3" }
202
- #
203
- # Connection URL.
204
- #
205
- # Resolver.new({}).resolve_connection("postgresql://localhost/foo")
206
- # # => { "host" => "localhost", "database" => "foo", "adapter" => "postgresql" }
207
- #
208
- def resolve_connection(spec)
209
- case spec
210
- when Symbol
211
- resolve_symbol_connection spec
212
- when String
213
- resolve_string_connection spec
214
- when Hash
215
- resolve_hash_connection spec
196
+ # Returns fully resolved connection, accepts hash, string or symbol.
197
+ # Always returns a hash.
198
+ #
199
+ # == Examples
200
+ #
201
+ # Symbol representing current environment.
202
+ #
203
+ # Resolver.new("production" => {}).resolve_connection(:production)
204
+ # # => {}
205
+ #
206
+ # One layer deep hash of connection values.
207
+ #
208
+ # Resolver.new({}).resolve_connection("adapter" => "sqlite3")
209
+ # # => { "adapter" => "sqlite3" }
210
+ #
211
+ # Connection URL.
212
+ #
213
+ # Resolver.new({}).resolve_connection("postgresql://localhost/foo")
214
+ # # => { "host" => "localhost", "database" => "foo", "adapter" => "postgresql" }
215
+ #
216
+ def resolve_connection(config_or_env, pool_name = nil)
217
+ case config_or_env
218
+ when Symbol
219
+ resolve_symbol_connection config_or_env, pool_name
220
+ when String
221
+ resolve_url_connection config_or_env
222
+ when Hash
223
+ resolve_hash_connection config_or_env
224
+ else
225
+ raise TypeError, "Invalid type for configuration. Expected Symbol, String, or Hash. Got #{config_or_env.inspect}"
226
+ end
216
227
  end
217
- end
218
228
 
219
- def resolve_string_connection(spec)
220
- # Rails has historically accepted a string to mean either
221
- # an environment key or a URL spec, so we have deprecated
222
- # this ambiguous behaviour and in the future this function
223
- # can be removed in favor of resolve_url_connection.
224
- if configurations.key?(spec) || spec !~ /:/
225
- ActiveSupport::Deprecation.warn(<<-MSG.squish)
226
- Passing a string to ActiveRecord::Base.establish_connection for a
227
- configuration lookup is deprecated, please pass a symbol
228
- (#{spec.to_sym.inspect}) instead.
229
- MSG
230
-
231
- resolve_symbol_connection(spec)
232
- else
233
- resolve_url_connection(spec)
229
+ # Takes the environment such as +:production+ or +:development+ and a
230
+ # pool name the corresponds to the name given by the connection pool
231
+ # to the connection. That pool name is merged into the hash with the
232
+ # name key.
233
+ #
234
+ # This requires that the @configurations was initialized with a key that
235
+ # matches.
236
+ #
237
+ # configurations = #<ActiveRecord::DatabaseConfigurations:0x00007fd9fdace3e0
238
+ # @configurations=[
239
+ # #<ActiveRecord::DatabaseConfigurations::HashConfig:0x00007fd9fdace250
240
+ # @env_name="production", @spec_name="primary", @config={"database"=>"my_db"}>
241
+ # ]>
242
+ #
243
+ # Resolver.new(configurations).resolve_symbol_connection(:production, "primary")
244
+ # # => { "database" => "my_db" }
245
+ def resolve_symbol_connection(env_name, pool_name)
246
+ db_config = configurations.find_db_config(env_name)
247
+
248
+ if db_config
249
+ resolve_connection(db_config.config).merge("name" => pool_name.to_s)
250
+ else
251
+ raise AdapterNotSpecified, <<~MSG
252
+ The `#{env_name}` database is not configured for the `#{ActiveRecord::ConnectionHandling::DEFAULT_ENV.call}` environment.
253
+
254
+ Available databases configurations are:
255
+
256
+ #{build_configuration_sentence}
257
+ MSG
258
+ end
234
259
  end
235
- end
236
260
 
237
- # Takes the environment such as +:production+ or +:development+.
238
- # This requires that the @configurations was initialized with a key that
239
- # matches.
240
- #
241
- # Resolver.new("production" => {}).resolve_symbol_connection(:production)
242
- # # => {}
243
- #
244
- def resolve_symbol_connection(spec)
245
- if config = configurations[spec.to_s]
246
- resolve_connection(config)
247
- else
248
- raise(AdapterNotSpecified, "'#{spec}' database is not configured. Available: #{configurations.keys.inspect}")
261
+ def build_configuration_sentence # :nodoc:
262
+ configs = configurations.configs_for(include_replicas: true)
263
+
264
+ configs.group_by(&:env_name).map do |env, config|
265
+ namespaces = config.map(&:spec_name)
266
+ if namespaces.size > 1
267
+ "#{env}: #{namespaces.join(", ")}"
268
+ else
269
+ env
270
+ end
271
+ end.join("\n")
249
272
  end
250
- end
251
273
 
252
- # Accepts a hash. Expands the "url" key that contains a
253
- # URL database connection to a full connection
254
- # hash and merges with the rest of the hash.
255
- # Connection details inside of the "url" key win any merge conflicts
256
- def resolve_hash_connection(spec)
257
- if spec["url"] && spec["url"] !~ /^jdbc:/
258
- connection_hash = resolve_url_connection(spec.delete("url"))
259
- spec.merge!(connection_hash)
274
+ # Accepts a hash. Expands the "url" key that contains a
275
+ # URL database connection to a full connection
276
+ # hash and merges with the rest of the hash.
277
+ # Connection details inside of the "url" key win any merge conflicts
278
+ def resolve_hash_connection(spec)
279
+ if spec["url"] && spec["url"] !~ /^jdbc:/
280
+ connection_hash = resolve_url_connection(spec.delete("url"))
281
+ spec.merge!(connection_hash)
282
+ end
283
+ spec
260
284
  end
261
- spec
262
- end
263
285
 
264
- # Takes a connection URL.
265
- #
266
- # Resolver.new({}).resolve_url_connection("postgresql://localhost/foo")
267
- # # => { "host" => "localhost", "database" => "foo", "adapter" => "postgresql" }
268
- #
269
- def resolve_url_connection(url)
270
- ConnectionUrlResolver.new(url).to_hash
271
- end
286
+ # Takes a connection URL.
287
+ #
288
+ # Resolver.new({}).resolve_url_connection("postgresql://localhost/foo")
289
+ # # => { "host" => "localhost", "database" => "foo", "adapter" => "postgresql" }
290
+ #
291
+ def resolve_url_connection(url)
292
+ ConnectionUrlResolver.new(url).to_hash
293
+ end
272
294
  end
273
295
  end
274
296
  end