1use serde::{Deserialize, Serialize};
9use serde_json::Value as JsonValue;
10
11#[derive(Clone, Debug, Serialize, Deserialize)]
17pub struct Predicate {
18 pub col: String,
19 pub op: String,
20 #[serde(skip_serializing_if = "Option::is_none")]
21 pub val: Option<JsonValue>,
22}
23
24impl Predicate {
25 pub fn new(col: impl Into<String>, op: impl Into<String>, val: impl Into<JsonValue>) -> Self {
27 Self {
28 col: col.into(),
29 op: op.into(),
30 val: Some(val.into()),
31 }
32 }
33
34 pub fn unary(col: impl Into<String>, op: impl Into<String>) -> Self {
36 Self {
37 col: col.into(),
38 op: op.into(),
39 val: None,
40 }
41 }
42}
43
44#[derive(Clone, Debug, Serialize, Deserialize)]
46pub struct OrderBy {
47 pub col: String,
48 #[serde(skip_serializing_if = "Option::is_none")]
49 pub dir: Option<String>,
50}
51
52impl OrderBy {
53 pub fn asc(col: impl Into<String>) -> Self {
54 Self {
55 col: col.into(),
56 dir: Some("asc".into()),
57 }
58 }
59 pub fn desc(col: impl Into<String>) -> Self {
60 Self {
61 col: col.into(),
62 dir: Some("desc".into()),
63 }
64 }
65}
66
67#[derive(Clone, Debug, Serialize, Deserialize)]
73pub struct Aggregation {
74 #[serde(skip_serializing_if = "Option::is_none")]
75 pub col: Option<String>,
76 pub op: String,
77 #[serde(skip_serializing_if = "Option::is_none")]
78 pub alias: Option<String>,
79}
80
81impl Aggregation {
82 pub fn count(alias: Option<&str>) -> Self {
84 Self {
85 col: None,
86 op: "count".into(),
87 alias: alias.map(str::to_owned),
88 }
89 }
90
91 pub fn over(op: impl Into<String>, col: impl Into<String>, alias: Option<&str>) -> Self {
94 Self {
95 col: Some(col.into()),
96 op: op.into(),
97 alias: alias.map(str::to_owned),
98 }
99 }
100}
101
102#[derive(Clone, Debug, Default, Serialize, Deserialize)]
108pub struct QueryRequest {
109 #[serde(default, skip_serializing_if = "Vec::is_empty")]
110 pub columns: Vec<String>,
111 #[serde(default, skip_serializing_if = "Vec::is_empty")]
112 pub predicates: Vec<Predicate>,
113 #[serde(default, skip_serializing_if = "Vec::is_empty")]
114 pub group_by: Vec<String>,
115 #[serde(default, skip_serializing_if = "Vec::is_empty")]
116 pub aggregations: Vec<Aggregation>,
117 #[serde(default, skip_serializing_if = "Vec::is_empty")]
118 pub having: Vec<Predicate>,
119 #[serde(default, skip_serializing_if = "std::ops::Not::not")]
120 pub distinct: bool,
121 #[serde(default, skip_serializing_if = "Vec::is_empty")]
122 pub order_by: Vec<OrderBy>,
123 #[serde(skip_serializing_if = "Option::is_none")]
124 pub limit: Option<u64>,
125 #[serde(skip_serializing_if = "Option::is_none")]
126 pub page: Option<u64>,
127 #[serde(skip_serializing_if = "Option::is_none")]
128 pub page_size: Option<u64>,
129}
130
131impl QueryRequest {
132 pub fn builder() -> QueryRequestBuilder {
134 QueryRequestBuilder::default()
135 }
136}
137
138#[derive(Clone, Debug, Default)]
140pub struct QueryRequestBuilder {
141 inner: QueryRequest,
142}
143
144impl QueryRequestBuilder {
145 pub fn columns<I, S>(mut self, cols: I) -> Self
147 where
148 I: IntoIterator<Item = S>,
149 S: Into<String>,
150 {
151 self.inner.columns = cols.into_iter().map(Into::into).collect();
152 self
153 }
154
155 pub fn predicate(mut self, p: Predicate) -> Self {
157 self.inner.predicates.push(p);
158 self
159 }
160
161 pub fn group_by<I, S>(mut self, cols: I) -> Self
163 where
164 I: IntoIterator<Item = S>,
165 S: Into<String>,
166 {
167 self.inner.group_by = cols.into_iter().map(Into::into).collect();
168 self
169 }
170
171 pub fn aggregation(mut self, a: Aggregation) -> Self {
173 self.inner.aggregations.push(a);
174 self
175 }
176
177 pub fn having(mut self, p: Predicate) -> Self {
179 self.inner.having.push(p);
180 self
181 }
182
183 pub fn distinct(mut self, yes: bool) -> Self {
185 self.inner.distinct = yes;
186 self
187 }
188
189 pub fn order_by(mut self, o: OrderBy) -> Self {
191 self.inner.order_by.push(o);
192 self
193 }
194
195 pub fn limit(mut self, n: u64) -> Self {
197 self.inner.limit = Some(n);
198 self
199 }
200
201 pub fn page(mut self, n: u64) -> Self {
203 self.inner.page = Some(n);
204 self
205 }
206
207 pub fn page_size(mut self, n: u64) -> Self {
209 self.inner.page_size = Some(n);
210 self
211 }
212
213 pub fn build(self) -> QueryRequest {
215 self.inner
216 }
217}
218
219#[derive(Clone, Debug, Serialize, Deserialize)]
221pub struct QueryResponse {
222 pub data: Vec<JsonValue>,
224 #[serde(default)]
226 pub page: Option<u64>,
227 #[serde(default)]
229 pub page_size: Option<u64>,
230}
231
232#[derive(Clone, Debug, Serialize, Deserialize)]
234pub struct SqlResponse {
235 pub data: Vec<JsonValue>,
237 #[serde(default)]
239 pub max_rows: Option<u64>,
240}
241
242#[derive(Clone, Debug, Serialize)]
244pub struct SqlRequest {
245 pub sql: String,
246 #[serde(skip_serializing_if = "Option::is_none")]
247 pub max_rows: Option<u64>,
248}