activerecord 5.2.8.1 → 6.1.6.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 (316) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1255 -596
  3. data/MIT-LICENSE +3 -1
  4. data/README.rdoc +7 -5
  5. data/examples/performance.rb +1 -1
  6. data/lib/active_record/aggregations.rb +9 -8
  7. data/lib/active_record/association_relation.rb +30 -10
  8. data/lib/active_record/associations/alias_tracker.rb +19 -16
  9. data/lib/active_record/associations/association.rb +100 -41
  10. data/lib/active_record/associations/association_scope.rb +23 -21
  11. data/lib/active_record/associations/belongs_to_association.rb +55 -48
  12. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +7 -6
  13. data/lib/active_record/associations/builder/association.rb +45 -22
  14. data/lib/active_record/associations/builder/belongs_to.rb +29 -59
  15. data/lib/active_record/associations/builder/collection_association.rb +8 -17
  16. data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +17 -41
  17. data/lib/active_record/associations/builder/has_many.rb +8 -2
  18. data/lib/active_record/associations/builder/has_one.rb +33 -2
  19. data/lib/active_record/associations/builder/singular_association.rb +3 -1
  20. data/lib/active_record/associations/collection_association.rb +44 -34
  21. data/lib/active_record/associations/collection_proxy.rb +25 -21
  22. data/lib/active_record/associations/foreign_association.rb +20 -0
  23. data/lib/active_record/associations/has_many_association.rb +26 -13
  24. data/lib/active_record/associations/has_many_through_association.rb +24 -18
  25. data/lib/active_record/associations/has_one_association.rb +43 -31
  26. data/lib/active_record/associations/has_one_through_association.rb +5 -5
  27. data/lib/active_record/associations/join_dependency/join_association.rb +44 -22
  28. data/lib/active_record/associations/join_dependency/join_part.rb +5 -5
  29. data/lib/active_record/associations/join_dependency.rb +91 -60
  30. data/lib/active_record/associations/preloader/association.rb +69 -43
  31. data/lib/active_record/associations/preloader/through_association.rb +49 -40
  32. data/lib/active_record/associations/preloader.rb +47 -34
  33. data/lib/active_record/associations/singular_association.rb +3 -17
  34. data/lib/active_record/associations/through_association.rb +1 -1
  35. data/lib/active_record/associations.rb +137 -25
  36. data/lib/active_record/attribute_assignment.rb +17 -19
  37. data/lib/active_record/attribute_methods/before_type_cast.rb +13 -7
  38. data/lib/active_record/attribute_methods/dirty.rb +101 -40
  39. data/lib/active_record/attribute_methods/primary_key.rb +20 -25
  40. data/lib/active_record/attribute_methods/query.rb +4 -8
  41. data/lib/active_record/attribute_methods/read.rb +14 -56
  42. data/lib/active_record/attribute_methods/serialization.rb +12 -7
  43. data/lib/active_record/attribute_methods/time_zone_conversion.rb +12 -15
  44. data/lib/active_record/attribute_methods/write.rb +18 -34
  45. data/lib/active_record/attribute_methods.rb +81 -143
  46. data/lib/active_record/attributes.rb +46 -9
  47. data/lib/active_record/autosave_association.rb +57 -42
  48. data/lib/active_record/base.rb +4 -17
  49. data/lib/active_record/callbacks.rb +158 -43
  50. data/lib/active_record/coders/yaml_column.rb +1 -2
  51. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +272 -130
  52. data/lib/active_record/connection_adapters/abstract/database_limits.rb +7 -36
  53. data/lib/active_record/connection_adapters/abstract/database_statements.rb +167 -146
  54. data/lib/active_record/connection_adapters/abstract/query_cache.rb +18 -14
  55. data/lib/active_record/connection_adapters/abstract/quoting.rb +98 -47
  56. data/lib/active_record/connection_adapters/abstract/savepoints.rb +3 -3
  57. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +153 -110
  58. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +211 -90
  59. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +2 -4
  60. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +385 -144
  61. data/lib/active_record/connection_adapters/abstract/transaction.rb +167 -69
  62. data/lib/active_record/connection_adapters/abstract_adapter.rb +229 -99
  63. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +243 -275
  64. data/lib/active_record/connection_adapters/column.rb +30 -12
  65. data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
  66. data/lib/active_record/connection_adapters/legacy_pool_manager.rb +35 -0
  67. data/lib/active_record/connection_adapters/mysql/column.rb +1 -1
  68. data/lib/active_record/connection_adapters/mysql/database_statements.rb +88 -32
  69. data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +1 -2
  70. data/lib/active_record/connection_adapters/mysql/quoting.rb +59 -7
  71. data/lib/active_record/connection_adapters/mysql/schema_creation.rb +34 -10
  72. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +48 -32
  73. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +18 -7
  74. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +142 -19
  75. data/lib/active_record/connection_adapters/mysql/type_metadata.rb +14 -9
  76. data/lib/active_record/connection_adapters/mysql2_adapter.rb +53 -18
  77. data/lib/active_record/connection_adapters/pool_config.rb +73 -0
  78. data/lib/active_record/connection_adapters/pool_manager.rb +47 -0
  79. data/lib/active_record/connection_adapters/postgresql/column.rb +37 -28
  80. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +40 -54
  81. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -2
  82. data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +1 -4
  83. data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -5
  84. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +2 -2
  85. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +10 -2
  86. data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +0 -1
  87. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +1 -2
  88. data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
  89. data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +3 -4
  90. data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
  91. data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
  92. data/lib/active_record/connection_adapters/postgresql/oid/point.rb +3 -4
  93. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +25 -7
  94. data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
  95. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +9 -7
  96. data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +15 -3
  97. data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
  98. data/lib/active_record/connection_adapters/postgresql/quoting.rb +47 -10
  99. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +2 -2
  100. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +19 -4
  101. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +107 -91
  102. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +0 -1
  103. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +120 -100
  104. data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +31 -26
  105. data/lib/active_record/connection_adapters/postgresql/utils.rb +0 -1
  106. data/lib/active_record/connection_adapters/postgresql_adapter.rb +224 -120
  107. data/lib/active_record/connection_adapters/schema_cache.rb +159 -21
  108. data/lib/active_record/connection_adapters/sql_type_metadata.rb +17 -6
  109. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +146 -0
  110. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +42 -7
  111. data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -1
  112. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +77 -13
  113. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +174 -186
  114. data/lib/active_record/connection_adapters/statement_pool.rb +0 -1
  115. data/lib/active_record/connection_adapters.rb +52 -0
  116. data/lib/active_record/connection_handling.rb +293 -33
  117. data/lib/active_record/core.rb +333 -98
  118. data/lib/active_record/counter_cache.rb +8 -30
  119. data/lib/active_record/database_configurations/connection_url_resolver.rb +99 -0
  120. data/lib/active_record/database_configurations/database_config.rb +80 -0
  121. data/lib/active_record/database_configurations/hash_config.rb +96 -0
  122. data/lib/active_record/database_configurations/url_config.rb +53 -0
  123. data/lib/active_record/database_configurations.rb +273 -0
  124. data/lib/active_record/delegated_type.rb +209 -0
  125. data/lib/active_record/destroy_association_async_job.rb +36 -0
  126. data/lib/active_record/dynamic_matchers.rb +3 -4
  127. data/lib/active_record/enum.rb +108 -36
  128. data/lib/active_record/errors.rb +62 -19
  129. data/lib/active_record/explain.rb +10 -6
  130. data/lib/active_record/explain_subscriber.rb +1 -1
  131. data/lib/active_record/fixture_set/file.rb +10 -17
  132. data/lib/active_record/fixture_set/model_metadata.rb +32 -0
  133. data/lib/active_record/fixture_set/render_context.rb +17 -0
  134. data/lib/active_record/fixture_set/table_row.rb +152 -0
  135. data/lib/active_record/fixture_set/table_rows.rb +46 -0
  136. data/lib/active_record/fixtures.rb +200 -481
  137. data/lib/active_record/gem_version.rb +3 -3
  138. data/lib/active_record/inheritance.rb +53 -24
  139. data/lib/active_record/insert_all.rb +212 -0
  140. data/lib/active_record/integration.rb +67 -17
  141. data/lib/active_record/internal_metadata.rb +28 -9
  142. data/lib/active_record/legacy_yaml_adapter.rb +7 -3
  143. data/lib/active_record/locking/optimistic.rb +37 -23
  144. data/lib/active_record/locking/pessimistic.rb +9 -5
  145. data/lib/active_record/log_subscriber.rb +35 -35
  146. data/lib/active_record/middleware/database_selector/resolver/session.rb +48 -0
  147. data/lib/active_record/middleware/database_selector/resolver.rb +92 -0
  148. data/lib/active_record/middleware/database_selector.rb +77 -0
  149. data/lib/active_record/migration/command_recorder.rb +96 -44
  150. data/lib/active_record/migration/compatibility.rb +145 -64
  151. data/lib/active_record/migration/join_table.rb +0 -1
  152. data/lib/active_record/migration.rb +206 -157
  153. data/lib/active_record/model_schema.rb +148 -22
  154. data/lib/active_record/nested_attributes.rb +4 -7
  155. data/lib/active_record/no_touching.rb +8 -1
  156. data/lib/active_record/null_relation.rb +0 -1
  157. data/lib/active_record/persistence.rb +267 -59
  158. data/lib/active_record/query_cache.rb +21 -4
  159. data/lib/active_record/querying.rb +40 -23
  160. data/lib/active_record/railtie.rb +116 -59
  161. data/lib/active_record/railties/console_sandbox.rb +2 -4
  162. data/lib/active_record/railties/controller_runtime.rb +30 -35
  163. data/lib/active_record/railties/databases.rake +411 -80
  164. data/lib/active_record/readonly_attributes.rb +4 -0
  165. data/lib/active_record/reflection.rb +109 -93
  166. data/lib/active_record/relation/batches/batch_enumerator.rb +25 -9
  167. data/lib/active_record/relation/batches.rb +44 -35
  168. data/lib/active_record/relation/calculations.rb +157 -90
  169. data/lib/active_record/relation/delegation.rb +35 -50
  170. data/lib/active_record/relation/finder_methods.rb +64 -39
  171. data/lib/active_record/relation/from_clause.rb +5 -1
  172. data/lib/active_record/relation/merger.rb +32 -40
  173. data/lib/active_record/relation/predicate_builder/array_handler.rb +13 -13
  174. data/lib/active_record/relation/predicate_builder/association_query_value.rb +5 -9
  175. data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +1 -2
  176. data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +11 -10
  177. data/lib/active_record/relation/predicate_builder/range_handler.rb +3 -23
  178. data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
  179. data/lib/active_record/relation/predicate_builder.rb +62 -45
  180. data/lib/active_record/relation/query_attribute.rb +13 -8
  181. data/lib/active_record/relation/query_methods.rb +476 -187
  182. data/lib/active_record/relation/record_fetch_warning.rb +3 -3
  183. data/lib/active_record/relation/spawn_methods.rb +9 -9
  184. data/lib/active_record/relation/where_clause.rb +115 -62
  185. data/lib/active_record/relation.rb +379 -115
  186. data/lib/active_record/result.rb +64 -38
  187. data/lib/active_record/runtime_registry.rb +2 -2
  188. data/lib/active_record/sanitization.rb +22 -41
  189. data/lib/active_record/schema.rb +2 -11
  190. data/lib/active_record/schema_dumper.rb +54 -9
  191. data/lib/active_record/schema_migration.rb +7 -9
  192. data/lib/active_record/scoping/default.rb +4 -8
  193. data/lib/active_record/scoping/named.rb +17 -24
  194. data/lib/active_record/scoping.rb +8 -9
  195. data/lib/active_record/secure_token.rb +16 -8
  196. data/lib/active_record/serialization.rb +5 -3
  197. data/lib/active_record/signed_id.rb +116 -0
  198. data/lib/active_record/statement_cache.rb +49 -6
  199. data/lib/active_record/store.rb +88 -9
  200. data/lib/active_record/suppressor.rb +2 -2
  201. data/lib/active_record/table_metadata.rb +42 -43
  202. data/lib/active_record/tasks/database_tasks.rb +277 -81
  203. data/lib/active_record/tasks/mysql_database_tasks.rb +37 -39
  204. data/lib/active_record/tasks/postgresql_database_tasks.rb +27 -32
  205. data/lib/active_record/tasks/sqlite_database_tasks.rb +14 -17
  206. data/lib/active_record/test_databases.rb +24 -0
  207. data/lib/active_record/test_fixtures.rb +287 -0
  208. data/lib/active_record/timestamp.rb +43 -32
  209. data/lib/active_record/touch_later.rb +23 -22
  210. data/lib/active_record/transactions.rb +62 -118
  211. data/lib/active_record/translation.rb +1 -1
  212. data/lib/active_record/type/adapter_specific_registry.rb +3 -13
  213. data/lib/active_record/type/hash_lookup_type_map.rb +0 -1
  214. data/lib/active_record/type/serialized.rb +6 -3
  215. data/lib/active_record/type/time.rb +10 -0
  216. data/lib/active_record/type/type_map.rb +0 -1
  217. data/lib/active_record/type/unsigned_integer.rb +0 -1
  218. data/lib/active_record/type.rb +10 -5
  219. data/lib/active_record/type_caster/connection.rb +15 -15
  220. data/lib/active_record/type_caster/map.rb +8 -8
  221. data/lib/active_record/validations/associated.rb +1 -2
  222. data/lib/active_record/validations/numericality.rb +35 -0
  223. data/lib/active_record/validations/uniqueness.rb +38 -30
  224. data/lib/active_record/validations.rb +4 -3
  225. data/lib/active_record.rb +13 -12
  226. data/lib/arel/alias_predication.rb +9 -0
  227. data/lib/arel/attributes/attribute.rb +41 -0
  228. data/lib/arel/collectors/bind.rb +29 -0
  229. data/lib/arel/collectors/composite.rb +39 -0
  230. data/lib/arel/collectors/plain_string.rb +20 -0
  231. data/lib/arel/collectors/sql_string.rb +27 -0
  232. data/lib/arel/collectors/substitute_binds.rb +35 -0
  233. data/lib/arel/crud.rb +42 -0
  234. data/lib/arel/delete_manager.rb +18 -0
  235. data/lib/arel/errors.rb +9 -0
  236. data/lib/arel/expressions.rb +29 -0
  237. data/lib/arel/factory_methods.rb +49 -0
  238. data/lib/arel/insert_manager.rb +49 -0
  239. data/lib/arel/math.rb +45 -0
  240. data/lib/arel/nodes/and.rb +32 -0
  241. data/lib/arel/nodes/ascending.rb +23 -0
  242. data/lib/arel/nodes/binary.rb +126 -0
  243. data/lib/arel/nodes/bind_param.rb +44 -0
  244. data/lib/arel/nodes/case.rb +55 -0
  245. data/lib/arel/nodes/casted.rb +62 -0
  246. data/lib/arel/nodes/comment.rb +29 -0
  247. data/lib/arel/nodes/count.rb +12 -0
  248. data/lib/arel/nodes/delete_statement.rb +45 -0
  249. data/lib/arel/nodes/descending.rb +23 -0
  250. data/lib/arel/nodes/equality.rb +15 -0
  251. data/lib/arel/nodes/extract.rb +24 -0
  252. data/lib/arel/nodes/false.rb +16 -0
  253. data/lib/arel/nodes/full_outer_join.rb +8 -0
  254. data/lib/arel/nodes/function.rb +44 -0
  255. data/lib/arel/nodes/grouping.rb +11 -0
  256. data/lib/arel/nodes/homogeneous_in.rb +76 -0
  257. data/lib/arel/nodes/in.rb +15 -0
  258. data/lib/arel/nodes/infix_operation.rb +92 -0
  259. data/lib/arel/nodes/inner_join.rb +8 -0
  260. data/lib/arel/nodes/insert_statement.rb +37 -0
  261. data/lib/arel/nodes/join_source.rb +20 -0
  262. data/lib/arel/nodes/matches.rb +18 -0
  263. data/lib/arel/nodes/named_function.rb +23 -0
  264. data/lib/arel/nodes/node.rb +51 -0
  265. data/lib/arel/nodes/node_expression.rb +13 -0
  266. data/lib/arel/nodes/ordering.rb +27 -0
  267. data/lib/arel/nodes/outer_join.rb +8 -0
  268. data/lib/arel/nodes/over.rb +15 -0
  269. data/lib/arel/nodes/regexp.rb +16 -0
  270. data/lib/arel/nodes/right_outer_join.rb +8 -0
  271. data/lib/arel/nodes/select_core.rb +67 -0
  272. data/lib/arel/nodes/select_statement.rb +41 -0
  273. data/lib/arel/nodes/sql_literal.rb +19 -0
  274. data/lib/arel/nodes/string_join.rb +11 -0
  275. data/lib/arel/nodes/table_alias.rb +31 -0
  276. data/lib/arel/nodes/terminal.rb +16 -0
  277. data/lib/arel/nodes/true.rb +16 -0
  278. data/lib/arel/nodes/unary.rb +44 -0
  279. data/lib/arel/nodes/unary_operation.rb +20 -0
  280. data/lib/arel/nodes/unqualified_column.rb +22 -0
  281. data/lib/arel/nodes/update_statement.rb +41 -0
  282. data/lib/arel/nodes/values_list.rb +9 -0
  283. data/lib/arel/nodes/window.rb +126 -0
  284. data/lib/arel/nodes/with.rb +11 -0
  285. data/lib/arel/nodes.rb +70 -0
  286. data/lib/arel/order_predications.rb +13 -0
  287. data/lib/arel/predications.rb +250 -0
  288. data/lib/arel/select_manager.rb +270 -0
  289. data/lib/arel/table.rb +118 -0
  290. data/lib/arel/tree_manager.rb +72 -0
  291. data/lib/arel/update_manager.rb +34 -0
  292. data/lib/arel/visitors/dot.rb +308 -0
  293. data/lib/arel/visitors/mysql.rb +93 -0
  294. data/lib/arel/visitors/postgresql.rb +120 -0
  295. data/lib/arel/visitors/sqlite.rb +38 -0
  296. data/lib/arel/visitors/to_sql.rb +899 -0
  297. data/lib/arel/visitors/visitor.rb +45 -0
  298. data/lib/arel/visitors.rb +13 -0
  299. data/lib/arel/window_predications.rb +9 -0
  300. data/lib/arel.rb +54 -0
  301. data/lib/rails/generators/active_record/application_record/application_record_generator.rb +0 -1
  302. data/lib/rails/generators/active_record/migration/migration_generator.rb +3 -5
  303. data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +3 -1
  304. data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +7 -5
  305. data/lib/rails/generators/active_record/migration.rb +19 -2
  306. data/lib/rails/generators/active_record/model/model_generator.rb +39 -2
  307. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
  308. data/lib/rails/generators/active_record/model/templates/model.rb.tt +10 -1
  309. metadata +116 -30
  310. data/lib/active_record/attribute_decorators.rb +0 -90
  311. data/lib/active_record/collection_cache_key.rb +0 -53
  312. data/lib/active_record/connection_adapters/connection_specification.rb +0 -287
  313. data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -33
  314. data/lib/active_record/define_callbacks.rb +0 -22
  315. data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -19
  316. data/lib/active_record/relation/where_clause_factory.rb +0 -34
@@ -1,90 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module ActiveRecord
4
- module AttributeDecorators # :nodoc:
5
- extend ActiveSupport::Concern
6
-
7
- included do
8
- class_attribute :attribute_type_decorations, instance_accessor: false, default: TypeDecorator.new # :internal:
9
- end
10
-
11
- module ClassMethods # :nodoc:
12
- # This method is an internal API used to create class macros such as
13
- # +serialize+, and features like time zone aware attributes.
14
- #
15
- # Used to wrap the type of an attribute in a new type.
16
- # When the schema for a model is loaded, attributes with the same name as
17
- # +column_name+ will have their type yielded to the given block. The
18
- # return value of that block will be used instead.
19
- #
20
- # Subsequent calls where +column_name+ and +decorator_name+ are the same
21
- # will override the previous decorator, not decorate twice. This can be
22
- # used to create idempotent class macros like +serialize+
23
- def decorate_attribute_type(column_name, decorator_name, &block)
24
- matcher = ->(name, _) { name == column_name.to_s }
25
- key = "_#{column_name}_#{decorator_name}"
26
- decorate_matching_attribute_types(matcher, key, &block)
27
- end
28
-
29
- # This method is an internal API used to create higher level features like
30
- # time zone aware attributes.
31
- #
32
- # When the schema for a model is loaded, +matcher+ will be called for each
33
- # attribute with its name and type. If the matcher returns a truthy value,
34
- # the type will then be yielded to the given block, and the return value
35
- # of that block will replace the type.
36
- #
37
- # Subsequent calls to this method with the same value for +decorator_name+
38
- # will replace the previous decorator, not decorate twice. This can be
39
- # used to ensure that class macros are idempotent.
40
- def decorate_matching_attribute_types(matcher, decorator_name, &block)
41
- reload_schema_from_cache
42
- decorator_name = decorator_name.to_s
43
-
44
- # Create new hashes so we don't modify parent classes
45
- self.attribute_type_decorations = attribute_type_decorations.merge(decorator_name => [matcher, block])
46
- end
47
-
48
- private
49
-
50
- def load_schema!
51
- super
52
- attribute_types.each do |name, type|
53
- decorated_type = attribute_type_decorations.apply(name, type)
54
- define_attribute(name, decorated_type)
55
- end
56
- end
57
- end
58
-
59
- class TypeDecorator # :nodoc:
60
- delegate :clear, to: :@decorations
61
-
62
- def initialize(decorations = {})
63
- @decorations = decorations
64
- end
65
-
66
- def merge(*args)
67
- TypeDecorator.new(@decorations.merge(*args))
68
- end
69
-
70
- def apply(name, type)
71
- decorations = decorators_for(name, type)
72
- decorations.inject(type) do |new_type, block|
73
- block.call(new_type)
74
- end
75
- end
76
-
77
- private
78
-
79
- def decorators_for(name, type)
80
- matching(name, type).map(&:last)
81
- end
82
-
83
- def matching(name, type)
84
- @decorations.values.select do |(matcher, _)|
85
- matcher.call(name, type)
86
- end
87
- end
88
- end
89
- end
90
- end
@@ -1,53 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module ActiveRecord
4
- module CollectionCacheKey
5
- def collection_cache_key(collection = all, timestamp_column = :updated_at) # :nodoc:
6
- query_signature = ActiveSupport::Digest.hexdigest(collection.to_sql)
7
- key = "#{collection.model_name.cache_key}/query-#{query_signature}"
8
-
9
- if collection.loaded? || collection.distinct_value
10
- size = collection.records.size
11
- if size > 0
12
- timestamp = collection.max_by(&timestamp_column)._read_attribute(timestamp_column)
13
- end
14
- else
15
- if collection.eager_loading?
16
- collection = collection.send(:apply_join_dependency)
17
- end
18
- column_type = type_for_attribute(timestamp_column)
19
- column = connection.column_name_from_arel_node(collection.arel_attribute(timestamp_column))
20
- select_values = "COUNT(*) AS #{connection.quote_column_name("size")}, MAX(%s) AS timestamp"
21
-
22
- if collection.has_limit_or_offset?
23
- query = collection.select("#{column} AS collection_cache_key_timestamp")
24
- subquery_alias = "subquery_for_cache_key"
25
- subquery_column = "#{subquery_alias}.collection_cache_key_timestamp"
26
- subquery = query.arel.as(subquery_alias)
27
- arel = Arel::SelectManager.new(subquery).project(select_values % subquery_column)
28
- else
29
- query = collection.unscope(:order)
30
- query.select_values = [select_values % column]
31
- arel = query.arel
32
- end
33
-
34
- result = connection.select_one(arel, nil)
35
-
36
- if result.blank?
37
- size = 0
38
- timestamp = nil
39
- else
40
- size = result["size"]
41
- timestamp = column_type.deserialize(result["timestamp"])
42
- end
43
-
44
- end
45
-
46
- if timestamp
47
- "#{key}-#{size}-#{timestamp.utc.to_s(cache_timestamp_format)}"
48
- else
49
- "#{key}-#{size}"
50
- end
51
- end
52
- end
53
- end
@@ -1,287 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "uri"
4
-
5
- module ActiveRecord
6
- module ConnectionAdapters
7
- class ConnectionSpecification #:nodoc:
8
- attr_reader :name, :config, :adapter_method
9
-
10
- def initialize(name, config, adapter_method)
11
- @name, @config, @adapter_method = name, config, adapter_method
12
- end
13
-
14
- def initialize_dup(original)
15
- @config = original.config.dup
16
- end
17
-
18
- def to_hash
19
- @config.merge(name: @name)
20
- end
21
-
22
- # Expands a connection string into a hash.
23
- class ConnectionUrlResolver # :nodoc:
24
- # == Example
25
- #
26
- # url = "postgresql://foo:bar@localhost:9000/foo_test?pool=5&timeout=3000"
27
- # ConnectionUrlResolver.new(url).to_hash
28
- # # => {
29
- # "adapter" => "postgresql",
30
- # "host" => "localhost",
31
- # "port" => 9000,
32
- # "database" => "foo_test",
33
- # "username" => "foo",
34
- # "password" => "bar",
35
- # "pool" => "5",
36
- # "timeout" => "3000"
37
- # }
38
- def initialize(url)
39
- raise "Database URL cannot be empty" if url.blank?
40
- @uri = uri_parser.parse(url)
41
- @adapter = @uri.scheme && @uri.scheme.tr("-", "_")
42
- @adapter = "postgresql" if @adapter == "postgres"
43
-
44
- if @uri.opaque
45
- @uri.opaque, @query = @uri.opaque.split("?", 2)
46
- else
47
- @query = @uri.query
48
- end
49
- end
50
-
51
- # Converts the given URL to a full connection hash.
52
- def to_hash
53
- config = raw_config.reject { |_, value| value.blank? }
54
- config.map { |key, value| config[key] = uri_parser.unescape(value) if value.is_a? String }
55
- config
56
- end
57
-
58
- private
59
-
60
- def uri
61
- @uri
62
- end
63
-
64
- def uri_parser
65
- @uri_parser ||= URI::Parser.new
66
- end
67
-
68
- # Converts the query parameters of the URI into a hash.
69
- #
70
- # "localhost?pool=5&reaping_frequency=2"
71
- # # => { "pool" => "5", "reaping_frequency" => "2" }
72
- #
73
- # returns empty hash if no query present.
74
- #
75
- # "localhost"
76
- # # => {}
77
- def query_hash
78
- Hash[(@query || "").split("&").map { |pair| pair.split("=") }]
79
- end
80
-
81
- def raw_config
82
- if uri.opaque
83
- query_hash.merge(
84
- "adapter" => @adapter,
85
- "database" => uri.opaque)
86
- else
87
- query_hash.merge(
88
- "adapter" => @adapter,
89
- "username" => uri.user,
90
- "password" => uri.password,
91
- "port" => uri.port,
92
- "database" => database_from_path,
93
- "host" => uri.hostname)
94
- end
95
- end
96
-
97
- # Returns name of the database.
98
- def database_from_path
99
- if @adapter == "sqlite3"
100
- # 'sqlite3:/foo' is absolute, because that makes sense. The
101
- # corresponding relative version, 'sqlite3:foo', is handled
102
- # elsewhere, as an "opaque".
103
-
104
- uri.path
105
- else
106
- # Only SQLite uses a filename as the "database" name; for
107
- # anything else, a leading slash would be silly.
108
-
109
- uri.path.sub(%r{^/}, "")
110
- end
111
- end
112
- end
113
-
114
- ##
115
- # Builds a ConnectionSpecification from user input.
116
- class Resolver # :nodoc:
117
- attr_reader :configurations
118
-
119
- # Accepts a hash two layers deep, keys on the first layer represent
120
- # environments such as "production". Keys must be strings.
121
- def initialize(configurations)
122
- @configurations = configurations
123
- end
124
-
125
- # Returns a hash with database connection information.
126
- #
127
- # == Examples
128
- #
129
- # Full hash Configuration.
130
- #
131
- # configurations = { "production" => { "host" => "localhost", "database" => "foo", "adapter" => "sqlite3" } }
132
- # Resolver.new(configurations).resolve(:production)
133
- # # => { "host" => "localhost", "database" => "foo", "adapter" => "sqlite3"}
134
- #
135
- # Initialized with URL configuration strings.
136
- #
137
- # configurations = { "production" => "postgresql://localhost/foo" }
138
- # Resolver.new(configurations).resolve(:production)
139
- # # => { "host" => "localhost", "database" => "foo", "adapter" => "postgresql" }
140
- #
141
- def resolve(config)
142
- if config
143
- resolve_connection config
144
- elsif env = ActiveRecord::ConnectionHandling::RAILS_ENV.call
145
- resolve_symbol_connection env.to_sym
146
- else
147
- raise AdapterNotSpecified
148
- end
149
- end
150
-
151
- # Expands each key in @configurations hash into fully resolved hash
152
- def resolve_all
153
- config = configurations.dup
154
-
155
- if env = ActiveRecord::ConnectionHandling::DEFAULT_ENV.call
156
- env_config = config[env] if config[env].is_a?(Hash) && !(config[env].key?("adapter") || config[env].key?("url"))
157
- end
158
-
159
- config.reject! { |k, v| v.is_a?(Hash) && !(v.key?("adapter") || v.key?("url")) }
160
- config.merge! env_config if env_config
161
-
162
- config.each do |key, value|
163
- config[key] = resolve(value) if value
164
- end
165
-
166
- config
167
- end
168
-
169
- # Returns an instance of ConnectionSpecification for a given adapter.
170
- # Accepts a hash one layer deep that contains all connection information.
171
- #
172
- # == Example
173
- #
174
- # config = { "production" => { "host" => "localhost", "database" => "foo", "adapter" => "sqlite3" } }
175
- # spec = Resolver.new(config).spec(:production)
176
- # spec.adapter_method
177
- # # => "sqlite3_connection"
178
- # spec.config
179
- # # => { "host" => "localhost", "database" => "foo", "adapter" => "sqlite3" }
180
- #
181
- def spec(config)
182
- spec = resolve(config).symbolize_keys
183
-
184
- raise(AdapterNotSpecified, "database configuration does not specify adapter") unless spec.key?(:adapter)
185
-
186
- # Require the adapter itself and give useful feedback about
187
- # 1. Missing adapter gems and
188
- # 2. Adapter gems' missing dependencies.
189
- path_to_adapter = "active_record/connection_adapters/#{spec[:adapter]}_adapter"
190
- begin
191
- require path_to_adapter
192
- rescue LoadError => e
193
- # We couldn't require the adapter itself. Raise an exception that
194
- # points out config typos and missing gems.
195
- if e.path == path_to_adapter
196
- # We can assume that a non-builtin adapter was specified, so it's
197
- # either misspelled or missing from Gemfile.
198
- 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
199
-
200
- # Bubbled up from the adapter require. Prefix the exception message
201
- # with some guidance about how to address it and reraise.
202
- else
203
- raise LoadError, "Error loading the '#{spec[:adapter]}' Active Record adapter. Missing a gem it depends on? #{e.message}", e.backtrace
204
- end
205
- end
206
-
207
- adapter_method = "#{spec[:adapter]}_connection"
208
-
209
- unless ActiveRecord::Base.respond_to?(adapter_method)
210
- raise AdapterNotFound, "database configuration specifies nonexistent #{spec.config[:adapter]} adapter"
211
- end
212
-
213
- ConnectionSpecification.new(spec.delete(:name) || "primary", spec, adapter_method)
214
- end
215
-
216
- private
217
-
218
- # Returns fully resolved connection, accepts hash, string or symbol.
219
- # Always returns a hash.
220
- #
221
- # == Examples
222
- #
223
- # Symbol representing current environment.
224
- #
225
- # Resolver.new("production" => {}).resolve_connection(:production)
226
- # # => {}
227
- #
228
- # One layer deep hash of connection values.
229
- #
230
- # Resolver.new({}).resolve_connection("adapter" => "sqlite3")
231
- # # => { "adapter" => "sqlite3" }
232
- #
233
- # Connection URL.
234
- #
235
- # Resolver.new({}).resolve_connection("postgresql://localhost/foo")
236
- # # => { "host" => "localhost", "database" => "foo", "adapter" => "postgresql" }
237
- #
238
- def resolve_connection(spec)
239
- case spec
240
- when Symbol
241
- resolve_symbol_connection spec
242
- when String
243
- resolve_url_connection spec
244
- when Hash
245
- resolve_hash_connection spec
246
- end
247
- end
248
-
249
- # Takes the environment such as +:production+ or +:development+.
250
- # This requires that the @configurations was initialized with a key that
251
- # matches.
252
- #
253
- # Resolver.new("production" => {}).resolve_symbol_connection(:production)
254
- # # => {}
255
- #
256
- def resolve_symbol_connection(spec)
257
- if config = configurations[spec.to_s]
258
- resolve_connection(config).merge("name" => spec.to_s)
259
- else
260
- raise(AdapterNotSpecified, "'#{spec}' database is not configured. Available: #{configurations.keys.inspect}")
261
- end
262
- end
263
-
264
- # Accepts a hash. Expands the "url" key that contains a
265
- # URL database connection to a full connection
266
- # hash and merges with the rest of the hash.
267
- # Connection details inside of the "url" key win any merge conflicts
268
- def resolve_hash_connection(spec)
269
- if spec["url"] && spec["url"] !~ /^jdbc:/
270
- connection_hash = resolve_url_connection(spec.delete("url"))
271
- spec.merge!(connection_hash)
272
- end
273
- spec
274
- end
275
-
276
- # Takes a connection URL.
277
- #
278
- # Resolver.new({}).resolve_url_connection("postgresql://localhost/foo")
279
- # # => { "host" => "localhost", "database" => "foo", "adapter" => "postgresql" }
280
- #
281
- def resolve_url_connection(url)
282
- ConnectionUrlResolver.new(url).to_hash
283
- end
284
- end
285
- end
286
- end
287
- end
@@ -1,33 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module ActiveRecord
4
- module ConnectionAdapters
5
- module DetermineIfPreparableVisitor
6
- attr_accessor :preparable
7
-
8
- def accept(*)
9
- @preparable = true
10
- super
11
- end
12
-
13
- def visit_Arel_Nodes_In(o, collector)
14
- @preparable = false
15
-
16
- if Array === o.right && !o.right.empty?
17
- o.right.delete_if do |bind|
18
- if Arel::Nodes::BindParam === bind && Relation::QueryAttribute === bind.value
19
- !bind.value.boundable?
20
- end
21
- end
22
- end
23
-
24
- super
25
- end
26
-
27
- def visit_Arel_Nodes_SqlLiteral(*)
28
- @preparable = false
29
- super
30
- end
31
- end
32
- end
33
- end
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module ActiveRecord
4
- # This module exists because ActiveRecord::AttributeMethods::Dirty needs to
5
- # define callbacks, but continue to have its version of +save+ be the super
6
- # method of ActiveRecord::Callbacks. This will be removed when the removal
7
- # of deprecated code removes this need.
8
- module DefineCallbacks
9
- extend ActiveSupport::Concern
10
-
11
- module ClassMethods # :nodoc:
12
- include ActiveModel::Callbacks
13
- end
14
-
15
- included do
16
- include ActiveModel::Validations::Callbacks
17
-
18
- define_model_callbacks :initialize, :find, :touch, only: :after
19
- define_model_callbacks :save, :create, :update, :destroy
20
- end
21
- end
22
- end
@@ -1,19 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module ActiveRecord
4
- class PredicateBuilder
5
- class BaseHandler # :nodoc:
6
- def initialize(predicate_builder)
7
- @predicate_builder = predicate_builder
8
- end
9
-
10
- def call(attribute, value)
11
- predicate_builder.build(attribute, value.id)
12
- end
13
-
14
- protected
15
-
16
- attr_reader :predicate_builder
17
- end
18
- end
19
- end
@@ -1,34 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module ActiveRecord
4
- class Relation
5
- class WhereClauseFactory # :nodoc:
6
- def initialize(klass, predicate_builder)
7
- @klass = klass
8
- @predicate_builder = predicate_builder
9
- end
10
-
11
- def build(opts, other)
12
- case opts
13
- when String, Array
14
- parts = [klass.sanitize_sql(other.empty? ? opts : ([opts] + other))]
15
- when Hash
16
- attributes = predicate_builder.resolve_column_aliases(opts)
17
- attributes.stringify_keys!
18
-
19
- parts = predicate_builder.build_from_hash(attributes)
20
- when Arel::Nodes::Node
21
- parts = [opts]
22
- else
23
- raise ArgumentError, "Unsupported argument type: #{opts} (#{opts.class})"
24
- end
25
-
26
- WhereClause.new(parts)
27
- end
28
-
29
- protected
30
-
31
- attr_reader :klass, :predicate_builder
32
- end
33
- end
34
- end