TSK-1997: refactoring DB Enum

This commit is contained in:
Mustapha Zorgati 2023-03-04 10:40:05 +01:00
parent f64e38eb27
commit b2be25e2ef
19 changed files with 83 additions and 119 deletions

View File

@ -78,9 +78,9 @@ public class SampleDataGenerator {
private List<String> parseScripts(Stream<String> scripts) {
try (Connection connection = dataSource.getConnection()) {
String dbProductId = DB.getDatabaseProductId(connection);
DB db = DB.getDB(connection);
return scripts
.map(script -> SqlReplacer.getScriptAsSql(dbProductId, now, script))
.map(script -> SqlReplacer.getScriptAsSql(db, now, script))
.collect(Collectors.toList());
} catch (SQLException e) {
throw new RuntimeSqlException("Connection to database failed.", e);
@ -92,7 +92,7 @@ public class SampleDataGenerator {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(
"Generating sample data for database of type '{}' with url '{}' and schema '{}'.",
DB.getDatabaseProductName(connection),
DB.getDB(connection).dbProductName,
connection.getMetaData().getURL(),
schema);
}

View File

@ -25,8 +25,8 @@ final class SqlReplacer {
// to prevent initialization
private SqlReplacer() {}
static String getScriptAsSql(String dbProductId, ZonedDateTime now, String scriptPath) {
return parseAndReplace(getScriptBufferedStream(scriptPath), now, dbProductId);
static String getScriptAsSql(DB db, ZonedDateTime now, String scriptPath) {
return parseAndReplace(getScriptBufferedStream(scriptPath), now, db);
}
/**
@ -70,13 +70,12 @@ final class SqlReplacer {
return sql.replace("''", String.format("'%s'", EMPTY_PLACEHOLDER));
}
private static String parseAndReplace(
BufferedReader bufferedReader, ZonedDateTime now, String dbProductId) {
private static String parseAndReplace(BufferedReader bufferedReader, ZonedDateTime now, DB db) {
String sql = bufferedReader.lines().collect(Collectors.joining(System.lineSeparator()));
if (DB.isDb2(dbProductId) || DB.isOracle(dbProductId)) {
if (DB.DB2 == db || DB.ORACLE == db) {
sql = replaceBooleanWithInteger(sql);
}
if (DB.isOracle(dbProductId)) {
if (DB.ORACLE == db) {
sql = replaceEmptyStringWithPlaceholder(sql);
// Oracle needs to be informed about the timestamp format used in data scripts
sql = "ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF3';\n" + sql;

View File

@ -32,7 +32,7 @@ public final class DataSourceGenerator {
if (dockerContainer.isPresent()) {
dockerContainer.get().start();
DATA_SOURCE = DockerContainerCreator.createDataSource(dockerContainer.get());
if (DB.isOracle(db.dbProductId)) {
if (DB.ORACLE == db) {
initOracleSchema(DATA_SOURCE, SCHEMA_NAME);
}
} else {

View File

@ -1,9 +1,9 @@
package pro.taskana.common.api.exceptions;
/**
* This exception is thrown when using TASKANA with the CONNECTION_MANAGED_EXTERNALLY
* ConnectionManagementMode and an attempt is made to call an API method before the
* TaskananEngine#setConnection() method has been called.
* This exception is thrown when using TASKANA with the EXPLICIT ConnectionManagementMode and an
* attempt is made to call an API method before the TaskananEngine#setConnection() method has been
* called.
*/
public class ConnectionNotSetException extends TaskanaRuntimeException {

View File

@ -2,6 +2,7 @@ package pro.taskana.common.internal.configuration;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Arrays;
import pro.taskana.common.api.exceptions.SystemException;
import pro.taskana.common.api.exceptions.UnsupportedDatabaseException;
@ -21,59 +22,26 @@ public enum DB {
this.dbProductId = dbProductId;
}
public static boolean isH2(String dbProductId) {
return H2.dbProductId.equals(dbProductId);
public static DB getDB(String dbProductId) {
return Arrays.stream(DB.values())
.filter(db -> dbProductId.contains(db.dbProductId))
.findFirst()
.orElseThrow(() -> new UnsupportedDatabaseException(dbProductId));
}
public static boolean isDb2(String dbProductId) {
return DB2.dbProductId.equals(dbProductId);
}
public static boolean isPostgres(String dbProductId) {
return POSTGRES.dbProductId.equals(dbProductId);
}
public static boolean isOracle(String dbProductId) {
return ORACLE.dbProductId.equals(dbProductId);
}
public static boolean isOracleDb(String dbProductName) {
return ORACLE.dbProductName.equals(dbProductName);
}
public static String getDatabaseProductName(Connection connection) throws SQLException {
return connection.getMetaData().getDatabaseProductName();
}
public static DB getDbForId(String databaseId) {
if (isH2(databaseId)) {
return H2;
} else if (isDb2(databaseId)) {
return DB2;
} else if (isOracle(databaseId)) {
return ORACLE;
} else if (isPostgres(databaseId)) {
return POSTGRES;
}
throw new SystemException("Unknown database id: " + databaseId);
}
public static String getDatabaseProductId(Connection connection) throws SQLException {
public static DB getDB(Connection connection) {
String dbProductName = DB.getDatabaseProductName(connection);
if (dbProductName.contains(H2.dbProductName)) {
return H2.dbProductId;
} else if (dbProductName.contains(DB2.dbProductName)) {
return DB2.dbProductId;
} else if (dbProductName.contains(ORACLE.dbProductName)) {
return ORACLE.dbProductId;
} else if (POSTGRES.dbProductName.equals(dbProductName)) {
return POSTGRES.dbProductId;
} else {
throw new UnsupportedDatabaseException(dbProductName);
}
return Arrays.stream(DB.values())
.filter(db -> dbProductName.contains(db.dbProductName))
.findFirst()
.orElseThrow(() -> new UnsupportedDatabaseException(dbProductName));
}
public String getProductId() {
return this.dbProductId;
private static String getDatabaseProductName(Connection connection) {
try {
return connection.getMetaData().getDatabaseProductName();
} catch (SQLException e) {
throw new SystemException("Could not extract meta data from connection", e);
}
}
}

View File

@ -60,15 +60,15 @@ public class DbSchemaCreator {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(
"Using database of type {} with url '{}'",
DB.getDatabaseProductName(connection),
DB.getDB(connection).dbProductName,
connection.getMetaData().getURL());
}
String dbProductId = DB.getDatabaseProductId(connection);
DB db = DB.getDB(connection);
ScriptRunner runner = getScriptRunnerInstance(connection);
if (!isSchemaPreexisting(connection, dbProductId)) {
String scriptPath = selectDbScriptFileName(dbProductId);
if (!isSchemaPreexisting(connection, db)) {
String scriptPath = selectDbScriptFileName(db);
InputStream resourceAsStream = DbSchemaCreator.class.getResourceAsStream(scriptPath);
BufferedReader reader =
new BufferedReader(new InputStreamReader(resourceAsStream, StandardCharsets.UTF_8));
@ -132,9 +132,9 @@ public class DbSchemaCreator {
this.dataSource = dataSource;
}
private static String selectDbScriptFileName(String dbProductId) {
private static String selectDbScriptFileName(DB db) {
switch (DB.getDbForId(dbProductId)) {
switch (db) {
case DB2:
return DB_SCHEMA_DB2;
case ORACLE:
@ -146,9 +146,9 @@ public class DbSchemaCreator {
}
}
private static String selectDbSchemaDetectionScript(String dbProductId) {
private static String selectDbSchemaDetectionScript(DB db) {
switch (DB.getDbForId(dbProductId)) {
switch (db) {
case DB2:
return DB_SCHEMA_DETECTION_DB2;
case ORACLE:
@ -168,11 +168,11 @@ public class DbSchemaCreator {
return runner;
}
private boolean isSchemaPreexisting(Connection connection, String dbProductId) {
private boolean isSchemaPreexisting(Connection connection, DB db) {
ScriptRunner runner = getScriptRunnerInstance(connection);
runner.setErrorLogWriter(errorLogWriter);
String scriptPath = selectDbSchemaDetectionScript(dbProductId);
String scriptPath = selectDbSchemaDetectionScript(db);
try (InputStream resource = DbSchemaCreator.class.getResourceAsStream(scriptPath);
InputStreamReader inputReader = new InputStreamReader(resource, StandardCharsets.UTF_8);
BufferedReader reader = new BufferedReader(inputReader)) {

View File

@ -6,7 +6,7 @@ import java.time.LocalTime;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Test;
public class LocalTimeIntervalTest {
class LocalTimeIntervalTest {
@Test
void naturalOrderingIsDefinedByBegin() {

View File

@ -10,7 +10,7 @@ import org.junit.jupiter.api.Test;
import pro.taskana.common.api.LocalTimeInterval;
public class WorkingTimeScheduleTest {
class WorkingTimeScheduleTest {
@Test
void creationFailsIfWorkingTimesOverlap() {

View File

@ -112,17 +112,17 @@ public class TaskanaHistoryEngineImpl implements TaskanaHistoryEngine {
Configuration configuration = new Configuration(environment);
// set databaseId
String databaseProductName;
DB db;
try (Connection con = taskanaEngineConfiguration.getDatasource().getConnection()) {
databaseProductName = DB.getDatabaseProductName(con);
configuration.setDatabaseId(DB.getDatabaseProductId(con));
db = DB.getDB(con);
configuration.setDatabaseId(db.dbProductId);
} catch (SQLException e) {
throw new SystemException("Could not open a connection to set the databaseId", e);
}
// register type handlers
if (DB.isOracleDb(databaseProductName)) {
if (DB.ORACLE == db) {
// Use NULL instead of OTHER when jdbcType is not specified for null values,
// otherwise oracle driver will chunck on null values
configuration.setJdbcTypeForNull(JdbcType.NULL);
@ -142,7 +142,7 @@ public class TaskanaHistoryEngineImpl implements TaskanaHistoryEngine {
configuration.addMapper(UserMapper.class);
SqlSessionFactory localSessionFactory;
if (DB.isOracleDb(databaseProductName)) {
if (DB.ORACLE == db) {
localSessionFactory =
new SqlSessionFactoryBuilder() {
@Override

View File

@ -96,8 +96,8 @@ public abstract class AbstractAccTest {
? schemaName
: DataSourceGenerator.getSchemaName();
try (Connection connection = dataSource.getConnection()) {
String dbProductId = DB.getDatabaseProductId(connection);
if (DB.isOracle(dbProductId)) {
DB db = DB.getDB(connection);
if (DB.ORACLE == db) {
initOracleSchema(dataSource, schemaNameTmp);
}
}

View File

@ -12,13 +12,13 @@ import pro.taskana.common.internal.configuration.DbSchemaCreator;
import pro.taskana.testapi.OracleSchemaHelper;
import pro.taskana.testapi.extensions.TestContainerExtension;
class TaskanaEngineExplizitTest {
class TaskanaEngineExplicitTest {
@Test
void should_CreateTaskanaEnine_When_ExplizitModeIsActive() throws Exception {
void should_CreateTaskanaEngine_When_ExplizitModeIsActive() throws Exception {
String schemaName = TestContainerExtension.determineSchemaName();
if (DB.isOracle(TestContainerExtension.EXECUTION_DATABASE.dbProductId)) {
if (DB.ORACLE == TestContainerExtension.EXECUTION_DATABASE) {
OracleSchemaHelper.initOracleSchema(TestContainerExtension.DATA_SOURCE, schemaName);
}

View File

@ -878,8 +878,8 @@ public class TaskanaConfiguration {
}
try (Connection connection = dataSource.getConnection()) {
String databaseProductId = DB.getDatabaseProductId(connection);
if (DB.isPostgres(databaseProductId)) {
DB db = DB.getDB(connection);
if (DB.POSTGRES == db) {
return schemaName.toLowerCase();
} else {
return schemaName.toUpperCase();

View File

@ -369,10 +369,10 @@ public class TaskanaEngineImpl implements TaskanaEngine {
Configuration configuration = new Configuration(environment);
// set databaseId
String databaseProductName;
DB db;
try (Connection con = taskanaEngineConfiguration.getDatasource().getConnection()) {
databaseProductName = DB.getDatabaseProductName(con);
configuration.setDatabaseId(DB.getDatabaseProductId(con));
db = DB.getDB(con);
configuration.setDatabaseId(db.dbProductId);
} catch (SQLException e) {
throw new SystemException(
@ -382,7 +382,7 @@ public class TaskanaEngineImpl implements TaskanaEngine {
}
// register type handlers
if (DB.isOracleDb(databaseProductName)) {
if (DB.ORACLE == db) {
// Use NULL instead of OTHER when jdbcType is not specified for null values,
// otherwise oracle driver will chunk on null values
configuration.setJdbcTypeForNull(JdbcType.NULL);
@ -411,7 +411,7 @@ public class TaskanaEngineImpl implements TaskanaEngine {
configuration.addMapper(ConfigurationMapper.class);
SqlSessionFactory localSessionFactory;
if (DB.isOracleDb(databaseProductName)) {
if (DB.ORACLE == db) {
localSessionFactory =
new SqlSessionFactoryBuilder() {
@Override
@ -426,24 +426,21 @@ public class TaskanaEngineImpl implements TaskanaEngine {
return SqlSessionManager.newInstance(localSessionFactory);
}
private boolean initializeDbSchema(TaskanaConfiguration taskanaEngineConfiguration)
private void initializeDbSchema(TaskanaConfiguration taskanaEngineConfiguration)
throws SQLException {
DbSchemaCreator dbSchemaCreator =
new DbSchemaCreator(
taskanaEngineConfiguration.getDatasource(), taskanaEngineConfiguration.getSchemaName());
boolean schemaCreated = dbSchemaCreator.run();
if (!schemaCreated) {
if (!dbSchemaCreator.isValidSchemaVersion(MINIMAL_TASKANA_SCHEMA_VERSION)) {
if (!schemaCreated && !dbSchemaCreator.isValidSchemaVersion(MINIMAL_TASKANA_SCHEMA_VERSION)) {
throw new SystemException(
"The Database Schema Version doesn't match the expected minimal version "
+ MINIMAL_TASKANA_SCHEMA_VERSION);
}
}
((ConfigurationServiceImpl) getConfigurationService())
.checkSecureAccess(taskanaEngineConfiguration.isSecurityEnabled());
((ConfigurationServiceImpl) getConfigurationService()).setupDefaultCustomAttributes();
return schemaCreated;
}
/**

View File

@ -43,7 +43,7 @@ public class JobRunner {
TaskanaTransactionProvider.executeInTransactionIfPossible(
txProvider,
() -> {
Boolean successful = taskanaEngine.runAsAdmin(() -> runScheduledJob(scheduledJob));
boolean successful = taskanaEngine.runAsAdmin(() -> runScheduledJob(scheduledJob));
if (successful) {
jobService.deleteJob(scheduledJob);
}

View File

@ -676,7 +676,7 @@ public class TaskQueryImpl implements TaskQuery {
@Override
public TaskQuery orderByClassificationKey(SortDirection sortDirection) {
return DB.isDb2(getDatabaseId())
return DB.DB2 == getDB()
? addOrderCriteria("TCLASSIFICATION_KEY", sortDirection)
: addOrderCriteria("t.CLASSIFICATION_KEY", sortDirection);
}
@ -767,7 +767,7 @@ public class TaskQueryImpl implements TaskQuery {
public TaskQuery orderByClassificationName(SortDirection sortDirection) {
joinWithClassifications = true;
addClassificationNameToSelectClauseForOrdering = true;
return DB.isDb2(getDatabaseId())
return DB.DB2 == getDB()
? addOrderCriteria("CNAME", sortDirection)
: addOrderCriteria("c.NAME", sortDirection);
}
@ -1096,7 +1096,7 @@ public class TaskQueryImpl implements TaskQuery {
public TaskQuery orderByAttachmentClassificationId(SortDirection sortDirection) {
joinWithAttachments = true;
addAttachmentColumnsToSelectClauseForOrdering = true;
return DB.isDb2(getDatabaseId())
return DB.DB2 == getDB()
? addOrderCriteria("ACLASSIFICATION_ID", sortDirection)
: addOrderCriteria("a.CLASSIFICATION_ID", sortDirection);
}
@ -1133,7 +1133,7 @@ public class TaskQueryImpl implements TaskQuery {
public TaskQuery orderByAttachmentClassificationKey(SortDirection sortDirection) {
joinWithAttachments = true;
addAttachmentColumnsToSelectClauseForOrdering = true;
return DB.isDb2(getDatabaseId())
return DB.DB2 == getDB()
? addOrderCriteria("ACLASSIFICATION_KEY", sortDirection)
: addOrderCriteria("a.CLASSIFICATION_KEY", sortDirection);
}
@ -1170,7 +1170,7 @@ public class TaskQueryImpl implements TaskQuery {
public TaskQuery orderByAttachmentClassificationName(SortDirection sortDirection) {
joinWithAttachments = true;
addAttachmentClassificationNameToSelectClauseForOrdering = true;
return DB.isDb2(getDatabaseId())
return DB.DB2 == getDB()
? addOrderCriteria("ACNAME", sortDirection)
: addOrderCriteria("ac.NAME", sortDirection);
}
@ -1265,7 +1265,7 @@ public class TaskQueryImpl implements TaskQuery {
public TaskQuery orderByAttachmentReceived(SortDirection sortDirection) {
joinWithAttachments = true;
addAttachmentColumnsToSelectClauseForOrdering = true;
return DB.isDb2(getDatabaseId())
return DB.DB2 == getDB()
? addOrderCriteria("ARECEIVED", sortDirection)
: addOrderCriteria("a.RECEIVED", sortDirection);
}
@ -1926,7 +1926,7 @@ public class TaskQueryImpl implements TaskQuery {
public TaskQuery orderByWorkbasketName(SortDirection sortDirection) {
joinWithWorkbaskets = true;
addWorkbasketNameToSelectClauseForOrdering = true;
return DB.DB2.dbProductId.equals(getDatabaseId())
return DB.DB2 == getDB()
? addOrderCriteria("WNAME", sortDirection)
: addOrderCriteria("w.NAME", sortDirection);
}
@ -1934,7 +1934,7 @@ public class TaskQueryImpl implements TaskQuery {
@Override
public TaskQuery orderByOwnerLongName(SortDirection sortDirection) {
joinWithUserInfo = true;
return DB.isDb2(getDatabaseId())
return DB.DB2 == getDB()
? addOrderCriteria("ULONG_NAME", sortDirection)
: addOrderCriteria("u.LONG_NAME", sortDirection);
}
@ -2069,9 +2069,9 @@ public class TaskQueryImpl implements TaskQuery {
// optimized query for db2 can't be used for now in case of selectAndClaim because of temporary
// tables and the "for update" clause clashing in db2
private String getLinkToMapperScript() {
if (DB.isDb2(getDatabaseId()) && !selectAndClaim) {
if (DB.DB2 == getDB() && !selectAndClaim) {
return LINK_TO_MAPPER_DB2;
} else if (selectAndClaim && DB.isOracle(getDatabaseId())) {
} else if (selectAndClaim && DB.ORACLE == getDB()) {
return LINK_TO_MAPPER_ORACLE;
} else {
return LINK_TO_MAPPER;
@ -2079,7 +2079,7 @@ public class TaskQueryImpl implements TaskQuery {
}
private String getLinkToCounterTaskScript() {
return DB.isDb2(getDatabaseId()) ? LINK_TO_COUNTER_DB2 : LINK_TO_COUNTER;
return DB.DB2 == getDB() ? LINK_TO_COUNTER_DB2 : LINK_TO_COUNTER;
}
private void validateAllTimeIntervals(TimeInterval[] intervals) {
@ -2131,8 +2131,8 @@ public class TaskQueryImpl implements TaskQuery {
}
}
private String getDatabaseId() {
return this.taskanaEngine.getSqlSession().getConfiguration().getDatabaseId();
private DB getDB() {
return DB.getDB(this.taskanaEngine.getSqlSession().getConfiguration().getDatabaseId());
}
private void setupJoinAndOrderParameters() {

View File

@ -115,11 +115,11 @@ class TaskanaSecurityConfigAccTest {
try (Connection connection = DataSourceGenerator.getDataSource().getConnection()) {
String dbProductId = DB.getDatabaseProductId(connection);
DB db = DB.getDB(connection);
String sql;
final String securityFlagAsString;
if (DB.isOracle(dbProductId)) {
if (DB.ORACLE == db) {
securityFlagAsString = securityFlag ? "1" : "0";
} else {
securityFlagAsString = String.valueOf(securityFlag);

View File

@ -54,7 +54,7 @@ public class TestContainerExtension implements InvocationInterceptor {
String schemaName = determineSchemaName();
store.put(STORE_SCHEMA_NAME, schemaName);
store.put(STORE_DATA_SOURCE, DATA_SOURCE);
if (DB.isOracle(EXECUTION_DATABASE.dbProductId)) {
if (DB.ORACLE == EXECUTION_DATABASE) {
initOracleSchema(DATA_SOURCE, schemaName);
}
} else if (TaskanaEngineConfigurationModifier.class.isAssignableFrom(testClass)

View File

@ -31,7 +31,7 @@ public class TestConfiguration {
try (Connection connection = dataSource.getConnection()) {
LOGGER.debug(
"Using database of type {} with url '{}'",
DB.getDatabaseProductName(connection),
DB.getDB(connection).dbProductName,
connection.getMetaData().getURL());
} catch (SQLException e) {
LOGGER.error(e.getMessage(), e);

View File

@ -30,9 +30,9 @@ class SchemaNameCustomizableTest {
void resetDb() throws SQLException {
SampleDataGenerator sampleDataGenerator;
try (Connection connection = dataSource.getConnection()) {
String databaseProductId = DB.getDatabaseProductId(connection);
DB db = DB.getDB(connection);
if (DB.isPostgres(databaseProductId)) {
if (DB.POSTGRES == db) {
schemaName = schemaName.toLowerCase(Locale.ENGLISH);
}
}