migration.rb 42.5 KB
Newer Older
1
require "set"
L
Lars Kanis 已提交
2
require "zlib"
X
Xavier Noria 已提交
3
require "active_support/core_ext/module/attribute_accessors"
4
require "active_support/core_ext/regexp"
5

6
module ActiveRecord
7 8 9 10 11 12 13
  class MigrationError < ActiveRecordError#:nodoc:
    def initialize(message = nil)
      message = "\n\n#{message}\n\n" if message
      super
    end
  end

14 15 16
  # Exception that can be raised to stop migrations from being rolled back.
  # For example the following migration is not reversible.
  # Rolling back this migration will raise an ActiveRecord::IrreversibleMigration error.
17
  #
18
  #   class IrreversibleMigrationExample < ActiveRecord::Migration[5.0]
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
  #     def change
  #       create_table :distributors do |t|
  #         t.string :zipcode
  #       end
  #
  #       execute <<-SQL
  #         ALTER TABLE distributors
  #           ADD CONSTRAINT zipchk
  #             CHECK (char_length(zipcode) = 5) NO INHERIT;
  #       SQL
  #     end
  #   end
  #
  # There are two ways to mitigate this problem.
  #
34
  # 1. Define <tt>#up</tt> and <tt>#down</tt> methods instead of <tt>#change</tt>:
35
  #
36
  #  class ReversibleMigrationExample < ActiveRecord::Migration[5.0]
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
  #    def up
  #      create_table :distributors do |t|
  #        t.string :zipcode
  #      end
  #
  #      execute <<-SQL
  #        ALTER TABLE distributors
  #          ADD CONSTRAINT zipchk
  #            CHECK (char_length(zipcode) = 5) NO INHERIT;
  #      SQL
  #    end
  #
  #    def down
  #      execute <<-SQL
  #        ALTER TABLE distributors
  #          DROP CONSTRAINT zipchk
  #      SQL
  #
  #      drop_table :distributors
  #    end
  #  end
  #
59
  # 2. Use the #reversible method in <tt>#change</tt> method:
60
  #
61
  #   class ReversibleMigrationExample < ActiveRecord::Migration[5.0]
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
  #     def change
  #       create_table :distributors do |t|
  #         t.string :zipcode
  #       end
  #
  #       reversible do |dir|
  #         dir.up do
  #           execute <<-SQL
  #             ALTER TABLE distributors
  #               ADD CONSTRAINT zipchk
  #                 CHECK (char_length(zipcode) = 5) NO INHERIT;
  #           SQL
  #         end
  #
  #         dir.down do
  #           execute <<-SQL
  #             ALTER TABLE distributors
  #               DROP CONSTRAINT zipchk
  #           SQL
  #         end
  #       end
  #     end
  #   end
85
  class IrreversibleMigration < MigrationError
86
  end
87

88
  class DuplicateMigrationVersionError < MigrationError#:nodoc:
89 90 91 92 93 94
    def initialize(version = nil)
      if version
        super("Multiple migrations have the version number #{version}.")
      else
        super("Duplicate migration version error.")
      end
95 96
    end
  end
97

98
  class DuplicateMigrationNameError < MigrationError#:nodoc:
99 100 101 102 103 104
    def initialize(name = nil)
      if name
        super("Multiple migrations have the name #{name}.")
      else
        super("Duplicate migration name.")
      end
105 106 107
    end
  end

108
  class UnknownMigrationVersionError < MigrationError #:nodoc:
109 110 111 112 113 114
    def initialize(version = nil)
      if version
        super("No migration with version number #{version}.")
      else
        super("Unknown migration version.")
      end
115 116 117
    end
  end

118
  class IllegalMigrationNameError < MigrationError#:nodoc:
119 120 121 122 123 124
    def initialize(name = nil)
      if name
        super("Illegal name for migration file: #{name}\n\t(only lower case letters, numbers, and '_' allowed).")
      else
        super("Illegal name for migration.")
      end
125 126 127
    end
  end

128
  class PendingMigrationError < MigrationError#:nodoc:
129 130
    def initialize(message = nil)
      if !message && defined?(Rails.env)
131
        super("Migrations are pending. To resolve this issue, run:\n\n        bin/rails db:migrate RAILS_ENV=#{::Rails.env}")
132
      elsif !message
133
        super("Migrations are pending. To resolve this issue, run:\n\n        bin/rails db:migrate")
134
      else
135
        super
136
      end
S
schneems 已提交
137 138 139
    end
  end

140 141 142 143 144 145 146 147
  class ConcurrentMigrationError < MigrationError #:nodoc:
    DEFAULT_MESSAGE = "Cannot run migrations because another migration process is currently running.".freeze

    def initialize(message = DEFAULT_MESSAGE)
      super
    end
  end

148 149
  class NoEnvironmentInSchemaError < MigrationError #:nodoc:
    def initialize
150
      msg = "Environment data not found in the schema. To resolve this issue, run: \n\n        bin/rails db:environment:set"
151 152 153 154 155 156 157 158 159 160
      if defined?(Rails.env)
        super("#{msg} RAILS_ENV=#{::Rails.env}")
      else
        super(msg)
      end
    end
  end

  class ProtectedEnvironmentError < ActiveRecordError #:nodoc:
    def initialize(env = "production")
161 162
      msg = "You are attempting to run a destructive action against your '#{env}' database.\n"
      msg << "If you are sure you want to continue, run the same command with the environment variable:\n"
163 164 165 166 167
      msg << "DISABLE_DATABASE_ENVIRONMENT_CHECK=1"
      super(msg)
    end
  end

S
schneems 已提交
168
  class EnvironmentMismatchError < ActiveRecordError
169
    def initialize(current: nil, stored: nil)
170
      msg =  "You are attempting to modify a database that was last run in `#{ stored }` environment.\n"
171
      msg << "You are running in `#{ current }` environment. "
172
      msg << "If you are sure you want to continue, first set the environment using:\n\n"
173
      msg << "        bin/rails db:environment:set"
174
      if defined?(Rails.env)
175
        super("#{msg} RAILS_ENV=#{::Rails.env}\n\n")
176
      else
177
        super("#{msg}\n\n")
178
      end
S
schneems 已提交
179 180 181
    end
  end

R
Rizwan Reza 已提交
182
  # = Active Record Migrations
183 184
  #
  # Migrations can manage the evolution of a schema used by several physical
R
Rizwan Reza 已提交
185 186
  # databases. It's a solution to the common problem of adding a field to make
  # a new feature work in your local database, but being unsure of how to
187
  # push that change to other developers and to the production server. With
R
Rizwan Reza 已提交
188
  # migrations, you can describe the transformations in self-contained classes
189
  # that can be checked into version control systems and executed against
R
Rizwan Reza 已提交
190
  # another database that might be one, two, or five versions behind.
191 192 193
  #
  # Example of a simple migration:
  #
194
  #   class AddSsl < ActiveRecord::Migration[5.0]
195
  #     def up
196
  #       add_column :accounts, :ssl_enabled, :boolean, default: true
197
  #     end
198
  #
199
  #     def down
200 201 202 203
  #       remove_column :accounts, :ssl_enabled
  #     end
  #   end
  #
204 205
  # This migration will add a boolean flag to the accounts table and remove it
  # if you're backing out of the migration. It shows how all migrations have
206
  # two methods +up+ and +down+ that describes the transformations
R
Rizwan Reza 已提交
207
  # required to implement or remove the migration. These methods can consist
208
  # of both the migration specific methods like +add_column+ and +remove_column+,
209
  # but may also contain regular Ruby code for generating data needed for the
R
Rizwan Reza 已提交
210
  # transformations.
211 212 213
  #
  # Example of a more complex migration that also needs to initialize data:
  #
214
  #   class AddSystemSettings < ActiveRecord::Migration[5.0]
215
  #     def up
216
  #       create_table :system_settings do |t|
217 218
  #         t.string  :name
  #         t.string  :label
V
Vijay Dev 已提交
219
  #         t.text    :value
220
  #         t.string  :type
V
Vijay Dev 已提交
221
  #         t.integer :position
222
  #       end
223
  #
224 225 226
  #       SystemSetting.create  name:  'notice',
  #                             label: 'Use notice?',
  #                             value: 1
227
  #     end
228
  #
229
  #     def down
230 231 232 233
  #       drop_table :system_settings
  #     end
  #   end
  #
234
  # This migration first adds the +system_settings+ table, then creates the very
R
Rizwan Reza 已提交
235
  # first row in it using the Active Record model that relies on the table. It
236
  # also uses the more advanced +create_table+ syntax where you can specify a
R
Rizwan Reza 已提交
237
  # complete table schema in one block call.
238 239 240
  #
  # == Available transformations
  #
241 242 243 244 245 246 247
  # === Creation
  #
  # * <tt>create_join_table(table_1, table_2, options)</tt>: Creates a join
  #   table having its name as the lexical order of the first two
  #   arguments. See
  #   ActiveRecord::ConnectionAdapters::SchemaStatements#create_join_table for
  #   details.
248
  # * <tt>create_table(name, options)</tt>: Creates a table called +name+ and
R
Rizwan Reza 已提交
249
  #   makes the table object available to a block that can then add columns to it,
250
  #   following the same format as +add_column+. See example above. The options hash
251
  #   is for fragments like "DEFAULT CHARSET=UTF-8" that are appended to the create
R
Rizwan Reza 已提交
252
  #   table definition.
253
  # * <tt>add_column(table_name, column_name, type, options)</tt>: Adds a new column
R
Rizwan Reza 已提交
254
  #   to the table called +table_name+
255
  #   named +column_name+ specified to be one of the following types:
256
  #   <tt>:string</tt>, <tt>:text</tt>, <tt>:integer</tt>, <tt>:float</tt>,
R
Rizwan Reza 已提交
257
  #   <tt>:decimal</tt>, <tt>:datetime</tt>, <tt>:timestamp</tt>, <tt>:time</tt>,
258
  #   <tt>:date</tt>, <tt>:binary</tt>, <tt>:boolean</tt>. A default value can be
259
  #   specified by passing an +options+ hash like <tt>{ default: 11 }</tt>.
260
  #   Other options include <tt>:limit</tt> and <tt>:null</tt> (e.g.
261
  #   <tt>{ limit: 50, null: false }</tt>) -- see
R
Rizwan Reza 已提交
262
  #   ActiveRecord::ConnectionAdapters::TableDefinition#column for details.
263 264 265
  # * <tt>add_foreign_key(from_table, to_table, options)</tt>: Adds a new
  #   foreign key. +from_table+ is the table with the key column, +to_table+ contains
  #   the referenced primary key.
266
  # * <tt>add_index(table_name, column_names, options)</tt>: Adds a new index
R
Rizwan Reza 已提交
267
  #   with the name of the column. Other options include
268
  #   <tt>:name</tt>, <tt>:unique</tt> (e.g.
269
  #   <tt>{ name: 'users_name_index', unique: true }</tt>) and <tt>:order</tt>
L
Lincoln Lee 已提交
270
  #   (e.g. <tt>{ order: { name: :desc } }</tt>).
271 272 273
  # * <tt>add_reference(:table_name, :reference_name)</tt>: Adds a new column
  #   +reference_name_id+ by default an integer. See
  #   ActiveRecord::ConnectionAdapters::SchemaStatements#add_reference for details.
274 275 276 277 278 279 280
  # * <tt>add_timestamps(table_name, options)</tt>: Adds timestamps (+created_at+
  #   and +updated_at+) columns to +table_name+.
  #
  # === Modification
  #
  # * <tt>change_column(table_name, column_name, type, options)</tt>:  Changes
  #   the column to a different type using the same parameters as add_column.
281 282 283 284
  # * <tt>change_column_default(table_name, column_name, default_or_changes)</tt>:
  #   Sets a default value for +column_name+ defined by +default_or_changes+ on
  #   +table_name+. Passing a hash containing <tt>:from</tt> and <tt>:to</tt>
  #   as +default_or_changes+ will make this change reversible in the migration.
285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309
  # * <tt>change_column_null(table_name, column_name, null, default = nil)</tt>:
  #   Sets or removes a +NOT NULL+ constraint on +column_name+. The +null+ flag
  #   indicates whether the value can be +NULL+. See
  #   ActiveRecord::ConnectionAdapters::SchemaStatements#change_column_null for
  #   details.
  # * <tt>change_table(name, options)</tt>: Allows to make column alterations to
  #   the table called +name+. It makes the table object available to a block that
  #   can then add/remove columns, indexes or foreign keys to it.
  # * <tt>rename_column(table_name, column_name, new_column_name)</tt>: Renames
  #   a column but keeps the type and content.
  # * <tt>rename_index(table_name, old_name, new_name)</tt>: Renames an index.
  # * <tt>rename_table(old_name, new_name)</tt>: Renames the table called +old_name+
  #   to +new_name+.
  #
  # === Deletion
  #
  # * <tt>drop_table(name)</tt>: Drops the table called +name+.
  # * <tt>drop_join_table(table_1, table_2, options)</tt>: Drops the join table
  #   specified by the given arguments.
  # * <tt>remove_column(table_name, column_name, type, options)</tt>: Removes the column
  #   named +column_name+ from the table called +table_name+.
  # * <tt>remove_columns(table_name, *column_names)</tt>: Removes the given
  #   columns from the table definition.
  # * <tt>remove_foreign_key(from_table, options_or_to_table)</tt>: Removes the
  #   given foreign key from the table called +table_name+.
A
Aleksandar Diklic 已提交
310 311
  # * <tt>remove_index(table_name, column: column_names)</tt>: Removes the index
  #   specified by +column_names+.
312
  # * <tt>remove_index(table_name, name: index_name)</tt>: Removes the index
313
  #   specified by +index_name+.
314 315 316 317
  # * <tt>remove_reference(table_name, ref_name, options)</tt>: Removes the
  #   reference(s) on +table_name+ specified by +ref_name+.
  # * <tt>remove_timestamps(table_name, options)</tt>: Removes the timestamp
  #   columns (+created_at+ and +updated_at+) from the table definition.
318 319 320
  #
  # == Irreversible transformations
  #
321 322
  # Some transformations are destructive in a manner that cannot be reversed.
  # Migrations of that kind should raise an <tt>ActiveRecord::IrreversibleMigration</tt>
R
Rizwan Reza 已提交
323
  # exception in their +down+ method.
324
  #
325 326
  # == Running migrations from within Rails
  #
327 328
  # The Rails package has several tools to help create and apply migrations.
  #
329
  # To generate a new migration, you can use
330
  #   rails generate migration MyNewMigration
P
Pratik Naik 已提交
331
  #
332
  # where MyNewMigration is the name of your migration. The generator will
333 334
  # create an empty migration file <tt>timestamp_my_new_migration.rb</tt>
  # in the <tt>db/migrate/</tt> directory where <tt>timestamp</tt> is the
R
Rizwan Reza 已提交
335
  # UTC formatted date and time that the migration was generated.
P
Pratik Naik 已提交
336 337
  #
  # There is a special syntactic shortcut to generate migrations that add fields to a table.
R
Rizwan Reza 已提交
338
  #
339
  #   rails generate migration add_fieldname_to_tablename fieldname:string
P
Pratik Naik 已提交
340
  #
341
  # This will generate the file <tt>timestamp_add_fieldname_to_tablename.rb</tt>, which will look like this:
342
  #   class AddFieldnameToTablename < ActiveRecord::Migration[5.0]
343
  #     def change
344
  #       add_column :tablenames, :fieldname, :string
P
Pratik Naik 已提交
345 346
  #     end
  #   end
347
  #
348
  # To run migrations against the currently configured database, use
349
  # <tt>rails db:migrate</tt>. This will update the database by running all of the
350
  # pending migrations, creating the <tt>schema_migrations</tt> table
351
  # (see "About the schema_migrations table" section below) if missing. It will also
P
Pratik Naik 已提交
352 353
  # invoke the db:schema:dump task, which will update your db/schema.rb file
  # to match the structure of your database.
354 355
  #
  # To roll the database back to a previous migration version, use
356
  # <tt>rails db:migrate VERSION=X</tt> where <tt>X</tt> is the version to which
357
  # you wish to downgrade. Alternatively, you can also use the STEP option if you
358
  # wish to rollback last few migrations. <tt>rails db:migrate STEP=2</tt> will rollback
359
  # the latest two migrations.
360 361
  #
  # If any of the migrations throw an <tt>ActiveRecord::IrreversibleMigration</tt> exception,
362
  # that step will fail and you'll have some manual work to do.
363
  #
364 365
  # == Database support
  #
366
  # Migrations are currently supported in MySQL, PostgreSQL, SQLite,
367
  # SQL Server, and Oracle (all supported databases except DB2).
368 369 370 371 372
  #
  # == More examples
  #
  # Not all migrations change the schema. Some just fix the data:
  #
373
  #   class RemoveEmptyTags < ActiveRecord::Migration[5.0]
374
  #     def up
V
Vijay Dev 已提交
375
  #       Tag.all.each { |tag| tag.destroy if tag.pages.empty? }
376
  #     end
377
  #
378
  #     def down
379
  #       # not much we can do to restore deleted data
380
  #       raise ActiveRecord::IrreversibleMigration, "Can't recover the deleted tags"
381 382 383 384 385
  #     end
  #   end
  #
  # Others remove columns when they migrate up instead of down:
  #
386
  #   class RemoveUnnecessaryItemAttributes < ActiveRecord::Migration[5.0]
387
  #     def up
388 389 390 391
  #       remove_column :items, :incomplete_items_count
  #       remove_column :items, :completed_items_count
  #     end
  #
392
  #     def down
393 394 395 396
  #       add_column :items, :incomplete_items_count
  #       add_column :items, :completed_items_count
  #     end
  #   end
397
  #
D
David Heinemeier Hansson 已提交
398
  # And sometimes you need to do something in SQL not abstracted directly by migrations:
399
  #
400
  #   class MakeJoinUnique < ActiveRecord::Migration[5.0]
401
  #     def up
402 403 404
  #       execute "ALTER TABLE `pages_linked_pages` ADD UNIQUE `page_id_linked_page_id` (`page_id`,`linked_page_id`)"
  #     end
  #
405
  #     def down
406 407 408
  #       execute "ALTER TABLE `pages_linked_pages` DROP INDEX `page_id_linked_page_id`"
  #     end
  #   end
409
  #
410
  # == Using a model after changing its table
411
  #
412 413 414
  # Sometimes you'll want to add a column in a migration and populate it
  # immediately after. In that case, you'll need to make a call to
  # <tt>Base#reset_column_information</tt> in order to ensure that the model has the
R
Rizwan Reza 已提交
415
  # latest column data from after the new column was added. Example:
416
  #
417
  #   class AddPeopleSalary < ActiveRecord::Migration[5.0]
A
Aaron Patterson 已提交
418
  #     def up
419
  #       add_column :people, :salary, :integer
420
  #       Person.reset_column_information
V
Vijay Dev 已提交
421
  #       Person.all.each do |p|
422
  #         p.update_attribute :salary, SalaryCalculator.compute(p)
423 424
  #       end
  #     end
425
  #   end
J
Jamis Buck 已提交
426 427 428 429 430 431 432 433 434
  #
  # == Controlling verbosity
  #
  # By default, migrations will describe the actions they are taking, writing
  # them to the console as they happen, along with benchmarks describing how
  # long each step took.
  #
  # You can quiet them down by setting ActiveRecord::Migration.verbose = false.
  #
P
Pratik Naik 已提交
435
  # You can also insert your own messages and benchmarks by using the +say_with_time+
J
Jamis Buck 已提交
436 437
  # method:
  #
A
Aaron Patterson 已提交
438
  #   def up
J
Jamis Buck 已提交
439 440
  #     ...
  #     say_with_time "Updating salaries..." do
V
Vijay Dev 已提交
441
  #       Person.all.each do |p|
442
  #         p.update_attribute :salary, SalaryCalculator.compute(p)
J
Jamis Buck 已提交
443 444 445 446 447 448 449
  #       end
  #     end
  #     ...
  #   end
  #
  # The phrase "Updating salaries..." would then be printed, along with the
  # benchmark for the block when the block completes.
450
  #
451 452 453 454 455 456 457 458 459 460 461 462
  # == Timestamped Migrations
  #
  # By default, Rails generates migrations that look like:
  #
  #    20080717013526_your_migration_name.rb
  #
  # The prefix is a generation timestamp (in UTC).
  #
  # If you'd prefer to use numeric prefixes, you can turn timestamped migrations
  # off by setting:
  #
  #    config.active_record.timestamped_migrations = false
463
  #
464
  # In application.rb.
465
  #
466 467 468
  # == Reversible Migrations
  #
  # Reversible migrations are migrations that know how to go +down+ for you.
469
  # You simply supply the +up+ logic, and the Migration system figures out
470 471 472 473 474
  # how to execute the down commands for you.
  #
  # To define a reversible migration, define the +change+ method in your
  # migration like this:
  #
475
  #   class TenderloveMigration < ActiveRecord::Migration[5.0]
476
  #     def change
477
  #       create_table(:horses) do |t|
478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496
  #         t.column :content, :text
  #         t.column :remind_at, :datetime
  #       end
  #     end
  #   end
  #
  # This migration will create the horses table for you on the way up, and
  # automatically figure out how to drop the table on the way down.
  #
  # Some commands like +remove_column+ cannot be reversed.  If you care to
  # define how to move up and down in these cases, you should define the +up+
  # and +down+ methods as before.
  #
  # If a command cannot be reversed, an
  # <tt>ActiveRecord::IrreversibleMigration</tt> exception will be raised when
  # the migration is moving down.
  #
  # For a list of commands that are reversible, please see
  # <tt>ActiveRecord::Migration::CommandRecorder</tt>.
497 498 499 500 501 502 503 504
  #
  # == Transactional Migrations
  #
  # If the database adapter supports DDL transactions, all migrations will
  # automatically be wrapped in a transaction. There are queries that you
  # can't execute inside a transaction though, and for these situations
  # you can turn the automatic transactions off.
  #
505
  #   class ChangeEnum < ActiveRecord::Migration[5.0]
506 507
  #     disable_ddl_transaction!
  #
508 509 510 511 512 513 514
  #     def up
  #       execute "ALTER TYPE model_size ADD VALUE 'new_value'"
  #     end
  #   end
  #
  # Remember that you can still open your own transactions, even if you
  # are in a Migration with <tt>self.disable_ddl_transaction!</tt>.
515
  class Migration
516 517
    autoload :CommandRecorder, "active_record/migration/command_recorder"
    autoload :Compatibility, "active_record/migration/compatibility"
518 519 520 521 522 523 524 525 526 527 528 529 530

    # This must be defined before the inherited hook, below
    class Current < Migration # :nodoc:
    end

    def self.inherited(subclass) # :nodoc:
      super
      if subclass.superclass == Migration
        subclass.include Compatibility::Legacy
      end
    end

    def self.[](version)
531
      Compatibility.find(version)
532 533 534
    end

    def self.current_version
535
      ActiveRecord::VERSION::STRING.to_f
536
    end
537

538
    MigrationFilenameRegexp = /\A([0-9]+)_([_a-z0-9]*)\.?([_a-z0-9]*)?\.rb\z/ # :nodoc:
S
schneems 已提交
539 540

    # This class is used to verify that all migrations have been run before
G
Gaurish Sharma 已提交
541
    # loading a web page if <tt>config.active_record.migration_error</tt> is set to :page_load
S
schneems 已提交
542
    class CheckPending
543
      def initialize(app)
S
schneems 已提交
544
        @app = app
545
        @last_check = 0
S
schneems 已提交
546 547 548
      end

      def call(env)
549
        if connection.supports_migrations?
550 551
          mtime = ActiveRecord::Migrator.last_migration.mtime.to_i
          if @last_check < mtime
552
            ActiveRecord::Migration.check_pending!(connection)
553 554
            @last_check = mtime
          end
555
        end
556
        @app.call(env)
S
schneems 已提交
557
      end
558 559 560

      private

561 562 563
        def connection
          ActiveRecord::Base.connection
        end
S
schneems 已提交
564 565
    end

566
    class << self
567
      attr_accessor :delegate # :nodoc:
568
      attr_accessor :disable_ddl_transaction # :nodoc:
569

570 571 572 573
      def nearest_delegate # :nodoc:
        delegate || superclass.nearest_delegate
      end

574
      # Raises <tt>ActiveRecord::PendingMigrationError</tt> error if any migrations are pending.
575 576
      def check_pending!(connection = Base.connection)
        raise ActiveRecord::PendingMigrationError if ActiveRecord::Migrator.needs_migration?(connection)
577
      end
S
schneems 已提交
578

579
      def load_schema_if_pending!
580
        if ActiveRecord::Migrator.needs_migration? || !ActiveRecord::Migrator.any_migrations?
L
Luke Hutscal 已提交
581
          # Roundtrip to Rake to allow plugins to hook into database initialization.
Y
Yves Senn 已提交
582 583 584
          FileUtils.cd Rails.root do
            current_config = Base.connection_config
            Base.clear_all_connections!
585
            system("bin/rails db:test:prepare")
Y
Yves Senn 已提交
586 587 588
            # Establish a new connection, the old database may be gone (db:test:prepare uses purge)
            Base.establish_connection(current_config)
          end
589 590 591 592 593 594 595 596 597 598
          check_pending!
        end
      end

      def maintain_test_schema! # :nodoc:
        if ActiveRecord::Base.maintain_test_schema
          suppress_messages { load_schema_if_pending! }
        end
      end

599
      def method_missing(name, *args, &block) # :nodoc:
600
        nearest_delegate.send(name, *args, &block)
601
      end
602

603 604 605
      def migrate(direction)
        new.migrate direction
      end
606

607 608 609 610
      # Disable the transaction wrapping this migration.
      # You can still create your own transactions even after calling #disable_ddl_transaction!
      #
      # For more details read the {"Transactional Migrations" section above}[rdoc-ref:Migration].
611 612 613
      def disable_ddl_transaction!
        @disable_ddl_transaction = true
      end
614 615 616 617 618
    end

    def disable_ddl_transaction # :nodoc:
      self.class.disable_ddl_transaction
    end
619

620
    cattr_accessor :verbose
621
    attr_accessor :name, :version
622

623 624 625
    def initialize(name = self.class.name, version = nil)
      @name       = name
      @version    = version
626
      @connection = nil
627 628
    end

629
    self.verbose = true
630 631 632
    # instantiate the delegate object after initialize is defined
    self.delegate = new

633 634
    # Reverses the migration commands for the given block and
    # the given migrations.
635 636 637 638 639
    #
    # The following migration will remove the table 'horses'
    # and create the table 'apples' on the way up, and the reverse
    # on the way down.
    #
640
    #   class FixTLMigration < ActiveRecord::Migration[5.0]
641 642 643 644 645 646 647 648 649 650 651 652 653
    #     def change
    #       revert do
    #         create_table(:horses) do |t|
    #           t.text :content
    #           t.datetime :remind_at
    #         end
    #       end
    #       create_table(:apples) do |t|
    #         t.string :variety
    #       end
    #     end
    #   end
    #
654 655 656
    # Or equivalently, if +TenderloveMigration+ is defined as in the
    # documentation for Migration:
    #
657
    #   require_relative '20121212123456_tenderlove_migration'
658
    #
659
    #   class FixupTLMigration < ActiveRecord::Migration[5.0]
660 661 662 663 664 665 666 667
    #     def change
    #       revert TenderloveMigration
    #
    #       create_table(:apples) do |t|
    #         t.string :variety
    #       end
    #     end
    #   end
668
    #
669 670 671 672
    # This command can be nested.
    def revert(*migration_classes)
      run(*migration_classes.reverse, revert: true) unless migration_classes.empty?
      if block_given?
673 674
        if connection.respond_to? :revert
          connection.revert { yield }
675
        else
676
          recorder = CommandRecorder.new(connection)
677 678
          @connection = recorder
          suppress_messages do
679
            connection.revert { yield }
680 681 682 683 684 685
          end
          @connection = recorder.delegate
          recorder.commands.each do |cmd, args, block|
            send(cmd, *args, &block)
          end
        end
686
      end
687 688 689
    end

    def reverting?
690
      connection.respond_to?(:reverting) && connection.reverting
691 692
    end

693
    class ReversibleBlockHelper < Struct.new(:reverting) # :nodoc:
694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711
      def up
        yield unless reverting
      end

      def down
        yield if reverting
      end
    end

    # Used to specify an operation that can be run in one direction or another.
    # Call the methods +up+ and +down+ of the yielded object to run a block
    # only in one given direction.
    # The whole block will be called in the right order within the migration.
    #
    # In the following example, the looping on users will always be done
    # when the three columns 'first_name', 'last_name' and 'full_name' exist,
    # even when migrating down:
    #
712
    #    class SplitNameMigration < ActiveRecord::Migration[5.0]
713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730
    #      def change
    #        add_column :users, :first_name, :string
    #        add_column :users, :last_name, :string
    #
    #        reversible do |dir|
    #          User.reset_column_information
    #          User.all.each do |u|
    #            dir.up   { u.first_name, u.last_name = u.full_name.split(' ') }
    #            dir.down { u.full_name = "#{u.first_name} #{u.last_name}" }
    #            u.save
    #          end
    #        end
    #
    #        revert { add_column :users, :full_name, :string }
    #      end
    #    end
    def reversible
      helper = ReversibleBlockHelper.new(reverting?)
731
      execute_block { yield helper }
732 733
    end

734 735 736 737 738 739 740 741 742 743 744 745 746
    # Runs the given migration classes.
    # Last argument can specify options:
    # - :direction (default is :up)
    # - :revert (default is false)
    def run(*migration_classes)
      opts = migration_classes.extract_options!
      dir = opts[:direction] || :up
      dir = (dir == :down ? :up : :down) if opts[:revert]
      if reverting?
        # If in revert and going :up, say, we want to execute :down without reverting, so
        revert { run(*migration_classes, direction: dir, revert: true) }
      else
        migration_classes.each do |migration_class|
747
          migration_class.new.exec_migration(connection, dir)
748 749 750 751
        end
      end
    end

752 753
    def up
      self.class.delegate = self
754
      return unless self.class.respond_to?(:up)
755 756 757 758 759
      self.class.up
    end

    def down
      self.class.delegate = self
760
      return unless self.class.respond_to?(:down)
761 762 763
      self.class.down
    end

764 765 766
    # Execute this migration in the named direction
    def migrate(direction)
      return unless respond_to?(direction)
J
Jamis Buck 已提交
767

768 769 770 771
      case direction
      when :up   then announce "migrating"
      when :down then announce "reverting"
      end
J
Jamis Buck 已提交
772

773 774
      time   = nil
      ActiveRecord::Base.connection_pool.with_connection do |conn|
775
        time = Benchmark.measure do
776
          exec_migration(conn, direction)
777
        end
778
      end
779

780 781 782
      case direction
      when :up   then announce "migrated (%.4fs)" % time.real; write
      when :down then announce "reverted (%.4fs)" % time.real; write
J
Jamis Buck 已提交
783
      end
784
    end
785 786 787 788 789 790 791 792 793 794 795 796 797 798 799

    def exec_migration(conn, direction)
      @connection = conn
      if respond_to?(:change)
        if direction == :down
          revert { change }
        else
          change
        end
      else
        send(direction)
      end
    ensure
      @connection = nil
    end
J
Jamis Buck 已提交
800

801 802 803
    def write(text="")
      puts(text) if verbose
    end
804

805 806 807 808 809
    def announce(message)
      text = "#{version} #{name}: #{message}"
      length = [0, 75 - text.length].max
      write "== %s %s" % [text, "=" * length]
    end
J
Jamis Buck 已提交
810

811 812 813
    def say(message, subitem=false)
      write "#{subitem ? "   ->" : "--"} #{message}"
    end
J
Jamis Buck 已提交
814

815 816 817 818 819 820 821 822
    def say_with_time(message)
      say(message)
      result = nil
      time = Benchmark.measure { result = yield }
      say "%.4fs" % time.real, :subitem
      say("#{result} rows", :subitem) if result.is_a?(Integer)
      result
    end
823

824 825 826 827 828 829
    def suppress_messages
      save, self.verbose = verbose, false
      yield
    ensure
      self.verbose = save
    end
830

831
    def connection
832
      @connection || ActiveRecord::Base.connection
833
    end
834

835
    def method_missing(method, *arguments, &block)
836
      arg_list = arguments.map(&:inspect) * ", "
837 838

      say_with_time "#{method}(#{arg_list})" do
839
        unless connection.respond_to? :revert
840
          unless arguments.empty? || [:execute, :enable_extension, :disable_extension].include?(method)
841
            arguments[0] = proper_table_name(arguments.first, table_name_options)
842 843
            if [:rename_table, :add_foreign_key].include?(method) ||
              (method == :remove_foreign_key && !arguments.second.is_a?(Hash))
Y
Yves Senn 已提交
844 845
              arguments[1] = proper_table_name(arguments.second, table_name_options)
            end
846
          end
847
        end
848 849
        return super unless connection.respond_to?(method)
        connection.send(method, *arguments, &block)
J
Jamis Buck 已提交
850
      end
851
    end
852

853 854
    def copy(destination, sources, options = {})
      copied = []
855

A
Arun Agrawal 已提交
856
      FileUtils.mkdir_p(destination) unless File.exist?(destination)
857

858 859
      destination_migrations = ActiveRecord::Migrator.migrations(destination)
      last = destination_migrations.last
860
      sources.each do |scope, path|
861
        source_migrations = ActiveRecord::Migrator.migrations(path)
862

863
        source_migrations.each do |migration|
864 865 866 867 868 869 870 871 872 873 874
          source = File.binread(migration.filename)
          inserted_comment = "# This migration comes from #{scope} (originally #{migration.version})\n"
          if /\A#.*\b(?:en)?coding:\s*\S+/ =~ source
            # If we have a magic comment in the original migration,
            # insert our comment after the first newline(end of the magic comment line)
            # so the magic keep working.
            # Note that magic comments must be at the first line(except sh-bang).
            source[/\n/] = "\n#{inserted_comment}"
          else
            source = "#{inserted_comment}#{source}"
          end
875

876
          if duplicate = destination_migrations.detect { |m| m.name == migration.name }
877 878
            if options[:on_skip] && duplicate.scope != scope.to_s
              options[:on_skip].call(scope, migration)
879
            end
880 881
            next
          end
882

883
          migration.version = next_migration_number(last ? last.version + 1 : 0).to_i
884
          new_path = File.join(destination, "#{migration.version}_#{migration.name.underscore}.#{scope}.rb")
885 886
          old_path, migration.filename = migration.filename, new_path
          last = migration
887

888
          File.binwrite(migration.filename, source)
889
          copied << migration
890
          options[:on_copy].call(scope, migration, old_path) if options[:on_copy]
891
          destination_migrations << migration
892 893 894
        end
      end

895 896 897
      copied
    end

898 899 900 901 902 903 904 905 906 907 908
    # Finds the correct table name given an Active Record object.
    # Uses the Active Record object's own table_name, or pre/suffix from the
    # options passed in.
    def proper_table_name(name, options = {})
      if name.respond_to? :table_name
        name.table_name
      else
        "#{options[:table_name_prefix]}#{name}#{options[:table_name_suffix]}"
      end
    end

V
Vijay Dev 已提交
909
    # Determines the version number of the next migration.
910 911 912 913
    def next_migration_number(number)
      if ActiveRecord::Base.timestamped_migrations
        [Time.now.utc.strftime("%Y%m%d%H%M%S"), "%.14d" % number].max
      else
914
        SchemaMigration.normalize_migration_number(number)
915
      end
916
    end
M
Marc-Andre Lafortune 已提交
917

918 919 920
    # Builds a hash for use in ActiveRecord::Migration#proper_table_name using
    # the Active Record object's table_name prefix and suffix
    def table_name_options(config = ActiveRecord::Base) #:nodoc:
921 922 923 924 925 926
      {
        table_name_prefix: config.table_name_prefix,
        table_name_suffix: config.table_name_suffix
      }
    end

M
Marc-Andre Lafortune 已提交
927
    private
928 929 930 931 932 933
      def execute_block
        if connection.respond_to? :execute_block
          super # use normal delegation to record the block
        else
          yield
        end
M
Marc-Andre Lafortune 已提交
934
      end
935 936
  end

937 938
  # MigrationProxy is used to defer loading of the actual migration classes
  # until they are needed
939 940
  class MigrationProxy < Struct.new(:name, :version, :filename, :scope)
    def initialize(name, version, filename, scope)
941 942 943
      super
      @migration = nil
    end
944

945 946 947 948
    def basename
      File.basename(filename)
    end

949 950 951 952
    def mtime
      File.mtime filename
    end

953
    delegate :migrate, :announce, :write, :disable_ddl_transaction, to: :migration
954 955 956 957 958 959 960 961

    private

      def migration
        @migration ||= load_migration
      end

      def load_migration
962
        require(File.expand_path(filename))
963
        name.constantize.new(name, version)
964 965 966
      end
  end

A
Arun Agrawal 已提交
967 968
  class NullMigration < MigrationProxy #:nodoc:
    def initialize
969 970 971 972 973 974 975 976
      super(nil, 0, nil, nil)
    end

    def mtime
      0
    end
  end

977
  class Migrator#:nodoc:
978
    class << self
979 980
      attr_writer :migrations_paths
      alias :migrations_path= :migrations_paths=
981

982
      def migrate(migrations_paths, target_version = nil, &block)
983
        case
984 985 986 987 988 989 990 991
        when target_version.nil?
          up(migrations_paths, target_version, &block)
        when current_version == 0 && target_version == 0
          []
        when current_version > target_version
          down(migrations_paths, target_version, &block)
        else
          up(migrations_paths, target_version, &block)
992 993
        end
      end
994

995 996
      def rollback(migrations_paths, steps=1)
        move(:down, migrations_paths, steps)
997
      end
998

999 1000
      def forward(migrations_paths, steps=1)
        move(:up, migrations_paths, steps)
1001 1002
      end

1003 1004 1005 1006
      def up(migrations_paths, target_version = nil)
        migrations = migrations(migrations_paths)
        migrations.select! { |m| yield m } if block_given?

1007
        new(:up, migrations, target_version).migrate
1008
      end
1009

1010
      def down(migrations_paths, target_version = nil)
1011 1012 1013
        migrations = migrations(migrations_paths)
        migrations.select! { |m| yield m } if block_given?

1014
        new(:down, migrations, target_version).migrate
1015
      end
1016

1017
      def run(direction, migrations_paths, target_version)
1018
        new(direction, migrations(migrations_paths), target_version).run
1019 1020 1021
      end

      def open(migrations_paths)
1022
        new(:up, migrations(migrations_paths), nil)
1023
      end
1024

1025
      def schema_migrations_table_name
A
Aaron Patterson 已提交
1026
        SchemaMigration.table_name
1027 1028
      end

1029
      def get_all_versions(connection = Base.connection)
1030 1031 1032 1033 1034 1035
        ActiveSupport::Deprecation.silence do
          if connection.table_exists?(schema_migrations_table_name)
            SchemaMigration.all.map { |x| x.version.to_i }.sort
          else
            []
          end
1036
        end
1037 1038
      end

1039
      def current_version(connection = Base.connection)
1040
        get_all_versions(connection).max || 0
1041
      end
1042

1043
      def needs_migration?(connection = Base.connection)
1044
        (migrations(migrations_paths).collect(&:version) - get_all_versions(connection)).size > 0
1045 1046
      end

1047 1048 1049 1050
      def any_migrations?
        migrations(migrations_paths).any?
      end

A
Arun Agrawal 已提交
1051
      def last_migration #:nodoc:
1052
        migrations(migrations_paths).last || NullMigration.new
1053 1054
      end

1055
      def migrations_paths
1056
        @migrations_paths ||= ["db/migrate"]
Y
yui-knk 已提交
1057
        # just to not break things if someone uses: migrations_path = some_string
1058
        Array(@migrations_paths)
1059 1060
      end

1061
      def match_to_migration_filename?(filename) # :nodoc:
1062
        Migration::MigrationFilenameRegexp.match?(File.basename(filename))
1063 1064 1065 1066 1067 1068
      end

      def parse_migration_filename(filename) # :nodoc:
        File.basename(filename).scan(Migration::MigrationFilenameRegexp).first
      end

1069
      def migrations(paths)
1070
        paths = Array(paths)
1071

1072
        files = Dir[*paths.map { |p| "#{p}/**/[0-9]*_*.rb" }]
1073

A
Aaron Patterson 已提交
1074
        migrations = files.map do |file|
1075
          version, name, scope = parse_migration_filename(file)
1076 1077
          raise IllegalMigrationNameError.new(file) unless version
          version = version.to_i
A
Aaron Patterson 已提交
1078
          name = name.camelize
1079

1080
          MigrationProxy.new(name, version, file, scope)
1081 1082 1083 1084 1085
        end

        migrations.sort_by(&:version)
      end

1086 1087
      private

1088
      def move(direction, migrations_paths, steps)
1089
        migrator = new(direction, migrations(migrations_paths))
1090 1091 1092 1093 1094
        start_index = migrator.migrations.index(migrator.current_migration)

        if start_index
          finish = migrator.migrations[start_index + steps]
          version = finish ? finish.version : 0
1095
          send(direction, migrations_paths, version)
1096 1097
        end
      end
1098
    end
1099

1100
    def initialize(direction, migrations, target_version = nil)
1101
      raise StandardError.new("This database does not yet support migrations") unless Base.connection.supports_migrations?
1102

1103 1104 1105
      @direction         = direction
      @target_version    = target_version
      @migrated_versions = nil
1106
      @migrations        = migrations
1107

1108 1109
      validate(@migrations)

1110
      Base.connection.initialize_schema_migrations_table
1111
      Base.connection.initialize_internal_metadata_table
1112 1113 1114
    end

    def current_version
1115
      migrated.max || 0
1116
    end
1117

1118 1119 1120
    def current_migration
      migrations.detect { |m| m.version == current_version }
    end
1121
    alias :current :current_migration
1122

1123
    def run
1124 1125 1126 1127
      if use_advisory_lock?
        with_advisory_lock { run_without_lock }
      else
        run_without_lock
1128
      end
1129
    end
1130

1131
    def migrate
1132 1133 1134 1135
      if use_advisory_lock?
        with_advisory_lock { migrate_without_lock }
      else
        migrate_without_lock
1136
      end
1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147
    end

    def runnable
      runnable = migrations[start..finish]
      if up?
        runnable.reject { |m| ran?(m) }
      else
        # skip the last migration if we're headed down, but not ALL the way down
        runnable.pop if target
        runnable.find_all { |m| ran?(m) }
      end
1148
    end
1149

1150
    def migrations
1151
      down? ? @migrations.reverse : @migrations.sort_by(&:version)
1152 1153
    end

1154
    def pending_migrations
1155
      already_migrated = migrated
1156
      migrations.reject { |m| already_migrated.include?(m.version) }
1157 1158 1159
    end

    def migrated
1160 1161 1162 1163 1164
      @migrated_versions || load_migrated
    end

    def load_migrated
      @migrated_versions = Set.new(self.class.get_all_versions)
1165 1166
    end

1167
    private
1168

1169
      # Used for running a specific migration.
1170 1171 1172 1173
      def run_without_lock
        migration = migrations.detect { |m| m.version == @target_version }
        raise UnknownMigrationVersionError.new(@target_version) if migration.nil?
        execute_migration_in_transaction(migration, @direction)
1174

1175 1176
        record_environment
      end
1177

1178
      # Used for running multiple migrations up to or down to a certain value.
1179 1180 1181 1182
      def migrate_without_lock
        if invalid_target?
          raise UnknownMigrationVersionError.new(@target_version)
        end
1183

1184 1185 1186
        runnable.each do |migration|
          execute_migration_in_transaction(migration, @direction)
        end
1187

1188 1189
        record_environment
      end
1190

1191
      # Stores the current environment in the database.
1192 1193 1194 1195
      def record_environment
        return if down?
        ActiveRecord::InternalMetadata[:environment] = ActiveRecord::Migrator.current_environment
      end
1196

1197 1198 1199
      def ran?(migration)
        migrated.include?(migration.version.to_i)
      end
1200

1201
      # Return true if a valid version is not provided.
1202 1203 1204
      def invalid_target?
        !target && @target_version && @target_version > 0
      end
1205

1206 1207 1208
      def execute_migration_in_transaction(migration, direction)
        return if down? && !migrated.include?(migration.version.to_i)
        return if up?   &&  migrated.include?(migration.version.to_i)
1209

1210
        Base.logger.info "Migrating to #{migration.name} (#{migration.version})" if Base.logger
1211

1212 1213 1214 1215 1216 1217 1218 1219 1220
        ddl_transaction(migration) do
          migration.migrate(direction)
          record_version_state_after_migrating(migration.version)
        end
      rescue => e
        msg = "An error has occurred, "
        msg << "this and " if use_transaction?(migration)
        msg << "all later migrations canceled:\n\n#{e}"
        raise StandardError, msg, e.backtrace
N
Neeraj Singh 已提交
1221 1222
      end

1223 1224 1225
      def target
        migrations.detect { |m| m.version == @target_version }
      end
1226

1227 1228 1229
      def finish
        migrations.index(target) || migrations.size - 1
      end
1230

1231 1232 1233
      def start
        up? ? 0 : (migrations.index(current) || 0)
      end
1234

1235 1236 1237
      def validate(migrations)
        name ,= migrations.group_by(&:name).find { |_,v| v.length > 1 }
        raise DuplicateMigrationNameError.new(name) if name
1238

1239 1240 1241
        version ,= migrations.group_by(&:version).find { |_,v| v.length > 1 }
        raise DuplicateMigrationVersionError.new(version) if version
      end
1242

1243 1244 1245 1246 1247 1248 1249 1250
      def record_version_state_after_migrating(version)
        if down?
          migrated.delete(version)
          ActiveRecord::SchemaMigration.where(version: version.to_s).delete_all
        else
          migrated << version
          ActiveRecord::SchemaMigration.create!(version: version.to_s)
        end
1251
      end
1252

1253 1254 1255
      def self.last_stored_environment
        return nil if current_version == 0
        raise NoEnvironmentInSchemaError unless ActiveRecord::InternalMetadata.table_exists?
1256

1257 1258 1259 1260
        environment = ActiveRecord::InternalMetadata[:environment]
        raise NoEnvironmentInSchemaError unless environment
        environment
      end
1261

1262 1263 1264
      def self.current_environment
        ActiveRecord::ConnectionHandling::DEFAULT_ENV.call
      end
S
schneems 已提交
1265

1266 1267 1268
      def self.protected_environment?
        ActiveRecord::Base.protected_environments.include?(last_stored_environment) if last_stored_environment
      end
1269

1270 1271 1272
      def up?
        @direction == :up
      end
1273

1274 1275 1276
      def down?
        @direction == :down
      end
1277

1278
      # Wrap the migration in a transaction only if supported by the adapter.
1279 1280 1281 1282 1283 1284
      def ddl_transaction(migration)
        if use_transaction?(migration)
          Base.transaction { yield }
        else
          yield
        end
1285
      end
1286

1287 1288 1289
      def use_transaction?(migration)
        !migration.disable_ddl_transaction && Base.connection.supports_ddl_transactions?
      end
1290

1291 1292 1293
      def use_advisory_lock?
        Base.connection.supports_advisory_locks?
      end
1294

1295 1296 1297 1298 1299 1300 1301 1302 1303
      def with_advisory_lock
        lock_id = generate_migrator_advisory_lock_id
        got_lock = Base.connection.get_advisory_lock(lock_id)
        raise ConcurrentMigrationError unless got_lock
        load_migrated # reload schema_migrations to be sure it wasn't changed by another process before we got the lock
        yield
      ensure
        Base.connection.release_advisory_lock(lock_id) if got_lock
      end
1304

1305 1306 1307 1308 1309
      MIGRATOR_SALT = 2053462845
      def generate_migrator_advisory_lock_id
        db_name_hash = Zlib.crc32(Base.connection.current_database)
        MIGRATOR_SALT * db_name_hash
      end
1310
  end
1311
end