elif_orm/
query.rs

1//! Query Builder - Type-safe, fluent query builder for complex database operations
2//!
3//! Provides a fluent interface for building queries with type safety,
4//! compile-time validation, joins, subqueries, aggregations, and pagination.
5
6use std::fmt;
7use std::marker::PhantomData;
8use serde_json::Value;
9use sqlx::Row;
10
11use crate::error::ModelResult;
12use crate::model::Model;
13
14/// Query operator types
15#[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/// Where clause condition
53#[derive(Debug, Clone)]
54pub struct WhereCondition {
55    pub column: String,
56    pub operator: QueryOperator,
57    pub value: Option<Value>,
58    pub values: Vec<Value>, // For IN, NOT IN, BETWEEN
59}
60
61/// Join types
62#[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/// Join clause
82#[derive(Debug, Clone)]
83pub struct JoinClause {
84    pub join_type: JoinType,
85    pub table: String,
86    pub on_conditions: Vec<(String, String)>, // (left_column, right_column)
87}
88
89/// Order by direction
90#[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/// Order by clause
106#[derive(Debug, Clone)]
107pub struct OrderByClause {
108    pub column: String,
109    pub direction: OrderDirection,
110}
111
112/// Query builder for constructing database queries
113#[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    /// Create a new query builder
154    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    // <<<ELIF:BEGIN agent-editable:query_builder_select>>>
171    /// Add SELECT fields to the query
172    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    /// Add SELECT DISTINCT to the query
187    pub fn select_distinct(mut self, fields: &str) -> Self {
188        self.distinct = true;
189        self.select(fields)
190    }
191
192    /// Set the FROM table
193    pub fn from(mut self, table: &str) -> Self {
194        self.from_table = Some(table.to_string());
195        self
196    }
197    // <<<ELIF:END agent-editable:query_builder_select>>>
198
199    // <<<ELIF:BEGIN agent-editable:query_builder_where>>>
200    /// Add WHERE condition with equality
201    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    /// Add WHERE condition with not equal
212    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    /// Add WHERE condition with greater than
223    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    /// Add WHERE condition with greater than or equal
234    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    /// Add WHERE condition with less than
245    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    /// Add WHERE condition with less than or equal
256    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    /// Add WHERE condition with LIKE
267    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    /// Add WHERE condition with NOT LIKE
278    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    /// Add WHERE condition with IN
289    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    /// Add WHERE condition with NOT IN
300    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    /// Add WHERE condition with IS NULL
311    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    /// Add WHERE condition with IS NOT NULL
322    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    /// Add WHERE condition with BETWEEN
333    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    // <<<ELIF:END agent-editable:query_builder_where>>>
343
344    // <<<ELIF:BEGIN agent-editable:query_builder_joins>>>
345    /// Add INNER JOIN to the query
346    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    /// Add LEFT JOIN to the query
356    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    /// Add RIGHT JOIN to the query
366    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    // <<<ELIF:END agent-editable:query_builder_joins>>>
375
376    // <<<ELIF:BEGIN agent-editable:query_builder_order>>>
377    /// Add ORDER BY clause (ascending)
378    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    /// Add ORDER BY clause (descending)
387    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    /// Add GROUP BY clause
396    pub fn group_by(mut self, column: &str) -> Self {
397        self.group_by.push(column.to_string());
398        self
399    }
400
401    /// Add HAVING clause (same as WHERE for now)
402    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    // <<<ELIF:END agent-editable:query_builder_order>>>
412
413    // <<<ELIF:BEGIN agent-editable:query_builder_aggregations>>>
414    /// Add aggregate functions to SELECT
415    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    /// Add SUM aggregate
426    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    /// Add AVG aggregate
437    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    /// Add MIN aggregate
448    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    /// Add MAX aggregate
459    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    /// Add custom SELECT expression
470    pub fn select_raw(mut self, expression: &str) -> Self {
471        self.select_fields.push(expression.to_string());
472        self
473    }
474    // <<<ELIF:END agent-editable:query_builder_aggregations>>>
475
476    // <<<ELIF:BEGIN agent-editable:query_builder_pagination>>>
477    /// Add LIMIT clause
478    pub fn limit(mut self, count: i64) -> Self {
479        self.limit_value = Some(count);
480        self
481    }
482
483    /// Add OFFSET clause
484    pub fn offset(mut self, count: i64) -> Self {
485        self.offset_value = Some(count);
486        self
487    }
488
489    /// Add pagination (LIMIT + OFFSET)
490    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    /// Cursor-based pagination (for better performance on large datasets)
497    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    // <<<ELIF:END agent-editable:query_builder_pagination>>>
519
520    // <<<ELIF:BEGIN agent-editable:query_builder_advanced>>>    
521    /// Add UNION to combine results from another query
522    pub fn union(self, _other_query: QueryBuilder<M>) -> Self {
523        // TODO: Implement UNION functionality
524        // For now, this is a placeholder for advanced union support
525        self
526    }
527
528    /// Add UNION ALL to combine results from another query
529    pub fn union_all(self, _other_query: QueryBuilder<M>) -> Self {
530        // TODO: Implement UNION ALL functionality
531        self
532    }
533
534    /// Add a subquery in the WHERE clause
535    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    /// Add EXISTS subquery condition
549    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    /// Add NOT EXISTS subquery condition
560    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    /// Add raw WHERE condition for complex cases
571    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    /// Add logical grouping with OR conditions
582    pub fn or_where<F>(mut self, closure: F) -> Self 
583    where 
584        F: FnOnce(QueryBuilder<M>) -> QueryBuilder<M>,
585    {
586        // TODO: Implement OR condition grouping
587        // This is a placeholder for complex logical operations
588        let inner_query = closure(QueryBuilder::new());
589        // For now, just add the conditions (proper OR logic needs more work)
590        self.where_conditions.extend(inner_query.where_conditions);
591        self
592    }
593    // <<<ELIF:END agent-editable:query_builder_advanced>>>
594
595    // <<<ELIF:BEGIN agent-editable:query_builder_sql_generation>>>
596    /// Convert the query to SQL string
597    pub fn to_sql(&self) -> String {
598        let mut sql = String::new();
599
600        // SELECT clause
601        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        // FROM clause
614        if let Some(table) = &self.from_table {
615            sql.push_str(&format!(" FROM {}", table));
616        }
617
618        // JOIN clauses
619        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        // WHERE clause
633        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        // GROUP BY clause
640        if !self.group_by.is_empty() {
641            sql.push_str(&format!(" GROUP BY {}", self.group_by.join(", ")));
642        }
643
644        // HAVING clause
645        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        // ORDER BY clause
652        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        // LIMIT clause
663        if let Some(limit) = self.limit_value {
664            sql.push_str(&format!(" LIMIT {}", limit));
665        }
666
667        // OFFSET clause
668        if let Some(offset) = self.offset_value {
669            sql.push_str(&format!(" OFFSET {}", offset));
670        }
671
672        sql
673    }
674
675    /// Build WHERE condition strings
676    fn build_where_conditions(&self, conditions: &[WhereCondition]) -> Vec<String> {
677        conditions
678            .iter()
679            .map(|condition| {
680                // Handle special raw conditions
681                if condition.column == "RAW" {
682                    if let Some(Value::String(raw_sql)) = &condition.value {
683                        return raw_sql.clone();
684                    }
685                }
686                
687                // Handle EXISTS and NOT EXISTS
688                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                        // Handle subqueries (stored in value field) vs regular IN lists (stored in values field)
700                        if let Some(Value::String(subquery)) = &condition.value {
701                            if subquery.starts_with('(') && subquery.ends_with(')') {
702                                // This is a subquery
703                                format!("{} {} {}", condition.column, condition.operator, subquery)
704                            } else {
705                                // Single value IN (unusual case)
706                                format!("{} {} ({})", condition.column, condition.operator, self.format_value(&condition.value.as_ref().unwrap()))
707                            }
708                        } else {
709                            // Regular IN with multiple values
710                            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) // Invalid BETWEEN
728                        }
729                    }
730                    _ => {
731                        if let Some(value) = &condition.value {
732                            // Handle subquery values
733                            if let Value::String(val_str) = value {
734                                if val_str.starts_with('(') && val_str.ends_with(')') {
735                                    // This looks like a subquery
736                                    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) // Fallback
745                        }
746                    }
747                }
748            })
749            .collect()
750    }
751
752    /// Format a value for SQL
753    fn format_value(&self, value: &Value) -> String {
754        match value {
755            Value::String(s) => format!("'{}'", s.replace('\'', "''")), // Escape single quotes
756            Value::Number(n) => n.to_string(),
757            Value::Bool(b) => b.to_string(),
758            Value::Null => "NULL".to_string(),
759            _ => "NULL".to_string(), // Arrays and objects not yet supported
760        }
761    }
762    // <<<ELIF:END agent-editable:query_builder_sql_generation>>>
763
764    // <<<ELIF:BEGIN agent-editable:query_builder_performance>>>
765    /// Get parameter bindings (for prepared statements)
766    /// Enhanced to support subqueries and complex conditions
767    pub fn bindings(&self) -> Vec<Value> {
768        let mut bindings = Vec::new();
769        
770        for condition in &self.where_conditions {
771            // Skip RAW, EXISTS, NOT EXISTS conditions from parameter binding
772            if matches!(condition.column.as_str(), "RAW" | "EXISTS" | "NOT EXISTS") {
773                continue;
774            }
775            
776            if let Some(value) = &condition.value {
777                // Skip subquery values (they're already formatted)
778                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    /// Clone this query builder for use in subqueries
800    pub fn clone_for_subquery(&self) -> Self {
801        self.clone()
802    }
803    
804    /// Optimize query by analyzing conditions
805    pub fn optimize(self) -> Self {
806        // TODO: Implement query optimization strategies
807        // - Remove redundant conditions
808        // - Optimize join order
809        // - Suggest index usage
810        self
811    }
812    
813    /// Get query complexity score for performance monitoring
814    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; // Joins are more expensive
819        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    // <<<ELIF:END agent-editable:query_builder_performance>>>
829}
830
831// Implement specialized methods for Model-typed query builders
832impl<M: Model> QueryBuilder<M> {
833    // <<<ELIF:BEGIN agent-editable:query_model_execution>>>
834    /// Execute query and return models
835    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    /// Execute query with chunking for large datasets
850    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    /// Execute query and return raw SQL results (for complex aggregations)
879    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            // Convert PostgreSQL row to JSON
890            // This is a simplified implementation
891            for i in 0..row.len() {
892                if let Ok(column) = row.try_get::<Option<String>, _>(i) {
893                    let column_name = format!("column_{}", i); // Placeholder - real implementation would get actual column names
894                    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    // <<<ELIF:END agent-editable:query_model_execution>>>
904
905    /// Execute query and return first model
906    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    /// Execute query and return first model or error
913    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    /// Count query results
920    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    /// Execute aggregation query and return single result
933    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            // For aggregations, typically return the first column
942            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}