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
704 def initialize(db, directory, opts=OPTS)
705   super
706   @target = opts[:target]
707   @applied_migrations = get_applied_migrations
708   @migration_tuples = get_migration_tuples
709 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
714 def self.run_single(db, path, opts=OPTS)
715   new(db, File.dirname(path), opts).run_single(path, opts[:direction] || :up)
716 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
720 def is_current?
721   migration_tuples.empty?
722 end
run() click to toggle source

Apply all migration tuples on the database

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

The default column storing migration filenames.

    # File lib/sequel/extensions/migration.rb
774 def default_schema_column
775   :filename
776 end
default_schema_table() click to toggle source

The default table storing migration filenames.

    # File lib/sequel/extensions/migration.rb
779 def default_schema_table
780   :schema_migrations
781 end
get_applied_migrations() click to toggle source

Returns filenames of all applied migrations

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

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

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

Returns tuples of migration, filename, and direction

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