1use std::fmt;
2use std::io::BufRead;
3use std::str;
4
5use das::SetStatement;
6use dds::{
7 AlterDatabaseStatement, AlterTableStatement, CreateIndexStatement, CreateTableStatement,
8 DropDatabaseStatement, DropEventStatement, DropFunctionStatement, DropIndexStatement,
9 DropLogfileGroupStatement, DropProcedureStatement, DropServerStatement,
10 DropSpatialReferenceSystemStatement, DropTableStatement, DropTablespaceStatement,
11 DropTriggerStatement, DropViewStatement, RenameTableStatement, TruncateTableStatement,
12};
13use dms::{
14 CompoundSelectStatement, DeleteStatement, InsertStatement, SelectStatement, UpdateStatement,
15};
16use nom::branch::alt;
17use nom::combinator::map;
18use nom::Offset;
19
20pub struct Parser;
21
22impl Parser {
23 pub fn parse(config: &ParseConfig, input: &str) -> Result<Statement, String> {
24 let input = input.trim();
25
26 let dds_parser = alt((
27 map(AlterDatabaseStatement::parse, Statement::AlterDatabase),
28 map(AlterTableStatement::parse, Statement::AlterTable),
29 map(CreateIndexStatement::parse, Statement::CreateIndex),
30 map(CreateTableStatement::parse, Statement::CreateTable),
31 map(DropDatabaseStatement::parse, Statement::DropDatabase),
32 map(DropEventStatement::parse, Statement::DropEvent),
33 map(DropFunctionStatement::parse, Statement::DropFunction),
34 map(DropIndexStatement::parse, Statement::DropIndex),
35 map(
36 DropLogfileGroupStatement::parse,
37 Statement::DropLogfileGroup,
38 ),
39 map(DropProcedureStatement::parse, Statement::DropProcedure),
40 map(DropServerStatement::parse, Statement::DropServer),
41 map(
42 DropSpatialReferenceSystemStatement::parse,
43 Statement::DropSpatialReferenceSystem,
44 ),
45 map(DropTableStatement::parse, Statement::DropTable),
46 map(DropTablespaceStatement::parse, Statement::DropTableSpace),
47 map(DropTriggerStatement::parse, Statement::DropTrigger),
48 map(DropViewStatement::parse, Statement::DropView),
49 map(RenameTableStatement::parse, Statement::RenameTable),
50 map(TruncateTableStatement::parse, Statement::TruncateTable),
51 ));
52
53 let das_parser = alt((map(SetStatement::parse, Statement::Set),));
54
55 let dms_parser = alt((
56 map(SelectStatement::parse, Statement::Select),
57 map(CompoundSelectStatement::parse, Statement::CompoundSelect),
58 map(InsertStatement::parse, Statement::Insert),
59 map(DeleteStatement::parse, Statement::Delete),
60 map(UpdateStatement::parse, Statement::Update),
61 ));
62
63 let mut parser = alt((dds_parser, dms_parser, das_parser));
64
65 match parser(input) {
66 Ok(result) => Ok(result.1),
67 Err(nom::Err::Error(err)) => {
68 if config.log_with_backtrace {
69 println!(">>>>>>>>>>>>>>>>>>>>");
70 for error in &err.errors {
71 println!("{:?} :: {:?}", error.0, error.1)
72 }
73 println!("<<<<<<<<<<<<<<<<<<<<");
74 }
75
76 let msg = err.errors[0].0;
77 let err_msg = format!("failed to parse sql, error near `{}`", msg);
78 Err(err_msg)
79 }
80 _ => Err(String::from("failed to parse sql: other error")),
81 }
82 }
83}
84
85#[derive(Default)]
86pub struct ParseConfig {
87 pub log_with_backtrace: bool,
88}
89
90#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
91pub enum Statement {
92 AlterDatabase(AlterDatabaseStatement),
94 AlterTable(AlterTableStatement),
95 CreateIndex(CreateIndexStatement),
96 CreateTable(CreateTableStatement),
97 DropDatabase(DropDatabaseStatement),
98 DropEvent(DropEventStatement),
99 DropFunction(DropFunctionStatement),
100 DropIndex(DropIndexStatement),
101 DropLogfileGroup(DropLogfileGroupStatement),
102 DropProcedure(DropProcedureStatement),
103 DropServer(DropServerStatement),
104 DropSpatialReferenceSystem(DropSpatialReferenceSystemStatement),
105 DropTable(DropTableStatement),
106 DropTableSpace(DropTablespaceStatement),
107 DropTrigger(DropTriggerStatement),
108 DropView(DropViewStatement),
109 RenameTable(RenameTableStatement),
110 TruncateTable(TruncateTableStatement),
111 Set(SetStatement),
113 Insert(InsertStatement),
115 CompoundSelect(CompoundSelectStatement),
116 Select(SelectStatement),
117 Delete(DeleteStatement),
118 Update(UpdateStatement),
119}
120
121impl fmt::Display for Statement {
122 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
123 match *self {
124 Statement::Select(ref select) => write!(f, "{}", select),
126 Statement::Insert(ref insert) => write!(f, "{}", insert),
127 Statement::CreateTable(ref create) => write!(f, "{}", create),
128 Statement::Delete(ref delete) => write!(f, "{}", delete),
129 Statement::DropTable(ref drop) => write!(f, "{}", drop),
130 Statement::DropDatabase(ref drop) => write!(f, "{}", drop),
131 Statement::TruncateTable(ref drop) => write!(f, "{}", drop),
132 Statement::Update(ref update) => write!(f, "{}", update),
133 Statement::Set(ref set) => write!(f, "{}", set),
134 _ => unimplemented!(),
135 }
136 }
137}