activerecord 6.1.7.6 → 7.0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (251) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +1575 -1016
  3. data/README.rdoc +3 -3
  4. data/lib/active_record/aggregations.rb +1 -1
  5. data/lib/active_record/association_relation.rb +0 -10
  6. data/lib/active_record/associations/association.rb +33 -17
  7. data/lib/active_record/associations/association_scope.rb +1 -3
  8. data/lib/active_record/associations/belongs_to_association.rb +15 -4
  9. data/lib/active_record/associations/belongs_to_polymorphic_association.rb +10 -2
  10. data/lib/active_record/associations/builder/association.rb +8 -2
  11. data/lib/active_record/associations/builder/belongs_to.rb +19 -6
  12. data/lib/active_record/associations/builder/collection_association.rb +10 -3
  13. data/lib/active_record/associations/builder/has_many.rb +3 -2
  14. data/lib/active_record/associations/builder/has_one.rb +2 -1
  15. data/lib/active_record/associations/builder/singular_association.rb +2 -2
  16. data/lib/active_record/associations/collection_association.rb +20 -22
  17. data/lib/active_record/associations/collection_proxy.rb +15 -5
  18. data/lib/active_record/associations/disable_joins_association_scope.rb +59 -0
  19. data/lib/active_record/associations/has_many_association.rb +8 -5
  20. data/lib/active_record/associations/has_many_through_association.rb +2 -1
  21. data/lib/active_record/associations/has_one_association.rb +10 -7
  22. data/lib/active_record/associations/has_one_through_association.rb +1 -1
  23. data/lib/active_record/associations/join_dependency.rb +23 -15
  24. data/lib/active_record/associations/preloader/association.rb +186 -52
  25. data/lib/active_record/associations/preloader/batch.rb +48 -0
  26. data/lib/active_record/associations/preloader/branch.rb +147 -0
  27. data/lib/active_record/associations/preloader/through_association.rb +50 -14
  28. data/lib/active_record/associations/preloader.rb +39 -113
  29. data/lib/active_record/associations/singular_association.rb +8 -2
  30. data/lib/active_record/associations/through_association.rb +3 -3
  31. data/lib/active_record/associations.rb +138 -100
  32. data/lib/active_record/asynchronous_queries_tracker.rb +60 -0
  33. data/lib/active_record/attribute_assignment.rb +1 -1
  34. data/lib/active_record/attribute_methods/before_type_cast.rb +7 -2
  35. data/lib/active_record/attribute_methods/dirty.rb +49 -16
  36. data/lib/active_record/attribute_methods/primary_key.rb +2 -2
  37. data/lib/active_record/attribute_methods/query.rb +2 -2
  38. data/lib/active_record/attribute_methods/read.rb +8 -6
  39. data/lib/active_record/attribute_methods/serialization.rb +57 -19
  40. data/lib/active_record/attribute_methods/time_zone_conversion.rb +4 -3
  41. data/lib/active_record/attribute_methods/write.rb +7 -10
  42. data/lib/active_record/attribute_methods.rb +19 -22
  43. data/lib/active_record/attributes.rb +24 -35
  44. data/lib/active_record/autosave_association.rb +8 -23
  45. data/lib/active_record/base.rb +19 -1
  46. data/lib/active_record/callbacks.rb +14 -16
  47. data/lib/active_record/coders/yaml_column.rb +4 -8
  48. data/lib/active_record/connection_adapters/abstract/connection_handler.rb +292 -0
  49. data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +209 -0
  50. data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +76 -0
  51. data/lib/active_record/connection_adapters/abstract/connection_pool.rb +47 -561
  52. data/lib/active_record/connection_adapters/abstract/database_limits.rb +0 -17
  53. data/lib/active_record/connection_adapters/abstract/database_statements.rb +46 -22
  54. data/lib/active_record/connection_adapters/abstract/query_cache.rb +24 -12
  55. data/lib/active_record/connection_adapters/abstract/quoting.rb +42 -72
  56. data/lib/active_record/connection_adapters/abstract/schema_creation.rb +4 -17
  57. data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +52 -23
  58. data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +14 -1
  59. data/lib/active_record/connection_adapters/abstract/schema_statements.rb +82 -25
  60. data/lib/active_record/connection_adapters/abstract/transaction.rb +15 -22
  61. data/lib/active_record/connection_adapters/abstract_adapter.rb +144 -82
  62. data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +115 -85
  63. data/lib/active_record/connection_adapters/column.rb +4 -0
  64. data/lib/active_record/connection_adapters/mysql/database_statements.rb +37 -25
  65. data/lib/active_record/connection_adapters/mysql/quoting.rb +50 -23
  66. data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +4 -1
  67. data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +7 -1
  68. data/lib/active_record/connection_adapters/mysql/schema_statements.rb +20 -1
  69. data/lib/active_record/connection_adapters/mysql2_adapter.rb +12 -6
  70. data/lib/active_record/connection_adapters/pool_config.rb +7 -7
  71. data/lib/active_record/connection_adapters/postgresql/column.rb +19 -1
  72. data/lib/active_record/connection_adapters/postgresql/database_statements.rb +20 -17
  73. data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
  74. data/lib/active_record/connection_adapters/postgresql/oid/date.rb +8 -0
  75. data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +5 -0
  76. data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +53 -14
  77. data/lib/active_record/connection_adapters/postgresql/oid/range.rb +1 -1
  78. data/lib/active_record/connection_adapters/postgresql/oid/timestamp.rb +15 -0
  79. data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +30 -0
  80. data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +18 -6
  81. data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
  82. data/lib/active_record/connection_adapters/postgresql/quoting.rb +76 -73
  83. data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +34 -0
  84. data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +21 -1
  85. data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +22 -1
  86. data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +25 -0
  87. data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +40 -21
  88. data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -10
  89. data/lib/active_record/connection_adapters/postgresql_adapter.rb +207 -106
  90. data/lib/active_record/connection_adapters/schema_cache.rb +39 -38
  91. data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +25 -19
  92. data/lib/active_record/connection_adapters/sqlite3/quoting.rb +33 -18
  93. data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +6 -0
  94. data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +19 -17
  95. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +98 -36
  96. data/lib/active_record/connection_adapters.rb +6 -5
  97. data/lib/active_record/connection_handling.rb +49 -55
  98. data/lib/active_record/core.rb +123 -148
  99. data/lib/active_record/database_configurations/connection_url_resolver.rb +2 -1
  100. data/lib/active_record/database_configurations/database_config.rb +12 -9
  101. data/lib/active_record/database_configurations/hash_config.rb +63 -5
  102. data/lib/active_record/database_configurations/url_config.rb +2 -2
  103. data/lib/active_record/database_configurations.rb +15 -32
  104. data/lib/active_record/delegated_type.rb +53 -12
  105. data/lib/active_record/destroy_association_async_job.rb +1 -1
  106. data/lib/active_record/disable_joins_association_relation.rb +39 -0
  107. data/lib/active_record/dynamic_matchers.rb +1 -1
  108. data/lib/active_record/encryption/cipher/aes256_gcm.rb +98 -0
  109. data/lib/active_record/encryption/cipher.rb +53 -0
  110. data/lib/active_record/encryption/config.rb +44 -0
  111. data/lib/active_record/encryption/configurable.rb +67 -0
  112. data/lib/active_record/encryption/context.rb +35 -0
  113. data/lib/active_record/encryption/contexts.rb +72 -0
  114. data/lib/active_record/encryption/derived_secret_key_provider.rb +12 -0
  115. data/lib/active_record/encryption/deterministic_key_provider.rb +14 -0
  116. data/lib/active_record/encryption/encryptable_record.rb +206 -0
  117. data/lib/active_record/encryption/encrypted_attribute_type.rb +140 -0
  118. data/lib/active_record/encryption/encrypted_fixtures.rb +38 -0
  119. data/lib/active_record/encryption/encrypting_only_encryptor.rb +12 -0
  120. data/lib/active_record/encryption/encryptor.rb +155 -0
  121. data/lib/active_record/encryption/envelope_encryption_key_provider.rb +55 -0
  122. data/lib/active_record/encryption/errors.rb +15 -0
  123. data/lib/active_record/encryption/extended_deterministic_queries.rb +160 -0
  124. data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +28 -0
  125. data/lib/active_record/encryption/key.rb +28 -0
  126. data/lib/active_record/encryption/key_generator.rb +42 -0
  127. data/lib/active_record/encryption/key_provider.rb +46 -0
  128. data/lib/active_record/encryption/message.rb +33 -0
  129. data/lib/active_record/encryption/message_serializer.rb +90 -0
  130. data/lib/active_record/encryption/null_encryptor.rb +21 -0
  131. data/lib/active_record/encryption/properties.rb +76 -0
  132. data/lib/active_record/encryption/read_only_null_encryptor.rb +24 -0
  133. data/lib/active_record/encryption/scheme.rb +99 -0
  134. data/lib/active_record/encryption.rb +55 -0
  135. data/lib/active_record/enum.rb +50 -43
  136. data/lib/active_record/errors.rb +67 -4
  137. data/lib/active_record/explain_registry.rb +11 -6
  138. data/lib/active_record/explain_subscriber.rb +1 -1
  139. data/lib/active_record/fixture_set/file.rb +15 -1
  140. data/lib/active_record/fixture_set/table_row.rb +41 -6
  141. data/lib/active_record/fixture_set/table_rows.rb +4 -4
  142. data/lib/active_record/fixtures.rb +20 -23
  143. data/lib/active_record/future_result.rb +139 -0
  144. data/lib/active_record/gem_version.rb +5 -5
  145. data/lib/active_record/inheritance.rb +55 -17
  146. data/lib/active_record/insert_all.rb +80 -14
  147. data/lib/active_record/integration.rb +4 -3
  148. data/lib/active_record/internal_metadata.rb +1 -5
  149. data/lib/active_record/legacy_yaml_adapter.rb +2 -39
  150. data/lib/active_record/locking/optimistic.rb +36 -21
  151. data/lib/active_record/locking/pessimistic.rb +10 -4
  152. data/lib/active_record/log_subscriber.rb +23 -7
  153. data/lib/active_record/middleware/database_selector/resolver.rb +6 -10
  154. data/lib/active_record/middleware/database_selector.rb +18 -6
  155. data/lib/active_record/middleware/shard_selector.rb +60 -0
  156. data/lib/active_record/migration/command_recorder.rb +8 -9
  157. data/lib/active_record/migration/compatibility.rb +93 -46
  158. data/lib/active_record/migration/join_table.rb +1 -1
  159. data/lib/active_record/migration.rb +167 -87
  160. data/lib/active_record/model_schema.rb +58 -59
  161. data/lib/active_record/nested_attributes.rb +13 -12
  162. data/lib/active_record/no_touching.rb +3 -3
  163. data/lib/active_record/null_relation.rb +2 -6
  164. data/lib/active_record/persistence.rb +231 -61
  165. data/lib/active_record/query_cache.rb +2 -2
  166. data/lib/active_record/query_logs.rb +149 -0
  167. data/lib/active_record/querying.rb +16 -6
  168. data/lib/active_record/railtie.rb +136 -22
  169. data/lib/active_record/railties/controller_runtime.rb +4 -5
  170. data/lib/active_record/railties/databases.rake +78 -136
  171. data/lib/active_record/readonly_attributes.rb +11 -0
  172. data/lib/active_record/reflection.rb +80 -49
  173. data/lib/active_record/relation/batches/batch_enumerator.rb +19 -5
  174. data/lib/active_record/relation/batches.rb +6 -6
  175. data/lib/active_record/relation/calculations.rb +92 -60
  176. data/lib/active_record/relation/delegation.rb +7 -7
  177. data/lib/active_record/relation/finder_methods.rb +31 -35
  178. data/lib/active_record/relation/merger.rb +20 -13
  179. data/lib/active_record/relation/predicate_builder/association_query_value.rb +20 -1
  180. data/lib/active_record/relation/predicate_builder.rb +1 -6
  181. data/lib/active_record/relation/query_attribute.rb +28 -11
  182. data/lib/active_record/relation/query_methods.rb +304 -68
  183. data/lib/active_record/relation/record_fetch_warning.rb +7 -9
  184. data/lib/active_record/relation/spawn_methods.rb +2 -2
  185. data/lib/active_record/relation/where_clause.rb +10 -19
  186. data/lib/active_record/relation.rb +189 -88
  187. data/lib/active_record/result.rb +23 -11
  188. data/lib/active_record/runtime_registry.rb +9 -13
  189. data/lib/active_record/sanitization.rb +17 -12
  190. data/lib/active_record/schema.rb +38 -23
  191. data/lib/active_record/schema_dumper.rb +29 -19
  192. data/lib/active_record/schema_migration.rb +4 -4
  193. data/lib/active_record/scoping/default.rb +60 -13
  194. data/lib/active_record/scoping/named.rb +3 -11
  195. data/lib/active_record/scoping.rb +64 -34
  196. data/lib/active_record/serialization.rb +6 -1
  197. data/lib/active_record/signed_id.rb +3 -3
  198. data/lib/active_record/store.rb +2 -2
  199. data/lib/active_record/suppressor.rb +11 -15
  200. data/lib/active_record/table_metadata.rb +6 -2
  201. data/lib/active_record/tasks/database_tasks.rb +127 -60
  202. data/lib/active_record/tasks/mysql_database_tasks.rb +1 -1
  203. data/lib/active_record/tasks/postgresql_database_tasks.rb +19 -13
  204. data/lib/active_record/test_databases.rb +1 -1
  205. data/lib/active_record/test_fixtures.rb +9 -6
  206. data/lib/active_record/timestamp.rb +3 -4
  207. data/lib/active_record/transactions.rb +12 -17
  208. data/lib/active_record/translation.rb +3 -3
  209. data/lib/active_record/type/adapter_specific_registry.rb +32 -7
  210. data/lib/active_record/type/hash_lookup_type_map.rb +34 -1
  211. data/lib/active_record/type/internal/timezone.rb +2 -2
  212. data/lib/active_record/type/serialized.rb +9 -5
  213. data/lib/active_record/type/type_map.rb +17 -20
  214. data/lib/active_record/type.rb +1 -2
  215. data/lib/active_record/validations/associated.rb +4 -4
  216. data/lib/active_record/validations/presence.rb +2 -2
  217. data/lib/active_record/validations/uniqueness.rb +4 -4
  218. data/lib/active_record/version.rb +1 -1
  219. data/lib/active_record.rb +225 -27
  220. data/lib/arel/attributes/attribute.rb +0 -8
  221. data/lib/arel/crud.rb +28 -22
  222. data/lib/arel/delete_manager.rb +18 -4
  223. data/lib/arel/filter_predications.rb +9 -0
  224. data/lib/arel/insert_manager.rb +2 -3
  225. data/lib/arel/nodes/and.rb +4 -0
  226. data/lib/arel/nodes/casted.rb +1 -1
  227. data/lib/arel/nodes/delete_statement.rb +12 -13
  228. data/lib/arel/nodes/filter.rb +10 -0
  229. data/lib/arel/nodes/function.rb +1 -0
  230. data/lib/arel/nodes/insert_statement.rb +2 -2
  231. data/lib/arel/nodes/select_core.rb +2 -2
  232. data/lib/arel/nodes/select_statement.rb +2 -2
  233. data/lib/arel/nodes/update_statement.rb +8 -3
  234. data/lib/arel/nodes.rb +1 -0
  235. data/lib/arel/predications.rb +11 -3
  236. data/lib/arel/select_manager.rb +10 -4
  237. data/lib/arel/table.rb +0 -1
  238. data/lib/arel/tree_manager.rb +0 -12
  239. data/lib/arel/update_manager.rb +18 -4
  240. data/lib/arel/visitors/dot.rb +80 -90
  241. data/lib/arel/visitors/mysql.rb +8 -2
  242. data/lib/arel/visitors/postgresql.rb +0 -10
  243. data/lib/arel/visitors/to_sql.rb +58 -2
  244. data/lib/arel.rb +2 -1
  245. data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +1 -1
  246. data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +1 -1
  247. data/lib/rails/generators/active_record/model/templates/model.rb.tt +1 -1
  248. data/lib/rails/generators/active_record/model/templates/module.rb.tt +2 -2
  249. data/lib/rails/generators/active_record/multi_db/multi_db_generator.rb +16 -0
  250. data/lib/rails/generators/active_record/multi_db/templates/multi_db.rb.tt +44 -0
  251. metadata +55 -11
data/lib/active_record.rb CHANGED
@@ -38,25 +38,27 @@ module ActiveRecord
38
38
 
39
39
  autoload :Base
40
40
  autoload :Callbacks
41
- autoload :Core
42
41
  autoload :ConnectionHandling
42
+ autoload :Core
43
43
  autoload :CounterCache
44
- autoload :DynamicMatchers
45
44
  autoload :DelegatedType
45
+ autoload :DestroyAssociationAsyncJob
46
+ autoload :DynamicMatchers
47
+ autoload :Encryption
46
48
  autoload :Enum
47
- autoload :InternalMetadata
48
49
  autoload :Explain
49
50
  autoload :Inheritance
50
51
  autoload :Integration
52
+ autoload :InternalMetadata
51
53
  autoload :Migration
52
54
  autoload :Migrator, "active_record/migration"
53
55
  autoload :ModelSchema
54
56
  autoload :NestedAttributes
55
57
  autoload :NoTouching
56
- autoload :TouchLater
57
58
  autoload :Persistence
58
59
  autoload :QueryCache
59
60
  autoload :Querying
61
+ autoload :QueryLogs
60
62
  autoload :ReadonlyAttributes
61
63
  autoload :RecordInvalid, "active_record/validations"
62
64
  autoload :Reflection
@@ -66,32 +68,37 @@ module ActiveRecord
66
68
  autoload :SchemaDumper
67
69
  autoload :SchemaMigration
68
70
  autoload :Scoping
71
+ autoload :SecureToken
69
72
  autoload :Serialization
70
- autoload :StatementCache
71
- autoload :Store
72
73
  autoload :SignedId
74
+ autoload :Store
73
75
  autoload :Suppressor
76
+ autoload :TestDatabases
77
+ autoload :TestFixtures, "active_record/fixtures"
74
78
  autoload :Timestamp
79
+ autoload :TouchLater
75
80
  autoload :Transactions
76
81
  autoload :Translation
77
82
  autoload :Validations
78
- autoload :SecureToken
79
- autoload :DestroyAssociationAsyncJob
80
83
 
81
84
  eager_autoload do
82
- autoload :ConnectionAdapters
83
-
84
85
  autoload :Aggregations
86
+ autoload :AssociationRelation
85
87
  autoload :Associations
88
+ autoload :AsynchronousQueriesTracker
86
89
  autoload :AttributeAssignment
87
90
  autoload :AttributeMethods
88
91
  autoload :AutosaveAssociation
89
-
92
+ autoload :ConnectionAdapters
93
+ autoload :DisableJoinsAssociationRelation
94
+ autoload :FutureResult
90
95
  autoload :LegacyYamlAdapter
91
-
92
- autoload :Relation
93
- autoload :AssociationRelation
94
96
  autoload :NullRelation
97
+ autoload :Relation
98
+ autoload :Result
99
+ autoload :StatementCache
100
+ autoload :TableMetadata
101
+ autoload :Type
95
102
 
96
103
  autoload_under "relation" do
97
104
  autoload :QueryMethods
@@ -102,15 +109,11 @@ module ActiveRecord
102
109
  autoload :Batches
103
110
  autoload :Delegation
104
111
  end
105
-
106
- autoload :Result
107
- autoload :TableMetadata
108
- autoload :Type
109
112
  end
110
113
 
111
114
  module Coders
112
- autoload :YAMLColumn, "active_record/coders/yaml_column"
113
115
  autoload :JSON, "active_record/coders/json"
116
+ autoload :YAMLColumn, "active_record/coders/yaml_column"
114
117
  end
115
118
 
116
119
  module AttributeMethods
@@ -122,9 +125,9 @@ module ActiveRecord
122
125
  autoload :PrimaryKey
123
126
  autoload :Query
124
127
  autoload :Read
128
+ autoload :Serialization
125
129
  autoload :TimeZoneConversion
126
130
  autoload :Write
127
- autoload :Serialization
128
131
  end
129
132
  end
130
133
 
@@ -141,29 +144,223 @@ module ActiveRecord
141
144
  extend ActiveSupport::Autoload
142
145
 
143
146
  eager_autoload do
144
- autoload :Named
145
147
  autoload :Default
148
+ autoload :Named
146
149
  end
147
150
  end
148
151
 
149
152
  module Middleware
150
153
  extend ActiveSupport::Autoload
151
154
 
152
- autoload :DatabaseSelector, "active_record/middleware/database_selector"
155
+ autoload :DatabaseSelector
156
+ autoload :ShardSelector
153
157
  end
154
158
 
155
159
  module Tasks
156
160
  extend ActiveSupport::Autoload
157
161
 
158
162
  autoload :DatabaseTasks
159
- autoload :SQLiteDatabaseTasks, "active_record/tasks/sqlite_database_tasks"
160
163
  autoload :MySQLDatabaseTasks, "active_record/tasks/mysql_database_tasks"
161
- autoload :PostgreSQLDatabaseTasks,
162
- "active_record/tasks/postgresql_database_tasks"
164
+ autoload :PostgreSQLDatabaseTasks, "active_record/tasks/postgresql_database_tasks"
165
+ autoload :SQLiteDatabaseTasks, "active_record/tasks/sqlite_database_tasks"
163
166
  end
164
167
 
165
- autoload :TestDatabases, "active_record/test_databases"
166
- autoload :TestFixtures, "active_record/fixtures"
168
+ # Lazily load the schema cache. This option will load the schema cache
169
+ # when a connection is established rather than on boot. If set,
170
+ # +config.active_record.use_schema_cache_dump+ will be set to false.
171
+ singleton_class.attr_accessor :lazily_load_schema_cache
172
+ self.lazily_load_schema_cache = false
173
+
174
+ # A list of tables or regex's to match tables to ignore when
175
+ # dumping the schema cache. For example if this is set to +[/^_/]+
176
+ # the schema cache will not dump tables named with an underscore.
177
+ singleton_class.attr_accessor :schema_cache_ignored_tables
178
+ self.schema_cache_ignored_tables = []
179
+
180
+ singleton_class.attr_accessor :legacy_connection_handling
181
+ self.legacy_connection_handling = true
182
+
183
+ singleton_class.attr_reader :default_timezone
184
+
185
+ # Determines whether to use Time.utc (using :utc) or Time.local (using :local) when pulling
186
+ # dates and times from the database. This is set to :utc by default.
187
+ def self.default_timezone=(default_timezone)
188
+ unless %i(local utc).include?(default_timezone)
189
+ raise ArgumentError, "default_timezone must be either :utc (default) or :local."
190
+ end
191
+
192
+ @default_timezone = default_timezone
193
+ end
194
+
195
+ self.default_timezone = :utc
196
+
197
+ singleton_class.attr_accessor :writing_role
198
+ self.writing_role = :writing
199
+
200
+ singleton_class.attr_accessor :reading_role
201
+ self.reading_role = :reading
202
+
203
+ # Sets the async_query_executor for an application. By default the thread pool executor
204
+ # set to +nil+ which will not run queries in the background. Applications must configure
205
+ # a thread pool executor to use this feature. Options are:
206
+ #
207
+ # * nil - Does not initialize a thread pool executor. Any async calls will be
208
+ # run in the foreground.
209
+ # * :global_thread_pool - Initializes a single +Concurrent::ThreadPoolExecutor+
210
+ # that uses the +async_query_concurrency+ for the +max_threads+ value.
211
+ # * :multi_thread_pool - Initializes a +Concurrent::ThreadPoolExecutor+ for each
212
+ # database connection. The initializer values are defined in the configuration hash.
213
+ singleton_class.attr_accessor :async_query_executor
214
+ self.async_query_executor = nil
215
+
216
+ def self.global_thread_pool_async_query_executor # :nodoc:
217
+ concurrency = global_executor_concurrency || 4
218
+ @global_thread_pool_async_query_executor ||= Concurrent::ThreadPoolExecutor.new(
219
+ min_threads: 0,
220
+ max_threads: concurrency,
221
+ max_queue: concurrency * 4,
222
+ fallback_policy: :caller_runs
223
+ )
224
+ end
225
+
226
+ # Set the +global_executor_concurrency+. This configuration value can only be used
227
+ # with the global thread pool async query executor.
228
+ def self.global_executor_concurrency=(global_executor_concurrency)
229
+ if self.async_query_executor.nil? || self.async_query_executor == :multi_thread_pool
230
+ raise ArgumentError, "`global_executor_concurrency` cannot be set when using the executor is nil or set to multi_thead_pool. For multiple thread pools, please set the concurrency in your database configuration."
231
+ end
232
+
233
+ @global_executor_concurrency = global_executor_concurrency
234
+ end
235
+
236
+ def self.global_executor_concurrency # :nodoc:
237
+ @global_executor_concurrency ||= nil
238
+ end
239
+
240
+ singleton_class.attr_accessor :index_nested_attribute_errors
241
+ self.index_nested_attribute_errors = false
242
+
243
+ ##
244
+ # :singleton-method:
245
+ #
246
+ # Specifies if the methods calling database queries should be logged below
247
+ # their relevant queries. Defaults to false.
248
+ singleton_class.attr_accessor :verbose_query_logs
249
+ self.verbose_query_logs = false
250
+
251
+ ##
252
+ # :singleton-method:
253
+ #
254
+ # Specifies the names of the queues used by background jobs.
255
+ singleton_class.attr_accessor :queues
256
+ self.queues = {}
257
+
258
+ singleton_class.attr_accessor :maintain_test_schema
259
+ self.maintain_test_schema = nil
260
+
261
+ ##
262
+ # :singleton-method:
263
+ # Specify a threshold for the size of query result sets. If the number of
264
+ # records in the set exceeds the threshold, a warning is logged. This can
265
+ # be used to identify queries which load thousands of records and
266
+ # potentially cause memory bloat.
267
+ singleton_class.attr_accessor :warn_on_records_fetched_greater_than
268
+ self.warn_on_records_fetched_greater_than = false
269
+
270
+ singleton_class.attr_accessor :application_record_class
271
+ self.application_record_class = nil
272
+
273
+ ##
274
+ # :singleton-method:
275
+ # Set the application to log or raise when an association violates strict loading.
276
+ # Defaults to :raise.
277
+ singleton_class.attr_accessor :action_on_strict_loading_violation
278
+ self.action_on_strict_loading_violation = :raise
279
+
280
+ ##
281
+ # :singleton-method:
282
+ # Specifies the format to use when dumping the database schema with Rails'
283
+ # Rakefile. If :sql, the schema is dumped as (potentially database-
284
+ # specific) SQL statements. If :ruby, the schema is dumped as an
285
+ # ActiveRecord::Schema file which can be loaded into any database that
286
+ # supports migrations. Use :ruby if you want to have different database
287
+ # adapters for, e.g., your development and test environments.
288
+ singleton_class.attr_accessor :schema_format
289
+ self.schema_format = :ruby
290
+
291
+ ##
292
+ # :singleton-method:
293
+ # Specifies if an error should be raised if the query has an order being
294
+ # ignored when doing batch queries. Useful in applications where the
295
+ # scope being ignored is error-worthy, rather than a warning.
296
+ singleton_class.attr_accessor :error_on_ignored_order
297
+ self.error_on_ignored_order = false
298
+
299
+ ##
300
+ # :singleton-method:
301
+ # Specify whether or not to use timestamps for migration versions
302
+ singleton_class.attr_accessor :timestamped_migrations
303
+ self.timestamped_migrations = true
304
+
305
+ ##
306
+ # :singleton-method:
307
+ # Specify whether schema dump should happen at the end of the
308
+ # bin/rails db:migrate command. This is true by default, which is useful for the
309
+ # development environment. This should ideally be false in the production
310
+ # environment where dumping schema is rarely needed.
311
+ singleton_class.attr_accessor :dump_schema_after_migration
312
+ self.dump_schema_after_migration = true
313
+
314
+ ##
315
+ # :singleton-method:
316
+ # Specifies which database schemas to dump when calling db:schema:dump.
317
+ # If the value is :schema_search_path (the default), any schemas listed in
318
+ # schema_search_path are dumped. Use :all to dump all schemas regardless
319
+ # of schema_search_path, or a string of comma separated schemas for a
320
+ # custom list.
321
+ singleton_class.attr_accessor :dump_schemas
322
+ self.dump_schemas = :schema_search_path
323
+
324
+ ##
325
+ # :singleton-method:
326
+ # Show a warning when Rails couldn't parse your database.yml
327
+ # for multiple databases.
328
+ singleton_class.attr_accessor :suppress_multiple_database_warning
329
+ self.suppress_multiple_database_warning = false
330
+
331
+ ##
332
+ # :singleton-method:
333
+ # If true, Rails will verify all foreign keys in the database after loading fixtures.
334
+ # An error will be raised if there are any foreign key violations, indicating incorrectly
335
+ # written fixtures.
336
+ # Supported by PostgreSQL and SQLite.
337
+ singleton_class.attr_accessor :verify_foreign_keys_for_fixtures
338
+ self.verify_foreign_keys_for_fixtures = false
339
+
340
+ singleton_class.attr_accessor :query_transformers
341
+ self.query_transformers = []
342
+
343
+ ##
344
+ # :singleton-method:
345
+ # Application configurable boolean that instructs the YAML Coder to use
346
+ # an unsafe load if set to true.
347
+ singleton_class.attr_accessor :use_yaml_unsafe_load
348
+ self.use_yaml_unsafe_load = false
349
+
350
+ ##
351
+ # :singleton-method:
352
+ # Application configurable boolean that denotes whether or not to raise
353
+ # an exception when the PostgreSQLAdapter is provided with an integer that
354
+ # is wider than signed 64bit representation
355
+ singleton_class.attr_accessor :raise_int_wider_than_64bit
356
+ self.raise_int_wider_than_64bit = true
357
+
358
+ ##
359
+ # :singleton-method:
360
+ # Application configurable array that provides additional permitted classes
361
+ # to Psych safe_load in the YAML Coder
362
+ singleton_class.attr_accessor :yaml_column_permitted_classes
363
+ self.yaml_column_permitted_classes = [Symbol]
167
364
 
168
365
  def self.eager_load!
169
366
  super
@@ -172,6 +369,7 @@ module ActiveRecord
172
369
  ActiveRecord::Associations.eager_load!
173
370
  ActiveRecord::AttributeMethods.eager_load!
174
371
  ActiveRecord::ConnectionAdapters.eager_load!
372
+ ActiveRecord::Encryption.eager_load!
175
373
  end
176
374
  end
177
375
 
@@ -27,14 +27,6 @@ module Arel # :nodoc: all
27
27
  relation.able_to_type_cast?
28
28
  end
29
29
  end
30
-
31
- class String < Attribute; end
32
- class Time < Attribute; end
33
- class Boolean < Attribute; end
34
- class Decimal < Attribute; end
35
- class Float < Attribute; end
36
- class Integer < Attribute; end
37
- class Undefined < Attribute; end
38
30
  end
39
31
 
40
32
  Attribute = Attributes::Attribute
data/lib/arel/crud.rb CHANGED
@@ -4,23 +4,6 @@ module Arel # :nodoc: all
4
4
  ###
5
5
  # FIXME hopefully we can remove this
6
6
  module Crud
7
- def compile_update(values, pk)
8
- um = UpdateManager.new
9
-
10
- if Nodes::SqlLiteral === values
11
- relation = @ctx.from
12
- else
13
- relation = values.first.first.relation
14
- end
15
- um.key = pk
16
- um.table relation
17
- um.set values
18
- um.take @ast.limit.expr if @ast.limit
19
- um.order(*@ast.orders)
20
- um.wheres = @ctx.wheres
21
- um
22
- end
23
-
24
7
  def compile_insert(values)
25
8
  im = create_insert
26
9
  im.insert values
@@ -31,11 +14,34 @@ module Arel # :nodoc: all
31
14
  InsertManager.new
32
15
  end
33
16
 
34
- def compile_delete
35
- dm = DeleteManager.new
36
- dm.take @ast.limit.expr if @ast.limit
37
- dm.wheres = @ctx.wheres
38
- dm.from @ctx.froms
17
+ def compile_update(
18
+ values,
19
+ key = nil,
20
+ having_clause = nil,
21
+ group_values_columns = []
22
+ )
23
+ um = UpdateManager.new(source)
24
+ um.set(values)
25
+ um.take(limit)
26
+ um.offset(offset)
27
+ um.order(*orders)
28
+ um.wheres = constraints
29
+ um.key = key
30
+
31
+ um.group(group_values_columns) unless group_values_columns.empty?
32
+ um.having(having_clause) unless having_clause.nil?
33
+ um
34
+ end
35
+
36
+ def compile_delete(key = nil, having_clause = nil, group_values_columns = [])
37
+ dm = DeleteManager.new(source)
38
+ dm.take(limit)
39
+ dm.offset(offset)
40
+ dm.order(*orders)
41
+ dm.wheres = constraints
42
+ dm.key = key
43
+ dm.group(group_values_columns) unless group_values_columns.empty?
44
+ dm.having(having_clause) unless having_clause.nil?
39
45
  dm
40
46
  end
41
47
  end
@@ -4,15 +4,29 @@ module Arel # :nodoc: all
4
4
  class DeleteManager < Arel::TreeManager
5
5
  include TreeManager::StatementMethods
6
6
 
7
- def initialize
8
- super
9
- @ast = Nodes::DeleteStatement.new
10
- @ctx = @ast
7
+ def initialize(table = nil)
8
+ @ast = Nodes::DeleteStatement.new(table)
11
9
  end
12
10
 
13
11
  def from(relation)
14
12
  @ast.relation = relation
15
13
  self
16
14
  end
15
+
16
+ def group(columns)
17
+ columns.each do |column|
18
+ column = Nodes::SqlLiteral.new(column) if String === column
19
+ column = Nodes::SqlLiteral.new(column.to_s) if Symbol === column
20
+
21
+ @ast.groups.push Nodes::Group.new column
22
+ end
23
+
24
+ self
25
+ end
26
+
27
+ def having(expr)
28
+ @ast.havings << expr
29
+ self
30
+ end
17
31
  end
18
32
  end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arel # :nodoc: all
4
+ module FilterPredications
5
+ def filter(expr)
6
+ Nodes::Filter.new(self, expr)
7
+ end
8
+ end
9
+ end
@@ -2,9 +2,8 @@
2
2
 
3
3
  module Arel # :nodoc: all
4
4
  class InsertManager < Arel::TreeManager
5
- def initialize
6
- super
7
- @ast = Nodes::InsertStatement.new
5
+ def initialize(table = nil)
6
+ @ast = Nodes::InsertStatement.new(table)
8
7
  end
9
8
 
10
9
  def into(table)
@@ -18,6 +18,10 @@ module Arel # :nodoc: all
18
18
  children[1]
19
19
  end
20
20
 
21
+ def fetch_attribute(&block)
22
+ children.any? && children.all? { |child| child.fetch_attribute(&block) }
23
+ end
24
+
21
25
  def hash
22
26
  children.hash
23
27
  end
@@ -47,7 +47,7 @@ module Arel # :nodoc: all
47
47
 
48
48
  def self.build_quoted(other, attribute = nil)
49
49
  case other
50
- when Arel::Nodes::Node, Arel::Attributes::Attribute, Arel::Table, Arel::Nodes::BindParam, Arel::SelectManager, Arel::Nodes::Quoted, Arel::Nodes::SqlLiteral
50
+ when Arel::Nodes::Node, Arel::Attributes::Attribute, Arel::Table, Arel::SelectManager, Arel::Nodes::SqlLiteral, ActiveModel::Attribute
51
51
  other
52
52
  else
53
53
  case attribute
@@ -3,17 +3,14 @@
3
3
  module Arel # :nodoc: all
4
4
  module Nodes
5
5
  class DeleteStatement < Arel::Nodes::Node
6
- attr_accessor :left, :right, :orders, :limit, :offset, :key
7
-
8
- alias :relation :left
9
- alias :relation= :left=
10
- alias :wheres :right
11
- alias :wheres= :right=
6
+ attr_accessor :relation, :wheres, :groups, :havings, :orders, :limit, :offset, :key
12
7
 
13
8
  def initialize(relation = nil, wheres = [])
14
9
  super()
15
- @left = relation
16
- @right = wheres
10
+ @relation = relation
11
+ @wheres = wheres
12
+ @groups = []
13
+ @havings = []
17
14
  @orders = []
18
15
  @limit = nil
19
16
  @offset = nil
@@ -22,19 +19,21 @@ module Arel # :nodoc: all
22
19
 
23
20
  def initialize_copy(other)
24
21
  super
25
- @left = @left.clone if @left
26
- @right = @right.clone if @right
22
+ @relation = @relation.clone if @relation
23
+ @wheres = @wheres.clone if @wheres
27
24
  end
28
25
 
29
26
  def hash
30
- [self.class, @left, @right, @orders, @limit, @offset, @key].hash
27
+ [self.class, @relation, @wheres, @orders, @limit, @offset, @key].hash
31
28
  end
32
29
 
33
30
  def eql?(other)
34
31
  self.class == other.class &&
35
- self.left == other.left &&
36
- self.right == other.right &&
32
+ self.relation == other.relation &&
33
+ self.wheres == other.wheres &&
37
34
  self.orders == other.orders &&
35
+ self.groups == other.groups &&
36
+ self.havings == other.havings &&
38
37
  self.limit == other.limit &&
39
38
  self.offset == other.offset &&
40
39
  self.key == other.key
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Arel # :nodoc: all
4
+ module Nodes
5
+ class Filter < Binary
6
+ include Arel::WindowPredications
7
+ include Arel::AliasPredication
8
+ end
9
+ end
10
+ end
@@ -4,6 +4,7 @@ module Arel # :nodoc: all
4
4
  module Nodes
5
5
  class Function < Arel::Nodes::NodeExpression
6
6
  include Arel::WindowPredications
7
+ include Arel::FilterPredications
7
8
  attr_accessor :expressions, :alias, :distinct
8
9
 
9
10
  def initialize(expr, aliaz = nil)
@@ -5,9 +5,9 @@ module Arel # :nodoc: all
5
5
  class InsertStatement < Arel::Nodes::Node
6
6
  attr_accessor :relation, :columns, :values, :select
7
7
 
8
- def initialize
8
+ def initialize(relation = nil)
9
9
  super()
10
- @relation = nil
10
+ @relation = relation
11
11
  @columns = []
12
12
  @values = nil
13
13
  @select = nil
@@ -6,9 +6,9 @@ module Arel # :nodoc: all
6
6
  attr_accessor :projections, :wheres, :groups, :windows, :comment
7
7
  attr_accessor :havings, :source, :set_quantifier, :optimizer_hints
8
8
 
9
- def initialize
9
+ def initialize(relation = nil)
10
10
  super()
11
- @source = JoinSource.new nil
11
+ @source = JoinSource.new(relation)
12
12
 
13
13
  # https://ronsavage.github.io/SQL/sql-92.bnf.html#set%20quantifier
14
14
  @set_quantifier = nil
@@ -6,9 +6,9 @@ module Arel # :nodoc: all
6
6
  attr_reader :cores
7
7
  attr_accessor :limit, :orders, :lock, :offset, :with
8
8
 
9
- def initialize(cores = [SelectCore.new])
9
+ def initialize(relation = nil)
10
10
  super()
11
- @cores = cores
11
+ @cores = [SelectCore.new(relation)]
12
12
  @orders = []
13
13
  @limit = nil
14
14
  @lock = nil
@@ -3,12 +3,15 @@
3
3
  module Arel # :nodoc: all
4
4
  module Nodes
5
5
  class UpdateStatement < Arel::Nodes::Node
6
- attr_accessor :relation, :wheres, :values, :orders, :limit, :offset, :key
6
+ attr_accessor :relation, :wheres, :values, :groups, :havings, :orders, :limit, :offset, :key
7
7
 
8
- def initialize
9
- @relation = nil
8
+ def initialize(relation = nil)
9
+ super()
10
+ @relation = relation
10
11
  @wheres = []
11
12
  @values = []
13
+ @groups = []
14
+ @havings = []
12
15
  @orders = []
13
16
  @limit = nil
14
17
  @offset = nil
@@ -30,6 +33,8 @@ module Arel # :nodoc: all
30
33
  self.relation == other.relation &&
31
34
  self.wheres == other.wheres &&
32
35
  self.values == other.values &&
36
+ self.groups == other.groups &&
37
+ self.havings == other.havings &&
33
38
  self.orders == other.orders &&
34
39
  self.limit == other.limit &&
35
40
  self.offset == other.offset &&
data/lib/arel/nodes.rb CHANGED
@@ -28,6 +28,7 @@ require "arel/nodes/with"
28
28
  # binary
29
29
  require "arel/nodes/binary"
30
30
  require "arel/nodes/equality"
31
+ require "arel/nodes/filter"
31
32
  require "arel/nodes/in"
32
33
  require "arel/nodes/join_source"
33
34
  require "arel/nodes/delete_statement"
@@ -39,7 +39,11 @@ module Arel # :nodoc: all
39
39
  self.in([])
40
40
  elsif open_ended?(other.begin)
41
41
  if open_ended?(other.end)
42
- not_in([])
42
+ if infinity?(other.begin) == 1 || infinity?(other.end) == -1
43
+ self.in([])
44
+ else
45
+ not_in([])
46
+ end
43
47
  elsif other.exclude_end?
44
48
  lt(other.end)
45
49
  else
@@ -52,7 +56,7 @@ module Arel # :nodoc: all
52
56
  else
53
57
  left = quoted_node(other.begin)
54
58
  right = quoted_node(other.end)
55
- Nodes::Between.new(self, left.and(right))
59
+ Nodes::Between.new(self, Nodes::And.new([left, right]))
56
60
  end
57
61
  end
58
62
 
@@ -80,7 +84,11 @@ module Arel # :nodoc: all
80
84
  not_in([])
81
85
  elsif open_ended?(other.begin)
82
86
  if open_ended?(other.end)
83
- self.in([])
87
+ if infinity?(other.begin) == 1 || infinity?(other.end) == -1
88
+ not_in([])
89
+ else
90
+ self.in([])
91
+ end
84
92
  elsif other.exclude_end?
85
93
  gteq(other.end)
86
94
  else