#libsql #sql #database-migrations #migration

migrations

A small library to handle migrations, with built in support for libsql

4 releases

0.2.2 Jun 26, 2024
0.2.1 Jun 26, 2024
0.2.0 Jun 26, 2024
0.1.0 Jun 25, 2024

#1450 in Database interfaces

MIT license

29KB
676 lines

migrations

Installation

cargo add migrations

Usage

Features

  • default: Includes files feature
  • files: Used for file based migrations, most likely text or json but those are functions passed into this store. ChangesetStores::files
  • sql: Used for sql based migrations, with a directory of folders each with an up.sql and down.sql. ChangesetStores::sql
  • libsql: Full features libsql migrations, uses sql feature. Migrations::libsql, MigrationStores::libsql
  • all: Includes all features

LibSql

use migrations::Migrations;

fn main() {
    let db = async_std::task::block_on(Builder::new_local(&db_identifier.as_str()).build()).unwrap();
    let connection = db.connect().unwrap();
    /**
    * The migrations folder should contain a set of folders that match: YYYYMMDDHHMMSS_<\w+>
    * Each migration is stored in its own folder, with two files up.sql and down.sql.
    **/
    let migrations = Migrations::libsql(connection, std::env::current_dir().unwrap().join("migrations"));
    migrations.setup().unwrap();
    migrations.migrate().unwrap();
    // rollback only the last migration
    migrations.rollback().unwrap();
    // rollback all migrations
    migrations.reset().unwrap();
}

Concepts

Migrations are based on the following internal concepts:

Changesets

Contains the changesets to be run, based on two traits Changeset and ChangesetStore.

pub trait ChangesetStore {
    fn create_changeset(&self, name: String) -> anyhow::Result<Box<dyn Changeset + '_>>;

    fn get_changesets(&self) -> anyhow::Result<Vec<Box<dyn Changeset>>>;

    fn clone(&self) -> Box<dyn ChangesetStore + '_>;
}

pub trait Changeset {
    fn identifier(&self) -> Identifier;

    fn apply(&self, store: &dyn MigrationStore) -> anyhow::Result<()>;

    fn rollback(&self, store: &dyn MigrationStore) -> anyhow::Result<()>;

    fn duplicate(&self) -> Box<dyn Changeset>;
}

FileActions

Allows a file to be used by a MigrationStore, such as a database running a sql file.

pub trait FileActions {
    fn run(&self, file: &PathBuf) -> anyhow::Result<()>;
}

MigrationStore

Runs the changesets, based on the MigrationStore traits.

pub trait MigrationStore {
    fn is_ready(&self) -> anyhow::Result<bool>;

    fn setup(&self) -> anyhow::Result<()>;

    fn is_applied(&self, identifier: &Identifier) -> bool;

    fn apply(&mut self, changeset: &Box<dyn Changeset>) -> anyhow::Result<()>;

    fn rollback(&mut self, changeset: &Box<dyn Changeset>) -> anyhow::Result<()>;

    fn clone(&self) -> Box<dyn MigrationStore + '_>;

    fn file_actions(&self) -> Option<&dyn FileActions> {
        None
    }
}

Dependencies

~1–12MB
~129K SLoC