gleager
Gleager is a database migration tool for Gleam.
It applies and rolls back versioned SQL migrations using a driver
abstraction. Any database library that can execute SQL statements and run
parameterised queries can be used by implementing the Driver type — see
the gleager/types module.
Migration files live in a directory and follow this format:
001_description.sql
002_another.sql
Each file contains annotated up and down sections:
-- migrate:up
CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT);
-- migrate:down
DROP TABLE users;
The version is extracted from the filename prefix (e.g. 001 from
001_description.sql). Migrations are applied in version order and
rolled back in reverse.
Example
import gleager
import gleager/types.{Driver}
import sqlight
pub fn main() {
sqlight.with_connection("dev.db", fn(conn) {
let driver = Driver(
migration_dir: "migrations",
exec: fn(sql, args) {
case args {
[] -> sqlight.exec(sql, on: conn)
_ -> {
let values = list.map(args, sqlight.text)
case sqlight.query(sql, on: conn, with: values, expecting: decode.int) {
Ok(_) -> Ok(Nil)
Error(e) -> Error(e)
}
}
}
},
query: fn(sql, args, decoder) {
let values = list.map(args, sqlight.text)
sqlight.query(sql, on: conn, with: values, expecting: decoder)
},
)
let assert Ok(Nil) = gleager.up(driver, steps: None)
})
}
Values
pub fn down(
driver: types.Driver(e),
steps steps: option.Option(Int),
) -> Result(Nil, types.MigrationError)
Rolls back applied migrations in reverse version order.
Each migration runs its down section inside a transaction: either all
statements succeed and the migration is removed from the tracking table,
or any failure rolls back the entire migration.
The steps parameter limits how many migrations are rolled back. Pass None
to roll back all applied migrations, or Some(n) to roll back at most n.
Returns Ok(Nil) when all requested migrations have been rolled back (or
if none are applied). Returns Error(MigrationError) if any migration
fails or the migration directory cannot be read.
Examples
// Roll back all applied migrations
let assert Ok(Nil) = gleager.down(driver, steps: None)
// Roll back only the last migration
let assert Ok(Nil) = gleager.down(driver, steps: Some(1))
pub fn up(
driver: types.Driver(e),
steps steps: option.Option(Int),
) -> Result(Nil, types.MigrationError)
Applies pending migrations from the migration directory in version order.
Migrations that have already been applied (tracked in a schema_migrations
table created automatically) are skipped. Each new migration runs inside a
transaction: either all its statements succeed and the migration is recorded,
or any failure rolls back the entire migration.
The steps parameter limits how many migrations are applied. Pass None
to apply all pending migrations, or Some(n) to apply at most n.
Returns Ok(Nil) when all requested migrations have been applied (or if
there are none). Returns Error(MigrationError) if any migration fails or
the migration directory cannot be read.
Examples
// Apply all pending migrations
let assert Ok(Nil) = gleager.up(driver, steps: None)
// Apply only the next 2 migrations
let assert Ok(Nil) = gleager.up(driver, steps: Some(2))