mithril_aggregator/dependency_injection/builder/support/
sqlite.rs

1use anyhow::Context;
2
3use mithril_persistence::database::{ApplicationNodeType, SqlMigration};
4use mithril_persistence::sqlite::{
5    ConnectionBuilder, ConnectionOptions, SqliteConnection, SqliteConnectionPool,
6};
7use std::sync::Arc;
8
9use crate::dependency_injection::builder::{
10    SQLITE_FILE, SQLITE_FILE_CARDANO_TRANSACTION, SQLITE_MONITORING_FILE,
11};
12use crate::dependency_injection::{DependenciesBuilder, DependenciesBuilderError, Result};
13use crate::{ExecutionEnvironment, get_dependency};
14
15impl DependenciesBuilder {
16    fn setup_connection_builder(
17        &self,
18        sqlite_file_name: &str,
19        migrations: Vec<SqlMigration>,
20    ) -> ConnectionBuilder {
21        let logger = self.root_logger();
22        let connection_builder = match self.configuration.environment() {
23            ExecutionEnvironment::Test
24                if self.configuration.data_stores_directory().to_string_lossy() == ":memory:" =>
25            {
26                ConnectionBuilder::open_memory()
27            }
28            _ => ConnectionBuilder::open_file(
29                &self.configuration.get_sqlite_dir().join(sqlite_file_name),
30            ),
31        };
32
33        connection_builder
34            .with_node_type(ApplicationNodeType::Aggregator)
35            .with_options(&[
36                ConnectionOptions::EnableForeignKeys,
37                ConnectionOptions::EnableWriteAheadLog,
38            ])
39            .with_logger(logger.clone())
40            .with_migrations(migrations)
41    }
42
43    fn build_sqlite_connection(
44        &self,
45        sqlite_file_name: &str,
46        migrations: Vec<SqlMigration>,
47    ) -> Result<SqliteConnection> {
48        self.setup_connection_builder(sqlite_file_name, migrations)
49            .build()
50            .map_err(|e| DependenciesBuilderError::Initialization {
51                message: "SQLite initialization: failed to build connection.".to_string(),
52                error: Some(e),
53            })
54    }
55
56    /// Execute cleanup operations on SQLite connections
57    pub async fn drop_sqlite_connections(&self) {
58        if let Some(connection) = &self.sqlite_connection {
59            let _ = connection.execute("pragma analysis_limit=400; pragma optimize;");
60        }
61
62        if let Some(pool) = &self.sqlite_connection_cardano_transaction_pool
63            && let Ok(connection) = pool.connection()
64        {
65            let _ = connection.execute("pragma analysis_limit=400; pragma optimize;");
66        }
67    }
68
69    /// Get SQLite connection
70    pub async fn get_sqlite_connection(&mut self) -> Result<Arc<SqliteConnection>> {
71        get_dependency!(
72            self.sqlite_connection = Arc::new(self.build_sqlite_connection(
73                SQLITE_FILE,
74                crate::database::migration::get_migrations(),
75            )?)
76        )
77    }
78    /// Get EventStore SQLite connection
79    pub async fn get_event_store_sqlite_connection(&mut self) -> Result<Arc<SqliteConnection>> {
80        get_dependency!(
81            self.sqlite_connection_event_store = Arc::new(self.build_sqlite_connection(
82                SQLITE_MONITORING_FILE,
83                crate::event_store::database::migration::get_migrations(),
84            )?)
85        )
86    }
87
88    async fn build_sqlite_connection_cardano_transaction_pool(
89        &mut self,
90    ) -> Result<Arc<SqliteConnectionPool>> {
91        let connection_pool_size = self
92            .configuration
93            .cardano_transactions_database_connection_pool_size();
94
95        let connection_pool = self.setup_connection_builder(
96            SQLITE_FILE_CARDANO_TRANSACTION,
97            mithril_persistence::database::cardano_transaction_migration::get_migrations(),
98        ).build_pool(connection_pool_size)
99            .with_context(|| {
100                "Dependencies Builder can not build SQLite connection pool for Cardano transactions"
101            })
102            ?;
103
104        Ok(Arc::new(connection_pool))
105    }
106
107    /// Get SQLite connection pool for the cardano transactions store
108    pub async fn get_sqlite_connection_cardano_transaction_pool(
109        &mut self,
110    ) -> Result<Arc<SqliteConnectionPool>> {
111        get_dependency!(self.sqlite_connection_cardano_transaction_pool)
112    }
113}