1use anyhow::Result;
14use dkdc_config::{Config, DUCKLAKE_EXTENSION, SQLITE_EXTENSION};
15use duckdb::{Connection, Statement};
16
17pub mod archives;
18pub mod files;
19pub mod secrets;
20
21pub struct Lake {
23 connection: Connection,
24 config: Config,
25}
26
27impl Lake {
28 pub fn new() -> Result<Self> {
30 let config = Config::new()?;
31 Self::with_config(config)
32 }
33
34 pub fn with_config(config: Config) -> Result<Self> {
36 config.ensure_metadata_db()?;
37
38 let connection = Connection::open_in_memory()?;
39
40 connection.execute_batch(&format!("INSTALL {};", DUCKLAKE_EXTENSION))?;
41 connection.execute_batch(&format!("INSTALL {};", SQLITE_EXTENSION))?;
42
43 let metadata_path = config.metadata_path();
44 let data_path = config.data_path();
45
46 connection.execute_batch(&format!(
47 "ATTACH '{}' AS metadata;",
48 metadata_path.display()
49 ))?;
50
51 connection.execute_batch(&format!(
52 "ATTACH 'ducklake:sqlite:{}' AS data (DATA_PATH '{}', ENCRYPTED);",
53 metadata_path.display(),
54 data_path.display()
55 ))?;
56
57 connection.execute_batch("USE data;")?;
58
59 Ok(Self { connection, config })
60 }
61
62 pub fn connection(&self) -> &Connection {
63 &self.connection
64 }
65
66 pub fn config(&self) -> &Config {
67 &self.config
68 }
69
70 pub fn execute(&self, sql: &str) -> Result<()> {
71 self.connection.execute_batch(sql)?;
72 Ok(())
73 }
74
75 pub fn prepare(&self, sql: &str) -> Result<Statement> {
76 Ok(self.connection.prepare(sql)?)
77 }
78
79 pub fn get_sql_commands(&self) -> String {
80 let metadata_path = self.config.metadata_path();
81 let data_path = self.config.data_path();
82
83 format!(
84 r#"INSTALL {};
85INSTALL {};
86
87ATTACH '{}' AS metadata;
88ATTACH 'ducklake:sqlite:{}' AS data (DATA_PATH '{}', ENCRYPTED);
89
90USE data;"#,
91 DUCKLAKE_EXTENSION,
92 SQLITE_EXTENSION,
93 metadata_path.display(),
94 metadata_path.display(),
95 data_path.display()
96 )
97 }
98}
99
100#[cfg(test)]
101mod tests {
102 use super::*;
103
104 #[test]
105 fn test_lake_creation() {
106 let lake = Lake::new();
107 assert!(lake.is_ok());
108 }
109}