update js
This commit is contained in:
		
							
								
								
									
										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"; | "use strict"; | ||||||
| Object.defineProperty(exports, "__esModule", { value: true }); | Object.defineProperty(exports, "__esModule", { value: true }); | ||||||
| // import * as sqlSyntaxParser from '../core/sqlSyntaxParser'; | // import * as sqlSyntaxParser from '../core/sqlSyntaxParser'; | ||||||
| const sqlSyntaxParser = require("../core/sqlSyntaxParser"); | const hiveSyntaxParser_1 = require("../core/parse/hive/hiveSyntaxParser"); | ||||||
| const sqlAutoCompleteParser = require("../core/sqlAutoCompleteParser"); | 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; | var sqlType; | ||||||
| (function (sqlType) { | (function (sqlType) { | ||||||
|     sqlType["Hive"] = "hive"; |     sqlType["Hive"] = "hive"; | ||||||
| @ -26,7 +62,8 @@ function sqlToParserArgs(sql) { | |||||||
|  */ |  */ | ||||||
| function parseSyntax(sql, type = sqlType.Hive) { | function parseSyntax(sql, type = sqlType.Hive) { | ||||||
|     const parserArgs = sqlToParserArgs(sql); |     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; | exports.parseSyntax = parseSyntax; | ||||||
| /** | /** | ||||||
| @ -34,6 +71,6 @@ exports.parseSyntax = parseSyntax; | |||||||
|  */ |  */ | ||||||
| function parserSql(sql, type = sqlType.Hive) { | function parserSql(sql, type = sqlType.Hive) { | ||||||
|     const parserArgs = sqlToParserArgs(sql); |     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; | 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", |   "name": "dt-sql-parser", | ||||||
|   "version": "3.0.0", |   "version": "3.0.1", | ||||||
|   "description": "sql,hive,parser ", |   "description": "sql,hive,parser ", | ||||||
|   "keywords": [ |   "keywords": [ | ||||||
|     "hive", |     "hive", | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user