activerecord 5.1.7 → 5.2.6
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 +583 -673
- 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/aggregations.rb +6 -5
- data/lib/active_record/association_relation.rb +7 -5
- data/lib/active_record/associations/alias_tracker.rb +19 -27
- data/lib/active_record/associations/association.rb +41 -37
- data/lib/active_record/associations/association_scope.rb +38 -50
- data/lib/active_record/associations/belongs_to_association.rb +27 -8
- 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 +12 -4
- data/lib/active_record/associations/builder/collection_association.rb +3 -3
- 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 +59 -47
- data/lib/active_record/associations/collection_proxy.rb +20 -49
- data/lib/active_record/associations/foreign_association.rb +2 -0
- data/lib/active_record/associations/has_many_association.rb +12 -1
- data/lib/active_record/associations/has_many_through_association.rb +36 -30
- data/lib/active_record/associations/has_one_association.rb +12 -1
- data/lib/active_record/associations/has_one_through_association.rb +13 -8
- data/lib/active_record/associations/join_dependency/join_association.rb +39 -63
- 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/join_dependency.rb +48 -93
- data/lib/active_record/associations/preloader/association.rb +45 -61
- data/lib/active_record/associations/preloader/through_association.rb +71 -79
- data/lib/active_record/associations/preloader.rb +18 -38
- data/lib/active_record/associations/singular_association.rb +14 -16
- data/lib/active_record/associations/through_association.rb +26 -11
- data/lib/active_record/associations.rb +40 -63
- data/lib/active_record/attribute_assignment.rb +2 -5
- data/lib/active_record/attribute_decorators.rb +3 -2
- data/lib/active_record/attribute_methods/before_type_cast.rb +2 -0
- data/lib/active_record/attribute_methods/dirty.rb +30 -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 +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 +21 -9
- data/lib/active_record/attribute_methods.rb +65 -24
- data/lib/active_record/attributes.rb +6 -5
- data/lib/active_record/autosave_association.rb +35 -19
- data/lib/active_record/base.rb +2 -0
- data/lib/active_record/callbacks.rb +8 -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 +12 -8
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +139 -41
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +7 -0
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +174 -33
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +15 -5
- data/lib/active_record/connection_adapters/abstract/quoting.rb +13 -31
- data/lib/active_record/connection_adapters/abstract/savepoints.rb +2 -0
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +14 -5
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +64 -6
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +31 -53
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +152 -81
- data/lib/active_record/connection_adapters/abstract/transaction.rb +66 -21
- data/lib/active_record/connection_adapters/abstract_adapter.rb +84 -97
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +92 -165
- 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 +13 -2
- data/lib/active_record/connection_adapters/mysql/column.rb +2 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +47 -2
- 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 -30
- 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 +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/array.rb +2 -0
- 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 +2 -0
- 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 +5 -3
- 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 +4 -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/oid.rb +3 -1
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +18 -0
- 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 +233 -111
- 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 +57 -73
- 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 +22 -0
- 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 +81 -94
- 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 +10 -3
- 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 +42 -3
- 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 +14 -17
- data/lib/active_record/locking/pessimistic.rb +9 -6
- data/lib/active_record/log_subscriber.rb +43 -0
- data/lib/active_record/migration/command_recorder.rb +11 -9
- data/lib/active_record/migration/compatibility.rb +47 -9
- data/lib/active_record/migration/join_table.rb +2 -0
- data/lib/active_record/migration.rb +189 -139
- data/lib/active_record/model_schema.rb +16 -21
- 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 +167 -16
- data/lib/active_record/query_cache.rb +6 -8
- data/lib/active_record/querying.rb +4 -2
- 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 +46 -36
- data/lib/active_record/readonly_attributes.rb +3 -2
- data/lib/active_record/reflection.rb +108 -194
- data/lib/active_record/relation/batches/batch_enumerator.rb +2 -0
- data/lib/active_record/relation/batches.rb +20 -5
- data/lib/active_record/relation/calculations.rb +45 -19
- data/lib/active_record/relation/delegation.rb +45 -27
- data/lib/active_record/relation/finder_methods.rb +75 -76
- 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/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/predicate_builder.rb +60 -79
- data/lib/active_record/relation/query_attribute.rb +28 -2
- data/lib/active_record/relation/query_methods.rb +128 -99
- 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 -68
- data/lib/active_record/relation/where_clause_factory.rb +5 -48
- data/lib/active_record/relation.rb +120 -214
- 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/default.rb +8 -9
- data/lib/active_record/scoping/named.rb +23 -7
- data/lib/active_record/scoping.rb +9 -8
- data/lib/active_record/secure_token.rb +2 -0
- data/lib/active_record/serialization.rb +2 -0
- data/lib/active_record/statement_cache.rb +23 -13
- 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 +25 -14
- 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 +6 -6
- data/lib/active_record/touch_later.rb +2 -0
- data/lib/active_record/transactions.rb +33 -28
- data/lib/active_record/translation.rb +2 -0
- 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 -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.rb +4 -1
- data/lib/active_record/type_caster/connection.rb +2 -0
- data/lib/active_record/type_caster/map.rb +3 -1
- data/lib/active_record/type_caster.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 +35 -5
- data/lib/active_record/validations.rb +2 -0
- data/lib/active_record/version.rb +2 -0
- data/lib/active_record.rb +11 -4
- 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/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/migration.rb +2 -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
- data/lib/rails/generators/active_record.rb +3 -1
- metadata +23 -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/user_provided_default.rb +0 -30
- data/lib/active_record/attribute.rb +0 -240
- data/lib/active_record/attribute_mutation_tracker.rb +0 -122
- 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/attribute_set.rb +0 -113
- 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
|
module ActiveRecord
|
2
4
|
# Statement cache is used to cache a single statement in order to avoid creating the AST again.
|
3
5
|
# Initializing the cache is done by passing the statement in the create block:
|
@@ -9,7 +11,7 @@ module ActiveRecord
|
|
9
11
|
# The cached statement is executed by using the
|
10
12
|
# {connection.execute}[rdoc-ref:ConnectionAdapters::DatabaseStatements#execute] method:
|
11
13
|
#
|
12
|
-
# cache.execute([], Book
|
14
|
+
# cache.execute([], Book.connection)
|
13
15
|
#
|
14
16
|
# The relation returned by the block is cached, and for each
|
15
17
|
# {execute}[rdoc-ref:ConnectionAdapters::DatabaseStatements#execute]
|
@@ -24,7 +26,7 @@ module ActiveRecord
|
|
24
26
|
#
|
25
27
|
# And pass the bind values as the first argument of +execute+ call.
|
26
28
|
#
|
27
|
-
# cache.execute(["my book"], Book
|
29
|
+
# cache.execute(["my book"], Book.connection)
|
28
30
|
class StatementCache # :nodoc:
|
29
31
|
class Substitute; end # :nodoc:
|
30
32
|
|
@@ -85,27 +87,35 @@ module ActiveRecord
|
|
85
87
|
end
|
86
88
|
end
|
87
89
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
bind_map
|
93
|
-
query_builder = connection.cacheable_query(self, relation.arel)
|
94
|
-
new query_builder, bind_map
|
90
|
+
def self.create(connection, callable = nil, &block)
|
91
|
+
relation = (callable || block).call Params.new
|
92
|
+
query_builder, binds = connection.cacheable_query(self, relation.arel)
|
93
|
+
bind_map = BindMap.new(binds)
|
94
|
+
new(query_builder, bind_map, relation.klass)
|
95
95
|
end
|
96
96
|
|
97
|
-
def initialize(query_builder, bind_map)
|
97
|
+
def initialize(query_builder, bind_map, klass)
|
98
98
|
@query_builder = query_builder
|
99
|
-
@bind_map
|
99
|
+
@bind_map = bind_map
|
100
|
+
@klass = klass
|
100
101
|
end
|
101
102
|
|
102
|
-
def execute(params,
|
103
|
+
def execute(params, connection, &block)
|
103
104
|
bind_values = bind_map.bind params
|
104
105
|
|
105
106
|
sql = query_builder.sql_for bind_values, connection
|
106
107
|
|
107
108
|
klass.find_by_sql(sql, bind_values, preparable: true, &block)
|
108
109
|
end
|
109
|
-
|
110
|
+
|
111
|
+
def self.unsupported_value?(value)
|
112
|
+
case value
|
113
|
+
when NilClass, Array, Range, Hash, Relation, Base then true
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
protected
|
118
|
+
|
119
|
+
attr_reader :query_builder, :bind_map, :klass
|
110
120
|
end
|
111
121
|
end
|
data/lib/active_record/store.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support/core_ext/hash/indifferent_access"
|
2
4
|
|
3
5
|
module ActiveRecord
|
@@ -133,7 +135,7 @@ module ActiveRecord
|
|
133
135
|
end
|
134
136
|
|
135
137
|
def store_accessor_for(store_attribute)
|
136
|
-
type_for_attribute(store_attribute
|
138
|
+
type_for_attribute(store_attribute).accessor
|
137
139
|
end
|
138
140
|
|
139
141
|
class HashAccessor # :nodoc:
|
@@ -1,7 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
class TableMetadata # :nodoc:
|
3
|
-
delegate :foreign_type, :foreign_key, to: :association, prefix: true
|
4
|
-
delegate :association_primary_key, to: :association
|
5
|
+
delegate :foreign_type, :foreign_key, :join_primary_key, :join_foreign_key, to: :association, prefix: true
|
5
6
|
|
6
7
|
def initialize(klass, arel_table, association = nil)
|
7
8
|
@klass = klass
|
@@ -29,7 +30,7 @@ module ActiveRecord
|
|
29
30
|
|
30
31
|
def type(column_name)
|
31
32
|
if klass
|
32
|
-
klass.type_for_attribute(column_name
|
33
|
+
klass.type_for_attribute(column_name)
|
33
34
|
else
|
34
35
|
Type.default_value
|
35
36
|
end
|
@@ -64,6 +65,14 @@ module ActiveRecord
|
|
64
65
|
association && association.polymorphic?
|
65
66
|
end
|
66
67
|
|
68
|
+
def aggregated_with?(aggregation_name)
|
69
|
+
klass && reflect_on_aggregation(aggregation_name)
|
70
|
+
end
|
71
|
+
|
72
|
+
def reflect_on_aggregation(aggregation_name)
|
73
|
+
klass.reflect_on_aggregation(aggregation_name)
|
74
|
+
end
|
75
|
+
|
67
76
|
# TODO Change this to private once we've dropped Ruby 2.2 support.
|
68
77
|
# Workaround for Ruby 2.2 "private attribute?" warning.
|
69
78
|
protected
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module Tasks # :nodoc:
|
3
5
|
class DatabaseAlreadyExists < StandardError; end # :nodoc:
|
@@ -52,10 +54,10 @@ module ActiveRecord
|
|
52
54
|
|
53
55
|
def check_protected_environments!
|
54
56
|
unless ENV["DISABLE_DATABASE_ENVIRONMENT_CHECK"]
|
55
|
-
current = ActiveRecord::
|
56
|
-
stored = ActiveRecord::
|
57
|
+
current = ActiveRecord::Base.connection.migration_context.current_environment
|
58
|
+
stored = ActiveRecord::Base.connection.migration_context.last_stored_environment
|
57
59
|
|
58
|
-
if ActiveRecord::
|
60
|
+
if ActiveRecord::Base.connection.migration_context.protected_environment?
|
59
61
|
raise ActiveRecord::ProtectedEnvironmentError.new(stored)
|
60
62
|
end
|
61
63
|
|
@@ -71,9 +73,9 @@ module ActiveRecord
|
|
71
73
|
@tasks[pattern] = task
|
72
74
|
end
|
73
75
|
|
74
|
-
register_task(/mysql/, ActiveRecord::Tasks::MySQLDatabaseTasks)
|
75
|
-
register_task(/postgresql/, ActiveRecord::Tasks::PostgreSQLDatabaseTasks)
|
76
|
-
register_task(/sqlite/, ActiveRecord::Tasks::SQLiteDatabaseTasks)
|
76
|
+
register_task(/mysql/, "ActiveRecord::Tasks::MySQLDatabaseTasks")
|
77
|
+
register_task(/postgresql/, "ActiveRecord::Tasks::PostgreSQLDatabaseTasks")
|
78
|
+
register_task(/sqlite/, "ActiveRecord::Tasks::SQLiteDatabaseTasks")
|
77
79
|
|
78
80
|
def db_dir
|
79
81
|
@db_dir ||= Rails.application.config.paths["db"].first
|
@@ -162,13 +164,12 @@ module ActiveRecord
|
|
162
164
|
end
|
163
165
|
|
164
166
|
def migrate
|
165
|
-
|
167
|
+
check_target_version
|
166
168
|
|
167
|
-
verbose = ENV["VERBOSE"] ? ENV["VERBOSE"]
|
168
|
-
version = ENV["VERSION"] ? ENV["VERSION"].to_i : nil
|
169
|
+
verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] != "false" : true
|
169
170
|
scope = ENV["SCOPE"]
|
170
171
|
verbose_was, Migration.verbose = Migration.verbose, verbose
|
171
|
-
|
172
|
+
Base.connection.migration_context.migrate(target_version) do |migration|
|
172
173
|
scope.blank? || scope == migration.scope
|
173
174
|
end
|
174
175
|
ActiveRecord::Base.clear_cache!
|
@@ -176,6 +177,16 @@ module ActiveRecord
|
|
176
177
|
Migration.verbose = verbose_was
|
177
178
|
end
|
178
179
|
|
180
|
+
def check_target_version
|
181
|
+
if target_version && !(Migration::MigrationFilenameRegexp.match?(ENV["VERSION"]) || /\A\d+\z/.match?(ENV["VERSION"]))
|
182
|
+
raise "Invalid format of target version: `VERSION=#{ENV['VERSION']}`"
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
def target_version
|
187
|
+
ENV["VERSION"].to_i if ENV["VERSION"] && !ENV["VERSION"].empty?
|
188
|
+
end
|
189
|
+
|
179
190
|
def charset_current(environment = env)
|
180
191
|
charset ActiveRecord::Base.configurations[environment]
|
181
192
|
end
|
@@ -259,7 +270,7 @@ module ActiveRecord
|
|
259
270
|
|
260
271
|
def check_schema_file(filename)
|
261
272
|
unless File.exist?(filename)
|
262
|
-
message = %{#{filename} doesn't exist yet. Run `rails db:migrate` to create it, then try again.}
|
273
|
+
message = %{#{filename} doesn't exist yet. Run `rails db:migrate` to create it, then try again.}.dup
|
263
274
|
message << %{ If you do not intend to use a database, you should instead alter #{Rails.root}/config/application.rb to limit the frameworks that will be loaded.} if defined?(::Rails.root)
|
264
275
|
Kernel.abort message
|
265
276
|
end
|
@@ -288,11 +299,11 @@ module ActiveRecord
|
|
288
299
|
private
|
289
300
|
|
290
301
|
def class_for_adapter(adapter)
|
291
|
-
|
292
|
-
unless
|
302
|
+
_key, task = @tasks.each_pair.detect { |pattern, _task| adapter[pattern] }
|
303
|
+
unless task
|
293
304
|
raise DatabaseNotSupported, "Rake tasks not supported by '#{adapter}' adapter"
|
294
305
|
end
|
295
|
-
|
306
|
+
task.is_a?(String) ? task.constantize : task
|
296
307
|
end
|
297
308
|
|
298
309
|
def each_current_configuration(environment)
|
@@ -1,8 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module Tasks # :nodoc:
|
3
5
|
class MySQLDatabaseTasks # :nodoc:
|
4
|
-
ACCESS_DENIED_ERROR = 1045
|
5
|
-
|
6
6
|
delegate :connection, :establish_connection, to: ActiveRecord::Base
|
7
7
|
|
8
8
|
def initialize(configuration)
|
@@ -19,20 +19,6 @@ module ActiveRecord
|
|
19
19
|
else
|
20
20
|
raise
|
21
21
|
end
|
22
|
-
rescue error_class => error
|
23
|
-
if error.respond_to?(:errno) && error.errno == ACCESS_DENIED_ERROR
|
24
|
-
$stdout.print error.message
|
25
|
-
establish_connection root_configuration_without_database
|
26
|
-
connection.create_database configuration["database"], creation_options
|
27
|
-
if configuration["username"] != "root"
|
28
|
-
connection.execute grant_statement.gsub(/\s+/, " ").strip
|
29
|
-
end
|
30
|
-
establish_connection configuration
|
31
|
-
else
|
32
|
-
$stderr.puts error.inspect
|
33
|
-
$stderr.puts "Couldn't create database for #{configuration.inspect}, #{creation_options.inspect}"
|
34
|
-
$stderr.puts "(If you set the charset manually, make sure you have a matching collation)" if configuration["encoding"]
|
35
|
-
end
|
36
22
|
end
|
37
23
|
|
38
24
|
def drop
|
@@ -59,6 +45,12 @@ module ActiveRecord
|
|
59
45
|
args.concat(["--no-data"])
|
60
46
|
args.concat(["--routines"])
|
61
47
|
args.concat(["--skip-comments"])
|
48
|
+
|
49
|
+
ignore_tables = ActiveRecord::SchemaDumper.ignore_tables
|
50
|
+
if ignore_tables.any?
|
51
|
+
args += ignore_tables.map { |table| "--ignore-table=#{configuration['database']}.#{table}" }
|
52
|
+
end
|
53
|
+
|
62
54
|
args.concat(["#{configuration['database']}"])
|
63
55
|
args.unshift(*extra_flags) if extra_flags
|
64
56
|
|
@@ -91,37 +83,6 @@ module ActiveRecord
|
|
91
83
|
end
|
92
84
|
end
|
93
85
|
|
94
|
-
def error_class
|
95
|
-
if configuration["adapter"].include?("jdbc")
|
96
|
-
require "active_record/railties/jdbcmysql_error"
|
97
|
-
ArJdbcMySQL::Error
|
98
|
-
elsif defined?(Mysql2)
|
99
|
-
Mysql2::Error
|
100
|
-
else
|
101
|
-
StandardError
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
def grant_statement
|
106
|
-
<<-SQL
|
107
|
-
GRANT ALL PRIVILEGES ON `#{configuration['database']}`.*
|
108
|
-
TO '#{configuration['username']}'@'localhost'
|
109
|
-
IDENTIFIED BY '#{configuration['password']}' WITH GRANT OPTION;
|
110
|
-
SQL
|
111
|
-
end
|
112
|
-
|
113
|
-
def root_configuration_without_database
|
114
|
-
configuration_without_database.merge(
|
115
|
-
"username" => "root",
|
116
|
-
"password" => root_password
|
117
|
-
)
|
118
|
-
end
|
119
|
-
|
120
|
-
def root_password
|
121
|
-
$stdout.print "Please provide the root password for your MySQL installation\n>"
|
122
|
-
$stdin.gets.strip
|
123
|
-
end
|
124
|
-
|
125
86
|
def prepare_command_options
|
126
87
|
args = {
|
127
88
|
"host" => "--host",
|
@@ -145,7 +106,7 @@ IDENTIFIED BY '#{configuration['password']}' WITH GRANT OPTION;
|
|
145
106
|
end
|
146
107
|
|
147
108
|
def run_cmd_error(cmd, args, action)
|
148
|
-
msg = "failed to execute: `#{cmd}`\n"
|
109
|
+
msg = "failed to execute: `#{cmd}`\n".dup
|
149
110
|
msg << "Please check the output above for any errors and make sure that `#{cmd}` is installed in your PATH and has proper permissions.\n\n"
|
150
111
|
msg
|
151
112
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "tempfile"
|
2
4
|
|
3
5
|
module ActiveRecord
|
@@ -66,6 +68,12 @@ module ActiveRecord
|
|
66
68
|
"--schema=#{part.strip}"
|
67
69
|
end
|
68
70
|
end
|
71
|
+
|
72
|
+
ignore_tables = ActiveRecord::SchemaDumper.ignore_tables
|
73
|
+
if ignore_tables.any?
|
74
|
+
args += ignore_tables.flat_map { |table| ["-T", table] }
|
75
|
+
end
|
76
|
+
|
69
77
|
args << configuration["database"]
|
70
78
|
run_cmd("pg_dump", args, "dumping")
|
71
79
|
remove_sql_header_comments(filename)
|
@@ -109,7 +117,7 @@ module ActiveRecord
|
|
109
117
|
end
|
110
118
|
|
111
119
|
def run_cmd_error(cmd, args, action)
|
112
|
-
msg = "failed to execute:\n"
|
120
|
+
msg = "failed to execute:\n".dup
|
113
121
|
msg << "#{cmd} #{args.join(' ')}\n\n"
|
114
122
|
msg << "Please check the output above for any errors and make sure that `#{cmd}` is installed in your PATH and has proper permissions.\n\n"
|
115
123
|
msg
|
@@ -128,7 +136,7 @@ module ActiveRecord
|
|
128
136
|
ensure
|
129
137
|
tempfile.close
|
130
138
|
end
|
131
|
-
FileUtils.
|
139
|
+
FileUtils.cp(tempfile.path, filename)
|
132
140
|
end
|
133
141
|
end
|
134
142
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
module Tasks # :nodoc:
|
3
5
|
class SQLiteDatabaseTasks # :nodoc:
|
@@ -36,9 +38,18 @@ module ActiveRecord
|
|
36
38
|
end
|
37
39
|
|
38
40
|
def structure_dump(filename, extra_flags)
|
39
|
-
|
40
|
-
|
41
|
-
|
41
|
+
args = []
|
42
|
+
args.concat(Array(extra_flags)) if extra_flags
|
43
|
+
args << configuration["database"]
|
44
|
+
|
45
|
+
ignore_tables = ActiveRecord::SchemaDumper.ignore_tables
|
46
|
+
if ignore_tables.any?
|
47
|
+
condition = ignore_tables.map { |table| connection.quote(table) }.join(", ")
|
48
|
+
args << "SELECT sql FROM sqlite_master WHERE tbl_name NOT IN (#{condition}) ORDER BY tbl_name, type DESC, name"
|
49
|
+
else
|
50
|
+
args << ".schema"
|
51
|
+
end
|
52
|
+
run_cmd("sqlite3", args, filename)
|
42
53
|
end
|
43
54
|
|
44
55
|
def structure_load(filename, extra_flags)
|
@@ -56,6 +67,17 @@ module ActiveRecord
|
|
56
67
|
def root
|
57
68
|
@root
|
58
69
|
end
|
70
|
+
|
71
|
+
def run_cmd(cmd, args, out)
|
72
|
+
fail run_cmd_error(cmd, args) unless Kernel.system(cmd, *args, out: out)
|
73
|
+
end
|
74
|
+
|
75
|
+
def run_cmd_error(cmd, args)
|
76
|
+
msg = "failed to execute:\n".dup
|
77
|
+
msg << "#{cmd} #{args.join(' ')}\n\n"
|
78
|
+
msg << "Please check the output above for any errors and make sure that `#{cmd}` is installed in your PATH and has proper permissions.\n\n"
|
79
|
+
msg
|
80
|
+
end
|
59
81
|
end
|
60
82
|
end
|
61
83
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module ActiveRecord
|
3
4
|
# = Active Record \Timestamp
|
4
5
|
#
|
@@ -43,8 +44,7 @@ module ActiveRecord
|
|
43
44
|
extend ActiveSupport::Concern
|
44
45
|
|
45
46
|
included do
|
46
|
-
class_attribute :record_timestamps
|
47
|
-
self.record_timestamps = true
|
47
|
+
class_attribute :record_timestamps, default: true
|
48
48
|
end
|
49
49
|
|
50
50
|
def initialize_dup(other) # :nodoc:
|
@@ -52,7 +52,7 @@ module ActiveRecord
|
|
52
52
|
clear_timestamp_attributes
|
53
53
|
end
|
54
54
|
|
55
|
-
|
55
|
+
module ClassMethods # :nodoc:
|
56
56
|
def touch_attributes_with_time(*names, time: nil)
|
57
57
|
attribute_names = timestamp_attributes_for_update_in_model
|
58
58
|
attribute_names |= names.map(&:to_s)
|
@@ -94,7 +94,7 @@ module ActiveRecord
|
|
94
94
|
|
95
95
|
all_timestamp_attributes_in_model.each do |column|
|
96
96
|
if !attribute_present?(column)
|
97
|
-
|
97
|
+
_write_attribute(column, current_time)
|
98
98
|
end
|
99
99
|
end
|
100
100
|
end
|
@@ -108,7 +108,7 @@ module ActiveRecord
|
|
108
108
|
|
109
109
|
timestamp_attributes_for_update_in_model.each do |column|
|
110
110
|
next if will_save_change_to_attribute?(column)
|
111
|
-
|
111
|
+
_write_attribute(column, current_time)
|
112
112
|
end
|
113
113
|
end
|
114
114
|
super(*args)
|
@@ -134,7 +134,7 @@ module ActiveRecord
|
|
134
134
|
self.class.send(:current_time_from_proper_timezone)
|
135
135
|
end
|
136
136
|
|
137
|
-
def max_updated_column_timestamp(timestamp_names =
|
137
|
+
def max_updated_column_timestamp(timestamp_names = timestamp_attributes_for_update_in_model)
|
138
138
|
timestamp_names
|
139
139
|
.map { |attr| self[attr] }
|
140
140
|
.compact
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveRecord
|
2
4
|
# See ActiveRecord::Transactions::ClassMethods for documentation.
|
3
5
|
module Transactions
|
@@ -168,7 +170,7 @@ module ActiveRecord
|
|
168
170
|
# writing, the only database that we're aware of that supports true nested
|
169
171
|
# transactions, is MS-SQL. Because of this, Active Record emulates nested
|
170
172
|
# transactions by using savepoints on MySQL and PostgreSQL. See
|
171
|
-
#
|
173
|
+
# https://dev.mysql.com/doc/refman/5.7/en/savepoint.html
|
172
174
|
# for more information about savepoints.
|
173
175
|
#
|
174
176
|
# === \Callbacks
|
@@ -188,7 +190,7 @@ module ActiveRecord
|
|
188
190
|
#
|
189
191
|
# === Caveats
|
190
192
|
#
|
191
|
-
# If you're on MySQL, then do not use Data Definition Language(DDL) operations in nested
|
193
|
+
# If you're on MySQL, then do not use Data Definition Language (DDL) operations in nested
|
192
194
|
# transactions blocks that are emulated with savepoints. That is, do not execute statements
|
193
195
|
# like 'CREATE TABLE' inside such blocks. This is because MySQL automatically
|
194
196
|
# releases all savepoints upon executing a DDL operation. When +transaction+
|
@@ -283,7 +285,7 @@ module ActiveRecord
|
|
283
285
|
fire_on = Array(options[:on])
|
284
286
|
assert_valid_transaction_action(fire_on)
|
285
287
|
options[:if] = Array(options[:if])
|
286
|
-
options[:if].unshift(
|
288
|
+
options[:if].unshift(-> { transaction_include_any_action?(fire_on) })
|
287
289
|
end
|
288
290
|
end
|
289
291
|
|
@@ -338,12 +340,14 @@ module ActiveRecord
|
|
338
340
|
# Ensure that it is not called if the object was never persisted (failed create),
|
339
341
|
# but call it after the commit of a destroyed object.
|
340
342
|
def committed!(should_run_callbacks: true) #:nodoc:
|
341
|
-
|
343
|
+
force_clear_transaction_record_state
|
344
|
+
if should_run_callbacks && (destroyed? || persisted?)
|
345
|
+
@_committed_already_called = true
|
342
346
|
_run_commit_without_transaction_enrollment_callbacks
|
343
347
|
_run_commit_callbacks
|
344
348
|
end
|
345
349
|
ensure
|
346
|
-
|
350
|
+
@_committed_already_called = false
|
347
351
|
end
|
348
352
|
|
349
353
|
# Call the #after_rollback callbacks. The +force_restore_state+ argument indicates if the record
|
@@ -380,13 +384,7 @@ module ActiveRecord
|
|
380
384
|
status = nil
|
381
385
|
self.class.transaction do
|
382
386
|
add_to_transaction
|
383
|
-
|
384
|
-
status = yield
|
385
|
-
rescue ActiveRecord::Rollback
|
386
|
-
clear_transaction_record_state
|
387
|
-
status = nil
|
388
|
-
end
|
389
|
-
|
387
|
+
status = yield
|
390
388
|
raise ActiveRecord::Rollback unless status
|
391
389
|
end
|
392
390
|
status
|
@@ -396,17 +394,29 @@ module ActiveRecord
|
|
396
394
|
end
|
397
395
|
end
|
398
396
|
|
397
|
+
protected
|
398
|
+
attr_reader :_committed_already_called, :_trigger_update_callback, :_trigger_destroy_callback
|
399
|
+
|
399
400
|
private
|
400
401
|
|
401
402
|
# Save the new record state and id of a record so it can be restored later if a transaction fails.
|
402
403
|
def remember_transaction_record_state
|
403
|
-
@_start_transaction_state[:id] = id
|
404
404
|
@_start_transaction_state.reverse_merge!(
|
405
|
+
id: id,
|
405
406
|
new_record: @new_record,
|
406
407
|
destroyed: @destroyed,
|
407
408
|
frozen?: frozen?,
|
408
409
|
)
|
409
410
|
@_start_transaction_state[:level] = (@_start_transaction_state[:level] || 0) + 1
|
411
|
+
remember_new_record_before_last_commit
|
412
|
+
end
|
413
|
+
|
414
|
+
def remember_new_record_before_last_commit
|
415
|
+
if _committed_already_called
|
416
|
+
@_new_record_before_last_commit = false
|
417
|
+
else
|
418
|
+
@_new_record_before_last_commit = @_start_transaction_state[:new_record]
|
419
|
+
end
|
410
420
|
end
|
411
421
|
|
412
422
|
# Clear the new record state and id of a record.
|
@@ -430,30 +440,24 @@ module ActiveRecord
|
|
430
440
|
@new_record = restore_state[:new_record]
|
431
441
|
@destroyed = restore_state[:destroyed]
|
432
442
|
pk = self.class.primary_key
|
433
|
-
if pk &&
|
434
|
-
|
443
|
+
if pk && _read_attribute(pk) != restore_state[:id]
|
444
|
+
_write_attribute(pk, restore_state[:id])
|
435
445
|
end
|
436
446
|
freeze if restore_state[:frozen?]
|
437
447
|
end
|
438
448
|
end
|
439
449
|
end
|
440
450
|
|
441
|
-
# Determine if a record was created or destroyed in a transaction. State should be one of :new_record or :destroyed.
|
442
|
-
def transaction_record_state(state)
|
443
|
-
@_start_transaction_state[state]
|
444
|
-
end
|
445
|
-
|
446
451
|
# Determine if a transaction included an action for :create, :update, or :destroy. Used in filtering callbacks.
|
447
452
|
def transaction_include_any_action?(actions)
|
448
453
|
actions.any? do |action|
|
449
454
|
case action
|
450
455
|
when :create
|
451
|
-
|
452
|
-
when :destroy
|
453
|
-
defined?(@_trigger_destroy_callback) && @_trigger_destroy_callback
|
456
|
+
persisted? && @_new_record_before_last_commit
|
454
457
|
when :update
|
455
|
-
!(
|
456
|
-
|
458
|
+
!(@_new_record_before_last_commit || destroyed?) && _trigger_update_callback
|
459
|
+
when :destroy
|
460
|
+
_trigger_destroy_callback
|
457
461
|
end
|
458
462
|
end
|
459
463
|
end
|
@@ -470,7 +474,7 @@ module ActiveRecord
|
|
470
474
|
# if it's associated with a transaction, then the state of the Active Record
|
471
475
|
# object will be updated to reflect the current state of the transaction.
|
472
476
|
#
|
473
|
-
# The
|
477
|
+
# The <tt>@transaction_state</tt> variable stores the states of the associated
|
474
478
|
# transaction. This relies on the fact that a transaction can only be in
|
475
479
|
# one rollback or commit (otherwise a list of states would be required).
|
476
480
|
# Each Active Record object inside of a transaction carries that transaction's
|
@@ -489,8 +493,9 @@ module ActiveRecord
|
|
489
493
|
|
490
494
|
def update_attributes_from_transaction_state(transaction_state)
|
491
495
|
if transaction_state && transaction_state.finalized?
|
492
|
-
restore_transaction_record_state if transaction_state.rolledback?
|
493
|
-
|
496
|
+
restore_transaction_record_state(transaction_state.fully_rolledback?) if transaction_state.rolledback?
|
497
|
+
force_clear_transaction_record_state if transaction_state.fully_committed?
|
498
|
+
clear_transaction_record_state if transaction_state.fully_completed?
|
494
499
|
end
|
495
500
|
end
|
496
501
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActiveRecord
|
4
|
+
module Type
|
5
|
+
class Json < ActiveModel::Type::Value
|
6
|
+
include ActiveModel::Type::Helpers::Mutable
|
7
|
+
|
8
|
+
def type
|
9
|
+
:json
|
10
|
+
end
|
11
|
+
|
12
|
+
def deserialize(value)
|
13
|
+
return value unless value.is_a?(::String)
|
14
|
+
ActiveSupport::JSON.decode(value) rescue nil
|
15
|
+
end
|
16
|
+
|
17
|
+
def serialize(value)
|
18
|
+
ActiveSupport::JSON.encode(value) unless value.nil?
|
19
|
+
end
|
20
|
+
|
21
|
+
def changed_in_place?(raw_old_value, new_value)
|
22
|
+
deserialize(raw_old_value) != new_value
|
23
|
+
end
|
24
|
+
|
25
|
+
def accessor
|
26
|
+
ActiveRecord::Store::StringKeyedHashAccessor
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|