Skip to content

Commit 55ada32

Browse files
committed
implement IfElseStatement for MySQL backend
1 parent 098e88b commit 55ada32

File tree

6 files changed

+97
-1
lines changed

6 files changed

+97
-1
lines changed

src/backend/query_builder.rs

+15
Original file line numberDiff line numberDiff line change
@@ -387,9 +387,24 @@ pub trait QueryBuilder:
387387
SimpleExpr::Constant(val) => {
388388
self.prepare_constant(val, sql);
389389
}
390+
SimpleExpr::IfElse(val) => {
391+
self.prepare_if_else_statement(val, sql);
392+
}
390393
}
391394
}
392395

396+
fn prepare_if_else_statement(&self, val: &Box<IfElseStatement>, sql: &mut dyn SqlWriter) {
397+
write!(sql, "IF ").unwrap();
398+
self.prepare_simple_expr(&val.when, sql);
399+
write!(sql, " THEN\n").unwrap();
400+
self.prepare_simple_expr(&val.then, sql);
401+
if let Some(otherwise) = &val.otherwise {
402+
write!(sql, "\nELSE\n").unwrap();
403+
self.prepare_simple_expr(otherwise, sql);
404+
};
405+
write!(sql, "\nEND IF").unwrap();
406+
}
407+
393408
/// Translate [`CaseStatement`] into SQL statement.
394409
fn prepare_case_statement(&self, stmts: &CaseStatement, sql: &mut dyn SqlWriter) {
395410
write!(sql, "(CASE").unwrap();

src/expr.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
//!
55
//! [`SimpleExpr`] is the expression common among select fields, where clauses and many other places.
66
7-
use crate::{func::*, query::*, types::*, value::*};
7+
use crate::{func::*, query::*, types::*, value::*, if_else::*};
88

99
/// Helper to build a [`SimpleExpr`].
1010
#[derive(Debug, Clone)]
@@ -35,6 +35,7 @@ pub enum SimpleExpr {
3535
AsEnum(DynIden, Box<SimpleExpr>),
3636
Case(Box<CaseStatement>),
3737
Constant(Value),
38+
IfElse(Box<IfElseStatement>),
3839
}
3940

4041
/// "Operator" methods for building complex expressions.

src/if_else.rs

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
use crate::{QueryBuilder, SimpleExpr};
2+
3+
#[derive(Debug, Clone, PartialEq)]
4+
pub struct IfElseStatement {
5+
pub when: SimpleExpr,
6+
pub then: SimpleExpr,
7+
pub otherwise: Option<SimpleExpr>
8+
}
9+
10+
impl IfElseStatement {
11+
12+
pub fn new(when: SimpleExpr, then: SimpleExpr, otherwise: Option<SimpleExpr>) -> Self {
13+
Self {
14+
when,
15+
then,
16+
otherwise
17+
}
18+
}
19+
20+
pub fn to_string<T: QueryBuilder>(&self, query_builder: T) -> String {
21+
let mut sql = String::with_capacity(256);
22+
query_builder.prepare_if_else_statement(&Box::new(self.clone()), &mut sql);
23+
sql
24+
}
25+
26+
}
27+
pub trait IfElseStatementBuilder {
28+
/// Build corresponding SQL statement for certain database backend and return SQL string
29+
fn build<T: QueryBuilder>(&self, query_builder: T) -> String;
30+
31+
/// Build corresponding SQL statement for certain database backend and return SQL string
32+
fn to_string<T: QueryBuilder>(&self, query_builder: T) -> String {
33+
self.build(query_builder)
34+
}
35+
}

src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -826,6 +826,7 @@ pub mod table;
826826
pub mod token;
827827
pub mod types;
828828
pub mod value;
829+
pub mod if_else;
829830

830831
#[doc(hidden)]
831832
#[cfg(feature = "tests-cfg")]
@@ -843,6 +844,7 @@ pub use table::*;
843844
pub use token::*;
844845
pub use types::*;
845846
pub use value::*;
847+
pub use if_else::*;
846848

847849
#[cfg(feature = "derive")]
848850
pub use sea_query_derive::{enum_def, Iden, IdenStatic};

tests/mysql/if_else.rs

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
use super::*;
2+
use pretty_assertions::assert_eq;
3+
4+
#[test]
5+
fn if_without_else() {
6+
let query = Query::select().column(Asterisk).from(Glyph::Table).take();
7+
let then = SimpleExpr::SubQuery(None, Box::new(query.into_sub_query_statement()));
8+
let if_statement = IfElseStatement::new(
9+
Expr::col(Glyph::Id).eq(1),
10+
then,
11+
None
12+
);
13+
assert_eq!(
14+
if_statement.to_string(MysqlQueryBuilder),
15+
[
16+
"IF `id` = 1 THEN",
17+
"(SELECT * FROM `glyph`)",
18+
"END IF"
19+
].join("\n")
20+
)
21+
}
22+
23+
#[test]
24+
fn if_with_else() {
25+
let query = Query::select().column(Asterisk).from(Glyph::Table).take();
26+
let then = SimpleExpr::SubQuery(None, Box::new(query.into_sub_query_statement()));
27+
let if_statement = IfElseStatement::new(
28+
Expr::col(Glyph::Id).eq(1),
29+
then,
30+
Some(Expr::val("23").into())
31+
);
32+
assert_eq!(
33+
if_statement.to_string(MysqlQueryBuilder),
34+
[
35+
"IF `id` = 1 THEN",
36+
"(SELECT * FROM `glyph`)",
37+
"ELSE",
38+
"'23'",
39+
"END IF"
40+
].join("\n")
41+
)
42+
}

tests/mysql/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ mod foreign_key;
44
mod index;
55
mod query;
66
mod table;
7+
mod if_else;
78

89
#[path = "../common.rs"]
910
mod common;

0 commit comments

Comments
 (0)