mirror of
https://github.com/eliasrenman/r-database.git
synced 2026-03-16 20:46:08 +01:00
feat: added database struct and tests
This commit is contained in:
@@ -1,3 +1,73 @@
|
|||||||
|
use std::{collections::HashMap, fs};
|
||||||
|
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use self::table::Table;
|
||||||
|
|
||||||
pub mod index;
|
pub mod index;
|
||||||
|
pub mod row;
|
||||||
pub mod table;
|
pub mod table;
|
||||||
pub mod row;
|
|
||||||
|
#[derive(Serialize, Deserialize)]
|
||||||
|
pub struct Database {
|
||||||
|
tables: HashMap<String, Table>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Database {
|
||||||
|
pub fn new(tables: HashMap<String, Table>) -> Database {
|
||||||
|
Database { tables: tables }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_file(file_path: String) -> Result<Database, &'static str> {
|
||||||
|
let serialized = fs::read_to_string(file_path);
|
||||||
|
if serialized.is_err() {
|
||||||
|
return Err("Failed loading from file");
|
||||||
|
}
|
||||||
|
let database: Database = serde_json::from_str(&serialized.unwrap()).unwrap();
|
||||||
|
return Ok(database);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_file(&self, file_path: &'static str) {
|
||||||
|
let serialized = serde_json::to_string(self).unwrap();
|
||||||
|
println!("serialized = {}", serialized);
|
||||||
|
let result = fs::write(file_path, serialized);
|
||||||
|
if result.is_err() {
|
||||||
|
panic!("Failed writing table to file")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use crate::database::{row::Row, table::Table, Database};
|
||||||
|
use std::{fs, path::Path};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_write_and_read_to_file() {
|
||||||
|
let mut table: Table = Table::new("Cats", "id");
|
||||||
|
table.insert_row(Row::new(hashmapJson!["id" => 1, "name" => "Ozzy"]));
|
||||||
|
table.insert_row(Row::new(hashmapJson!["id" => 2, "name" => "Simon"]));
|
||||||
|
let database = Database::new(hashmap!["Cats" => table]);
|
||||||
|
|
||||||
|
database.to_file("./db.json");
|
||||||
|
|
||||||
|
let exists = Path::try_exists(Path::new("./db.json"));
|
||||||
|
assert_eq!(exists.unwrap(), true);
|
||||||
|
|
||||||
|
let table = Database::from_file("./db.json".to_owned());
|
||||||
|
assert_eq!(table.is_ok(), true);
|
||||||
|
|
||||||
|
let db = table.unwrap();
|
||||||
|
let table = db.tables.get("Cats");
|
||||||
|
if table.is_none() {
|
||||||
|
panic!("Unable to find table");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
let row = table.unwrap().find_by_pk(&1u64);
|
||||||
|
assert_eq!(row.is_ok(), true);
|
||||||
|
|
||||||
|
// Cleanup file
|
||||||
|
let _result = fs::remove_file("./db.json");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -18,26 +18,6 @@ impl Table {
|
|||||||
Table { indexes: vec![], rows: HashMap::new(), name: name.to_string(), pk_key: pk_key.to_string() }
|
Table { indexes: vec![], rows: HashMap::new(), name: name.to_string(), pk_key: pk_key.to_string() }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_file(file_path: String) -> Result<Table, &'static str> {
|
|
||||||
let serialized = fs::read_to_string(file_path);
|
|
||||||
if serialized.is_err() {
|
|
||||||
return Err("Failed loading from file");
|
|
||||||
}
|
|
||||||
let table: Table = serde_json::from_str(&serialized.unwrap()).unwrap();
|
|
||||||
return Ok(table);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn to_file(&self, file_path: &'static str) {
|
|
||||||
|
|
||||||
let serialized = serde_json::to_string(self).unwrap();
|
|
||||||
println!("serialized = {}", serialized);
|
|
||||||
let result = fs::write(file_path, serialized);
|
|
||||||
if result.is_err() {
|
|
||||||
panic!("Failed writing table to file")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pub fn create_index(&mut self, index: Index) {
|
pub fn create_index(&mut self, index: Index) {
|
||||||
// TODO: Add row indexes to the index itself before pushing to the table
|
// TODO: Add row indexes to the index itself before pushing to the table
|
||||||
self.indexes.push(index)
|
self.indexes.push(index)
|
||||||
|
|||||||
10
src/main.rs
10
src/main.rs
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
macro_rules! hashmap {
|
macro_rules! hashmapJson {
|
||||||
($( $key: expr => $val: expr ),*) => {{
|
($( $key: expr => $val: expr ),*) => {{
|
||||||
let mut map: ::std::collections::HashMap<String, ::serde_json::Value> = ::std::collections::HashMap::new();
|
let mut map: ::std::collections::HashMap<String, ::serde_json::Value> = ::std::collections::HashMap::new();
|
||||||
$( map.insert($key.to_string(), serde_json::to_value($val).unwrap()); )*
|
$( map.insert($key.to_string(), serde_json::to_value($val).unwrap()); )*
|
||||||
@@ -7,6 +7,14 @@ macro_rules! hashmap {
|
|||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! hashmap {
|
||||||
|
($( $key: expr => $val: expr ),*) => {{
|
||||||
|
let mut map = ::std::collections::HashMap::new();
|
||||||
|
$( map.insert($key.to_string(), $val ))*;
|
||||||
|
map
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
mod database;
|
mod database;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::{fs, path::Path};
|
|
||||||
|
|
||||||
use crate::database::{table::Table, row::Row};
|
use crate::database::{table::Table, row::Row};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn should_find_two_rows() {
|
fn should_find_two_rows() {
|
||||||
let mut table: Table = Table::new("Cats", "id");
|
let mut table: Table = Table::new("Cats", "id");
|
||||||
table.insert_row(Row::new(hashmap!["id" => 1, "name" => "Ozzy"]));
|
table.insert_row(Row::new(hashmapJson!["id" => 1, "name" => "Ozzy"]));
|
||||||
table.insert_row(Row::new(hashmap!["id" => 2, "name" => "Simon"]));
|
table.insert_row(Row::new(hashmapJson!["id" => 2, "name" => "Simon"]));
|
||||||
|
|
||||||
let row = table.find_by_pk(&1u64);
|
let row = table.find_by_pk(&1u64);
|
||||||
assert_eq!(row.is_err(), false);
|
assert_eq!(row.is_err(), false);
|
||||||
@@ -24,32 +23,12 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn should_fail_to_find_row() {
|
fn should_fail_to_find_row() {
|
||||||
let mut table: Table = Table::new("Cats", "id");
|
let mut table: Table = Table::new("Cats", "id");
|
||||||
table.insert_row(Row::new(hashmap!["id" => 1, "name" => "Ozzy"]));
|
table.insert_row(Row::new(hashmapJson!["id" => 1, "name" => "Ozzy"]));
|
||||||
table.insert_row(Row::new(hashmap!["id" => 2, "name" => "Simon"]));
|
table.insert_row(Row::new(hashmapJson!["id" => 2, "name" => "Simon"]));
|
||||||
|
|
||||||
let row = table.find_by_pk(&3u64);
|
let row = table.find_by_pk(&3u64);
|
||||||
assert_eq!(row.is_err(), true);
|
assert_eq!(row.is_err(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn should_write_and_read_to_file() {
|
|
||||||
let mut table: Table = Table::new("Cats", "id");
|
|
||||||
table.insert_row(Row::new(hashmap!["id" => 1, "name" => "Ozzy"]));
|
|
||||||
table.insert_row(Row::new(hashmap!["id" => 2, "name" => "Simon"]));
|
|
||||||
table.to_file("./db.json");
|
|
||||||
|
|
||||||
let exists = Path::try_exists(Path::new("./db.json"));
|
|
||||||
assert_eq!(exists.unwrap(), true);
|
|
||||||
|
|
||||||
let table = Table::from_file("./db.json".to_owned());
|
|
||||||
assert_eq!(table.is_ok(), true);
|
|
||||||
|
|
||||||
let binding = table.unwrap();
|
|
||||||
let row = binding.find_by_pk(&1u64);
|
|
||||||
assert_eq!(row.is_ok(), true);
|
|
||||||
|
|
||||||
// Cleanup file
|
|
||||||
fs::remove_file("./db.json");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user