use serde_json::Value;
use vantage_core::{Result, error};
use vantage_table::table::Table;
use vantage_types::Entity;
use crate::graphql::api::{GraphqlApi, GraphqlReply};
use crate::graphql::impls::table_source::select_from_table;
use crate::graphql::types::AnyGraphqlType;
pub(crate) async fn aggregate_count<E: Entity<AnyGraphqlType>>(
table: &Table<GraphqlApi, E>,
) -> Result<i64> {
let api = table.data_source();
let field = api.count_field(table.table_name());
let rendered = select_from_table(table)
.render_aggregate_count(&field)
.await?;
match api
.post_graphql_reply(&rendered.query, &rendered.variables)
.await?
{
GraphqlReply::Data(data) => parse_count(&data, &field),
GraphqlReply::Errors(errors) => Err(error!(
"GraphQL server rejected the aggregate count; set `count: list` to count by listing rows",
field = field,
errors = errors
)),
}
}
fn parse_count(data: &Value, field: &str) -> Result<i64> {
data.get(field)
.and_then(|v| v.get("aggregate"))
.and_then(|v| v.get("count"))
.and_then(Value::as_i64)
.ok_or_else(|| {
error!(
"GraphQL aggregate response missing aggregate.count",
field = field,
got = data.to_string()
)
})
}