use super::{column, list_fail, tag};
use crate::{
ast::{
dml::{table, value, Source},
BulkDelete, BulkUpdate, Delete, Insert, Update, Value,
},
filter_expr,
pom::parser::*,
ColumnName,
};
fn returning<'a>() -> Parser<'a, char, Vec<ColumnName>> {
tag("returning=") * columns()
}
fn columns<'a>() -> Parser<'a, char, Vec<ColumnName>> {
list_fail(column(), sym(','))
}
pub fn insert<'a>() -> Parser<'a, char, Insert> {
(table() - sym('{') + columns() - sym('}') + (sym('?') * returning()).opt())
.map(|((into, columns), returning)| Insert {
into,
columns,
returning,
source: Source::Values(vec![]),
})
}
fn column_value<'a>() -> Parser<'a, char, (ColumnName, Value)> {
column() - sym('=') + value()
}
fn column_values<'a>() -> Parser<'a, char, Vec<(ColumnName, Value)>> {
list_fail(column_value(), sym(','))
}
pub fn update<'a>() -> Parser<'a, char, Update> {
(table() - sym('{') + column_values() - sym('}')
+ (sym('?') * filter_expr()).opt())
.map(|((table, column_values), condition)| {
let (columns, values) = column_values.into_iter().unzip();
Update {
table,
columns,
values,
condition,
}
})
}
pub fn delete<'a>() -> Parser<'a, char, Delete> {
(table() + (sym('?') * filter_expr()).opt())
.map(|(from, condition)| Delete { from, condition })
}
pub fn bulk_delete<'a>() -> Parser<'a, char, BulkDelete> {
(table() - sym('{') + columns() - sym('}')).map(|(from, columns)| {
BulkDelete {
from,
columns,
values: vec![],
}
})
}
pub fn bulk_update<'a>() -> Parser<'a, char, BulkUpdate> {
(table() - sym('{') + columns() - sym('}')).map(|(table, columns)| {
BulkUpdate {
table,
columns,
values: vec![],
}
})
}