use sqlx::Row;
use tollgate_core::AccountId;
use tollgate_store::StoreError;
use crate::{
ACTIVE_LEASE_SUM_SQL, DUE_PERIODS_SQL, PostgresStore, RECLAIM_DUE_LEASES_SQL, id_bytes,
instant::StoredInstant, storage,
};
pub async fn explain_active_lease_sum(
store: &PostgresStore,
account: AccountId,
) -> Result<String, StoreError> {
sqlx::raw_sql("ANALYZE tollgate_leases")
.execute(&store.pool)
.await
.map_err(storage)?;
let rows = sqlx::query(&format!("EXPLAIN {ACTIVE_LEASE_SUM_SQL}"))
.bind(id_bytes(account.0))
.fetch_all(&store.pool)
.await
.map_err(storage)?;
Ok(rows
.iter()
.map(|row| row.get::<String, _>(0))
.collect::<Vec<_>>()
.join("\n"))
}
pub async fn explain_reclaim_due_leases(
store: &PostgresStore,
cutoff: jiff::Timestamp,
limit: i64,
) -> Result<String, StoreError> {
let cutoff = StoredInstant::from(cutoff);
sqlx::raw_sql("ANALYZE tollgate_leases")
.execute(&store.pool)
.await
.map_err(storage)?;
let rows = sqlx::query(&format!("EXPLAIN {RECLAIM_DUE_LEASES_SQL}"))
.bind(cutoff.micros)
.bind(cutoff.submicro_nanos)
.bind(limit)
.fetch_all(&store.pool)
.await
.map_err(storage)?;
Ok(plan_text(&rows))
}
pub async fn explain_due_periods(
store: &PostgresStore,
period: &str,
boundary_us: i64,
limit: i64,
) -> Result<String, StoreError> {
sqlx::raw_sql("ANALYZE tollgate_accounts")
.execute(&store.pool)
.await
.map_err(storage)?;
let rows = sqlx::query(&format!("EXPLAIN {DUE_PERIODS_SQL}"))
.bind(period)
.bind(boundary_us)
.bind(limit)
.fetch_all(&store.pool)
.await
.map_err(storage)?;
Ok(plan_text(&rows))
}
fn plan_text(rows: &[sqlx::postgres::PgRow]) -> String {
rows.iter()
.map(|row| row.get::<String, _>(0))
.collect::<Vec<_>>()
.join("\n")
}
pub async fn truncate_all(store: &PostgresStore) -> Result<(), StoreError> {
sqlx::raw_sql(
"TRUNCATE tollgate_credential_keys, tollgate_usage_events, tollgate_leases, \
tollgate_snapshots, tollgate_accounts CASCADE",
)
.execute(&store.pool)
.await
.map_err(storage)?;
Ok(())
}
pub mod issuance_sql {
pub const ACCOUNT_LOCK: &str = crate::ACCOUNT_LOCK_SQL;
pub const LIVE_KEY_COUNT: &str = crate::LIVE_KEY_COUNT_SQL;
}
#[must_use]
pub fn pool(store: &PostgresStore) -> sqlx::PgPool {
store.pool.clone()
}