Skip to content

Commit

Permalink
Add migrate & rollback core helpers
Browse files Browse the repository at this point in the history
  • Loading branch information
jayvdb committed Apr 20, 2024
1 parent 3cfc92e commit de70ee6
Show file tree
Hide file tree
Showing 8 changed files with 73 additions and 62 deletions.
44 changes: 24 additions & 20 deletions butane/tests/migration-tests.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
use butane::migrations::{
adb::DeferredSqlType, adb::TypeIdentifier, adb::TypeKey, MemMigrations, Migration,
MigrationMut, Migrations, MigrationsMut,
};
use butane::migrations::adb::{DeferredSqlType, TypeIdentifier, TypeKey};
use butane::migrations::{self, MemMigrations, Migration, MigrationMut, Migrations, MigrationsMut};
use butane::{db::Connection, prelude::*, SqlType, SqlVal};
use butane_core::codegen::{butane_type_with_migrations, model_with_migrations};
#[cfg(feature = "pg")]
Expand Down Expand Up @@ -343,18 +341,21 @@ fn test_migrate(
.create_migration(&backends, "v2", ms.latest().as_ref())
.unwrap());

let mut to_apply = ms.unapplied_migrations(conn).unwrap();
let to_apply = ms.unapplied_migrations(conn).unwrap();
assert_eq!(to_apply.len(), 2);
for m in &to_apply {
m.apply(conn).unwrap();
}

migrations::migrate(conn, &ms).unwrap();

let to_apply = ms.unapplied_migrations(conn).unwrap();
assert_eq!(to_apply.len(), 0);

verify_sql(conn, &ms, expected_up_sql, expected_down_sql);

// Now downgrade, just to make sure we can
to_apply.reverse();
for m in to_apply {
m.downgrade(conn).unwrap();
}
migrations::rollback(conn, &ms).unwrap();

let to_apply = ms.unapplied_migrations(conn).unwrap();
assert_eq!(to_apply.len(), 2);
}

fn verify_sql(
Expand Down Expand Up @@ -559,16 +560,19 @@ fn migration_delete_table(conn: &mut Connection, expected_up_sql: &str, expected
.create_migration(&backends, "v2", ms.latest().as_ref())
.unwrap());

let mut to_apply = ms.unapplied_migrations(conn).unwrap();
let to_apply = ms.unapplied_migrations(conn).unwrap();
assert_eq!(to_apply.len(), 2);
for m in &to_apply {
m.apply(conn).unwrap();
}

migrations::migrate(conn, &ms).unwrap();

let to_apply = ms.unapplied_migrations(conn).unwrap();
assert_eq!(to_apply.len(), 0);

verify_sql(conn, &ms, expected_up_sql, expected_down_sql);

// Now downgrade, just to make sure we can
to_apply.reverse();
for m in to_apply {
m.downgrade(conn).unwrap();
}
migrations::rollback(conn, &ms).unwrap();

let to_apply = ms.unapplied_migrations(conn).unwrap();
assert_eq!(to_apply.len(), 2);
}
34 changes: 34 additions & 0 deletions butane_core/src/migrations/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,3 +326,37 @@ impl crate::internal::DataObjectInternal for ButaneMigration {
Ok(()) // no-op
}
}

/// Migrate forward.
pub fn migrate<M: Migration>(
connection: &mut impl crate::db::BackendConnection,
migrations: &impl Migrations<M = M>,
) -> Result<()> {
let to_apply = migrations.unapplied_migrations(connection)?;
for migration in &to_apply {
crate::info!("Applying migration {}", migration.name());
migration.apply(connection)?;
}
Ok(())
}

/// Rollback all applied migrations.
pub fn rollback<M: Migration>(
connection: &mut impl crate::db::BackendConnection,
migrations: &impl Migrations<M = M>,
) -> Result<()> {
let mut migration = match migrations.last_applied_migration(connection)? {
Some(migration) => migration,
None => return Ok(()),
};
migration.downgrade(connection)?;

while let Ok(Some(migration_name)) = migration.migration_from() {
migration = migrations
.get_migration(&migration_name)
.ok_or(Error::MigrationError("Migration not in chain".to_string()))?;
crate::info!("Rolling back migration {}", migration.name());
migration.downgrade(connection)?;
}
Ok(())
}
8 changes: 2 additions & 6 deletions butane_test_helper/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use std::sync::Mutex;

use block_id::{Alphabet, BlockId};
use butane_core::db::{connect, get_backend, pg, sqlite, Backend, Connection, ConnectionSpec};
use butane_core::migrations::{self, MemMigrations, Migration, Migrations, MigrationsMut};
use butane_core::migrations::{self, MemMigrations, Migration, MigrationsMut};
use once_cell::sync::Lazy;
use uuid::Uuid;

Expand Down Expand Up @@ -209,11 +209,7 @@ pub fn setup_db(backend: Box<dyn Backend>, conn: &mut Connection, migrate: bool)
"expected to create migration"
);
log::info!("created current migration");
let to_apply = mem_migrations.unapplied_migrations(conn).unwrap();
for m in to_apply {
log::info!("Applying migration {}", m.name());
m.apply(conn).unwrap();
}
migrations::migrate(conn, &mem_migrations).unwrap();
}

/// Create a sqlite [`Connection`].
Expand Down
7 changes: 2 additions & 5 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -505,14 +505,11 @@ to use these migrations:

``` rust
pub fn establish_connection() -> Connection {
use butane::migrations::{Migration, Migrations};
use butane::migrations;

let mut connection = butane::db::connect(&ConnectionSpec::load(".butane/connection.json").unwrap()).unwrap();
let migrations = butane_migrations::get_migrations().unwrap();
let to_apply = migrations.unapplied_migrations(&connection).unwrap();
for migration in to_apply {
migration.apply(&mut connection).unwrap();
}
migrations::migrate(&mut connection, &migrations).unwrap();
connection
}
```
Expand Down
7 changes: 2 additions & 5 deletions examples/getting_started/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ pub mod butane_migrations;
pub mod models;

use butane::db::{Connection, ConnectionSpec};
use butane::migrations::{Migration, Migrations};
use butane::migrations;
use butane::prelude::*;
use models::{Blog, Post};

Expand All @@ -15,10 +15,7 @@ pub fn establish_connection() -> Connection {
let mut connection =
butane::db::connect(&ConnectionSpec::load(".butane/connection.json").unwrap()).unwrap();
let migrations = butane_migrations::get_migrations().unwrap();
let to_apply = migrations.unapplied_migrations(&connection).unwrap();
for migration in to_apply {
migration.apply(&mut connection).unwrap();
}
migrations::migrate(&mut connection, &migrations).unwrap();
connection
}

Expand Down
18 changes: 4 additions & 14 deletions examples/getting_started/tests/rollback.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use butane::db::{BackendConnection, Connection};
use butane::migrations::{Migration, Migrations};
use butane::migrations;
use butane::DataObject;
use butane_test_helper::*;

Expand Down Expand Up @@ -38,22 +38,12 @@ fn migrate_and_rollback(mut connection: Connection) {
// Migrate forward.
let base_dir = std::path::PathBuf::from(".butane");
let migrations = butane_cli::get_migrations(&base_dir).unwrap();
let to_apply = migrations.unapplied_migrations(&connection).unwrap();
for migration in &to_apply {
migration
.apply(&mut connection)
.unwrap_or_else(|err| panic!("migration {} failed: {err}", migration.name()));
eprintln!("Applied {}", migration.name());
}

migrations::migrate(&mut connection, &migrations).unwrap();

insert_data(&connection);

// Rollback migrations.
for migration in to_apply.iter().rev() {
migration
.downgrade(&mut connection)
.unwrap_or_else(|err| panic!("rollback of {} failed: {err}", migration.name()));
eprintln!("Rolled back {}", migration.name());
}
migrations::rollback(&mut connection, &migrations).unwrap();
}
testall_no_migrate!(migrate_and_rollback);
7 changes: 2 additions & 5 deletions examples/newtype/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ pub mod butane_migrations;
pub mod models;

use butane::db::{Connection, ConnectionSpec};
use butane::migrations::{Migration, Migrations};
use butane::migrations;
use butane::prelude::*;
use models::{Blog, Post};

Expand All @@ -15,10 +15,7 @@ pub fn establish_connection() -> Connection {
let mut connection =
butane::db::connect(&ConnectionSpec::load(".butane/connection.json").unwrap()).unwrap();
let migrations = butane_migrations::get_migrations().unwrap();
let to_apply = migrations.unapplied_migrations(&connection).unwrap();
for migration in to_apply {
migration.apply(&mut connection).unwrap();
}
migrations::migrate(&mut connection, &migrations).unwrap();
connection
}

Expand Down
10 changes: 3 additions & 7 deletions examples/newtype/tests/rollback.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use butane::db::{BackendConnection, Connection};
use butane::migrations::{Migration, Migrations};
use butane::migrations::{self, Migration, Migrations};
use butane::DataObject;
use butane_test_helper::*;

Expand Down Expand Up @@ -32,12 +32,8 @@ fn migrate_and_rollback(mut connection: Connection) {
let base_dir = std::path::PathBuf::from(".butane");
let migrations = butane_cli::get_migrations(&base_dir).unwrap();
let to_apply = migrations.unapplied_migrations(&connection).unwrap();
for migration in &to_apply {
migration
.apply(&mut connection)
.unwrap_or_else(|err| panic!("migration {} failed: {err}", migration.name()));
eprintln!("Applied {}", migration.name());
}

migrations::migrate(&mut connection, &migrations).unwrap();

insert_data(&connection);

Expand Down

0 comments on commit de70ee6

Please sign in to comment.