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::opts::UpgradeCommandOpt;
use crate::Config;
use crate::StdResult;
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 applied_migration_names = manager.applied_migration_names()?;
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");
} 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 {
let pending_migrations = filter_pending_migrations(migrations, &applied_migration_names);
upgrade_all_pending_migrations(manager, &pending_migrations)?;
for migration in pending_migrations.iter() {
print_migration_info(migration);
manager.upgrade(migration)?;
}
}
Ok(())
}
fn is_up_to_date_migrations(migrations: &[Migration], applied_migration_names: &[String]) -> bool {
migrations.is_empty() || migrations.last().map(|m| m.name()) == applied_migration_names.first()
}
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(())
fn print_migration_info(migration: &Migration) {
println!("upgrade {}...", migration.name());
}

View File

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

View File

@ -24,7 +24,7 @@ pub(crate) enum Command {
List,
#[structopt(name = "upgrade", visible_alias = "up")]
Upgrade,
Upgrade(UpgradeCommandOpt),
#[structopt(name = "downgrade", visible_alias = "down")]
Downgrade(DowngradeCommandOpt),
@ -40,13 +40,22 @@ pub(crate) struct ApplyCommandOpt {
#[derive(Debug, StructOpt)]
pub(crate) struct MakeCommandOpt {
/// Name of the migration to create in specify directory.
#[structopt(parse(from_str))]
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)]
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")]
pub migrations_number: usize,