1
0
Fork 0
sqlite-reader/src/main.rs

60 lines
2.0 KiB
Rust

use anyhow::{bail, Result};
use sqlite_starter_rust::{
header::PageHeader, record::parse_record, schema::Schema, varint::parse_varint,
};
use std::convert::TryInto;
use std::fs::File;
use std::io::prelude::*;
fn main() -> Result<()> {
// Parse arguments
let args = std::env::args().collect::<Vec<_>>();
match args.len() {
0 | 1 => bail!("Missing <database path> and <command>"),
2 => bail!("Missing <command>"),
_ => {}
}
// Read database file into database
let mut file = File::open(&args[1])?;
let mut database = Vec::new();
file.read_to_end(&mut database)?;
// Parse command and act accordingly
let command = &args[2];
match command.as_str() {
".dbinfo" => {
// Parse page header from database
let page_header = PageHeader::parse(&database[100..108])?;
// Obtain all cell pointers
let cell_pointers = database[108..]
.chunks_exact(2)
.take(page_header.number_of_cells.into())
.map(|bytes| u16::from_be_bytes(bytes.try_into().unwrap()))
.collect::<Vec<_>>();
// Obtain all records from column 5
#[allow(unused_variables)]
let schemas = cell_pointers
.into_iter()
.map(|cell_pointer| {
let stream = &database[cell_pointer as usize..];
let (_, offset) = parse_varint(stream);
let (_rowid, read_bytes) = parse_varint(&stream[offset..]);
parse_record(&stream[offset + read_bytes..], 5)
.map(|record| Schema::parse(record).expect("Invalid record"))
})
.collect::<Result<Vec<_>>>()?;
println!("Your code goes here!");
// Uncomment this block to pass the first stage
// println!("number of tables: {}", schemas.len());
}
_ => bail!("Missing or invalid command passed: {}", command),
}
Ok(())
}