use anyhow::Result;
use sqlx::migrate::{MigrateError, Migrator};
use std::path::Path;
use structopt::StructOpt;
#[derive(StructOpt, Debug)]
pub struct Opt {
#[structopt(subcommand)]
pub command: Command,
}
#[derive(StructOpt, Debug)]
pub enum Command {
#[structopt(alias = "db")]
Database(DatabaseOpt),
#[structopt(alias = "mig")]
Migrate(MigrateOpt),
#[structopt(alias = "gen")]
Generate(GenerateOpt),
}
#[derive(StructOpt, Debug)]
pub struct DatabaseOpt {
#[structopt(subcommand)]
pub command: DatabaseCommand,
}
#[derive(StructOpt, Debug)]
pub enum DatabaseCommand {
Create {
#[structopt(long, short = "D", env)]
database_url: String,
},
Drop {
#[structopt(short)]
yes: bool,
#[structopt(long, short = "D", env)]
database_url: String,
},
Reset {
#[structopt(short)]
yes: bool,
#[structopt(long, default_value = "migrations")]
source: String,
#[structopt(long, short = "D", env)]
database_url: String,
},
Setup {
#[structopt(long, default_value = "migrations")]
source: String,
#[structopt(long, short = "D", env)]
database_url: String,
},
}
#[derive(StructOpt, Debug)]
pub struct MigrateOpt {
#[structopt(long, default_value = "migrations")]
pub source: String,
#[structopt(subcommand)]
pub command: MigrateCommand,
}
#[derive(StructOpt, Debug)]
pub struct GenerateOpt {
#[structopt(long, short = "D", env)]
pub database_url: String,
#[structopt(long, default_value = "migrations")]
pub source: String,
#[structopt(long)]
pub table: Option<String>,
#[structopt(short)]
pub reversible: bool,
}
impl GenerateOpt {
pub async fn validate(&self) -> Result<()> {
url::Url::parse(&self.database_url)?;
let migrator = Migrator::new(Path::new(&self.source)).await?;
for migration in migrator.iter() {
if migration.migration_type.is_reversible() != self.reversible {
Err(MigrateError::InvalidMixReversibleAndSimple)?
}
}
Ok(())
}
}
#[derive(StructOpt, Debug)]
pub enum MigrateCommand {
Add {
description: String,
#[structopt(short)]
reversible: bool,
},
Run {
#[structopt(long)]
dry_run: bool,
#[structopt(long)]
ignore_missing: bool,
#[structopt(long, short = "D", env)]
database_url: String,
},
Revert {
#[structopt(long)]
dry_run: bool,
#[structopt(long)]
ignore_missing: bool,
#[structopt(long, short = "D", env)]
database_url: String,
},
Info {
#[structopt(long, env)]
database_url: String,
},
BuildScript {
#[structopt(long)]
force: bool,
},
}