Module: Sequel::Migrator

Module | Sequel::Migrator
In: | lib/sequel/extensions/migration.rb

The Migrator module performs migrations based on migration files in a specified directory. The migration files should be named using the following pattern (in similar fashion to ActiveRecord migrations):

      <version>_<title>.rb

For example, the following files are considered migration files:

      001_create_sessions.rb
      002_add_data_column.rb
      ...

The migration files should contain one or more migration classes based on Sequel::Migration.

Migrations are generally run via the sequel command line tool, using the -m and -M switches. The -m switch specifies the migration directory, and the -M switch specifies the version to which to migrate.

You can apply migrations using the Migrator API, as well (this is necessary if you want to specify the version from which to migrate in addition to the version to which to migrate). To apply a migration, the apply method must be invoked with the database instance, the directory of migration files and the target version. If no current version is supplied, it is read from the database. The migrator automatically creates a schema_info table in the database to keep track of the current migration version. If no migration version is stored in the database, the version is considered to be 0. If no target version is specified, the database is migrated to the latest version available in the migration directory.

For example, to migrate the database to the latest version:

      Sequel::Migrator.apply(DB, '.')

To migrate the database from version 1 to version 5:

      Sequel::Migrator.apply(DB, '.', 5, 1)

### Methods

apply get_current_migration_version latest_migration_version migration_classes migration_files run schema_info_dataset set_current_migration_version

### Constants

DEFAULT_SCHEMA_COLUMN | = | :version
DEFAULT_SCHEMA_TABLE | = | :schema_info
MIGRATION_FILE_PATTERN | = | /\A\d+_.+\.rb\z/.freeze
MIGRATION_SPLITTER | = | '_'.freeze

### Public Class methods

apply(db, directory, target = nil, current = nil)

Wrapper for run, maintaining backwards API compatibility

[Source]

         # File lib/sequel/extensions/migration.rb, line 140
    140:     def self.apply(db, directory, target = nil, current = nil)
    141:       run(db, directory, :target => target, :current => current)
    142:     end

get_current_migration_version(db, opts={})

Gets the current migration version stored in the database. If no version number is stored, 0 is returned.

[Source]

         # File lib/sequel/extensions/migration.rb, line 175
    175:     def self.get_current_migration_version(db, opts={})
    176:       (schema_info_dataset(db, opts).first || {})[opts[:column] || DEFAULT_SCHEMA_COLUMN] || 0
    177:     end

latest_migration_version(directory)

Returns the latest version available in the specified directory.

[Source]

         # File lib/sequel/extensions/migration.rb, line 180
    180:     def self.latest_migration_version(directory)
    181:       l = migration_files(directory).last
    182:       l ? migration_version_from_file(File.basename(l)) : nil
    183:     end

migration_classes(directory, target, current, direction)

Returns a list of migration classes filtered for the migration range and ordered according to the migration direction.

[Source]

         # File lib/sequel/extensions/migration.rb, line 187
    187:     def self.migration_classes(directory, target, current, direction)
    188:       range = direction == :up ?
    189:         (current + 1)..target : (target + 1)..current
    190:
    191:       # Remove class definitions
    192:       Migration.descendants.each do |c|
    193:         Object.send(:remove_const, c.to_s) rescue nil
    194:       end
    195:       Migration.descendants.clear # remove any defined migration classes
    196:
    197:       # load migration files
    198:       migration_files(directory, range).each {|fn| load(fn)}
    199:
    200:       # get migration classes
    201:       classes = Migration.descendants
    202:       classes.reverse! if direction == :down
    203:       classes
    204:     end

migration_files(directory, range = nil)

Returns any found migration files in the supplied directory.

[Source]

         # File lib/sequel/extensions/migration.rb, line 207
    207:     def self.migration_files(directory, range = nil)
    208:       files = []
    209:       Dir.new(directory).each do |file|
    210:         files[migration_version_from_file(file)] = File.join(directory, file) if MIGRATION_FILE_PATTERN.match(file)
    211:       end
    212:       filtered = range ? files[range] : files
    213:       filtered ? filtered.compact : []
    214:     end

run(db, directory, opts={})

Migrates the supplied database using the migration files in the the specified directory. Options:

- :column - The column in the :table argument storing the migration version (default: :version).
- :current - The current version of the database. If not given, it is retrieved from the database using the :table and :column options.
- :table - The table containing the schema version (default: :schema_info).
- :target - The target version to which to migrate. If not given, migrates to the maximum version.

Examples:

      Sequel::Migrator.run(DB, "migrations")
      Sequel::Migrator.run(DB, "migrations", :target=>15, :current=>10)
      Sequel::Migrator.run(DB, "app1/migrations", :column=> :app2_version)
      Sequel::Migrator.run(DB, "app2/migrations", :column => :app2_version, :table=>:schema_info2)

[Source]

         # File lib/sequel/extensions/migration.rb, line 156
    156:     def self.run(db, directory, opts={})
    157:       raise(Error, "Must supply a valid migration path") unless directory and File.directory?(directory)
    158:       raise(Error, "No current version available") unless current = opts[:current] || get_current_migration_version(db, opts)
    159:       raise(Error, "No target version available") unless target  = opts[:target]  || latest_migration_version(directory)
    160:
    161:       direction = current < target ? :up : :down
    162:
    163:       classes = migration_classes(directory, target, current, direction)
    164:
    165:       db.transaction do
    166:         classes.each {|c| c.apply(db, direction)}
    167:         set_current_migration_version(db, target, opts)
    168:       end
    169:
    170:       target
    171:     end

schema_info_dataset(db, opts={})

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

[Source]

         # File lib/sequel/extensions/migration.rb, line 218
    218:     def self.schema_info_dataset(db, opts={})
    219:       column = opts[:column] || DEFAULT_SCHEMA_COLUMN
    220:       table  = opts[:table]  || DEFAULT_SCHEMA_TABLE
    221:       db.create_table?(table){Integer column}
    222:       db.alter_table(table){add_column column, Integer} unless db.from(table).columns.include?(column)
    223:       db.from(table)
    224:     end

set_current_migration_version(db, version, opts={})

Sets the current migration version stored in the database.

[Source]

         # File lib/sequel/extensions/migration.rb, line 227
    227:     def self.set_current_migration_version(db, version, opts={})
    228:       column = opts[:column] || DEFAULT_SCHEMA_COLUMN
    229:       dataset = schema_info_dataset(db, opts)
    230:       dataset.send(dataset.first ? :update : :insert, column => version)
    231:     end

[Validate]