diff --git a/Cargo.lock b/Cargo.lock index ccc36ee..25ffe8c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -55,6 +55,12 @@ dependencies = [ "version_check", ] +[[package]] +name = "once_cell" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1" + [[package]] name = "peg" version = "0.7.0" @@ -124,6 +130,7 @@ dependencies = [ "anyhow", "itertools", "nom", + "once_cell", "peg", "regex", ] diff --git a/Cargo.toml b/Cargo.toml index 05b964e..8856145 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,5 +22,6 @@ edition = "2018" anyhow = "1.0.43" # for easy error handling itertools = "0.10.3" # useful iterator extensions nom = "7.0.0" # for parsing +once_cell = "1.13.0" peg = "0.7.0" # for parsing -regex = "1.5.4" # for parsing +regex = "1.5.4" diff --git a/src/main.rs b/src/main.rs index 8ee684c..8f38d0c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,6 @@ use anyhow::{bail, Error, Result}; +use once_cell::sync::Lazy; +use regex::{Regex, RegexBuilder}; use sqlite_starter_rust::{ header::PageHeader, record::parse_record, schema::Schema, varint::parse_varint, }; @@ -7,6 +9,15 @@ use std::convert::TryInto; use std::fs::File; use std::io::prelude::*; +const QUERY_REGEX: Lazy = Lazy::new(|| { + let regex = "select ([a-zA-Z0-9*].*) FROM ([a-zA-Z0-9].*)"; + + RegexBuilder::new(regex) + .case_insensitive(true) + .build() + .expect("error in compiling regex") +}); + fn main() -> Result<()> { // Parse arguments let args = std::env::args().collect::>(); @@ -128,9 +139,19 @@ fn read_columns(query: &str, db_header: DBHeader, database: &[u8]) -> Result<(), }); for row in rows { - let cpos = *column_map.get(&columns[0]).unwrap(); + let mut output = String::new(); - println!("{}", String::from_utf8_lossy(&row[cpos])); + for column in columns.iter() { + let cpos = *column_map.get(column).unwrap(); + let s = String::from_utf8_lossy(&row[cpos]); + + output.push_str(&s); + output.push('|'); + } + + let output = output.trim_end_matches(|c| c == '|'); + + println!("{}", output); } Ok(()) @@ -189,6 +210,7 @@ fn count_rows_in_table(query: &str, db_header: DBHeader, database: &[u8]) -> Res Ok(()) } + fn find_column_positions(schema: &str) -> HashMap<&str, usize> { let schema = schema.trim_start_matches(|c| c != '('); let schema = schema @@ -205,16 +227,16 @@ fn find_column_positions(schema: &str) -> HashMap<&str, usize> { } fn read_column_and_table(query: &str) -> (Vec<&str>, &str) { - let mut query = query.split(' '); - query.next(); - let column = query.next().unwrap(); - let column = column + let matches = QUERY_REGEX.captures(query).unwrap(); + + let columns = matches.get(1).unwrap().as_str(); + let table = matches.get(2).unwrap().as_str(); + + let column = columns .split(',') .filter(|c| !c.is_empty()) .map(|c| c.trim()) .collect(); - query.next(); - let table = query.next().unwrap(); (column, table) }