From efee538846e85d078b6404943070285c30116fae Mon Sep 17 00:00:00 2001 From: Michael Vlach Date: Sat, 10 Aug 2024 19:49:46 +0200 Subject: [PATCH] [server] Search ids are not injected with previous queries #1192 (#1198) * Update main.rs * Update api.rs * Update db_exec_test.rs * Update db_pool.rs --- agdb_api/rust/src/api.rs | 2 +- agdb_server/src/db_pool.rs | 2 + agdb_server/tests/routes/db_exec_test.rs | 186 ++++++++++++++++++++++- examples/indexes/src/main.rs | 2 +- 4 files changed, 188 insertions(+), 4 deletions(-) diff --git a/agdb_api/rust/src/api.rs b/agdb_api/rust/src/api.rs index 577c597e5..84bfaf7e0 100644 --- a/agdb_api/rust/src/api.rs +++ b/agdb_api/rust/src/api.rs @@ -356,7 +356,7 @@ impl AgdbApi { &self, owner: &str, db: &str, - queries: &Vec, + queries: &[QueryType], ) -> AgdbApiResult<(u16, Vec)> { self.client .post( diff --git a/agdb_server/src/db_pool.rs b/agdb_server/src/db_pool.rs index 4527dd34c..981ded5d6 100644 --- a/agdb_server/src/db_pool.rs +++ b/agdb_server/src/db_pool.rs @@ -1446,6 +1446,7 @@ fn t_exec_mut( } QueryType::InsertEdges(q) => { do_audit = true; + inject_results(&mut q.ids, results)?; inject_results(&mut q.from, results)?; inject_results(&mut q.to, results)?; @@ -1453,6 +1454,7 @@ fn t_exec_mut( } QueryType::InsertNodes(q) => { do_audit = true; + inject_results(&mut q.ids, results)?; t.exec_mut(q) } QueryType::InsertValues(q) => { diff --git a/agdb_server/tests/routes/db_exec_test.rs b/agdb_server/tests/routes/db_exec_test.rs index 349c43378..e59f04926 100644 --- a/agdb_server/tests/routes/db_exec_test.rs +++ b/agdb_server/tests/routes/db_exec_test.rs @@ -1,5 +1,6 @@ use crate::TestServer; use crate::ADMIN; +use agdb::CountComparison; use agdb::DbElement; use agdb::DbId; use agdb::QueryBuilder; @@ -408,6 +409,187 @@ async fn use_result_in_search() -> anyhow::Result<()> { Ok(()) } +#[tokio::test] +async fn use_result_in_insert_ids() -> anyhow::Result<()> { + let mut server = TestServer::new().await?; + let owner = &server.next_user_name(); + let db = &server.next_db_name(); + server.api.user_login(ADMIN, ADMIN).await?; + server.api.admin_user_add(owner, owner).await?; + server.api.user_login(owner, owner).await?; + server.api.db_add(owner, db, DbType::Mapped).await?; + let queries = &vec![ + QueryBuilder::insert() + .nodes() + .aliases("root") + .query() + .into(), + QueryBuilder::insert() + .nodes() + .ids( + QueryBuilder::search() + .from("root") + .where_() + .node() + .and() + .distance(CountComparison::Equal(2)) + .query(), + ) + .count(3) + .query() + .into(), + QueryBuilder::insert() + .edges() + .ids( + QueryBuilder::search() + .from("root") + .to(":1") + .where_() + .edge() + .query(), + ) + .from(":0") + .to(":1") + .query() + .into(), + QueryBuilder::search().from(":0").to(":1").query().into(), + ]; + let (status, results) = server.api.db_exec(owner, db, queries).await?; + assert_eq!(status, 200); + assert_eq!( + results[3], + QueryResult { + result: 3, + elements: vec![ + DbElement { + id: DbId(1), + from: None, + to: None, + values: vec![] + }, + DbElement { + id: DbId(-5), + from: Some(DbId(1)), + to: Some(DbId(2)), + values: vec![] + }, + DbElement { + id: DbId(2), + from: None, + to: None, + values: vec![] + } + ] + } + ); + Ok(()) +} + +#[tokio::test] +async fn reentrant_queries() -> anyhow::Result<()> { + let mut server = TestServer::new().await?; + let owner = &server.next_user_name(); + let db = &server.next_db_name(); + server.api.user_login(ADMIN, ADMIN).await?; + server.api.admin_user_add(owner, owner).await?; + server.api.user_login(owner, owner).await?; + server.api.db_add(owner, db, DbType::Mapped).await?; + let queries = &vec![ + QueryBuilder::insert() + .nodes() + .aliases("root") + .query() + .into(), + QueryBuilder::insert() + .nodes() + .ids( + QueryBuilder::search() + .from(":0") + .where_() + .node() + .and() + .distance(CountComparison::Equal(2)) + .query(), + ) + .count(3) + .query() + .into(), + QueryBuilder::search() + .from(":0") + .to(":1") + .where_() + .edge() + .query() + .into(), + QueryBuilder::insert() + .edges() + .ids(":2") + .from(":0") + .to(":1") + .query() + .into(), + QueryBuilder::search().from(":0").to(":1").query().into(), + QueryBuilder::search().from(":0").to(":1").query().into(), + ]; + let (status, results) = server.api.db_exec(owner, db, queries).await?; + assert_eq!(status, 200); + assert_eq!( + results[4], + QueryResult { + result: 3, + elements: vec![ + DbElement { + id: DbId(1), + from: None, + to: None, + values: vec![] + }, + DbElement { + id: DbId(-5), + from: Some(DbId(1)), + to: Some(DbId(2)), + values: vec![] + }, + DbElement { + id: DbId(2), + from: None, + to: None, + values: vec![] + } + ] + } + ); + let (status, results) = server.api.db_exec(owner, db, queries).await?; + assert_eq!(status, 200); + assert_eq!( + results[4], + QueryResult { + result: 3, + elements: vec![ + DbElement { + id: DbId(1), + from: None, + to: None, + values: vec![] + }, + DbElement { + id: DbId(-7), + from: Some(DbId(1)), + to: Some(DbId(4)), + values: vec![] + }, + DbElement { + id: DbId(4), + from: None, + to: None, + values: vec![] + } + ] + } + ); + Ok(()) +} + #[tokio::test] async fn use_result_in_search_bad_query() -> anyhow::Result<()> { let mut server = TestServer::new().await?; @@ -544,7 +726,7 @@ async fn db_not_found() -> anyhow::Result<()> { server.api.user_login(owner, owner).await?; let status = server .api - .db_exec(owner, "db", &vec![]) + .db_exec(owner, "db", &[]) .await .unwrap_err() .status; @@ -557,7 +739,7 @@ async fn no_token() -> anyhow::Result<()> { let server = TestServer::new().await?; let status = server .api - .db_exec("user", "db", &vec![]) + .db_exec("user", "db", &[]) .await .unwrap_err() .status; diff --git a/examples/indexes/src/main.rs b/examples/indexes/src/main.rs index b8462968a..d247831ab 100644 --- a/examples/indexes/src/main.rs +++ b/examples/indexes/src/main.rs @@ -18,7 +18,7 @@ fn main() -> Result<(), QueryError> { let mut db = DbMemory::new("agdb_example")?; // Create two indexes, one for username and one for token. They can just as well - // be craeted later and will index all existing data as well. + // be created later and will index all existing data as well. db.exec_mut(&QueryBuilder::insert().index("username").query())?; db.exec_mut(&QueryBuilder::insert().index("token").query())?;