class Rotor::Migration
A change of a database's schema, with its version: a subclass says
version (an Int, unique among the migrations; the generator will
use the UTC time, 20261107120000) and either change, which
rolling back reverses, or up and down.
class CreateUsers < Rotor::Migration
version 20261107120000
def change
create_table :users do |t|
t.column :email, String
t.column :age, Int, default: 0
t.timestamps
end
create_index :users, [:email], unique: true
end
end
Forward, each call of change runs as it is made, in the migration's
transaction, so that repo (the migrator's repository, bound to that
transaction) sees what the calls above it did. Backward, change is
run again to record its calls, without running them, and their
reverses run in the reverse order: a call that cannot be reversed
(drop_table without its columns, remove_column without its type,
change_column without from:, drop_index by name alone, execute
without down:), or repo used in change, raises
Rotor::IrreversibleMigration before any runs. Use up and down
for those.
/home/runner/work/rotor/rotor/src/migration.qz:291
Constants
NO_DEFAULT: Rotor::NoDefault
What change_column takes to drop a column's default.
Class methods
def self.new -> Rotor::Migration
(Made by make.)
def self.migration_version -> Int
The migration's version, which its version statement sets (0
without one).
def self.transaction? -> Bool
Whether the migration runs in a transaction: true unless its class
says disable_transaction!.
static def self.version(v: Int) -> Void
Declares the migration's version, and checks that the class defines
change, or up and down, not both: an error where the class is
compiled.
static def self.disable_transaction! -> Void
Runs the migration outside a transaction (for create_index ..., concurrently: true, which PostgreSQL refuses in one): its version
is recorded after it succeeds, and a failure leaves what it did.
def self.plan(direction: Symbol) -> Array[Rotor::Operation]
The operations the migration runs direction (:up or :down),
recorded without running anything: change's reversed for :down.
Raises Rotor::IrreversibleMigration as a rollback would, and when
the migration uses repo (which a recording cannot run).
class DocAddViews < Rotor::Migration
version 20261107120000
def change
add_column :posts, :views, Int, default: 0
end
end
DocAddViews.plan(:up).map { |op| Rotor::Migrator.render(op) } # => [["ALTER TABLE \"posts\" ADD COLUMN \"views\" bigint NOT NULL DEFAULT 0"]]
DocAddViews.plan(:down).map { |op| Rotor::Migrator.render(op) } # => [["ALTER TABLE \"posts\" DROP COLUMN \"views\""]]
def self.identity(name: Symbol) -> Rotor::ColumnDef
An identity primary key named name.
Methods
def repo -> Rotor::Repo
The migrator's repository, in the migration's transaction: for data
migrations (repo.exec, repo.query). In change it makes the
migration irreversible: rolling back raises
Rotor::IrreversibleMigration (write up and down).
def create_table(name: Symbol, *, primary_key: Bool | Symbol = …, if_not_exists: Bool = …, &: (Rotor::TableBuilder) -> Void) -> Void
Creates the table name, its columns declared by the block, with an
id (bigint GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY) first
unless primary_key: false, another name for it (primary_key: :uid), or a column declared primary: true. With if_not_exists: true it reverses to drop_table ..., if_exists: true (as in Ecto:
rolling back drops the table even if it existed before).
def drop_table(name: Symbol, *, if_exists: Bool = …) -> Void
Drops the table name: not reversible, unless its columns are given
in a block as create_table's (its id included as there).
def drop_table(name: Symbol, *, primary_key: Bool | Symbol = …, if_exists: Bool = …, &: (Rotor::TableBuilder) -> Void) -> Void
Drops the table name: not reversible, unless its columns are given
in a block as create_table's (its id included as there).
def rename_table(name: Symbol, to: Symbol) -> Void
Renames the table name to to. Its indexes keep their names
(<name>_<columns>_index): drop_index by columns on the new name
does not find them; name them with name:.
def add_column(table: Symbol, name: Symbol, type: Type[Int], *, null: Bool = …, default: Int | Rotor::SQL::Raw | Nil = …) -> Void
Adds a column to table, as create_table's t.column declares
one.
def add_column(table: Symbol, name: Symbol, type: Type[Float], *, null: Bool = …, default: Float | Rotor::SQL::Raw | Nil = …) -> Void
Adds a column to table, as create_table's t.column declares
one.
def add_column(table: Symbol, name: Symbol, type: Type[String], *, null: Bool = …, default: String | Rotor::SQL::Raw | Nil = …) -> Void
Adds a column to table, as create_table's t.column declares
one.
def add_column(table: Symbol, name: Symbol, type: Type[Bool], *, null: Bool = …, default: Bool | Rotor::SQL::Raw | Nil = …) -> Void
Adds a column to table, as create_table's t.column declares
one.
def add_column(table: Symbol, name: Symbol, type: Type[Time], *, null: Bool = …, default: Rotor::SQL::Raw? = …) -> Void
Adds a column to table, as create_table's t.column declares
one.
def add_column(table: Symbol, name: Symbol, type: Type[Bytes], *, null: Bool = …, default: Bytes | Rotor::SQL::Raw | Nil = …) -> Void
Adds a column to table, as create_table's t.column declares
one.
def add_column(table: Symbol, name: Symbol, *, sql: String, null: Bool = …, default: String | Rotor::SQL::Raw | Nil = …) -> Void
Adds a column to table, as create_table's t.column declares
one.
def remove_column(table: Symbol, name: Symbol) -> Void
Removes the column name of table: not reversible.
def remove_column(table: Symbol, name: Symbol, type: Type[Object], *, null: Bool = …, default: Int | Float | String | Bool | Bytes | Rotor::SQL::Raw | Nil = …) -> Void
Removes the column name of table, reversibly: its class (Int
and the others) and settings as add_column takes them.
def remove_column(table: Symbol, name: Symbol, *, sql: String, null: Bool = …, default: Int | Float | String | Bool | Bytes | Rotor::SQL::Raw | Nil = …) -> Void
Removes the column name of table, reversibly: its class (Int
and the others) and settings as add_column takes them.
def rename_column(table: Symbol, name: Symbol, to: Symbol) -> Void
Renames the column name of table to to.
def change_column(table: Symbol, name: Symbol, *, null: Bool? = …, default: Int | Float | String | Bool | Bytes | Rotor::SQL::Raw | Rotor::NoDefault | Nil = …, from: Rotor::Was? = …) -> Void
Changes the column name of table: whether it admits NULL
(null:), its default (default:, NO_DEFAULT to drop it); nil
leaves a setting as it is. Reversible with from:, what each
setting changed was (from: Rotor::Was.new(null: true, default: Rotor::Migration::NO_DEFAULT)). A change of type goes through
execute.
def add_reference(table: Symbol, name: Symbol, *, to_table: Symbol? = …, on_delete: Symbol? = …, null: Bool = …, index: Bool = …) -> Void
Adds <name>_id to table, a bigint that references to_table
(by default name plural) by its id, and an index on it unless
index: false.
def remove_reference(table: Symbol, name: Symbol, *, to_table: Symbol? = …, on_delete: Symbol? = …, null: Bool = …, index: Bool = …) -> Void
Removes what add_reference added with the same arguments
(reversibly).
def create_index(table: Symbol, columns: Array[Symbol], *, unique: Bool = …, name: Symbol? = …, where: String? = …, concurrently: Bool = …) -> Void
Creates an index of table on columns, named
<table>_<columns>_index unless name: is given; where: (SQL)
makes it partial; concurrently: true builds it without locking
writes, which needs disable_transaction!.
def drop_index(table: Symbol, *, columns: Array[Symbol]? = …, name: Symbol? = …, unique: Bool = …, where: String? = …, concurrently: Bool = …) -> Void
Drops an index of table: the one create_index made on columns
(with name: when it was given one), reversibly; or by name:
alone, not reversibly.
def execute(sql: String, *, down: String? = …) -> Void
Runs sql, one statement (PostgreSQL takes one per call here: write
several executes); reversible when down: gives the SQL that
undoes it.