Packages

Simple pure gleam database agnostic migrations library for gleam

Current section

Files

Jump to
gleager README.md
Raw

README.md

# gleager
[![Package Version](https://img.shields.io/hexpm/v/gleager)](https://hex.pm/packages/gleager)
[![Hex Docs](https://img.shields.io/badge/hex-docs-ffaff3)](https://hexdocs.pm/gleager/)
A database migration tool for Gleam. Works with any SQL driver that implements
the `Driver` type — sqlight, pturso, or your own.
```sh
gleam add gleager
```
## Quick start
Create a `migrations` directory with versioned SQL files:
```sql
-- migrations/001_create_users.sql
-- migrate:up
CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT NOT NULL, email TEXT);
-- migrate:down
DROP TABLE users;
```
```sql
-- migrations/002_add_posts.sql
-- migrate:up
CREATE TABLE posts (id INTEGER PRIMARY KEY, user_id INTEGER NOT NULL, title TEXT, body TEXT);
CREATE INDEX idx_posts_user_id ON posts(user_id);
-- migrate:down
DROP INDEX idx_posts_user_id;
DROP TABLE posts;
```
Then apply them with sqlight:
```gleam
import gleager
import gleager/types.{Driver}
import gleam/dynamic/decode
import gleam/list
import sqlight
pub fn main() {
use conn <- sqlight.with_connection("dev.db")
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)
},
)
// Apply all pending migrations
let assert Ok(Nil) = gleager.up(driver, steps: None)
// Or apply only the next 2
let assert Ok(Nil) = gleager.up(driver, steps: Some(2))
// Roll back all applied migrations
let assert Ok(Nil) = gleager.down(driver, steps: None)
// Or roll back only the last one
let assert Ok(Nil) = gleager.down(driver, steps: Some(1))
}
```
## Migration file format
Migration files live in a single directory. The version is extracted from the
filename prefix:
```
migrations/
001_create_users.sql
002_add_posts.sql
003_add_settings.sql
```
Each file uses annotated sections:
```sql
-- migrate:up
<SQL to apply>
-- migrate:down
<SQL to roll back>
```
Migrations are applied in version order (`up`) and rolled back in reverse
(`down`). Each migration runs inside a transaction: either all statements
succeed and the migration is recorded in the `schema_migrations` tracking table,
or any failure rolls back the entire migration.
## Driver
gleager is database-agnostic. The `Driver(e)` type defines two callbacks:
- `exec(sql, args)` — run SQL statements, optionally with parameters
- `query(sql, args, decoder)` — run a parameterised query and decode the result
rows
See `gleager/types` for the full type definition, or the sqlight example above
for a working adapter.
## Development
```sh
gleam test # Run the test suite
```