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
701 def initialize(db, directory, opts=OPTS)
702   super
703   @target = opts[:target]
704   @applied_migrations = get_applied_migrations
705   @migration_tuples = get_migration_tuples
706 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
711 def self.run_single(db, path, opts=OPTS)
712   new(db, File.dirname(path), opts).run_single(path, opts[:direction] || :up)
713 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
717 def is_current?
718   migration_tuples.empty?
719 end
run() click to toggle source

Apply all migration tuples on the database

    # File lib/sequel/extensions/migration.rb
722 def run
723   migration_tuples.each do |m, f, direction|
724     apply_migration(m, f, direction)
725   end
726   nil
727 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
731 def run_single(path, direction)
732   migration = load_migration_file(path)
733   file_name = File.basename(path)
734   already_applied = applied_migrations.include?(file_name.downcase)
735 
736   return if direction == :up ? already_applied : !already_applied
737 
738   apply_migration(migration, file_name, direction)
739   nil
740 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
745 def apply_migration(migration, file_name, direction)
746   fi = file_name.downcase
747   t = Time.now
748 
749   db.log_info("Begin applying migration #{file_name}, direction: #{direction}")
750   checked_transaction(migration) do
751     migration.apply(db, direction)
752     direction == :up ? ds.insert(column=>fi) : ds.where(column=>fi).delete
753   end
754   db.log_info("Finished applying migration #{file_name}, direction: #{direction}, took #{sprintf('%0.6f', Time.now - t)} seconds")
755 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
759 def convert_from_schema_info
760   v = db[:schema_info].get(:version)
761   ds = db.from(table)
762   files.each do |path|
763     f = File.basename(path)
764     if migration_version_from_file(f) <= v
765       ds.insert(column=>f)
766     end
767   end
768 end
default_schema_column() click to toggle source

The default column storing migration filenames.

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

The default table storing migration filenames.

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

Returns filenames of all applied migrations

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

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

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

Returns tuples of migration, filename, and direction

    # File lib/sequel/extensions/migration.rb
815 def get_migration_tuples
816   up_mts = []
817   down_mts = []
818   files.each do |path|
819     f = File.basename(path)
820     fi = f.downcase
821     if target
822       if migration_version_from_file(f) > target
823         if applied_migrations.include?(fi)
824           down_mts << [load_migration_file(path), f, :down]
825         end
826       elsif !applied_migrations.include?(fi)
827         up_mts << [load_migration_file(path), f, :up]
828       end
829     elsif !applied_migrations.include?(fi)
830       up_mts << [load_migration_file(path), f, :up]
831     end
832   end
833   up_mts + down_mts.reverse
834 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
838 def schema_dataset
839   c = column
840   ds = db.from(table)
841   if !db.table_exists?(table)
842     begin
843       db.create_table(table){String c, :primary_key=>true}
844     rescue Sequel::DatabaseError => e
845       if db.database_type == :mysql && e.message.include?('max key length')
846         # Handle case where MySQL is used with utf8mb4 charset default, which
847         # only allows a maximum length of about 190 characters for string
848         # primary keys due to InnoDB limitations.
849         db.create_table(table){String c, :primary_key=>true, :size=>190}
850       else
851         raise e
852       end
853     end
854     if db.table_exists?(:schema_info) and vha = db[:schema_info].all and vha.length == 1 and
855        vha.first.keys == [:version] and vha.first.values.first.is_a?(Integer)
856       convert_from_schema_info
857     end
858   elsif !ds.columns.include?(c)
859     raise(Error, "Migrator table #{table} does not contain column #{c}")
860   end
861   ds
862 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
808 def split_migration_filename(path)
809   version, name = MIGRATION_FILE_PATTERN.match(File.basename(path)).captures
810   version = version.to_i
811   [version, name]
812 end