use miden_node_db::sqlite::ReadTx;
use miden_protocol::Felt;
use miden_protocol::account::{Account, AccountCode, AccountId};
use miden_protocol::asset::{Asset, AssetVault};
use crate::db::queries::{VALID_FOREVER, select_latest_storage};
use crate::errors::DatabaseError;
const SQL_NONCE_AND_CODE: &str = include_str!("select_account_nonce_and_code.sql");
const SQL_VAULT: &str = include_str!("select_account_vault.sql");
pub(crate) fn select_full_account(
tx: &ReadTx<'_>,
account_id: AccountId,
) -> Result<Account, DatabaseError> {
let (nonce, code) = tx
.query(SQL_NONCE_AND_CODE, &[&account_id, &VALID_FOREVER], |row| {
Ok((row.get::<Option<Felt>>(0)?, row.get::<AccountCode>(1)?))
})?
.into_iter()
.next()
.ok_or(DatabaseError::AccountNotFoundInDb(account_id))?;
let nonce = nonce.ok_or_else(|| {
DatabaseError::DataCorrupted(format!("No nonce found for account {account_id}"))
})?;
let storage = select_latest_storage(tx, account_id)?;
let assets = tx
.query(SQL_VAULT, &[&account_id, &VALID_FOREVER], |row| row.get::<Option<Asset>>(0))?
.into_iter()
.flatten()
.collect::<Vec<_>>();
let vault = AssetVault::new(&assets)?;
Ok(Account::new(account_id, vault, storage, code, nonce, None)?)
}