chore: Oracle: add JUnit TCs (#22788)
## Description - Add JUnit TCs - Minor improvement to reading of data types: `timestamp`, `raw`, `blob` Fixes #20535
This commit is contained in:
parent
aa7ef11aa1
commit
09fd519e2c
|
|
@ -1,11 +1,14 @@
|
||||||
package com.appsmith.external.helpers;
|
package com.appsmith.external.helpers;
|
||||||
|
|
||||||
import com.appsmith.external.constants.ConditionalOperator;
|
import com.appsmith.external.constants.ConditionalOperator;
|
||||||
|
import com.appsmith.external.datatypes.ClientDataType;
|
||||||
|
import com.appsmith.external.dtos.ExecuteActionDTO;
|
||||||
import com.appsmith.external.exceptions.pluginExceptions.AppsmithPluginError;
|
import com.appsmith.external.exceptions.pluginExceptions.AppsmithPluginError;
|
||||||
import com.appsmith.external.exceptions.pluginExceptions.AppsmithPluginException;
|
import com.appsmith.external.exceptions.pluginExceptions.AppsmithPluginException;
|
||||||
import com.appsmith.external.models.Condition;
|
import com.appsmith.external.models.Condition;
|
||||||
import com.appsmith.external.models.DatasourceConfiguration;
|
import com.appsmith.external.models.DatasourceConfiguration;
|
||||||
import com.appsmith.external.models.Endpoint;
|
import com.appsmith.external.models.Endpoint;
|
||||||
|
import com.appsmith.external.models.Param;
|
||||||
import com.appsmith.external.models.Property;
|
import com.appsmith.external.models.Property;
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.core.type.TypeReference;
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
|
|
@ -25,6 +28,7 @@ import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
@ -236,7 +240,7 @@ public class PluginUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setDataValueSafelyInFormData(Map<String, Object> formData, String field, Object value) {
|
public static Map setDataValueSafelyInFormData(Map<String, Object> formData, String field, Object value) {
|
||||||
|
|
||||||
// In case the formData has not been initialized before the fxn call, assign a new HashMap to the variable
|
// In case the formData has not been initialized before the fxn call, assign a new HashMap to the variable
|
||||||
if (formData == null) {
|
if (formData == null) {
|
||||||
|
|
@ -269,9 +273,11 @@ public class PluginUtils {
|
||||||
formData.put(field, valueMap);
|
formData.put(field, valueMap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return formData;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setValueSafelyInFormData(Map<String, Object> formData, String field, Object value) {
|
public static Map setValueSafelyInFormData(Map<String, Object> formData, String field, Object value) {
|
||||||
|
|
||||||
// In case the formData has not been initialized before the fxn call, assign a new HashMap to the variable
|
// In case the formData has not been initialized before the fxn call, assign a new HashMap to the variable
|
||||||
if (formData == null) {
|
if (formData == null) {
|
||||||
|
|
@ -297,6 +303,8 @@ public class PluginUtils {
|
||||||
// This is a top level field. Set the value
|
// This is a top level field. Set the value
|
||||||
formData.put(field, value);
|
formData.put(field, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return formData;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean endpointContainsLocalhost(Endpoint endpoint) {
|
public static boolean endpointContainsLocalhost(Endpoint endpoint) {
|
||||||
|
|
@ -464,4 +472,22 @@ public class PluginUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ExecuteActionDTO getExecuteDTOForTestWithBindingAndValueAndDataType(LinkedHashMap<String, List> bindingValueDataTypeMap) {
|
||||||
|
List<Param> params = new ArrayList<>();
|
||||||
|
bindingValueDataTypeMap.keySet().stream()
|
||||||
|
.forEach(bindingName -> {
|
||||||
|
String bindingValue = (String) (bindingValueDataTypeMap.get(bindingName)).get(0);
|
||||||
|
ClientDataType clientDataType = (ClientDataType) (bindingValueDataTypeMap.get(bindingName)).get(1);
|
||||||
|
Param param = new Param();
|
||||||
|
param.setKey(bindingName);
|
||||||
|
param.setValue(bindingValue);
|
||||||
|
param.setClientDataType(clientDataType);
|
||||||
|
params.add(param);
|
||||||
|
});
|
||||||
|
|
||||||
|
ExecuteActionDTO executeActionDTO = new ExecuteActionDTO();
|
||||||
|
executeActionDTO.setParams(params);
|
||||||
|
return executeActionDTO;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,25 +34,20 @@
|
||||||
</exclusion>
|
</exclusion>
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
<!-- Test Dependencies -->
|
|
||||||
<!-- https://mvnrepository.com/artifact/com.oracle.database.jdbc/ojdbc8 -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.oracle.database.jdbc</groupId>
|
<groupId>com.oracle.database.jdbc</groupId>
|
||||||
<artifactId>ojdbc8</artifactId>
|
<artifactId>ojdbc8</artifactId>
|
||||||
<version>21.9.0.0</version>
|
<version>21.9.0.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.testcontainers</groupId>
|
<!-- Test Dependencies -->
|
||||||
<artifactId>oracle-xe</artifactId>
|
<!-- https://mvnrepository.com/artifact/com.oracle.database.jdbc/ojdbc8 -->
|
||||||
<version>1.17.2</version>
|
<dependency>
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.testcontainers</groupId>
|
<groupId>org.testcontainers</groupId>
|
||||||
<artifactId>jdbc-test</artifactId>
|
<artifactId>oracle-xe</artifactId>
|
||||||
<version>1.11.4</version>
|
<version>1.18.0</version>
|
||||||
</dependency>
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
|
||||||
|
|
@ -115,13 +115,18 @@ public class OraclePlugin extends BasePlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Mono<ActionExecutionResult> execute(HikariDataSource connection, DatasourceConfiguration datasourceConfiguration, ActionConfiguration actionConfiguration) {
|
public Mono<ActionExecutionResult> execute(HikariDataSource connection,
|
||||||
|
DatasourceConfiguration datasourceConfiguration,
|
||||||
|
ActionConfiguration actionConfiguration) {
|
||||||
return Mono.error(
|
return Mono.error(
|
||||||
new AppsmithPluginException(OraclePluginError.QUERY_EXECUTION_FAILED, "Unsupported Operation"));
|
new AppsmithPluginException(OraclePluginError.QUERY_EXECUTION_FAILED, "Unsupported Operation"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Mono<ActionExecutionResult> executeParameterized(HikariDataSource connection, ExecuteActionDTO executeActionDTO, DatasourceConfiguration datasourceConfiguration, ActionConfiguration actionConfiguration) {
|
public Mono<ActionExecutionResult> executeParameterized(HikariDataSource connectionPool,
|
||||||
|
ExecuteActionDTO executeActionDTO,
|
||||||
|
DatasourceConfiguration datasourceConfiguration,
|
||||||
|
ActionConfiguration actionConfiguration) {
|
||||||
final Map<String, Object> formData = actionConfiguration.getFormData();
|
final Map<String, Object> formData = actionConfiguration.getFormData();
|
||||||
String query = getDataValueSafelyFromFormData(formData, BODY, STRING_TYPE, null);
|
String query = getDataValueSafelyFromFormData(formData, BODY, STRING_TYPE, null);
|
||||||
// Check for query parameter before performing the probably expensive fetch connection from the pool op.
|
// Check for query parameter before performing the probably expensive fetch connection from the pool op.
|
||||||
|
|
@ -144,7 +149,7 @@ public class OraclePlugin extends BasePlugin {
|
||||||
// In case of non-prepared statement, simply do binding-replacement and execute
|
// In case of non-prepared statement, simply do binding-replacement and execute
|
||||||
if (FALSE.equals(isPreparedStatement)) {
|
if (FALSE.equals(isPreparedStatement)) {
|
||||||
prepareConfigurationsForExecution(executeActionDTO, actionConfiguration, datasourceConfiguration);
|
prepareConfigurationsForExecution(executeActionDTO, actionConfiguration, datasourceConfiguration);
|
||||||
return executeCommon(connection, datasourceConfiguration, actionConfiguration, FALSE, null, null);
|
return executeCommon(connectionPool, datasourceConfiguration, actionConfiguration, FALSE, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// First extract all the bindings in order
|
// First extract all the bindings in order
|
||||||
|
|
@ -162,7 +167,7 @@ public class OraclePlugin extends BasePlugin {
|
||||||
updatedQuery = removeSemicolonFromQuery(updatedQuery);
|
updatedQuery = removeSemicolonFromQuery(updatedQuery);
|
||||||
}
|
}
|
||||||
setDataValueSafelyInFormData(formData, BODY, updatedQuery);
|
setDataValueSafelyInFormData(formData, BODY, updatedQuery);
|
||||||
return executeCommon(connection, datasourceConfiguration, actionConfiguration, TRUE,
|
return executeCommon(connectionPool, datasourceConfiguration, actionConfiguration, TRUE,
|
||||||
mustacheKeysInOrder, executeActionDTO);
|
mustacheKeysInOrder, executeActionDTO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -288,8 +293,9 @@ public class OraclePlugin extends BasePlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Mono<DatasourceStructure> getStructure(HikariDataSource connection, DatasourceConfiguration datasourceConfiguration) {
|
public Mono<DatasourceStructure> getStructure(HikariDataSource connectionPool,
|
||||||
return OracleDatasourceUtils.getStructure(connection, datasourceConfiguration);
|
DatasourceConfiguration datasourceConfiguration) {
|
||||||
|
return OracleDatasourceUtils.getStructure(connectionPool, datasourceConfiguration);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Set<String> populateHintMessages(List<String> columnNames) {
|
private Set<String> populateHintMessages(List<String> columnNames) {
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,8 @@ public class OracleErrorMessages {
|
||||||
|
|
||||||
public static final String INVALID_SSL_OPTION_ERROR_MSG = "The Appsmith server has found an unexpected SSL option: %s.";
|
public static final String INVALID_SSL_OPTION_ERROR_MSG = "The Appsmith server has found an unexpected SSL option: %s.";
|
||||||
|
|
||||||
public static final String CONNECTION_POOL_CREATION_FAILED_ERROR_MSG = "An exception occurred while creating connection pool. One or more arguments in the datasource configuration may be invalid.";
|
public static final String CONNECTION_POOL_CREATION_FAILED_ERROR_MSG = "An exception occurred while creating " +
|
||||||
|
"connection pool. One or more arguments in the datasource configuration may be invalid.";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
************************************************************************************************************************************************
|
************************************************************************************************************************************************
|
||||||
|
|
|
||||||
|
|
@ -307,10 +307,10 @@ public class OracleDatasourceUtils {
|
||||||
getSampleColumnNamesCSVString(columnNameToSampleColumnDataMap),
|
getSampleColumnNamesCSVString(columnNameToSampleColumnDataMap),
|
||||||
getSampleColumnDataCSVString(columnNameToSampleColumnDataMap));
|
getSampleColumnDataCSVString(columnNameToSampleColumnDataMap));
|
||||||
String updateQueryTemplate = MessageFormat.format("UPDATE {0} SET {1} WHERE " +
|
String updateQueryTemplate = MessageFormat.format("UPDATE {0} SET {1} WHERE " +
|
||||||
"1=0; -- Specify a valid condition here. Removing the condition may " +
|
"1=0 -- Specify a valid condition here. Removing the condition may " +
|
||||||
"update every row in the table!", table.getName(),
|
"update every row in the table!", table.getName(),
|
||||||
getSampleOneColumnUpdateString(columnNameToSampleColumnDataMap));
|
getSampleOneColumnUpdateString(columnNameToSampleColumnDataMap));
|
||||||
String deleteQueryTemplate = MessageFormat.format("DELETE FROM {0} WHERE 1=0;" +
|
String deleteQueryTemplate = MessageFormat.format("DELETE FROM {0} WHERE 1=0" +
|
||||||
" -- Specify a valid condition here. Removing the condition may " +
|
" -- Specify a valid condition here. Removing the condition may " +
|
||||||
"delete everything in the table!", table.getName());
|
"delete everything in the table!", table.getName());
|
||||||
|
|
||||||
|
|
@ -460,7 +460,7 @@ public class OracleDatasourceUtils {
|
||||||
int activeConnections = poolProxy.getActiveConnections();
|
int activeConnections = poolProxy.getActiveConnections();
|
||||||
int totalConnections = poolProxy.getTotalConnections();
|
int totalConnections = poolProxy.getTotalConnections();
|
||||||
int threadsAwaitingConnection = poolProxy.getThreadsAwaitingConnection();
|
int threadsAwaitingConnection = poolProxy.getThreadsAwaitingConnection();
|
||||||
log.debug("{0}: Hikari Pool stats : active - {1} , idle - {2}, awaiting - {3} , total - {4}", logPrefix,
|
log.debug(MessageFormat.format("{0}: Hikari Pool stats : active - {1} , idle - {2}, awaiting - {3} , total - {4}",
|
||||||
activeConnections, idleConnections, threadsAwaitingConnection, totalConnections);
|
logPrefix, activeConnections, idleConnections, threadsAwaitingConnection, totalConnections));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,8 @@ package com.external.plugins.utils;
|
||||||
|
|
||||||
import com.appsmith.external.plugins.SmartSubstitutionInterface;
|
import com.appsmith.external.plugins.SmartSubstitutionInterface;
|
||||||
import oracle.jdbc.OracleArray;
|
import oracle.jdbc.OracleArray;
|
||||||
|
import oracle.jdbc.OracleBlob;
|
||||||
import oracle.sql.CLOB;
|
import oracle.sql.CLOB;
|
||||||
import oracle.sql.Datum;
|
|
||||||
import org.apache.commons.lang.ObjectUtils;
|
import org.apache.commons.lang.ObjectUtils;
|
||||||
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
|
|
@ -13,9 +13,9 @@ import java.sql.ResultSetMetaData;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Statement;
|
import java.sql.Statement;
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.time.OffsetDateTime;
|
import java.time.OffsetDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.Base64;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
@ -32,6 +32,8 @@ public class OracleExecuteUtils implements SmartSubstitutionInterface {
|
||||||
public static final String TIMESTAMPLTZ_TYPE_NAME = "TIMESTAMP WITH LOCAL TIME ZONE";
|
public static final String TIMESTAMPLTZ_TYPE_NAME = "TIMESTAMP WITH LOCAL TIME ZONE";
|
||||||
public static final String CLOB_TYPE_NAME = "CLOB";
|
public static final String CLOB_TYPE_NAME = "CLOB";
|
||||||
public static final String NCLOB_TYPE_NAME = "NCLOB";
|
public static final String NCLOB_TYPE_NAME = "NCLOB";
|
||||||
|
public static final String RAW_TYPE_NAME = "RAW";
|
||||||
|
public static final String BLOB_TYPE_NAME = "BLOB";
|
||||||
public static final String AFFECTED_ROWS_KEY = "affectedRows";
|
public static final String AFFECTED_ROWS_KEY = "affectedRows";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -136,23 +138,36 @@ public class OracleExecuteUtils implements SmartSubstitutionInterface {
|
||||||
} else if (DATE_COLUMN_TYPE_NAME.equalsIgnoreCase(typeName)) {
|
} else if (DATE_COLUMN_TYPE_NAME.equalsIgnoreCase(typeName)) {
|
||||||
value = DateTimeFormatter.ISO_DATE.format(resultSet.getDate(i).toLocalDate());
|
value = DateTimeFormatter.ISO_DATE.format(resultSet.getDate(i).toLocalDate());
|
||||||
|
|
||||||
} else if (TIMESTAMP_TYPE_NAME.equalsIgnoreCase(typeName)) {
|
} else if (TIMESTAMP_TYPE_NAME.equalsIgnoreCase(typeName) || TIMESTAMPTZ_TYPE_NAME.equalsIgnoreCase(typeName) || TIMESTAMPLTZ_TYPE_NAME.equalsIgnoreCase(typeName)) {
|
||||||
value = DateTimeFormatter.ISO_DATE_TIME.format(
|
|
||||||
LocalDateTime.of(
|
|
||||||
resultSet.getDate(i).toLocalDate(),
|
|
||||||
resultSet.getTime(i).toLocalTime()
|
|
||||||
)
|
|
||||||
) + "Z";
|
|
||||||
|
|
||||||
} else if (TIMESTAMPTZ_TYPE_NAME.equalsIgnoreCase(typeName) || TIMESTAMPLTZ_TYPE_NAME.equalsIgnoreCase(typeName)) {
|
|
||||||
value = DateTimeFormatter.ISO_DATE_TIME.format(
|
value = DateTimeFormatter.ISO_DATE_TIME.format(
|
||||||
resultSet.getObject(i, OffsetDateTime.class)
|
resultSet.getObject(i, OffsetDateTime.class)
|
||||||
);
|
);
|
||||||
|
|
||||||
} else if (CLOB_TYPE_NAME.equalsIgnoreCase(typeName) || NCLOB_TYPE_NAME.equals(typeName)) {
|
} else if (CLOB_TYPE_NAME.equalsIgnoreCase(typeName) || NCLOB_TYPE_NAME.equals(typeName)) {
|
||||||
|
/**
|
||||||
|
* clob, nclob are textual data.
|
||||||
|
* Ref: https://docs.oracle.com/javadb/10.10.1.2/ref/rrefclob.html
|
||||||
|
*/
|
||||||
value = String.valueOf(((CLOB)resultSet.getObject(i)).getTarget().getPrefetchedData());
|
value = String.valueOf(((CLOB)resultSet.getObject(i)).getTarget().getPrefetchedData());
|
||||||
} else if (resultSet.getObject(i) instanceof OracleArray) {
|
} else if (resultSet.getObject(i) instanceof OracleArray) {
|
||||||
value = ((OracleArray)resultSet.getObject(i)).getArray();
|
value = ((OracleArray)resultSet.getObject(i)).getArray();
|
||||||
|
} else if (RAW_TYPE_NAME.equalsIgnoreCase(typeName)) {
|
||||||
|
/**
|
||||||
|
* Raw / Blob data cannot be interpreted as anything but a byte array. Hence, send it back as a
|
||||||
|
* base64 encoded string. The correct way to read the data for these types is for the user to
|
||||||
|
* cast them to a type before reading them, example:
|
||||||
|
* select utl_raw.cast_to_varchar2(c_raw) as c_raw, utl_raw.cast_to_varchar2(c_blob) as c_blob from TYPESTEST4
|
||||||
|
*/
|
||||||
|
value = Base64.getEncoder().encodeToString((byte[]) resultSet.getObject(i));
|
||||||
|
}
|
||||||
|
else if (BLOB_TYPE_NAME.equalsIgnoreCase(typeName)) {
|
||||||
|
/**
|
||||||
|
* Raw / Blob data cannot be interpreted as anything but a byte array. Hence, send it back as a
|
||||||
|
* base64 encoded string. The correct way to read the data for these types is for the user to
|
||||||
|
* cast them to a type before reading them, example:
|
||||||
|
* select utl_raw.cast_to_varchar2(c_raw) as c_raw, utl_raw.cast_to_varchar2(c_blob) as c_blob from TYPESTEST4
|
||||||
|
*/
|
||||||
|
value = ((OracleBlob)resultSet.getObject(i)).getBytes(1L,
|
||||||
|
(int) ((OracleBlob)resultSet.getObject(i)).length());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
value = resultSet.getObject(i).toString();
|
value = resultSet.getObject(i).toString();
|
||||||
|
|
|
||||||
328
app/server/appsmith-plugins/oraclePlugin/src/test/java/com/external/plugins/OracleExecutionTest.java
vendored
Normal file
328
app/server/appsmith-plugins/oraclePlugin/src/test/java/com/external/plugins/OracleExecutionTest.java
vendored
Normal file
|
|
@ -0,0 +1,328 @@
|
||||||
|
package com.external.plugins;
|
||||||
|
|
||||||
|
import com.appsmith.external.datatypes.ClientDataType;
|
||||||
|
import com.appsmith.external.dtos.ExecuteActionDTO;
|
||||||
|
import com.appsmith.external.models.ActionConfiguration;
|
||||||
|
import com.appsmith.external.models.ActionExecutionResult;
|
||||||
|
import com.zaxxer.hikari.HikariDataSource;
|
||||||
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.testcontainers.containers.OracleContainer;
|
||||||
|
import org.testcontainers.junit.jupiter.Container;
|
||||||
|
import org.testcontainers.junit.jupiter.Testcontainers;
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
import reactor.test.StepVerifier;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.text.MessageFormat;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static com.appsmith.external.helpers.PluginUtils.getExecuteDTOForTestWithBindingAndValueAndDataType;
|
||||||
|
import static com.appsmith.external.helpers.PluginUtils.setDataValueSafelyInFormData;
|
||||||
|
import static com.external.plugins.OracleTestDBContainerManager.getDefaultDatasourceConfig;
|
||||||
|
import static com.external.plugins.OracleTestDBContainerManager.oraclePluginExecutor;
|
||||||
|
import static com.external.plugins.OracleTestDBContainerManager.runSQLQueryOnOracleTestDB;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
@Testcontainers
|
||||||
|
public class OracleExecutionTest {
|
||||||
|
public static final String SQL_QUERY_CREATE_TABLE_FORMAT =
|
||||||
|
"create table {0} (\n" +
|
||||||
|
"c_varchar2 varchar2(20),\n" +
|
||||||
|
"c_nvarchar2 nvarchar2(20),\n" +
|
||||||
|
"c_number number,\n" +
|
||||||
|
"c_float float,\n" +
|
||||||
|
"c_date date,\n" +
|
||||||
|
"c_binary_float binary_float,\n" +
|
||||||
|
"c_binary_double binary_double,\n" +
|
||||||
|
"c_timestamp timestamp,\n" +
|
||||||
|
"c_timestamp_tz timestamp with time zone,\n" +
|
||||||
|
"c_timestamp_ltz timestamp with local time zone,\n" +
|
||||||
|
"c_interval_year interval year to month,\n" +
|
||||||
|
"c_interval_day interval day to second,\n" +
|
||||||
|
"c_rowid rowid,\n" +
|
||||||
|
"c_urowid urowid,\n" +
|
||||||
|
"c_char char(20),\n" +
|
||||||
|
"c_nchar nchar(20),\n" +
|
||||||
|
"c_clob clob,\n" +
|
||||||
|
"c_nclob nclob\n" +
|
||||||
|
")\n";
|
||||||
|
private static final String SQL_QUERY_TO_INSERT_ONE_ROW_FORMAT =
|
||||||
|
"insert into {0} values (\n" +
|
||||||
|
"''varchar2'',\n" +
|
||||||
|
"''nvarchar2'',\n" +
|
||||||
|
"{1},\n" +
|
||||||
|
"11.22,\n" +
|
||||||
|
"''03-OCT-02'',\n" +
|
||||||
|
"11.22,\n" +
|
||||||
|
"11.22,\n" +
|
||||||
|
"TIMESTAMP''1997-01-01 09:26:50.124'',\n" +
|
||||||
|
"TIMESTAMP''1997-01-01 09:26:56.66 +02:00'',\n" +
|
||||||
|
"TIMESTAMP''1999-04-05 8:00:00 US/Pacific'',\n" +
|
||||||
|
"INTERVAL ''1'' YEAR(3),\n" +
|
||||||
|
"INTERVAL ''1'' HOUR,\n" +
|
||||||
|
"''000001F8.0001.0006'',\n" +
|
||||||
|
"''000001F8.0001.0006'',\n" +
|
||||||
|
"''char'',\n" +
|
||||||
|
"''nchar'',\n" +
|
||||||
|
"''clob'',\n" +
|
||||||
|
"''nclob''\n" +
|
||||||
|
")";
|
||||||
|
|
||||||
|
private static final String SQL_QUERY_TO_INSERT_ONE_ROW_WITH_BINDING_FORMAT =
|
||||||
|
"insert into {0} values (\n" +
|
||||||
|
"'{{'binding1'}}',\n" +
|
||||||
|
"'{{'binding2'}}',\n" +
|
||||||
|
"'{{'binding3'}}',\n" +
|
||||||
|
"'{{'binding4'}}',\n" +
|
||||||
|
"'{{'binding5'}}',\n" +
|
||||||
|
"'{{'binding6'}}',\n" +
|
||||||
|
"'{{'binding7'}}',\n" +
|
||||||
|
"TO_TIMESTAMP('{{'binding8'}}', ''YYYY-MM-DD HH24:MI:SS.FF''),\n" +
|
||||||
|
"TO_TIMESTAMP('{{'binding9'}}', ''YYYY-MM-DD HH24:MI:SS.FF''),\n" +
|
||||||
|
"TO_TIMESTAMP('{{'binding10'}}', ''YYYY-MM-DD HH24:MI:SS.FF''),\n" +
|
||||||
|
"NUMTOYMINTERVAL('{{'binding11'}}', ''YEAR''),\n" +
|
||||||
|
"NUMTODSINTERVAL('{{'binding12'}}', ''HOUR''),\n" +
|
||||||
|
"'{{'binding13'}}',\n" +
|
||||||
|
"'{{'binding14'}}',\n" +
|
||||||
|
"'{{'binding15'}}',\n" +
|
||||||
|
"'{{'binding16'}}',\n" +
|
||||||
|
"'{{'binding17'}}',\n" +
|
||||||
|
"'{{'binding18'}}'\n" +
|
||||||
|
")";
|
||||||
|
|
||||||
|
public static final String SELECT_TEST_WITHOUT_PREPARED_STMT_TABLE_NAME = "testSelectWithPreparedStatementWithoutAnyBinding";
|
||||||
|
public static final String SELECT_TEST_WITH_PREPARED_STMT_TABLE_NAME = "testSelectWithPreparedStatementWithBinding";
|
||||||
|
public static final String INSERT_TEST_WITHOUT_PREPARED_STMT_TABLE_NAME = "testInsertWithPreparedStatementWithoutAnyBinding";
|
||||||
|
public static final String INSERT_TEST_WITH_PREPARED_STMT_TABLE_NAME = "testInsertWithPreparedStatementWithBinding";
|
||||||
|
public static final String UPDATE_TEST_WITHOUT_PREPARED_STMT_TABLE_NAME = "testUpdateWithPreparedStatementWithoutAnyBinding";
|
||||||
|
public static final String UPDATE_TEST_WITH_PREPARED_STMT_TABLE_NAME = "testUpdateWithPreparedStatementWithBinding";
|
||||||
|
public static final String DELETE_TEST_WITHOUT_PREPARED_STMT_TABLE_NAME = "testDeleteWithPreparedStatementWithoutAnyBinding";
|
||||||
|
public static final String DELETE_TEST_WITH_PREPARED_STMT_TABLE_NAME = "testDeleteWithPreparedStatementWithBinding";
|
||||||
|
|
||||||
|
@SuppressWarnings("rawtypes") // The type parameter for the container type is just itself and is pseudo-optional.
|
||||||
|
@Container
|
||||||
|
private static final OracleContainer oracleDB = OracleTestDBContainerManager.getOracleDBForTest();
|
||||||
|
|
||||||
|
private static HikariDataSource sharedConnectionPool = null;
|
||||||
|
|
||||||
|
@BeforeAll
|
||||||
|
public static void setup() throws SQLException {
|
||||||
|
sharedConnectionPool = oraclePluginExecutor.datasourceCreate(getDefaultDatasourceConfig(oracleDB)).block();
|
||||||
|
createTablesForTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void createTablesForTest() throws SQLException {
|
||||||
|
createTableWithName(SELECT_TEST_WITHOUT_PREPARED_STMT_TABLE_NAME);
|
||||||
|
createTableWithName(SELECT_TEST_WITH_PREPARED_STMT_TABLE_NAME);
|
||||||
|
createTableWithName(INSERT_TEST_WITHOUT_PREPARED_STMT_TABLE_NAME);
|
||||||
|
createTableWithName(INSERT_TEST_WITH_PREPARED_STMT_TABLE_NAME);
|
||||||
|
createTableWithName(UPDATE_TEST_WITHOUT_PREPARED_STMT_TABLE_NAME);
|
||||||
|
createTableWithName(UPDATE_TEST_WITH_PREPARED_STMT_TABLE_NAME);
|
||||||
|
createTableWithName(DELETE_TEST_WITHOUT_PREPARED_STMT_TABLE_NAME);
|
||||||
|
createTableWithName(DELETE_TEST_WITH_PREPARED_STMT_TABLE_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void createTableWithName(String tableName) throws SQLException {
|
||||||
|
String sqlQueryToCreateTable = MessageFormat.format(SQL_QUERY_CREATE_TABLE_FORMAT, tableName);
|
||||||
|
runSQLQueryOnOracleTestDB(sqlQueryToCreateTable, sharedConnectionPool);
|
||||||
|
|
||||||
|
String sqlQueryToInsertRow1 = MessageFormat.format(SQL_QUERY_TO_INSERT_ONE_ROW_FORMAT, tableName, 1);
|
||||||
|
runSQLQueryOnOracleTestDB(sqlQueryToInsertRow1, sharedConnectionPool);
|
||||||
|
|
||||||
|
String sqlQueryToInsertRow2 = MessageFormat.format(SQL_QUERY_TO_INSERT_ONE_ROW_FORMAT, tableName, 2);
|
||||||
|
runSQLQueryOnOracleTestDB(sqlQueryToInsertRow2, sharedConnectionPool);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSelectQueryWithPreparedStatementWithoutAnyBinding() {
|
||||||
|
String sqlSelectQuery = MessageFormat.format("SELECT c_number FROM {0} ORDER BY c_number",
|
||||||
|
SELECT_TEST_WITHOUT_PREPARED_STMT_TABLE_NAME);
|
||||||
|
Map formData = setDataValueSafelyInFormData(null, "body", sqlSelectQuery);
|
||||||
|
ActionConfiguration actionConfig = new ActionConfiguration();
|
||||||
|
actionConfig.setFormData(formData);
|
||||||
|
Mono<ActionExecutionResult> executionResultMono = oraclePluginExecutor.executeParameterized(sharedConnectionPool, new ExecuteActionDTO(),
|
||||||
|
getDefaultDatasourceConfig(oracleDB), actionConfig);
|
||||||
|
String expectedResultString = "[{\"C_NUMBER\":\"1\"},{\"C_NUMBER\":\"2\"}]";
|
||||||
|
verifyColumnValue(executionResultMono, expectedResultString);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testQueryWorksWithSemicolonInTheEnd() {
|
||||||
|
String sqlSelectQuery = MessageFormat.format("SELECT c_number FROM {0} ORDER BY c_number;",
|
||||||
|
SELECT_TEST_WITHOUT_PREPARED_STMT_TABLE_NAME);
|
||||||
|
Map formData = setDataValueSafelyInFormData(null, "body", sqlSelectQuery);
|
||||||
|
ActionConfiguration actionConfig = new ActionConfiguration();
|
||||||
|
actionConfig.setFormData(formData);
|
||||||
|
Mono<ActionExecutionResult> executionResultMono = oraclePluginExecutor.executeParameterized(sharedConnectionPool, new ExecuteActionDTO(),
|
||||||
|
getDefaultDatasourceConfig(oracleDB), actionConfig);
|
||||||
|
String expectedResultString = "[{\"C_NUMBER\":\"1\"},{\"C_NUMBER\":\"2\"}]";
|
||||||
|
verifyColumnValue(executionResultMono, expectedResultString);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSelectQueryWithPreparedStatementWithBinding() {
|
||||||
|
String sqlSelectQuery = MessageFormat.format("SELECT c_number FROM {0} WHERE " +
|
||||||
|
"c_varchar2='{{'binding1'}}' ORDER BY c_number DESC", SELECT_TEST_WITH_PREPARED_STMT_TABLE_NAME);
|
||||||
|
Map formData = setDataValueSafelyInFormData(null, "body", sqlSelectQuery);
|
||||||
|
ActionConfiguration actionConfig = new ActionConfiguration();
|
||||||
|
actionConfig.setFormData(formData);
|
||||||
|
|
||||||
|
LinkedHashMap<String, List> bindingNameToValueAndDataTypeMap = new LinkedHashMap<>();
|
||||||
|
bindingNameToValueAndDataTypeMap.put("binding1", List.of("varchar2", ClientDataType.STRING));
|
||||||
|
ExecuteActionDTO executeActionDTO =
|
||||||
|
getExecuteDTOForTestWithBindingAndValueAndDataType(bindingNameToValueAndDataTypeMap);
|
||||||
|
|
||||||
|
Mono<ActionExecutionResult> executionResultMono =
|
||||||
|
oraclePluginExecutor.executeParameterized(sharedConnectionPool, executeActionDTO,
|
||||||
|
getDefaultDatasourceConfig(oracleDB), actionConfig);
|
||||||
|
String expectedResultString = "[{\"C_NUMBER\":\"2\"},{\"C_NUMBER\":\"1\"}]";
|
||||||
|
verifyColumnValue(executionResultMono, expectedResultString);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testInsertQueryReturnValueWithPreparedStatementWithoutAnyBinding() {
|
||||||
|
String sqlInsertQuery = MessageFormat.format(SQL_QUERY_TO_INSERT_ONE_ROW_FORMAT,
|
||||||
|
INSERT_TEST_WITHOUT_PREPARED_STMT_TABLE_NAME, 3);
|
||||||
|
Map insertQueryFormData = setDataValueSafelyInFormData(null, "body", sqlInsertQuery);
|
||||||
|
ActionConfiguration insertQueryActionConfig = new ActionConfiguration();
|
||||||
|
insertQueryActionConfig.setFormData(insertQueryFormData);
|
||||||
|
Mono<ActionExecutionResult> insertQueryExecutionResultMono =
|
||||||
|
oraclePluginExecutor.executeParameterized(sharedConnectionPool, new ExecuteActionDTO(),
|
||||||
|
getDefaultDatasourceConfig(oracleDB), insertQueryActionConfig);
|
||||||
|
String insertQueryExpectedResultString = "[{\"affectedRows\":1}]";
|
||||||
|
verifyColumnValue(insertQueryExecutionResultMono, insertQueryExpectedResultString);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testInsertQueryVerifyNewRowAddedWithPreparedStatementWithoutAnyBinding() {
|
||||||
|
String sqlInsertQuery = MessageFormat.format(SQL_QUERY_TO_INSERT_ONE_ROW_FORMAT,
|
||||||
|
INSERT_TEST_WITHOUT_PREPARED_STMT_TABLE_NAME, 4);
|
||||||
|
Map insertQueryFormData = setDataValueSafelyInFormData(null, "body", sqlInsertQuery);
|
||||||
|
ActionConfiguration insertQueryActionConfig = new ActionConfiguration();
|
||||||
|
insertQueryActionConfig.setFormData(insertQueryFormData);
|
||||||
|
oraclePluginExecutor.executeParameterized(sharedConnectionPool, new ExecuteActionDTO(),
|
||||||
|
getDefaultDatasourceConfig(oracleDB), insertQueryActionConfig).block();
|
||||||
|
|
||||||
|
String sqlSelectQuery = MessageFormat.format("SELECT * FROM {0} WHERE c_number=4",
|
||||||
|
INSERT_TEST_WITHOUT_PREPARED_STMT_TABLE_NAME);
|
||||||
|
Map selectQueryFormData = setDataValueSafelyInFormData(null, "body", sqlSelectQuery);
|
||||||
|
ActionConfiguration selectQueryActionConfig = new ActionConfiguration();
|
||||||
|
selectQueryActionConfig.setFormData(selectQueryFormData);
|
||||||
|
Mono<ActionExecutionResult> selectQueryExecutionResultMono =
|
||||||
|
oraclePluginExecutor.executeParameterized(sharedConnectionPool, new ExecuteActionDTO(),
|
||||||
|
getDefaultDatasourceConfig(oracleDB), selectQueryActionConfig);
|
||||||
|
String selectQueryExpectedResultString = "[{\"C_VARCHAR2\":\"varchar2\",\"C_NVARCHAR2\":\"nvarchar2\"," +
|
||||||
|
"\"C_NUMBER\":\"4\",\"C_FLOAT\":\"11.22\",\"C_DATE\":\"2002-10-03\",\"C_BINARY_FLOAT\":\"11.22\"," +
|
||||||
|
"\"C_BINARY_DOUBLE\":\"11.22\",\"C_TIMESTAMP\":\"1997-01-01T09:26:50.124Z\"," +
|
||||||
|
"\"C_TIMESTAMP_TZ\":\"1997-01-01T09:26:56.66+02:00\",\"C_TIMESTAMP_LTZ\":\"1999-04-05T15:00:00Z\"," +
|
||||||
|
"\"C_INTERVAL_YEAR\":\"1-0\",\"C_INTERVAL_DAY\":\"0 1:0:0.0\",\"C_ROWID\":\"AAAAAAAAGAAAAH4AAB\"," +
|
||||||
|
"\"C_UROWID\":\"000001F8.0001.0006\",\"C_CHAR\":\"char \",\"C_NCHAR\":\"nchar " +
|
||||||
|
" \",\"C_CLOB\":\"clob\",\"C_NCLOB\":\"nclob\"}]";
|
||||||
|
verifyColumnValue(selectQueryExecutionResultMono, selectQueryExpectedResultString);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testInsertQueryReturnValueWithPreparedStatementWithBinding() {
|
||||||
|
String sqlInsertQuery = MessageFormat.format(SQL_QUERY_TO_INSERT_ONE_ROW_WITH_BINDING_FORMAT,
|
||||||
|
INSERT_TEST_WITH_PREPARED_STMT_TABLE_NAME);
|
||||||
|
Map insertQueryFormData = setDataValueSafelyInFormData(null, "body", sqlInsertQuery);
|
||||||
|
ActionConfiguration insertQueryActionConfig = new ActionConfiguration();
|
||||||
|
insertQueryActionConfig.setFormData(insertQueryFormData);
|
||||||
|
|
||||||
|
LinkedHashMap<String, List> bindingNameToValueAndDataTypeMap = new LinkedHashMap<>();
|
||||||
|
bindingNameToValueAndDataTypeMap.put("binding1", List.of("varchar2", ClientDataType.STRING));
|
||||||
|
bindingNameToValueAndDataTypeMap.put("binding2", List.of("nvarchar2", ClientDataType.STRING));
|
||||||
|
bindingNameToValueAndDataTypeMap.put("binding3", List.of("3", ClientDataType.NUMBER));
|
||||||
|
bindingNameToValueAndDataTypeMap.put("binding4", List.of("11.22", ClientDataType.NUMBER));
|
||||||
|
bindingNameToValueAndDataTypeMap.put("binding5", List.of("03-OCT-02", ClientDataType.STRING));
|
||||||
|
bindingNameToValueAndDataTypeMap.put("binding6", List.of("11.22", ClientDataType.NUMBER));
|
||||||
|
bindingNameToValueAndDataTypeMap.put("binding7", List.of("11.22", ClientDataType.NUMBER));
|
||||||
|
bindingNameToValueAndDataTypeMap.put("binding8", List.of("1997-01-01 09:26:50.124", ClientDataType.STRING));
|
||||||
|
bindingNameToValueAndDataTypeMap.put("binding9", List.of("1997-01-01 09:26:50.124", ClientDataType.STRING));
|
||||||
|
bindingNameToValueAndDataTypeMap.put("binding10", List.of("1997-01-01 09:26:50.124", ClientDataType.STRING));
|
||||||
|
bindingNameToValueAndDataTypeMap.put("binding11", List.of("1", ClientDataType.NUMBER));
|
||||||
|
bindingNameToValueAndDataTypeMap.put("binding12", List.of("1", ClientDataType.NUMBER));
|
||||||
|
bindingNameToValueAndDataTypeMap.put("binding13", List.of("000001F8.0001.0006", ClientDataType.STRING));
|
||||||
|
bindingNameToValueAndDataTypeMap.put("binding14", List.of("000001F8.0001.0006", ClientDataType.STRING));
|
||||||
|
bindingNameToValueAndDataTypeMap.put("binding15", List.of("char", ClientDataType.STRING));
|
||||||
|
bindingNameToValueAndDataTypeMap.put("binding16", List.of("nchar", ClientDataType.STRING));
|
||||||
|
bindingNameToValueAndDataTypeMap.put("binding17", List.of("clob", ClientDataType.STRING));
|
||||||
|
bindingNameToValueAndDataTypeMap.put("binding18", List.of("nclob", ClientDataType.STRING));
|
||||||
|
|
||||||
|
ExecuteActionDTO executeActionDTO =
|
||||||
|
getExecuteDTOForTestWithBindingAndValueAndDataType(bindingNameToValueAndDataTypeMap);
|
||||||
|
|
||||||
|
Mono<ActionExecutionResult> insertQueryExecutionResultMono =
|
||||||
|
oraclePluginExecutor.executeParameterized(sharedConnectionPool, executeActionDTO,
|
||||||
|
getDefaultDatasourceConfig(oracleDB), insertQueryActionConfig);
|
||||||
|
String insertQueryExpectedResultString = "[{\"affectedRows\":1}]";
|
||||||
|
verifyColumnValue(insertQueryExecutionResultMono, insertQueryExpectedResultString);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testInsertQueryVerifyNewRowAddedWithPreparedStatementWithBinding() {
|
||||||
|
String sqlInsertQuery = MessageFormat.format(SQL_QUERY_TO_INSERT_ONE_ROW_WITH_BINDING_FORMAT,
|
||||||
|
INSERT_TEST_WITH_PREPARED_STMT_TABLE_NAME);
|
||||||
|
Map insertQueryFormData = setDataValueSafelyInFormData(null, "body", sqlInsertQuery);
|
||||||
|
ActionConfiguration insertQueryActionConfig = new ActionConfiguration();
|
||||||
|
insertQueryActionConfig.setFormData(insertQueryFormData);
|
||||||
|
|
||||||
|
LinkedHashMap<String, List> bindingNameToValueAndDataTypeMap = new LinkedHashMap<>();
|
||||||
|
bindingNameToValueAndDataTypeMap.put("binding1", List.of("varchar2", ClientDataType.STRING));
|
||||||
|
bindingNameToValueAndDataTypeMap.put("binding2", List.of("nvarchar2", ClientDataType.STRING));
|
||||||
|
bindingNameToValueAndDataTypeMap.put("binding3", List.of("5", ClientDataType.NUMBER));
|
||||||
|
bindingNameToValueAndDataTypeMap.put("binding4", List.of("11.22", ClientDataType.NUMBER));
|
||||||
|
bindingNameToValueAndDataTypeMap.put("binding5", List.of("03-OCT-02", ClientDataType.STRING));
|
||||||
|
bindingNameToValueAndDataTypeMap.put("binding6", List.of("11.22", ClientDataType.NUMBER));
|
||||||
|
bindingNameToValueAndDataTypeMap.put("binding7", List.of("11.22", ClientDataType.NUMBER));
|
||||||
|
bindingNameToValueAndDataTypeMap.put("binding8", List.of("1997-01-01 09:26:50.124", ClientDataType.STRING));
|
||||||
|
bindingNameToValueAndDataTypeMap.put("binding9", List.of("1997-01-01 09:26:50.124", ClientDataType.STRING));
|
||||||
|
bindingNameToValueAndDataTypeMap.put("binding10", List.of("1997-01-01 09:26:50.124", ClientDataType.STRING));
|
||||||
|
bindingNameToValueAndDataTypeMap.put("binding11", List.of("1", ClientDataType.NUMBER));
|
||||||
|
bindingNameToValueAndDataTypeMap.put("binding12", List.of("1", ClientDataType.NUMBER));
|
||||||
|
bindingNameToValueAndDataTypeMap.put("binding13", List.of("000001F8.0001.0006", ClientDataType.STRING));
|
||||||
|
bindingNameToValueAndDataTypeMap.put("binding14", List.of("000001F8.0001.0006", ClientDataType.STRING));
|
||||||
|
bindingNameToValueAndDataTypeMap.put("binding15", List.of("char", ClientDataType.STRING));
|
||||||
|
bindingNameToValueAndDataTypeMap.put("binding16", List.of("nchar", ClientDataType.STRING));
|
||||||
|
bindingNameToValueAndDataTypeMap.put("binding17", List.of("clob", ClientDataType.STRING));
|
||||||
|
bindingNameToValueAndDataTypeMap.put("binding18", List.of("nclob", ClientDataType.STRING));
|
||||||
|
|
||||||
|
ExecuteActionDTO executeActionDTO =
|
||||||
|
getExecuteDTOForTestWithBindingAndValueAndDataType(bindingNameToValueAndDataTypeMap);
|
||||||
|
oraclePluginExecutor.executeParameterized(sharedConnectionPool, executeActionDTO,
|
||||||
|
getDefaultDatasourceConfig(oracleDB), insertQueryActionConfig).block();
|
||||||
|
|
||||||
|
String sqlSelectQuery = MessageFormat.format("SELECT c_varchar2, c_nvarchar2, c_number, c_float, c_date, " +
|
||||||
|
"c_binary_float, c_binary_double, c_timestamp, c_interval_year, " +
|
||||||
|
"c_interval_day, c_rowid, c_urowid, c_char, c_nchar, c_clob, c_nclob FROM {0} WHERE c_number=5",
|
||||||
|
INSERT_TEST_WITH_PREPARED_STMT_TABLE_NAME);
|
||||||
|
Map selectQueryFormData = setDataValueSafelyInFormData(null, "body", sqlSelectQuery);
|
||||||
|
ActionConfiguration selectQueryActionConfig = new ActionConfiguration();
|
||||||
|
selectQueryActionConfig.setFormData(selectQueryFormData);
|
||||||
|
Mono<ActionExecutionResult> selectQueryExecutionResultMono =
|
||||||
|
oraclePluginExecutor.executeParameterized(sharedConnectionPool, new ExecuteActionDTO(),
|
||||||
|
getDefaultDatasourceConfig(oracleDB), selectQueryActionConfig);
|
||||||
|
String selectQueryExpectedResultString = "[{\"C_VARCHAR2\":\"varchar2\",\"C_NVARCHAR2\":\"nvarchar2\"," +
|
||||||
|
"\"C_NUMBER\":\"5\",\"C_FLOAT\":\"11.22\",\"C_DATE\":\"2002-10-03\",\"C_BINARY_FLOAT\":\"11.22\"," +
|
||||||
|
"\"C_BINARY_DOUBLE\":\"11.22\",\"C_TIMESTAMP\":\"1997-01-01T09:26:50.124Z\"," +
|
||||||
|
"\"C_INTERVAL_YEAR\":\"1-0\",\"C_INTERVAL_DAY\":\"0 1:0:0.0\"," +
|
||||||
|
"\"C_ROWID\":\"AAAAAAAAGAAAAH4AAB\",\"C_UROWID\":\"000001F8.0001.0006\",\"C_CHAR\":\"char " +
|
||||||
|
" \",\"C_NCHAR\":\"nchar \",\"C_CLOB\":\"clob\",\"C_NCLOB\":\"nclob\"}]";
|
||||||
|
verifyColumnValue(selectQueryExecutionResultMono, selectQueryExpectedResultString);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verifyColumnValue(Mono<ActionExecutionResult> executionResultMono, String expectedResult) {
|
||||||
|
StepVerifier.create(executionResultMono)
|
||||||
|
.assertNext(actionExecutionResult -> {
|
||||||
|
assertTrue(actionExecutionResult.getIsExecutionSuccess(), actionExecutionResult.getBody().toString());
|
||||||
|
if (expectedResult != null) {
|
||||||
|
assertEquals(expectedResult, actionExecutionResult.getBody().toString());
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.verifyComplete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,163 @@
|
||||||
|
package com.external.plugins;
|
||||||
|
|
||||||
|
import com.appsmith.external.models.DatasourceStructure;
|
||||||
|
import com.zaxxer.hikari.HikariDataSource;
|
||||||
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.testcontainers.containers.OracleContainer;
|
||||||
|
import org.testcontainers.junit.jupiter.Container;
|
||||||
|
import org.testcontainers.junit.jupiter.Testcontainers;
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
import reactor.test.StepVerifier;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static com.appsmith.external.helpers.PluginUtils.STRING_TYPE;
|
||||||
|
import static com.appsmith.external.helpers.PluginUtils.getDataValueSafelyFromFormData;
|
||||||
|
import static com.external.plugins.OracleTestDBContainerManager.getDefaultDatasourceConfig;
|
||||||
|
import static com.external.plugins.OracleTestDBContainerManager.oraclePluginExecutor;
|
||||||
|
import static com.external.plugins.OracleTestDBContainerManager.runSQLQueryOnOracleTestDB;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
@Testcontainers
|
||||||
|
public class OracleGetDBSchemaTest {
|
||||||
|
public static final String SQL_QUERY_TO_CREATE_TABLE_WITH_PRIMARY_KEY =
|
||||||
|
"CREATE TABLE supplier\n" +
|
||||||
|
"( supplier_id numeric(10) not null,\n" +
|
||||||
|
" supplier_name varchar2(50) not null,\n" +
|
||||||
|
" contact_name varchar2(50),\n" +
|
||||||
|
" CONSTRAINT supplier_pk PRIMARY KEY (supplier_id)\n" +
|
||||||
|
")";
|
||||||
|
|
||||||
|
public static final String SQL_QUERY_TO_CREATE_TABLE_WITH_FOREIGN_KEY =
|
||||||
|
"CREATE TABLE products\n" +
|
||||||
|
"( product_id numeric(10) not null,\n" +
|
||||||
|
" supplier_id numeric(10) not null,\n" +
|
||||||
|
" CONSTRAINT fk_supplier\n" +
|
||||||
|
" FOREIGN KEY (supplier_id)\n" +
|
||||||
|
" REFERENCES supplier(supplier_id)\n" +
|
||||||
|
")";
|
||||||
|
|
||||||
|
@SuppressWarnings("rawtypes") // The type parameter for the container type is just itself and is pseudo-optional.
|
||||||
|
@Container
|
||||||
|
private static final OracleContainer oracleDB = OracleTestDBContainerManager.getOracleDBForTest();
|
||||||
|
|
||||||
|
private static HikariDataSource sharedConnectionPool = null;
|
||||||
|
|
||||||
|
@BeforeAll
|
||||||
|
public static void setup() throws SQLException {
|
||||||
|
sharedConnectionPool = oraclePluginExecutor.datasourceCreate(getDefaultDatasourceConfig(oracleDB)).block();
|
||||||
|
createTablesForTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void createTablesForTest() throws SQLException {
|
||||||
|
runSQLQueryOnOracleTestDB(SQL_QUERY_TO_CREATE_TABLE_WITH_PRIMARY_KEY, sharedConnectionPool);
|
||||||
|
runSQLQueryOnOracleTestDB(SQL_QUERY_TO_CREATE_TABLE_WITH_FOREIGN_KEY, sharedConnectionPool);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDBSchemaShowsAllTables() {
|
||||||
|
Mono<DatasourceStructure> datasourceStructureMono =
|
||||||
|
oraclePluginExecutor.getStructure(sharedConnectionPool,
|
||||||
|
getDefaultDatasourceConfig(oracleDB));
|
||||||
|
|
||||||
|
StepVerifier.create(datasourceStructureMono)
|
||||||
|
.assertNext(datasourceStructure -> {
|
||||||
|
Set<String> setOfAllTableNames = datasourceStructure.getTables().stream()
|
||||||
|
.map(DatasourceStructure.Table::getName)
|
||||||
|
.map(String::toLowerCase)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
assertTrue(setOfAllTableNames.equals(Set.of("supplier","products")), setOfAllTableNames.toString());
|
||||||
|
})
|
||||||
|
.verifyComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDBSchemaShowsAllColumnsAndTypesInATable() {
|
||||||
|
Mono<DatasourceStructure> datasourceStructureMono =
|
||||||
|
oraclePluginExecutor.getStructure(sharedConnectionPool,
|
||||||
|
getDefaultDatasourceConfig(oracleDB));
|
||||||
|
|
||||||
|
StepVerifier.create(datasourceStructureMono)
|
||||||
|
.assertNext(datasourceStructure -> {
|
||||||
|
DatasourceStructure.Table supplierTable = datasourceStructure.getTables().stream()
|
||||||
|
.filter(table -> "supplier".equalsIgnoreCase(table.getName()))
|
||||||
|
.findFirst()
|
||||||
|
.get();
|
||||||
|
|
||||||
|
assertTrue(supplierTable != null, "supplier table not found in DB schema");
|
||||||
|
|
||||||
|
Set<String> allColumnNames = supplierTable.getColumns().stream()
|
||||||
|
.map(DatasourceStructure.Column::getName)
|
||||||
|
.map(String::toLowerCase)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
Set<String> expectedColumnNames = Set.of("supplier_id", "supplier_name", "contact_name");
|
||||||
|
assertEquals(expectedColumnNames, allColumnNames, allColumnNames.toString());
|
||||||
|
|
||||||
|
supplierTable.getColumns().stream()
|
||||||
|
.forEach(column -> {
|
||||||
|
String columnName = column.getName().toLowerCase();
|
||||||
|
String columnType = column.getType().toLowerCase();
|
||||||
|
String expectedColumnType = null;
|
||||||
|
|
||||||
|
if ("supplier_id".equals(columnName)) {
|
||||||
|
expectedColumnType = "number";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
expectedColumnType = "varchar2";
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals(expectedColumnType, columnType, columnType);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.verifyComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDynamicSqlTemplateQueriesForATable() {
|
||||||
|
Mono<DatasourceStructure> datasourceStructureMono =
|
||||||
|
oraclePluginExecutor.getStructure(sharedConnectionPool,
|
||||||
|
getDefaultDatasourceConfig(oracleDB));
|
||||||
|
|
||||||
|
StepVerifier.create(datasourceStructureMono)
|
||||||
|
.assertNext(datasourceStructure -> {
|
||||||
|
DatasourceStructure.Table supplierTable = datasourceStructure.getTables().stream()
|
||||||
|
.filter(table -> "supplier".equalsIgnoreCase(table.getName()))
|
||||||
|
.findFirst()
|
||||||
|
.get();
|
||||||
|
|
||||||
|
assertTrue(supplierTable != null, "supplier table not found in DB schema");
|
||||||
|
|
||||||
|
supplierTable.getTemplates().stream()
|
||||||
|
.filter(template -> "select".equalsIgnoreCase(template.getTitle()) || "delete".equalsIgnoreCase(template.getTitle()))
|
||||||
|
.forEach(template -> {
|
||||||
|
/**
|
||||||
|
* Not sure how to test query templates for insert and update queries as these
|
||||||
|
* queries include column names in an order that is not fixed. Hence, skipping testing
|
||||||
|
* them for now.
|
||||||
|
*/
|
||||||
|
|
||||||
|
String expectedSelectQueryTemplate = null;
|
||||||
|
if ("select".equalsIgnoreCase(template.getTitle())) {
|
||||||
|
expectedSelectQueryTemplate = "select * from supplier where rownum < 10";
|
||||||
|
}
|
||||||
|
else if ("delete".equalsIgnoreCase(template.getTitle())) {
|
||||||
|
expectedSelectQueryTemplate = "delete from supplier where 1=0 -- specify a valid" +
|
||||||
|
" condition here. removing the condition may delete everything in the " +
|
||||||
|
"table!";
|
||||||
|
}
|
||||||
|
|
||||||
|
String templateQuery =
|
||||||
|
getDataValueSafelyFromFormData((Map<String, Object>) template.getConfiguration(), "body", STRING_TYPE);
|
||||||
|
assertEquals(expectedSelectQueryTemplate, templateQuery.toLowerCase(),
|
||||||
|
templateQuery.toLowerCase());
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.verifyComplete();
|
||||||
|
}
|
||||||
|
}
|
||||||
81
app/server/appsmith-plugins/oraclePlugin/src/test/java/com/external/plugins/OraclePluginConnectionTest.java
vendored
Executable file
81
app/server/appsmith-plugins/oraclePlugin/src/test/java/com/external/plugins/OraclePluginConnectionTest.java
vendored
Executable file
|
|
@ -0,0 +1,81 @@
|
||||||
|
package com.external.plugins;
|
||||||
|
|
||||||
|
|
||||||
|
import com.appsmith.external.models.DBAuth;
|
||||||
|
import com.appsmith.external.models.DatasourceConfiguration;
|
||||||
|
import com.appsmith.external.models.DatasourceTestResult;
|
||||||
|
import com.external.plugins.exceptions.OraclePluginError;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.testcontainers.containers.OracleContainer;
|
||||||
|
import org.testcontainers.junit.jupiter.Container;
|
||||||
|
import org.testcontainers.junit.jupiter.Testcontainers;
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
import reactor.test.StepVerifier;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static com.external.plugins.OracleTestDBContainerManager.getDefaultDatasourceConfig;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
@Testcontainers
|
||||||
|
public class OraclePluginConnectionTest {
|
||||||
|
|
||||||
|
OraclePlugin.OraclePluginExecutor oraclePluginExecutor = new OraclePlugin.OraclePluginExecutor();
|
||||||
|
|
||||||
|
@SuppressWarnings("rawtypes") // The type parameter for the container type is just itself and is pseudo-optional.
|
||||||
|
@Container
|
||||||
|
private static final OracleContainer oracleDB = OracleTestDBContainerManager.getOracleDBForTest();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDatasourceConnectionTestPassWithValidConfig() {
|
||||||
|
Mono<DatasourceTestResult> testDsResultMono =
|
||||||
|
oraclePluginExecutor.testDatasource(getDefaultDatasourceConfig(oracleDB));
|
||||||
|
StepVerifier.create(testDsResultMono)
|
||||||
|
.assertNext(testResult -> {
|
||||||
|
assertEquals(0, testResult.getInvalids().size());
|
||||||
|
})
|
||||||
|
.verifyComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDatasourceConnectionTestFailWithInvalidPassword() {
|
||||||
|
DatasourceConfiguration invalidDsConfig = getDefaultDatasourceConfig(oracleDB);
|
||||||
|
((DBAuth)invalidDsConfig.getAuthentication()).setPassword("invalid_password");
|
||||||
|
|
||||||
|
Mono<DatasourceTestResult> testDsResultMono =
|
||||||
|
oraclePluginExecutor.testDatasource(invalidDsConfig);
|
||||||
|
StepVerifier.create(testDsResultMono)
|
||||||
|
.assertNext(testResult -> {
|
||||||
|
assertNotEquals(0, testResult.getInvalids().size());
|
||||||
|
String expectedError = "Failed to initialize pool: ORA-01017: invalid username/password; logon " +
|
||||||
|
"denied";
|
||||||
|
boolean isExpectedErrorReceived = testResult.getInvalids().stream()
|
||||||
|
.anyMatch(errorString -> expectedError.equals(errorString.trim()));
|
||||||
|
assertTrue(isExpectedErrorReceived);
|
||||||
|
})
|
||||||
|
.verifyComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDatasourceConnectionTestFailWithInvalidUsername() {
|
||||||
|
DatasourceConfiguration invalidDsConfig = getDefaultDatasourceConfig(oracleDB);
|
||||||
|
((DBAuth)invalidDsConfig.getAuthentication()).setUsername("invalid_username");
|
||||||
|
|
||||||
|
Mono<DatasourceTestResult> testDsResultMono =
|
||||||
|
oraclePluginExecutor.testDatasource(invalidDsConfig);
|
||||||
|
StepVerifier.create(testDsResultMono)
|
||||||
|
.assertNext(testResult -> {
|
||||||
|
assertNotEquals(0, testResult.getInvalids().size());
|
||||||
|
String expectedError = "Failed to initialize pool: ORA-01017: invalid username/password; logon " +
|
||||||
|
"denied";
|
||||||
|
boolean isExpectedErrorReceived = testResult.getInvalids().stream()
|
||||||
|
.anyMatch(errorString -> expectedError.equals(errorString.trim()));
|
||||||
|
assertTrue(isExpectedErrorReceived);
|
||||||
|
})
|
||||||
|
.verifyComplete();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,64 @@
|
||||||
|
package com.external.plugins;
|
||||||
|
|
||||||
|
import com.appsmith.external.models.DBAuth;
|
||||||
|
import com.appsmith.external.models.DatasourceConfiguration;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static com.external.plugins.OracleTestDBContainerManager.getDefaultDatasourceConfig;
|
||||||
|
import static com.external.plugins.exceptions.OracleErrorMessages.DS_MISSING_ENDPOINT_ERROR_MSG;
|
||||||
|
import static com.external.plugins.exceptions.OracleErrorMessages.DS_MISSING_HOSTNAME_ERROR_MSG;
|
||||||
|
import static com.external.plugins.exceptions.OracleErrorMessages.DS_MISSING_PASSWORD_ERROR_MSG;
|
||||||
|
import static com.external.plugins.exceptions.OracleErrorMessages.DS_MISSING_USERNAME_ERROR_MSG;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
public class OraclePluginDatasourceValidityErrorsTest {
|
||||||
|
|
||||||
|
OraclePlugin.OraclePluginExecutor oraclePluginExecutor = new OraclePlugin.OraclePluginExecutor();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testErrorOnMissingUsername() {
|
||||||
|
DatasourceConfiguration dsConfigWithMissingUsername = getDefaultDatasourceConfig(null);
|
||||||
|
((DBAuth)dsConfigWithMissingUsername.getAuthentication()).setUsername("");
|
||||||
|
|
||||||
|
Set<String> dsValidateResult = oraclePluginExecutor.validateDatasource(dsConfigWithMissingUsername);
|
||||||
|
boolean isExpectedErrorReceived = dsValidateResult.stream()
|
||||||
|
.anyMatch(errorString -> DS_MISSING_USERNAME_ERROR_MSG.equals(errorString.trim()));
|
||||||
|
assertTrue(isExpectedErrorReceived);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testErrorOnMissingPassword() {
|
||||||
|
DatasourceConfiguration dsConfigWithMissingPassword = getDefaultDatasourceConfig(null);
|
||||||
|
((DBAuth)dsConfigWithMissingPassword.getAuthentication()).setPassword("");
|
||||||
|
|
||||||
|
Set<String> dsValidateResult = oraclePluginExecutor.validateDatasource(dsConfigWithMissingPassword);
|
||||||
|
boolean isExpectedErrorReceived = dsValidateResult.stream()
|
||||||
|
.anyMatch(errorString -> DS_MISSING_PASSWORD_ERROR_MSG.equals(errorString.trim()));
|
||||||
|
assertTrue(isExpectedErrorReceived);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testErrorOnMissingEndpoint() {
|
||||||
|
DatasourceConfiguration dsConfigWithMissingEndpoint = getDefaultDatasourceConfig(null);
|
||||||
|
dsConfigWithMissingEndpoint.setEndpoints(new ArrayList<>());
|
||||||
|
|
||||||
|
Set<String> dsValidateResult = oraclePluginExecutor.validateDatasource(dsConfigWithMissingEndpoint);
|
||||||
|
boolean isExpectedErrorReceived = dsValidateResult.stream()
|
||||||
|
.anyMatch(errorString -> DS_MISSING_ENDPOINT_ERROR_MSG.equals(errorString.trim()));
|
||||||
|
assertTrue(isExpectedErrorReceived);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testErrorOnMissingHost() {
|
||||||
|
DatasourceConfiguration dsConfigWithMissingHost = getDefaultDatasourceConfig(null);
|
||||||
|
dsConfigWithMissingHost.getEndpoints().get(0).setHost("");
|
||||||
|
|
||||||
|
Set<String> dsValidateResult = oraclePluginExecutor.validateDatasource(dsConfigWithMissingHost);
|
||||||
|
boolean isExpectedErrorReceived = dsValidateResult.stream()
|
||||||
|
.anyMatch(errorString -> DS_MISSING_HOSTNAME_ERROR_MSG.equals(errorString.trim()));
|
||||||
|
assertTrue(isExpectedErrorReceived);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,17 +1,12 @@
|
||||||
package com.external.plugins;
|
package com.external.plugins;
|
||||||
|
|
||||||
|
|
||||||
import com.external.plugins.exceptions.OraclePluginError;
|
import com.external.plugins.exceptions.OraclePluginError;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.testcontainers.junit.jupiter.Testcontainers;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Slf4j
|
public class OraclePluginErrorsTest {
|
||||||
@Testcontainers
|
|
||||||
public class OraclePluginTest {
|
|
||||||
@Test
|
@Test
|
||||||
public void verifyUniquenessOfOraclePluginErrorCode() {
|
public void verifyUniquenessOfOraclePluginErrorCode() {
|
||||||
assert (Arrays.stream(OraclePluginError.values()).map(OraclePluginError::getAppErrorCode).distinct().count() == OraclePluginError.values().length);
|
assert (Arrays.stream(OraclePluginError.values()).map(OraclePluginError::getAppErrorCode).distinct().count() == OraclePluginError.values().length);
|
||||||
|
|
@ -19,6 +14,5 @@ public class OraclePluginTest {
|
||||||
assert (Arrays.stream(OraclePluginError.values()).map(OraclePluginError::getAppErrorCode)
|
assert (Arrays.stream(OraclePluginError.values()).map(OraclePluginError::getAppErrorCode)
|
||||||
.filter(appErrorCode -> appErrorCode.length() != 11 || !appErrorCode.startsWith("PE-ORC"))
|
.filter(appErrorCode -> appErrorCode.length() != 11 || !appErrorCode.startsWith("PE-ORC"))
|
||||||
.collect(Collectors.toList()).size() == 0);
|
.collect(Collectors.toList()).size() == 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
package com.external.plugins;
|
||||||
|
|
||||||
|
import com.appsmith.external.models.Connection;
|
||||||
|
import com.appsmith.external.models.DBAuth;
|
||||||
|
import com.appsmith.external.models.DatasourceConfiguration;
|
||||||
|
import com.appsmith.external.models.Endpoint;
|
||||||
|
import com.appsmith.external.models.SSLDetails;
|
||||||
|
import com.zaxxer.hikari.HikariDataSource;
|
||||||
|
import org.testcontainers.containers.OracleContainer;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import static com.external.plugins.utils.OracleDatasourceUtils.getConnectionFromConnectionPool;
|
||||||
|
import static com.external.plugins.utils.OracleExecuteUtils.closeConnectionPostExecution;
|
||||||
|
|
||||||
|
public class OracleTestDBContainerManager {
|
||||||
|
public static final String ORACLE_USERNAME = "testUser";
|
||||||
|
public static final String ORACLE_PASSWORD = "testPassword";
|
||||||
|
public static final String ORACLE_DB_NAME = "testDB";
|
||||||
|
public static final String ORACLE_DOCKER_HUB_CONTAINER = "gvenzl/oracle-xe:21-slim-faststart";
|
||||||
|
static OraclePlugin.OraclePluginExecutor oraclePluginExecutor = new OraclePlugin.OraclePluginExecutor();
|
||||||
|
|
||||||
|
public static OracleContainer getOracleDBForTest() {
|
||||||
|
return new OracleContainer(ORACLE_DOCKER_HUB_CONTAINER)
|
||||||
|
.withDatabaseName(ORACLE_DB_NAME)
|
||||||
|
.withUsername(ORACLE_USERNAME)
|
||||||
|
.withPassword(ORACLE_PASSWORD);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DatasourceConfiguration getDefaultDatasourceConfig(OracleContainer oracleDB) {
|
||||||
|
DatasourceConfiguration dsConfig = new DatasourceConfiguration();
|
||||||
|
dsConfig.setAuthentication(new DBAuth());
|
||||||
|
((DBAuth)dsConfig.getAuthentication()).setUsername(OracleTestDBContainerManager.ORACLE_USERNAME);
|
||||||
|
((DBAuth)dsConfig.getAuthentication()).setPassword(OracleTestDBContainerManager.ORACLE_PASSWORD);
|
||||||
|
((DBAuth)dsConfig.getAuthentication()).setDatabaseName(OracleTestDBContainerManager.ORACLE_DB_NAME);
|
||||||
|
|
||||||
|
dsConfig.setEndpoints(new ArrayList<>());
|
||||||
|
String host = oracleDB == null ? "host" : oracleDB.getHost();
|
||||||
|
long port = oracleDB == null ? 1521L : (long)oracleDB.getOraclePort();
|
||||||
|
dsConfig.getEndpoints().add(new Endpoint(host, port));
|
||||||
|
|
||||||
|
dsConfig.setConnection(new Connection());
|
||||||
|
dsConfig.getConnection().setSsl(new SSLDetails());
|
||||||
|
dsConfig.getConnection().getSsl().setAuthType(SSLDetails.AuthType.DISABLE);
|
||||||
|
|
||||||
|
return dsConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void runSQLQueryOnOracleTestDB(String sqlQuery, HikariDataSource sharedConnectionPool) throws SQLException {
|
||||||
|
java.sql.Connection connectionFromPool = getConnectionFromConnectionPool(sharedConnectionPool);
|
||||||
|
Statement statement = connectionFromPool.createStatement();
|
||||||
|
statement.execute(sqlQuery);
|
||||||
|
closeConnectionPostExecution(null, statement, null, connectionFromPool);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user