sea_query/query/traits.rs
1use std::fmt::Debug;
2
3use crate::{backend::QueryBuilder, value::Values, SqlWriter, SqlWriterValues, SubQueryStatement};
4
5pub trait QueryStatementBuilder: Debug {
6 /// Build corresponding SQL statement for certain database backend and collect query parameters into a vector
7 fn build_any(&self, query_builder: &dyn QueryBuilder) -> (String, Values) {
8 let (placeholder, numbered) = query_builder.placeholder();
9 let mut sql = SqlWriterValues::new(placeholder, numbered);
10 self.build_collect_any_into(query_builder, &mut sql);
11 sql.into_parts()
12 }
13
14 /// Build corresponding SQL statement for certain database backend and collect query parameters
15 fn build_collect_any(
16 &self,
17 query_builder: &dyn QueryBuilder,
18 sql: &mut dyn SqlWriter,
19 ) -> String {
20 self.build_collect_any_into(query_builder, sql);
21 sql.to_string()
22 }
23
24 /// Build corresponding SQL statement into the SqlWriter for certain database backend and collect query parameters
25 fn build_collect_any_into(&self, query_builder: &dyn QueryBuilder, sql: &mut dyn SqlWriter);
26
27 fn into_sub_query_statement(self) -> SubQueryStatement;
28}
29
30pub trait QueryStatementWriter: QueryStatementBuilder {
31 /// Build corresponding SQL statement for certain database backend and return SQL string
32 ///
33 /// # Examples
34 ///
35 /// ```
36 /// use sea_query::{*, tests_cfg::*};
37 ///
38 /// let query = Query::select()
39 /// .column(Glyph::Aspect)
40 /// .from(Glyph::Table)
41 /// .and_where(Expr::expr(Expr::col(Glyph::Aspect).if_null(0)).gt(2))
42 /// .order_by(Glyph::Image, Order::Desc)
43 /// .order_by((Glyph::Table, Glyph::Aspect), Order::Asc)
44 /// .to_string(MysqlQueryBuilder);
45 ///
46 /// assert_eq!(
47 /// query,
48 /// r#"SELECT `aspect` FROM `glyph` WHERE IFNULL(`aspect`, 0) > 2 ORDER BY `image` DESC, `glyph`.`aspect` ASC"#
49 /// );
50 /// ```
51 fn to_string<T: QueryBuilder>(&self, query_builder: T) -> String {
52 let mut sql = String::with_capacity(256);
53 self.build_collect_any_into(&query_builder, &mut sql);
54 sql
55 }
56
57 /// Build corresponding SQL statement for certain database backend and collect query parameters into a vector
58 ///
59 /// # Examples
60 ///
61 /// ```
62 /// use sea_query::{*, tests_cfg::*};
63 ///
64 /// let (query, params) = Query::select()
65 /// .column(Glyph::Aspect)
66 /// .from(Glyph::Table)
67 /// .and_where(Expr::expr(Expr::col(Glyph::Aspect).if_null(0)).gt(2))
68 /// .order_by(Glyph::Image, Order::Desc)
69 /// .order_by((Glyph::Table, Glyph::Aspect), Order::Asc)
70 /// .build(MysqlQueryBuilder);
71 ///
72 /// assert_eq!(
73 /// query,
74 /// r#"SELECT `aspect` FROM `glyph` WHERE IFNULL(`aspect`, ?) > ? ORDER BY `image` DESC, `glyph`.`aspect` ASC"#
75 /// );
76 /// assert_eq!(
77 /// params,
78 /// Values(vec![Value::Int(Some(0)), Value::Int(Some(2))])
79 /// );
80 /// ```
81 fn build<T: QueryBuilder>(&self, query_builder: T) -> (String, Values) {
82 let (placeholder, numbered) = query_builder.placeholder();
83 let mut sql = SqlWriterValues::new(placeholder, numbered);
84 self.build_collect_into(query_builder, &mut sql);
85 sql.into_parts()
86 }
87
88 /// Build corresponding SQL statement for certain database backend and collect query parameters
89 ///
90 /// # Examples
91 ///
92 /// ```
93 /// use sea_query::{*, tests_cfg::*};
94 ///
95 /// let query = Query::select()
96 /// .column(Glyph::Aspect)
97 /// .from(Glyph::Table)
98 /// .and_where(Expr::expr(Expr::col(Glyph::Aspect).if_null(0)).gt(2))
99 /// .order_by(Glyph::Image, Order::Desc)
100 /// .order_by((Glyph::Table, Glyph::Aspect), Order::Asc)
101 /// .to_owned();
102 ///
103 /// assert_eq!(
104 /// query.to_string(MysqlQueryBuilder),
105 /// r#"SELECT `aspect` FROM `glyph` WHERE IFNULL(`aspect`, 0) > 2 ORDER BY `image` DESC, `glyph`.`aspect` ASC"#
106 /// );
107 ///
108 /// let (placeholder, numbered) = MysqlQueryBuilder.placeholder();
109 /// let mut sql = SqlWriterValues::new(placeholder, numbered);
110 ///
111 /// assert_eq!(
112 /// query.build_collect(MysqlQueryBuilder, &mut sql),
113 /// r#"SELECT `aspect` FROM `glyph` WHERE IFNULL(`aspect`, ?) > ? ORDER BY `image` DESC, `glyph`.`aspect` ASC"#
114 /// );
115 ///
116 /// let (sql, values) = sql.into_parts();
117 /// assert_eq!(
118 /// values,
119 /// Values(vec![Value::Int(Some(0)), Value::Int(Some(2))])
120 /// );
121 /// ```
122 fn build_collect<T: QueryBuilder>(&self, query_builder: T, sql: &mut dyn SqlWriter) -> String {
123 self.build_collect_into(query_builder, sql);
124 sql.to_string()
125 }
126
127 fn build_collect_into<T: QueryBuilder>(&self, query_builder: T, sql: &mut dyn SqlWriter);
128}