1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
//! dml parser contains algorithm for parsing restq DML syntax into
//! a DML AST.
//!
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(','))
}

/// product{product_id,created_by,created,is_active}?returning=product_id,name
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(','))
}

/// product{description="I'm the new description now",is_active=false}?product_id=1
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,
        }
    })
}

///  product?product_id=1
pub fn delete<'a>() -> Parser<'a, char, Delete> {
    (table() + (sym('?') * filter_expr()).opt())
        .map(|(from, condition)| Delete { from, condition })
}

/// bulk delete
pub fn bulk_delete<'a>() -> Parser<'a, char, BulkDelete> {
    (table() - sym('{') + columns() - sym('}')).map(|(from, columns)| {
        BulkDelete {
            from,
            columns,
            values: vec![],
        }
    })
}

/// bulk update
pub fn bulk_update<'a>() -> Parser<'a, char, BulkUpdate> {
    (table() - sym('{') + columns() - sym('}')).map(|(table, columns)| {
        BulkUpdate {
            table,
            columns,
            values: vec![],
        }
    })
}