UNPKG

gethue

Version:

Hue is an Open source SQL Query Editor for Databases/Warehouses

263 lines (238 loc) 8.85 kB
// 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 $ from 'jquery'; import * as ko from 'knockout'; import { getComputes, getNamespaces } from '../../../catalog/contextCatalog'; import { NAMESPACES_REFRESHED_TOPIC } from '../../../catalog/events'; import AssistDbNamespace from '../../../ko/components/assist/assistDbNamespace'; import huePubSub from '../../../utils/huePubSub'; import { getFromLocalStorage } from '../../../utils/storageUtils'; class AssistDbSource { /** * @param {Object} options * @param {Object} options.i18n * @param {string} options.type * @param {Namespace} [options.initialNamespace] - Optional initial namespace to use * @param {Compute} [options.initialCompute] - Optional initial compute to use * @param {Connector} options.connector * @param {string} options.name * @param {boolean} options.nonSqlType - Optional, default false * @param {Object} options.navigationSettings * @constructor */ constructor(options) { const self = this; // TODO: Get rid of sourceType self.sourceType = options.type; self.connector = options.connector; self.name = options.name; self.i18n = options.i18n; self.nonSqlType = options.nonSqlType; self.navigationSettings = options.navigationSettings; self.initialNamespace = options.initialNamespace || getFromLocalStorage('contextSelector.lastSelectedNamespace'); self.initialCompute = options.initialCompute || getFromLocalStorage('contextSelector.lastSelectedCompute'); self.selectedNamespace = ko.observable(); self.namespaces = ko.observableArray(); self.loadedDeferred = $.Deferred(); self.loading = ko.observable(false); self.hasErrors = ko.observable(false); self.filter = { querySpec: ko.observable({}).extend({ rateLimit: 300 }) }; self.filteredNamespaces = ko.pureComputed(() => { if ( !self.filter.querySpec() || typeof self.filter.querySpec().query === 'undefined' || !self.filter.querySpec().query ) { return self.namespaces(); } return self .namespaces() .filter( namespace => namespace.name.toLowerCase().indexOf(self.filter.querySpec().query.toLowerCase()) !== -1 ); }); self.autocompleteFromNamespaces = (nonPartial, partial) => { const result = []; const partialLower = partial.toLowerCase(); self.namespaces().forEach(namespace => { if (namespace.name.toLowerCase().indexOf(partialLower) === 0) { result.push(nonPartial + partial + namespace.name.substring(partial.length)); } }); return result; }; const ensureDbSet = () => { if (self.nonSqlType) { if (!self.selectedNamespace().selectedDatabase()) { self.selectedNamespace().selectedDatabase(self.selectedNamespace().databases()[0]); self.selectedNamespace().selectedDatabaseChanged(); } } }; self.selectedNamespace.subscribe(namespace => { if (namespace && !namespace.loaded() && !namespace.loading()) { namespace.initDatabases(ensureDbSet); } else { ensureDbSet(); } }); self.hasNamespaces = ko.pureComputed(() => self.namespaces().length > 0); huePubSub.subscribe(NAMESPACES_REFRESHED_TOPIC, connectorId => { if (self.connector.id !== connectorId) { return; } self.loading(true); getNamespaces({ connector: self.connector }) .then(context => { const newNamespaces = []; const existingNamespaceIndex = {}; self.namespaces().forEach(assistNamespace => { existingNamespaceIndex[assistNamespace.namespace.id] = assistNamespace; }); context.namespaces.forEach(newNamespace => { if (existingNamespaceIndex[newNamespace.id]) { existingNamespaceIndex[newNamespace.id].namespace = newNamespace; existingNamespaceIndex[newNamespace.id].name = newNamespace.name; existingNamespaceIndex[newNamespace.id].status(newNamespace.status); newNamespaces.push(existingNamespaceIndex[newNamespace.id]); } else { newNamespaces.push( new AssistDbNamespace({ sourceType: self.sourceType, connector: self.connector, namespace: newNamespace, i18n: self.i18n, nonSqlType: self.nonSqlType, navigationSettings: self.navigationSettings }) ); } }); self.namespaces(newNamespaces); }) .catch() .finally(() => { self.loading(false); }); }); } whenLoaded(callback) { const self = this; self.loadedDeferred.done(callback); } loadNamespaces(refresh) { const self = this; self.loading(true); if (refresh) { getComputes({ connector: self.connector, clearCache: true }).catch(); } return getNamespaces({ connector: self.connector, clearCache: refresh }) .then(context => { const assistNamespaces = []; let activeNamespace; let activeCompute; context.namespaces.forEach(namespace => { const assistNamespace = new AssistDbNamespace({ sourceType: self.sourceType, namespace: namespace, connector: self.connector, i18n: self.i18n, nonSqlType: self.nonSqlType, navigationSettings: self.navigationSettings }); if (self.initialNamespace && namespace.id === self.initialNamespace.id) { activeNamespace = assistNamespace; if (self.initialCompute) { activeNamespace.namespace.computes.some(compute => { if (compute.id === self.initialCompute.id) { activeCompute = compute; } }); } } assistNamespaces.push(assistNamespace); }); self.namespaces(assistNamespaces); if (!refresh) { if (activeNamespace) { self.selectedNamespace(activeNamespace); } else if (assistNamespaces.length) { self.selectedNamespace(assistNamespaces[0]); } if (activeCompute) { self.selectedNamespace().compute(activeCompute); } else if ( self.selectedNamespace() && self.selectedNamespace().namespace && self.selectedNamespace().namespace.computes && self.selectedNamespace().namespace.computes.length ) { self.selectedNamespace().compute(self.selectedNamespace().namespace.computes[0]); } } }) .catch(() => { self.hasErrors(true); }) .finally(() => { self.loadedDeferred.resolve(); self.loading(false); }); } highlightInside(catalogEntry) { const self = this; if (self.navigationSettings.rightAssist) { return; } const whenLoaded = () => { self.namespaces().some(namespace => { if (namespace.namespace.id === catalogEntry.namespace.id) { if (self.selectedNamespace() !== namespace) { self.selectedNamespace(namespace); } if (self.selectedNamespace().hasEntries()) { self.selectedNamespace().highlightInside(catalogEntry); } else { self.selectedNamespace().initDatabases(() => { self.selectedNamespace().highlightInside(catalogEntry); }); } return true; } }); }; if (self.namespaces().length) { whenLoaded(); } else if (self.loading()) { const loadingSub = self.loading.subscribe(() => { loadingSub.dispose(); whenLoaded(); }); } else { self.loadNamespaces().then(whenLoaded); } } triggerRefresh() { const self = this; self.loadNamespaces(true); } } export default AssistDbSource;