فهرست منبع

[editor] Combine local and api top joins

Johan Ahlen 4 سال پیش
والد
کامیت
fc8f6ffd26
1فایلهای تغییر یافته به همراه56 افزوده شده و 5 حذف شده
  1. 56 5
      desktop/core/src/desktop/js/catalog/optimizer/SqlAnalyzer.ts

+ 56 - 5
desktop/core/src/desktop/js/catalog/optimizer/SqlAnalyzer.ts

@@ -15,8 +15,9 @@
 // limitations under the License.
 
 import { CancellablePromise } from 'api/cancellablePromise';
-import { OptimizerMeta } from 'catalog/DataCatalogEntry';
-import { TopAggs, TopColumns, TopFilters, TopJoins } from 'catalog/MultiTableEntry';
+import contextCatalog from 'catalog/contextCatalog';
+import { OptimizerMeta, TableSourceMeta } from 'catalog/DataCatalogEntry';
+import { TopAggs, TopColumns, TopFilters, TopJoins, TopJoinValue } from 'catalog/MultiTableEntry';
 import ApiStrategy from 'catalog/optimizer/ApiStrategy';
 import {
   API_STRATEGY,
@@ -29,9 +30,9 @@ import {
   SimilarityOptions
 } from 'catalog/optimizer/optimizer';
 
-import { OptimizerResponse } from 'catalog/dataCatalog';
+import dataCatalog, { OptimizerResponse } from 'catalog/dataCatalog';
 import sqlParserRepository from 'parse/sql/sqlParserRepository';
-import { Connector } from 'types/config';
+import { Connector, Namespace } from 'types/config';
 import { hueWindow } from 'types/types';
 import I18n from 'utils/i18n';
 
@@ -85,7 +86,57 @@ export default class SqlAnalyzer implements Optimizer {
   }
 
   fetchTopJoins(options: PopularityOptions): CancellablePromise<TopJoins> {
-    return this.apiStrategy.fetchTopJoins(options);
+    const apiPromise = this.apiStrategy.fetchTopJoins(options);
+
+    const path = options.paths[0].join('.');
+
+    return new CancellablePromise<TopJoins>((resolve, reject, onCancel) => {
+      contextCatalog
+        .getNamespaces({ connector: this.connector, silenceErrors: !options.silenceErrors })
+        .then(async (result: { namespaces: Namespace[] }) => {
+          if (!result.namespaces.length || !result.namespaces[0].computes.length) {
+            reject('No namespace or compute found');
+            console.warn(result);
+            return;
+          }
+          const entry = await dataCatalog.getEntry({
+            connector: this.connector,
+            path: path,
+            namespace: result.namespaces[0],
+            compute: result.namespaces[0].computes[0]
+          });
+
+          const sourceMetaPromise = entry.getSourceMeta(options);
+
+          onCancel(() => {
+            apiPromise.cancel();
+            sourceMetaPromise.cancel();
+          });
+
+          try {
+            const sourceMeta = await sourceMetaPromise;
+            const values: TopJoinValue[] = ((<TableSourceMeta>sourceMeta).foreign_keys || []).map(
+              key => ({
+                totalTableCount: 22,
+                totalQueryCount: 3,
+                joinCols: [{ columns: [path + '.' + key.name, key.to] }],
+                tables: [path].concat(key.to.split('.', 2).join('.')),
+                joinType: 'join'
+              })
+            );
+
+            try {
+              const apiResponse = await apiPromise;
+              values.push(...apiResponse.values);
+            } catch (err) {}
+
+            resolve({ values });
+          } catch (err) {
+            reject(err);
+          }
+        })
+        .catch(reject);
+    });
   }
 
   analyzeCompatibility(options: CompatibilityOptions): CancellablePromise<unknown> {