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 eeead6aae1 Issue #1941 (Table Input final cleanup, extra test) (#6768)
eeead6aae1 is described below

commit eeead6aae1c007526027320368875858fa260bec
Author: Matt Casters <[email protected]>
AuthorDate: Thu Mar 12 08:21:45 2026 +0100

    Issue #1941 (Table Input final cleanup, extra test) (#6768)
---
 .../pipeline/transforms/tableinput/TableInput.java | 102 +++++++-------
 .../transforms/tableinput/TableInputData.java      |   8 +-
 .../transforms/tableinput/TableInputDialog.java    |  60 ++++-----
 .../transforms/tableinput/TableInputMeta.java      | 150 +++++----------------
 .../transforms/tableinput/TableInputMetaTest.java  |  76 +++++++++++
 .../tableinput/src/test/resources/transform.xml    |  27 ++++
 6 files changed, 223 insertions(+), 200 deletions(-)

diff --git 
a/plugins/transforms/tableinput/src/main/java/org/apache/hop/pipeline/transforms/tableinput/TableInput.java
 
b/plugins/transforms/tableinput/src/main/java/org/apache/hop/pipeline/transforms/tableinput/TableInput.java
index 9a18cc44ce..2aa42fb7f1 100644
--- 
a/plugins/transforms/tableinput/src/main/java/org/apache/hop/pipeline/transforms/tableinput/TableInput.java
+++ 
b/plugins/transforms/tableinput/src/main/java/org/apache/hop/pipeline/transforms/tableinput/TableInput.java
@@ -26,6 +26,7 @@ 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.exception.HopException;
+import org.apache.hop.core.exception.HopTransformException;
 import org.apache.hop.core.row.IRowMeta;
 import org.apache.hop.core.row.IValueMeta;
 import org.apache.hop.core.row.RowDataUtil;
@@ -36,10 +37,10 @@ import org.apache.hop.pipeline.Pipeline;
 import org.apache.hop.pipeline.PipelineMeta;
 import org.apache.hop.pipeline.transform.BaseTransform;
 import org.apache.hop.pipeline.transform.TransformMeta;
+import org.jetbrains.annotations.Nullable;
 
 /** Reads information from a database table by using freehand SQL */
 public class TableInput extends BaseTransform<TableInputMeta, TableInputData> {
-
   private static final Class<?> PKG = TableInputMeta.class;
 
   public TableInput(
@@ -89,10 +90,10 @@ public class TableInput extends 
BaseTransform<TableInputMeta, TableInputData> {
   @Override
   public boolean processRow() throws HopException {
     if (first) { // we just got started
+      first = false;
 
       Object[] parameters;
       IRowMeta parametersMeta;
-      first = false;
 
       // Make sure we read data from source transforms...
       if (data.infoStream.getTransformMeta() != null) {
@@ -117,9 +118,9 @@ public class TableInput extends 
BaseTransform<TableInputMeta, TableInputData> {
                     + data.infoStream.getTransformName()
                     + "]");
           }
-          RowMetaAndData rmad = readStartDate(); // Read values in lookup 
table (look)
-          parameters = rmad.getData();
-          parametersMeta = rmad.getRowMeta();
+          RowMetaAndData rowMetaAndData = readStartDate(); // Read values in 
lookup table (look)
+          parameters = rowMetaAndData.getData();
+          parametersMeta = rowMetaAndData.getRowMeta();
         }
         if (parameters != null && isDetailed()) {
           logDetailed("Query parameters found = " + 
parametersMeta.getString(parameters));
@@ -139,64 +140,39 @@ public class TableInput extends 
BaseTransform<TableInputMeta, TableInputData> {
         return false;
       }
     } else {
-      if (data.thisrow != null) { // We can expect more rows
-
+      if (data.thisRow != null) { // We can expect more rows
         try {
-          data.nextrow = data.db.getRow(data.rs, false);
+          data.nextRow = data.db.getRow(data.rs, false);
         } catch (HopDatabaseException e) {
           if (e.getCause() instanceof SQLException && isStopped()) {
-            // This exception indicates we tried reading a row after the 
statment for this transform
-            // was cancelled
-            // this is expected and ok so do not pass the exception up
+            // This exception indicates we tried reading a row after the 
statement
+            // (for this transform) was canceled.
+            // This is expected and ok so do not pass the exception up.
+            //
             logDebug(e.getMessage());
             return false;
           } else {
             throw e;
           }
         }
-        if (data.nextrow != null) {
+        if (data.nextRow != null) {
           incrementLinesInput();
         }
       }
     }
 
-    if (data.thisrow == null) { // Finished reading?
-
-      boolean done = false;
-      if (meta.isExecuteEachInputRow()) { // Try to get another row from the 
input stream
-        Object[] nextRow = getRowFrom(data.rowSet);
-        if (nextRow == null) { // Nothing more to get!
-
-          done = true;
-        } else {
-          // First close the previous query, otherwise we run out of cursors!
-          closePreviousQuery();
-
-          boolean success = doQuery(data.rowSet.getRowMeta(), nextRow); // OK, 
perform a new query
-          if (!success) {
-            return false;
-          }
-
-          if (data.thisrow != null) {
-            putRow(data.rowMeta, data.thisrow); // fill the rowset(s). (wait 
for empty)
-            data.thisrow = data.nextrow;
-
-            if (checkFeedback(getLinesInput()) && isBasic()) {
-              logBasic("linenr " + getLinesInput());
-            }
-          }
-        }
-      } else {
-        done = true;
+    if (data.thisRow == null) { // Finished reading?
+      Boolean done = determineDoneReading();
+      if (done == null) {
+        return false;
       }
-
       if (done) {
         setOutputDone(); // signal end to receiver(s)
         return false; // end of data or error.
       }
     } else {
-      putRow(data.rowMeta, data.thisrow); // fill the rowset(s). (wait for 
empty)
-      data.thisrow = data.nextrow;
+      putRow(data.rowMeta, data.thisRow); // fill the rowset(s). (wait for 
empty)
+      data.thisRow = data.nextRow;
 
       if (checkFeedback(getLinesInput()) && isBasic()) {
         logBasic("linenr " + getLinesInput());
@@ -206,6 +182,38 @@ public class TableInput extends 
BaseTransform<TableInputMeta, TableInputData> {
     return true;
   }
 
+  private @Nullable Boolean determineDoneReading()
+      throws HopTransformException, HopDatabaseException {
+    boolean done = false;
+    if (meta.isExecuteEachInputRow()) { // Try to get another row from the 
input stream
+      Object[] nextRow = getRowFrom(data.rowSet);
+      if (nextRow == null) { // Nothing more to get!
+
+        done = true;
+      } else {
+        // First close the previous query, otherwise we run out of cursors!
+        closePreviousQuery();
+
+        boolean success = doQuery(data.rowSet.getRowMeta(), nextRow); // OK, 
perform a new query
+        if (!success) {
+          return null;
+        }
+
+        if (data.thisRow != null) {
+          putRow(data.rowMeta, data.thisRow); // fill the rowset(s). (wait for 
empty)
+          data.thisRow = data.nextRow;
+
+          if (checkFeedback(getLinesInput()) && isBasic()) {
+            logBasic("linenr " + getLinesInput());
+          }
+        }
+      }
+    } else {
+      done = true;
+    }
+    return done;
+  }
+
   private void closePreviousQuery() throws HopDatabaseException {
     if (data.db != null) {
       data.db.closeQuery(data.rs);
@@ -255,11 +263,11 @@ public class TableInput extends 
BaseTransform<TableInputMeta, TableInputData> {
       }
 
       // Get the first row...
-      data.thisrow = data.db.getRow(data.rs);
-      if (data.thisrow != null) {
+      data.thisRow = data.db.getRow(data.rs);
+      if (data.thisRow != null) {
         incrementLinesInput();
-        data.nextrow = data.db.getRow(data.rs);
-        if (data.nextrow != null) {
+        data.nextRow = data.db.getRow(data.rs);
+        if (data.nextRow != null) {
           incrementLinesInput();
         }
       }
diff --git 
a/plugins/transforms/tableinput/src/main/java/org/apache/hop/pipeline/transforms/tableinput/TableInputData.java
 
b/plugins/transforms/tableinput/src/main/java/org/apache/hop/pipeline/transforms/tableinput/TableInputData.java
index ca846abd25..1af83d2a88 100644
--- 
a/plugins/transforms/tableinput/src/main/java/org/apache/hop/pipeline/transforms/tableinput/TableInputData.java
+++ 
b/plugins/transforms/tableinput/src/main/java/org/apache/hop/pipeline/transforms/tableinput/TableInputData.java
@@ -27,8 +27,8 @@ import org.apache.hop.pipeline.transform.stream.IStream;
 
 @SuppressWarnings("java:S1104")
 public class TableInputData extends BaseTransformData implements 
ITransformData {
-  public Object[] nextrow;
-  public Object[] thisrow;
+  public Object[] nextRow;
+  public Object[] thisRow;
   public Database db;
   public ResultSet rs;
   public String lookupTransform;
@@ -41,8 +41,8 @@ public class TableInputData extends BaseTransformData 
implements ITransformData
     super();
 
     db = null;
-    thisrow = null;
-    nextrow = null;
+    thisRow = null;
+    nextRow = null;
     rs = null;
     lookupTransform = null;
   }
diff --git 
a/plugins/transforms/tableinput/src/main/java/org/apache/hop/pipeline/transforms/tableinput/TableInputDialog.java
 
b/plugins/transforms/tableinput/src/main/java/org/apache/hop/pipeline/transforms/tableinput/TableInputDialog.java
index 961cc813ce..3c5020a3c1 100644
--- 
a/plugins/transforms/tableinput/src/main/java/org/apache/hop/pipeline/transforms/tableinput/TableInputDialog.java
+++ 
b/plugins/transforms/tableinput/src/main/java/org/apache/hop/pipeline/transforms/tableinput/TableInputDialog.java
@@ -72,7 +72,7 @@ public class TableInputDialog extends BaseTransformDialog {
 
   private MetaSelectionLine<DatabaseMeta> wConnection;
 
-  private TextComposite wSql;
+  private TextComposite wSqlComposite;
 
   private CCombo wDataFrom;
 
@@ -87,9 +87,7 @@ public class TableInputDialog extends BaseTransformDialog {
 
   private Label wlPosition;
 
-  private Label wlSqlFromFile;
   private TextVar wSqlFromFile;
-  private Button wbSqlFromFile;
 
   public TableInputDialog(
       Shell parent, IVariables variables, TableInputMeta transformMeta, 
PipelineMeta pipelineMeta) {
@@ -108,7 +106,7 @@ public class TableInputDialog extends BaseTransformDialog {
     wConnection.addListener(SWT.Selection, e -> getSqlReservedWords());
 
     // Load SQL from file
-    wlSqlFromFile = new Label(shell, SWT.RIGHT);
+    Label wlSqlFromFile = new Label(shell, SWT.RIGHT);
     wlSqlFromFile.setText(BaseMessages.getString(PKG, 
"TableInputDialog.LoadSqlFromFile"));
     PropsUi.setLook(wlSqlFromFile);
     FormData fdlSqlFromFile = new FormData();
@@ -116,7 +114,7 @@ public class TableInputDialog extends BaseTransformDialog {
     fdlSqlFromFile.right = new FormAttachment(middle, -margin);
     fdlSqlFromFile.top = new FormAttachment(wConnection, margin);
     wlSqlFromFile.setLayoutData(fdlSqlFromFile);
-    wbSqlFromFile = new Button(shell, SWT.PUSH);
+    Button wbSqlFromFile = new Button(shell, SWT.PUSH);
     PropsUi.setLook(wbSqlFromFile);
     wbSqlFromFile.setText(BaseMessages.getString(PKG, 
"TableInputDialog.Browse"));
     FormData fdbSqlFromFile = new FormData();
@@ -153,7 +151,7 @@ public class TableInputDialog extends BaseTransformDialog {
     wSqlFromFile.addModifyListener(
         e -> {
           if (Utils.isEmpty(wSqlFromFile.getText())) {
-            wSql.setEditable(true);
+            wSqlComposite.setEditable(true);
           }
         });
 
@@ -277,30 +275,30 @@ public class TableInputDialog extends BaseTransformDialog 
{
     wbTable.setLayoutData(fdbTable);
 
     if (EnvironmentUtils.getInstance().isWeb()) {
-      wSql =
+      wSqlComposite =
           new StyledTextComp(
               variables, shell, SWT.MULTI | SWT.LEFT | SWT.BORDER | 
SWT.H_SCROLL | SWT.V_SCROLL);
     } else {
-      wSql =
+      wSqlComposite =
           new SQLStyledTextComp(
               variables, shell, SWT.MULTI | SWT.LEFT | SWT.BORDER | 
SWT.H_SCROLL | SWT.V_SCROLL);
     }
-    PropsUi.setLook(wSql, Props.WIDGET_STYLE_FIXED);
-    wSql.addModifyListener(lsMod);
+    PropsUi.setLook(wSqlComposite, Props.WIDGET_STYLE_FIXED);
+    wSqlComposite.addModifyListener(lsMod);
     FormData fdSql = new FormData();
     fdSql.left = new FormAttachment(0, 0);
     fdSql.top = new FormAttachment(wbTable, margin);
     fdSql.right = new FormAttachment(100, -margin);
     fdSql.bottom = new FormAttachment(wlPosition, -margin);
     fdSql.height = 200;
-    wSql.setLayoutData(fdSql);
-    wSql.addModifyListener(
+    wSqlComposite.setLayoutData(fdSql);
+    wSqlComposite.addModifyListener(
         arg0 -> {
           setSqlToolTip();
           setPosition();
         });
 
-    wSql.addKeyListener(
+    wSqlComposite.addKeyListener(
         new KeyAdapter() {
           @Override
           public void keyPressed(KeyEvent e) {
@@ -312,7 +310,7 @@ public class TableInputDialog extends BaseTransformDialog {
             setPosition();
           }
         });
-    wSql.addFocusListener(
+    wSqlComposite.addFocusListener(
         new FocusAdapter() {
           @Override
           public void focusGained(FocusEvent e) {
@@ -324,7 +322,7 @@ public class TableInputDialog extends BaseTransformDialog {
             setPosition();
           }
         });
-    wSql.addMouseListener(
+    wSqlComposite.addMouseListener(
         new MouseAdapter() {
           @Override
           public void mouseDoubleClick(MouseEvent e) {
@@ -349,7 +347,7 @@ public class TableInputDialog extends BaseTransformDialog {
 
     final List<String> sqlKeywords = getSqlReservedWords();
 
-    wSql.addLineStyleListener(sqlKeywords);
+    wSqlComposite.addLineStyleListener(sqlKeywords);
     getData();
     input.setChanged(changed);
 
@@ -379,8 +377,8 @@ public class TableInputDialog extends BaseTransformDialog {
   }
 
   public void setPosition() {
-    int lineNumber = wSql.getLineNumber();
-    int columnNumber = wSql.getColumnNumber();
+    int lineNumber = wSqlComposite.getLineNumber();
+    int columnNumber = wSqlComposite.getColumnNumber();
     wlPosition.setText(
         BaseMessages.getString(
             PKG, "TableInputDialog.Position.Label", "" + lineNumber, "" + 
columnNumber));
@@ -389,13 +387,13 @@ public class TableInputDialog extends BaseTransformDialog 
{
   private void loadSqlFromFileAndSetReadOnly() {
     String path = variables.resolve(wSqlFromFile.getText());
     if (Utils.isEmpty(path)) {
-      wSql.setEditable(true);
+      wSqlComposite.setEditable(true);
       return;
     }
     try {
       String content = HopVfs.getTextFileContent(path, Const.XML_ENCODING);
-      wSql.setText(content);
-      wSql.setEditable(false);
+      wSqlComposite.setText(content);
+      wSqlComposite.setEditable(false);
     } catch (HopFileException e) {
       MessageBox mb = new MessageBox(shell, SWT.OK | SWT.ICON_WARNING);
       mb.setText(BaseMessages.getString(PKG, 
"TableInputDialog.DialogCaptionError"));
@@ -404,13 +402,13 @@ public class TableInputDialog extends BaseTransformDialog 
{
               + Const.CR
               + e.getMessage());
       mb.open();
-      wSql.setEditable(true);
+      wSqlComposite.setEditable(true);
     }
   }
 
   protected void setSqlToolTip() {
     if (wVariables.getSelection()) {
-      wSql.setToolTipText(variables.resolve(wSql.getText()));
+      wSqlComposite.setToolTipText(variables.resolve(wSqlComposite.getText()));
     }
   }
 
@@ -418,7 +416,7 @@ public class TableInputDialog extends BaseTransformDialog {
   public void getData() {
 
     if (input.getSql() != null) {
-      wSql.setText(input.getSql());
+      wSqlComposite.setText(input.getSql());
     }
     if (input.getConnection() != null) {
       wConnection.setText(input.getConnection());
@@ -428,7 +426,7 @@ public class TableInputDialog extends BaseTransformDialog {
     if (!Utils.isEmpty(wSqlFromFile.getText())) {
       loadSqlFromFileAndSetReadOnly();
     } else {
-      wSql.setEditable(true);
+      wSqlComposite.setEditable(true);
     }
 
     wLimit.setText(Const.NVL(input.getRowLimit(), ""));
@@ -451,9 +449,9 @@ public class TableInputDialog extends BaseTransformDialog {
     meta.setConnection(wConnection.getText());
 
     meta.setSql(
-        preview && !Utils.isEmpty(wSql.getSelectionText())
-            ? wSql.getSelectionText()
-            : wSql.getText());
+        preview && !Utils.isEmpty(wSqlComposite.getSelectionText())
+            ? wSqlComposite.getSelectionText()
+            : wSqlComposite.getText());
     meta.setSqlFromFile(wSqlFromFile.getText());
 
     meta.setRowLimit(wLimit.getText());
@@ -498,7 +496,7 @@ public class TableInputDialog extends BaseTransformDialog {
                 + databaseMeta.getQuotedSchemaTableCombination(
                     variables, std.getSchemaName(), std.getTableName())
                 + Const.CR;
-        wSql.setText(sql);
+        wSqlComposite.setText(sql);
 
         MessageBox yn = new MessageBox(shell, SWT.YES | SWT.NO | SWT.CANCEL | 
SWT.ICON_QUESTION);
         yn.setMessage(BaseMessages.getString(PKG, 
"TableInputDialog.IncludeFieldNamesInSQL"));
@@ -508,7 +506,7 @@ public class TableInputDialog extends BaseTransformDialog {
           case SWT.CANCEL:
             break;
           case SWT.NO:
-            wSql.setText(sql);
+            wSqlComposite.setText(sql);
             break;
           case SWT.YES:
             Database db = new Database(loggingObject, variables, databaseMeta);
@@ -531,7 +529,7 @@ public class TableInputDialog extends BaseTransformDialog {
                         + databaseMeta.getQuotedSchemaTableCombination(
                             variables, std.getSchemaName(), std.getTableName())
                         + Const.CR;
-                wSql.setText(sql);
+                wSqlComposite.setText(sql);
               } else {
                 MessageBox mb = new MessageBox(shell, SWT.OK | SWT.ICON_ERROR);
                 mb.setMessage(
diff --git 
a/plugins/transforms/tableinput/src/main/java/org/apache/hop/pipeline/transforms/tableinput/TableInputMeta.java
 
b/plugins/transforms/tableinput/src/main/java/org/apache/hop/pipeline/transforms/tableinput/TableInputMeta.java
index 7eeb2aa14b..cb626021f6 100644
--- 
a/plugins/transforms/tableinput/src/main/java/org/apache/hop/pipeline/transforms/tableinput/TableInputMeta.java
+++ 
b/plugins/transforms/tableinput/src/main/java/org/apache/hop/pipeline/transforms/tableinput/TableInputMeta.java
@@ -18,6 +18,8 @@
 package org.apache.hop.pipeline.transforms.tableinput;
 
 import java.util.List;
+import lombok.Getter;
+import lombok.Setter;
 import org.apache.hop.core.CheckResult;
 import org.apache.hop.core.Const;
 import org.apache.hop.core.ICheckResult;
@@ -29,7 +31,6 @@ import org.apache.hop.core.exception.HopDatabaseException;
 import org.apache.hop.core.exception.HopException;
 import org.apache.hop.core.exception.HopFileException;
 import org.apache.hop.core.exception.HopTransformException;
-import org.apache.hop.core.exception.HopXmlException;
 import org.apache.hop.core.row.IRowMeta;
 import org.apache.hop.core.row.IValueMeta;
 import org.apache.hop.core.row.RowDataUtil;
@@ -51,7 +52,6 @@ import org.apache.hop.pipeline.transform.stream.IStream;
 import org.apache.hop.pipeline.transform.stream.IStream.StreamType;
 import org.apache.hop.pipeline.transform.stream.Stream;
 import org.apache.hop.pipeline.transform.stream.StreamIcon;
-import org.w3c.dom.Node;
 
 @Transform(
     id = "TableInput",
@@ -62,6 +62,8 @@ import org.w3c.dom.Node;
     documentationUrl = "/pipeline/transforms/tableinput.html",
     keywords = "i18n::TableInputMeta.keyword",
     actionTransformTypes = {ActionTransformType.INPUT, 
ActionTransformType.RDBMS})
+@Getter
+@Setter
 public class TableInputMeta extends BaseTransformMeta<TableInput, 
TableInputData> {
 
   private static final Class<?> PKG = TableInputMeta.class;
@@ -100,94 +102,20 @@ public class TableInputMeta extends 
BaseTransformMeta<TableInput, TableInputData
     super();
   }
 
-  /**
-   * @return Returns true if the transform should be run per row
-   */
-  public boolean isExecuteEachInputRow() {
-    return executeEachInputRow;
-  }
-
-  /**
-   * @param oncePerRow true if the transform should be run per row
-   */
-  public void setExecuteEachInputRow(boolean oncePerRow) {
-    this.executeEachInputRow = oncePerRow;
-  }
-
-  /**
-   * @return Returns the rowLimit.
-   */
-  public String getRowLimit() {
-    return rowLimit;
-  }
-
-  /**
-   * @param rowLimit The rowLimit to set.
-   */
-  public void setRowLimit(String rowLimit) {
-    this.rowLimit = rowLimit;
-  }
-
-  /**
-   * @return Returns the sql.
-   */
-  public String getSql() {
-    return sql;
-  }
-
-  /**
-   * @param sql The sql to set.
-   */
-  public void setSql(String sql) {
-    this.sql = sql;
-  }
-
-  public String getConnection() {
-    return connection;
-  }
-
-  public void setConnection(String connection) {
-    this.connection = connection;
-  }
-
-  public String getLookup() {
-    return lookup;
-  }
-
-  public void setLookup(String lookup) {
-    this.lookup = lookup;
-  }
-
-  public String getSqlFromFile() {
-    return sqlFromFile;
-  }
-
-  public void setSqlFromFile(String sqlFromFile) {
-    this.sqlFromFile = sqlFromFile;
-  }
-
-  /**
-   * Returns the SQL to execute: either from the inline editor or loaded from 
the file specified by
-   * sqlFromFile (using VFS). Variables are resolved in the file path.
-   */
-  public String getEffectiveSql(IVariables variables) throws HopException {
-    if (!Utils.isEmpty(sqlFromFile)) {
-      String path = variables.resolve(sqlFromFile);
-      try {
-        return HopVfs.getTextFileContent(path, Const.XML_ENCODING);
-      } catch (HopFileException e) {
-        throw new HopException(
-            BaseMessages.getString(PKG, 
"TableInputMeta.Exception.CouldNotLoadSqlFromFile", path),
-            e);
-      }
-    }
-    return sql;
+  public TableInputMeta(TableInputMeta m) {
+    this();
+    this.connection = m.connection;
+    this.executeEachInputRow = m.executeEachInputRow;
+    this.lookup = m.lookup;
+    this.rowLimit = m.rowLimit;
+    this.sql = m.sql;
+    this.sqlFromFile = m.sqlFromFile;
+    this.variableReplacementActive = m.variableReplacementActive;
   }
 
   @Override
   public Object clone() {
-    TableInputMeta retval = (TableInputMeta) super.clone();
-    return retval;
+    return new TableInputMeta(this);
   }
 
   @Override
@@ -286,22 +214,22 @@ public class TableInputMeta extends 
BaseTransformMeta<TableInput, TableInputData
     }
   }
 
-  @Override
-  public String getXml() throws HopException {
-
-    List<IStream> infoStreams = getTransformIOMeta().getInfoStreams();
-    lookup = infoStreams.get(0).getTransformName();
-
-    return super.getXml();
-  }
-
-  @Override
-  public void loadXml(Node transformNode, IHopMetadataProvider 
metadataProvider)
-      throws HopXmlException {
-    super.loadXml(transformNode, metadataProvider);
-
-    IStream infoStream = getTransformIOMeta().getInfoStreams().get(0);
-    infoStream.setSubject(lookup);
+  /**
+   * Returns the SQL to execute: either from the inline editor or loaded from 
the file specified by
+   * sqlFromFile (using VFS). Variables are resolved in the file path.
+   */
+  public String getEffectiveSql(IVariables variables) throws HopException {
+    if (!Utils.isEmpty(sqlFromFile)) {
+      String path = variables.resolve(sqlFromFile);
+      try {
+        return HopVfs.getTextFileContent(path, Const.XML_ENCODING);
+      } catch (HopFileException e) {
+        throw new HopException(
+            BaseMessages.getString(PKG, 
"TableInputMeta.Exception.CouldNotLoadSqlFromFile", path),
+            e);
+      }
+    }
+    return sql;
   }
 
   @Override
@@ -515,9 +443,9 @@ public class TableInputMeta extends 
BaseTransformMeta<TableInput, TableInputData
           
metadataProvider.getSerializer(DatabaseMeta.class).load(variables.resolve(connection));
       String effectiveSql = getEffectiveSql(variables);
 
-      // Find the lookupfields...
+      // Find the lookup fields.
       IRowMeta out = new RowMeta();
-      // TODO: this builds, but does it work in all cases.
+
       getFields(
           out, transformMeta.getName(), new IRowMeta[] {info}, null, 
variables, metadataProvider);
 
@@ -546,20 +474,6 @@ public class TableInputMeta extends 
BaseTransformMeta<TableInput, TableInputData
     }
   }
 
-  /**
-   * @return Returns the variableReplacementActive.
-   */
-  public boolean isVariableReplacementActive() {
-    return variableReplacementActive;
-  }
-
-  /**
-   * @param variableReplacementActive The variableReplacementActive to set.
-   */
-  public void setVariableReplacementActive(boolean variableReplacementActive) {
-    this.variableReplacementActive = variableReplacementActive;
-  }
-
   /**
    * Returns the Input/Output metadata for this transform. The generator 
transform only produces
    * output, does not accept input!
diff --git 
a/plugins/transforms/tableinput/src/test/java/org/apache/hop/pipeline/transforms/tableinput/TableInputMetaTest.java
 
b/plugins/transforms/tableinput/src/test/java/org/apache/hop/pipeline/transforms/tableinput/TableInputMetaTest.java
new file mode 100644
index 0000000000..c037c678b7
--- /dev/null
+++ 
b/plugins/transforms/tableinput/src/test/java/org/apache/hop/pipeline/transforms/tableinput/TableInputMetaTest.java
@@ -0,0 +1,76 @@
+/*
+ * 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.pipeline.transforms.tableinput;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Objects;
+import org.apache.hop.core.xml.XmlHandler;
+import org.apache.hop.metadata.serializer.memory.MemoryMetadataProvider;
+import org.apache.hop.metadata.serializer.xml.XmlMetadataUtil;
+import org.apache.hop.pipeline.transform.TransformMeta;
+import org.apache.hop.pipeline.transform.stream.IStream;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+class TableInputMetaTest {
+  @Test
+  void testLoadSave() throws Exception {
+    Path path = 
Paths.get(Objects.requireNonNull(getClass().getResource("/transform.xml")).toURI());
+    String xml = Files.readString(path);
+    TableInputMeta meta = new TableInputMeta();
+    XmlMetadataUtil.deSerializeFromXml(
+        XmlHandler.loadXmlString(xml, TransformMeta.XML_TAG),
+        TableInputMeta.class,
+        meta,
+        new MemoryMetadataProvider());
+
+    validate(meta);
+
+    // Do a round trip:
+    //
+    String xmlCopy =
+        XmlHandler.openTag(TransformMeta.XML_TAG)
+            + XmlMetadataUtil.serializeObjectToXml(meta)
+            + XmlHandler.closeTag(TransformMeta.XML_TAG);
+    TableInputMeta metaCopy = new TableInputMeta();
+    XmlMetadataUtil.deSerializeFromXml(
+        XmlHandler.loadXmlString(xmlCopy, TransformMeta.XML_TAG),
+        TableInputMeta.class,
+        metaCopy,
+        new MemoryMetadataProvider());
+    validate(metaCopy);
+  }
+
+  private static void validate(TableInputMeta meta) {
+    Assertions.assertEquals("h2", meta.getConnection());
+    Assertions.assertEquals("100", meta.getRowLimit());
+    Assertions.assertEquals("parameters", meta.getLookup());
+    Assertions.assertTrue(meta.isExecuteEachInputRow());
+    Assertions.assertTrue(meta.isVariableReplacementActive());
+    Assertions.assertEquals("SELECT ID, NAME FROM PUBLIC.DDLTEST WHERE NAME = 
?", meta.getSql());
+
+    // Do we have an IO stream?
+    
Assertions.assertFalse(meta.getTransformIOMeta().getInfoStreams().isEmpty());
+    IStream stream = meta.getTransformIOMeta().getInfoStreams().get(0);
+    Assertions.assertNotNull(stream);
+    Assertions.assertEquals("parameters", stream.getSubject());
+  }
+}
diff --git a/plugins/transforms/tableinput/src/test/resources/transform.xml 
b/plugins/transforms/tableinput/src/test/resources/transform.xml
new file mode 100644
index 0000000000..845c492b96
--- /dev/null
+++ b/plugins/transforms/tableinput/src/test/resources/transform.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ 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.
+  ~
+  -->
+<transform>
+    <connection>h2</connection>
+    <execute_each_row>Y</execute_each_row>
+    <limit>100</limit>
+    <lookup>parameters</lookup>
+    <sql>SELECT ID, NAME FROM PUBLIC.DDLTEST WHERE NAME = ?</sql>
+    <sql_from_file/>
+    <variables_active>Y</variables_active>
+</transform>

Reply via email to