Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

start separate database operations -- io, util, queries, etc #13

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,3 @@ tracing-test = "0.2.5"
[lib]
path = "src/lib.rs"

# [[bin]]
# name = "cargobase"
# path = "main.rs"
File renamed without changes.
7 changes: 7 additions & 0 deletions src/database_components/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
pub mod columns;
pub mod row;
pub mod table;

pub use columns::{Column, Columns};
pub use row::Row;
pub use table::Table;
File renamed without changes.
5 changes: 5 additions & 0 deletions src/table.rs → src/database_components/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ impl Table {
Ok(())
}

/*
* update this....
* automatucally convert to Value
* let _ = serde_json::to_value(&data).unwrap();
*/
fn add_multiple_rows(&mut self, rows: &[Value]) -> Result<(), String> {
for row in rows {
self.add_single_row(row.clone())?;
Expand Down
140 changes: 2 additions & 138 deletions src/database.rs → src/database_operations/core.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,7 @@
use std::collections::HashMap;
use std::path::{Path, PathBuf};

use serde::{Deserialize, Serialize};
use tracing;

use crate::{query::Operation, DatabaseError, Query, Table, View};

#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
pub struct Database {
pub(crate) name: String,
pub(crate) file_name: PathBuf,
pub(crate) tables: HashMap<String, Table>,
}
use crate::{Database, DatabaseError, Table, View};

impl Database {
pub async fn new(name: &str) -> Self {
Expand Down Expand Up @@ -90,88 +80,6 @@ impl Database {
}
}

pub(crate) async fn save_to_file(&self) -> Result<(), tokio::io::Error> {
let json_data = serde_json::to_string_pretty(&self)?;
tokio::fs::write(&self.file_name, json_data).await?;
tracing::info!("Database saved to file: {:?}", self.file_name);
Ok(())
}

pub(crate) async fn load_from_file<P: AsRef<Path>>(
file_name: P,
) -> Result<Self, tokio::io::Error> {
let json_data = tokio::fs::read_to_string(file_name.as_ref()).await?;
let db: Database = serde_json::from_str(&json_data)?;
tracing::info!(
"Database loaded from file: {:?}",
file_name.as_ref().display()
);
Ok(db)
}

pub(crate) fn get_table_mut(&mut self, table_name: &str) -> Option<&mut Table> {
tracing::debug!("looking for table: {}", table_name);
let table = self.tables.get_mut(table_name);

if let Some(_) = table {
tracing::debug!("table found: {}", table_name);
} else {
tracing::error!("table not found: {}", table_name);
}

table
}

pub fn add_row(&mut self) -> Query {
Query {
db_file_name: self.file_name.clone(),
table_name: None,
operation: Operation::Create,
update_data: None,
row_data: None,
}
}

pub fn get_rows(&self) -> Query {
Query {
db_file_name: self.file_name.clone(),
table_name: None,
operation: Operation::Read,
update_data: None,
row_data: None,
}
}

pub fn get_single(&self) -> Query {
Query {
db_file_name: self.file_name.clone(),
table_name: None,
operation: Operation::Read,
update_data: None,
row_data: None,
}
}

pub fn delete_single(&self) -> Query {
Query {
db_file_name: self.file_name.clone(),
table_name: None,
operation: Operation::Delete,
update_data: None,
row_data: None,
}
}

pub fn update_row(&self) -> Query {
Query {
db_file_name: self.file_name.clone(),
table_name: None,
operation: Operation::Update,
update_data: None,
row_data: None,
}
}

pub fn view(&self) {
let view = View::new(self);
view.all_tables();
Expand Down Expand Up @@ -230,6 +138,7 @@ impl Database {

#[cfg(test)]
mod tests {
use serde::{Deserialize, Serialize};
use serde_json::json;
use tracing_test::traced_test;

Expand Down Expand Up @@ -330,51 +239,6 @@ mod tests {
assert_eq!(db.tables.len(), 1);
}

#[tokio::test]
async fn test_save_to_file() {
use tempfile::NamedTempFile;

let temp_file = NamedTempFile::new().expect("Failed to create a temporary file");
let db_path = temp_file.path().to_path_buf();
// let db_path = temp_file.path().to_str().unwrap().to_string();

let db = Database {
name: "test_db".to_string(),
file_name: db_path.clone(),
tables: HashMap::new(),
};

db.save_to_file().await.expect("Failed to save database");
let loaded_db = Database::load_from_file(&db_path)
.await
.expect("Failed to load database");
assert_eq!(db, loaded_db);
}

#[tokio::test]
async fn test_load_from_file() {
use tempfile::NamedTempFile;

let temp_file = NamedTempFile::new().expect("Failed to create a temporary file");
let db_path = temp_file.path().to_path_buf();
// let db_path = temp_file.path().to_str().unwrap().to_string();

let db = Database {
name: "test_db".to_string(),
file_name: db_path.clone(),
// file_name: db_path.to_string(),
tables: HashMap::new(),
};

db.save_to_file().await.expect("Failed to save database");

let loaded_db = Database::load_from_file(&db_path)
.await
.expect("Failed to load database");

assert_eq!(db, loaded_db);
}

#[tokio::test]
async fn test_rename_table_success() {
let mut db = setup_temp_db().await;
Expand Down
74 changes: 74 additions & 0 deletions src/database_operations/io.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
use std::path::Path;

use crate::Database;

impl Database {
pub(crate) async fn save_to_file(&self) -> Result<(), tokio::io::Error> {
let json_data = serde_json::to_string_pretty(&self)?;
tokio::fs::write(&self.file_name, json_data).await?;
tracing::info!("Database saved to file: {:?}", self.file_name);
Ok(())
}

pub(crate) async fn load_from_file<P: AsRef<Path>>(
file_name: P,
) -> Result<Self, tokio::io::Error> {
let json_data = tokio::fs::read_to_string(file_name.as_ref()).await?;
let db: Database = serde_json::from_str(&json_data)?;
tracing::info!(
"Database loaded from file: {:?}",
file_name.as_ref().display()
);
Ok(db)
}
}

#[cfg(test)]

mod tests {

use super::*;
use std::collections::HashMap;

#[tokio::test]
async fn test_save_to_file() {
use tempfile::NamedTempFile;

let temp_file = NamedTempFile::new().expect("Failed to create a temporary file");
let db_path = temp_file.path().to_path_buf();

let db = Database {
name: "test_db".to_string(),
file_name: db_path.clone(),
tables: HashMap::new(),
};

db.save_to_file().await.expect("Failed to save database");
let loaded_db = Database::load_from_file(&db_path)
.await
.expect("Failed to load database");
assert_eq!(db, loaded_db);
}

#[tokio::test]
async fn test_load_from_file() {
use tempfile::NamedTempFile;

let temp_file = NamedTempFile::new().expect("Failed to create a temporary file");
let db_path = temp_file.path().to_path_buf();

let db = Database {
name: "test_db".to_string(),
file_name: db_path.clone(),
tables: HashMap::new(),
};

db.save_to_file().await.expect("Failed to save database");

let loaded_db = Database::load_from_file(&db_path)
.await
.expect("Failed to load database");

assert_eq!(db, loaded_db);
}
}
18 changes: 18 additions & 0 deletions src/database_operations/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
pub mod core;
pub mod io;
pub mod query;
pub mod utils;

use crate::Table;

use std::collections::HashMap;
use std::path::PathBuf;
use serde::{Deserialize, Serialize};

#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
pub struct Database {
pub(crate) name: String,
pub(crate) file_name: PathBuf,
pub(crate) tables: HashMap<String, Table>,
}

Loading
Loading