activerecord 5.1.0 → 5.2.3
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 +5 -5
- data/CHANGELOG.md +596 -450
- data/MIT-LICENSE +1 -1
- data/README.rdoc +5 -5
- data/examples/performance.rb +2 -0
- data/examples/simple.rb +2 -0
- data/lib/active_record.rb +11 -4
- data/lib/active_record/aggregations.rb +6 -5
- data/lib/active_record/association_relation.rb +7 -5
- data/lib/active_record/associations.rb +77 -85
- data/lib/active_record/associations/alias_tracker.rb +23 -32
- data/lib/active_record/associations/association.rb +49 -35
- data/lib/active_record/associations/association_scope.rb +55 -55
- data/lib/active_record/associations/belongs_to_association.rb +30 -11
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +8 -8
- data/lib/active_record/associations/builder/association.rb +4 -7
- data/lib/active_record/associations/builder/belongs_to.rb +21 -8
- data/lib/active_record/associations/builder/collection_association.rb +1 -1
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +3 -1
- data/lib/active_record/associations/builder/has_many.rb +2 -0
- data/lib/active_record/associations/builder/has_one.rb +2 -0
- data/lib/active_record/associations/builder/singular_association.rb +2 -0
- data/lib/active_record/associations/collection_association.rb +66 -53
- data/lib/active_record/associations/collection_proxy.rb +30 -73
- data/lib/active_record/associations/foreign_association.rb +2 -0
- data/lib/active_record/associations/has_many_association.rb +13 -2
- data/lib/active_record/associations/has_many_through_association.rb +37 -19
- data/lib/active_record/associations/has_one_association.rb +14 -1
- data/lib/active_record/associations/has_one_through_association.rb +13 -8
- data/lib/active_record/associations/join_dependency.rb +52 -96
- data/lib/active_record/associations/join_dependency/join_association.rb +22 -75
- data/lib/active_record/associations/join_dependency/join_base.rb +9 -8
- data/lib/active_record/associations/join_dependency/join_part.rb +9 -9
- data/lib/active_record/associations/preloader.rb +17 -37
- data/lib/active_record/associations/preloader/association.rb +53 -92
- data/lib/active_record/associations/preloader/through_association.rb +72 -73
- data/lib/active_record/associations/singular_association.rb +14 -16
- data/lib/active_record/associations/through_association.rb +27 -12
- data/lib/active_record/attribute_assignment.rb +2 -5
- data/lib/active_record/attribute_decorators.rb +3 -2
- data/lib/active_record/attribute_methods.rb +65 -24
- data/lib/active_record/attribute_methods/before_type_cast.rb +2 -0
- data/lib/active_record/attribute_methods/dirty.rb +33 -216
- data/lib/active_record/attribute_methods/primary_key.rb +10 -13
- data/lib/active_record/attribute_methods/query.rb +2 -0
- data/lib/active_record/attribute_methods/read.rb +9 -3
- data/lib/active_record/attribute_methods/serialization.rb +23 -0
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +6 -8
- data/lib/active_record/attribute_methods/write.rb +22 -19
- data/lib/active_record/attributes.rb +7 -6
- data/lib/active_record/autosave_association.rb +15 -13
- data/lib/active_record/base.rb +2 -0
- data/lib/active_record/callbacks.rb +12 -6
- data/lib/active_record/coders/json.rb +2 -0
- data/lib/active_record/coders/yaml_column.rb +2 -0
- data/lib/active_record/collection_cache_key.rb +15 -11
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +120 -39
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +7 -0
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +192 -37
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +13 -2
- data/lib/active_record/connection_adapters/abstract/quoting.rb +15 -25
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +15 -6
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +65 -7
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +31 -53
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +158 -87
- data/lib/active_record/connection_adapters/abstract/transaction.rb +66 -21
- data/lib/active_record/connection_adapters/abstract_adapter.rb +86 -98
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +126 -189
- data/lib/active_record/connection_adapters/column.rb +4 -2
- data/lib/active_record/connection_adapters/connection_specification.rb +17 -3
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +13 -2
- data/lib/active_record/connection_adapters/mysql/column.rb +2 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +45 -15
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +2 -0
- data/lib/active_record/connection_adapters/mysql/quoting.rb +9 -10
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +5 -3
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +7 -10
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +30 -23
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +106 -1
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +2 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +8 -2
- data/lib/active_record/connection_adapters/postgresql/column.rb +30 -1
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +6 -32
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +13 -1
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bit_varying.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/bytea.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date.rb +23 -0
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/inet.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +3 -11
- data/lib/active_record/connection_adapters/postgresql/oid/legacy_point.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +8 -2
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +4 -2
- data/lib/active_record/connection_adapters/postgresql/oid/uuid.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/oid/vector.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid/xml.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +22 -1
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +19 -25
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +50 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +24 -11
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +20 -13
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +258 -129
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +75 -87
- data/lib/active_record/connection_adapters/schema_cache.rb +4 -2
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +2 -0
- data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +2 -0
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +24 -1
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +2 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +6 -15
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +3 -2
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +75 -1
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +90 -96
- data/lib/active_record/connection_adapters/statement_pool.rb +2 -0
- data/lib/active_record/connection_handling.rb +4 -2
- data/lib/active_record/core.rb +41 -61
- data/lib/active_record/counter_cache.rb +20 -15
- data/lib/active_record/define_callbacks.rb +5 -3
- data/lib/active_record/dynamic_matchers.rb +9 -9
- data/lib/active_record/enum.rb +18 -13
- data/lib/active_record/errors.rb +60 -15
- data/lib/active_record/explain.rb +3 -1
- data/lib/active_record/explain_registry.rb +2 -0
- data/lib/active_record/explain_subscriber.rb +2 -0
- data/lib/active_record/fixture_set/file.rb +2 -0
- data/lib/active_record/fixtures.rb +67 -60
- data/lib/active_record/gem_version.rb +4 -2
- data/lib/active_record/inheritance.rb +49 -19
- data/lib/active_record/integration.rb +58 -19
- data/lib/active_record/internal_metadata.rb +2 -0
- data/lib/active_record/legacy_yaml_adapter.rb +3 -1
- data/lib/active_record/locking/optimistic.rb +30 -42
- data/lib/active_record/locking/pessimistic.rb +10 -7
- data/lib/active_record/log_subscriber.rb +46 -4
- data/lib/active_record/migration.rb +189 -139
- data/lib/active_record/migration/command_recorder.rb +11 -9
- data/lib/active_record/migration/compatibility.rb +81 -29
- data/lib/active_record/migration/join_table.rb +2 -0
- data/lib/active_record/model_schema.rb +74 -58
- data/lib/active_record/nested_attributes.rb +18 -6
- data/lib/active_record/no_touching.rb +3 -1
- data/lib/active_record/null_relation.rb +2 -0
- data/lib/active_record/persistence.rb +199 -54
- data/lib/active_record/query_cache.rb +8 -10
- data/lib/active_record/querying.rb +5 -3
- data/lib/active_record/railtie.rb +62 -6
- data/lib/active_record/railties/console_sandbox.rb +2 -0
- data/lib/active_record/railties/controller_runtime.rb +2 -0
- data/lib/active_record/railties/databases.rake +48 -38
- data/lib/active_record/readonly_attributes.rb +3 -2
- data/lib/active_record/reflection.rb +137 -207
- data/lib/active_record/relation.rb +132 -207
- data/lib/active_record/relation/batches.rb +32 -17
- data/lib/active_record/relation/batches/batch_enumerator.rb +2 -0
- data/lib/active_record/relation/calculations.rb +66 -25
- data/lib/active_record/relation/delegation.rb +45 -29
- data/lib/active_record/relation/finder_methods.rb +76 -85
- data/lib/active_record/relation/from_clause.rb +2 -8
- data/lib/active_record/relation/merger.rb +53 -23
- data/lib/active_record/relation/predicate_builder.rb +60 -79
- data/lib/active_record/relation/predicate_builder/array_handler.rb +10 -7
- data/lib/active_record/relation/predicate_builder/association_query_value.rb +46 -0
- data/lib/active_record/relation/predicate_builder/base_handler.rb +2 -2
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +12 -1
- data/lib/active_record/relation/predicate_builder/polymorphic_array_value.rb +56 -0
- data/lib/active_record/relation/predicate_builder/range_handler.rb +26 -9
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
- data/lib/active_record/relation/query_attribute.rb +28 -2
- data/lib/active_record/relation/query_methods.rb +135 -103
- data/lib/active_record/relation/record_fetch_warning.rb +2 -0
- data/lib/active_record/relation/spawn_methods.rb +4 -2
- data/lib/active_record/relation/where_clause.rb +65 -67
- data/lib/active_record/relation/where_clause_factory.rb +5 -48
- data/lib/active_record/result.rb +2 -0
- data/lib/active_record/runtime_registry.rb +2 -0
- data/lib/active_record/sanitization.rb +129 -121
- data/lib/active_record/schema.rb +4 -2
- data/lib/active_record/schema_dumper.rb +36 -26
- data/lib/active_record/schema_migration.rb +2 -0
- data/lib/active_record/scoping.rb +12 -10
- data/lib/active_record/scoping/default.rb +10 -7
- data/lib/active_record/scoping/named.rb +40 -12
- data/lib/active_record/secure_token.rb +2 -0
- data/lib/active_record/serialization.rb +2 -0
- data/lib/active_record/statement_cache.rb +22 -12
- data/lib/active_record/store.rb +3 -1
- data/lib/active_record/suppressor.rb +2 -0
- data/lib/active_record/table_metadata.rb +12 -3
- data/lib/active_record/tasks/database_tasks.rb +38 -26
- data/lib/active_record/tasks/mysql_database_tasks.rb +11 -50
- data/lib/active_record/tasks/postgresql_database_tasks.rb +11 -3
- data/lib/active_record/tasks/sqlite_database_tasks.rb +25 -3
- data/lib/active_record/timestamp.rb +13 -6
- data/lib/active_record/touch_later.rb +2 -0
- data/lib/active_record/transactions.rb +32 -27
- data/lib/active_record/translation.rb +2 -0
- data/lib/active_record/type.rb +4 -1
- data/lib/active_record/type/adapter_specific_registry.rb +2 -0
- data/lib/active_record/type/date.rb +2 -0
- data/lib/active_record/type/date_time.rb +2 -0
- data/lib/active_record/type/decimal_without_scale.rb +2 -0
- data/lib/active_record/type/hash_lookup_type_map.rb +2 -0
- data/lib/active_record/type/internal/timezone.rb +2 -0
- data/lib/active_record/type/json.rb +30 -0
- data/lib/active_record/type/serialized.rb +6 -0
- data/lib/active_record/type/text.rb +2 -0
- data/lib/active_record/type/time.rb +2 -0
- data/lib/active_record/type/type_map.rb +2 -0
- data/lib/active_record/type/unsigned_integer.rb +2 -0
- data/lib/active_record/type_caster.rb +2 -0
- data/lib/active_record/type_caster/connection.rb +2 -0
- data/lib/active_record/type_caster/map.rb +3 -1
- data/lib/active_record/validations.rb +2 -0
- data/lib/active_record/validations/absence.rb +2 -0
- data/lib/active_record/validations/associated.rb +2 -0
- data/lib/active_record/validations/length.rb +2 -0
- data/lib/active_record/validations/presence.rb +2 -0
- data/lib/active_record/validations/uniqueness.rb +36 -6
- data/lib/active_record/version.rb +2 -0
- data/lib/rails/generators/active_record.rb +3 -1
- data/lib/rails/generators/active_record/application_record/application_record_generator.rb +27 -0
- data/lib/rails/generators/active_record/{model/templates/application_record.rb → application_record/templates/application_record.rb.tt} +0 -0
- data/lib/rails/generators/active_record/migration.rb +2 -0
- data/lib/rails/generators/active_record/migration/migration_generator.rb +3 -1
- data/lib/rails/generators/active_record/migration/templates/{create_table_migration.rb → create_table_migration.rb.tt} +0 -0
- data/lib/rails/generators/active_record/migration/templates/{migration.rb → migration.rb.tt} +0 -0
- data/lib/rails/generators/active_record/model/model_generator.rb +2 -23
- data/lib/rails/generators/active_record/model/templates/{model.rb → model.rb.tt} +0 -0
- data/lib/rails/generators/active_record/model/templates/{module.rb → module.rb.tt} +0 -0
- metadata +24 -36
- data/lib/active_record/associations/preloader/belongs_to.rb +0 -15
- data/lib/active_record/associations/preloader/collection_association.rb +0 -17
- data/lib/active_record/associations/preloader/has_many.rb +0 -15
- data/lib/active_record/associations/preloader/has_many_through.rb +0 -19
- data/lib/active_record/associations/preloader/has_one.rb +0 -15
- data/lib/active_record/associations/preloader/has_one_through.rb +0 -9
- data/lib/active_record/associations/preloader/singular_association.rb +0 -18
- data/lib/active_record/attribute.rb +0 -240
- data/lib/active_record/attribute/user_provided_default.rb +0 -30
- data/lib/active_record/attribute_mutation_tracker.rb +0 -113
- data/lib/active_record/attribute_set.rb +0 -113
- data/lib/active_record/attribute_set/builder.rb +0 -124
- data/lib/active_record/attribute_set/yaml_encoder.rb +0 -41
- data/lib/active_record/connection_adapters/postgresql/oid/json.rb +0 -10
- data/lib/active_record/railties/jdbcmysql_error.rb +0 -16
- data/lib/active_record/relation/predicate_builder/association_query_handler.rb +0 -88
- data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +0 -59
- data/lib/active_record/type/internal/abstract_json.rb +0 -33
@@ -1,10 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module ConnectionAdapters
|
3
5
|
class TransactionState
|
4
|
-
VALID_STATES = Set.new([:committed, :rolledback, nil])
|
5
|
-
|
6
6
|
def initialize(state = nil)
|
7
7
|
@state = state
|
8
|
+
@children = []
|
9
|
+
end
|
10
|
+
|
11
|
+
def add_child(state)
|
12
|
+
@children << state
|
8
13
|
end
|
9
14
|
|
10
15
|
def finalized?
|
@@ -12,11 +17,23 @@ module ActiveRecord
|
|
12
17
|
end
|
13
18
|
|
14
19
|
def committed?
|
15
|
-
@state == :committed
|
20
|
+
@state == :committed || @state == :fully_committed
|
21
|
+
end
|
22
|
+
|
23
|
+
def fully_committed?
|
24
|
+
@state == :fully_committed
|
16
25
|
end
|
17
26
|
|
18
27
|
def rolledback?
|
19
|
-
@state == :rolledback
|
28
|
+
@state == :rolledback || @state == :fully_rolledback
|
29
|
+
end
|
30
|
+
|
31
|
+
def fully_rolledback?
|
32
|
+
@state == :fully_rolledback
|
33
|
+
end
|
34
|
+
|
35
|
+
def fully_completed?
|
36
|
+
completed?
|
20
37
|
end
|
21
38
|
|
22
39
|
def completed?
|
@@ -24,10 +41,43 @@ module ActiveRecord
|
|
24
41
|
end
|
25
42
|
|
26
43
|
def set_state(state)
|
27
|
-
|
44
|
+
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
45
|
+
The set_state method is deprecated and will be removed in
|
46
|
+
Rails 6.0. Please use rollback! or commit! to set transaction
|
47
|
+
state directly.
|
48
|
+
MSG
|
49
|
+
case state
|
50
|
+
when :rolledback
|
51
|
+
rollback!
|
52
|
+
when :committed
|
53
|
+
commit!
|
54
|
+
when nil
|
55
|
+
nullify!
|
56
|
+
else
|
28
57
|
raise ArgumentError, "Invalid transaction state: #{state}"
|
29
58
|
end
|
30
|
-
|
59
|
+
end
|
60
|
+
|
61
|
+
def rollback!
|
62
|
+
@children.each { |c| c.rollback! }
|
63
|
+
@state = :rolledback
|
64
|
+
end
|
65
|
+
|
66
|
+
def full_rollback!
|
67
|
+
@children.each { |c| c.rollback! }
|
68
|
+
@state = :fully_rolledback
|
69
|
+
end
|
70
|
+
|
71
|
+
def commit!
|
72
|
+
@state = :committed
|
73
|
+
end
|
74
|
+
|
75
|
+
def full_commit!
|
76
|
+
@state = :fully_committed
|
77
|
+
end
|
78
|
+
|
79
|
+
def nullify!
|
80
|
+
@state = nil
|
31
81
|
end
|
32
82
|
end
|
33
83
|
|
@@ -56,10 +106,6 @@ module ActiveRecord
|
|
56
106
|
records << record
|
57
107
|
end
|
58
108
|
|
59
|
-
def rollback
|
60
|
-
@state.set_state(:rolledback)
|
61
|
-
end
|
62
|
-
|
63
109
|
def rollback_records
|
64
110
|
ite = records.uniq
|
65
111
|
while record = ite.shift
|
@@ -71,10 +117,6 @@ module ActiveRecord
|
|
71
117
|
end
|
72
118
|
end
|
73
119
|
|
74
|
-
def commit
|
75
|
-
@state.set_state(:committed)
|
76
|
-
end
|
77
|
-
|
78
120
|
def before_commit_records
|
79
121
|
records.uniq.each(&:before_committed!) if @run_commit_callbacks
|
80
122
|
end
|
@@ -100,8 +142,11 @@ module ActiveRecord
|
|
100
142
|
end
|
101
143
|
|
102
144
|
class SavepointTransaction < Transaction
|
103
|
-
def initialize(connection, savepoint_name, options, *args)
|
145
|
+
def initialize(connection, savepoint_name, parent_transaction, options, *args)
|
104
146
|
super(connection, options, *args)
|
147
|
+
|
148
|
+
parent_transaction.state.add_child(@state)
|
149
|
+
|
105
150
|
if options[:isolation]
|
106
151
|
raise ActiveRecord::TransactionIsolationError, "cannot set transaction isolation in a nested transaction"
|
107
152
|
end
|
@@ -110,12 +155,12 @@ module ActiveRecord
|
|
110
155
|
|
111
156
|
def rollback
|
112
157
|
connection.rollback_to_savepoint(savepoint_name)
|
113
|
-
|
158
|
+
@state.rollback!
|
114
159
|
end
|
115
160
|
|
116
161
|
def commit
|
117
162
|
connection.release_savepoint(savepoint_name)
|
118
|
-
|
163
|
+
@state.commit!
|
119
164
|
end
|
120
165
|
|
121
166
|
def full_rollback?; false; end
|
@@ -133,12 +178,12 @@ module ActiveRecord
|
|
133
178
|
|
134
179
|
def rollback
|
135
180
|
connection.rollback_db_transaction
|
136
|
-
|
181
|
+
@state.full_rollback!
|
137
182
|
end
|
138
183
|
|
139
184
|
def commit
|
140
185
|
connection.commit_db_transaction
|
141
|
-
|
186
|
+
@state.full_commit!
|
142
187
|
end
|
143
188
|
end
|
144
189
|
|
@@ -155,7 +200,7 @@ module ActiveRecord
|
|
155
200
|
if @stack.empty?
|
156
201
|
RealTransaction.new(@connection, options, run_commit_callbacks: run_commit_callbacks)
|
157
202
|
else
|
158
|
-
SavepointTransaction.new(@connection, "active_record_#{@stack.size}", options,
|
203
|
+
SavepointTransaction.new(@connection, "active_record_#{@stack.size}", @stack.last, options,
|
159
204
|
run_commit_callbacks: run_commit_callbacks)
|
160
205
|
end
|
161
206
|
|
@@ -204,7 +249,7 @@ module ActiveRecord
|
|
204
249
|
rollback_transaction if transaction
|
205
250
|
else
|
206
251
|
begin
|
207
|
-
commit_transaction
|
252
|
+
commit_transaction if transaction
|
208
253
|
rescue Exception
|
209
254
|
rollback_transaction(transaction) unless transaction.state.completed?
|
210
255
|
raise
|
@@ -1,11 +1,15 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require "active_record/connection_adapters/determine_if_preparable_visitor"
|
3
4
|
require "active_record/connection_adapters/schema_cache"
|
4
5
|
require "active_record/connection_adapters/sql_type_metadata"
|
5
6
|
require "active_record/connection_adapters/abstract/schema_dumper"
|
6
7
|
require "active_record/connection_adapters/abstract/schema_creation"
|
8
|
+
require "active_support/concurrency/load_interlock_aware_monitor"
|
7
9
|
require "arel/collectors/bind"
|
10
|
+
require "arel/collectors/composite"
|
8
11
|
require "arel/collectors/sql_string"
|
12
|
+
require "arel/collectors/substitute_binds"
|
9
13
|
|
10
14
|
module ActiveRecord
|
11
15
|
module ConnectionAdapters # :nodoc:
|
@@ -68,7 +72,6 @@ module ActiveRecord
|
|
68
72
|
include Quoting, DatabaseStatements, SchemaStatements
|
69
73
|
include DatabaseLimits
|
70
74
|
include QueryCache
|
71
|
-
include ColumnDumper
|
72
75
|
include Savepoints
|
73
76
|
|
74
77
|
SIMPLE_INT = /\A\d+\z/
|
@@ -78,7 +81,9 @@ module ActiveRecord
|
|
78
81
|
alias :in_use? :owner
|
79
82
|
|
80
83
|
def self.type_cast_config_to_integer(config)
|
81
|
-
if config
|
84
|
+
if config.is_a?(Integer)
|
85
|
+
config
|
86
|
+
elsif config =~ SIMPLE_INT
|
82
87
|
config.to_i
|
83
88
|
else
|
84
89
|
config
|
@@ -102,10 +107,11 @@ module ActiveRecord
|
|
102
107
|
@logger = logger
|
103
108
|
@config = config
|
104
109
|
@pool = nil
|
110
|
+
@idle_since = Concurrent.monotonic_time
|
105
111
|
@schema_cache = SchemaCache.new self
|
106
112
|
@quoted_column_names, @quoted_table_names = {}, {}
|
107
113
|
@visitor = arel_visitor
|
108
|
-
@lock =
|
114
|
+
@lock = ActiveSupport::Concurrency::LoadInterlockAwareMonitor.new
|
109
115
|
|
110
116
|
if self.class.type_cast_config_to_boolean(config.fetch(:prepared_statements) { true })
|
111
117
|
@prepared_statements = true
|
@@ -115,6 +121,14 @@ module ActiveRecord
|
|
115
121
|
end
|
116
122
|
end
|
117
123
|
|
124
|
+
def migrations_paths # :nodoc:
|
125
|
+
@config[:migrations_paths] || Migrator.migrations_paths
|
126
|
+
end
|
127
|
+
|
128
|
+
def migration_context # :nodoc:
|
129
|
+
MigrationContext.new(migrations_paths)
|
130
|
+
end
|
131
|
+
|
118
132
|
class Version
|
119
133
|
include Comparable
|
120
134
|
|
@@ -127,51 +141,14 @@ module ActiveRecord
|
|
127
141
|
end
|
128
142
|
end
|
129
143
|
|
130
|
-
class BindCollector < Arel::Collectors::Bind
|
131
|
-
def compile(bvs, conn)
|
132
|
-
casted_binds = bvs.map(&:value_for_database)
|
133
|
-
super(casted_binds.map { |value| conn.quote(value) })
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
class SQLString < Arel::Collectors::SQLString
|
138
|
-
def compile(bvs, conn)
|
139
|
-
super(bvs)
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
def collector
|
144
|
-
if prepared_statements
|
145
|
-
SQLString.new
|
146
|
-
else
|
147
|
-
BindCollector.new
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
def arel_visitor # :nodoc:
|
152
|
-
Arel::Visitors::ToSql.new(self)
|
153
|
-
end
|
154
|
-
|
155
144
|
def valid_type?(type) # :nodoc:
|
156
145
|
!native_database_types[type].nil?
|
157
146
|
end
|
158
147
|
|
159
|
-
def schema_creation
|
160
|
-
SchemaCreation.new self
|
161
|
-
end
|
162
|
-
|
163
|
-
# Returns an array of +Column+ objects for the table specified by +table_name+.
|
164
|
-
def columns(table_name) # :nodoc:
|
165
|
-
table_name = table_name.to_s
|
166
|
-
column_definitions(table_name).map do |field|
|
167
|
-
new_column_from_field(table_name, field)
|
168
|
-
end
|
169
|
-
end
|
170
|
-
|
171
148
|
# this method must only be called while holding connection pool's mutex
|
172
149
|
def lease
|
173
150
|
if in_use?
|
174
|
-
msg = "Cannot lease connection, "
|
151
|
+
msg = "Cannot lease connection, ".dup
|
175
152
|
if @owner == Thread.current
|
176
153
|
msg << "it is already leased by the current thread."
|
177
154
|
else
|
@@ -198,6 +175,7 @@ module ActiveRecord
|
|
198
175
|
"Current thread: #{Thread.current}."
|
199
176
|
end
|
200
177
|
|
178
|
+
@idle_since = Concurrent.monotonic_time
|
201
179
|
@owner = nil
|
202
180
|
else
|
203
181
|
raise ActiveRecordError, "Cannot expire connection, it is not currently leased."
|
@@ -217,6 +195,12 @@ module ActiveRecord
|
|
217
195
|
end
|
218
196
|
end
|
219
197
|
|
198
|
+
# Seconds since this connection was returned to the pool
|
199
|
+
def seconds_idle # :nodoc:
|
200
|
+
return 0 if in_use?
|
201
|
+
Concurrent.monotonic_time - @idle_since
|
202
|
+
end
|
203
|
+
|
220
204
|
def unprepared_statement
|
221
205
|
old_prepared_statements, @prepared_statements = @prepared_statements, false
|
222
206
|
yield
|
@@ -230,16 +214,6 @@ module ActiveRecord
|
|
230
214
|
self.class::ADAPTER_NAME
|
231
215
|
end
|
232
216
|
|
233
|
-
def supports_migrations? # :nodoc:
|
234
|
-
true
|
235
|
-
end
|
236
|
-
deprecate :supports_migrations?
|
237
|
-
|
238
|
-
def supports_primary_key? # :nodoc:
|
239
|
-
true
|
240
|
-
end
|
241
|
-
deprecate :supports_primary_key?
|
242
|
-
|
243
217
|
# Does this adapter support DDL rollbacks in transactions? That is, would
|
244
218
|
# CREATE TABLE or ALTER TABLE get rolled back by a transaction?
|
245
219
|
def supports_ddl_transactions?
|
@@ -308,6 +282,11 @@ module ActiveRecord
|
|
308
282
|
false
|
309
283
|
end
|
310
284
|
|
285
|
+
# Does this adapter support creating invalid constraints?
|
286
|
+
def supports_validate_constraints?
|
287
|
+
false
|
288
|
+
end
|
289
|
+
|
311
290
|
# Does this adapter support creating foreign key constraints
|
312
291
|
# in the same statement as creating the table?
|
313
292
|
def supports_foreign_keys_in_create?
|
@@ -349,6 +328,11 @@ module ActiveRecord
|
|
349
328
|
false
|
350
329
|
end
|
351
330
|
|
331
|
+
# Does this adapter support foreign/external tables?
|
332
|
+
def supports_foreign_tables?
|
333
|
+
false
|
334
|
+
end
|
335
|
+
|
352
336
|
# This is meant to be implemented by the adapters that support extensions
|
353
337
|
def disable_extension(name)
|
354
338
|
end
|
@@ -411,6 +395,19 @@ module ActiveRecord
|
|
411
395
|
reset_transaction
|
412
396
|
end
|
413
397
|
|
398
|
+
# Immediately forget this connection ever existed. Unlike disconnect!,
|
399
|
+
# this will not communicate with the server.
|
400
|
+
#
|
401
|
+
# After calling this method, the behavior of all other methods becomes
|
402
|
+
# undefined. This is called internally just before a forked process gets
|
403
|
+
# rid of a connection that belonged to its parent.
|
404
|
+
def discard!
|
405
|
+
# This should be overridden by concrete adapters.
|
406
|
+
#
|
407
|
+
# Prevent @connection's finalizer from touching the socket, or
|
408
|
+
# otherwise communicating with its server, when it is collected.
|
409
|
+
end
|
410
|
+
|
414
411
|
# Reset the state of this connection, directing the DBMS to clear
|
415
412
|
# transactions and other connection-related server-side state. Usually a
|
416
413
|
# database-dependent operation.
|
@@ -436,10 +433,7 @@ module ActiveRecord
|
|
436
433
|
# Checks whether the connection to the database is still active (i.e. not stale).
|
437
434
|
# This is done under the hood by calling #active?. If the connection
|
438
435
|
# is no longer active, then this method will reconnect to the database.
|
439
|
-
def verify!
|
440
|
-
if ignored.size > 0
|
441
|
-
ActiveSupport::Deprecation.warn("Passing arguments to #verify method of the connection has no effect and has been deprecated. Please remove all arguments from the #verify method call.")
|
442
|
-
end
|
436
|
+
def verify!
|
443
437
|
reconnect! unless active?
|
444
438
|
end
|
445
439
|
|
@@ -475,40 +469,12 @@ module ActiveRecord
|
|
475
469
|
pool.checkin self
|
476
470
|
end
|
477
471
|
|
478
|
-
def
|
479
|
-
|
480
|
-
initialize_type_map(mapping)
|
481
|
-
end
|
482
|
-
end
|
483
|
-
|
484
|
-
def new_column(name, default, sql_type_metadata, null, table_name, default_function = nil, collation = nil) # :nodoc:
|
485
|
-
Column.new(name, default, sql_type_metadata, null, table_name, default_function, collation)
|
472
|
+
def column_name_for_operation(operation, node) # :nodoc:
|
473
|
+
column_name_from_arel_node(node)
|
486
474
|
end
|
487
475
|
|
488
|
-
def
|
489
|
-
|
490
|
-
end
|
491
|
-
|
492
|
-
def column_name_for_operation(operation, node) # :nodoc:
|
493
|
-
visitor.accept(node, collector).value
|
494
|
-
end
|
495
|
-
|
496
|
-
def combine_bind_parameters(
|
497
|
-
from_clause: [],
|
498
|
-
join_clause: [],
|
499
|
-
where_clause: [],
|
500
|
-
having_clause: [],
|
501
|
-
limit: nil,
|
502
|
-
offset: nil
|
503
|
-
) # :nodoc:
|
504
|
-
result = from_clause + join_clause + where_clause + having_clause
|
505
|
-
if limit
|
506
|
-
result << limit
|
507
|
-
end
|
508
|
-
if offset
|
509
|
-
result << offset
|
510
|
-
end
|
511
|
-
result
|
476
|
+
def column_name_from_arel_node(node) # :nodoc:
|
477
|
+
visitor.accept(node, Arel::Collectors::SQLString.new).value
|
512
478
|
end
|
513
479
|
|
514
480
|
def default_index_type?(index) # :nodoc:
|
@@ -516,8 +482,13 @@ module ActiveRecord
|
|
516
482
|
end
|
517
483
|
|
518
484
|
private
|
485
|
+
def type_map
|
486
|
+
@type_map ||= Type::TypeMap.new.tap do |mapping|
|
487
|
+
initialize_type_map(mapping)
|
488
|
+
end
|
489
|
+
end
|
519
490
|
|
520
|
-
def initialize_type_map(m)
|
491
|
+
def initialize_type_map(m = type_map)
|
521
492
|
register_class_with_limit m, %r(boolean)i, Type::Boolean
|
522
493
|
register_class_with_limit m, %r(char)i, Type::String
|
523
494
|
register_class_with_limit m, %r(binary)i, Type::Binary
|
@@ -535,6 +506,8 @@ module ActiveRecord
|
|
535
506
|
m.alias_type %r(number)i, "decimal"
|
536
507
|
m.alias_type %r(double)i, "float"
|
537
508
|
|
509
|
+
m.register_type %r(^json)i, Type::Json.new
|
510
|
+
|
538
511
|
m.register_type(%r(decimal)i) do |sql_type|
|
539
512
|
scale = extract_scale(sql_type)
|
540
513
|
precision = extract_precision(sql_type)
|
@@ -550,7 +523,7 @@ module ActiveRecord
|
|
550
523
|
|
551
524
|
def reload_type_map
|
552
525
|
type_map.clear
|
553
|
-
initialize_type_map
|
526
|
+
initialize_type_map
|
554
527
|
end
|
555
528
|
|
556
529
|
def register_class_with_limit(mapping, key, klass)
|
@@ -579,12 +552,7 @@ module ActiveRecord
|
|
579
552
|
end
|
580
553
|
|
581
554
|
def extract_limit(sql_type)
|
582
|
-
|
583
|
-
when /^bigint/i
|
584
|
-
8
|
585
|
-
when /\((.*)\)/
|
586
|
-
$1.to_i
|
587
|
-
end
|
555
|
+
$1.to_i if sql_type =~ /\((.*)\)/
|
588
556
|
end
|
589
557
|
|
590
558
|
def translate_exception_class(e, sql)
|
@@ -608,12 +576,14 @@ module ActiveRecord
|
|
608
576
|
type_casted_binds: type_casted_binds,
|
609
577
|
statement_name: statement_name,
|
610
578
|
connection_id: object_id) do
|
579
|
+
begin
|
611
580
|
@lock.synchronize do
|
612
581
|
yield
|
613
582
|
end
|
583
|
+
rescue => e
|
584
|
+
raise translate_exception_class(e, sql)
|
614
585
|
end
|
615
|
-
|
616
|
-
raise translate_exception_class(e, sql)
|
586
|
+
end
|
617
587
|
end
|
618
588
|
|
619
589
|
def translate_exception(exception, message)
|
@@ -635,6 +605,24 @@ module ActiveRecord
|
|
635
605
|
columns(table_name).detect { |c| c.name == column_name } ||
|
636
606
|
raise(ActiveRecordError, "No such column: #{table_name}.#{column_name}")
|
637
607
|
end
|
608
|
+
|
609
|
+
def collector
|
610
|
+
if prepared_statements
|
611
|
+
Arel::Collectors::Composite.new(
|
612
|
+
Arel::Collectors::SQLString.new,
|
613
|
+
Arel::Collectors::Bind.new,
|
614
|
+
)
|
615
|
+
else
|
616
|
+
Arel::Collectors::SubstituteBinds.new(
|
617
|
+
self,
|
618
|
+
Arel::Collectors::SQLString.new,
|
619
|
+
)
|
620
|
+
end
|
621
|
+
end
|
622
|
+
|
623
|
+
def arel_visitor
|
624
|
+
Arel::Visitors::ToSql.new(self)
|
625
|
+
end
|
638
626
|
end
|
639
627
|
end
|
640
628
|
end
|