Skip to main content

dkdc_lake/
secrets.rs

1use crate::Lake;
2use anyhow::Result;
3use dkdc_config::SECRETS_TABLE_NAME;
4use duckdb::params;
5
6impl Lake {
7    pub fn create_secrets_table(&self) -> Result<()> {
8        let sql = format!(
9            "CREATE TABLE IF NOT EXISTS {} (
10                filepath VARCHAR,
11                filename VARCHAR,
12                filedata BLOB,
13                filesize BIGINT,
14                fileupdated TIMESTAMP
15            )",
16            SECRETS_TABLE_NAME
17        );
18        self.execute(&sql)?;
19        Ok(())
20    }
21
22    pub fn set_secret(&self, name: &str, value: &[u8]) -> Result<()> {
23        self.create_secrets_table()?;
24
25        let sql = format!(
26            "INSERT INTO {} (filepath, filename, filedata, filesize, fileupdated)
27             VALUES (?, ?, ?, ?, ?)",
28            SECRETS_TABLE_NAME
29        );
30
31        let mut stmt = self.prepare(&sql)?;
32        use chrono::Utc;
33        stmt.execute(params![
34            "./secrets",
35            name,
36            value,
37            value.len() as i64,
38            Utc::now().to_rfc3339(),
39        ])?;
40
41        Ok(())
42    }
43
44    pub fn get_secret(&self, name: &str) -> Result<Option<Vec<u8>>> {
45        let sql = format!(
46            "SELECT filedata
47             FROM {}
48             WHERE filepath = './secrets' AND filename = ?
49             ORDER BY fileupdated DESC
50             LIMIT 1",
51            SECRETS_TABLE_NAME
52        );
53
54        let mut stmt = self.prepare(&sql)?;
55        let mut rows = stmt.query(params![name])?;
56
57        if let Some(row) = rows.next()? {
58            Ok(Some(row.get(0)?))
59        } else {
60            Ok(None)
61        }
62    }
63
64    pub fn list_secrets(&self) -> Result<Vec<String>> {
65        let sql = format!(
66            "SELECT DISTINCT filename
67             FROM {}
68             WHERE filepath = './secrets'
69             ORDER BY filename",
70            SECRETS_TABLE_NAME
71        );
72
73        let mut stmt = self.prepare(&sql)?;
74        let mut rows = stmt.query([])?;
75
76        let mut secrets = Vec::new();
77        while let Some(row) = rows.next()? {
78            secrets.push(row.get(0)?);
79        }
80
81        Ok(secrets)
82    }
83
84    pub fn delete_secret(&self, name: &str) -> Result<bool> {
85        let sql = format!(
86            "DELETE FROM {} WHERE filepath = './secrets' AND filename = ?",
87            SECRETS_TABLE_NAME
88        );
89
90        let mut stmt = self.prepare(&sql)?;
91        let count = stmt.execute(params![name])?;
92
93        Ok(count > 0)
94    }
95}