activerecord 7.1.5.1 → 8.0.2
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 +369 -2484
- data/README.rdoc +15 -15
- data/examples/performance.rb +2 -2
- data/lib/active_record/association_relation.rb +2 -1
- data/lib/active_record/associations/alias_tracker.rb +31 -23
- data/lib/active_record/associations/association.rb +43 -12
- data/lib/active_record/associations/belongs_to_association.rb +21 -8
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +3 -2
- data/lib/active_record/associations/builder/association.rb +7 -6
- data/lib/active_record/associations/builder/belongs_to.rb +1 -0
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +2 -2
- 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/collection_association.rb +17 -9
- data/lib/active_record/associations/collection_proxy.rb +14 -1
- data/lib/active_record/associations/disable_joins_association_scope.rb +1 -1
- data/lib/active_record/associations/errors.rb +265 -0
- data/lib/active_record/associations/has_many_association.rb +1 -1
- data/lib/active_record/associations/has_many_through_association.rb +10 -3
- data/lib/active_record/associations/join_dependency/join_association.rb +1 -1
- data/lib/active_record/associations/nested_error.rb +47 -0
- data/lib/active_record/associations/preloader/association.rb +4 -3
- 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/singular_association.rb +14 -3
- data/lib/active_record/associations/through_association.rb +1 -1
- data/lib/active_record/associations.rb +92 -295
- data/lib/active_record/asynchronous_queries_tracker.rb +28 -24
- data/lib/active_record/attribute_assignment.rb +0 -2
- data/lib/active_record/attribute_methods/composite_primary_key.rb +84 -0
- data/lib/active_record/attribute_methods/primary_key.rb +25 -61
- data/lib/active_record/attribute_methods/read.rb +1 -13
- data/lib/active_record/attribute_methods/serialization.rb +4 -24
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +9 -18
- data/lib/active_record/attribute_methods.rb +71 -75
- data/lib/active_record/attributes.rb +63 -49
- data/lib/active_record/autosave_association.rb +92 -57
- data/lib/active_record/base.rb +2 -3
- data/lib/active_record/callbacks.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/connection_handler.rb +48 -122
- data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +0 -1
- data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +1 -1
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +286 -77
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +119 -55
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +197 -76
- data/lib/active_record/connection_adapters/abstract/quoting.rb +66 -92
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +4 -5
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +12 -3
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +48 -12
- data/lib/active_record/connection_adapters/abstract/transaction.rb +140 -67
- data/lib/active_record/connection_adapters/abstract_adapter.rb +85 -90
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +71 -52
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +9 -1
- data/lib/active_record/connection_adapters/mysql/quoting.rb +50 -57
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +2 -8
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +56 -45
- data/lib/active_record/connection_adapters/mysql2/database_statements.rb +92 -101
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +13 -31
- data/lib/active_record/connection_adapters/pool_config.rb +14 -13
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +86 -41
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +10 -0
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +14 -4
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +58 -58
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +2 -4
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +1 -11
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +36 -20
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +3 -2
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +75 -28
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +73 -113
- data/lib/active_record/connection_adapters/schema_cache.rb +124 -131
- data/lib/active_record/connection_adapters/sqlite3/column.rb +14 -1
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +81 -97
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +57 -46
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +16 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +13 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +29 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +35 -3
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +183 -87
- data/lib/active_record/connection_adapters/statement_pool.rb +4 -2
- data/lib/active_record/connection_adapters/trilogy/database_statements.rb +39 -69
- data/lib/active_record/connection_adapters/trilogy_adapter.rb +19 -65
- data/lib/active_record/connection_adapters.rb +65 -0
- data/lib/active_record/connection_handling.rb +74 -37
- data/lib/active_record/core.rb +132 -51
- data/lib/active_record/counter_cache.rb +19 -10
- data/lib/active_record/database_configurations/connection_url_resolver.rb +9 -2
- data/lib/active_record/database_configurations/database_config.rb +23 -4
- data/lib/active_record/database_configurations/hash_config.rb +46 -34
- data/lib/active_record/database_configurations/url_config.rb +20 -1
- data/lib/active_record/database_configurations.rb +1 -1
- data/lib/active_record/delegated_type.rb +41 -17
- data/lib/active_record/dynamic_matchers.rb +2 -2
- data/lib/active_record/encryption/config.rb +3 -1
- data/lib/active_record/encryption/encryptable_record.rb +7 -7
- data/lib/active_record/encryption/encrypted_attribute_type.rb +33 -4
- data/lib/active_record/encryption/encryptor.rb +28 -6
- data/lib/active_record/encryption/extended_deterministic_queries.rb +4 -2
- 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 +4 -0
- data/lib/active_record/encryption/null_encryptor.rb +4 -0
- data/lib/active_record/encryption/read_only_null_encryptor.rb +4 -0
- data/lib/active_record/encryption/scheme.rb +8 -1
- data/lib/active_record/enum.rb +20 -16
- data/lib/active_record/errors.rb +54 -20
- data/lib/active_record/explain.rb +13 -24
- data/lib/active_record/fixtures.rb +37 -33
- data/lib/active_record/future_result.rb +21 -13
- data/lib/active_record/gem_version.rb +4 -4
- data/lib/active_record/inheritance.rb +4 -2
- data/lib/active_record/insert_all.rb +19 -16
- data/lib/active_record/integration.rb +4 -1
- data/lib/active_record/internal_metadata.rb +48 -34
- data/lib/active_record/locking/optimistic.rb +8 -7
- data/lib/active_record/log_subscriber.rb +5 -32
- data/lib/active_record/message_pack.rb +1 -1
- data/lib/active_record/migration/command_recorder.rb +33 -14
- data/lib/active_record/migration/compatibility.rb +8 -3
- data/lib/active_record/migration/default_strategy.rb +4 -5
- data/lib/active_record/migration/pending_migration_connection.rb +2 -2
- data/lib/active_record/migration.rb +104 -98
- data/lib/active_record/model_schema.rb +32 -70
- data/lib/active_record/nested_attributes.rb +15 -9
- data/lib/active_record/normalization.rb +3 -7
- data/lib/active_record/persistence.rb +127 -451
- data/lib/active_record/query_cache.rb +19 -8
- data/lib/active_record/query_logs.rb +104 -37
- data/lib/active_record/query_logs_formatter.rb +17 -28
- data/lib/active_record/querying.rb +24 -12
- data/lib/active_record/railtie.rb +26 -68
- data/lib/active_record/railties/controller_runtime.rb +13 -4
- data/lib/active_record/railties/databases.rake +43 -61
- data/lib/active_record/reflection.rb +112 -53
- data/lib/active_record/relation/batches/batch_enumerator.rb +19 -5
- data/lib/active_record/relation/batches.rb +138 -72
- data/lib/active_record/relation/calculations.rb +122 -82
- data/lib/active_record/relation/delegation.rb +30 -22
- data/lib/active_record/relation/finder_methods.rb +32 -18
- data/lib/active_record/relation/merger.rb +12 -14
- data/lib/active_record/relation/predicate_builder/array_handler.rb +2 -2
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +10 -2
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +1 -1
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +4 -3
- data/lib/active_record/relation/predicate_builder.rb +16 -3
- data/lib/active_record/relation/query_attribute.rb +1 -1
- data/lib/active_record/relation/query_methods.rb +317 -101
- data/lib/active_record/relation/spawn_methods.rb +3 -19
- data/lib/active_record/relation/where_clause.rb +7 -19
- data/lib/active_record/relation.rb +561 -119
- data/lib/active_record/result.rb +95 -46
- data/lib/active_record/runtime_registry.rb +39 -0
- data/lib/active_record/sanitization.rb +31 -25
- data/lib/active_record/schema.rb +8 -6
- data/lib/active_record/schema_dumper.rb +53 -20
- data/lib/active_record/schema_migration.rb +31 -14
- data/lib/active_record/scoping/named.rb +6 -2
- data/lib/active_record/signed_id.rb +24 -4
- data/lib/active_record/statement_cache.rb +19 -19
- data/lib/active_record/store.rb +7 -3
- data/lib/active_record/table_metadata.rb +2 -13
- data/lib/active_record/tasks/database_tasks.rb +87 -58
- data/lib/active_record/tasks/mysql_database_tasks.rb +1 -3
- data/lib/active_record/tasks/postgresql_database_tasks.rb +1 -1
- data/lib/active_record/tasks/sqlite_database_tasks.rb +4 -3
- data/lib/active_record/test_fixtures.rb +98 -89
- data/lib/active_record/testing/query_assertions.rb +121 -0
- data/lib/active_record/timestamp.rb +2 -2
- data/lib/active_record/token_for.rb +22 -12
- data/lib/active_record/touch_later.rb +1 -1
- data/lib/active_record/transaction.rb +132 -0
- data/lib/active_record/transactions.rb +72 -17
- data/lib/active_record/translation.rb +0 -2
- data/lib/active_record/type/serialized.rb +1 -3
- data/lib/active_record/type_caster/connection.rb +4 -4
- data/lib/active_record/validations/associated.rb +9 -3
- data/lib/active_record/validations/uniqueness.rb +23 -18
- data/lib/active_record/validations.rb +4 -1
- data/lib/active_record.rb +138 -57
- data/lib/arel/alias_predication.rb +1 -1
- data/lib/arel/collectors/bind.rb +4 -2
- data/lib/arel/collectors/composite.rb +7 -0
- data/lib/arel/collectors/sql_string.rb +2 -2
- data/lib/arel/collectors/substitute_binds.rb +3 -3
- data/lib/arel/nodes/binary.rb +1 -7
- data/lib/arel/nodes/bound_sql_literal.rb +9 -5
- data/lib/arel/nodes/{and.rb → nary.rb} +5 -2
- data/lib/arel/nodes/node.rb +5 -4
- data/lib/arel/nodes/sql_literal.rb +8 -1
- data/lib/arel/nodes.rb +2 -2
- data/lib/arel/predications.rb +1 -1
- data/lib/arel/select_manager.rb +1 -1
- data/lib/arel/table.rb +3 -7
- data/lib/arel/tree_manager.rb +3 -2
- data/lib/arel/update_manager.rb +2 -1
- data/lib/arel/visitors/dot.rb +1 -0
- data/lib/arel/visitors/mysql.rb +9 -4
- data/lib/arel/visitors/postgresql.rb +1 -12
- data/lib/arel/visitors/sqlite.rb +25 -0
- data/lib/arel/visitors/to_sql.rb +29 -16
- data/lib/arel.rb +7 -3
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +4 -1
- metadata +18 -16
- data/lib/active_record/relation/record_fetch_warning.rb +0 -49
@@ -2,44 +2,17 @@
|
|
2
2
|
|
3
3
|
require "active_record/connection_adapters/abstract_mysql_adapter"
|
4
4
|
|
5
|
-
gem "trilogy", "~> 2.
|
5
|
+
gem "trilogy", "~> 2.7"
|
6
6
|
require "trilogy"
|
7
7
|
|
8
8
|
require "active_record/connection_adapters/trilogy/database_statements"
|
9
9
|
|
10
10
|
module ActiveRecord
|
11
|
-
module ConnectionHandling # :nodoc:
|
12
|
-
def trilogy_adapter_class
|
13
|
-
ConnectionAdapters::TrilogyAdapter
|
14
|
-
end
|
15
|
-
|
16
|
-
# Establishes a connection to the database that's used by all Active Record objects.
|
17
|
-
def trilogy_connection(config)
|
18
|
-
configuration = config.dup
|
19
|
-
|
20
|
-
# Set FOUND_ROWS capability on the connection so UPDATE queries returns number of rows
|
21
|
-
# matched rather than number of rows updated.
|
22
|
-
configuration[:found_rows] = true
|
23
|
-
|
24
|
-
options = [
|
25
|
-
configuration[:host],
|
26
|
-
configuration[:port],
|
27
|
-
configuration[:database],
|
28
|
-
configuration[:username],
|
29
|
-
configuration[:password],
|
30
|
-
configuration[:socket],
|
31
|
-
0
|
32
|
-
]
|
33
|
-
|
34
|
-
trilogy_adapter_class.new nil, logger, options, configuration
|
35
|
-
end
|
36
|
-
end
|
37
11
|
module ConnectionAdapters
|
38
12
|
class TrilogyAdapter < AbstractMysqlAdapter
|
39
13
|
ER_BAD_DB_ERROR = 1049
|
40
14
|
ER_DBACCESS_DENIED_ERROR = 1044
|
41
15
|
ER_ACCESS_DENIED_ERROR = 1045
|
42
|
-
ER_SERVER_SHUTDOWN = 1053
|
43
16
|
|
44
17
|
ADAPTER_NAME = "Trilogy"
|
45
18
|
|
@@ -99,16 +72,22 @@ module ActiveRecord
|
|
99
72
|
end
|
100
73
|
end
|
101
74
|
|
102
|
-
def initialize(
|
103
|
-
|
75
|
+
def initialize(config, *)
|
76
|
+
config = config.dup
|
104
77
|
|
105
|
-
if
|
78
|
+
# Trilogy ignores `socket` if `host is set. We want the opposite to allow
|
79
|
+
# configuring UNIX domain sockets via `DATABASE_URL`.
|
80
|
+
config.delete(:host) if config[:socket]
|
81
|
+
|
82
|
+
# Set FOUND_ROWS capability on the connection so UPDATE queries returns number of rows
|
83
|
+
# matched rather than number of rows updated.
|
84
|
+
config[:found_rows] = true
|
85
|
+
|
86
|
+
if config[:prepared_statements]
|
106
87
|
raise ArgumentError, "Trilogy currently doesn't support prepared statements. Remove `prepared_statements: true` from your database configuration."
|
107
88
|
end
|
108
89
|
|
109
|
-
|
110
|
-
# configuring UNIX domain sockets via `DATABASE_URL`.
|
111
|
-
@config.delete(:host) if @config[:socket]
|
90
|
+
super
|
112
91
|
end
|
113
92
|
|
114
93
|
TYPE_MAP = Type::TypeMap.new.tap { |m| initialize_type_map(m) }
|
@@ -137,14 +116,12 @@ module ActiveRecord
|
|
137
116
|
true
|
138
117
|
end
|
139
118
|
|
140
|
-
def
|
141
|
-
|
142
|
-
conn.escape(string)
|
143
|
-
end
|
119
|
+
def connected?
|
120
|
+
!(@raw_connection.nil? || @raw_connection.closed?)
|
144
121
|
end
|
145
122
|
|
146
123
|
def active?
|
147
|
-
|
124
|
+
connected? && @lock.synchronize { @raw_connection&.ping; verified! } || false
|
148
125
|
rescue ::Trilogy::Error
|
149
126
|
false
|
150
127
|
end
|
@@ -172,23 +149,6 @@ module ActiveRecord
|
|
172
149
|
TYPE_MAP.lookup(type).is_a?(Type::String) || TYPE_MAP.lookup(type).is_a?(Type::Text)
|
173
150
|
end
|
174
151
|
|
175
|
-
def each_hash(result)
|
176
|
-
return to_enum(:each_hash, result) unless block_given?
|
177
|
-
|
178
|
-
keys = result.fields.map(&:to_sym)
|
179
|
-
result.rows.each do |row|
|
180
|
-
hash = {}
|
181
|
-
idx = 0
|
182
|
-
row.each do |value|
|
183
|
-
hash[keys[idx]] = value
|
184
|
-
idx += 1
|
185
|
-
end
|
186
|
-
yield hash
|
187
|
-
end
|
188
|
-
|
189
|
-
nil
|
190
|
-
end
|
191
|
-
|
192
152
|
def error_number(exception)
|
193
153
|
exception.error_code if exception.respond_to?(:error_code)
|
194
154
|
end
|
@@ -206,7 +166,7 @@ module ActiveRecord
|
|
206
166
|
end
|
207
167
|
|
208
168
|
def full_version
|
209
|
-
|
169
|
+
database_version.full_version_string
|
210
170
|
end
|
211
171
|
|
212
172
|
def get_full_version
|
@@ -219,18 +179,12 @@ module ActiveRecord
|
|
219
179
|
if exception.is_a?(::Trilogy::TimeoutError) && !exception.error_code
|
220
180
|
return ActiveRecord::AdapterTimeout.new(message, sql: sql, binds: binds, connection_pool: @pool)
|
221
181
|
end
|
222
|
-
error_code = exception.error_code if exception.respond_to?(:error_code)
|
223
|
-
|
224
|
-
case error_code
|
225
|
-
when ER_SERVER_SHUTDOWN
|
226
|
-
return ConnectionFailed.new(message, connection_pool: @pool)
|
227
|
-
end
|
228
182
|
|
229
183
|
case exception
|
230
|
-
when
|
184
|
+
when ::Trilogy::ConnectionClosed, ::Trilogy::EOFError
|
231
185
|
return ConnectionFailed.new(message, connection_pool: @pool)
|
232
186
|
when ::Trilogy::Error
|
233
|
-
if
|
187
|
+
if exception.is_a?(SystemCallError) || exception.message.include?("TRILOGY_INVALID_SEQUENCE_ID")
|
234
188
|
return ConnectionFailed.new(message, connection_pool: @pool)
|
235
189
|
end
|
236
190
|
end
|
@@ -1,9 +1,74 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "active_support/core_ext/string/filters"
|
4
|
+
|
3
5
|
module ActiveRecord
|
4
6
|
module ConnectionAdapters
|
5
7
|
extend ActiveSupport::Autoload
|
6
8
|
|
9
|
+
@adapters = {}
|
10
|
+
|
11
|
+
class << self
|
12
|
+
# Registers a custom database adapter.
|
13
|
+
#
|
14
|
+
# Can also be used to define aliases.
|
15
|
+
#
|
16
|
+
# == Example
|
17
|
+
#
|
18
|
+
# ActiveRecord::ConnectionAdapters.register("megadb", "MegaDB::ActiveRecordAdapter", "mega_db/active_record_adapter")
|
19
|
+
#
|
20
|
+
# ActiveRecord::ConnectionAdapters.register("mysql", "ActiveRecord::ConnectionAdapters::TrilogyAdapter", "active_record/connection_adapters/trilogy_adapter")
|
21
|
+
#
|
22
|
+
def register(name, class_name, path = class_name.underscore)
|
23
|
+
@adapters[name.to_s] = [class_name, path]
|
24
|
+
end
|
25
|
+
|
26
|
+
def resolve(adapter_name) # :nodoc:
|
27
|
+
# Require the adapter itself and give useful feedback about
|
28
|
+
# 1. Missing adapter gems.
|
29
|
+
# 2. Incorrectly registered adapters.
|
30
|
+
# 3. Adapter gems' missing dependencies.
|
31
|
+
class_name, path_to_adapter = @adapters[adapter_name.to_s]
|
32
|
+
|
33
|
+
unless class_name
|
34
|
+
raise AdapterNotFound, <<~MSG.squish
|
35
|
+
Database configuration specifies nonexistent '#{adapter_name}' adapter.
|
36
|
+
Available adapters are: #{@adapters.keys.sort.join(", ")}.
|
37
|
+
Ensure that the adapter is spelled correctly in config/database.yml and that you've added the necessary
|
38
|
+
adapter gem to your Gemfile if it's not in the list of available adapters.
|
39
|
+
MSG
|
40
|
+
end
|
41
|
+
|
42
|
+
unless Object.const_defined?(class_name)
|
43
|
+
begin
|
44
|
+
require path_to_adapter
|
45
|
+
rescue LoadError => error
|
46
|
+
# We couldn't require the adapter itself.
|
47
|
+
if error.path == path_to_adapter
|
48
|
+
# We can assume here that a non-builtin adapter was specified and the path
|
49
|
+
# registered by the adapter gem is incorrect.
|
50
|
+
raise LoadError, "Error loading the '#{adapter_name}' Active Record adapter. Ensure that the path registered by the adapter gem is correct. #{error.message}", error.backtrace
|
51
|
+
else
|
52
|
+
# Bubbled up from the adapter require. Prefix the exception message
|
53
|
+
# with some guidance about how to address it and reraise.
|
54
|
+
raise LoadError, "Error loading the '#{adapter_name}' Active Record adapter. Missing a gem it depends on? #{error.message}", error.backtrace
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
begin
|
60
|
+
Object.const_get(class_name)
|
61
|
+
rescue NameError => error
|
62
|
+
raise AdapterNotFound, "Could not load the #{class_name} Active Record adapter (#{error.message})."
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
register "sqlite3", "ActiveRecord::ConnectionAdapters::SQLite3Adapter", "active_record/connection_adapters/sqlite3_adapter"
|
68
|
+
register "mysql2", "ActiveRecord::ConnectionAdapters::Mysql2Adapter", "active_record/connection_adapters/mysql2_adapter"
|
69
|
+
register "trilogy", "ActiveRecord::ConnectionAdapters::TrilogyAdapter", "active_record/connection_adapters/trilogy_adapter"
|
70
|
+
register "postgresql", "ActiveRecord::ConnectionAdapters::PostgreSQLAdapter", "active_record/connection_adapters/postgresql_adapter"
|
71
|
+
|
7
72
|
eager_autoload do
|
8
73
|
autoload :AbstractAdapter
|
9
74
|
end
|
@@ -87,6 +87,8 @@ module ActiveRecord
|
|
87
87
|
|
88
88
|
connections = []
|
89
89
|
|
90
|
+
@shard_keys = shards.keys
|
91
|
+
|
90
92
|
if shards.empty?
|
91
93
|
shards[:default] = database
|
92
94
|
end
|
@@ -175,6 +177,18 @@ module ActiveRecord
|
|
175
177
|
connected_to_stack.pop
|
176
178
|
end
|
177
179
|
|
180
|
+
# Passes the block to +connected_to+ for every +shard+ the
|
181
|
+
# model is configured to connect to (if any), and returns the
|
182
|
+
# results in an array.
|
183
|
+
#
|
184
|
+
# Optionally, +role+ and/or +prevent_writes+ can be passed which
|
185
|
+
# will be forwarded to each +connected_to+ call.
|
186
|
+
def connected_to_all_shards(role: nil, prevent_writes: false, &blk)
|
187
|
+
shard_keys.map do |shard|
|
188
|
+
connected_to(shard: shard, role: role, prevent_writes: prevent_writes, &blk)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
178
192
|
# Use a specified connection.
|
179
193
|
#
|
180
194
|
# This method is useful for ensuring that a specific connection is
|
@@ -243,22 +257,64 @@ module ActiveRecord
|
|
243
257
|
# Clears the query cache for all connections associated with the current thread.
|
244
258
|
def clear_query_caches_for_current_thread
|
245
259
|
connection_handler.each_connection_pool do |pool|
|
246
|
-
pool.
|
260
|
+
pool.clear_query_cache
|
247
261
|
end
|
248
262
|
end
|
249
263
|
|
250
264
|
# Returns the connection currently associated with the class. This can
|
251
265
|
# also be used to "borrow" the connection to do database work unrelated
|
252
266
|
# to any of the specific Active Records.
|
267
|
+
# The connection will remain leased for the entire duration of the request
|
268
|
+
# or job, or until +#release_connection+ is called.
|
269
|
+
def lease_connection
|
270
|
+
connection_pool.lease_connection
|
271
|
+
end
|
272
|
+
|
273
|
+
# Soft deprecated. Use +#with_connection+ or +#lease_connection+ instead.
|
253
274
|
def connection
|
254
|
-
|
275
|
+
pool = connection_pool
|
276
|
+
if pool.permanent_lease?
|
277
|
+
case ActiveRecord.permanent_connection_checkout
|
278
|
+
when :deprecated
|
279
|
+
ActiveRecord.deprecator.warn <<~MESSAGE
|
280
|
+
Called deprecated `ActiveRecord::Base.connection` method.
|
281
|
+
|
282
|
+
Either use `with_connection` or `lease_connection`.
|
283
|
+
MESSAGE
|
284
|
+
when :disallowed
|
285
|
+
raise ActiveRecordError, <<~MESSAGE
|
286
|
+
Called deprecated `ActiveRecord::Base.connection` method.
|
287
|
+
|
288
|
+
Either use `with_connection` or `lease_connection`.
|
289
|
+
MESSAGE
|
290
|
+
end
|
291
|
+
pool.lease_connection
|
292
|
+
else
|
293
|
+
pool.active_connection
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
# Return the currently leased connection into the pool
|
298
|
+
def release_connection
|
299
|
+
connection_pool.release_connection
|
300
|
+
end
|
301
|
+
|
302
|
+
# Checkouts a connection from the pool, yield it and then check it back in.
|
303
|
+
# If a connection was already leased via #lease_connection or a parent call to
|
304
|
+
# #with_connection, that same connection is yieled.
|
305
|
+
# If #lease_connection is called inside the block, the connection won't be checked
|
306
|
+
# back in.
|
307
|
+
# If #connection is called inside the block, the connection won't be checked back in
|
308
|
+
# unless the +prevent_permanent_checkout+ argument is set to +true+.
|
309
|
+
def with_connection(prevent_permanent_checkout: false, &block)
|
310
|
+
connection_pool.with_connection(prevent_permanent_checkout: prevent_permanent_checkout, &block)
|
255
311
|
end
|
256
312
|
|
257
313
|
attr_writer :connection_specification_name
|
258
314
|
|
259
315
|
# Returns the connection specification name from the current class or its parent.
|
260
316
|
def connection_specification_name
|
261
|
-
if
|
317
|
+
if @connection_specification_name.nil?
|
262
318
|
return self == Base ? Base.name : superclass.connection_specification_name
|
263
319
|
end
|
264
320
|
@connection_specification_name
|
@@ -279,8 +335,12 @@ module ActiveRecord
|
|
279
335
|
connection_pool.db_config
|
280
336
|
end
|
281
337
|
|
338
|
+
def adapter_class # :nodoc:
|
339
|
+
connection_pool.db_config.adapter_class
|
340
|
+
end
|
341
|
+
|
282
342
|
def connection_pool
|
283
|
-
connection_handler.retrieve_connection_pool(connection_specification_name, role: current_role, shard: current_shard
|
343
|
+
connection_handler.retrieve_connection_pool(connection_specification_name, role: current_role, shard: current_shard, strict: true)
|
284
344
|
end
|
285
345
|
|
286
346
|
def retrieve_connection
|
@@ -292,16 +352,9 @@ module ActiveRecord
|
|
292
352
|
connection_handler.connected?(connection_specification_name, role: current_role, shard: current_shard)
|
293
353
|
end
|
294
354
|
|
295
|
-
def remove_connection
|
296
|
-
if
|
297
|
-
ActiveRecord.deprecator.warn(<<-MSG.squish)
|
298
|
-
The name argument for `#remove_connection` is deprecated without replacement
|
299
|
-
and will be removed in Rails 7.2. `#remove_connection` should always be called
|
300
|
-
on the connection class directly, which makes the name argument obsolete.
|
301
|
-
MSG
|
302
|
-
end
|
355
|
+
def remove_connection
|
356
|
+
name = @connection_specification_name if defined?(@connection_specification_name)
|
303
357
|
|
304
|
-
name ||= @connection_specification_name if defined?(@connection_specification_name)
|
305
358
|
# if removing a connection that has a pool, we reset the
|
306
359
|
# connection_specification_name so it will use the parent
|
307
360
|
# pool.
|
@@ -312,39 +365,23 @@ module ActiveRecord
|
|
312
365
|
connection_handler.remove_connection_pool(name, role: current_role, shard: current_shard)
|
313
366
|
end
|
314
367
|
|
315
|
-
def
|
316
|
-
|
368
|
+
def schema_cache # :nodoc:
|
369
|
+
connection_pool.schema_cache
|
317
370
|
end
|
318
371
|
|
319
|
-
def
|
320
|
-
|
321
|
-
connection_handler.clear_active_connections!(role)
|
322
|
-
end
|
323
|
-
|
324
|
-
def clear_reloadable_connections!(role = nil)
|
325
|
-
deprecation_for_delegation(__method__)
|
326
|
-
connection_handler.clear_reloadable_connections!(role)
|
372
|
+
def clear_cache! # :nodoc:
|
373
|
+
connection_pool.schema_cache.clear!
|
327
374
|
end
|
328
375
|
|
329
|
-
def
|
330
|
-
|
331
|
-
connection_handler.clear_all_connections!(role)
|
376
|
+
def shard_keys
|
377
|
+
connection_class_for_self.instance_variable_get(:@shard_keys) || []
|
332
378
|
end
|
333
379
|
|
334
|
-
def
|
335
|
-
|
336
|
-
connection_handler.flush_idle_connections!(role)
|
380
|
+
def sharded?
|
381
|
+
shard_keys.any?
|
337
382
|
end
|
338
383
|
|
339
384
|
private
|
340
|
-
def deprecation_for_delegation(method)
|
341
|
-
ActiveRecord.deprecator.warn(<<-MSG.squish)
|
342
|
-
Calling `ActiveRecord::Base.#{method} is deprecated. Please
|
343
|
-
call the method directly on the connection handler; for
|
344
|
-
example: `ActiveRecord::Base.connection_handler.#{method}`.
|
345
|
-
MSG
|
346
|
-
end
|
347
|
-
|
348
385
|
def resolve_config_for_connection(config_or_env)
|
349
386
|
raise "Anonymous class is not allowed." unless name
|
350
387
|
|