From 7d382c7b1f800d7cfe8e27509018678ae8556376 Mon Sep 17 00:00:00 2001 From: 0xZensh Date: Sun, 17 Sep 2023 00:15:36 +0800 Subject: [PATCH] improve /v1/publication/list_by_gids api. --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/api/bookmark.rs | 11 ++--- src/api/creation.rs | 11 ++--- src/api/mod.rs | 27 +++------- src/api/publication.rs | 12 ++--- src/db/model_publication.rs | 98 +++++++++++++++++-------------------- 7 files changed, 70 insertions(+), 93 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bce5b3d..093a396 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3025,7 +3025,7 @@ dependencies = [ [[package]] name = "writing" -version = "0.10.3" +version = "0.10.4" dependencies = [ "anyhow", "async-trait", diff --git a/Cargo.toml b/Cargo.toml index 887bbf9..b6ccf67 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "writing" -version = "0.10.3" +version = "0.10.4" edition = "2021" rust-version = "1.64" description = "" diff --git a/src/api/bookmark.rs b/src/api/bookmark.rs index 27d1e59..b8f475a 100644 --- a/src/api/bookmark.rs +++ b/src/api/bookmark.rs @@ -199,15 +199,14 @@ pub async fn list( token_to_xid(&input.page_token), ) .await?; - let next_page_token = if res.len() >= page_size as usize { - to.with_option(token_from_xid(res.last().unwrap().id)) - } else { - None - }; Ok(to.with(SuccessResponse { total_size: None, - next_page_token, + next_page_token: to.with_option(token_from_xid(if res.len() >= page_size as usize { + Some(res.last().unwrap().id) + } else { + None + })), result: res .iter() .map(|r| BookmarkOutput::from(r.to_owned(), &to)) diff --git a/src/api/creation.rs b/src/api/creation.rs index 0310ac4..d3d734d 100644 --- a/src/api/creation.rs +++ b/src/api/creation.rs @@ -236,15 +236,14 @@ pub async fn list( input.status, ) .await?; - let next_page_token = if res.len() >= page_size as usize { - to.with_option(token_from_xid(res.last().unwrap().id)) - } else { - None - }; Ok(to.with(SuccessResponse { total_size: None, - next_page_token, + next_page_token: to.with_option(token_from_xid(if res.len() >= page_size as usize { + Some(res.last().unwrap().id) + } else { + None + })), result: res .iter() .map(|r| CreationOutput::from(r.to_owned(), &to)) diff --git a/src/api/mod.rs b/src/api/mod.rs index b7c40df..b290ef7 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -128,25 +128,12 @@ pub fn token_to_xid(page_token: &Option>>) -> Option } } -pub fn token_from_xid(id: xid::Id) -> Option> { - cbor_to_vec(&PackObject::Cbor(id)).ok() -} - -// pub fn token_to_publication( -// page_token: &Option>>, -// ) -> Option<(xid::Id, Language, i16)> { -// match page_token.as_ref().map(|v| v.unwrap_ref()) { -// Some(v) => cbor_from_slice::<(PackObject, PackObject, i16)>(&v) -// .ok() -// .map(|v| (v.0.unwrap(), v.1.unwrap(), v.2)), -// _ => None, -// } -// } - -// pub fn token_from_publication(v: (xid::Id, Language, i16)) -> Option> { -// let v = (PackObject::Cbor(v.0), PackObject::Cbor(v.1), v.2); -// cbor_to_vec(&v).ok() -// } +pub fn token_from_xid(id: Option) -> Option> { + match id { + Some(id) => cbor_to_vec(&PackObject::Cbor(id)).ok(), + _ => None, + } +} #[derive(Debug, Deserialize, Validate)] pub struct UpdateStatusInput { @@ -194,7 +181,7 @@ mod tests { #[test] fn token_to_xid_works() { let input = xid::new(); - let v = token_from_xid(input).unwrap(); + let v = token_from_xid(Some(input)).unwrap(); assert_eq!(hex_string(&v).len(), 26); let rt = token_to_xid(&Some(PackObject::Cbor(v))); assert_eq!(rt, Some(input)); diff --git a/src/api/publication.rs b/src/api/publication.rs index d63cc76..45787fb 100644 --- a/src/api/publication.rs +++ b/src/api/publication.rs @@ -297,16 +297,14 @@ pub async fn list( ctx.language, ) .await?; - let next_page_token = if res.len() >= page_size as usize { - let v = res.last().unwrap(); - to.with_option(token_from_xid(v.cid)) - } else { - None - }; Ok(to.with(SuccessResponse { total_size: None, - next_page_token, + next_page_token: to.with_option(token_from_xid(if res.len() >= page_size as usize { + Some(res.last().unwrap().cid) + } else { + None + })), result: res .iter() .map(|r| PublicationOutput::from(r.to_owned(), &to)) diff --git a/src/db/model_publication.rs b/src/db/model_publication.rs index 529f98f..a37a9db 100644 --- a/src/db/model_publication.rs +++ b/src/db/model_publication.rs @@ -756,75 +756,69 @@ impl Publication { select_fields: Vec, page_token: Option, language: Option, - ) -> anyhow::Result<(Vec, xid::Id)> { + ) -> anyhow::Result<(Vec, Option)> { let fields = Self::select_fields(select_fields, true)?; - let secs: u32 = 3600 * 48; - let query_size: i32 = match gids.len() { - v if v <= 5 => 5, - v if v <= 20 => 4, - v if v <= 50 => 3, - v if v <= 100 => 2, - _ => 1, - }; - - let mut res: Vec = Vec::with_capacity(gids.len() * 2); + let secs: u32 = 3600 * 24; + let mut res: Vec = Vec::new(); + let query = format!( + "SELECT {} FROM publication WHERE gid=? AND status=? AND cid>=? AND cid=? AND cid *prev = doc, - // or original language - None if doc.language == doc.from_language => *prev = doc, - _ => {} // ignore + } else { + let prev = res.last_mut().unwrap(); + if prev.cid != doc.cid { + res.push(doc); + } else if prev.language != doc.language { + match language { + // prefer language match + Some(lang) if lang == doc.language => *prev = doc, + // or original language + None if doc.language == doc.from_language => *prev = doc, + _ => {} // ignore + } } } } + } - if local_size >= query_size { - break; - } + if !res.is_empty() { + res.sort_by(|a, b| b.cid.partial_cmp(&a.cid).unwrap()); + return Ok((res, Some(start_id))); } + + i += 1; + end_id = start_id; } - Ok((res, start_id)) + Ok((res, None)) } pub async fn list_published_by_cid(