Sfoglia il codice sorgente

HUE-8856 [autocomplete] Add sqlParserRepository for dynamic loading of SQL parsers on demand

Johan Ahlen 6 anni fa
parent
commit
eb6bef9ec6

+ 3 - 2
.babelrc

@@ -3,7 +3,8 @@
   "plugins": [
     ["module-resolver", {
       "root": ["./desktop/core/src/desktop/js"]
-    }]
+    }],
+    "@babel/plugin-syntax-dynamic-import"
   ],
   "overrides": [{
     "test": "./desktop/core/src/desktop/js/parse/sqlAutocompleteParser.js",
@@ -12,4 +13,4 @@
     "test": "./desktop/core/src/desktop/js/parse/sqlSyntaxParser.js",
     "compact": false
   }]
-}
+}

+ 3 - 0
desktop/core/src/desktop/js/hue.js

@@ -72,6 +72,8 @@ import sqlStatementsParser from 'parse/sqlStatementsParser'; // In search.ko and
 import HueFileEntry from 'doc/hueFileEntry';
 import HueDocument from 'doc/hueDocument';
 
+import sqlParserRepository from 'parse/sql/sqlParserRepository';
+
 // TODO: Migrate away
 window._ = _;
 window.apiHelper = apiHelper;
@@ -111,6 +113,7 @@ window.sqlAutocompleteParser = sqlAutocompleteParser;
 window.SqlAutocompleter = SqlAutocompleter;
 window.SqlFunctions = SqlFunctions;
 window.SqlSetOptions = SqlSetOptions;
+window.sqlParserRepository = sqlParserRepository;
 window.sqlStatementsParser = sqlStatementsParser;
 window.sqlUtils = sqlUtils;
 window.sqlWorkerHandler = sqlWorkerHandler;

+ 55 - 0
desktop/core/src/desktop/js/parse/sql/sqlParserRepository.js

@@ -0,0 +1,55 @@
+// 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.
+
+/* eslint-disable */
+/**
+ * AUTOCOMPLETE_MODULES and SYNTAX_MODULES are generated, do not edit manually, see tools/jison/generateParsers.js
+ */
+const AUTOCOMPLETE_MODULES = {
+  generic: () => import(/* webpackChunkName: "generic-parser" */ 'parse/sql/generic/genericAutocompleteParser'),
+  impala: () => import(/* webpackChunkName: "impala-parser" */ 'parse/sql/impala/impalaAutocompleteParser'),
+  hive: () => import(/* webpackChunkName: "hive-parser" */ 'parse/sql/hive/hiveAutocompleteParser')
+};
+const SYNTAX_MODULES = {
+  generic: () => import(/* webpackChunkName: "generic-parser" */ 'parse/sql/generic/genericSyntaxParser'),
+  impala: () => import(/* webpackChunkName: "impala-parser" */ 'parse/sql/impala/impalaSyntaxParser'),
+  hive: () => import(/* webpackChunkName: "hive-parser" */ 'parse/sql/hive/hiveSyntaxParser')
+};
+/* eslint-enable */
+
+class SqlParserRepository {
+  constructor() {
+    this.modulePromises = {};
+  }
+
+  async getAutocompleter(sourceType) {
+    if (!this.modulePromises[sourceType + 'Autocomplete']) {
+      this.modulePromises[sourceType + 'Autocomplete'] = AUTOCOMPLETE_MODULES[sourceType]();
+    }
+    return this.modulePromises[sourceType + 'Autocomplete'];
+  }
+
+  async getSyntaxParser(sourceType) {
+    if (!this.modulePromises[sourceType + 'Syntax']) {
+      this.modulePromises[sourceType + 'Syntax'] = AUTOCOMPLETE_MODULES[sourceType]();
+    }
+    return this.modulePromises[sourceType + 'Syntax'];
+  }
+}
+
+const sqlParserRepository = new SqlParserRepository();
+
+export default sqlParserRepository;

+ 9 - 0
package-lock.json

@@ -471,6 +471,15 @@
         "@babel/helper-plugin-utils": "^7.0.0"
       }
     },
+    "@babel/plugin-syntax-dynamic-import": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.2.0.tgz",
+      "integrity": "sha512-mVxuJ0YroI/h/tbFTPGZR8cv6ai+STMKNBq0f8hFxsxWjl94qqhsb+wXbpNMDPU3cfR1TIsVFzU3nXyZMqyK4w==",
+      "dev": true,
+      "requires": {
+        "@babel/helper-plugin-utils": "^7.0.0"
+      }
+    },
     "@babel/plugin-syntax-json-strings": {
       "version": "7.2.0",
       "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.2.0.tgz",

+ 37 - 1
tools/jison/generateParsers.js

@@ -42,6 +42,11 @@ const SQL_STATEMENTS_PARSER_JSDOC =
   ' */\n';
 
 const JISON_FOLDER = 'desktop/core/src/desktop/js/parse/jison/';
+const SQL_PARSER_REPOSITORY_PATH = 'desktop/core/src/desktop/js/parse/sql/sqlParserRepository.js';
+const SYNTAX_PARSER_IMPORT_TEMPLATE =
+  '  KEY: () => import(/* webpackChunkName: "KEY-parser" */ \'parse/sql/KEY/KEYSyntaxParser\')';
+const AUTOCOMPLETE_PARSER_IMPORT_TEMPLATE =
+  '  KEY: () => import(/* webpackChunkName: "KEY-parser" */ \'parse/sql/KEY/KEYAutocompleteParser\')';
 
 const parserDefinitions = {
   globalSearchParser: {
@@ -180,7 +185,6 @@ const generateParser = parserName =>
                     writeFile(parserConfig.outputFolder + generatedJsFileName, finalContents)
                       .then(() => {
                         deleteFile(generatedJsFileName);
-                        console.log('Done!\n');
                         resolve();
                       })
                       .catch(reject);
@@ -215,6 +219,7 @@ const findParser = (fileIndex, folder, sharedFiles, autocomplete) => {
       sources: ['sql/' + folder + '/' + prefix + '_header.jison'].concat(sharedFiles),
       lexer: 'sql/' + folder + '/sql.jisonlex',
       target: 'sql/' + folder + '/' + parserName + '.jison',
+      sqlParser: autocomplete ? 'AUTOCOMPLETE' : 'SYNTAX',
       outputFolder: 'desktop/core/src/desktop/js/parse/sql/' + folder + '/',
       afterParse: contents =>
         new Promise(resolve => {
@@ -344,6 +349,37 @@ identifySqlParsers().then(() => {
           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.join(',\n') + '\n}'
+        );
+        contents = contents.replace(
+          /const AUTOCOMPLETE_MODULES = [^}]+}/,
+          'const AUTOCOMPLETE_MODULES = {\n' + autocompParsers.join(',\n') + '\n}'
+        );
+        writeFile(SQL_PARSER_REPOSITORY_PATH, contents).then(() => {
+          console.log('Done!\n');
+        });
+      });
     }
   };
 

+ 2 - 1
webpack.config.js

@@ -57,7 +57,8 @@ module.exports = {
   },
   output: {
     path:  __dirname + '/desktop/core/src/desktop/static/desktop/js/bundles/hue',
-    filename: '[name]-bundle-[hash].js'
+    filename: '[name]-bundle-[hash].js',
+    chunkFilename: '[name]-bundle-[hash].js',
   },
   module: {
     rules: [