Files
prism/lib/prism/orm/migrator.rb
T

70 lines
1.9 KiB
Ruby

module Prism
module Orm
class Migrator
Entry = Struct.new(:version, :name, :path)
def initialize(store, migrations_path)
@store = store
@migrations_path = migrations_path
end
def entries
Dir.glob(File.join(@migrations_path, '*.rb')).sort.map do |path|
version, name = File.basename(path, '.rb').split('_', 2)
Entry.new(version, name, path)
end
end
def pending
applied = @store.applied_migrations
entries.reject { |entry| applied.include?(entry.version) }
end
# Pairs every migration file on disk with whether it has been applied
# to this store, in the same order `entries`/`pending` use - the data
# `prism db:status` (like `rails db:migrate:status`) prints, but kept
# here so it is available to any caller, not just the CLI.
def status
applied = @store.applied_migrations
entries.map { |entry| [entry, applied.include?(entry.version)] }
end
def migrate!
applied = pending.map { |entry| apply(entry) }
applied.map(&:version)
end
def rollback!(steps = 1)
versions = @store.applied_migrations.sort.last(steps).reverse
versions.map do |version|
entry = entries.find { |candidate| candidate.version == version }
next unless entry
revert(entry)
entry.version
end.compact
end
private
def apply(entry)
migration = load_migration(entry)
migration.up
@store.record_migration(entry.version)
entry
end
def revert(entry)
migration = load_migration(entry)
migration.down
@store.forget_migration(entry.version)
end
def load_migration(entry)
class_name = Inflector.camelize(entry.name)
load entry.path
Object.const_get(class_name).new(@store)
end
end
end
end