3 releases
0.1.2 | Apr 20, 2021 |
---|---|
0.1.1 | Sep 5, 2019 |
0.1.0 | Aug 20, 2019 |
#1749 in Parser implementations
19KB
353 lines
sql-script-parser iterates over SQL statements in SQL script
Legal
Dual-licensed under MIT
or the UNLICENSE.
Features
- parses SQL scripts (currently MySQL) to sequence of separate SQL statements.
- marks parts of the SQL statement as different token types (keywords, strings, comments, ...).
- not validating input, only splits SQL statements without checking that they are valid.
Usage
Add dependency to Cargo.toml:
[dependencies]
sql-script-parser = "0.1"
Parse SQL:
use sql_script_parser::sql_script_parser;
let sql = include_bytes!("../tests/demo.sql");
let mut parser = sql_script_parser(sql).map(|x| x.statement);
assert_eq!(parser.next(), Some(&b"select 1;\n"[..]));
assert_eq!(parser.next(), Some(&b"select 2"[..]));
assert_eq!(parser.next(), None);
Advanced - use custom tokenizer:
use sql_script_parser::*;
struct DmlDdlSqlScriptTokenizer;
struct SqlStatement<'a> {
sql_script: SqlScript<'a>,
kind: SqlStatementKind,
}
#[derive(Debug, PartialEq)]
enum SqlStatementKind {
Ddl,
Dml,
}
impl<'a> SqlScriptTokenizer<'a, SqlStatement<'a>> for DmlDdlSqlScriptTokenizer {
fn apply(&self, sql_script: SqlScript<'a>, tokens: &[SqlToken]) -> SqlStatement<'a> {
let mut tokens_general = tokens.iter().filter(|x| {
[
SqlTokenKind::Word,
SqlTokenKind::Symbol,
SqlTokenKind::String,
]
.contains(&x.kind)
});
let kind = if let Some(first_keyword) = tokens_general.next() {
if first_keyword.kind == SqlTokenKind::Word {
let token = std::str::from_utf8(first_keyword.extract(&sql_script))
.unwrap()
.to_lowercase();
match token.as_str() {
"alter" | "create" | "drop" => SqlStatementKind::Ddl,
_ => SqlStatementKind::Dml,
}
} else {
SqlStatementKind::Dml
}
} else {
SqlStatementKind::Dml
};
SqlStatement { sql_script, kind }
}
}
let sql = include_bytes!("../tests/custom.sql");
let mut parser = SqlScriptParser::new(DmlDdlSqlScriptTokenizer {}, sql).map(|x| x.kind);
assert_eq!(parser.next(), Some(SqlStatementKind::Dml));
assert_eq!(parser.next(), Some(SqlStatementKind::Ddl));
assert_eq!(parser.next(), Some(SqlStatementKind::Dml));
assert_eq!(parser.next(), Some(SqlStatementKind::Ddl));
assert_eq!(parser.next(), None);