activerecord 5.1.0 → 5.2.0.rc1
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 +410 -530
- data/MIT-LICENSE +1 -1
- data/README.rdoc +4 -4
- 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 +4 -2
- data/lib/active_record/associations/alias_tracker.rb +23 -32
- data/lib/active_record/associations/association.rb +20 -21
- data/lib/active_record/associations/association_scope.rb +49 -49
- data/lib/active_record/associations/belongs_to_association.rb +12 -10
- data/lib/active_record/associations/belongs_to_polymorphic_association.rb +4 -7
- data/lib/active_record/associations/builder/association.rb +4 -7
- data/lib/active_record/associations/builder/belongs_to.rb +10 -6
- 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 +50 -41
- data/lib/active_record/associations/collection_proxy.rb +22 -39
- 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 +12 -18
- data/lib/active_record/associations/has_one_association.rb +5 -1
- data/lib/active_record/associations/has_one_through_association.rb +8 -7
- data/lib/active_record/associations/join_dependency/join_association.rb +17 -64
- 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/join_dependency.rb +27 -44
- 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/preloader.rb +17 -37
- data/lib/active_record/associations/singular_association.rb +14 -10
- data/lib/active_record/associations/through_association.rb +26 -11
- data/lib/active_record/associations.rb +68 -76
- data/lib/active_record/attribute_assignment.rb +2 -0
- 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 +24 -214
- 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 +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 +22 -19
- data/lib/active_record/attribute_methods.rb +48 -12
- data/lib/active_record/attributes.rb +7 -6
- data/lib/active_record/autosave_association.rb +8 -11
- 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 +14 -10
- 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 +175 -33
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +8 -2
- data/lib/active_record/connection_adapters/abstract/quoting.rb +13 -24
- 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 +58 -3
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +31 -53
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +165 -85
- data/lib/active_record/connection_adapters/abstract/transaction.rb +45 -9
- data/lib/active_record/connection_adapters/abstract_adapter.rb +83 -97
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +118 -180
- 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 +2 -0
- data/lib/active_record/connection_adapters/mysql/column.rb +2 -0
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +11 -17
- 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/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_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 +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 +2 -1
- 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 +14 -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 +269 -126
- 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 +64 -85
- 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 +18 -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 +71 -1
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +92 -95
- 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 +39 -60
- data/lib/active_record/counter_cache.rb +3 -2
- data/lib/active_record/define_callbacks.rb +5 -3
- data/lib/active_record/dynamic_matchers.rb +9 -9
- data/lib/active_record/enum.rb +17 -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 +9 -9
- 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 +8 -6
- data/lib/active_record/locking/pessimistic.rb +9 -6
- data/lib/active_record/log_subscriber.rb +46 -4
- data/lib/active_record/migration/command_recorder.rb +11 -9
- data/lib/active_record/migration/compatibility.rb +74 -22
- data/lib/active_record/migration/join_table.rb +2 -0
- data/lib/active_record/migration.rb +181 -137
- data/lib/active_record/model_schema.rb +73 -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 +153 -18
- data/lib/active_record/query_cache.rb +17 -12
- data/lib/active_record/querying.rb +4 -2
- data/lib/active_record/railtie.rb +61 -3
- 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 +47 -37
- data/lib/active_record/readonly_attributes.rb +3 -2
- data/lib/active_record/reflection.rb +131 -204
- data/lib/active_record/relation/batches/batch_enumerator.rb +2 -0
- data/lib/active_record/relation/batches.rb +32 -17
- data/lib/active_record/relation/calculations.rb +58 -20
- data/lib/active_record/relation/delegation.rb +10 -29
- data/lib/active_record/relation/finder_methods.rb +74 -85
- data/lib/active_record/relation/from_clause.rb +2 -8
- data/lib/active_record/relation/merger.rb +51 -20
- 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/predicate_builder.rb +53 -78
- data/lib/active_record/relation/query_attribute.rb +9 -2
- data/lib/active_record/relation/query_methods.rb +101 -95
- data/lib/active_record/relation/record_fetch_warning.rb +2 -0
- data/lib/active_record/relation/spawn_methods.rb +3 -1
- 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/relation.rb +99 -202
- 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 +10 -7
- data/lib/active_record/scoping/named.rb +38 -12
- data/lib/active_record/scoping.rb +12 -10
- 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 +37 -25
- 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 +5 -5
- 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/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 +25 -37
- 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 -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/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 -33
@@ -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
|
-
attr_reader :bind_map, :query_builder
|
89
|
-
|
90
90
|
def self.create(connection, block = Proc.new)
|
91
|
-
relation
|
92
|
-
|
93
|
-
|
94
|
-
new
|
91
|
+
relation = 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
|
@@ -223,22 +234,22 @@ module ActiveRecord
|
|
223
234
|
class_for_adapter(configuration["adapter"]).new(*arguments).structure_load(filename, structure_load_flags)
|
224
235
|
end
|
225
236
|
|
226
|
-
def load_schema(configuration, format = ActiveRecord::Base.schema_format, file = nil) # :nodoc:
|
237
|
+
def load_schema(configuration, format = ActiveRecord::Base.schema_format, file = nil, environment = env) # :nodoc:
|
227
238
|
file ||= schema_file(format)
|
228
239
|
|
240
|
+
check_schema_file(file)
|
241
|
+
ActiveRecord::Base.establish_connection(configuration)
|
242
|
+
|
229
243
|
case format
|
230
244
|
when :ruby
|
231
|
-
check_schema_file(file)
|
232
|
-
ActiveRecord::Base.establish_connection(configuration)
|
233
245
|
load(file)
|
234
246
|
when :sql
|
235
|
-
check_schema_file(file)
|
236
247
|
structure_load(configuration, file)
|
237
248
|
else
|
238
249
|
raise ArgumentError, "unknown format #{format.inspect}"
|
239
250
|
end
|
240
251
|
ActiveRecord::InternalMetadata.create_table
|
241
|
-
ActiveRecord::InternalMetadata[:environment] =
|
252
|
+
ActiveRecord::InternalMetadata[:environment] = environment
|
242
253
|
end
|
243
254
|
|
244
255
|
def schema_file(format = ActiveRecord::Base.schema_format)
|
@@ -251,16 +262,16 @@ module ActiveRecord
|
|
251
262
|
end
|
252
263
|
|
253
264
|
def load_schema_current(format = ActiveRecord::Base.schema_format, file = nil, environment = env)
|
254
|
-
each_current_configuration(environment) { |configuration|
|
255
|
-
load_schema configuration, format, file
|
265
|
+
each_current_configuration(environment) { |configuration, configuration_environment|
|
266
|
+
load_schema configuration, format, file, configuration_environment
|
256
267
|
}
|
257
268
|
ActiveRecord::Base.establish_connection(environment.to_sym)
|
258
269
|
end
|
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.}
|
263
|
-
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)
|
273
|
+
message = %{#{filename} doesn't exist yet. Run `rails db:migrate` to create it, then try again.}.dup
|
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
|
266
277
|
end
|
@@ -288,20 +299,21 @@ 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)
|
299
310
|
environments = [environment]
|
300
311
|
environments << "test" if environment == "development"
|
301
312
|
|
302
|
-
|
303
|
-
|
304
|
-
|
313
|
+
ActiveRecord::Base.configurations.slice(*environments).each do |configuration_environment, configuration|
|
314
|
+
next unless configuration["database"]
|
315
|
+
|
316
|
+
yield configuration, configuration_environment
|
305
317
|
end
|
306
318
|
end
|
307
319
|
|
@@ -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,8 +45,14 @@ module ActiveRecord
|
|
59
45
|
args.concat(["--no-data"])
|
60
46
|
args.concat(["--routines"])
|
61
47
|
args.concat(["--skip-comments"])
|
62
|
-
|
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
|
+
|
63
54
|
args.concat(["#{configuration['database']}"])
|
55
|
+
args.unshift(*extra_flags) if extra_flags
|
64
56
|
|
65
57
|
run_cmd("mysqldump", args, "dumping")
|
66
58
|
end
|
@@ -69,7 +61,7 @@ module ActiveRecord
|
|
69
61
|
args = prepare_command_options
|
70
62
|
args.concat(["--execute", %{SET FOREIGN_KEY_CHECKS = 0; SOURCE #{filename}; SET FOREIGN_KEY_CHECKS = 1}])
|
71
63
|
args.concat(["--database", "#{configuration['database']}"])
|
72
|
-
args.
|
64
|
+
args.unshift(*extra_flags) if extra_flags
|
73
65
|
|
74
66
|
run_cmd("mysql", args, "loading")
|
75
67
|
end
|
@@ -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
|
@@ -20,7 +22,7 @@ module ActiveRecord
|
|
20
22
|
configuration.merge("encoding" => encoding)
|
21
23
|
establish_connection configuration
|
22
24
|
rescue ActiveRecord::StatementInvalid => error
|
23
|
-
if
|
25
|
+
if error.cause.is_a?(PG::DuplicateDatabase)
|
24
26
|
raise DatabaseAlreadyExists
|
25
27
|
else
|
26
28
|
raise
|
@@ -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:
|
@@ -87,7 +87,7 @@ module ActiveRecord
|
|
87
87
|
|
88
88
|
all_timestamp_attributes_in_model.each do |column|
|
89
89
|
if !attribute_present?(column)
|
90
|
-
|
90
|
+
_write_attribute(column, current_time)
|
91
91
|
end
|
92
92
|
end
|
93
93
|
end
|
@@ -101,7 +101,7 @@ module ActiveRecord
|
|
101
101
|
|
102
102
|
timestamp_attributes_for_update_in_model.each do |column|
|
103
103
|
next if will_save_change_to_attribute?(column)
|
104
|
-
|
104
|
+
_write_attribute(column, current_time)
|
105
105
|
end
|
106
106
|
end
|
107
107
|
super(*args)
|
@@ -127,7 +127,7 @@ module ActiveRecord
|
|
127
127
|
self.class.send(:current_time_from_proper_timezone)
|
128
128
|
end
|
129
129
|
|
130
|
-
def max_updated_column_timestamp(timestamp_names =
|
130
|
+
def max_updated_column_timestamp(timestamp_names = timestamp_attributes_for_update_in_model)
|
131
131
|
timestamp_names
|
132
132
|
.map { |attr| self[attr] }
|
133
133
|
.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
|
|
@@ -430,8 +432,8 @@ module ActiveRecord
|
|
430
432
|
@new_record = restore_state[:new_record]
|
431
433
|
@destroyed = restore_state[:destroyed]
|
432
434
|
pk = self.class.primary_key
|
433
|
-
if pk &&
|
434
|
-
|
435
|
+
if pk && _read_attribute(pk) != restore_state[:id]
|
436
|
+
_write_attribute(pk, restore_state[:id])
|
435
437
|
end
|
436
438
|
freeze if restore_state[:frozen?]
|
437
439
|
end
|
@@ -470,7 +472,7 @@ module ActiveRecord
|
|
470
472
|
# if it's associated with a transaction, then the state of the Active Record
|
471
473
|
# object will be updated to reflect the current state of the transaction.
|
472
474
|
#
|
473
|
-
# The
|
475
|
+
# The <tt>@transaction_state</tt> variable stores the states of the associated
|
474
476
|
# transaction. This relies on the fact that a transaction can only be in
|
475
477
|
# one rollback or commit (otherwise a list of states would be required).
|
476
478
|
# Each Active Record object inside of a transaction carries that transaction's
|
@@ -490,7 +492,7 @@ module ActiveRecord
|
|
490
492
|
def update_attributes_from_transaction_state(transaction_state)
|
491
493
|
if transaction_state && transaction_state.finalized?
|
492
494
|
restore_transaction_record_state if transaction_state.rolledback?
|
493
|
-
clear_transaction_record_state
|
495
|
+
clear_transaction_record_state if transaction_state.fully_completed?
|
494
496
|
end
|
495
497
|
end
|
496
498
|
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
|