dkdc-lake 0.1.0

Data lake management for dkdc (don't know, don't care)
Documentation
use crate::Lake;
use anyhow::Result;
use dkdc_config::SECRETS_TABLE_NAME;
use duckdb::params;

impl Lake {
    pub fn create_secrets_table(&self) -> Result<()> {
        let sql = format!(
            "CREATE TABLE IF NOT EXISTS {} (
                filepath VARCHAR,
                filename VARCHAR,
                filedata BLOB,
                filesize BIGINT,
                fileupdated TIMESTAMP
            )",
            SECRETS_TABLE_NAME
        );
        self.execute(&sql)?;
        Ok(())
    }

    pub fn set_secret(&self, name: &str, value: &[u8]) -> Result<()> {
        self.create_secrets_table()?;

        let sql = format!(
            "INSERT INTO {} (filepath, filename, filedata, filesize, fileupdated)
             VALUES (?, ?, ?, ?, ?)",
            SECRETS_TABLE_NAME
        );

        let mut stmt = self.prepare(&sql)?;
        use chrono::Utc;
        stmt.execute(params![
            "./secrets",
            name,
            value,
            value.len() as i64,
            Utc::now().to_rfc3339(),
        ])?;

        Ok(())
    }

    pub fn get_secret(&self, name: &str) -> Result<Option<Vec<u8>>> {
        let sql = format!(
            "SELECT filedata
             FROM {}
             WHERE filepath = './secrets' AND filename = ?
             ORDER BY fileupdated DESC
             LIMIT 1",
            SECRETS_TABLE_NAME
        );

        let mut stmt = self.prepare(&sql)?;
        let mut rows = stmt.query(params![name])?;

        if let Some(row) = rows.next()? {
            Ok(Some(row.get(0)?))
        } else {
            Ok(None)
        }
    }

    pub fn list_secrets(&self) -> Result<Vec<String>> {
        let sql = format!(
            "SELECT DISTINCT filename
             FROM {}
             WHERE filepath = './secrets'
             ORDER BY filename",
            SECRETS_TABLE_NAME
        );

        let mut stmt = self.prepare(&sql)?;
        let mut rows = stmt.query([])?;

        let mut secrets = Vec::new();
        while let Some(row) = rows.next()? {
            secrets.push(row.get(0)?);
        }

        Ok(secrets)
    }

    pub fn delete_secret(&self, name: &str) -> Result<bool> {
        let sql = format!(
            "DELETE FROM {} WHERE filepath = './secrets' AND filename = ?",
            SECRETS_TABLE_NAME
        );

        let mut stmt = self.prepare(&sql)?;
        let count = stmt.execute(params![name])?;

        Ok(count > 0)
    }
}