we_trust_sqlite/writer/
mod.rs1use yykv_types::DsError;
2type Result<T> = std::result::Result<T, DsError>;
3use crate::utils::parse_varint;
4use tokio::fs::{File, OpenOptions};
5use tokio::io::{AsyncReadExt, AsyncSeekExt, AsyncWriteExt, SeekFrom};
6
7mod btree;
8mod pager;
9mod payload;
10mod wal;
11
12pub use wal::WalWriter;
13
14pub struct NativeWriter {
16 path: String,
17}
18
19impl NativeWriter {
20 pub fn new(path: impl Into<String>) -> Self {
21 Self { path: path.into() }
22 }
23
24 pub async fn ensure_initialized(&self) -> Result<()> {
26 if tokio::fs::metadata(&self.path).await.is_ok() {
27 return Ok(());
28 }
29
30 let mut file = OpenOptions::new()
31 .create(true)
32 .write(true)
33 .open(&self.path)
34 .await
35 .map_err(|e| DsError::io(format!("Failed to create database file: {}", e)))?;
36
37 let page_size: u32 = 4096;
38 let mut header = vec![0u8; page_size as usize];
39
40 header[0..16].copy_from_slice(b"SQLite format 3\0");
42
43 header[16..18].copy_from_slice(&(page_size as u16).to_be_bytes());
45
46 header[18] = 1;
48 header[19] = 1;
50
51 header[20] = 0;
53
54 header[21] = 64;
56 header[22] = 32;
58 header[23] = 32;
60
61 header[24..28].copy_from_slice(&1u32.to_be_bytes());
63
64 header[28..32].copy_from_slice(&1u32.to_be_bytes());
66
67 header[32..36].copy_from_slice(&0u32.to_be_bytes());
69 header[36..40].copy_from_slice(&0u32.to_be_bytes());
71
72 header[40..44].copy_from_slice(&1u32.to_be_bytes());
74 header[44..48].copy_from_slice(&4u32.to_be_bytes());
76
77 header[48..52].copy_from_slice(&0u32.to_be_bytes());
79
80 header[52..56].copy_from_slice(&0u32.to_be_bytes());
82
83 header[56..60].copy_from_slice(&1u32.to_be_bytes());
85
86 header[60..64].copy_from_slice(&0u32.to_be_bytes());
88
89 header[64..68].copy_from_slice(&0u32.to_be_bytes());
91
92 header[68..72].copy_from_slice(&0u32.to_be_bytes());
94
95 header[92..96].copy_from_slice(&1u32.to_be_bytes());
100
101 header[96..100].copy_from_slice(&3034000u32.to_be_bytes());
103
104 header[100] = 0x0D;
107 header[105] = (page_size >> 8) as u8;
109 header[106] = (page_size & 0xFF) as u8;
110
111 file.write_all(&header)
112 .await
113 .map_err(|e| DsError::io(format!("Failed to write database header: {}", e)))?;
114
115 Ok(())
116 }
117}