use std::num::NonZeroUsize;
use miden_node_db::sqlite::{ReadTx, Row};
use miden_protocol::Word;
use miden_protocol::account::AccountId;
use crate::db::queries::VALID_FOREVER;
use crate::errors::DatabaseError;
const SQL_FIRST_PAGE: &str = include_str!("select_account_commitments_page.sql");
const SQL_AFTER_CURSOR: &str = include_str!("select_account_commitments_page_after.sql");
#[derive(Debug)]
pub struct AccountCommitmentsPage {
pub commitments: Vec<(AccountId, Word)>,
pub next_cursor: Option<AccountId>,
}
pub(crate) fn select_account_commitments_paged(
tx: &ReadTx<'_>,
page_size: NonZeroUsize,
after_account_id: Option<AccountId>,
) -> Result<AccountCommitmentsPage, DatabaseError> {
let limit = i64::try_from(page_size.get() + 1).expect("page size fits within i64");
let mut commitments = match after_account_id {
Some(cursor) => {
tx.query(SQL_AFTER_CURSOR, &[&limit, &VALID_FOREVER, &cursor], commitment_from_row)?
},
None => tx.query(SQL_FIRST_PAGE, &[&limit, &VALID_FOREVER], commitment_from_row)?,
};
let next_cursor = if commitments.len() > page_size.get() {
commitments.pop(); commitments.last().map(|(id, _)| *id)
} else {
None
};
Ok(AccountCommitmentsPage { commitments, next_cursor })
}
fn commitment_from_row(row: &Row<'_>) -> Result<(AccountId, Word), miden_node_db::DatabaseError> {
Ok((row.get::<AccountId>(0)?, row.get::<Word>(1)?))
}