activerecord 6.1.7.6 → 7.0.8
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 +1570 -1016
- 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 +55 -11
@@ -36,7 +36,7 @@ module ActiveRecord
|
|
36
36
|
include Savepoints
|
37
37
|
|
38
38
|
SIMPLE_INT = /\A\d+\z/
|
39
|
-
COMMENT_REGEX = %r{(
|
39
|
+
COMMENT_REGEX = %r{(?:--.*\n)|/\*(?:[^*]|\*[^/])*\*/}m
|
40
40
|
|
41
41
|
attr_accessor :pool
|
42
42
|
attr_reader :visitor, :owner, :logger, :lock
|
@@ -68,15 +68,7 @@ module ActiveRecord
|
|
68
68
|
def self.build_read_query_regexp(*parts) # :nodoc:
|
69
69
|
parts += DEFAULT_READ_QUERY
|
70
70
|
parts = parts.map { |part| /#{part}/i }
|
71
|
-
/\A(?:[
|
72
|
-
end
|
73
|
-
|
74
|
-
def self.quoted_column_names # :nodoc:
|
75
|
-
@quoted_column_names ||= {}
|
76
|
-
end
|
77
|
-
|
78
|
-
def self.quoted_table_names # :nodoc:
|
79
|
-
@quoted_table_names ||= {}
|
71
|
+
/\A(?:[(\s]|#{COMMENT_REGEX})*#{Regexp.union(*parts)}/
|
80
72
|
end
|
81
73
|
|
82
74
|
def initialize(connection, logger = nil, config = {}) # :nodoc:
|
@@ -88,7 +80,7 @@ module ActiveRecord
|
|
88
80
|
@logger = logger
|
89
81
|
@config = config
|
90
82
|
@pool = ActiveRecord::ConnectionAdapters::NullPool.new
|
91
|
-
@idle_since =
|
83
|
+
@idle_since = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
92
84
|
@visitor = arel_visitor
|
93
85
|
@statements = build_statement_pool
|
94
86
|
@lock = ActiveSupport::Concurrency::LoadInterlockAwareMonitor.new
|
@@ -102,6 +94,25 @@ module ActiveRecord
|
|
102
94
|
)
|
103
95
|
end
|
104
96
|
|
97
|
+
EXCEPTION_NEVER = { Exception => :never }.freeze # :nodoc:
|
98
|
+
EXCEPTION_IMMEDIATE = { Exception => :immediate }.freeze # :nodoc:
|
99
|
+
private_constant :EXCEPTION_NEVER, :EXCEPTION_IMMEDIATE
|
100
|
+
def with_instrumenter(instrumenter, &block) # :nodoc:
|
101
|
+
Thread.handle_interrupt(EXCEPTION_NEVER) do
|
102
|
+
previous_instrumenter = @instrumenter
|
103
|
+
@instrumenter = instrumenter
|
104
|
+
Thread.handle_interrupt(EXCEPTION_IMMEDIATE, &block)
|
105
|
+
ensure
|
106
|
+
@instrumenter = previous_instrumenter
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def check_if_write_query(sql) # :nodoc:
|
111
|
+
if preventing_writes? && write_query?(sql)
|
112
|
+
raise ActiveRecord::ReadOnlyError, "Write query attempted while in readonly mode: #{sql}"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
105
116
|
def replica?
|
106
117
|
@config[:replica] || false
|
107
118
|
end
|
@@ -121,10 +132,10 @@ module ActiveRecord
|
|
121
132
|
# will return true based on +current_preventing_writes+.
|
122
133
|
def preventing_writes?
|
123
134
|
return true if replica?
|
124
|
-
return ActiveRecord::Base.connection_handler.prevent_writes if ActiveRecord
|
125
|
-
return false if
|
135
|
+
return ActiveRecord::Base.connection_handler.prevent_writes if ActiveRecord.legacy_connection_handling
|
136
|
+
return false if connection_class.nil?
|
126
137
|
|
127
|
-
|
138
|
+
connection_class.current_preventing_writes
|
128
139
|
end
|
129
140
|
|
130
141
|
def migrations_paths # :nodoc:
|
@@ -159,7 +170,7 @@ module ActiveRecord
|
|
159
170
|
alias :prepared_statements :prepared_statements?
|
160
171
|
|
161
172
|
def prepared_statements_disabled_cache # :nodoc:
|
162
|
-
|
173
|
+
ActiveSupport::IsolatedExecutionState[:active_record_prepared_statements_disabled_cache] ||= Set.new
|
163
174
|
end
|
164
175
|
|
165
176
|
class Version
|
@@ -201,8 +212,20 @@ module ActiveRecord
|
|
201
212
|
@owner = Thread.current
|
202
213
|
end
|
203
214
|
|
204
|
-
def
|
205
|
-
@pool.
|
215
|
+
def connection_class # :nodoc:
|
216
|
+
@pool.connection_class
|
217
|
+
end
|
218
|
+
|
219
|
+
# The role (e.g. +:writing+) for the current connection. In a
|
220
|
+
# non-multi role application, +:writing+ is returned.
|
221
|
+
def role
|
222
|
+
@pool.role
|
223
|
+
end
|
224
|
+
|
225
|
+
# The shard (e.g. +:default+) for the current connection. In
|
226
|
+
# a non-sharded application, +:default+ is returned.
|
227
|
+
def shard
|
228
|
+
@pool.shard
|
206
229
|
end
|
207
230
|
|
208
231
|
def schema_cache
|
@@ -223,7 +246,7 @@ module ActiveRecord
|
|
223
246
|
"Current thread: #{Thread.current}."
|
224
247
|
end
|
225
248
|
|
226
|
-
@idle_since =
|
249
|
+
@idle_since = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
227
250
|
@owner = nil
|
228
251
|
else
|
229
252
|
raise ActiveRecordError, "Cannot expire connection, it is not currently leased."
|
@@ -246,7 +269,7 @@ module ActiveRecord
|
|
246
269
|
# Seconds since this connection was returned to the pool
|
247
270
|
def seconds_idle # :nodoc:
|
248
271
|
return 0 if in_use?
|
249
|
-
|
272
|
+
Process.clock_gettime(Process::CLOCK_MONOTONIC) - @idle_since
|
250
273
|
end
|
251
274
|
|
252
275
|
def unprepared_statement
|
@@ -344,6 +367,11 @@ module ActiveRecord
|
|
344
367
|
false
|
345
368
|
end
|
346
369
|
|
370
|
+
# Does this adapter support creating deferrable constraints?
|
371
|
+
def supports_deferrable_constraints?
|
372
|
+
false
|
373
|
+
end
|
374
|
+
|
347
375
|
# Does this adapter support creating check constraints?
|
348
376
|
def supports_check_constraints?
|
349
377
|
false
|
@@ -418,6 +446,15 @@ module ActiveRecord
|
|
418
446
|
false
|
419
447
|
end
|
420
448
|
|
449
|
+
def supports_concurrent_connections?
|
450
|
+
true
|
451
|
+
end
|
452
|
+
|
453
|
+
def async_enabled? # :nodoc:
|
454
|
+
supports_concurrent_connections? &&
|
455
|
+
!ActiveRecord.async_query_executor.nil? && !pool.async_executor.nil?
|
456
|
+
end
|
457
|
+
|
421
458
|
# This is meant to be implemented by the adapters that support extensions
|
422
459
|
def disable_extension(name)
|
423
460
|
end
|
@@ -426,6 +463,10 @@ module ActiveRecord
|
|
426
463
|
def enable_extension(name)
|
427
464
|
end
|
428
465
|
|
466
|
+
# This is meant to be implemented by the adapters that support custom enum types
|
467
|
+
def create_enum(*) # :nodoc:
|
468
|
+
end
|
469
|
+
|
429
470
|
def advisory_locks_enabled? # :nodoc:
|
430
471
|
supports_advisory_locks? && @advisory_locks_enabled
|
431
472
|
end
|
@@ -461,6 +502,11 @@ module ActiveRecord
|
|
461
502
|
yield
|
462
503
|
end
|
463
504
|
|
505
|
+
# Override to check all foreign key constraints in a database.
|
506
|
+
def all_foreign_keys_valid?
|
507
|
+
true
|
508
|
+
end
|
509
|
+
|
464
510
|
# CONNECTION MANAGEMENT ====================================
|
465
511
|
|
466
512
|
# Checks whether the connection to the database is still active. This includes
|
@@ -539,6 +585,10 @@ module ActiveRecord
|
|
539
585
|
#
|
540
586
|
# This is useful for when you need to call a proprietary method such as
|
541
587
|
# PostgreSQL's lo_* methods.
|
588
|
+
#
|
589
|
+
# Active Record cannot track if the database is getting modified using
|
590
|
+
# this client. If that is the case, generally you'll want to invalidate
|
591
|
+
# the query cache using +ActiveRecord::Base.clear_query_cache+.
|
542
592
|
def raw_connection
|
543
593
|
disable_lazy_transactions!
|
544
594
|
@connection
|
@@ -599,78 +649,84 @@ module ActiveRecord
|
|
599
649
|
def check_version # :nodoc:
|
600
650
|
end
|
601
651
|
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
652
|
+
# Returns the version identifier of the schema currently available in
|
653
|
+
# the database. This is generally equal to the number of the highest-
|
654
|
+
# numbered migration that has been executed, or 0 if no schema
|
655
|
+
# information is present / the database is empty.
|
656
|
+
def schema_version
|
657
|
+
migration_context.current_version
|
658
|
+
end
|
659
|
+
|
660
|
+
class << self
|
661
|
+
private
|
662
|
+
def initialize_type_map(m)
|
663
|
+
register_class_with_limit m, %r(boolean)i, Type::Boolean
|
664
|
+
register_class_with_limit m, %r(char)i, Type::String
|
665
|
+
register_class_with_limit m, %r(binary)i, Type::Binary
|
666
|
+
register_class_with_limit m, %r(text)i, Type::Text
|
667
|
+
register_class_with_precision m, %r(date)i, Type::Date
|
668
|
+
register_class_with_precision m, %r(time)i, Type::Time
|
669
|
+
register_class_with_precision m, %r(datetime)i, Type::DateTime
|
670
|
+
register_class_with_limit m, %r(float)i, Type::Float
|
671
|
+
register_class_with_limit m, %r(int)i, Type::Integer
|
672
|
+
|
673
|
+
m.alias_type %r(blob)i, "binary"
|
674
|
+
m.alias_type %r(clob)i, "text"
|
675
|
+
m.alias_type %r(timestamp)i, "datetime"
|
676
|
+
m.alias_type %r(numeric)i, "decimal"
|
677
|
+
m.alias_type %r(number)i, "decimal"
|
678
|
+
m.alias_type %r(double)i, "float"
|
679
|
+
|
680
|
+
m.register_type %r(^json)i, Type::Json.new
|
681
|
+
|
682
|
+
m.register_type(%r(decimal)i) do |sql_type|
|
683
|
+
scale = extract_scale(sql_type)
|
684
|
+
precision = extract_precision(sql_type)
|
685
|
+
|
686
|
+
if scale == 0
|
687
|
+
# FIXME: Remove this class as well
|
688
|
+
Type::DecimalWithoutScale.new(precision: precision)
|
689
|
+
else
|
690
|
+
Type::Decimal.new(precision: precision, scale: scale)
|
691
|
+
end
|
692
|
+
end
|
606
693
|
end
|
607
|
-
end
|
608
694
|
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
register_class_with_limit m, %r(text)i, Type::Text
|
614
|
-
register_class_with_precision m, %r(date)i, Type::Date
|
615
|
-
register_class_with_precision m, %r(time)i, Type::Time
|
616
|
-
register_class_with_precision m, %r(datetime)i, Type::DateTime
|
617
|
-
register_class_with_limit m, %r(float)i, Type::Float
|
618
|
-
register_class_with_limit m, %r(int)i, Type::Integer
|
619
|
-
|
620
|
-
m.alias_type %r(blob)i, "binary"
|
621
|
-
m.alias_type %r(clob)i, "text"
|
622
|
-
m.alias_type %r(timestamp)i, "datetime"
|
623
|
-
m.alias_type %r(numeric)i, "decimal"
|
624
|
-
m.alias_type %r(number)i, "decimal"
|
625
|
-
m.alias_type %r(double)i, "float"
|
626
|
-
|
627
|
-
m.register_type %r(^json)i, Type::Json.new
|
628
|
-
|
629
|
-
m.register_type(%r(decimal)i) do |sql_type|
|
630
|
-
scale = extract_scale(sql_type)
|
631
|
-
precision = extract_precision(sql_type)
|
632
|
-
|
633
|
-
if scale == 0
|
634
|
-
# FIXME: Remove this class as well
|
635
|
-
Type::DecimalWithoutScale.new(precision: precision)
|
636
|
-
else
|
637
|
-
Type::Decimal.new(precision: precision, scale: scale)
|
695
|
+
def register_class_with_limit(mapping, key, klass)
|
696
|
+
mapping.register_type(key) do |*args|
|
697
|
+
limit = extract_limit(args.last)
|
698
|
+
klass.new(limit: limit)
|
638
699
|
end
|
639
700
|
end
|
640
|
-
end
|
641
701
|
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
702
|
+
def register_class_with_precision(mapping, key, klass)
|
703
|
+
mapping.register_type(key) do |*args|
|
704
|
+
precision = extract_precision(args.last)
|
705
|
+
klass.new(precision: precision)
|
706
|
+
end
|
707
|
+
end
|
646
708
|
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
709
|
+
def extract_scale(sql_type)
|
710
|
+
case sql_type
|
711
|
+
when /\((\d+)\)/ then 0
|
712
|
+
when /\((\d+)(,(\d+))\)/ then $3.to_i
|
713
|
+
end
|
651
714
|
end
|
652
|
-
end
|
653
715
|
|
654
|
-
|
655
|
-
|
656
|
-
precision = extract_precision(args.last)
|
657
|
-
klass.new(precision: precision)
|
716
|
+
def extract_precision(sql_type)
|
717
|
+
$1.to_i if sql_type =~ /\((\d+)(,\d+)?\)/
|
658
718
|
end
|
659
|
-
end
|
660
719
|
|
661
|
-
|
662
|
-
|
663
|
-
when /\((\d+)\)/ then 0
|
664
|
-
when /\((\d+)(,(\d+))\)/ then $3.to_i
|
720
|
+
def extract_limit(sql_type)
|
721
|
+
$1.to_i if sql_type =~ /\((.*)\)/
|
665
722
|
end
|
666
|
-
|
723
|
+
end
|
667
724
|
|
668
|
-
|
669
|
-
$1.to_i if sql_type =~ /\((\d+)(,\d+)?\)/
|
670
|
-
end
|
725
|
+
TYPE_MAP = Type::TypeMap.new.tap { |m| initialize_type_map(m) }
|
671
726
|
|
672
|
-
|
673
|
-
|
727
|
+
private
|
728
|
+
def type_map
|
729
|
+
TYPE_MAP
|
674
730
|
end
|
675
731
|
|
676
732
|
def translate_exception_class(e, sql, binds)
|
@@ -683,7 +739,7 @@ module ActiveRecord
|
|
683
739
|
exception
|
684
740
|
end
|
685
741
|
|
686
|
-
def log(sql, name = "SQL", binds = [], type_casted_binds = [], statement_name = nil) # :doc:
|
742
|
+
def log(sql, name = "SQL", binds = [], type_casted_binds = [], statement_name = nil, async: false, &block) # :doc:
|
687
743
|
@instrumenter.instrument(
|
688
744
|
"sql.active_record",
|
689
745
|
sql: sql,
|
@@ -691,15 +747,21 @@ module ActiveRecord
|
|
691
747
|
binds: binds,
|
692
748
|
type_casted_binds: type_casted_binds,
|
693
749
|
statement_name: statement_name,
|
750
|
+
async: async,
|
694
751
|
connection: self) do
|
695
|
-
@lock.synchronize
|
696
|
-
yield
|
697
|
-
end
|
752
|
+
@lock.synchronize(&block)
|
698
753
|
rescue => e
|
699
754
|
raise translate_exception_class(e, sql, binds)
|
700
755
|
end
|
701
756
|
end
|
702
757
|
|
758
|
+
def transform_query(sql)
|
759
|
+
ActiveRecord.query_transformers.each do |transformer|
|
760
|
+
sql = transformer.call(sql)
|
761
|
+
end
|
762
|
+
sql
|
763
|
+
end
|
764
|
+
|
703
765
|
def translate_exception(exception, message:, sql:, binds:)
|
704
766
|
# override in derived class
|
705
767
|
case exception
|