From 6ed821e4b84fe4fa11a843c5ab4fa16cbcbbe529 Mon Sep 17 00:00:00 2001 From: Jeff Baskin Date: Tue, 12 Jul 2022 16:55:20 -0400 Subject: [PATCH] Began building database engine seperate from query language. --- src/database/database.rs | 130 +++++++++++++++++++++++++++++++++++++++ src/database/mod.rs | 2 + 2 files changed, 132 insertions(+) create mode 100644 src/database/database.rs diff --git a/src/database/database.rs b/src/database/database.rs new file mode 100644 index 0000000..c6c403a --- /dev/null +++ b/src/database/database.rs @@ -0,0 +1,130 @@ +use async_std::sync::{Arc, RwLock}; +use std::{collections::HashMap, fmt, str::FromStr}; + +#[derive(Clone, PartialEq)] +pub enum Field { + Table, +} + +impl fmt::Display for Field { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Field::Table => write!(f, "table"), + } + } +} + +impl FromStr for Field { + type Err = (); + fn from_str(input: &str) -> Result { + match input { + "table" => Ok(Field::Table), + _ => Err(()), + } + } +} + +pub struct Table { + fields: Arc>>, +} + +impl Table { + pub async fn new() -> Self { + Self { + fields: Arc::new(RwLock::new(HashMap::new())), + } + } + + pub async fn add_field(&self, name: &str, ftype: &str) { + let mut fmap = self.fields.write().await; + fmap.insert(name.to_string(), Field::from_str(ftype).unwrap()); + } + + pub async fn fields(&self) -> HashMap { + let fmap = self.fields.read().await; + fmap.clone() + } +} + +pub struct Database; + +impl Database { + pub async fn new() -> Self { + Self {} + } + + pub async fn add_table(&self, _name: String) -> Table { + Table::new().await + } +} + +#[cfg(test)] +mod tables { + use super::*; + + #[async_std::test] + async fn new_table() { + Table::new().await; + } + + #[async_std::test] + async fn add_field() { + let table = Table::new().await; + let mut expected: HashMap = HashMap::new(); + expected.insert("stan".to_string(), Field::Table); + expected.insert("lee".to_string(), Field::Table); + table.add_field("stan", "table").await; + table.add_field("lee", "table").await; + let output = table.fields().await; + assert!(output == expected, "Table did not get the fields added."); + } +} + +#[cfg(test)] +mod databases { + use super::*; + + #[async_std::test] + async fn new_database() { + Database::new().await; + } + + #[async_std::test] + async fn add_table() { + let db = Database::new().await; + db.add_table("fred".to_string()).await; + } +} + +#[cfg(test)] +mod fields { + use super::*; + + fn get_field_map() -> HashMap { + let mut fields: HashMap = HashMap::new(); + fields.insert("table".to_string(), Field::Table); + return fields; + } + + #[test] + fn convert_to_string() { + for (key, value) in get_field_map().iter() { + assert!(key == &value.to_string(), "\n\nGot: {}\nWant: {}\n\n", value.to_string(), key); + } + } + + #[test] + fn convert_from_string() { + for (key, value) in get_field_map().iter() { + assert!(&Field::from_str(key).unwrap() == value, "\n\nDid not return a Field::{}", key); + } + } + + #[test] + fn convert_from_string_error() -> Result<(), String> { + match Field::from_str("jkljkl") { + Ok(_) => Err("Field jkljkl should not exist.".to_string()), + Err(_) => Ok(()), + } + } +} diff --git a/src/database/mod.rs b/src/database/mod.rs index 53e3016..67ea004 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -2,6 +2,8 @@ use async_graphql::{Context, EmptySubscription, Error, Object, Result, Schema}; use async_std::sync::RwLock; use serde_json; +mod database; + #[derive(Clone)] struct Table { name: String,