From ed19261b213742c7cec4cbbee4b2b7442f14f3e8 Mon Sep 17 00:00:00 2001 From: Muhannad Alrusayni Date: Tue, 14 Sep 2021 14:14:36 +0300 Subject: [PATCH] Fix #120 --- src/backend/query_builder.rs | 2 ++ src/query/delete.rs | 65 +++++++++++++++++++++++++++++++++++- 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/src/backend/query_builder.rs b/src/backend/query_builder.rs index e67c7b2e1..f29753a7e 100644 --- a/src/backend/query_builder.rs +++ b/src/backend/query_builder.rs @@ -215,6 +215,8 @@ pub trait QueryBuilder: QuotedBuilder { write!(sql, " LIMIT ").unwrap(); self.prepare_value(limit, sql, collector); } + + self.prepare_returning(&delete.returning, sql, collector); } /// Translate [`SimpleExpr`] into SQL statement. diff --git a/src/query/delete.rs b/src/query/delete.rs index f8b9f695b..d8c83e2e0 100644 --- a/src/query/delete.rs +++ b/src/query/delete.rs @@ -4,7 +4,7 @@ use crate::{ query::{condition::*, OrderedStatement}, types::*, value::*, - QueryStatementBuilder, + Query, QueryStatementBuilder, SelectExpr, SelectStatement, }; /// Delete existing rows from the table @@ -39,6 +39,7 @@ pub struct DeleteStatement { pub(crate) wherei: ConditionHolder, pub(crate) orders: Vec, pub(crate) limit: Option, + pub(crate) returning: Vec, } impl Default for DeleteStatement { @@ -55,6 +56,7 @@ impl DeleteStatement { wherei: ConditionHolder::new(), orders: Vec::new(), limit: None, + returning: Vec::new(), } } @@ -97,6 +99,67 @@ impl DeleteStatement { self.limit = Some(Value::BigUnsigned(Some(limit))); self } + + /// RETURNING expressions. Postgres only. + /// + /// ``` + /// use sea_query::{tests_cfg::*, *}; + /// + /// let query = Query::delete() + /// .from_table(Glyph::Table) + /// .and_where(Expr::col(Glyph::Id).eq(1)) + /// .returning(Query::select().column(Glyph::Id).take()) + /// .to_owned(); + /// + /// assert_eq!( + /// query.to_string(MysqlQueryBuilder), + /// r#"DELETE FROM `glyph` WHERE `id` = 1"# + /// ); + /// assert_eq!( + /// query.to_string(PostgresQueryBuilder), + /// r#"DELETE FROM "glyph" WHERE "id" = 1 RETURNING "id""# + /// ); + /// assert_eq!( + /// query.to_string(SqliteQueryBuilder), + /// r#"DELETE FROM `glyph` WHERE `id` = 1"# + /// ); + /// ``` + pub fn returning(&mut self, select: SelectStatement) -> &mut Self { + self.returning = select.selects; + self + } + + /// RETURNING a column after delete. Postgres only. + /// Wrapper over [`DeleteStatement::returning()`]. + /// + /// ``` + /// use sea_query::{tests_cfg::*, *}; + /// + /// let query = Query::delete() + /// .from_table(Glyph::Table) + /// .and_where(Expr::col(Glyph::Id).eq(1)) + /// .returning_col(Glyph::Id) + /// .to_owned(); + /// + /// assert_eq!( + /// query.to_string(MysqlQueryBuilder), + /// r#"DELETE FROM `glyph` WHERE `id` = 1"# + /// ); + /// assert_eq!( + /// query.to_string(PostgresQueryBuilder), + /// r#"DELETE FROM "glyph" WHERE "id" = 1 RETURNING "id""# + /// ); + /// assert_eq!( + /// query.to_string(SqliteQueryBuilder), + /// r#"DELETE FROM `glyph` WHERE `id` = 1"# + /// ); + /// ``` + pub fn returning_col(&mut self, col: C) -> &mut Self + where + C: IntoIden, + { + self.returning(Query::select().column(col.into_iden()).take()) + } } impl QueryStatementBuilder for DeleteStatement {