浏览代码

HUE-9117 [editor] Add default limit input next to execute in editor v2

Johan Ahlen 5 年之前
父节点
当前提交
f65625679c

+ 16 - 0
desktop/core/src/desktop/js/apps/notebook2/components/ko.executableActions.js

@@ -50,6 +50,9 @@ const TEMPLATE = `
       <!-- /ko -->
     <!-- /ko -->
   </div>
+  <form autocomplete="off" class="inline-block">
+    <input class="input-small limit-input" type="text" ${ window.PREVENT_AUTOFILL_INPUT_ATTRS } placeholder="${ I18n('Limit') }" data-bind="textInput: limit">
+  </form>
 </div>
 `;
 
@@ -64,6 +67,14 @@ class ExecutableActions extends DisposableComponent {
     this.partOfRunningExecution = ko.observable(false);
     this.beforeExecute = params.beforeExecute;
 
+    this.limit = ko.observable();
+
+    this.subscribe(this.limit, newVal => {
+      if (this.activeExecutable()) {
+        this.activeExecutable().executor.limit = newVal;
+      }
+    });
+
     this.waiting = ko.pureComputed(
       () =>
         this.activeExecutable() &&
@@ -93,11 +104,16 @@ class ExecutableActions extends DisposableComponent {
     });
 
     this.subscribe(this.activeExecutable, this.updateFromExecutable.bind(this));
+
+    if (this.activeExecutable()) {
+      this.updateFromExecutable(this.activeExecutable());
+    }
   }
 
   updateFromExecutable(executable) {
     this.status(executable.status);
     this.partOfRunningExecution(executable.isPartOfRunningExecution());
+    this.limit(executable.executor.limit);
   }
 
   async stop() {

+ 2 - 0
desktop/core/src/desktop/js/apps/notebook2/components/ko.executableActions.test.js

@@ -16,6 +16,7 @@ describe('ko.executableActions.js', () => {
       isReady: () => true,
       reset: () => {},
       nextExecutable: {},
+      executor: {},
       status: EXECUTION_STATUS.ready
     };
     const activeExecutable = () => mockExecutable;
@@ -44,6 +45,7 @@ describe('ko.executableActions.js', () => {
       isReady: () => true,
       reset: () => {},
       nextExecutable: {},
+      executor: {},
       status: EXECUTION_STATUS.ready
     };
     const activeExecutable = () => mockExecutable;

+ 2 - 0
desktop/core/src/desktop/js/apps/notebook2/execution/executor.js

@@ -41,6 +41,8 @@ class Executor {
     this.isOptimizerEnabled = options.isOptimizerEnabled;
     this.executables = [];
 
+    this.limit = 10;
+
     this.snippet = options.snippet;
   }
 

+ 19 - 2
desktop/core/src/desktop/js/apps/notebook2/execution/sqlExecutable.js

@@ -19,6 +19,8 @@ import Executable from 'apps/notebook2/execution/executable';
 
 const BATCHABLE_STATEMENT_TYPES = /ALTER|CREATE|DELETE|DROP|GRANT|INSERT|INVALIDATE|LOAD|SET|TRUNCATE|UPDATE|UPSERT|USE/i;
 
+const SELECT_END_REGEX = /([^;]*)([;]?[^;]*)/;
+
 export default class SqlExecutable extends Executable {
   /**
    * @param options
@@ -34,7 +36,22 @@ export default class SqlExecutable extends Executable {
   }
 
   getStatement() {
-    return this.statement || this.parsedStatement.statement;
+    let statement = this.statement || this.parsedStatement.statement;
+    if (
+      this.parsedStatement &&
+      this.parsedStatement.firstToken.toLowerCase() === 'select' &&
+      this.executor.limit &&
+      !/\slimit\s[0-9]/i.test(statement)
+    ) {
+      const endMatch = statement.match(SELECT_END_REGEX);
+      if (endMatch) {
+        statement = endMatch[1] + ' LIMIT ' + this.executor.limit;
+        if (endMatch[2]) {
+          statement += endMatch[2];
+        }
+      }
+    }
+    return statement;
   }
 
   async internalExecute() {
@@ -85,7 +102,7 @@ export default class SqlExecutable extends Executable {
   toJson() {
     return JSON.stringify({
       id: this.id,
-      statement: this.parsedStatement.statement,
+      statement: this.getStatement(),
       database: this.database
       // session:
     });

+ 11 - 5
desktop/core/src/desktop/js/apps/notebook2/execution/sqlExecutable.test.js

@@ -30,12 +30,15 @@ describe('sqlExecutable.js', () => {
    * @param statement
    * @return {SqlExecutable}
    */
-  const createSubject = statement => {
+  const createSubject = (statement, limit) => {
     if (typeof statement === 'string') {
       return new SqlExecutable({
         database: 'default',
-        parsedStatement: { statement: statement },
-        sourceType: 'impala'
+        parsedStatement: { statement: statement, firstToken: 'select' },
+        sourceType: 'impala',
+        executor: {
+          limit: limit
+        }
       });
     }
 
@@ -44,7 +47,10 @@ describe('sqlExecutable.js', () => {
       namespace: { id: 'namespace' },
       database: 'default',
       parsedStatement: statement,
-      sourceType: 'impala'
+      sourceType: 'impala',
+      executor: {
+        limit: limit
+      }
     });
   };
 
@@ -55,7 +61,7 @@ describe('sqlExecutable.js', () => {
   });
 
   it('should handle parsed statements', () => {
-    const subject = createSubject({ statement: 'SELECT * FROM customers' });
+    const subject = createSubject({ statement: 'SELECT * FROM customers', firstToken: 'SELECT' });
 
     expect(subject.getStatement()).toEqual('SELECT * FROM customers');
   });

+ 11 - 7
desktop/core/src/desktop/js/apps/notebook2/snippet.js

@@ -700,13 +700,17 @@ export default class Snippet {
     });
 
     this.statement = ko.pureComputed(() => {
-      let statement = this.isSqlDialect()
-        ? this.selectedStatement()
-          ? this.selectedStatement()
-          : this.positionStatement() !== null
-          ? this.positionStatement().statement
-          : this.statement_raw()
-        : this.statement_raw();
+      let statement = this.statement_raw();
+      if (this.isSqlDialect()) {
+        if (this.activeExecutable()) {
+          statement = this.activeExecutable().getStatement();
+        } else if (this.selectedStatement()) {
+          statement = this.selectedStatement();
+        } else if (this.positionStatement()) {
+          statement = this.positionStatement().statement;
+        }
+      }
+
       const variables = this.variables().reduce((variables, variable) => {
         variables[variable.name()] = variable;
         return variables;

文件差异内容过多而无法显示
+ 0 - 0
desktop/core/src/desktop/static/desktop/css/hue.css


文件差异内容过多而无法显示
+ 0 - 0
desktop/core/src/desktop/static/desktop/css/hue3-extra.css


+ 8 - 0
desktop/core/src/desktop/static/desktop/less/components/hue-snippet-execute-actions.less

@@ -39,4 +39,12 @@
       .hue-inset-box-shadow;
     }
   }
+
+  .limit-input {
+    border-radius: 2px;
+    height: 13px;
+    width: 32px;
+    margin: 0 5px;
+    padding: 5px 6px;
+  }
 }

部分文件因为文件数量过多而无法显示