Skip to content
Snippets Groups Projects
Commit 19c0295a authored by Éloïs's avatar Éloïs
Browse files

[ref] gva: rework pagination cursors

parent 6657adae
No related branches found
No related tags found
1 merge request!1335Gva proto 2
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
use crate::{ use crate::{
uds_of_pubkey::UdsWithSum, uds_of_pubkey::UdsWithSum,
utxos::{UtxoIdWithBlockNumber, UtxosWithSum}, utxos::{UtxoCursor, UtxosWithSum},
*, *,
}; };
use dubp::{documents::transaction::TransactionInputV10, wallet::prelude::*}; use dubp::{documents::transaction::TransactionInputV10, wallet::prelude::*};
...@@ -110,11 +110,18 @@ pub fn find_inputs<BcDb: BcV2DbReadable, GvaDb: GvaV1DbReadable, TxsMpDb: TxsMpV ...@@ -110,11 +110,18 @@ pub fn find_inputs<BcDb: BcV2DbReadable, GvaDb: GvaV1DbReadable, TxsMpDb: TxsMpV
&script, &script,
)?; )?;
inputs.extend(written_utxos.into_iter().map( inputs.extend(written_utxos.into_iter().map(
|(UtxoIdWithBlockNumber(utxo_id, _), source_amount)| TransactionInputV10 { |(
UtxoCursor {
tx_hash,
output_index,
..
},
source_amount,
)| TransactionInputV10 {
amount: source_amount, amount: source_amount,
id: SourceIdV10::Utxo(UtxoIdV10 { id: SourceIdV10::Utxo(UtxoIdV10 {
tx_hash: utxo_id.tx_hash, tx_hash,
output_index: utxo_id.output_index, output_index: output_index as usize,
}), }),
}, },
)); ));
......
...@@ -43,7 +43,11 @@ use duniter_dbs::{ ...@@ -43,7 +43,11 @@ use duniter_dbs::{
use resiter::filter::Filter; use resiter::filter::Filter;
use resiter::filter_map::FilterMap; use resiter::filter_map::FilterMap;
use resiter::map::Map; use resiter::map::Map;
use std::collections::BTreeSet; use std::{collections::BTreeSet, str::FromStr};
pub(crate) fn wrong_cursor() -> StringErr {
StringErr("wrong cursor".to_owned())
}
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct DbsReader; pub struct DbsReader;
......
...@@ -75,8 +75,9 @@ where ...@@ -75,8 +75,9 @@ where
impl<T> Copy for PageInfo<T> where T: Copy {} impl<T> Copy for PageInfo<T> where T: Copy {}
pub(crate) fn has_next_page< pub(crate) fn has_next_page<
C: std::fmt::Debug + Default + Ord, 'i,
I: DoubleEndedIterator<Item = C>, C: 'static + std::fmt::Debug + Default + Ord,
I: DoubleEndedIterator<Item = &'i C>,
>( >(
mut page_cursors: I, mut page_cursors: I,
last_cursor_opt: Option<C>, last_cursor_opt: Option<C>,
...@@ -92,7 +93,7 @@ pub(crate) fn has_next_page< ...@@ -92,7 +93,7 @@ pub(crate) fn has_next_page<
page_cursors.next() page_cursors.next()
} { } {
//println!("TMP page_end_cursor={:?}", page_end_cursor); //println!("TMP page_end_cursor={:?}", page_end_cursor);
page_end_cursor != last_cursor page_end_cursor != &last_cursor
} else { } else {
page_info.pos.unwrap_or_default() < last_cursor page_info.pos.unwrap_or_default() < last_cursor
} }
...@@ -105,8 +106,9 @@ pub(crate) fn has_next_page< ...@@ -105,8 +106,9 @@ pub(crate) fn has_next_page<
} }
pub(crate) fn has_previous_page< pub(crate) fn has_previous_page<
C: std::fmt::Debug + Default + Ord, 'i,
I: DoubleEndedIterator<Item = C>, C: 'static + std::fmt::Debug + Default + Ord,
I: DoubleEndedIterator<Item = &'i C>,
>( >(
mut page_cursors: I, mut page_cursors: I,
first_cursor_opt: Option<C>, first_cursor_opt: Option<C>,
...@@ -121,7 +123,7 @@ pub(crate) fn has_previous_page< ...@@ -121,7 +123,7 @@ pub(crate) fn has_previous_page<
} else { } else {
page_cursors.next_back() page_cursors.next_back()
} { } {
page_start_cursor != first_cursor page_start_cursor != &first_cursor
} else { } else {
page_info.pos.unwrap_or_default() > first_cursor page_info.pos.unwrap_or_default() > first_cursor
} }
......
...@@ -30,7 +30,7 @@ pub fn all_uds_of_pubkey<B: Backend>( ...@@ -30,7 +30,7 @@ pub fn all_uds_of_pubkey<B: Backend>(
bc_db: &BcV2Db<B>, bc_db: &BcV2Db<B>,
gva_db: &GvaV1Db<B>, gva_db: &GvaV1Db<B>,
pubkey: PublicKey, pubkey: PublicKey,
page_info: PageInfo<u32>, page_info: PageInfo<BlockNumber>,
) -> KvResult<PagedData<UdsWithSum>> { ) -> KvResult<PagedData<UdsWithSum>> {
( (
bc_db.uds_reval(), bc_db.uds_reval(),
...@@ -67,7 +67,7 @@ pub fn all_uds_of_pubkey<B: Backend>( ...@@ -67,7 +67,7 @@ pub fn all_uds_of_pubkey<B: Backend>(
} }
Some(pos) => { Some(pos) => {
if page_info.order { if page_info.order {
blocks_with_ud.iter(U32BE(pos).., move |it| { blocks_with_ud.iter(U32BE(pos.0).., move |it| {
all_uds_of_pubkey_inner::<B, _>( all_uds_of_pubkey_inner::<B, _>(
gva_idty, gva_idty,
page_info, page_info,
...@@ -79,7 +79,7 @@ pub fn all_uds_of_pubkey<B: Backend>( ...@@ -79,7 +79,7 @@ pub fn all_uds_of_pubkey<B: Backend>(
} else { } else {
let last_ud_opt = let last_ud_opt =
blocks_with_ud.iter(.., |it| it.keys().reverse().next_res())?; blocks_with_ud.iter(.., |it| it.keys().reverse().next_res())?;
blocks_with_ud.iter(..=U32BE(pos), move |it| { blocks_with_ud.iter(..=U32BE(pos.0), move |it| {
all_uds_of_pubkey_inner::<B, _>( all_uds_of_pubkey_inner::<B, _>(
gva_idty, gva_idty,
page_info, page_info,
...@@ -99,7 +99,7 @@ pub fn all_uds_of_pubkey<B: Backend>( ...@@ -99,7 +99,7 @@ pub fn all_uds_of_pubkey<B: Backend>(
fn all_uds_of_pubkey_inner<B, I>( fn all_uds_of_pubkey_inner<B, I>(
gva_idty: GvaIdtyDbV1, gva_idty: GvaIdtyDbV1,
page_info: PageInfo<u32>, page_info: PageInfo<BlockNumber>,
blocks_with_ud: I, blocks_with_ud: I,
uds_reval: TxColRo<B::Col, UdsRevalEvent>, uds_reval: TxColRo<B::Col, UdsRevalEvent>,
last_ud_opt: Option<BlockNumber>, last_ud_opt: Option<BlockNumber>,
...@@ -165,8 +165,8 @@ where ...@@ -165,8 +165,8 @@ where
Ok(PagedData { Ok(PagedData {
has_previous_page: has_previous_page( has_previous_page: has_previous_page(
uds_with_sum.uds.iter().map(|(bn, _sa)| bn.0), uds_with_sum.uds.iter().map(|(bn, _sa)| bn),
first_ud.map(|bn| bn.0), first_ud,
page_info, page_info,
true, true,
), ),
...@@ -177,7 +177,7 @@ where ...@@ -177,7 +177,7 @@ where
fn filter_blocks_numbers<I: Iterator<Item = KvResult<BlockNumber>>>( fn filter_blocks_numbers<I: Iterator<Item = KvResult<BlockNumber>>>(
gva_idty: GvaIdtyDbV1, gva_idty: GvaIdtyDbV1,
page_info: PageInfo<u32>, page_info: PageInfo<BlockNumber>,
blocks_with_ud: I, blocks_with_ud: I,
) -> KvResult<Vec<BlockNumber>> { ) -> KvResult<Vec<BlockNumber>> {
let mut is_member_changes = SmallVec::<[BlockNumber; 4]>::new(); let mut is_member_changes = SmallVec::<[BlockNumber; 4]>::new();
...@@ -251,7 +251,7 @@ fn filter_blocks_numbers<I: Iterator<Item = KvResult<BlockNumber>>>( ...@@ -251,7 +251,7 @@ fn filter_blocks_numbers<I: Iterator<Item = KvResult<BlockNumber>>>(
pub fn unspent_uds_of_pubkey<BcDb: BcV2DbReadable>( pub fn unspent_uds_of_pubkey<BcDb: BcV2DbReadable>(
bc_db: &BcDb, bc_db: &BcDb,
pubkey: PublicKey, pubkey: PublicKey,
page_info: PageInfo<u32>, page_info: PageInfo<BlockNumber>,
bn_to_exclude_opt: Option<&BTreeSet<BlockNumber>>, bn_to_exclude_opt: Option<&BTreeSet<BlockNumber>>,
amount_target_opt: Option<SourceAmount>, amount_target_opt: Option<SourceAmount>,
) -> KvResult<PagedData<UdsWithSum>> { ) -> KvResult<PagedData<UdsWithSum>> {
...@@ -264,7 +264,7 @@ pub fn unspent_uds_of_pubkey<BcDb: BcV2DbReadable>( ...@@ -264,7 +264,7 @@ pub fn unspent_uds_of_pubkey<BcDb: BcV2DbReadable>(
let mut blocks_numbers = if let Some(pos) = page_info.pos { let mut blocks_numbers = if let Some(pos) = page_info.pos {
if page_info.order { if page_info.order {
uds.iter( uds.iter(
UdIdV2(pubkey, BlockNumber(pos))..UdIdV2(pubkey, BlockNumber(u32::MAX)), UdIdV2(pubkey, pos)..UdIdV2(pubkey, BlockNumber(u32::MAX)),
|it| { |it| {
let it = it.keys().map_ok(|UdIdV2(_p, bn)| bn); let it = it.keys().map_ok(|UdIdV2(_p, bn)| bn);
if let Some(bn_to_exclude) = bn_to_exclude_opt { if let Some(bn_to_exclude) = bn_to_exclude_opt {
...@@ -276,9 +276,7 @@ pub fn unspent_uds_of_pubkey<BcDb: BcV2DbReadable>( ...@@ -276,9 +276,7 @@ pub fn unspent_uds_of_pubkey<BcDb: BcV2DbReadable>(
}, },
)? )?
} else { } else {
uds.iter( uds.iter(UdIdV2(pubkey, BlockNumber(0))..=UdIdV2(pubkey, pos), |it| {
UdIdV2(pubkey, BlockNumber(0))..=UdIdV2(pubkey, BlockNumber(pos)),
|it| {
let it = it.keys().reverse().map_ok(|UdIdV2(_p, bn)| bn); let it = it.keys().reverse().map_ok(|UdIdV2(_p, bn)| bn);
if let Some(bn_to_exclude) = bn_to_exclude_opt { if let Some(bn_to_exclude) = bn_to_exclude_opt {
it.filter_ok(|bn| !bn_to_exclude.contains(&bn)) it.filter_ok(|bn| !bn_to_exclude.contains(&bn))
...@@ -286,8 +284,7 @@ pub fn unspent_uds_of_pubkey<BcDb: BcV2DbReadable>( ...@@ -286,8 +284,7 @@ pub fn unspent_uds_of_pubkey<BcDb: BcV2DbReadable>(
} else { } else {
it.collect::<KvResult<Vec<_>>>() it.collect::<KvResult<Vec<_>>>()
} }
}, })?
)?
} }
} else if page_info.order { } else if page_info.order {
uds.iter( uds.iter(
...@@ -354,14 +351,14 @@ pub fn unspent_uds_of_pubkey<BcDb: BcV2DbReadable>( ...@@ -354,14 +351,14 @@ pub fn unspent_uds_of_pubkey<BcDb: BcV2DbReadable>(
}; };
Ok(PagedData { Ok(PagedData {
has_previous_page: has_previous_page( has_previous_page: has_previous_page(
uds_with_sum.uds.iter().map(|(bn, _sa)| bn.0), uds_with_sum.uds.iter().map(|(bn, _sa)| bn),
first_ud_opt.map(|bn| bn.0), first_ud_opt,
page_info, page_info,
true, true,
), ),
has_next_page: has_next_page( has_next_page: has_next_page(
uds_with_sum.uds.iter().map(|(bn, _sa)| bn.0), uds_with_sum.uds.iter().map(|(bn, _sa)| bn),
last_ud_opt.map(|bn| bn.0), last_ud_opt,
page_info, page_info,
true, true,
), ),
...@@ -606,7 +603,7 @@ mod tests { ...@@ -606,7 +603,7 @@ mod tests {
&gva_db, &gva_db,
pk, pk,
PageInfo { PageInfo {
pos: Some(50), pos: Some(BlockNumber(50)),
..Default::default() ..Default::default()
}, },
)?; )?;
...@@ -683,7 +680,7 @@ mod tests { ...@@ -683,7 +680,7 @@ mod tests {
&gva_db, &gva_db,
pk, pk,
PageInfo { PageInfo {
pos: Some(55), pos: Some(BlockNumber(55)),
order: false, order: false,
..Default::default() ..Default::default()
}, },
...@@ -750,7 +747,7 @@ mod tests { ...@@ -750,7 +747,7 @@ mod tests {
&bc_db, &bc_db,
pk, pk,
PageInfo { PageInfo {
pos: Some(30), pos: Some(BlockNumber(30)),
..Default::default() ..Default::default()
}, },
None, None,
...@@ -806,7 +803,7 @@ mod tests { ...@@ -806,7 +803,7 @@ mod tests {
&bc_db, &bc_db,
pk, pk,
PageInfo { PageInfo {
pos: Some(40), pos: Some(BlockNumber(40)),
order: false, order: false,
..Default::default() ..Default::default()
}, },
......
...@@ -18,17 +18,50 @@ use duniter_dbs::{GvaUtxoIdDbV1, SourceAmountValV2}; ...@@ -18,17 +18,50 @@ use duniter_dbs::{GvaUtxoIdDbV1, SourceAmountValV2};
use crate::*; use crate::*;
#[derive(Clone, Copy, Debug, Eq, PartialEq)] #[derive(Clone, Copy, Debug, Default, Eq, Ord, PartialEq, PartialOrd)]
pub struct UtxoIdWithBlockNumber(pub UtxoIdV10, pub BlockNumber); pub struct UtxoCursor {
impl std::fmt::Display for UtxoIdWithBlockNumber { pub block_number: BlockNumber,
pub tx_hash: Hash,
pub output_index: u8,
}
impl std::fmt::Display for UtxoCursor {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}:{}:{}", self.1, self.0.tx_hash, self.0.output_index,) write!(
f,
"{}:{}:{}",
self.block_number, self.tx_hash, self.output_index,
)
}
}
impl FromStr for UtxoCursor {
type Err = StringErr;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut s = s.split(':');
let block_number = s
.next()
.ok_or_else(wrong_cursor)?
.parse()
.map_err(|_| wrong_cursor())?;
let tx_hash =
Hash::from_hex(s.next().ok_or_else(wrong_cursor)?).map_err(|_| wrong_cursor())?;
let output_index = s
.next()
.ok_or_else(wrong_cursor)?
.parse()
.map_err(|_| wrong_cursor())?;
Ok(Self {
block_number,
tx_hash,
output_index,
})
} }
} }
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct UtxosWithSum { pub struct UtxosWithSum {
pub utxos: Vec<(UtxoIdWithBlockNumber, SourceAmount)>, pub utxos: Vec<(UtxoCursor, SourceAmount)>,
pub sum: SourceAmount, pub sum: SourceAmount,
} }
...@@ -36,7 +69,7 @@ pub fn find_script_utxos<GvaDb: GvaV1DbReadable, TxsMpDb: TxsMpV2DbReadable>( ...@@ -36,7 +69,7 @@ pub fn find_script_utxos<GvaDb: GvaV1DbReadable, TxsMpDb: TxsMpV2DbReadable>(
gva_db_ro: &GvaDb, gva_db_ro: &GvaDb,
txs_mp_db_ro: &TxsMpDb, txs_mp_db_ro: &TxsMpDb,
amount_target_opt: Option<SourceAmount>, amount_target_opt: Option<SourceAmount>,
page_info: PageInfo<String>, page_info: PageInfo<UtxoCursor>,
script: &WalletScriptV10, script: &WalletScriptV10,
) -> anyhow::Result<PagedData<UtxosWithSum>> { ) -> anyhow::Result<PagedData<UtxosWithSum>> {
let mempool_filter = |k_res: KvResult<GvaUtxoIdDbV1>| match k_res { let mempool_filter = |k_res: KvResult<GvaUtxoIdDbV1>| match k_res {
...@@ -61,13 +94,10 @@ pub fn find_script_utxos<GvaDb: GvaV1DbReadable, TxsMpDb: TxsMpV2DbReadable>( ...@@ -61,13 +94,10 @@ pub fn find_script_utxos<GvaDb: GvaV1DbReadable, TxsMpDb: TxsMpV2DbReadable>(
.iter(k_min..k_max, |it| { .iter(k_min..k_max, |it| {
it.keys().filter_map(mempool_filter).next_res() it.keys().filter_map(mempool_filter).next_res()
})? })?
.map(|gva_utxo_id| { .map(|gva_utxo_id| UtxoCursor {
format!( block_number: BlockNumber(gva_utxo_id.get_block_number()),
"{}:{}:{}", tx_hash: gva_utxo_id.get_tx_hash(),
gva_utxo_id.get_block_number(), output_index: gva_utxo_id.get_output_index(),
gva_utxo_id.get_tx_hash(),
gva_utxo_id.get_output_index()
)
}) })
} else { } else {
None None
...@@ -78,35 +108,29 @@ pub fn find_script_utxos<GvaDb: GvaV1DbReadable, TxsMpDb: TxsMpV2DbReadable>( ...@@ -78,35 +108,29 @@ pub fn find_script_utxos<GvaDb: GvaV1DbReadable, TxsMpDb: TxsMpV2DbReadable>(
.iter(k_min..k_max, |it| { .iter(k_min..k_max, |it| {
it.keys().reverse().filter_map(mempool_filter).next_res() it.keys().reverse().filter_map(mempool_filter).next_res()
})? })?
.map(|gva_utxo_id| { .map(|gva_utxo_id| UtxoCursor {
format!( block_number: BlockNumber(gva_utxo_id.get_block_number()),
"{}:{}:{}", tx_hash: gva_utxo_id.get_tx_hash(),
gva_utxo_id.get_block_number(), output_index: gva_utxo_id.get_output_index(),
gva_utxo_id.get_tx_hash(),
gva_utxo_id.get_output_index()
)
}) })
} else { } else {
None None
}; };
if let Some(ref pos) = page_info.pos { if let Some(ref pos) = page_info.pos {
let mut pos = pos.split(':');
let block_number = pos
.next()
.ok_or_else(|| anyhow::Error::msg("invalid cursor"))?
.parse()?;
let tx_hash = Hash::from_hex(
pos.next()
.ok_or_else(|| anyhow::Error::msg("invalid cursor"))?,
)?;
let output_index = pos
.next()
.ok_or_else(|| anyhow::Error::msg("invalid cursor"))?
.parse()?;
if page_info.order { if page_info.order {
k_min = GvaUtxoIdDbV1::new_(script_hash, block_number, tx_hash, output_index); k_min = GvaUtxoIdDbV1::new_(
script_hash,
pos.block_number.0,
pos.tx_hash,
pos.output_index,
);
} else { } else {
k_max = GvaUtxoIdDbV1::new_(script_hash, block_number, tx_hash, output_index); k_max = GvaUtxoIdDbV1::new_(
script_hash,
pos.block_number.0,
pos.tx_hash,
pos.output_index,
);
} }
} }
let mut sum = SourceAmount::ZERO; let mut sum = SourceAmount::ZERO;
...@@ -118,19 +142,17 @@ pub fn find_script_utxos<GvaDb: GvaV1DbReadable, TxsMpDb: TxsMpV2DbReadable>( ...@@ -118,19 +142,17 @@ pub fn find_script_utxos<GvaDb: GvaV1DbReadable, TxsMpDb: TxsMpV2DbReadable>(
let it = it.filter_map(|entry_res| match entry_res { let it = it.filter_map(|entry_res| match entry_res {
Ok((gva_utxo_id, SourceAmountValV2(utxo_amount))) => { Ok((gva_utxo_id, SourceAmountValV2(utxo_amount))) => {
let tx_hash = gva_utxo_id.get_tx_hash(); let tx_hash = gva_utxo_id.get_tx_hash();
let output_index = gva_utxo_id.get_output_index() as u32; let output_index = gva_utxo_id.get_output_index();
match txs_mp_db_ro match txs_mp_db_ro
.utxos_ids() .utxos_ids()
.contains_key(&UtxoIdDbV2(tx_hash, output_index)) .contains_key(&UtxoIdDbV2(tx_hash, output_index as u32))
{ {
Ok(false) => Some(Ok(( Ok(false) => Some(Ok((
UtxoIdWithBlockNumber( UtxoCursor {
UtxoIdV10 {
tx_hash, tx_hash,
output_index: output_index as usize, output_index,
block_number: BlockNumber(gva_utxo_id.get_block_number()),
}, },
BlockNumber(gva_utxo_id.get_block_number()),
),
utxo_amount, utxo_amount,
))), ))),
Ok(true) => None, Ok(true) => None,
...@@ -218,17 +240,13 @@ pub fn find_script_utxos<GvaDb: GvaV1DbReadable, TxsMpDb: TxsMpV2DbReadable>( ...@@ -218,17 +240,13 @@ pub fn find_script_utxos<GvaDb: GvaV1DbReadable, TxsMpDb: TxsMpV2DbReadable>(
Ok(PagedData { Ok(PagedData {
has_next_page: has_next_page( has_next_page: has_next_page(
utxos utxos.iter().map(|(utxo_id_with_bn, _sa)| utxo_id_with_bn),
.iter()
.map(|(utxo_id_with_bn, _sa)| utxo_id_with_bn.to_string()),
last_cursor_opt, last_cursor_opt,
page_info.clone(), page_info,
order, order,
), ),
has_previous_page: has_previous_page( has_previous_page: has_previous_page(
utxos utxos.iter().map(|(utxo_id_with_bn, _sa)| utxo_id_with_bn),
.iter()
.map(|(utxo_id_with_bn, _sa)| utxo_id_with_bn.to_string()),
first_cursor_opt, first_cursor_opt,
page_info, page_info,
order, order,
...@@ -281,7 +299,7 @@ mod tests { ...@@ -281,7 +299,7 @@ mod tests {
utxos, utxos,
vec![ vec![
( (
UtxoIdWithBlockNumber( UtxoCursor(
UtxoIdV10 { UtxoIdV10 {
tx_hash: Hash::default(), tx_hash: Hash::default(),
output_index: 0 output_index: 0
...@@ -291,7 +309,7 @@ mod tests { ...@@ -291,7 +309,7 @@ mod tests {
SourceAmount::with_base0(50) SourceAmount::with_base0(50)
), ),
( (
UtxoIdWithBlockNumber( UtxoCursor(
UtxoIdV10 { UtxoIdV10 {
tx_hash: Hash::default(), tx_hash: Hash::default(),
output_index: 1 output_index: 1
...@@ -324,7 +342,7 @@ mod tests { ...@@ -324,7 +342,7 @@ mod tests {
assert_eq!( assert_eq!(
utxos, utxos,
vec![( vec![(
UtxoIdWithBlockNumber( UtxoCursor(
UtxoIdV10 { UtxoIdV10 {
tx_hash: Hash::default(), tx_hash: Hash::default(),
output_index: 2 output_index: 2
...@@ -359,23 +377,19 @@ mod tests { ...@@ -359,23 +377,19 @@ mod tests {
utxos, utxos,
vec![ vec![
( (
UtxoIdWithBlockNumber( UtxoCursor {
UtxoIdV10 { block_number: BlockNumber(0),
tx_hash: Hash::default(), tx_hash: Hash::default(),
output_index: 2 output_index: 2,
}, },
BlockNumber(0),
),
SourceAmount::with_base0(120) SourceAmount::with_base0(120)
), ),
( (
UtxoIdWithBlockNumber( UtxoCursor {
UtxoIdV10 { block_number: BlockNumber(0),
tx_hash: Hash::default(), tx_hash: Hash::default(),
output_index: 1 output_index: 1,
}, },
BlockNumber(0),
),
SourceAmount::with_base0(80) SourceAmount::with_base0(80)
) )
] ]
......
...@@ -41,7 +41,7 @@ use crate::entities::{ ...@@ -41,7 +41,7 @@ use crate::entities::{
}; };
use crate::inputs::{TxIssuer, TxRecipient, UdsFilter}; use crate::inputs::{TxIssuer, TxRecipient, UdsFilter};
use crate::inputs_validators::TxCommentValidator; use crate::inputs_validators::TxCommentValidator;
use crate::pagination::{PaginationWithIntCursor, PaginationWithStrCursor}; use crate::pagination::Pagination;
use crate::schema::{GraphQlSchema, SchemaData}; use crate::schema::{GraphQlSchema, SchemaData};
#[cfg(test)] #[cfg(test)]
use crate::tests::create_dbs_reader; use crate::tests::create_dbs_reader;
......
use std::str::FromStr;
// Copyright (C) 2020 Éloïs SANCHEZ. // Copyright (C) 2020 Éloïs SANCHEZ.
// //
// This program is free software: you can redistribute it and/or modify // This program is free software: you can redistribute it and/or modify
...@@ -27,34 +29,23 @@ impl Default for Order { ...@@ -27,34 +29,23 @@ impl Default for Order {
} }
#[derive(Default, async_graphql::InputObject)] #[derive(Default, async_graphql::InputObject)]
pub(crate) struct PaginationWithStrCursor { pub(crate) struct Pagination {
/// Identifier of the 1st desired element (of the last one in descending order) /// Identifier of the 1st desired element (of the last one in descending order)
cursor: Option<String>, cursor: Option<String>,
ord: Order, ord: Order,
page_size: Option<u32>, page_size: Option<u32>,
} }
impl PaginationWithStrCursor { impl Pagination {
pub(crate) fn convert_to_page_info(self) -> duniter_dbs_read_ops::PageInfo<String> { pub(crate) fn convert_to_page_info<
duniter_dbs_read_ops::PageInfo::new( E: 'static + std::error::Error + Send + Sync,
self.cursor, T: FromStr<Err = E>,
self.ord == Order::Asc, >(
self.page_size.map(|n| n as usize), self,
) ) -> anyhow::Result<duniter_dbs_read_ops::PageInfo<T>> {
} Ok(duniter_dbs_read_ops::PageInfo::new(
} self.cursor.map(|c| T::from_str(&c)).transpose()?,
#[derive(Clone, Copy, Default, async_graphql::InputObject)]
pub(crate) struct PaginationWithIntCursor {
cursor: Option<u32>,
ord: Order,
page_size: Option<u32>,
}
impl PaginationWithIntCursor {
pub(crate) fn convert_to_page_info(self) -> duniter_dbs_read_ops::PageInfo<u32> {
duniter_dbs_read_ops::PageInfo::new(
self.cursor,
self.ord == Order::Asc, self.ord == Order::Asc,
self.page_size.map(|n| n as usize), self.page_size.map(|n| n as usize),
) ))
} }
} }
...@@ -46,10 +46,10 @@ impl UdsQuery { ...@@ -46,10 +46,10 @@ impl UdsQuery {
ctx: &async_graphql::Context<'_>, ctx: &async_graphql::Context<'_>,
#[graphql(desc = "Ed25519 public key on base 58 representation")] pubkey: String, #[graphql(desc = "Ed25519 public key on base 58 representation")] pubkey: String,
#[graphql(default)] filter: UdsFilter, #[graphql(default)] filter: UdsFilter,
#[graphql(desc = "pagination", default)] pagination: PaginationWithIntCursor, #[graphql(desc = "pagination", default)] pagination: Pagination,
#[graphql(desc = "Amount needed")] amount: Option<i64>, #[graphql(desc = "Amount needed")] amount: Option<i64>,
) -> async_graphql::Result<Connection<usize, UdGva, Sum, EmptyFields>> { ) -> async_graphql::Result<Connection<usize, UdGva, Sum, EmptyFields>> {
let pagination = PaginationWithIntCursor::convert_to_page_info(pagination); let pagination = Pagination::convert_to_page_info(pagination)?;
let pubkey = PublicKey::from_base58(&pubkey)?; let pubkey = PublicKey::from_base58(&pubkey)?;
......
...@@ -17,7 +17,7 @@ use crate::*; ...@@ -17,7 +17,7 @@ use crate::*;
use async_graphql::connection::*; use async_graphql::connection::*;
use duniter_dbs::GvaV1DbReadable; use duniter_dbs::GvaV1DbReadable;
use duniter_dbs_read_ops::{ use duniter_dbs_read_ops::{
utxos::{UtxoIdWithBlockNumber, UtxosWithSum}, utxos::{UtxoCursor, UtxosWithSum},
PagedData, PagedData,
}; };
...@@ -30,10 +30,10 @@ impl UtxosQuery { ...@@ -30,10 +30,10 @@ impl UtxosQuery {
&self, &self,
ctx: &async_graphql::Context<'_>, ctx: &async_graphql::Context<'_>,
#[graphql(desc = "DUBP wallet script")] script: String, #[graphql(desc = "DUBP wallet script")] script: String,
#[graphql(desc = "pagination", default)] pagination: PaginationWithStrCursor, #[graphql(desc = "pagination", default)] pagination: Pagination,
#[graphql(desc = "Amount needed")] amount: Option<i64>, #[graphql(desc = "Amount needed")] amount: Option<i64>,
) -> async_graphql::Result<Connection<String, UtxoGva, Sum, EmptyFields>> { ) -> async_graphql::Result<Connection<String, UtxoGva, Sum, EmptyFields>> {
let pagination = PaginationWithStrCursor::convert_to_page_info(pagination); let pagination = Pagination::convert_to_page_info(pagination)?;
let script = dubp::documents_parser::wallet_script_from_str(&script)?; let script = dubp::documents_parser::wallet_script_from_str(&script)?;
...@@ -61,11 +61,11 @@ impl UtxosQuery { ...@@ -61,11 +61,11 @@ impl UtxosQuery {
&script, &script,
)?; )?;
let mut times = Vec::with_capacity(paged_data.data.utxos.len()); let mut times = Vec::with_capacity(paged_data.data.utxos.len());
for (UtxoIdWithBlockNumber(_utxo_id, bn), _sa) in &paged_data.data.utxos { for (UtxoCursor { block_number, .. }, _sa) in &paged_data.data.utxos {
times.push( times.push(
dbs.gva_db dbs.gva_db
.blockchain_time() .blockchain_time()
.get(&U32BE(bn.0))? .get(&U32BE(block_number.0))?
.unwrap_or_else(|| unreachable!()), .unwrap_or_else(|| unreachable!()),
); );
} }
...@@ -87,15 +87,15 @@ impl UtxosQuery { ...@@ -87,15 +87,15 @@ impl UtxosQuery {
}, },
); );
conn.append(utxos.into_iter().zip(times.into_iter()).map( conn.append(utxos.into_iter().zip(times.into_iter()).map(
|((utxo_id_with_bn, source_amount), blockchain_time)| { |((utxo_cursor, source_amount), blockchain_time)| {
Edge::new( Edge::new(
utxo_id_with_bn.to_string(), utxo_cursor.to_string(),
UtxoGva { UtxoGva {
amount: source_amount.amount(), amount: source_amount.amount(),
base: source_amount.base(), base: source_amount.base(),
tx_hash: utxo_id_with_bn.0.tx_hash.to_hex(), tx_hash: utxo_cursor.tx_hash.to_hex(),
output_index: utxo_id_with_bn.0.output_index as u32, output_index: utxo_cursor.output_index as u32,
written_block: (utxo_id_with_bn.1).0, written_block: utxo_cursor.block_number.0,
written_time: blockchain_time, written_time: blockchain_time,
}, },
) )
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment