1use crate::Lake;
2use anyhow::Result;
3use dkdc_config::ARCHIVES_TABLE_NAME;
4use duckdb::params;
5
6impl Lake {
7 pub fn create_archives_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 ARCHIVES_TABLE_NAME
17 );
18 self.execute(&sql)?;
19 Ok(())
20 }
21
22 pub fn add_archive(&self, name: &str, data: &[u8]) -> Result<()> {
23 self.create_archives_table()?;
24
25 let sql = format!(
26 "INSERT INTO {} (filepath, filename, filedata, filesize, fileupdated)
27 VALUES (?, ?, ?, ?, ?)",
28 ARCHIVES_TABLE_NAME
29 );
30
31 let mut stmt = self.prepare(&sql)?;
32 use chrono::Utc;
33 stmt.execute(params![
34 "./archives",
35 name,
36 data,
37 data.len() as i64,
38 Utc::now().to_rfc3339(),
39 ])?;
40
41 Ok(())
42 }
43
44 pub fn get_archive(&self, name: &str) -> Result<Option<Vec<u8>>> {
45 let sql = format!(
46 "SELECT filedata
47 FROM {}
48 WHERE filepath = './archives' AND filename = ?
49 ORDER BY fileupdated DESC
50 LIMIT 1",
51 ARCHIVES_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_archives(&self) -> Result<Vec<String>> {
65 let sql = format!(
66 "SELECT DISTINCT filename
67 FROM {}
68 WHERE filepath = './archives'
69 ORDER BY filename",
70 ARCHIVES_TABLE_NAME
71 );
72
73 let mut stmt = self.prepare(&sql)?;
74 let mut rows = stmt.query([])?;
75
76 let mut archives = Vec::new();
77 while let Some(row) = rows.next()? {
78 archives.push(row.get(0)?);
79 }
80
81 Ok(archives)
82 }
83}