Skip to main content

max / makenotwork

1.6 KB · 54 lines History Blame Raw
1 //! Database backup freshness check storage.
2
3 use super::{BackupCheckResult, Result, SqlitePool};
4 use tracing::instrument;
5
6 #[instrument(skip_all)]
7 pub async fn insert_backup_check(pool: &SqlitePool, result: &BackupCheckResult) -> Result<i64> {
8 let row = sqlx::query(
9 "INSERT INTO backup_checks (target, database_name, status, last_backup_at, size_bytes, age_hours, checked_at, error)
10 VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
11 )
12 .bind(&result.target)
13 .bind(&result.database_name)
14 .bind(&result.status)
15 .bind(&result.last_backup_at)
16 .bind(result.size_bytes)
17 .bind(result.age_hours)
18 .bind(&result.checked_at)
19 .bind(&result.error)
20 .execute(pool)
21 .await?;
22 Ok(row.last_insert_rowid())
23 }
24
25 /// Get the latest backup check for a specific target and database.
26 #[instrument(skip_all)]
27 pub async fn get_latest_backup_check(
28 pool: &SqlitePool,
29 target: &str,
30 database_name: &str,
31 ) -> Result<Option<BackupCheckRow>> {
32 Ok(sqlx::query_as::<_, BackupCheckRow>(
33 "SELECT id, target, database_name, status, last_backup_at, size_bytes, age_hours, checked_at, error
34 FROM backup_checks WHERE target = ? AND database_name = ? ORDER BY id DESC LIMIT 1",
35 )
36 .bind(target)
37 .bind(database_name)
38 .fetch_optional(pool)
39 .await?)
40 }
41
42 #[derive(Debug, Clone, sqlx::FromRow, serde::Serialize)]
43 pub struct BackupCheckRow {
44 pub id: i64,
45 pub target: String,
46 pub database_name: String,
47 pub status: String,
48 pub last_backup_at: Option<String>,
49 pub size_bytes: Option<i64>,
50 pub age_hours: Option<i64>,
51 pub checked_at: String,
52 pub error: Option<String>,
53 }
54