Remove DISTINCT and GROUP BY, double visitor

pull/618/head
Alex Baker 6 years ago
parent d6a3484004
commit 299a63d4c6

@ -7,7 +7,6 @@ package com.todoroo.astrid.dao;
import android.support.test.runner.AndroidJUnit4;
import com.todoroo.andlib.data.Property;
import com.todoroo.andlib.sql.Query;
import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.astrid.dao.TaskDao.TaskCriteria;
@ -21,19 +20,12 @@ import org.tasks.injection.TestComponent;
import javax.inject.Inject;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNotSame;
import static junit.framework.Assert.assertNull;
import static junit.framework.Assert.assertTrue;
@RunWith(AndroidJUnit4.class)
public class TaskDaoTests extends InjectingTestCase {
public static Property<?>[] IDS = new Property<?>[] { Task.ID };
public static Property<?>[] TITLES = new Property<?>[] { Task.ID,
Task.TITLE };
@Inject TaskDao taskDao;
/**
@ -41,13 +33,13 @@ public class TaskDaoTests extends InjectingTestCase {
*/
@Test
public void testTaskCreation() {
assertEquals(0, taskDao.toList(Query.select(IDS)).size());
assertEquals(0, taskDao.toList(Query.select()).size());
// create task "happy"
Task task = new Task();
task.setTitle("happy");
taskDao.save(task);
assertEquals(1, taskDao.toList(Query.select(IDS)).size());
assertEquals(1, taskDao.toList(Query.select()).size());
long happyId = task.getId();
assertNotSame(Task.NO_ID, happyId);
task = taskDao.fetch(happyId);
@ -57,14 +49,14 @@ public class TaskDaoTests extends InjectingTestCase {
task = new Task();
task.setTitle("sad");
taskDao.save(task);
assertEquals(2, taskDao.toList(Query.select(IDS)).size());
assertEquals(2, taskDao.toList(Query.select()).size());
// rename sad to melancholy
long sadId = task.getId();
assertNotSame(Task.NO_ID, sadId);
task.setTitle("melancholy");
taskDao.save(task);
assertEquals(2, taskDao.toList(Query.select(IDS)).size());
assertEquals(2, taskDao.toList(Query.select()).size());
// check state
task = taskDao.fetch(happyId);
@ -112,10 +104,10 @@ public class TaskDaoTests extends InjectingTestCase {
taskDao.save(task);
// check is active
assertEquals(5, taskDao.toList(Query.select(TITLES).where(TaskCriteria.isActive())).size());
assertEquals(5, taskDao.toList(Query.select().where(TaskCriteria.isActive())).size());
// check is visible
assertEquals(5, taskDao.toList(Query.select(TITLES).where(TaskCriteria.isVisible())).size());
assertEquals(5, taskDao.toList(Query.select().where(TaskCriteria.isVisible())).size());
}
/**
@ -123,18 +115,18 @@ public class TaskDaoTests extends InjectingTestCase {
*/
@Test
public void testTDeletion() {
assertEquals(0, taskDao.toList(Query.select(IDS)).size());
assertEquals(0, taskDao.toList(Query.select()).size());
// create task "happy"
Task task = new Task();
task.setTitle("happy");
taskDao.save(task);
assertEquals(1, taskDao.toList(Query.select(IDS)).size());
assertEquals(1, taskDao.toList(Query.select()).size());
// delete
long happyId = task.getId();
assertEquals(1, taskDao.deleteById(happyId));
assertEquals(0, taskDao.toList(Query.select(IDS)).size());
assertEquals(0, taskDao.toList(Query.select()).size());
}
/**
@ -149,7 +141,7 @@ public class TaskDaoTests extends InjectingTestCase {
taskDao.save(task);
assertEquals(0, taskDao.toList(Query.select(IDS)).size());
assertEquals(0, taskDao.toList(Query.select()).size());
}
/**
@ -157,14 +149,14 @@ public class TaskDaoTests extends InjectingTestCase {
*/
@Test
public void testInvalidIndex() {
assertEquals(0, taskDao.toList(Query.select(IDS)).size());
assertEquals(0, taskDao.toList(Query.select()).size());
assertNull(taskDao.fetch(1));
assertEquals(0, taskDao.deleteById(1));
// make sure db still works
assertEquals(0, taskDao.toList(Query.select(IDS)).size());
assertEquals(0, taskDao.toList(Query.select()).size());
}
@Override

@ -190,7 +190,7 @@ public class GoogleTaskSyncAdapter extends InjectingAbstractThreadedSyncAdapter
}
private void pushLocalChanges() throws UserRecoverableAuthIOException {
List<Task> tasks = taskDao.toList(Query.select(Task.PROPERTIES)
List<Task> tasks = taskDao.toList(Query.select()
.join(Join.left(GoogleTask.TABLE.as("gt"), Task.ID.eq(Field.field("gt.task"))))
.where(Criterion.or(
Task.MODIFICATION_DATE.gt(Field.field("gt.last_sync")),

@ -108,8 +108,6 @@ public abstract class Property<TYPE> extends Field implements Cloneable {
RETURN visitLong(Property<Long> property, PARAMETER data);
RETURN visitDouble(Property<Double> property, PARAMETER data);
RETURN visitString(Property<String> property, PARAMETER data);
}
@ -231,18 +229,10 @@ public abstract class Property<TYPE> extends Field implements Cloneable {
// --- pseudo-properties
/** Runs a SQL function and returns the result as a string */
public static class IntegerFunctionProperty extends IntegerProperty {
public IntegerFunctionProperty(String function, String columnName) {
super(columnName, function);
alias = columnName;
}
}
/** Counting in aggregated tables. Returns the result of COUNT(1) */
public static final class CountProperty extends IntegerFunctionProperty {
public static class CountProperty extends IntegerProperty {
public CountProperty() {
super("COUNT(1)", "count");
alias = "count";
}
}
}

@ -114,12 +114,6 @@ public class TodorooCursor extends CursorWrapper {
return cursor.getLong(column);
}
@Override
public Object visitDouble(Property<Double> property, TodorooCursor cursor) {
int column = columnIndex(property, cursor);
return cursor.getDouble(column);
}
@Override
public Object visitString(Property<String> property, TodorooCursor cursor) {
int column = columnIndex(property, cursor);

@ -6,14 +6,13 @@
package com.todoroo.andlib.sql;
import com.todoroo.andlib.data.Property;
import com.todoroo.astrid.data.Task;
import java.util.ArrayList;
import static com.todoroo.andlib.sql.SqlConstants.ALL;
import static com.todoroo.andlib.sql.SqlConstants.COMMA;
import static com.todoroo.andlib.sql.SqlConstants.DISTINCT;
import static com.todoroo.andlib.sql.SqlConstants.FROM;
import static com.todoroo.andlib.sql.SqlConstants.GROUP_BY;
import static com.todoroo.andlib.sql.SqlConstants.LIMIT;
import static com.todoroo.andlib.sql.SqlConstants.ORDER_BY;
import static com.todoroo.andlib.sql.SqlConstants.SELECT;
@ -28,23 +27,19 @@ public final class Query {
private final ArrayList<Criterion> criterions = new ArrayList<>();
private final ArrayList<Field> fields = new ArrayList<>();
private final ArrayList<Join> joins = new ArrayList<>();
private final ArrayList<Field> groupBies = new ArrayList<>();
private final ArrayList<Order> orders = new ArrayList<>();
private int limits = -1;
private boolean distinct = false;
private Query(Field... fields) {
this.fields.addAll(asList(fields));
}
public static Query select(Field... fields) {
return new Query(fields);
public static Query select() {
return new Query(Task.PROPERTIES);
}
public static Query selectDistinct(Field... fields) {
Query query = new Query(fields);
query.distinct = true;
return query;
public static Query select(Field... fields) {
return new Query(fields);
}
public Query from(SqlTable fromTable) {
@ -62,11 +57,6 @@ public final class Query {
return this;
}
public Query groupBy(Field... groupBy) {
groupBies.addAll(asList(groupBy));
return this;
}
public Query orderBy(Order... order) {
orders.addAll(asList(order));
return this;
@ -96,11 +86,10 @@ public final class Query {
visitJoinClause(sql);
if(queryTemplate == null) {
visitWhereClause(sql);
visitGroupByClause(sql);
visitOrderByClause(sql);
visitLimitClause(sql);
} else {
if(groupBies.size() > 0 || orders.size() > 0) {
if(orders.size() > 0) {
throw new IllegalStateException("Can't have extras AND query template"); //$NON-NLS-1$
}
sql.append(queryTemplate);
@ -120,17 +109,6 @@ public final class Query {
sql.deleteCharAt(sql.length() - 1).append(SPACE);
}
private void visitGroupByClause(StringBuilder sql) {
if (groupBies.isEmpty()) {
return;
}
sql.append(GROUP_BY);
for (Field groupBy : groupBies) {
sql.append(SPACE).append(groupBy).append(COMMA);
}
sql.deleteCharAt(sql.length() - 1).append(SPACE);
}
private void visitWhereClause(StringBuilder sql) {
if (criterions.isEmpty()) {
return;
@ -156,9 +134,6 @@ public final class Query {
private void visitSelectClause(StringBuilder sql) {
sql.append(SELECT).append(SPACE);
if(distinct) {
sql.append(DISTINCT).append(SPACE);
}
if (fields.isEmpty()) {
sql.append(ALL).append(SPACE);
return;

@ -8,7 +8,6 @@ package com.todoroo.andlib.sql;
import java.util.ArrayList;
import static com.todoroo.andlib.sql.SqlConstants.COMMA;
import static com.todoroo.andlib.sql.SqlConstants.GROUP_BY;
import static com.todoroo.andlib.sql.SqlConstants.LIMIT;
import static com.todoroo.andlib.sql.SqlConstants.ORDER_BY;
import static com.todoroo.andlib.sql.SqlConstants.SPACE;
@ -26,7 +25,6 @@ public final class QueryTemplate {
private final ArrayList<Criterion> criterions = new ArrayList<>();
private final ArrayList<Join> joins = new ArrayList<>();
private final ArrayList<Field> groupBies = new ArrayList<>();
private final ArrayList<Order> orders = new ArrayList<>();
private Integer limit = null;
@ -50,7 +48,6 @@ public final class QueryTemplate {
StringBuilder sql = new StringBuilder();
visitJoinClause(sql);
visitWhereClause(sql);
visitGroupByClause(sql);
visitOrderByClause(sql);
if(limit != null) {
sql.append(LIMIT).append(SPACE).append(limit);
@ -69,17 +66,6 @@ public final class QueryTemplate {
sql.deleteCharAt(sql.length() - 1).append(SPACE);
}
private void visitGroupByClause(StringBuilder sql) {
if (groupBies.isEmpty()) {
return;
}
sql.append(GROUP_BY);
for (Field groupBy : groupBies) {
sql.append(SPACE).append(groupBy).append(COMMA);
}
sql.deleteCharAt(sql.length() - 1).append(SPACE);
}
private void visitWhereClause(StringBuilder sql) {
if (criterions.isEmpty()) {
return;

@ -7,7 +7,6 @@ package com.todoroo.andlib.sql;
public final class SqlConstants {
public static final String SELECT = "SELECT";
public static final String DISTINCT = "DISTINCT";
public static final String SPACE = " ";
public static final String AS = "AS";
public static final String COMMA = ",";
@ -20,7 +19,6 @@ public final class SqlConstants {
public static final String AND = "AND";
public static final String OR = "OR";
public static final String ORDER_BY = "ORDER BY";
public static final String GROUP_BY = "GROUP BY";
public static final String WHERE = "WHERE";
public static final String NOT = "NOT";
public static final String LIMIT = "LIMIT";

@ -124,7 +124,7 @@ public class TasksXmlExporter {
try {
String output = setupFile(backupDirectory,
exportType);
int tasks = taskDao.count(Query.select(Task.ID));
int tasks = taskDao.count(Query.select());
if(tasks > 0) {
doTasksExport(output);
@ -185,7 +185,7 @@ public class TasksXmlExporter {
}
private void serializeTasks() throws IOException {
List<Task> tasks = taskDao.toList(Query.select(Task.PROPERTIES).orderBy(Order.asc(Task.ID)));
List<Task> tasks = taskDao.toList(Query.select().orderBy(Order.asc(Task.ID)));
int length = tasks.size();
for(int i = 0; i < length; i++) {
Task task = tasks.get(i);

@ -206,7 +206,7 @@ public class TasksXmlImporter {
}
// if the task's name and creation date match an existing task, skip
Query query = Query.select(Task.ID, Task.COMPLETION_DATE, Task.DELETION_DATE)
Query query = Query.select()
.where(Criterion.and(Task.TITLE.eq(title), Task.CREATION_DATE.eq(created)));
if (taskDao.count(query) > 0) {
skipCount++;

@ -125,7 +125,7 @@ public class OldTaskPreferences extends InjectingPreferenceActivity {
private int deleteCalendarEvents(Criterion criterion) {
int deletedEventCount = 0;
List<Task> tasks = taskDao.toList(Query.select(Task.ID, Task.CALENDAR_URI).where(criterion));
List<Task> tasks = taskDao.toList(Query.select().where(criterion));
for (Task task : tasks) {
if (calendarEventProvider.deleteEvent(task)) {
deletedEventCount++;

@ -82,7 +82,7 @@ public abstract class TaskDao {
public List<Task> query(Filter filter) {
String query = PermaSql.replacePlaceholders(filter.getSqlQuery());
return query(Query.select(Task.PROPERTIES).withQueryTemplate(query)).toList();
return query(Query.select().withQueryTemplate(query)).toList();
}
public List<Task> toList(Query query) {
@ -207,9 +207,8 @@ public abstract class TaskDao {
}
public TodorooCursor fetchFiltered(String queryTemplate, Property<?>... properties) {
return query(queryTemplate == null
? Query.selectDistinct(properties)
: Query.select(properties).withQueryTemplate(PermaSql.replacePlaceholders(queryTemplate)));
return query(Query.select(properties)
.withQueryTemplate(PermaSql.replacePlaceholders(queryTemplate)));
}
/**

@ -167,7 +167,7 @@ public class Astrid2TaskProvider extends InjectingContentProvider {
private Cursor getTasks() {
MatrixCursor ret = new MatrixCursor(TASK_FIELD_LIST);
List<Integer> importanceColors = checkBoxes.get().getPriorityColors();
Query query = Query.select(Task.ID, Task.TITLE, Task.IMPORTANCE, Task.DUE_DATE)
Query query = Query.select()
.where(Criterion.and(TaskCriteria.isActive(), TaskCriteria.isVisible()))
.orderBy(SortHelper.defaultTaskOrder()).limit(MAX_NUMBER_OF_TASKS);
for (Task task : taskDao.get().toList(query)) {

@ -53,7 +53,7 @@ public final class ReminderService {
}
public void scheduleAllAlarms(TaskDao taskDao) {
Query query = Query.select(Task.PROPERTIES).where(Criterion.and(
Query query = Query.select().where(Criterion.and(
TaskCriteria.isActive(),
Criterion.or(Task.REMINDER_FLAGS.gt(0), Task.REMINDER_PERIOD.gt(0))));
for (Task task : taskDao.toList(query)) {

@ -147,7 +147,7 @@ class AstridOrderedListFragmentHelper {
if(chained.size() > 0) {
// move recurring items to item parent
List<Task> tasks = taskDao.toList(Query.select(Task.UUID, Task.RECURRENCE).where(
List<Task> tasks = taskDao.toList(Query.select().where(
Criterion.and(Task.UUID.in(chained.toArray(new String[chained.size()])),
Task.RECURRENCE.isNotNull(), Functions.length(Task.RECURRENCE).gt(0))));

@ -231,7 +231,7 @@ public class NotificationManager {
ArrayList<Long> taskIds = newArrayList(transform(notifications, n -> n.taskId));
QueryTemplate query = new QueryTemplate().where(Task.ID.in(taskIds));
Filter filter = new Filter(context.getString(R.string.notifications), query);
List<Task> tasks = taskDao.toList(Query.select(Task.PROPERTIES)
List<Task> tasks = taskDao.toList(Query.select()
.withQueryTemplate(query.toString()));
long when = notificationDao.latestTimestamp();
int maxPriority = 3;

Loading…
Cancel
Save