activerecord 6.1.7.8 → 7.0.8.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +1582 -1018
- data/README.rdoc +3 -3
- data/lib/active_record/aggregations.rb +1 -1
- data/lib/active_record/association_relation.rb +0 -10
- data/lib/active_record/associations/association.rb +33 -17
- data/lib/active_record/associations/association_scope.rb +1 -3
- data/lib/active_record/associations/belongs_to_association.rb +15 -4
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +10 -2
- data/lib/active_record/associations/builder/association.rb +8 -2
- data/lib/active_record/associations/builder/belongs_to.rb +19 -6
- data/lib/active_record/associations/builder/collection_association.rb +10 -3
- data/lib/active_record/associations/builder/has_many.rb +3 -2
- data/lib/active_record/associations/builder/has_one.rb +2 -1
- data/lib/active_record/associations/builder/singular_association.rb +2 -2
- data/lib/active_record/associations/collection_association.rb +20 -22
- data/lib/active_record/associations/collection_proxy.rb +15 -5
- data/lib/active_record/associations/disable_joins_association_scope.rb +59 -0
- data/lib/active_record/associations/has_many_association.rb +8 -5
- data/lib/active_record/associations/has_many_through_association.rb +2 -1
- data/lib/active_record/associations/has_one_association.rb +10 -7
- data/lib/active_record/associations/has_one_through_association.rb +1 -1
- data/lib/active_record/associations/join_dependency.rb +23 -15
- data/lib/active_record/associations/preloader/association.rb +186 -52
- data/lib/active_record/associations/preloader/batch.rb +48 -0
- data/lib/active_record/associations/preloader/branch.rb +147 -0
- data/lib/active_record/associations/preloader/through_association.rb +50 -14
- data/lib/active_record/associations/preloader.rb +39 -113
- data/lib/active_record/associations/singular_association.rb +8 -2
- data/lib/active_record/associations/through_association.rb +3 -3
- data/lib/active_record/associations.rb +138 -100
- data/lib/active_record/asynchronous_queries_tracker.rb +60 -0
- data/lib/active_record/attribute_assignment.rb +1 -1
- data/lib/active_record/attribute_methods/before_type_cast.rb +7 -2
- data/lib/active_record/attribute_methods/dirty.rb +49 -16
- data/lib/active_record/attribute_methods/primary_key.rb +2 -2
- data/lib/active_record/attribute_methods/query.rb +2 -2
- data/lib/active_record/attribute_methods/read.rb +8 -6
- data/lib/active_record/attribute_methods/serialization.rb +57 -19
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +4 -3
- data/lib/active_record/attribute_methods/write.rb +7 -10
- data/lib/active_record/attribute_methods.rb +19 -22
- data/lib/active_record/attributes.rb +24 -35
- data/lib/active_record/autosave_association.rb +8 -23
- data/lib/active_record/base.rb +19 -1
- data/lib/active_record/callbacks.rb +14 -16
- data/lib/active_record/coders/yaml_column.rb +4 -8
- data/lib/active_record/connection_adapters/abstract/connection_handler.rb +292 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool/queue.rb +209 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool/reaper.rb +76 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +47 -561
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +0 -17
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +46 -22
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +24 -12
- data/lib/active_record/connection_adapters/abstract/quoting.rb +42 -72
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +4 -17
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +52 -23
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +14 -1
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +82 -25
- data/lib/active_record/connection_adapters/abstract/transaction.rb +15 -22
- data/lib/active_record/connection_adapters/abstract_adapter.rb +144 -82
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +115 -85
- data/lib/active_record/connection_adapters/column.rb +4 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +37 -25
- data/lib/active_record/connection_adapters/mysql/quoting.rb +50 -23
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +4 -1
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +7 -1
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +20 -1
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +12 -6
- data/lib/active_record/connection_adapters/pool_config.rb +7 -7
- data/lib/active_record/connection_adapters/postgresql/column.rb +19 -1
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +20 -17
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +8 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +5 -0
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +53 -14
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/timestamp.rb +15 -0
- data/lib/active_record/connection_adapters/postgresql/oid/timestamp_with_time_zone.rb +30 -0
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +18 -6
- data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +76 -73
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +34 -0
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +21 -1
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +22 -1
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +25 -0
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +40 -21
- data/lib/active_record/connection_adapters/postgresql/utils.rb +9 -10
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +207 -106
- data/lib/active_record/connection_adapters/schema_cache.rb +39 -38
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +25 -19
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +33 -18
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +6 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +19 -17
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +98 -36
- data/lib/active_record/connection_adapters.rb +6 -5
- data/lib/active_record/connection_handling.rb +49 -55
- data/lib/active_record/core.rb +123 -148
- data/lib/active_record/database_configurations/connection_url_resolver.rb +2 -1
- data/lib/active_record/database_configurations/database_config.rb +12 -9
- data/lib/active_record/database_configurations/hash_config.rb +63 -5
- data/lib/active_record/database_configurations/url_config.rb +2 -2
- data/lib/active_record/database_configurations.rb +15 -32
- data/lib/active_record/delegated_type.rb +53 -12
- data/lib/active_record/destroy_association_async_job.rb +1 -1
- data/lib/active_record/disable_joins_association_relation.rb +39 -0
- data/lib/active_record/dynamic_matchers.rb +1 -1
- data/lib/active_record/encryption/cipher/aes256_gcm.rb +98 -0
- data/lib/active_record/encryption/cipher.rb +53 -0
- data/lib/active_record/encryption/config.rb +44 -0
- data/lib/active_record/encryption/configurable.rb +67 -0
- data/lib/active_record/encryption/context.rb +35 -0
- data/lib/active_record/encryption/contexts.rb +72 -0
- data/lib/active_record/encryption/derived_secret_key_provider.rb +12 -0
- data/lib/active_record/encryption/deterministic_key_provider.rb +14 -0
- data/lib/active_record/encryption/encryptable_record.rb +206 -0
- data/lib/active_record/encryption/encrypted_attribute_type.rb +140 -0
- data/lib/active_record/encryption/encrypted_fixtures.rb +38 -0
- data/lib/active_record/encryption/encrypting_only_encryptor.rb +12 -0
- data/lib/active_record/encryption/encryptor.rb +155 -0
- data/lib/active_record/encryption/envelope_encryption_key_provider.rb +55 -0
- data/lib/active_record/encryption/errors.rb +15 -0
- data/lib/active_record/encryption/extended_deterministic_queries.rb +160 -0
- data/lib/active_record/encryption/extended_deterministic_uniqueness_validator.rb +28 -0
- data/lib/active_record/encryption/key.rb +28 -0
- data/lib/active_record/encryption/key_generator.rb +42 -0
- data/lib/active_record/encryption/key_provider.rb +46 -0
- data/lib/active_record/encryption/message.rb +33 -0
- data/lib/active_record/encryption/message_serializer.rb +90 -0
- data/lib/active_record/encryption/null_encryptor.rb +21 -0
- data/lib/active_record/encryption/properties.rb +76 -0
- data/lib/active_record/encryption/read_only_null_encryptor.rb +24 -0
- data/lib/active_record/encryption/scheme.rb +99 -0
- data/lib/active_record/encryption.rb +55 -0
- data/lib/active_record/enum.rb +50 -43
- data/lib/active_record/errors.rb +67 -4
- data/lib/active_record/explain_registry.rb +11 -6
- data/lib/active_record/explain_subscriber.rb +1 -1
- data/lib/active_record/fixture_set/file.rb +15 -1
- data/lib/active_record/fixture_set/table_row.rb +41 -6
- data/lib/active_record/fixture_set/table_rows.rb +4 -4
- data/lib/active_record/fixtures.rb +20 -23
- data/lib/active_record/future_result.rb +139 -0
- data/lib/active_record/gem_version.rb +5 -5
- data/lib/active_record/inheritance.rb +55 -17
- data/lib/active_record/insert_all.rb +80 -14
- data/lib/active_record/integration.rb +4 -3
- data/lib/active_record/internal_metadata.rb +1 -5
- data/lib/active_record/legacy_yaml_adapter.rb +2 -39
- data/lib/active_record/locking/optimistic.rb +36 -21
- data/lib/active_record/locking/pessimistic.rb +10 -4
- data/lib/active_record/log_subscriber.rb +23 -7
- data/lib/active_record/middleware/database_selector/resolver.rb +6 -10
- data/lib/active_record/middleware/database_selector.rb +18 -6
- data/lib/active_record/middleware/shard_selector.rb +60 -0
- data/lib/active_record/migration/command_recorder.rb +8 -9
- data/lib/active_record/migration/compatibility.rb +93 -46
- data/lib/active_record/migration/join_table.rb +1 -1
- data/lib/active_record/migration.rb +167 -87
- data/lib/active_record/model_schema.rb +58 -59
- data/lib/active_record/nested_attributes.rb +13 -12
- data/lib/active_record/no_touching.rb +3 -3
- data/lib/active_record/null_relation.rb +2 -6
- data/lib/active_record/persistence.rb +231 -61
- data/lib/active_record/query_cache.rb +2 -2
- data/lib/active_record/query_logs.rb +149 -0
- data/lib/active_record/querying.rb +16 -6
- data/lib/active_record/railtie.rb +136 -22
- data/lib/active_record/railties/controller_runtime.rb +4 -5
- data/lib/active_record/railties/databases.rake +78 -136
- data/lib/active_record/readonly_attributes.rb +11 -0
- data/lib/active_record/reflection.rb +80 -49
- data/lib/active_record/relation/batches/batch_enumerator.rb +19 -5
- data/lib/active_record/relation/batches.rb +6 -6
- data/lib/active_record/relation/calculations.rb +92 -60
- data/lib/active_record/relation/delegation.rb +7 -7
- data/lib/active_record/relation/finder_methods.rb +31 -35
- data/lib/active_record/relation/merger.rb +20 -13
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +20 -1
- data/lib/active_record/relation/predicate_builder.rb +1 -6
- data/lib/active_record/relation/query_attribute.rb +28 -11
- data/lib/active_record/relation/query_methods.rb +304 -68
- data/lib/active_record/relation/record_fetch_warning.rb +7 -9
- data/lib/active_record/relation/spawn_methods.rb +2 -2
- data/lib/active_record/relation/where_clause.rb +10 -19
- data/lib/active_record/relation.rb +189 -88
- data/lib/active_record/result.rb +23 -11
- data/lib/active_record/runtime_registry.rb +9 -13
- data/lib/active_record/sanitization.rb +17 -12
- data/lib/active_record/schema.rb +38 -23
- data/lib/active_record/schema_dumper.rb +29 -19
- data/lib/active_record/schema_migration.rb +4 -4
- data/lib/active_record/scoping/default.rb +60 -13
- data/lib/active_record/scoping/named.rb +3 -11
- data/lib/active_record/scoping.rb +64 -34
- data/lib/active_record/serialization.rb +6 -1
- data/lib/active_record/signed_id.rb +3 -3
- data/lib/active_record/store.rb +2 -2
- data/lib/active_record/suppressor.rb +11 -15
- data/lib/active_record/table_metadata.rb +6 -2
- data/lib/active_record/tasks/database_tasks.rb +127 -60
- data/lib/active_record/tasks/mysql_database_tasks.rb +1 -1
- data/lib/active_record/tasks/postgresql_database_tasks.rb +19 -13
- data/lib/active_record/test_databases.rb +1 -1
- data/lib/active_record/test_fixtures.rb +9 -6
- data/lib/active_record/timestamp.rb +3 -4
- data/lib/active_record/transactions.rb +12 -17
- data/lib/active_record/translation.rb +3 -3
- data/lib/active_record/type/adapter_specific_registry.rb +32 -7
- data/lib/active_record/type/hash_lookup_type_map.rb +34 -1
- data/lib/active_record/type/internal/timezone.rb +2 -2
- data/lib/active_record/type/serialized.rb +9 -5
- data/lib/active_record/type/type_map.rb +17 -20
- data/lib/active_record/type.rb +1 -2
- data/lib/active_record/validations/associated.rb +4 -4
- data/lib/active_record/validations/presence.rb +2 -2
- data/lib/active_record/validations/uniqueness.rb +4 -4
- data/lib/active_record/version.rb +1 -1
- data/lib/active_record.rb +225 -27
- data/lib/arel/attributes/attribute.rb +0 -8
- data/lib/arel/crud.rb +28 -22
- data/lib/arel/delete_manager.rb +18 -4
- data/lib/arel/filter_predications.rb +9 -0
- data/lib/arel/insert_manager.rb +2 -3
- data/lib/arel/nodes/and.rb +4 -0
- data/lib/arel/nodes/casted.rb +1 -1
- data/lib/arel/nodes/delete_statement.rb +12 -13
- data/lib/arel/nodes/filter.rb +10 -0
- data/lib/arel/nodes/function.rb +1 -0
- data/lib/arel/nodes/insert_statement.rb +2 -2
- data/lib/arel/nodes/select_core.rb +2 -2
- data/lib/arel/nodes/select_statement.rb +2 -2
- data/lib/arel/nodes/update_statement.rb +8 -3
- data/lib/arel/nodes.rb +1 -0
- data/lib/arel/predications.rb +11 -3
- data/lib/arel/select_manager.rb +10 -4
- data/lib/arel/table.rb +0 -1
- data/lib/arel/tree_manager.rb +0 -12
- data/lib/arel/update_manager.rb +18 -4
- data/lib/arel/visitors/dot.rb +80 -90
- data/lib/arel/visitors/mysql.rb +8 -2
- data/lib/arel/visitors/postgresql.rb +0 -10
- data/lib/arel/visitors/to_sql.rb +58 -2
- data/lib/arel.rb +2 -1
- data/lib/rails/generators/active_record/application_record/templates/application_record.rb.tt +1 -1
- data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +1 -1
- data/lib/rails/generators/active_record/model/templates/model.rb.tt +1 -1
- data/lib/rails/generators/active_record/model/templates/module.rb.tt +2 -2
- data/lib/rails/generators/active_record/multi_db/multi_db_generator.rb +16 -0
- data/lib/rails/generators/active_record/multi_db/templates/multi_db.rb.tt +44 -0
- metadata +53 -9
@@ -3,7 +3,9 @@
|
|
3
3
|
require "thread"
|
4
4
|
require "concurrent/map"
|
5
5
|
require "monitor"
|
6
|
-
|
6
|
+
|
7
|
+
require "active_record/connection_adapters/abstract/connection_pool/queue"
|
8
|
+
require "active_record/connection_adapters/abstract/connection_pool/reaper"
|
7
9
|
|
8
10
|
module ActiveRecord
|
9
11
|
module ConnectionAdapters
|
@@ -17,6 +19,13 @@ module ActiveRecord
|
|
17
19
|
def set_schema_cache(cache)
|
18
20
|
self.schema_cache = cache
|
19
21
|
end
|
22
|
+
|
23
|
+
def lazily_set_schema_cache
|
24
|
+
return unless ActiveRecord.lazily_load_schema_cache
|
25
|
+
|
26
|
+
cache = SchemaCache.load_from(db_config.lazy_schema_cache_path)
|
27
|
+
set_schema_cache(cache)
|
28
|
+
end
|
20
29
|
end
|
21
30
|
|
22
31
|
class NullPool # :nodoc:
|
@@ -24,9 +33,10 @@ module ActiveRecord
|
|
24
33
|
|
25
34
|
attr_accessor :schema_cache
|
26
35
|
|
27
|
-
def
|
28
|
-
|
29
|
-
end
|
36
|
+
def connection_class; end
|
37
|
+
def checkin(_); end
|
38
|
+
def remove(_); end
|
39
|
+
def async_executor; end
|
30
40
|
end
|
31
41
|
|
32
42
|
# Connection pool base class for managing Active Record database
|
@@ -90,278 +100,15 @@ module ActiveRecord
|
|
90
100
|
# * private methods that require being called in a +synchronize+ blocks
|
91
101
|
# are now explicitly documented
|
92
102
|
class ConnectionPool
|
93
|
-
# Threadsafe, fair, LIFO queue. Meant to be used by ConnectionPool
|
94
|
-
# with which it shares a Monitor.
|
95
|
-
class Queue
|
96
|
-
def initialize(lock = Monitor.new)
|
97
|
-
@lock = lock
|
98
|
-
@cond = @lock.new_cond
|
99
|
-
@num_waiting = 0
|
100
|
-
@queue = []
|
101
|
-
end
|
102
|
-
|
103
|
-
# Test if any threads are currently waiting on the queue.
|
104
|
-
def any_waiting?
|
105
|
-
synchronize do
|
106
|
-
@num_waiting > 0
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
# Returns the number of threads currently waiting on this
|
111
|
-
# queue.
|
112
|
-
def num_waiting
|
113
|
-
synchronize do
|
114
|
-
@num_waiting
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
|
-
# Add +element+ to the queue. Never blocks.
|
119
|
-
def add(element)
|
120
|
-
synchronize do
|
121
|
-
@queue.push element
|
122
|
-
@cond.signal
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
# If +element+ is in the queue, remove and return it, or +nil+.
|
127
|
-
def delete(element)
|
128
|
-
synchronize do
|
129
|
-
@queue.delete(element)
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
# Remove all elements from the queue.
|
134
|
-
def clear
|
135
|
-
synchronize do
|
136
|
-
@queue.clear
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
|
-
# Remove the head of the queue.
|
141
|
-
#
|
142
|
-
# If +timeout+ is not given, remove and return the head of the
|
143
|
-
# queue if the number of available elements is strictly
|
144
|
-
# greater than the number of threads currently waiting (that
|
145
|
-
# is, don't jump ahead in line). Otherwise, return +nil+.
|
146
|
-
#
|
147
|
-
# If +timeout+ is given, block if there is no element
|
148
|
-
# available, waiting up to +timeout+ seconds for an element to
|
149
|
-
# become available.
|
150
|
-
#
|
151
|
-
# Raises:
|
152
|
-
# - ActiveRecord::ConnectionTimeoutError if +timeout+ is given and no element
|
153
|
-
# becomes available within +timeout+ seconds,
|
154
|
-
def poll(timeout = nil)
|
155
|
-
synchronize { internal_poll(timeout) }
|
156
|
-
end
|
157
|
-
|
158
|
-
private
|
159
|
-
def internal_poll(timeout)
|
160
|
-
no_wait_poll || (timeout && wait_poll(timeout))
|
161
|
-
end
|
162
|
-
|
163
|
-
def synchronize(&block)
|
164
|
-
@lock.synchronize(&block)
|
165
|
-
end
|
166
|
-
|
167
|
-
# Test if the queue currently contains any elements.
|
168
|
-
def any?
|
169
|
-
!@queue.empty?
|
170
|
-
end
|
171
|
-
|
172
|
-
# A thread can remove an element from the queue without
|
173
|
-
# waiting if and only if the number of currently available
|
174
|
-
# connections is strictly greater than the number of waiting
|
175
|
-
# threads.
|
176
|
-
def can_remove_no_wait?
|
177
|
-
@queue.size > @num_waiting
|
178
|
-
end
|
179
|
-
|
180
|
-
# Removes and returns the head of the queue if possible, or +nil+.
|
181
|
-
def remove
|
182
|
-
@queue.pop
|
183
|
-
end
|
184
|
-
|
185
|
-
# Remove and return the head of the queue if the number of
|
186
|
-
# available elements is strictly greater than the number of
|
187
|
-
# threads currently waiting. Otherwise, return +nil+.
|
188
|
-
def no_wait_poll
|
189
|
-
remove if can_remove_no_wait?
|
190
|
-
end
|
191
|
-
|
192
|
-
# Waits on the queue up to +timeout+ seconds, then removes and
|
193
|
-
# returns the head of the queue.
|
194
|
-
def wait_poll(timeout)
|
195
|
-
@num_waiting += 1
|
196
|
-
|
197
|
-
t0 = Concurrent.monotonic_time
|
198
|
-
elapsed = 0
|
199
|
-
loop do
|
200
|
-
ActiveSupport::Dependencies.interlock.permit_concurrent_loads do
|
201
|
-
@cond.wait(timeout - elapsed)
|
202
|
-
end
|
203
|
-
|
204
|
-
return remove if any?
|
205
|
-
|
206
|
-
elapsed = Concurrent.monotonic_time - t0
|
207
|
-
if elapsed >= timeout
|
208
|
-
msg = "could not obtain a connection from the pool within %0.3f seconds (waited %0.3f seconds); all pooled connections were in use" %
|
209
|
-
[timeout, elapsed]
|
210
|
-
raise ConnectionTimeoutError, msg
|
211
|
-
end
|
212
|
-
end
|
213
|
-
ensure
|
214
|
-
@num_waiting -= 1
|
215
|
-
end
|
216
|
-
end
|
217
|
-
|
218
|
-
# Adds the ability to turn a basic fair FIFO queue into one
|
219
|
-
# biased to some thread.
|
220
|
-
module BiasableQueue # :nodoc:
|
221
|
-
class BiasedConditionVariable # :nodoc:
|
222
|
-
# semantics of condition variables guarantee that +broadcast+, +broadcast_on_biased+,
|
223
|
-
# +signal+ and +wait+ methods are only called while holding a lock
|
224
|
-
def initialize(lock, other_cond, preferred_thread)
|
225
|
-
@real_cond = lock.new_cond
|
226
|
-
@other_cond = other_cond
|
227
|
-
@preferred_thread = preferred_thread
|
228
|
-
@num_waiting_on_real_cond = 0
|
229
|
-
end
|
230
|
-
|
231
|
-
def broadcast
|
232
|
-
broadcast_on_biased
|
233
|
-
@other_cond.broadcast
|
234
|
-
end
|
235
|
-
|
236
|
-
def broadcast_on_biased
|
237
|
-
@num_waiting_on_real_cond = 0
|
238
|
-
@real_cond.broadcast
|
239
|
-
end
|
240
|
-
|
241
|
-
def signal
|
242
|
-
if @num_waiting_on_real_cond > 0
|
243
|
-
@num_waiting_on_real_cond -= 1
|
244
|
-
@real_cond
|
245
|
-
else
|
246
|
-
@other_cond
|
247
|
-
end.signal
|
248
|
-
end
|
249
|
-
|
250
|
-
def wait(timeout)
|
251
|
-
if Thread.current == @preferred_thread
|
252
|
-
@num_waiting_on_real_cond += 1
|
253
|
-
@real_cond
|
254
|
-
else
|
255
|
-
@other_cond
|
256
|
-
end.wait(timeout)
|
257
|
-
end
|
258
|
-
end
|
259
|
-
|
260
|
-
def with_a_bias_for(thread)
|
261
|
-
previous_cond = nil
|
262
|
-
new_cond = nil
|
263
|
-
synchronize do
|
264
|
-
previous_cond = @cond
|
265
|
-
@cond = new_cond = BiasedConditionVariable.new(@lock, @cond, thread)
|
266
|
-
end
|
267
|
-
yield
|
268
|
-
ensure
|
269
|
-
synchronize do
|
270
|
-
@cond = previous_cond if previous_cond
|
271
|
-
new_cond.broadcast_on_biased if new_cond # wake up any remaining sleepers
|
272
|
-
end
|
273
|
-
end
|
274
|
-
end
|
275
|
-
|
276
|
-
# Connections must be leased while holding the main pool mutex. This is
|
277
|
-
# an internal subclass that also +.leases+ returned connections while
|
278
|
-
# still in queue's critical section (queue synchronizes with the same
|
279
|
-
# <tt>@lock</tt> as the main pool) so that a returned connection is already
|
280
|
-
# leased and there is no need to re-enter synchronized block.
|
281
|
-
class ConnectionLeasingQueue < Queue # :nodoc:
|
282
|
-
include BiasableQueue
|
283
|
-
|
284
|
-
private
|
285
|
-
def internal_poll(timeout)
|
286
|
-
conn = super
|
287
|
-
conn.lease if conn
|
288
|
-
conn
|
289
|
-
end
|
290
|
-
end
|
291
|
-
|
292
|
-
# Every +frequency+ seconds, the reaper will call +reap+ and +flush+ on
|
293
|
-
# +pool+. A reaper instantiated with a zero frequency will never reap
|
294
|
-
# the connection pool.
|
295
|
-
#
|
296
|
-
# Configure the frequency by setting +reaping_frequency+ in your database
|
297
|
-
# yaml file (default 60 seconds).
|
298
|
-
class Reaper
|
299
|
-
attr_reader :pool, :frequency
|
300
|
-
|
301
|
-
def initialize(pool, frequency)
|
302
|
-
@pool = pool
|
303
|
-
@frequency = frequency
|
304
|
-
end
|
305
|
-
|
306
|
-
@mutex = Mutex.new
|
307
|
-
@pools = {}
|
308
|
-
@threads = {}
|
309
|
-
|
310
|
-
class << self
|
311
|
-
def register_pool(pool, frequency) # :nodoc:
|
312
|
-
@mutex.synchronize do
|
313
|
-
unless @threads[frequency]&.alive?
|
314
|
-
@threads[frequency] = spawn_thread(frequency)
|
315
|
-
end
|
316
|
-
@pools[frequency] ||= []
|
317
|
-
@pools[frequency] << WeakRef.new(pool)
|
318
|
-
end
|
319
|
-
end
|
320
|
-
|
321
|
-
private
|
322
|
-
def spawn_thread(frequency)
|
323
|
-
Thread.new(frequency) do |t|
|
324
|
-
# Advise multi-threaded app servers to ignore this thread for
|
325
|
-
# the purposes of fork safety warnings
|
326
|
-
Thread.current.thread_variable_set(:fork_safe, true)
|
327
|
-
running = true
|
328
|
-
while running
|
329
|
-
sleep t
|
330
|
-
@mutex.synchronize do
|
331
|
-
@pools[frequency].select! do |pool|
|
332
|
-
pool.weakref_alive? && !pool.discarded?
|
333
|
-
end
|
334
|
-
|
335
|
-
@pools[frequency].each do |p|
|
336
|
-
p.reap
|
337
|
-
p.flush
|
338
|
-
rescue WeakRef::RefError
|
339
|
-
end
|
340
|
-
|
341
|
-
if @pools[frequency].empty?
|
342
|
-
@pools.delete(frequency)
|
343
|
-
@threads.delete(frequency)
|
344
|
-
running = false
|
345
|
-
end
|
346
|
-
end
|
347
|
-
end
|
348
|
-
end
|
349
|
-
end
|
350
|
-
end
|
351
|
-
|
352
|
-
def run
|
353
|
-
return unless frequency && frequency > 0
|
354
|
-
self.class.register_pool(pool, frequency)
|
355
|
-
end
|
356
|
-
end
|
357
|
-
|
358
103
|
include MonitorMixin
|
359
104
|
include QueryCache::ConnectionPoolConfiguration
|
360
105
|
include ConnectionAdapters::AbstractPool
|
361
106
|
|
362
107
|
attr_accessor :automatic_reconnect, :checkout_timeout
|
363
|
-
attr_reader :db_config, :size, :reaper, :pool_config, :
|
108
|
+
attr_reader :db_config, :size, :reaper, :pool_config, :connection_class, :async_executor, :role, :shard
|
364
109
|
|
110
|
+
alias_method :connection_klass, :connection_class
|
111
|
+
deprecate :connection_klass
|
365
112
|
delegate :schema_cache, :schema_cache=, to: :pool_config
|
366
113
|
|
367
114
|
# Creates a new ConnectionPool object. +pool_config+ is a PoolConfig
|
@@ -375,7 +122,9 @@ module ActiveRecord
|
|
375
122
|
|
376
123
|
@pool_config = pool_config
|
377
124
|
@db_config = pool_config.db_config
|
378
|
-
@
|
125
|
+
@connection_class = pool_config.connection_class
|
126
|
+
@role = pool_config.role
|
127
|
+
@shard = pool_config.shard
|
379
128
|
|
380
129
|
@checkout_timeout = db_config.checkout_timeout
|
381
130
|
@idle_timeout = db_config.idle_timeout
|
@@ -407,6 +156,10 @@ module ActiveRecord
|
|
407
156
|
|
408
157
|
@lock_thread = false
|
409
158
|
|
159
|
+
@async_executor = build_async_executor
|
160
|
+
|
161
|
+
lazily_set_schema_cache
|
162
|
+
|
410
163
|
@reaper = Reaper.new(self, db_config.reaping_frequency)
|
411
164
|
@reaper.run
|
412
165
|
end
|
@@ -713,7 +466,28 @@ module ActiveRecord
|
|
713
466
|
end
|
714
467
|
end
|
715
468
|
|
469
|
+
def schedule_query(future_result) # :nodoc:
|
470
|
+
@async_executor.post { future_result.execute_or_skip }
|
471
|
+
Thread.pass
|
472
|
+
end
|
473
|
+
|
716
474
|
private
|
475
|
+
def build_async_executor
|
476
|
+
case ActiveRecord.async_query_executor
|
477
|
+
when :multi_thread_pool
|
478
|
+
if @db_config.max_threads > 0
|
479
|
+
Concurrent::ThreadPoolExecutor.new(
|
480
|
+
min_threads: @db_config.min_threads,
|
481
|
+
max_threads: @db_config.max_threads,
|
482
|
+
max_queue: @db_config.max_queue,
|
483
|
+
fallback_policy: :caller_runs
|
484
|
+
)
|
485
|
+
end
|
486
|
+
when :global_thread_pool
|
487
|
+
ActiveRecord.global_thread_pool_async_query_executor
|
488
|
+
end
|
489
|
+
end
|
490
|
+
|
717
491
|
#--
|
718
492
|
# this is unfortunately not concurrent
|
719
493
|
def bulk_make_new_connections(num_new_conns_needed)
|
@@ -757,13 +531,13 @@ module ActiveRecord
|
|
757
531
|
end
|
758
532
|
|
759
533
|
newly_checked_out = []
|
760
|
-
timeout_time =
|
534
|
+
timeout_time = Process.clock_gettime(Process::CLOCK_MONOTONIC) + (@checkout_timeout * 2)
|
761
535
|
|
762
536
|
@available.with_a_bias_for(Thread.current) do
|
763
537
|
loop do
|
764
538
|
synchronize do
|
765
539
|
return if collected_conns.size == @connections.size && @now_connecting == 0
|
766
|
-
remaining_timeout = timeout_time -
|
540
|
+
remaining_timeout = timeout_time - Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
767
541
|
remaining_timeout = 0 if remaining_timeout < 0
|
768
542
|
conn = checkout_for_exclusive_access(remaining_timeout)
|
769
543
|
collected_conns << conn
|
@@ -937,293 +711,5 @@ module ActiveRecord
|
|
937
711
|
raise
|
938
712
|
end
|
939
713
|
end
|
940
|
-
|
941
|
-
# ConnectionHandler is a collection of ConnectionPool objects. It is used
|
942
|
-
# for keeping separate connection pools that connect to different databases.
|
943
|
-
#
|
944
|
-
# For example, suppose that you have 5 models, with the following hierarchy:
|
945
|
-
#
|
946
|
-
# class Author < ActiveRecord::Base
|
947
|
-
# end
|
948
|
-
#
|
949
|
-
# class BankAccount < ActiveRecord::Base
|
950
|
-
# end
|
951
|
-
#
|
952
|
-
# class Book < ActiveRecord::Base
|
953
|
-
# establish_connection :library_db
|
954
|
-
# end
|
955
|
-
#
|
956
|
-
# class ScaryBook < Book
|
957
|
-
# end
|
958
|
-
#
|
959
|
-
# class GoodBook < Book
|
960
|
-
# end
|
961
|
-
#
|
962
|
-
# And a database.yml that looked like this:
|
963
|
-
#
|
964
|
-
# development:
|
965
|
-
# database: my_application
|
966
|
-
# host: localhost
|
967
|
-
#
|
968
|
-
# library_db:
|
969
|
-
# database: library
|
970
|
-
# host: some.library.org
|
971
|
-
#
|
972
|
-
# Your primary database in the development environment is "my_application"
|
973
|
-
# but the Book model connects to a separate database called "library_db"
|
974
|
-
# (this can even be a database on a different machine).
|
975
|
-
#
|
976
|
-
# Book, ScaryBook and GoodBook will all use the same connection pool to
|
977
|
-
# "library_db" while Author, BankAccount, and any other models you create
|
978
|
-
# will use the default connection pool to "my_application".
|
979
|
-
#
|
980
|
-
# The various connection pools are managed by a single instance of
|
981
|
-
# ConnectionHandler accessible via ActiveRecord::Base.connection_handler.
|
982
|
-
# All Active Record models use this handler to determine the connection pool that they
|
983
|
-
# should use.
|
984
|
-
#
|
985
|
-
# The ConnectionHandler class is not coupled with the Active models, as it has no knowledge
|
986
|
-
# about the model. The model needs to pass a connection specification name to the handler,
|
987
|
-
# in order to look up the correct connection pool.
|
988
|
-
class ConnectionHandler
|
989
|
-
FINALIZER = lambda { |_| ActiveSupport::ForkTracker.check! }
|
990
|
-
private_constant :FINALIZER
|
991
|
-
|
992
|
-
def initialize
|
993
|
-
# These caches are keyed by pool_config.connection_specification_name (PoolConfig#connection_specification_name).
|
994
|
-
@owner_to_pool_manager = Concurrent::Map.new(initial_capacity: 2)
|
995
|
-
|
996
|
-
# Backup finalizer: if the forked child skipped Kernel#fork the early discard has not occurred
|
997
|
-
ObjectSpace.define_finalizer self, FINALIZER
|
998
|
-
end
|
999
|
-
|
1000
|
-
def prevent_writes # :nodoc:
|
1001
|
-
Thread.current[:prevent_writes]
|
1002
|
-
end
|
1003
|
-
|
1004
|
-
def prevent_writes=(prevent_writes) # :nodoc:
|
1005
|
-
Thread.current[:prevent_writes] = prevent_writes
|
1006
|
-
end
|
1007
|
-
|
1008
|
-
# Prevent writing to the database regardless of role.
|
1009
|
-
#
|
1010
|
-
# In some cases you may want to prevent writes to the database
|
1011
|
-
# even if you are on a database that can write. `while_preventing_writes`
|
1012
|
-
# will prevent writes to the database for the duration of the block.
|
1013
|
-
#
|
1014
|
-
# This method does not provide the same protection as a readonly
|
1015
|
-
# user and is meant to be a safeguard against accidental writes.
|
1016
|
-
#
|
1017
|
-
# See `READ_QUERY` for the queries that are blocked by this
|
1018
|
-
# method.
|
1019
|
-
def while_preventing_writes(enabled = true)
|
1020
|
-
unless ActiveRecord::Base.legacy_connection_handling
|
1021
|
-
raise NotImplementedError, "`while_preventing_writes` is only available on the connection_handler with legacy_connection_handling"
|
1022
|
-
end
|
1023
|
-
|
1024
|
-
original, self.prevent_writes = self.prevent_writes, enabled
|
1025
|
-
yield
|
1026
|
-
ensure
|
1027
|
-
self.prevent_writes = original
|
1028
|
-
end
|
1029
|
-
|
1030
|
-
def connection_pool_names # :nodoc:
|
1031
|
-
owner_to_pool_manager.keys
|
1032
|
-
end
|
1033
|
-
|
1034
|
-
def all_connection_pools
|
1035
|
-
owner_to_pool_manager.values.flat_map { |m| m.pool_configs.map(&:pool) }
|
1036
|
-
end
|
1037
|
-
|
1038
|
-
def connection_pool_list(role = ActiveRecord::Base.current_role)
|
1039
|
-
owner_to_pool_manager.values.flat_map { |m| m.pool_configs(role).map(&:pool) }
|
1040
|
-
end
|
1041
|
-
alias :connection_pools :connection_pool_list
|
1042
|
-
|
1043
|
-
def establish_connection(config, owner_name: Base, role: ActiveRecord::Base.current_role, shard: Base.current_shard)
|
1044
|
-
owner_name = config.to_s if config.is_a?(Symbol)
|
1045
|
-
|
1046
|
-
pool_config = resolve_pool_config(config, owner_name)
|
1047
|
-
db_config = pool_config.db_config
|
1048
|
-
|
1049
|
-
# Protects the connection named `ActiveRecord::Base` from being removed
|
1050
|
-
# if the user calls `establish_connection :primary`.
|
1051
|
-
if owner_to_pool_manager.key?(pool_config.connection_specification_name)
|
1052
|
-
remove_connection_pool(pool_config.connection_specification_name, role: role, shard: shard)
|
1053
|
-
end
|
1054
|
-
|
1055
|
-
message_bus = ActiveSupport::Notifications.instrumenter
|
1056
|
-
payload = {}
|
1057
|
-
if pool_config
|
1058
|
-
payload[:spec_name] = pool_config.connection_specification_name
|
1059
|
-
payload[:shard] = shard
|
1060
|
-
payload[:config] = db_config.configuration_hash
|
1061
|
-
end
|
1062
|
-
|
1063
|
-
if ActiveRecord::Base.legacy_connection_handling
|
1064
|
-
owner_to_pool_manager[pool_config.connection_specification_name] ||= LegacyPoolManager.new
|
1065
|
-
else
|
1066
|
-
owner_to_pool_manager[pool_config.connection_specification_name] ||= PoolManager.new
|
1067
|
-
end
|
1068
|
-
pool_manager = get_pool_manager(pool_config.connection_specification_name)
|
1069
|
-
pool_manager.set_pool_config(role, shard, pool_config)
|
1070
|
-
|
1071
|
-
message_bus.instrument("!connection.active_record", payload) do
|
1072
|
-
pool_config.pool
|
1073
|
-
end
|
1074
|
-
end
|
1075
|
-
|
1076
|
-
# Returns true if there are any active connections among the connection
|
1077
|
-
# pools that the ConnectionHandler is managing.
|
1078
|
-
def active_connections?(role = ActiveRecord::Base.current_role)
|
1079
|
-
connection_pool_list(role).any?(&:active_connection?)
|
1080
|
-
end
|
1081
|
-
|
1082
|
-
# Returns any connections in use by the current thread back to the pool,
|
1083
|
-
# and also returns connections to the pool cached by threads that are no
|
1084
|
-
# longer alive.
|
1085
|
-
def clear_active_connections!(role = ActiveRecord::Base.current_role)
|
1086
|
-
connection_pool_list(role).each(&:release_connection)
|
1087
|
-
end
|
1088
|
-
|
1089
|
-
# Clears the cache which maps classes.
|
1090
|
-
#
|
1091
|
-
# See ConnectionPool#clear_reloadable_connections! for details.
|
1092
|
-
def clear_reloadable_connections!(role = ActiveRecord::Base.current_role)
|
1093
|
-
connection_pool_list(role).each(&:clear_reloadable_connections!)
|
1094
|
-
end
|
1095
|
-
|
1096
|
-
def clear_all_connections!(role = ActiveRecord::Base.current_role)
|
1097
|
-
connection_pool_list(role).each(&:disconnect!)
|
1098
|
-
end
|
1099
|
-
|
1100
|
-
# Disconnects all currently idle connections.
|
1101
|
-
#
|
1102
|
-
# See ConnectionPool#flush! for details.
|
1103
|
-
def flush_idle_connections!(role = ActiveRecord::Base.current_role)
|
1104
|
-
connection_pool_list(role).each(&:flush!)
|
1105
|
-
end
|
1106
|
-
|
1107
|
-
# Locate the connection of the nearest super class. This can be an
|
1108
|
-
# active or defined connection: if it is the latter, it will be
|
1109
|
-
# opened and set as the active connection for the class it was defined
|
1110
|
-
# for (not necessarily the current class).
|
1111
|
-
def retrieve_connection(spec_name, role: ActiveRecord::Base.current_role, shard: ActiveRecord::Base.current_shard) # :nodoc:
|
1112
|
-
pool = retrieve_connection_pool(spec_name, role: role, shard: shard)
|
1113
|
-
|
1114
|
-
unless pool
|
1115
|
-
if shard != ActiveRecord::Base.default_shard
|
1116
|
-
message = "No connection pool for '#{spec_name}' found for the '#{shard}' shard."
|
1117
|
-
elsif ActiveRecord::Base.connection_handler != ActiveRecord::Base.default_connection_handler
|
1118
|
-
message = "No connection pool for '#{spec_name}' found for the '#{ActiveRecord::Base.current_role}' role."
|
1119
|
-
elsif role != ActiveRecord::Base.default_role
|
1120
|
-
message = "No connection pool for '#{spec_name}' found for the '#{role}' role."
|
1121
|
-
else
|
1122
|
-
message = "No connection pool for '#{spec_name}' found."
|
1123
|
-
end
|
1124
|
-
|
1125
|
-
raise ConnectionNotEstablished, message
|
1126
|
-
end
|
1127
|
-
|
1128
|
-
pool.connection
|
1129
|
-
end
|
1130
|
-
|
1131
|
-
# Returns true if a connection that's accessible to this class has
|
1132
|
-
# already been opened.
|
1133
|
-
def connected?(spec_name, role: ActiveRecord::Base.current_role, shard: ActiveRecord::Base.current_shard)
|
1134
|
-
pool = retrieve_connection_pool(spec_name, role: role, shard: shard)
|
1135
|
-
pool && pool.connected?
|
1136
|
-
end
|
1137
|
-
|
1138
|
-
# Remove the connection for this class. This will close the active
|
1139
|
-
# connection and the defined connection (if they exist). The result
|
1140
|
-
# can be used as an argument for #establish_connection, for easily
|
1141
|
-
# re-establishing the connection.
|
1142
|
-
def remove_connection(owner, role: ActiveRecord::Base.current_role, shard: ActiveRecord::Base.current_shard)
|
1143
|
-
remove_connection_pool(owner, role: role, shard: shard)&.configuration_hash
|
1144
|
-
end
|
1145
|
-
deprecate remove_connection: "Use #remove_connection_pool, which now returns a DatabaseConfig object instead of a Hash"
|
1146
|
-
|
1147
|
-
def remove_connection_pool(owner, role: ActiveRecord::Base.current_role, shard: ActiveRecord::Base.current_shard)
|
1148
|
-
if pool_manager = get_pool_manager(owner)
|
1149
|
-
pool_config = pool_manager.remove_pool_config(role, shard)
|
1150
|
-
|
1151
|
-
if pool_config
|
1152
|
-
pool_config.disconnect!
|
1153
|
-
pool_config.db_config
|
1154
|
-
end
|
1155
|
-
end
|
1156
|
-
end
|
1157
|
-
|
1158
|
-
# Retrieving the connection pool happens a lot, so we cache it in @owner_to_pool_manager.
|
1159
|
-
# This makes retrieving the connection pool O(1) once the process is warm.
|
1160
|
-
# When a connection is established or removed, we invalidate the cache.
|
1161
|
-
def retrieve_connection_pool(owner, role: ActiveRecord::Base.current_role, shard: ActiveRecord::Base.current_shard)
|
1162
|
-
pool_config = get_pool_manager(owner)&.get_pool_config(role, shard)
|
1163
|
-
pool_config&.pool
|
1164
|
-
end
|
1165
|
-
|
1166
|
-
private
|
1167
|
-
attr_reader :owner_to_pool_manager
|
1168
|
-
|
1169
|
-
# Returns the pool manager for an owner.
|
1170
|
-
#
|
1171
|
-
# Using `"primary"` to look up the pool manager for `ActiveRecord::Base` is
|
1172
|
-
# deprecated in favor of looking it up by `"ActiveRecord::Base"`.
|
1173
|
-
#
|
1174
|
-
# During the deprecation period, if `"primary"` is passed, the pool manager
|
1175
|
-
# for `ActiveRecord::Base` will still be returned.
|
1176
|
-
def get_pool_manager(owner)
|
1177
|
-
return owner_to_pool_manager[owner] if owner_to_pool_manager.key?(owner)
|
1178
|
-
|
1179
|
-
if owner == "primary"
|
1180
|
-
ActiveSupport::Deprecation.warn("Using `\"primary\"` as a `connection_specification_name` is deprecated and will be removed in Rails 7.0.0. Please use `ActiveRecord::Base`.")
|
1181
|
-
owner_to_pool_manager[Base.name]
|
1182
|
-
end
|
1183
|
-
end
|
1184
|
-
|
1185
|
-
# Returns an instance of PoolConfig for a given adapter.
|
1186
|
-
# Accepts a hash one layer deep that contains all connection information.
|
1187
|
-
#
|
1188
|
-
# == Example
|
1189
|
-
#
|
1190
|
-
# config = { "production" => { "host" => "localhost", "database" => "foo", "adapter" => "sqlite3" } }
|
1191
|
-
# pool_config = Base.configurations.resolve_pool_config(:production)
|
1192
|
-
# pool_config.db_config.configuration_hash
|
1193
|
-
# # => { host: "localhost", database: "foo", adapter: "sqlite3" }
|
1194
|
-
#
|
1195
|
-
def resolve_pool_config(config, owner_name)
|
1196
|
-
db_config = Base.configurations.resolve(config)
|
1197
|
-
|
1198
|
-
raise(AdapterNotSpecified, "database configuration does not specify adapter") unless db_config.adapter
|
1199
|
-
|
1200
|
-
# Require the adapter itself and give useful feedback about
|
1201
|
-
# 1. Missing adapter gems and
|
1202
|
-
# 2. Adapter gems' missing dependencies.
|
1203
|
-
path_to_adapter = "active_record/connection_adapters/#{db_config.adapter}_adapter"
|
1204
|
-
begin
|
1205
|
-
require path_to_adapter
|
1206
|
-
rescue LoadError => e
|
1207
|
-
# We couldn't require the adapter itself. Raise an exception that
|
1208
|
-
# points out config typos and missing gems.
|
1209
|
-
if e.path == path_to_adapter
|
1210
|
-
# We can assume that a non-builtin adapter was specified, so it's
|
1211
|
-
# either misspelled or missing from Gemfile.
|
1212
|
-
raise LoadError, "Could not load the '#{db_config.adapter}' Active Record adapter. Ensure that the adapter is spelled correctly in config/database.yml and that you've added the necessary adapter gem to your Gemfile.", e.backtrace
|
1213
|
-
|
1214
|
-
# Bubbled up from the adapter require. Prefix the exception message
|
1215
|
-
# with some guidance about how to address it and reraise.
|
1216
|
-
else
|
1217
|
-
raise LoadError, "Error loading the '#{db_config.adapter}' Active Record adapter. Missing a gem it depends on? #{e.message}", e.backtrace
|
1218
|
-
end
|
1219
|
-
end
|
1220
|
-
|
1221
|
-
unless ActiveRecord::Base.respond_to?(db_config.adapter_method)
|
1222
|
-
raise AdapterNotFound, "database configuration specifies nonexistent #{db_config.adapter} adapter"
|
1223
|
-
end
|
1224
|
-
|
1225
|
-
ConnectionAdapters::PoolConfig.new(owner_name, db_config)
|
1226
|
-
end
|
1227
|
-
end
|
1228
714
|
end
|
1229
715
|
end
|
@@ -12,28 +12,11 @@ module ActiveRecord
|
|
12
12
|
max_identifier_length
|
13
13
|
end
|
14
14
|
|
15
|
-
# Returns the maximum allowed length for an index name. This
|
16
|
-
# limit is enforced by \Rails and is less than or equal to
|
17
|
-
# #index_name_length. The gap between
|
18
|
-
# #index_name_length is to allow internal \Rails
|
19
|
-
# operations to use prefixes in temporary operations.
|
20
|
-
def allowed_index_name_length
|
21
|
-
index_name_length
|
22
|
-
end
|
23
|
-
deprecate :allowed_index_name_length
|
24
|
-
|
25
15
|
# Returns the maximum length of an index name.
|
26
16
|
def index_name_length
|
27
17
|
max_identifier_length
|
28
18
|
end
|
29
19
|
|
30
|
-
# Returns the maximum number of elements in an IN (x,y,z) clause.
|
31
|
-
# +nil+ means no limit.
|
32
|
-
def in_clause_length
|
33
|
-
nil
|
34
|
-
end
|
35
|
-
deprecate :in_clause_length
|
36
|
-
|
37
20
|
private
|
38
21
|
def bind_params_length
|
39
22
|
65535
|