activerecord 6.0.0 → 6.1.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activerecord might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +872 -582
- data/MIT-LICENSE +1 -1
- data/README.rdoc +3 -3
- data/lib/active_record.rb +7 -13
- data/lib/active_record/aggregations.rb +1 -2
- data/lib/active_record/association_relation.rb +22 -12
- data/lib/active_record/associations.rb +116 -13
- data/lib/active_record/associations/alias_tracker.rb +19 -16
- data/lib/active_record/associations/association.rb +49 -29
- data/lib/active_record/associations/association_scope.rb +17 -15
- data/lib/active_record/associations/belongs_to_association.rb +15 -5
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +1 -1
- data/lib/active_record/associations/builder/association.rb +9 -3
- data/lib/active_record/associations/builder/belongs_to.rb +10 -7
- data/lib/active_record/associations/builder/collection_association.rb +5 -4
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +0 -3
- data/lib/active_record/associations/builder/has_many.rb +6 -2
- data/lib/active_record/associations/builder/has_one.rb +11 -14
- data/lib/active_record/associations/builder/singular_association.rb +1 -1
- data/lib/active_record/associations/collection_association.rb +25 -8
- data/lib/active_record/associations/collection_proxy.rb +14 -7
- data/lib/active_record/associations/foreign_association.rb +13 -0
- data/lib/active_record/associations/has_many_association.rb +24 -3
- data/lib/active_record/associations/has_many_through_association.rb +10 -4
- data/lib/active_record/associations/has_one_association.rb +15 -1
- data/lib/active_record/associations/join_dependency.rb +77 -42
- data/lib/active_record/associations/join_dependency/join_association.rb +36 -14
- data/lib/active_record/associations/join_dependency/join_part.rb +3 -3
- data/lib/active_record/associations/preloader.rb +13 -8
- data/lib/active_record/associations/preloader/association.rb +51 -25
- data/lib/active_record/associations/preloader/through_association.rb +2 -2
- data/lib/active_record/associations/singular_association.rb +1 -1
- data/lib/active_record/associations/through_association.rb +1 -1
- data/lib/active_record/attribute_assignment.rb +10 -9
- data/lib/active_record/attribute_methods.rb +64 -54
- data/lib/active_record/attribute_methods/before_type_cast.rb +13 -10
- data/lib/active_record/attribute_methods/dirty.rb +3 -13
- data/lib/active_record/attribute_methods/primary_key.rb +6 -4
- data/lib/active_record/attribute_methods/query.rb +3 -6
- data/lib/active_record/attribute_methods/read.rb +8 -12
- data/lib/active_record/attribute_methods/serialization.rb +11 -6
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +12 -15
- data/lib/active_record/attribute_methods/write.rb +12 -21
- data/lib/active_record/attributes.rb +32 -8
- data/lib/active_record/autosave_association.rb +63 -44
- data/lib/active_record/base.rb +2 -14
- data/lib/active_record/callbacks.rb +153 -24
- data/lib/active_record/coders/yaml_column.rb +1 -2
- data/lib/active_record/connection_adapters.rb +50 -0
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +202 -138
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +2 -44
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +86 -37
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +4 -9
- data/lib/active_record/connection_adapters/abstract/quoting.rb +34 -34
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +3 -3
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +152 -116
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +137 -52
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +3 -3
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +263 -107
- data/lib/active_record/connection_adapters/abstract/transaction.rb +82 -35
- data/lib/active_record/connection_adapters/abstract_adapter.rb +74 -76
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +149 -115
- data/lib/active_record/connection_adapters/column.rb +15 -1
- data/lib/active_record/connection_adapters/deduplicable.rb +29 -0
- data/lib/active_record/connection_adapters/legacy_pool_manager.rb +31 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +30 -36
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +1 -2
- data/lib/active_record/connection_adapters/mysql/quoting.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +32 -7
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +8 -0
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +1 -1
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +17 -13
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +10 -1
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +31 -13
- data/lib/active_record/connection_adapters/pool_config.rb +63 -0
- data/lib/active_record/connection_adapters/pool_manager.rb +43 -0
- data/lib/active_record/connection_adapters/postgresql/column.rb +24 -1
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +21 -56
- data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +3 -5
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +10 -2
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/oid/interval.rb +49 -0
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -3
- data/lib/active_record/connection_adapters/postgresql/oid/macaddr.rb +25 -0
- data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -3
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +24 -6
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +11 -2
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +4 -4
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +7 -3
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +72 -54
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +8 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +0 -1
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +81 -57
- data/lib/active_record/connection_adapters/schema_cache.rb +98 -15
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +10 -0
- data/lib/active_record/connection_adapters/sqlite3/database_statements.rb +38 -12
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +1 -2
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +5 -1
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +38 -5
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +61 -57
- data/lib/active_record/connection_adapters/statement_pool.rb +0 -1
- data/lib/active_record/connection_handling.rb +211 -81
- data/lib/active_record/core.rb +237 -69
- data/lib/active_record/counter_cache.rb +4 -1
- data/lib/active_record/database_configurations.rb +124 -85
- data/lib/active_record/database_configurations/connection_url_resolver.rb +98 -0
- data/lib/active_record/database_configurations/database_config.rb +52 -9
- data/lib/active_record/database_configurations/hash_config.rb +54 -8
- data/lib/active_record/database_configurations/url_config.rb +15 -41
- data/lib/active_record/delegated_type.rb +209 -0
- data/lib/active_record/destroy_association_async_job.rb +36 -0
- data/lib/active_record/dynamic_matchers.rb +2 -3
- data/lib/active_record/enum.rb +40 -16
- data/lib/active_record/errors.rb +47 -12
- data/lib/active_record/explain.rb +9 -5
- data/lib/active_record/explain_subscriber.rb +1 -1
- data/lib/active_record/fixture_set/file.rb +10 -17
- data/lib/active_record/fixture_set/model_metadata.rb +1 -2
- data/lib/active_record/fixture_set/render_context.rb +1 -1
- data/lib/active_record/fixture_set/table_row.rb +2 -3
- data/lib/active_record/fixture_set/table_rows.rb +0 -1
- data/lib/active_record/fixtures.rb +54 -11
- data/lib/active_record/gem_version.rb +1 -1
- data/lib/active_record/inheritance.rb +40 -21
- data/lib/active_record/insert_all.rb +39 -10
- data/lib/active_record/integration.rb +3 -5
- data/lib/active_record/internal_metadata.rb +16 -7
- data/lib/active_record/legacy_yaml_adapter.rb +7 -3
- data/lib/active_record/locking/optimistic.rb +22 -17
- data/lib/active_record/locking/pessimistic.rb +6 -2
- data/lib/active_record/log_subscriber.rb +27 -9
- data/lib/active_record/middleware/database_selector.rb +4 -2
- data/lib/active_record/middleware/database_selector/resolver.rb +14 -14
- data/lib/active_record/middleware/database_selector/resolver/session.rb +3 -0
- data/lib/active_record/migration.rb +114 -84
- data/lib/active_record/migration/command_recorder.rb +53 -45
- data/lib/active_record/migration/compatibility.rb +70 -20
- data/lib/active_record/migration/join_table.rb +0 -1
- data/lib/active_record/model_schema.rb +120 -15
- data/lib/active_record/nested_attributes.rb +2 -5
- data/lib/active_record/no_touching.rb +1 -1
- data/lib/active_record/null_relation.rb +0 -1
- data/lib/active_record/persistence.rb +50 -46
- data/lib/active_record/query_cache.rb +15 -5
- data/lib/active_record/querying.rb +12 -7
- data/lib/active_record/railtie.rb +65 -45
- data/lib/active_record/railties/databases.rake +267 -93
- data/lib/active_record/readonly_attributes.rb +4 -0
- data/lib/active_record/reflection.rb +77 -63
- data/lib/active_record/relation.rb +108 -67
- data/lib/active_record/relation/batches.rb +38 -32
- data/lib/active_record/relation/batches/batch_enumerator.rb +25 -9
- data/lib/active_record/relation/calculations.rb +102 -45
- data/lib/active_record/relation/delegation.rb +9 -7
- data/lib/active_record/relation/finder_methods.rb +55 -17
- data/lib/active_record/relation/from_clause.rb +5 -1
- data/lib/active_record/relation/merger.rb +27 -26
- data/lib/active_record/relation/predicate_builder.rb +55 -35
- data/lib/active_record/relation/predicate_builder/array_handler.rb +8 -9
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +4 -5
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +3 -3
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +1 -1
- data/lib/active_record/relation/query_methods.rb +340 -180
- data/lib/active_record/relation/record_fetch_warning.rb +3 -3
- data/lib/active_record/relation/spawn_methods.rb +8 -8
- data/lib/active_record/relation/where_clause.rb +104 -58
- data/lib/active_record/result.rb +41 -34
- data/lib/active_record/runtime_registry.rb +2 -2
- data/lib/active_record/sanitization.rb +6 -17
- data/lib/active_record/schema_dumper.rb +34 -4
- data/lib/active_record/schema_migration.rb +2 -8
- data/lib/active_record/scoping.rb +0 -1
- data/lib/active_record/scoping/default.rb +0 -1
- data/lib/active_record/scoping/named.rb +7 -18
- data/lib/active_record/secure_token.rb +16 -8
- data/lib/active_record/serialization.rb +5 -3
- data/lib/active_record/signed_id.rb +116 -0
- data/lib/active_record/statement_cache.rb +20 -4
- data/lib/active_record/store.rb +3 -3
- data/lib/active_record/suppressor.rb +2 -2
- data/lib/active_record/table_metadata.rb +39 -36
- data/lib/active_record/tasks/database_tasks.rb +139 -113
- data/lib/active_record/tasks/mysql_database_tasks.rb +34 -36
- data/lib/active_record/tasks/postgresql_database_tasks.rb +24 -27
- data/lib/active_record/tasks/sqlite_database_tasks.rb +13 -10
- data/lib/active_record/test_databases.rb +5 -4
- data/lib/active_record/test_fixtures.rb +38 -16
- data/lib/active_record/timestamp.rb +4 -7
- data/lib/active_record/touch_later.rb +20 -21
- data/lib/active_record/transactions.rb +22 -71
- data/lib/active_record/type.rb +8 -2
- data/lib/active_record/type/adapter_specific_registry.rb +2 -5
- data/lib/active_record/type/hash_lookup_type_map.rb +0 -1
- data/lib/active_record/type/serialized.rb +6 -3
- data/lib/active_record/type/time.rb +10 -0
- data/lib/active_record/type/type_map.rb +0 -1
- data/lib/active_record/type/unsigned_integer.rb +0 -1
- data/lib/active_record/type_caster/connection.rb +0 -1
- data/lib/active_record/type_caster/map.rb +8 -5
- data/lib/active_record/validations.rb +3 -3
- data/lib/active_record/validations/associated.rb +1 -2
- data/lib/active_record/validations/numericality.rb +35 -0
- data/lib/active_record/validations/uniqueness.rb +24 -4
- data/lib/arel.rb +15 -12
- data/lib/arel/attributes/attribute.rb +4 -0
- data/lib/arel/collectors/bind.rb +5 -0
- data/lib/arel/collectors/composite.rb +8 -0
- data/lib/arel/collectors/sql_string.rb +7 -0
- data/lib/arel/collectors/substitute_binds.rb +7 -0
- data/lib/arel/nodes.rb +3 -1
- data/lib/arel/nodes/binary.rb +82 -8
- data/lib/arel/nodes/bind_param.rb +8 -0
- data/lib/arel/nodes/casted.rb +21 -9
- data/lib/arel/nodes/equality.rb +6 -9
- data/lib/arel/nodes/grouping.rb +3 -0
- data/lib/arel/nodes/homogeneous_in.rb +72 -0
- data/lib/arel/nodes/in.rb +8 -1
- data/lib/arel/nodes/infix_operation.rb +13 -1
- data/lib/arel/nodes/join_source.rb +1 -1
- data/lib/arel/nodes/node.rb +7 -6
- data/lib/arel/nodes/ordering.rb +27 -0
- data/lib/arel/nodes/sql_literal.rb +3 -0
- data/lib/arel/nodes/table_alias.rb +7 -3
- data/lib/arel/nodes/unary.rb +0 -1
- data/lib/arel/predications.rb +17 -24
- data/lib/arel/select_manager.rb +1 -2
- data/lib/arel/table.rb +13 -5
- data/lib/arel/visitors.rb +0 -7
- data/lib/arel/visitors/dot.rb +14 -3
- data/lib/arel/visitors/mysql.rb +11 -1
- data/lib/arel/visitors/postgresql.rb +15 -5
- data/lib/arel/visitors/sqlite.rb +0 -1
- data/lib/arel/visitors/to_sql.rb +89 -79
- data/lib/arel/visitors/visitor.rb +0 -1
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +0 -1
- data/lib/rails/generators/active_record/migration.rb +6 -2
- data/lib/rails/generators/active_record/migration/migration_generator.rb +1 -0
- data/lib/rails/generators/active_record/migration/templates/create_table_migration.rb.tt +2 -0
- data/lib/rails/generators/active_record/migration/templates/migration.rb.tt +4 -4
- data/lib/rails/generators/active_record/model/model_generator.rb +38 -2
- data/lib/rails/generators/active_record/model/templates/abstract_base_class.rb.tt +7 -0
- metadata +27 -24
- data/lib/active_record/attribute_decorators.rb +0 -90
- data/lib/active_record/connection_adapters/connection_specification.rb +0 -297
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +0 -29
- data/lib/active_record/define_callbacks.rb +0 -22
- data/lib/active_record/railties/collection_cache_association_loading.rb +0 -34
- data/lib/active_record/relation/predicate_builder/base_handler.rb +0 -18
- data/lib/active_record/relation/where_clause_factory.rb +0 -33
- data/lib/arel/attributes.rb +0 -22
- data/lib/arel/visitors/depth_first.rb +0 -204
- data/lib/arel/visitors/ibm_db.rb +0 -34
- data/lib/arel/visitors/informix.rb +0 -62
- data/lib/arel/visitors/mssql.rb +0 -157
- data/lib/arel/visitors/oracle.rb +0 -159
- data/lib/arel/visitors/oracle12.rb +0 -66
- data/lib/arel/visitors/where_sql.rb +0 -23
@@ -5,10 +5,11 @@ module ActiveRecord
|
|
5
5
|
class TransactionState
|
6
6
|
def initialize(state = nil)
|
7
7
|
@state = state
|
8
|
-
@children =
|
8
|
+
@children = nil
|
9
9
|
end
|
10
10
|
|
11
11
|
def add_child(state)
|
12
|
+
@children ||= []
|
12
13
|
@children << state
|
13
14
|
end
|
14
15
|
|
@@ -41,12 +42,12 @@ module ActiveRecord
|
|
41
42
|
end
|
42
43
|
|
43
44
|
def rollback!
|
44
|
-
@children
|
45
|
+
@children&.each { |c| c.rollback! }
|
45
46
|
@state = :rolledback
|
46
47
|
end
|
47
48
|
|
48
49
|
def full_rollback!
|
49
|
-
@children
|
50
|
+
@children&.each { |c| c.rollback! }
|
50
51
|
@state = :fully_rolledback
|
51
52
|
end
|
52
53
|
|
@@ -69,24 +70,40 @@ module ActiveRecord
|
|
69
70
|
def closed?; true; end
|
70
71
|
def open?; false; end
|
71
72
|
def joinable?; false; end
|
72
|
-
def add_record(record); end
|
73
|
+
def add_record(record, _ = true); end
|
73
74
|
end
|
74
75
|
|
75
76
|
class Transaction #:nodoc:
|
76
|
-
attr_reader :connection, :state, :
|
77
|
+
attr_reader :connection, :state, :savepoint_name, :isolation_level
|
78
|
+
attr_accessor :written
|
77
79
|
|
78
|
-
def initialize(connection,
|
80
|
+
def initialize(connection, isolation: nil, joinable: true, run_commit_callbacks: false)
|
79
81
|
@connection = connection
|
80
82
|
@state = TransactionState.new
|
81
|
-
@records =
|
82
|
-
@isolation_level =
|
83
|
+
@records = nil
|
84
|
+
@isolation_level = isolation
|
83
85
|
@materialized = false
|
84
|
-
@joinable =
|
86
|
+
@joinable = joinable
|
85
87
|
@run_commit_callbacks = run_commit_callbacks
|
88
|
+
@lazy_enrollment_records = nil
|
86
89
|
end
|
87
90
|
|
88
|
-
def add_record(record)
|
89
|
-
records
|
91
|
+
def add_record(record, ensure_finalize = true)
|
92
|
+
@records ||= []
|
93
|
+
if ensure_finalize
|
94
|
+
@records << record
|
95
|
+
else
|
96
|
+
@lazy_enrollment_records ||= ObjectSpace::WeakMap.new
|
97
|
+
@lazy_enrollment_records[record] = record
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def records
|
102
|
+
if @lazy_enrollment_records
|
103
|
+
@records.concat @lazy_enrollment_records.values
|
104
|
+
@lazy_enrollment_records = nil
|
105
|
+
end
|
106
|
+
@records
|
90
107
|
end
|
91
108
|
|
92
109
|
def materialize!
|
@@ -98,7 +115,8 @@ module ActiveRecord
|
|
98
115
|
end
|
99
116
|
|
100
117
|
def rollback_records
|
101
|
-
|
118
|
+
return unless records
|
119
|
+
ite = records.uniq(&:__id__)
|
102
120
|
already_run_callbacks = {}
|
103
121
|
while record = ite.shift
|
104
122
|
trigger_callbacks = record.trigger_transactional_callbacks?
|
@@ -107,17 +125,18 @@ module ActiveRecord
|
|
107
125
|
record.rolledback!(force_restore_state: full_rollback?, should_run_callbacks: should_run_callbacks)
|
108
126
|
end
|
109
127
|
ensure
|
110
|
-
ite
|
128
|
+
ite&.each do |i|
|
111
129
|
i.rolledback!(force_restore_state: full_rollback?, should_run_callbacks: false)
|
112
130
|
end
|
113
131
|
end
|
114
132
|
|
115
133
|
def before_commit_records
|
116
|
-
records.uniq.each(&:before_committed!) if @run_commit_callbacks
|
134
|
+
records.uniq.each(&:before_committed!) if records && @run_commit_callbacks
|
117
135
|
end
|
118
136
|
|
119
137
|
def commit_records
|
120
|
-
|
138
|
+
return unless records
|
139
|
+
ite = records.uniq(&:__id__)
|
121
140
|
already_run_callbacks = {}
|
122
141
|
while record = ite.shift
|
123
142
|
if @run_commit_callbacks
|
@@ -131,7 +150,7 @@ module ActiveRecord
|
|
131
150
|
end
|
132
151
|
end
|
133
152
|
ensure
|
134
|
-
ite
|
153
|
+
ite&.each { |i| i.committed!(should_run_callbacks: false) }
|
135
154
|
end
|
136
155
|
|
137
156
|
def full_rollback?; true; end
|
@@ -141,8 +160,8 @@ module ActiveRecord
|
|
141
160
|
end
|
142
161
|
|
143
162
|
class SavepointTransaction < Transaction
|
144
|
-
def initialize(connection, savepoint_name, parent_transaction,
|
145
|
-
super(connection,
|
163
|
+
def initialize(connection, savepoint_name, parent_transaction, **options)
|
164
|
+
super(connection, **options)
|
146
165
|
|
147
166
|
parent_transaction.state.add_child(@state)
|
148
167
|
|
@@ -202,18 +221,29 @@ module ActiveRecord
|
|
202
221
|
@lazy_transactions_enabled = true
|
203
222
|
end
|
204
223
|
|
205
|
-
def begin_transaction(
|
224
|
+
def begin_transaction(isolation: nil, joinable: true, _lazy: true)
|
206
225
|
@connection.lock.synchronize do
|
207
226
|
run_commit_callbacks = !current_transaction.joinable?
|
208
227
|
transaction =
|
209
228
|
if @stack.empty?
|
210
|
-
RealTransaction.new(
|
229
|
+
RealTransaction.new(
|
230
|
+
@connection,
|
231
|
+
isolation: isolation,
|
232
|
+
joinable: joinable,
|
233
|
+
run_commit_callbacks: run_commit_callbacks
|
234
|
+
)
|
211
235
|
else
|
212
|
-
SavepointTransaction.new(
|
213
|
-
|
236
|
+
SavepointTransaction.new(
|
237
|
+
@connection,
|
238
|
+
"active_record_#{@stack.size}",
|
239
|
+
@stack.last,
|
240
|
+
isolation: isolation,
|
241
|
+
joinable: joinable,
|
242
|
+
run_commit_callbacks: run_commit_callbacks
|
243
|
+
)
|
214
244
|
end
|
215
245
|
|
216
|
-
if @connection.supports_lazy_transactions? && lazy_transactions_enabled? &&
|
246
|
+
if @connection.supports_lazy_transactions? && lazy_transactions_enabled? && _lazy
|
217
247
|
@has_unmaterialized_transactions = true
|
218
248
|
else
|
219
249
|
transaction.materialize!
|
@@ -274,10 +304,12 @@ module ActiveRecord
|
|
274
304
|
end
|
275
305
|
end
|
276
306
|
|
277
|
-
def within_new_transaction(
|
307
|
+
def within_new_transaction(isolation: nil, joinable: true)
|
278
308
|
@connection.lock.synchronize do
|
279
|
-
transaction = begin_transaction
|
280
|
-
yield
|
309
|
+
transaction = begin_transaction(isolation: isolation, joinable: joinable)
|
310
|
+
ret = yield
|
311
|
+
completed = true
|
312
|
+
ret
|
281
313
|
rescue Exception => error
|
282
314
|
if transaction
|
283
315
|
rollback_transaction
|
@@ -285,15 +317,31 @@ module ActiveRecord
|
|
285
317
|
end
|
286
318
|
raise
|
287
319
|
ensure
|
288
|
-
if
|
289
|
-
if
|
290
|
-
|
320
|
+
if transaction
|
321
|
+
if error
|
322
|
+
# @connection still holds an open transaction, so we must not
|
323
|
+
# put it back in the pool for reuse
|
324
|
+
@connection.throw_away! unless transaction.state.rolledback?
|
291
325
|
else
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
326
|
+
if Thread.current.status == "aborting"
|
327
|
+
rollback_transaction
|
328
|
+
else
|
329
|
+
if !completed && transaction.written
|
330
|
+
ActiveSupport::Deprecation.warn(<<~EOW)
|
331
|
+
Using `return`, `break` or `throw` to exit a transaction block is
|
332
|
+
deprecated without replacement. If the `throw` came from
|
333
|
+
`Timeout.timeout(duration)`, pass an exception class as a second
|
334
|
+
argument so it doesn't use `throw` to abort its block. This results
|
335
|
+
in the transaction being committed, but in the next release of Rails
|
336
|
+
it will rollback.
|
337
|
+
EOW
|
338
|
+
end
|
339
|
+
begin
|
340
|
+
commit_transaction
|
341
|
+
rescue Exception
|
342
|
+
rollback_transaction(transaction) unless transaction.state.completed?
|
343
|
+
raise
|
344
|
+
end
|
297
345
|
end
|
298
346
|
end
|
299
347
|
end
|
@@ -309,7 +357,6 @@ module ActiveRecord
|
|
309
357
|
end
|
310
358
|
|
311
359
|
private
|
312
|
-
|
313
360
|
NULL_TRANSACTION = NullTransaction.new
|
314
361
|
|
315
362
|
# Deallocate invalidated prepared statements outside of the transaction
|
@@ -1,58 +1,18 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "
|
3
|
+
require "set"
|
4
4
|
require "active_record/connection_adapters/schema_cache"
|
5
5
|
require "active_record/connection_adapters/sql_type_metadata"
|
6
6
|
require "active_record/connection_adapters/abstract/schema_dumper"
|
7
7
|
require "active_record/connection_adapters/abstract/schema_creation"
|
8
8
|
require "active_support/concurrency/load_interlock_aware_monitor"
|
9
|
-
require "active_support/deprecation"
|
10
9
|
require "arel/collectors/bind"
|
11
10
|
require "arel/collectors/composite"
|
12
11
|
require "arel/collectors/sql_string"
|
13
12
|
require "arel/collectors/substitute_binds"
|
14
|
-
require "concurrent/atomic/thread_local_var"
|
15
13
|
|
16
14
|
module ActiveRecord
|
17
15
|
module ConnectionAdapters # :nodoc:
|
18
|
-
extend ActiveSupport::Autoload
|
19
|
-
|
20
|
-
autoload :Column
|
21
|
-
autoload :ConnectionSpecification
|
22
|
-
|
23
|
-
autoload_at "active_record/connection_adapters/abstract/schema_definitions" do
|
24
|
-
autoload :IndexDefinition
|
25
|
-
autoload :ColumnDefinition
|
26
|
-
autoload :ChangeColumnDefinition
|
27
|
-
autoload :ForeignKeyDefinition
|
28
|
-
autoload :TableDefinition
|
29
|
-
autoload :Table
|
30
|
-
autoload :AlterTable
|
31
|
-
autoload :ReferenceDefinition
|
32
|
-
end
|
33
|
-
|
34
|
-
autoload_at "active_record/connection_adapters/abstract/connection_pool" do
|
35
|
-
autoload :ConnectionHandler
|
36
|
-
end
|
37
|
-
|
38
|
-
autoload_under "abstract" do
|
39
|
-
autoload :SchemaStatements
|
40
|
-
autoload :DatabaseStatements
|
41
|
-
autoload :DatabaseLimits
|
42
|
-
autoload :Quoting
|
43
|
-
autoload :ConnectionPool
|
44
|
-
autoload :QueryCache
|
45
|
-
autoload :Savepoints
|
46
|
-
end
|
47
|
-
|
48
|
-
autoload_at "active_record/connection_adapters/abstract/transaction" do
|
49
|
-
autoload :TransactionManager
|
50
|
-
autoload :NullTransaction
|
51
|
-
autoload :RealTransaction
|
52
|
-
autoload :SavepointTransaction
|
53
|
-
autoload :TransactionState
|
54
|
-
end
|
55
|
-
|
56
16
|
# Active Record supports multiple database systems. AbstractAdapter and
|
57
17
|
# related classes form the abstraction layer which makes this possible.
|
58
18
|
# An AbstractAdapter represents a connection to a database, and provides an
|
@@ -77,6 +37,7 @@ module ActiveRecord
|
|
77
37
|
include Savepoints
|
78
38
|
|
79
39
|
SIMPLE_INT = /\A\d+\z/
|
40
|
+
COMMENT_REGEX = %r{(?:\-\-.*\n)*|/\*(?:[^\*]|\*[^/])*\*/}m
|
80
41
|
|
81
42
|
attr_accessor :pool
|
82
43
|
attr_reader :visitor, :owner, :logger, :lock
|
@@ -102,9 +63,13 @@ module ActiveRecord
|
|
102
63
|
end
|
103
64
|
end
|
104
65
|
|
66
|
+
DEFAULT_READ_QUERY = [:begin, :commit, :explain, :release, :rollback, :savepoint, :select, :with] # :nodoc:
|
67
|
+
private_constant :DEFAULT_READ_QUERY
|
68
|
+
|
105
69
|
def self.build_read_query_regexp(*parts) # :nodoc:
|
106
|
-
parts
|
107
|
-
|
70
|
+
parts += DEFAULT_READ_QUERY
|
71
|
+
parts = parts.map { |part| /#{part}/i }
|
72
|
+
/\A(?:[\(\s]|#{COMMENT_REGEX})*#{Regexp.union(*parts)}/
|
108
73
|
end
|
109
74
|
|
110
75
|
def self.quoted_column_names # :nodoc:
|
@@ -129,12 +94,9 @@ module ActiveRecord
|
|
129
94
|
@statements = build_statement_pool
|
130
95
|
@lock = ActiveSupport::Concurrency::LoadInterlockAwareMonitor.new
|
131
96
|
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
else
|
136
|
-
@prepared_statement_status = Concurrent::ThreadLocalVar.new(false)
|
137
|
-
end
|
97
|
+
@prepared_statements = self.class.type_cast_config_to_boolean(
|
98
|
+
config.fetch(:prepared_statements, true)
|
99
|
+
)
|
138
100
|
|
139
101
|
@advisory_locks_enabled = self.class.type_cast_config_to_boolean(
|
140
102
|
config.fetch(:advisory_locks, true)
|
@@ -145,12 +107,26 @@ module ActiveRecord
|
|
145
107
|
@config[:replica] || false
|
146
108
|
end
|
147
109
|
|
110
|
+
def use_metadata_table?
|
111
|
+
@config.fetch(:use_metadata_table, true)
|
112
|
+
end
|
113
|
+
|
148
114
|
# Determines whether writes are currently being prevents.
|
149
115
|
#
|
150
|
-
# Returns true if the connection is a replica
|
151
|
-
#
|
116
|
+
# Returns true if the connection is a replica.
|
117
|
+
#
|
118
|
+
# If the application is using legacy handling, returns
|
119
|
+
# true if `connection_handler.prevent_writes` is set.
|
120
|
+
#
|
121
|
+
# If the application is using the new connection handling
|
122
|
+
# will return true based on `current_preventing_writes`.
|
152
123
|
def preventing_writes?
|
153
|
-
replica?
|
124
|
+
return true if replica?
|
125
|
+
return ActiveRecord::Base.connection_handler.prevent_writes if ActiveRecord::Base.legacy_connection_handling
|
126
|
+
return false if owner_name.nil?
|
127
|
+
|
128
|
+
klass = self.owner_name.safe_constantize
|
129
|
+
klass&.current_preventing_writes
|
154
130
|
end
|
155
131
|
|
156
132
|
def migrations_paths # :nodoc:
|
@@ -164,12 +140,15 @@ module ActiveRecord
|
|
164
140
|
def schema_migration # :nodoc:
|
165
141
|
@schema_migration ||= begin
|
166
142
|
conn = self
|
167
|
-
spec_name = conn.pool.
|
168
|
-
|
143
|
+
spec_name = conn.pool.pool_config.connection_specification_name
|
144
|
+
|
145
|
+
return ActiveRecord::SchemaMigration if spec_name == "ActiveRecord::Base"
|
146
|
+
|
147
|
+
schema_migration_name = "#{spec_name}::SchemaMigration"
|
169
148
|
|
170
149
|
Class.new(ActiveRecord::SchemaMigration) do
|
171
|
-
define_singleton_method(:name) {
|
172
|
-
define_singleton_method(:to_s) {
|
150
|
+
define_singleton_method(:name) { schema_migration_name }
|
151
|
+
define_singleton_method(:to_s) { schema_migration_name }
|
173
152
|
|
174
153
|
self.connection_specification_name = spec_name
|
175
154
|
end
|
@@ -177,7 +156,11 @@ module ActiveRecord
|
|
177
156
|
end
|
178
157
|
|
179
158
|
def prepared_statements
|
180
|
-
@
|
159
|
+
@prepared_statements && !prepared_statements_disabled_cache.include?(object_id)
|
160
|
+
end
|
161
|
+
|
162
|
+
def prepared_statements_disabled_cache # :nodoc:
|
163
|
+
Thread.current[:ar_prepared_statements_disabled_cache] ||= Set.new
|
181
164
|
end
|
182
165
|
|
183
166
|
class Version
|
@@ -219,6 +202,10 @@ module ActiveRecord
|
|
219
202
|
@owner = Thread.current
|
220
203
|
end
|
221
204
|
|
205
|
+
def owner_name # :nodoc:
|
206
|
+
@pool.owner_name
|
207
|
+
end
|
208
|
+
|
222
209
|
def schema_cache
|
223
210
|
@pool.get_schema_cache(self)
|
224
211
|
end
|
@@ -264,7 +251,10 @@ module ActiveRecord
|
|
264
251
|
end
|
265
252
|
|
266
253
|
def unprepared_statement
|
267
|
-
|
254
|
+
cache = prepared_statements_disabled_cache.add(object_id) if @prepared_statements
|
255
|
+
yield
|
256
|
+
ensure
|
257
|
+
cache&.delete(object_id)
|
268
258
|
end
|
269
259
|
|
270
260
|
# Returns the human-readable name of the adapter. Use mixed case - one
|
@@ -305,6 +295,10 @@ module ActiveRecord
|
|
305
295
|
false
|
306
296
|
end
|
307
297
|
|
298
|
+
def supports_partitioned_indexes?
|
299
|
+
false
|
300
|
+
end
|
301
|
+
|
308
302
|
# Does this adapter support index sort order?
|
309
303
|
def supports_index_sort_order?
|
310
304
|
false
|
@@ -351,12 +345,10 @@ module ActiveRecord
|
|
351
345
|
false
|
352
346
|
end
|
353
347
|
|
354
|
-
# Does this adapter support creating
|
355
|
-
|
356
|
-
|
357
|
-
supports_foreign_keys?
|
348
|
+
# Does this adapter support creating check constraints?
|
349
|
+
def supports_check_constraints?
|
350
|
+
false
|
358
351
|
end
|
359
|
-
deprecate :supports_foreign_keys_in_create?
|
360
352
|
|
361
353
|
# Does this adapter support views?
|
362
354
|
def supports_views?
|
@@ -388,12 +380,6 @@ module ActiveRecord
|
|
388
380
|
false
|
389
381
|
end
|
390
382
|
|
391
|
-
# Does this adapter support multi-value insert?
|
392
|
-
def supports_multi_insert?
|
393
|
-
true
|
394
|
-
end
|
395
|
-
deprecate :supports_multi_insert?
|
396
|
-
|
397
383
|
# Does this adapter support virtual columns?
|
398
384
|
def supports_virtual_columns?
|
399
385
|
false
|
@@ -409,6 +395,10 @@ module ActiveRecord
|
|
409
395
|
false
|
410
396
|
end
|
411
397
|
|
398
|
+
def supports_common_table_expressions?
|
399
|
+
false
|
400
|
+
end
|
401
|
+
|
412
402
|
def supports_lazy_transactions?
|
413
403
|
false
|
414
404
|
end
|
@@ -521,6 +511,12 @@ module ActiveRecord
|
|
521
511
|
# this should be overridden by concrete adapters
|
522
512
|
end
|
523
513
|
|
514
|
+
# Removes the connection from the pool and disconnect it.
|
515
|
+
def throw_away!
|
516
|
+
pool.remove self
|
517
|
+
disconnect!
|
518
|
+
end
|
519
|
+
|
524
520
|
# Clear any caching the database adapter may be doing.
|
525
521
|
def clear_cache!
|
526
522
|
@lock.synchronize { @statements.clear } if @statements
|
@@ -549,7 +545,7 @@ module ActiveRecord
|
|
549
545
|
@connection
|
550
546
|
end
|
551
547
|
|
552
|
-
def default_uniqueness_comparison(attribute, value
|
548
|
+
def default_uniqueness_comparison(attribute, value) # :nodoc:
|
553
549
|
attribute.eq(value)
|
554
550
|
end
|
555
551
|
|
@@ -577,10 +573,6 @@ module ActiveRecord
|
|
577
573
|
pool.checkin self
|
578
574
|
end
|
579
575
|
|
580
|
-
def column_name_for_operation(operation, node) # :nodoc:
|
581
|
-
visitor.compile(node)
|
582
|
-
end
|
583
|
-
|
584
576
|
def default_index_type?(index) # :nodoc:
|
585
577
|
index.using.nil?
|
586
578
|
end
|
@@ -609,7 +601,6 @@ module ActiveRecord
|
|
609
601
|
end
|
610
602
|
|
611
603
|
private
|
612
|
-
|
613
604
|
def type_map
|
614
605
|
@type_map ||= Type::TypeMap.new.tap do |mapping|
|
615
606
|
initialize_type_map(mapping)
|
@@ -701,7 +692,6 @@ module ActiveRecord
|
|
701
692
|
binds: binds,
|
702
693
|
type_casted_binds: type_casted_binds,
|
703
694
|
statement_name: statement_name,
|
704
|
-
connection_id: object_id,
|
705
695
|
connection: self) do
|
706
696
|
@lock.synchronize do
|
707
697
|
yield
|
@@ -756,6 +746,14 @@ module ActiveRecord
|
|
756
746
|
|
757
747
|
def build_statement_pool
|
758
748
|
end
|
749
|
+
|
750
|
+
# Builds the result object.
|
751
|
+
#
|
752
|
+
# This is an internal hook to make possible connection adapters to build
|
753
|
+
# custom result objects with connection-specific data.
|
754
|
+
def build_result(columns:, rows:, column_types: {})
|
755
|
+
ActiveRecord::Result.new(columns, rows, column_types)
|
756
|
+
end
|
759
757
|
end
|
760
758
|
end
|
761
759
|
end
|