This commit is contained in:
HSunboy 2018-07-02 18:01:01 +08:00
commit a729770b76
13 changed files with 17964 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
node_modules

8
README.md Normal file
View File

@ -0,0 +1,8 @@
### dt-sql-parser
本项目用于处理sql目前含有功能
1. 解析sql生成语法树(不支持CREATE等语句具体可以查看`core/astParser`文件)支持单条sql语句
2. 去除sql中的的注释(目前支持--类型注释)
语法解析模块代码来自nquery <http://github.com/alibaba/nquery/>

8513
core/astParser.js Normal file

File diff suppressed because it is too large Load Diff

12
core/cache.js Normal file
View File

@ -0,0 +1,12 @@
class Cache extends Map {
constructor(options){
super(...arguments)
}
set(key,value){
super.set(key,value);
}
}
module.exports=Cache;

9254
core/nquery.js Normal file

File diff suppressed because it is too large Load Diff

7
index.js Normal file
View File

@ -0,0 +1,7 @@
const parser = require("./lib/parser");
const filter = require("./lib/filter");
console.log(filter)
module.exports={
parser,
filter
}

75
lib/filter.js Normal file
View File

@ -0,0 +1,75 @@
const replaceStrFormIndexArr=require("../utils").replaceStrFormIndexArr;
function filterComments(sql) {
let tmpArr = [];
const comments = [];
for (let i = 0; i < sql.length; i++) {
let char = sql[i];
//读取字符
if (char == "'" || char == "\"" || char == "-" || char == "\n") {
//推入数组
tmpArr.push({
index: i,
char: char
});
}
//校验数组是否有匹配语法
if (tmpArr.length < 2) {
if (tmpArr[0] && tmpArr[0].char == "\n") {
tmpArr = [];
}
continue;
}
let firstChar = tmpArr[0];
let lastChar = tmpArr[tmpArr.length - 1];
if (firstChar.char == "'" || firstChar.char == "\"") {
//引号匹配,则清空
if (lastChar.char == firstChar.char) {
tmpArr = [];
continue;
}
} else if (firstChar.char == "-") {
//假如第一个是横线,则开始校验注释规则
//判断是否为两个注释符号,不是,则清空
if (tmpArr[1].char != "-") {
tmpArr = [];
continue;
}
//为注释作用域,遇到换行符,则结束注释
else if (lastChar.char == "\n") {
comments.push({
begin: firstChar.index,
end: lastChar.index
})
tmpArr = [];
continue;
}
//解析结束
else if (i == sql.length - 1) {
comments.push({
begin: firstChar.index,
end: i
})
continue;
}
} else {
tmpArr = [];
}
}
sql = replaceStrFormIndexArr(sql, '', comments)
return sql;
}
function cleanSql(sql){
return filterComments(sql).trim();
}
exports.filterComments=filterComments;
exports.cleanSql=cleanSql;

22
lib/parser.js Normal file
View File

@ -0,0 +1,22 @@
const Parser = require('../core/astParser');
const Cache = require("../core/cache");
const filter = require("./filter");
const astCache=new Cache();
function parse(sql){
const cleanSql=filter.cleanSql(sql);
console.log(cleanSql)
let ast=astCache.get(cleanSql);
if(ast){
return ast
}else{
ast=Parser.parse(cleanSql).ast;
astCache.set(cleanSql,ast);
return ast;
}
}
exports.parse=parse;

5
package-lock.json generated Normal file
View File

@ -0,0 +1,5 @@
{
"name": "dt-sql-parser",
"version": "1.0.0",
"lockfileVersion": 1
}

10
package.json Normal file
View File

@ -0,0 +1,10 @@
{
"name": "dt-sql-parser",
"version": "1.0.0",
"description": "sql parser",
"main": "index.js",
"scripts": {},
"author": "xiaokang",
"license": "ISC",
"devDependencies": {}
}

21
test/example.js Normal file
View File

@ -0,0 +1,21 @@
const example={
test0:`--alter table sx_622_1 add partition(pa=${"${bdp.system.bizdate}"});
SELECT muyun_test_down1.id, muyun_test_down1.name, muyun_test_down2.age
FROM muyun_test_down1
JOIN muyun_test_down2
ON muyun_test_down1.id = muyun_test_down2.id
`,
test1:`create table sql_task_comment_test(id int comment 'id') comment 'sql test';
--sdfsss`,
test2:` INSERT INTO TABLE muyun_test_down4
SELECT muyun_test_down1.id, muyun_test_down1.name, muyun_test_down2.age
FROM muyun_test_down1
JOIN muyun_test_down2
ON muyun_test_down1.id = muyun_test_down2.id;`,
test3:`--alter table sx_622_1 add partition(pa=${"${bdp.system.bizdate}"});
alter table sx_622_1 add partition(pa=${"${bdp.system.cyctime}"});
alter table sx_622_1 add partition(pa=${"${bdp.system.currmonth}"});
alter table sx_622_1 add partition(pa=${"${bdp.system.premonth}"});`
}
module.exports=example;

12
test/index.js Normal file
View File

@ -0,0 +1,12 @@
const dtSqlParser=require("../index");
const example=require("./example");
const testMap=Object.entries(example);
for(let [key,value] of testMap){
console.log(`******${key}********`)
console.log(value)
console.log(`******result********`)
console.log(dtSqlParser.parser.parse(value));
console.log(`********************`)
}

24
utils/index.js Normal file
View File

@ -0,0 +1,24 @@
function replaceStrFormIndexArr(str, replaceStr, indexArr) {
let arr = [];
let result = "";
let index = 0;
if (!indexArr || indexArr.length < 1) {
return str;
}
for (let i = 0; i < indexArr.length; i++) {
let indexItem = indexArr[i];
let begin = indexItem.begin;
result = result + str.substring(index, begin) + replaceStr;
index = indexItem.end + 1;
if (i == indexArr.length - 1) {
result = result + str.substring(index);
}
}
return result;
}
exports.replaceStrFormIndexArr=replaceStrFormIndexArr;