activerecord 4.2.0 → 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 -971
  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/aggregations.rb +267 -248
  8. data/lib/active_record/association_relation.rb +24 -6
  9. data/lib/active_record/associations/alias_tracker.rb +29 -35
  10. data/lib/active_record/associations/association.rb +135 -56
  11. data/lib/active_record/associations/association_scope.rb +103 -131
  12. data/lib/active_record/associations/belongs_to_association.rb +67 -54
  13. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -12
  14. data/lib/active_record/associations/builder/association.rb +27 -40
  15. data/lib/active_record/associations/builder/belongs_to.rb +69 -55
  16. data/lib/active_record/associations/builder/collection_association.rb +10 -29
  17. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +60 -70
  18. data/lib/active_record/associations/builder/has_many.rb +8 -4
  19. data/lib/active_record/associations/builder/has_one.rb +46 -5
  20. data/lib/active_record/associations/builder/singular_association.rb +16 -10
  21. data/lib/active_record/associations/collection_association.rb +138 -274
  22. data/lib/active_record/associations/collection_proxy.rb +252 -151
  23. data/lib/active_record/associations/foreign_association.rb +20 -0
  24. data/lib/active_record/associations/has_many_association.rb +35 -83
  25. data/lib/active_record/associations/has_many_through_association.rb +62 -80
  26. data/lib/active_record/associations/has_one_association.rb +62 -49
  27. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  28. data/lib/active_record/associations/join_dependency/join_association.rb +38 -80
  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 +138 -162
  32. data/lib/active_record/associations/preloader/association.rb +90 -119
  33. data/lib/active_record/associations/preloader/through_association.rb +85 -65
  34. data/lib/active_record/associations/preloader.rb +92 -94
  35. data/lib/active_record/associations/singular_association.rb +18 -45
  36. data/lib/active_record/associations/through_association.rb +48 -23
  37. data/lib/active_record/associations.rb +1737 -1596
  38. data/lib/active_record/attribute_assignment.rb +56 -183
  39. data/lib/active_record/attribute_decorators.rb +39 -15
  40. data/lib/active_record/attribute_methods/before_type_cast.rb +15 -5
  41. data/lib/active_record/attribute_methods/dirty.rb +174 -134
  42. data/lib/active_record/attribute_methods/primary_key.rb +91 -83
  43. data/lib/active_record/attribute_methods/query.rb +6 -5
  44. data/lib/active_record/attribute_methods/read.rb +20 -76
  45. data/lib/active_record/attribute_methods/serialization.rb +40 -20
  46. data/lib/active_record/attribute_methods/time_zone_conversion.rb +62 -36
  47. data/lib/active_record/attribute_methods/write.rb +33 -55
  48. data/lib/active_record/attribute_methods.rb +124 -143
  49. data/lib/active_record/attributes.rb +214 -74
  50. data/lib/active_record/autosave_association.rb +115 -46
  51. data/lib/active_record/base.rb +60 -49
  52. data/lib/active_record/callbacks.rb +100 -74
  53. data/lib/active_record/coders/json.rb +3 -1
  54. data/lib/active_record/coders/yaml_column.rb +24 -12
  55. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +796 -290
  56. data/lib/active_record/connection_adapters/abstract/database_limits.rb +26 -8
  57. data/lib/active_record/connection_adapters/abstract/database_statements.rb +247 -108
  58. data/lib/active_record/connection_adapters/abstract/query_cache.rb +82 -23
  59. data/lib/active_record/connection_adapters/abstract/quoting.rb +171 -53
  60. data/lib/active_record/connection_adapters/abstract/savepoints.rb +6 -4
  61. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +74 -46
  62. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +366 -227
  63. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +79 -36
  64. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +706 -222
  65. data/lib/active_record/connection_adapters/abstract/transaction.rb +191 -87
  66. data/lib/active_record/connection_adapters/abstract_adapter.rb +468 -194
  67. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +535 -597
  68. data/lib/active_record/connection_adapters/column.rb +56 -43
  69. data/lib/active_record/connection_adapters/connection_specification.rb +174 -152
  70. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +29 -0
  71. data/lib/active_record/connection_adapters/mysql/column.rb +27 -0
  72. data/lib/active_record/connection_adapters/mysql/database_statements.rb +200 -0
  73. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +72 -0
  74. data/lib/active_record/connection_adapters/mysql/quoting.rb +81 -0
  75. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +72 -0
  76. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +95 -0
  77. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +88 -0
  78. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +264 -0
  79. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +31 -0
  80. data/lib/active_record/connection_adapters/mysql2_adapter.rb +59 -195
  81. data/lib/active_record/connection_adapters/postgresql/column.rb +21 -11
  82. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +65 -115
  83. data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +44 -0
  84. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +50 -57
  85. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +9 -8
  86. data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
  87. data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +5 -2
  88. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +5 -1
  89. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +13 -1
  90. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +9 -13
  91. data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
  92. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +7 -3
  93. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +31 -19
  94. data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
  95. data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
  96. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +45 -0
  97. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -9
  98. data/lib/active_record/connection_adapters/postgresql/oid/{integer.rb → oid.rb} +6 -2
  99. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +33 -11
  100. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +52 -34
  101. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -1
  102. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +67 -51
  103. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +10 -5
  104. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +3 -1
  105. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +3 -1
  106. data/lib/active_record/connection_adapters/postgresql/oid.rb +23 -25
  107. data/lib/active_record/connection_adapters/postgresql/quoting.rb +144 -47
  108. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +27 -14
  109. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -0
  110. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +178 -108
  111. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +50 -0
  112. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +474 -286
  113. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +36 -0
  114. data/lib/active_record/connection_adapters/postgresql/utils.rb +12 -8
  115. data/lib/active_record/connection_adapters/postgresql_adapter.rb +558 -363
  116. data/lib/active_record/connection_adapters/schema_cache.rb +72 -25
  117. data/lib/active_record/connection_adapters/sql_type_metadata.rb +37 -0
  118. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +118 -0
  119. data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +21 -0
  120. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +103 -0
  121. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +17 -0
  122. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +19 -0
  123. data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +18 -0
  124. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +137 -0
  125. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +288 -359
  126. data/lib/active_record/connection_adapters/statement_pool.rb +34 -13
  127. data/lib/active_record/connection_handling.rb +176 -41
  128. data/lib/active_record/core.rb +266 -233
  129. data/lib/active_record/counter_cache.rb +68 -50
  130. data/lib/active_record/database_configurations/database_config.rb +37 -0
  131. data/lib/active_record/database_configurations/hash_config.rb +50 -0
  132. data/lib/active_record/database_configurations/url_config.rb +79 -0
  133. data/lib/active_record/database_configurations.rb +233 -0
  134. data/lib/active_record/define_callbacks.rb +22 -0
  135. data/lib/active_record/dynamic_matchers.rb +87 -105
  136. data/lib/active_record/enum.rb +164 -88
  137. data/lib/active_record/errors.rb +189 -53
  138. data/lib/active_record/explain.rb +23 -11
  139. data/lib/active_record/explain_registry.rb +4 -2
  140. data/lib/active_record/explain_subscriber.rb +11 -6
  141. data/lib/active_record/fixture_set/file.rb +35 -9
  142. data/lib/active_record/fixture_set/model_metadata.rb +33 -0
  143. data/lib/active_record/fixture_set/render_context.rb +17 -0
  144. data/lib/active_record/fixture_set/table_row.rb +153 -0
  145. data/lib/active_record/fixture_set/table_rows.rb +47 -0
  146. data/lib/active_record/fixtures.rb +226 -495
  147. data/lib/active_record/gem_version.rb +4 -2
  148. data/lib/active_record/inheritance.rb +158 -112
  149. data/lib/active_record/insert_all.rb +179 -0
  150. data/lib/active_record/integration.rb +123 -29
  151. data/lib/active_record/internal_metadata.rb +53 -0
  152. data/lib/active_record/legacy_yaml_adapter.rb +48 -0
  153. data/lib/active_record/locale/en.yml +3 -2
  154. data/lib/active_record/locking/optimistic.rb +91 -98
  155. data/lib/active_record/locking/pessimistic.rb +18 -6
  156. data/lib/active_record/log_subscriber.rb +76 -33
  157. data/lib/active_record/middleware/database_selector/resolver/session.rb +45 -0
  158. data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
  159. data/lib/active_record/middleware/database_selector.rb +75 -0
  160. data/lib/active_record/migration/command_recorder.rb +177 -90
  161. data/lib/active_record/migration/compatibility.rb +244 -0
  162. data/lib/active_record/migration/join_table.rb +8 -6
  163. data/lib/active_record/migration.rb +634 -288
  164. data/lib/active_record/model_schema.rb +314 -112
  165. data/lib/active_record/nested_attributes.rb +266 -214
  166. data/lib/active_record/no_touching.rb +15 -2
  167. data/lib/active_record/null_relation.rb +24 -37
  168. data/lib/active_record/persistence.rb +559 -124
  169. data/lib/active_record/query_cache.rb +19 -23
  170. data/lib/active_record/querying.rb +43 -29
  171. data/lib/active_record/railtie.rb +148 -47
  172. data/lib/active_record/railties/collection_cache_association_loading.rb +34 -0
  173. data/lib/active_record/railties/console_sandbox.rb +2 -0
  174. data/lib/active_record/railties/controller_runtime.rb +34 -33
  175. data/lib/active_record/railties/databases.rake +338 -202
  176. data/lib/active_record/readonly_attributes.rb +5 -4
  177. data/lib/active_record/reflection.rb +460 -299
  178. data/lib/active_record/relation/batches/batch_enumerator.rb +69 -0
  179. data/lib/active_record/relation/batches.rb +207 -55
  180. data/lib/active_record/relation/calculations.rb +269 -248
  181. data/lib/active_record/relation/delegation.rb +70 -80
  182. data/lib/active_record/relation/finder_methods.rb +279 -255
  183. data/lib/active_record/relation/from_clause.rb +26 -0
  184. data/lib/active_record/relation/merger.rb +83 -69
  185. data/lib/active_record/relation/predicate_builder/array_handler.rb +27 -25
  186. data/lib/active_record/relation/predicate_builder/association_query_value.rb +43 -0
  187. data/lib/active_record/relation/predicate_builder/base_handler.rb +18 -0
  188. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +19 -0
  189. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +53 -0
  190. data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -0
  191. data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
  192. data/lib/active_record/relation/predicate_builder.rb +116 -92
  193. data/lib/active_record/relation/query_attribute.rb +50 -0
  194. data/lib/active_record/relation/query_methods.rb +574 -391
  195. data/lib/active_record/relation/record_fetch_warning.rb +51 -0
  196. data/lib/active_record/relation/spawn_methods.rb +18 -16
  197. data/lib/active_record/relation/where_clause.rb +190 -0
  198. data/lib/active_record/relation/where_clause_factory.rb +33 -0
  199. data/lib/active_record/relation.rb +518 -340
  200. data/lib/active_record/result.rb +79 -42
  201. data/lib/active_record/runtime_registry.rb +6 -4
  202. data/lib/active_record/sanitization.rb +144 -121
  203. data/lib/active_record/schema.rb +21 -24
  204. data/lib/active_record/schema_dumper.rb +112 -93
  205. data/lib/active_record/schema_migration.rb +24 -20
  206. data/lib/active_record/scoping/default.rb +101 -84
  207. data/lib/active_record/scoping/named.rb +86 -33
  208. data/lib/active_record/scoping.rb +45 -26
  209. data/lib/active_record/secure_token.rb +40 -0
  210. data/lib/active_record/serialization.rb +5 -5
  211. data/lib/active_record/statement_cache.rb +73 -36
  212. data/lib/active_record/store.rb +127 -42
  213. data/lib/active_record/suppressor.rb +61 -0
  214. data/lib/active_record/table_metadata.rb +75 -0
  215. data/lib/active_record/tasks/database_tasks.rb +309 -99
  216. data/lib/active_record/tasks/mysql_database_tasks.rb +58 -88
  217. data/lib/active_record/tasks/postgresql_database_tasks.rb +82 -31
  218. data/lib/active_record/tasks/sqlite_database_tasks.rb +38 -16
  219. data/lib/active_record/test_databases.rb +23 -0
  220. data/lib/active_record/test_fixtures.rb +224 -0
  221. data/lib/active_record/timestamp.rb +86 -40
  222. data/lib/active_record/touch_later.rb +66 -0
  223. data/lib/active_record/transactions.rb +215 -139
  224. data/lib/active_record/translation.rb +3 -1
  225. data/lib/active_record/type/adapter_specific_registry.rb +129 -0
  226. data/lib/active_record/type/date.rb +4 -41
  227. data/lib/active_record/type/date_time.rb +4 -38
  228. data/lib/active_record/type/decimal_without_scale.rb +6 -2
  229. data/lib/active_record/type/hash_lookup_type_map.rb +13 -5
  230. data/lib/active_record/type/internal/timezone.rb +17 -0
  231. data/lib/active_record/type/json.rb +30 -0
  232. data/lib/active_record/type/serialized.rb +30 -15
  233. data/lib/active_record/type/text.rb +2 -2
  234. data/lib/active_record/type/time.rb +11 -16
  235. data/lib/active_record/type/type_map.rb +15 -17
  236. data/lib/active_record/type/unsigned_integer.rb +9 -7
  237. data/lib/active_record/type.rb +78 -23
  238. data/lib/active_record/type_caster/connection.rb +34 -0
  239. data/lib/active_record/type_caster/map.rb +20 -0
  240. data/lib/active_record/type_caster.rb +9 -0
  241. data/lib/active_record/validations/absence.rb +25 -0
  242. data/lib/active_record/validations/associated.rb +13 -4
  243. data/lib/active_record/validations/length.rb +26 -0
  244. data/lib/active_record/validations/presence.rb +14 -13
  245. data/lib/active_record/validations/uniqueness.rb +43 -46
  246. data/lib/active_record/validations.rb +39 -35
  247. data/lib/active_record/version.rb +3 -1
  248. data/lib/active_record.rb +43 -21
  249. data/lib/arel/alias_predication.rb +9 -0
  250. data/lib/arel/attributes/attribute.rb +37 -0
  251. data/lib/arel/attributes.rb +22 -0
  252. data/lib/arel/collectors/bind.rb +24 -0
  253. data/lib/arel/collectors/composite.rb +31 -0
  254. data/lib/arel/collectors/plain_string.rb +20 -0
  255. data/lib/arel/collectors/sql_string.rb +20 -0
  256. data/lib/arel/collectors/substitute_binds.rb +28 -0
  257. data/lib/arel/crud.rb +42 -0
  258. data/lib/arel/delete_manager.rb +18 -0
  259. data/lib/arel/errors.rb +9 -0
  260. data/lib/arel/expressions.rb +29 -0
  261. data/lib/arel/factory_methods.rb +49 -0
  262. data/lib/arel/insert_manager.rb +49 -0
  263. data/lib/arel/math.rb +45 -0
  264. data/lib/arel/nodes/and.rb +32 -0
  265. data/lib/arel/nodes/ascending.rb +23 -0
  266. data/lib/arel/nodes/binary.rb +52 -0
  267. data/lib/arel/nodes/bind_param.rb +36 -0
  268. data/lib/arel/nodes/case.rb +55 -0
  269. data/lib/arel/nodes/casted.rb +50 -0
  270. data/lib/arel/nodes/comment.rb +29 -0
  271. data/lib/arel/nodes/count.rb +12 -0
  272. data/lib/arel/nodes/delete_statement.rb +45 -0
  273. data/lib/arel/nodes/descending.rb +23 -0
  274. data/lib/arel/nodes/equality.rb +18 -0
  275. data/lib/arel/nodes/extract.rb +24 -0
  276. data/lib/arel/nodes/false.rb +16 -0
  277. data/lib/arel/nodes/full_outer_join.rb +8 -0
  278. data/lib/arel/nodes/function.rb +44 -0
  279. data/lib/arel/nodes/grouping.rb +8 -0
  280. data/lib/arel/nodes/in.rb +8 -0
  281. data/lib/arel/nodes/infix_operation.rb +80 -0
  282. data/lib/arel/nodes/inner_join.rb +8 -0
  283. data/lib/arel/nodes/insert_statement.rb +37 -0
  284. data/lib/arel/nodes/join_source.rb +20 -0
  285. data/lib/arel/nodes/matches.rb +18 -0
  286. data/lib/arel/nodes/named_function.rb +23 -0
  287. data/lib/arel/nodes/node.rb +50 -0
  288. data/lib/arel/nodes/node_expression.rb +13 -0
  289. data/lib/arel/nodes/outer_join.rb +8 -0
  290. data/lib/arel/nodes/over.rb +15 -0
  291. data/lib/arel/nodes/regexp.rb +16 -0
  292. data/lib/arel/nodes/right_outer_join.rb +8 -0
  293. data/lib/arel/nodes/select_core.rb +67 -0
  294. data/lib/arel/nodes/select_statement.rb +41 -0
  295. data/lib/arel/nodes/sql_literal.rb +16 -0
  296. data/lib/arel/nodes/string_join.rb +11 -0
  297. data/lib/arel/nodes/table_alias.rb +27 -0
  298. data/lib/arel/nodes/terminal.rb +16 -0
  299. data/lib/arel/nodes/true.rb +16 -0
  300. data/lib/arel/nodes/unary.rb +45 -0
  301. data/lib/arel/nodes/unary_operation.rb +20 -0
  302. data/lib/arel/nodes/unqualified_column.rb +22 -0
  303. data/lib/arel/nodes/update_statement.rb +41 -0
  304. data/lib/arel/nodes/values_list.rb +9 -0
  305. data/lib/arel/nodes/window.rb +126 -0
  306. data/lib/arel/nodes/with.rb +11 -0
  307. data/lib/arel/nodes.rb +68 -0
  308. data/lib/arel/order_predications.rb +13 -0
  309. data/lib/arel/predications.rb +257 -0
  310. data/lib/arel/select_manager.rb +271 -0
  311. data/lib/arel/table.rb +110 -0
  312. data/lib/arel/tree_manager.rb +72 -0
  313. data/lib/arel/update_manager.rb +34 -0
  314. data/lib/arel/visitors/depth_first.rb +204 -0
  315. data/lib/arel/visitors/dot.rb +297 -0
  316. data/lib/arel/visitors/ibm_db.rb +34 -0
  317. data/lib/arel/visitors/informix.rb +62 -0
  318. data/lib/arel/visitors/mssql.rb +157 -0
  319. data/lib/arel/visitors/mysql.rb +83 -0
  320. data/lib/arel/visitors/oracle.rb +159 -0
  321. data/lib/arel/visitors/oracle12.rb +66 -0
  322. data/lib/arel/visitors/postgresql.rb +110 -0
  323. data/lib/arel/visitors/sqlite.rb +39 -0
  324. data/lib/arel/visitors/to_sql.rb +889 -0
  325. data/lib/arel/visitors/visitor.rb +46 -0
  326. data/lib/arel/visitors/where_sql.rb +23 -0
  327. data/lib/arel/visitors.rb +20 -0
  328. data/lib/arel/window_predications.rb +9 -0
  329. data/lib/arel.rb +51 -0
  330. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
  331. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +5 -0
  332. data/lib/rails/generators/active_record/migration/migration_generator.rb +42 -37
  333. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +24 -0
  334. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +11 -8
  335. data/lib/rails/generators/active_record/migration.rb +31 -1
  336. data/lib/rails/generators/active_record/model/model_generator.rb +19 -22
  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 +166 -60
  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_set/builder.rb +0 -86
  349. data/lib/active_record/attribute_set.rb +0 -77
  350. data/lib/active_record/connection_adapters/mysql_adapter.rb +0 -491
  351. data/lib/active_record/connection_adapters/postgresql/array_parser.rb +0 -93
  352. data/lib/active_record/connection_adapters/postgresql/oid/float.rb +0 -21
  353. data/lib/active_record/connection_adapters/postgresql/oid/infinity.rb +0 -13
  354. data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -35
  355. data/lib/active_record/connection_adapters/postgresql/oid/time.rb +0 -11
  356. data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
  357. data/lib/active_record/serializers/xml_serializer.rb +0 -193
  358. data/lib/active_record/type/big_integer.rb +0 -13
  359. data/lib/active_record/type/binary.rb +0 -50
  360. data/lib/active_record/type/boolean.rb +0 -30
  361. data/lib/active_record/type/decimal.rb +0 -40
  362. data/lib/active_record/type/decorator.rb +0 -14
  363. data/lib/active_record/type/float.rb +0 -19
  364. data/lib/active_record/type/integer.rb +0 -55
  365. data/lib/active_record/type/mutable.rb +0 -16
  366. data/lib/active_record/type/numeric.rb +0 -36
  367. data/lib/active_record/type/string.rb +0 -36
  368. data/lib/active_record/type/time_value.rb +0 -38
  369. data/lib/active_record/type/value.rb +0 -101
  370. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +0 -22
  371. data/lib/rails/generators/active_record/model/templates/model.rb +0 -10
  372. /data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
@@ -0,0 +1,129 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_model/type/registry"
4
+
5
+ module ActiveRecord
6
+ # :stopdoc:
7
+ module Type
8
+ class AdapterSpecificRegistry < ActiveModel::Type::Registry
9
+ def add_modifier(options, klass, **args)
10
+ registrations << DecorationRegistration.new(options, klass, **args)
11
+ end
12
+
13
+ private
14
+
15
+ def registration_klass
16
+ Registration
17
+ end
18
+
19
+ def find_registration(symbol, *args)
20
+ registrations
21
+ .select { |registration| registration.matches?(symbol, *args) }
22
+ .max
23
+ end
24
+ end
25
+
26
+ class Registration
27
+ def initialize(name, block, adapter: nil, override: nil)
28
+ @name = name
29
+ @block = block
30
+ @adapter = adapter
31
+ @override = override
32
+ end
33
+
34
+ def call(_registry, *args, adapter: nil, **kwargs)
35
+ if kwargs.any? # https://bugs.ruby-lang.org/issues/10856
36
+ block.call(*args, **kwargs)
37
+ else
38
+ block.call(*args)
39
+ end
40
+ end
41
+
42
+ def matches?(type_name, *args, **kwargs)
43
+ type_name == name && matches_adapter?(**kwargs)
44
+ end
45
+
46
+ def <=>(other)
47
+ if conflicts_with?(other)
48
+ raise TypeConflictError.new("Type #{name} was registered for all
49
+ adapters, but shadows a native type with
50
+ the same name for #{other.adapter}".squish)
51
+ end
52
+ priority <=> other.priority
53
+ end
54
+
55
+ protected
56
+
57
+ attr_reader :name, :block, :adapter, :override
58
+
59
+ def priority
60
+ result = 0
61
+ if adapter
62
+ result |= 1
63
+ end
64
+ if override
65
+ result |= 2
66
+ end
67
+ result
68
+ end
69
+
70
+ def priority_except_adapter
71
+ priority & 0b111111100
72
+ end
73
+
74
+ private
75
+
76
+ def matches_adapter?(adapter: nil, **)
77
+ (self.adapter.nil? || adapter == self.adapter)
78
+ end
79
+
80
+ def conflicts_with?(other)
81
+ same_priority_except_adapter?(other) &&
82
+ has_adapter_conflict?(other)
83
+ end
84
+
85
+ def same_priority_except_adapter?(other)
86
+ priority_except_adapter == other.priority_except_adapter
87
+ end
88
+
89
+ def has_adapter_conflict?(other)
90
+ (override.nil? && other.adapter) ||
91
+ (adapter && other.override.nil?)
92
+ end
93
+ end
94
+
95
+ class DecorationRegistration < Registration
96
+ def initialize(options, klass, adapter: nil)
97
+ @options = options
98
+ @klass = klass
99
+ @adapter = adapter
100
+ end
101
+
102
+ def call(registry, *args, **kwargs)
103
+ subtype = registry.lookup(*args, **kwargs.except(*options.keys))
104
+ klass.new(subtype)
105
+ end
106
+
107
+ def matches?(*args, **kwargs)
108
+ matches_adapter?(**kwargs) && matches_options?(**kwargs)
109
+ end
110
+
111
+ def priority
112
+ super | 4
113
+ end
114
+
115
+ private
116
+ attr_reader :options, :klass
117
+
118
+ def matches_options?(**kwargs)
119
+ options.all? do |key, value|
120
+ kwargs[key] == value
121
+ end
122
+ end
123
+ end
124
+ end
125
+
126
+ class TypeConflictError < StandardError
127
+ end
128
+ # :startdoc:
129
+ end
@@ -1,46 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module Type
3
- class Date < Value # :nodoc:
4
- def type
5
- :date
6
- end
7
-
8
- def klass
9
- ::Date
10
- end
11
-
12
- def type_cast_for_schema(value)
13
- "'#{value.to_s(:db)}'"
14
- end
15
-
16
- private
17
-
18
- def cast_value(value)
19
- if value.is_a?(::String)
20
- return if value.empty?
21
- fast_string_to_date(value) || fallback_string_to_date(value)
22
- elsif value.respond_to?(:to_date)
23
- value.to_date
24
- else
25
- value
26
- end
27
- end
28
-
29
- def fast_string_to_date(string)
30
- if string =~ ConnectionAdapters::Column::Format::ISO_DATE
31
- new_date $1.to_i, $2.to_i, $3.to_i
32
- end
33
- end
34
-
35
- def fallback_string_to_date(string)
36
- new_date(*::Date._parse(string, false).values_at(:year, :mon, :mday))
37
- end
38
-
39
- def new_date(year, mon, mday)
40
- if year && year != 0
41
- ::Date.new(year, mon, mday) rescue nil
42
- end
43
- end
5
+ class Date < ActiveModel::Type::Date
6
+ include Internal::Timezone
44
7
  end
45
8
  end
46
9
  end
@@ -1,43 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module Type
3
- class DateTime < Value # :nodoc:
4
- include TimeValue
5
-
6
- def type
7
- :datetime
8
- end
9
-
10
- def type_cast_for_database(value)
11
- zone_conversion_method = ActiveRecord::Base.default_timezone == :utc ? :getutc : :getlocal
12
-
13
- if value.acts_like?(:time)
14
- value.send(zone_conversion_method)
15
- else
16
- super
17
- end
18
- end
19
-
20
- private
21
-
22
- def cast_value(string)
23
- return string unless string.is_a?(::String)
24
- return if string.empty?
25
-
26
- fast_string_to_time(string) || fallback_string_to_time(string)
27
- end
28
-
29
- # '0.123456' -> 123456
30
- # '1.123456' -> 123456
31
- def microseconds(time)
32
- time[:sec_fraction] ? (time[:sec_fraction] * 1_000_000).to_i : 0
33
- end
34
-
35
- def fallback_string_to_time(string)
36
- time_hash = ::Date._parse(string)
37
- time_hash[:sec_fraction] = microseconds(time_hash)
38
-
39
- new_time(*time_hash.values_at(:year, :mon, :mday, :hour, :min, :sec, :sec_fraction, :offset))
40
- end
5
+ class DateTime < ActiveModel::Type::DateTime
6
+ include Internal::Timezone
41
7
  end
42
8
  end
43
9
  end
@@ -1,11 +1,15 @@
1
- require 'active_record/type/big_integer'
1
+ # frozen_string_literal: true
2
2
 
3
3
  module ActiveRecord
4
4
  module Type
5
- class DecimalWithoutScale < BigInteger # :nodoc:
5
+ class DecimalWithoutScale < ActiveModel::Type::BigInteger # :nodoc:
6
6
  def type
7
7
  :decimal
8
8
  end
9
+
10
+ def type_cast_for_schema(value)
11
+ value.to_s.inspect
12
+ end
9
13
  end
10
14
  end
11
15
  end
@@ -1,17 +1,25 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module Type
3
5
  class HashLookupTypeMap < TypeMap # :nodoc:
4
- delegate :key?, to: :@mapping
5
-
6
6
  def alias_type(type, alias_type)
7
7
  register_type(type) { |_, *args| lookup(alias_type, *args) }
8
8
  end
9
9
 
10
- private
10
+ def key?(key)
11
+ @mapping.key?(key)
12
+ end
11
13
 
12
- def perform_fetch(type, *args, &block)
13
- @mapping.fetch(type, block).call(type, *args)
14
+ def keys
15
+ @mapping.keys
14
16
  end
17
+
18
+ private
19
+
20
+ def perform_fetch(type, *args, &block)
21
+ @mapping.fetch(type, block).call(type, *args)
22
+ end
15
23
  end
16
24
  end
17
25
  end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module Type
5
+ module Internal
6
+ module Timezone
7
+ def is_utc?
8
+ ActiveRecord::Base.default_timezone == :utc
9
+ end
10
+
11
+ def default_timezone
12
+ ActiveRecord::Base.default_timezone
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module Type
5
+ class Json < ActiveModel::Type::Value
6
+ include ActiveModel::Type::Helpers::Mutable
7
+
8
+ def type
9
+ :json
10
+ end
11
+
12
+ def deserialize(value)
13
+ return value unless value.is_a?(::String)
14
+ ActiveSupport::JSON.decode(value) rescue nil
15
+ end
16
+
17
+ def serialize(value)
18
+ ActiveSupport::JSON.encode(value) unless value.nil?
19
+ end
20
+
21
+ def changed_in_place?(raw_old_value, new_value)
22
+ deserialize(raw_old_value) != new_value
23
+ end
24
+
25
+ def accessor
26
+ ActiveRecord::Store::StringKeyedHashAccessor
27
+ end
28
+ end
29
+ end
30
+ end
@@ -1,8 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module Type
3
- class Serialized < DelegateClass(Type::Value) # :nodoc:
4
- include Mutable
5
- include Decorator
5
+ class Serialized < DelegateClass(ActiveModel::Type::Value) # :nodoc:
6
+ undef to_yaml if method_defined?(:to_yaml)
7
+
8
+ include ActiveModel::Type::Helpers::Mutable
6
9
 
7
10
  attr_reader :subtype, :coder
8
11
 
@@ -12,7 +15,7 @@ module ActiveRecord
12
15
  super(subtype)
13
16
  end
14
17
 
15
- def type_cast_from_database(value)
18
+ def deserialize(value)
16
19
  if default_value?(value)
17
20
  value
18
21
  else
@@ -20,37 +23,49 @@ module ActiveRecord
20
23
  end
21
24
  end
22
25
 
23
- def type_cast_for_database(value)
26
+ def serialize(value)
24
27
  return if value.nil?
25
28
  unless default_value?(value)
26
29
  super coder.dump(value)
27
30
  end
28
31
  end
29
32
 
33
+ def inspect
34
+ Kernel.instance_method(:inspect).bind(self).call
35
+ end
36
+
30
37
  def changed_in_place?(raw_old_value, value)
31
38
  return false if value.nil?
32
- subtype.changed_in_place?(raw_old_value, coder.dump(value))
39
+ raw_new_value = encoded(value)
40
+ raw_old_value.nil? != raw_new_value.nil? ||
41
+ subtype.changed_in_place?(raw_old_value, raw_new_value)
33
42
  end
34
43
 
35
44
  def accessor
36
45
  ActiveRecord::Store::IndifferentHashAccessor
37
46
  end
38
47
 
39
- def init_with(coder)
40
- @coder = coder['coder']
41
- super
48
+ def assert_valid_value(value)
49
+ if coder.respond_to?(:assert_valid_value)
50
+ coder.assert_valid_value(value, action: "serialize")
51
+ end
42
52
  end
43
53
 
44
- def encode_with(coder)
45
- coder['coder'] = @coder
46
- super
54
+ def force_equality?(value)
55
+ coder.respond_to?(:object_class) && value.is_a?(coder.object_class)
47
56
  end
48
57
 
49
58
  private
50
59
 
51
- def default_value?(value)
52
- value == coder.load(nil)
53
- end
60
+ def default_value?(value)
61
+ value == coder.load(nil)
62
+ end
63
+
64
+ def encoded(value)
65
+ unless default_value?(value)
66
+ coder.dump(value)
67
+ end
68
+ end
54
69
  end
55
70
  end
56
71
  end
@@ -1,8 +1,8 @@
1
- require 'active_record/type/string'
1
+ # frozen_string_literal: true
2
2
 
3
3
  module ActiveRecord
4
4
  module Type
5
- class Text < String # :nodoc:
5
+ class Text < ActiveModel::Type::String # :nodoc:
6
6
  def type
7
7
  :text
8
8
  end
@@ -1,24 +1,19 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module Type
3
- class Time < Value # :nodoc:
4
- include TimeValue
5
+ class Time < ActiveModel::Type::Time
6
+ include Internal::Timezone
5
7
 
6
- def type
7
- :time
8
+ class Value < DelegateClass(::Time) # :nodoc:
8
9
  end
9
10
 
10
- private
11
-
12
- def cast_value(value)
13
- return value unless value.is_a?(::String)
14
- return if value.empty?
15
-
16
- dummy_time_value = "2000-01-01 #{value}"
17
-
18
- fast_string_to_time(dummy_time_value) || begin
19
- time_hash = ::Date._parse(dummy_time_value)
20
- return if time_hash[:hour].nil?
21
- new_time(*time_hash.values_at(:year, :mon, :mday, :hour, :min, :sec, :sec_fraction))
11
+ def serialize(value)
12
+ case value = super
13
+ when ::Time
14
+ Value.new(value)
15
+ else
16
+ value
22
17
  end
23
18
  end
24
19
  end
@@ -1,17 +1,19 @@
1
- require 'thread_safe'
1
+ # frozen_string_literal: true
2
+
3
+ require "concurrent/map"
2
4
 
3
5
  module ActiveRecord
4
6
  module Type
5
7
  class TypeMap # :nodoc:
6
8
  def initialize
7
9
  @mapping = {}
8
- @cache = ThreadSafe::Cache.new do |h, key|
9
- h.fetch_or_store(key, ThreadSafe::Cache.new)
10
+ @cache = Concurrent::Map.new do |h, key|
11
+ h.fetch_or_store(key, Concurrent::Map.new)
10
12
  end
11
13
  end
12
14
 
13
15
  def lookup(lookup_key, *args)
14
- fetch(lookup_key, *args) { default_value }
16
+ fetch(lookup_key, *args) { Type.default_value }
15
17
  end
16
18
 
17
19
  def fetch(lookup_key, *args, &block)
@@ -44,21 +46,17 @@ module ActiveRecord
44
46
 
45
47
  private
46
48
 
47
- def perform_fetch(lookup_key, *args)
48
- matching_pair = @mapping.reverse_each.detect do |key, _|
49
- key === lookup_key
50
- end
49
+ def perform_fetch(lookup_key, *args)
50
+ matching_pair = @mapping.reverse_each.detect do |key, _|
51
+ key === lookup_key
52
+ end
51
53
 
52
- if matching_pair
53
- matching_pair.last.call(lookup_key, *args)
54
- else
55
- yield lookup_key, *args
54
+ if matching_pair
55
+ matching_pair.last.call(lookup_key, *args)
56
+ else
57
+ yield lookup_key, *args
58
+ end
56
59
  end
57
- end
58
-
59
- def default_value
60
- @default_value ||= Value.new
61
- end
62
60
  end
63
61
  end
64
62
  end
@@ -1,15 +1,17 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActiveRecord
2
4
  module Type
3
- class UnsignedInteger < Integer # :nodoc:
5
+ class UnsignedInteger < ActiveModel::Type::Integer # :nodoc:
4
6
  private
5
7
 
6
- def max_value
7
- super * 2
8
- end
8
+ def max_value
9
+ super * 2
10
+ end
9
11
 
10
- def min_value
11
- 0
12
- end
12
+ def min_value
13
+ 0
14
+ end
13
15
  end
14
16
  end
15
17
  end
@@ -1,23 +1,78 @@
1
- require 'active_record/type/decorator'
2
- require 'active_record/type/mutable'
3
- require 'active_record/type/numeric'
4
- require 'active_record/type/time_value'
5
- require 'active_record/type/value'
6
-
7
- require 'active_record/type/big_integer'
8
- require 'active_record/type/binary'
9
- require 'active_record/type/boolean'
10
- require 'active_record/type/date'
11
- require 'active_record/type/date_time'
12
- require 'active_record/type/decimal'
13
- require 'active_record/type/decimal_without_scale'
14
- require 'active_record/type/float'
15
- require 'active_record/type/integer'
16
- require 'active_record/type/serialized'
17
- require 'active_record/type/string'
18
- require 'active_record/type/text'
19
- require 'active_record/type/time'
20
- require 'active_record/type/unsigned_integer'
21
-
22
- require 'active_record/type/type_map'
23
- require 'active_record/type/hash_lookup_type_map'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_model/type"
4
+
5
+ require "active_record/type/internal/timezone"
6
+
7
+ require "active_record/type/date"
8
+ require "active_record/type/date_time"
9
+ require "active_record/type/decimal_without_scale"
10
+ require "active_record/type/json"
11
+ require "active_record/type/time"
12
+ require "active_record/type/text"
13
+ require "active_record/type/unsigned_integer"
14
+
15
+ require "active_record/type/serialized"
16
+ require "active_record/type/adapter_specific_registry"
17
+
18
+ require "active_record/type/type_map"
19
+ require "active_record/type/hash_lookup_type_map"
20
+
21
+ module ActiveRecord
22
+ module Type
23
+ @registry = AdapterSpecificRegistry.new
24
+
25
+ class << self
26
+ attr_accessor :registry # :nodoc:
27
+ delegate :add_modifier, to: :registry
28
+
29
+ # Add a new type to the registry, allowing it to be referenced as a
30
+ # symbol by {ActiveRecord::Base.attribute}[rdoc-ref:Attributes::ClassMethods#attribute].
31
+ # If your type is only meant to be used with a specific database adapter, you can
32
+ # do so by passing <tt>adapter: :postgresql</tt>. If your type has the same
33
+ # name as a native type for the current adapter, an exception will be
34
+ # raised unless you specify an +:override+ option. <tt>override: true</tt> will
35
+ # cause your type to be used instead of the native type. <tt>override:
36
+ # false</tt> will cause the native type to be used over yours if one exists.
37
+ def register(type_name, klass = nil, **options, &block)
38
+ registry.register(type_name, klass, **options, &block)
39
+ end
40
+
41
+ def lookup(*args, adapter: current_adapter_name, **kwargs) # :nodoc:
42
+ registry.lookup(*args, adapter: adapter, **kwargs)
43
+ end
44
+
45
+ def default_value # :nodoc:
46
+ @default_value ||= Value.new
47
+ end
48
+
49
+ private
50
+
51
+ def current_adapter_name
52
+ ActiveRecord::Base.connection.adapter_name.downcase.to_sym
53
+ end
54
+ end
55
+
56
+ BigInteger = ActiveModel::Type::BigInteger
57
+ Binary = ActiveModel::Type::Binary
58
+ Boolean = ActiveModel::Type::Boolean
59
+ Decimal = ActiveModel::Type::Decimal
60
+ Float = ActiveModel::Type::Float
61
+ Integer = ActiveModel::Type::Integer
62
+ String = ActiveModel::Type::String
63
+ Value = ActiveModel::Type::Value
64
+
65
+ register(:big_integer, Type::BigInteger, override: false)
66
+ register(:binary, Type::Binary, override: false)
67
+ register(:boolean, Type::Boolean, override: false)
68
+ register(:date, Type::Date, override: false)
69
+ register(:datetime, Type::DateTime, override: false)
70
+ register(:decimal, Type::Decimal, override: false)
71
+ register(:float, Type::Float, override: false)
72
+ register(:integer, Type::Integer, override: false)
73
+ register(:json, Type::Json, override: false)
74
+ register(:string, Type::String, override: false)
75
+ register(:text, Type::Text, override: false)
76
+ register(:time, Type::Time, override: false)
77
+ end
78
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module TypeCaster
5
+ class Connection # :nodoc:
6
+ def initialize(klass, table_name)
7
+ @klass = klass
8
+ @table_name = table_name
9
+ end
10
+
11
+ def type_cast_for_database(attr_name, value)
12
+ return value if value.is_a?(Arel::Nodes::BindParam)
13
+ type = type_for_attribute(attr_name)
14
+ type.serialize(value)
15
+ end
16
+
17
+ def type_for_attribute(attr_name)
18
+ schema_cache = connection.schema_cache
19
+
20
+ if schema_cache.data_source_exists?(table_name)
21
+ column = schema_cache.columns_hash(table_name)[attr_name.to_s]
22
+ type = connection.lookup_cast_type_from_column(column) if column
23
+ end
24
+
25
+ type || Type.default_value
26
+ end
27
+
28
+ delegate :connection, to: :@klass, private: true
29
+
30
+ private
31
+ attr_reader :table_name
32
+ end
33
+ end
34
+ end