This is an automated email from the ASF dual-hosted git repository.

hansva pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/hop.git


The following commit(s) were added to refs/heads/main by this push:
     new a998b0008d Clear filter in database perspective when switching 
projects, fixes #8453 (#8485)
a998b0008d is described below

commit a998b0008d0e599d7ce19297b0913cde9f509804
Author: Matt Casters <[email protected]>
AuthorDate: Mon Sep 21 13:15:16 2026 +0200

    Clear filter in database perspective when switching projects, fixes #8453 
(#8485)
---
 .../perspective/database/DatabaseWorkbench.java    | 154 +++++++++++----------
 .../database/DatabaseWorkbenchFilterTest.java      | 109 +++++++++++++++
 2 files changed, 189 insertions(+), 74 deletions(-)

diff --git 
a/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/database/DatabaseWorkbench.java
 
b/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/database/DatabaseWorkbench.java
index fd2b5f5a05..0133555fac 100644
--- 
a/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/database/DatabaseWorkbench.java
+++ 
b/ui/src/main/java/org/apache/hop/ui/hopgui/perspective/database/DatabaseWorkbench.java
@@ -257,6 +257,7 @@ public class DatabaseWorkbench extends Composite implements 
TabClosable {
               e ->
                   host.asyncExec(
                       () -> {
+                        clearSearchFilter(false);
                         closeSqlEditorTabs();
                         operationsPanel.cancelAll();
                         operationsPanel.clearAll();
@@ -427,12 +428,19 @@ public class DatabaseWorkbench extends Composite 
implements TabClosable {
   }
 
   public void clearSearchFilter() {
+    clearSearchFilter(true);
+  }
+
+  public void clearSearchFilter(boolean rebuildTree) {
     if (searchText != null && !searchText.isDisposed()) {
       searchText.setText("");
     }
+    cancelScheduledFilterApply();
     filterText = "";
     filterMatcher = new SearchMatcher("", false, false, false);
-    rebuildTree();
+    if (rebuildTree) {
+      rebuildTree();
+    }
   }
 
   private void scheduleFilterApply() {
@@ -463,9 +471,6 @@ public class DatabaseWorkbench extends Composite implements 
TabClosable {
     try {
       tree.removeAll();
       for (DatabaseConnectionState state : connections.values()) {
-        if (!connectionMatches(state)) {
-          continue;
-        }
         TreeItem connectionItem = new TreeItem(tree, SWT.NONE);
         connectionItem.setText(state.getDatabaseMeta().getName());
         connectionItem.setImage(
@@ -542,62 +547,6 @@ public class DatabaseWorkbench extends Composite 
implements TabClosable {
     }
   }
 
-  private boolean connectionMatches(DatabaseConnectionState state) {
-    if (Utils.isEmpty(filterText)) {
-      return true;
-    }
-    DatabaseMeta meta = state.getDatabaseMeta();
-    if (filterMatcher.matches(meta.getName())) {
-      return true;
-    }
-    DatabaseMetaInformation info = state.getInformation();
-    if (info == null) {
-      return false;
-    }
-    if (info.getSchemas() != null) {
-      for (Schema schema : info.getSchemas()) {
-        if (filterMatcher.matches(schema.getSchemaName())) {
-          return true;
-        }
-        if (schema.getItems() != null) {
-          for (String table : schema.getItems()) {
-            if (filterMatcher.matches(table)) {
-              return true;
-            }
-          }
-        }
-      }
-    }
-    if (info.getTables() != null) {
-      for (String table : info.getTables()) {
-        if (filterMatcher.matches(table)) {
-          return true;
-        }
-      }
-    }
-    if (mapHasMatch(info.getViewMap()) || mapHasMatch(info.getSynonymMap())) {
-      return true;
-    }
-    return false;
-  }
-
-  private boolean mapHasMatch(Map<String, Collection<String>> map) {
-    if (map == null) {
-      return false;
-    }
-    for (Collection<String> names : map.values()) {
-      if (names == null) {
-        continue;
-      }
-      for (String name : names) {
-        if (filterMatcher.matches(name)) {
-          return true;
-        }
-      }
-    }
-    return false;
-  }
-
   private void fillConnectionChildren(TreeItem connectionItem, 
DatabaseConnectionState state) {
     DatabaseMetaInformation info = state.getInformation();
     String connectionName = state.getDatabaseMeta().getName();
@@ -619,6 +568,9 @@ public class DatabaseWorkbench extends Composite implements 
TabClosable {
     Catalog[] catalogs = info.getCatalogs();
     if (catalogs != null && catalogs.length > 0) {
       for (Catalog catalog : catalogs) {
+        if (!catalogOrChildMatches(catalog, info)) {
+          continue;
+        }
         TreeItem catalogItem = new TreeItem(connectionItem, SWT.NONE);
         catalogItem.setText(Const.NVL(catalog.getCatalogName(), ""));
         catalogItem.setImage(GuiResource.getInstance().getImageFolder());
@@ -649,22 +601,72 @@ public class DatabaseWorkbench extends Composite 
implements TabClosable {
   }
 
   private boolean schemaOrChildMatches(Schema schema, DatabaseMetaInformation 
info) {
+    return schemaOrChildMatches(filterMatcher, filterText, schema, info);
+  }
+
+  static boolean schemaOrChildMatches(
+      SearchMatcher matcher, String filterText, Schema schema, 
DatabaseMetaInformation info) {
     if (Utils.isEmpty(filterText)) {
       return true;
     }
-    if (filterMatcher.matches(schema.getSchemaName())) {
+    if (matcher.matches(schema.getSchemaName())) {
       return true;
     }
     if (schema.getItems() != null) {
       for (String table : schema.getItems()) {
-        if (filterMatcher.matches(table)) {
+        if (matcher.matches(table)) {
           return true;
         }
       }
     }
-    for (String view : DatabaseTreeUtil.namesForSchema(info.getViewMap(), 
schema.getSchemaName())) {
-      if (filterMatcher.matches(view)) {
-        return true;
+    if (info != null) {
+      for (String view :
+          DatabaseTreeUtil.namesForSchema(info.getViewMap(), 
schema.getSchemaName())) {
+        if (matcher.matches(view)) {
+          return true;
+        }
+      }
+      for (String synonym :
+          DatabaseTreeUtil.namesForSchema(info.getSynonymMap(), 
schema.getSchemaName())) {
+        if (matcher.matches(synonym)) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  private boolean catalogOrChildMatches(Catalog catalog, 
DatabaseMetaInformation info) {
+    return catalogOrChildMatches(filterMatcher, filterText, catalog, info);
+  }
+
+  static boolean catalogOrChildMatches(
+      SearchMatcher matcher, String filterText, Catalog catalog, 
DatabaseMetaInformation info) {
+    if (Utils.isEmpty(filterText)) {
+      return true;
+    }
+    if (matcher.matches(catalog.getCatalogName())) {
+      return true;
+    }
+    if (catalog.getItems() != null) {
+      for (String table : catalog.getItems()) {
+        if (matcher.matches(table)) {
+          return true;
+        }
+      }
+    }
+    if (info != null) {
+      for (String view :
+          DatabaseTreeUtil.namesForSchema(info.getViewMap(), 
catalog.getCatalogName())) {
+        if (matcher.matches(view)) {
+          return true;
+        }
+      }
+      for (String synonym :
+          DatabaseTreeUtil.namesForSchema(info.getSynonymMap(), 
catalog.getCatalogName())) {
+        if (matcher.matches(synonym)) {
+          return true;
+        }
       }
     }
     return false;
@@ -698,7 +700,7 @@ public class DatabaseWorkbench extends Composite implements 
TabClosable {
     }
     names.sort(String.CASE_INSENSITIVE_ORDER);
     for (String name : names) {
-      if (!matchesFilter(name, schemaName, connectionName)) {
+      if (!matchesFilter(name, schemaName)) {
         continue;
       }
       DatabaseTreeNode.Kind kind = DatabaseTreeUtil.kindOf(name, views, 
synonyms);
@@ -709,13 +711,16 @@ public class DatabaseWorkbench extends Composite 
implements TabClosable {
     }
   }
 
-  private boolean matchesFilter(String name, String schemaName, String 
connectionName) {
+  private boolean matchesFilter(String name, String schemaName) {
+    return matchesFilter(filterMatcher, filterText, name, schemaName);
+  }
+
+  static boolean matchesFilter(
+      SearchMatcher matcher, String filterText, String name, String 
schemaName) {
     if (Utils.isEmpty(filterText)) {
       return true;
     }
-    return filterMatcher.matches(name)
-        || filterMatcher.matches(schemaName)
-        || filterMatcher.matches(connectionName);
+    return matcher.matches(name) || (schemaName != null && 
matcher.matches(schemaName));
   }
 
   private void addFolder(
@@ -732,6 +737,10 @@ public class DatabaseWorkbench extends Composite 
implements TabClosable {
     folder.setImage(GuiResource.getInstance().getImageFolder());
     folder.setData(DatabaseTreeNode.folder(connectionName, folderName));
     addTables(folder, connectionName, null, names, kind);
+    if (!Utils.isEmpty(filterText) && folder.getItemCount() == 0) {
+      folder.dispose();
+      return;
+    }
     FolderTreeIcons.setExpanded(folder, true);
   }
 
@@ -745,10 +754,7 @@ public class DatabaseWorkbench extends Composite 
implements TabClosable {
       return;
     }
     for (String name : names) {
-      if (!Utils.isEmpty(filterText)
-          && !filterMatcher.matches(name)
-          && !filterMatcher.matches(schemaName)
-          && !filterMatcher.matches(connectionName)) {
+      if (!matchesFilter(name, schemaName)) {
         continue;
       }
       TreeItem item = new TreeItem(parent, SWT.NONE);
diff --git 
a/ui/src/test/java/org/apache/hop/ui/hopgui/perspective/database/DatabaseWorkbenchFilterTest.java
 
b/ui/src/test/java/org/apache/hop/ui/hopgui/perspective/database/DatabaseWorkbenchFilterTest.java
new file mode 100644
index 0000000000..bfdbc1e6ae
--- /dev/null
+++ 
b/ui/src/test/java/org/apache/hop/ui/hopgui/perspective/database/DatabaseWorkbenchFilterTest.java
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.
+ */
+
+package org.apache.hop.ui.hopgui.perspective.database;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import org.apache.hop.core.database.Catalog;
+import org.apache.hop.core.database.DatabaseMetaInformation;
+import org.apache.hop.core.database.Schema;
+import org.apache.hop.core.search.SearchMatcher;
+import org.junit.jupiter.api.Test;
+
+class DatabaseWorkbenchFilterTest {
+
+  @Test
+  void matchesFilterReturnsTrueWhenFilterIsEmpty() {
+    SearchMatcher matcher = new SearchMatcher("", false, false, false);
+    assertTrue(DatabaseWorkbench.matchesFilter(matcher, "", "customers", 
"public"));
+    assertTrue(DatabaseWorkbench.matchesFilter(matcher, null, "customers", 
"public"));
+  }
+
+  @Test
+  void matchesFilterMatchesTableName() {
+    SearchMatcher matcher = new SearchMatcher("cust", false, false, false);
+    assertTrue(DatabaseWorkbench.matchesFilter(matcher, "cust", "customers", 
"public"));
+    assertTrue(DatabaseWorkbench.matchesFilter(matcher, "cust", 
"CUSTOMER_ORDER", "public"));
+    assertFalse(DatabaseWorkbench.matchesFilter(matcher, "cust", "orders", 
"public"));
+  }
+
+  @Test
+  void matchesFilterMatchesSchemaName() {
+    SearchMatcher matcher = new SearchMatcher("pub", false, false, false);
+    assertTrue(DatabaseWorkbench.matchesFilter(matcher, "pub", "orders", 
"public"));
+    assertFalse(DatabaseWorkbench.matchesFilter(matcher, "pub", "orders", 
"analytics"));
+  }
+
+  @Test
+  void schemaOrChildMatchesWithEmptyFilter() {
+    SearchMatcher matcher = new SearchMatcher("", false, false, false);
+    Schema schema = new Schema("public", new String[] {"customers"});
+    assertTrue(DatabaseWorkbench.schemaOrChildMatches(matcher, "", schema, 
null));
+  }
+
+  @Test
+  void schemaOrChildMatchesSchemaName() {
+    SearchMatcher matcher = new SearchMatcher("pub", false, false, false);
+    Schema schema = new Schema("public", new String[] {"orders"});
+    assertTrue(DatabaseWorkbench.schemaOrChildMatches(matcher, "pub", schema, 
null));
+  }
+
+  @Test
+  void schemaOrChildMatchesTableName() {
+    SearchMatcher matcher = new SearchMatcher("cust", false, false, false);
+    Schema schema = new Schema("sales", new String[] {"customers", "orders"});
+    assertTrue(DatabaseWorkbench.schemaOrChildMatches(matcher, "cust", schema, 
null));
+
+    Schema other = new Schema("sales", new String[] {"orders", "products"});
+    assertFalse(DatabaseWorkbench.schemaOrChildMatches(matcher, "cust", other, 
null));
+  }
+
+  @Test
+  void schemaOrChildMatchesViewsAndSynonyms() {
+    SearchMatcher matcher = new SearchMatcher("view_order", false, false, 
false);
+    Schema schema = new Schema("sales", new String[] {"customers"});
+
+    DatabaseMetaInformation info = mock(DatabaseMetaInformation.class);
+    Map<String, Collection<String>> viewMap = Map.of("sales", 
List.of("view_orders"));
+    when(info.getViewMap()).thenReturn(viewMap);
+
+    assertTrue(DatabaseWorkbench.schemaOrChildMatches(matcher, "view_order", 
schema, info));
+  }
+
+  @Test
+  void catalogOrChildMatchesCatalogNameOrItems() {
+    SearchMatcher emptyMatcher = new SearchMatcher("", false, false, false);
+    Catalog catalog = new Catalog("cat1", new String[] {"orders"});
+    assertTrue(DatabaseWorkbench.catalogOrChildMatches(emptyMatcher, "", 
catalog, null));
+
+    SearchMatcher nameMatcher = new SearchMatcher("cat1", false, false, false);
+    assertTrue(DatabaseWorkbench.catalogOrChildMatches(nameMatcher, "cat1", 
catalog, null));
+
+    SearchMatcher itemMatcher = new SearchMatcher("ord", false, false, false);
+    assertTrue(DatabaseWorkbench.catalogOrChildMatches(itemMatcher, "ord", 
catalog, null));
+
+    SearchMatcher noMatcher = new SearchMatcher("cust", false, false, false);
+    assertFalse(DatabaseWorkbench.catalogOrChildMatches(noMatcher, "cust", 
catalog, null));
+  }
+}

Reply via email to