class Sequel::TimestampMigrator

The migrator used if any migration file version is greater than 20000101. Stores filenames of migration files, and can figure out which migrations have not been applied and apply them, even if earlier migrations are added after later migrations. If you plan to do that, the responsibility is on you to make sure the migrations don't conflict. Part of the migration extension.

Constants

Error

Attributes

applied_migrations[R]

Array of strings of applied migration filenames

migration_tuples[R]

Get tuples of migrations, filenames, and actions for each migration

Public Class Methods

new(db, directory, opts=OPTS) click to toggle source

Set up all state for the migrator instance

Calls superclass method Sequel::Migrator::new
    # File lib/sequel/extensions/migration.rb
700 def initialize(db, directory, opts=OPTS)
701   super
702   @target = opts[:target]
703   @applied_migrations = get_applied_migrations
704   @migration_tuples = get_migration_tuples
705 end
run_single(db, path, opts=OPTS) click to toggle source

Apply the migration in the given file path. See Migrator.run for the available options. Additionally, this method supports the :direction option for whether to run the migration up (default) or down.

    # File lib/sequel/extensions/migration.rb
710 def self.run_single(db, path, opts=OPTS)
711   new(db, File.dirname(path), opts).run_single(path, opts[:direction] || :up)
712 end

Public Instance Methods

is_current?() click to toggle source

The timestamp migrator is current if there are no migrations to apply in either direction.

    # File lib/sequel/extensions/migration.rb
716 def is_current?
717   migration_tuples.empty?
718 end
run() click to toggle source

Apply all migration tuples on the database

    # File lib/sequel/extensions/migration.rb
721 def run
722   migration_tuples.each do |m, f, direction|
723     apply_migration(m, f, direction)
724   end
725   nil
726 end
run_single(path, direction) click to toggle source

Apply single migration tuple at the given path with the given direction on the database.

    # File lib/sequel/extensions/migration.rb
730 def run_single(path, direction)
731   migration = load_migration_file(path)
732   file_name = File.basename(path)
733   already_applied = applied_migrations.include?(file_name.downcase)
734 
735   return if direction == :up ? already_applied : !already_applied
736 
737   apply_migration(migration, file_name, direction)
738   nil
739 end

Private Instance Methods

apply_migration(migration, file_name, direction) click to toggle source

Apply a single migration with the given filename in the given direction.

    # File lib/sequel/extensions/migration.rb
744 def apply_migration(migration, file_name, direction)
745   fi = file_name.downcase
746   t = Time.now
747 
748   db.log_info("Begin applying migration #{file_name}, direction: #{direction}")
749   checked_transaction(migration) do
750     migration.apply(db, direction)
751     direction == :up ? ds.insert(column=>fi) : ds.where(column=>fi).delete
752   end
753   db.log_info("Finished applying migration #{file_name}, direction: #{direction}, took #{sprintf('%0.6f', Time.now - t)} seconds")
754 end
convert_from_schema_info() click to toggle source

Convert the schema_info table to the new schema_migrations table format, using the version of the schema_info table and the current migration files.

    # File lib/sequel/extensions/migration.rb
758 def convert_from_schema_info
759   v = db[:schema_info].get(:version)
760   ds = db.from(table)
761   files.each do |path|
762     f = File.basename(path)
763     if migration_version_from_file(f) <= v
764       ds.insert(column=>f)
765     end
766   end
767 end
default_schema_column() click to toggle source

The default column storing migration filenames.

    # File lib/sequel/extensions/migration.rb
770 def default_schema_column
771   :filename
772 end
default_schema_table() click to toggle source

The default table storing migration filenames.

    # File lib/sequel/extensions/migration.rb
775 def default_schema_table
776   :schema_migrations
777 end
get_applied_migrations() click to toggle source

Returns filenames of all applied migrations

    # File lib/sequel/extensions/migration.rb
780 def get_applied_migrations
781   am = ds.select_order_map(column)
782   missing_migration_files = am - files.map{|f| File.basename(f).downcase}
783   raise(Error, "Applied migration files not in file system: #{missing_migration_files.join(', ')}") if missing_migration_files.length > 0 && !@allow_missing_migration_files
784   am
785 end
get_migration_files() click to toggle source

Returns any migration files found in the migrator's directory.

    # File lib/sequel/extensions/migration.rb
788 def get_migration_files
789   files = []
790   Dir.new(directory).each do |file|
791     next unless MIGRATION_FILE_PATTERN.match(file)
792     files << File.join(directory, file)
793   end
794   files.sort! do |a, b|
795     a_ver, a_name = split_migration_filename(a)
796     b_ver, b_name = split_migration_filename(b)
797     x = a_ver <=> b_ver
798     if x.zero?
799       x = a_name <=> b_name
800     end
801     x
802   end
803   files
804 end
get_migration_tuples() click to toggle source

Returns tuples of migration, filename, and direction

    # File lib/sequel/extensions/migration.rb
814 def get_migration_tuples
815   up_mts = []
816   down_mts = []
817   files.each do |path|
818     f = File.basename(path)
819     fi = f.downcase
820     if target
821       if migration_version_from_file(f) > target
822         if applied_migrations.include?(fi)
823           down_mts << [load_migration_file(path), f, :down]
824         end
825       elsif !applied_migrations.include?(fi)
826         up_mts << [load_migration_file(path), f, :up]
827       end
828     elsif !applied_migrations.include?(fi)
829       up_mts << [load_migration_file(path), f, :up]
830     end
831   end
832   up_mts + down_mts.reverse
833 end
schema_dataset() click to toggle source

Returns the dataset for the schema_migrations table. If no such table exists, it is automatically created.

    # File lib/sequel/extensions/migration.rb
837 def schema_dataset
838   c = column
839   ds = db.from(table)
840   if !db.table_exists?(table)
841     begin
842       db.create_table(table){String c, :primary_key=>true}
843     rescue Sequel::DatabaseError => e
844       if db.database_type == :mysql && e.message =~ /max key length/
845         # Handle case where MySQL is used with utf8mb4 charset default, which
846         # only allows a maximum length of about 190 characters for string
847         # primary keys due to InnoDB limitations.
848         db.create_table(table){String c, :primary_key=>true, :size=>190}
849       else
850         raise e
851       end
852     end
853     if db.table_exists?(:schema_info) and vha = db[:schema_info].all and vha.length == 1 and
854        vha.first.keys == [:version] and vha.first.values.first.is_a?(Integer)
855       convert_from_schema_info
856     end
857   elsif !ds.columns.include?(c)
858     raise(Error, "Migrator table #{table} does not contain column #{c}")
859   end
860   ds
861 end
split_migration_filename(path) click to toggle source

Return an integer and name (without extension) for the given path.

    # File lib/sequel/extensions/migration.rb
807 def split_migration_filename(path)
808   version, name = MIGRATION_FILE_PATTERN.match(File.basename(path)).captures
809   version = version.to_i
810   [version, name]
811 end