sqlite_rs/pager/
mod.rs

1pub mod page;
2
3use std::num::NonZeroU32;
4
5use crate::{
6  header::{
7    FileFormatReadVersion, FileFormatWriteVersion, MagicHeaderString, PageSize,
8    ReservedBytesPerPage,
9  },
10  io::SqliteIo,
11  result::{SqliteError, SqliteResult},
12  traits::ParseBytes,
13};
14
15use self::page::Page;
16
17#[derive(Debug)]
18pub struct SqlitePager {
19  io: SqliteIo,
20  page_size: PageSize,
21  reserved_bytes_per_page: ReservedBytesPerPage,
22  // cur_page_number: usize,
23  // btree_page_header: BtreePageHeader,
24}
25
26impl SqlitePager {
27  pub fn connect(mut io: SqliteIo) -> SqliteResult<Self> {
28    io.rewind()?;
29    const BYTES_TO_READ: usize = MagicHeaderString::LENGTH_BYTES
30      + PageSize::LENGTH_BYTES
31      + FileFormatWriteVersion::LENGTH_BYTES
32      + FileFormatReadVersion::LENGTH_BYTES
33      + ReservedBytesPerPage::LENGTH_BYTES;
34    let mut buf = [0u8; BYTES_TO_READ];
35
36    let bytes_read = io.read(&mut buf)?;
37    trace!("[{bytes_read}] Bytes read from [{}]", io.mode());
38    let pager = if bytes_read > 0 {
39      Self {
40        io,
41        page_size: PageSize::parse_bytes(&buf[16..=17])?,
42        reserved_bytes_per_page: ReservedBytesPerPage::parse_bytes(&[buf[20]])?,
43      }
44    } else {
45      Self {
46        io,
47        page_size: PageSize::default(),
48        reserved_bytes_per_page: ReservedBytesPerPage::default(),
49      }
50    };
51    Ok(pager)
52  }
53  pub fn first(&mut self) -> SqliteResult<Page> {
54    self.read(1)
55  }
56
57  pub fn read(&mut self, page_number: u32) -> SqliteResult<Page> {
58    if self.io.is_empty()? {
59      return Err(SqliteError::EmptyDb);
60    }
61    let page_number = NonZeroU32::new(page_number)
62      .ok_or(SqliteError::Custom("page number can't be zero `0`.".into()))?
63      .get();
64    let page_size = self.page_size().clone();
65    let offset_from_start = (page_number - 1) * u32::from(&page_size);
66    // dbg!(&offset_from_start);
67    self.io.seek(offset_from_start.into())?;
68
69    match page_size {
70      PageSize::L512 => {
71        const BUF_SIZE: usize = 512;
72        let mut buf: [u8; BUF_SIZE] = [0; BUF_SIZE];
73        // TODO: Write tests
74        self.io.read(&mut buf)?;
75
76        Ok(Page {
77          length: page_size,
78          raw_data: buf.to_vec(),
79        })
80      }
81      PageSize::L1024 => {
82        const BUF_SIZE: usize = 1024;
83        let mut buf: [u8; BUF_SIZE] = [0; BUF_SIZE];
84        self.io.read(&mut buf)?;
85
86        Ok(Page {
87          length: page_size,
88          raw_data: buf.to_vec(),
89        })
90      }
91      PageSize::L2048 => {
92        const BUF_SIZE: usize = 2048;
93        let mut buf: [u8; BUF_SIZE] = [0; BUF_SIZE];
94        self.io.read(&mut buf)?;
95
96        Ok(Page {
97          length: page_size,
98          raw_data: buf.to_vec(),
99        })
100      }
101      PageSize::L4096 => {
102        const BUF_SIZE: usize = 4096;
103        let mut buf: [u8; BUF_SIZE] = [0; BUF_SIZE];
104        self.io.read(&mut buf)?;
105
106        Ok(Page {
107          length: page_size,
108          raw_data: buf.to_vec(),
109        })
110      }
111      PageSize::L8192 => {
112        const BUF_SIZE: usize = 8192;
113        let mut buf: [u8; BUF_SIZE] = [0; BUF_SIZE];
114        self.io.read(&mut buf)?;
115
116        Ok(Page {
117          length: page_size,
118          raw_data: buf.to_vec(),
119        })
120      }
121      PageSize::L16384 => {
122        const BUF_SIZE: usize = 16384;
123        let mut buf: [u8; BUF_SIZE] = [0; BUF_SIZE];
124        self.io.read(&mut buf)?;
125
126        Ok(Page {
127          length: page_size,
128          raw_data: buf.to_vec(),
129        })
130      }
131      PageSize::L32768 => {
132        const BUF_SIZE: usize = 32768;
133        let mut buf: [u8; BUF_SIZE] = [0; BUF_SIZE];
134        self.io.read(&mut buf)?;
135        let mut final_buffer = [0u8; Page::MAX_LENGTH];
136        for (idx, byte) in buf.iter().enumerate() {
137          final_buffer[idx] = *byte;
138        }
139        Ok(Page {
140          length: page_size,
141          raw_data: buf.to_vec(),
142        })
143      }
144      PageSize::L65536 => {
145        const BUF_SIZE: usize = 65536;
146        let mut buf: [u8; BUF_SIZE] = [0; BUF_SIZE];
147        self.io.read(&mut buf)?;
148        let mut final_buffer = [0u8; Page::MAX_LENGTH];
149        for (idx, byte) in buf.iter().enumerate() {
150          final_buffer[idx] = *byte;
151        }
152        Ok(Page {
153          length: page_size,
154          raw_data: buf.to_vec(),
155        })
156      }
157    }
158  }
159
160  pub fn page_size(&self) -> &PageSize {
161    &self.page_size
162  }
163
164  pub fn reserved_bytes_per_page(&self) -> &ReservedBytesPerPage {
165    &self.reserved_bytes_per_page
166  }
167
168  pub fn io(&self) -> &SqliteIo {
169    &self.io
170  }
171
172  pub fn io_mut(&mut self) -> &mut SqliteIo {
173    &mut self.io
174  }
175}