update js
This commit is contained in:
parent
93125a715a
commit
62aa00ebf1
3382
lib/core/parse/generic/genericAutocompleteParser.js
Normal file
3382
lib/core/parse/generic/genericAutocompleteParser.js
Normal file
File diff suppressed because one or more lines are too long
3347
lib/core/parse/generic/genericSyntaxParser.js
Normal file
3347
lib/core/parse/generic/genericSyntaxParser.js
Normal file
File diff suppressed because one or more lines are too long
1983
lib/core/parse/generic/sqlParseSupport.js
Normal file
1983
lib/core/parse/generic/sqlParseSupport.js
Normal file
File diff suppressed because it is too large
Load Diff
5705
lib/core/parse/hive/hiveAutocompleteParser.js
Normal file
5705
lib/core/parse/hive/hiveAutocompleteParser.js
Normal file
File diff suppressed because one or more lines are too long
5644
lib/core/parse/hive/hiveSyntaxParser.js
Normal file
5644
lib/core/parse/hive/hiveSyntaxParser.js
Normal file
File diff suppressed because one or more lines are too long
2208
lib/core/parse/hive/sqlParseSupport.js
Normal file
2208
lib/core/parse/hive/sqlParseSupport.js
Normal file
File diff suppressed because it is too large
Load Diff
5407
lib/core/parse/impala/impalaAutocompleteParser.js
Normal file
5407
lib/core/parse/impala/impalaAutocompleteParser.js
Normal file
File diff suppressed because one or more lines are too long
5364
lib/core/parse/impala/impalaSyntaxParser.js
Normal file
5364
lib/core/parse/impala/impalaSyntaxParser.js
Normal file
File diff suppressed because one or more lines are too long
2289
lib/core/parse/impala/sqlParseSupport.js
Normal file
2289
lib/core/parse/impala/sqlParseSupport.js
Normal file
File diff suppressed because it is too large
Load Diff
4518
lib/core/parse/sqlFunctions.js
Normal file
4518
lib/core/parse/sqlFunctions.js
Normal file
File diff suppressed because it is too large
Load Diff
84
lib/core/parse/sqlParserRepository.js
Normal file
84
lib/core/parse/sqlParserRepository.js
Normal file
@ -0,0 +1,84 @@
|
||||
"use strict";
|
||||
// Licensed to Cloudera, Inc. under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. Cloudera, Inc. licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* AUTOCOMPLETE_MODULES and SYNTAX_MODULES are generated, do not edit manually, see tools/jison/generateParsers.js
|
||||
*/
|
||||
const AUTOCOMPLETE_MODULES = {
|
||||
calcite: require("calcite/calciteAutocompleteParser"),
|
||||
druid: require("druid/druidAutocompleteParser"),
|
||||
elasticsearch: require("elasticsearch/elasticsearchAutocompleteParser"),
|
||||
flink: require("flink/flinkAutocompleteParser"),
|
||||
generic: require("generic/genericAutocompleteParser"),
|
||||
hive: require("hive/hiveAutocompleteParser"),
|
||||
impala: require("impala/impalaAutocompleteParser"),
|
||||
ksql: require("ksql/ksqlAutocompleteParser"),
|
||||
phoenix: require("phoenix/phoenixAutocompleteParser"),
|
||||
presto: require("presto/prestoAutocompleteParser")
|
||||
};
|
||||
const SYNTAX_MODULES = {
|
||||
calcite: require("calcite/calciteSyntaxParser"),
|
||||
druid: require("druid/druidSyntaxParser"),
|
||||
elasticsearch: require("elasticsearch/elasticsearchSyntaxParser"),
|
||||
flink: require("flink/flinkSyntaxParser"),
|
||||
generic: require("generic/genericSyntaxParser"),
|
||||
hive: require("hive/hiveSyntaxParser"),
|
||||
impala: require("impala/impalaSyntaxParser"),
|
||||
ksql: require("ksql/ksqlSyntaxParser"),
|
||||
phoenix: require("phoenix/phoenixSyntaxParser"),
|
||||
presto: require("presto/prestoSyntaxParser")
|
||||
};
|
||||
/* eslint-enable */
|
||||
class SqlParserRepository {
|
||||
constructor() {
|
||||
this.modulePromises = {};
|
||||
}
|
||||
getParser(sourceType, parserType) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (!this.modulePromises[sourceType + parserType]) {
|
||||
const modules = parserType === 'Autocomplete' ? AUTOCOMPLETE_MODULES : SYNTAX_MODULES;
|
||||
this.modulePromises[sourceType + parserType] = new Promise((resolve, reject) => {
|
||||
const targetModule = modules[sourceType] || modules.generic;
|
||||
resolve(targetModule);
|
||||
});
|
||||
}
|
||||
return this.modulePromises[sourceType + parserType];
|
||||
});
|
||||
}
|
||||
getAutocompleter(sourceType) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
return this.getParser(sourceType, 'Autocomplete');
|
||||
});
|
||||
}
|
||||
getSyntaxParser(sourceType) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
return this.getParser(sourceType, 'Syntax');
|
||||
});
|
||||
}
|
||||
}
|
||||
const sqlParserRepository = new SqlParserRepository();
|
||||
exports.default = sqlParserRepository;
|
75
lib/core/parse/stringDistance.js
Normal file
75
lib/core/parse/stringDistance.js
Normal file
@ -0,0 +1,75 @@
|
||||
"use strict";
|
||||
// Licensed to Cloudera, Inc. under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. Cloudera, Inc. licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
/**
|
||||
* Calculates the Optimal String Alignment distance between two strings. Returns 0 when the strings are equal and the
|
||||
* distance when not, distances is less than or equal to the length of the longest string.
|
||||
*
|
||||
* @param strA
|
||||
* @param strB
|
||||
* @param [ignoreCase]
|
||||
* @returns {number} The similarity
|
||||
*/
|
||||
const stringDistance = function (strA, strB, ignoreCase) {
|
||||
if (ignoreCase) {
|
||||
strA = strA.toLowerCase();
|
||||
strB = strB.toLowerCase();
|
||||
}
|
||||
// TODO: Consider other algorithms for performance
|
||||
const strALength = strA.length;
|
||||
const strBLength = strB.length;
|
||||
if (strALength === 0) {
|
||||
return strBLength;
|
||||
}
|
||||
if (strBLength === 0) {
|
||||
return strALength;
|
||||
}
|
||||
const distances = new Array(strALength);
|
||||
let cost, deletion, insertion, substitution, transposition;
|
||||
for (let i = 0; i <= strALength; i++) {
|
||||
distances[i] = new Array(strBLength);
|
||||
distances[i][0] = i;
|
||||
for (let j = 1; j <= strBLength; j++) {
|
||||
if (!i) {
|
||||
distances[0][j] = j;
|
||||
}
|
||||
else {
|
||||
cost = strA[i - 1] === strB[j - 1] ? 0 : 1;
|
||||
deletion = distances[i - 1][j] + 1;
|
||||
insertion = distances[i][j - 1] + 1;
|
||||
substitution = distances[i - 1][j - 1] + cost;
|
||||
if (deletion <= insertion && deletion <= substitution) {
|
||||
distances[i][j] = deletion;
|
||||
}
|
||||
else if (insertion <= deletion && insertion <= substitution) {
|
||||
distances[i][j] = insertion;
|
||||
}
|
||||
else {
|
||||
distances[i][j] = substitution;
|
||||
}
|
||||
if (i > 1 && j > 1 && strA[i] === strB[j - 1] && strA[i - 1] === strB[j]) {
|
||||
transposition = distances[i - 2][j - 2] + cost;
|
||||
if (transposition < distances[i][j]) {
|
||||
distances[i][j] = transposition;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return distances[strALength][strBLength];
|
||||
};
|
||||
exports.default = stringDistance;
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,8 +1,44 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
// import * as sqlSyntaxParser from '../core/sqlSyntaxParser';
|
||||
const sqlSyntaxParser = require("../core/sqlSyntaxParser");
|
||||
const sqlAutoCompleteParser = require("../core/sqlAutoCompleteParser");
|
||||
const hiveSyntaxParser_1 = require("../core/parse/hive/hiveSyntaxParser");
|
||||
const hiveAutocompleteParser_1 = require("../core/parse/hive/hiveAutocompleteParser");
|
||||
const impalaSyntaxParser_1 = require("../core/parse/impala/impalaSyntaxParser");
|
||||
const impalaAutocompleteParser_1 = require("../core/parse/impala/impalaAutocompleteParser");
|
||||
const genericSyntaxParser_1 = require("../core/parse/generic/genericSyntaxParser");
|
||||
const genericAutocompleteParser_1 = require("../core/parse/generic/genericAutocompleteParser");
|
||||
function getSyntaxParser(type) {
|
||||
switch (type) {
|
||||
case sqlType.Hive: {
|
||||
return hiveSyntaxParser_1.default;
|
||||
}
|
||||
case sqlType.Impala: {
|
||||
return impalaSyntaxParser_1.default;
|
||||
}
|
||||
case sqlType.None: {
|
||||
return genericSyntaxParser_1.default;
|
||||
}
|
||||
default: {
|
||||
return hiveSyntaxParser_1.default;
|
||||
}
|
||||
}
|
||||
}
|
||||
function getAutoCompleteParser(type) {
|
||||
switch (type) {
|
||||
case sqlType.Hive: {
|
||||
return hiveAutocompleteParser_1.default;
|
||||
}
|
||||
case sqlType.Impala: {
|
||||
return impalaAutocompleteParser_1.default;
|
||||
}
|
||||
case sqlType.None: {
|
||||
return genericAutocompleteParser_1.default;
|
||||
}
|
||||
default: {
|
||||
return hiveAutocompleteParser_1.default;
|
||||
}
|
||||
}
|
||||
}
|
||||
var sqlType;
|
||||
(function (sqlType) {
|
||||
sqlType["Hive"] = "hive";
|
||||
@ -26,7 +62,8 @@ function sqlToParserArgs(sql) {
|
||||
*/
|
||||
function parseSyntax(sql, type = sqlType.Hive) {
|
||||
const parserArgs = sqlToParserArgs(sql);
|
||||
return sqlSyntaxParser.parser.parseSyntax(parserArgs[0], parserArgs[1], type, false);
|
||||
console.log(getSyntaxParser(type));
|
||||
return getSyntaxParser(type).parseSyntax(parserArgs[0], parserArgs[1], type, false);
|
||||
}
|
||||
exports.parseSyntax = parseSyntax;
|
||||
/**
|
||||
@ -34,6 +71,6 @@ exports.parseSyntax = parseSyntax;
|
||||
*/
|
||||
function parserSql(sql, type = sqlType.Hive) {
|
||||
const parserArgs = sqlToParserArgs(sql);
|
||||
return sqlAutoCompleteParser.parser.parseSql(parserArgs[0], parserArgs[1], type, false);
|
||||
return getAutoCompleteParser(type).parseSql(parserArgs[0], parserArgs[1], type, false);
|
||||
}
|
||||
exports.parserSql = parserSql;
|
||||
|
467
lib/scripts/generateParsers.js
Normal file
467
lib/scripts/generateParsers.js
Normal file
@ -0,0 +1,467 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const exec = require('child_process').exec;
|
||||
const LICENSE = '// Licensed to Cloudera, Inc. under one\n' +
|
||||
'// or more contributor license agreements. See the NOTICE file\n' +
|
||||
'// distributed with this work for additional information\n' +
|
||||
'// regarding copyright ownership. Cloudera, Inc. licenses this file\n' +
|
||||
'// to you under the Apache License, Version 2.0 (the\n' +
|
||||
'// "License"); you may not use this file except in compliance\n' +
|
||||
'// with the License. You may obtain a copy of the License at\n' +
|
||||
'//\n' +
|
||||
'// http://www.apache.org/licenses/LICENSE-2.0\n' +
|
||||
'//\n' +
|
||||
'// Unless required by applicable law or agreed to in writing, software\n' +
|
||||
'// distributed under the License is distributed on an "AS IS" BASIS,\n' +
|
||||
'// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n' +
|
||||
'// See the License for the specific language governing permissions and\n' +
|
||||
'// limitations under the License.\n';
|
||||
const SQL_STATEMENTS_PARSER_JSDOC = '/**\n' +
|
||||
' * @param {string} input\n' +
|
||||
' *\n' +
|
||||
' * @return {SqlStatementsParserResult}\n' +
|
||||
' */\n';
|
||||
const PARSER_FOLDER = path.join(process.cwd(), 'src/core/parse/');
|
||||
const JISON_FOLDER = path.join(process.cwd(), 'src/jison/');
|
||||
const SQL_PARSER_REPOSITORY_PATH = path.join(PARSER_FOLDER, 'sqlParserRepository.js');
|
||||
const SYNTAX_PARSER_IMPORT_TEMPLATE = ' KEY: require("KEY/KEYSyntaxParser")';
|
||||
const AUTOCOMPLETE_PARSER_IMPORT_TEMPLATE = ' KEY: require("KEY/KEYAutocompleteParser")';
|
||||
const parserDefinitions = {
|
||||
globalSearchParser: {
|
||||
sources: [path.join(JISON_FOLDER, 'globalSearchParser.jison')],
|
||||
target: path.join(JISON_FOLDER, 'globalSearchParser.jison'),
|
||||
outputFolder: PARSER_FOLDER,
|
||||
afterParse: contents => new Promise(resolve => {
|
||||
resolve(LICENSE +
|
||||
contents.replace('var globalSearchParser = ', "import SqlParseSupport from './sqlParseSupport';\n\nvar globalSearchParser = ") +
|
||||
'\nexport default globalSearchParser;\n');
|
||||
})
|
||||
},
|
||||
solrFormulaParser: {
|
||||
sources: [path.join(JISON_FOLDER, 'solrFormulaParser.jison')],
|
||||
target: path.join(JISON_FOLDER, 'solrFormulaParser.jison'),
|
||||
outputFolder: PARSER_FOLDER,
|
||||
afterParse: contents => new Promise(resolve => {
|
||||
resolve(LICENSE + contents + 'export default solrFormulaParser;\n');
|
||||
})
|
||||
},
|
||||
solrQueryParser: {
|
||||
sources: [path.join(JISON_FOLDER, 'solrQueryParser.jison')],
|
||||
target: path.join(JISON_FOLDER, 'solrQueryParser.jison'),
|
||||
outputFolder: PARSER_FOLDER,
|
||||
afterParse: contents => new Promise(resolve => {
|
||||
resolve(LICENSE + contents + 'export default solrQueryParser;\n');
|
||||
})
|
||||
},
|
||||
sqlStatementsParser: {
|
||||
sources: [path.join(JISON_FOLDER, 'sqlStatementsParser.jison')],
|
||||
target: path.join(JISON_FOLDER, 'sqlStatementsParser.jison'),
|
||||
outputFolder: PARSER_FOLDER,
|
||||
afterParse: contents => new Promise(resolve => {
|
||||
resolve(LICENSE +
|
||||
contents.replace('parse: function parse', SQL_STATEMENTS_PARSER_JSDOC + 'parse: function parse') +
|
||||
'export default sqlStatementsParser;\n');
|
||||
})
|
||||
}
|
||||
};
|
||||
const mkdir = path => new Promise((resolve, reject) => {
|
||||
if (fs.existsSync(path)) {
|
||||
resolve();
|
||||
}
|
||||
else {
|
||||
fs.mkdir(path, err => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
});
|
||||
const readFile = path => new Promise((resolve, reject) => {
|
||||
fs.readFile(path, (err, buf) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
}
|
||||
resolve(buf ? buf.toString() : '');
|
||||
});
|
||||
});
|
||||
const writeFile = (path, contents) => new Promise((resolve, reject) => {
|
||||
fs.writeFile(path, contents, err => {
|
||||
if (err) {
|
||||
reject();
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
const copyFile = (source, destination, contentsCallback) => new Promise((resolve, reject) => {
|
||||
readFile(source)
|
||||
.then(contents => {
|
||||
writeFile(destination, contentsCallback ? contentsCallback(contents) : contents)
|
||||
.then(resolve)
|
||||
.catch(reject);
|
||||
})
|
||||
.catch(reject);
|
||||
});
|
||||
const deleteFile = path => {
|
||||
fs.unlinkSync(path);
|
||||
};
|
||||
const execCmd = cmd => new Promise((resolve, reject) => {
|
||||
exec(cmd, (err, stdout, stderr) => {
|
||||
if (err) {
|
||||
reject('stderr:\n' + stderr + '\n\nstdout:\n' + stdout);
|
||||
}
|
||||
resolve(stdout);
|
||||
});
|
||||
});
|
||||
const generateParser = parserName => new Promise((resolve, reject) => {
|
||||
const parserConfig = parserDefinitions[parserName];
|
||||
/**
|
||||
* 合并jison文件,生成待编译文件
|
||||
*/
|
||||
const concatPromise = new Promise((resolve, reject) => {
|
||||
if (parserConfig.sources.length > 1 && parserConfig.target) {
|
||||
console.log('Concatenating files...');
|
||||
const promises = parserConfig.sources.map(fileName => readFile(fileName));
|
||||
Promise.all(promises)
|
||||
.then(contents => {
|
||||
writeFile(parserConfig.target, contents.join('')).then(() => {
|
||||
resolve(parserConfig.target);
|
||||
});
|
||||
})
|
||||
.catch(reject);
|
||||
}
|
||||
else if (parserConfig.sources.length === 1) {
|
||||
resolve(parserConfig.sources[0]);
|
||||
}
|
||||
else {
|
||||
reject('No jison source specified');
|
||||
}
|
||||
});
|
||||
concatPromise
|
||||
.then(targetPath => {
|
||||
console.log(`Generate precomplier jison success(${targetPath})...`);
|
||||
let jisonCommand = 'jison ' + targetPath;
|
||||
if (parserConfig.lexer) {
|
||||
jisonCommand += ' ' + parserConfig.lexer;
|
||||
}
|
||||
jisonCommand += ' -m js';
|
||||
console.log('Generating parser...');
|
||||
execCmd(jisonCommand)
|
||||
.then(stdout => {
|
||||
if (/\S/.test(stdout)) {
|
||||
console.log('got output for: ' + jisonCommand);
|
||||
console.log(stdout);
|
||||
}
|
||||
if (parserConfig.sources.length > 1) {
|
||||
deleteFile(targetPath); // Remove concatenated file
|
||||
}
|
||||
console.log('Adjusting JS...');
|
||||
/**
|
||||
* 删除生成文件,复制到配置的文件夹中
|
||||
*/
|
||||
const generatedJsFileName = parserConfig.target
|
||||
.replace('.jison', '.js')
|
||||
.replace(/^.*\/([^/]+)$/, '$1');
|
||||
readFile(generatedJsFileName)
|
||||
.then(contents => {
|
||||
parserConfig
|
||||
.afterParse(contents)
|
||||
.then(finalContents => {
|
||||
writeFile(path.join(parserConfig.outputFolder, generatedJsFileName), finalContents)
|
||||
.then(() => {
|
||||
deleteFile(generatedJsFileName);
|
||||
resolve();
|
||||
})
|
||||
.catch(reject);
|
||||
})
|
||||
.catch(reject);
|
||||
})
|
||||
.catch(reject);
|
||||
})
|
||||
.catch(reject);
|
||||
})
|
||||
.catch(reject);
|
||||
});
|
||||
let parsersToGenerate = [];
|
||||
const invalid = [];
|
||||
let all = false;
|
||||
const listDir = folder => new Promise(resolve => {
|
||||
fs.readdir(folder, (err, files) => {
|
||||
resolve(files);
|
||||
});
|
||||
});
|
||||
/**
|
||||
* 构造,添加子语言模块编译配置
|
||||
* @param {*} fileIndex 文件的存在表
|
||||
* @param {*} folder 对应的子语言文件夹
|
||||
* @param {*} sharedFiles 子语言核心jison文件
|
||||
* @param {*} autocomplete 是否为补全文件
|
||||
*/
|
||||
const findParser = (fileIndex, folder, sharedFiles, autocomplete) => {
|
||||
const prefix = autocomplete ? 'autocomplete' : 'syntax';
|
||||
if (fileIndex[prefix + '_header.jison'] && fileIndex[prefix + '_footer.jison']) {
|
||||
const parserName = folder + (autocomplete ? 'AutocompleteParser' : 'SyntaxParser');
|
||||
const parserDefinition = {
|
||||
sources: [path.join(JISON_FOLDER, 'sql', folder, prefix + '_header.jison')].concat(sharedFiles),
|
||||
lexer: path.join(JISON_FOLDER, 'sql', folder, '/sql.jisonlex'),
|
||||
target: path.join(JISON_FOLDER, 'sql', folder, parserName + '.jison'),
|
||||
sqlParser: autocomplete ? 'AUTOCOMPLETE' : 'SYNTAX',
|
||||
outputFolder: path.join(PARSER_FOLDER, folder),
|
||||
afterParse: contents => new Promise(resolve => {
|
||||
resolve(LICENSE +
|
||||
contents
|
||||
.replace('var ' + parserName + ' = ', "import SqlParseSupport from " +
|
||||
"'./sqlParseSupport';\n\nvar " +
|
||||
parserName +
|
||||
' = ')
|
||||
.replace('loc: yyloc,', "loc: lexer.yylloc, ruleId: stack.slice(stack.length - 2, stack.length).join(''),") +
|
||||
'\nexport default ' +
|
||||
parserName +
|
||||
';\n');
|
||||
})
|
||||
};
|
||||
parserDefinition.sources.push(path.join(JISON_FOLDER, 'sql', folder, prefix + '_footer.jison'));
|
||||
parserDefinitions[parserName] = parserDefinition;
|
||||
}
|
||||
else {
|
||||
console.log("Warn: Could not find '" +
|
||||
prefix +
|
||||
"_header.jison' or '" +
|
||||
prefix +
|
||||
"_footer.jison' in " +
|
||||
JISON_FOLDER +
|
||||
'sql/' +
|
||||
folder +
|
||||
'/');
|
||||
}
|
||||
};
|
||||
/**
|
||||
* 添加所有子语言编译配置
|
||||
*/
|
||||
const identifySqlParsers = () => new Promise(resolve => {
|
||||
listDir(JISON_FOLDER + 'sql').then(files => {
|
||||
const promises = [];
|
||||
files.forEach(folder => {
|
||||
const subLanguageJisonFolder = path.join(JISON_FOLDER, 'sql', folder);
|
||||
promises.push(
|
||||
/**
|
||||
* 遍历具体的语言目录
|
||||
*/
|
||||
listDir(subLanguageJisonFolder).then(jisonFiles => {
|
||||
/**
|
||||
* 文件目录记录表
|
||||
*/
|
||||
const fileIndex = {};
|
||||
jisonFiles.forEach(jisonFile => {
|
||||
fileIndex[jisonFile] = true;
|
||||
});
|
||||
/**
|
||||
* 挑选核心的jison文件(剥除autocomplate,syntax的功能文件)
|
||||
*/
|
||||
const sharedFiles = jisonFiles
|
||||
.filter(jisonFile => jisonFile.indexOf('sql_') !== -1)
|
||||
.map(jisonFile => path.join(subLanguageJisonFolder, jisonFile));
|
||||
if (fileIndex['sql.jisonlex']) {
|
||||
/**
|
||||
* 添加子语言自动补全编译配置
|
||||
* 加入了error.jison,为了在校验失败的情况下也能够提示?
|
||||
*/
|
||||
findParser(fileIndex, folder, sharedFiles, true);
|
||||
/**
|
||||
* 添加子语言语法检查配置
|
||||
*/
|
||||
findParser(fileIndex, folder, sharedFiles.filter(path => path.indexOf('_error.jison') === -1), false);
|
||||
}
|
||||
else {
|
||||
console.log("Warn: Could not find 'sql.jisonlex' in " + JISON_FOLDER + 'sql/' + folder + '/');
|
||||
}
|
||||
}));
|
||||
});
|
||||
Promise.all(promises).then(resolve);
|
||||
});
|
||||
});
|
||||
const copyTests = (source, target) => new Promise((resolve, reject) => {
|
||||
const replaceRegexp = new RegExp(source + '(Autocomplete|Syntax)Parser', 'g');
|
||||
mkdir(PARSER_FOLDER + target)
|
||||
.then(() => {
|
||||
mkdir(PARSER_FOLDER + target + '/test')
|
||||
.then(() => {
|
||||
listDir(PARSER_FOLDER + source + '/test')
|
||||
.then(testFiles => {
|
||||
const copyPromises = [];
|
||||
testFiles.forEach(testFile => {
|
||||
copyPromises.push(copyFile(PARSER_FOLDER + source + '/test/' + testFile, PARSER_FOLDER + target + '/test/' + testFile.replace(source, target), contents => contents.replace(replaceRegexp, target + '$1Parser')));
|
||||
});
|
||||
Promise.all(copyPromises)
|
||||
.then(resolve)
|
||||
.catch(reject);
|
||||
})
|
||||
.catch(reject);
|
||||
})
|
||||
.catch(reject);
|
||||
})
|
||||
.catch(reject);
|
||||
});
|
||||
/**
|
||||
* 校验,配置自定义语言
|
||||
*/
|
||||
const prepareForNewParser = () => new Promise((resolve, reject) => {
|
||||
/**
|
||||
* 根据一个子语言文件夹来生成一个特殊sql名字的语法文件
|
||||
* -new generic postgresql
|
||||
* 根据generic文件夹生成postgresql语法文件
|
||||
*/
|
||||
if (process.argv.length === 3 && process.argv[0] === '-new') {
|
||||
process.argv.shift();
|
||||
const source = process.argv.shift();
|
||||
const target = process.argv.shift();
|
||||
console.log("Generating new parser '" + target + "' based on '" + source + "'...");
|
||||
process.argv.push(target);
|
||||
if (!Object.keys(parserDefinitions).some(key => {
|
||||
if (key.indexOf(source) === 0) {
|
||||
copyTests(source, target)
|
||||
.then(() => {
|
||||
mkdir(JISON_FOLDER + 'sql/' + target)
|
||||
.then(() => {
|
||||
listDir(JISON_FOLDER + 'sql/' + source).then(files => {
|
||||
const copyPromises = [];
|
||||
files.forEach(file => {
|
||||
copyPromises.push(copyFile(JISON_FOLDER + 'sql/' + source + '/' + file, JISON_FOLDER + 'sql/' + target + '/' + file));
|
||||
});
|
||||
Promise.all(copyPromises).then(() => {
|
||||
const autocompleteSources = [
|
||||
'sql/' + target + '/autocomplete_header.jison'
|
||||
];
|
||||
const syntaxSources = ['sql/' + target + '/syntax_header.jison'];
|
||||
files.forEach(file => {
|
||||
if (file.indexOf('sql_') === 0) {
|
||||
autocompleteSources.push('sql/' + target + '/' + file);
|
||||
syntaxSources.push('sql/' + target + '/' + file);
|
||||
}
|
||||
});
|
||||
autocompleteSources.push('sql/' + target + '/autocomplete_footer.jison');
|
||||
syntaxSources.push('sql/' + target + '/syntax_footer.jison');
|
||||
mkdir('desktop/core/src/desktop/js/parse/sql/' + target).then(() => {
|
||||
copyFile('desktop/core/src/desktop/js/parse/sql/' +
|
||||
source +
|
||||
'/sqlParseSupport.js', 'desktop/core/src/desktop/js/parse/sql/' +
|
||||
target +
|
||||
'/sqlParseSupport.js', contents => contents.replace(/parser\.yy\.activeDialect = '[^']+';'/g, "parser.yy.activeDialect = '" + target + "';")).then(() => {
|
||||
identifySqlParsers()
|
||||
.then(resolve)
|
||||
.catch(reject);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err);
|
||||
});
|
||||
})
|
||||
.catch(reject);
|
||||
return true;
|
||||
}
|
||||
})) {
|
||||
reject("No existing parser found for '" + source + "'");
|
||||
}
|
||||
}
|
||||
else {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
identifySqlParsers().then(() => {
|
||||
process.argv.shift();
|
||||
process.argv.shift();
|
||||
console.log('Generate sub language success...');
|
||||
prepareForNewParser().then(() => {
|
||||
console.log('Generate custom language success...');
|
||||
process.argv.forEach(arg => {
|
||||
if (arg === 'all') {
|
||||
/**
|
||||
* 编译全部
|
||||
*/
|
||||
all = true;
|
||||
}
|
||||
else if (parserDefinitions[arg]) {
|
||||
/**
|
||||
* 特点编译目标
|
||||
*/
|
||||
parsersToGenerate.push(arg);
|
||||
}
|
||||
else {
|
||||
/**
|
||||
* 根据关键字匹配编译目标
|
||||
*/
|
||||
let prefixFound = false;
|
||||
Object.keys(parserDefinitions).forEach(key => {
|
||||
if (key.indexOf(arg) === 0) {
|
||||
prefixFound = true;
|
||||
parsersToGenerate.push(key);
|
||||
}
|
||||
});
|
||||
if (!prefixFound) {
|
||||
invalid.push(arg);
|
||||
}
|
||||
}
|
||||
});
|
||||
if (all) {
|
||||
parsersToGenerate = Object.keys(parserDefinitions);
|
||||
}
|
||||
if (invalid.length) {
|
||||
console.log("No parser config found for: '" + invalid.join("', '") + "'");
|
||||
console.log('\nPossible options are:\n ' +
|
||||
['all'].concat(Object.keys(parserDefinitions)).join('\n ') +
|
||||
'\n');
|
||||
return;
|
||||
}
|
||||
const parserCount = parsersToGenerate.length;
|
||||
let idx = 0;
|
||||
/**
|
||||
* 执行编译
|
||||
*/
|
||||
const generateRecursive = () => {
|
||||
idx++;
|
||||
if (parsersToGenerate.length) {
|
||||
const parserName = parsersToGenerate.pop();
|
||||
if (parserCount > 1) {
|
||||
console.log("Generating '" + parserName + "' (" + idx + '/' + parserCount + ')...');
|
||||
}
|
||||
else {
|
||||
console.log("Generating '" + parserName + "'...");
|
||||
}
|
||||
generateParser(parserName)
|
||||
.then(generateRecursive)
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
console.log('FAIL!');
|
||||
});
|
||||
}
|
||||
else {
|
||||
const autocompParsers = [];
|
||||
const syntaxParsers = [];
|
||||
console.log('Updating sqlParserRepository.js...');
|
||||
Object.keys(parserDefinitions).forEach(key => {
|
||||
if (parserDefinitions[key].sqlParser === 'AUTOCOMPLETE') {
|
||||
autocompParsers.push(AUTOCOMPLETE_PARSER_IMPORT_TEMPLATE.replace(/KEY/g, key.replace('AutocompleteParser', '')));
|
||||
}
|
||||
else if (parserDefinitions[key].sqlParser === 'SYNTAX') {
|
||||
syntaxParsers.push(SYNTAX_PARSER_IMPORT_TEMPLATE.replace(/KEY/g, key.replace('SyntaxParser', '')));
|
||||
}
|
||||
});
|
||||
readFile(SQL_PARSER_REPOSITORY_PATH).then(contents => {
|
||||
contents = contents.replace(/const SYNTAX_MODULES = [^}]+}/, 'const SYNTAX_MODULES = {\n' + syntaxParsers.sort().join(',\n') + '\n}');
|
||||
contents = contents.replace(/const AUTOCOMPLETE_MODULES = [^}]+}/, 'const AUTOCOMPLETE_MODULES = {\n' + autocompParsers.sort().join(',\n') + '\n}');
|
||||
writeFile(SQL_PARSER_REPOSITORY_PATH, contents).then(() => {
|
||||
console.log('Done!\n');
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
/**
|
||||
* 集中精力办大事
|
||||
*/
|
||||
generateRecursive();
|
||||
});
|
||||
});
|
||||
/* eslint-enable no-restricted-syntax */
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "dt-sql-parser",
|
||||
"version": "3.0.0",
|
||||
"version": "3.0.1",
|
||||
"description": "sql,hive,parser ",
|
||||
"keywords": [
|
||||
"hive",
|
||||
|
Loading…
Reference in New Issue
Block a user