activerecord 4.2.0 → 6.0.5.1

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 (373) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +852 -801
  3. data/MIT-LICENSE +4 -2
  4. data/README.rdoc +14 -13
  5. data/examples/performance.rb +33 -32
  6. data/examples/simple.rb +5 -4
  7. data/lib/active_record/advisory_lock_base.rb +18 -0
  8. data/lib/active_record/aggregations.rb +267 -249
  9. data/lib/active_record/association_relation.rb +26 -6
  10. data/lib/active_record/associations/alias_tracker.rb +29 -36
  11. data/lib/active_record/associations/association.rb +137 -55
  12. data/lib/active_record/associations/association_scope.rb +110 -132
  13. data/lib/active_record/associations/belongs_to_association.rb +67 -54
  14. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -12
  15. data/lib/active_record/associations/builder/association.rb +27 -40
  16. data/lib/active_record/associations/builder/belongs_to.rb +69 -55
  17. data/lib/active_record/associations/builder/collection_association.rb +10 -29
  18. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +58 -70
  19. data/lib/active_record/associations/builder/has_many.rb +8 -4
  20. data/lib/active_record/associations/builder/has_one.rb +46 -5
  21. data/lib/active_record/associations/builder/singular_association.rb +16 -10
  22. data/lib/active_record/associations/collection_association.rb +150 -275
  23. data/lib/active_record/associations/collection_proxy.rb +253 -152
  24. data/lib/active_record/associations/foreign_association.rb +20 -0
  25. data/lib/active_record/associations/has_many_association.rb +35 -84
  26. data/lib/active_record/associations/has_many_through_association.rb +62 -80
  27. data/lib/active_record/associations/has_one_association.rb +62 -49
  28. data/lib/active_record/associations/has_one_through_association.rb +20 -11
  29. data/lib/active_record/associations/join_dependency/join_association.rb +43 -78
  30. data/lib/active_record/associations/join_dependency/join_base.rb +10 -9
  31. data/lib/active_record/associations/join_dependency/join_part.rb +14 -14
  32. data/lib/active_record/associations/join_dependency.rb +159 -162
  33. data/lib/active_record/associations/preloader/association.rb +102 -113
  34. data/lib/active_record/associations/preloader/through_association.rb +85 -65
  35. data/lib/active_record/associations/preloader.rb +96 -95
  36. data/lib/active_record/associations/singular_association.rb +18 -45
  37. data/lib/active_record/associations/through_association.rb +49 -24
  38. data/lib/active_record/associations.rb +1737 -1596
  39. data/lib/active_record/attribute_assignment.rb +57 -185
  40. data/lib/active_record/attribute_decorators.rb +39 -17
  41. data/lib/active_record/attribute_methods/before_type_cast.rb +14 -5
  42. data/lib/active_record/attribute_methods/dirty.rb +174 -134
  43. data/lib/active_record/attribute_methods/primary_key.rb +90 -84
  44. data/lib/active_record/attribute_methods/query.rb +6 -5
  45. data/lib/active_record/attribute_methods/read.rb +20 -77
  46. data/lib/active_record/attribute_methods/serialization.rb +40 -21
  47. data/lib/active_record/attribute_methods/time_zone_conversion.rb +61 -37
  48. data/lib/active_record/attribute_methods/write.rb +33 -56
  49. data/lib/active_record/attribute_methods.rb +124 -143
  50. data/lib/active_record/attributes.rb +213 -74
  51. data/lib/active_record/autosave_association.rb +125 -54
  52. data/lib/active_record/base.rb +60 -49
  53. data/lib/active_record/callbacks.rb +101 -76
  54. data/lib/active_record/coders/json.rb +3 -1
  55. data/lib/active_record/coders/yaml_column.rb +36 -13
  56. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +810 -291
  57. data/lib/active_record/connection_adapters/abstract/database_limits.rb +26 -8
  58. data/lib/active_record/connection_adapters/abstract/database_statements.rb +253 -108
  59. data/lib/active_record/connection_adapters/abstract/query_cache.rb +83 -24
  60. data/lib/active_record/connection_adapters/abstract/quoting.rb +171 -53
  61. data/lib/active_record/connection_adapters/abstract/savepoints.rb +6 -4
  62. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +74 -47
  63. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +383 -239
  64. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +79 -36
  65. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +736 -235
  66. data/lib/active_record/connection_adapters/abstract/transaction.rb +190 -87
  67. data/lib/active_record/connection_adapters/abstract_adapter.rb +487 -192
  68. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +536 -600
  69. data/lib/active_record/connection_adapters/column.rb +56 -43
  70. data/lib/active_record/connection_adapters/connection_specification.rb +174 -153
  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 +196 -0
  74. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +71 -0
  75. data/lib/active_record/connection_adapters/mysql/quoting.rb +81 -0
  76. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +71 -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 +268 -0
  80. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +31 -0
  81. data/lib/active_record/connection_adapters/mysql2_adapter.rb +59 -196
  82. data/lib/active_record/connection_adapters/postgresql/column.rb +21 -11
  83. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +71 -115
  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 +5 -1
  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/jsonb.rb +3 -11
  97. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +44 -0
  98. data/lib/active_record/connection_adapters/postgresql/oid/money.rb +7 -9
  99. data/lib/active_record/connection_adapters/postgresql/oid/{infinity.rb → oid.rb} +5 -3
  100. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +32 -11
  101. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +70 -34
  102. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +4 -1
  103. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +67 -51
  104. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +9 -5
  105. data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +3 -1
  106. data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +3 -1
  107. data/lib/active_record/connection_adapters/postgresql/oid.rb +23 -25
  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 +49 -0
  113. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +465 -291
  114. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +36 -0
  115. data/lib/active_record/connection_adapters/postgresql/utils.rb +11 -8
  116. data/lib/active_record/connection_adapters/postgresql_adapter.rb +565 -363
  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 +119 -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 +102 -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 +299 -364
  127. data/lib/active_record/connection_adapters/statement_pool.rb +33 -13
  128. data/lib/active_record/connection_handling.rb +167 -41
  129. data/lib/active_record/core.rb +277 -233
  130. data/lib/active_record/counter_cache.rb +71 -50
  131. data/lib/active_record/database_configurations/database_config.rb +37 -0
  132. data/lib/active_record/database_configurations/hash_config.rb +50 -0
  133. data/lib/active_record/database_configurations/url_config.rb +78 -0
  134. data/lib/active_record/database_configurations.rb +233 -0
  135. data/lib/active_record/define_callbacks.rb +22 -0
  136. data/lib/active_record/dynamic_matchers.rb +87 -106
  137. data/lib/active_record/enum.rb +172 -89
  138. data/lib/active_record/errors.rb +189 -53
  139. data/lib/active_record/explain.rb +22 -11
  140. data/lib/active_record/explain_registry.rb +4 -2
  141. data/lib/active_record/explain_subscriber.rb +11 -6
  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 +152 -0
  146. data/lib/active_record/fixture_set/table_rows.rb +46 -0
  147. data/lib/active_record/fixtures.rb +225 -497
  148. data/lib/active_record/gem_version.rb +6 -4
  149. data/lib/active_record/inheritance.rb +158 -115
  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 +48 -0
  154. data/lib/active_record/locale/en.yml +3 -2
  155. data/lib/active_record/locking/optimistic.rb +99 -98
  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/resolver/session.rb +45 -0
  159. data/lib/active_record/middleware/database_selector/resolver.rb +87 -0
  160. data/lib/active_record/middleware/database_selector.rb +74 -0
  161. data/lib/active_record/migration/command_recorder.rb +166 -91
  162. data/lib/active_record/migration/compatibility.rb +244 -0
  163. data/lib/active_record/migration/join_table.rb +8 -7
  164. data/lib/active_record/migration.rb +636 -290
  165. data/lib/active_record/model_schema.rb +344 -112
  166. data/lib/active_record/nested_attributes.rb +265 -215
  167. data/lib/active_record/no_touching.rb +15 -2
  168. data/lib/active_record/null_relation.rb +24 -38
  169. data/lib/active_record/persistence.rb +559 -125
  170. data/lib/active_record/query_cache.rb +19 -23
  171. data/lib/active_record/querying.rb +44 -30
  172. data/lib/active_record/railtie.rb +166 -47
  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 +341 -202
  177. data/lib/active_record/readonly_attributes.rb +5 -4
  178. data/lib/active_record/reflection.rb +461 -302
  179. data/lib/active_record/relation/batches/batch_enumerator.rb +69 -0
  180. data/lib/active_record/relation/batches.rb +206 -55
  181. data/lib/active_record/relation/calculations.rb +270 -249
  182. data/lib/active_record/relation/delegation.rb +76 -84
  183. data/lib/active_record/relation/finder_methods.rb +287 -255
  184. data/lib/active_record/relation/from_clause.rb +30 -0
  185. data/lib/active_record/relation/merger.rb +86 -68
  186. data/lib/active_record/relation/predicate_builder/array_handler.rb +27 -25
  187. data/lib/active_record/relation/predicate_builder/association_query_value.rb +43 -0
  188. data/lib/active_record/relation/predicate_builder/base_handler.rb +18 -0
  189. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +19 -0
  190. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +53 -0
  191. data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -0
  192. data/lib/active_record/relation/predicate_builder/relation_handler.rb +7 -1
  193. data/lib/active_record/relation/predicate_builder.rb +112 -92
  194. data/lib/active_record/relation/query_attribute.rb +50 -0
  195. data/lib/active_record/relation/query_methods.rb +612 -392
  196. data/lib/active_record/relation/record_fetch_warning.rb +51 -0
  197. data/lib/active_record/relation/spawn_methods.rb +18 -17
  198. data/lib/active_record/relation/where_clause.rb +189 -0
  199. data/lib/active_record/relation/where_clause_factory.rb +33 -0
  200. data/lib/active_record/relation.rb +533 -340
  201. data/lib/active_record/result.rb +79 -43
  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 -20
  207. data/lib/active_record/scoping/default.rb +98 -82
  208. data/lib/active_record/scoping/named.rb +91 -33
  209. data/lib/active_record/scoping.rb +45 -27
  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 +90 -0
  216. data/lib/active_record/tasks/database_tasks.rb +309 -99
  217. data/lib/active_record/tasks/mysql_database_tasks.rb +58 -89
  218. data/lib/active_record/tasks/postgresql_database_tasks.rb +81 -31
  219. data/lib/active_record/tasks/sqlite_database_tasks.rb +37 -16
  220. data/lib/active_record/test_databases.rb +23 -0
  221. data/lib/active_record/test_fixtures.rb +243 -0
  222. data/lib/active_record/timestamp.rb +86 -41
  223. data/lib/active_record/touch_later.rb +65 -0
  224. data/lib/active_record/transactions.rb +222 -146
  225. data/lib/active_record/translation.rb +3 -1
  226. data/lib/active_record/type/adapter_specific_registry.rb +126 -0
  227. data/lib/active_record/type/date.rb +4 -41
  228. data/lib/active_record/type/date_time.rb +4 -38
  229. data/lib/active_record/type/decimal_without_scale.rb +6 -2
  230. data/lib/active_record/type/hash_lookup_type_map.rb +12 -5
  231. data/lib/active_record/type/internal/timezone.rb +17 -0
  232. data/lib/active_record/type/json.rb +30 -0
  233. data/lib/active_record/type/serialized.rb +29 -15
  234. data/lib/active_record/type/text.rb +2 -2
  235. data/lib/active_record/type/time.rb +21 -16
  236. data/lib/active_record/type/type_map.rb +16 -19
  237. data/lib/active_record/type/unsigned_integer.rb +9 -8
  238. data/lib/active_record/type.rb +77 -23
  239. data/lib/active_record/type_caster/connection.rb +34 -0
  240. data/lib/active_record/type_caster/map.rb +20 -0
  241. data/lib/active_record/type_caster.rb +9 -0
  242. data/lib/active_record/validations/absence.rb +25 -0
  243. data/lib/active_record/validations/associated.rb +12 -4
  244. data/lib/active_record/validations/length.rb +26 -0
  245. data/lib/active_record/validations/presence.rb +14 -13
  246. data/lib/active_record/validations/uniqueness.rb +43 -46
  247. data/lib/active_record/validations.rb +38 -35
  248. data/lib/active_record/version.rb +3 -1
  249. data/lib/active_record.rb +44 -21
  250. data/lib/arel/alias_predication.rb +9 -0
  251. data/lib/arel/attributes/attribute.rb +37 -0
  252. data/lib/arel/attributes.rb +22 -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/and.rb +32 -0
  266. data/lib/arel/nodes/ascending.rb +23 -0
  267. data/lib/arel/nodes/binary.rb +52 -0
  268. data/lib/arel/nodes/bind_param.rb +36 -0
  269. data/lib/arel/nodes/case.rb +55 -0
  270. data/lib/arel/nodes/casted.rb +50 -0
  271. data/lib/arel/nodes/comment.rb +29 -0
  272. data/lib/arel/nodes/count.rb +12 -0
  273. data/lib/arel/nodes/delete_statement.rb +45 -0
  274. data/lib/arel/nodes/descending.rb +23 -0
  275. data/lib/arel/nodes/equality.rb +18 -0
  276. data/lib/arel/nodes/extract.rb +24 -0
  277. data/lib/arel/nodes/false.rb +16 -0
  278. data/lib/arel/nodes/full_outer_join.rb +8 -0
  279. data/lib/arel/nodes/function.rb +44 -0
  280. data/lib/arel/nodes/grouping.rb +8 -0
  281. data/lib/arel/nodes/in.rb +8 -0
  282. data/lib/arel/nodes/infix_operation.rb +80 -0
  283. data/lib/arel/nodes/inner_join.rb +8 -0
  284. data/lib/arel/nodes/insert_statement.rb +37 -0
  285. data/lib/arel/nodes/join_source.rb +20 -0
  286. data/lib/arel/nodes/matches.rb +18 -0
  287. data/lib/arel/nodes/named_function.rb +23 -0
  288. data/lib/arel/nodes/node.rb +50 -0
  289. data/lib/arel/nodes/node_expression.rb +13 -0
  290. data/lib/arel/nodes/outer_join.rb +8 -0
  291. data/lib/arel/nodes/over.rb +15 -0
  292. data/lib/arel/nodes/regexp.rb +16 -0
  293. data/lib/arel/nodes/right_outer_join.rb +8 -0
  294. data/lib/arel/nodes/select_core.rb +67 -0
  295. data/lib/arel/nodes/select_statement.rb +41 -0
  296. data/lib/arel/nodes/sql_literal.rb +16 -0
  297. data/lib/arel/nodes/string_join.rb +11 -0
  298. data/lib/arel/nodes/table_alias.rb +27 -0
  299. data/lib/arel/nodes/terminal.rb +16 -0
  300. data/lib/arel/nodes/true.rb +16 -0
  301. data/lib/arel/nodes/unary.rb +45 -0
  302. data/lib/arel/nodes/unary_operation.rb +20 -0
  303. data/lib/arel/nodes/unqualified_column.rb +22 -0
  304. data/lib/arel/nodes/update_statement.rb +41 -0
  305. data/lib/arel/nodes/values_list.rb +9 -0
  306. data/lib/arel/nodes/window.rb +126 -0
  307. data/lib/arel/nodes/with.rb +11 -0
  308. data/lib/arel/nodes.rb +68 -0
  309. data/lib/arel/order_predications.rb +13 -0
  310. data/lib/arel/predications.rb +256 -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/depth_first.rb +203 -0
  316. data/lib/arel/visitors/dot.rb +296 -0
  317. data/lib/arel/visitors/ibm_db.rb +34 -0
  318. data/lib/arel/visitors/informix.rb +62 -0
  319. data/lib/arel/visitors/mssql.rb +156 -0
  320. data/lib/arel/visitors/mysql.rb +83 -0
  321. data/lib/arel/visitors/oracle.rb +158 -0
  322. data/lib/arel/visitors/oracle12.rb +65 -0
  323. data/lib/arel/visitors/postgresql.rb +109 -0
  324. data/lib/arel/visitors/sqlite.rb +38 -0
  325. data/lib/arel/visitors/to_sql.rb +888 -0
  326. data/lib/arel/visitors/visitor.rb +45 -0
  327. data/lib/arel/visitors/where_sql.rb +22 -0
  328. data/lib/arel/visitors.rb +20 -0
  329. data/lib/arel/window_predications.rb +9 -0
  330. data/lib/arel.rb +62 -0
  331. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +26 -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/migration_generator.rb +42 -37
  334. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +24 -0
  335. data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +11 -8
  336. data/lib/rails/generators/active_record/migration.rb +30 -1
  337. data/lib/rails/generators/active_record/model/model_generator.rb +18 -22
  338. data/lib/rails/generators/active_record/model/templates/model.rb.tt +22 -0
  339. data/lib/rails/generators/active_record.rb +7 -5
  340. metadata +174 -63
  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 -149
  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/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/integer.rb +0 -11
  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 -30
  362. data/lib/active_record/type/decimal.rb +0 -40
  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 -55
  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 -36
  369. data/lib/active_record/type/time_value.rb +0 -38
  370. data/lib/active_record/type/value.rb +0 -101
  371. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb +0 -22
  372. data/lib/rails/generators/active_record/model/templates/model.rb +0 -10
  373. /data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
@@ -0,0 +1,126 @@
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
+ def registration_klass
15
+ Registration
16
+ end
17
+
18
+ def find_registration(symbol, *args, **kwargs)
19
+ registrations
20
+ .select { |registration| registration.matches?(symbol, *args, **kwargs) }
21
+ .max
22
+ end
23
+ end
24
+
25
+ class Registration
26
+ def initialize(name, block, adapter: nil, override: nil)
27
+ @name = name
28
+ @block = block
29
+ @adapter = adapter
30
+ @override = override
31
+ end
32
+
33
+ def call(_registry, *args, adapter: nil, **kwargs)
34
+ if kwargs.any? # https://bugs.ruby-lang.org/issues/10856
35
+ block.call(*args, **kwargs)
36
+ else
37
+ block.call(*args)
38
+ end
39
+ end
40
+
41
+ def matches?(type_name, *args, **kwargs)
42
+ type_name == name && matches_adapter?(**kwargs)
43
+ end
44
+
45
+ def <=>(other)
46
+ if conflicts_with?(other)
47
+ raise TypeConflictError.new("Type #{name} was registered for all
48
+ adapters, but shadows a native type with
49
+ the same name for #{other.adapter}".squish)
50
+ end
51
+ priority <=> other.priority
52
+ end
53
+
54
+ protected
55
+ attr_reader :name, :block, :adapter, :override
56
+
57
+ def priority
58
+ result = 0
59
+ if adapter
60
+ result |= 1
61
+ end
62
+ if override
63
+ result |= 2
64
+ end
65
+ result
66
+ end
67
+
68
+ def priority_except_adapter
69
+ priority & 0b111111100
70
+ end
71
+
72
+ private
73
+ def matches_adapter?(adapter: nil, **)
74
+ (self.adapter.nil? || adapter == self.adapter)
75
+ end
76
+
77
+ def conflicts_with?(other)
78
+ same_priority_except_adapter?(other) &&
79
+ has_adapter_conflict?(other)
80
+ end
81
+
82
+ def same_priority_except_adapter?(other)
83
+ priority_except_adapter == other.priority_except_adapter
84
+ end
85
+
86
+ def has_adapter_conflict?(other)
87
+ (override.nil? && other.adapter) ||
88
+ (adapter && other.override.nil?)
89
+ end
90
+ end
91
+
92
+ class DecorationRegistration < Registration
93
+ def initialize(options, klass, adapter: nil)
94
+ @options = options
95
+ @klass = klass
96
+ @adapter = adapter
97
+ end
98
+
99
+ def call(registry, *args, **kwargs)
100
+ subtype = registry.lookup(*args, **kwargs.except(*options.keys))
101
+ klass.new(subtype)
102
+ end
103
+
104
+ def matches?(*args, **kwargs)
105
+ matches_adapter?(**kwargs) && matches_options?(**kwargs)
106
+ end
107
+
108
+ def priority
109
+ super | 4
110
+ end
111
+
112
+ private
113
+ attr_reader :options, :klass
114
+
115
+ def matches_options?(**kwargs)
116
+ options.all? do |key, value|
117
+ kwargs[key] == value
118
+ end
119
+ end
120
+ end
121
+ end
122
+
123
+ class TypeConflictError < StandardError
124
+ end
125
+ # :startdoc:
126
+ 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,24 @@
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
+ def perform_fetch(type, *args, &block)
20
+ @mapping.fetch(type, block).call(type, *args)
21
+ end
15
22
  end
16
23
  end
17
24
  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,48 @@ 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
59
+ def default_value?(value)
60
+ value == coder.load(nil)
61
+ end
50
62
 
51
- def default_value?(value)
52
- value == coder.load(nil)
53
- end
63
+ def encoded(value)
64
+ unless default_value?(value)
65
+ coder.dump(value)
66
+ end
67
+ end
54
68
  end
55
69
  end
56
70
  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,26 +1,31 @@
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
19
+
20
+ private
21
+ def cast_value(value)
22
+ case value = super
23
+ when Value
24
+ value.__getobj__
25
+ else
26
+ value
27
+ end
28
+ end
24
29
  end
25
30
  end
26
31
  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)
@@ -43,22 +45,17 @@ module ActiveRecord
43
45
  end
44
46
 
45
47
  private
46
-
47
- def perform_fetch(lookup_key, *args)
48
- matching_pair = @mapping.reverse_each.detect do |key, _|
49
- key === lookup_key
50
- end
51
-
52
- if matching_pair
53
- matching_pair.last.call(lookup_key, *args)
54
- else
55
- yield lookup_key, *args
48
+ def perform_fetch(lookup_key, *args)
49
+ matching_pair = @mapping.reverse_each.detect do |key, _|
50
+ key === lookup_key
51
+ end
52
+
53
+ if matching_pair
54
+ matching_pair.last.call(lookup_key, *args)
55
+ else
56
+ yield lookup_key, *args
57
+ end
56
58
  end
57
- end
58
-
59
- def default_value
60
- @default_value ||= Value.new
61
- end
62
59
  end
63
60
  end
64
61
  end
@@ -1,15 +1,16 @@
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
7
+ def max_value
8
+ super * 2
9
+ end
5
10
 
6
- def max_value
7
- super * 2
8
- end
9
-
10
- def min_value
11
- 0
12
- end
11
+ def min_value
12
+ 0
13
+ end
13
14
  end
14
15
  end
15
16
  end
@@ -1,23 +1,77 @@
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
+ def current_adapter_name
51
+ ActiveRecord::Base.connection.adapter_name.downcase.to_sym
52
+ end
53
+ end
54
+
55
+ BigInteger = ActiveModel::Type::BigInteger
56
+ Binary = ActiveModel::Type::Binary
57
+ Boolean = ActiveModel::Type::Boolean
58
+ Decimal = ActiveModel::Type::Decimal
59
+ Float = ActiveModel::Type::Float
60
+ Integer = ActiveModel::Type::Integer
61
+ String = ActiveModel::Type::String
62
+ Value = ActiveModel::Type::Value
63
+
64
+ register(:big_integer, Type::BigInteger, override: false)
65
+ register(:binary, Type::Binary, override: false)
66
+ register(:boolean, Type::Boolean, override: false)
67
+ register(:date, Type::Date, override: false)
68
+ register(:datetime, Type::DateTime, override: false)
69
+ register(:decimal, Type::Decimal, override: false)
70
+ register(:float, Type::Float, override: false)
71
+ register(:integer, Type::Integer, override: false)
72
+ register(:json, Type::Json, override: false)
73
+ register(:string, Type::String, override: false)
74
+ register(:text, Type::Text, override: false)
75
+ register(:time, Type::Time, override: false)
76
+ end
77
+ 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