use std::convert::TryFrom;
use diesel::{dsl::count_star, prelude::*};
use crate::error::InternalError;
use crate::registry::{diesel::schema::splinter_nodes, MetadataPredicate, RegistryError};
use super::{apply_predicate_filters, RegistryOperations};
pub(in crate::registry::diesel) trait RegistryCountNodesOperation {
fn count_nodes(&self, predicates: &[MetadataPredicate]) -> Result<u32, RegistryError>;
}
impl<'a, C> RegistryCountNodesOperation for RegistryOperations<'a, C>
where
C: diesel::Connection,
i64: diesel::deserialize::FromSql<diesel::sql_types::BigInt, C::Backend>,
{
fn count_nodes(&self, predicates: &[MetadataPredicate]) -> Result<u32, RegistryError> {
if predicates.is_empty() {
let count = splinter_nodes::table
.count()
.get_result::<i64>(self.conn)?;
Ok(u32::try_from(count).map_err(|_| {
RegistryError::InternalError(InternalError::with_message(
"The number of nodes is larger than the max u32".to_string(),
))
})?)
} else {
let mut query = splinter_nodes::table
.into_boxed()
.select(splinter_nodes::all_columns);
query = apply_predicate_filters(query, predicates);
let count = query.select(count_star()).first::<i64>(self.conn)?;
Ok(u32::try_from(count).map_err(|_| {
RegistryError::InternalError(InternalError::with_message(
"The number of nodes is larger than the max u32".to_string(),
))
})?)
}
}
}