use surrealdb::opt::IntoQuery;
use surrealqlx::surrql;
use crate::{db::queries::parse_query, errors::Error};
#[derive(Debug, serde::Deserialize, PartialEq, Eq, Clone, Copy)]
pub struct Count {
count: u64,
}
impl Count {
#[cfg(test)]
pub const fn new(count: u64) -> Self {
Self { count }
}
pub async fn count<C: surrealdb::Connection>(
db: &surrealdb::Surreal<C>,
table: &'static str,
) -> Result<u64, Error> {
let result: Option<Self> = db.query(count()).bind(("table", table)).await?.take(0)?;
Ok(result.map_or_else(
|| {
log::warn!("When counting entries in table {table}, no count was returned",);
0
},
|c| c.count,
))
}
pub async fn count_orphaned<C: surrealdb::Connection>(
db: &surrealdb::Surreal<C>,
table: &str,
relation: &str,
) -> Result<u64, Error> {
let result: Option<Self> = db.query(count_orphaned(table, relation)).await?.take(0)?;
Ok(result.map_or_else(
|| {
log::warn!(
"When counting orphaned entries in table {table}, no count was returned",
);
0
},
|c| c.count,
))
}
pub async fn count_orphaned_both<C: surrealdb::Connection>(
db: &surrealdb::Surreal<C>,
table: &str,
relation1: &str,
relation2: &str,
) -> Result<u64, Error> {
let result: Option<Self> = db
.query(count_orphaned_both(table, relation1, relation2))
.await?
.take(0)?;
Ok(result.map_or_else(
|| {
log::warn!(
"When counting orphaned entries in table {table}, no count was returned",
);
0
},
|c| c.count,
))
}
}
#[must_use]
pub const fn count() -> impl IntoQuery {
surrql!("SELECT count() FROM type::table($table) GROUP ALL")
}
#[must_use]
pub fn count_orphaned<Table: AsRef<str>, Rel: AsRef<str>>(
table: Table,
rel: Rel,
) -> impl IntoQuery {
fn count_orphaned_statement(table: &str, rel: &str) -> impl IntoQuery + use<> {
parse_query(format!(
"SELECT count() FROM {table} WHERE count(->{rel}) = 0 GROUP ALL"
))
}
count_orphaned_statement(table.as_ref(), rel.as_ref())
}
#[must_use]
pub fn count_orphaned_both<Table: AsRef<str>, Rel1: AsRef<str>, Rel2: AsRef<str>>(
table: Table,
rel1: Rel1,
rel2: Rel2,
) -> impl IntoQuery {
fn count_orphaned_both_statement(
table: &str,
rel1: &str,
rel2: &str,
) -> impl IntoQuery + use<> {
parse_query(format!(
"SELECT count() FROM {table} WHERE count(->{rel1}) = 0 AND count(->{rel2}) = 0 GROUP ALL"
))
}
count_orphaned_both_statement(table.as_ref(), rel1.as_ref(), rel2.as_ref())
}
#[must_use]
#[inline]
pub const fn read_many() -> impl IntoQuery {
surrql!("SELECT * FROM $ids")
}
#[must_use]
pub const fn read_rand() -> impl IntoQuery {
surrql!(
"SELECT type::fields($fields) FROM type::table($table) ORDER BY RAND() LIMIT type::int($limit)"
)
}