diff --git a/.gitignore b/.gitignore index f97c79a..ffde888 100644 --- a/.gitignore +++ b/.gitignore @@ -13,16 +13,16 @@ Cargo.lock # MSVC Windows builds of rustc generate these, which store debugging information *.pdb -# RustRover -# JetBrains specific template is maintained in a separate JetBrains.gitignore that can -# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore -# and can be added to the global gitignore or merged into this file. For a more nuclear -# option (not recommended) you can uncomment the following to ignore the entire idea folder. -#.idea/ cargobase.json -test.json +cargobase-async.json -src/main.rs +src/cargobase/cargobase.json +src/cargobase-async/cargobase-async.json + +src/cargobase/main.rs +src/cargobase-async/main.rs .env + +_deprecated diff --git a/Cargo.toml b/Cargo.toml index dd5b32f..2bcfbb2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,20 +8,20 @@ members = [ # version = "0.1.1" # edition = "2021" # -# [dependencies] -# serde = { version = "1.0.215", features = ["derive"] } -# serde_json = { version = "1.0.132", features = ["raw_value"] } -# serde_derive = "1.0.188" -# base64 = "0.22.1" +[workspace.dependencies] +serde = { version = "1.0.215", features = ["derive"] } +serde_json = { version = "1.0.132", features = ["raw_value"] } +serde_derive = "1.0.188" +base64 = "0.22.1" # tokio = { version = "1", features = ["full"], optional = true} -# uuid = {version ="1.11.0", features = ["v4"] } -# thiserror = "2.0.3" -# tempfile = "3.14.0" -# serde-reflection = "0.4.0" -# tracing = "0.1" -# tracing-subscriber = "0.3" -# tracing-test = "0.2.5" -# +uuid = {version ="1.11.0", features = ["v4"] } +thiserror = "2.0.3" +tempfile = "3.14.0" +serde-reflection = "0.4.0" +tracing = "0.1" +tracing-subscriber = "0.3" +tracing-test = "0.2.5" + # [features] # default = ["sync", "async"] # for development # # default = ["sync"] diff --git a/cargobase-async/Cargo.toml b/cargobase-async/Cargo.toml new file mode 100644 index 0000000..ac6865d --- /dev/null +++ b/cargobase-async/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "cargobase-async" +version = "0.1.0" +edition = "2021" + +[dependencies] +cargobase = { path = "../cargobase" } # Dependency on the core crate +tokio = { version = "1", features = ["full"] } +async-trait = "0.1" + +# Optional: Features specific to async crate +[features] +default = [] + diff --git a/cargobase-async/src/lib.rs b/cargobase-async/src/lib.rs new file mode 100644 index 0000000..e69de29 diff --git a/cargobase/Cargo.toml b/cargobase/Cargo.toml new file mode 100644 index 0000000..203171b --- /dev/null +++ b/cargobase/Cargo.toml @@ -0,0 +1,32 @@ +[package] +name = "cargobase" +version = "0.1.1" +edition = "2021" + +[dependencies] +serde = { workspace = true } +serde_json = { workspace = true } +serde_derive = { workspace = true } +uuid = { workspace = true } +thiserror = { workspace = true } +tempfile = { workspace = true } +serde-reflection = { workspace = true } +tracing = { workspace = true } +tracing-subscriber = { workspace = true } +tracing-test = { workspace = true } +# serde = { version = "1.0.215", features = ["derive"] } +# serde_json = { version = "1.0.132", features = ["raw_value"] } +# serde_derive = "1.0.188" +# # base64 = "0.22.1" +# # tokio = { version = "1", features = ["full"], optional = true} +# uuid = {version ="1.11.0", features = ["v4"] } +# thiserror = "2.0.3" +# tempfile = "3.14.0" +# serde-reflection = "0.4.0" +# tracing = "0.1" +# tracing-subscriber = "0.3" +# tracing-test = "0.2.5" + +[features] +default = ["sync"] +sync = [] diff --git a/src/cargobase/columns.rs b/cargobase/src/cargobase/columns.rs similarity index 100% rename from src/cargobase/columns.rs rename to cargobase/src/cargobase/columns.rs diff --git a/src/cargobase/database.rs b/cargobase/src/cargobase/database.rs similarity index 68% rename from src/cargobase/database.rs rename to cargobase/src/cargobase/database.rs index b6f8dd0..1d48e7b 100644 --- a/src/cargobase/database.rs +++ b/cargobase/src/cargobase/database.rs @@ -41,35 +41,35 @@ impl Database { } } - #[cfg(feature = "async")] - pub async fn new_async(name: &str) -> Self { - let name = name.to_string(); - let file_name = format!("{name}.json"); - - if tokio::fs::metadata(&file_name).await.is_ok() { - tracing::info!("Database already exists: {name}, loading database"); - - // Load the database from the file - match Database::load_from_file_async(&file_name).await { - Ok(db) => return db, - Err(e) => { - tracing::error!("Failed to load database from file: {file_name}, error: {e}"); - } - } - } else { - tracing::info!("Creating new database: {file_name}"); - // Create an empty JSON file for the new database - if let Err(e) = tokio::fs::write(&file_name, "{}").await { - tracing::error!("Failed to create database file: {e}"); - } - } - - Database { - name, - file_name, - tables: Vec::new(), - } - } + // #[cfg(feature = "async")] + // pub async fn new_async(name: &str) -> Self { + // let name = name.to_string(); + // let file_name = format!("{name}.json"); + // + // if tokio::fs::metadata(&file_name).await.is_ok() { + // tracing::info!("Database already exists: {name}, loading database"); + // + // // Load the database from the file + // match Database::load_from_file_async(&file_name).await { + // Ok(db) => return db, + // Err(e) => { + // tracing::error!("Failed to load database from file: {file_name}, error: {e}"); + // } + // } + // } else { + // tracing::info!("Creating new database: {file_name}"); + // // Create an empty JSON file for the new database + // if let Err(e) = tokio::fs::write(&file_name, "{}").await { + // tracing::error!("Failed to create database file: {e}"); + // } + // } + // + // Database { + // name, + // file_name, + // tables: Vec::new(), + // } + // } pub fn drop_database(&self) -> Result<(), DatabaseError> { if std::fs::remove_file(&self.file_name).is_err() { @@ -122,13 +122,13 @@ impl Database { Ok(()) } - #[cfg(feature = "async")] - pub(crate) async fn save_to_file_async(&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(()) - } + // #[cfg(feature = "async")] + // pub(crate) async fn save_to_file_async(&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) fn load_from_file(file_name: &str) -> Result { let json_data = std::fs::read_to_string(file_name)?; @@ -137,13 +137,13 @@ impl Database { Ok(db) } - #[cfg(feature = "async")] - pub(crate) async fn load_from_file_async(file_name: &str) -> Result { - let json_data = tokio::fs::read_to_string(file_name).await?; - let db: Database = serde_json::from_str(&json_data)?; - tracing::info!("Database loaded from file: {}", file_name); - Ok(db) - } + // #[cfg(feature = "async")] + // pub(crate) async fn load_from_file_async(file_name: &str) -> Result { + // let json_data = tokio::fs::read_to_string(file_name).await?; + // let db: Database = serde_json::from_str(&json_data)?; + // tracing::info!("Database loaded from file: {}", file_name); + // Ok(db) + // } pub(crate) fn get_table_mut(&mut self, table_name: &str) -> Option<&mut Table> { self.tables.iter_mut().find(|t| t.name == table_name) @@ -218,8 +218,8 @@ mod tests { use crate::cargobase::setup_temp_db; use crate::{Columns, Table}; - #[cfg(feature = "async")] - use crate::cargobase::setup_temp_db_async; + // #[cfg(feature = "async")] + // use crate::cargobase::setup_temp_db_async; #[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Default)] struct TestData { @@ -239,18 +239,18 @@ mod tests { assert_eq!(db.tables.len(), 1); // the setup_temp_db function adds a table } - #[cfg(feature = "async")] - #[tokio::test] - async fn test_database_new_async() { - let db = setup_temp_db_async().await; - - let db_name = &db.name.to_string(); - let fnn = format!("{db_name}.json"); - - assert_eq!(db.name, db_name.to_string()); - assert_eq!(db.file_name, fnn); - assert_eq!(db.tables.len(), 1); // the setup_temp_db function adds a table - } + // #[cfg(feature = "async")] + // #[tokio::test] + // async fn test_database_new_async() { + // let db = setup_temp_db_async().await; + // + // let db_name = &db.name.to_string(); + // let fnn = format!("{db_name}.json"); + // + // assert_eq!(db.name, db_name.to_string()); + // assert_eq!(db.file_name, fnn); + // assert_eq!(db.tables.len(), 1); // the setup_temp_db function adds a table + // } #[test] fn test_drop_database() { @@ -345,49 +345,49 @@ mod tests { assert_eq!(db, loaded_db); } - #[cfg(feature = "async")] - #[tokio::test] - async fn test_save_to_file_async() { - use tempfile::NamedTempFile; - - let temp_file = NamedTempFile::new().expect("Failed to create a temporary file"); - 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: vec![], - }; - - db.save_to_file_async() - .await - .expect("Failed to save database"); - let loaded_db = Database::load_from_file(&db_path).expect("Failed to load database"); - assert_eq!(db, loaded_db); - } - - #[cfg(feature = "async")] - #[tokio::test] - async fn test_load_from_file_async() { - use tempfile::NamedTempFile; - - let temp_file = NamedTempFile::new().expect("Failed to create a temporary file"); - let db_path = temp_file.path().to_str().unwrap().to_string(); - - let db = Database { - name: "test_db".to_string(), - file_name: db_path.to_string(), - tables: vec![], - }; - - db.save_to_file_async() - .await - .expect("Failed to save database"); - - let loaded_db = Database::load_from_file_async(&db_path) - .await - .expect("Failed to load database"); - - assert_eq!(db, loaded_db); - } + // #[cfg(feature = "async")] + // #[tokio::test] + // async fn test_save_to_file_async() { + // use tempfile::NamedTempFile; + // + // let temp_file = NamedTempFile::new().expect("Failed to create a temporary file"); + // 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: vec![], + // }; + // + // db.save_to_file_async() + // .await + // .expect("Failed to save database"); + // let loaded_db = Database::load_from_file(&db_path).expect("Failed to load database"); + // assert_eq!(db, loaded_db); + // } + + // #[cfg(feature = "async")] + // #[tokio::test] + // async fn test_load_from_file_async() { + // use tempfile::NamedTempFile; + // + // let temp_file = NamedTempFile::new().expect("Failed to create a temporary file"); + // let db_path = temp_file.path().to_str().unwrap().to_string(); + // + // let db = Database { + // name: "test_db".to_string(), + // file_name: db_path.to_string(), + // tables: vec![], + // }; + // + // db.save_to_file_async() + // .await + // .expect("Failed to save database"); + // + // let loaded_db = Database::load_from_file_async(&db_path) + // .await + // .expect("Failed to load database"); + // + // assert_eq!(db, loaded_db); + // } } diff --git a/src/cargobase/errors/errors.rs b/cargobase/src/cargobase/errors/errors.rs similarity index 100% rename from src/cargobase/errors/errors.rs rename to cargobase/src/cargobase/errors/errors.rs diff --git a/src/cargobase/errors/mod.rs b/cargobase/src/cargobase/errors/mod.rs similarity index 100% rename from src/cargobase/errors/mod.rs rename to cargobase/src/cargobase/errors/mod.rs diff --git a/src/cargobase/mod.rs b/cargobase/src/cargobase/mod.rs similarity index 83% rename from src/cargobase/mod.rs rename to cargobase/src/cargobase/mod.rs index edf3740..107089a 100644 --- a/src/cargobase/mod.rs +++ b/cargobase/src/cargobase/mod.rs @@ -16,5 +16,5 @@ pub use table::Table; pub use util::setup_temp_db; pub use view::View; -#[cfg(feature = "async")] -pub use util::setup_temp_db_async; +// #[cfg(feature = "async")] +// pub use util::setup_temp_db_async; diff --git a/src/cargobase/query.rs b/cargobase/src/cargobase/query.rs similarity index 100% rename from src/cargobase/query.rs rename to cargobase/src/cargobase/query.rs diff --git a/src/cargobase/row.rs b/cargobase/src/cargobase/row.rs similarity index 100% rename from src/cargobase/row.rs rename to cargobase/src/cargobase/row.rs diff --git a/src/cargobase/table.rs b/cargobase/src/cargobase/table.rs similarity index 100% rename from src/cargobase/table.rs rename to cargobase/src/cargobase/table.rs diff --git a/cargobase/src/cargobase/util.rs b/cargobase/src/cargobase/util.rs new file mode 100644 index 0000000..9279b7f --- /dev/null +++ b/cargobase/src/cargobase/util.rs @@ -0,0 +1,110 @@ +use serde::{Deserialize, Serialize}; +use tempfile::NamedTempFile; + +use super::{Columns, Database, Table}; + +// #[cfg(feature = "async")] +// use tokio::fs; + +#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Default)] +struct TestData { + id: String, + name: String, +} + +pub fn setup_temp_db() -> Database { + // Create a temporary file + let temp_file = NamedTempFile::new().expect("Failed to create a temporary file"); + let db_path = temp_file.path().to_str().unwrap().to_string(); + + // Initialize the test database + let mut db = Database::new(&db_path); + let test_columns = Columns::from_struct::(true); + + let mut table = Table::new("TestTable".to_string(), test_columns); + db.add_table(&mut table).unwrap(); + + db +} + +// #[cfg(feature = "async")] +// pub async fn setup_temp_db_async() -> Database { +// let temp_file = NamedTempFile::new().expect("Failed to create a temporary file"); +// let db_path = temp_file.path().to_str().unwrap().to_string(); +// +// // Initialize the test database +// let mut db = Database::new_async(&db_path).await; +// let test_columns = Columns::from_struct::(true); +// +// let mut table = Table::new("TestTable".to_string(), test_columns); +// db.add_table(&mut table).unwrap(); +// +// db.save_to_file_async() +// .await +// .expect("Failed to save database"); +// +// db +// } + +#[cfg(test)] +mod tests { + use super::*; + use std::fs; + + #[test] + fn test_setup_temp_db() { + let db = setup_temp_db(); + assert_eq!(db.tables.len(), 1); + assert_eq!(db.tables[0].name, "TestTable"); + } + + #[test] + fn test_temp_file_cleanup() { + // Create a temporary database + let temp_file = NamedTempFile::new().expect("Failed to create a temporary file"); + let db_path = temp_file.path().to_str().unwrap().to_string(); + + // Drop the file explicitly by dropping the `NamedTempFile` instance + drop(temp_file); + + // Verify that the temporary file is removed + let file_exists = fs::metadata(&db_path).is_ok(); + assert!( + !file_exists, + "Temporary file `{}` should have been removed after being dropped", + db_path + ); + } + + // #[cfg(feature = "async")] + // #[tokio::test] + // async fn test_setup_temp_db_async() { + // let db = setup_temp_db_async().await; + // assert_eq!(db.tables.len(), 1); + // assert_eq!(db.tables[0].name, "TestTable"); + // } + // + // #[cfg(feature = "async")] + // #[tokio::test] + // async fn test_temp_file_cleanup_async() { + // // Create a temporary database + // let temp_file = tempfile::Builder::new() + // .prefix("test_db") + // .suffix(".json") + // .tempfile() + // .expect("Failed to create a temporary file"); + // + // let db_path = temp_file.path().to_str().unwrap().to_string(); + // + // // Drop the file explicitly by dropping the `NamedTempFile` instance + // drop(temp_file); + // + // // Verify that the temporary file is removed + // let file_exists = fs::metadata(&db_path).is_ok(); + // assert!( + // !file_exists, + // "Temporary file `{}` should have been removed after being dropped", + // db_path + // ); + // } +} diff --git a/src/cargobase/view.rs b/cargobase/src/cargobase/view.rs similarity index 100% rename from src/cargobase/view.rs rename to cargobase/src/cargobase/view.rs diff --git a/src/lib.rs b/cargobase/src/lib.rs similarity index 100% rename from src/lib.rs rename to cargobase/src/lib.rs diff --git a/cargobase/src/main.rs b/cargobase/src/main.rs new file mode 100644 index 0000000..df8b376 --- /dev/null +++ b/cargobase/src/main.rs @@ -0,0 +1,359 @@ +// use cargobase::init_tracing; +// use cargobase::{Column, Columns, Database, Table}; +use cargobase::Database; + +use serde::{Deserialize, Serialize}; +// use serde_json::json; +use std::error::Error; +// use uuid::Uuid; +use tracing_subscriber::fmt; + +#[derive(Debug, Serialize, Deserialize, Default, Clone)] +pub struct TestData { + pub id: Option, + pub name: Option, + pub email: Option, +} +// #[derive(Debug, Serialize, Deserialize, Default)] +// pub struct Testing { +// pub id: String, +// pub location: String, +// pub age: String, +// } +// #[derive(Debug, Serialize, Deserialize, Default)] +// pub struct ThisErrorTesting { +// pub id: String, +// pub location: String, +// pub age: String, +// } + +fn main() -> Result<(), Box> { + init_tracing(); + let db = Database::new("cargobase"); + // let mut db = Database::new("cargobase"); + // db.drop_database()?; + // let mut db = Database::new("cargobase"); + // let mut db = Database::new("cargobase_rows"); + // println!("{:#?}", db); + // + // + // + // + // + // + // + // let mut db = Database::new("TestUpdateAndDelete"); + // let mut test_table = Table::new( + // "TestTracingInfo".to_string(), + // Columns::from_struct::(true), + // ); + // println!("{:#?}", test_table); + // db.add_table(&mut test_table)?; + // let record1 = TestData { + // id: Some(Uuid::new_v4().to_string()), + // name: Some("Jon Doe".to_string()), + // email: Some("jondoe@email.com".to_string()), + // }; + // let record2 = TestData { + // id: Some(Uuid::new_v4().to_string()), + // name: Some("Jane Doe".to_string()), + // email: Some("janedoe@email.com".to_string()), + // }; + // let record3 = TestData { + // id: Some(Uuid::new_v4().to_string()), + // name: Some("alice cooper".to_string()), + // email: None, + // }; + // let test_data = vec![record1, record2, record3]; + // test_data.iter().for_each(|data| { + // db.add_row() + // .from("TestTracingInfo") + // .data_from_struct::(data.clone()) + // .execute_add() + // .expect("Failed to add row"); + // }); + // + // + // + // db.update_row() + // .from("TestTracingInfo") + // .data(json!({ + // "id": "4", + // "name": "Abuja", + // "email": "99", + // })) + // .where_eq::("id", "0727f3ca-89ca-4d4d-88cd-598d2979645b")?; + // + // + // db.delete_single() + // .from("TestTracingInfo") + // .where_eq::("id", "4")?; + // + // + // + // + // + // + // + // + // + // let mut test_table = Table::new("TestNoFileName".to_string(), Columns::from_struct::(true)); + + // db.drop_table("TestNoFileName")?; + // + + // db.add_row() + // .from("Test") + // .data_from_struct::(record1) + // .execute_add() + // .expect("Failed to add row"); + // + // db.add_row() + // .from("Test") + // .data_from_struct::(record2) + // .execute_add() + // .expect("Failed to add row"); + + // let all_test_data: Vec = db.get_rows().from("Test").all(); + // + // all_test_data.iter().for_each(|data| { + // println!("{:#?}", data.email); + // }); + // let rows: Vec = db.get_rows().from("Test").all(); + // println!("rows! {:#?}", rows); + + // let mut this_error_table_ordered = Table::new("ThisErrorTestingOrdered".to_string(), Columns::from_struct::(true)); + + // let _ = db.add_table(&mut this_error_table_ordered); + // let _ = db.drop_table("TestTracingInfo"); + + db.view(); + // db.view_table("Test_from_struct"); + Ok(()) +} + +// #[cfg(feature = "logging")] +pub fn init_tracing() { + let subscriber = fmt::Subscriber::builder() + .with_max_level(tracing::Level::WARN) + .finish(); + /* + example implementation: + info!(target: "cargobase", "Database `{name}` already exists, loading..."); + */ + tracing::subscriber::set_global_default(subscriber).expect("Failed to set subscriber"); +} +// ************************************************************************** // +// ************************************************************************** // +// ************************************************************************** // +// ************************************************************************** // +// ************************************************************************** // +// ************************************************************************** // +// +// +// +// let new_row = Testing { +// id: "3333".to_string(), +// location: "^^^^over there".to_string(), +// age: "?????fml rust is hard".to_string(), +// }; +// +// db.add_row() +// .to("Test_from_struct") +// .data_from_struct::(new_row) +// .execute_add() +// .expect("Failed to add row"); +// +// +// #[derive(Debug, Serialize, Deserialize)] +// pub struct User { +// pub id: String, +// pub name: String, +// pub age: String, +// } + +// let user_columns = Columns::new(vec![ +// Column::new("id", true), +// Column::new("name", true), +// Column::new("age", true), +// ]); +// +// let post_columns = Columns::new(vec![ +// Column::new("id", true), +// Column::new("title", true), +// Column::new("content", true), +// ]); + +// let test_colums = Columns::new(vec![ +// Column::new("id", true), +// Column::new("name", true), +// Column::new("email", true), +// ]); + +// let mut users_table = Table::new("Users".to_string(), user_columns); +// let mut posts_table = Table::new("Posts".to_string(), post_columns); +// let mut test_table = Table::new("Test".to_string(), test_colums); + +// +// db.add_table(&mut users_table); +// db.add_table(&mut posts_table); +// db.add_table(&mut test_table); +// +// let user1 = User { +// id: Uuid::new_v4().to_string(), +// name: "Jon Doe".to_string(), +// age: "30".to_string(), +// }; +// +// let user2 = User { +// id: Uuid::new_v4().to_string(), +// name: "Jane Doe".to_string(), +// age: "25".to_string(), +// }; +// +// let posts = vec![ +// json!({ +// "id": Uuid::new_v4().to_string(), +// "title": "Hello, world!", +// "content": "This is my first post.", +// }), +// json!({ +// "id": Uuid::new_v4().to_string(), +// "title": "Hello, again!", +// "content": "This is my second post.", +// }), +// ]; +// +// let users = vec![user1, user2]; + +// let test_data = vec![ +// json!({ +// "id": Uuid::new_v4().to_string(), +// "name": "Jon Doe", +// "email": "jondoe@email.com" +// }), +// json!({ +// "id": Uuid::new_v4().to_string(), +// "name": "Jane Doe", +// "email": "janedoe@email.com" +// }), +// ]; +// +// users_table.add_row(&mut db, json!(users)); +// posts_table.add_row(&mut db, json!(posts)); +// test_table.add_row(&mut db, json!(test_data)); + +// let all_test_data: Vec = db.get_rows().from("Test").all(); + +// let all_rows: Vec = db.get_rows().from("Users").all(); +// println!("{:#?}", all_rows.len()); +// println!("{:#?}", all_rows); +// all_rows.iter().for_each(|user| { +// println!("{:#?}", user.id); +// }); + +// println!("db: {:#?}", db); + +// let single_user: User = db +// .get_single() +// .from("Users") +// .where_eq("id", "39fe81e3-23a3-4212-b608-c4d11b33d995")?; +// +// println!("{:#?}", single_user); + +// let single_user_to_delete: User = db +// .delete_single() +// .from("Users") +// .where_eq("id", "597c4e6d-1a3b-4618-a0f5-7bfb71a243f0")?; + +// println!("{:#?}", single_user_to_delete); + +// "597c4e6d-1a3b-4618-a0f5-7bfb71a243f0" + +// let all_rows: Vec = db.get_rows().from("Users").all(); +// println!("{:#?}", all_rows.len()); +// let _ = db.drop_table("Droppable"); +// +// +// +// +// +// +// let test_columns = vec![ +// Column::new("id", true), +// Column::new("name", true), +// Column::new("email", true), +// ]; + +// let mut test_table = Table::new("Test".to_string(), Columns::new(test_columns)); + +// let test_columns = Columns::new(vec![ +// Column::new("id", true), +// Column::new("location", true), +// Column::new("age", true), +// ]); +// +// let test_columns_default = Columns::from_struct::(true); +// +// let mut test_table_from_struct = +// Table::new("Test_from_struct".to_string(), test_columns_default); +// +// println!("rows: {:?}", test_table_from_struct.rows); +// println!("columns: {:?}", test_table_from_struct.columns); + +// TODO: update add_table method so it doesnt crash the program is the table already exists +// +// db.add_table(&mut test_table_from_struct)?; + +// let testing_data = vec![ +// Testing { +// id: "1".to_string(), +// location: "Lagos".to_string(), +// age: "30".to_string(), +// }, +// Testing { +// id: "2".to_string(), +// location: "Abuja".to_string(), +// age: "25".to_string(), +// }, +// ]; +// // +// test_table_from_struct.add_row(&mut db, json!(testing_data)); + +// db.add_table(&mut test_table)?; + +// db.tables.iter().for_each(|table| { +// println!("{:#?}", table.name); +// }); +// +// +// +// db.get_rows() +// .from("Test") +// .all() +// .iter() +// .for_each(|data: &TestData| { +// println!("{:#?}", data.email); +// }); +// +// let record: Testing = db // must have the type/struct +// .get_single() +// .from("Test_from_struct") +// .where_eq("id", "1")?; +// println!("record: {:#?}", record); + +// let deleted_record = db +// .delete_single() +// .from("Test_from_struct") +// .where_eq::("id", "1")?; +// +// println!("deleted_record: {:#?}", deleted_record); + +// db.update_row() +// .from("Test_from_struct") +// .data(json!({ +// "id": "4", +// "location": "Abuja", +// "age": "99", +// })) +// .where_eq::("id", "2")?; diff --git a/src/cargobase/util.rs b/src/cargobase/util.rs deleted file mode 100644 index 2bb63f2..0000000 --- a/src/cargobase/util.rs +++ /dev/null @@ -1,110 +0,0 @@ -use serde::{Deserialize, Serialize}; -use tempfile::NamedTempFile; - -use super::{Columns, Database, Table}; - -// #[cfg(feature = "async")] -// use tokio::fs; - -#[derive(Serialize, Deserialize, Debug, PartialEq, Clone, Default)] -struct TestData { - id: String, - name: String, -} - -pub fn setup_temp_db() -> Database { - // Create a temporary file - let temp_file = NamedTempFile::new().expect("Failed to create a temporary file"); - let db_path = temp_file.path().to_str().unwrap().to_string(); - - // Initialize the test database - let mut db = Database::new(&db_path); - let test_columns = Columns::from_struct::(true); - - let mut table = Table::new("TestTable".to_string(), test_columns); - db.add_table(&mut table).unwrap(); - - db -} - -#[cfg(feature = "async")] -pub async fn setup_temp_db_async() -> Database { - let temp_file = NamedTempFile::new().expect("Failed to create a temporary file"); - let db_path = temp_file.path().to_str().unwrap().to_string(); - - // Initialize the test database - let mut db = Database::new_async(&db_path).await; - let test_columns = Columns::from_struct::(true); - - let mut table = Table::new("TestTable".to_string(), test_columns); - db.add_table(&mut table).unwrap(); - - db.save_to_file_async() - .await - .expect("Failed to save database"); - - db -} - -#[cfg(test)] -mod tests { - use super::*; - use std::fs; - - #[test] - fn test_setup_temp_db() { - let db = setup_temp_db(); - assert_eq!(db.tables.len(), 1); - assert_eq!(db.tables[0].name, "TestTable"); - } - - #[test] - fn test_temp_file_cleanup() { - // Create a temporary database - let temp_file = NamedTempFile::new().expect("Failed to create a temporary file"); - let db_path = temp_file.path().to_str().unwrap().to_string(); - - // Drop the file explicitly by dropping the `NamedTempFile` instance - drop(temp_file); - - // Verify that the temporary file is removed - let file_exists = fs::metadata(&db_path).is_ok(); - assert!( - !file_exists, - "Temporary file `{}` should have been removed after being dropped", - db_path - ); - } - - #[cfg(feature = "async")] - #[tokio::test] - async fn test_setup_temp_db_async() { - let db = setup_temp_db_async().await; - assert_eq!(db.tables.len(), 1); - assert_eq!(db.tables[0].name, "TestTable"); - } - - #[cfg(feature = "async")] - #[tokio::test] - async fn test_temp_file_cleanup_async() { - // Create a temporary database - let temp_file = tempfile::Builder::new() - .prefix("test_db") - .suffix(".json") - .tempfile() - .expect("Failed to create a temporary file"); - - let db_path = temp_file.path().to_str().unwrap().to_string(); - - // Drop the file explicitly by dropping the `NamedTempFile` instance - drop(temp_file); - - // Verify that the temporary file is removed - let file_exists = fs::metadata(&db_path).is_ok(); - assert!( - !file_exists, - "Temporary file `{}` should have been removed after being dropped", - db_path - ); - } -}