Skip to content
This repository has been archived by the owner on Jul 23, 2024. It is now read-only.

Commit

Permalink
Paginate library pins query
Browse files Browse the repository at this point in the history
  • Loading branch information
garryod committed Oct 9, 2023
1 parent ddf96e7 commit fe21ba3
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 4 deletions.
1 change: 1 addition & 0 deletions backend/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions backend/pin_packing/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ version = "0.1.0"
edition = "2021"

[dependencies]
anyhow = { workspace = true }
async-graphql = { workspace = true }
axum = { workspace = true }
clap = { workspace = true }
Expand Down
52 changes: 48 additions & 4 deletions backend/pin_packing/src/resolvers/pin_library.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,15 @@ use crate::tables::{
pin_library::{self, PinStatus},
pin_mount,
};
use async_graphql::{ComplexObject, Context, Object};
use async_graphql::{
connection::{query, Connection, Edge, EmptyFields},
ComplexObject, Context, Object,
};
use opa_client::subject_authorization;
use sea_orm::{ActiveValue, DatabaseConnection, EntityTrait, IntoActiveModel, ModelTrait};
use sea_orm::{
ActiveValue, CursorTrait, DatabaseConnection, EntityTrait, IntoActiveModel, ModelTrait,
PaginatorTrait,
};

#[ComplexObject]
impl pin_library::Model {
Expand All @@ -23,10 +29,48 @@ impl PinLibraryQuery {
async fn library_pins(
&self,
ctx: &Context<'_>,
) -> async_graphql::Result<Vec<pin_library::Model>> {
after: Option<String>,
before: Option<String>,
first: Option<i32>,
last: Option<i32>,
) -> async_graphql::Result<Connection<usize, pin_library::Model, EmptyFields, EmptyFields>>
{
subject_authorization!("xchemlab.pin_packing.read_pin_library", ctx).await?;
let database = ctx.data::<DatabaseConnection>()?;
Ok(pin_library::Entity::find().all(database).await?)
let pin_query = pin_library::Entity::find();
let pin_count = pin_query.clone().count(database).await? as usize;
let mut pin_cursor = pin_query.cursor_by(pin_library::Column::Barcode);
query(
after,
before,
first,
last,
|after, before, first, last| async move {
let (after, before) = match (after, before, first, last) {
(Some(after), None, Some(first), None) => Ok((after, after + first)),
(None, Some(before), None, Some(last)) => Ok((before - last, before)),
(None, None, None, None) => Ok((0, pin_count)),
_ => Err(anyhow::anyhow!(
"Could not determine desired pagination behaviour."
)),
}?;

let pins = pin_cursor
.after(after as u64)
.before(before as u64)
.all(database)
.await?;

let mut connection = Connection::new(after > 0, before < pin_count);
connection.edges.extend(
pins.into_iter()
.enumerate()
.map(|(idx, pin)| Edge::new(after + idx, pin)),
);
Ok::<_, async_graphql::Error>(connection)
},
)
.await
}
}

Expand Down

0 comments on commit fe21ba3

Please sign in to comment.