mirror of
https://seed.radicle.dev/rad:z4V1sjrXqjvFdnCUbxPFqd5p4DtH5.git
synced 2026-11-02 18:20:29 +08:00
Move patch pagination into the patch service
This commit is contained in:
@@ -19,8 +19,6 @@ use radicle_types::traits::patch::PatchesMut;
|
||||
|
||||
use crate::AppState;
|
||||
|
||||
use either::Either;
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn list_patches(
|
||||
ctx: tauri::State<'_, AppState>,
|
||||
@@ -32,43 +30,9 @@ pub async fn list_patches(
|
||||
take: Option<usize>,
|
||||
) -> Result<types::cobs::PaginatedQuery<Vec<models::patch::Patch>>, Error> {
|
||||
let profile = ctx.profile();
|
||||
let cursor = skip.unwrap_or(0);
|
||||
let aliases = profile.aliases();
|
||||
let counts = sqlite_service.counts(rid)?;
|
||||
let patches = match status.clone() {
|
||||
None => Either::Left(sqlite_service.list(rid)?),
|
||||
Some(s) => Either::Right(sqlite_service.list_by_status(rid, s.into())?),
|
||||
};
|
||||
|
||||
match take {
|
||||
None => {
|
||||
let content = patches
|
||||
.map(|(id, patch)| models::patch::Patch::new(id, &patch, &aliases))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
Ok::<_, Error>(cobs::PaginatedQuery {
|
||||
cursor: 0,
|
||||
more: false,
|
||||
content,
|
||||
})
|
||||
}
|
||||
Some(take) => {
|
||||
let total = status.map_or_else(|| counts.total(), |status| counts[status.into()]);
|
||||
let more = cursor + take < total;
|
||||
|
||||
let content = patches
|
||||
.skip(cursor)
|
||||
.take(take)
|
||||
.map(|(id, patch)| models::patch::Patch::new(id, &patch, &aliases))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
Ok::<_, Error>(cobs::PaginatedQuery {
|
||||
cursor,
|
||||
more,
|
||||
content,
|
||||
})
|
||||
}
|
||||
}
|
||||
Ok(sqlite_service.list_paginated(rid, status, skip, take, &aliases)?)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
use radicle::identity;
|
||||
use radicle::node::AliasStore;
|
||||
use radicle::patch;
|
||||
use radicle::patch::Patch;
|
||||
use radicle::patch::PatchId;
|
||||
|
||||
use crate::cobs;
|
||||
use crate::domain::patch::models;
|
||||
|
||||
pub trait PatchStorage {
|
||||
@@ -39,4 +41,49 @@ pub trait PatchService {
|
||||
&self,
|
||||
rid: identity::RepoId,
|
||||
) -> Result<models::patch::PatchCounts, models::patch::CountsError>;
|
||||
|
||||
/// One page of patch summaries, shared by all drivers so pagination
|
||||
/// behaves identically everywhere. Rows are consumed lazily: with `take`
|
||||
/// set, patches beyond the requested page are never deserialized.
|
||||
/// Without `take` the full list is returned and `skip` is ignored.
|
||||
fn list_paginated(
|
||||
&self,
|
||||
rid: identity::RepoId,
|
||||
status: Option<cobs::query::PatchStatus>,
|
||||
skip: Option<usize>,
|
||||
take: Option<usize>,
|
||||
aliases: &impl AliasStore,
|
||||
) -> Result<cobs::PaginatedQuery<Vec<models::patch::Patch>>, models::patch::ListPatchesError>
|
||||
{
|
||||
let patches: Box<dyn Iterator<Item = (PatchId, Patch)> + '_> = match status {
|
||||
None => Box::new(self.list(rid)?),
|
||||
Some(status) => Box::new(self.list_by_status(rid, status.into())?),
|
||||
};
|
||||
let summary =
|
||||
|(id, patch): (PatchId, Patch)| models::patch::Patch::new(id, &patch, aliases);
|
||||
|
||||
match take {
|
||||
None => Ok(cobs::PaginatedQuery {
|
||||
cursor: 0,
|
||||
more: false,
|
||||
content: patches.map(summary).collect::<Vec<_>>(),
|
||||
}),
|
||||
Some(take) => {
|
||||
let cursor = skip.unwrap_or(0);
|
||||
let mut content = patches
|
||||
.skip(cursor)
|
||||
.take(take + 1)
|
||||
.map(summary)
|
||||
.collect::<Vec<_>>();
|
||||
let more = content.len() > take;
|
||||
content.truncate(take);
|
||||
|
||||
Ok(cobs::PaginatedQuery {
|
||||
cursor,
|
||||
more,
|
||||
content,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,9 +15,9 @@ use radicle::node::NodeId;
|
||||
use radicle::{git, identity};
|
||||
use radicle_types as types;
|
||||
use radicle_types::cobs::CobOptions;
|
||||
use radicle_types::cobs::FromRadicleAction;
|
||||
use radicle_types::cobs::issue;
|
||||
use radicle_types::cobs::issue::NewIssue;
|
||||
use radicle_types::cobs::{self, FromRadicleAction};
|
||||
use radicle_types::config::Version;
|
||||
use radicle_types::domain::issue::service::Service as IssueService;
|
||||
use radicle_types::domain::issue::traits::IssueService as _;
|
||||
@@ -627,7 +627,7 @@ async fn issue_threads_handler(
|
||||
struct PatchesBody {
|
||||
pub rid: identity::RepoId,
|
||||
pub skip: Option<usize>,
|
||||
pub take: Option<isize>,
|
||||
pub take: Option<usize>,
|
||||
pub status: Option<types::cobs::query::PatchStatus>,
|
||||
}
|
||||
|
||||
@@ -640,50 +640,12 @@ async fn patches_handler(
|
||||
status,
|
||||
}): Json<PatchesBody>,
|
||||
) -> impl IntoResponse {
|
||||
let profile = ctx.profile;
|
||||
let cursor = skip.unwrap_or(0);
|
||||
let aliases = profile.aliases();
|
||||
let aliases = ctx.profile.aliases();
|
||||
let page = ctx
|
||||
.patches
|
||||
.list_paginated(rid, status, skip, take, &aliases)?;
|
||||
|
||||
let patches = match status {
|
||||
None => ctx.patches.list(rid)?.collect::<Vec<_>>(),
|
||||
Some(s) => ctx
|
||||
.patches
|
||||
.list_by_status(rid, s.into())?
|
||||
.collect::<Vec<_>>(),
|
||||
};
|
||||
|
||||
if let Some(t) = take
|
||||
&& t < 0
|
||||
{
|
||||
// Return all patches
|
||||
let content = patches
|
||||
.into_iter()
|
||||
.map(|(id, patch)| models::patch::Patch::new(id, &patch, &aliases))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
return Ok::<_, Error>(Json(cobs::PaginatedQuery {
|
||||
cursor: 0,
|
||||
more: false,
|
||||
content,
|
||||
}));
|
||||
}
|
||||
|
||||
let take = take.unwrap_or(20) as usize;
|
||||
|
||||
let more = cursor + take < patches.len();
|
||||
|
||||
let patches = patches
|
||||
.into_iter()
|
||||
.skip(cursor)
|
||||
.take(take)
|
||||
.map(|(id, patch)| models::patch::Patch::new(id, &patch, &aliases))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
Ok::<_, Error>(Json(cobs::PaginatedQuery {
|
||||
cursor,
|
||||
more,
|
||||
content: patches,
|
||||
}))
|
||||
Ok::<_, Error>(Json(page))
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
|
||||
Reference in New Issue
Block a user