icydb_core/db/query/
dynamic.rs1use crate::db::query::{
7 builder::AggregateExpr,
8 expr::{FilterExpr, OrderTerm},
9};
10
11#[derive(Clone, Debug)]
20pub struct DynamicQuery {
21 entity: String,
22 filter: Option<FilterExpr>,
23 order: Vec<OrderTerm>,
24 fields: Vec<String>,
25 limit: Option<u32>,
26 group_fields: Vec<String>,
27 aggregates: Vec<AggregateExpr>,
28 grouped_limits: Option<(u32, u32)>,
29 cursor: Option<String>,
30}
31
32impl DynamicQuery {
33 #[must_use]
35 pub fn new(entity: impl Into<String>) -> Self {
36 Self {
37 entity: entity.into(),
38 filter: None,
39 order: Vec::new(),
40 fields: Vec::new(),
41 limit: None,
42 group_fields: Vec::new(),
43 aggregates: Vec::new(),
44 grouped_limits: None,
45 cursor: None,
46 }
47 }
48
49 #[must_use]
51 pub fn filter(mut self, filter: impl Into<FilterExpr>) -> Self {
52 self.filter = Some(filter.into());
53 self
54 }
55
56 #[must_use]
58 pub fn order_by(mut self, order: OrderTerm) -> Self {
59 self.order.push(order);
60 self
61 }
62
63 #[must_use]
68 pub fn select<I, S>(mut self, fields: I) -> Self
69 where
70 I: IntoIterator<Item = S>,
71 S: Into<String>,
72 {
73 self.fields = fields.into_iter().map(Into::into).collect();
74 self
75 }
76
77 #[must_use]
79 pub const fn limit(mut self, limit: u32) -> Self {
80 self.limit = Some(limit);
81 self
82 }
83
84 #[must_use]
86 pub fn group_by(mut self, field: impl Into<String>) -> Self {
87 self.group_fields.push(field.into());
88 self
89 }
90
91 #[must_use]
93 pub fn aggregate(mut self, aggregate: AggregateExpr) -> Self {
94 self.aggregates.push(aggregate);
95 self
96 }
97
98 #[must_use]
103 pub const fn grouped_limits(mut self, max_groups: u32, max_group_bytes: u32) -> Self {
104 self.grouped_limits = Some((max_groups, max_group_bytes));
105 self
106 }
107
108 #[must_use]
110 pub fn cursor(mut self, cursor: impl Into<String>) -> Self {
111 self.cursor = Some(cursor.into());
112 self
113 }
114
115 pub(in crate::db) const fn entity(&self) -> &str {
116 self.entity.as_str()
117 }
118
119 pub(in crate::db) const fn filter_expr(&self) -> Option<&FilterExpr> {
120 self.filter.as_ref()
121 }
122
123 pub(in crate::db) const fn order_terms(&self) -> &[OrderTerm] {
124 self.order.as_slice()
125 }
126
127 pub(in crate::db) const fn selected_fields(&self) -> &[String] {
128 self.fields.as_slice()
129 }
130
131 pub(in crate::db) const fn row_limit(&self) -> Option<u32> {
132 self.limit
133 }
134
135 pub(in crate::db) const fn has_grouping(&self) -> bool {
136 !self.group_fields.is_empty() || !self.aggregates.is_empty()
137 }
138
139 pub(in crate::db) const fn group_fields(&self) -> &[String] {
140 self.group_fields.as_slice()
141 }
142
143 pub(in crate::db) const fn aggregates(&self) -> &[AggregateExpr] {
144 self.aggregates.as_slice()
145 }
146
147 pub(in crate::db) const fn grouped_execution_limits(&self) -> Option<(u32, u32)> {
148 self.grouped_limits
149 }
150
151 pub(in crate::db) fn continuation_cursor(&self) -> Option<&str> {
152 self.cursor.as_deref()
153 }
154}