Skip to main content

sway_groups_core/db/
database.rs

1//! Database connection and management.
2
3use sea_orm::{ConnectOptions, Database, DatabaseConnection, Schema, ConnectionTrait};
4use std::path::PathBuf;
5use anyhow::Result as AnyResult;
6use tracing::info;
7
8use crate::db::entities::{
9    FocusHistoryEntity, GroupEntity, GroupStateEntity, HiddenWorkspaceEntity,
10    OutputEntity, PendingWorkspaceEventEntity, SettingEntity,
11    WorkspaceEntity, WorkspaceGroupEntity,
12};
13
14/// Database manager for sway-groups.
15#[derive(Clone)]
16pub struct DatabaseManager {
17    conn: DatabaseConnection,
18}
19
20impl DatabaseManager {
21    /// Create a new database manager with the given database path.
22    pub async fn new(db_path: PathBuf) -> AnyResult<Self> {
23        let url = format!("sqlite://{}?mode=rwc", db_path.display());
24
25        let mut options = ConnectOptions::new(&url);
26        options.sqlx_logging_level(tracing::log::LevelFilter::Debug);
27
28        let conn = Database::connect(options).await?;
29
30        // Enable WAL mode before schema creation for better concurrent read/write performance
31        conn.execute_unprepared("PRAGMA journal_mode=WAL").await?;
32
33        let backend = conn.get_database_backend();
34        let schema = Schema::new(backend);
35
36        let mut stmt = schema.create_table_from_entity(GroupEntity);
37        stmt.if_not_exists();
38        conn.execute(&stmt).await?;
39        info!("Ensured table 'groups' exists");
40
41        let mut stmt = schema.create_table_from_entity(WorkspaceEntity);
42        stmt.if_not_exists();
43        conn.execute(&stmt).await?;
44        info!("Ensured table 'workspaces' exists");
45
46        let mut stmt = schema.create_table_from_entity(WorkspaceGroupEntity);
47        stmt.if_not_exists();
48        conn.execute(&stmt).await?;
49        info!("Ensured table 'workspace_groups' exists");
50
51        let mut stmt = schema.create_table_from_entity(OutputEntity);
52        stmt.if_not_exists();
53        conn.execute(&stmt).await?;
54        info!("Ensured table 'outputs' exists");
55
56        let mut stmt = schema.create_table_from_entity(FocusHistoryEntity);
57        stmt.if_not_exists();
58        conn.execute(&stmt).await?;
59        info!("Ensured table 'focus_history' exists");
60
61        let mut stmt = schema.create_table_from_entity(GroupStateEntity);
62        stmt.if_not_exists();
63        conn.execute(&stmt).await?;
64        info!("Ensured table 'group_state' exists");
65
66        let mut stmt = schema.create_table_from_entity(PendingWorkspaceEventEntity);
67        stmt.if_not_exists();
68        conn.execute(&stmt).await?;
69        info!("Ensured table 'pending_workspace_events' exists");
70
71        let mut stmt = schema.create_table_from_entity(HiddenWorkspaceEntity);
72        stmt.if_not_exists();
73        conn.execute(&stmt).await?;
74        info!("Ensured table 'hidden_workspaces' exists");
75
76        let mut stmt = schema.create_table_from_entity(SettingEntity);
77        stmt.if_not_exists();
78        conn.execute(&stmt).await?;
79        info!("Ensured table 'settings' exists");
80
81        Ok(Self { conn })
82    }
83
84    /// Get the database connection.
85    pub fn conn(&self) -> &DatabaseConnection {
86        &self.conn
87    }
88}