Module: Sequel::Migrator
- Defined in:
- lib/sequel/migration.rb
Overview
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.
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)
Constant Summary collapse
- MIGRATION_FILE_PATTERN =
'[0-9][0-9][0-9]_*.rb'.freeze
Class Method Summary collapse
-
.apply(db, directory, target = nil, current = nil) ⇒ Object
Migrates the supplied database in the specified directory from the current version to the target version.
-
.get_current_migration_version(db) ⇒ Object
Gets the current migration version stored in the database.
-
.latest_migration_version(directory) ⇒ Object
Returns the latest version available in the specified directory.
-
.migration_classes(directory, target, current, direction) ⇒ Object
Returns a list of migration classes filtered for the migration range and ordered according to the migration direction.
-
.migration_files(directory, range = nil) ⇒ Object
Returns any found migration files in the supplied directory.
-
.schema_info_dataset(db) ⇒ Object
Returns the dataset for the schema_info table.
-
.set_current_migration_version(db, version) ⇒ Object
Sets the current migration version stored in the database.
Class Method Details
.apply(db, directory, target = nil, current = nil) ⇒ Object
Migrates the supplied database in the specified directory from the current version to the target version. If no current version is supplied, it is extracted from a schema_info table. The schema_info table is automatically created and maintained by the apply function.
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/sequel/migration.rb', line 105 def self.apply(db, directory, target = nil, current = nil) # determine current and target version and direction current ||= get_current_migration_version(db) target ||= latest_migration_version(directory) raise Error, "No current version available" if current.nil? raise Error, "No target version available" if target.nil? direction = current < target ? :up : :down classes = migration_classes(directory, target, current, direction) db.transaction do classes.each {|c| c.apply(db, direction)} set_current_migration_version(db, target) end target end |
.get_current_migration_version(db) ⇒ Object
Gets the current migration version stored in the database. If no version number is stored, 0 is returned.
166 167 168 169 |
# File 'lib/sequel/migration.rb', line 166 def self.get_current_migration_version(db) r = schema_info_dataset(db).first r ? r[:version] : 0 end |
.latest_migration_version(directory) ⇒ Object
Returns the latest version available in the specified directory.
159 160 161 162 |
# File 'lib/sequel/migration.rb', line 159 def self.latest_migration_version(directory) l = migration_files(directory).last l ? File.basename(l).to_i : nil end |
.migration_classes(directory, target, current, direction) ⇒ Object
Returns a list of migration classes filtered for the migration range and ordered according to the migration direction.
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/sequel/migration.rb', line 126 def self.migration_classes(directory, target, current, direction) range = direction == :up ? (current + 1)..target : (target + 1)..current # Remove class definitions Migration.descendants.each do |c| Object.send(:remove_const, c.to_s) rescue nil end Migration.descendants.clear # remove any defined migration classes # load migration files migration_files(directory, range).each {|fn| load(fn)} # get migration classes classes = Migration.descendants classes.reverse! if direction == :down classes end |
.migration_files(directory, range = nil) ⇒ Object
Returns any found migration files in the supplied directory.
148 149 150 151 152 153 154 155 156 |
# File 'lib/sequel/migration.rb', line 148 def self.migration_files(directory, range = nil) pattern = File.join(directory, MIGRATION_FILE_PATTERN) files = Dir[pattern].inject([]) do |m, path| m[File.basename(path).to_i] = path m end filtered = range ? files[range] : files filtered ? filtered.compact : [] end |
.schema_info_dataset(db) ⇒ Object
Returns the dataset for the schema_info table. If no such table exists, it is automatically created.
183 184 185 186 187 188 189 |
# File 'lib/sequel/migration.rb', line 183 def self.schema_info_dataset(db) unless db.table_exists?(:schema_info) db.create_table(:schema_info) {integer :version} end db[:schema_info] end |
.set_current_migration_version(db, version) ⇒ Object
Sets the current migration version stored in the database.
172 173 174 175 176 177 178 179 |
# File 'lib/sequel/migration.rb', line 172 def self.set_current_migration_version(db, version) dataset = schema_info_dataset(db) if dataset.first dataset.update(:version => version) else dataset << {:version => version} end end |