activerecord 7.0.8.1 → 7.2.2.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +642 -1925
- data/MIT-LICENSE +1 -1
- data/README.rdoc +29 -29
- data/examples/performance.rb +2 -2
- data/lib/active_record/aggregations.rb +16 -13
- data/lib/active_record/association_relation.rb +2 -2
- data/lib/active_record/associations/alias_tracker.rb +25 -19
- data/lib/active_record/associations/association.rb +35 -12
- data/lib/active_record/associations/association_scope.rb +16 -9
- data/lib/active_record/associations/belongs_to_association.rb +23 -8
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +3 -2
- data/lib/active_record/associations/builder/association.rb +3 -3
- data/lib/active_record/associations/builder/belongs_to.rb +22 -8
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +3 -7
- data/lib/active_record/associations/builder/has_many.rb +3 -4
- data/lib/active_record/associations/builder/has_one.rb +3 -4
- data/lib/active_record/associations/builder/singular_association.rb +4 -0
- data/lib/active_record/associations/collection_association.rb +26 -14
- data/lib/active_record/associations/collection_proxy.rb +29 -11
- data/lib/active_record/associations/errors.rb +265 -0
- data/lib/active_record/associations/foreign_association.rb +10 -3
- data/lib/active_record/associations/has_many_association.rb +21 -14
- data/lib/active_record/associations/has_many_through_association.rb +17 -7
- data/lib/active_record/associations/has_one_association.rb +10 -3
- data/lib/active_record/associations/join_dependency/join_association.rb +30 -27
- data/lib/active_record/associations/join_dependency.rb +10 -10
- data/lib/active_record/associations/nested_error.rb +47 -0
- data/lib/active_record/associations/preloader/association.rb +33 -8
- data/lib/active_record/associations/preloader/branch.rb +7 -1
- data/lib/active_record/associations/preloader/through_association.rb +1 -3
- data/lib/active_record/associations/preloader.rb +13 -10
- data/lib/active_record/associations/singular_association.rb +7 -1
- data/lib/active_record/associations/through_association.rb +22 -11
- data/lib/active_record/associations.rb +354 -485
- data/lib/active_record/attribute_assignment.rb +0 -4
- data/lib/active_record/attribute_methods/before_type_cast.rb +17 -0
- data/lib/active_record/attribute_methods/composite_primary_key.rb +84 -0
- data/lib/active_record/attribute_methods/dirty.rb +53 -35
- data/lib/active_record/attribute_methods/primary_key.rb +45 -25
- data/lib/active_record/attribute_methods/query.rb +28 -16
- data/lib/active_record/attribute_methods/read.rb +8 -7
- data/lib/active_record/attribute_methods/serialization.rb +131 -32
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +11 -6
- data/lib/active_record/attribute_methods/write.rb +6 -6
- data/lib/active_record/attribute_methods.rb +148 -33
- data/lib/active_record/attributes.rb +64 -50
- data/lib/active_record/autosave_association.rb +69 -37
- data/lib/active_record/base.rb +9 -5
- data/lib/active_record/callbacks.rb +11 -25
- data/lib/active_record/coders/column_serializer.rb +61 -0
- data/lib/active_record/coders/json.rb +1 -1
- data/lib/active_record/coders/yaml_column.rb +70 -42
- data/lib/active_record/connection_adapters/abstract/connection_handler.rb +123 -131
- data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +2 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +4 -1
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +323 -88
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +5 -0
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +160 -45
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +217 -63
- data/lib/active_record/connection_adapters/abstract/quoting.rb +72 -63
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +4 -3
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +18 -4
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +137 -11
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +307 -129
- data/lib/active_record/connection_adapters/abstract/transaction.rb +367 -75
- data/lib/active_record/connection_adapters/abstract_adapter.rb +510 -111
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +278 -125
- data/lib/active_record/connection_adapters/column.rb +9 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +1 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +26 -139
- data/lib/active_record/connection_adapters/mysql/quoting.rb +53 -54
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +9 -0
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +6 -0
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +25 -13
- data/lib/active_record/connection_adapters/mysql2/database_statements.rb +152 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +101 -68
- data/lib/active_record/connection_adapters/pool_config.rb +20 -10
- data/lib/active_record/connection_adapters/pool_manager.rb +19 -9
- data/lib/active_record/connection_adapters/postgresql/column.rb +14 -3
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +100 -43
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +6 -0
- data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -2
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +11 -2
- data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +14 -4
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +65 -61
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +3 -9
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +76 -6
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +151 -2
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +53 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +370 -63
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +367 -201
- data/lib/active_record/connection_adapters/schema_cache.rb +302 -79
- data/lib/active_record/connection_adapters/sqlite3/column.rb +62 -0
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +60 -43
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +45 -46
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +22 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +14 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +16 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +50 -8
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +290 -110
- data/lib/active_record/connection_adapters/statement_pool.rb +7 -0
- data/lib/active_record/connection_adapters/trilogy/database_statements.rb +99 -0
- data/lib/active_record/connection_adapters/trilogy_adapter.rb +229 -0
- data/lib/active_record/connection_adapters.rb +124 -1
- data/lib/active_record/connection_handling.rb +96 -104
- data/lib/active_record/core.rb +251 -176
- data/lib/active_record/counter_cache.rb +68 -34
- data/lib/active_record/database_configurations/connection_url_resolver.rb +8 -3
- data/lib/active_record/database_configurations/database_config.rb +26 -5
- data/lib/active_record/database_configurations/hash_config.rb +52 -34
- data/lib/active_record/database_configurations/url_config.rb +37 -12
- data/lib/active_record/database_configurations.rb +87 -34
- data/lib/active_record/delegated_type.rb +39 -10
- data/lib/active_record/deprecator.rb +7 -0
- data/lib/active_record/destroy_association_async_job.rb +3 -1
- data/lib/active_record/dynamic_matchers.rb +2 -2
- data/lib/active_record/encryption/auto_filtered_parameters.rb +66 -0
- data/lib/active_record/encryption/cipher/aes256_gcm.rb +4 -1
- data/lib/active_record/encryption/config.rb +25 -1
- data/lib/active_record/encryption/configurable.rb +12 -19
- data/lib/active_record/encryption/context.rb +10 -3
- data/lib/active_record/encryption/contexts.rb +5 -1
- data/lib/active_record/encryption/derived_secret_key_provider.rb +8 -2
- data/lib/active_record/encryption/encryptable_record.rb +45 -21
- data/lib/active_record/encryption/encrypted_attribute_type.rb +47 -12
- data/lib/active_record/encryption/encryptor.rb +18 -3
- data/lib/active_record/encryption/extended_deterministic_queries.rb +66 -69
- data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +3 -3
- data/lib/active_record/encryption/key_generator.rb +12 -1
- data/lib/active_record/encryption/key_provider.rb +1 -1
- data/lib/active_record/encryption/message_pack_message_serializer.rb +76 -0
- data/lib/active_record/encryption/message_serializer.rb +6 -0
- data/lib/active_record/encryption/null_encryptor.rb +4 -0
- data/lib/active_record/encryption/properties.rb +3 -3
- data/lib/active_record/encryption/read_only_null_encryptor.rb +4 -0
- data/lib/active_record/encryption/scheme.rb +22 -21
- data/lib/active_record/encryption.rb +3 -0
- data/lib/active_record/enum.rb +129 -28
- data/lib/active_record/errors.rb +151 -31
- data/lib/active_record/explain.rb +21 -12
- data/lib/active_record/fixture_set/model_metadata.rb +14 -4
- data/lib/active_record/fixture_set/render_context.rb +2 -0
- data/lib/active_record/fixture_set/table_row.rb +29 -8
- data/lib/active_record/fixtures.rb +167 -97
- data/lib/active_record/future_result.rb +47 -8
- data/lib/active_record/gem_version.rb +3 -3
- data/lib/active_record/inheritance.rb +34 -18
- data/lib/active_record/insert_all.rb +72 -22
- data/lib/active_record/integration.rb +11 -8
- data/lib/active_record/internal_metadata.rb +124 -20
- data/lib/active_record/locking/optimistic.rb +8 -7
- data/lib/active_record/locking/pessimistic.rb +5 -2
- data/lib/active_record/log_subscriber.rb +18 -22
- data/lib/active_record/marshalling.rb +59 -0
- data/lib/active_record/message_pack.rb +124 -0
- data/lib/active_record/middleware/database_selector/resolver.rb +4 -0
- data/lib/active_record/middleware/database_selector.rb +6 -8
- data/lib/active_record/middleware/shard_selector.rb +3 -1
- data/lib/active_record/migration/command_recorder.rb +106 -8
- data/lib/active_record/migration/compatibility.rb +147 -5
- data/lib/active_record/migration/default_strategy.rb +22 -0
- data/lib/active_record/migration/execution_strategy.rb +19 -0
- data/lib/active_record/migration/pending_migration_connection.rb +21 -0
- data/lib/active_record/migration.rb +234 -117
- data/lib/active_record/model_schema.rb +90 -102
- data/lib/active_record/nested_attributes.rb +48 -11
- data/lib/active_record/normalization.rb +163 -0
- data/lib/active_record/persistence.rb +168 -339
- data/lib/active_record/promise.rb +84 -0
- data/lib/active_record/query_cache.rb +18 -25
- data/lib/active_record/query_logs.rb +92 -52
- data/lib/active_record/query_logs_formatter.rb +41 -0
- data/lib/active_record/querying.rb +33 -8
- data/lib/active_record/railtie.rb +129 -85
- data/lib/active_record/railties/controller_runtime.rb +22 -7
- data/lib/active_record/railties/databases.rake +145 -154
- data/lib/active_record/railties/job_runtime.rb +23 -0
- data/lib/active_record/readonly_attributes.rb +32 -5
- data/lib/active_record/reflection.rb +267 -69
- data/lib/active_record/relation/batches/batch_enumerator.rb +20 -5
- data/lib/active_record/relation/batches.rb +198 -63
- data/lib/active_record/relation/calculations.rb +250 -93
- data/lib/active_record/relation/delegation.rb +30 -19
- data/lib/active_record/relation/finder_methods.rb +93 -18
- data/lib/active_record/relation/merger.rb +6 -6
- data/lib/active_record/relation/predicate_builder/array_handler.rb +2 -2
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +18 -3
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +10 -7
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +5 -1
- data/lib/active_record/relation/predicate_builder.rb +28 -16
- data/lib/active_record/relation/query_attribute.rb +2 -1
- data/lib/active_record/relation/query_methods.rb +576 -107
- data/lib/active_record/relation/record_fetch_warning.rb +3 -0
- data/lib/active_record/relation/spawn_methods.rb +5 -4
- data/lib/active_record/relation/where_clause.rb +7 -19
- data/lib/active_record/relation.rb +580 -90
- data/lib/active_record/result.rb +49 -48
- data/lib/active_record/runtime_registry.rb +63 -1
- data/lib/active_record/sanitization.rb +70 -25
- data/lib/active_record/schema.rb +8 -7
- data/lib/active_record/schema_dumper.rb +63 -14
- data/lib/active_record/schema_migration.rb +75 -24
- data/lib/active_record/scoping/default.rb +15 -5
- data/lib/active_record/scoping/named.rb +3 -2
- data/lib/active_record/scoping.rb +2 -1
- data/lib/active_record/secure_password.rb +60 -0
- data/lib/active_record/secure_token.rb +21 -3
- data/lib/active_record/signed_id.rb +27 -6
- data/lib/active_record/statement_cache.rb +7 -7
- data/lib/active_record/store.rb +8 -8
- data/lib/active_record/suppressor.rb +3 -1
- data/lib/active_record/table_metadata.rb +1 -1
- data/lib/active_record/tasks/database_tasks.rb +190 -118
- data/lib/active_record/tasks/mysql_database_tasks.rb +15 -6
- data/lib/active_record/tasks/postgresql_database_tasks.rb +16 -13
- data/lib/active_record/tasks/sqlite_database_tasks.rb +16 -7
- data/lib/active_record/test_fixtures.rb +170 -155
- data/lib/active_record/testing/query_assertions.rb +121 -0
- data/lib/active_record/timestamp.rb +31 -17
- data/lib/active_record/token_for.rb +123 -0
- data/lib/active_record/touch_later.rb +12 -7
- data/lib/active_record/transaction.rb +132 -0
- data/lib/active_record/transactions.rb +106 -24
- data/lib/active_record/translation.rb +0 -2
- data/lib/active_record/type/adapter_specific_registry.rb +1 -8
- data/lib/active_record/type/internal/timezone.rb +7 -2
- data/lib/active_record/type/serialized.rb +1 -3
- data/lib/active_record/type/time.rb +4 -0
- data/lib/active_record/type_caster/connection.rb +4 -4
- data/lib/active_record/validations/absence.rb +1 -1
- data/lib/active_record/validations/associated.rb +9 -3
- data/lib/active_record/validations/numericality.rb +5 -4
- data/lib/active_record/validations/presence.rb +5 -28
- data/lib/active_record/validations/uniqueness.rb +61 -11
- data/lib/active_record/validations.rb +12 -5
- data/lib/active_record/version.rb +1 -1
- data/lib/active_record.rb +247 -33
- data/lib/arel/alias_predication.rb +1 -1
- data/lib/arel/collectors/bind.rb +2 -0
- data/lib/arel/collectors/composite.rb +7 -0
- data/lib/arel/collectors/sql_string.rb +1 -1
- data/lib/arel/collectors/substitute_binds.rb +1 -1
- data/lib/arel/errors.rb +10 -0
- data/lib/arel/factory_methods.rb +4 -0
- data/lib/arel/nodes/binary.rb +6 -7
- data/lib/arel/nodes/bound_sql_literal.rb +65 -0
- data/lib/arel/nodes/cte.rb +36 -0
- data/lib/arel/nodes/fragments.rb +35 -0
- data/lib/arel/nodes/homogeneous_in.rb +1 -9
- data/lib/arel/nodes/leading_join.rb +8 -0
- data/lib/arel/nodes/{and.rb → nary.rb} +5 -2
- data/lib/arel/nodes/node.rb +115 -5
- data/lib/arel/nodes/sql_literal.rb +13 -0
- data/lib/arel/nodes/table_alias.rb +4 -0
- data/lib/arel/nodes.rb +6 -2
- data/lib/arel/predications.rb +3 -1
- data/lib/arel/select_manager.rb +1 -1
- data/lib/arel/table.rb +9 -5
- data/lib/arel/tree_manager.rb +8 -3
- data/lib/arel/update_manager.rb +2 -1
- data/lib/arel/visitors/dot.rb +1 -0
- data/lib/arel/visitors/mysql.rb +17 -5
- data/lib/arel/visitors/postgresql.rb +1 -12
- data/lib/arel/visitors/sqlite.rb +25 -0
- data/lib/arel/visitors/to_sql.rb +112 -34
- data/lib/arel/visitors/visitor.rb +2 -2
- data/lib/arel.rb +21 -3
- data/lib/rails/generators/active_record/application_record/USAGE +8 -0
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +4 -1
- data/lib/rails/generators/active_record/migration.rb +3 -1
- data/lib/rails/generators/active_record/model/USAGE +113 -0
- data/lib/rails/generators/active_record/model/model_generator.rb +15 -6
- metadata +59 -17
- data/lib/active_record/connection_adapters/legacy_pool_manager.rb +0 -35
- data/lib/active_record/null_relation.rb +0 -63
data/lib/active_record/errors.rb
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "active_support/deprecation"
|
4
|
+
|
3
5
|
module ActiveRecord
|
6
|
+
include ActiveSupport::Deprecation::DeprecatedConstantAccessor
|
7
|
+
|
4
8
|
# = Active Record Errors
|
5
9
|
#
|
6
10
|
# Generic Active Record exception class.
|
7
11
|
class ActiveRecordError < StandardError
|
8
12
|
end
|
9
13
|
|
10
|
-
# Raised when trying to use a feature in Active Record which requires Active Job but the gem is not present.
|
11
|
-
class ActiveJobRequiredError < ActiveRecordError
|
12
|
-
end
|
13
|
-
|
14
14
|
# Raised when the single-table inheritance mechanism fails to locate the subclass
|
15
15
|
# (for example due to improper usage of column that
|
16
16
|
# {ActiveRecord::Base.inheritance_column}[rdoc-ref:ModelSchema::ClassMethods#inheritance_column]
|
@@ -51,10 +51,31 @@ module ActiveRecord
|
|
51
51
|
class AdapterNotFound < ActiveRecordError
|
52
52
|
end
|
53
53
|
|
54
|
+
# Superclass for all errors raised from an Active Record adapter.
|
55
|
+
class AdapterError < ActiveRecordError
|
56
|
+
def initialize(message = nil, connection_pool: nil)
|
57
|
+
@connection_pool = connection_pool
|
58
|
+
super(message)
|
59
|
+
end
|
60
|
+
|
61
|
+
attr_reader :connection_pool
|
62
|
+
end
|
63
|
+
|
54
64
|
# Raised when connection to the database could not been established (for example when
|
55
|
-
# {ActiveRecord::Base.
|
65
|
+
# {ActiveRecord::Base.lease_connection=}[rdoc-ref:ConnectionHandling#lease_connection]
|
56
66
|
# is given a +nil+ object).
|
57
|
-
class ConnectionNotEstablished <
|
67
|
+
class ConnectionNotEstablished < AdapterError
|
68
|
+
def initialize(message = nil, connection_pool: nil)
|
69
|
+
super(message, connection_pool: connection_pool)
|
70
|
+
end
|
71
|
+
|
72
|
+
def set_pool(connection_pool)
|
73
|
+
unless @connection_pool
|
74
|
+
@connection_pool = connection_pool
|
75
|
+
end
|
76
|
+
|
77
|
+
self
|
78
|
+
end
|
58
79
|
end
|
59
80
|
|
60
81
|
# Raised when a connection could not be obtained within the connection
|
@@ -90,7 +111,7 @@ module ActiveRecord
|
|
90
111
|
# Raised when a pool was unable to get ahold of all its connections
|
91
112
|
# to perform a "group" action such as
|
92
113
|
# {ActiveRecord::Base.connection_pool.disconnect!}[rdoc-ref:ConnectionAdapters::ConnectionPool#disconnect!]
|
93
|
-
# or {ActiveRecord::Base.clear_reloadable_connections!}[rdoc-ref:ConnectionAdapters::ConnectionHandler#clear_reloadable_connections!].
|
114
|
+
# or {ActiveRecord::Base.connection_handler.clear_reloadable_connections!}[rdoc-ref:ConnectionAdapters::ConnectionHandler#clear_reloadable_connections!].
|
94
115
|
class ExclusiveConnectionTimeoutError < ConnectionTimeoutError
|
95
116
|
end
|
96
117
|
|
@@ -112,8 +133,18 @@ module ActiveRecord
|
|
112
133
|
end
|
113
134
|
|
114
135
|
# Raised by {ActiveRecord::Base#save!}[rdoc-ref:Persistence#save!] and
|
115
|
-
# {ActiveRecord::Base.
|
116
|
-
# methods when a record
|
136
|
+
# {ActiveRecord::Base.update_attribute!}[rdoc-ref:Persistence#update_attribute!]
|
137
|
+
# methods when a record failed to validate or cannot be saved due to any of the
|
138
|
+
# <tt>before_*</tt> callbacks throwing +:abort+. See
|
139
|
+
# ActiveRecord::Callbacks for further details.
|
140
|
+
#
|
141
|
+
# class Product < ActiveRecord::Base
|
142
|
+
# before_save do
|
143
|
+
# throw :abort if price < 0
|
144
|
+
# end
|
145
|
+
# end
|
146
|
+
#
|
147
|
+
# Product.create! # => raises an ActiveRecord::RecordNotSaved
|
117
148
|
class RecordNotSaved < ActiveRecordError
|
118
149
|
attr_reader :record
|
119
150
|
|
@@ -124,15 +155,17 @@ module ActiveRecord
|
|
124
155
|
end
|
125
156
|
|
126
157
|
# Raised by {ActiveRecord::Base#destroy!}[rdoc-ref:Persistence#destroy!]
|
127
|
-
# when a
|
128
|
-
#
|
158
|
+
# when a record cannot be destroyed due to any of the
|
159
|
+
# <tt>before_destroy</tt> callbacks throwing +:abort+. See
|
160
|
+
# ActiveRecord::Callbacks for further details.
|
129
161
|
#
|
130
|
-
#
|
131
|
-
#
|
132
|
-
#
|
133
|
-
#
|
162
|
+
# class User < ActiveRecord::Base
|
163
|
+
# before_destroy do
|
164
|
+
# throw :abort if still_active?
|
165
|
+
# end
|
134
166
|
# end
|
135
167
|
#
|
168
|
+
# User.first.destroy! # => raises an ActiveRecord::RecordNotDestroyed
|
136
169
|
class RecordNotDestroyed < ActiveRecordError
|
137
170
|
attr_reader :record
|
138
171
|
|
@@ -155,14 +188,23 @@ module ActiveRecord
|
|
155
188
|
# Superclass for all database execution errors.
|
156
189
|
#
|
157
190
|
# Wraps the underlying database error as +cause+.
|
158
|
-
class StatementInvalid <
|
159
|
-
def initialize(message = nil, sql: nil, binds: nil)
|
160
|
-
super(message || $!&.message)
|
191
|
+
class StatementInvalid < AdapterError
|
192
|
+
def initialize(message = nil, sql: nil, binds: nil, connection_pool: nil)
|
193
|
+
super(message || $!&.message, connection_pool: connection_pool)
|
161
194
|
@sql = sql
|
162
195
|
@binds = binds
|
163
196
|
end
|
164
197
|
|
165
198
|
attr_reader :sql, :binds
|
199
|
+
|
200
|
+
def set_query(sql, binds)
|
201
|
+
unless @sql
|
202
|
+
@sql = sql
|
203
|
+
@binds = binds
|
204
|
+
end
|
205
|
+
|
206
|
+
self
|
207
|
+
end
|
166
208
|
end
|
167
209
|
|
168
210
|
# Defunct wrapper class kept for compatibility.
|
@@ -189,8 +231,13 @@ module ActiveRecord
|
|
189
231
|
foreign_key: nil,
|
190
232
|
target_table: nil,
|
191
233
|
primary_key: nil,
|
192
|
-
primary_key_column: nil
|
234
|
+
primary_key_column: nil,
|
235
|
+
query_parser: nil,
|
236
|
+
connection_pool: nil
|
193
237
|
)
|
238
|
+
@original_message = message
|
239
|
+
@query_parser = query_parser
|
240
|
+
|
194
241
|
if table
|
195
242
|
type = primary_key_column.bigint? ? :bigint : primary_key_column.type
|
196
243
|
msg = <<~EOM.squish
|
@@ -208,7 +255,24 @@ module ActiveRecord
|
|
208
255
|
if message
|
209
256
|
msg << "\nOriginal message: #{message}"
|
210
257
|
end
|
211
|
-
|
258
|
+
|
259
|
+
super(msg, sql: sql, binds: binds, connection_pool: connection_pool)
|
260
|
+
end
|
261
|
+
|
262
|
+
def set_query(sql, binds)
|
263
|
+
if @query_parser && !@sql
|
264
|
+
self.class.new(
|
265
|
+
message: @original_message,
|
266
|
+
sql: sql,
|
267
|
+
binds: binds,
|
268
|
+
connection_pool: @connection_pool,
|
269
|
+
**@query_parser.call(sql)
|
270
|
+
).tap do |exception|
|
271
|
+
exception.set_backtrace backtrace
|
272
|
+
end
|
273
|
+
else
|
274
|
+
super
|
275
|
+
end
|
212
276
|
end
|
213
277
|
end
|
214
278
|
|
@@ -224,6 +288,19 @@ module ActiveRecord
|
|
224
288
|
class RangeError < StatementInvalid
|
225
289
|
end
|
226
290
|
|
291
|
+
# Raised when a statement produces an SQL warning.
|
292
|
+
class SQLWarning < AdapterError
|
293
|
+
attr_reader :code, :level
|
294
|
+
attr_accessor :sql
|
295
|
+
|
296
|
+
def initialize(message = nil, code = nil, level = nil, sql = nil, connection_pool = nil)
|
297
|
+
super(message, connection_pool: connection_pool)
|
298
|
+
@code = code
|
299
|
+
@level = level
|
300
|
+
@sql = sql
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
227
304
|
# Raised when the number of placeholders in an SQL fragment passed to
|
228
305
|
# {ActiveRecord::Base.where}[rdoc-ref:QueryMethods#where]
|
229
306
|
# does not match the number of values supplied.
|
@@ -242,21 +319,22 @@ module ActiveRecord
|
|
242
319
|
ActiveRecord::Tasks::DatabaseTasks.create_current
|
243
320
|
end
|
244
321
|
|
245
|
-
def initialize(message = nil)
|
246
|
-
super(message || "Database not found")
|
322
|
+
def initialize(message = nil, connection_pool: nil)
|
323
|
+
super(message || "Database not found", connection_pool: connection_pool)
|
247
324
|
end
|
248
325
|
|
249
326
|
class << self
|
250
327
|
def db_error(db_name)
|
251
328
|
NoDatabaseError.new(<<~MSG)
|
252
|
-
We could not find your database: #{db_name}.
|
329
|
+
We could not find your database: #{db_name}. Available database configurations can be found in config/database.yml.
|
330
|
+
|
331
|
+
To resolve this error:
|
253
332
|
|
254
|
-
To
|
333
|
+
- Did you not create the database, or did you delete it? To create the database, run:
|
255
334
|
|
256
|
-
|
257
|
-
- Has the database name changed? Check your database.yml config has the correct database name.
|
335
|
+
bin/rails db:create
|
258
336
|
|
259
|
-
|
337
|
+
- Has the database name changed? Verify that config/database.yml contains the correct database name.
|
260
338
|
MSG
|
261
339
|
end
|
262
340
|
end
|
@@ -304,6 +382,12 @@ module ActiveRecord
|
|
304
382
|
end
|
305
383
|
|
306
384
|
# Raised on attempt to lazily load records that are marked as strict loading.
|
385
|
+
#
|
386
|
+
# You can resolve this error by eager loading marked records before accessing
|
387
|
+
# them. The
|
388
|
+
# {Eager Loading Associations}[https://guides.rubyonrails.org/active_record_querying.html#eager-loading-associations]
|
389
|
+
# guide covers solutions, such as using
|
390
|
+
# {ActiveRecord::Base.includes}[rdoc-ref:QueryMethods#includes].
|
307
391
|
class StrictLoadingViolationError < ActiveRecordError
|
308
392
|
end
|
309
393
|
|
@@ -396,10 +480,15 @@ module ActiveRecord
|
|
396
480
|
# relation.loaded? # => true
|
397
481
|
#
|
398
482
|
# # Methods which try to mutate a loaded relation fail.
|
399
|
-
# relation.where!(title: 'TODO') # => ActiveRecord::
|
400
|
-
# relation.limit!(5) # => ActiveRecord::
|
401
|
-
class
|
483
|
+
# relation.where!(title: 'TODO') # => ActiveRecord::UnmodifiableRelation
|
484
|
+
# relation.limit!(5) # => ActiveRecord::UnmodifiableRelation
|
485
|
+
class UnmodifiableRelation < ActiveRecordError
|
402
486
|
end
|
487
|
+
deprecate_constant(
|
488
|
+
:ImmutableRelation,
|
489
|
+
"ActiveRecord::UnmodifiableRelation",
|
490
|
+
deprecator: ActiveRecord.deprecator
|
491
|
+
)
|
403
492
|
|
404
493
|
# TransactionIsolationError will be raised under the following conditions:
|
405
494
|
#
|
@@ -407,13 +496,26 @@ module ActiveRecord
|
|
407
496
|
# * You are joining an existing open transaction
|
408
497
|
# * You are creating a nested (savepoint) transaction
|
409
498
|
#
|
410
|
-
# The mysql2 and postgresql adapters support setting the transaction isolation level.
|
499
|
+
# The mysql2, trilogy, and postgresql adapters support setting the transaction isolation level.
|
411
500
|
class TransactionIsolationError < ActiveRecordError
|
412
501
|
end
|
413
502
|
|
414
503
|
# TransactionRollbackError will be raised when a transaction is rolled
|
415
504
|
# back by the database due to a serialization failure or a deadlock.
|
416
505
|
#
|
506
|
+
# These exceptions should not be generally rescued in nested transaction
|
507
|
+
# blocks, because they have side-effects in the actual enclosing transaction
|
508
|
+
# and internal Active Record state. They can be rescued if you are above the
|
509
|
+
# root transaction block, though.
|
510
|
+
#
|
511
|
+
# In that case, beware of transactional tests, however, because they run test
|
512
|
+
# cases in their own umbrella transaction. If you absolutely need to handle
|
513
|
+
# these exceptions in tests please consider disabling transactional tests in
|
514
|
+
# the affected test class (<tt>self.use_transactional_tests = false</tt>).
|
515
|
+
#
|
516
|
+
# Due to the aforementioned side-effects, this exception should not be raised
|
517
|
+
# manually by users.
|
518
|
+
#
|
417
519
|
# See the following:
|
418
520
|
#
|
419
521
|
# * https://www.postgresql.org/docs/current/static/transaction-iso.html
|
@@ -428,11 +530,17 @@ module ActiveRecord
|
|
428
530
|
|
429
531
|
# SerializationFailure will be raised when a transaction is rolled
|
430
532
|
# back by the database due to a serialization failure.
|
533
|
+
#
|
534
|
+
# This is a subclass of TransactionRollbackError, please make sure to check
|
535
|
+
# its documentation to be aware of its caveats.
|
431
536
|
class SerializationFailure < TransactionRollbackError
|
432
537
|
end
|
433
538
|
|
434
539
|
# Deadlocked will be raised when a transaction is rolled
|
435
540
|
# back by the database when a deadlock is encountered.
|
541
|
+
#
|
542
|
+
# This is a subclass of TransactionRollbackError, please make sure to check
|
543
|
+
# its documentation to be aware of its caveats.
|
436
544
|
class Deadlocked < TransactionRollbackError
|
437
545
|
end
|
438
546
|
|
@@ -461,6 +569,11 @@ module ActiveRecord
|
|
461
569
|
class AdapterTimeout < QueryAborted
|
462
570
|
end
|
463
571
|
|
572
|
+
# ConnectionFailed will be raised when the network connection to the
|
573
|
+
# database fails while sending a query or waiting for its result.
|
574
|
+
class ConnectionFailed < QueryAborted
|
575
|
+
end
|
576
|
+
|
464
577
|
# UnknownAttributeReference is raised when an unknown and potentially unsafe
|
465
578
|
# value is passed to a query method. For example, passing a non column name
|
466
579
|
# value to a relation's #order method might cause this exception.
|
@@ -483,4 +596,11 @@ module ActiveRecord
|
|
483
596
|
# values, such as request parameters or model attributes to query methods.
|
484
597
|
class UnknownAttributeReference < ActiveRecordError
|
485
598
|
end
|
599
|
+
|
600
|
+
# DatabaseVersionError will be raised when the database version is not supported, or when
|
601
|
+
# the database version cannot be determined.
|
602
|
+
class DatabaseVersionError < ActiveRecordError
|
603
|
+
end
|
486
604
|
end
|
605
|
+
|
606
|
+
require "active_record/associations/errors"
|
@@ -16,17 +16,18 @@ module ActiveRecord
|
|
16
16
|
|
17
17
|
# Makes the adapter execute EXPLAIN for the tuples of queries and bindings.
|
18
18
|
# Returns a formatted string ready to be logged.
|
19
|
-
def exec_explain(queries) # :nodoc:
|
20
|
-
str =
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
19
|
+
def exec_explain(queries, options = []) # :nodoc:
|
20
|
+
str = with_connection do |c|
|
21
|
+
queries.map do |sql, binds|
|
22
|
+
msg = +"#{build_explain_clause(c, options)} #{sql}"
|
23
|
+
unless binds.empty?
|
24
|
+
msg << " "
|
25
|
+
msg << binds.map { |attr| render_bind(c, attr) }.inspect
|
26
|
+
end
|
27
|
+
msg << "\n"
|
28
|
+
msg << c.explain(sql, binds, options)
|
29
|
+
end.join("\n")
|
30
|
+
end
|
30
31
|
# Overriding inspect to be more human readable, especially in the console.
|
31
32
|
def str.inspect
|
32
33
|
self
|
@@ -36,7 +37,7 @@ module ActiveRecord
|
|
36
37
|
end
|
37
38
|
|
38
39
|
private
|
39
|
-
def render_bind(attr)
|
40
|
+
def render_bind(connection, attr)
|
40
41
|
if ActiveModel::Attribute === attr
|
41
42
|
value = if attr.type.binary? && attr.value
|
42
43
|
"<#{attr.value_for_database.to_s.bytesize} bytes of binary data>"
|
@@ -50,5 +51,13 @@ module ActiveRecord
|
|
50
51
|
|
51
52
|
[attr&.name, value]
|
52
53
|
end
|
54
|
+
|
55
|
+
def build_explain_clause(connection, options = [])
|
56
|
+
if connection.respond_to?(:build_explain_clause, true)
|
57
|
+
connection.build_explain_clause(options)
|
58
|
+
else
|
59
|
+
"EXPLAIN for:"
|
60
|
+
end
|
61
|
+
end
|
53
62
|
end
|
54
63
|
end
|
@@ -12,12 +12,22 @@ module ActiveRecord
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def primary_key_type
|
15
|
-
@primary_key_type ||= @model_class &&
|
15
|
+
@primary_key_type ||= @model_class && column_type(@model_class.primary_key)
|
16
16
|
end
|
17
17
|
|
18
|
-
def
|
19
|
-
@
|
20
|
-
|
18
|
+
def column_type(column_name)
|
19
|
+
@column_type ||= {}
|
20
|
+
return @column_type[column_name] if @column_type.key?(column_name)
|
21
|
+
|
22
|
+
@column_type[column_name] = @model_class && @model_class.type_for_attribute(column_name).type
|
23
|
+
end
|
24
|
+
|
25
|
+
def has_column?(column_name)
|
26
|
+
column_names.include?(column_name)
|
27
|
+
end
|
28
|
+
|
29
|
+
def column_names
|
30
|
+
@column_names ||= @model_class ? @model_class.columns.map(&:name).to_set : Set.new
|
21
31
|
end
|
22
32
|
|
23
33
|
def timestamp_column_names
|
@@ -87,7 +87,7 @@ module ActiveRecord
|
|
87
87
|
return unless model_class
|
88
88
|
fill_timestamps
|
89
89
|
interpolate_label
|
90
|
-
generate_primary_key
|
90
|
+
model_class.composite_primary_key? ? generate_composite_primary_key : generate_primary_key
|
91
91
|
resolve_enums
|
92
92
|
resolve_sti_reflections
|
93
93
|
end
|
@@ -117,14 +117,26 @@ module ActiveRecord
|
|
117
117
|
end
|
118
118
|
|
119
119
|
def generate_primary_key
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
120
|
+
pk = model_metadata.primary_key_name
|
121
|
+
|
122
|
+
unless column_defined?(pk)
|
123
|
+
@row[pk] = ActiveRecord::FixtureSet.identify(@label, model_metadata.column_type(pk))
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def generate_composite_primary_key
|
128
|
+
composite_key = ActiveRecord::FixtureSet.composite_identify(@label, model_metadata.primary_key_name)
|
129
|
+
composite_key.each do |column, value|
|
130
|
+
next if column_defined?(column)
|
131
|
+
|
132
|
+
@row[column] = value
|
125
133
|
end
|
126
134
|
end
|
127
135
|
|
136
|
+
def column_defined?(col)
|
137
|
+
!model_metadata.has_column?(col) || @row.include?(col)
|
138
|
+
end
|
139
|
+
|
128
140
|
def resolve_enums
|
129
141
|
reflection_class.defined_enums.each do |name, values|
|
130
142
|
if @row.include?(name)
|
@@ -151,8 +163,17 @@ module ActiveRecord
|
|
151
163
|
raise PrimaryKeyError.new(@label, association, value)
|
152
164
|
end
|
153
165
|
|
154
|
-
|
155
|
-
|
166
|
+
if fk_name.is_a?(Array)
|
167
|
+
composite_key = ActiveRecord::FixtureSet.composite_identify(value, fk_name)
|
168
|
+
composite_key.each do |column, value|
|
169
|
+
next if column_defined?(column)
|
170
|
+
|
171
|
+
@row[column] = value
|
172
|
+
end
|
173
|
+
else
|
174
|
+
fk_type = reflection_class.type_for_attribute(fk_name).type
|
175
|
+
@row[fk_name] = ActiveRecord::FixtureSet.identify(value, fk_type)
|
176
|
+
end
|
156
177
|
end
|
157
178
|
when :has_many
|
158
179
|
if association.options[:through]
|