From 686a7b9ebb2cb7b5748a6fc343047fecd50ef694 Mon Sep 17 00:00:00 2001 From: Sander Hautvast Date: Fri, 28 Oct 2022 15:42:53 +0200 Subject: [PATCH] added rootpage stuff --- src/database.rs | 59 +++++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 4 +--- src/page.rs | 33 ++++++++++++++------------- src/values.rs | 2 +- 4 files changed, 77 insertions(+), 21 deletions(-) diff --git a/src/database.rs b/src/database.rs index e69de29..12ef7b5 100644 --- a/src/database.rs +++ b/src/database.rs @@ -0,0 +1,59 @@ +use crate::page::Page; + + +fn write_header(mut rootpage: Page, n_pages: u32) { + rootpage.put_u8a(&MAGIC_HEADER); + rootpage.put_u16(DEFAULT_PAGE_SIZE); + rootpage.put_u8(FILE_FORMAT_WRITE_VERSION); + rootpage.put_u8(FILE_FORMAT_READ_VERSION); + rootpage.put_u8(RESERVED_SIZE); + rootpage.put_u8(MAX_EMBED_PAYLOAD_FRACTION); + rootpage.put_u8(MIN_EMBED_PAYLOAD_FRACTION); + rootpage.put_u8(LEAF_PAYLOAD_FRACTION); + rootpage.put_u32(FILECHANGE_COUNTER); + rootpage.put_u32(n_pages);// file size in pages + rootpage.put_u32(FREELIST_TRUNK_PAGE_HUMBER);// Page number of the first freelist trunk page. + rootpage.put_u32(TOTAL_N_FREELIST_PAGES); + rootpage.put_u32(SCHEMA_COOKIE); + rootpage.put_u32(SQLITE_SCHEMAVERSION); + rootpage.put_u32(SUGGESTED_CACHESIZE); + rootpage.put_u32(LARGEST_ROOT_BTREE_PAGE); + rootpage.put_u32(ENCODING_UTF8); + rootpage.put_u32(USER_VERSION); + rootpage.put_u32(VACUUM_MODE_OFF);// True (non-zero) for incremental-vacuum mode. False (zero) otherwise. + rootpage.put_u32(APP_ID);// Application ID + rootpage.put_u8a(&FILLER);// Reserved for expansion. Must be zero. + rootpage.put_u8a(&VERSION_VALID_FOR);// The version-valid-for number + rootpage.put_u8a(&SQLITE_VERSION);// SQLITE_VERSION_NUMBER + rootpage.put_u8(TABLE_LEAF_PAGE); // leaf table b-tree page for schema + rootpage.put_u16(NO_FREE_BLOCKS); // zero if there are no freeblocks + rootpage.put_u16(1); // the number of cells on this page +} + +const MAGIC_HEADER: [u8; 16] = [0x53, 0x51, 0x4c, 0x69, 0x74, 0x65, 0x20, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x20, 0x33, 0x00]; +pub const DEFAULT_PAGE_SIZE: u16 = 4096; +const FILE_FORMAT_WRITE_VERSION: u8 = 1; +const FILE_FORMAT_READ_VERSION: u8 = 1; +const RESERVED_SIZE: u8 = 0; +const MAX_EMBED_PAYLOAD_FRACTION: u8 = 0x40; +const MIN_EMBED_PAYLOAD_FRACTION: u8 = 0x20; +const LEAF_PAYLOAD_FRACTION: u8 = 0x20; +const FILECHANGE_COUNTER: u32 = 1; +const FREELIST_TRUNK_PAGE_HUMBER: u32 = 0; +const TOTAL_N_FREELIST_PAGES: u32 = 0; +const SCHEMA_COOKIE: u32 = 1; +const SQLITE_SCHEMAVERSION: u32 = 4; +const SUGGESTED_CACHESIZE: u32 = 0; +const LARGEST_ROOT_BTREE_PAGE: u32 = 0; +const ENCODING_UTF8: u32 = 1; +const USER_VERSION: u32 = 0; +const VACUUM_MODE_OFF: u32 = 0; +const APP_ID: u32 = 0; +const FILLER: [u8; 20] = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]; +const VERSION_VALID_FOR: [u8; 4] = [0, 0, 0x03, 250]; +const SQLITE_VERSION: [u8; 4] = [0x00, 0x2e, 0x5F, 0x1A]; +const NO_FREE_BLOCKS: u16 = 0; +pub const TABLE_LEAF_PAGE: u8 = 0x0d; +pub const TABLE_INTERIOR_PAGE: u8 = 0x05; +const INDEX_LEAF_PAGE: u8 = 0x0a; +const INDEX_INTERIOR_PAGE: u8 = 0x02; \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index a5e1935..5b0ccc0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,9 +5,7 @@ mod values; mod varint; mod record; -const DEFAULT_PAGE_SIZE: usize = 4096; -const TABLE_INTERIOR_PAGE: u8 = 0x05; -const TABLE_LEAF_PAGE: u8 = 0x0D; + #[cfg(test)] mod tests { diff --git a/src/page.rs b/src/page.rs index 4d76b14..b2f5a7b 100644 --- a/src/page.rs +++ b/src/page.rs @@ -1,6 +1,5 @@ -use crate::{DEFAULT_PAGE_SIZE, TABLE_LEAF_PAGE}; use crate::bytebuffer::ByteBuffer; - +use crate::database; const POSITION_CELL_COUNT: u32 = 3; const START_OF_CONTENT_AREA: u32 = 5; @@ -10,7 +9,7 @@ pub enum PageType { } /// Represents an SQLite page -struct Page { +pub struct Page { data: ByteBuffer, key: i64, children: Vec, @@ -19,9 +18,9 @@ struct Page { } impl Page { - fn with_capacity(size: usize, page_type: PageType) -> Self { + fn with_capacity(size: u16, page_type: PageType) -> Self { Self { - data: ByteBuffer::new(size), + data: ByteBuffer::new(size as usize), key: 0, children: Vec::new(), number: 0, @@ -30,47 +29,47 @@ impl Page { } fn new_leaf() -> Self { - let mut page = Page::with_capacity(DEFAULT_PAGE_SIZE, PageType::Leaf); - page.put_u8(TABLE_LEAF_PAGE); + let mut page = Page::with_capacity(database::DEFAULT_PAGE_SIZE, PageType::Leaf); + page.put_u8(database::TABLE_LEAF_PAGE); page } fn new_interior() -> Self { - let mut page = Page::with_capacity(DEFAULT_PAGE_SIZE, PageType::Interior); - page.put_u8(TABLE_LEAF_PAGE); + let mut page = Page::with_capacity(database::DEFAULT_PAGE_SIZE, PageType::Interior); + page.put_u8(database::TABLE_LEAF_PAGE); page } - fn add_child(&mut self, child: Self) { + pub fn add_child(&mut self, child: Self) { self.children.push(child); } - fn fw_position(&mut self, new_position: usize) { + pub fn fw_position(&mut self, new_position: usize) { self.data.fw_position = new_position; } - fn bw_position(&mut self, new_position: usize) { + pub fn bw_position(&mut self, new_position: usize) { self.data.bw_position = new_position; } - fn put_u8a(&mut self, value: &[u8]) { + pub fn put_u8a(&mut self, value: &[u8]) { self.data.put_u8a(value); } - fn put_u8(&mut self, value: u8) { + pub fn put_u8(&mut self, value: u8) { self.data.put_u8(value); } - fn put_u16(&mut self, value: u16) { + pub fn put_u16(&mut self, value: u16) { self.data.put_u16(value); } - fn put_u32(&mut self, value: u32) { + pub fn put_u32(&mut self, value: u32) { self.data.put_u32(value); } // may panic - fn get_page_nr_last_child(self) -> u32 { + pub fn get_page_nr_last_child(self) -> u32 { self.children[self.children.len()-1].number } } \ No newline at end of file diff --git a/src/values.rs b/src/values.rs index 6b28553..204fe83 100644 --- a/src/values.rs +++ b/src/values.rs @@ -42,7 +42,7 @@ fn sqlite_integer_to_bytes(value: i64) -> Vec { if value == 0 || value == 1 { vec![] } else { - return long_to_bytes(value, get_length_of_byte_encoding(value)); + return i64_to_bytes(value, get_length_of_byte_encoding(value)); } }