use diesel::prelude::*;
use miden_node_db::DatabaseError;
use miden_protocol::account::{Account, AccountId};
use miden_protocol::transaction::TransactionId;
use crate::db::models::conv as conversions;
use crate::db::schema;
#[derive(Debug, Clone, Insertable)]
#[diesel(table_name = schema::accounts)]
#[diesel(check_for_backend(diesel::sqlite::Sqlite))]
pub struct AccountInsert {
pub account_id: Vec<u8>,
pub account_data: Vec<u8>,
pub last_tx_id: Vec<u8>,
}
#[derive(Debug, Clone, Queryable, Selectable)]
#[diesel(table_name = schema::accounts)]
#[diesel(check_for_backend(diesel::sqlite::Sqlite))]
pub struct AccountRow {
pub account_data: Vec<u8>,
}
pub fn upsert_account(
conn: &mut SqliteConnection,
account_id: AccountId,
account: &Account,
last_tx_id: TransactionId,
) -> Result<(), DatabaseError> {
let row = AccountInsert {
account_id: conversions::account_id_to_bytes(account_id),
account_data: conversions::account_to_bytes(account),
last_tx_id: conversions::transaction_id_to_bytes(&last_tx_id),
};
diesel::insert_into(schema::accounts::table)
.values(&row)
.on_conflict(schema::accounts::account_id)
.do_update()
.set((
schema::accounts::account_data.eq(&row.account_data),
schema::accounts::last_tx_id.eq(&row.last_tx_id),
))
.execute(conn)?;
Ok(())
}
pub fn account_last_tx(
conn: &mut SqliteConnection,
account_id: AccountId,
) -> Result<Option<TransactionId>, DatabaseError> {
let account_id_bytes = conversions::account_id_to_bytes(account_id);
let last_tx_id: Option<Vec<u8>> = schema::accounts::table
.find(&account_id_bytes)
.select(schema::accounts::last_tx_id)
.first(conn)
.optional()?;
last_tx_id
.map(|bytes| conversions::transaction_id_from_bytes(&bytes))
.transpose()
}
pub fn get_account(
conn: &mut SqliteConnection,
account_id: AccountId,
) -> Result<Option<Account>, DatabaseError> {
let account_id_bytes = conversions::account_id_to_bytes(account_id);
let row: Option<AccountRow> = schema::accounts::table
.find(&account_id_bytes)
.select(AccountRow::as_select())
.first(conn)
.optional()?;
row.map(|AccountRow { account_data }| conversions::account_from_bytes(&account_data))
.transpose()
}