mod paging;
mod partial_window;
use crate::{
db::{
ExplainAggregateTerminalPlan, ExplainExecutionNodeDescriptor,
query::{AggregateExpr, CompareOp, ExplainPlan, FilterExpr, QueryTracePlan},
response::{QueryResponse, Response},
session::macros::{impl_session_materialization_methods, impl_session_query_shape_methods},
},
error::Error,
traits::{Entity, SingletonEntity},
types::{Decimal, Id},
value::InputValue,
};
use icydb_core as core;
pub use partial_window::PartialWindowLoadQuery;
pub struct FluentLoadQuery<'a, E: Entity> {
pub(crate) inner: core::db::FluentLoadQuery<'a, E>,
}
impl<'a, E: Entity> FluentLoadQuery<'a, E> {
#[cfg(feature = "diagnostics")]
#[doc(hidden)]
pub fn execute_with_attribution(
&self,
) -> Result<(QueryResponse<E>, crate::db::QueryExecutionAttribution), Error>
where
E: Entity,
{
let (result, attribution) = self.inner.execute_with_attribution()?;
Ok((QueryResponse::from_core(result), attribution))
}
impl_session_query_shape_methods!();
#[must_use]
pub fn partial_window(self, limit: u32) -> PartialWindowLoadQuery<'a, E> {
PartialWindowLoadQuery {
inner: self.inner.partial_window(limit),
}
}
#[must_use]
pub fn trusted_read_unchecked(mut self) -> Self {
self.inner = self.inner.trusted_read_unchecked();
self
}
pub fn group_by(mut self, field: impl AsRef<str>) -> Result<Self, Error> {
self.inner = self.inner.group_by(field)?;
Ok(self)
}
#[must_use]
pub fn aggregate(mut self, aggregate: AggregateExpr) -> Self {
self.inner = self.inner.aggregate(aggregate);
self
}
#[must_use]
pub fn grouped_limits(mut self, max_groups: u64, max_group_bytes: u64) -> Self {
self.inner = self.inner.grouped_limits(max_groups, max_group_bytes);
self
}
pub fn having_group(
mut self,
field: impl AsRef<str>,
op: CompareOp,
value: InputValue,
) -> Result<Self, Error> {
self.inner = self.inner.having_group(field, op, value)?;
Ok(self)
}
pub fn having_aggregate(
mut self,
aggregate_index: usize,
op: CompareOp,
value: InputValue,
) -> Result<Self, Error> {
self.inner = self.inner.having_aggregate(aggregate_index, op, value)?;
Ok(self)
}
impl_session_materialization_methods!();
pub fn execute_rows(&self) -> Result<Response<E>, Error>
where
E: Entity,
{
Ok(Response::from_core(self.inner.execute_rows()?))
}
pub fn plan_hash_hex(&self) -> Result<String, Error> {
Ok(self.inner.plan_hash_hex()?)
}
pub fn trace(&self) -> Result<QueryTracePlan, Error> {
Ok(self.inner.trace()?)
}
pub fn explain(&self) -> Result<ExplainPlan, Error> {
Ok(self.inner.explain()?)
}
pub fn exists(&self) -> Result<bool, Error>
where
E: Entity,
{
Ok(self.inner.exists()?)
}
#[cfg(feature = "diagnostics")]
#[doc(hidden)]
pub fn exists_with_attribution(
&self,
) -> Result<(bool, crate::db::FluentTerminalExecutionAttribution), Error>
where
E: Entity,
{
Ok(self.inner.exists_with_attribution()?)
}
pub fn explain_exists(&self) -> Result<ExplainAggregateTerminalPlan, Error>
where
E: Entity,
{
Ok(self.inner.explain_exists()?)
}
pub fn not_exists(&self) -> Result<bool, Error>
where
E: Entity,
{
Ok(self.inner.not_exists()?)
}
pub fn collect_complete(&self) -> Result<Vec<E>, Error>
where
E: Entity,
{
Ok(self.inner.collect_complete()?)
}
#[cfg(feature = "diagnostics")]
#[doc(hidden)]
pub fn collect_complete_with_attribution(
&self,
) -> Result<(Vec<E>, crate::db::QueryExecutionAttribution), Error>
where
E: Entity,
{
Ok(self.inner.collect_complete_with_attribution()?)
}
pub fn count_exact(&self) -> Result<u32, Error>
where
E: Entity,
{
Ok(self.inner.count_exact()?)
}
pub fn explain_count_exact(&self) -> Result<ExplainAggregateTerminalPlan, Error>
where
E: Entity,
{
Ok(self.inner.explain_count_exact()?)
}
#[cfg(feature = "diagnostics")]
#[doc(hidden)]
pub fn count_exact_with_attribution(
&self,
) -> Result<(u32, crate::db::FluentTerminalExecutionAttribution), Error>
where
E: Entity,
{
Ok(self.inner.count_exact_with_attribution()?)
}
pub fn explain_not_exists(&self) -> Result<ExplainAggregateTerminalPlan, Error>
where
E: Entity,
{
Ok(self.inner.explain_not_exists()?)
}
pub fn explain_execution(&self) -> Result<ExplainExecutionNodeDescriptor, Error>
where
E: Entity,
{
Ok(self.inner.explain_execution()?)
}
pub fn explain_execution_text(&self) -> Result<String, Error>
where
E: Entity,
{
Ok(self.inner.explain_execution_text()?)
}
pub fn explain_execution_json(&self) -> Result<String, Error>
where
E: Entity,
{
Ok(self.inner.explain_execution_json()?)
}
pub fn explain_execution_verbose(&self) -> Result<String, Error>
where
E: Entity,
{
Ok(self.inner.explain_execution_verbose()?)
}
pub fn min_id_exact(&self) -> Result<Option<Id<E>>, Error>
where
E: Entity,
{
Ok(self.inner.min_id_exact()?)
}
pub fn explain_min_id_exact(&self) -> Result<ExplainAggregateTerminalPlan, Error>
where
E: Entity,
{
Ok(self.inner.explain_min_id_exact()?)
}
pub fn min_exact_by(&self, field: impl AsRef<str>) -> Result<Option<Id<E>>, Error>
where
E: Entity,
{
Ok(self.inner.min_exact_by(field)?)
}
pub fn explain_min_exact_by(
&self,
field: impl AsRef<str>,
) -> Result<ExplainAggregateTerminalPlan, Error>
where
E: Entity,
{
Ok(self.inner.explain_min_exact_by(field)?)
}
pub fn max_id_exact(&self) -> Result<Option<Id<E>>, Error>
where
E: Entity,
{
Ok(self.inner.max_id_exact()?)
}
pub fn explain_max_id_exact(&self) -> Result<ExplainAggregateTerminalPlan, Error>
where
E: Entity,
{
Ok(self.inner.explain_max_id_exact()?)
}
pub fn max_exact_by(&self, field: impl AsRef<str>) -> Result<Option<Id<E>>, Error>
where
E: Entity,
{
Ok(self.inner.max_exact_by(field)?)
}
pub fn explain_max_exact_by(
&self,
field: impl AsRef<str>,
) -> Result<ExplainAggregateTerminalPlan, Error>
where
E: Entity,
{
Ok(self.inner.explain_max_exact_by(field)?)
}
pub fn sum_exact(&self, field: impl AsRef<str>) -> Result<Option<Decimal>, Error>
where
E: Entity,
{
Ok(self.inner.sum_exact(field)?)
}
pub fn explain_sum_exact(
&self,
field: impl AsRef<str>,
) -> Result<ExplainAggregateTerminalPlan, Error>
where
E: Entity,
{
Ok(self.inner.explain_sum_exact(field)?)
}
pub fn avg_exact(&self, field: impl AsRef<str>) -> Result<Option<Decimal>, Error>
where
E: Entity,
{
Ok(self.inner.avg_exact(field)?)
}
pub fn explain_avg_exact(
&self,
field: impl AsRef<str>,
) -> Result<ExplainAggregateTerminalPlan, Error>
where
E: Entity,
{
Ok(self.inner.explain_avg_exact(field)?)
}
pub fn try_one(&self) -> Result<Option<E>, Error>
where
E: Entity,
{
icydb_core::db::ResponseCardinalityExt::try_entity(self.inner.execute_rows()?)
.map_err(Into::into)
}
}
impl<E: Entity + SingletonEntity> FluentLoadQuery<'_, E> {
#[must_use]
pub fn singleton(mut self) -> Self
where
E::Key: Default,
{
self.inner = self.inner.singleton();
self
}
}