feat: add config to upgrade command

... which adds the possibility to pass a specific migration
name to be updated
This commit is contained in:
Dmitriy Pleshevskiy 2021-02-25 00:47:13 +03:00
parent 8aa57a00bc
commit bd57c75dfc
3 changed files with 36 additions and 25 deletions

View File

@ -1,39 +1,41 @@
use crate::database::migration::*; use crate::database::migration::*;
use crate::opts::UpgradeCommandOpt;
use crate::Config; use crate::Config;
use crate::StdResult; use crate::StdResult;
use std::convert::TryFrom; use std::convert::TryFrom;
pub(crate) fn upgrade_pending_migrations(config: Config) -> StdResult<()> { pub(crate) fn upgrade_pending_migrations(config: Config, opts: UpgradeCommandOpt) -> StdResult<()> {
let mut manager = MigrationManager::try_from(&config)?; let mut manager = MigrationManager::try_from(&config)?;
let applied_migration_names = manager.applied_migration_names()?; let applied_migration_names = manager.applied_migration_names()?;
let migrations = config.migrations()?; let migrations = config.migrations()?;
if is_up_to_date_migrations(&migrations, &applied_migration_names) { let pending_migrations = filter_pending_migrations(migrations, &applied_migration_names);
if pending_migrations.is_empty() {
println!("Up to date"); println!("Up to date");
} else if let Some(migration_name) = opts.migration_name {
let target_migration = pending_migrations
.iter()
.find(|m| m.name() == &migration_name);
match target_migration {
Some(migration) => {
print_migration_info(migration);
manager.upgrade(migration)?;
}
None => {
eprintln!(r#"Cannot find migration with "{}" name"#, migration_name);
}
}
} else { } else {
let pending_migrations = filter_pending_migrations(migrations, &applied_migration_names); for migration in pending_migrations.iter() {
upgrade_all_pending_migrations(manager, &pending_migrations)?; print_migration_info(migration);
manager.upgrade(migration)?;
}
} }
Ok(()) Ok(())
} }
fn is_up_to_date_migrations(migrations: &[Migration], applied_migration_names: &[String]) -> bool { fn print_migration_info(migration: &Migration) {
migrations.is_empty() || migrations.last().map(|m| m.name()) == applied_migration_names.first() println!("upgrade {}...", migration.name());
}
fn upgrade_all_pending_migrations<ManagerT>(
mut manager: ManagerT,
pending_migrations: &[Migration],
) -> StdResult<()>
where
ManagerT: Sized + DatabaseMigrationManager,
{
for migration in pending_migrations.iter() {
println!("upgrade {}...", migration.name());
manager.upgrade(migration)?;
}
Ok(())
} }

View File

@ -31,9 +31,9 @@ fn main() -> StdResult<()> {
let config = Config::read(opt.config)?; let config = Config::read(opt.config)?;
commands::print_migration_lists(config)?; commands::print_migration_lists(config)?;
} }
Command::Upgrade => { Command::Upgrade(opts) => {
let config = Config::read(opt.config)?; let config = Config::read(opt.config)?;
commands::upgrade_pending_migrations(config)?; commands::upgrade_pending_migrations(config, opts)?;
} }
Command::Downgrade(opts) => { Command::Downgrade(opts) => {
let config = Config::read(opt.config)?; let config = Config::read(opt.config)?;

View File

@ -24,7 +24,7 @@ pub(crate) enum Command {
List, List,
#[structopt(name = "upgrade", visible_alias = "up")] #[structopt(name = "upgrade", visible_alias = "up")]
Upgrade, Upgrade(UpgradeCommandOpt),
#[structopt(name = "downgrade", visible_alias = "down")] #[structopt(name = "downgrade", visible_alias = "down")]
Downgrade(DowngradeCommandOpt), Downgrade(DowngradeCommandOpt),
@ -40,13 +40,22 @@ pub(crate) struct ApplyCommandOpt {
#[derive(Debug, StructOpt)] #[derive(Debug, StructOpt)]
pub(crate) struct MakeCommandOpt { pub(crate) struct MakeCommandOpt {
/// Name of the migration to create in specify directory.
#[structopt(parse(from_str))] #[structopt(parse(from_str))]
pub migration_name: String, pub migration_name: String,
} }
#[derive(Debug, StructOpt)]
pub(crate) struct UpgradeCommandOpt {
/// Name of the existing migration that will update the schema
/// in the database.
#[structopt(long = "name")]
pub migration_name: Option<String>,
}
#[derive(Debug, StructOpt)] #[derive(Debug, StructOpt)]
pub(crate) struct DowngradeCommandOpt { pub(crate) struct DowngradeCommandOpt {
/// How many applied migrations do we have to rollback /// How many applied migrations do we have to rollback.
#[structopt(long = "number", short = "n", default_value = "1")] #[structopt(long = "number", short = "n", default_value = "1")]
pub migrations_number: usize, pub migrations_number: usize,