diff options
| author | Owen Jacobson <owen@grimoire.ca> | 2024-10-22 19:12:34 -0400 |
|---|---|---|
| committer | Owen Jacobson <owen@grimoire.ca> | 2024-10-22 19:12:34 -0400 |
| commit | 6430854352745f45281021c305b4e350bc92d535 (patch) | |
| tree | c6901c22a45e36415f63efe988d4d4f2a309df81 /src/cli/recanonicalize.rs | |
| parent | 98af8ff80da919a1126ba7c6afa65e6654b5ecde (diff) | |
| parent | db940bacd096a33a65f29759e70ea1acf6186a67 (diff) | |
Merge branch 'unicode-normalization'
Diffstat (limited to 'src/cli/recanonicalize.rs')
| -rw-r--r-- | src/cli/recanonicalize.rs | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/src/cli/recanonicalize.rs b/src/cli/recanonicalize.rs new file mode 100644 index 0000000..5f8a1db --- /dev/null +++ b/src/cli/recanonicalize.rs @@ -0,0 +1,86 @@ +use sqlx::sqlite::SqlitePool; + +use crate::{app::App, db}; + +/// Command-line entry point for repairing canonical names in the `hi` database. +/// This command may be necessary after an upgrade, if the canonical forms of +/// names has changed. It will re-calculate the canonical form of each name in +/// the database, based on its display form, and store the results back to the +/// database. +/// +/// This is intended to be used as a Clap [Parser], to capture command-line +/// arguments for the `hi-recanonicalize` command: +/// +/// ```no_run +/// # use hi::recanonicalize::cli::Error; +/// # +/// # #[tokio::main] +/// # async fn main() -> Result<(), Error> { +/// use clap::Parser; +/// use hi::cli::recanonicalize::Args; +/// +/// let args = Args::parse(); +/// args.run().await?; +/// # Ok(()) +/// # } +/// ``` +#[derive(clap::Parser)] +#[command( + version, + about = "Recanonicalize names in the `hi` database.", + long_about = r#"Recanonicalize names in the `hi` database. + +The `hi` server must not be running while this command is run. + +The database at `--database-url` will also be created, or upgraded, automatically."# +)] +pub struct Args { + /// Sqlite URL or path for the `hi` database + #[arg(short, long, env, default_value = "sqlite://.hi")] + database_url: String, + + /// Sqlite URL or path for a backup of the `hi` database during upgrades + #[arg(short = 'D', long, env, default_value = "sqlite://.hi.backup")] + backup_database_url: String, +} + +impl Args { + /// Recanonicalizes the `hi` database, using the parsed configuation in + /// `self`. + /// + /// This will perform the following tasks: + /// + /// * Migrate the `hi` database (at `--database-url`). + /// * Recanonicalize names in the `login` and `channel` tables. + /// + /// # Errors + /// + /// Will return `Err` if the canonicalization or database upgrade processes + /// fail. The specific [`Error`] variant will expose the cause + /// of the failure. + pub async fn run(self) -> Result<(), Error> { + let pool = self.pool().await?; + + let app = App::from(pool); + app.logins().recanonicalize().await?; + app.channels().recanonicalize().await?; + + Ok(()) + } + + async fn pool(&self) -> Result<SqlitePool, db::Error> { + db::prepare(&self.database_url, &self.backup_database_url).await + } +} + +/// Errors that can be raised by [`Args::run`]. +#[derive(Debug, thiserror::Error)] +#[error(transparent)] +pub enum Error { + // /// Failure due to `io::Error`. See [`io::Error`]. + // Io(#[from] io::Error), + /// Failure due to a database initialization error. See [`db::Error`]. + Database(#[from] db::Error), + /// Failure due to a data manipulation error. See [`sqlx::Error`]. + Sqlx(#[from] sqlx::Error), +} |
