Refactor recursive queries

pull/2278/head
Alex Baker 1 year ago
parent 9e60949019
commit 47f4ae8dde

@ -152,85 +152,43 @@ public class SortHelper {
}
public static String orderSelectForSortTypeRecursive(int sortType) {
String select;
switch (sortType) {
case SORT_ALPHA:
return switch (sortType) {
case SORT_ALPHA ->
// Return an empty string, providing a value to fill the WITH clause template
select = "''";
break;
case SORT_DUE:
select = "(CASE WHEN (tasks.dueDate=0) THEN (strftime('%s','now')*1000)*2 ELSE "
+ ADJUSTED_DUE_DATE.replace("dueDate", "tasks.dueDate")
+ " END)+tasks.importance AS sort_duedate";
break;
case SORT_START:
select = "(CASE WHEN (tasks.hideUntil=0) THEN (strftime('%s','now')*1000)*2 ELSE "
+ ADJUSTED_START_DATE.replace("hideUntil", "tasks.hideUntil")
+ " END)+tasks.importance AS sort_startdate";
break;
case SORT_IMPORTANCE:
select = "tasks.importance*(strftime('%s','now')*1000)+(CASE WHEN (tasks.dueDate=0) THEN (strftime('%s','now')*1000) ELSE tasks.dueDate END) AS sort_importance";
break;
case SORT_MODIFIED:
select = "tasks.modified AS sort_modified";
break;
case SORT_CREATED:
select = "tasks.created AS sort_created";
break;
case SORT_GTASKS:
select = "tasks.`order` AS sort_manual";
break;
case SORT_CALDAV:
select = CALDAV_ORDER_COLUMN + " AS sort_manual";
break;
default:
select ="(CASE WHEN (tasks.dueDate=0) "
+ // if no due date
"THEN (strftime('%s','now')*1000)*2 "
+ // then now * 2
"ELSE ("
+ ADJUSTED_DUE_DATE.replace("dueDate", "tasks.dueDate")
+ ") END) "
+ // else due time
// add slightly less than 2 days * importance to give due date priority over importance in case of tie
"+ 172799999 * tasks.importance AS sort_smart";
}
return select;
"''";
case SORT_DUE -> "(CASE WHEN (tasks.dueDate=0) THEN (strftime('%s','now')*1000)*2 ELSE "
+ ADJUSTED_DUE_DATE.replace("dueDate", "tasks.dueDate")
+ " END)+tasks.importance";
case SORT_START -> "(CASE WHEN (tasks.hideUntil=0) THEN (strftime('%s','now')*1000)*2 ELSE "
+ ADJUSTED_START_DATE.replace("hideUntil", "tasks.hideUntil")
+ " END)+tasks.importance";
case SORT_IMPORTANCE ->
"tasks.importance*(strftime('%s','now')*1000)+(CASE WHEN (tasks.dueDate=0) THEN (strftime('%s','now')*1000) ELSE tasks.dueDate END)";
case SORT_MODIFIED -> "tasks.modified";
case SORT_CREATED -> "tasks.created";
case SORT_GTASKS -> "tasks.`order`";
case SORT_CALDAV -> CALDAV_ORDER_COLUMN;
default -> "(CASE WHEN (tasks.dueDate=0) "
+ // if no due date
"THEN (strftime('%s','now')*1000)*2 "
+ // then now * 2
"ELSE ("
+ ADJUSTED_DUE_DATE.replace("dueDate", "tasks.dueDate")
+ ") END) "
+ // else due time
// add slightly less than 2 days * importance to give due date priority over importance in case of tie
"+ 172799999 * tasks.importance";
};
}
public static Order orderForSortTypeRecursive(int sortMode, boolean reverse) {
Order order;
switch (sortMode) {
case SORT_ALPHA:
order = Order.asc("sort_title");
break;
case SORT_DUE:
order = Order.asc("sort_duedate");
break;
case SORT_START:
order = Order.asc("sort_startdate");
break;
case SORT_IMPORTANCE:
order = Order.asc("sort_importance");
break;
case SORT_MODIFIED:
order = Order.desc("sort_modified");
break;
case SORT_CREATED:
order = Order.desc("sort_created");
break;
case SORT_GTASKS:
case SORT_CALDAV:
order = Order.asc("sort_manual");
break;
default:
order = Order.asc("sort_smart");
}
Order order = switch (sortMode) {
case SORT_MODIFIED, SORT_CREATED -> Order.desc("primary_sort");
default -> Order.asc("primary_sort");
};
if (sortMode != SORT_ALPHA) {
order.addSecondaryExpression(Order.asc("sort_title"));
}
if (reverse) {
order = order.reverse();
}

@ -39,44 +39,22 @@ internal object TaskListQueryRecursive {
.where(activeAndVisible())
fun getRecursiveQuery(
filter: Filter,
preferences: QueryPreferences,
filter: Filter,
preferences: QueryPreferences,
): MutableList<String> {
var joinedQuery = JOINS
var where = " WHERE recursive_tasks.hidden = 0"
val parentQuery: String
when (filter) {
is CaldavFilter -> {
parentQuery = newCaldavQuery(filter.uuid)
}
is GtasksFilter -> {
parentQuery = newCaldavQuery(filter.list.uuid!!)
}
else -> {
parentQuery = PermaSql.replacePlaceholdersForQuery(filter.getSqlQuery())
joinedQuery += " LEFT JOIN (SELECT task, max(indent) AS max_indent FROM recursive_tasks GROUP BY task) AS recursive_indents ON recursive_indents.task = tasks._id "
where += " AND indent = max_indent "
}
val parentQuery = when (filter) {
is CaldavFilter -> newCaldavQuery(filter.uuid)
is GtasksFilter -> newCaldavQuery(filter.list.uuid!!)
else -> PermaSql.replacePlaceholdersForQuery(filter.getSqlQuery())
}
joinedQuery += where
val manualSort = preferences.isManualSort
val sortMode: Int
val sortField: String
when {
manualSort && filter is GtasksFilter -> {
sortMode = SortHelper.SORT_GTASKS
sortField = "tasks.`order`"
}
manualSort && filter is CaldavFilter -> {
sortMode = SortHelper.SORT_CALDAV
sortField = SortHelper.CALDAV_ORDER_COLUMN
}
else -> {
sortMode = preferences.sortMode
sortField = "NULL"
}
val sortMode = when {
manualSort && filter is GtasksFilter -> SortHelper.SORT_GTASKS
manualSort && filter is CaldavFilter -> SortHelper.SORT_CALDAV
else -> preferences.sortMode
}
val reverseSort = preferences.isReverseSort && sortMode != SortHelper.SORT_GTASKS && sortMode != SortHelper.SORT_CALDAV
val reverseSort =
preferences.isReverseSort && sortMode != SortHelper.SORT_GTASKS && sortMode != SortHelper.SORT_CALDAV
val sortSelect = SortHelper.orderSelectForSortTypeRecursive(sortMode)
val parentCompleted = if (preferences.completedTasksAtBottom) "tasks.completed > 0" else "0"
val completionSort =
@ -85,26 +63,29 @@ internal object TaskListQueryRecursive {
} else {
"0"
}
val withClause ="""
val withClause = """
CREATE TEMPORARY TABLE `recursive_tasks` AS
WITH RECURSIVE recursive_tasks (task, parent_complete, subtask_complete, completion_sort, parent, collapsed, hidden, indent, title, sortField, primary_sort, secondary_sort, sort_group) AS (
SELECT tasks._id, $parentCompleted as parent_complete, 0 as subtask_complete, $completionSort as completion_sort, 0 as parent, tasks.collapsed as collapsed, 0 as hidden, 0 AS sort_indent, UPPER(tasks.title) AS sort_title, $sortSelect, $sortField as primary_sort, NULL as secondarySort, ${SortHelper.getSortGroup(sortMode)} FROM tasks
WITH RECURSIVE recursive_tasks (task, parent_complete, subtask_complete, completion_sort, parent, collapsed, hidden, indent, title, primary_sort, secondary_sort, sort_group) AS (
SELECT tasks._id, $parentCompleted as parent_complete, 0 as subtask_complete, $completionSort as completion_sort, 0 as parent, tasks.collapsed as collapsed, 0 as hidden, 0 AS sort_indent, UPPER(tasks.title) AS sort_title, $sortSelect as primary_sort, NULL as secondarySort, ${SortHelper.getSortGroup(sortMode)}
FROM tasks
$parentQuery
UNION ALL SELECT tasks._id, recursive_tasks.parent_complete, $parentCompleted as subtask_complete, $completionSort as completion_sort, recursive_tasks.task as parent, tasks.collapsed as collapsed, CASE WHEN recursive_tasks.collapsed > 0 OR recursive_tasks.hidden > 0 THEN 1 ELSE 0 END as hidden, recursive_tasks.indent+1 AS sort_indent, UPPER(tasks.title) AS sort_title, $sortSelect, recursive_tasks.primary_sort as primary_sort, $sortField as secondary_sort, recursive_tasks.sort_group FROM tasks
UNION ALL SELECT tasks._id, recursive_tasks.parent_complete, $parentCompleted as subtask_complete, $completionSort as completion_sort, recursive_tasks.task as parent, tasks.collapsed as collapsed, CASE WHEN recursive_tasks.collapsed > 0 OR recursive_tasks.hidden > 0 THEN 1 ELSE 0 END as hidden, recursive_tasks.indent+1 AS sort_indent, UPPER(tasks.title) AS sort_title, recursive_tasks.primary_sort as primary_sort, $sortSelect as secondary_sort, recursive_tasks.sort_group FROM tasks
$SUBTASK_QUERY
ORDER BY parent_complete ASC, sort_indent DESC, subtask_complete ASC, completion_sort DESC, ${SortHelper.orderForSortTypeRecursive(sortMode, reverseSort)}
) SELECT * FROM recursive_tasks
WHERE indent = (SELECT MAX(indent) FROM recursive_tasks as r WHERE r.task = recursive_tasks.task)
""".trimIndent()
return mutableListOf(
"DROP TABLE IF EXISTS `temp`.`recursive_tasks`",
SortHelper.adjustQueryForFlags(preferences, withClause),
"CREATE INDEX `r_tasks` ON `recursive_tasks` (`task`)",
"CREATE INDEX `r_parents` ON `recursive_tasks` (`parent`)",
Query.select(*FIELDS)
.withQueryTemplate(PermaSql.replacePlaceholdersForQuery(joinedQuery))
.from(Task.TABLE)
.toString())
"DROP TABLE IF EXISTS `recursive_tasks`",
SortHelper.adjustQueryForFlags(preferences, withClause),
"CREATE INDEX `r_tasks` ON `recursive_tasks` (`task`)",
"CREATE INDEX `r_parents` ON `recursive_tasks` (`parent`)",
Query.select(*FIELDS)
.withQueryTemplate(PermaSql.replacePlaceholdersForQuery("$JOINS WHERE recursive_tasks.hidden = 0"))
.from(Task.TABLE)
.toString(),
)
}
private fun newCaldavQuery(list: String) =
@ -117,4 +98,4 @@ internal object TaskListQueryRecursive {
CaldavTask.DELETED.eq(0))))
.where(Criterion.and(activeAndVisible(), Task.PARENT.eq(0)))
.toString()
}
}

Loading…
Cancel
Save