# migrations ## Installation ```shell 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 ```rust 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`. ```rust pub trait ChangesetStore { fn create_changeset(&self, name: String) -> anyhow::Result>; fn get_changesets(&self) -> anyhow::Result>>; fn clone(&self) -> Box; } 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; } ``` ### FileActions Allows a file to be used by a MigrationStore, such as a database running a sql file. ```rust pub trait FileActions { fn run(&self, file: &PathBuf) -> anyhow::Result<()>; } ``` ### MigrationStore Runs the changesets, based on the `MigrationStore` traits. ```rust pub trait MigrationStore { fn is_ready(&self) -> anyhow::Result; fn setup(&self) -> anyhow::Result<()>; fn is_applied(&self, identifier: &Identifier) -> bool; fn apply(&mut self, changeset: &Box) -> anyhow::Result<()>; fn rollback(&mut self, changeset: &Box) -> anyhow::Result<()>; fn clone(&self) -> Box; fn file_actions(&self) -> Option<&dyn FileActions> { None } } ```