From 5bea71dbb4d4323a93b35b5ab7555190dd9bbfbb Mon Sep 17 00:00:00 2001 From: Bryan Newbold Date: Sun, 17 Jun 2018 17:01:39 -0700 Subject: implement reverse lookups --- rust/src/api_server.rs | 89 ++++++++++++++++++++++++++++++++++++++----- rust/tests/test_api_server.rs | 35 +++++++++++++++++ 2 files changed, 115 insertions(+), 9 deletions(-) diff --git a/rust/src/api_server.rs b/rust/src/api_server.rs index c167c067..b6445535 100644 --- a/rust/src/api_server.rs +++ b/rust/src/api_server.rs @@ -171,7 +171,7 @@ fn creator_row2entity(ident: Option, rev: CreatorRevRow) -> Res fn file_row2entity( ident: Option, rev: FileRevRow, - conn: DbConn, + conn: &DbConn, ) -> Result { let (state, ident_id, redirect_id) = match ident { Some(i) => ( @@ -184,7 +184,7 @@ fn file_row2entity( let releases: Vec = file_release::table .filter(file_release::file_rev.eq(rev.id)) - .get_results(&conn)? + .get_results(conn)? .iter() .map(|r: &FileReleaseRow| r.target_release_ident_id.to_string()) .collect(); @@ -209,7 +209,7 @@ fn file_row2entity( fn release_row2entity( ident: Option, rev: ReleaseRevRow, - conn: DbConn, + conn: &DbConn, ) -> Result { let (state, ident_id, redirect_id) = match ident { Some(i) => ( @@ -222,7 +222,7 @@ fn release_row2entity( let refs: Vec = release_ref::table .filter(release_ref::release_rev.eq(rev.id)) - .get_results(&conn) + .get_results(conn) .expect("fetch release refs") .iter() .map(|r: &ReleaseRefRow| ReleaseRef { @@ -239,7 +239,7 @@ fn release_row2entity( let contribs: Vec = release_contrib::table .filter(release_contrib::release_rev.eq(rev.id)) - .get_results(&conn) + .get_results(conn) .expect("fetch release refs") .iter() .map(|c: &ReleaseContribRow| ReleaseContrib { @@ -348,6 +348,23 @@ impl Server { creator_row2entity(Some(ident), rev) } + fn get_creator_releases_handler(&self, id: String) -> Result> { + let conn = self.db_pool.get().expect("db_pool error"); + let id = uuid::Uuid::parse_str(&id)?; + + // TODO: some kind of unique or group-by? + let rows: Vec<(ReleaseRevRow, ReleaseIdentRow, ReleaseContribRow)> = release_rev::table + .inner_join(release_ident::table) + .inner_join(release_contrib::table) + .filter(release_contrib::creator_ident_id.eq(&id)) + .filter(release_ident::is_live.eq(true)) + .filter(release_ident::redirect_id.is_null()) + .load(&conn)?; + + rows.into_iter() + .map(|(rev, ident, _)| release_row2entity(Some(ident), rev, &conn)).collect() + } + fn get_file_handler(&self, id: String) -> Result { let conn = self.db_pool.get().expect("db_pool error"); let id = uuid::Uuid::parse_str(&id)?; @@ -357,7 +374,7 @@ impl Server { .inner_join(file_rev::table) .first(&conn)?; - file_row2entity(Some(ident), rev, conn) + file_row2entity(Some(ident), rev, &conn) } fn lookup_file_handler(&self, sha1: String) -> Result { @@ -370,7 +387,7 @@ impl Server { .filter(file_ident::redirect_id.is_null()) .first(&conn)?; - file_row2entity(Some(ident), rev, conn) + file_row2entity(Some(ident), rev, &conn) } fn get_release_handler(&self, id: String) -> Result { @@ -382,7 +399,7 @@ impl Server { .inner_join(release_rev::table) .first(&conn)?; - release_row2entity(Some(ident), rev, conn) + release_row2entity(Some(ident), rev, &conn) } fn lookup_release_handler(&self, doi: String) -> Result { @@ -395,7 +412,23 @@ impl Server { .filter(release_ident::redirect_id.is_null()) .first(&conn)?; - release_row2entity(Some(ident), rev, conn) + release_row2entity(Some(ident), rev, &conn) + } + + fn get_release_files_handler(&self, id: String) -> Result> { + let conn = self.db_pool.get().expect("db_pool error"); + let id = uuid::Uuid::parse_str(&id)?; + + let rows: Vec<(FileRevRow, FileIdentRow, FileReleaseRow)> = file_rev::table + .inner_join(file_ident::table) + .inner_join(file_release::table) + .filter(file_release::target_release_ident_id.eq(&id)) + .filter(file_ident::is_live.eq(true)) + .filter(file_ident::redirect_id.is_null()) + .load(&conn)?; + + rows.into_iter() + .map(|(rev, ident, _)| file_row2entity(Some(ident), rev, &conn)).collect() } fn get_work_handler(&self, id: String) -> Result { @@ -410,6 +443,21 @@ impl Server { work_row2entity(Some(ident), rev) } + fn get_work_releases_handler(&self, id: String) -> Result> { + let conn = self.db_pool.get().expect("db_pool error"); + let id = uuid::Uuid::parse_str(&id)?; + + let rows: Vec<(ReleaseRevRow, ReleaseIdentRow)> = release_rev::table + .inner_join(release_ident::table) + .filter(release_rev::work_ident_id.eq(&id)) + .filter(release_ident::is_live.eq(true)) + .filter(release_ident::redirect_id.is_null()) + .load(&conn)?; + + rows.into_iter() + .map(|(rev, ident)| release_row2entity(Some(ident), rev, &conn)).collect() + } + fn create_container_handler( &self, entity: models::ContainerEntity, @@ -919,6 +967,29 @@ impl Api for Server { String ); + // Rename "wrap_lookup_handler"? + wrap_lookup_handler!( + get_release_files, + get_release_files_handler, + GetReleaseFilesResponse, + id, + String + ); + wrap_lookup_handler!( + get_work_releases, + get_work_releases_handler, + GetWorkReleasesResponse, + id, + String + ); + wrap_lookup_handler!( + get_creator_releases, + get_creator_releases_handler, + GetCreatorReleasesResponse, + id, + String + ); + fn accept_editgroup( &self, id: i64, diff --git a/rust/tests/test_api_server.rs b/rust/tests/test_api_server.rs index 32db268c..05dd493f 100644 --- a/rust/tests/test_api_server.rs +++ b/rust/tests/test_api_server.rs @@ -146,6 +146,41 @@ fn test_lookups() { ); } +#[test] +fn test_reverse_lookups() { + let (headers, router, _conn) = setup(); + + check_response( + request::get( + "http://localhost:9411/v0/creator/00000000-0000-0000-2222-000000000002/releases", + headers.clone(), + &router, + ), + status::Ok, + Some("bigger example"), + ); + + check_response( + request::get( + "http://localhost:9411/v0/release/00000000-0000-0000-4444-000000000002/files", + headers.clone(), + &router, + ), + status::Ok, + Some("7d97e98f8af710c7e7fe703abc8f639e0ee507c4"), + ); + + check_response( + request::get( + "http://localhost:9411/v0/work/00000000-0000-0000-5555-000000000002/releases", + headers.clone(), + &router, + ), + status::Ok, + Some("bigger example"), + ); +} + #[test] fn test_post_container() { let (headers, router, _conn) = setup(); -- cgit v1.2.3