activerecord 5.0.7 → 5.1.7
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 +657 -2080
- data/MIT-LICENSE +1 -1
- data/README.rdoc +1 -1
- data/examples/performance.rb +28 -28
- data/examples/simple.rb +3 -3
- data/lib/active_record/aggregations.rb +244 -244
- data/lib/active_record/association_relation.rb +5 -5
- data/lib/active_record/associations/alias_tracker.rb +10 -11
- data/lib/active_record/associations/association.rb +23 -5
- data/lib/active_record/associations/association_scope.rb +95 -81
- data/lib/active_record/associations/belongs_to_association.rb +7 -4
- data/lib/active_record/associations/builder/belongs_to.rb +30 -16
- data/lib/active_record/associations/builder/collection_association.rb +1 -2
- data/lib/active_record/associations/builder/has_and_belongs_to_many.rb +27 -27
- data/lib/active_record/associations/collection_association.rb +36 -205
- data/lib/active_record/associations/collection_proxy.rb +132 -63
- data/lib/active_record/associations/has_many_association.rb +10 -19
- data/lib/active_record/associations/has_many_through_association.rb +12 -4
- data/lib/active_record/associations/has_one_association.rb +24 -28
- data/lib/active_record/associations/has_one_through_association.rb +5 -1
- data/lib/active_record/associations/join_dependency/join_association.rb +4 -28
- data/lib/active_record/associations/join_dependency/join_base.rb +1 -1
- data/lib/active_record/associations/join_dependency/join_part.rb +1 -1
- data/lib/active_record/associations/join_dependency.rb +121 -118
- data/lib/active_record/associations/preloader/association.rb +64 -64
- data/lib/active_record/associations/preloader/belongs_to.rb +0 -2
- data/lib/active_record/associations/preloader/collection_association.rb +6 -6
- data/lib/active_record/associations/preloader/has_many.rb +0 -2
- data/lib/active_record/associations/preloader/singular_association.rb +6 -8
- data/lib/active_record/associations/preloader/through_association.rb +41 -41
- data/lib/active_record/associations/preloader.rb +94 -94
- data/lib/active_record/associations/singular_association.rb +8 -25
- data/lib/active_record/associations/through_association.rb +2 -5
- data/lib/active_record/associations.rb +1591 -1562
- data/lib/active_record/attribute/user_provided_default.rb +4 -2
- data/lib/active_record/attribute.rb +98 -71
- data/lib/active_record/attribute_assignment.rb +61 -61
- data/lib/active_record/attribute_decorators.rb +35 -13
- data/lib/active_record/attribute_methods/before_type_cast.rb +7 -7
- data/lib/active_record/attribute_methods/dirty.rb +229 -46
- data/lib/active_record/attribute_methods/primary_key.rb +74 -73
- data/lib/active_record/attribute_methods/read.rb +39 -35
- data/lib/active_record/attribute_methods/serialization.rb +7 -7
- data/lib/active_record/attribute_methods/time_zone_conversion.rb +35 -58
- data/lib/active_record/attribute_methods/write.rb +30 -33
- data/lib/active_record/attribute_methods.rb +56 -65
- data/lib/active_record/attribute_mutation_tracker.rb +63 -11
- data/lib/active_record/attribute_set/builder.rb +27 -33
- data/lib/active_record/attribute_set/yaml_encoder.rb +41 -0
- data/lib/active_record/attribute_set.rb +9 -6
- data/lib/active_record/attributes.rb +22 -22
- data/lib/active_record/autosave_association.rb +18 -13
- data/lib/active_record/base.rb +24 -22
- data/lib/active_record/callbacks.rb +56 -14
- data/lib/active_record/coders/yaml_column.rb +9 -11
- data/lib/active_record/collection_cache_key.rb +3 -4
- data/lib/active_record/connection_adapters/abstract/connection_pool.rb +330 -284
- data/lib/active_record/connection_adapters/abstract/database_limits.rb +1 -3
- data/lib/active_record/connection_adapters/abstract/database_statements.rb +39 -37
- data/lib/active_record/connection_adapters/abstract/query_cache.rb +32 -27
- data/lib/active_record/connection_adapters/abstract/quoting.rb +62 -51
- data/lib/active_record/connection_adapters/abstract/schema_creation.rb +10 -20
- data/lib/active_record/connection_adapters/abstract/schema_definitions.rb +74 -79
- data/lib/active_record/connection_adapters/abstract/schema_dumper.rb +53 -41
- data/lib/active_record/connection_adapters/abstract/schema_statements.rb +120 -100
- data/lib/active_record/connection_adapters/abstract/transaction.rb +49 -43
- data/lib/active_record/connection_adapters/abstract_adapter.rb +165 -135
- data/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +404 -424
- data/lib/active_record/connection_adapters/column.rb +26 -4
- data/lib/active_record/connection_adapters/connection_specification.rb +128 -118
- data/lib/active_record/connection_adapters/mysql/column.rb +6 -31
- data/lib/active_record/connection_adapters/mysql/database_statements.rb +36 -49
- data/lib/active_record/connection_adapters/mysql/explain_pretty_printer.rb +22 -22
- data/lib/active_record/connection_adapters/mysql/quoting.rb +6 -12
- data/lib/active_record/connection_adapters/mysql/schema_creation.rb +49 -45
- data/lib/active_record/connection_adapters/mysql/schema_definitions.rb +16 -19
- data/lib/active_record/connection_adapters/mysql/schema_dumper.rb +54 -28
- data/lib/active_record/connection_adapters/mysql/schema_statements.rb +43 -0
- data/lib/active_record/connection_adapters/mysql/type_metadata.rb +7 -6
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +23 -27
- data/lib/active_record/connection_adapters/postgresql/database_statements.rb +32 -53
- data/lib/active_record/connection_adapters/postgresql/explain_pretty_printer.rb +3 -3
- data/lib/active_record/connection_adapters/postgresql/oid/array.rb +19 -9
- data/lib/active_record/connection_adapters/postgresql/oid/bit.rb +5 -3
- data/lib/active_record/connection_adapters/postgresql/oid/cidr.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/date_time.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/decimal.rb +1 -1
- data/lib/active_record/connection_adapters/postgresql/oid/enum.rb +3 -3
- data/lib/active_record/connection_adapters/postgresql/oid/hstore.rb +16 -16
- data/lib/active_record/connection_adapters/postgresql/oid/jsonb.rb +0 -10
- data/lib/active_record/connection_adapters/postgresql/oid/{rails_5_1_point.rb → legacy_point.rb} +9 -16
- data/lib/active_record/connection_adapters/postgresql/oid/money.rb +2 -2
- data/lib/active_record/connection_adapters/postgresql/oid/oid.rb +13 -0
- data/lib/active_record/connection_adapters/postgresql/oid/point.rb +28 -8
- data/lib/active_record/connection_adapters/postgresql/oid/range.rb +32 -30
- data/lib/active_record/connection_adapters/postgresql/oid/specialized_string.rb +2 -1
- data/lib/active_record/connection_adapters/postgresql/oid/type_map_initializer.rb +51 -51
- data/lib/active_record/connection_adapters/postgresql/oid.rb +22 -21
- data/lib/active_record/connection_adapters/postgresql/quoting.rb +40 -35
- data/lib/active_record/connection_adapters/postgresql/schema_creation.rb +15 -0
- data/lib/active_record/connection_adapters/postgresql/schema_definitions.rb +37 -24
- data/lib/active_record/connection_adapters/postgresql/schema_dumper.rb +19 -23
- data/lib/active_record/connection_adapters/postgresql/schema_statements.rb +182 -222
- data/lib/active_record/connection_adapters/postgresql/type_metadata.rb +6 -4
- data/lib/active_record/connection_adapters/postgresql/utils.rb +7 -5
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +198 -167
- data/lib/active_record/connection_adapters/schema_cache.rb +16 -7
- data/lib/active_record/connection_adapters/sql_type_metadata.rb +3 -3
- data/lib/active_record/connection_adapters/sqlite3/explain_pretty_printer.rb +1 -1
- data/lib/active_record/connection_adapters/sqlite3/quoting.rb +16 -19
- data/lib/active_record/connection_adapters/sqlite3/schema_creation.rb +1 -8
- data/lib/active_record/connection_adapters/sqlite3/schema_definitions.rb +28 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_dumper.rb +17 -0
- data/lib/active_record/connection_adapters/sqlite3/schema_statements.rb +32 -0
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +184 -167
- data/lib/active_record/connection_adapters/statement_pool.rb +7 -7
- data/lib/active_record/connection_handling.rb +14 -26
- data/lib/active_record/core.rb +109 -93
- data/lib/active_record/counter_cache.rb +60 -13
- data/lib/active_record/define_callbacks.rb +20 -0
- data/lib/active_record/dynamic_matchers.rb +80 -79
- data/lib/active_record/enum.rb +8 -6
- data/lib/active_record/errors.rb +64 -15
- data/lib/active_record/explain.rb +1 -2
- data/lib/active_record/explain_registry.rb +1 -1
- data/lib/active_record/explain_subscriber.rb +7 -4
- data/lib/active_record/fixture_set/file.rb +11 -8
- data/lib/active_record/fixtures.rb +66 -53
- data/lib/active_record/gem_version.rb +1 -1
- data/lib/active_record/inheritance.rb +93 -79
- data/lib/active_record/integration.rb +7 -7
- data/lib/active_record/internal_metadata.rb +3 -16
- data/lib/active_record/legacy_yaml_adapter.rb +1 -1
- data/lib/active_record/locking/optimistic.rb +69 -74
- data/lib/active_record/locking/pessimistic.rb +10 -1
- data/lib/active_record/log_subscriber.rb +23 -28
- data/lib/active_record/migration/command_recorder.rb +94 -94
- data/lib/active_record/migration/compatibility.rb +100 -47
- data/lib/active_record/migration/join_table.rb +6 -6
- data/lib/active_record/migration.rb +153 -155
- data/lib/active_record/model_schema.rb +94 -107
- data/lib/active_record/nested_attributes.rb +200 -199
- data/lib/active_record/null_relation.rb +11 -34
- data/lib/active_record/persistence.rb +65 -50
- data/lib/active_record/query_cache.rb +2 -6
- data/lib/active_record/querying.rb +3 -4
- data/lib/active_record/railtie.rb +16 -17
- data/lib/active_record/railties/controller_runtime.rb +6 -2
- data/lib/active_record/railties/databases.rake +105 -133
- data/lib/active_record/railties/jdbcmysql_error.rb +1 -1
- data/lib/active_record/readonly_attributes.rb +2 -2
- data/lib/active_record/reflection.rb +154 -108
- data/lib/active_record/relation/batches/batch_enumerator.rb +1 -1
- data/lib/active_record/relation/batches.rb +80 -51
- data/lib/active_record/relation/calculations.rb +169 -162
- data/lib/active_record/relation/delegation.rb +32 -31
- data/lib/active_record/relation/finder_methods.rb +197 -231
- data/lib/active_record/relation/merger.rb +58 -62
- data/lib/active_record/relation/predicate_builder/array_handler.rb +7 -5
- data/lib/active_record/relation/predicate_builder/association_query_handler.rb +23 -23
- data/lib/active_record/relation/predicate_builder/base_handler.rb +3 -1
- data/lib/active_record/relation/predicate_builder/basic_object_handler.rb +0 -8
- data/lib/active_record/relation/predicate_builder/polymorphic_array_handler.rb +12 -10
- data/lib/active_record/relation/predicate_builder/range_handler.rb +0 -8
- data/lib/active_record/relation/predicate_builder.rb +92 -89
- data/lib/active_record/relation/query_attribute.rb +1 -1
- data/lib/active_record/relation/query_methods.rb +255 -293
- data/lib/active_record/relation/record_fetch_warning.rb +3 -3
- data/lib/active_record/relation/spawn_methods.rb +4 -5
- data/lib/active_record/relation/where_clause.rb +80 -65
- data/lib/active_record/relation/where_clause_factory.rb +47 -8
- data/lib/active_record/relation.rb +93 -119
- data/lib/active_record/result.rb +41 -32
- data/lib/active_record/runtime_registry.rb +3 -3
- data/lib/active_record/sanitization.rb +176 -192
- data/lib/active_record/schema.rb +3 -3
- data/lib/active_record/schema_dumper.rb +15 -38
- data/lib/active_record/schema_migration.rb +8 -4
- data/lib/active_record/scoping/default.rb +90 -90
- data/lib/active_record/scoping/named.rb +11 -11
- data/lib/active_record/scoping.rb +6 -6
- data/lib/active_record/secure_token.rb +2 -2
- data/lib/active_record/statement_cache.rb +13 -15
- data/lib/active_record/store.rb +31 -32
- data/lib/active_record/suppressor.rb +2 -1
- data/lib/active_record/table_metadata.rb +9 -5
- data/lib/active_record/tasks/database_tasks.rb +65 -55
- data/lib/active_record/tasks/mysql_database_tasks.rb +76 -73
- data/lib/active_record/tasks/postgresql_database_tasks.rb +72 -47
- data/lib/active_record/tasks/sqlite_database_tasks.rb +18 -16
- data/lib/active_record/timestamp.rb +46 -25
- data/lib/active_record/touch_later.rb +1 -2
- data/lib/active_record/transactions.rb +97 -109
- data/lib/active_record/type/adapter_specific_registry.rb +46 -42
- data/lib/active_record/type/decimal_without_scale.rb +13 -0
- data/lib/active_record/type/hash_lookup_type_map.rb +3 -3
- data/lib/active_record/type/internal/abstract_json.rb +4 -0
- data/lib/active_record/type/serialized.rb +14 -8
- data/lib/active_record/type/text.rb +9 -0
- data/lib/active_record/type/time.rb +0 -1
- data/lib/active_record/type/type_map.rb +11 -15
- data/lib/active_record/type/unsigned_integer.rb +15 -0
- data/lib/active_record/type.rb +17 -13
- data/lib/active_record/type_caster/connection.rb +8 -6
- data/lib/active_record/type_caster/map.rb +3 -1
- data/lib/active_record/type_caster.rb +2 -2
- data/lib/active_record/validations/associated.rb +1 -1
- data/lib/active_record/validations/presence.rb +2 -2
- data/lib/active_record/validations/uniqueness.rb +8 -39
- data/lib/active_record/validations.rb +4 -4
- data/lib/active_record/version.rb +1 -1
- data/lib/active_record.rb +20 -20
- data/lib/rails/generators/active_record/migration/migration_generator.rb +37 -34
- data/lib/rails/generators/active_record/migration.rb +1 -1
- data/lib/rails/generators/active_record/model/model_generator.rb +9 -9
- data/lib/rails/generators/active_record.rb +4 -4
- metadata +24 -13
- data/lib/active_record/relation/predicate_builder/class_handler.rb +0 -27
@@ -277,8 +277,10 @@ module ActiveRecord
|
|
277
277
|
#
|
278
278
|
# * <tt>change_column(table_name, column_name, type, options)</tt>: Changes
|
279
279
|
# the column to a different type using the same parameters as add_column.
|
280
|
-
# * <tt>change_column_default(table_name, column_name,
|
281
|
-
# default value for +column_name+ defined by +
|
280
|
+
# * <tt>change_column_default(table_name, column_name, default_or_changes)</tt>:
|
281
|
+
# Sets a default value for +column_name+ defined by +default_or_changes+ on
|
282
|
+
# +table_name+. Passing a hash containing <tt>:from</tt> and <tt>:to</tt>
|
283
|
+
# as +default_or_changes+ will make this change reversible in the migration.
|
282
284
|
# * <tt>change_column_null(table_name, column_name, null, default = nil)</tt>:
|
283
285
|
# Sets or removes a +NOT NULL+ constraint on +column_name+. The +null+ flag
|
284
286
|
# indicates whether the value can be +NULL+. See
|
@@ -510,8 +512,8 @@ module ActiveRecord
|
|
510
512
|
# Remember that you can still open your own transactions, even if you
|
511
513
|
# are in a Migration with <tt>self.disable_ddl_transaction!</tt>.
|
512
514
|
class Migration
|
513
|
-
autoload :CommandRecorder,
|
514
|
-
autoload :Compatibility,
|
515
|
+
autoload :CommandRecorder, "active_record/migration/command_recorder"
|
516
|
+
autoload :Compatibility, "active_record/migration/compatibility"
|
515
517
|
|
516
518
|
# This must be defined before the inherited hook, below
|
517
519
|
class Current < Migration # :nodoc:
|
@@ -520,7 +522,10 @@ module ActiveRecord
|
|
520
522
|
def self.inherited(subclass) # :nodoc:
|
521
523
|
super
|
522
524
|
if subclass.superclass == Migration
|
523
|
-
|
525
|
+
raise StandardError, "Directly inheriting from ActiveRecord::Migration is not supported. " \
|
526
|
+
"Please specify the Rails release the migration was written for:\n" \
|
527
|
+
"\n" \
|
528
|
+
" class #{subclass} < ActiveRecord::Migration[4.2]"
|
524
529
|
end
|
525
530
|
end
|
526
531
|
|
@@ -543,21 +548,19 @@ module ActiveRecord
|
|
543
548
|
end
|
544
549
|
|
545
550
|
def call(env)
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
@last_check = mtime
|
551
|
-
end
|
551
|
+
mtime = ActiveRecord::Migrator.last_migration.mtime.to_i
|
552
|
+
if @last_check < mtime
|
553
|
+
ActiveRecord::Migration.check_pending!(connection)
|
554
|
+
@last_check = mtime
|
552
555
|
end
|
553
556
|
@app.call(env)
|
554
557
|
end
|
555
558
|
|
556
559
|
private
|
557
560
|
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
+
def connection
|
562
|
+
ActiveRecord::Base.connection
|
563
|
+
end
|
561
564
|
end
|
562
565
|
|
563
566
|
class << self
|
@@ -687,7 +690,7 @@ module ActiveRecord
|
|
687
690
|
connection.respond_to?(:reverting) && connection.reverting
|
688
691
|
end
|
689
692
|
|
690
|
-
|
693
|
+
ReversibleBlockHelper = Struct.new(:reverting) do # :nodoc:
|
691
694
|
def up
|
692
695
|
yield unless reverting
|
693
696
|
end
|
@@ -725,7 +728,7 @@ module ActiveRecord
|
|
725
728
|
# end
|
726
729
|
def reversible
|
727
730
|
helper = ReversibleBlockHelper.new(reverting?)
|
728
|
-
execute_block{ yield helper }
|
731
|
+
execute_block { yield helper }
|
729
732
|
end
|
730
733
|
|
731
734
|
# Runs the given migration classes.
|
@@ -767,7 +770,7 @@ module ActiveRecord
|
|
767
770
|
when :down then announce "reverting"
|
768
771
|
end
|
769
772
|
|
770
|
-
time
|
773
|
+
time = nil
|
771
774
|
ActiveRecord::Base.connection_pool.with_connection do |conn|
|
772
775
|
time = Benchmark.measure do
|
773
776
|
exec_migration(conn, direction)
|
@@ -795,7 +798,7 @@ module ActiveRecord
|
|
795
798
|
@connection = nil
|
796
799
|
end
|
797
800
|
|
798
|
-
def write(text="")
|
801
|
+
def write(text = "")
|
799
802
|
puts(text) if verbose
|
800
803
|
end
|
801
804
|
|
@@ -805,7 +808,7 @@ module ActiveRecord
|
|
805
808
|
write "== %s %s" % [text, "=" * length]
|
806
809
|
end
|
807
810
|
|
808
|
-
def say(message, subitem=false)
|
811
|
+
def say(message, subitem = false)
|
809
812
|
write "#{subitem ? " ->" : "--"} #{message}"
|
810
813
|
end
|
811
814
|
|
@@ -830,7 +833,7 @@ module ActiveRecord
|
|
830
833
|
end
|
831
834
|
|
832
835
|
def method_missing(method, *arguments, &block)
|
833
|
-
arg_list = arguments.map(&:inspect) *
|
836
|
+
arg_list = arguments.map(&:inspect) * ", "
|
834
837
|
|
835
838
|
say_with_time "#{method}(#{arg_list})" do
|
836
839
|
unless connection.respond_to? :revert
|
@@ -922,19 +925,18 @@ module ActiveRecord
|
|
922
925
|
end
|
923
926
|
|
924
927
|
private
|
925
|
-
|
926
|
-
|
927
|
-
|
928
|
-
|
929
|
-
|
928
|
+
def execute_block
|
929
|
+
if connection.respond_to? :execute_block
|
930
|
+
super # use normal delegation to record the block
|
931
|
+
else
|
932
|
+
yield
|
933
|
+
end
|
930
934
|
end
|
931
|
-
end
|
932
935
|
end
|
933
936
|
|
934
937
|
# MigrationProxy is used to defer loading of the actual migration classes
|
935
938
|
# until they are needed
|
936
|
-
|
937
|
-
|
939
|
+
MigrationProxy = Struct.new(:name, :version, :filename, :scope) do
|
938
940
|
def initialize(name, version, filename, scope)
|
939
941
|
super
|
940
942
|
@migration = nil
|
@@ -960,7 +962,6 @@ module ActiveRecord
|
|
960
962
|
require(File.expand_path(filename))
|
961
963
|
name.constantize.new(name, version)
|
962
964
|
end
|
963
|
-
|
964
965
|
end
|
965
966
|
|
966
967
|
class NullMigration < MigrationProxy #:nodoc:
|
@@ -991,11 +992,11 @@ module ActiveRecord
|
|
991
992
|
end
|
992
993
|
end
|
993
994
|
|
994
|
-
def rollback(migrations_paths, steps=1)
|
995
|
+
def rollback(migrations_paths, steps = 1)
|
995
996
|
move(:down, migrations_paths, steps)
|
996
997
|
end
|
997
998
|
|
998
|
-
def forward(migrations_paths, steps=1)
|
999
|
+
def forward(migrations_paths, steps = 1)
|
999
1000
|
move(:up, migrations_paths, steps)
|
1000
1001
|
end
|
1001
1002
|
|
@@ -1024,14 +1025,13 @@ module ActiveRecord
|
|
1024
1025
|
def schema_migrations_table_name
|
1025
1026
|
SchemaMigration.table_name
|
1026
1027
|
end
|
1028
|
+
deprecate :schema_migrations_table_name
|
1027
1029
|
|
1028
1030
|
def get_all_versions(connection = Base.connection)
|
1029
|
-
|
1030
|
-
|
1031
|
-
|
1032
|
-
|
1033
|
-
[]
|
1034
|
-
end
|
1031
|
+
if SchemaMigration.table_exists?
|
1032
|
+
SchemaMigration.all_versions.map(&:to_i)
|
1033
|
+
else
|
1034
|
+
[]
|
1035
1035
|
end
|
1036
1036
|
end
|
1037
1037
|
|
@@ -1052,7 +1052,7 @@ module ActiveRecord
|
|
1052
1052
|
end
|
1053
1053
|
|
1054
1054
|
def migrations_paths
|
1055
|
-
@migrations_paths ||= [
|
1055
|
+
@migrations_paths ||= ["db/migrate"]
|
1056
1056
|
# just to not break things if someone uses: migrations_path = some_string
|
1057
1057
|
Array(@migrations_paths)
|
1058
1058
|
end
|
@@ -1115,8 +1115,6 @@ module ActiveRecord
|
|
1115
1115
|
end
|
1116
1116
|
|
1117
1117
|
def initialize(direction, migrations, target_version = nil)
|
1118
|
-
raise StandardError.new("This database does not yet support migrations") unless Base.connection.supports_migrations?
|
1119
|
-
|
1120
1118
|
@direction = direction
|
1121
1119
|
@target_version = target_version
|
1122
1120
|
@migrated_versions = nil
|
@@ -1124,8 +1122,8 @@ module ActiveRecord
|
|
1124
1122
|
|
1125
1123
|
validate(@migrations)
|
1126
1124
|
|
1127
|
-
|
1128
|
-
|
1125
|
+
ActiveRecord::SchemaMigration.create_table
|
1126
|
+
ActiveRecord::InternalMetadata.create_table
|
1129
1127
|
end
|
1130
1128
|
|
1131
1129
|
def current_version
|
@@ -1183,148 +1181,148 @@ module ActiveRecord
|
|
1183
1181
|
|
1184
1182
|
private
|
1185
1183
|
|
1186
|
-
|
1187
|
-
|
1188
|
-
|
1189
|
-
|
1190
|
-
|
1191
|
-
|
1192
|
-
record_environment
|
1193
|
-
result
|
1194
|
-
end
|
1184
|
+
# Used for running a specific migration.
|
1185
|
+
def run_without_lock
|
1186
|
+
migration = migrations.detect { |m| m.version == @target_version }
|
1187
|
+
raise UnknownMigrationVersionError.new(@target_version) if migration.nil?
|
1188
|
+
result = execute_migration_in_transaction(migration, @direction)
|
1195
1189
|
|
1196
|
-
|
1197
|
-
|
1198
|
-
if invalid_target?
|
1199
|
-
raise UnknownMigrationVersionError.new(@target_version)
|
1190
|
+
record_environment
|
1191
|
+
result
|
1200
1192
|
end
|
1201
1193
|
|
1202
|
-
|
1203
|
-
|
1204
|
-
|
1194
|
+
# Used for running multiple migrations up to or down to a certain value.
|
1195
|
+
def migrate_without_lock
|
1196
|
+
if invalid_target?
|
1197
|
+
raise UnknownMigrationVersionError.new(@target_version)
|
1198
|
+
end
|
1205
1199
|
|
1206
|
-
|
1207
|
-
|
1208
|
-
|
1200
|
+
result = runnable.each do |migration|
|
1201
|
+
execute_migration_in_transaction(migration, @direction)
|
1202
|
+
end
|
1209
1203
|
|
1210
|
-
|
1211
|
-
|
1212
|
-
|
1213
|
-
ActiveRecord::InternalMetadata[:environment] = ActiveRecord::Migrator.current_environment
|
1214
|
-
end
|
1204
|
+
record_environment
|
1205
|
+
result
|
1206
|
+
end
|
1215
1207
|
|
1216
|
-
|
1217
|
-
|
1218
|
-
|
1208
|
+
# Stores the current environment in the database.
|
1209
|
+
def record_environment
|
1210
|
+
return if down?
|
1211
|
+
ActiveRecord::InternalMetadata[:environment] = ActiveRecord::Migrator.current_environment
|
1212
|
+
end
|
1219
1213
|
|
1220
|
-
|
1221
|
-
|
1222
|
-
|
1223
|
-
end
|
1214
|
+
def ran?(migration)
|
1215
|
+
migrated.include?(migration.version.to_i)
|
1216
|
+
end
|
1224
1217
|
|
1225
|
-
|
1226
|
-
|
1227
|
-
|
1218
|
+
# Return true if a valid version is not provided.
|
1219
|
+
def invalid_target?
|
1220
|
+
!target && @target_version && @target_version > 0
|
1221
|
+
end
|
1228
1222
|
|
1229
|
-
|
1223
|
+
def execute_migration_in_transaction(migration, direction)
|
1224
|
+
return if down? && !migrated.include?(migration.version.to_i)
|
1225
|
+
return if up? && migrated.include?(migration.version.to_i)
|
1230
1226
|
|
1231
|
-
|
1232
|
-
|
1233
|
-
|
1227
|
+
Base.logger.info "Migrating to #{migration.name} (#{migration.version})" if Base.logger
|
1228
|
+
|
1229
|
+
ddl_transaction(migration) do
|
1230
|
+
migration.migrate(direction)
|
1231
|
+
record_version_state_after_migrating(migration.version)
|
1232
|
+
end
|
1233
|
+
rescue => e
|
1234
|
+
msg = "An error has occurred, "
|
1235
|
+
msg << "this and " if use_transaction?(migration)
|
1236
|
+
msg << "all later migrations canceled:\n\n#{e}"
|
1237
|
+
raise StandardError, msg, e.backtrace
|
1234
1238
|
end
|
1235
|
-
rescue => e
|
1236
|
-
msg = "An error has occurred, "
|
1237
|
-
msg << "this and " if use_transaction?(migration)
|
1238
|
-
msg << "all later migrations canceled:\n\n#{e}"
|
1239
|
-
raise StandardError, msg, e.backtrace
|
1240
|
-
end
|
1241
1239
|
|
1242
|
-
|
1243
|
-
|
1244
|
-
|
1240
|
+
def target
|
1241
|
+
migrations.detect { |m| m.version == @target_version }
|
1242
|
+
end
|
1245
1243
|
|
1246
|
-
|
1247
|
-
|
1248
|
-
|
1244
|
+
def finish
|
1245
|
+
migrations.index(target) || migrations.size - 1
|
1246
|
+
end
|
1249
1247
|
|
1250
|
-
|
1251
|
-
|
1252
|
-
|
1248
|
+
def start
|
1249
|
+
up? ? 0 : (migrations.index(current) || 0)
|
1250
|
+
end
|
1253
1251
|
|
1254
|
-
|
1255
|
-
|
1256
|
-
|
1252
|
+
def validate(migrations)
|
1253
|
+
name , = migrations.group_by(&:name).find { |_, v| v.length > 1 }
|
1254
|
+
raise DuplicateMigrationNameError.new(name) if name
|
1257
1255
|
|
1258
|
-
|
1259
|
-
|
1260
|
-
|
1256
|
+
version , = migrations.group_by(&:version).find { |_, v| v.length > 1 }
|
1257
|
+
raise DuplicateMigrationVersionError.new(version) if version
|
1258
|
+
end
|
1261
1259
|
|
1262
|
-
|
1263
|
-
|
1264
|
-
|
1265
|
-
|
1266
|
-
|
1267
|
-
|
1268
|
-
|
1260
|
+
def record_version_state_after_migrating(version)
|
1261
|
+
if down?
|
1262
|
+
migrated.delete(version)
|
1263
|
+
ActiveRecord::SchemaMigration.where(version: version.to_s).delete_all
|
1264
|
+
else
|
1265
|
+
migrated << version
|
1266
|
+
ActiveRecord::SchemaMigration.create!(version: version.to_s)
|
1267
|
+
end
|
1269
1268
|
end
|
1270
|
-
end
|
1271
1269
|
|
1272
|
-
|
1273
|
-
|
1274
|
-
|
1270
|
+
def self.last_stored_environment
|
1271
|
+
return nil if current_version == 0
|
1272
|
+
raise NoEnvironmentInSchemaError unless ActiveRecord::InternalMetadata.table_exists?
|
1275
1273
|
|
1276
|
-
|
1277
|
-
|
1278
|
-
|
1279
|
-
|
1274
|
+
environment = ActiveRecord::InternalMetadata[:environment]
|
1275
|
+
raise NoEnvironmentInSchemaError unless environment
|
1276
|
+
environment
|
1277
|
+
end
|
1280
1278
|
|
1281
|
-
|
1282
|
-
|
1283
|
-
|
1279
|
+
def self.current_environment
|
1280
|
+
ActiveRecord::ConnectionHandling::DEFAULT_ENV.call
|
1281
|
+
end
|
1284
1282
|
|
1285
|
-
|
1286
|
-
|
1287
|
-
|
1283
|
+
def self.protected_environment?
|
1284
|
+
ActiveRecord::Base.protected_environments.include?(last_stored_environment) if last_stored_environment
|
1285
|
+
end
|
1288
1286
|
|
1289
|
-
|
1290
|
-
|
1291
|
-
|
1287
|
+
def up?
|
1288
|
+
@direction == :up
|
1289
|
+
end
|
1292
1290
|
|
1293
|
-
|
1294
|
-
|
1295
|
-
|
1291
|
+
def down?
|
1292
|
+
@direction == :down
|
1293
|
+
end
|
1296
1294
|
|
1297
|
-
|
1298
|
-
|
1299
|
-
|
1300
|
-
|
1301
|
-
|
1302
|
-
|
1295
|
+
# Wrap the migration in a transaction only if supported by the adapter.
|
1296
|
+
def ddl_transaction(migration)
|
1297
|
+
if use_transaction?(migration)
|
1298
|
+
Base.transaction { yield }
|
1299
|
+
else
|
1300
|
+
yield
|
1301
|
+
end
|
1303
1302
|
end
|
1304
|
-
end
|
1305
1303
|
|
1306
|
-
|
1307
|
-
|
1308
|
-
|
1304
|
+
def use_transaction?(migration)
|
1305
|
+
!migration.disable_ddl_transaction && Base.connection.supports_ddl_transactions?
|
1306
|
+
end
|
1309
1307
|
|
1310
|
-
|
1311
|
-
|
1312
|
-
|
1308
|
+
def use_advisory_lock?
|
1309
|
+
Base.connection.supports_advisory_locks?
|
1310
|
+
end
|
1313
1311
|
|
1314
|
-
|
1315
|
-
|
1316
|
-
|
1317
|
-
|
1318
|
-
|
1319
|
-
|
1320
|
-
|
1321
|
-
|
1322
|
-
|
1312
|
+
def with_advisory_lock
|
1313
|
+
lock_id = generate_migrator_advisory_lock_id
|
1314
|
+
got_lock = Base.connection.get_advisory_lock(lock_id)
|
1315
|
+
raise ConcurrentMigrationError unless got_lock
|
1316
|
+
load_migrated # reload schema_migrations to be sure it wasn't changed by another process before we got the lock
|
1317
|
+
yield
|
1318
|
+
ensure
|
1319
|
+
Base.connection.release_advisory_lock(lock_id) if got_lock
|
1320
|
+
end
|
1323
1321
|
|
1324
|
-
|
1325
|
-
|
1326
|
-
|
1327
|
-
|
1328
|
-
|
1322
|
+
MIGRATOR_SALT = 2053462845
|
1323
|
+
def generate_migrator_advisory_lock_id
|
1324
|
+
db_name_hash = Zlib.crc32(Base.connection.current_database)
|
1325
|
+
MIGRATOR_SALT * db_name_hash
|
1326
|
+
end
|
1329
1327
|
end
|
1330
1328
|
end
|