Skip to main content

kipuka/config/
db.rs

1//! Database configuration.
2//!
3//! Kipuka supports three database backends via sqlx:
4//!
5//! - **SQLite** — default, zero-dependency option for single-node deployments.
6//! - **PostgreSQL** — recommended for HA and multi-node setups.
7//! - **MariaDB** — alternative for environments where MySQL-compatible
8//!   databases are the standard.
9
10use serde::Deserialize;
11
12/// `[database]` section — connection pool configuration.
13///
14/// ```toml
15/// [database]
16/// url = "sqlite:///var/lib/kipuka/kipuka.db"
17/// max_connections = 10
18/// min_connections = 2
19/// ```
20#[derive(Debug, Clone, Deserialize)]
21#[serde(deny_unknown_fields)]
22pub struct DbConfig {
23    /// Database connection URL.
24    ///
25    /// Examples:
26    /// - `"sqlite:///var/lib/kipuka/kipuka.db"` — file-backed SQLite
27    /// - `"sqlite::memory:"` — in-memory SQLite (testing only)
28    /// - `"postgres://user:pass@host/kipuka"` — PostgreSQL
29    /// - `"mariadb://user:pass@host/kipuka"` — MariaDB
30    ///
31    /// Supports secret prefixes: `env:VAR`, `file:/path`, `prompt:Label`,
32    /// `keyring:name`, `systemd-creds:name`.
33    pub url: super::SecretRef,
34
35    /// Maximum number of connections in the pool.
36    ///
37    /// Default: 10 for PostgreSQL/MariaDB, 1 for SQLite (WAL mode
38    /// serializes writes regardless of pool size).
39    pub max_connections: Option<u32>,
40
41    /// Minimum number of idle connections maintained in the pool.
42    ///
43    /// Default: none (sqlx default applies).
44    pub min_connections: Option<u32>,
45
46    /// Connection acquisition timeout in seconds.
47    ///
48    /// Default: 30.
49    #[serde(default = "default_connect_timeout_secs")]
50    pub connect_timeout_secs: u64,
51
52    /// Maximum connection lifetime in seconds before recycling.
53    ///
54    /// Default: 3600 (1 hour).
55    #[serde(default = "default_max_lifetime_secs")]
56    pub max_lifetime_secs: u64,
57
58    /// Enable SQLite WAL (Write-Ahead Logging) mode.
59    ///
60    /// WAL provides better concurrent read performance by allowing
61    /// readers and writers to proceed simultaneously.  Enabled by
62    /// default for SQLite; ignored for other backends.
63    #[serde(default = "bool_true")]
64    pub sqlite_wal: bool,
65
66    /// Run pending migrations at startup.
67    ///
68    /// Default: `true`.
69    #[serde(default = "bool_true")]
70    pub run_migrations: bool,
71}
72
73fn default_connect_timeout_secs() -> u64 {
74    30
75}
76
77fn default_max_lifetime_secs() -> u64 {
78    3600
79}
80
81fn bool_true() -> bool {
82    true
83}
84
85impl Default for DbConfig {
86    fn default() -> Self {
87        Self {
88            url: super::SecretRef::from("sqlite:///var/lib/kipuka/kipuka.db"),
89            max_connections: None,
90            min_connections: None,
91            connect_timeout_secs: default_connect_timeout_secs(),
92            max_lifetime_secs: default_max_lifetime_secs(),
93            sqlite_wal: true,
94            run_migrations: true,
95        }
96    }
97}