Refactor recursive query to use builder

gtask_related_email
Alex Baker 5 years ago
parent 0878820fe3
commit b5a85e44bb

@ -4,7 +4,6 @@ import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.NonNull;
import com.todoroo.andlib.sql.Criterion;
import com.todoroo.andlib.sql.Field;
import com.todoroo.andlib.sql.Join;
import com.todoroo.andlib.sql.QueryTemplate;
import com.todoroo.astrid.dao.TaskDao;
@ -51,15 +50,15 @@ public class CaldavFilter extends Filter {
private static QueryTemplate queryTemplate(CaldavCalendar caldavCalendar) {
return new QueryTemplate()
.join(Join.left(CaldavTask.TABLE, Task.ID.eq(Field.field("caldav_tasks.cd_task"))))
.join(Join.left(CaldavTask.TABLE, Task.ID.eq(CaldavTask.TASK)))
.where(getCriterion(caldavCalendar));
}
public static Criterion getCriterion(CaldavCalendar caldavCalendar) {
return Criterion.and(
TaskDao.TaskCriteria.activeAndVisible(),
Field.field("caldav_tasks.cd_deleted").eq(0),
Field.field("caldav_tasks.cd_calendar").eq(caldavCalendar.getUuid()));
CaldavTask.DELETED.eq(0),
CaldavTask.CALENDAR.eq(caldavCalendar.getUuid()));
}
private static Map<String, Object> getValuesForNewTask(CaldavCalendar caldavCalendar) {
@ -89,11 +88,6 @@ public class CaldavFilter extends Filter {
calendar = source.readParcelable(getClass().getClassLoader());
}
@Override
public boolean supportsSubtasks() {
return false;
}
@Override
public int getMenu() {
return R.menu.menu_caldav_list_fragment;

@ -4,7 +4,6 @@ import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.NonNull;
import com.todoroo.andlib.sql.Criterion;
import com.todoroo.andlib.sql.Field;
import com.todoroo.andlib.sql.Join;
import com.todoroo.andlib.sql.QueryTemplate;
import com.todoroo.astrid.dao.TaskDao;
@ -70,15 +69,15 @@ public class GtasksFilter extends Filter {
private static QueryTemplate getQueryTemplate(GoogleTaskList list) {
return new QueryTemplate()
.join(Join.left(GoogleTask.TABLE, Task.ID.eq(Field.field("google_tasks.gt_task"))))
.join(Join.left(GoogleTask.TABLE, Task.ID.eq(GoogleTask.TASK)))
.where(getCriterion(list));
}
public static Criterion getCriterion(GoogleTaskList list) {
return Criterion.and(
TaskDao.TaskCriteria.activeAndVisible(),
Field.field("google_tasks.gt_deleted").eq(0),
Field.field("google_tasks.gt_list_id").eq(list.getRemoteId()));
GoogleTask.DELETED.eq(0),
GoogleTask.LIST.eq(list.getRemoteId()));
}
private static Map<String, Object> getValuesForNewTasks(GoogleTaskList list) {

@ -14,7 +14,7 @@ public class CaldavTask {
public static final String KEY = "caldav";
@Deprecated public static final Table TABLE = new Table("caldav_tasks");
public static final Table TABLE = new Table("caldav_tasks");
public static final Property.IntegerProperty PARENT =
new Property.IntegerProperty(TABLE, "cd_parent");
@ -22,6 +22,12 @@ public class CaldavTask {
public static final Property.IntegerProperty TASK =
new Property.IntegerProperty(TABLE, "cd_task");
public static final Property.LongProperty DELETED =
new Property.LongProperty(TABLE, "cd_deleted");
public static final Property.StringProperty CALENDAR =
new Property.StringProperty(TABLE, "cd_calendar");
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "cd_id")
private long id;

@ -12,9 +12,8 @@ public class GoogleTask {
public static final String KEY = "gtasks"; // $NON-NLS-1$
@Deprecated public static final Table TABLE = new Table("google_tasks");
public static final Table TABLE = new Table("google_tasks");
@Deprecated
public static final Property.IntegerProperty ORDER =
new Property.IntegerProperty(GoogleTask.TABLE, "gt_order");
@ -24,6 +23,12 @@ public class GoogleTask {
public static final Property.IntegerProperty TASK =
new Property.IntegerProperty(TABLE, "gt_task");
public static final Property.LongProperty DELETED =
new Property.LongProperty(TABLE, "gt_deleted");
public static final Property.StringProperty LIST =
new Property.StringProperty(TABLE, "gt_list_id");
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name = "gt_id")
private transient long id;

@ -23,7 +23,6 @@ import com.todoroo.andlib.data.Table;
import com.todoroo.andlib.sql.Criterion;
import com.todoroo.andlib.sql.Field;
import com.todoroo.andlib.sql.Join;
import com.todoroo.andlib.sql.Order;
import com.todoroo.andlib.sql.Query;
import com.todoroo.andlib.sql.QueryTemplate;
import com.todoroo.astrid.api.CaldavFilter;
@ -57,6 +56,7 @@ public class TaskListViewModel extends ViewModel implements Observer<PagedList<T
new PagedList.Config.Builder().setPageSize(20).build();
private static final Table RECURSIVE = new Table("recursive_tasks");
private static final Field RECURSIVE_TASK = field(RECURSIVE + ".task");
private static final Field TASKS = field("tasks.*");
private static final Field GTASK = field(GTASK_METADATA_JOIN + ".*");
private static final Field GEOFENCE = field("geofences.*");
@ -130,6 +130,12 @@ public class TaskListViewModel extends ViewModel implements Observer<PagedList<T
Criterion.and(caldavJoinCriterion, field(CALDAV_METADATA_JOIN + ".cd_calendar").eq(uuid));
}
String joins =
Join.left(GoogleTask.TABLE.as(GTASK_METADATA_JOIN), gtaskJoinCriterion).toString()
+ Join.left(CaldavTask.TABLE.as(CALDAV_METADATA_JOIN), caldavJoinCriterion)
+ Join.left(Geofence.TABLE, field(Geofence.TABLE_NAME + ".task").eq(Task.ID))
+ Join.left(Place.TABLE, field(Place.TABLE_NAME + ".uid").eq(field("geofences.place")));
if (atLeastLollipop()
&& (filter instanceof CaldavFilter
|| (!preferences.isManualSort() && filter instanceof GtasksFilter))) {
@ -144,50 +150,53 @@ public class TaskListViewModel extends ViewModel implements Observer<PagedList<T
fields.add(TAGS_RECURSIVE);
fields.add(INDENT);
String joinedQuery =
Join.left(Task.TABLE, Task.ID.eq(field("recursive_tasks.task")))
+ Join.left(GoogleTask.TABLE.as(GTASK_METADATA_JOIN), gtaskJoinCriterion).toString()
+ Join.left(CaldavTask.TABLE.as(CALDAV_METADATA_JOIN), caldavJoinCriterion)
+ Join.left(Geofence.TABLE, field(Geofence.TABLE_NAME + ".task").eq(Task.ID))
+ Join.left(Place.TABLE, field(Place.TABLE_NAME + ".uid").eq(field("geofences.place")));
String sortSelect = SortHelper.orderSelectForSortTypeRecursive(preferences.getSortMode());
Order order = SortHelper.orderForSortTypeRecursive(preferences);
Field parent;
QueryTemplate query;
String joinedQuery = Join.left(Task.TABLE, Task.ID.eq(RECURSIVE_TASK)) + joins;
String parentQuery;
QueryTemplate subtaskQuery = new QueryTemplate();
if (filter instanceof CaldavFilter) {
query = new QueryTemplate()
Criterion criterion = CaldavFilter.getCriterion(((CaldavFilter) filter).getCalendar());
parentQuery =
new QueryTemplate()
.join(Join.left(CaldavTask.TABLE, Task.ID.eq(CaldavTask.TASK)))
.where(Criterion.and(criterion, CaldavTask.PARENT.eq(0)))
.toString();
subtaskQuery
.join(Join.inner(RECURSIVE, RECURSIVE_TASK.eq(CaldavTask.PARENT)))
.join(Join.left(CaldavTask.TABLE, Task.ID.eq(CaldavTask.TASK)))
.where(CaldavFilter.getCriterion(((CaldavFilter) filter).getCalendar()));
parent = CaldavTask.PARENT;
.where(criterion);
} else {
query = new QueryTemplate()
Criterion criterion = GtasksFilter.getCriterion(((GtasksFilter) filter).getList());
parentQuery =
new QueryTemplate()
.join(Join.left(GoogleTask.TABLE, Task.ID.eq(GoogleTask.TASK)))
.where(Criterion.and(criterion, GoogleTask.PARENT.eq(0)))
.toString();
subtaskQuery
.join(Join.inner(RECURSIVE, RECURSIVE_TASK.eq(GoogleTask.PARENT)))
.join(Join.left(GoogleTask.TABLE, Task.ID.eq(GoogleTask.TASK)))
.where(GtasksFilter.getCriterion(((GtasksFilter) filter).getList()));
parent = GoogleTask.PARENT;
.where(criterion);
}
String filterSql = query.toString();
String withClause = "WITH RECURSIVE\n"
+ " recursive_tasks (task, indent, title, sortField) AS (\n"
+ " SELECT _id, 0 AS sort_indent, UPPER(title) AS sort_title, " + sortSelect + "\n"
String sortSelect = SortHelper.orderSelectForSortTypeRecursive(preferences.getSortMode());
String withClause =
"WITH RECURSIVE recursive_tasks (task, indent, title, sortField) AS (\n"
+ " SELECT tasks._id, 0 AS sort_indent, UPPER(title) AS sort_title, "
+ sortSelect
+ " FROM tasks\n"
+ filterSql
+ " AND " + parent + " = 0\n"
+ " UNION ALL\n"
+ " SELECT _id, recursive_tasks.indent+1 AS sort_indent, UPPER(tasks.title) AS sort_title, " + sortSelect + "\n"
+ parentQuery
+ "\nUNION ALL SELECT tasks._id, recursive_tasks.indent+1 AS sort_indent, UPPER(tasks.title) AS sort_title, "
+ sortSelect
+ " FROM tasks\n"
+ " INNER JOIN recursive_tasks ON " + parent + " = recursive_tasks.task\n"
+ filterSql
+ " ORDER BY sort_indent DESC, " + order + "\n"
+ " )\n";
withClause = SortHelper.adjustQueryForFlags(preferences, withClause);
+ subtaskQuery
+ "\nORDER BY sort_indent DESC, "
+ SortHelper.orderForSortTypeRecursive(preferences)
+ ")";
return Query.select(fields.toArray(new Field[0]))
.withQueryTemplate(PermaSql.replacePlaceholdersForQuery(joinedQuery))
.withPreClause(withClause)
.from(RECURSIVE)
.toString();
.withPreClause(SortHelper.adjustQueryForFlags(preferences, withClause))
.withQueryTemplate(PermaSql.replacePlaceholdersForQuery(joinedQuery))
.from(RECURSIVE)
.toString();
} else {
fields.add(TAGS);
@ -195,12 +204,9 @@ public class TaskListViewModel extends ViewModel implements Observer<PagedList<T
// Eventually, we might consider restructuring things so that this query is constructed
// elsewhere.
String joinedQuery =
Join.left(Tag.TABLE.as(TAGS_METADATA_JOIN), tagsJoinCriterion).toString()
+ Join.left(GoogleTask.TABLE.as(GTASK_METADATA_JOIN), gtaskJoinCriterion)
+ Join.left(CaldavTask.TABLE.as(CALDAV_METADATA_JOIN), caldavJoinCriterion)
+ Join.left(Geofence.TABLE, field(Geofence.TABLE_NAME + ".task").eq(Task.ID))
+ Join.left(Place.TABLE, field(Place.TABLE_NAME + ".uid").eq(field("geofences.place")))
+ filter.getSqlQuery();
Join.left(Tag.TABLE.as(TAGS_METADATA_JOIN), tagsJoinCriterion).toString()
+ joins
+ filter.getSqlQuery();
String query =
SortHelper.adjustQueryForFlagsAndSort(preferences, joinedQuery, preferences.getSortMode());

Loading…
Cancel
Save