activerecord 5.1.7 → 5.2.0.beta1
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 +221 -900
- data/README.rdoc +3 -3
- data/examples/performance.rb +2 -0
- data/examples/simple.rb +2 -0
- data/lib/active_record.rb +10 -3
- data/lib/active_record/aggregations.rb +2 -0
- data/lib/active_record/association_relation.rb +2 -0
- data/lib/active_record/associations.rb +13 -42
- data/lib/active_record/associations/alias_tracker.rb +17 -17
- data/lib/active_record/associations/association.rb +11 -22
- data/lib/active_record/associations/association_scope.rb +32 -44
- data/lib/active_record/associations/belongs_to_association.rb +6 -4
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +3 -1
- data/lib/active_record/associations/builder/association.rb +2 -5
- data/lib/active_record/associations/builder/belongs_to.rb +7 -12
- 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 +41 -33
- data/lib/active_record/associations/collection_proxy.rb +11 -14
- data/lib/active_record/associations/foreign_association.rb +2 -0
- data/lib/active_record/associations/has_many_association.rb +4 -2
- data/lib/active_record/associations/has_many_through_association.rb +4 -2
- data/lib/active_record/associations/has_one_association.rb +3 -1
- data/lib/active_record/associations/has_one_through_association.rb +3 -1
- data/lib/active_record/associations/join_dependency.rb +22 -40
- data/lib/active_record/associations/join_dependency/join_association.rb +17 -56
- data/lib/active_record/associations/join_dependency/join_base.rb +9 -8
- data/lib/active_record/associations/join_dependency/join_part.rb +2 -9
- data/lib/active_record/associations/preloader.rb +17 -37
- data/lib/active_record/associations/preloader/association.rb +42 -58
- data/lib/active_record/associations/preloader/through_association.rb +71 -79
- data/lib/active_record/associations/singular_association.rb +14 -10
- data/lib/active_record/associations/through_association.rb +3 -1
- data/lib/active_record/attribute_assignment.rb +2 -0
- data/lib/active_record/attribute_decorators.rb +3 -2
- data/lib/active_record/attribute_methods.rb +47 -7
- data/lib/active_record/attribute_methods/before_type_cast.rb +2 -0
- data/lib/active_record/attribute_methods/dirty.rb +25 -214
- data/lib/active_record/attribute_methods/primary_key.rb +7 -6
- data/lib/active_record/attribute_methods/query.rb +2 -0
- data/lib/active_record/attribute_methods/read.rb +8 -2
- 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 +21 -9
- data/lib/active_record/attributes.rb +7 -6
- data/lib/active_record/autosave_association.rb +5 -11
- data/lib/active_record/base.rb +2 -0
- data/lib/active_record/callbacks.rb +6 -8
- 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 +10 -5
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +110 -35
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +2 -0
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +120 -28
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +7 -2
- data/lib/active_record/connection_adapters/abstract/quoting.rb +14 -33
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +13 -5
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +40 -2
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +31 -53
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +103 -63
- data/lib/active_record/connection_adapters/abstract/transaction.rb +45 -9
- data/lib/active_record/connection_adapters/abstract_adapter.rb +62 -90
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +75 -138
- data/lib/active_record/connection_adapters/column.rb +3 -1
- data/lib/active_record/connection_adapters/connection_specification.rb +17 -3
- data/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb +2 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +2 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +3 -1
- 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 -6
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +30 -30
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +91 -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 +2 -0
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +6 -0
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/oid.rb +2 -1
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +3 -11
- 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_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 -1
- 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 +3 -5
- 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 +10 -0
- data/lib/active_record/connection_adapters/postgresql/referential_integrity.rb +19 -25
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +11 -7
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +20 -13
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +79 -65
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql/utils.rb +2 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +47 -82
- data/lib/active_record/connection_adapters/schema_cache.rb +2 -0
- 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 +19 -2
- 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 +71 -1
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +34 -89
- 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 +27 -57
- data/lib/active_record/counter_cache.rb +15 -12
- data/lib/active_record/define_callbacks.rb +5 -3
- data/lib/active_record/dynamic_matchers.rb +9 -9
- data/lib/active_record/enum.rb +15 -13
- data/lib/active_record/errors.rb +54 -21
- 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 +40 -24
- data/lib/active_record/gem_version.rb +5 -3
- data/lib/active_record/inheritance.rb +6 -5
- 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 +31 -20
- data/lib/active_record/locking/pessimistic.rb +10 -7
- data/lib/active_record/log_subscriber.rb +2 -0
- data/lib/active_record/migration.rb +47 -21
- data/lib/active_record/migration/command_recorder.rb +11 -9
- data/lib/active_record/migration/compatibility.rb +20 -2
- data/lib/active_record/migration/join_table.rb +2 -0
- data/lib/active_record/model_schema.rb +29 -38
- 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 +184 -40
- data/lib/active_record/query_cache.rb +17 -12
- data/lib/active_record/querying.rb +3 -1
- data/lib/active_record/railtie.rb +54 -1
- 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 +41 -28
- data/lib/active_record/readonly_attributes.rb +3 -2
- data/lib/active_record/reflection.rb +100 -182
- data/lib/active_record/relation.rb +61 -193
- data/lib/active_record/relation/batches.rb +20 -5
- data/lib/active_record/relation/batches/batch_enumerator.rb +2 -0
- data/lib/active_record/relation/calculations.rb +40 -23
- data/lib/active_record/relation/delegation.rb +10 -27
- data/lib/active_record/relation/finder_methods.rb +53 -49
- data/lib/active_record/relation/from_clause.rb +2 -8
- data/lib/active_record/relation/merger.rb +22 -19
- data/lib/active_record/relation/predicate_builder.rb +42 -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 +54 -0
- data/lib/active_record/relation/predicate_builder/range_handler.rb +22 -6
- data/lib/active_record/relation/predicate_builder/relation_handler.rb +6 -0
- data/lib/active_record/relation/query_attribute.rb +9 -2
- data/lib/active_record/relation/query_methods.rb +80 -69
- data/lib/active_record/relation/record_fetch_warning.rb +2 -0
- data/lib/active_record/relation/spawn_methods.rb +2 -0
- data/lib/active_record/relation/where_clause.rb +50 -67
- data/lib/active_record/relation/where_clause_factory.rb +4 -46
- data/lib/active_record/result.rb +2 -0
- data/lib/active_record/runtime_registry.rb +2 -0
- data/lib/active_record/sanitization.rb +15 -9
- data/lib/active_record/schema.rb +3 -1
- data/lib/active_record/schema_dumper.rb +24 -23
- data/lib/active_record/schema_migration.rb +2 -0
- data/lib/active_record/scoping.rb +9 -8
- data/lib/active_record/scoping/default.rb +6 -7
- data/lib/active_record/scoping/named.rb +15 -7
- 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 +2 -0
- data/lib/active_record/suppressor.rb +2 -0
- data/lib/active_record/table_metadata.rb +3 -1
- data/lib/active_record/tasks/database_tasks.rb +23 -12
- data/lib/active_record/tasks/mysql_database_tasks.rb +9 -48
- data/lib/active_record/tasks/postgresql_database_tasks.rb +10 -2
- data/lib/active_record/tasks/sqlite_database_tasks.rb +25 -3
- data/lib/active_record/timestamp.rb +5 -12
- data/lib/active_record/touch_later.rb +2 -0
- data/lib/active_record/transactions.rb +9 -7
- 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 +2 -4
- 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 +2 -0
- 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 +25 -38
- 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 -122
- data/lib/active_record/attribute_set.rb +0 -113
- data/lib/active_record/attribute_set/builder.rb +0 -126
- 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 -37
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "set"
|
2
4
|
|
3
5
|
module ActiveRecord
|
@@ -8,23 +10,22 @@ module ActiveRecord
|
|
8
10
|
# Returns this record's primary key value wrapped in an array if one is
|
9
11
|
# available.
|
10
12
|
def to_key
|
11
|
-
sync_with_transaction_state
|
12
13
|
key = id
|
13
14
|
[key] if key
|
14
15
|
end
|
15
16
|
|
16
17
|
# Returns the primary key value.
|
17
18
|
def id
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
end
|
19
|
+
sync_with_transaction_state
|
20
|
+
primary_key = self.class.primary_key
|
21
|
+
_read_attribute(primary_key) if primary_key
|
22
22
|
end
|
23
23
|
|
24
24
|
# Sets the primary key value.
|
25
25
|
def id=(value)
|
26
26
|
sync_with_transaction_state
|
27
|
-
|
27
|
+
primary_key = self.class.primary_key
|
28
|
+
_write_attribute(primary_key, value) if primary_key
|
28
29
|
end
|
29
30
|
|
30
31
|
# Queries the primary key value.
|
@@ -1,9 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module AttributeMethods
|
3
5
|
module Read
|
4
6
|
extend ActiveSupport::Concern
|
5
7
|
|
6
|
-
module ClassMethods
|
8
|
+
module ClassMethods # :nodoc:
|
7
9
|
private
|
8
10
|
|
9
11
|
# We want to generate the methods via module_eval rather than
|
@@ -29,9 +31,11 @@ module ActiveRecord
|
|
29
31
|
temp_method = "__temp__#{safe_name}"
|
30
32
|
|
31
33
|
ActiveRecord::AttributeMethods::AttrNames.set_name_cache safe_name, name
|
34
|
+
sync_with_transaction_state = "sync_with_transaction_state" if name == primary_key
|
32
35
|
|
33
36
|
generated_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ + 1
|
34
37
|
def #{temp_method}
|
38
|
+
#{sync_with_transaction_state}
|
35
39
|
name = ::ActiveRecord::AttributeMethods::AttrNames::ATTR_#{safe_name}
|
36
40
|
_read_attribute(name) { |n| missing_attribute(n, caller) }
|
37
41
|
end
|
@@ -54,7 +58,9 @@ module ActiveRecord
|
|
54
58
|
attr_name.to_s
|
55
59
|
end
|
56
60
|
|
57
|
-
|
61
|
+
primary_key = self.class.primary_key
|
62
|
+
name = primary_key if name == "id".freeze && primary_key
|
63
|
+
sync_with_transaction_state if name == primary_key
|
58
64
|
_read_attribute(name, &block)
|
59
65
|
end
|
60
66
|
|
@@ -1,8 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module AttributeMethods
|
3
5
|
module Serialization
|
4
6
|
extend ActiveSupport::Concern
|
5
7
|
|
8
|
+
class ColumnNotSerializableError < StandardError
|
9
|
+
def initialize(name, type)
|
10
|
+
super <<-EOS.strip_heredoc
|
11
|
+
Column `#{name}` of type #{type.class} does not support `serialize` feature.
|
12
|
+
Usually it means that you are trying to use `serialize`
|
13
|
+
on a column that already implements serialization natively.
|
14
|
+
EOS
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
6
18
|
module ClassMethods
|
7
19
|
# If you have an attribute that needs to be saved to the database as an
|
8
20
|
# object, and retrieved as the same object, then specify the name of that
|
@@ -58,9 +70,20 @@ module ActiveRecord
|
|
58
70
|
end
|
59
71
|
|
60
72
|
decorate_attribute_type(attr_name, :serialize) do |type|
|
73
|
+
if type_incompatible_with_serialize?(type, class_name_or_coder)
|
74
|
+
raise ColumnNotSerializableError.new(attr_name, type)
|
75
|
+
end
|
76
|
+
|
61
77
|
Type::Serialized.new(type, coder)
|
62
78
|
end
|
63
79
|
end
|
80
|
+
|
81
|
+
private
|
82
|
+
|
83
|
+
def type_incompatible_with_serialize?(type, class_name)
|
84
|
+
type.is_a?(ActiveRecord::Type::Json) && class_name == ::JSON ||
|
85
|
+
type.respond_to?(:type_cast_array, true) && class_name == ::Array
|
86
|
+
end
|
64
87
|
end
|
65
88
|
end
|
66
89
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module AttributeMethods
|
3
5
|
module TimeZoneConversion
|
@@ -54,17 +56,13 @@ module ActiveRecord
|
|
54
56
|
extend ActiveSupport::Concern
|
55
57
|
|
56
58
|
included do
|
57
|
-
mattr_accessor :time_zone_aware_attributes, instance_writer: false
|
58
|
-
self.time_zone_aware_attributes = false
|
59
|
-
|
60
|
-
class_attribute :skip_time_zone_conversion_for_attributes, instance_writer: false
|
61
|
-
self.skip_time_zone_conversion_for_attributes = []
|
59
|
+
mattr_accessor :time_zone_aware_attributes, instance_writer: false, default: false
|
62
60
|
|
63
|
-
class_attribute :
|
64
|
-
|
61
|
+
class_attribute :skip_time_zone_conversion_for_attributes, instance_writer: false, default: []
|
62
|
+
class_attribute :time_zone_aware_types, instance_writer: false, default: [ :datetime, :time ]
|
65
63
|
end
|
66
64
|
|
67
|
-
module ClassMethods
|
65
|
+
module ClassMethods # :nodoc:
|
68
66
|
private
|
69
67
|
|
70
68
|
def inherited(subclass)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module AttributeMethods
|
3
5
|
module Write
|
@@ -7,17 +9,19 @@ module ActiveRecord
|
|
7
9
|
attribute_method_suffix "="
|
8
10
|
end
|
9
11
|
|
10
|
-
module ClassMethods
|
12
|
+
module ClassMethods # :nodoc:
|
11
13
|
private
|
12
14
|
|
13
15
|
def define_method_attribute=(name)
|
14
16
|
safe_name = name.unpack("h*".freeze).first
|
15
17
|
ActiveRecord::AttributeMethods::AttrNames.set_name_cache safe_name, name
|
18
|
+
sync_with_transaction_state = "sync_with_transaction_state" if name == primary_key
|
16
19
|
|
17
20
|
generated_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ + 1
|
18
21
|
def __temp__#{safe_name}=(value)
|
19
22
|
name = ::ActiveRecord::AttributeMethods::AttrNames::ATTR_#{safe_name}
|
20
|
-
|
23
|
+
#{sync_with_transaction_state}
|
24
|
+
_write_attribute(name, value)
|
21
25
|
end
|
22
26
|
alias_method #{(name + '=').inspect}, :__temp__#{safe_name}=
|
23
27
|
undef_method :__temp__#{safe_name}=
|
@@ -35,21 +39,29 @@ module ActiveRecord
|
|
35
39
|
attr_name.to_s
|
36
40
|
end
|
37
41
|
|
38
|
-
|
39
|
-
|
40
|
-
|
42
|
+
primary_key = self.class.primary_key
|
43
|
+
name = primary_key if name == "id".freeze && primary_key
|
44
|
+
sync_with_transaction_state if name == primary_key
|
45
|
+
_write_attribute(name, value)
|
41
46
|
end
|
42
47
|
|
43
|
-
|
44
|
-
|
45
|
-
|
48
|
+
# This method exists to avoid the expensive primary_key check internally, without
|
49
|
+
# breaking compatibility with the write_attribute API
|
50
|
+
def _write_attribute(attr_name, value) # :nodoc:
|
51
|
+
@attributes.write_from_user(attr_name.to_s, value)
|
46
52
|
value
|
47
53
|
end
|
48
54
|
|
49
55
|
private
|
56
|
+
def write_attribute_without_type_cast(attr_name, value)
|
57
|
+
name = attr_name.to_s
|
58
|
+
@attributes.write_cast_value(name, value)
|
59
|
+
value
|
60
|
+
end
|
61
|
+
|
50
62
|
# Handle *= for method_missing.
|
51
63
|
def attribute=(attribute_name, value)
|
52
|
-
|
64
|
+
_write_attribute(attribute_name, value)
|
53
65
|
end
|
54
66
|
end
|
55
67
|
end
|
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_model/attribute/user_provided_default"
|
2
4
|
|
3
5
|
module ActiveRecord
|
4
6
|
# See ActiveRecord::Attributes::ClassMethods for documentation
|
@@ -6,8 +8,7 @@ module ActiveRecord
|
|
6
8
|
extend ActiveSupport::Concern
|
7
9
|
|
8
10
|
included do
|
9
|
-
class_attribute :attributes_to_define_after_schema_loads, instance_accessor: false # :internal:
|
10
|
-
self.attributes_to_define_after_schema_loads = {}
|
11
|
+
class_attribute :attributes_to_define_after_schema_loads, instance_accessor: false, default: {} # :internal:
|
11
12
|
end
|
12
13
|
|
13
14
|
module ClassMethods
|
@@ -56,7 +57,7 @@ module ActiveRecord
|
|
56
57
|
# store_listing = StoreListing.new(price_in_cents: '10.1')
|
57
58
|
#
|
58
59
|
# # before
|
59
|
-
# store_listing.price_in_cents # => BigDecimal(10.1)
|
60
|
+
# store_listing.price_in_cents # => BigDecimal.new(10.1)
|
60
61
|
#
|
61
62
|
# class StoreListing < ActiveRecord::Base
|
62
63
|
# attribute :price_in_cents, :integer
|
@@ -249,14 +250,14 @@ module ActiveRecord
|
|
249
250
|
if value == NO_DEFAULT_PROVIDED
|
250
251
|
default_attribute = _default_attributes[name].with_type(type)
|
251
252
|
elsif from_user
|
252
|
-
default_attribute = Attribute::UserProvidedDefault.new(
|
253
|
+
default_attribute = ActiveModel::Attribute::UserProvidedDefault.new(
|
253
254
|
name,
|
254
255
|
value,
|
255
256
|
type,
|
256
257
|
_default_attributes.fetch(name.to_s) { nil },
|
257
258
|
)
|
258
259
|
else
|
259
|
-
default_attribute = Attribute.from_database(name, value, type)
|
260
|
+
default_attribute = ActiveModel::Attribute.from_database(name, value, type)
|
260
261
|
end
|
261
262
|
_default_attributes[name] = default_attribute
|
262
263
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
# = Active Record Autosave Association
|
3
5
|
#
|
@@ -140,8 +142,7 @@ module ActiveRecord
|
|
140
142
|
|
141
143
|
included do
|
142
144
|
Associations::Builder::Association.extensions << AssociationBuilderExtension
|
143
|
-
mattr_accessor :index_nested_attribute_errors, instance_writer: false
|
144
|
-
self.index_nested_attribute_errors = false
|
145
|
+
mattr_accessor :index_nested_attribute_errors, instance_writer: false, default: false
|
145
146
|
end
|
146
147
|
|
147
148
|
module ClassMethods # :nodoc:
|
@@ -216,13 +217,7 @@ module ActiveRecord
|
|
216
217
|
method = :validate_single_association
|
217
218
|
end
|
218
219
|
|
219
|
-
define_non_cyclic_method(validation_method)
|
220
|
-
send(method, reflection)
|
221
|
-
# TODO: remove the following line as soon as the return value of
|
222
|
-
# callbacks is ignored, that is, returning `false` does not
|
223
|
-
# display a deprecation warning or halts the callback chain.
|
224
|
-
true
|
225
|
-
end
|
220
|
+
define_non_cyclic_method(validation_method) { send(method, reflection) }
|
226
221
|
validate validation_method
|
227
222
|
after_validation :_ensure_no_duplicate_errors
|
228
223
|
end
|
@@ -369,7 +364,6 @@ module ActiveRecord
|
|
369
364
|
# association whether or not the parent was a new record before saving.
|
370
365
|
def before_save_collection_association
|
371
366
|
@new_record_before_save = new_record?
|
372
|
-
true
|
373
367
|
end
|
374
368
|
|
375
369
|
def after_save_collection_association
|
@@ -389,7 +383,7 @@ module ActiveRecord
|
|
389
383
|
autosave = reflection.options[:autosave]
|
390
384
|
|
391
385
|
# reconstruct the scope now that we know the owner's id
|
392
|
-
association.reset_scope
|
386
|
+
association.reset_scope
|
393
387
|
|
394
388
|
if records = associated_records_to_validate_or_save(association, @new_record_before_save, autosave)
|
395
389
|
if autosave
|
data/lib/active_record/base.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
# = Active Record \Callbacks
|
3
5
|
#
|
@@ -96,9 +98,9 @@ module ActiveRecord
|
|
96
98
|
# == Types of callbacks
|
97
99
|
#
|
98
100
|
# There are four types of callbacks accepted by the callback macros: Method references (symbol), callback objects,
|
99
|
-
# inline methods (using a proc)
|
101
|
+
# inline methods (using a proc). Method references and callback objects
|
100
102
|
# are the recommended approaches, inline methods using a proc are sometimes appropriate (such as for
|
101
|
-
# creating mix-ins)
|
103
|
+
# creating mix-ins).
|
102
104
|
#
|
103
105
|
# The method reference callbacks work by specifying a protected or private method available in the object, like this:
|
104
106
|
#
|
@@ -238,7 +240,7 @@ module ActiveRecord
|
|
238
240
|
#
|
239
241
|
# private
|
240
242
|
#
|
241
|
-
# def
|
243
|
+
# def log_children
|
242
244
|
# # Child processing
|
243
245
|
# end
|
244
246
|
#
|
@@ -263,7 +265,7 @@ module ActiveRecord
|
|
263
265
|
#
|
264
266
|
# private
|
265
267
|
#
|
266
|
-
# def
|
268
|
+
# def log_children
|
267
269
|
# # Child processing
|
268
270
|
# end
|
269
271
|
#
|
@@ -330,10 +332,6 @@ module ActiveRecord
|
|
330
332
|
_run_touch_callbacks { super }
|
331
333
|
end
|
332
334
|
|
333
|
-
def increment!(attribute, by = 1, touch: nil) # :nodoc:
|
334
|
-
touch ? _run_touch_callbacks { super } : super
|
335
|
-
end
|
336
|
-
|
337
335
|
private
|
338
336
|
|
339
337
|
def create_or_update(*)
|
@@ -1,17 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module CollectionCacheKey
|
3
5
|
def collection_cache_key(collection = all, timestamp_column = :updated_at) # :nodoc:
|
4
6
|
query_signature = Digest::MD5.hexdigest(collection.to_sql)
|
5
7
|
key = "#{collection.model_name.cache_key}/query-#{query_signature}"
|
6
8
|
|
7
|
-
if collection.loaded?
|
8
|
-
size = collection.
|
9
|
+
if collection.loaded?
|
10
|
+
size = collection.size
|
9
11
|
if size > 0
|
10
12
|
timestamp = collection.max_by(×tamp_column)._read_attribute(timestamp_column)
|
11
13
|
end
|
12
14
|
else
|
15
|
+
if collection.eager_loading?
|
16
|
+
collection = collection.send(:apply_join_dependency)
|
17
|
+
end
|
13
18
|
column_type = type_for_attribute(timestamp_column.to_s)
|
14
|
-
column =
|
19
|
+
column = connection.column_name_from_arel_node(collection.arel_attribute(timestamp_column))
|
15
20
|
select_values = "COUNT(*) AS #{connection.quote_column_name("size")}, MAX(%s) AS timestamp"
|
16
21
|
|
17
22
|
if collection.has_limit_or_offset?
|
@@ -20,14 +25,14 @@ module ActiveRecord
|
|
20
25
|
subquery_alias = "subquery_for_cache_key"
|
21
26
|
subquery_column = "#{subquery_alias}.#{timestamp_column}"
|
22
27
|
subquery = query.arel.as(subquery_alias)
|
23
|
-
arel = Arel::SelectManager.new(
|
28
|
+
arel = Arel::SelectManager.new(subquery).project(select_values % subquery_column)
|
24
29
|
else
|
25
30
|
query = collection.unscope(:order)
|
26
31
|
query.select_values = [select_values % column]
|
27
32
|
arel = query.arel
|
28
33
|
end
|
29
34
|
|
30
|
-
result = connection.select_one(arel, nil
|
35
|
+
result = connection.select_one(arel, nil)
|
31
36
|
|
32
37
|
if result.blank?
|
33
38
|
size = 0
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "thread"
|
2
4
|
require "concurrent/map"
|
3
5
|
require "monitor"
|
@@ -61,15 +63,13 @@ module ActiveRecord
|
|
61
63
|
# There are several connection-pooling-related options that you can add to
|
62
64
|
# your database connection configuration:
|
63
65
|
#
|
64
|
-
# * +pool+: number
|
65
|
-
# * +
|
66
|
-
#
|
67
|
-
#
|
68
|
-
#
|
69
|
-
#
|
70
|
-
#
|
71
|
-
# Regardless of this setting, the Reaper will be invoked before every
|
72
|
-
# blocking wait. (Default +nil+, which means don't schedule the Reaper).
|
66
|
+
# * +pool+: maximum number of connections the pool may manage (default 5).
|
67
|
+
# * +idle_timeout+: number of seconds that a connection will be kept
|
68
|
+
# unused in the pool before it is automatically disconnected (default
|
69
|
+
# 300 seconds). Set this to zero to keep connections forever.
|
70
|
+
# * +checkout_timeout+: number of seconds to wait for a connection to
|
71
|
+
# become available before giving up and raising a timeout error (default
|
72
|
+
# 5 seconds).
|
73
73
|
#
|
74
74
|
#--
|
75
75
|
# Synchronization policy:
|
@@ -80,11 +80,8 @@ module ActiveRecord
|
|
80
80
|
# * private methods that require being called in a +synchronize+ blocks
|
81
81
|
# are now explicitly documented
|
82
82
|
class ConnectionPool
|
83
|
-
# Threadsafe, fair,
|
84
|
-
# with which it shares a Monitor.
|
85
|
-
#
|
86
|
-
# The Queue in stdlib's 'thread' could replace this class except
|
87
|
-
# stdlib's doesn't support waiting with a timeout.
|
83
|
+
# Threadsafe, fair, LIFO queue. Meant to be used by ConnectionPool
|
84
|
+
# with which it shares a Monitor.
|
88
85
|
class Queue
|
89
86
|
def initialize(lock = Monitor.new)
|
90
87
|
@lock = lock
|
@@ -173,7 +170,7 @@ module ActiveRecord
|
|
173
170
|
|
174
171
|
# Removes and returns the head of the queue if possible, or +nil+.
|
175
172
|
def remove
|
176
|
-
@queue.
|
173
|
+
@queue.pop
|
177
174
|
end
|
178
175
|
|
179
176
|
# Remove and return the head the queue if the number of
|
@@ -191,9 +188,7 @@ module ActiveRecord
|
|
191
188
|
t0 = Time.now
|
192
189
|
elapsed = 0
|
193
190
|
loop do
|
194
|
-
|
195
|
-
@cond.wait(timeout - elapsed)
|
196
|
-
end
|
191
|
+
@cond.wait(timeout - elapsed)
|
197
192
|
|
198
193
|
return remove if any?
|
199
194
|
|
@@ -270,7 +265,7 @@ module ActiveRecord
|
|
270
265
|
# Connections must be leased while holding the main pool mutex. This is
|
271
266
|
# an internal subclass that also +.leases+ returned connections while
|
272
267
|
# still in queue's critical section (queue synchronizes with the same
|
273
|
-
#
|
268
|
+
# <tt>@lock</tt> as the main pool) so that a returned connection is already
|
274
269
|
# leased and there is no need to re-enter synchronized block.
|
275
270
|
class ConnectionLeasingQueue < Queue # :nodoc:
|
276
271
|
include BiasableQueue
|
@@ -283,12 +278,12 @@ module ActiveRecord
|
|
283
278
|
end
|
284
279
|
end
|
285
280
|
|
286
|
-
# Every +frequency+ seconds, the reaper will call +reap+
|
287
|
-
# A reaper instantiated with a
|
288
|
-
# connection pool.
|
281
|
+
# Every +frequency+ seconds, the reaper will call +reap+ and +flush+ on
|
282
|
+
# +pool+. A reaper instantiated with a zero frequency will never reap
|
283
|
+
# the connection pool.
|
289
284
|
#
|
290
|
-
# Configure the frequency by setting
|
291
|
-
#
|
285
|
+
# Configure the frequency by setting +reaping_frequency+ in your database
|
286
|
+
# yaml file (default 60 seconds).
|
292
287
|
class Reaper
|
293
288
|
attr_reader :pool, :frequency
|
294
289
|
|
@@ -298,11 +293,12 @@ module ActiveRecord
|
|
298
293
|
end
|
299
294
|
|
300
295
|
def run
|
301
|
-
return unless frequency
|
296
|
+
return unless frequency && frequency > 0
|
302
297
|
Thread.new(frequency, pool) { |t, p|
|
303
298
|
loop do
|
304
299
|
sleep t
|
305
300
|
p.reap
|
301
|
+
p.flush
|
306
302
|
end
|
307
303
|
}
|
308
304
|
end
|
@@ -326,8 +322,10 @@ module ActiveRecord
|
|
326
322
|
@spec = spec
|
327
323
|
|
328
324
|
@checkout_timeout = (spec.config[:checkout_timeout] && spec.config[:checkout_timeout].to_f) || 5
|
329
|
-
@
|
330
|
-
|
325
|
+
if @idle_timeout = spec.config.fetch(:idle_timeout, 300)
|
326
|
+
@idle_timeout = @idle_timeout.to_f
|
327
|
+
@idle_timeout = nil if @idle_timeout <= 0
|
328
|
+
end
|
331
329
|
|
332
330
|
# default max pool size to 5
|
333
331
|
@size = (spec.config[:pool] && spec.config[:pool].to_i) || 5
|
@@ -340,7 +338,7 @@ module ActiveRecord
|
|
340
338
|
# then that +thread+ does indeed own that +conn+. However, an absence of a such
|
341
339
|
# mapping does not mean that the +thread+ doesn't own the said connection. In
|
342
340
|
# that case +conn.owner+ attr should be consulted.
|
343
|
-
# Access and modification of
|
341
|
+
# Access and modification of <tt>@thread_cached_conns</tt> does not require
|
344
342
|
# synchronization.
|
345
343
|
@thread_cached_conns = Concurrent::Map.new(initial_capacity: @size)
|
346
344
|
|
@@ -357,6 +355,12 @@ module ActiveRecord
|
|
357
355
|
@available = ConnectionLeasingQueue.new self
|
358
356
|
|
359
357
|
@lock_thread = false
|
358
|
+
|
359
|
+
# +reaping_frequency+ is configurable mostly for historical reasons, but it could
|
360
|
+
# also be useful if someone wants a very low +idle_timeout+.
|
361
|
+
reaping_frequency = spec.config.fetch(:reaping_frequency, 60)
|
362
|
+
@reaper = Reaper.new(self, reaping_frequency && reaping_frequency.to_f)
|
363
|
+
@reaper.run
|
360
364
|
end
|
361
365
|
|
362
366
|
def lock_thread=(lock_thread)
|
@@ -449,6 +453,21 @@ module ActiveRecord
|
|
449
453
|
disconnect(false)
|
450
454
|
end
|
451
455
|
|
456
|
+
# Discards all connections in the pool (even if they're currently
|
457
|
+
# leased!), along with the pool itself. Any further interaction with the
|
458
|
+
# pool (except #spec and #schema_cache) is undefined.
|
459
|
+
#
|
460
|
+
# See AbstractAdapter#discard!
|
461
|
+
def discard! # :nodoc:
|
462
|
+
synchronize do
|
463
|
+
return if @connections.nil? # already discarded
|
464
|
+
@connections.each do |conn|
|
465
|
+
conn.discard!
|
466
|
+
end
|
467
|
+
@connections = @available = @thread_cached_conns = nil
|
468
|
+
end
|
469
|
+
end
|
470
|
+
|
452
471
|
# Clears the cache which maps classes and re-connects connections that
|
453
472
|
# require reloading.
|
454
473
|
#
|
@@ -574,6 +593,35 @@ module ActiveRecord
|
|
574
593
|
end
|
575
594
|
end
|
576
595
|
|
596
|
+
# Disconnect all connections that have been idle for at least
|
597
|
+
# +minimum_idle+ seconds. Connections currently checked out, or that were
|
598
|
+
# checked in less than +minimum_idle+ seconds ago, are unaffected.
|
599
|
+
def flush(minimum_idle = @idle_timeout)
|
600
|
+
return if minimum_idle.nil?
|
601
|
+
|
602
|
+
idle_connections = synchronize do
|
603
|
+
@connections.select do |conn|
|
604
|
+
!conn.in_use? && conn.seconds_idle >= minimum_idle
|
605
|
+
end.each do |conn|
|
606
|
+
conn.lease
|
607
|
+
|
608
|
+
@available.delete conn
|
609
|
+
@connections.delete conn
|
610
|
+
end
|
611
|
+
end
|
612
|
+
|
613
|
+
idle_connections.each do |conn|
|
614
|
+
conn.disconnect!
|
615
|
+
end
|
616
|
+
end
|
617
|
+
|
618
|
+
# Disconnect all currently idle connections. Connections currently checked
|
619
|
+
# out are unaffected.
|
620
|
+
def flush!
|
621
|
+
reap
|
622
|
+
flush(-1)
|
623
|
+
end
|
624
|
+
|
577
625
|
def num_waiting_in_queue # :nodoc:
|
578
626
|
@available.num_waiting
|
579
627
|
end
|
@@ -681,7 +729,7 @@ module ActiveRecord
|
|
681
729
|
# this block can't be easily moved into attempt_to_checkout_all_existing_connections's
|
682
730
|
# rescue block, because doing so would put it outside of synchronize section, without
|
683
731
|
# being in a critical section thread_report might become inaccurate
|
684
|
-
msg = "could not obtain ownership of all database connections in #{checkout_timeout} seconds"
|
732
|
+
msg = "could not obtain ownership of all database connections in #{checkout_timeout} seconds".dup
|
685
733
|
|
686
734
|
thread_report = []
|
687
735
|
@connections.each do |conn|
|
@@ -736,10 +784,10 @@ module ActiveRecord
|
|
736
784
|
# Implementation detail: the connection returned by +acquire_connection+
|
737
785
|
# will already be "+connection.lease+ -ed" to the current thread.
|
738
786
|
def acquire_connection(checkout_timeout)
|
739
|
-
# NOTE: we rely on
|
787
|
+
# NOTE: we rely on <tt>@available.poll</tt> and +try_to_checkout_new_connection+ to
|
740
788
|
# +conn.lease+ the returned connection (and to do this in a +synchronized+
|
741
789
|
# section). This is not the cleanest implementation, as ideally we would
|
742
|
-
# <tt>synchronize { conn.lease }</tt> in this method, but by leaving it to
|
790
|
+
# <tt>synchronize { conn.lease }</tt> in this method, but by leaving it to <tt>@available.poll</tt>
|
743
791
|
# and +try_to_checkout_new_connection+ we can piggyback on +synchronize+ sections
|
744
792
|
# of the said methods and avoid an additional +synchronize+ overhead.
|
745
793
|
if conn = @available.poll || try_to_checkout_new_connection
|
@@ -763,7 +811,7 @@ module ActiveRecord
|
|
763
811
|
end
|
764
812
|
end
|
765
813
|
|
766
|
-
# If the pool is not at a
|
814
|
+
# If the pool is not at a <tt>@size</tt> limit, establish new connection. Connecting
|
767
815
|
# to the DB is done outside main synchronized section.
|
768
816
|
#--
|
769
817
|
# Implementation constraint: a newly established connection returned by this
|
@@ -829,7 +877,7 @@ module ActiveRecord
|
|
829
877
|
# end
|
830
878
|
#
|
831
879
|
# class Book < ActiveRecord::Base
|
832
|
-
# establish_connection
|
880
|
+
# establish_connection :library_db
|
833
881
|
# end
|
834
882
|
#
|
835
883
|
# class ScaryBook < Book
|
@@ -861,15 +909,35 @@ module ActiveRecord
|
|
861
909
|
# All Active Record models use this handler to determine the connection pool that they
|
862
910
|
# should use.
|
863
911
|
#
|
864
|
-
# The ConnectionHandler class is not coupled with the Active models, as it has no
|
912
|
+
# The ConnectionHandler class is not coupled with the Active models, as it has no knowledge
|
865
913
|
# about the model. The model needs to pass a specification name to the handler,
|
866
|
-
# in order to
|
914
|
+
# in order to look up the correct connection pool.
|
867
915
|
class ConnectionHandler
|
916
|
+
def self.unowned_pool_finalizer(pid_map) # :nodoc:
|
917
|
+
lambda do |_|
|
918
|
+
discard_unowned_pools(pid_map)
|
919
|
+
end
|
920
|
+
end
|
921
|
+
|
922
|
+
def self.discard_unowned_pools(pid_map) # :nodoc:
|
923
|
+
pid_map.each do |pid, pools|
|
924
|
+
pools.values.compact.each(&:discard!) unless pid == Process.pid
|
925
|
+
end
|
926
|
+
end
|
927
|
+
|
868
928
|
def initialize
|
869
929
|
# These caches are keyed by spec.name (ConnectionSpecification#name).
|
870
930
|
@owner_to_pool = Concurrent::Map.new(initial_capacity: 2) do |h, k|
|
931
|
+
# Discard the parent's connection pools immediately; we have no need
|
932
|
+
# of them
|
933
|
+
ConnectionHandler.discard_unowned_pools(h)
|
934
|
+
|
871
935
|
h[k] = Concurrent::Map.new(initial_capacity: 2)
|
872
936
|
end
|
937
|
+
|
938
|
+
# Backup finalizer: if the forked child never needed a pool, the above
|
939
|
+
# early discard has not occurred
|
940
|
+
ObjectSpace.define_finalizer self, ConnectionHandler.unowned_pool_finalizer(@owner_to_pool)
|
873
941
|
end
|
874
942
|
|
875
943
|
def connection_pool_list
|
@@ -923,6 +991,13 @@ module ActiveRecord
|
|
923
991
|
connection_pool_list.each(&:disconnect!)
|
924
992
|
end
|
925
993
|
|
994
|
+
# Disconnects all currently idle connections.
|
995
|
+
#
|
996
|
+
# See ConnectionPool#flush! for details.
|
997
|
+
def flush_idle_connections!
|
998
|
+
connection_pool_list.each(&:flush!)
|
999
|
+
end
|
1000
|
+
|
926
1001
|
# Locate the connection of the nearest super class. This can be an
|
927
1002
|
# active or defined connection: if it is the latter, it will be
|
928
1003
|
# opened and set as the active connection for the class it was defined
|