Эх сурвалжийг харах

[frontend] use encoded tags for complex db types when copying result to clipboard (#2887)

Co-authored-by: Björn Alm <balm@cloudera.com>
Bjorn Alm 3 жил өмнө
parent
commit
c40a2981e1

+ 2 - 0
desktop/core/src/desktop/js/utils/hueUtils.ts

@@ -38,6 +38,7 @@ import stripHtmlFromFunctions from './html/stripHtmlForFunctions';
 import deleteAllEmptyStringKeys from './string/deleteAllEmptyStringKeys';
 import equalIgnoreCase from './string/equalIgnoreCase';
 import parseHivePseudoJson from './string/parseHivePseudoJson';
+import isComplexDBTypeDefinition from './string/isComplexDBTypeDefinition';
 import UUID from './string/UUID';
 
 import waitForObservable from './timing/waitForObservable';
@@ -77,6 +78,7 @@ export default {
   isOverflowing,
   logError,
   parseHivePseudoJson,
+  isComplexDBTypeDefinition,
   removeURLParameter,
   replaceURL,
   scrollbarWidth,

+ 63 - 0
desktop/core/src/desktop/js/utils/string/isComplexDBTypeDefinition.test.js

@@ -0,0 +1,63 @@
+// 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.
+
+import isComplexDBTypeDefinition from './isComplexDBTypeDefinition';
+
+describe('hue.utils.js', () => {
+  describe('isComplexDBTypeDefinition', () => {
+    beforeEach(() => {});
+
+    it('returns true for complex DB type definitions', () => {
+      expect(isComplexDBTypeDefinition('map<string,array<string>>')).toEqual(true);
+      expect(isComplexDBTypeDefinition('MAP<string,array<string>>')).toEqual(true);
+      expect(isComplexDBTypeDefinition('array<string>')).toEqual(true);
+      expect(isComplexDBTypeDefinition('ARRAY<string>')).toEqual(true);
+      expect(isComplexDBTypeDefinition('struct<f1:bigint,f2:bigint>')).toEqual(true);
+      expect(isComplexDBTypeDefinition('STRUCT<f1:bigint,f2:bigint>')).toEqual(true);
+      expect(
+        isComplexDBTypeDefinition('uniontype<int, double, array<string>, struct<a:int,b:string>>')
+      ).toEqual(true);
+      expect(
+        isComplexDBTypeDefinition('UNIONTYPE<int, double, array<string>, struct<a:int,b:string>>')
+      ).toEqual(true);
+    });
+
+    it('returns false for other strings', () => {
+      expect(isComplexDBTypeDefinition('<string,array<string>>')).toEqual(false);
+      expect(isComplexDBTypeDefinition('<b>test</b>')).toEqual(false);
+      expect(isComplexDBTypeDefinition('<string>')).toEqual(false);
+      expect(isComplexDBTypeDefinition('xxx<f1:bigint,f2:bigint>')).toEqual(false);
+      expect(isComplexDBTypeDefinition('map')).toEqual(false);
+      expect(isComplexDBTypeDefinition('MAP')).toEqual(false);
+      expect(isComplexDBTypeDefinition('ARRAY')).toEqual(false);
+      expect(isComplexDBTypeDefinition('array')).toEqual(false);
+      expect(isComplexDBTypeDefinition('struc')).toEqual(false);
+      expect(isComplexDBTypeDefinition('STRUCT')).toEqual(false);
+      expect(isComplexDBTypeDefinition('uniontype')).toEqual(false);
+      expect(isComplexDBTypeDefinition('UNIONTYPE')).toEqual(false);
+    });
+
+    it('returns false for all non string based input', () => {
+      expect(isComplexDBTypeDefinition(12)).toEqual(false);
+      expect(isComplexDBTypeDefinition(-12)).toEqual(false);
+      expect(isComplexDBTypeDefinition({})).toEqual(false);
+      expect(isComplexDBTypeDefinition(undefined)).toEqual(false);
+      expect(isComplexDBTypeDefinition(new Date())).toEqual(false);
+      expect(isComplexDBTypeDefinition(null)).toEqual(false);
+      expect(isComplexDBTypeDefinition([])).toEqual(false);
+    });
+  });
+});

+ 23 - 0
desktop/core/src/desktop/js/utils/string/isComplexDBTypeDefinition.ts

@@ -0,0 +1,23 @@
+// 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.
+
+// Complex data type definitions used by Hive
+const complexTypes = /^(map|struct|array|uniontype)<.*>$/i;
+
+const isComplexDBTypeDefinition = (dataType: string | number): boolean =>
+  typeof dataType === 'string' ? complexTypes.test(dataType) : false;
+
+export default isComplexDBTypeDefinition;

+ 4 - 2
desktop/core/src/desktop/templates/common_notebook_ko_components.mako

@@ -407,8 +407,10 @@ else:
               result += '</tr>';
               data.forEach(function (row) {
                 result += '<tr>';
-                for (var i = 1; i < row.length; i++) { // Skip the row number column
-                  result += '<td>' + hueUtils.html2text(row[i]) + '</td>';
+                for (var i = 1; i < row.length; i++) { // Skip the row number column              
+                  var htmlDecodedValue = hueUtils.html2text(row[i]);
+                  var needsToStayEncoded = hueUtils.isComplexDBTypeDefinition(htmlDecodedValue)
+                  result += '<td>' + ( needsToStayEncoded ? row[i] : htmlDecodedValue) + '</td>';
                 }
                 result += '</tr>';
               });