class Rotor::Migrator

Runs migrations (Rotor::Migration classes) against a database and records which ran in a table (schema_migrations unless table: says otherwise: version bigint PRIMARY KEY, inserted_at), which migrate and rollback create when it is missing.

class MigCreateUsers < Rotor::Migration
  version 20261107120000

  def change
    create_table :users do |t|
      t.column :name, String
    end
  end
end

class MigAddAge < Rotor::Migration
  version 20261108090000

  def change
    add_column :users, :age, Int, default: 0
  end
end

PG::Pool.open("postgres://app@localhost/shop") do |pool|
  migrator = Rotor::Migrator.new(Rotor::Repo.new(pool: pool), [MigCreateUsers, MigAddAge], log: ->(line: String) { puts line })
  migrator.migrate     # [20261107120000, 20261108090000]
  migrator.status      # [[20261107120000, "MigCreateUsers", :up], [20261108090000, "MigAddAge", :up]]
  migrator.rollback    # [20261108090000]
end

/home/runner/work/rotor/rotor/src/migrator.qz:60

Class methods

def self.new(repo: Rotor::Repo, migrations: Array[Type[Rotor::Migration]], *, table: String = …, allow_out_of_order: Bool = …, lock_timeout: Duration? = …, log: shareable (String) -> Void? = …) -> Rotor::Migrator

A migrator of migrations (in any order) over repo. log gets a line as each migration starts and ends. Raises ArgumentError for a migration without a version, or two with one version.

/home/runner/work/rotor/rotor/src/migrator.qz:71

def self.release(r: Rotor::Repo, key: Int, reset: Bool) -> StandardError?

Leaves the connection of r as the migrator found it: no transaction, the lock key released (a warning when this session does not hold it), and the settings reset when reset. The error that stopped it, or nil.

/home/runner/work/rotor/rotor/src/migrator.qz:198

def self.attempt(&: () -> Object?) -> StandardError?

The error the block raised, or nil.

/home/runner/work/rotor/rotor/src/migrator.qz:209

def self.lock_key(table: String) -> Int

The advisory lock's key for the table table: the first 60 bits of SHA-256 of rotor.migrations.<table>, so that two programs agree.

/home/runner/work/rotor/rotor/src/migrator.qz:258

def self.render(op: Rotor::Operation) -> Array[String]

The SQL statements that do op, in order.

op = Rotor::Operation::RenameColumn.new("posts", "body", "content")
Rotor::Migrator.render(op)  # => ["ALTER TABLE \"posts\" RENAME COLUMN \"body\" TO \"content\""]

/home/runner/work/rotor/rotor/src/migrator.qz:266

def self.column(c: Rotor::ColumnDef) -> String

A column's definition in CREATE TABLE and ADD COLUMN.

/home/runner/work/rotor/rotor/src/migrator.qz:296

def self.references(r: Rotor::Reference) -> String

REFERENCES "t" ("id"), with its ON DELETE.

/home/runner/work/rotor/rotor/src/migrator.qz:309

def self.index(i: Rotor::IndexDef, if_not_exists: Bool) -> String

CREATE [UNIQUE] INDEX ....

/home/runner/work/rotor/rotor/src/migrator.qz:321

def self.literal(v: Int | Float | String | Bool | Bytes | Rotor::SQL::Raw) -> String

A default as SQL: a literal of its value, or the SQL given.

Rotor::Migrator.literal("it's")              # => "'it''s'"
Rotor::Migrator.literal(1.5)                 # => "1.5"
Rotor::Migrator.literal(Rotor::SQL.raw("now()"))  # => "now()"

/home/runner/work/rotor/rotor/src/migrator.qz:336

Methods

def applied -> Array[Int]

The versions applied, ascending (none when the table is missing).

/home/runner/work/rotor/rotor/src/migrator.qz:89

def pending -> Array[Int]

The versions of the migrations given that are not applied, ascending.

/home/runner/work/rotor/rotor/src/migrator.qz:93

def status -> Array[[Int, String, Symbol]]

Each version, ascending: the migration's class name and :up (applied) or :pending; an applied version none of the migrations has is :unknown, with an empty name.

/home/runner/work/rotor/rotor/src/migrator.qz:101

def migrate(*, to: Int? = …) -> Array[Int]

Runs the pending migrations, ascending, up to and including to when it is given: the versions run.

/home/runner/work/rotor/rotor/src/migrator.qz:113

def rollback(*, steps: Int = …) -> Array[Int]

Rolls back the steps highest versions applied, highest first (as Ecto: by version, not by when they were applied, which differ only after allow_out_of_order:): the versions rolled back.

/home/runner/work/rotor/rotor/src/migrator.qz:133

def rollback(*, to: Int) -> Array[Int]

Rolls back the versions applied above to (which stays applied), highest first: the versions rolled back.

/home/runner/work/rotor/rotor/src/migrator.qz:140