Skip to content

Conversation

@akhil-testsigma
Copy link
Contributor

@akhil-testsigma akhil-testsigma commented Jan 6, 2026

Publish this addon as public

Addon Name: OracleDB_Queries
Jarvis Link: https://jarvis.testsigma.com/ui/tenants/2817/addons
Jira : https://testsigma.atlassian.net/browse/CUS-9809
Added class to execute multiple queries at a time in oracle db

Summary by CodeRabbit

  • New Features
    • Added support for executing multiple Oracle SELECT queries across Android, iOS, Mobile Web, and Web platforms
    • Query results are automatically formatted and logged for test visibility
    • Results can be captured and stored in runtime variables for use in subsequent test steps

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Jan 6, 2026

📝 Walkthrough

Walkthrough

The pull request bumps the project version from 1.0.9 to 1.0.10 and introduces four new OracleMultipleQueriesSelect action classes across Android, iOS, Mobile Web, and Web platforms. Each action executes multiple Oracle SELECT queries sequentially over a JDBC connection, formats results, and stores aggregated output into runtime variables.

Changes

Cohort / File(s) Summary
Project Version Bump
pom.xml
Version incremented from 1.0.9 to 1.0.10.
Oracle Multi-Query Actions
src/main/java/com/testsigma/addons/android/OracleMultipleQueriesSelect.java, src/main/java/com/testsigma/addons/ios/OracleMultipleQueriesSelect.java, src/main/java/com/testsigma/addons/mobileweb/OracleMultipleQueriesSelect.java, src/main/java/com/testsigma/addons/web/OracleMultipleQueriesSelect.java
Four new platform-specific action classes (extending AndroidAction, IOSAction, WebAction respectively) that accept semicolon-separated SELECT queries and a DB connection URL via TestData fields. Each establishes a JDBC connection, splits and executes queries, formats results into UI-friendly and log-friendly outputs, accumulates row values, and stores concatenated results into a runtime variable if provided. All implement execute() method with resource cleanup in finally blocks and error handling via stack trace capture.

Sequence Diagram

sequenceDiagram
    participant Action as OracleMultipleQueriesSelect
    participant DB as DatabaseUtil
    participant JDBC as JDBC Driver
    participant Oracle as Oracle Database
    participant Runtime as Runtime Variable

    Action->>Action: Parse queries from testData1
    Action->>DB: getConnection(testData2 - URL)
    DB->>JDBC: DriverManager.getConnection(url)
    JDBC->>Oracle: Establish connection
    Oracle-->>JDBC: Connection OK
    JDBC-->>DB: Return Connection
    DB-->>Action: Return Connection

    Action->>Action: Split queries by semicolon

    loop For each query
        Action->>JDBC: Create Statement
        Action->>JDBC: Execute query (SELECT)
        JDBC->>Oracle: Run query
        Oracle-->>JDBC: ResultSet
        JDBC-->>Action: ResultSet + Metadata

        Action->>Action: Extract column names from metadata
        Action->>Action: Iterate rows, build output
        Action->>Action: Format UI-friendly output
        Action->>Action: Format log-friendly output
        Action->>Action: Accumulate row values (comma-separated)
    end

    alt Runtime variable provided
        Action->>Runtime: Store aggregated runtimeValue with variable name
        Runtime-->>Action: Variable stored
    end

    Action->>JDBC: Close Statement
    Action->>JDBC: Close Connection
    JDBC->>Oracle: Disconnect
    Oracle-->>JDBC: OK
    JDBC-->>Action: Resources cleaned

    Action-->>Action: Return Result.SUCCESS with message
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • Ganesh-Testsigma
  • vigneshtestsigma

Poem

🐰 Across the platforms, queries dance free,
Android, iOS, Web—all agree!
Oracle whispers its data so bright,
Multiple queries in one swift flight. 🚀
Results runtime-bound, the magic's set right!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding a class to execute multiple Oracle DB queries. It directly matches the PR objectives and file changes.
✨ Finishing touches
  • 📝 Generate docstrings

Warning

Review ran into problems

🔥 Problems

Git: Failed to clone repository. Please run the @coderabbitai full review command to re-trigger a full review. If the issue persists, set path_filters to include or exclude specific files.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
oracledb_queries/src/main/java/com/testsigma/addons/web/OracleMultipleQueriesSelect.java (1)

1-140: Same critical and major issues as Android action.

This Web action contains the same issues identified in the Android action review:

Critical issues:

  • No null validation for testData1 and testData2 (lines 51, 54)
  • SQL injection risk - no validation that queries are SELECT-only (lines 54-65)
  • ResultSet resource leak (line 64 onwards)

Major issues:

  • No connection/query timeout (lines 51-53)
  • Sensitive data exposure in logs (lines 62, 73)

Code duplication:

  • This action duplicates the Android implementation with only WebAction base class and ApplicationType.WEB differing

Refer to the Android action review comments for detailed fixes. The essential refactor to extract common logic would address the duplication across all platform actions.

oracledb_queries/src/main/java/com/testsigma/addons/mobileweb/OracleMultipleQueriesSelect.java (1)

1-140: Same critical and major issues as Android and Web actions.

This MobileWeb action contains identical issues:

Critical:

  • Missing null validation for required inputs (lines 51, 54)
  • SQL injection vulnerability (lines 54-65)
  • ResultSet never closed (line 64 onwards)

Major:

  • No timeout configuration (lines 51-53)
  • PII/sensitive data logging (lines 62, 73)

Essential refactor:

  • Code duplicated from Android/Web actions

See the Android action review for detailed remediation steps.

oracledb_queries/src/main/java/com/testsigma/addons/ios/OracleMultipleQueriesSelect.java (1)

1-142: Same critical and major issues as other platform actions.

This iOS action contains the same issues identified in the Android action:

Critical issues:

  • No null validation for testData1 and testData2 (lines 53, 56)
  • SQL injection risk - queries not validated as SELECT-only (lines 56-66)
  • ResultSet resource leak (line 66 onwards)

Major issues:

  • No connection/query timeout (lines 53-54)
  • Sensitive data exposure in logs (lines 64, 74)

Code duplication:

  • Core logic duplicated from Android/Web/MobileWeb actions

Refer to the Android action review for detailed remediation approaches and the essential refactor to eliminate duplication.

🤖 Fix all issues with AI Agents
In
@oracledb_queries/src/main/java/com/testsigma/addons/android/OracleMultipleQueriesSelect.java:
- Around line 1-140: The Android action OracleMultipleQueriesSelect duplicates
the same execute logic across platform-specific classes; extract the shared
DB-query/run-time-variable logic into a new utility (e.g.,
OracleMultipleQueriesExecutor) with a static method (e.g., execute(TestData
queries, TestData connectionUrl, TestData variableName, Logger logger,
Consumer<String> setSuccessMessage, Consumer<String> setErrorMessage)) that
contains the core code currently inside OracleMultipleQueriesSelect.execute(),
and update OracleMultipleQueriesSelect.execute() (and the iOS/MobileWeb/Web
action classes) to simply delegate to that utility, passing
testData1/testData2/testData3, logger, this::setSuccessMessage and
this::setErrorMessage so platform classes only differ by their base class and
ApplicationType.
- Around line 62-74: The code currently logs and displays the full SQL text
(variable query) via logger.info(...) and successMessage.append(...), which may
expose PII; update OracleMultipleQueriesSelect to stop emitting raw query
strings: replace the direct uses of query in logger.info and successMessage with
a sanitized representation (e.g., a helper method sanitizeQuery(String query)
that strips or masks literal values and parameters and/or returns only the query
type and table names), or log only the queryCounter and query type; ensure
successMessage shows the sanitizedQuery or a generic message like "Query N:
SELECT ... (parameters redacted)"; update references to logger.info("Executing
Query [" + queryCounter + "]: " + query) and successMessage.append(...
.append(query) ...) to use the sanitized value and add a short comment in docs
or method javadoc warning users not to include sensitive data in queries.
- Line 7: Remove the unused import of WebAction in
OracleMultipleQueriesSelect.java: delete the line importing
com.testsigma.sdk.WebAction since the class extends AndroidAction and never
references WebAction (class OracleMultipleQueriesSelect); after removal, rebuild
to ensure no references remain.
- Around line 51-53: The code in OracleMultipleQueriesSelect.java calls
DatabaseUtil.getConnection(testData2.getValue().toString()) and then creates a
Statement (stmt) without any timeouts; update the code to set a statement/query
timeout (use stmt.setQueryTimeout(seconds) after creating the Statement) and set
a network/connection timeout on the Connection (e.g.,
connection.setNetworkTimeout(...) or ensure DatabaseUtil.getConnection(...)
configures a socket/connection timeout), and if applicable set the driver login
timeout (DriverManager.setLoginTimeout or equivalent) so the action cannot hang
indefinitely while waiting for the DB.
- Around line 54-65: The loop executing user-supplied SQL in
OracleMultipleQueriesSelect.java (variables: testData1, queries, rawQuery,
query, and the stmt.executeQuery call producing ResultSet rs) must validate each
statement is a read-only SELECT before executing: trim and strip leading
comments, reject any query containing a semicolon or any DDL/DML keywords (e.g.,
INSERT, UPDATE, DELETE, DROP, ALTER, CREATE, TRUNCATE) and require the first
non-whitespace token to match a case-insensitive "SELECT" (e.g., regex like
^\s*(?i)select\b). For invalid queries, log an error or throw an exception and
skip executing it instead of calling stmt.executeQuery; keep the validation
logic adjacent to where rawQuery/query are prepared so no non-SELECT statement
can reach stmt.executeQuery.
- Around line 49-56: The code in OracleMultipleQueriesSelect accesses testData1
and testData2 (and their getValue() results) without null checks and can NPE;
before using them in the method where connection and stmt are created, validate
that testData1, testData2 and their getValue() results are non-null (e.g., in
the start of the execute/run method in OracleMultipleQueriesSelect), and handle
failures by logging a clear error via logger (including which input is missing)
and returning/throwing a controlled exception instead of proceeding to
connection/statement creation; ensure the split(" ;") on
testData1.getValue().toString() only runs after validation.
- Around line 64-119: The ResultSet created by stmt.executeQuery(query) in
OracleMultipleQueriesSelect is never closed, leaking DB resources and risking
issues when reusing the same Statement; fix by ensuring each ResultSet (variable
rs) is closed after processing—preferably wrap the executeQuery/iteration in a
try-with-resources or explicitly call rs.close() in a finally block right after
logging and before incrementing queryCounter, so every loop iteration closes its
ResultSet before the next executeQuery on stmt.

In
@oracledb_queries/src/main/java/com/testsigma/addons/ios/OracleMultipleQueriesSelect.java:
- Line 7: Remove the unused imports in OracleMultipleQueriesSelect.java: delete
the import of com.testsigma.sdk.WebAction and the import of
org.openqa.selenium.devtools.v135.io.IO since the class extends IOSAction and
neither symbol is referenced; ensure only required imports remain and run a
quick compile or IDE optimize imports to confirm no other unused imports exist.
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 03547c9 and d1d6f55.

📒 Files selected for processing (5)
  • oracledb_queries/pom.xml
  • oracledb_queries/src/main/java/com/testsigma/addons/android/OracleMultipleQueriesSelect.java
  • oracledb_queries/src/main/java/com/testsigma/addons/ios/OracleMultipleQueriesSelect.java
  • oracledb_queries/src/main/java/com/testsigma/addons/mobileweb/OracleMultipleQueriesSelect.java
  • oracledb_queries/src/main/java/com/testsigma/addons/web/OracleMultipleQueriesSelect.java
🔇 Additional comments (1)
oracledb_queries/pom.xml (1)

9-9: LGTM: Version bump aligns with new feature addition.

The version increment from 1.0.9 to 1.0.10 is appropriate for introducing the new OracleMultipleQueriesSelect action classes across platforms.

Comment on lines +1 to +140
package com.testsigma.addons.android;

import com.testsigma.addons.oracledb.util.DatabaseUtil;
import com.testsigma.sdk.AndroidAction;
import com.testsigma.sdk.ApplicationType;
import com.testsigma.sdk.Result;
import com.testsigma.sdk.WebAction;
import com.testsigma.sdk.annotation.Action;
import com.testsigma.sdk.annotation.RunTimeData;
import com.testsigma.sdk.annotation.TestData;
import lombok.Data;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.openqa.selenium.NoSuchElementException;

import java.sql.*;

@Data
@Action(
actionText = "Execute OracleDB Multiple Select-Queries on the connection DB_Connection_URL and store output into a variable-name",
description = "Executes multiple Oracle SELECT queries, logs formatted result sets, and stores output in a runtime variable.",
applicationType = ApplicationType.ANDROID
)
public class OracleMultipleQueriesSelect extends AndroidAction {

@TestData(reference = "Select-Queries")
private com.testsigma.sdk.TestData testData1;

@TestData(reference = "DB_Connection_URL")
private com.testsigma.sdk.TestData testData2;

@TestData(reference = "variable-name", isRuntimeVariable = true)
private com.testsigma.sdk.TestData testData3;

@RunTimeData
private com.testsigma.sdk.RunTimeData runTimeData;

@Override
public Result execute() throws NoSuchElementException {

Result result = Result.SUCCESS;
DatabaseUtil databaseUtil = new DatabaseUtil();

Connection connection = null;
Statement stmt = null;

StringBuilder successMessage = new StringBuilder();
StringBuilder runtimeValue = new StringBuilder();

try {
logger.info("====== Oracle DB Multiple Query Execution Started ======");

connection = databaseUtil.getConnection(testData2.getValue().toString());
stmt = connection.createStatement();

String[] queries = testData1.getValue().toString().split(";");
int queryCounter = 1;

for (String rawQuery : queries) {

String query = rawQuery.trim();
if (query.isEmpty()) continue;

logger.info("Executing Query [" + queryCounter + "]: " + query);

ResultSet rs = stmt.executeQuery(query);
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();

/* ---------- UI OUTPUT ---------- */
successMessage.append("<br><b>Query ")
.append(queryCounter)
.append(" Result: ")
.append(query)
.append("</b><br>");

/* ---------- LOG OUTPUT ---------- */
StringBuilder log = new StringBuilder();
log.append("\nQuery ").append(queryCounter)
.append(" Result: ").append(query).append("\n");

log.append("--------------------------------------------------------\n");

// Headers
StringBuilder headerRow = new StringBuilder();
for (int i = 1; i <= columnCount; i++) {
headerRow.append(rsmd.getColumnName(i));
if (i < columnCount) headerRow.append(" | ");
}
log.append(headerRow).append("\n");
log.append("--------------------------------------------------------\n");

// UI headers
for (int i = 1; i <= columnCount; i++) {
successMessage.append(rsmd.getColumnName(i)).append(" | ");
}
successMessage.append("<br>");

// Rows
while (rs.next()) {
StringBuilder row = new StringBuilder();
for (int j = 1; j <= columnCount; j++) {
String value = rs.getString(j);
String safe = value == null ? "" : value;

row.append(safe);
if (j < columnCount) row.append(" | ");

successMessage.append(safe).append(" | ");
runtimeValue.append(safe).append(",");
}
log.append(row).append("\n");
successMessage.append("<br>");
}

logger.info(log.toString());
logger.info("Query [" + queryCounter + "] executed successfully");

queryCounter++;
}

if (testData3 != null) {
runTimeData = new com.testsigma.sdk.RunTimeData();
runTimeData.setKey(testData3.getValue().toString());
runTimeData.setValue(runtimeValue.toString().replaceAll(",$", ""));
}

setSuccessMessage("Successfully executed all queries.<br>" + successMessage);
logger.info("====== Oracle DB Multiple Query Execution Completed ======");

} catch (Exception e) {
setErrorMessage(ExceptionUtils.getStackTrace(e));
return Result.FAILED;
} finally {
try { if (stmt != null) stmt.close(); } catch (Exception ignored) {}
try { if (connection != null) connection.close(); } catch (Exception ignored) {}
}

return result;
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Significant code duplication across platform actions.

This Android action is nearly identical to the iOS, MobileWeb, and Web variants (files under review). Only the package, base class, and ApplicationType differ. The core logic (lines 38-139) is duplicated 4 times, violating DRY principles and making maintenance error-prone.

💡 Refactor suggestion: Extract common logic

Consider creating a shared utility class or base action:

// New shared utility
public class OracleMultipleQueriesExecutor {
    public static Result execute(
        TestData queries, 
        TestData connectionUrl,
        TestData variableName,
        Logger logger,
        Consumer<String> successMessageSetter,
        Consumer<String> errorMessageSetter
    ) {
        // Move the entire execute logic here
    }
}

Then each platform action becomes:

@Override
public Result execute() {
    return OracleMultipleQueriesExecutor.execute(
        testData1, testData2, testData3, 
        logger, this::setSuccessMessage, this::setErrorMessage
    );
}

This reduces duplication from ~140 lines × 4 files to a single shared implementation.

🤖 Prompt for AI Agents
In
@oracledb_queries/src/main/java/com/testsigma/addons/android/OracleMultipleQueriesSelect.java
around lines 1 - 140, The Android action OracleMultipleQueriesSelect duplicates
the same execute logic across platform-specific classes; extract the shared
DB-query/run-time-variable logic into a new utility (e.g.,
OracleMultipleQueriesExecutor) with a static method (e.g., execute(TestData
queries, TestData connectionUrl, TestData variableName, Logger logger,
Consumer<String> setSuccessMessage, Consumer<String> setErrorMessage)) that
contains the core code currently inside OracleMultipleQueriesSelect.execute(),
and update OracleMultipleQueriesSelect.execute() (and the iOS/MobileWeb/Web
action classes) to simply delegate to that utility, passing
testData1/testData2/testData3, logger, this::setSuccessMessage and
this::setErrorMessage so platform classes only differ by their base class and
ApplicationType.

import com.testsigma.sdk.AndroidAction;
import com.testsigma.sdk.ApplicationType;
import com.testsigma.sdk.Result;
import com.testsigma.sdk.WebAction;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Remove unused import.

WebAction is imported but never used. This class extends AndroidAction.

🔎 Proposed fix
-import com.testsigma.sdk.WebAction;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import com.testsigma.sdk.WebAction;
🤖 Prompt for AI Agents
In
@oracledb_queries/src/main/java/com/testsigma/addons/android/OracleMultipleQueriesSelect.java
at line 7, Remove the unused import of WebAction in
OracleMultipleQueriesSelect.java: delete the line importing
com.testsigma.sdk.WebAction since the class extends AndroidAction and never
references WebAction (class OracleMultipleQueriesSelect); after removal, rebuild
to ensure no references remain.

Comment on lines +49 to +56
try {
logger.info("====== Oracle DB Multiple Query Execution Started ======");

connection = databaseUtil.getConnection(testData2.getValue().toString());
stmt = connection.createStatement();

String[] queries = testData1.getValue().toString().split(";");
int queryCounter = 1;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Add null validation for required inputs.

testData1 and testData2 are accessed without null checks. If either field or their values are null, a NullPointerException will be thrown.

🔎 Recommended fix: Add validation
 try {
     logger.info("====== Oracle DB Multiple Query Execution Started ======");
+
+    if (testData1 == null || testData1.getValue() == null) {
+        setErrorMessage("Select-Queries parameter is required");
+        return Result.FAILED;
+    }
+    if (testData2 == null || testData2.getValue() == null) {
+        setErrorMessage("DB_Connection_URL parameter is required");
+        return Result.FAILED;
+    }

     connection = databaseUtil.getConnection(testData2.getValue().toString());
🤖 Prompt for AI Agents
In
@oracledb_queries/src/main/java/com/testsigma/addons/android/OracleMultipleQueriesSelect.java
around lines 49 - 56, The code in OracleMultipleQueriesSelect accesses testData1
and testData2 (and their getValue() results) without null checks and can NPE;
before using them in the method where connection and stmt are created, validate
that testData1, testData2 and their getValue() results are non-null (e.g., in
the start of the execute/run method in OracleMultipleQueriesSelect), and handle
failures by logging a clear error via logger (including which input is missing)
and returning/throwing a controlled exception instead of proceeding to
connection/statement creation; ensure the split(" ;") on
testData1.getValue().toString() only runs after validation.

Comment on lines +51 to +53

connection = databaseUtil.getConnection(testData2.getValue().toString());
stmt = connection.createStatement();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Add connection and query timeout to prevent hanging.

No timeouts are configured for the database connection or statement execution. If the database is slow or unresponsive, the action could hang indefinitely.

🔎 Recommended fix: Set timeouts
 connection = databaseUtil.getConnection(testData2.getValue().toString());
 stmt = connection.createStatement();
+stmt.setQueryTimeout(30); // 30 seconds timeout per query

Additionally, consider configuring connection timeout in DatabaseUtil.getConnection() if not already done.

🤖 Prompt for AI Agents
In
@oracledb_queries/src/main/java/com/testsigma/addons/android/OracleMultipleQueriesSelect.java
around lines 51 - 53, The code in OracleMultipleQueriesSelect.java calls
DatabaseUtil.getConnection(testData2.getValue().toString()) and then creates a
Statement (stmt) without any timeouts; update the code to set a statement/query
timeout (use stmt.setQueryTimeout(seconds) after creating the Statement) and set
a network/connection timeout on the Connection (e.g.,
connection.setNetworkTimeout(...) or ensure DatabaseUtil.getConnection(...)
configures a socket/connection timeout), and if applicable set the driver login
timeout (DriverManager.setLoginTimeout or equivalent) so the action cannot hang
indefinitely while waiting for the DB.

Comment on lines +54 to +65

String[] queries = testData1.getValue().toString().split(";");
int queryCounter = 1;

for (String rawQuery : queries) {

String query = rawQuery.trim();
if (query.isEmpty()) continue;

logger.info("Executing Query [" + queryCounter + "]: " + query);

ResultSet rs = stmt.executeQuery(query);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

SQL injection risk: Validate queries are SELECT-only.

User-provided queries are executed without validation. While the action description specifies "SELECT queries," there's no enforcement preventing malicious users from injecting DML/DDL statements (INSERT, UPDATE, DELETE, DROP, etc.).

🔎 Recommended fix: Add query type validation
 String[] queries = testData1.getValue().toString().split(";");
 int queryCounter = 1;

 for (String rawQuery : queries) {

     String query = rawQuery.trim();
     if (query.isEmpty()) continue;
+
+    // Validate query is SELECT only
+    if (!query.toUpperCase().startsWith("SELECT")) {
+        setErrorMessage("Only SELECT queries are allowed. Query [" + queryCounter + "]: " + query);
+        return Result.FAILED;
+    }

     logger.info("Executing Query [" + queryCounter + "]: " + query);
🤖 Prompt for AI Agents
In
@oracledb_queries/src/main/java/com/testsigma/addons/android/OracleMultipleQueriesSelect.java
around lines 54 - 65, The loop executing user-supplied SQL in
OracleMultipleQueriesSelect.java (variables: testData1, queries, rawQuery,
query, and the stmt.executeQuery call producing ResultSet rs) must validate each
statement is a read-only SELECT before executing: trim and strip leading
comments, reject any query containing a semicolon or any DDL/DML keywords (e.g.,
INSERT, UPDATE, DELETE, DROP, ALTER, CREATE, TRUNCATE) and require the first
non-whitespace token to match a case-insensitive "SELECT" (e.g., regex like
^\s*(?i)select\b). For invalid queries, log an error or throw an exception and
skip executing it instead of calling stmt.executeQuery; keep the validation
logic adjacent to where rawQuery/query are prepared so no non-SELECT statement
can reach stmt.executeQuery.

Comment on lines +62 to +74

logger.info("Executing Query [" + queryCounter + "]: " + query);

ResultSet rs = stmt.executeQuery(query);
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();

/* ---------- UI OUTPUT ---------- */
successMessage.append("<br><b>Query ")
.append(queryCounter)
.append(" Result: ")
.append(query)
.append("</b><br>");
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Potential PII/sensitive data exposure in logs.

The full query text is logged at line 64 and included in the success message at line 73. If queries contain sensitive data (e.g., WHERE email='[email protected]'), this could violate privacy policies (GDPR, CCPA) and leak PII into logs.

Consider:

  • Redacting query parameters in logs
  • Logging only query structure/type instead of full text
  • Documenting that users should not include sensitive data in queries
🤖 Prompt for AI Agents
In
@oracledb_queries/src/main/java/com/testsigma/addons/android/OracleMultipleQueriesSelect.java
around lines 62 - 74, The code currently logs and displays the full SQL text
(variable query) via logger.info(...) and successMessage.append(...), which may
expose PII; update OracleMultipleQueriesSelect to stop emitting raw query
strings: replace the direct uses of query in logger.info and successMessage with
a sanitized representation (e.g., a helper method sanitizeQuery(String query)
that strips or masks literal values and parameters and/or returns only the query
type and table names), or log only the queryCounter and query type; ensure
successMessage shows the sanitizedQuery or a generic message like "Query N:
SELECT ... (parameters redacted)"; update references to logger.info("Executing
Query [" + queryCounter + "]: " + query) and successMessage.append(...
.append(query) ...) to use the sanitized value and add a short comment in docs
or method javadoc warning users not to include sensitive data in queries.

Comment on lines +64 to +119

ResultSet rs = stmt.executeQuery(query);
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();

/* ---------- UI OUTPUT ---------- */
successMessage.append("<br><b>Query ")
.append(queryCounter)
.append(" Result: ")
.append(query)
.append("</b><br>");

/* ---------- LOG OUTPUT ---------- */
StringBuilder log = new StringBuilder();
log.append("\nQuery ").append(queryCounter)
.append(" Result: ").append(query).append("\n");

log.append("--------------------------------------------------------\n");

// Headers
StringBuilder headerRow = new StringBuilder();
for (int i = 1; i <= columnCount; i++) {
headerRow.append(rsmd.getColumnName(i));
if (i < columnCount) headerRow.append(" | ");
}
log.append(headerRow).append("\n");
log.append("--------------------------------------------------------\n");

// UI headers
for (int i = 1; i <= columnCount; i++) {
successMessage.append(rsmd.getColumnName(i)).append(" | ");
}
successMessage.append("<br>");

// Rows
while (rs.next()) {
StringBuilder row = new StringBuilder();
for (int j = 1; j <= columnCount; j++) {
String value = rs.getString(j);
String safe = value == null ? "" : value;

row.append(safe);
if (j < columnCount) row.append(" | ");

successMessage.append(safe).append(" | ");
runtimeValue.append(safe).append(",");
}
log.append(row).append("\n");
successMessage.append("<br>");
}

logger.info(log.toString());
logger.info("Query [" + queryCounter + "] executed successfully");

queryCounter++;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Critical resource leak: ResultSet never closed.

ResultSet objects created at line 65 are never closed, causing resource leaks. Additionally, reusing the same Statement for multiple queries without closing the previous ResultSet can lead to issues.

🔎 Recommended fix: Close ResultSet after each query
 for (String rawQuery : queries) {

     String query = rawQuery.trim();
     if (query.isEmpty()) continue;

     logger.info("Executing Query [" + queryCounter + "]: " + query);

-    ResultSet rs = stmt.executeQuery(query);
-    ResultSetMetaData rsmd = rs.getMetaData();
-    int columnCount = rsmd.getColumnCount();
+    ResultSet rs = null;
+    try {
+        rs = stmt.executeQuery(query);
+        ResultSetMetaData rsmd = rs.getMetaData();
+        int columnCount = rsmd.getColumnCount();

-    /* ---------- UI OUTPUT ---------- */
-    successMessage.append("<br><b>Query ")
-            .append(queryCounter)
-            .append(" Result: ")
-            .append(query)
-            .append("</b><br>");
+        /* ---------- UI OUTPUT ---------- */
+        successMessage.append("<br><b>Query ")
+                .append(queryCounter)
+                .append(" Result: ")
+                .append(query)
+                .append("</b><br>");

-    /* ---------- LOG OUTPUT ---------- */
-    StringBuilder log = new StringBuilder();
-    log.append("\nQuery ").append(queryCounter)
-            .append(" Result: ").append(query).append("\n");
+        /* ---------- LOG OUTPUT ---------- */
+        StringBuilder log = new StringBuilder();
+        log.append("\nQuery ").append(queryCounter)
+                .append(" Result: ").append(query).append("\n");

-    log.append("--------------------------------------------------------\n");
+        log.append("--------------------------------------------------------\n");

-    // Headers
-    StringBuilder headerRow = new StringBuilder();
-    for (int i = 1; i <= columnCount; i++) {
-        headerRow.append(rsmd.getColumnName(i));
-        if (i < columnCount) headerRow.append(" | ");
-    }
-    log.append(headerRow).append("\n");
-    log.append("--------------------------------------------------------\n");
+        // Headers
+        StringBuilder headerRow = new StringBuilder();
+        for (int i = 1; i <= columnCount; i++) {
+            headerRow.append(rsmd.getColumnName(i));
+            if (i < columnCount) headerRow.append(" | ");
+        }
+        log.append(headerRow).append("\n");
+        log.append("--------------------------------------------------------\n");

-    // UI headers
-    for (int i = 1; i <= columnCount; i++) {
-        successMessage.append(rsmd.getColumnName(i)).append(" | ");
-    }
-    successMessage.append("<br>");
+        // UI headers
+        for (int i = 1; i <= columnCount; i++) {
+            successMessage.append(rsmd.getColumnName(i)).append(" | ");
+        }
+        successMessage.append("<br>");

-    // Rows
-    while (rs.next()) {
-        StringBuilder row = new StringBuilder();
-        for (int j = 1; j <= columnCount; j++) {
-            String value = rs.getString(j);
-            String safe = value == null ? "" : value;
-
-            row.append(safe);
-            if (j < columnCount) row.append(" | ");
-
-            successMessage.append(safe).append(" | ");
-            runtimeValue.append(safe).append(",");
+        // Rows
+        while (rs.next()) {
+            StringBuilder row = new StringBuilder();
+            for (int j = 1; j <= columnCount; j++) {
+                String value = rs.getString(j);
+                String safe = value == null ? "" : value;
+
+                row.append(safe);
+                if (j < columnCount) row.append(" | ");
+
+                successMessage.append(safe).append(" | ");
+                runtimeValue.append(safe).append(",");
+            }
+            log.append(row).append("\n");
+            successMessage.append("<br>");
         }
-        log.append(row).append("\n");
-        successMessage.append("<br>");
-    }

-    logger.info(log.toString());
-    logger.info("Query [" + queryCounter + "] executed successfully");
+        logger.info(log.toString());
+        logger.info("Query [" + queryCounter + "] executed successfully");
+    } finally {
+        try { if (rs != null) rs.close(); } catch (Exception ignored) {}
+    }

     queryCounter++;
 }
🤖 Prompt for AI Agents
In
@oracledb_queries/src/main/java/com/testsigma/addons/android/OracleMultipleQueriesSelect.java
around lines 64 - 119, The ResultSet created by stmt.executeQuery(query) in
OracleMultipleQueriesSelect is never closed, leaking DB resources and risking
issues when reusing the same Statement; fix by ensuring each ResultSet (variable
rs) is closed after processing—preferably wrap the executeQuery/iteration in a
try-with-resources or explicitly call rs.close() in a finally block right after
logging and before incrementing queryCounter, so every loop iteration closes its
ResultSet before the next executeQuery on stmt.

import com.testsigma.sdk.ApplicationType;
import com.testsigma.sdk.IOSAction;
import com.testsigma.sdk.Result;
import com.testsigma.sdk.WebAction;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Remove unused imports.

Two imports are unused:

  • Line 7: WebAction (class extends IOSAction)
  • Line 14: org.openqa.selenium.devtools.v135.io.IO (never referenced)
🔎 Proposed fix
-import com.testsigma.sdk.WebAction;
 import com.testsigma.sdk.annotation.Action;
 import com.testsigma.sdk.annotation.RunTimeData;
 import com.testsigma.sdk.annotation.TestData;
 import lombok.Data;
 import org.apache.commons.lang3.exception.ExceptionUtils;
 import org.openqa.selenium.NoSuchElementException;
-import org.openqa.selenium.devtools.v135.io.IO;

 import java.sql.*;

Also applies to: 14-14

🤖 Prompt for AI Agents
In
@oracledb_queries/src/main/java/com/testsigma/addons/ios/OracleMultipleQueriesSelect.java
at line 7, Remove the unused imports in OracleMultipleQueriesSelect.java: delete
the import of com.testsigma.sdk.WebAction and the import of
org.openqa.selenium.devtools.v135.io.IO since the class extends IOSAction and
neither symbol is referenced; ensure only required imports remain and run a
quick compile or IDE optimize imports to confirm no other unused imports exist.

@akhil-testsigma akhil-testsigma merged commit 4c3f495 into dev Jan 11, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants