1use std::fmt;
7use std::marker::PhantomData;
8use serde_json::Value;
9use sqlx::Row;
10
11use crate::error::ModelResult;
12use crate::model::Model;
13
14#[derive(Debug, Clone, PartialEq)]
16pub enum QueryOperator {
17 Equal,
18 NotEqual,
19 GreaterThan,
20 GreaterThanOrEqual,
21 LessThan,
22 LessThanOrEqual,
23 Like,
24 NotLike,
25 In,
26 NotIn,
27 IsNull,
28 IsNotNull,
29 Between,
30}
31
32impl fmt::Display for QueryOperator {
33 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
34 match self {
35 QueryOperator::Equal => write!(f, "="),
36 QueryOperator::NotEqual => write!(f, "!="),
37 QueryOperator::GreaterThan => write!(f, ">"),
38 QueryOperator::GreaterThanOrEqual => write!(f, ">="),
39 QueryOperator::LessThan => write!(f, "<"),
40 QueryOperator::LessThanOrEqual => write!(f, "<="),
41 QueryOperator::Like => write!(f, "LIKE"),
42 QueryOperator::NotLike => write!(f, "NOT LIKE"),
43 QueryOperator::In => write!(f, "IN"),
44 QueryOperator::NotIn => write!(f, "NOT IN"),
45 QueryOperator::IsNull => write!(f, "IS NULL"),
46 QueryOperator::IsNotNull => write!(f, "IS NOT NULL"),
47 QueryOperator::Between => write!(f, "BETWEEN"),
48 }
49 }
50}
51
52#[derive(Debug, Clone)]
54pub struct WhereCondition {
55 pub column: String,
56 pub operator: QueryOperator,
57 pub value: Option<Value>,
58 pub values: Vec<Value>, }
60
61#[derive(Debug, Clone, PartialEq)]
63pub enum JoinType {
64 Inner,
65 Left,
66 Right,
67 Full,
68}
69
70impl fmt::Display for JoinType {
71 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
72 match self {
73 JoinType::Inner => write!(f, "INNER JOIN"),
74 JoinType::Left => write!(f, "LEFT JOIN"),
75 JoinType::Right => write!(f, "RIGHT JOIN"),
76 JoinType::Full => write!(f, "FULL JOIN"),
77 }
78 }
79}
80
81#[derive(Debug, Clone)]
83pub struct JoinClause {
84 pub join_type: JoinType,
85 pub table: String,
86 pub on_conditions: Vec<(String, String)>, }
88
89#[derive(Debug, Clone, PartialEq)]
91pub enum OrderDirection {
92 Asc,
93 Desc,
94}
95
96impl fmt::Display for OrderDirection {
97 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
98 match self {
99 OrderDirection::Asc => write!(f, "ASC"),
100 OrderDirection::Desc => write!(f, "DESC"),
101 }
102 }
103}
104
105#[derive(Debug, Clone)]
107pub struct OrderByClause {
108 pub column: String,
109 pub direction: OrderDirection,
110}
111
112#[derive(Debug)]
114pub struct QueryBuilder<M = ()> {
115 select_fields: Vec<String>,
116 from_table: Option<String>,
117 where_conditions: Vec<WhereCondition>,
118 joins: Vec<JoinClause>,
119 order_by: Vec<OrderByClause>,
120 group_by: Vec<String>,
121 having_conditions: Vec<WhereCondition>,
122 limit_value: Option<i64>,
123 offset_value: Option<i64>,
124 distinct: bool,
125 _phantom: PhantomData<M>,
126}
127
128impl<M> Clone for QueryBuilder<M> {
129 fn clone(&self) -> Self {
130 Self {
131 select_fields: self.select_fields.clone(),
132 from_table: self.from_table.clone(),
133 where_conditions: self.where_conditions.clone(),
134 joins: self.joins.clone(),
135 order_by: self.order_by.clone(),
136 group_by: self.group_by.clone(),
137 having_conditions: self.having_conditions.clone(),
138 limit_value: self.limit_value,
139 offset_value: self.offset_value,
140 distinct: self.distinct,
141 _phantom: PhantomData,
142 }
143 }
144}
145
146impl<M> Default for QueryBuilder<M> {
147 fn default() -> Self {
148 Self::new()
149 }
150}
151
152impl<M> QueryBuilder<M> {
153 pub fn new() -> Self {
155 Self {
156 select_fields: Vec::new(),
157 from_table: None,
158 where_conditions: Vec::new(),
159 joins: Vec::new(),
160 order_by: Vec::new(),
161 group_by: Vec::new(),
162 having_conditions: Vec::new(),
163 limit_value: None,
164 offset_value: None,
165 distinct: false,
166 _phantom: PhantomData,
167 }
168 }
169
170 pub fn select(mut self, fields: &str) -> Self {
173 if fields == "*" {
174 self.select_fields.push("*".to_string());
175 } else {
176 self.select_fields.extend(
177 fields
178 .split(',')
179 .map(|f| f.trim().to_string())
180 .collect::<Vec<String>>()
181 );
182 }
183 self
184 }
185
186 pub fn select_distinct(mut self, fields: &str) -> Self {
188 self.distinct = true;
189 self.select(fields)
190 }
191
192 pub fn from(mut self, table: &str) -> Self {
194 self.from_table = Some(table.to_string());
195 self
196 }
197 pub fn where_eq<T: Into<Value>>(mut self, column: &str, value: T) -> Self {
202 self.where_conditions.push(WhereCondition {
203 column: column.to_string(),
204 operator: QueryOperator::Equal,
205 value: Some(value.into()),
206 values: Vec::new(),
207 });
208 self
209 }
210
211 pub fn where_ne<T: Into<Value>>(mut self, column: &str, value: T) -> Self {
213 self.where_conditions.push(WhereCondition {
214 column: column.to_string(),
215 operator: QueryOperator::NotEqual,
216 value: Some(value.into()),
217 values: Vec::new(),
218 });
219 self
220 }
221
222 pub fn where_gt<T: Into<Value>>(mut self, column: &str, value: T) -> Self {
224 self.where_conditions.push(WhereCondition {
225 column: column.to_string(),
226 operator: QueryOperator::GreaterThan,
227 value: Some(value.into()),
228 values: Vec::new(),
229 });
230 self
231 }
232
233 pub fn where_gte<T: Into<Value>>(mut self, column: &str, value: T) -> Self {
235 self.where_conditions.push(WhereCondition {
236 column: column.to_string(),
237 operator: QueryOperator::GreaterThanOrEqual,
238 value: Some(value.into()),
239 values: Vec::new(),
240 });
241 self
242 }
243
244 pub fn where_lt<T: Into<Value>>(mut self, column: &str, value: T) -> Self {
246 self.where_conditions.push(WhereCondition {
247 column: column.to_string(),
248 operator: QueryOperator::LessThan,
249 value: Some(value.into()),
250 values: Vec::new(),
251 });
252 self
253 }
254
255 pub fn where_lte<T: Into<Value>>(mut self, column: &str, value: T) -> Self {
257 self.where_conditions.push(WhereCondition {
258 column: column.to_string(),
259 operator: QueryOperator::LessThanOrEqual,
260 value: Some(value.into()),
261 values: Vec::new(),
262 });
263 self
264 }
265
266 pub fn where_like(mut self, column: &str, pattern: &str) -> Self {
268 self.where_conditions.push(WhereCondition {
269 column: column.to_string(),
270 operator: QueryOperator::Like,
271 value: Some(Value::String(pattern.to_string())),
272 values: Vec::new(),
273 });
274 self
275 }
276
277 pub fn where_not_like(mut self, column: &str, pattern: &str) -> Self {
279 self.where_conditions.push(WhereCondition {
280 column: column.to_string(),
281 operator: QueryOperator::NotLike,
282 value: Some(Value::String(pattern.to_string())),
283 values: Vec::new(),
284 });
285 self
286 }
287
288 pub fn where_in<T: Into<Value>>(mut self, column: &str, values: Vec<T>) -> Self {
290 self.where_conditions.push(WhereCondition {
291 column: column.to_string(),
292 operator: QueryOperator::In,
293 value: None,
294 values: values.into_iter().map(|v| v.into()).collect(),
295 });
296 self
297 }
298
299 pub fn where_not_in<T: Into<Value>>(mut self, column: &str, values: Vec<T>) -> Self {
301 self.where_conditions.push(WhereCondition {
302 column: column.to_string(),
303 operator: QueryOperator::NotIn,
304 value: None,
305 values: values.into_iter().map(|v| v.into()).collect(),
306 });
307 self
308 }
309
310 pub fn where_null(mut self, column: &str) -> Self {
312 self.where_conditions.push(WhereCondition {
313 column: column.to_string(),
314 operator: QueryOperator::IsNull,
315 value: None,
316 values: Vec::new(),
317 });
318 self
319 }
320
321 pub fn where_not_null(mut self, column: &str) -> Self {
323 self.where_conditions.push(WhereCondition {
324 column: column.to_string(),
325 operator: QueryOperator::IsNotNull,
326 value: None,
327 values: Vec::new(),
328 });
329 self
330 }
331
332 pub fn where_between<T: Into<Value>>(mut self, column: &str, start: T, end: T) -> Self {
334 self.where_conditions.push(WhereCondition {
335 column: column.to_string(),
336 operator: QueryOperator::Between,
337 value: None,
338 values: vec![start.into(), end.into()],
339 });
340 self
341 }
342 pub fn join(mut self, table: &str, left_col: &str, right_col: &str) -> Self {
347 self.joins.push(JoinClause {
348 join_type: JoinType::Inner,
349 table: table.to_string(),
350 on_conditions: vec![(left_col.to_string(), right_col.to_string())],
351 });
352 self
353 }
354
355 pub fn left_join(mut self, table: &str, left_col: &str, right_col: &str) -> Self {
357 self.joins.push(JoinClause {
358 join_type: JoinType::Left,
359 table: table.to_string(),
360 on_conditions: vec![(left_col.to_string(), right_col.to_string())],
361 });
362 self
363 }
364
365 pub fn right_join(mut self, table: &str, left_col: &str, right_col: &str) -> Self {
367 self.joins.push(JoinClause {
368 join_type: JoinType::Right,
369 table: table.to_string(),
370 on_conditions: vec![(left_col.to_string(), right_col.to_string())],
371 });
372 self
373 }
374 pub fn order_by(mut self, column: &str) -> Self {
379 self.order_by.push(OrderByClause {
380 column: column.to_string(),
381 direction: OrderDirection::Asc,
382 });
383 self
384 }
385
386 pub fn order_by_desc(mut self, column: &str) -> Self {
388 self.order_by.push(OrderByClause {
389 column: column.to_string(),
390 direction: OrderDirection::Desc,
391 });
392 self
393 }
394
395 pub fn group_by(mut self, column: &str) -> Self {
397 self.group_by.push(column.to_string());
398 self
399 }
400
401 pub fn having_eq<T: Into<Value>>(mut self, column: &str, value: T) -> Self {
403 self.having_conditions.push(WhereCondition {
404 column: column.to_string(),
405 operator: QueryOperator::Equal,
406 value: Some(value.into()),
407 values: Vec::new(),
408 });
409 self
410 }
411 pub fn select_count(mut self, column: &str, alias: Option<&str>) -> Self {
416 let select_expr = if let Some(alias) = alias {
417 format!("COUNT({}) AS {}", column, alias)
418 } else {
419 format!("COUNT({})", column)
420 };
421 self.select_fields.push(select_expr);
422 self
423 }
424
425 pub fn select_sum(mut self, column: &str, alias: Option<&str>) -> Self {
427 let select_expr = if let Some(alias) = alias {
428 format!("SUM({}) AS {}", column, alias)
429 } else {
430 format!("SUM({})", column)
431 };
432 self.select_fields.push(select_expr);
433 self
434 }
435
436 pub fn select_avg(mut self, column: &str, alias: Option<&str>) -> Self {
438 let select_expr = if let Some(alias) = alias {
439 format!("AVG({}) AS {}", column, alias)
440 } else {
441 format!("AVG({})", column)
442 };
443 self.select_fields.push(select_expr);
444 self
445 }
446
447 pub fn select_min(mut self, column: &str, alias: Option<&str>) -> Self {
449 let select_expr = if let Some(alias) = alias {
450 format!("MIN({}) AS {}", column, alias)
451 } else {
452 format!("MIN({})", column)
453 };
454 self.select_fields.push(select_expr);
455 self
456 }
457
458 pub fn select_max(mut self, column: &str, alias: Option<&str>) -> Self {
460 let select_expr = if let Some(alias) = alias {
461 format!("MAX({}) AS {}", column, alias)
462 } else {
463 format!("MAX({})", column)
464 };
465 self.select_fields.push(select_expr);
466 self
467 }
468
469 pub fn select_raw(mut self, expression: &str) -> Self {
471 self.select_fields.push(expression.to_string());
472 self
473 }
474 pub fn limit(mut self, count: i64) -> Self {
479 self.limit_value = Some(count);
480 self
481 }
482
483 pub fn offset(mut self, count: i64) -> Self {
485 self.offset_value = Some(count);
486 self
487 }
488
489 pub fn paginate(mut self, per_page: i64, page: i64) -> Self {
491 self.limit_value = Some(per_page);
492 self.offset_value = Some((page - 1) * per_page);
493 self
494 }
495
496 pub fn paginate_cursor<T: Into<Value>>(mut self, cursor_column: &str, cursor_value: Option<T>, per_page: i64, direction: OrderDirection) -> Self {
498 self.limit_value = Some(per_page);
499
500 if let Some(cursor_val) = cursor_value {
501 match direction {
502 OrderDirection::Asc => {
503 self = self.where_gt(cursor_column, cursor_val);
504 }
505 OrderDirection::Desc => {
506 self = self.where_lt(cursor_column, cursor_val);
507 }
508 }
509 }
510
511 self.order_by.push(OrderByClause {
512 column: cursor_column.to_string(),
513 direction,
514 });
515
516 self
517 }
518 pub fn union(self, _other_query: QueryBuilder<M>) -> Self {
523 self
526 }
527
528 pub fn union_all(self, _other_query: QueryBuilder<M>) -> Self {
530 self
532 }
533
534 pub fn where_subquery<T: Into<Value>>(mut self, column: &str, operator: QueryOperator, subquery: QueryBuilder<M>) -> Self {
536 let subquery_sql = subquery.to_sql();
537 let formatted_value = format!("({})", subquery_sql);
538
539 self.where_conditions.push(WhereCondition {
540 column: column.to_string(),
541 operator,
542 value: Some(Value::String(formatted_value)),
543 values: Vec::new(),
544 });
545 self
546 }
547
548 pub fn where_exists(mut self, subquery: QueryBuilder<M>) -> Self {
550 self.where_conditions.push(WhereCondition {
551 column: "EXISTS".to_string(),
552 operator: QueryOperator::Equal,
553 value: Some(Value::String(format!("({})", subquery.to_sql()))),
554 values: Vec::new(),
555 });
556 self
557 }
558
559 pub fn where_not_exists(mut self, subquery: QueryBuilder<M>) -> Self {
561 self.where_conditions.push(WhereCondition {
562 column: "NOT EXISTS".to_string(),
563 operator: QueryOperator::Equal,
564 value: Some(Value::String(format!("({})", subquery.to_sql()))),
565 values: Vec::new(),
566 });
567 self
568 }
569
570 pub fn where_raw(mut self, raw_condition: &str) -> Self {
572 self.where_conditions.push(WhereCondition {
573 column: "RAW".to_string(),
574 operator: QueryOperator::Equal,
575 value: Some(Value::String(raw_condition.to_string())),
576 values: Vec::new(),
577 });
578 self
579 }
580
581 pub fn or_where<F>(mut self, closure: F) -> Self
583 where
584 F: FnOnce(QueryBuilder<M>) -> QueryBuilder<M>,
585 {
586 let inner_query = closure(QueryBuilder::new());
589 self.where_conditions.extend(inner_query.where_conditions);
591 self
592 }
593 pub fn to_sql(&self) -> String {
598 let mut sql = String::new();
599
600 if self.distinct {
602 sql.push_str("SELECT DISTINCT ");
603 } else {
604 sql.push_str("SELECT ");
605 }
606
607 if self.select_fields.is_empty() {
608 sql.push('*');
609 } else {
610 sql.push_str(&self.select_fields.join(", "));
611 }
612
613 if let Some(table) = &self.from_table {
615 sql.push_str(&format!(" FROM {}", table));
616 }
617
618 for join in &self.joins {
620 sql.push_str(&format!(" {} {}", join.join_type, join.table));
621 if !join.on_conditions.is_empty() {
622 sql.push_str(" ON ");
623 let conditions: Vec<String> = join
624 .on_conditions
625 .iter()
626 .map(|(left, right)| format!("{} = {}", left, right))
627 .collect();
628 sql.push_str(&conditions.join(" AND "));
629 }
630 }
631
632 if !self.where_conditions.is_empty() {
634 sql.push_str(" WHERE ");
635 let conditions = self.build_where_conditions(&self.where_conditions);
636 sql.push_str(&conditions.join(" AND "));
637 }
638
639 if !self.group_by.is_empty() {
641 sql.push_str(&format!(" GROUP BY {}", self.group_by.join(", ")));
642 }
643
644 if !self.having_conditions.is_empty() {
646 sql.push_str(" HAVING ");
647 let conditions = self.build_where_conditions(&self.having_conditions);
648 sql.push_str(&conditions.join(" AND "));
649 }
650
651 if !self.order_by.is_empty() {
653 sql.push_str(" ORDER BY ");
654 let order_clauses: Vec<String> = self
655 .order_by
656 .iter()
657 .map(|clause| format!("{} {}", clause.column, clause.direction))
658 .collect();
659 sql.push_str(&order_clauses.join(", "));
660 }
661
662 if let Some(limit) = self.limit_value {
664 sql.push_str(&format!(" LIMIT {}", limit));
665 }
666
667 if let Some(offset) = self.offset_value {
669 sql.push_str(&format!(" OFFSET {}", offset));
670 }
671
672 sql
673 }
674
675 fn build_where_conditions(&self, conditions: &[WhereCondition]) -> Vec<String> {
677 conditions
678 .iter()
679 .map(|condition| {
680 if condition.column == "RAW" {
682 if let Some(Value::String(raw_sql)) = &condition.value {
683 return raw_sql.clone();
684 }
685 }
686
687 if condition.column == "EXISTS" || condition.column == "NOT EXISTS" {
689 if let Some(Value::String(subquery)) = &condition.value {
690 return format!("{} {}", condition.column, subquery);
691 }
692 }
693
694 match &condition.operator {
695 QueryOperator::IsNull | QueryOperator::IsNotNull => {
696 format!("{} {}", condition.column, condition.operator)
697 }
698 QueryOperator::In | QueryOperator::NotIn => {
699 if let Some(Value::String(subquery)) = &condition.value {
701 if subquery.starts_with('(') && subquery.ends_with(')') {
702 format!("{} {} {}", condition.column, condition.operator, subquery)
704 } else {
705 format!("{} {} ({})", condition.column, condition.operator, self.format_value(&condition.value.as_ref().unwrap()))
707 }
708 } else {
709 let values: Vec<String> = condition
711 .values
712 .iter()
713 .map(|v| self.format_value(v))
714 .collect();
715 format!("{} {} ({})", condition.column, condition.operator, values.join(", "))
716 }
717 }
718 QueryOperator::Between => {
719 if condition.values.len() == 2 {
720 format!(
721 "{} BETWEEN {} AND {}",
722 condition.column,
723 self.format_value(&condition.values[0]),
724 self.format_value(&condition.values[1])
725 )
726 } else {
727 format!("{} = NULL", condition.column) }
729 }
730 _ => {
731 if let Some(value) = &condition.value {
732 if let Value::String(val_str) = value {
734 if val_str.starts_with('(') && val_str.ends_with(')') {
735 format!("{} {} {}", condition.column, condition.operator, val_str)
737 } else {
738 format!("{} {} {}", condition.column, condition.operator, self.format_value(value))
739 }
740 } else {
741 format!("{} {} {}", condition.column, condition.operator, self.format_value(value))
742 }
743 } else {
744 format!("{} = NULL", condition.column) }
746 }
747 }
748 })
749 .collect()
750 }
751
752 fn format_value(&self, value: &Value) -> String {
754 match value {
755 Value::String(s) => format!("'{}'", s.replace('\'', "''")), Value::Number(n) => n.to_string(),
757 Value::Bool(b) => b.to_string(),
758 Value::Null => "NULL".to_string(),
759 _ => "NULL".to_string(), }
761 }
762 pub fn bindings(&self) -> Vec<Value> {
768 let mut bindings = Vec::new();
769
770 for condition in &self.where_conditions {
771 if matches!(condition.column.as_str(), "RAW" | "EXISTS" | "NOT EXISTS") {
773 continue;
774 }
775
776 if let Some(value) = &condition.value {
777 if let Value::String(val_str) = value {
779 if !val_str.starts_with('(') || !val_str.ends_with(')') {
780 bindings.push(value.clone());
781 }
782 } else {
783 bindings.push(value.clone());
784 }
785 }
786 bindings.extend(condition.values.clone());
787 }
788
789 for condition in &self.having_conditions {
790 if let Some(value) = &condition.value {
791 bindings.push(value.clone());
792 }
793 bindings.extend(condition.values.clone());
794 }
795
796 bindings
797 }
798
799 pub fn clone_for_subquery(&self) -> Self {
801 self.clone()
802 }
803
804 pub fn optimize(self) -> Self {
806 self
811 }
812
813 pub fn complexity_score(&self) -> u32 {
815 let mut score = 0;
816
817 score += self.where_conditions.len() as u32;
818 score += self.joins.len() as u32 * 2; score += self.group_by.len() as u32;
820 score += self.having_conditions.len() as u32;
821
822 if self.distinct {
823 score += 1;
824 }
825
826 score
827 }
828 }
830
831impl<M: Model> QueryBuilder<M> {
833 pub async fn get(self, pool: &sqlx::Pool<sqlx::Postgres>) -> ModelResult<Vec<M>> {
836 let sql = self.to_sql();
837 let rows = sqlx::query(&sql)
838 .fetch_all(pool)
839 .await?;
840
841 let mut models = Vec::new();
842 for row in rows {
843 models.push(M::from_row(&row)?);
844 }
845
846 Ok(models)
847 }
848
849 pub async fn chunk<F>(
851 mut self,
852 pool: &sqlx::Pool<sqlx::Postgres>,
853 chunk_size: i64,
854 mut callback: F
855 ) -> ModelResult<()>
856 where
857 F: FnMut(Vec<M>) -> Result<(), crate::error::ModelError>,
858 {
859 let mut offset = 0;
860 loop {
861 let chunk_query = self.clone()
862 .limit(chunk_size)
863 .offset(offset);
864
865 let chunk = chunk_query.get(pool).await?;
866
867 if chunk.is_empty() {
868 break;
869 }
870
871 callback(chunk)?;
872 offset += chunk_size;
873 }
874
875 Ok(())
876 }
877
878 pub async fn get_raw(self, pool: &sqlx::Pool<sqlx::Postgres>) -> ModelResult<Vec<serde_json::Value>> {
880 let sql = self.to_sql();
881 let rows = sqlx::query(&sql)
882 .fetch_all(pool)
883 .await?;
884
885 let mut results = Vec::new();
886 for row in rows {
887 let mut json_row = serde_json::Map::new();
888
889 for i in 0..row.len() {
892 if let Ok(column) = row.try_get::<Option<String>, _>(i) {
893 let column_name = format!("column_{}", i); json_row.insert(column_name, serde_json::Value::String(column.unwrap_or_default()));
895 }
896 }
897
898 results.push(serde_json::Value::Object(json_row));
899 }
900
901 Ok(results)
902 }
903 pub async fn first(self, pool: &sqlx::Pool<sqlx::Postgres>) -> ModelResult<Option<M>> {
907 let query = self.limit(1);
908 let mut results = query.get(pool).await?;
909 Ok(results.pop())
910 }
911
912 pub async fn first_or_fail(self, pool: &sqlx::Pool<sqlx::Postgres>) -> ModelResult<M> {
914 self.first(pool)
915 .await?
916 .ok_or_else(|| crate::error::ModelError::NotFound(M::table_name().to_string()))
917 }
918
919 pub async fn count(mut self, pool: &sqlx::Pool<sqlx::Postgres>) -> ModelResult<i64> {
921 self.select_fields = vec!["COUNT(*)".to_string()];
922 let sql = self.to_sql();
923
924 let row = sqlx::query(&sql)
925 .fetch_one(pool)
926 .await?;
927
928 let count: i64 = row.try_get(0)?;
929 Ok(count)
930 }
931
932 pub async fn aggregate(self, pool: &sqlx::Pool<sqlx::Postgres>) -> ModelResult<Option<serde_json::Value>> {
934 let sql = self.to_sql();
935
936 let row_opt = sqlx::query(&sql)
937 .fetch_optional(pool)
938 .await?;
939
940 if let Some(row) = row_opt {
941 if let Ok(result) = row.try_get::<Option<i64>, _>(0) {
943 return Ok(Some(serde_json::Value::Number(serde_json::Number::from(result.unwrap_or(0)))));
944 } else if let Ok(result) = row.try_get::<Option<f64>, _>(0) {
945 return Ok(Some(serde_json::Number::from_f64(result.unwrap_or(0.0)).map(serde_json::Value::Number).unwrap_or(serde_json::Value::Null)));
946 } else if let Ok(result) = row.try_get::<Option<String>, _>(0) {
947 return Ok(Some(serde_json::Value::String(result.unwrap_or_default())));
948 }
949 }
950
951 Ok(None)
952 }
953}