### Cigogne TOML Configuration File Example Source: https://context7.com/billuc/cigogne/llms.txt Example structure of the `priv/cigogne.toml` file, controlling database connection, migration table, and migration folder settings. The `[migrations.dependencies]` section tracks included library migrations. ```toml # priv/cigogne.toml # Database connection — URL takes precedence over individual fields [database] # url = "postgres://user:pass@localhost:5432/mydb" host = "localhost" user = "postgres" # password = "postgres" # not recommended in version control port = 5432 name = "mydb" # Where to store the migration tracking table [migration-table] schema = "public" table = "_migrations" # Where cigogne looks for .sql migration files (relative to priv/) [migrations] migration_folder = "migrations" # Tracks the last migration synced from each library dependency [migrations.dependencies] auth_lib = "20240922065413-AddAuthTables" ``` -------------------------------- ### Basic lib Project Structure Source: https://github.com/billuc/cigogne/blob/main/test_libs/lib/README.md This is a placeholder for an example of the project in use. It imports the lib module and defines a main function. ```gleam import lib pub fn main() -> Nil { // TODO: An example of the project in use } ``` -------------------------------- ### Add my_app Package Source: https://github.com/billuc/cigogne/blob/main/test_libs/my_app/README.md Install the my_app package using the gleam add command. Specify the version to ensure compatibility. ```shell gleam add my_app@1 ``` -------------------------------- ### CLI: Update Configuration Source: https://context7.com/billuc/cigogne/llms.txt Update an existing `priv/cigogne.toml` file, for example, to change the database URL. ```sh # Update existing cigogne.toml (e.g., change DB URL) gleam run -m cigogne config update --url postgres://user:pass@localhost:5432/mydb ``` -------------------------------- ### Basic Gleam Project Structure Source: https://github.com/billuc/cigogne/blob/main/test_libs/my_app/README.md A minimal Gleam program structure. This example shows the import statement and a basic main function, intended as a placeholder for actual usage. ```gleam import my_app pub fn main() -> Nil { // TODO: An example of the project in use } ``` -------------------------------- ### Update Cigogne Configuration (Gleam) Source: https://context7.com/billuc/cigogne/llms.txt Writes or overwrites the `priv/cigogne.toml` file with the provided `Config`. This is useful for scripting configuration setup. ```gleam import cigogne import cigogne/config import gleam/result pub fn write_config() -> Result(Nil, cigogne.CigogneError) { let cfg = config.Config( database: config.DetailedDbConfig( host: option.Some("db.internal"), user: option.Some("app_user"), password: option.None, port: option.Some(5432), name: option.Some("production_db"), ), migration_table: config.MigrationTableConfig( schema: option.Some("public"), table: option.Some("_migrations"), ), migrations: config.MigrationsConfig( application_name: "my_app", migration_folder: option.Some("migrations"), dependencies: [], no_hash_check: option.None, ), ) cigogne.update_config(cfg) // → Updated config file at priv/cigogne.toml } ``` -------------------------------- ### Programmatic Cigogne Migration Initialization Source: https://github.com/billuc/cigogne/blob/main/README.md Integrate cigogne into your Gleam server initialization to ensure the database is up-to-date. This involves getting configuration, creating an engine, and applying all pending migrations. ```gleam import cigogne import cigogne/config pub fn init() -> Nil { use config <- result.try(config.get("my-app")) // Configure cigogne using a custom config object. Example: // let config = config.Config( // ..config.default_config, // database: config.UrlDbConfig("postgres://my_user@192.168.0.101:5433/my_db") // ) use engine <- result.try(cigogne.create_engine(config)) cigogne.apply_all(engine) } ``` -------------------------------- ### update_config Source: https://context7.com/billuc/cigogne/llms.txt Writes (or overwrites) `priv/cigogne.toml` with the given `Config`. This function is useful for scripting configuration setup. ```APIDOC ## `cigogne.update_config` Writes (or overwrites) `priv/cigogne.toml` with the given `Config`. Useful for scripting configuration setup. ```gleam import cigogne import cigogne/config import gleam/result pub fn write_config() -> Result(Nil, cigogne.CigogneError) { let cfg = config.Config( database: config.DetailedDbConfig( host: option.Some("db.internal"), user: option.Some("app_user"), password: option.None, port: option.Some(5432), name: option.Some("production_db"), ), migration_table: config.MigrationTableConfig( schema: option.Some("public"), table: option.Some("_migrations"), ), migrations: config.MigrationsConfig( application_name: "my_app", migration_folder: option.Some("migrations"), dependencies: [], no_hash_check: option.None, ), ) cigogne.update_config(cfg) // → Updated config file at priv/cigogne.toml } ``` ``` -------------------------------- ### Install Cigogne Dev Dependency Source: https://github.com/billuc/cigogne/blob/main/README.md Add cigogne as a development dependency to your Gleam project using the gleam add command. ```sh gleam add --dev cigogne ``` -------------------------------- ### Constructing a Zero Migration in Gleam Source: https://context7.com/billuc/cigogne/llms.txt Use `migration.create_zero_migration` to define a bootstrap migration, typically for setting up extensions. This is useful for initial database setup before other migrations run. ```gleam import cigogne/migration import gleam/time/timestamp // Construct a manual migration (e.g., a bootstrap zero-migration) let zero_mig = migration.create_zero_migration( "CreateExtensions", ["CREATE EXTENSION IF NOT EXISTS pgcrypto;"], ["DROP EXTENSION IF EXISTS pgcrypto;"] ) ``` -------------------------------- ### Getting Canonical Migration Filename in Gleam Source: https://context7.com/billuc/cigogne/llms.txt Use `migration.to_fullname` to retrieve the canonical filename for a migration, which is used for sorting and tracking purposes. ```gleam migration.to_fullname(my_mig) // → "20240101120000-CreateProducts" ``` -------------------------------- ### CLI: Initialize Configuration Source: https://context7.com/billuc/cigogne/llms.txt Generate a default `priv/cigogne.toml` configuration file. ```sh # Initialize the cigogne.toml config file with defaults gleam run -m cigogne config init ``` -------------------------------- ### Gleam: Create Migration Engine (from file) Source: https://context7.com/billuc/cigogne/llms.txt Create a `MigrationEngine` by reading configuration from `priv/cigogne.toml`. This automatically handles database connection, migration table creation, and loading of migration files. ```gleam import cigogne import cigogne/config import gleam/result import gleam/io pub fn start_app() -> Result(Nil, cigogne.CigogneError) { // Option 1: read config from priv/cigogne.toml automatically use app_name <- result.try( config.get_app_name() |> result.map_error(cigogne.ConfigError), ) use cfg <- result.try( config.get(app_name) |> result.map_error(cigogne.ConfigError), ) use engine <- result.try(cigogne.create_engine(cfg)) io.println("Engine ready") Ok(engine) } ``` -------------------------------- ### Gleam: Create Migration Engine (manual config) Source: https://context7.com/billuc/cigogne/llms.txt Manually construct a `Config` object to create a `MigrationEngine`. This allows for programmatic control over database connection details, migration table schema, and migration folder. ```gleam import cigogne import cigogne/config import gleam/result import gleam/io import gleam/option pub fn start_app() -> Result(Nil, cigogne.CigogneError) { // Option 2: build config manually let cfg = config.Config( database: config.UrlDbConfig("postgres://admin:secret@localhost:5432/mydb"), migration_table: config.MigrationTableConfig( schema: option.Some("public"), table: option.Some("_migrations"), ), migrations: config.MigrationsConfig( application_name: "my_app", migration_folder: option.Some("migrations"), dependencies: [], no_hash_check: option.None, ), ) use engine <- result.try(cigogne.create_engine(cfg)) io.println("Engine ready") Ok(engine) } ``` -------------------------------- ### cigogne.create_engine Source: https://context7.com/billuc/cigogne/llms.txt Creates a `MigrationEngine` from a `Config`. Connects to the database, creates the `_migrations` table if absent, loads applied migrations, reads migration files from disk, and verifies SHA-256 hashes to detect any files modified after being applied. Returns `Result(MigrationEngine, CigogneError)`. ```APIDOC ## `cigogne.create_engine` Creates a `MigrationEngine` from a `Config`. Connects to the database, creates the `_migrations` table if absent, loads applied migrations, reads migration files from disk, and verifies SHA-256 hashes to detect any files modified after being applied. Returns `Result(MigrationEngine, CigogneError)`. ```gleam import cigogne import cigogne/config import gleam/result import gleam/io pub fn start_app() -> Result(Nil, cigogne.CigogneError) { // Option 1: read config from priv/cigogne.toml automatically use app_name <- result.try( config.get_app_name() |> result.map_error(cigogne.ConfigError), ) use cfg <- result.try(config.get(app_name) |> result.map_error(cigogne.ConfigError)) // Option 2: build config manually let cfg = config.Config( database: config.UrlDbConfig("postgres://admin:secret@localhost:5432/mydb"), migration_table: config.MigrationTableConfig( schema: option.Some("public"), table: option.Some("_migrations"), ), migrations: config.MigrationsConfig( application_name: "my_app", migration_folder: option.Some("migrations"), dependencies: [], no_hash_check: option.None, ), ) use engine <- result.try(cigogne.create_engine(cfg)) io.println("Engine ready") Ok(engine) } ``` ``` -------------------------------- ### Create a New Timestamped Migration File Source: https://context7.com/billuc/cigogne/llms.txt Use `new_migration` to scaffold a new `.sql` migration file with empty up/down SQL skeletons. The file is placed in `priv//-.sql`. ```gleam import cigogne import cigogne/config import gleam/result pub fn scaffold_migration() -> Result(Nil, cigogne.CigogneError) { let migrations_cfg = config.MigrationsConfig( application_name: "my_app", migration_folder: option.Some("migrations"), dependencies: [], no_hash_check: option.None, ) use _ <- result.try(cigogne.new_migration(migrations_cfg, "AddProductsTable")) // → Migration file created: priv/migrations/20240922131500-AddProductsTable.sql Ok(Nil) } ``` -------------------------------- ### Load Configuration (Gleam) Source: https://context7.com/billuc/cigogne/llms.txt Loads a `Config` from a project's `priv/cigogne.toml` file. Falls back to `default_config` if no config file is found. `get_app_name` reads the project name from `gleam.toml`. ```gleam import cigogne/config import gleam/result import gleam/io pub fn load_config() -> Result(config.Config, config.ConfigError) { use app_name <- result.try(config.get_app_name()) // app_name = "my_app" (read from gleam.toml) use cfg <- result.map(config.get(app_name)) // Reads from priv/cigogne.toml; falls back to EnvVarConfig if not found io.println("Migrations folder: " <> config.get_migrations_folder(cfg.migrations)) cfg } ``` -------------------------------- ### CLI Commands Source: https://context7.com/billuc/cigogne/llms.txt The cigogne CLI is the primary interface for running migrations from the shell. Every command supports optional flags to override the database connection, migration table, and migrations folder. Run `gleam run -m cigogne help` for the full flag reference. ```APIDOC ## CLI Commands The cigogne CLI is the primary interface for running migrations from the shell. Every command supports optional flags to override the database connection, migration table, and migrations folder. Run `gleam run -m cigogne help` for the full flag reference. ```sh # Create a new timestamped migration file in priv/migrations/ gleam run -m cigogne new --name AddUsers # → Created: priv/migrations/20240922065413-AddUsers.sql # Apply the next unapplied migration gleam run -m cigogne up # Apply the next N migrations gleam run -m cigogne up --count 3 # Apply ALL unapplied migrations gleam run -m cigogne all # Roll back the most recently applied migration gleam run -m cigogne down # Roll back the last N applied migrations gleam run -m cigogne down --count 2 # Show applied and pending migrations gleam run -m cigogne show # Print all unapplied migrations as raw SQL gleam run -m cigogne print unapplied # Initialize the cigogne.toml config file with defaults gleam run -m cigogne config init # Update existing cigogne.toml (e.g., change DB URL) gleam run -m cigogne config update --url postgres://user:pass@localhost:5432/mydb # Include migrations from a dependency library gleam run -m cigogne include --name my_lib # Remove (reverse) a previously included library's migrations gleam run -m cigogne remove --name my_lib # Override connection flags inline (useful in CI) gleam run -m cigogne all \ --url postgres://ci_user:ci_pass@db:5432/mydb \ --no-hash-check ``` ``` -------------------------------- ### config.get / config.get_app_name Source: https://context7.com/billuc/cigogne/llms.txt Load a `Config` from a project's `priv/cigogne.toml` file. `get_app_name` reads the project name from `gleam.toml`. Falls back to `default_config` (using `DATABASE_URL` env var) if no config file is found. ```APIDOC ## `config.get` / `config.get_app_name` Load a `Config` from a project's `priv/cigogne.toml` file. `get_app_name` reads the project name from `gleam.toml`. Falls back to `default_config` (using `DATABASE_URL` env var) if no config file is found. ```gleam import cigogne/config import gleam/result import gleam/io pub fn load_config() -> Result(config.Config, config.ConfigError) { use app_name <- result.try(config.get_app_name()) // app_name = "my_app" (read from gleam.toml) use cfg <- result.map(config.get(app_name)) // Reads from priv/cigogne.toml; falls back to EnvVarConfig if not found io.println("Migrations folder: " <> config.get_migrations_folder(cfg.migrations)) cfg } ``` ``` -------------------------------- ### CLI: Include Dependency Migrations Source: https://context7.com/billuc/cigogne/llms.txt Incorporate migrations from a specified dependency library. ```sh # Include migrations from a dependency library gleam run -m cigogne include --name my_lib ``` -------------------------------- ### CLI: Print Pending Migrations Source: https://context7.com/billuc/cigogne/llms.txt Output the raw SQL for all unapplied migrations. ```sh # Print all unapplied migrations as raw SQL gleam run -m cigogne print unapplied ``` -------------------------------- ### Execute Cigogne Migrations via CLI Source: https://github.com/billuc/cigogne/blob/main/README.md Manage database migrations using the gleam run -m cigogne command. Available actions include applying migrations (up, down, all), showing applied migrations, and creating new migration files. ```sh # Apply the next migration gleam run -m cigogne up # Roll back the last applied migration gleam run -m cigogne down # Apply all migrations not yet applied gleam run -m cigogne all # Show the applied migration gleam run -m cigogne show # Create a new migration with name NAME gleam run -m cigogne new --name NAME ``` -------------------------------- ### Cigogne SQL Migration File Format Source: https://github.com/billuc/cigogne/blob/main/README.md Migration SQL files should follow the format -.sql. Use --- migration:up, --- migration:down, and --- migration:end comments to delineate migration phases. ```sql --- migration:up CREATE TABLE users( id UUID PRIMARY KEY, firstName TEXT NOT NULL, age INT NOT NULL ); --- migration:down DROP TABLE users; --- migration:end ``` -------------------------------- ### Run and Test Gleam Project Source: https://github.com/billuc/cigogne/blob/main/test_libs/lib/README.md These commands are used for local development. 'gleam run' executes the project, and 'gleam test' runs the test suite. ```sh gleam run # Run the project ``` ```sh gleam test # Run the tests ``` -------------------------------- ### CLI: Show Migration Status Source: https://context7.com/billuc/cigogne/llms.txt Display a list of applied and pending database migrations. ```sh # Show applied and pending migrations gleam run -m cigogne show ``` -------------------------------- ### Include Migrations from Dependencies Source: https://github.com/billuc/cigogne/blob/main/README.md Use the 'include-lib' CLI action to merge migration files from a specified library into your project's migration set. Running the command again will include any new migrations from the library. ```sh gleam run -m cigogne include-lib --lib-name my_lib ``` -------------------------------- ### CLI: Create New Migration Source: https://context7.com/billuc/cigogne/llms.txt Generate a new timestamped SQL migration file with a specified name in the default migration directory. ```sh # Create a new timestamped migration file in priv/migrations/ gleam run -m cigogne new --name AddUsers # → Created: priv/migrations/20240922065413-AddUsers.sql ``` -------------------------------- ### cigogne.new_migration Source: https://context7.com/billuc/cigogne/llms.txt Creates a new timestamped SQL migration file with empty up/down skeletons. The file is saved in the configured migrations folder. ```APIDOC ## `cigogne.new_migration` Creates a new timestamped `.sql` migration file on disk with an empty up/down skeleton. The file is placed in `priv//-.sql`. ```gleam import cigogne import cigogne/config import gleam/result pub fn scaffold_migration() -> Result(Nil, cigogne.CigogneError) { let migrations_cfg = config.MigrationsConfig( application_name: "my_app", migration_folder: option.Some("migrations"), dependencies: [], no_hash_check: option.None, ) use _ <- result.try(cigogne.new_migration(migrations_cfg, "AddProductsTable")) // → Migration file created: priv/migrations/20240922131500-AddProductsTable.sql Ok(Nil) } ``` ``` -------------------------------- ### SQL Migration File Format Source: https://context7.com/billuc/cigogne/llms.txt Each migration is a `.sql` file named `-.sql` placed in `priv/migrations/`. The file must contain `--- migration:up`, `--- migration:down`, and `--- migration:end` markers. An optional flag `disable_transaction` can be added to the `up` marker for DDL statements that cannot run inside a transaction. ```APIDOC ## SQL Migration File Format Each migration is a `.sql` file named `-.sql` placed in `priv/migrations/`. The file must contain `--- migration:up`, `--- migration:down`, and `--- migration:end` markers. An optional flag `disable_transaction` can be added to the `up` marker for DDL statements that cannot run inside a transaction. ```sql --- migration:up CREATE TABLE users ( id UUID PRIMARY KEY, name TEXT NOT NULL, age INT NOT NULL ); --- migration:down DROP TABLE users; --- migration:end ``` ```sql --- migration:up:disable_transaction CREATE INDEX CONCURRENTLY idx_users_name ON users(name); --- migration:down:disable_transaction DROP INDEX CONCURRENTLY idx_users_name; --- migration:end ``` ``` -------------------------------- ### Inspect Migration State from a Live Engine Source: https://context7.com/billuc/cigogne/llms.txt Use `get_all_migrations`, `get_applied_migrations`, and `get_unapplied_migrations` to inspect migration status without performing database writes. ```gleam import cigogne import cigogne/migration import gleam/list import gleam/io pub fn inspect(engine: cigogne.MigrationEngine) -> Nil { let all = cigogne.get_all_migrations(engine) let applied = cigogne.get_applied_migrations(engine) let pending = cigogne.get_unapplied_migrations(engine) io.println("Total: " <> list.length(all) |> int.to_string) io.println("Applied: " <> list.length(applied) |> int.to_string) io.println("Pending: " <> list.length(pending) |> int.to_string) list.each(pending, fn(m) { io.println(" ↳ " <> migration.to_fullname(m)) }) } ``` -------------------------------- ### priv/cigogne.toml Configuration File Source: https://context7.com/billuc/cigogne/llms.txt The TOML config file controls all aspects of cigogne's behavior. Generate a default with `gleam run -m cigogne config init`. The `[migrations.dependencies]` section tracks the last-included migration per library. ```APIDOC ## `priv/cigogne.toml` Configuration File The TOML config file controls all aspects of cigogne's behavior. Generate a default with `gleam run -m cigogne config init`. The `[migrations.dependencies]` section tracks the last-included migration per library. ```toml # priv/cigogne.toml # Database connection — URL takes precedence over individual fields [database] # url = "postgres://user:pass@localhost:5432/mydb" host = "localhost" user = "postgres" # password = "postgres" # not recommended in version control port = 5432 name = "mydb" # Where to store the migration tracking table [migration-table] schema = "public" table = "_migrations" # Where cigogne looks for .sql migration files (relative to priv/) [migrations] migration_folder = "migrations" # Tracks the last migration synced from each library dependency [migrations.dependencies] auth_lib = "20240922065413-AddAuthTables" ``` ``` -------------------------------- ### cigogne.apply Source: https://context7.com/billuc/cigogne/llms.txt Applies the next single unapplied migration. Returns an error if the database is already up to date. ```APIDOC ## `cigogne.apply` Applies exactly the next single unapplied migration. Returns `Error(NothingToApply)` when the database is already up to date. ```gleam import cigogne import gleam/result import gleam/io pub fn step_up(engine: cigogne.MigrationEngine) -> Result(Nil, cigogne.CigogneError) { case cigogne.apply(engine) { Ok(_) -> Ok(Nil) Error(cigogne.NothingToApply) -> { io.println("Already up to date!") Ok(Nil) } Error(err) -> Error(err) } } ``` ``` -------------------------------- ### cigogne.apply_all Source: https://context7.com/billuc/cigogne/llms.txt Applies all unapplied migrations in chronological order. Transactional migrations are wrapped in a single transaction for atomicity. ```APIDOC ## `cigogne.apply_all` Applies every unapplied migration in chronological order. All transactional migrations in a contiguous group are wrapped in a single transaction, so they succeed or fail atomically. Returns `Result(Nil, CigogneError)`. ```gleam import cigogne import cigogne/config import gleam/result pub fn migrate_to_latest(cfg: config.Config) -> Result(Nil, cigogne.CigogneError) { use engine <- result.try(cigogne.create_engine(cfg)) use _ <- result.try(cigogne.apply_all(engine)) // Output (example): // Applying migration 20240101123246-CreateTodos // Applying migration 20240922065413-AddTagsTable // // Migrations applied: // 20240101123246-CreateTodos // 20240922065413-AddTagsTable Ok(Nil) } ``` ``` -------------------------------- ### Default Cigogne Configuration File Source: https://github.com/billuc/cigogne/blob/main/README.md This TOML file defines the default configuration for database connections, migration table settings, and migration folder paths. It can be customized or generated using `gleam run -m cigogne update-config`. ```toml # This section will be overridden by eventual users of the library [database] # If url is defined, it is used to connect to the database # url = "" # If other data in this section is defined, it is used to connect # Otherwise, we fallback to the DATABASE_URL environment variable # host = "localhost" # user = "postgres" # # /!\ It is not recommended to have your password there # password = "postgres" # port = 5432 # name = "postgres" # This section will be overridden by eventual users of the library [migration-table] # schema = "public" # table = "_migrations" [migrations] # migration_folder = "migrations" [migrations.dependencies] ``` -------------------------------- ### Upgrade to Cigogne v3+ Schema Script (Shell) Source: https://context7.com/billuc/cigogne/llms.txt A one-time script to run after upgrading to Cigogne v3+ to add the `sha256` column to the `_migrations` table for file integrity checks. ```shell # Run after upgrading cigogne to v3+ for the first time gleam run -m cigogne/to_v3 # Expected output: # Connected to database # Is v3 already applied? false # Sha256 column created ``` -------------------------------- ### Include Dependency Migrations (Gleam) Source: https://context7.com/billuc/cigogne/llms.txt Merges a dependency library's migrations into the current project. This creates a combined migration file for all un-included migrations from the specified library. ```gleam import cigogne import cigogne/config import gleam/result pub fn include_dependency(cfg: config.Config) -> Result(Nil, cigogne.CigogneError) { use engine <- result.try(cigogne.create_engine(cfg)) // Include all pending migrations from "auth_lib" use _ <- result.try(cigogne.include_lib(engine, "auth_lib")) // → Created migration at priv/migrations/20240922140000-auth_lib.sql // → cigogne.toml updated with dependency tracking Ok(Nil) } ``` -------------------------------- ### Safe Database Migration with Error Handling in Gleam Source: https://context7.com/billuc/cigogne/llms.txt Implement robust database migration logic using `cigogne.create_engine` and `cigogne.apply_all`. This function handles various `CigogneError` types, providing specific feedback for different failure scenarios. ```gleam import cigogne import cigogne/config import gleam/result import gleam/io pub fn safe_migrate(cfg: config.Config) -> Nil { let outcome = cigogne.create_engine(cfg) |> result.try(cigogne.apply_all) case outcome { Ok(_) -> io.println("All migrations applied successfully.") Error(cigogne.NothingToApply) -> io.println("Already up to date — nothing to apply.") Error(cigogne.DatabaseError(db_err)) -> io.println_error("DB error: " <> cigogne.print_error(cigogne.DatabaseError(db_err))) Error(cigogne.MigrationError(cigogne.FileHashChanged(name))) -> io.println_error("Migration file was modified after being applied: " <> name) Error(cigogne.MigrationError(cigogne.MigrationNotFound(name))) -> io.println_error("Missing migration file for applied entry: " <> name) Error(err) -> cigogne.print_error(err) } } ``` -------------------------------- ### SQL Migration File Structure Source: https://context7.com/billuc/cigogne/llms.txt Define up and down migration steps using specific markers. Use `disable_transaction` for DDL statements that cannot run within a transaction. ```sql --- --- migration:up CREATE TABLE users ( id UUID PRIMARY KEY, name TEXT NOT NULL, age INT NOT NULL ); --- migration:down DROP TABLE users; --- migration:end ``` ```sql --- --- migration:up:disable_transaction CREATE INDEX CONCURRENTLY idx_users_name ON users(name); --- migration:down:disable_transaction DROP INDEX CONCURRENTLY idx_users_name; --- migration:end ``` -------------------------------- ### cigogne.read_migrations Source: https://context7.com/billuc/cigogne/llms.txt Reads and parses all SQL migration files from the configured folder without a database connection. Useful for inspecting migrations. ```APIDOC ## `cigogne.read_migrations` Reads and parses all `.sql` migration files from the configured folder without connecting to the database. Useful for inspecting migrations without needing a live DB connection. ```gleam import cigogne import cigogne/config import gleam/result import gleam/list import gleam/io pub fn list_migration_files(cfg: config.Config) -> Result(Nil, cigogne.CigogneError) { use migrations <- result.try(cigogne.read_migrations(cfg)) list.each(migrations, fn(m) { io.println(m.name <> " — up queries: " <> {m.queries_up |> list.length |> int.to_string}) }) Ok(Nil) } ``` ``` -------------------------------- ### Building a Timestamped Migration Manually in Gleam Source: https://context7.com/billuc/cigogne/llms.txt Manually construct a `migration.Migration` instance for custom migration definitions. Ensure all fields, including path, timestamp, name, queries, and options, are correctly populated. ```gleam import cigogne/migration import gleam/time/timestamp // Build a timestamped migration manually let my_mig = migration.Migration( path: "priv/migrations/20240101120000-CreateProducts.sql", timestamp: timestamp.from_unix_seconds(1_704_110_400), name: "CreateProducts", queries_up: [ "CREATE TABLE products (id UUID PRIMARY KEY, title TEXT NOT NULL, price NUMERIC(10,2));", ], queries_down: ["DROP TABLE products;"], options: migration.MigrationOptions(disable_transaction: False), sha256: "", ) ``` -------------------------------- ### CLI: Apply Migrations Source: https://context7.com/billuc/cigogne/llms.txt Apply the next unapplied migration, a specific number of migrations, or all pending migrations. ```sh # Apply the next unapplied migration gleam run -m cigogne up # Apply the next N migrations gleam run -m cigogne up --count 3 # Apply ALL unapplied migrations gleam run -m cigogne all ``` -------------------------------- ### Read Migration Files Without Database Connection Source: https://context7.com/billuc/cigogne/llms.txt Use `read_migrations` to parse all `.sql` migration files from the configured folder. This is useful for inspecting migrations without needing a live database connection. ```gleam import cigogne import cigogne/config import gleam/result import gleam/list import gleam/io pub fn list_migration_files(cfg: config.Config) -> Result(Nil, cigogne.CigogneError) { use migrations <- result.try(cigogne.read_migrations(cfg)) list.each(migrations, fn(m) { io.println(m.name <> " — up queries: " <> {m.queries_up |> list.length |> int.to_string}) }) Ok(Nil) } ``` -------------------------------- ### Apply the Next Single Unapplied Migration Source: https://context7.com/billuc/cigogne/llms.txt Use `apply` to migrate the database by one step. Handles the case where no migrations are pending. ```gleam import cigogne import gleam/result import gleam/io pub fn step_up(engine: cigogne.MigrationEngine) -> Result(Nil, cigogne.CigogneError) { case cigogne.apply(engine) { Ok(_) -> Ok(Nil) Error(cigogne.NothingToApply) -> { io.println("Already up to date!") Ok(Nil) } Error(err) -> Error(err) } } ``` -------------------------------- ### CLI: Override Connection Flags Source: https://context7.com/billuc/cigogne/llms.txt Provide database connection details and other flags directly on the command line, useful for CI environments. ```sh # Override connection flags inline (useful in CI) gleam run -m cigogne all \ --url postgres://ci_user:ci_pass@db:5432/mydb \ --no-hash-check ``` -------------------------------- ### Apply All Unapplied Migrations Chronologically Source: https://context7.com/billuc/cigogne/llms.txt Use `apply_all` to apply all pending migrations in order. Transactional migrations are grouped for atomic success or failure. ```gleam import cigogne import cigogne/config import gleam/result pub fn migrate_to_latest(cfg: config.Config) -> Result(Nil, cigogne.CigogneError) { use engine <- result.try(cigogne.create_engine(cfg)) use _ <- result.try(cigogne.apply_all(engine)) // Output (example): // Applying migration 20240101123246-CreateTodos // Applying migration 20240922065413-AddTagsTable // // Migrations applied: // 20240101123246-CreateTodos // 20240922065413-AddTagsTable Ok(Nil) } ``` -------------------------------- ### cigogne.get_all_migrations / get_applied_migrations / get_unapplied_migrations Source: https://context7.com/billuc/cigogne/llms.txt Inspects migration state from a live engine without performing any database writes, providing counts of all, applied, and unapplied migrations. ```APIDOC ## `cigogne.get_all_migrations` / `get_applied_migrations` / `get_unapplied_migrations` Inspect migration state from a live engine without performing any database writes. ```gleam import cigogne import cigogne/migration import gleam/list import gleam/io pub fn inspect(engine: cigogne.MigrationEngine) -> Nil { let all = cigogne.get_all_migrations(engine) let applied = cigogne.get_applied_migrations(engine) let pending = cigogne.get_unapplied_migrations(engine) io.println("Total: " <> list.length(all) |> int.to_string) io.println("Applied: " <> list.length(applied) |> int.to_string) io.println("Pending: " <> list.length(pending) |> int.to_string) list.each(pending, fn(m) { io.println(" ↳ " <> migration.to_fullname(m)) }) } ``` ``` -------------------------------- ### cigogne/to_v3 — Schema Upgrade Script Source: https://context7.com/billuc/cigogne/llms.txt One-time migration script for projects upgrading from cigogne v1/v2 to v3+. v3 introduced a `sha256` column in `_migrations` for file integrity checks. Run this once after updating the library. ```APIDOC ## `cigogne/to_v3` — Schema Upgrade Script One-time migration script for projects upgrading from cigogne v1/v2 to v3+. v3 introduced a `sha256` column in `_migrations` for file integrity checks. Run this once after updating the library. ```sh # Run after upgrading cigogne to v3+ for the first time gleam run -m cigogne/to_v3 # Expected output: # Connected to database # Is v3 already applied? false # Sha256 column created ``` ``` -------------------------------- ### include_lib / remove_lib Source: https://context7.com/billuc/cigogne/llms.txt Merge a dependency library's migrations into the current project. `include_lib` creates a combined migration file for all un-included migrations from `lib_name`. `remove_lib` creates a reversal migration that undoes all previously included migrations. ```APIDOC ## `cigogne.include_lib` / `cigogne.remove_lib` Merge a dependency library's migrations into the current project. `include_lib` creates a combined migration file for all un-included migrations from `lib_name`. `remove_lib` creates a reversal migration that undoes all previously included migrations. ```gleam import cigogne import cigogne/config import gleam/result pub fn include_dependency(cfg: config.Config) -> Result(Nil, cigogne.CigogneError) { use engine <- result.try(cigogne.create_engine(cfg)) // Include all pending migrations from "auth_lib" use _ <- result.try(cigogne.include_lib(engine, "auth_lib")) // → Created migration at priv/migrations/20240922140000-auth_lib.sql // → cigogne.toml updated with dependency tracking Ok(Nil) } pub fn remove_dependency(cfg: config.Config) -> Result(Nil, cigogne.CigogneError) { use engine <- result.try(cigogne.create_engine(cfg)) // Reverse all auth_lib migrations use _ <- result.try(cigogne.remove_lib(engine, "auth_lib")) // → Created migration at priv/migrations/20240922140001-remove_auth_lib.sql Ok(Nil) } ``` ``` -------------------------------- ### Add lib Package to Gleam Project Source: https://github.com/billuc/cigogne/blob/main/test_libs/lib/README.md Use this command to add the lib package to your Gleam project. Ensure you specify the desired version. ```sh gleam add lib@1 ``` -------------------------------- ### Remove Dependency Migrations (Gleam) Source: https://context7.com/billuc/cigogne/llms.txt Creates a reversal migration that undoes all previously included migrations from a specified library. This is used to remove a dependency's migrations. ```gleam import cigogne import cigogne/config import gleam/result pub fn remove_dependency(cfg: config.Config) -> Result(Nil, cigogne.CigogneError) { use engine <- result.try(cigogne.create_engine(cfg)) // Reverse all auth_lib migrations use _ <- result.try(cigogne.remove_lib(engine, "auth_lib")) // → Created migration at priv/migrations/20240922140001-remove_auth_lib.sql Ok(Nil) } ``` -------------------------------- ### Apply the Next N Unapplied Migrations Source: https://context7.com/billuc/cigogne/llms.txt Use `apply_n` to apply a specific number of pending migrations. If fewer than `count` migrations remain, all will be applied. A count of 0 or less is a no-op. ```gleam import cigogne import gleam/result pub fn apply_three(engine: cigogne.MigrationEngine) -> Result(Nil, cigogne.CigogneError) { use _ <- result.try(cigogne.apply_n(engine, 3)) // Applies up to the next 3 migrations Ok(Nil) } ``` -------------------------------- ### Convert Migrations to Version 3 Source: https://github.com/billuc/cigogne/blob/main/README.md Use this command to automatically update your migration files to be compatible with version 3 of cigogne, which includes hash checking. This is necessary if you are using Gleam versions earlier than 1.9.0. ```sh gleam run -m cigogne/to_v3 ``` -------------------------------- ### Comparing Migrations Chronologically in Gleam Source: https://context7.com/billuc/cigogne/llms.txt Employ `migration.compare` to determine the chronological order between two migrations. This is essential for applying migrations in the correct sequence. ```gleam migration.compare(zero_mig, my_mig) // → order.Lt ``` -------------------------------- ### cigogne.rollback Source: https://context7.com/billuc/cigogne/llms.txt Rolls back the most recently applied migration by executing its `--- migration:down` queries. Returns an error if there are no migrations to roll back. ```APIDOC ## `cigogne.rollback` Rolls back the most recently applied migration by executing its `--- migration:down` queries. ```gleam import cigogne import gleam/result import gleam/io pub fn undo_last(engine: cigogne.MigrationEngine) -> Result(Nil, cigogne.CigogneError) { case cigogne.rollback(engine) { Ok(_) -> Ok(Nil) Error(cigogne.NothingToRollback) -> { io.println("Nothing to roll back — database is clean.") Ok(Nil) } Error(err) -> Error(err) } } ``` ``` -------------------------------- ### cigogne.apply_n Source: https://context7.com/billuc/cigogne/llms.txt Applies the next specified number of unapplied migrations. If fewer migrations remain than the count, all remaining migrations are applied. A count of 0 or less results in no operation. ```APIDOC ## `cigogne.apply_n` Applies the next `count` unapplied migrations. If fewer than `count` remain, it applies all of them. A `count` ≤ 0 is a no-op. ```gleam import cigogne import gleam/result pub fn apply_three(engine: cigogne.MigrationEngine) -> Result(Nil, cigogne.CigogneError) { use _ <- result.try(cigogne.apply_n(engine, 3)) // Applies up to the next 3 migrations Ok(Nil) } ``` ``` -------------------------------- ### CLI: Remove Dependency Migrations Source: https://context7.com/billuc/cigogne/llms.txt Reverse the inclusion of migrations from a previously specified library. ```sh # Remove (reverse) a previously included library's migrations gleam run -m cigogne remove --name my_lib ``` -------------------------------- ### Apply Migration If Not Applied (Gleam) Source: https://context7.com/billuc/cigogne/llms.txt Ensures a specific migration is applied only if it hasn't been already. This function is safe to call multiple times. ```gleam import cigogne import cigogne/migration import gleam/result import gleam/time/timestamp pub fn ensure_bootstrap(engine: cigogne.MigrationEngine) -> Result(Nil, cigogne.CigogneError) { let bootstrap = migration.Migration( path: "priv/migrations/20240101000000-Bootstrap.sql", timestamp: timestamp.from_unix_seconds(1_704_067_200), name: "Bootstrap", queries_up: ["CREATE TABLE IF NOT EXISTS settings (key TEXT PRIMARY KEY, value TEXT);"], queries_down: ["DROP TABLE IF EXISTS settings;"], options: migration.default_migration_options, sha256: "", ) cigogne.apply_migration_if_not_applied(engine, bootstrap) } ``` -------------------------------- ### cigogne.rollback_n Source: https://context7.com/billuc/cigogne/llms.txt Rolls back the last specified number of applied migrations in reverse chronological order. A count of 0 or less results in no operation. ```APIDOC ## `cigogne.rollback_n` Rolls back the last `count` applied migrations in reverse chronological order. A `count` ≤ 0 is a no-op. ```gleam import cigogne import gleam/result pub fn undo_three(engine: cigogne.MigrationEngine) -> Result(Nil, cigogne.CigogneError) { use _ <- result.try(cigogne.rollback_n(engine, 3)) Ok(Nil) } ``` ``` -------------------------------- ### Remove Migrations from Dependencies Source: https://github.com/billuc/cigogne/blob/main/README.md The 'remove-lib' command combines all migrations previously included from a specified library and inverts their 'up' and 'down' operations, effectively rolling back those migrations without deleting the files. ```sh gleam run -m cigogne remove-lib --lib-name my_lib ``` -------------------------------- ### apply_migration_if_not_applied Source: https://context7.com/billuc/cigogne/llms.txt Idempotently applies a specific Migration only if it has not already been applied. This function is safe to call multiple times. ```APIDOC ## `cigogne.apply_migration_if_not_applied` Idempotently applies a specific `Migration` only if it has not already been applied. Safe to call multiple times. ```gleam import cigogne import cigogne/migration import gleam/result import gleam/time/timestamp pub fn ensure_bootstrap(engine: cigogne.MigrationEngine) -> Result(Nil, cigogne.CigogneError) { let bootstrap = migration.Migration( path: "priv/migrations/20240101000000-Bootstrap.sql", timestamp: timestamp.from_unix_seconds(1_704_067_200), name: "Bootstrap", queries_up: ["CREATE TABLE IF NOT EXISTS settings (key TEXT PRIMARY KEY, value TEXT);"], queries_down: ["DROP TABLE IF EXISTS settings;"], options: migration.default_migration_options, sha256: "", ) cigogne.apply_migration_if_not_applied(engine, bootstrap) } ``` ``` -------------------------------- ### CLI: Rollback Migrations Source: https://context7.com/billuc/cigogne/llms.txt Reverse the most recently applied migration or a specified number of applied migrations. ```sh # Roll back the most recently applied migration gleam run -m cigogne down # Roll back the last N applied migrations gleam run -m cigogne down --count 2 ``` -------------------------------- ### Rollback the Last N Applied Migrations Source: https://context7.com/billuc/cigogne/llms.txt Use `rollback_n` to undo a specified number of the most recent migrations. A count of 0 or less is a no-op. ```gleam import cigogne import gleam/result pub fn undo_three(engine: cigogne.MigrationEngine) -> Result(Nil, cigogne.CigogneError) { use _ <- result.try(cigogne.rollback_n(engine, 3)) Ok(Nil) } ``` -------------------------------- ### Rollback the Most Recently Applied Migration Source: https://context7.com/billuc/cigogne/llms.txt Use `rollback` to undo the last applied migration. Handles the case where there are no migrations to roll back. ```gleam import cigogne import gleam/result import gleam/io pub fn undo_last(engine: cigogne.MigrationEngine) -> Result(Nil, cigogne.CigogneError) { case cigogne.rollback(engine) { Ok(_) -> Ok(Nil) Error(cigogne.NothingToRollback) -> { io.println("Nothing to roll back — database is clean.") Ok(Nil) } Error(err) -> Error(err) } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.