graphic_walker_parser/parser/
mod.rs

1pub mod error;
2pub mod model;
3pub mod workflow;
4
5mod builder;
6mod expr;
7mod panit;
8
9use base64::{engine::general_purpose, Engine as _};
10use error::ParserError;
11use expr::*;
12use model::{DataView, Sort, DSL};
13use panit::*;
14use sqlparser::ast::*;
15use sqlparser::dialect::DuckDbDialect;
16use sqlparser::parser::Parser as SqlParser;
17use std::{collections::HashMap, io::Read, result};
18use workflow::*;
19
20use self::builder::QueryBuilder;
21
22pub type Result<T> = result::Result<T, ParserError>;
23
24pub fn parse_dsl(
25    dataset: &model::Dataset,
26    query: &str,
27    params: ParserParams,
28) -> Result<std::string::String> {
29    // serialize dsl
30    let dsl: DSL = match serde_json::from_str(query) {
31        Ok(it) => it,
32        Err(err) => return Err(ParserError::DSLSerializeError(err.to_string())),
33    };
34
35    // biild parser
36    let parser = Parser::new(params);
37
38    let ast = parser.parser_dsl(dsl, dataset)?;
39
40    // check sql security
41    let res = ast.to_string();
42    if !check_dsl(res.to_string()) {
43        return Err(ParserError::SecurityCheckError);
44    }
45
46    Ok(res)
47}
48
49pub fn check_dsl(sql: String) -> bool {
50    let res_ast = SqlParser::parse_sql(&DuckDbDialect {}, &sql);
51    if res_ast.is_err() {
52        return false;
53    }
54    let res_statements = res_ast.unwrap();
55    if res_statements.len() != 1 {
56        return false;
57    }
58    let check = matches!(res_statements[0], Statement::Query(_));
59    check
60}