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}