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 dc2d3d4310 Add encoding option to SQL action, fixes #6666 (#6747)
dc2d3d4310 is described below

commit dc2d3d4310ba09d7760b6a421ec8a6724fafaedf
Author: Hans Van Akelyen <[email protected]>
AuthorDate: Mon Mar 9 15:31:43 2026 +0100

    Add encoding option to SQL action, fixes #6666 (#6747)
---
 .../modules/ROOT/pages/workflow/actions/sql.adoc   |  1 +
 .../apache/hop/workflow/actions/sql/ActionSql.java | 72 +++++-----------------
 .../hop/workflow/actions/sql/ActionSqlDialog.java  | 62 ++++++++++++++++++-
 .../actions/sql/messages/messages_en_US.properties |  2 +
 .../actions/sql/WorkflowActionSqlTest.java         |  3 +
 5 files changed, 84 insertions(+), 56 deletions(-)

diff --git a/docs/hop-user-manual/modules/ROOT/pages/workflow/actions/sql.adoc 
b/docs/hop-user-manual/modules/ROOT/pages/workflow/actions/sql.adoc
index aa06e262b4..2333363909 100644
--- a/docs/hop-user-manual/modules/ROOT/pages/workflow/actions/sql.adoc
+++ b/docs/hop-user-manual/modules/ROOT/pages/workflow/actions/sql.adoc
@@ -39,6 +39,7 @@ Common uses associated with the SQL workflow action include 
truncating tables, d
 |Database Connection|The database connection to use.
 |SQL from file|Enable this option to load the SQL statement from a file given 
by the SQL filename
 |SQL filename|The filename for the file with SQL statements.
+|File encoding|Character encoding of the SQL file (e.g. UTF-8, windows-1252). 
Leave empty to use the system default. Useful when the file is UTF-8 but the 
system uses another encoding (e.g. Windows-1252).
 |Send SQL as single statement?|Enable this option to not separate the 
statement by semicolons.
 This is often useful when a script is given or multiple statements should be 
processed and committed as one single statement.
 |Use variable substitution?|Enables variables to be used in the SQL Script.
diff --git 
a/plugins/actions/sql/src/main/java/org/apache/hop/workflow/actions/sql/ActionSql.java
 
b/plugins/actions/sql/src/main/java/org/apache/hop/workflow/actions/sql/ActionSql.java
index 1c166f5efc..cd6e654698 100644
--- 
a/plugins/actions/sql/src/main/java/org/apache/hop/workflow/actions/sql/ActionSql.java
+++ 
b/plugins/actions/sql/src/main/java/org/apache/hop/workflow/actions/sql/ActionSql.java
@@ -22,6 +22,8 @@ import java.io.BufferedReader;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.util.List;
+import lombok.Getter;
+import lombok.Setter;
 import org.apache.commons.vfs2.FileObject;
 import org.apache.hop.core.Const;
 import org.apache.hop.core.ICheckResult;
@@ -57,6 +59,8 @@ import org.apache.hop.workflow.action.validator.AndValidator;
     keywords = "i18n::ActionSql.keyword",
     documentationUrl = "/workflow/actions/sql.html",
     actionTransformTypes = {ActionTransformType.RDBMS})
+@Getter
+@Setter
 public class ActionSql extends ActionBase implements Cloneable, IAction {
   private static final Class<?> PKG = ActionSql.class;
 
@@ -79,6 +83,9 @@ public class ActionSql extends ActionBase implements 
Cloneable, IAction {
   @HopMetadataProperty(key = "sqlfilename")
   private String sqlFilename;
 
+  @HopMetadataProperty(key = "sqlfilename_encoding")
+  private String sqlFilenameEncoding;
+
   @HopMetadataProperty(key = "sendOneStatement")
   private boolean sendOneStatement = false;
 
@@ -98,54 +105,6 @@ public class ActionSql extends ActionBase implements 
Cloneable, IAction {
     return je;
   }
 
-  public void setSql(String sql) {
-    this.sql = sql;
-  }
-
-  public String getSql() {
-    return sql;
-  }
-
-  public String getSqlFilename() {
-    return sqlFilename;
-  }
-
-  public void setSqlFilename(String sqlfilename) {
-    this.sqlFilename = sqlfilename;
-  }
-
-  public boolean isUseVariableSubstitution() {
-    return useVariableSubstitution;
-  }
-
-  public void setUseVariableSubstitution(boolean subs) {
-    useVariableSubstitution = subs;
-  }
-
-  public void setSqlFromFile(boolean sqlfromfilein) {
-    sqlFromFile = sqlfromfilein;
-  }
-
-  public boolean isSqlFromFile() {
-    return sqlFromFile;
-  }
-
-  public boolean isSendOneStatement() {
-    return sendOneStatement;
-  }
-
-  public void setSendOneStatement(boolean sendOneStatementin) {
-    sendOneStatement = sendOneStatementin;
-  }
-
-  public void setConnection(String connection) {
-    this.connection = connection;
-  }
-
-  public String getConnection() {
-    return connection;
-  }
-
   @Override
   public Result execute(Result previousResult, int nr) {
     Result result = previousResult;
@@ -177,8 +136,15 @@ public class ActionSql extends ActionBase implements 
Cloneable, IAction {
 
             InputStream inputStream = HopVfs.getInputStream(sqlFile);
             try {
-              InputStreamReader inputStreamReader =
-                  new InputStreamReader(new BufferedInputStream(inputStream, 
500));
+              String encoding = resolve(getSqlFilenameEncoding());
+              InputStreamReader inputStreamReader;
+              if (Utils.isEmpty(encoding)) {
+                inputStreamReader =
+                    new InputStreamReader(new BufferedInputStream(inputStream, 
500));
+              } else {
+                inputStreamReader =
+                    new InputStreamReader(new BufferedInputStream(inputStream, 
500), encoding);
+              }
               StringBuilder lineSB = new StringBuilder(256);
               lineSB.setLength(0);
 
@@ -236,11 +202,7 @@ public class ActionSql extends ActionBase implements 
Cloneable, IAction {
       logError(BaseMessages.getString(PKG, "ActionSQL.NoDatabaseConnection"));
     }
 
-    if (result.getNrErrors() == 0) {
-      result.setResult(true);
-    } else {
-      result.setResult(false);
-    }
+    result.setResult(result.getNrErrors() == 0);
 
     return result;
   }
diff --git 
a/plugins/actions/sql/src/main/java/org/apache/hop/workflow/actions/sql/ActionSqlDialog.java
 
b/plugins/actions/sql/src/main/java/org/apache/hop/workflow/actions/sql/ActionSqlDialog.java
index 2d404108fa..c5beb87cef 100644
--- 
a/plugins/actions/sql/src/main/java/org/apache/hop/workflow/actions/sql/ActionSqlDialog.java
+++ 
b/plugins/actions/sql/src/main/java/org/apache/hop/workflow/actions/sql/ActionSqlDialog.java
@@ -17,6 +17,8 @@
 
 package org.apache.hop.workflow.actions.sql;
 
+import java.nio.charset.Charset;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 import org.apache.hop.core.Const;
@@ -28,6 +30,7 @@ import org.apache.hop.i18n.BaseMessages;
 import org.apache.hop.ui.core.PropsUi;
 import org.apache.hop.ui.core.dialog.BaseDialog;
 import org.apache.hop.ui.core.dialog.MessageBox;
+import org.apache.hop.ui.core.widget.ComboVar;
 import org.apache.hop.ui.core.widget.MetaSelectionLine;
 import org.apache.hop.ui.core.widget.SQLStyledTextComp;
 import org.apache.hop.ui.core.widget.StyledTextComp;
@@ -38,6 +41,8 @@ import org.apache.hop.ui.workflow.action.ActionDialog;
 import org.apache.hop.workflow.WorkflowMeta;
 import org.apache.hop.workflow.action.IAction;
 import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.events.FocusListener;
 import org.eclipse.swt.layout.FormAttachment;
 import org.eclipse.swt.layout.FormData;
 import org.eclipse.swt.widgets.Button;
@@ -78,6 +83,9 @@ public class ActionSqlDialog extends ActionDialog {
   private Label wlFilename;
   private Button wbFilename;
   private TextVar wFilename;
+  private Label wlEncoding;
+  private ComboVar wEncoding;
+  private boolean gotEncodings = false;
 
   public ActionSqlDialog(
       Shell parent, ActionSql action, WorkflowMeta workflowMeta, IVariables 
variables) {
@@ -164,13 +172,45 @@ public class ActionSqlDialog extends ActionDialog {
                 FILETYPES,
                 true));
 
+    // File encoding (when SQL from file)
+    wlEncoding = new Label(shell, SWT.RIGHT);
+    wlEncoding.setText(BaseMessages.getString(PKG, 
"ActionSQL.Encoding.Label"));
+    PropsUi.setLook(wlEncoding);
+    FormData fdlEncoding = new FormData();
+    fdlEncoding.left = new FormAttachment(0, 0);
+    fdlEncoding.top = new FormAttachment(wbFilename, margin);
+    fdlEncoding.right = new FormAttachment(middle, -margin);
+    wlEncoding.setLayoutData(fdlEncoding);
+
+    wEncoding = new ComboVar(variables, shell, SWT.BORDER | SWT.READ_ONLY);
+    wEncoding.setEditable(true);
+    PropsUi.setLook(wEncoding);
+    wEncoding.setToolTipText(BaseMessages.getString(PKG, 
"ActionSQL.Encoding.Tooltip"));
+    FormData fdEncoding = new FormData();
+    fdEncoding.left = new FormAttachment(middle, 0);
+    fdEncoding.top = new FormAttachment(wbFilename, margin);
+    fdEncoding.right = new FormAttachment(100, -margin);
+    wEncoding.setLayoutData(fdEncoding);
+    wEncoding.addFocusListener(
+        new FocusListener() {
+          @Override
+          public void focusLost(FocusEvent e) {
+            // Do nothing
+          }
+
+          @Override
+          public void focusGained(FocusEvent e) {
+            setEncodings();
+          }
+        });
+
     // Send one SQL Statement?
     Label wlUseOneStatement = new Label(shell, SWT.RIGHT);
     wlUseOneStatement.setText(BaseMessages.getString(PKG, 
"ActionSQL.SendOneStatement.Label"));
     PropsUi.setLook(wlUseOneStatement);
     FormData fdlUseOneStatement = new FormData();
     fdlUseOneStatement.left = new FormAttachment(0, 0);
-    fdlUseOneStatement.top = new FormAttachment(wbFilename, margin);
+    fdlUseOneStatement.top = new FormAttachment(wlEncoding, margin);
     fdlUseOneStatement.right = new FormAttachment(middle, -margin);
     wlUseOneStatement.setLayoutData(fdlUseOneStatement);
     wSendOneStatement = new Button(shell, SWT.CHECK);
@@ -291,6 +331,7 @@ public class ActionSqlDialog extends ActionDialog {
     wSqlFromFile.setSelection(action.isSqlFromFile());
     wSendOneStatement.setSelection(action.isSendOneStatement());
     wFilename.setText(Const.nullToEmpty(action.getSqlFilename()));
+    wEncoding.setText(Const.nullToEmpty(action.getSqlFilenameEncoding()));
   }
 
   @Override
@@ -302,11 +343,29 @@ public class ActionSqlDialog extends ActionDialog {
     wlFilename.setEnabled(wSqlFromFile.getSelection());
     wFilename.setEnabled(wSqlFromFile.getSelection());
     wbFilename.setEnabled(wSqlFromFile.getSelection());
+    wlEncoding.setEnabled(wSqlFromFile.getSelection());
+    wEncoding.setEnabled(wSqlFromFile.getSelection());
     wSql.setEnabled(!wSqlFromFile.getSelection());
     wlSql.setEnabled(!wSqlFromFile.getSelection());
     wlPosition.setEnabled(!wSqlFromFile.getSelection());
   }
 
+  private void setEncodings() {
+    if (!gotEncodings) {
+      gotEncodings = true;
+      wEncoding.removeAll();
+      List<Charset> values = new 
ArrayList<>(Charset.availableCharsets().values());
+      for (Charset charSet : values) {
+        wEncoding.add(charSet.displayName());
+      }
+      String defEncoding = Const.getEnvironmentVariable("file.encoding", 
"UTF-8");
+      int idx = Const.indexOfString(defEncoding, wEncoding.getItems());
+      if (idx >= 0) {
+        wEncoding.select(idx);
+      }
+    }
+  }
+
   private void cancel() {
     action = null;
     dispose();
@@ -326,6 +385,7 @@ public class ActionSqlDialog extends ActionDialog {
     action.setUseVariableSubstitution(wUseSubs.getSelection());
     action.setSqlFromFile(wSqlFromFile.getSelection());
     action.setSqlFilename(wFilename.getText());
+    action.setSqlFilenameEncoding(wEncoding.getText());
     action.setSendOneStatement(wSendOneStatement.getSelection());
     action.setChanged();
 
diff --git 
a/plugins/actions/sql/src/main/resources/org/apache/hop/workflow/actions/sql/messages/messages_en_US.properties
 
b/plugins/actions/sql/src/main/resources/org/apache/hop/workflow/actions/sql/messages/messages_en_US.properties
index f47cdcf0b3..ba035892f3 100644
--- 
a/plugins/actions/sql/src/main/resources/org/apache/hop/workflow/actions/sql/messages/messages_en_US.properties
+++ 
b/plugins/actions/sql/src/main/resources/org/apache/hop/workflow/actions/sql/messages/messages_en_US.properties
@@ -22,6 +22,8 @@ ActionSQL.ErrorRunAction=An error occurred executing this 
action \: {0}
 ActionSQL.ErrorRunningSQLfromFile=Error running SQL from file
 ActionSQL.Filename.Label=SQL filename
 ActionSQL.Filename.Tooltip=SQL filename
+ActionSQL.Encoding.Label=File encoding
+ActionSQL.Encoding.Tooltip=Character encoding of the SQL file (e.g. UTF-8, 
windows-1252). Leave empty for system default.
 ActionSQL.Filetype.All=All files
 ActionSQL.Filetype.Sql=Sql files
 ActionSQL.Filetype.Text=Text files
diff --git 
a/plugins/actions/sql/src/test/java/org/apache/hop/workflow/actions/sql/WorkflowActionSqlTest.java
 
b/plugins/actions/sql/src/test/java/org/apache/hop/workflow/actions/sql/WorkflowActionSqlTest.java
index 643599065d..a1c60998f2 100644
--- 
a/plugins/actions/sql/src/test/java/org/apache/hop/workflow/actions/sql/WorkflowActionSqlTest.java
+++ 
b/plugins/actions/sql/src/test/java/org/apache/hop/workflow/actions/sql/WorkflowActionSqlTest.java
@@ -40,6 +40,7 @@ class WorkflowActionSqlTest extends 
WorkflowActionLoadSaveTestSupport<ActionSql>
         "useVariableSubstitution",
         "sqlFromFile",
         "sqlFilename",
+        "sqlFilenameEncoding",
         "sendOneStatement",
         "connection");
   }
@@ -51,6 +52,7 @@ class WorkflowActionSqlTest extends 
WorkflowActionLoadSaveTestSupport<ActionSql>
         "useVariableSubstitution", "isUseVariableSubstitution",
         "sqlFromFile", "isSqlFromFile",
         "sqlFilename", "getSqlFilename",
+        "sqlFilenameEncoding", "getSqlFilenameEncoding",
         "sendOneStatement", "isSendOneStatement",
         "connection", "getConnection");
   }
@@ -62,6 +64,7 @@ class WorkflowActionSqlTest extends 
WorkflowActionLoadSaveTestSupport<ActionSql>
         "useVariableSubstitution", "setUseVariableSubstitution",
         "sqlFromFile", "setSqlFromFile",
         "sqlFilename", "setSqlFilename",
+        "sqlFilenameEncoding", "setSqlFilenameEncoding",
         "sendOneStatement", "setSendOneStatement",
         "connection", "setConnection");
   }

Reply via email to