rsfbclient_diesel/fb/
query_builder.rs1use super::backend::{Fb, FbReturningClause};
4use diesel::backend::sql_dialect::default_keyword_for_insert::DoesNotSupportDefaultKeyword;
5use diesel::insertable::ColumnInsertValue;
6use diesel::insertable::DefaultableColumnInsertValue;
7use diesel::insertable::InsertValues;
8use diesel::query_builder::*;
9use diesel::AppearsOnTable;
10use diesel::Column;
11use diesel::Expression;
12use diesel::QueryResult;
13
14pub struct FbQueryBuilder {
15 query: String,
16 pub has_cursor: bool,
17}
18
19impl FbQueryBuilder {
20 pub fn new() -> Self {
21 FbQueryBuilder {
22 query: String::new(),
23 has_cursor: true,
24 }
25 }
26}
27
28impl Default for FbQueryBuilder {
29 fn default() -> Self {
30 FbQueryBuilder::new()
31 }
32}
33
34impl QueryBuilder<Fb> for FbQueryBuilder {
35 fn push_sql(&mut self, sql: &str) {
36 self.query.push_str(sql);
37
38 if sql.trim().to_lowercase() == "returning" {
39 self.has_cursor = false;
40 }
41 }
42
43 fn push_identifier(&mut self, identifier: &str) -> QueryResult<()> {
44 self.query.push_str(identifier);
45
46 Ok(())
47 }
48
49 fn push_bind_param(&mut self) {
50 self.query.push('?');
51 }
52
53 fn finish(self) -> String {
54 self.query
55 }
56}
57
58impl QueryFragment<Fb> for LimitOffsetClause<NoLimitClause, NoOffsetClause> {
59 fn walk_ast(&self, _out: AstPass<Fb>) -> QueryResult<()> {
60 Ok(())
61 }
62}
63
64impl<L> QueryFragment<Fb> for LimitOffsetClause<LimitClause<L>, NoOffsetClause>
65where
66 L: QueryFragment<Fb>,
67{
68 fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, Fb>) -> QueryResult<()> {
69 out.push_sql(" FIRST ");
70 self.limit_clause.0.walk_ast(out.reborrow())?;
71 out.push_sql(" ");
72 Ok(())
73 }
74}
75
76impl<L> QueryFragment<Fb> for LimitOffsetClause<LimitClause<L>, OffsetClause<L>>
77where
78 L: QueryFragment<Fb>,
79{
80 fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, Fb>) -> QueryResult<()> {
81 out.push_sql(" FIRST ");
82 self.limit_clause.0.walk_ast(out.reborrow())?;
83 out.push_sql(" SKIP ");
84 self.offset_clause.0.walk_ast(out.reborrow())?;
85 out.push_sql(" ");
86 Ok(())
87 }
88}
89
90impl<F, S, D, W, O, LOf, G, H, LC> QueryFragment<Fb, crate::fb::backend::FbSelectStatementSyntax>
91 for SelectStatement<F, S, D, W, O, LOf, G, H, LC>
92where
93 S: QueryFragment<Fb>,
94 F: QueryFragment<Fb>,
95 D: QueryFragment<Fb>,
96 W: QueryFragment<Fb>,
97 O: QueryFragment<Fb>,
98 LOf: QueryFragment<Fb>,
99 G: QueryFragment<Fb>,
100 H: QueryFragment<Fb>,
101 LC: QueryFragment<Fb>,
102{
103 fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, Fb>) -> QueryResult<()> {
104 out.push_sql("SELECT ");
105 self.limit_offset.walk_ast(out.reborrow())?;
106 self.distinct.walk_ast(out.reborrow())?;
107 self.select.walk_ast(out.reborrow())?;
108 self.from.walk_ast(out.reborrow())?;
109 self.where_clause.walk_ast(out.reborrow())?;
110 self.group_by.walk_ast(out.reborrow())?;
111 self.having.walk_ast(out.reborrow())?;
112 self.order.walk_ast(out.reborrow())?;
113 self.locking.walk_ast(out.reborrow())?;
114 Ok(())
115 }
116}
117
118impl<'a, ST, QS, GB> QueryFragment<Fb, crate::fb::backend::FbSelectStatementSyntax>
119 for BoxedSelectStatement<'a, ST, QS, Fb, GB>
120where
121 QS: QueryFragment<Fb>,
122 BoxedLimitOffsetClause<'a, Fb>: QueryFragment<Fb>,
123{
124 fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, Fb>) -> QueryResult<()> {
125 out.push_sql("SELECT ");
126 self.limit_offset.walk_ast(out.reborrow())?;
127 self.distinct.walk_ast(out.reborrow())?;
128 self.select.walk_ast(out.reborrow())?;
129 self.from.walk_ast(out.reborrow())?;
130 self.where_clause.walk_ast(out.reborrow())?;
131 self.group_by.walk_ast(out.reborrow())?;
132 self.having.walk_ast(out.reborrow())?;
133 self.order.walk_ast(out.reborrow())?;
134 Ok(())
135 }
136}
137
138impl<Col, Expr> InsertValues<Col::Table, Fb>
139 for DefaultableColumnInsertValue<ColumnInsertValue<Col, Expr>>
140where
141 Col: Column,
142 Expr: Expression<SqlType = Col::SqlType> + AppearsOnTable<NoFromClause>,
143 Self: QueryFragment<Fb>,
144{
145 fn column_names(&self, mut out: AstPass<'_, '_, Fb>) -> QueryResult<()> {
146 if let Self::Expression(..) = *self {
147 out.push_identifier(Col::NAME)?;
148 }
149 Ok(())
150 }
151}
152
153impl<Col, Expr> QueryFragment<Fb, DoesNotSupportDefaultKeyword>
154 for DefaultableColumnInsertValue<ColumnInsertValue<Col, Expr>>
155where
156 Expr: QueryFragment<Fb>,
157{
158 fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, Fb>) -> QueryResult<()> {
159 if let Self::Expression(ref inner) = *self {
160 inner.walk_ast(out.reborrow())?;
161 }
162 Ok(())
163 }
164}
165
166impl<Expr> QueryFragment<Fb, FbReturningClause> for ReturningClause<Expr>
167where
168 Expr: QueryFragment<Fb>,
169{
170 fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, Fb>) -> QueryResult<()> {
171 out.push_sql(" RETURNING ");
172 self.0.walk_ast(out.reborrow())?;
173 Ok(())
174 }
175}