sqlighters/
builder.rs

1use crate::database::SchemaRecord;
2use crate::page::{self, Page};
3use crate::record::Record;
4use std::mem;
5
6pub struct DatabaseBuilder {
7    pub current_page: Page,
8    pub n_records_on_current_page: u16,
9    pub leaf_pages: Vec<Page>,
10    pub schema: Option<SchemaRecord>,
11}
12
13fn new_page() -> Page {
14    let mut page = Page::new_leaf();
15    page.fw_position = 8;
16    page
17}
18
19impl DatabaseBuilder {
20    pub fn new() -> Self {
21        Self {
22            current_page: new_page(),
23            n_records_on_current_page: 0,
24            leaf_pages: Vec::new(),
25            schema: None,
26        }
27    }
28
29    pub fn add_record(&mut self, record: Record) {
30        if self.current_page_is_full(&record) {
31            self.finish_current_page();
32            self.leaf_pages
33                .push(mem::replace(&mut self.current_page, new_page()));
34            self.n_records_on_current_page = 0;
35        }
36
37        self.current_page.key = record.rowid; //clone?
38        let bytes: Vec<u8> = record.into();
39        self.current_page.put_bytes_bw(&bytes);
40        self.current_page.put_u16(self.current_page.bw_position);
41        self.n_records_on_current_page += 1;
42    }
43
44    pub fn schema(&mut self, table_name: &str, sql: &str) {
45        self.schema = Some(SchemaRecord::new(1, table_name, 2, sql));
46    }
47
48    fn current_page_is_full(&self, record: &Record) -> bool {
49        self.current_page.bw_position - record.bytes_len() <= self.current_page.fw_position + 5
50    }
51
52    fn finish_current_page(&mut self) {
53        self.current_page.fw_position = page::POSITION_CELL_COUNT;
54        self.current_page.put_u16(self.n_records_on_current_page);
55        self.current_page.put_u16(self.current_page.bw_position);
56    }
57}