use crate::sql::{SQL, Token};
use crate::traits::{SQLParam, ToSQL};
use crate::types::{Bool, Compatible};
use super::{Expr, NonNull, SQLExpr, Scalar};
pub fn in_array<'a, V, E, I, R>(expr: E, values: I) -> SQLExpr<'a, V, Bool, NonNull, Scalar>
where
V: SQLParam + 'a,
E: Expr<'a, V>,
I: IntoIterator<Item = R>,
R: Expr<'a, V>,
E::SQLType: Compatible<R::SQLType>,
{
let left_sql = expr.into_sql();
let mut values_iter = values.into_iter();
let sql = match values_iter.next() {
None => left_sql.append(SQL::raw("IN (SELECT NULL WHERE 1=0)")),
Some(first_value) => {
let mut result = left_sql
.push(Token::IN)
.push(Token::LPAREN)
.append(first_value.into_sql());
for value in values_iter {
result = result.push(Token::COMMA).append(value.into_sql());
}
result.push(Token::RPAREN)
}
};
SQLExpr::new(sql)
}
pub fn not_in_array<'a, V, E, I, R>(expr: E, values: I) -> SQLExpr<'a, V, Bool, NonNull, Scalar>
where
V: SQLParam + 'a,
E: Expr<'a, V>,
I: IntoIterator<Item = R>,
R: Expr<'a, V>,
E::SQLType: Compatible<R::SQLType>,
{
let left_sql = expr.into_sql();
let mut values_iter = values.into_iter();
let sql = match values_iter.next() {
None => left_sql.append(SQL::raw("NOT IN (SELECT NULL WHERE 1=0)")),
Some(first_value) => {
let mut result = left_sql
.push(Token::NOT)
.push(Token::IN)
.push(Token::LPAREN)
.append(first_value.into_sql());
for value in values_iter {
result = result.push(Token::COMMA).append(value.into_sql());
}
result.push(Token::RPAREN)
}
};
SQLExpr::new(sql)
}
pub fn in_subquery<'a, V, E, S>(expr: E, subquery: S) -> SQLExpr<'a, V, Bool, NonNull, Scalar>
where
V: SQLParam + 'a,
E: ToSQL<'a, V>,
S: ToSQL<'a, V>,
{
SQLExpr::new(
expr.into_sql()
.push(Token::IN)
.append(subquery.into_sql().parens()),
)
}
pub fn not_in_subquery<'a, V, E, S>(expr: E, subquery: S) -> SQLExpr<'a, V, Bool, NonNull, Scalar>
where
V: SQLParam + 'a,
E: ToSQL<'a, V>,
S: ToSQL<'a, V>,
{
SQLExpr::new(
expr.into_sql()
.push(Token::NOT)
.push(Token::IN)
.append(subquery.into_sql().parens()),
)
}
pub fn exists<'a, V, S>(subquery: S) -> SQLExpr<'a, V, Bool, NonNull, Scalar>
where
V: SQLParam + 'a,
S: ToSQL<'a, V>,
{
SQLExpr::new(
SQL::from_iter([Token::EXISTS, Token::LPAREN])
.append(subquery.into_sql())
.push(Token::RPAREN),
)
}
pub fn not_exists<'a, V, S>(subquery: S) -> SQLExpr<'a, V, Bool, NonNull, Scalar>
where
V: SQLParam + 'a,
S: ToSQL<'a, V>,
{
SQLExpr::new(
SQL::from_iter([Token::NOT, Token::EXISTS, Token::LPAREN])
.append(subquery.into_sql())
.push(Token::RPAREN),
)
}