TSK-1658: PR amends

This commit is contained in:
Tristan 2021-07-14 17:32:51 +02:00 committed by Tristan2357
parent 375a92291d
commit 1eb3ccec78
11 changed files with 411 additions and 308 deletions

View File

@ -0,0 +1,50 @@
package pro.taskana.common.internal.util;
public class SqlProviderUtil {
private SqlProviderUtil() {}
public static void whereIn(String collection, String column, StringBuilder sb) {
sb.append("<if test='")
.append(collection)
.append(" != null'>AND ")
.append(column)
.append(" IN(<foreach item='item' collection='")
.append(collection)
.append("' separator=',' >#{item}</foreach>)</if> ");
}
public static void whereNotIn(String collection, String column, StringBuilder sb) {
sb.append("<if test='")
.append(collection)
.append(" != null'>AND ")
.append(column)
.append(" NOT IN(<foreach item='item' collection='")
.append(collection)
.append("' separator=',' >#{item}</foreach>)</if> ");
}
public static void whereInTime(String collection, String column, StringBuilder sb) {
sb.append("<if test='")
.append(collection)
.append(" !=null'> AND (<foreach item='item' collection='")
.append(collection)
.append("' separator=' OR ' > ( <if test='item.begin!=null'> ")
.append(column)
.append(
" &gt;= #{item.begin} </if> <if test='item.begin!=null and item.end!=null'> AND"
+ " </if><if test='item.end!=null'> ")
.append(column)
.append(" &lt;=#{item.end} </if>)</foreach>)</if> ");
}
public static void whereLike(String collection, String column, StringBuilder sb) {
sb.append("<if test='")
.append(collection)
.append(" != null'>AND (<foreach item='item' collection='")
.append(collection)
.append("' separator=' OR '>UPPER(")
.append(column)
.append(") LIKE #{item}</foreach>)</if> ");
}
}

View File

@ -4,7 +4,7 @@ import pro.taskana.common.api.QueryColumnName;
/**
* Enum containing the column names for {@link
* pro.taskana.task.internal.TaskQueryMapper#queryObjectReferenceColumnValues}.
* pro.taskana.task.internal.ObjectReferenceMapper#queryObjectReferenceColumnValues}.
*/
public enum ObjectReferenceQueryColumnName implements QueryColumnName {
ID("id"),
@ -14,7 +14,7 @@ public enum ObjectReferenceQueryColumnName implements QueryColumnName {
TYPE("type"),
VALUE("value");
private String name;
private final String name;
ObjectReferenceQueryColumnName(String name) {
this.name = name;

View File

@ -1,10 +1,12 @@
package pro.taskana.task.internal;
import java.util.List;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.SelectProvider;
import org.apache.ibatis.annotations.Update;
import pro.taskana.task.api.models.ObjectReference;
@ -45,13 +47,35 @@ public interface ObjectReferenceMapper {
@Result(property = "value", column = "VALUE")
ObjectReference findByObjectReference(@Param("objectReference") ObjectReference objectReference);
@SelectProvider(type = ObjectReferenceQuerySqlProvider.class, method = "queryObjectReferences")
@Result(property = "id", column = "ID")
@Result(property = "company", column = "COMPANY")
@Result(property = "system", column = "SYSTEM")
@Result(property = "systemInstance", column = "SYSTEM_INSTANCE")
@Result(property = "type", column = "TYPE")
@Result(property = "value", column = "VALUE")
List<ObjectReference> queryObjectReferences(ObjectReferenceQueryImpl objectReference);
@SelectProvider(
type = ObjectReferenceQuerySqlProvider.class,
method = "countQueryObjectReferences")
long countQueryObjectReferences(ObjectReferenceQueryImpl objectReference);
@SelectProvider(
type = ObjectReferenceQuerySqlProvider.class,
method = "queryObjectReferenceColumnValues")
List<String> queryObjectReferenceColumnValues(ObjectReferenceQueryImpl objectReference);
@Insert(
"INSERT INTO OBJECT_REFERENCE (ID, COMPANY, SYSTEM, SYSTEM_INSTANCE, TYPE, VALUE) VALUES (#{ref.id}, #{ref.company}, #{ref.system}, #{ref.systemInstance}, #{ref.type}, #{ref.value})")
"INSERT INTO OBJECT_REFERENCE (ID, COMPANY, SYSTEM, SYSTEM_INSTANCE, TYPE, VALUE) "
+ "VALUES (#{ref.id}, #{ref.company}, #{ref.system}, #{ref.systemInstance}, #{ref.type}, #{ref.value})")
void insert(@Param("ref") ObjectReference ref);
@Update(
value =
"UPDATE OBJECT_REFERENCE SET COMPANY = #{ref.company}, SYSTEM = #{ref.system}, SYSTEM_INSTANCE = #{ref.systemInstance}, TYPE = #{ref.type}, VALUE = #{ref.value} WHERE ID = #{ref.id}")
"UPDATE OBJECT_REFERENCE "
+ "SET COMPANY = #{ref.company}, SYSTEM = #{ref.system}, SYSTEM_INSTANCE = #{ref.systemInstance}, TYPE = #{ref.type}, VALUE = #{ref.value} "
+ "WHERE ID = #{ref.id}")
void update(@Param("ref") ObjectReference ref);
@Delete("DELETE FROM OBJECT_REFERENCE WHERE ID = #{id}")

View File

@ -16,11 +16,11 @@ import pro.taskana.task.api.models.ObjectReference;
public class ObjectReferenceQueryImpl implements ObjectReferenceQuery {
private static final String LINK_TO_MAPPER =
"pro.taskana.task.internal.TaskQueryMapper.queryObjectReferences";
"pro.taskana.task.internal.ObjectReferenceMapper.queryObjectReferences";
private static final String LINK_TO_COUNTER =
"pro.taskana.task.internal.TaskQueryMapper.countQueryObjectReferences";
"pro.taskana.task.internal.ObjectReferenceMapper.countQueryObjectReferences";
private static final String LINK_TO_VALUEMAPPER =
"pro.taskana.task.internal.TaskQueryMapper.queryObjectReferenceColumnValues";
"pro.taskana.task.internal.ObjectReferenceMapper.queryObjectReferenceColumnValues";
private final InternalTaskanaEngine taskanaEngine;
private final List<String> orderBy;
private ObjectReferenceQueryColumnName columnName;

View File

@ -0,0 +1,55 @@
package pro.taskana.task.internal;
import static pro.taskana.common.internal.util.SqlProviderUtil.whereIn;
public class ObjectReferenceQuerySqlProvider {
private static final String OPENING_SCRIPT_TAG = "<script>";
private static final String CLOSING_SCRIPT_TAG = "</script>";
private static final String OPENING_WHERE_TAG = "<where>";
private static final String CLOSING_WHERE_TAG = "</where>";
private ObjectReferenceQuerySqlProvider() {}
public static String queryObjectReferences() {
return OPENING_SCRIPT_TAG
+ "SELECT ID, COMPANY, SYSTEM, SYSTEM_INSTANCE, TYPE, VALUE "
+ "FROM OBJECT_REFERENCE "
+ OPENING_WHERE_TAG
+ commonObjectReferenceWhereStatement()
+ CLOSING_WHERE_TAG
+ "<if test=\"_databaseId == 'db2'\">with UR </if> "
+ CLOSING_SCRIPT_TAG;
}
public static String countQueryObjectReferences() {
return OPENING_SCRIPT_TAG
+ "SELECT COUNT(ID) "
+ "FROM OBJECT_REFERENCE "
+ OPENING_WHERE_TAG
+ commonObjectReferenceWhereStatement()
+ CLOSING_WHERE_TAG
+ "<if test=\"_databaseId == 'db2'\">with UR </if> "
+ CLOSING_SCRIPT_TAG;
}
public static String queryObjectReferenceColumnValues() {
return OPENING_SCRIPT_TAG
+ "SELECT DISTINCT ${columnName} "
+ "FROM OBJECT_REFERENCE "
+ OPENING_WHERE_TAG
+ commonObjectReferenceWhereStatement()
+ CLOSING_WHERE_TAG
+ "<if test=\"_databaseId == 'db2'\">with UR </if> "
+ CLOSING_SCRIPT_TAG;
}
private static String commonObjectReferenceWhereStatement() {
StringBuilder sb = new StringBuilder();
whereIn("company", "COMPANY", sb);
whereIn("system", "SYSTEM", sb);
whereIn("systemInstance", "SYSTEM_INSTANCE", sb);
whereIn("type", "TYPE", sb);
whereIn("value", "VALUE", sb);
return sb.toString();
}
}

View File

@ -629,8 +629,7 @@ public class TaskQueryImpl implements TaskQuery {
switch (customField) {
case CUSTOM_1:
this.custom1Like =
toUpperCopy(strings); // why are we doing this? the sql is always an upper?
this.custom1Like = toUpperCopy(strings);
break;
case CUSTOM_2:
this.custom2Like = toUpperCopy(strings);

View File

@ -4,7 +4,6 @@ import java.util.List;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.SelectProvider;
import pro.taskana.task.api.models.ObjectReference;
import pro.taskana.task.internal.models.TaskSummaryImpl;
/** This class provides a mapper for all task queries. */
@ -111,27 +110,12 @@ public interface TaskQueryMapper {
@Result(property = "custom16", column = "CUSTOM_16")
List<TaskSummaryImpl> queryTaskSummariesDb2(TaskQueryImpl taskQuery);
@SelectProvider(type = TaskQuerySqlProvider.class, method = "queryObjectReferences")
@Result(property = "id", column = "ID")
@Result(property = "company", column = "COMPANY")
@Result(property = "system", column = "SYSTEM")
@Result(property = "systemInstance", column = "SYSTEM_INSTANCE")
@Result(property = "type", column = "TYPE")
@Result(property = "value", column = "VALUE")
List<ObjectReference> queryObjectReferences(ObjectReferenceQueryImpl objectReference);
@SelectProvider(type = TaskQuerySqlProvider.class, method = "countQueryTasks")
Long countQueryTasks(TaskQueryImpl taskQuery);
@SelectProvider(type = TaskQuerySqlProvider.class, method = "countQueryTasksDb2")
Long countQueryTasksDb2(TaskQueryImpl taskQuery);
@SelectProvider(type = TaskQuerySqlProvider.class, method = "countQueryObjectReferences")
Long countQueryObjectReferences(ObjectReferenceQueryImpl objectReference);
@SelectProvider(type = TaskQuerySqlProvider.class, method = "queryTaskColumnValues")
List<String> queryTaskColumnValues(TaskQueryImpl taskQuery);
@SelectProvider(type = TaskQuerySqlProvider.class, method = "queryObjectReferenceColumnValues")
List<String> queryObjectReferenceColumnValues(ObjectReferenceQueryImpl objectReference);
}

View File

@ -1,33 +1,44 @@
package pro.taskana.task.internal;
import static pro.taskana.common.internal.util.SqlProviderUtil.whereIn;
import static pro.taskana.common.internal.util.SqlProviderUtil.whereInTime;
import static pro.taskana.common.internal.util.SqlProviderUtil.whereLike;
import static pro.taskana.common.internal.util.SqlProviderUtil.whereNotIn;
import java.util.stream.IntStream;
@SuppressWarnings({"checkstyle:LineLength", "checkstyle:Indentation"})
public class TaskQuerySqlProvider {
private static final String OPENING_SCRIPT_TAG = "<script>";
private static final String CLOSING_SCRIPT_TAG = "</script>";
private static final String OPENING_WHERE_TAG = "<where>";
private static final String CLOSING_WHERE_TAG = "</where>";
private static final String WILDCARD_LIKE_STATEMENT =
"<if test='wildcardSearchValueLike != null and wildcardSearchFieldIn != null'>AND ("
+ "<foreach item='item' collection='wildcardSearchFieldIn' separator=' OR '>"
+ "UPPER(t.${item}) "
+ "LIKE #{wildcardSearchValueLike}"
+ "</foreach>)"
+ "</if> ";
private TaskQuerySqlProvider() {}
public static String queryTaskSummaries() {
return OPENING_SCRIPT_TAG
+ "SELECT <if test=\"useDistinctKeyword\">DISTINCT</if> t.ID, t.EXTERNAL_ID, t.CREATED, t.CLAIMED, t.COMPLETED, t.MODIFIED, t.PLANNED, t.DUE, t.NAME, t.CREATOR, t.DESCRIPTION, t.NOTE, t.PRIORITY, t.STATE, t.CLASSIFICATION_KEY, "
+ "t.CLASSIFICATION_CATEGORY, t.CLASSIFICATION_ID, t.WORKBASKET_ID, t.DOMAIN, t.WORKBASKET_KEY, t.BUSINESS_PROCESS_ID, t.PARENT_BUSINESS_PROCESS_ID, t.OWNER, t.POR_COMPANY, t.POR_SYSTEM, t.POR_INSTANCE, t.POR_TYPE, "
+ "t.POR_VALUE, t.IS_READ, t.IS_TRANSFERRED, t.CUSTOM_1, t.CUSTOM_2, t.CUSTOM_3, t.CUSTOM_4, t.CUSTOM_5, t.CUSTOM_6, t.CUSTOM_7, t.CUSTOM_8, t.CUSTOM_9, t.CUSTOM_10, t.CUSTOM_11, t.CUSTOM_12, t.CUSTOM_13, t.CUSTOM_14, t.CUSTOM_15, t.CUSTOM_16"
+ "SELECT <if test=\"useDistinctKeyword\">DISTINCT</if> "
+ "t.ID, t.EXTERNAL_ID, t.CREATED, t.CLAIMED, t.COMPLETED, t.MODIFIED, t.PLANNED, t.DUE, "
+ "t.NAME, t.CREATOR, t.DESCRIPTION, t.NOTE, t.PRIORITY, t.STATE, t.CLASSIFICATION_KEY, "
+ "t.CLASSIFICATION_CATEGORY, t.CLASSIFICATION_ID, t.WORKBASKET_ID, t.DOMAIN, "
+ "t.WORKBASKET_KEY, t.BUSINESS_PROCESS_ID, t.PARENT_BUSINESS_PROCESS_ID, t.OWNER, "
+ "t.POR_COMPANY, t.POR_SYSTEM, t.POR_INSTANCE, t.POR_TYPE, t.POR_VALUE, t.IS_READ, "
+ "t.IS_TRANSFERRED, t.CUSTOM_1, t.CUSTOM_2, t.CUSTOM_3, t.CUSTOM_4, t.CUSTOM_5, "
+ "t.CUSTOM_6, t.CUSTOM_7, t.CUSTOM_8, t.CUSTOM_9, t.CUSTOM_10, t.CUSTOM_11, t.CUSTOM_12, "
+ "t.CUSTOM_13, t.CUSTOM_14, t.CUSTOM_15, t.CUSTOM_16"
+ "<if test=\"addAttachmentColumnsToSelectClauseForOrdering\">"
+ ", a.CLASSIFICATION_ID, a.CLASSIFICATION_KEY, a.CHANNEL, a.REF_VALUE, a.RECEIVED"
+ "</if>"
+ "<if test=\"addClassificationNameToSelectClauseForOrdering\">"
+ ", c.NAME "
+ "</if>"
+ "<if test=\"addAttachmentClassificationNameToSelectClauseForOrdering\">"
+ ", ac.NAME "
+ "</if>"
+ "<if test=\"addWorkbasketNameToSelectClauseForOrdering\">"
+ ", w.NAME "
+ "</if>"
+ "<if test=\"addClassificationNameToSelectClauseForOrdering\">, c.NAME </if>"
+ "<if test=\"addAttachmentClassificationNameToSelectClauseForOrdering\">, ac.NAME </if>"
+ "<if test=\"addWorkbasketNameToSelectClauseForOrdering\">, w.NAME </if>"
+ "FROM TASK t "
+ "<if test=\"joinWithAttachments\">"
+ "LEFT JOIN ATTACHMENT AS a ON t.ID = a.TASK_ID "
@ -43,58 +54,64 @@ public class TaskQuerySqlProvider {
+ "</if>"
+ OPENING_WHERE_TAG
+ "<if test='accessIdIn != null'> "
+ "AND t.WORKBASKET_ID IN ( "
+ "SELECT WID from (SELECT WORKBASKET_ID as WID, MAX(PERM_READ::int) as MAX_READ FROM WORKBASKET_ACCESS_LIST AS s where "
+ "ACCESS_ID IN (<foreach item='item' collection='accessIdIn' separator=',' >#{item}</foreach>) "
+ "group by WORKBASKET_ID ) AS f where max_read = 1 ) "
+ "AND t.WORKBASKET_ID IN ("
+ "SELECT WID from ("
+ "SELECT WORKBASKET_ID "
+ "as WID, MAX(PERM_READ::int) "
+ "as MAX_READ FROM WORKBASKET_ACCESS_LIST "
+ "AS s where ACCESS_ID IN "
+ "(<foreach item='item' collection='accessIdIn' separator=',' >#{item}</foreach>) "
+ "group by WORKBASKET_ID) "
+ "AS f where max_read = 1) "
+ "</if> "
+ commonTaskWhereStatement()
+ "<if test='wildcardSearchValueLike != null and wildcardSearchFieldIn != null'>AND (<foreach item='item' collection='wildcardSearchFieldIn' separator=' OR '>UPPER(t.${item}) LIKE #{wildcardSearchValueLike}</foreach>)</if> "
+ WILDCARD_LIKE_STATEMENT
+ commonTaskObjectReferenceWhereStatement()
+ "<if test='selectAndClaim == true'> AND t.STATE = 'READY' </if>"
+ CLOSING_WHERE_TAG
+ "<if test='!orderBy.isEmpty()'>ORDER BY <foreach item='item' collection='orderBy' separator=',' >${item}</foreach></if> "
+ "<if test='selectAndClaim == true'> FETCH FIRST ROW ONLY FOR UPDATE </if>"
+ "<if test=\"_databaseId == 'db2'\">WITH RS USE AND KEEP UPDATE LOCKS </if> "
+ "<if test='!orderBy.isEmpty()'>"
+ "ORDER BY <foreach item='item' collection='orderBy' separator=',' >${item}</foreach>"
+ "</if> "
+ "<if test='selectAndClaim == true'> "
+ "FETCH FIRST ROW ONLY FOR UPDATE "
+ "</if>"
+ "<if test=\"_databaseId == 'db2'\">WITH RS USE AND KEEP UPDATE LOCKS </if>"
+ CLOSING_SCRIPT_TAG;
}
public static String queryTaskSummariesDb2() {
return OPENING_SCRIPT_TAG
+ "WITH X (ID, EXTERNAL_ID, CREATED, CLAIMED, COMPLETED, MODIFIED, PLANNED, DUE, NAME, CREATOR, DESCRIPTION, NOTE, PRIORITY, STATE, TCLASSIFICATION_KEY, "
+ "CLASSIFICATION_CATEGORY, CLASSIFICATION_ID, WORKBASKET_ID, DOMAIN, WORKBASKET_KEY, BUSINESS_PROCESS_ID, PARENT_BUSINESS_PROCESS_ID, OWNER, "
+ "POR_COMPANY, POR_SYSTEM, POR_INSTANCE, POR_TYPE, POR_VALUE, IS_READ, IS_TRANSFERRED, CUSTOM_1, CUSTOM_2, CUSTOM_3, CUSTOM_4, CUSTOM_5, "
+ "CUSTOM_6, CUSTOM_7, CUSTOM_8, CUSTOM_9, CUSTOM_10, CUSTOM_11, CUSTOM_12, CUSTOM_13, CUSTOM_14, CUSTOM_15, CUSTOM_16"
+ "WITH X ("
+ "ID, EXTERNAL_ID, CREATED, CLAIMED, COMPLETED, MODIFIED, PLANNED, DUE, NAME, CREATOR, "
+ "DESCRIPTION, NOTE, PRIORITY, STATE, TCLASSIFICATION_KEY, CLASSIFICATION_CATEGORY, "
+ "CLASSIFICATION_ID, WORKBASKET_ID, DOMAIN, WORKBASKET_KEY, BUSINESS_PROCESS_ID, "
+ "PARENT_BUSINESS_PROCESS_ID, OWNER, POR_COMPANY, POR_SYSTEM, POR_INSTANCE, POR_TYPE, "
+ "POR_VALUE, IS_READ, IS_TRANSFERRED, CUSTOM_1, CUSTOM_2, CUSTOM_3, CUSTOM_4, CUSTOM_5, "
+ "CUSTOM_6, CUSTOM_7, CUSTOM_8, CUSTOM_9, CUSTOM_10, CUSTOM_11, CUSTOM_12, CUSTOM_13, "
+ "CUSTOM_14, CUSTOM_15, CUSTOM_16"
+ "<if test=\"addAttachmentColumnsToSelectClauseForOrdering\">"
+ ", ACLASSIFICATION_ID, ACLASSIFICATION_KEY, CHANNEL, REF_VALUE, RECEIVED"
+ "</if>"
+ "<if test=\"addClassificationNameToSelectClauseForOrdering\">"
+ ", CNAME "
+ "</if>"
+ "<if test=\"addAttachmentClassificationNameToSelectClauseForOrdering\">"
+ ", ACNAME "
+ "</if>"
+ "<if test=\"addWorkbasketNameToSelectClauseForOrdering\">"
+ ", WNAME "
+ "</if>"
+ " ) "
+ " AS (SELECT <if test=\"useDistinctKeyword\">DISTINCT</if> t.ID, t.EXTERNAL_ID, t.CREATED, t.CLAIMED, t.COMPLETED, t.MODIFIED, t.PLANNED, t.DUE, t.NAME, t.CREATOR, t.DESCRIPTION, t.NOTE, t.PRIORITY, t.STATE, t.CLASSIFICATION_KEY, "
+ " t.CLASSIFICATION_CATEGORY, t.CLASSIFICATION_ID, t.WORKBASKET_ID, t.DOMAIN, t.WORKBASKET_KEY, t.BUSINESS_PROCESS_ID, t.PARENT_BUSINESS_PROCESS_ID, t.OWNER, "
+ "t.POR_COMPANY, t.POR_SYSTEM, t.POR_INSTANCE, t.POR_TYPE, t.POR_VALUE, t.IS_READ, t.IS_TRANSFERRED, t.CUSTOM_1, t.CUSTOM_2, t.CUSTOM_3, t.CUSTOM_4, t.CUSTOM_5, "
+ "t.CUSTOM_6, t.CUSTOM_7, t.CUSTOM_8, t.CUSTOM_9, t.CUSTOM_10, t.CUSTOM_11, t.CUSTOM_12, t.CUSTOM_13, t.CUSTOM_14, t.CUSTOM_15, t.CUSTOM_16"
+ "<if test=\"addClassificationNameToSelectClauseForOrdering\">, CNAME </if>"
+ "<if test=\"addAttachmentClassificationNameToSelectClauseForOrdering\">, ACNAME </if>"
+ "<if test=\"addWorkbasketNameToSelectClauseForOrdering\">, WNAME </if>"
+ ") AS ("
+ "SELECT <if test=\"useDistinctKeyword\">DISTINCT</if> "
+ "t.ID, t.EXTERNAL_ID, t.CREATED, t.CLAIMED, t.COMPLETED, t.MODIFIED, t.PLANNED, t.DUE, "
+ "t.NAME, t.CREATOR, t.DESCRIPTION, t.NOTE, t.PRIORITY, t.STATE, t.CLASSIFICATION_KEY, "
+ "t.CLASSIFICATION_CATEGORY, t.CLASSIFICATION_ID, t.WORKBASKET_ID, t.DOMAIN, "
+ "t.WORKBASKET_KEY, t.BUSINESS_PROCESS_ID, t.PARENT_BUSINESS_PROCESS_ID, t.OWNER, "
+ "t.POR_COMPANY, t.POR_SYSTEM, t.POR_INSTANCE, t.POR_TYPE, t.POR_VALUE, t.IS_READ, "
+ "t.IS_TRANSFERRED, t.CUSTOM_1, t.CUSTOM_2, t.CUSTOM_3, t.CUSTOM_4, t.CUSTOM_5, "
+ "t.CUSTOM_6, t.CUSTOM_7, t.CUSTOM_8, t.CUSTOM_9, t.CUSTOM_10, t.CUSTOM_11, t.CUSTOM_12, "
+ "t.CUSTOM_13, t.CUSTOM_14, t.CUSTOM_15, t.CUSTOM_16"
+ "<if test=\"addAttachmentColumnsToSelectClauseForOrdering\">"
+ ", a.CLASSIFICATION_ID, a.CLASSIFICATION_KEY, a.CHANNEL, a.REF_VALUE, a.RECEIVED"
+ "</if>"
+ "<if test=\"addClassificationNameToSelectClauseForOrdering\">"
+ ", c.NAME "
+ "</if>"
+ "<if test=\"addAttachmentClassificationNameToSelectClauseForOrdering\">"
+ ", ac.NAME "
+ "</if>"
+ "<if test=\"addWorkbasketNameToSelectClauseForOrdering\">"
+ ", w.NAME "
+ "</if>"
+ " FROM TASK t "
+ "<if test=\"addClassificationNameToSelectClauseForOrdering\">, c.NAME </if>"
+ "<if test=\"addAttachmentClassificationNameToSelectClauseForOrdering\">, ac.NAME </if>"
+ "<if test=\"addWorkbasketNameToSelectClauseForOrdering\">, w.NAME </if>"
+ "FROM TASK t "
+ "<if test=\"joinWithAttachments\">"
+ "LEFT JOIN ATTACHMENT a ON t.ID = a.TASK_ID "
+ "</if>"
@ -110,90 +127,75 @@ public class TaskQuerySqlProvider {
+ OPENING_WHERE_TAG
+ commonTaskWhereStatement()
+ commonTaskObjectReferenceWhereStatement()
+ "<if test='wildcardSearchValueLike != null and wildcardSearchFieldIn != null'>AND (<foreach item='item' collection='wildcardSearchFieldIn' separator=' OR '>UPPER(t.${item}) LIKE #{wildcardSearchValueLike}</foreach>)</if> "
+ WILDCARD_LIKE_STATEMENT
+ CLOSING_WHERE_TAG
+ "), Y (ID, EXTERNAL_ID, CREATED, CLAIMED, COMPLETED, MODIFIED, PLANNED, DUE, NAME, CREATOR, DESCRIPTION, NOTE, PRIORITY, STATE, TCLASSIFICATION_KEY, "
+ " CLASSIFICATION_CATEGORY, CLASSIFICATION_ID, WORKBASKET_ID, DOMAIN, WORKBASKET_KEY, BUSINESS_PROCESS_ID, PARENT_BUSINESS_PROCESS_ID, OWNER, "
+ "POR_COMPANY, POR_SYSTEM, POR_INSTANCE, POR_TYPE, POR_VALUE, IS_READ, IS_TRANSFERRED, CUSTOM_1, CUSTOM_2, CUSTOM_3, CUSTOM_4, CUSTOM_5, "
+ "CUSTOM_6, CUSTOM_7, CUSTOM_8, CUSTOM_9, CUSTOM_10, CUSTOM_11, CUSTOM_12, CUSTOM_13, CUSTOM_14, CUSTOM_15, CUSTOM_16"
+ "), Y ("
+ "ID, EXTERNAL_ID, CREATED, CLAIMED, COMPLETED, MODIFIED, PLANNED, DUE, NAME, CREATOR, "
+ "DESCRIPTION, NOTE, PRIORITY, STATE, TCLASSIFICATION_KEY, CLASSIFICATION_CATEGORY, "
+ "CLASSIFICATION_ID, WORKBASKET_ID, DOMAIN, WORKBASKET_KEY, BUSINESS_PROCESS_ID, "
+ "PARENT_BUSINESS_PROCESS_ID, OWNER, POR_COMPANY, POR_SYSTEM, POR_INSTANCE, POR_TYPE, "
+ "POR_VALUE, IS_READ, IS_TRANSFERRED, CUSTOM_1, CUSTOM_2, CUSTOM_3, CUSTOM_4, CUSTOM_5, "
+ "CUSTOM_6, CUSTOM_7, CUSTOM_8, CUSTOM_9, CUSTOM_10, CUSTOM_11, CUSTOM_12, CUSTOM_13, "
+ "CUSTOM_14, CUSTOM_15, CUSTOM_16"
+ "<if test=\"addAttachmentColumnsToSelectClauseForOrdering\">"
+ ", ACLASSIFICATION_ID, ACLASSIFICATION_KEY, CHANNEL, REF_VALUE, RECEIVED"
+ "</if>"
+ "<if test=\"addClassificationNameToSelectClauseForOrdering\">"
+ ", CNAME "
+ "</if>"
+ "<if test=\"addAttachmentClassificationNameToSelectClauseForOrdering\">"
+ ", ACNAME "
+ "</if>"
+ "<if test=\"addWorkbasketNameToSelectClauseForOrdering\">"
+ ", WNAME "
+ "</if>"
+ ", FLAG ) "
+ "AS "
+ "(SELECT ID, EXTERNAL_ID, CREATED, CLAIMED, COMPLETED, MODIFIED, PLANNED, DUE, NAME, CREATOR, DESCRIPTION, NOTE, PRIORITY, STATE, TCLASSIFICATION_KEY, "
+ " CLASSIFICATION_CATEGORY, CLASSIFICATION_ID, WORKBASKET_ID, DOMAIN, WORKBASKET_KEY, BUSINESS_PROCESS_ID, PARENT_BUSINESS_PROCESS_ID, OWNER, "
+ "POR_COMPANY, POR_SYSTEM, POR_INSTANCE, POR_TYPE, POR_VALUE, IS_READ, IS_TRANSFERRED, CUSTOM_1, CUSTOM_2, CUSTOM_3, CUSTOM_4, CUSTOM_5, "
+ "CUSTOM_6, CUSTOM_7, CUSTOM_8, CUSTOM_9, CUSTOM_10, CUSTOM_11, CUSTOM_12, CUSTOM_13, CUSTOM_14, CUSTOM_15, CUSTOM_16"
+ "<if test=\"addClassificationNameToSelectClauseForOrdering\">, CNAME </if>"
+ "<if test=\"addAttachmentClassificationNameToSelectClauseForOrdering\">, ACNAME </if>"
+ "<if test=\"addWorkbasketNameToSelectClauseForOrdering\">, WNAME </if>"
+ ", FLAG ) AS ("
+ "SELECT ID, EXTERNAL_ID, CREATED, CLAIMED, COMPLETED, MODIFIED, PLANNED, DUE, NAME, "
+ "CREATOR, DESCRIPTION, NOTE, PRIORITY, STATE, TCLASSIFICATION_KEY, "
+ "CLASSIFICATION_CATEGORY, CLASSIFICATION_ID, WORKBASKET_ID, DOMAIN, WORKBASKET_KEY, "
+ "BUSINESS_PROCESS_ID, PARENT_BUSINESS_PROCESS_ID, OWNER, POR_COMPANY, POR_SYSTEM, "
+ "POR_INSTANCE, POR_TYPE, POR_VALUE, IS_READ, IS_TRANSFERRED, CUSTOM_1, CUSTOM_2, "
+ "CUSTOM_3, CUSTOM_4, CUSTOM_5, CUSTOM_6, CUSTOM_7, CUSTOM_8, CUSTOM_9, CUSTOM_10, "
+ "CUSTOM_11, CUSTOM_12, CUSTOM_13, CUSTOM_14, CUSTOM_15, CUSTOM_16"
+ "<if test=\"addAttachmentColumnsToSelectClauseForOrdering\">"
+ ", ACLASSIFICATION_ID, ACLASSIFICATION_KEY, CHANNEL, REF_VALUE, RECEIVED"
+ "</if>"
+ "<if test=\"addClassificationNameToSelectClauseForOrdering\">"
+ ", CNAME "
+ "</if>"
+ "<if test=\"addAttachmentClassificationNameToSelectClauseForOrdering\">"
+ ", ACNAME "
+ "</if>"
+ "<if test=\"addWorkbasketNameToSelectClauseForOrdering\">"
+ ", WNAME "
+ "</if>"
+ ", (SELECT 1 FROM WORKBASKET_ACCESS_LIST s WHERE "
+ "<if test=\"addClassificationNameToSelectClauseForOrdering\">, CNAME </if>"
+ "<if test=\"addAttachmentClassificationNameToSelectClauseForOrdering\">, ACNAME </if>"
+ "<if test=\"addWorkbasketNameToSelectClauseForOrdering\">, WNAME </if>"
+ ", ("
+ "SELECT 1 "
+ "FROM WORKBASKET_ACCESS_LIST s "
+ "WHERE "
+ "<if test='accessIdIn != null'> "
+ "s.ACCESS_ID IN (<foreach item='item' collection='accessIdIn' separator=',' >#{item}</foreach>) and "
+ "</if>"
+ "s.WORKBASKET_ID = X.WORKBASKET_ID AND "
+ "s.perm_read = 1 "
+ "fetch first 1 rows only "
+ ") FROM X )"
+ "SELECT ID, EXTERNAL_ID, CREATED, CLAIMED, COMPLETED, MODIFIED, PLANNED, DUE, NAME, CREATOR, DESCRIPTION, NOTE, PRIORITY, STATE, TCLASSIFICATION_KEY, "
+ " CLASSIFICATION_CATEGORY, CLASSIFICATION_ID, WORKBASKET_ID, DOMAIN, WORKBASKET_KEY, BUSINESS_PROCESS_ID, PARENT_BUSINESS_PROCESS_ID, OWNER, "
+ "POR_COMPANY, POR_SYSTEM, POR_INSTANCE, POR_TYPE, POR_VALUE, IS_READ, IS_TRANSFERRED, CUSTOM_1, CUSTOM_2, CUSTOM_3, CUSTOM_4, CUSTOM_5, "
+ "CUSTOM_6, CUSTOM_7, CUSTOM_8, CUSTOM_9, CUSTOM_10, CUSTOM_11, CUSTOM_12, CUSTOM_13, CUSTOM_14, CUSTOM_15, CUSTOM_16"
+ "s.ACCESS_ID IN "
+ "(<foreach item='item' collection='accessIdIn' separator=',' >#{item}</foreach>) "
+ "and </if>"
+ "s.WORKBASKET_ID = X.WORKBASKET_ID AND s.perm_read = 1 fetch first 1 rows only ) "
+ "FROM X )"
+ "SELECT ID, EXTERNAL_ID, CREATED, CLAIMED, COMPLETED, MODIFIED, PLANNED, DUE, NAME, "
+ "CREATOR, DESCRIPTION, NOTE, PRIORITY, STATE, TCLASSIFICATION_KEY, "
+ "CLASSIFICATION_CATEGORY, CLASSIFICATION_ID, WORKBASKET_ID, DOMAIN, WORKBASKET_KEY, "
+ "BUSINESS_PROCESS_ID, PARENT_BUSINESS_PROCESS_ID, OWNER, POR_COMPANY, POR_SYSTEM, "
+ "POR_INSTANCE, POR_TYPE, POR_VALUE, IS_READ, IS_TRANSFERRED, CUSTOM_1, CUSTOM_2, "
+ "CUSTOM_3, CUSTOM_4, CUSTOM_5, CUSTOM_6, CUSTOM_7, CUSTOM_8, CUSTOM_9, CUSTOM_10, "
+ "CUSTOM_11, CUSTOM_12, CUSTOM_13, CUSTOM_14, CUSTOM_15, CUSTOM_16"
+ "<if test=\"addAttachmentColumnsToSelectClauseForOrdering\">"
+ ", ACLASSIFICATION_ID, ACLASSIFICATION_KEY, CHANNEL, REF_VALUE, RECEIVED "
+ "</if>"
+ "<if test=\"addClassificationNameToSelectClauseForOrdering\">"
+ ", CNAME "
+ "</if>"
+ "<if test=\"addAttachmentClassificationNameToSelectClauseForOrdering\">"
+ ", ACNAME "
+ "</if>"
+ "<if test=\"addWorkbasketNameToSelectClauseForOrdering\">"
+ ", WNAME "
+ "</if>"
+ " FROM Y WHERE FLAG = 1 "
+ "<if test='!orderBy.isEmpty()'>ORDER BY <foreach item='item' collection='orderBy' separator=',' >"
+ "${item}"
+ "</foreach>"
+ "<if test=\"addClassificationNameToSelectClauseForOrdering\">, CNAME </if>"
+ "<if test=\"addAttachmentClassificationNameToSelectClauseForOrdering\">, ACNAME </if>"
+ "<if test=\"addWorkbasketNameToSelectClauseForOrdering\">, WNAME </if>"
+ "FROM Y "
+ "WHERE FLAG = 1 "
+ "<if test='!orderBy.isEmpty()'>"
+ "ORDER BY <foreach item='item' collection='orderBy' separator=',' >${item}</foreach>"
+ "</if> "
+ "<if test='selectAndClaim == true'>FETCH FIRST ROW ONLY FOR UPDATE WITH RS USE AND KEEP UPDATE LOCKS</if>"
+ "<if test='selectAndClaim == true'>"
+ "FETCH FIRST ROW ONLY FOR UPDATE WITH RS USE AND KEEP UPDATE LOCKS"
+ "</if>"
+ "<if test='selectAndClaim == false'> with UR</if>"
+ CLOSING_SCRIPT_TAG;
}
public static String queryObjectReferences() {
return OPENING_SCRIPT_TAG
+ "SELECT ID, COMPANY, SYSTEM, SYSTEM_INSTANCE, TYPE, VALUE "
+ "FROM OBJECT_REFERENCE "
+ OPENING_WHERE_TAG
+ commonObjectReferenceWhereStatement()
+ CLOSING_WHERE_TAG
+ "<if test=\"_databaseId == 'db2'\">with UR </if> "
+ CLOSING_SCRIPT_TAG;
}
public static String countQueryTasks() {
return OPENING_SCRIPT_TAG
+ "SELECT COUNT( <if test=\"useDistinctKeyword\">DISTINCT</if> t.ID) FROM TASK t "
+ "SELECT COUNT( <if test=\"useDistinctKeyword\">DISTINCT</if> t.ID) "
+ "FROM TASK t "
+ "<if test=\"joinWithAttachments\">"
+ "LEFT JOIN ATTACHMENT AS a ON t.ID = a.TASK_ID "
+ "</if>"
@ -205,21 +207,26 @@ public class TaskQuerySqlProvider {
+ "</if>"
+ OPENING_WHERE_TAG
+ "<if test='accessIdIn != null'> "
+ "AND t.WORKBASKET_ID IN ( "
+ "select WID from (select WORKBASKET_ID as WID, MAX(PERM_READ::int) as MAX_READ FROM WORKBASKET_ACCESS_LIST AS s where "
+ "ACCESS_ID IN (<foreach item='item' collection='accessIdIn' separator=',' >#{item}</foreach>) "
+ "group by WORKBASKET_ID ) AS f where max_read = 1 ) "
+ "AND t.WORKBASKET_ID IN ("
+ "select WID from ("
+ "select WORKBASKET_ID as WID, MAX(PERM_READ::int) "
+ "as MAX_READ FROM WORKBASKET_ACCESS_LIST AS s "
+ "where ACCESS_ID IN "
+ "(<foreach item='item' collection='accessIdIn' separator=',' >#{item}</foreach>) "
+ "group by WORKBASKET_ID) AS f where max_read = 1) "
+ "</if> "
+ commonTaskWhereStatement()
+ commonTaskObjectReferenceWhereStatement()
+ "<if test='wildcardSearchValueLike != null and wildcardSearchFieldIn != null'>AND (<foreach item='item' collection='wildcardSearchFieldIn' separator=' OR '>UPPER(t.${item}) LIKE #{wildcardSearchValueLike}</foreach>)</if> "
+ WILDCARD_LIKE_STATEMENT
+ CLOSING_WHERE_TAG
+ CLOSING_SCRIPT_TAG;
}
public static String countQueryTasksDb2() {
return OPENING_SCRIPT_TAG
+ "WITH X (ID, WORKBASKET_ID) AS (SELECT <if test=\"useDistinctKeyword\">DISTINCT</if> t.ID, t.WORKBASKET_ID FROM TASK t "
+ "WITH X (ID, WORKBASKET_ID) AS ("
+ "SELECT <if test=\"useDistinctKeyword\">DISTINCT</if> "
+ "t.ID, t.WORKBASKET_ID FROM TASK t "
+ "<if test=\"joinWithAttachments\">"
+ "LEFT JOIN ATTACHMENT AS a ON t.ID = a.TASK_ID "
+ "</if>"
@ -232,29 +239,17 @@ public class TaskQuerySqlProvider {
+ OPENING_WHERE_TAG
+ commonTaskWhereStatement()
+ commonTaskObjectReferenceWhereStatement()
+ "<if test='wildcardSearchValueLike != null and wildcardSearchFieldIn != null'>AND (<foreach item='item' collection='wildcardSearchFieldIn' separator=' OR '>UPPER(t.${item}) LIKE #{wildcardSearchValueLike}</foreach>)</if> "
+ WILDCARD_LIKE_STATEMENT
+ CLOSING_WHERE_TAG
+ "), Y (ID, FLAG) AS "
+ "(SELECT ID, (SELECT 1 FROM WORKBASKET_ACCESS_LIST s WHERE "
+ "<if test='accessIdIn != null'> "
+ "s.ACCESS_ID IN (<foreach item='item' collection='accessIdIn' separator=',' >#{item}</foreach>) and "
+ "</if>"
+ "s.WORKBASKET_ID = X.WORKBASKET_ID AND "
+ "s.perm_read = 1 "
+ "fetch first 1 rows only "
+ ") FROM X ) "
+ "SELECT COUNT(*) FROM Y WHERE FLAG = 1 "
+ "with UR "
+ CLOSING_SCRIPT_TAG;
}
public static String countQueryObjectReferences() {
return OPENING_SCRIPT_TAG
+ "SELECT COUNT(ID) FROM OBJECT_REFERENCE "
+ OPENING_WHERE_TAG
+ commonObjectReferenceWhereStatement()
+ CLOSING_WHERE_TAG
+ "<if test=\"_databaseId == 'db2'\">with UR </if> "
+ "), Y (ID, FLAG) AS ("
+ "SELECT ID, ("
+ "SELECT 1 FROM WORKBASKET_ACCESS_LIST s "
+ "WHERE <if test='accessIdIn != null'> s.ACCESS_ID IN "
+ "(<foreach item='item' collection='accessIdIn' separator=',' >#{item}</foreach>) "
+ "and </if> "
+ "s.WORKBASKET_ID = X.WORKBASKET_ID AND s.perm_read = 1 fetch first 1 rows only ) "
+ "FROM X ) SELECT COUNT(*) "
+ "FROM Y WHERE FLAG = 1 with UR"
+ CLOSING_SCRIPT_TAG;
}
@ -273,14 +268,18 @@ public class TaskQuerySqlProvider {
+ "</if>"
+ OPENING_WHERE_TAG
+ "<if test='accessIdIn != null'> "
+ "AND t.WORKBASKET_ID IN ( "
+ "select WID from (select WORKBASKET_ID as WID, MAX(PERM_READ) as MAX_READ FROM WORKBASKET_ACCESS_LIST where "
+ "ACCESS_ID IN (<foreach item='item' collection='accessIdIn' separator=',' >#{item}</foreach>) "
+ "group by WORKBASKET_ID ) where max_read = 1 ) "
+ "AND t.WORKBASKET_ID IN ("
+ "select WID from ("
+ "select WORKBASKET_ID as WID, MAX(PERM_READ) as MAX_READ FROM WORKBASKET_ACCESS_LIST "
+ "where ACCESS_ID IN "
+ "(<foreach item='item' collection='accessIdIn' separator=',' >#{item}</foreach>) "
+ "group by WORKBASKET_ID) "
+ "where max_read = 1) "
+ "</if> "
+ commonTaskWhereStatement()
+ CLOSING_WHERE_TAG
+ "<if test='!orderBy.isEmpty()'>ORDER BY <foreach item='item' collection='orderBy' separator=',' >"
+ "<if test='!orderBy.isEmpty()'>"
+ "ORDER BY <foreach item='item' collection='orderBy' separator=',' >"
+ "<choose>"
+ "<when test=\"item.contains('TCLASSIFICATION_KEY ASC')\">"
+ "t.CLASSIFICATION_KEY ASC"
@ -312,22 +311,10 @@ public class TaskQuerySqlProvider {
+ "<when test=\"item.contains('A_CLASSIFICATION_NAME ASC')\">"
+ "ac.NAME ASC"
+ "</when>"
+ "<otherwise>"
+ "${item}"
+ "</otherwise>"
+ "<otherwise>${item}</otherwise>"
+ "</choose>"
+ "</foreach></if> "
+ "<if test=\"_databaseId == 'db2'\">with UR </if> "
+ CLOSING_SCRIPT_TAG;
}
public static String queryObjectReferenceColumnValues() {
return OPENING_SCRIPT_TAG
+ "SELECT DISTINCT ${columnName} "
+ "FROM OBJECT_REFERENCE "
+ OPENING_WHERE_TAG
+ commonObjectReferenceWhereStatement()
+ CLOSING_WHERE_TAG
+ "</foreach>"
+ "</if> "
+ "<if test=\"_databaseId == 'db2'\">with UR </if> "
+ CLOSING_SCRIPT_TAG;
}
@ -336,21 +323,24 @@ public class TaskQuerySqlProvider {
return "<if test='objectReferences != null'>"
+ "AND (<foreach item='item' collection='objectReferences' separator=' OR '> "
+ "<if test='item.company != null'>t.POR_COMPANY = #{item.company} </if>"
+ "<if test='item.system != null'> <if test='item.company != null'>AND</if> t.POR_SYSTEM = #{item.system} </if>"
+ "<if test='item.systemInstance != null'> <if test='item.company != null or item.system != null'>AND</if> t.POR_INSTANCE = #{item.systemInstance} </if>"
+ "<if test='item.type != null'> <if test='item.company != null or item.system != null or item.systemInstance != null'>AND</if> t.POR_TYPE = #{item.type} </if>"
+ "<if test='item.value != null'> <if test='item.company != null or item.system != null or item.systemInstance != null or item.type != null'>AND</if> t.POR_VALUE = #{item.value} </if>"
+ "</foreach>)</if>";
}
private static String commonObjectReferenceWhereStatement() {
StringBuilder sb = new StringBuilder();
whereIn("company", "COMPANY", sb);
whereIn("system", "SYSTEM", sb);
whereIn("systemInstance", "SYSTEM_INSTANCE", sb);
whereIn("type", "TYPE", sb);
whereIn("value", "VALUE", sb);
return sb.toString();
+ "<if test='item.system != null'> "
+ "<if test='item.company != null'>AND</if> "
+ "t.POR_SYSTEM = #{item.system} </if>"
+ "<if test='item.systemInstance != null'> "
+ "<if test='item.company != null or item.system != null'>AND</if> "
+ "t.POR_INSTANCE = #{item.systemInstance} </if>"
+ "<if test='item.type != null'> "
+ "<if test='item.company != null or item.system != null or item.systemInstance != null'>"
+ "AND</if> "
+ "t.POR_TYPE = #{item.type} </if>"
+ "<if test='item.value != null'> "
+ "<if test='item.company != null or item.system != null "
+ "or item.systemInstance != null or item.type != null'>"
+ "AND</if> "
+ "t.POR_VALUE = #{item.value} "
+ "</if>"
+ "</foreach>)"
+ "</if>";
}
private static String commonTaskWhereStatement() {
@ -413,7 +403,9 @@ public class TaskQuerySqlProvider {
sb.append("<if test='isRead != null'>AND IS_READ = #{isRead}</if> ");
sb.append("<if test='isTransferred != null'>AND IS_TRANSFERRED = #{isTransferred}</if> ");
sb.append(
"<if test='workbasketKeyDomainIn != null'>AND (<foreach item='item' collection='workbasketKeyDomainIn' separator=' OR '>(WORKBASKET_KEY = #{item.key} AND DOMAIN = #{item.domain})</foreach>)</if> ");
"<if test='workbasketKeyDomainIn != null'>AND (<foreach item='item'"
+ " collection='workbasketKeyDomainIn' separator=' OR '>(WORKBASKET_KEY = #{item.key}"
+ " AND DOMAIN = #{item.domain})</foreach>)</if> ");
return sb.toString();
}
@ -430,47 +422,4 @@ public class TaskQuerySqlProvider {
whereNotIn(collectionNotIn, column, sb);
});
}
private static void whereIn(String collection, String column, StringBuilder sb) {
sb.append("<if test='")
.append(collection)
.append(" != null'>AND ")
.append(column)
.append(" IN(<foreach item='item' collection='")
.append(collection)
.append("' separator=',' >#{item}</foreach>)</if> ");
}
private static void whereNotIn(String collection, String column, StringBuilder sb) {
sb.append("<if test='")
.append(collection)
.append(" != null'>AND ")
.append(column)
.append(" NOT IN(<foreach item='item' collection='")
.append(collection)
.append("' separator=',' >#{item}</foreach>)</if> ");
}
private static void whereInTime(String collection, String column, StringBuilder sb) {
sb.append("<if test='")
.append(collection)
.append(" !=null'> AND (<foreach item='item' collection='")
.append(collection)
.append("' separator=' OR ' > ( <if test='item.begin!=null'> ")
.append(column)
.append(
" &gt;= #{item.begin} </if> <if test='item.begin!=null and item.end!=null'> AND </if><if test='item.end!=null'> ")
.append(column)
.append(" &lt;=#{item.end} </if>)</foreach>)</if> ");
}
private static void whereLike(String collection, String column, StringBuilder sb) {
sb.append("<if test='")
.append(collection)
.append(" != null'>AND (<foreach item='item' collection='")
.append(collection)
.append("' separator=' OR '>UPPER(")
.append(column)
.append(") LIKE #{item}</foreach>)</if> ");
}
}

View File

@ -26,10 +26,13 @@ import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.DeleteProvider;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.InsertProvider;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.SelectProvider;
import org.apache.ibatis.annotations.Update;
import org.apache.ibatis.annotations.UpdateProvider;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.DynamicTest;
@ -41,6 +44,7 @@ import pro.taskana.common.api.exceptions.ErrorCode;
import pro.taskana.common.api.exceptions.TaskanaException;
import pro.taskana.common.api.exceptions.TaskanaRuntimeException;
import pro.taskana.common.internal.logging.LoggingAspect;
import pro.taskana.common.internal.util.CheckedFunction;
import pro.taskana.common.internal.util.MapCreator;
/**
@ -304,27 +308,60 @@ class ArchitectureTest {
private static ArchCondition<JavaClass> notUseCurrentTimestampSqlFunction() {
Function<JavaMethod, List<String>> getSqlStringsFromMethod =
(method) -> {
List<String> values = new ArrayList<>();
final Optional<Select> selectAnnotation = method.tryGetAnnotationOfType(Select.class);
final Optional<Update> updateAnnotation = method.tryGetAnnotationOfType(Update.class);
final Optional<Insert> insertAnnotation = method.tryGetAnnotationOfType(Insert.class);
final Optional<Delete> deleteAnnotation = method.tryGetAnnotationOfType(Delete.class);
CheckedFunction.wrap(
(method) -> {
List<String> values = new ArrayList<>();
final Optional<Select> selectAnnotation = method.tryGetAnnotationOfType(Select.class);
final Optional<Update> updateAnnotation = method.tryGetAnnotationOfType(Update.class);
final Optional<Insert> insertAnnotation = method.tryGetAnnotationOfType(Insert.class);
final Optional<Delete> deleteAnnotation = method.tryGetAnnotationOfType(Delete.class);
final Optional<SelectProvider> selectProviderAnnotation =
method.tryGetAnnotationOfType(SelectProvider.class);
final Optional<UpdateProvider> updateProviderAnnotation =
method.tryGetAnnotationOfType(UpdateProvider.class);
final Optional<InsertProvider> insertProviderAnnotation =
method.tryGetAnnotationOfType(InsertProvider.class);
final Optional<DeleteProvider> deleteProviderAnnotation =
method.tryGetAnnotationOfType(DeleteProvider.class);
if (selectAnnotation.isPresent()) {
values.addAll(Arrays.asList(selectAnnotation.get().value()));
}
if (updateAnnotation.isPresent()) {
values.addAll(Arrays.asList(updateAnnotation.get().value()));
}
if (insertAnnotation.isPresent()) {
values.addAll(Arrays.asList(insertAnnotation.get().value()));
}
if (deleteAnnotation.isPresent()) {
values.addAll(Arrays.asList(deleteAnnotation.get().value()));
}
return values;
};
if (selectAnnotation.isPresent()) {
values.addAll(Arrays.asList(selectAnnotation.get().value()));
}
if (updateAnnotation.isPresent()) {
values.addAll(Arrays.asList(updateAnnotation.get().value()));
}
if (insertAnnotation.isPresent()) {
values.addAll(Arrays.asList(insertAnnotation.get().value()));
}
if (deleteAnnotation.isPresent()) {
values.addAll(Arrays.asList(deleteAnnotation.get().value()));
}
if (selectProviderAnnotation.isPresent()) {
values.add(
executeStaticProviderMethod(
selectProviderAnnotation.get().type(),
selectProviderAnnotation.get().method()));
}
if (updateProviderAnnotation.isPresent()) {
values.add(
executeStaticProviderMethod(
updateProviderAnnotation.get().type(),
updateProviderAnnotation.get().method()));
}
if (insertProviderAnnotation.isPresent()) {
values.add(
executeStaticProviderMethod(
insertProviderAnnotation.get().type(),
insertProviderAnnotation.get().method()));
}
if (deleteProviderAnnotation.isPresent()) {
values.add(
executeStaticProviderMethod(
deleteProviderAnnotation.get().type(),
deleteProviderAnnotation.get().method()));
}
return values;
});
return new ArchCondition<JavaClass>("not use the SQL function 'CURRENT_TIMESTAMP'") {
@Override
@ -352,4 +389,9 @@ class ArchitectureTest {
}
};
}
private static String executeStaticProviderMethod(Class<?> clazz, String methodName)
throws Exception {
return clazz.getMethod(methodName).invoke(null).toString();
}
}

View File

@ -11,25 +11,17 @@ import org.junit.jupiter.api.extension.ExtendWith;
import pro.taskana.common.test.security.JaasExtension;
import pro.taskana.task.api.ObjectReferenceQuery;
import pro.taskana.task.api.TaskQuery;
import pro.taskana.task.api.TaskService;
import pro.taskana.task.api.models.ObjectReference;
/** Acceptance test for all "query classifications with pagination" scenarios. */
@ExtendWith(JaasExtension.class)
class QueryObjectreferencesWithPaginationAccTest extends AbstractAccTest {
class QueryObjectReferencesWithPaginationAccTest extends AbstractAccTest {
private TaskService taskService;
private TaskQuery taskQuery;
private ObjectReferenceQuery objRefQuery;
QueryObjectreferencesWithPaginationAccTest() {
super();
}
@BeforeEach
void before() {
taskService = taskanaEngine.getTaskService();
taskQuery = taskService.createTaskQuery();
TaskQuery taskQuery = taskanaEngine.getTaskService().createTaskQuery();
objRefQuery = taskQuery.createObjectReferenceQuery();
}

View File

@ -25,7 +25,6 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSession;
@ -43,6 +42,7 @@ import pro.taskana.common.api.BaseQuery.SortDirection;
import pro.taskana.common.api.TimeInterval;
import pro.taskana.common.api.exceptions.InvalidArgumentException;
import pro.taskana.common.internal.util.CollectionUtil;
import pro.taskana.common.internal.util.Pair;
import pro.taskana.common.internal.util.Triplet;
import pro.taskana.common.test.security.JaasExtension;
import pro.taskana.common.test.security.WithAccessId;
@ -238,7 +238,7 @@ class QueryTasksAccTest extends AbstractAccTest {
Attachment attachment =
createAttachment(
"DOCTYPE_DEFAULT", // prio 99, SL P2000D
"DOCTYPE_DEFAULT", // priority 99, SL P2000D
createObjectReference(
"COMPANY_A",
"SYSTEM_B",
@ -288,7 +288,7 @@ class QueryTasksAccTest extends AbstractAccTest {
@WithAccessId(user = "admin")
@TestFactory
Stream<DynamicTest> should_ReturnCorrectResults_When_QueryingForCustomXLikeInAndNotIn() {
Stream<DynamicTest> should_ReturnCorrectResults_When_QueryingForCustomXStatements() {
List<Triplet<TaskCustomField, String[], Integer>> list =
List.of(
Triplet.of(TaskCustomField.CUSTOM_1, new String[] {"custom%", "p%", "%xyz%", "efg"}, 3),
@ -312,10 +312,10 @@ class QueryTasksAccTest extends AbstractAccTest {
return DynamicTest.stream(
list.iterator(),
t -> t.getLeft().name(),
t -> testQueryForCustomX(t.getLeft(), t.getMiddle(), t.getRight()));
t -> testQueryForCustomXLikeAndIn(t.getLeft(), t.getMiddle(), t.getRight()));
}
void testQueryForCustomX(
void testQueryForCustomXLikeAndIn(
TaskCustomField customField, String[] searchArguments, int expectedResult) throws Exception {
List<TaskSummary> results =
TASK_SERVICE.createTaskQuery().customAttributeLike(customField, searchArguments).list();
@ -327,35 +327,43 @@ class QueryTasksAccTest extends AbstractAccTest {
List<TaskSummary> result2 =
TASK_SERVICE.createTaskQuery().customAttributeIn(customField, customAttributes).list();
assertThat(result2).hasSize(expectedResult);
}
List<String> allCustomAttributesWithValues =
TASK_SERVICE.createTaskQuery().list().stream()
.map(t -> t.getCustomAttribute(customField))
.filter(Objects::nonNull)
.collect(Collectors.toList());
@WithAccessId(user = "admin")
@TestFactory
Stream<DynamicTest> should_ReturnCorrectResults_When_QueryingForCustomXNotIn() {
// carefully constructed to always return exactly 2 results
List<Pair<TaskCustomField, String[]>> list =
List.of(
Pair.of(TaskCustomField.CUSTOM_1, new String[] {"custom1"}),
Pair.of(TaskCustomField.CUSTOM_2, new String[] {"%"}),
Pair.of(TaskCustomField.CUSTOM_3, new String[] {"custom3"}),
Pair.of(TaskCustomField.CUSTOM_4, new String[] {"%"}),
Pair.of(TaskCustomField.CUSTOM_5, new String[] {"ew", "al", "el"}),
Pair.of(TaskCustomField.CUSTOM_6, new String[] {"11", "vvg"}),
Pair.of(TaskCustomField.CUSTOM_7, new String[] {"%"}),
Pair.of(TaskCustomField.CUSTOM_8, new String[] {"%"}),
Pair.of(TaskCustomField.CUSTOM_9, new String[] {"%"}),
Pair.of(TaskCustomField.CUSTOM_10, new String[] {"custom10"}),
Pair.of(TaskCustomField.CUSTOM_11, new String[] {"custom11"}),
Pair.of(TaskCustomField.CUSTOM_12, new String[] {"custom12"}),
Pair.of(TaskCustomField.CUSTOM_13, new String[] {"custom13"}),
Pair.of(TaskCustomField.CUSTOM_14, new String[] {"abc"}),
Pair.of(TaskCustomField.CUSTOM_15, new String[] {"custom15"}),
Pair.of(TaskCustomField.CUSTOM_16, new String[] {"custom16"}));
assertThat(list).hasSameSizeAs(TaskCustomField.values());
// NotIn with an empty String should return all Tasks with a value in the specified customField
List<TaskSummary> results3 =
TASK_SERVICE.createTaskQuery().customAttributeNotIn(customField, "").list();
return DynamicTest.stream(
list.iterator(),
t -> t.getLeft().name(),
t -> testQueryForCustomXNotIn(t.getLeft(), t.getRight()));
}
assertThat(results3)
.extracting(t -> t.getCustomAttribute(customField))
.isEqualTo(allCustomAttributesWithValues);
List<String> customAttributeList = Arrays.asList(customAttributes);
List<String> allCustomAttributesWithValuesExceptResult2 =
allCustomAttributesWithValues.stream()
.filter(s -> !customAttributeList.contains(s))
.collect(Collectors.toList());
/* NotIn with the already used customAttributes should result in all Tasks with values in the
specified customField, except the ones specified in customAttributes*/
List<TaskSummary> results4 =
TASK_SERVICE.createTaskQuery().customAttributeNotIn(customField, customAttributes).list();
assertThat(results4)
.extracting(t -> t.getCustomAttribute(customField))
.isEqualTo(allCustomAttributesWithValuesExceptResult2);
void testQueryForCustomXNotIn(TaskCustomField customField, String[] searchArguments)
throws Exception {
long results =
TASK_SERVICE.createTaskQuery().customAttributeNotIn(customField, searchArguments).count();
assertThat(results).isEqualTo(2);
}
@WithAccessId(user = "admin")