use clap::Args;
use serde::{Deserialize, Serialize};
use crate::{
errors::CLIError,
operators::{
clickhouse_operators::{
apply_migrations, create_migrations_table,
get_clickhouse_client_and_ping, get_migrations_from_clickhouse,
},
migrations_operators::{get_migrations_from_dir, MigrationOnDisk},
},
};
#[derive(Args, Clone, Deserialize, Serialize)]
pub struct SetupArgs {
#[arg(env = "CLICKHOUSE_URL", default_value = None)]
pub url: Option<String>,
#[arg(env = "CLICKHOUSE_USER", default_value = None)]
pub user: Option<String>,
#[arg(env = "CLICKHOUSE_PASSWORD", default_value = None)]
pub password: Option<String>,
#[arg(env = "CLICKHOUSE_DB", default_value = None)]
pub database: Option<String>,
}
pub async fn run_pending_migrations(config: SetupArgs) -> Result<(), CLIError> {
let client = get_clickhouse_client_and_ping(config).await?;
create_migrations_table(client.clone()).await?;
let local_migrations = get_migrations_from_dir().await?;
let applied_migrations = get_migrations_from_clickhouse(client.clone()).await?;
let local_migrations_not_in_db: Vec<MigrationOnDisk> = local_migrations
.iter()
.filter_map(|m| {
if applied_migrations
.iter()
.any(|applied_migration| applied_migration.version == m.version)
{
return None;
}
Some(m.clone())
})
.collect();
apply_migrations(client.clone(), local_migrations_not_in_db).await?;
Ok(())
}