From 3fbf29f71ad7885f13c5e95ec4f856fd2c0f1d92 Mon Sep 17 00:00:00 2001 From: librelois Date: Fri, 4 Jun 2021 02:37:38 +0200 Subject: [PATCH] feat(gql): add field aggregate.sum for query wallets --- gql/src/entities.rs | 30 ++++++++++++++++++++++++++++++ gql/src/queries/wallets.rs | 16 ++++++++++++++-- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/gql/src/entities.rs b/gql/src/entities.rs index b2c93db..295700a 100644 --- a/gql/src/entities.rs +++ b/gql/src/entities.rs @@ -33,6 +33,31 @@ pub(crate) struct AmountWithBase { pub(crate) amount: i32, pub(crate) base: i32, } +impl AmountWithBase { + fn increment_base(self) -> Self { + Self { + amount: self.amount / 10, + base: self.base + 1, + } + } +} +impl std::ops::Add for AmountWithBase { + type Output = Self; + + fn add(self, rhs: Self) -> Self::Output { + #[allow(clippy::comparison_chain)] + if self.base == rhs.base { + Self { + amount: self.amount + rhs.amount, + base: self.base, + } + } else if self.base > rhs.base { + self.add(rhs.increment_base()) + } else { + self.increment_base().add(rhs) + } + } +} impl From for AmountWithBase { fn from(sa: SourceAmount) -> Self { Self { @@ -41,6 +66,11 @@ impl From for AmountWithBase { } } } +impl std::iter::Sum for AmountWithBase { + fn sum>(iter: I) -> Self { + iter.fold(AmountWithBase::default(), std::ops::Add::add) + } +} #[derive(async_graphql::SimpleObject)] pub(crate) struct EdgeTx { diff --git a/gql/src/queries/wallets.rs b/gql/src/queries/wallets.rs index 699a085..aa3636b 100644 --- a/gql/src/queries/wallets.rs +++ b/gql/src/queries/wallets.rs @@ -32,7 +32,7 @@ impl WalletsQuery { #[graphql(desc = "minimal balance")] min_balance: Option, #[graphql(desc = "pagination", default)] pagination: Pagination, #[graphql(desc = "Wallet type filter", default)] wallet_type_filter: WalletTypeFilter, - ) -> async_graphql::Result> { + ) -> async_graphql::Result> { let QueryContext { is_whitelisted } = ctx.data::()?; let data = ctx.data::()?; @@ -160,7 +160,19 @@ impl WalletsQuery { } }; - let mut conn = Connection::new(has_previous_page, has_next_page); + let sum = if ctx.look_ahead().field("aggregate").field("sum").exists() { + data.iter().map(|wallet| wallet.balance).sum() + } else { + AmountWithBase::default() + }; + + let mut conn = Connection::with_additional_fields( + has_previous_page, + has_next_page, + AggregateSum { + aggregate: Sum { sum }, + }, + ); conn.append( data.into_iter()