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

mattcasters 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 8eb9a1e790 Issue #8777: Fix false positive result on error and 
populate schema in Action Truncate tables (#8778)
8eb9a1e790 is described below

commit 8eb9a1e79059e7c1cc45b1d0e437765fe8a9e2a7
Author: Samuel Willyanto <[email protected]>
AuthorDate: Sat Oct 10 00:42:41 2026 +0700

    Issue #8777: Fix false positive result on error and populate schema in 
Action Truncate tables (#8778)
---
 .../truncatetables/ActionTruncateTables.java       |  40 +++++++-
 .../truncatetables/ActionTruncateTablesDialog.java | 111 +++++++++++++++------
 .../messages/messages_en_US.properties             |   2 +
 .../truncatetables/ActionTruncateTablesTest.java   | 107 ++++++++++++++++++++
 4 files changed, 227 insertions(+), 33 deletions(-)

diff --git 
a/plugins/actions/truncatetables/src/main/java/org/apache/hop/workflow/actions/truncatetables/ActionTruncateTables.java
 
b/plugins/actions/truncatetables/src/main/java/org/apache/hop/workflow/actions/truncatetables/ActionTruncateTables.java
index 34679ea5c3..605b0a0da1 100644
--- 
a/plugins/actions/truncatetables/src/main/java/org/apache/hop/workflow/actions/truncatetables/ActionTruncateTables.java
+++ 
b/plugins/actions/truncatetables/src/main/java/org/apache/hop/workflow/actions/truncatetables/ActionTruncateTables.java
@@ -19,6 +19,9 @@ package org.apache.hop.workflow.actions.truncatetables;
 
 import java.util.ArrayList;
 import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.hop.core.CheckResult;
+import org.apache.hop.core.ICheckResult;
 import org.apache.hop.core.Result;
 import org.apache.hop.core.RowMetaAndData;
 import org.apache.hop.core.annotations.Action;
@@ -28,6 +31,7 @@ import org.apache.hop.core.variables.IVariables;
 import org.apache.hop.i18n.BaseMessages;
 import org.apache.hop.metadata.api.HopMetadataProperty;
 import org.apache.hop.metadata.api.HopMetadataPropertyType;
+import org.apache.hop.metadata.api.IHopMetadataProvider;
 import org.apache.hop.resource.ResourceEntry;
 import org.apache.hop.resource.ResourceEntry.ResourceType;
 import org.apache.hop.resource.ResourceReference;
@@ -216,13 +220,13 @@ public class ActionTruncateTables extends ActionBase 
implements Cloneable, IActi
           }
         }
       } catch (Exception dbe) {
-        result.setNrErrors(1);
+        updateErrors();
         logError(
             BaseMessages.getString(
                 PKG, "ActionTruncateTables.Error.RunningEntry", 
dbe.getMessage()));
       }
     } else {
-      result.setNrErrors(1);
+      updateErrors();
       logError(BaseMessages.getString(PKG, 
"ActionTruncateTables.NoDbConnection"));
     }
 
@@ -266,4 +270,36 @@ public class ActionTruncateTables extends ActionBase 
implements Cloneable, IActi
   public void setArgFromPrevious(boolean argFromPrevious) {
     this.argFromPrevious = argFromPrevious;
   }
+
+  @Override
+  public void check(
+      List<ICheckResult> remarks,
+      WorkflowMeta workflowMeta,
+      IVariables variables,
+      IHopMetadataProvider metadataProvider) {
+
+    String realConnection = variables.resolve(connection);
+    if (Utils.isEmpty(realConnection)
+        || workflowMeta == null
+        || workflowMeta.findDatabase(realConnection, variables) == null) {
+      String message = BaseMessages.getString(PKG, 
"ActionTruncateTables.NoDbConnection");
+      remarks.add(new CheckResult(ICheckResult.TYPE_RESULT_WARNING, message, 
this));
+    }
+
+    if (!argFromPrevious) {
+      if (Utils.isEmpty(items)) {
+        String message =
+            BaseMessages.getString(PKG, 
"ActionTruncateTables.CheckResult.NoTablesSelected");
+        remarks.add(new CheckResult(ICheckResult.TYPE_RESULT_WARNING, message, 
this));
+      } else {
+        for (TruncateTableItem item : items) {
+          if (StringUtils.isEmpty(variables.resolve(item.getTableName()))) {
+            String message =
+                BaseMessages.getString(PKG, 
"ActionTruncateTables.CheckResult.TableNameIsEmpty");
+            remarks.add(new CheckResult(ICheckResult.TYPE_RESULT_WARNING, 
message, this));
+          }
+        }
+      }
+    }
+  }
 }
diff --git 
a/plugins/actions/truncatetables/src/main/java/org/apache/hop/workflow/actions/truncatetables/ActionTruncateTablesDialog.java
 
b/plugins/actions/truncatetables/src/main/java/org/apache/hop/workflow/actions/truncatetables/ActionTruncateTablesDialog.java
index 16823d259e..82a2b89469 100644
--- 
a/plugins/actions/truncatetables/src/main/java/org/apache/hop/workflow/actions/truncatetables/ActionTruncateTablesDialog.java
+++ 
b/plugins/actions/truncatetables/src/main/java/org/apache/hop/workflow/actions/truncatetables/ActionTruncateTablesDialog.java
@@ -17,11 +17,15 @@
 
 package org.apache.hop.workflow.actions.truncatetables;
 
-import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
 import java.util.List;
+import java.util.Map;
+import org.apache.hop.core.Const;
 import org.apache.hop.core.database.Database;
 import org.apache.hop.core.database.DatabaseMeta;
-import org.apache.hop.core.exception.HopDatabaseException;
 import org.apache.hop.core.util.Utils;
 import org.apache.hop.core.variables.IVariables;
 import org.apache.hop.i18n.BaseMessages;
@@ -302,38 +306,83 @@ public class ActionTruncateTablesDialog extends 
ActionDialog {
   }
 
   private void getTableName() {
-    DatabaseMeta databaseMeta = 
getWorkflowMeta().findDatabase(wConnection.getText(), variables);
-    if (databaseMeta != null) {
-
-      try (Database database = new Database(loggingObject, variables, 
databaseMeta)) {
-        database.connect();
-        String[] tableNames = database.getTablenames();
-        Arrays.sort(tableNames);
-        EnterSelectionDialog dialog =
-            new EnterSelectionDialog(
-                shell,
-                tableNames,
-                BaseMessages.getString(PKG, 
"ActionTruncateTables.SelectTables.Title"),
-                BaseMessages.getString(PKG, 
"ActionTruncateTables.SelectTables.Message"));
-        dialog.setMulti(true);
-        dialog.setAvoidQuickSearch();
-        if (dialog.open() != null) {
-          int[] idx = dialog.getSelectionIndeces();
-          for (int j : idx) {
-            TableItem tableItem = new TableItem(wFields.table, SWT.NONE);
-            tableItem.setText(1, tableNames[j]);
+    String connectionName = wConnection.getText();
+    if (Utils.isEmpty(connectionName)) {
+      MessageBox mb = new MessageBox(shell, SWT.OK | SWT.ICON_ERROR);
+      mb.setText(BaseMessages.getString(PKG, "System.Dialog.Error.Title"));
+      mb.setMessage(BaseMessages.getString(PKG, 
"ActionTruncateTables.NoDbConnection"));
+      mb.open();
+      return;
+    }
+
+    DatabaseMeta databaseMeta = getWorkflowMeta().findDatabase(connectionName, 
variables);
+    if (databaseMeta == null) {
+      MessageBox mb = new MessageBox(shell, SWT.OK | SWT.ICON_ERROR);
+      mb.setText(BaseMessages.getString(PKG, "System.Dialog.Error.Title"));
+      mb.setMessage(BaseMessages.getString(PKG, 
"ActionTruncateTables.NoDbConnection"));
+      mb.open();
+      return;
+    }
+
+    try (Database database = new Database(loggingObject, variables, 
databaseMeta)) {
+      database.connect();
+      Map<String, Collection<String>> tableMap = database.getTableMap();
+      List<String> displayList = new ArrayList<>();
+      List<String[]> schemaTableList = new ArrayList<>();
+
+      if (tableMap != null && !tableMap.isEmpty()) {
+        List<String> schemas = new ArrayList<>(tableMap.keySet());
+        Collections.sort(schemas, 
Comparator.nullsFirst(String.CASE_INSENSITIVE_ORDER));
+        for (String schema : schemas) {
+          Collection<String> tableCollection = tableMap.get(schema);
+          if (tableCollection != null) {
+            List<String> tables = new ArrayList<>(tableCollection);
+            Collections.sort(tables, 
Comparator.nullsFirst(String.CASE_INSENSITIVE_ORDER));
+            for (String table : tables) {
+              String displayName = Utils.isEmpty(schema) ? table : schema + 
"." + table;
+              displayList.add(displayName);
+              schemaTableList.add(new String[] {table, Const.NVL(schema, "")});
+            }
           }
         }
-      } catch (HopDatabaseException e) {
-        new ErrorDialog(
-            shell,
-            BaseMessages.getString(PKG, "System.Dialog.Error.Title"),
-            BaseMessages.getString(PKG, 
"ActionTruncateTables.ConnectionError.DialogMessage"),
-            e);
       }
-      wFields.removeEmptyRows();
-      wFields.setRowNums();
-      wFields.optWidth(true);
+
+      if (displayList.isEmpty()) {
+        MessageBox mb = new MessageBox(shell, SWT.OK | SWT.ICON_WARNING);
+        mb.setText(BaseMessages.getString(PKG, "System.Dialog.Warning.Title"));
+        mb.setMessage(
+            BaseMessages.getString(PKG, 
"ActionTruncateTables.ConnectionError.DialogMessage"));
+        mb.open();
+        return;
+      }
+
+      String[] displayArray = displayList.toArray(new String[0]);
+      EnterSelectionDialog dialog =
+          new EnterSelectionDialog(
+              shell,
+              displayArray,
+              BaseMessages.getString(PKG, 
"ActionTruncateTables.SelectTables.Title"),
+              BaseMessages.getString(PKG, 
"ActionTruncateTables.SelectTables.Message"));
+      dialog.setMulti(true);
+      dialog.setAvoidQuickSearch();
+      if (dialog.open() != null) {
+        int[] idx = dialog.getSelectionIndeces();
+        for (int j : idx) {
+          String[] st = schemaTableList.get(j);
+          TableItem tableItem = new TableItem(wFields.table, SWT.NONE);
+          tableItem.setText(1, st[0]);
+          tableItem.setText(2, st[1]);
+        }
+      }
+    } catch (Exception e) {
+      new ErrorDialog(
+          shell,
+          BaseMessages.getString(PKG, "System.Dialog.Error.Title"),
+          BaseMessages.getString(PKG, 
"ActionTruncateTables.ConnectionError.DialogMessage"),
+          e);
     }
+    wFields.removeEmptyRows();
+    wFields.setRowNums();
+    wFields.optWidth(true);
   }
 }
diff --git 
a/plugins/actions/truncatetables/src/main/resources/org/apache/hop/workflow/actions/truncatetables/messages/messages_en_US.properties
 
b/plugins/actions/truncatetables/src/main/resources/org/apache/hop/workflow/actions/truncatetables/messages/messages_en_US.properties
index 23890952aa..da95625832 100644
--- 
a/plugins/actions/truncatetables/src/main/resources/org/apache/hop/workflow/actions/truncatetables/messages/messages_en_US.properties
+++ 
b/plugins/actions/truncatetables/src/main/resources/org/apache/hop/workflow/actions/truncatetables/messages/messages_en_US.properties
@@ -18,6 +18,8 @@
 #
 
 ActionTruncateTables.ArgEmpty=This argument is empty\!
+ActionTruncateTables.CheckResult.NoTablesSelected=No tables selected to 
truncate.
+ActionTruncateTables.CheckResult.TableNameIsEmpty=Table name is empty.
 ActionTruncateTables.ConnectionError.DialogMessage=Error\!Can not return table 
names list\!
 ActionTruncateTables.Description=Truncate one or several tables.
 ActionTruncateTables.Error.CanNotFindTable=We can not find table [{0}]\!
diff --git 
a/plugins/actions/truncatetables/src/test/java/org/apache/hop/workflow/actions/truncatetables/ActionTruncateTablesTest.java
 
b/plugins/actions/truncatetables/src/test/java/org/apache/hop/workflow/actions/truncatetables/ActionTruncateTablesTest.java
new file mode 100644
index 0000000000..e3c1238b90
--- /dev/null
+++ 
b/plugins/actions/truncatetables/src/test/java/org/apache/hop/workflow/actions/truncatetables/ActionTruncateTablesTest.java
@@ -0,0 +1,107 @@
+/*
+ * 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.workflow.actions.truncatetables;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import org.apache.hop.core.HopClientEnvironment;
+import org.apache.hop.core.Result;
+import org.apache.hop.core.logging.HopLogStore;
+import org.apache.hop.core.logging.LogLevel;
+import org.apache.hop.workflow.Workflow;
+import org.apache.hop.workflow.WorkflowMeta;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+class ActionTruncateTablesTest {
+
+  @BeforeAll
+  static void setUp() throws Exception {
+    HopClientEnvironment.init();
+    HopLogStore.init();
+  }
+
+  @Test
+  void testExecuteWithNoConnection() {
+    ActionTruncateTables action = new ActionTruncateTables();
+    action.setConnection(null);
+
+    Result result = action.execute(new Result(), 0);
+
+    assertFalse(result.getResult());
+    assertEquals(1, result.getNrErrors());
+  }
+
+  @Test
+  void testExecuteWithNonExistentConnection() {
+    ActionTruncateTables action = new ActionTruncateTables();
+    action.setConnection("non-existent-db");
+
+    WorkflowMeta workflowMeta = mock(WorkflowMeta.class);
+    when(workflowMeta.findDatabase(anyString(), any())).thenReturn(null);
+
+    Workflow workflow = mock(Workflow.class);
+    when(workflow.getWorkflowMeta()).thenReturn(workflowMeta);
+    when(workflow.getLogLevel()).thenReturn(LogLevel.BASIC);
+
+    action.setParentWorkflow(workflow);
+    action.setParentWorkflowMeta(workflowMeta);
+
+    Result result = action.execute(new Result(), 0);
+
+    assertFalse(result.getResult());
+    assertEquals(1, result.getNrErrors());
+  }
+
+  @Test
+  void testCheckRemarks() {
+    ActionTruncateTables action = new ActionTruncateTables();
+    action.setConnection(null);
+
+    java.util.List<org.apache.hop.core.ICheckResult> remarks = new 
java.util.ArrayList<>();
+    WorkflowMeta workflowMeta = mock(WorkflowMeta.class);
+    when(workflowMeta.findDatabase(any(), any())).thenReturn(null);
+
+    org.apache.hop.core.variables.Variables variables =
+        new org.apache.hop.core.variables.Variables();
+    action.check(remarks, workflowMeta, variables, null);
+
+    assertFalse(remarks.isEmpty());
+    assertEquals(org.apache.hop.core.ICheckResult.TYPE_RESULT_WARNING, 
remarks.get(0).getType());
+  }
+
+  @Test
+  void testCheckRemarksWithArgFromPrevious() {
+    ActionTruncateTables action = new ActionTruncateTables();
+    action.setArgFromPrevious(true);
+    action.setConnection(null);
+
+    java.util.List<org.apache.hop.core.ICheckResult> remarks = new 
java.util.ArrayList<>();
+    WorkflowMeta workflowMeta = mock(WorkflowMeta.class);
+
+    action.check(remarks, workflowMeta, new 
org.apache.hop.core.variables.Variables(), null);
+
+    assertFalse(remarks.isEmpty());
+    assertEquals(org.apache.hop.core.ICheckResult.TYPE_RESULT_WARNING, 
remarks.get(0).getType());
+  }
+}

Reply via email to