metis_core/dal/database/
mod.rs

1pub mod configuration_repository;
2pub mod models;
3pub mod repository;
4pub mod schema;
5
6use diesel::prelude::*;
7use diesel::sqlite::SqliteConnection;
8use diesel_migrations::{embed_migrations, EmbeddedMigrations, MigrationHarness};
9
10pub const MIGRATIONS: EmbeddedMigrations = embed_migrations!("src/dal/database/migrations");
11
12/// Database connection and migration management
13pub struct Database {
14    connection_string: String,
15}
16
17impl Database {
18    /// Create a new database connection and run migrations
19    ///
20    /// # Arguments
21    /// * `connection_string` - SQLite connection string (e.g., ":memory:", "database.db", "file:database.db?mode=rw")
22    pub fn new(connection_string: &str) -> Result<Self, Box<dyn std::error::Error + Send + Sync>> {
23        // Run migrations once to ensure the database is set up
24        let mut connection = SqliteConnection::establish(connection_string)?;
25        connection.run_pending_migrations(MIGRATIONS)?;
26
27        Ok(Self {
28            connection_string: connection_string.to_string(),
29        })
30    }
31
32    /// Get a new connection to the database
33    pub fn get_connection(
34        &self,
35    ) -> Result<SqliteConnection, Box<dyn std::error::Error + Send + Sync>> {
36        let mut connection = SqliteConnection::establish(&self.connection_string)?;
37
38        // For in-memory databases, we need to run migrations on each connection
39        // since each connection is a separate database
40        if self.connection_string == ":memory:" {
41            connection.run_pending_migrations(MIGRATIONS)?;
42        }
43
44        Ok(connection)
45    }
46
47    /// Get a document repository with a new connection
48    pub fn repository(
49        &self,
50    ) -> Result<repository::DocumentRepository, Box<dyn std::error::Error + Send + Sync>> {
51        let connection = self.get_connection()?;
52        Ok(repository::DocumentRepository::new(connection))
53    }
54
55    /// Get a document repository (consumes the database) - kept for compatibility
56    pub fn into_repository(self) -> repository::DocumentRepository {
57        let connection = self.get_connection().expect("Failed to get connection");
58        repository::DocumentRepository::new(connection)
59    }
60
61    /// Get a configuration repository with a new connection
62    pub fn configuration_repository(
63        &self,
64    ) -> Result<
65        configuration_repository::ConfigurationRepository,
66        Box<dyn std::error::Error + Send + Sync>,
67    > {
68        let connection = self.get_connection()?;
69        Ok(configuration_repository::ConfigurationRepository::new(
70            connection,
71        ))
72    }
73}