TSK-447: taskana now supports postgresql

TSK-447: fixed bool<->integer problem with postgres


TSK-447: postgresql now working


TSK-477: now using h2 db again (taskana-rest-spring-example)
This commit is contained in:
Mustapha Zorgati 2018-04-30 17:09:08 +02:00
parent c2b0ba5daf
commit cf0921ba8d
22 changed files with 408 additions and 181 deletions

View File

@ -1,4 +1,4 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>pro.taskana</groupId>
@ -164,6 +164,12 @@
<version>1.4.196</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.ibm.db2.jcc</groupId>
<artifactId>db2jcc4</artifactId>

View File

@ -60,7 +60,7 @@ public interface TaskanaEngine {
* @param connection
* - The java.sql.Connection that is controlled by the client
*/
void setConnection(java.sql.Connection connection);
void setConnection(java.sql.Connection connection) throws java.sql.SQLException;
/**
* Closes the client's connection, sets it to null and switches to mode PARTICIPATE. Only applicable in mode
@ -68,20 +68,6 @@ public interface TaskanaEngine {
*/
void closeConnection();
/**
* Connection management mode. Controls the connection handling of taskana
* <ul>
* <li>PARTICIPATE - taskana participates in global transaction. This is the default mode</li>
* <li>AUTOCOMMIT - taskana commits each API call separately</li>
* <li>EXPLICIT - commit processing is managed explicitly by the client</li>
* </ul>
*/
enum ConnectionManagementMode {
PARTICIPATE,
AUTOCOMMIT,
EXPLICIT
}
/**
* check whether the current user is member of one of the roles specified.
*
@ -100,4 +86,18 @@ public interface TaskanaEngine {
* If the current user is not member of any specified role
*/
void checkRoleMembership(TaskanaRole... roles) throws NotAuthorizedException;
/**
* Connection management mode. Controls the connection handling of taskana
* <ul>
* <li>PARTICIPATE - taskana participates in global transaction. This is the default mode</li>
* <li>AUTOCOMMIT - taskana commits each API call separately</li>
* <li>EXPLICIT - commit processing is managed explicitly by the client</li>
* </ul>
*/
enum ConnectionManagementMode {
PARTICIPATE,
AUTOCOMMIT,
EXPLICIT
}
}

View File

@ -20,6 +20,7 @@ public class DbSchemaCreator {
private static final Logger LOGGER = LoggerFactory.getLogger(DbSchemaCreator.class);
private static final String SQL = "/sql";
private static final String DB_SCHEMA = SQL + "/taskana-schema.sql";
private static final String DB_SCHEMA_POSTGRES = SQL + "/taskana-schema-postgres.sql";
private static final String DB_SCHEMA_DETECTION = SQL + "/schema-detection.sql";
private DataSource dataSource;
private StringWriter outWriter = new StringWriter();
@ -32,6 +33,10 @@ public class DbSchemaCreator {
this.dataSource = dataSource;
}
private static String selectDbScriptFileName(String dbProductName) {
return "PostgreSQL".equals(dbProductName) ? DB_SCHEMA_POSTGRES : DB_SCHEMA;
}
/**
* Run all db scripts.
*
@ -48,7 +53,8 @@ public class DbSchemaCreator {
runner.setErrorLogWriter(errorLogWriter);
try {
if (!isSchemaPreexisting(runner)) {
runner.runScript(new InputStreamReader(this.getClass().getResourceAsStream(DB_SCHEMA)));
runner.runScript(new InputStreamReader(this.getClass()
.getResourceAsStream(selectDbScriptFileName(connection.getMetaData().getDatabaseProductName()))));
}
} finally {
runner.closeConnection();

View File

@ -1,5 +1,6 @@
package pro.taskana.impl;
import java.sql.SQLException;
import java.sql.SQLIntegrityConstraintViolationException;
import java.time.Duration;
import java.time.Instant;
@ -395,10 +396,8 @@ public class ClassificationServiceImpl implements ClassificationService {
}
private boolean isReferentialIntegrityConstraintViolation(PersistenceException e) {
return ((e.getCause().getClass().getName().equals("org.h2.jdbc.JdbcSQLException")
&& e.getMessage().contains("23503"))
|| (e.getCause() instanceof SQLIntegrityConstraintViolationException
&& e.getMessage().contains("-532")));
return e.getCause() instanceof SQLException && ((SQLException) e.getCause()).getSQLState().equals("23503")
|| e.getCause() instanceof SQLIntegrityConstraintViolationException && e.getMessage().contains("-532");
}
}

View File

@ -62,16 +62,56 @@ public class TaskanaEngineImpl implements TaskanaEngine {
protected ConnectionManagementMode mode = ConnectionManagementMode.PARTICIPATE;
protected java.sql.Connection connection = null;
public static TaskanaEngine createTaskanaEngine(TaskanaEngineConfiguration taskanaEngineConfiguration) {
return new TaskanaEngineImpl(taskanaEngineConfiguration);
}
protected TaskanaEngineImpl(TaskanaEngineConfiguration taskanaEngineConfiguration) {
this.taskanaEngineConfiguration = taskanaEngineConfiguration;
createTransactionFactory(taskanaEngineConfiguration.getUseManagedTransactions());
this.sessionManager = createSqlSessionManager();
}
public static TaskanaEngine createTaskanaEngine(TaskanaEngineConfiguration taskanaEngineConfiguration) {
return new TaskanaEngineImpl(taskanaEngineConfiguration);
}
/**
* With sessionStack, we maintain a Stack of SqlSessionManager objects on a per thread basis. SqlSessionManager is
* the MyBatis object that wraps database connections. The purpose of this stack is to keep track of nested calls.
* Each external API call is wrapped into taskanaEngineImpl.openConnection(); .....
* taskanaEngineImpl.returnConnection(); calls. In order to avoid duplicate opening / closing of connections, we use
* the sessionStack in the following way: Each time, an openConnection call is received, we push the current
* sessionManager onto the stack. On the first call to openConnection, we call sessionManager.startManagedSession()
* to open a database connection. On each call to returnConnection() we pop one instance of sessionManager from the
* stack. When the stack becomes empty, we close the database connection by calling sessionManager.close()
*
* @return Stack of SqlSessionManager
*/
protected static Deque<SqlSessionManager> getSessionStack() {
Deque<SqlSessionManager> stack = sessionStack.get();
if (stack == null) {
stack = new ArrayDeque<>();
sessionStack.set(stack);
}
return stack;
}
protected static SqlSessionManager getSessionFromStack() {
Deque<SqlSessionManager> stack = getSessionStack();
if (stack.isEmpty()) {
return null;
}
return stack.peek();
}
protected static void pushSessionToStack(SqlSessionManager session) {
getSessionStack().push(session);
}
protected static void popSessionFromStack() {
Deque<SqlSessionManager> stack = getSessionStack();
if (!stack.isEmpty()) {
stack.pop();
}
}
@Override
public TaskService getTaskService() {
SqlSession session = this.sessionManager;
@ -140,17 +180,15 @@ public class TaskanaEngineImpl implements TaskanaEngine {
* The connection that passed into TaskanaEngine
*/
@Override
public void setConnection(java.sql.Connection connection) {
public void setConnection(java.sql.Connection connection) throws SQLException {
if (connection != null) {
this.connection = connection;
// disabling auto commit for passed connection in order to gain full control over the connection management
connection.setAutoCommit(false);
mode = ConnectionManagementMode.EXPLICIT;
sessionManager.startManagedSession(connection);
} else if (this.connection != null) {
this.connection = null;
if (sessionManager.isManagedSessionStarted()) {
sessionManager.close();
}
mode = ConnectionManagementMode.PARTICIPATE;
closeConnection();
}
}
@ -291,6 +329,8 @@ public class TaskanaEngineImpl implements TaskanaEngine {
configuration.setDatabaseId("db2");
} else if (databaseProductName.contains("H2")) {
configuration.setDatabaseId("h2");
} else if (databaseProductName.equals("PostgreSQL")) {
configuration.setDatabaseId("postgres");
} else {
LOGGER.error(
"Method createSqlSessionManager() didn't find database with name {}. Throwing UnsupportedDatabaseException",
@ -335,46 +375,6 @@ public class TaskanaEngineImpl implements TaskanaEngine {
}
}
/**
* With sessionStack, we maintain a Stack of SqlSessionManager objects on a per thread basis. SqlSessionManager is
* the MyBatis object that wraps database connections. The purpose of this stack is to keep track of nested calls.
* Each external API call is wrapped into taskanaEngineImpl.openConnection(); .....
* taskanaEngineImpl.returnConnection(); calls. In order to avoid duplicate opening / closing of connections, we use
* the sessionStack in the following way: Each time, an openConnection call is received, we push the current
* sessionManager onto the stack. On the first call to openConnection, we call sessionManager.startManagedSession()
* to open a database connection. On each call to returnConnection() we pop one instance of sessionManager from the
* stack. When the stack becomes empty, we close the database connection by calling sessionManager.close()
*
* @return Stack of SqlSessionManager
*/
protected static Deque<SqlSessionManager> getSessionStack() {
Deque<SqlSessionManager> stack = sessionStack.get();
if (stack == null) {
stack = new ArrayDeque<>();
sessionStack.set(stack);
}
return stack;
}
protected static SqlSessionManager getSessionFromStack() {
Deque<SqlSessionManager> stack = getSessionStack();
if (stack.isEmpty()) {
return null;
}
return stack.peek();
}
protected static void pushSessionToStack(SqlSessionManager session) {
getSessionStack().push(session);
}
protected static void popSessionFromStack() {
Deque<SqlSessionManager> stack = getSessionStack();
if (!stack.isEmpty()) {
stack.pop();
}
}
/**
* Returns true if the given domain does exist in the configuration.
*

View File

@ -1,7 +1,6 @@
package pro.taskana.impl.persistence;
import java.sql.CallableStatement;
import java.sql.Clob;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
@ -30,9 +29,7 @@ public class MapTypeHandler extends BaseTypeHandler<Map> {
LOGGER.debug("Input-Map before serializing: ", parameter);
// Convert Map to JSON string
JSONObject jsonObj = new JSONObject(parameter);
Clob content = ps.getConnection().createClob();
content.setString(1, jsonObj.toString());
ps.setClob(i, content);
ps.setString(i, jsonObj.toString());
} else {
ps.setNull(i, Types.BLOB);
}
@ -40,36 +37,34 @@ public class MapTypeHandler extends BaseTypeHandler<Map> {
@Override
public Map getNullableResult(ResultSet rs, String columnName) throws SQLException {
Clob fieldValue = rs.getClob(columnName);
String fieldValue = rs.getString(columnName);
if (fieldValue != null) {
return convertClobToMap(fieldValue);
return convertToMap(fieldValue);
}
return null;
}
@Override
public Map getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
Clob fieldValue = rs.getClob(columnIndex);
String fieldValue = rs.getString(columnIndex);
if (fieldValue != null) {
return convertClobToMap(fieldValue);
return convertToMap(fieldValue);
}
return null;
}
@Override
public Map getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
Clob fieldValue = cs.getClob(columnIndex);
String fieldValue = cs.getString(columnIndex);
if (fieldValue != null) {
return convertClobToMap(fieldValue);
return convertToMap(fieldValue);
}
return null;
}
private Map convertClobToMap(Clob fieldValue) throws SQLException {
String content = fieldValue.getSubString(1L, (int) fieldValue.length());
JSONObject jsonObj = new JSONObject(content);
Map result = jsonObj.toMap();
return result;
private Map convertToMap(String fieldValue) throws SQLException {
JSONObject jsonObj = new JSONObject(fieldValue);
return jsonObj.toMap();
}
}

View File

@ -11,7 +11,6 @@ import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import org.apache.ibatis.type.ClobTypeHandler;
import org.apache.ibatis.type.JdbcType;
import pro.taskana.impl.AttachmentImpl;
import pro.taskana.impl.AttachmentSummaryImpl;
@ -46,7 +45,7 @@ public interface AttachmentMapper {
@Result(property = "objectReference.value", column = "REF_VALUE"),
@Result(property = "channel", column = "CHANNEL"),
@Result(property = "received", column = "RECEIVED"),
@Result(property = "customAttributes", column = "CUSTOM_ATTRIBUTES", jdbcType = JdbcType.CLOB,
@Result(property = "customAttributes", column = "CUSTOM_ATTRIBUTES",
javaType = Map.class, typeHandler = MapTypeHandler.class)
})
List<AttachmentImpl> findAttachmentsByTaskId(@Param("taskId") String taskId);
@ -70,7 +69,7 @@ public interface AttachmentMapper {
@Result(property = "objectReference.value", column = "REF_VALUE"),
@Result(property = "channel", column = "CHANNEL"),
@Result(property = "received", column = "RECEIVED"),
@Result(property = "customAttributes", column = "CUSTOM_ATTRIBUTES", jdbcType = JdbcType.CLOB,
@Result(property = "customAttributes", column = "CUSTOM_ATTRIBUTES",
javaType = Map.class, typeHandler = MapTypeHandler.class)
})
AttachmentImpl getAttachment(@Param("attachmentId") String attachmentId);
@ -107,7 +106,7 @@ public interface AttachmentMapper {
+ "<if test=\"_databaseId == 'db2'\">with UR </if> "
+ "</script>")
@Results(value = {
@Result(property = "customAttributes", column = "CUSTOM_ATTRIBUTES", jdbcType = JdbcType.CLOB,
@Result(property = "customAttributes", column = "CUSTOM_ATTRIBUTES",
javaType = String.class, typeHandler = ClobTypeHandler.class)
})
String getCustomAttributesAsString(@Param("attachmentId") String attachmentId);

View File

@ -9,7 +9,6 @@ import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import org.apache.ibatis.type.JdbcType;
import pro.taskana.impl.Job;
import pro.taskana.impl.persistence.MapTypeHandler;
@ -19,8 +18,19 @@ import pro.taskana.impl.persistence.MapTypeHandler;
*/
public interface JobMapper {
@Insert("INSERT INTO TASKANA.JOB (JOB_ID, CREATED, STARTED, COMPLETED, STATE, EXECUTOR, ARGUMENTS) "
+ "VALUES (NEXT VALUE FOR TASKANA.JOB_SEQ, #{job.created}, #{job.started}, #{job.completed}, #{job.state}, #{job.executor}, #{job.arguments,jdbcType=CLOB, javaType=java.util.Map,typeHandler=pro.taskana.impl.persistence.MapTypeHandler} )")
@Insert("<script>"
+ "INSERT INTO TASKANA.JOB (JOB_ID, CREATED, STARTED, COMPLETED, STATE, EXECUTOR, ARGUMENTS) "
+ "VALUES ("
+ "<choose>"
+ "<when test=\"_databaseId == 'db2'\">"
+ "NEXT VALUE FOR TASKANA.JOB_SEQ"
+ "</when>"
+ "<otherwise>"
+ "nextval('TASKANA.JOB_SEQ')"
+ "</otherwise>"
+ "</choose>"
+ ", #{job.created}, #{job.started}, #{job.completed}, #{job.state}, #{job.executor}, #{job.arguments,javaType=java.util.Map,typeHandler=pro.taskana.impl.persistence.MapTypeHandler} )"
+ "</script>")
void insertJob(@Param("job") Job job);
@Select("SELECT JOB_ID, CREATED, STARTED, COMPLETED, STATE, EXECUTOR, ARGUMENTS "
@ -34,7 +44,7 @@ public interface JobMapper {
@Result(property = "completed", column = "COMPLETED"),
@Result(property = "state", column = "STATE"),
@Result(property = "executor", column = "EXECUTOR"),
@Result(property = "arguments", column = "ARGUMENTS", jdbcType = JdbcType.CLOB,
@Result(property = "arguments", column = "ARGUMENTS",
javaType = Map.class, typeHandler = MapTypeHandler.class)
})
List<Job> findJobsToRun();

View File

@ -32,9 +32,9 @@ public interface QueryMapper {
+ "<where>"
+ "<if test='accessIdIn != null'> "
+ "AND t.WORKBASKET_ID IN ( "
+ "select WID from (select WORKBASKET_ID as WID, max(PERM_READ) as MAX_READ FROM TASKANA.WORKBASKET_ACCESS_LIST where "
+ "SELECT WID from (SELECT WORKBASKET_ID as WID, MAX(PERM_READ::int) as MAX_READ FROM TASKANA.WORKBASKET_ACCESS_LIST AS s where "
+ "ACCESS_ID IN (<foreach item='item' collection='accessIdIn' separator=',' >#{item}</foreach>) "
+ "group by WORKBASKET_ID ) where max_read = 1 ) "
+ "group by WORKBASKET_ID ) AS f where max_read = 1 ) "
+ "</if> "
+ "<if test='taskIds != null'>AND t.ID IN(<foreach item='item' collection='taskIds' separator=',' >#{item}</foreach>)</if> "
+ "<if test='createdIn !=null'> AND ( <foreach item='item' collection='createdIn' separator=' OR ' > ( <if test='item.begin!=null'> t.CREATED &gt;= #{item.begin} </if> <if test='item.begin!=null and item.end!=null'> AND </if><if test='item.end!=null'> t.CREATED &lt;=#{item.end} </if>)</foreach>)</if> "
@ -234,10 +234,10 @@ public interface QueryMapper {
+ "SELECT DISTINCT "
+ "w.ID, w.KEY, w.NAME, w.DOMAIN, W.TYPE, w.DESCRIPTION, w.OWNER, w.ORG_LEVEL_1, w.ORG_LEVEL_2, w.ORG_LEVEL_3, w.ORG_LEVEL_4 from TASKANA.WORKBASKET w "
+ "<if test = 'joinWithAccessList'> "
+ "LEFT OUTER JOIN (select WORKBASKET_ID as WID, max(PERM_READ) as MAX_READ, max(PERM_OPEN) as MAX_OPEN, "
+ "MAX(PERM_APPEND) as MAX_APPEND, MAX(PERM_TRANSFER) as MAX_TRANSFER, MAX(PERM_DISTRIBUTE) as MAX_DISTRIBUTE, MAX(PERM_CUSTOM_1) as MAX_CUSTOM_1, MAX(PERM_CUSTOM_2) as MAX_CUSTOM_2, "
+ "MAX(PERM_CUSTOM_3) as MAX_CUSTOM_3, MAX(PERM_CUSTOM_4) as MAX_CUSTOM_4, MAX(PERM_CUSTOM_5) as MAX_CUSTOM_5, MAX(PERM_CUSTOM_6) as MAX_CUSTOM_6, MAX(PERM_CUSTOM_7) as MAX_CUSTOM_7, "
+ "MAX(PERM_CUSTOM_8) as MAX_CUSTOM_8, MAX(PERM_CUSTOM_9) as MAX_CUSTOM_9, MAX(PERM_CUSTOM_10) as MAX_CUSTOM_10, MAX(PERM_CUSTOM_11) as MAX_CUSTOM_11, MAX(PERM_CUSTOM_12) as MAX_CUSTOM_12 "
+ "LEFT OUTER JOIN (select WORKBASKET_ID as WID, MAX(PERM_READ::int) as MAX_READ, MAX(PERM_OPEN::int) as MAX_OPEN, "
+ "MAX(PERM_APPEND::int) as MAX_APPEND, MAX(PERM_TRANSFER::int) as MAX_TRANSFER, MAX(PERM_DISTRIBUTE::int) as MAX_DISTRIBUTE, MAX(PERM_CUSTOM_1::int) as MAX_CUSTOM_1, MAX(PERM_CUSTOM_2::int) as MAX_CUSTOM_2, "
+ "MAX(PERM_CUSTOM_3::int) as MAX_CUSTOM_3, MAX(PERM_CUSTOM_4::int) as MAX_CUSTOM_4, MAX(PERM_CUSTOM_5::int) as MAX_CUSTOM_5, MAX(PERM_CUSTOM_6::int) as MAX_CUSTOM_6, MAX(PERM_CUSTOM_7::int) as MAX_CUSTOM_7, "
+ "MAX(PERM_CUSTOM_8::int) as MAX_CUSTOM_8, MAX(PERM_CUSTOM_9::int) as MAX_CUSTOM_9, MAX(PERM_CUSTOM_10::int) as MAX_CUSTOM_10, MAX(PERM_CUSTOM_11::int) as MAX_CUSTOM_11, MAX(PERM_CUSTOM_12::int) as MAX_CUSTOM_12 "
+ "FROM TASKANA.WORKBASKET_ACCESS_LIST where ACCESS_ID IN (<if test='accessId != null'><foreach item='item' collection='accessId' separator=',' >#{item}</foreach></if>) group by WORKBASKET_ID ) a "
+ "on (w.ID = a.WID)"
+ "</if> "
@ -357,9 +357,9 @@ public interface QueryMapper {
+ "<where>"
+ "<if test='accessIdIn != null'> "
+ "AND t.WORKBASKET_ID IN ( "
+ "select WID from (select WORKBASKET_ID as WID, max(PERM_READ) as MAX_READ FROM TASKANA.WORKBASKET_ACCESS_LIST where "
+ "select WID from (select WORKBASKET_ID as WID, MAX(PERM_READ::int) as MAX_READ FROM TASKANA.WORKBASKET_ACCESS_LIST AS s where "
+ "ACCESS_ID IN (<foreach item='item' collection='accessIdIn' separator=',' >#{item}</foreach>) "
+ "group by WORKBASKET_ID ) where max_read = 1 ) "
+ "group by WORKBASKET_ID ) AS f where max_read = 1 ) "
+ "</if> "
+ "<if test='taskIds != null'>AND t.ID IN(<foreach item='item' collection='taskIds' separator=',' >#{item}</foreach>)</if> "
+ "<if test='createdIn !=null'> AND ( <foreach item='item' collection='createdIn' separator=' OR ' > ( <if test='item.begin!=null'> t.CREATED &gt;= #{item.begin} </if> <if test='item.begin!=null and item.end!=null'> AND </if><if test='item.end!=null'> t.CREATED &lt;=#{item.end} </if>)</foreach>)</if> "
@ -493,10 +493,10 @@ public interface QueryMapper {
@Select("<script>"
+ "SELECT COUNT(w.ID) from TASKANA.WORKBASKET w "
+ "<if test = 'joinWithAccessList'> "
+ "LEFT OUTER JOIN (select WORKBASKET_ID as WID, max(PERM_READ) as MAX_READ, max(PERM_OPEN) as MAX_OPEN, "
+ "MAX(PERM_APPEND) as MAX_APPEND, MAX(PERM_TRANSFER) as MAX_TRANSFER, MAX(PERM_DISTRIBUTE) as MAX_DISTRIBUTE, MAX(PERM_CUSTOM_1) as MAX_CUSTOM_1, MAX(PERM_CUSTOM_2) as MAX_CUSTOM_2, "
+ "MAX(PERM_CUSTOM_3) as MAX_CUSTOM_3, MAX(PERM_CUSTOM_4) as MAX_CUSTOM_4, MAX(PERM_CUSTOM_5) as MAX_CUSTOM_5, MAX(PERM_CUSTOM_6) as MAX_CUSTOM_6, MAX(PERM_CUSTOM_7) as MAX_CUSTOM_7, "
+ "MAX(PERM_CUSTOM_8) as MAX_CUSTOM_8, MAX(PERM_CUSTOM_9) as MAX_CUSTOM_9, MAX(PERM_CUSTOM_10) as MAX_CUSTOM_10, MAX(PERM_CUSTOM_11) as MAX_CUSTOM_11, MAX(PERM_CUSTOM_12) as MAX_CUSTOM_12 "
+ "LEFT OUTER JOIN (select WORKBASKET_ID as WID, MAX(PERM_READ::int) as MAX_READ, MAX(PERM_OPEN::int) as MAX_OPEN, "
+ "MAX(PERM_APPEND::int) as MAX_APPEND, MAX(PERM_TRANSFER::int) as MAX_TRANSFER, MAX(PERM_DISTRIBUTE::int) as MAX_DISTRIBUTE, MAX(PERM_CUSTOM_1::int) as MAX_CUSTOM_1, MAX(PERM_CUSTOM_2::int) as MAX_CUSTOM_2, "
+ "MAX(PERM_CUSTOM_3::int) as MAX_CUSTOM_3, MAX(PERM_CUSTOM_4::int) as MAX_CUSTOM_4, MAX(PERM_CUSTOM_5::int) as MAX_CUSTOM_5, MAX(PERM_CUSTOM_6::int) as MAX_CUSTOM_6, MAX(PERM_CUSTOM_7::int) as MAX_CUSTOM_7, "
+ "MAX(PERM_CUSTOM_8::int) as MAX_CUSTOM_8, MAX(PERM_CUSTOM_9::int) as MAX_CUSTOM_9, MAX(PERM_CUSTOM_10::int) as MAX_CUSTOM_10, MAX(PERM_CUSTOM_11::int) as MAX_CUSTOM_11, MAX(PERM_CUSTOM_12::int) as MAX_CUSTOM_12 "
+ "FROM TASKANA.WORKBASKET_ACCESS_LIST where ACCESS_ID IN (<if test='accessId != null'><foreach item='item' collection='accessId' separator=',' >#{item}</foreach></if>) group by WORKBASKET_ID ) a "
+ "on (w.ID = a.WID)"
+ "</if> "
@ -577,7 +577,7 @@ public interface QueryMapper {
+ "<where>"
+ "<if test='accessIdIn != null'> "
+ "AND t.WORKBASKET_ID IN ( "
+ "select WID from (select WORKBASKET_ID as WID, max(PERM_READ) as MAX_READ FROM TASKANA.WORKBASKET_ACCESS_LIST where "
+ "select WID from (select WORKBASKET_ID as WID, MAX(PERM_READ) as MAX_READ FROM TASKANA.WORKBASKET_ACCESS_LIST where "
+ "ACCESS_ID IN (<foreach item='item' collection='accessIdIn' separator=',' >#{item}</foreach>) "
+ "group by WORKBASKET_ID ) where max_read = 1 ) "
+ "</if> "
@ -717,10 +717,10 @@ public interface QueryMapper {
@Select("<script>SELECT DISTINCT ${columnName} "
+ "FROM TASKANA.WORKBASKET w "
+ "<if test = 'joinWithAccessList'> "
+ "LEFT OUTER JOIN (select WORKBASKET_ID as WID, max(PERM_READ) as MAX_READ, max(PERM_OPEN) as MAX_OPEN, "
+ "MAX(PERM_APPEND) as MAX_APPEND, MAX(PERM_TRANSFER) as MAX_TRANSFER, MAX(PERM_DISTRIBUTE) as MAX_DISTRIBUTE, MAX(PERM_CUSTOM_1) as MAX_CUSTOM_1, MAX(PERM_CUSTOM_2) as MAX_CUSTOM_2, "
+ "MAX(PERM_CUSTOM_3) as MAX_CUSTOM_3, MAX(PERM_CUSTOM_4) as MAX_CUSTOM_4, MAX(PERM_CUSTOM_5) as MAX_CUSTOM_5, MAX(PERM_CUSTOM_6) as MAX_CUSTOM_6, MAX(PERM_CUSTOM_7) as MAX_CUSTOM_7, "
+ "MAX(PERM_CUSTOM_8) as MAX_CUSTOM_8, MAX(PERM_CUSTOM_9) as MAX_CUSTOM_9, MAX(PERM_CUSTOM_10) as MAX_CUSTOM_10, MAX(PERM_CUSTOM_11) as MAX_CUSTOM_11, MAX(PERM_CUSTOM_12) as MAX_CUSTOM_12 "
+ "LEFT OUTER JOIN (select WORKBASKET_ID as WID, MAX(PERM_READ::int) as MAX_READ, MAX(PERM_OPEN::int) as MAX_OPEN, "
+ "MAX(PERM_APPEND::int) as MAX_APPEND, MAX(PERM_TRANSFER::int) as MAX_TRANSFER, MAX(PERM_DISTRIBUTE::int) as MAX_DISTRIBUTE, MAX(PERM_CUSTOM_1::int) as MAX_CUSTOM_1, MAX(PERM_CUSTOM_2::int) as MAX_CUSTOM_2, "
+ "MAX(PERM_CUSTOM_3::int) as MAX_CUSTOM_3, MAX(PERM_CUSTOM_4::int) as MAX_CUSTOM_4, MAX(PERM_CUSTOM_5::int) as MAX_CUSTOM_5, MAX(PERM_CUSTOM_6::int) as MAX_CUSTOM_6, MAX(PERM_CUSTOM_7::int) as MAX_CUSTOM_7, "
+ "MAX(PERM_CUSTOM_8::int) as MAX_CUSTOM_8, MAX(PERM_CUSTOM_9::int) as MAX_CUSTOM_9, MAX(PERM_CUSTOM_10::int) as MAX_CUSTOM_10, MAX(PERM_CUSTOM_11::int) as MAX_CUSTOM_11, MAX(PERM_CUSTOM_12::int) as MAX_CUSTOM_12 "
+ "FROM TASKANA.WORKBASKET_ACCESS_LIST where ACCESS_ID IN (<if test='accessId != null'><foreach item='item' collection='accessId' separator=',' >#{item}</foreach></if>) group by WORKBASKET_ID ) a "
+ "on (w.ID = a.WID)"
+ "</if> "
@ -779,7 +779,15 @@ public interface QueryMapper {
+ "<if test=\"permission.name() == 'CUSTOM_9'\">a.MAX_CUSTOM_9</if>"
+ "<if test=\"permission.name() == 'CUSTOM_10'\">a.MAX_CUSTOM_10</if>"
+ "<if test=\"permission.name() == 'CUSTOM_11'\">a.MAX_CUSTOM_11</if>"
+ "<if test=\"permission.name() == 'CUSTOM_12'\">a.MAX_CUSTOM_12</if> = 1 "
+ "<if test=\"permission.name() == 'CUSTOM_12'\">a.MAX_CUSTOM_12</if>"
+ "<choose>"
+ "<when test=\"_databaseId == 'postgres'\">"
+ "= TRUE "
+ "</when>"
+ "<otherwise>"
+ "= 1 "
+ "</otherwise>"
+ "</choose>"
+ "</if>)"
+ "</if>"
+ "</where>"

View File

@ -11,7 +11,6 @@ import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import org.apache.ibatis.type.JdbcType;
import pro.taskana.impl.MinimalTaskSummary;
import pro.taskana.impl.TaskImpl;
@ -59,9 +58,9 @@ public interface TaskMapper {
@Result(property = "primaryObjRef.value", column = "POR_VALUE"),
@Result(property = "isRead", column = "IS_READ"),
@Result(property = "isTransferred", column = "IS_TRANSFERRED"),
@Result(property = "callbackInfo", column = "CALLBACK_INFO", jdbcType = JdbcType.CLOB,
@Result(property = "callbackInfo", column = "CALLBACK_INFO",
javaType = Map.class, typeHandler = MapTypeHandler.class),
@Result(property = "customAttributes", column = "CUSTOM_ATTRIBUTES", jdbcType = JdbcType.CLOB,
@Result(property = "customAttributes", column = "CUSTOM_ATTRIBUTES",
javaType = Map.class, typeHandler = MapTypeHandler.class),
@Result(property = "custom1", column = "CUSTOM_1"),
@Result(property = "custom2", column = "CUSTOM_2"),
@ -184,7 +183,9 @@ public interface TaskMapper {
@Param("referencetask") TaskSummaryImpl referencetask);
@Select("<script>SELECT ID, STATE, WORKBASKET_ID FROM TASKANA.TASK "
+ "WHERE ID IN(<foreach item='item' collection='taskIds' separator=',' >#{item}</foreach>) "
+ "<if test=\" taskIds != null and !taskIds.isEmpty() \">"
+ "WHERE ID IN( <foreach item='item' collection='taskIds' separator=',' >#{item}</foreach> ) "
+ "</if>"
+ "<if test=\"_databaseId == 'db2'\">with UR </if> "
+ "</script>")
@Results(value = {

View File

@ -23,6 +23,7 @@ public interface TaskMonitorMapper {
@Select("<script>"
+ "<if test=\"_databaseId == 'db2'\">SELECT WORKBASKET_KEY, (DAYS(DUE) - DAYS(CURRENT_TIMESTAMP)) as AGE_IN_DAYS, COUNT(*) as NUMBER_OF_TASKS</if> "
+ "<if test=\"_databaseId == 'h2'\">SELECT WORKBASKET_KEY, DATEDIFF('DAY', CURRENT_TIMESTAMP, DUE) as AGE_IN_DAYS, COUNT(*) as NUMBER_OF_TASKS</if> "
+ "<if test=\"_databaseId == 'postgres'\">SELECT WORKBASKET_KEY, DATE_PART('DAY', DUE - CURRENT_TIMESTAMP) as AGE_IN_DAYS, COUNT(*) as NUMBER_OF_TASKS</if> "
+ "FROM TASKANA.TASK "
+ "<where>"
+ "<if test=\"workbasketIds != null\">"
@ -44,6 +45,7 @@ public interface TaskMonitorMapper {
+ "</where>"
+ "<if test=\"_databaseId == 'db2'\">GROUP BY WORKBASKET_KEY, (DAYS(DUE) - DAYS(CURRENT_TIMESTAMP))</if> "
+ "<if test=\"_databaseId == 'h2'\">GROUP BY WORKBASKET_KEY, DATEDIFF('DAY', CURRENT_TIMESTAMP, DUE)</if> "
+ "<if test=\"_databaseId == 'postgres'\">GROUP BY WORKBASKET_KEY, DATE_PART('DAY', DUE - CURRENT_TIMESTAMP)</if> "
+ "<if test=\"_databaseId == 'db2'\">with UR </if> "
+ "</script>")
@Results({
@ -60,6 +62,7 @@ public interface TaskMonitorMapper {
@Select("<script>"
+ "<if test=\"_databaseId == 'db2'\">SELECT CLASSIFICATION_CATEGORY, (DAYS(DUE) - DAYS(CURRENT_TIMESTAMP)) as AGE_IN_DAYS, COUNT(*) as NUMBER_OF_TASKS</if> "
+ "<if test=\"_databaseId == 'h2'\">SELECT CLASSIFICATION_CATEGORY, DATEDIFF('DAY', CURRENT_TIMESTAMP, DUE) as AGE_IN_DAYS, COUNT(*) as NUMBER_OF_TASKS</if> "
+ "<if test=\"_databaseId == 'postgres'\">SELECT CLASSIFICATION_CATEGORY, DATE_PART('DAY', DUE - CURRENT_TIMESTAMP) as AGE_IN_DAYS, COUNT(*) as NUMBER_OF_TASKS</if> "
+ "FROM TASKANA.TASK "
+ "<where>"
+ "<if test=\"workbasketIds != null\">"
@ -81,6 +84,7 @@ public interface TaskMonitorMapper {
+ "</where>"
+ "<if test=\"_databaseId == 'db2'\">GROUP BY CLASSIFICATION_CATEGORY, (DAYS(DUE) - DAYS(CURRENT_TIMESTAMP))</if> "
+ "<if test=\"_databaseId == 'h2'\">GROUP BY CLASSIFICATION_CATEGORY, DATEDIFF('DAY', CURRENT_TIMESTAMP, DUE)</if> "
+ "<if test=\"_databaseId == 'postgres'\">GROUP BY CLASSIFICATION_CATEGORY, DATE_PART('DAY', DUE - CURRENT_TIMESTAMP)</if> "
+ "<if test=\"_databaseId == 'db2'\">with UR </if> "
+ "</script>")
@Results({
@ -97,6 +101,7 @@ public interface TaskMonitorMapper {
@Select("<script>"
+ "<if test=\"_databaseId == 'db2'\">SELECT CLASSIFICATION_KEY, (DAYS(DUE) - DAYS(CURRENT_TIMESTAMP)) as AGE_IN_DAYS, COUNT(*) as NUMBER_OF_TASKS</if> "
+ "<if test=\"_databaseId == 'h2'\">SELECT CLASSIFICATION_KEY, DATEDIFF('DAY', CURRENT_TIMESTAMP, DUE) as AGE_IN_DAYS, COUNT(*) as NUMBER_OF_TASKS</if> "
+ "<if test=\"_databaseId == 'postgres'\">SELECT CLASSIFICATION_KEY, DATE_PART('DAY', DUE - CURRENT_TIMESTAMP) as AGE_IN_DAYS, COUNT(*) as NUMBER_OF_TASKS</if> "
+ "FROM TASKANA.TASK "
+ "<where>"
+ "<if test=\"workbasketIds != null\">"
@ -118,6 +123,7 @@ public interface TaskMonitorMapper {
+ "</where>"
+ "<if test=\"_databaseId == 'db2'\">GROUP BY CLASSIFICATION_KEY, (DAYS(DUE) - DAYS(CURRENT_TIMESTAMP))</if> "
+ "<if test=\"_databaseId == 'h2'\">GROUP BY CLASSIFICATION_KEY, DATEDIFF('DAY', CURRENT_TIMESTAMP, DUE)</if> "
+ "<if test=\"_databaseId == 'postgres'\">GROUP BY CLASSIFICATION_KEY, DATE_PART('DAY', DUE - CURRENT_TIMESTAMP)</if> "
+ "<if test=\"_databaseId == 'db2'\">with UR </if> "
+ "</script>")
@Results({
@ -134,6 +140,7 @@ public interface TaskMonitorMapper {
@Select("<script>"
+ "<if test=\"_databaseId == 'db2'\">SELECT T.CLASSIFICATION_KEY as TASK_CLASSIFICATION_KEY, A.CLASSIFICATION_KEY as ATTACHMENT_CLASSIFICATION_KEY, (DAYS(DUE) - DAYS(CURRENT_TIMESTAMP)) as AGE_IN_DAYS, COUNT(*) as NUMBER_OF_TASKS</if> "
+ "<if test=\"_databaseId == 'h2'\">SELECT T.CLASSIFICATION_KEY as TASK_CLASSIFICATION_KEY, A.CLASSIFICATION_KEY as ATTACHMENT_CLASSIFICATION_KEY, DATEDIFF('DAY', CURRENT_TIMESTAMP, DUE) as AGE_IN_DAYS, COUNT(*) as NUMBER_OF_TASKS</if> "
+ "<if test=\"_databaseId == 'postgres'\">SELECT T.CLASSIFICATION_KEY as TASK_CLASSIFICATION_KEY, A.CLASSIFICATION_KEY as ATTACHMENT_CLASSIFICATION_KEY, DATE_PART('DAY', DUE - CURRENT_TIMESTAMP) as AGE_IN_DAYS, COUNT(*) as NUMBER_OF_TASKS</if> "
+ "FROM TASKANA.TASK AS T LEFT JOIN TASKANA.ATTACHMENT AS A ON T.ID = A.TASK_ID "
+ "<where>"
+ "<if test=\"workbasketIds != null\">"
@ -155,6 +162,7 @@ public interface TaskMonitorMapper {
+ "</where>"
+ "<if test=\"_databaseId == 'db2'\">GROUP BY T.CLASSIFICATION_KEY, A.CLASSIFICATION_KEY, (DAYS(DUE) - DAYS(CURRENT_TIMESTAMP))</if> "
+ "<if test=\"_databaseId == 'h2'\">GROUP BY T.CLASSIFICATION_KEY, A.CLASSIFICATION_KEY, DATEDIFF('DAY', CURRENT_TIMESTAMP, DUE)</if> "
+ "<if test=\"_databaseId == 'postgres'\">GROUP BY T.CLASSIFICATION_KEY, A.CLASSIFICATION_KEY, DATE_PART('DAY', DUE - CURRENT_TIMESTAMP)</if> "
+ "<if test=\"_databaseId == 'db2'\">with UR </if> "
+ "</script>")
@Results({
@ -173,6 +181,7 @@ public interface TaskMonitorMapper {
@Select("<script>"
+ "<if test=\"_databaseId == 'db2'\">SELECT ${customField} as CUSTOM_FIELD, (DAYS(DUE) - DAYS(CURRENT_TIMESTAMP)) as AGE_IN_DAYS, COUNT(*) as NUMBER_OF_TASKS</if> "
+ "<if test=\"_databaseId == 'h2'\">SELECT ${customField} as CUSTOM_FIELD, DATEDIFF('DAY', CURRENT_TIMESTAMP, DUE) as AGE_IN_DAYS, COUNT(*) as NUMBER_OF_TASKS</if> "
+ "<if test=\"_databaseId == 'postgres'\">SELECT ${customField} as CUSTOM_FIELD, DATE_PART('DAY', DUE - CURRENT_TIMESTAMP) as AGE_IN_DAYS, COUNT(*) as NUMBER_OF_TASKS</if> "
+ "FROM TASKANA.TASK "
+ "<where>"
+ "<if test=\"workbasketIds != null\">"
@ -194,6 +203,7 @@ public interface TaskMonitorMapper {
+ "</where>"
+ "<if test=\"_databaseId == 'db2'\">GROUP BY ${customField}, (DAYS(DUE) - DAYS(CURRENT_TIMESTAMP))</if> "
+ "<if test=\"_databaseId == 'h2'\">GROUP BY ${customField}, DATEDIFF('DAY', CURRENT_TIMESTAMP, DUE)</if> "
+ "<if test=\"_databaseId == 'postgres'\">GROUP BY ${customField}, DATE_PART('DAY', DUE - CURRENT_TIMESTAMP)</if> "
+ "<if test=\"_databaseId == 'db2'\">with UR </if> "
+ "</script>")
@Results({
@ -248,6 +258,10 @@ public interface TaskMonitorMapper {
+ "#{selectedItem.upperAgeLimit} >= DATEDIFF('DAY', CURRENT_TIMESTAMP, DUE) AND "
+ "#{selectedItem.lowerAgeLimit} &lt;= DATEDIFF('DAY', CURRENT_TIMESTAMP, DUE) "
+ "</if> "
+ "<if test=\"_databaseId == 'postgres'\">"
+ "#{selectedItem.upperAgeLimit} >= DATE_PART('day', DUE - CURRENT_TIMESTAMP ) AND "
+ "#{selectedItem.lowerAgeLimit} &lt;= DATE_PART('day', DUE - CURRENT_TIMESTAMP ) "
+ "</if> "
+ "</foreach>) "
+ "</where>"
+ "<if test=\"_databaseId == 'db2'\">with UR </if> "

View File

@ -90,7 +90,8 @@ public interface WorkbasketAccessMapper {
@Delete("DELETE FROM TASKANA.WORKBASKET_ACCESS_LIST where ACCESS_ID = #{accessId}")
void deleteAccessItemsForAccessId(@Param("accessId") String accessId);
@Select("<script>SELECT MAX(PERM_READ) AS P_READ, MAX(PERM_OPEN) AS P_OPEN, MAX(PERM_APPEND) AS P_APPEND, MAX(PERM_TRANSFER) AS P_TRANSFER, MAX(PERM_DISTRIBUTE) AS P_DISTRIBUTE, MAX(PERM_CUSTOM_1) AS P_CUSTOM_1, MAX(PERM_CUSTOM_2) AS P_CUSTOM_2, MAX(PERM_CUSTOM_3) AS P_CUSTOM_3, MAX(PERM_CUSTOM_4) AS P_CUSTOM_4, MAX(PERM_CUSTOM_5) AS P_CUSTOM_5, MAX(PERM_CUSTOM_6) AS P_CUSTOM_6, MAX(PERM_CUSTOM_7) AS P_CUSTOM_7, MAX(PERM_CUSTOM_8) AS P_CUSTOM_8, MAX(PERM_CUSTOM_9) AS P_CUSTOM_9, MAX(PERM_CUSTOM_10) AS P_CUSTOM_10, MAX(PERM_CUSTOM_11) AS P_CUSTOM_11, MAX(PERM_CUSTOM_12) AS P_CUSTOM_12 "
@Select("<script>"
+ "SELECT MAX(PERM_READ::int) AS P_READ, MAX(PERM_OPEN::int) AS P_OPEN, MAX(PERM_APPEND::int) AS P_APPEND, MAX(PERM_TRANSFER::int) AS P_TRANSFER, MAX(PERM_DISTRIBUTE::int) AS P_DISTRIBUTE, MAX(PERM_CUSTOM_1::int) AS P_CUSTOM_1, MAX(PERM_CUSTOM_2::int) AS P_CUSTOM_2, MAX(PERM_CUSTOM_3::int) AS P_CUSTOM_3, MAX(PERM_CUSTOM_4::int) AS P_CUSTOM_4, MAX(PERM_CUSTOM_5::int) AS P_CUSTOM_5, MAX(PERM_CUSTOM_6::int) AS P_CUSTOM_6, MAX(PERM_CUSTOM_7::int) AS P_CUSTOM_7, MAX(PERM_CUSTOM_8::int) AS P_CUSTOM_8, MAX(PERM_CUSTOM_9::int) AS P_CUSTOM_9, MAX(PERM_CUSTOM_10::int) AS P_CUSTOM_10, MAX(PERM_CUSTOM_11::int) AS P_CUSTOM_11, MAX(PERM_CUSTOM_12::int) AS P_CUSTOM_12 "
+ "FROM TASKANA.WORKBASKET_ACCESS_LIST "
+ "WHERE WORKBASKET_ID = #{workbasketId} "
+ "AND ACCESS_ID IN(<foreach item='item' collection='accessIds' separator=',' >#{item}</foreach>) "
@ -120,7 +121,8 @@ public interface WorkbasketAccessMapper {
WorkbasketAccessItemImpl findByWorkbasketAndAccessId(
@Param("workbasketId") String workbasketId, @Param("accessIds") List<String> accessIds);
@Select("<script>SELECT MAX(PERM_READ) AS P_READ, MAX(PERM_OPEN) AS P_OPEN, MAX(PERM_APPEND) AS P_APPEND, MAX(PERM_TRANSFER) AS P_TRANSFER, MAX(PERM_DISTRIBUTE) AS P_DISTRIBUTE, MAX(PERM_CUSTOM_1) AS P_CUSTOM_1, MAX(PERM_CUSTOM_2) AS P_CUSTOM_2, MAX(PERM_CUSTOM_3) AS P_CUSTOM_3, MAX(PERM_CUSTOM_4) AS P_CUSTOM_4, MAX(PERM_CUSTOM_5) AS P_CUSTOM_5, MAX(PERM_CUSTOM_6) AS P_CUSTOM_6, MAX(PERM_CUSTOM_7) AS P_CUSTOM_7, MAX(PERM_CUSTOM_8) AS P_CUSTOM_8, MAX(PERM_CUSTOM_9) AS P_CUSTOM_9, MAX(PERM_CUSTOM_10) AS P_CUSTOM_10, MAX(PERM_CUSTOM_11) AS P_CUSTOM_11, MAX(PERM_CUSTOM_12) AS P_CUSTOM_12 "
@Select("<script>"
+ "SELECT MAX(PERM_READ::int) AS P_READ, MAX(PERM_OPEN::int) AS P_OPEN, MAX(PERM_APPEND::int) AS P_APPEND, MAX(PERM_TRANSFER::int) AS P_TRANSFER, MAX(PERM_DISTRIBUTE::int) AS P_DISTRIBUTE, MAX(PERM_CUSTOM_1::int) AS P_CUSTOM_1, MAX(PERM_CUSTOM_2::int) AS P_CUSTOM_2, MAX(PERM_CUSTOM_3::int) AS P_CUSTOM_3, MAX(PERM_CUSTOM_4::int) AS P_CUSTOM_4, MAX(PERM_CUSTOM_5::int) AS P_CUSTOM_5, MAX(PERM_CUSTOM_6::int) AS P_CUSTOM_6, MAX(PERM_CUSTOM_7::int) AS P_CUSTOM_7, MAX(PERM_CUSTOM_8::int) AS P_CUSTOM_8, MAX(PERM_CUSTOM_9::int) AS P_CUSTOM_9, MAX(PERM_CUSTOM_10::int) AS P_CUSTOM_10, MAX(PERM_CUSTOM_11::int) AS P_CUSTOM_11, MAX(PERM_CUSTOM_12::int) AS P_CUSTOM_12 "
+ "FROM TASKANA.WORKBASKET_ACCESS_LIST "
+ "WHERE WORKBASKET_ID in (SELECT ID FROM TASKANA.WORKBASKET WHERE KEY = #{workbasketKey} AND DOMAIN = #{domain} ) "
+ "AND ACCESS_ID IN(<foreach item='item' collection='accessIds' separator=',' >#{item}</foreach>) "

View File

@ -0,0 +1,187 @@
CREATE SCHEMA IF NOT EXISTS TASKANA;
CREATE TABLE TASKANA.TASKANA_SCHEMA_VERSION(
ID CHAR(40) NOT NULL,
VERSION VARCHAR(255) NOT NULL,
PRIMARY KEY (ID)
);
INSERT INTO TASKANA.TASKANA_SCHEMA_VERSION VALUES ('1', '0.1.2');
CREATE TABLE TASKANA.CLASSIFICATION(
ID CHAR(40) NOT NULL,
KEY VARCHAR(32) NOT NULL,
PARENT_ID VARCHAR(40) NOT NULL,
CATEGORY VARCHAR(32),
TYPE VARCHAR(32),
DOMAIN VARCHAR(255) NOT NULL,
VALID_IN_DOMAIN BOOLEAN NOT NULL,
CREATED TIMESTAMP NULL,
MODIFIED TIMESTAMP NULL,
NAME VARCHAR(255) NULL,
DESCRIPTION VARCHAR(255) NULL,
PRIORITY INT NOT NULL,
SERVICE_LEVEL VARCHAR(255) NULL,
APPLICATION_ENTRY_POINT VARCHAR(255) NULL,
CUSTOM_1 VARCHAR(255) NULL,
CUSTOM_2 VARCHAR(255) NULL,
CUSTOM_3 VARCHAR(255) NULL,
CUSTOM_4 VARCHAR(255) NULL,
CUSTOM_5 VARCHAR(255) NULL,
CUSTOM_6 VARCHAR(255) NULL,
CUSTOM_7 VARCHAR(255) NULL,
CUSTOM_8 VARCHAR(255) NULL,
PRIMARY KEY (ID),
CONSTRAINT UC_CLASS_KEY_DOMAIN UNIQUE (KEY, DOMAIN)
);
CREATE TABLE TASKANA.WORKBASKET(
ID CHAR(40) NOT NULL,
KEY VARCHAR(64) NOT NULL,
CREATED TIMESTAMP NULL,
MODIFIED TIMESTAMP NULL,
NAME VARCHAR(255) NOT NULL,
DOMAIN VARCHAR(32) NOT NULL,
TYPE VARCHAR(16) NOT NULL,
DESCRIPTION VARCHAR(255) NULL,
OWNER VARCHAR(128) NULL,
CUSTOM_1 VARCHAR(255) NULL,
CUSTOM_2 VARCHAR(255) NULL,
CUSTOM_3 VARCHAR(255) NULL,
CUSTOM_4 VARCHAR(255) NULL,
ORG_LEVEL_1 VARCHAR(255) NULL,
ORG_LEVEL_2 VARCHAR(255) NULL,
ORG_LEVEL_3 VARCHAR(255) NULL,
ORG_LEVEL_4 VARCHAR(255) NULL,
PRIMARY KEY (ID),
CONSTRAINT WB_KEY_DOMAIN UNIQUE (KEY, DOMAIN)
);
CREATE TABLE TASKANA.TASK (
ID CHAR(40) NOT NULL,
CREATED TIMESTAMP NULL,
CLAIMED TIMESTAMP NULL,
COMPLETED TIMESTAMP NULL,
MODIFIED TIMESTAMP NULL,
PLANNED TIMESTAMP NULL,
DUE TIMESTAMP NULL,
NAME VARCHAR(255) NULL,
CREATOR VARCHAR(32) NULL,
DESCRIPTION VARCHAR(1024) NULL,
NOTE VARCHAR(4096) NULL,
PRIORITY INT NULL,
STATE VARCHAR(20) NULL,
CLASSIFICATION_CATEGORY VARCHAR(32) NULL,
CLASSIFICATION_KEY VARCHAR(32) NULL,
CLASSIFICATION_ID CHAR(40) NULL,
WORKBASKET_ID CHAR(40) NULL,
WORKBASKET_KEY VARCHAR(64) NULL,
DOMAIN VARCHAR(32) NULL,
BUSINESS_PROCESS_ID VARCHAR(128) NULL,
PARENT_BUSINESS_PROCESS_ID VARCHAR(128) NULL,
OWNER VARCHAR(32) NULL,
POR_COMPANY VARCHAR(32) NOT NULL,
POR_SYSTEM VARCHAR(32) NOT NULL,
POR_INSTANCE VARCHAR(32) NOT NULL,
POR_TYPE VARCHAR(32) NOT NULL,
POR_VALUE VARCHAR(128) NOT NULL,
IS_READ BOOLEAN NOT NULL,
IS_TRANSFERRED BOOLEAN NOT NULL,
CALLBACK_INFO TEXT NULL,
CUSTOM_ATTRIBUTES TEXT NULL,
CUSTOM_1 VARCHAR(255) NULL,
CUSTOM_2 VARCHAR(255) NULL,
CUSTOM_3 VARCHAR(255) NULL,
CUSTOM_4 VARCHAR(255) NULL,
CUSTOM_5 VARCHAR(255) NULL,
CUSTOM_6 VARCHAR(255) NULL,
CUSTOM_7 VARCHAR(255) NULL,
CUSTOM_8 VARCHAR(255) NULL,
CUSTOM_9 VARCHAR(255) NULL,
CUSTOM_10 VARCHAR(255) NULL,
CUSTOM_11 VARCHAR(255) NULL,
CUSTOM_12 VARCHAR(255) NULL,
CUSTOM_13 VARCHAR(255) NULL,
CUSTOM_14 VARCHAR(255) NULL,
CUSTOM_15 VARCHAR(255) NULL,
CUSTOM_16 VARCHAR(255) NULL,
PRIMARY KEY (ID),
CONSTRAINT TASK_WB FOREIGN KEY (WORKBASKET_ID) REFERENCES TASKANA.WORKBASKET ON DELETE NO ACTION,
CONSTRAINT TASK_CLASS FOREIGN KEY (CLASSIFICATION_ID) REFERENCES TASKANA.CLASSIFICATION ON DELETE NO ACTION
);
CREATE TABLE TASKANA.DISTRIBUTION_TARGETS(
SOURCE_ID CHAR(40) NOT NULL,
TARGET_ID CHAR(40) NOT NULL,
PRIMARY KEY (SOURCE_ID, TARGET_ID)
);
CREATE TABLE TASKANA.WORKBASKET_ACCESS_LIST(
ID CHAR(40) NOT NULL,
WORKBASKET_ID CHAR(40) NOT NULL,
ACCESS_ID VARCHAR(255) NOT NULL,
PERM_READ BOOLEAN NOT NULL,
PERM_OPEN BOOLEAN NOT NULL,
PERM_APPEND BOOLEAN NOT NULL,
PERM_TRANSFER BOOLEAN NOT NULL,
PERM_DISTRIBUTE BOOLEAN NOT NULL,
PERM_CUSTOM_1 BOOLEAN NOT NULL,
PERM_CUSTOM_2 BOOLEAN NOT NULL,
PERM_CUSTOM_3 BOOLEAN NOT NULL,
PERM_CUSTOM_4 BOOLEAN NOT NULL,
PERM_CUSTOM_5 BOOLEAN NOT NULL,
PERM_CUSTOM_6 BOOLEAN NOT NULL,
PERM_CUSTOM_7 BOOLEAN NOT NULL,
PERM_CUSTOM_8 BOOLEAN NOT NULL,
PERM_CUSTOM_9 BOOLEAN NOT NULL,
PERM_CUSTOM_10 BOOLEAN NOT NULL,
PERM_CUSTOM_11 BOOLEAN NOT NULL,
PERM_CUSTOM_12 BOOLEAN NOT NULL,
PRIMARY KEY (ID),
CONSTRAINT ACCESS_LIST_WB FOREIGN KEY (WORKBASKET_ID) REFERENCES TASKANA.WORKBASKET ON DELETE CASCADE
);
CREATE TABLE TASKANA.OBJECT_REFERENCE(
ID CHAR(40) NOT NULL,
COMPANY VARCHAR(32) NOT NULL,
SYSTEM VARCHAR(32) NOT NULL,
SYSTEM_INSTANCE VARCHAR(32) NOT NULL,
TYPE VARCHAR(32) NOT NULL,
VALUE VARCHAR(128) NOT NULL
);
CREATE TABLE TASKANA.ATTACHMENT(
ID CHAR(40) NOT NULL,
TASK_ID CHAR(40) NOT NULL,
CREATED TIMESTAMP NULL,
MODIFIED TIMESTAMP NULL,
CLASSIFICATION_KEY VARCHAR(32) NULL,
CLASSIFICATION_ID CHAR(40) NULL,
REF_COMPANY VARCHAR(32) NOT NULL,
REF_SYSTEM VARCHAR(32) NOT NULL,
REF_INSTANCE VARCHAR(32) NOT NULL,
REF_TYPE VARCHAR(32) NOT NULL,
REF_VALUE VARCHAR(128) NOT NULL,
CHANNEL VARCHAR(64) NULL,
RECEIVED TIMESTAMP NULL,
CUSTOM_ATTRIBUTES TEXT NULL,
PRIMARY KEY (ID),
CONSTRAINT ATT_CLASS FOREIGN KEY (CLASSIFICATION_ID) REFERENCES TASKANA.CLASSIFICATION ON DELETE NO ACTION
);
CREATE TABLE TASKANA.JOB(
JOB_ID INTEGER NOT NULL,
CREATED TIMESTAMP NULL,
STARTED TIMESTAMP NULL,
COMPLETED TIMESTAMP NULL,
STATE VARCHAR(32) NULL,
EXECUTOR VARCHAR(128) NOT NULL,
ARGUMENTS TEXT NULL,
PRIMARY KEY (JOB_ID)
);
CREATE SEQUENCE TASKANA.JOB_SEQ
MINVALUE 1
START WITH 1
INCREMENT BY 1
CACHE 10;

View File

@ -23,7 +23,6 @@ import pro.taskana.database.TestDataGenerator;
import pro.taskana.exceptions.ClassificationNotFoundException;
import pro.taskana.exceptions.NotAuthorizedException;
import pro.taskana.impl.ObjectReference;
import pro.taskana.impl.TaskanaEngineImpl;
import pro.taskana.impl.configuration.DBCleaner;
import pro.taskana.impl.configuration.TaskanaEngineConfigurationTest;
@ -51,7 +50,7 @@ public abstract class AbstractAccTest {
dataSource = TaskanaEngineConfigurationTest.getDataSource();
taskanaEngineConfiguration = new TaskanaEngineConfiguration(dataSource, false);
taskanaEngine = taskanaEngineConfiguration.buildTaskanaEngine();
((TaskanaEngineImpl) taskanaEngine).setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT);
taskanaEngine.setConnectionManagementMode(ConnectionManagementMode.AUTOCOMMIT);
cleaner.clearDb(dataSource, false);
TestDataGenerator testDataGenerator = new TestDataGenerator();
testDataGenerator.generateTestData(dataSource);

View File

@ -218,7 +218,7 @@ public class DistributionTargetsAccTest extends AbstractAccTest {
groupNames = {"group_1", "group_2", "businessadmin"})
@Test
public void testSetDistributionTargets()
throws NotAuthorizedException, WorkbasketNotFoundException, InvalidWorkbasketException, SQLException {
throws NotAuthorizedException, WorkbasketNotFoundException, SQLException {
WorkbasketService workbasketService = taskanaEngine.getWorkbasketService();
Workbasket sourceWorkbasket = workbasketService.getWorkbasket("GPK_KSC_1", "DOMAIN_A");
@ -232,8 +232,9 @@ public class DistributionTargetsAccTest extends AbstractAccTest {
.list();
assertEquals(2, newDistributionTargets.size());
List<String> newDistributionTargetIds = newDistributionTargets.stream().map(t -> t.getId()).collect(
Collectors.toList());
List<String> newDistributionTargetIds = newDistributionTargets.stream()
.map(WorkbasketSummary::getId)
.collect(Collectors.toList());
workbasketService.setDistributionTargets(sourceWorkbasket.getId(), newDistributionTargetIds);
List<WorkbasketSummary> changedTargets = workbasketService.getDistributionTargets(sourceWorkbasket.getId());

View File

@ -436,7 +436,7 @@ public class ClassificationServiceImplIntExplicitTest {
}
@After
public void cleanUp() {
public void cleanUp() throws SQLException {
taskanaEngineImpl.setConnection(null);
}

View File

@ -490,7 +490,7 @@ public class TaskServiceImplIntExplicitTest {
}
@After
public void cleanUp() {
public void cleanUp() throws SQLException {
taskanaEngineImpl.setConnection(null);
}
}

View File

@ -189,7 +189,7 @@ public class WorkbasketServiceImplIntExplicitTest {
}
@After
public void cleanUp() {
public void cleanUp() throws SQLException {
taskanaEngineImpl.setConnection(null);
}

View File

@ -8,7 +8,6 @@ import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.type.ClobTypeHandler;
import org.apache.ibatis.type.JdbcType;
import pro.taskana.impl.TaskImpl;
import pro.taskana.impl.persistence.MapTypeHandler;
@ -20,7 +19,7 @@ public interface TaskTestMapper {
@Select("select CUSTOM_ATTRIBUTES from TASKANA.TASK where id = #{taskId}")
@Results(value = {
@Result(property = "customAttributes", column = "CUSTOM_ATTRIBUTES", jdbcType = JdbcType.CLOB,
@Result(property = "customAttributes", column = "CUSTOM_ATTRIBUTES",
javaType = String.class, typeHandler = ClobTypeHandler.class)
})
String getCustomAttributesAsString(@Param("taskId") String taskId);
@ -56,7 +55,7 @@ public interface TaskTestMapper {
@Result(property = "primaryObjRef.value", column = "POR_VALUE"),
@Result(property = "isRead", column = "IS_READ"),
@Result(property = "isTransferred", column = "IS_TRANSFERRED"),
@Result(property = "customAttributes", column = "CUSTOM_ATTRIBUTES", jdbcType = JdbcType.CLOB,
@Result(property = "customAttributes", column = "CUSTOM_ATTRIBUTES",
javaType = Map.class, typeHandler = MapTypeHandler.class),
@Result(property = "custom1", column = "CUSTOM_1"),
@Result(property = "custom2", column = "CUSTOM_2"),

View File

@ -1,9 +1,10 @@
-- the order is important!
DELETE FROM TASKANA.ATTACHMENT;
DELETE FROM TASKANA.TASK;
DELETE FROM TASKANA.WORKBASKET_ACCESS_LIST;
DELETE FROM TASKANA.WORKBASKET;
DELETE FROM TASKANA.DISTRIBUTION_TARGETS;
DELETE FROM TASKANA.CLASSIFICATION;
DELETE FROM TASKANA.OBJECT_REFERENCE;
DELETE FROM TASKANA.ATTACHMENT;
DELETE FROM TASKANA.JOB;
COMMIT;

View File

@ -1,11 +1,11 @@
DROP TABLE TASKANA.TASKANA_SCHEMA_VERSION;
DROP TABLE TASKANA.TASK;
DROP TABLE TASKANA.WORKBASKET_ACCESS_LIST;
DROP TABLE TASKANA.WORKBASKET;
DROP TABLE TASKANA.DISTRIBUTION_TARGETS;
DROP TABLE TASKANA.CLASSIFICATION;
DROP TABLE TASKANA.OBJECT_REFERENCE;
DROP TABLE TASKANA.ATTACHMENT;
DROP TABLE TASKANA.JOB;
DROP TABLE TASKANA.TASKANA_SCHEMA_VERSION CASCADE;
DROP TABLE TASKANA.TASK CASCADE;
DROP TABLE TASKANA.WORKBASKET_ACCESS_LIST CASCADE;
DROP TABLE TASKANA.WORKBASKET CASCADE;
DROP TABLE TASKANA.DISTRIBUTION_TARGETS CASCADE;
DROP TABLE TASKANA.CLASSIFICATION CASCADE;
DROP TABLE TASKANA.OBJECT_REFERENCE CASCADE;
DROP TABLE TASKANA.ATTACHMENT CASCADE;
DROP TABLE TASKANA.JOB CASCADE;
DROP SEQUENCE TASKANA.JOB_SEQ;
COMMIT;