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
Array of strings of applied migration filenames
Get tuples of migrations, filenames, and actions for each migration
Public Class Methods
Source
# 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
Set up all state for the migrator instance
Sequel::Migrator::new
Source
# 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
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.
Public Instance Methods
Source
# File lib/sequel/extensions/migration.rb 717 def is_current? 718 migration_tuples.empty? 719 end
The timestamp migrator is current if there are no migrations to apply in either direction.
Source
# 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
Apply all migration tuples on the database
Source
# 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
Apply single migration tuple at the given path with the given direction on the database.
Private Instance Methods
Source
# 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
Apply a single migration with the given filename in the given direction.
Source
# 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
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.
Source
# File lib/sequel/extensions/migration.rb 771 def default_schema_column 772 :filename 773 end
The default column storing migration filenames.
Source
# File lib/sequel/extensions/migration.rb 776 def default_schema_table 777 :schema_migrations 778 end
The default table storing migration filenames.
Source
# 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
Returns filenames of all applied migrations
Source
# 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
Returns any migration files found in the migrator’s directory.
Source
# 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
Returns tuples of migration, filename, and direction
Source
# 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
Returns the dataset for the schema_migrations table. If no such table exists, it is automatically created.
Source
# 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
Return an integer and name (without extension) for the given path.