///|
/// A DELETE statement builder. Generative like `Select`, and it shares the same
/// WHERE clause.
pub struct Delete {
table : String
filter : Where
returning : Array[String]
}
///|
/// Start a DELETE from `table`.
pub fn delete(table : String) -> Delete {
{ table, filter: Where::new(), returning: [], }
}
///|
fn Delete::dup(self : Delete) -> Delete {
{
table: self.table,
filter: self.filter.dup(),
returning: self.returning.copy(),
}
}
///|
/// Narrow the delete with `col op ?`. Conditions are ANDed together.
pub fn Delete::where_(
self : Delete,
col : String,
op : String,
val : Value,
) -> Delete {
let d = self.dup()
d.filter.conds.push({ col, op, val, })
d
}
///|
/// Narrow the delete with a boolean `Predicate` tree. See `Select::where_pred`.
pub fn Delete::where_pred(self : Delete, pred : Predicate) -> Delete {
let d = self.dup()
d.filter.preds.push(pred)
d
}
///|
/// Narrow the delete with `col IN (subquery)` — "delete the rows some other query
/// picks out". The subquery's bound values splice in at the predicate's position.
pub fn Delete::where_in(self : Delete, col : String, sub : Select) -> Delete {
let d = self.dup()
d.filter.sub_conds.push({ col, op: "IN", sub, })
d
}
///|
/// Narrow the delete with `col NOT IN (subquery)`. See `where_in`.
pub fn Delete::where_not_in(
self : Delete,
col : String,
sub : Select,
) -> Delete {
let d = self.dup()
d.filter.sub_conds.push({ col, op: "NOT IN", sub, })
d
}
///|
/// Return `col` from each deleted row (SQLite 3.35+, PostgreSQL) — the row's
/// contents survive the delete only if you ask for them here. Repeatable;
/// `build_for(Mysql)` drops it.
pub fn Delete::returning(self : Delete, col : String) -> Delete {
let d = self.dup()
d.returning.push(col)
d
}
///|
/// Return every column of each deleted row (`RETURNING *`). See `returning`.
pub fn Delete::returning_all(self : Delete) -> Delete {
self.returning("*")
}
///|
/// Render `(sql, params)` for the SQLite/PostgreSQL dialect.
pub fn Delete::build(self : Delete) -> (String, Array[Value]) {
self.build_for(Sqlite)
}
///|
/// Render `(sql, params)` for `dialect`. Identical everywhere but `RETURNING`,
/// which MySQL does not have and so does not get.
pub fn Delete::build_for(
self : Delete,
dialect : Dialect,
) -> (String, Array[Value]) {
let params : Array[Value] = []
let mut sql = "DELETE FROM " + self.table
let where_sql = self.filter.sql(params)
if where_sql != "" {
sql = sql + " WHERE " + where_sql
}
if self.returning.length() > 0 && dialect != Mysql {
sql = sql + " RETURNING " + self.returning.join(", ")
}
(sql, params)
}
///|
pub extend LockMode with Debug::{to_repr}
///|
pub extend LockMode with Eq::{not_equal, equal}
///|
pub extend LockClause with Debug::{to_repr}
///|
pub extend LockClause with Eq::{not_equal, equal}