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