mithril_aggregator/commands/
database_command.rs

1use std::path::PathBuf;
2
3use anyhow::Context;
4use clap::{Parser, Subcommand};
5use slog::{debug, Logger};
6
7use mithril_common::StdResult;
8
9use crate::{dependency_injection::DependenciesBuilder, Configuration, ExecutionEnvironment};
10
11/// Database tools
12#[derive(Parser, Debug, Clone)]
13pub struct DatabaseCommand {
14    /// commands
15    #[clap(subcommand)]
16    pub database_subcommand: DatabaseSubCommand,
17}
18
19impl DatabaseCommand {
20    pub async fn execute(&self, root_logger: Logger) -> StdResult<()> {
21        self.database_subcommand.execute(root_logger).await
22    }
23}
24
25#[derive(Debug, Clone, Subcommand)]
26pub enum DatabaseSubCommand {
27    /// Migrate databases located in the given stores directory
28    Migrate(MigrateCommand),
29
30    /// Vacuum the aggregator main database
31    Vacuum(VacuumCommand),
32}
33
34impl DatabaseSubCommand {
35    pub async fn execute(&self, root_logger: Logger) -> StdResult<()> {
36        match self {
37            Self::Migrate(cmd) => cmd.execute(root_logger).await,
38            Self::Vacuum(cmd) => cmd.execute(root_logger).await,
39        }
40    }
41}
42
43#[derive(Parser, Debug, Clone)]
44pub struct MigrateCommand {
45    /// Stores directory
46    #[clap(long, env = "STORES_DIRECTORY")]
47    stores_directory: PathBuf,
48}
49
50impl MigrateCommand {
51    pub async fn execute(&self, root_logger: Logger) -> StdResult<()> {
52        let config = Configuration {
53            environment: ExecutionEnvironment::Production,
54            data_stores_directory: self.stores_directory.clone(),
55            // Temporary solution to avoid the need to provide a full configuration
56            ..Configuration::new_sample(std::env::temp_dir())
57        };
58        debug!(root_logger, "DATABASE MIGRATE command"; "config" => format!("{config:?}"));
59        println!(
60            "Migrating databases from stores directory: {}",
61            self.stores_directory.to_string_lossy()
62        );
63        let mut dependencies_builder =
64            DependenciesBuilder::new(root_logger.clone(), config.clone());
65
66        dependencies_builder
67            .get_sqlite_connection()
68            .await
69            .with_context(|| "Dependencies Builder can not get sqlite connection")?;
70
71        dependencies_builder
72            .get_event_store_sqlite_connection()
73            .await
74            .with_context(|| "Dependencies Builder can not get event store sqlite connection")?;
75
76        dependencies_builder
77            .get_sqlite_connection_cardano_transaction_pool()
78            .await
79            .with_context(|| {
80                "Dependencies Builder can not get cardano transaction pool sqlite connection"
81            })?;
82
83        Ok(())
84    }
85}
86
87#[derive(Parser, Debug, Clone)]
88pub struct VacuumCommand {
89    /// Stores directory
90    #[clap(long, env = "STORES_DIRECTORY")]
91    stores_directory: PathBuf,
92}
93
94impl VacuumCommand {
95    pub async fn execute(&self, root_logger: Logger) -> StdResult<()> {
96        let config = Configuration {
97            environment: ExecutionEnvironment::Production,
98            data_stores_directory: self.stores_directory.clone(),
99            // Temporary solution to avoid the need to provide a full configuration
100            ..Configuration::new_sample(std::env::temp_dir())
101        };
102        debug!(root_logger, "DATABASE VACUUM command"; "config" => format!("{config:?}"));
103        println!(
104            "Vacuuming database from stores directory: {}",
105            self.stores_directory.to_string_lossy()
106        );
107        let mut dependencies_builder =
108            DependenciesBuilder::new(root_logger.clone(), config.clone());
109
110        dependencies_builder
111            .get_upkeep_service()
112            .await
113            .with_context(|| "Dependencies Builder can not get upkeep service")?
114            .vacuum()
115            .await
116            .with_context(|| "Upkeep service can not vacuum")?;
117
118        Ok(())
119    }
120}