Skip to main content

shaperail_core/
database.rs

1//! Database engine and multi-database configuration types for M14.
2
3use serde::{Deserialize, Serialize};
4
5/// Supported database engines for multi-database (M14).
6///
7/// SQL engines (Postgres, MySQL, SQLite) use the ORM layer; MongoDB uses its own driver.
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
9#[serde(rename_all = "lowercase")]
10pub enum DatabaseEngine {
11    /// PostgreSQL — full feature coverage.
12    Postgres,
13
14    /// MySQL / MariaDB — 95% feature coverage.
15    MySQL,
16
17    /// SQLite — 85% feature coverage (e.g. no full-text search like Postgres).
18    SQLite,
19
20    /// MongoDB — 75% feature coverage via mongodb crate.
21    MongoDB,
22}
23
24impl DatabaseEngine {
25    /// Default engine when not specified (single-DB backward compat).
26    pub const fn default_engine() -> Self {
27        Self::Postgres
28    }
29
30    /// Returns true for SQL backends (Postgres, MySQL, SQLite).
31    pub const fn is_sql(&self) -> bool {
32        matches!(self, Self::Postgres | Self::MySQL | Self::SQLite)
33    }
34
35    /// Returns true for MongoDB.
36    pub const fn is_mongo(&self) -> bool {
37        matches!(self, Self::MongoDB)
38    }
39}
40
41impl Default for DatabaseEngine {
42    fn default() -> Self {
43        Self::default_engine()
44    }
45}
46
47#[cfg(test)]
48mod tests {
49    use super::*;
50
51    #[test]
52    fn engine_is_sql() {
53        assert!(DatabaseEngine::Postgres.is_sql());
54        assert!(DatabaseEngine::MySQL.is_sql());
55        assert!(DatabaseEngine::SQLite.is_sql());
56        assert!(!DatabaseEngine::MongoDB.is_sql());
57    }
58
59    #[test]
60    fn engine_serde() {
61        let s = serde_json::to_string(&DatabaseEngine::Postgres).unwrap();
62        assert_eq!(s, r#""postgres""#);
63        let e: DatabaseEngine = serde_json::from_str(&s).unwrap();
64        assert_eq!(e, DatabaseEngine::Postgres);
65    }
66
67    #[test]
68    fn engine_is_mongo() {
69        assert!(DatabaseEngine::MongoDB.is_mongo());
70        assert!(!DatabaseEngine::Postgres.is_mongo());
71        assert!(!DatabaseEngine::MySQL.is_mongo());
72        assert!(!DatabaseEngine::SQLite.is_mongo());
73    }
74
75    #[test]
76    fn engine_default_is_postgres() {
77        assert_eq!(DatabaseEngine::default(), DatabaseEngine::Postgres);
78        assert_eq!(DatabaseEngine::default_engine(), DatabaseEngine::Postgres);
79    }
80
81    #[test]
82    fn all_engine_variants_serde() {
83        let pairs = [
84            (DatabaseEngine::Postgres, "postgres"),
85            (DatabaseEngine::MySQL, "mysql"),
86            (DatabaseEngine::SQLite, "sqlite"),
87            (DatabaseEngine::MongoDB, "mongodb"),
88        ];
89        for (engine, expected_str) in pairs {
90            let json = serde_json::to_string(&engine).unwrap();
91            assert_eq!(json, format!("\"{expected_str}\""));
92            let back: DatabaseEngine = serde_json::from_str(&json).unwrap();
93            assert_eq!(back, engine);
94        }
95    }
96}