Browse Source

HUE-7820 [assist] Only refresh the open SQL entity in the assist panel

Johan Ahlen 7 years ago
parent
commit
053ca72364

+ 15 - 3
apps/metastore/src/metastore/static/metastore/js/metastore.ko.js

@@ -33,6 +33,8 @@ var MetastoreViewModel = (function () {
     self.navigatorEnabled = ko.observable(options.navigatorEnabled || false);
     self.sourceType = ko.observable(options.sourceType || 'hive');
 
+    self.catalogEntry = ko.observable();
+
     self.navigatorEnabled.subscribe(function (newValue) {
       huePubSub.publish('meta.navigator.enabled', newValue);
     });
@@ -193,6 +195,15 @@ var MetastoreViewModel = (function () {
 
   var lastLoadDatabasesPromise = null;
 
+  MetastoreViewModel.prototype.reload = function () {
+    var self = this;
+    if (!self.reloading() && self.catalogEntry()) {
+      self.reloading(true);
+      // Clear will publish when done
+      self.catalogEntry().clear(self.catalogEntry().getSourceType() === 'impala' ? 'invalidate' : 'cache');
+    }
+  };
+
   MetastoreViewModel.prototype.loadDatabases = function () {
     var self = this;
     if (self.loadingDatabases() && lastLoadDatabasesPromise) {
@@ -209,14 +220,15 @@ var MetastoreViewModel = (function () {
       self.loadingDatabases(false);
     });
 
-    DataCatalog.getEntry({ sourceType: self.sourceType(), path: [] }).done(function (sourceEntry) {
-      sourceEntry.getChildren().done(function (databaseEntries) {
+    DataCatalog.getEntry({ sourceType: self.sourceType(), path: [], definition: { type: 'source' } }).done(function (entry) {
+      self.catalogEntry(entry);
+      entry.getChildren().done(function (databaseEntries) {
         self.databases($.map(databaseEntries, function (databaseEntry) {
           return new MetastoreDatabase({ catalogEntry: databaseEntry, optimizerEnabled: self.optimizerEnabled });
         }));
         deferred.resolve();
       }).fail(deferred.reject);
-    }).fail(deferred.reject);
+    });
 
     return lastLoadDatabasesPromise;
   };

+ 18 - 6
apps/metastore/src/metastore/static/metastore/js/metastore.model.js

@@ -73,11 +73,17 @@ var MetastoreDatabase = (function () {
     self.table = ko.observable(null);
   }
 
-  MetastoreDatabase.prototype.load = function (callback, optimizerEnabled, navigatorEnabled) {
+  MetastoreDatabase.prototype.reload = function () {
     var self = this;
-    if (self.loading()) {
-      return;
+    if (!self.loading()) {
+      self.loading(true);
+      // Clear will publish when done
+      self.catalogEntry.clear(self.catalogEntry.getSourceType() === 'impala' ? 'invalidate' : 'cache');
     }
+  };
+
+  MetastoreDatabase.prototype.load = function (callback, optimizerEnabled, navigatorEnabled) {
+    var self = this;
 
     self.loading(true);
 
@@ -516,6 +522,15 @@ var MetastoreTable = (function () {
     };
   }
 
+  MetastoreTable.prototype.reload = function () {
+    var self = this;
+    if (!self.loading()) {
+      self.loading(true);
+      // Clear will publish when done
+      self.catalogEntry.clear(self.catalogEntry.getSourceType() === 'impala' ? 'invalidate' : 'cache');
+    }
+  };
+
   MetastoreTable.prototype.showImportData = function () {
     var self = this;
     $("#import-data-modal").empty().html('<div class="modal-header"><button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">&times;</span></button><h2 class="modal-title"></h2></div><div class="modal-body"><i class="fa fa-spinner fa-spin fa-2x muted"></i></div>').modal("show");
@@ -528,9 +543,6 @@ var MetastoreTable = (function () {
 
   MetastoreTable.prototype.load = function () {
     var self = this;
-    if (self.loading()) {
-      return;
-    }
     self.loading(true);
     self.fetchFields();
     self.fetchDetails();

+ 8 - 7
apps/metastore/src/metastore/templates/metastore.mako

@@ -607,8 +607,8 @@ ${ components.menubar(is_embeddable) }
 
 <script type="text/html" id="metastore-databases-actions">
   <div class="inline-block pull-right">
-    <a class="inactive-action" href="javascript:void(0)" data-bind="tooltip: { placement: 'bottom', delay: 750 }, publish: { 'data.catalog.refresh.entry': { invalidate: true, sourceType: sourceType(), path: [] }}">
-      <i class="pointer fa fa-refresh" data-bind="css: { 'fa-spin blue' : $root.reloading }" title="${_('Refresh')}"></i>
+    <a class="inactive-action" href="javascript:void(0)" data-bind="tooltip: { placement: 'bottom', delay: 750 }, click: reload">
+      <i class="pointer fa fa-refresh" data-bind="css: { 'fa-spin blue' : loading }" title="${_('Refresh')}"></i>
     </a>
     % if has_write_access:
       % if is_embeddable:
@@ -624,7 +624,7 @@ ${ components.menubar(is_embeddable) }
 
 <script type="text/html" id="metastore-tables-actions">
   <div class="inline-block pull-right">
-    <a class="inactive-action" href="javascript:void(0)" data-bind="tooltip: { placement: 'bottom', delay: 750 }, publish: { 'data.catalog.refresh.entry': { invalidate: true, catalogEntry: database().catalogEntry } }" title="${_('Refresh')}"><i class="pointer fa fa-refresh" data-bind="css: { 'fa-spin blue' : $root.reloading }"></i></a>
+    <a class="inactive-action" href="javascript:void(0)" data-bind="tooltip: { placement: 'bottom', delay: 750 }, click: reload" title="${_('Refresh')}"><i class="pointer fa fa-refresh" data-bind="css: { 'fa-spin blue' : loading }"></i></a>
     % if has_write_access:
       % if is_embeddable:
         <a class="inactive-action margin-left-10" data-bind="tooltip: { placement: 'bottom', delay: 750 }, click: function () { huePubSub.publish('open.link', '${ url('indexer:importer_prefill', source_type='all', target_type='table') }' + database().catalogEntry.name ); }" title="${_('Create a new table')}" href="javascript:void(0)"><i class="fa fa-plus"></i></a>
@@ -652,7 +652,7 @@ ${ components.menubar(is_embeddable) }
     % else:
       <a class="inactive-action" data-bind="tooltip: { placement: 'bottom', delay: 750 }, attr: { 'href': '/metastore/table/'+ catalogEntry.path.join('/') + '/read' }" title="${_('Browse Data')}"><i class="fa fa-play fa-fw"></i></a>
     % endif
-    <a class="inactive-action" data-bind="tooltip: { placement: 'bottom', delay: 750 }, publish: { 'data.catalog.refresh.entry': { invalidate: true, catalogEntry: catalogEntry } }" title="${_('Refresh')}" href="javascript:void(0)"><i class="pointer fa fa-refresh fa-fw" data-bind="css: { 'fa-spin blue' : $root.reloading }"></i></a>
+    <a class="inactive-action" data-bind="tooltip: { placement: 'bottom', delay: 750 }, click: reload" title="${_('Refresh')}" href="javascript:void(0)"><i class="pointer fa fa-refresh fa-fw" data-bind="css: { 'fa-spin blue' : loading }"></i></a>
     % if has_write_access:
       <a class="inactive-action" href="#" data-bind="tooltip: { placement: 'bottom', delay: 750 }, click: showImportData, visible: tableDetails() && ! tableDetails().is_view" title="${_('Import Data')}"><i class="fa fa-upload fa-fw"></i></a>
     % endif
@@ -1412,10 +1412,11 @@ ${ components.menubar(is_embeddable) }
       ko.applyBindings(viewModel, $('#metastoreComponents')[0]);
 
       if (location.getParameter('refresh') === 'true') {
-        huePubSub.publish('data.catalog.refresh.entry', { sourceType: viewModel.sourceType(), path: [] });
-        hueUtils.replaceURL('?');
+        DataCatalog.getEntry({ sourceType: viewModel.sourceType(), path: [], definition: { type: 'source' }}).done(function (entry) {
+          huePubSub.publish('data.catalog.refresh.entry', { invalidate: sourceType() === 'impala' ? 'invalidate' : 'cache', catalogEntry: entry });
+          hueUtils.replaceURL('?');
+        });
       }
-
     });
   })();
 </script>

+ 28 - 0
desktop/core/src/desktop/static/desktop/js/apiHelper.js

@@ -1543,6 +1543,34 @@ var ApiHelper = (function () {
     return promise;
   };
 
+  /**
+   * @param {Object} options
+   * @param {string} options.sourceType
+   * @param {string} options.invalidate - [invalidate|invalidateAndFlush]
+   * @param {string} [options.database]
+   * @param {boolean} [options.silenceErrors]
+   */
+  ApiHelper.prototype.invalidateSourceMetadata = function (options) {
+    var self = this;
+    var deferred = $.Deferred();
+
+    if (options.sourceType === 'impala' && (options.invalidate === 'invalidate' || options.invalidate === 'invalidateAndFlush')) {
+      var data = {
+        flush_all: options.invalidate === 'invalidateAndFlush'
+      };
+
+      if (options.database) {
+        data.database = options.database;
+      }
+
+      var request = self.simplePost(IMPALA_INVALIDATE_API, data, options).done(deferred.resolve).fail(deferred.reject);
+
+      return new CancellablePromise(deferred.promise(), request);
+    }
+
+    return deferred.resolve().promise();
+  };
+
 
   /**
    * @param {Object} options

+ 2 - 2
desktop/core/src/desktop/static/desktop/js/assist/assistDbEntry.js

@@ -241,9 +241,9 @@ var AssistDbEntry = (function () {
     self.isSearchVisible(!self.isSearchVisible());
   };
 
-  AssistDbEntry.prototype.triggerRefresh = function (data, event) {
+  AssistDbEntry.prototype.triggerRefresh = function () {
     var self = this;
-    self.assistDbSource.triggerRefresh(data, event);
+    self.catalogEntry.clear(self.invalidateOnRefresh());
   };
 
   AssistDbEntry.prototype.highlightInside = function (path) {

+ 61 - 57
desktop/core/src/desktop/static/desktop/js/assist/assistDbSource.js

@@ -51,6 +51,7 @@ var AssistDbSource = (function () {
     self.apiHelper = ApiHelper.getInstance();
     self.sourceType = options.type;
     self.name = options.name;
+    self.catalogEntry;
 
     self.hasErrors = ko.observable(false);
     self.simpleStyles = ko.observable(false);
@@ -181,7 +182,8 @@ var AssistDbSource = (function () {
 
     self.loaded = ko.observable(false);
     self.loading = ko.observable(false);
-    var dbIndex = {};
+    self.dbIndex = {};
+
     var nestedFilter = {
       querySpec: ko.observable({}),
       showTables: ko.observable(true),
@@ -203,52 +205,18 @@ var AssistDbSource = (function () {
       nestedFilter.activeEditorTables(activeTables);
     });
 
-    var updateDatabases = function (names, lastSelectedDb) {
-      dbIndex = {};
-      var hasNavMeta = false;
-      var dbPromises = [];
-      var dbs = [];
-
-      names.forEach(function (name) {
-        dbPromises.push(DataCatalog.getEntry({ sourceType: self.sourceType, path: name, definition: { type: 'database' }}).done( function (catalogEntry) {
-          hasNavMeta = hasNavMeta || !!catalogEntry.navigatorMeta;
-          var database = new AssistDbEntry(catalogEntry, null, self, nestedFilter, self.i18n, self.navigationSettings);
-          dbIndex[name] = database;
-          if (name === lastSelectedDb) {
-            self.selectedDatabase(database);
-            self.selectedDatabaseChanged();
-          }
-          dbs.push(database);
-        }));
-      });
-
-      $.when.apply($, dbPromises).always(function () {
-        if (!hasNavMeta) {
-          if (self.sourceType !== 'solr') {
-            DataCatalog.getEntry({ sourceType: self.sourceType, path: [], definition: { type: 'source' } })
-              .done(function (catalogEntry) { catalogEntry.loadNavigatorMetaForChildren({ silenceErrors: true }) });
-          }
-        }
-        dbs.sort(sortFunctions[self.activeSort()]);
-        self.databases(dbs);
-        self.reloading(false);
-        self.loading(false);
-        self.loaded(true);
-      });
-    };
-
     self.setDatabase = function (databaseName) {
       if (databaseName && self.selectedDatabase() && databaseName === self.selectedDatabase().catalogEntry.name) {
         return;
       }
-      if (databaseName && dbIndex[databaseName]) {
-        self.selectedDatabase(dbIndex[databaseName]);
+      if (databaseName && self.dbIndex[databaseName]) {
+        self.selectedDatabase(self.dbIndex[databaseName]);
         self.selectedDatabaseChanged();
         return;
       }
       var lastSelectedDb = self.apiHelper.getFromTotalStorage('assist_' + self.sourceType, 'lastSelectedDb', 'default');
-      if (lastSelectedDb && dbIndex[lastSelectedDb]) {
-        self.selectedDatabase(dbIndex[lastSelectedDb]);
+      if (lastSelectedDb && self.dbIndex[lastSelectedDb]) {
+        self.selectedDatabase(self.dbIndex[lastSelectedDb]);
         self.selectedDatabaseChanged();
       } else if (self.databases().length > 0) {
         self.selectedDatabase(self.databases()[0]);
@@ -261,23 +229,48 @@ var AssistDbSource = (function () {
         return;
       }
       self.loading(true);
-      var lastSelectedDb = self.selectedDatabase() ? self.selectedDatabase().catalogEntry.name : null;
+      self.hasErrors(false);
+
+      var lastSelectedDbName = self.selectedDatabase() ? self.selectedDatabase().catalogEntry.name : null;
+
       self.selectedDatabase(null);
       self.databases([]);
-      self.apiHelper.loadDatabases({
-        sourceType: self.sourceType,
-        successCallback: function(data) {
-          self.hasErrors(false);
-          updateDatabases(data, lastSelectedDb);
+
+      DataCatalog.getEntry({ sourceType: self.sourceType, path : [], definition: { type: 'source' }}).done(function (catalogEntry) {
+        self.catalogEntry = catalogEntry;
+        self.catalogEntry.getChildren().done(function (databaseEntries) {
+          self.dbIndex = {};
+          var hasNavMeta = false;
+          var dbs = [];
+
+          databaseEntries.forEach(function (catalogEntry) {
+            hasNavMeta = hasNavMeta || !!catalogEntry.navigatorMeta;
+            var database = new AssistDbEntry(catalogEntry, null, self, nestedFilter, self.i18n, self.navigationSettings);
+            self.dbIndex[catalogEntry.name] = database;
+            if (catalogEntry.name === lastSelectedDbName) {
+              self.selectedDatabase(database);
+              self.selectedDatabaseChanged();
+            }
+            dbs.push(database);
+          });
+
+          if (!hasNavMeta && self.sourceType !== 'solr') {
+            self.catalogEntry.loadNavigatorMetaForChildren({ silenceErrors: true });
+          }
+          dbs.sort(sortFunctions[self.activeSort()]);
+          self.databases(dbs);
+
           if (typeof callback === 'function') {
             callback();
           }
-        },
-        errorCallback: function() {
+        }).fail(function () {
           self.hasErrors(true);
-          updateDatabases([]);
-        },
-        database: lastSelectedDb
+        }).always(function () {
+          self.loaded(true);
+          self.loading(false);
+          self.reloading(false);
+        });
+
       });
     };
 
@@ -316,13 +309,22 @@ var AssistDbSource = (function () {
       self.invalidateOnRefresh('invalidate');
     });
 
-    huePubSub.subscribe('assist.db.refresh', function (options) {
-      if (typeof options.sourceTypes === 'undefined' || options.sourceTypes.indexOf(self.sourceType) !== -1) {
-        window.setTimeout(function () {
-          self.reload(options.allCacheTypes);
-        }, 0);
+    huePubSub.subscribe('data.catalog.entry.refreshed', function (refreshedEntry) {
+      if (self.catalogEntry === refreshedEntry) {
+        self.initDatabases();
+      } else if (refreshedEntry.getSourceType() === self.sourceType) {
+        var findAndReloadInside = function (entries) {
+          return entries.some(function (entry) {
+            if (entry.catalogEntry === refreshedEntry) {
+              entry.loadEntries();
+              return true;
+            }
+            return findAndReloadInside(entry.entries());
+          })
+        };
+        findAndReloadInside(self.databases());
       }
-    });
+    })
   }
 
   AssistDbSource.prototype.highlightInside = function (path) {
@@ -386,7 +388,9 @@ var AssistDbSource = (function () {
 
   AssistDbSource.prototype.triggerRefresh = function (data, event) {
     var self = this;
-    huePubSub.publish('assist.db.refresh', { sourceTypes: [self.sourceType], allCacheTypes: event.shiftKey });
+    if (self.catalogEntry) {
+      self.catalogEntry.clear(self.invalidateOnRefresh());
+    }
   };
 
   return AssistDbSource;

+ 84 - 38
desktop/core/src/desktop/static/desktop/js/dataCatalog.js

@@ -46,7 +46,7 @@ var DataCatalog = (function () {
 
   DataCatalog.prototype.clearStorage = function () {
     var self = this;
-    self.store.clear()
+    return self.store.clear()
   };
 
   DataCatalog.prototype.updateStore = function (dataCatalogEntry) {
@@ -259,7 +259,17 @@ var DataCatalog = (function () {
    * @return {CancellablePromise}
    */
   var reloadSourceMeta = function (dataCatalogEntry, apiOptions) {
-    dataCatalogEntry.sourceMetaPromise = fetchAndSave('fetchSourceMetadata', 'sourceMeta', dataCatalogEntry, apiOptions);
+    if (dataCatalogEntry.dataCatalog.invalidatePromise) {
+      var deferred = $.Deferred();
+
+      var cancellablePromises = [];
+      dataCatalogEntry.dataCatalog.invalidatePromise.always(function () {
+        cancellablePromises.push(fetchAndSave('fetchSourceMetadata', 'sourceMeta', dataCatalogEntry, apiOptions).done(deferred.resolve).fail(deferred.reject))
+      });
+      dataCatalogEntry.sourceMetaPromise = new CancellablePromise(deferred.promise(), undefined, cancellablePromises);
+    } else {
+      dataCatalogEntry.sourceMetaPromise = fetchAndSave('fetchSourceMetadata', 'sourceMeta', dataCatalogEntry, apiOptions);
+    }
     return dataCatalogEntry.sourceMetaPromise;
   };
 
@@ -372,20 +382,62 @@ var DataCatalog = (function () {
   /**
    * Resets the entry and clears the cache
    *
-   * @return {Promise}
+   * @param {string} [invalidate] - 'cache', 'invalidate' or 'invalidateAndFlush', default 'cache', only used for Impala
+   * @param {boolean} [cascade] - Default false, only used when the entry is for the source
+   * @return {CancellablePromise}
    */
-  DataCatalogEntry.prototype.clear = function () {
+  DataCatalogEntry.prototype.clear = function (invalidate, cascade) {
     var self = this;
-    var deferred = $.Deferred();
+
+    var invalidatePromise;
+
+    if (!invalidate) {
+      invalidate = 'cache';
+    }
+
+    if (invalidate !== 'cache' && self.getSourceType() === 'impala') {
+      if (self.dataCatalog.invalidatePromise) {
+        invalidatePromise = self.dataCatalog.invalidatePromise;
+      } else {
+        if (self.path.length) {
+          invalidatePromise = ApiHelper.getInstance().invalidateSourceMetadata({
+            sourceType: self.getSourceType(),
+            invalidate: invalidate,
+            database: self.path[0]
+          });
+        } else {
+          invalidatePromise = ApiHelper.getInstance().invalidateSourceMetadata({
+            sourceType: self.getSourceType(),
+            invalidate: invalidate
+          });
+        }
+        self.dataCatalog.invalidatePromise = invalidatePromise;
+        invalidatePromise.always(function () {
+          delete self.dataCatalog.invalidatePromise;
+        });
+      }
+    } else {
+      invalidatePromise = $.Deferred().resolve().promise();
+    }
 
     self.reset();
 
-    self.save().then(deferred.resolve).catch(deferred.reject);
+    var saveDeferred = $.Deferred();
 
-    deferred.always(function () {
+    if (self.isSource() && cascade) {
+      self.dataCatalog.entries = {};
+      self.dataCatalog.clearStorage().then(saveDeferred.resolve).catch(saveDeferred.reject);
+    } else {
+      self.save().then(saveDeferred.resolve).catch(saveDeferred.reject);
+    }
+
+    var clearPromise = $.when(invalidatePromise, saveDeferred);
+
+    clearPromise.always(function () {
       huePubSub.publish('data.catalog.entry.refreshed', self);
     });
-    return deferred.promise();
+
+    return new CancellablePromise(clearPromise, undefined, [invalidatePromise]);
   };
 
   /**
@@ -440,26 +492,28 @@ var DataCatalog = (function () {
         || (sourceMeta.value && sourceMeta.value.fields) || (sourceMeta.item && sourceMeta.item.fields);
       if (entities) {
         entities.forEach(function (entity) {
-          promises.push(self.dataCatalog.getEntry({ path: self.path.concat(entity.name || entity) }).done(function (catalogEntry) {
-            if (!catalogEntry.definition || typeof catalogEntry.definition.index === 'undefined') {
-              var definition = typeof entity === 'object' ? entity : {};
-              if (typeof entity !== 'object') {
-                if (self.path.length === 0) {
-                  definition.type = 'database';
-                } else if (self.path.length === 1) {
-                  definition.type = 'table';
-                } else if (self.path.length === 2) {
-                  definition.type = 'column';
+          if (!sourceMeta.databases || ((entity || entity.name) !== '_impala_builtins')) {
+            promises.push(self.dataCatalog.getEntry({path: self.path.concat(entity.name || entity)}).done(function (catalogEntry) {
+              if (!catalogEntry.definition || typeof catalogEntry.definition.index === 'undefined') {
+                var definition = typeof entity === 'object' ? entity : {};
+                if (typeof entity !== 'object') {
+                  if (self.path.length === 0) {
+                    definition.type = 'database';
+                  } else if (self.path.length === 1) {
+                    definition.type = 'table';
+                  } else if (self.path.length === 2) {
+                    definition.type = 'column';
+                  }
                 }
+                if (sourceMeta.partition_keys) {
+                  definition.partitionKey = !!partitionKeys[entity.name];
+                }
+                definition.index = index++;
+                catalogEntry.definition = definition;
+                catalogEntry.saveLater();
               }
-              if (sourceMeta.partition_keys) {
-                definition.partitionKey = !!partitionKeys[entity.name];
-              }
-              definition.index = index++;
-              catalogEntry.definition = definition;
-              catalogEntry.saveLater();
-            }
-          }));
+            }));
+          }
         });
       }
       if (self.getSourceType() === 'impala' && self.isComplex()) {
@@ -1138,19 +1192,11 @@ var DataCatalog = (function () {
   };
 
   huePubSub.subscribe('data.catalog.refresh.entry', function (options) {
-    if (options.catalogEntry) {
-      if (options.invalidate && options.catalogEntry.getSourceType() === 'impala') {
-        huePubSub.publish('assist.invalidate.on.refresh'); // TODO: Replace with invalidate call as no need for pubsub
-      }
-      options.catalogEntry.clear();
-    } else if (options.sourceType && options.path) {
-      if (options.invalidate && options.sourceType === 'impala') {
-        huePubSub.publish('assist.invalidate.on.refresh'); // TODO: Replace with invalidate call as no need for pubsub
+    options.catalogEntry.clear(options.invalidate).always(function () {
+      if (options.callback) {
+        options.callback();
       }
-      getCatalog(options.sourceType).getEntry({ path: options.path }).done(function (entry) {
-        entry.clear()
-      })
-    }
+    });
   });
 
   var allNavigatorTagsPromise = undefined;

+ 3 - 1
desktop/core/src/desktop/templates/assist.mako

@@ -1179,7 +1179,9 @@ from desktop.views import _ko
         });
 
         huePubSub.subscribe('assist.collections.refresh', function() {
-          huePubSub.publish('assist.db.refresh', { sourceTypes: ['solr'], allCacheTypes: false });
+          DataCatalog.getEntry({ sourceType: 'solr', path: [] }).done(function (entry) {
+            entry.clear('cache', true);
+          });
         });
 
         self.selectedSource = ko.observable(null);

+ 4 - 2
desktop/core/src/desktop/templates/ko_components/ko_history_panel.mako

@@ -229,8 +229,10 @@ from desktop.views import _ko
                     huePubSub.publish('open.link', notebook.onSuccessUrl());
                   }
 
-                  if (notebook.onSuccessUrl() == 'assist.db.refresh') {
-                    huePubSub.publish('assist.db.refresh', {sourceTypes: [snippet.type()]});
+                  if (notebook.onSuccessUrl() === 'assist.db.refresh') {
+                    DataCatalog.getEntry({ sourceType: snippet.type(), path: [] }).done(function (entry) {
+                      entry.clear('cache', true);
+                    });
                   } else if (notebook.onSuccessUrl()) {
                     huePubSub.publish(notebook.pubSubUrl());
                   }

+ 16 - 8
desktop/libs/notebook/src/notebook/static/notebook/js/notebook.ko.js

@@ -368,10 +368,16 @@ var EditorViewModel = (function() {
 
     self.updateDatabases = function () {
       if (self.isSqlDialect()) {
-        self.getApiHelper().loadDatabases({
-          sourceType: self.type(),
-          silenceErrors: true,
-          successCallback: self.availableDatabases
+        DataCatalog.getEntry({ sourceType: self.type(), path: [], definition: { type: 'source' }}).done(function (sourceEntry) {
+          sourceEntry.getChildren({ silenceErrors: true }).done(function (databaseEntries) {
+            var databaseNames = [];
+            databaseEntries.forEach(function (databaseEntry) {
+              databaseNames.push(databaseEntry.name);
+            });
+            self.availableDatabases(databaseNames);
+          }).fail(function () {
+            self.availableDatabases([]);
+          });
         });
       } else {
         self.availableDatabases([]);
@@ -767,7 +773,9 @@ var EditorViewModel = (function() {
           huePubSub.publish('assist.invalidate.impala', { flush: false, database: db });
         }
         ignoreNextAssistDatabaseUpdate = true;
-        huePubSub.publish('assist.db.refresh', { sourceTypes: [self.type()] });
+        DataCatalog.getEntry({ sourceType: self.type(), path: [] }).done(function (entry) {
+          entry.clear('cache', true);
+        });
       });
     }, 0);
 
@@ -3020,11 +3028,11 @@ var EditorViewModel = (function() {
       })
     }, self.huePubSubId);
 
-    huePubSub.subscribe('assist.db.refresh', function (options) {
+    huePubSub.subscribe('data.catalog.entry.refreshed', function (catalogEntry) {
       var notebook = self.selectedNotebook();
-      if (notebook) {
+      if (catalogEntry.isSource() && notebook) {
         notebook.snippets().forEach(function (snippet) {
-          if (options.sourceTypes.indexOf(snippet.type()) !== -1) {
+          if (catalogEntry.getSourceType() === snippet.type()) {
             snippet.updateDatabases();
           }
         });