Remove TodorooCursor

pull/618/head
Alex Baker 6 years ago
parent 8a2cbbd91a
commit 8a8ab611b2

@ -102,8 +102,7 @@ public class GtasksListService {
public void deleteList(GoogleTaskList gtasksList) {
List<Task> tasks = taskListDataProvider
.constructCursor(new GtasksFilter(gtasksList), Task.PROPERTIES)
.toList();
.toList(new GtasksFilter(gtasksList));
for (Task task : tasks) {
taskDeleter.markDeleted(task);
}

@ -7,10 +7,10 @@ package com.todoroo.astrid.gtasks;
import android.app.Activity;
import android.content.Context;
import android.database.Cursor;
import android.os.Bundle;
import com.todoroo.andlib.data.Property;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.astrid.activity.TaskListFragment;
import com.todoroo.astrid.adapter.TaskAdapter;
import com.todoroo.astrid.api.GtasksFilter;
@ -78,7 +78,7 @@ public class GtasksSubtaskListFragment extends GtasksListFragment {
}
@Override
protected TaskAdapter createTaskAdapter(TodorooCursor cursor) {
protected TaskAdapter createTaskAdapter(Cursor cursor) {
return helper.createTaskAdapter(theme.wrap(context), cursor);
}

@ -9,7 +9,6 @@ import android.content.Context;
import android.database.Cursor;
import android.text.TextUtils;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.astrid.activity.TaskListFragment;
import com.todoroo.astrid.adapter.TaskAdapter;
@ -56,7 +55,7 @@ class OrderedMetadataListFragmentHelper {
updater.initialize(filter);
}
TaskAdapter createTaskAdapter(Context context, TodorooCursor cursor) {
TaskAdapter createTaskAdapter(Context context, Cursor cursor) {
taskAdapter = new DraggableTaskAdapter(context, cursor);
taskAdapter.setOnCompletedTaskListener(this::setCompletedForItemAndSubtasks);

@ -5,6 +5,7 @@
*/
package com.todoroo.andlib.data;
import android.database.Cursor;
import android.text.TextUtils;
import com.todoroo.andlib.sql.Criterion;
@ -60,8 +61,7 @@ public abstract class Property<TYPE> extends Field implements Cloneable {
/**
* Accept a visitor
*/
abstract public <RETURN, PARAMETER> RETURN accept(
PropertyVisitor<RETURN, PARAMETER> visitor, PARAMETER data);
abstract public TYPE getValue(Cursor data);
/**
* Return a clone of this property
@ -95,22 +95,6 @@ public abstract class Property<TYPE> extends Field implements Cloneable {
}
}
// --- helper classes and interfaces
/**
* Visitor interface for property classes
*
* @author Tim Su <tim@todoroo.com>
*
*/
public interface PropertyVisitor<RETURN, PARAMETER> {
RETURN visitInteger(Property<Integer> property, PARAMETER data);
RETURN visitLong(Property<Long> property, PARAMETER data);
RETURN visitString(Property<String> property, PARAMETER data);
}
// --- children
/**
@ -130,9 +114,8 @@ public abstract class Property<TYPE> extends Field implements Cloneable {
}
@Override
public <RETURN, PARAMETER> RETURN accept(
PropertyVisitor<RETURN, PARAMETER> visitor, PARAMETER data) {
return visitor.visitInteger(this, data);
public Integer getValue(Cursor data) {
return data.getInt(data.getColumnIndexOrThrow(getColumnName()));
}
@Override
@ -159,9 +142,8 @@ public abstract class Property<TYPE> extends Field implements Cloneable {
}
@Override
public <RETURN, PARAMETER> RETURN accept(
PropertyVisitor<RETURN, PARAMETER> visitor, PARAMETER data) {
return visitor.visitString(this, data);
public String getValue(Cursor data) {
return data.getString(data.getColumnIndexOrThrow(getColumnName()));
}
@Override
@ -203,9 +185,8 @@ public abstract class Property<TYPE> extends Field implements Cloneable {
}
@Override
public <RETURN, PARAMETER> RETURN accept(
PropertyVisitor<RETURN, PARAMETER> visitor, PARAMETER data) {
return visitor.visitLong(this, data);
public Long getValue(Cursor data) {
return data.getLong(data.getColumnIndexOrThrow(getColumnName()));
}
@Override

@ -1,127 +0,0 @@
/**
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.andlib.data;
import android.database.Cursor;
import android.database.CursorWrapper;
import com.todoroo.andlib.data.Property.PropertyVisitor;
import com.todoroo.astrid.data.Task;
import java.util.ArrayList;
import java.util.List;
import java.util.WeakHashMap;
/**
* AstridCursor wraps a cursor and allows users to query for individual
* {@link Property} types or read an entire {@link AbstractModel} from
* a database row.
*
* @author Tim Su <tim@todoroo.com>
*
*/
public class TodorooCursor extends CursorWrapper {
/** Properties read by this cursor */
private final Property<?>[] properties;
/** Weakly cache field name to column id references for this cursor.
* Because it's a weak hash map, entire keys can be discarded by GC */
private final WeakHashMap<String, Integer> columnIndexCache;
/** Property reading visitor */
private static final CursorReadingVisitor reader = new CursorReadingVisitor();
/**
* Create an <code>AstridCursor</code> from the supplied {@link Cursor}
* object.
*
* @param properties properties read from this cursor
*/
public TodorooCursor(Cursor cursor, Property<?>[] properties) {
super(cursor);
this.properties = properties;
columnIndexCache = new WeakHashMap<>();
}
public List<Task> toList() {
List<Task> result = new ArrayList<>();
try {
for (moveToFirst() ; !isAfterLast() ; moveToNext()) {
result.add(toModel());
}
} finally {
close();
}
return result;
}
public Task toModel() {
return new Task(this);
}
/**
* Get the value for the given property on the underlying {@link Cursor}
*
* @param <PROPERTY_TYPE> type to return
* @param property to retrieve
*/
public <PROPERTY_TYPE> PROPERTY_TYPE get(Property<?> property) {
return (PROPERTY_TYPE)property.accept(reader, this);
}
/**
* Gets entire property list
*/
public Property<?>[] getProperties() {
return properties;
}
/**
* Use cache to get the column index for the given field name
*/
synchronized int getColumnIndexFromCache(String field) {
Integer index = columnIndexCache.get(field);
if(index == null) {
index = getColumnIndexOrThrow(field);
columnIndexCache.put(field, index);
}
return index;
}
/**
* Visitor that reads the given property from a cursor
*
* @author Tim Su <tim@todoroo.com>
*
*/
public static class CursorReadingVisitor implements PropertyVisitor<Object, TodorooCursor> {
@Override
public Object visitInteger(Property<Integer> property, TodorooCursor cursor) {
int column = columnIndex(property, cursor);
return cursor.getInt(column);
}
@Override
public Object visitLong(Property<Long> property, TodorooCursor cursor) {
int column = columnIndex(property, cursor);
return cursor.getLong(column);
}
@Override
public Object visitString(Property<String> property, TodorooCursor cursor) {
int column = columnIndex(property, cursor);
return cursor.getString(column);
}
private int columnIndex(Property<?> property, TodorooCursor cursor) {
return cursor.getColumnIndexFromCache(property.getColumnName());
}
}
}

@ -130,7 +130,9 @@ public final class TaskEditFragment extends InjectingFragment implements Toolbar
toolbar.setOnMenuItemClickListener(this);
MenuColorizer.colorToolbar(context, toolbar);
notificationManager.cancel(model.getId());
if (!model.isNew()) {
notificationManager.cancel(model.getId());
}
commentsController.initialize(model, comments);
commentsController.reloadView();

@ -28,7 +28,6 @@ import android.view.View;
import android.view.ViewGroup;
import com.todoroo.andlib.data.Property;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.sql.Criterion;
import com.todoroo.andlib.sql.QueryTemplate;
import com.todoroo.astrid.adapter.TaskAdapter;
@ -434,7 +433,7 @@ public class TaskListFragment extends InjectingFragment implements
}
}
protected TaskAdapter createTaskAdapter(TodorooCursor cursor) {
protected TaskAdapter createTaskAdapter(Cursor cursor) {
return new TaskAdapter(context, cursor);
}
@ -450,7 +449,7 @@ public class TaskListFragment extends InjectingFragment implements
return;
}
TodorooCursor currentCursor = taskListDataProvider.constructCursor(filter, taskProperties());
Cursor currentCursor = taskListDataProvider.constructCursor(filter, taskProperties());
if (currentCursor == null) {
return;
}
@ -470,7 +469,7 @@ public class TaskListFragment extends InjectingFragment implements
}
public void reconstructCursor() {
TodorooCursor cursor = taskListDataProvider.constructCursor(filter, taskProperties());
Cursor cursor = taskListDataProvider.constructCursor(filter, taskProperties());
if (cursor == null || taskAdapter == null) {
return;
}

@ -16,7 +16,6 @@ import com.google.common.collect.ObjectArrays;
import com.todoroo.andlib.data.Property;
import com.todoroo.andlib.data.Property.LongProperty;
import com.todoroo.andlib.data.Property.StringProperty;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.astrid.activity.TaskListFragment;
import com.todoroo.astrid.data.Task;
@ -35,9 +34,9 @@ public class TaskAdapter extends CursorAdapter implements Filterable {
public List<Integer> getTaskPositions(List<Long> longs) {
List<Integer> result = new ArrayList<>();
TodorooCursor taskCursor = getTaskCursor();
Cursor taskCursor = getTaskCursor();
for (taskCursor.moveToFirst() ; !taskCursor.isAfterLast() ; taskCursor.moveToNext()) {
if (longs.contains(taskCursor.get(Task.ID))) {
if (longs.contains(Task.ID.getValue(taskCursor))) {
result.add(taskCursor.getPosition());
}
}
@ -94,35 +93,35 @@ public class TaskAdapter extends CursorAdapter implements Filterable {
}
private TodorooCursor getTaskCursor() {
return (TodorooCursor) getCursor();
private Cursor getTaskCursor() {
return getCursor();
}
public long getTaskId(int position) {
TodorooCursor c = getTaskCursor();
Cursor c = getTaskCursor();
if (c != null) {
if (c.moveToPosition(position)) {
return c.get(Task.ID);
return Task.ID.getValue(c);
}
}
return Task.NO_ID;
}
public Task getTask(int position) {
TodorooCursor c = getTaskCursor();
Cursor c = getTaskCursor();
if (c != null) {
if (c.moveToPosition(position)) {
return c.toModel();
return new Task(c);
}
}
return null;
}
protected String getItemUuid(int position) {
TodorooCursor c = getTaskCursor();
Cursor c = getTaskCursor();
if (c != null) {
if (c.moveToPosition(position)) {
return c.get(Task.UUID);
return Task.UUID.getValue(c);
} else {
return Task.NO_UUID;
}

@ -12,7 +12,6 @@ import android.content.Context;
import android.database.Cursor;
import com.todoroo.andlib.data.Property;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.sql.Criterion;
import com.todoroo.andlib.sql.Functions;
import com.todoroo.andlib.sql.Query;
@ -23,6 +22,7 @@ import com.todoroo.astrid.data.Task;
import org.tasks.BuildConfig;
import org.tasks.jobs.AfterSaveIntentService;
import java.util.ArrayList;
import java.util.List;
import timber.log.Timber;
@ -76,13 +76,25 @@ public abstract class TaskDao {
}
}
private List<Task> toList(Cursor cursor) {
List<Task> result = new ArrayList<>();
try {
for (cursor.moveToFirst() ; !cursor.isAfterLast() ; cursor.moveToNext()) {
result.add(new Task(cursor));
}
} finally {
cursor.close();
}
return result;
}
public List<Task> query(Filter filter) {
String query = PermaSql.replacePlaceholders(filter.getSqlQuery());
return query(Query.select().withQueryTemplate(query)).toList();
return toList(query(Query.select().withQueryTemplate(query)));
}
public List<Task> toList(Query query) {
return query(query).toList();
return toList(query(query));
}
@android.arch.persistence.room.Query("UPDATE tasks SET completed = :completionDate " +
@ -197,21 +209,24 @@ public abstract class TaskDao {
save(item);
}
public TodorooCursor fetchFiltered(String queryTemplate, Property<?>... properties) {
public Cursor fetchFiltered(String queryTemplate, Property<?>... properties) {
return query(Query.select(properties)
.withQueryTemplate(PermaSql.replacePlaceholders(queryTemplate)));
}
public List<Task> fetchFiltered(String query) {
return toList(fetchFiltered(query, Task.PROPERTIES));
}
/**
* Construct a query with SQL DSL objects
*/
public TodorooCursor query(Query query) {
public Cursor query(Query query) {
String queryString = query.from(Task.TABLE).toString();
if (BuildConfig.DEBUG) {
Timber.v(queryString);
}
Cursor cursor = database.rawQuery(queryString);
return new TodorooCursor(cursor, query.getFields());
return database.rawQuery(queryString);
}
}

@ -77,7 +77,7 @@ public class TaskDeleter {
String query = filter.getSqlQuery()
.replace(isVisible().toString(), all.toString())
.replace(notCompleted().toString(), all.toString());
for (Task task : taskDao.fetchFiltered(query, Task.PROPERTIES).toList()) {
for (Task task : taskDao.fetchFiltered(query)) {
if (task.isCompleted()) {
completed.add(task);
}

@ -4,7 +4,6 @@ import android.content.Context;
import android.database.Cursor;
import android.text.TextUtils;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.sql.Criterion;
import com.todoroo.andlib.sql.Functions;
import com.todoroo.andlib.sql.Query;
@ -49,7 +48,7 @@ class AstridOrderedListFragmentHelper {
updater.initialize(list, filter);
}
TaskAdapter createTaskAdapter(Context context, TodorooCursor cursor) {
TaskAdapter createTaskAdapter(Context context, Cursor cursor) {
taskAdapter = new DraggableTaskAdapter(context, cursor);
taskAdapter.setOnCompletedTaskListener(this::setCompletedForItemAndSubtasks);

@ -1,8 +1,8 @@
package com.todoroo.astrid.subtasks;
import android.database.Cursor;
import android.text.TextUtils;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.astrid.api.Filter;
import com.todoroo.astrid.dao.TaskDao;
import org.tasks.data.TaskListMetadataDao;
@ -120,7 +120,7 @@ public class SubtasksFilterUpdater {
sql = sql.replace(
TaskDao.TaskCriteria.activeAndVisible().toString(),
TaskDao.TaskCriteria.notDeleted().toString());
TodorooCursor tasks = taskDao.fetchFiltered(sql, Task.UUID);
Cursor tasks = taskDao.fetchFiltered(sql, Task.UUID);
try {
for (tasks.moveToFirst(); !tasks.isAfterLast(); tasks.moveToNext()) {
String id = tasks.getString(0);

@ -1,10 +1,10 @@
package com.todoroo.astrid.subtasks;
import android.content.Context;
import android.database.Cursor;
import android.text.TextUtils;
import com.todoroo.andlib.data.Property;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.sql.Criterion;
import com.todoroo.andlib.sql.Query;
import com.todoroo.astrid.api.Filter;
@ -170,11 +170,11 @@ public class SubtasksHelper {
private static <A, B> HashMap<A, B> getIdMap(TaskDao taskDao, Iterable<A> keys, Property<A> keyProperty, Property<B> valueProperty) {
HashMap<A, B> map = new HashMap<>();
TodorooCursor tasks = taskDao.query(Query.select(keyProperty, valueProperty).where(keyProperty.in(keys)));
Cursor tasks = taskDao.query(Query.select(keyProperty, valueProperty).where(keyProperty.in(keys)));
try {
for (tasks.moveToFirst(); !tasks.isAfterLast(); tasks.moveToNext()) {
A key = tasks.get(keyProperty);
B value = tasks.get(valueProperty);
A key = keyProperty.getValue(tasks);
B value = valueProperty.getValue(tasks);
map.put(key, value);
}
} finally {

@ -7,9 +7,9 @@ package com.todoroo.astrid.subtasks;
import android.app.Activity;
import android.content.Context;
import android.database.Cursor;
import android.text.TextUtils;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.astrid.activity.TaskListFragment;
import com.todoroo.astrid.adapter.TaskAdapter;
import com.todoroo.astrid.api.Filter;
@ -102,7 +102,7 @@ public class SubtasksListFragment extends TaskListFragment {
}
@Override
protected TaskAdapter createTaskAdapter(TodorooCursor cursor) {
protected TaskAdapter createTaskAdapter(Cursor cursor) {
return helper.createTaskAdapter(theme.wrap(context), cursor);
}

@ -7,8 +7,8 @@ package com.todoroo.astrid.subtasks;
import android.app.Activity;
import android.content.Context;
import android.database.Cursor;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.astrid.activity.TaskListFragment;
import com.todoroo.astrid.adapter.TaskAdapter;
import com.todoroo.astrid.api.TagFilter;
@ -72,7 +72,7 @@ public class SubtasksTagListFragment extends TagListFragment {
}
@Override
protected TaskAdapter createTaskAdapter(TodorooCursor cursor) {
protected TaskAdapter createTaskAdapter(Cursor cursor) {
return helper.createTaskAdapter(theme.wrap(context), cursor);
}

@ -1,9 +1,9 @@
package org.tasks.data;
import android.database.Cursor;
import android.database.sqlite.SQLiteException;
import com.todoroo.andlib.data.Property;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.sql.Criterion;
import com.todoroo.andlib.sql.Field;
import com.todoroo.andlib.sql.Join;
@ -15,6 +15,8 @@ import com.todoroo.astrid.data.Task;
import org.tasks.preferences.Preferences;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import javax.inject.Inject;
@ -36,7 +38,20 @@ public class TaskListDataProvider {
this.preferences = preferences;
}
public TodorooCursor constructCursor(Filter filter, Property<?>[] properties) {
public List<Task> toList(Filter filter) {
Cursor cursor = constructCursor(filter, Task.PROPERTIES);
List<Task> result = new ArrayList<>();
try {
for (cursor.moveToFirst() ; !cursor.isAfterLast() ; cursor.moveToNext()) {
result.add(new Task(cursor));
}
} finally {
cursor.close();
}
return result;
}
public Cursor constructCursor(Filter filter, Property<?>[] properties) {
Criterion tagsJoinCriterion = Criterion.and(
Task.ID.eq(Field.field(TAGS_METADATA_JOIN + ".task")));

@ -16,7 +16,6 @@ import android.view.ViewGroup;
import com.bignerdranch.android.multiselector.ModalMultiSelectorCallback;
import com.bignerdranch.android.multiselector.MultiSelector;
import com.google.common.primitives.Longs;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.astrid.activity.TaskListActivity;
import com.todoroo.astrid.activity.TaskListFragment;
import com.todoroo.astrid.adapter.TaskAdapter;
@ -108,7 +107,7 @@ public class TaskListRecyclerAdapter extends RecyclerView.Adapter<ViewHolder> im
public void onBindViewHolder(ViewHolder holder, int position) {
Cursor cursor = adapter.getCursor();
cursor.moveToPosition(position);
holder.bindView((TodorooCursor) cursor);
holder.bindView(cursor);
holder.setMoving(false);
holder.setIndent(adapter.getIndent(holder.task));
}

@ -3,6 +3,7 @@ package org.tasks.tasklist;
import android.annotation.SuppressLint;
import android.app.PendingIntent;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Paint;
import android.support.v7.app.AlertDialog;
import android.text.SpannableString;
@ -18,7 +19,6 @@ import android.widget.TextView;
import com.bignerdranch.android.multiselector.MultiSelector;
import com.bignerdranch.android.multiselector.MultiSelectorBindingHolder;
import com.google.common.collect.Lists;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.astrid.adapter.TaskAdapter;
import com.todoroo.astrid.api.TaskAction;
@ -191,9 +191,9 @@ class ViewHolder extends MultiSelectorBindingHolder {
return indent > 0;
}
void bindView(TodorooCursor cursor) {
tagsString = cursor.get(TaskAdapter.TAGS);
hasFiles = (Long) cursor.get(TaskAdapter.FILE_ID_PROPERTY) > 0;
void bindView(Cursor cursor) {
tagsString = TaskAdapter.TAGS.getValue(cursor);
hasFiles = TaskAdapter.FILE_ID_PROPERTY.getValue(cursor) > 0;
// TODO: see if this is a performance issue
task = new Task(cursor);

@ -4,6 +4,7 @@ import android.appwidget.AppWidgetManager;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Paint;
import android.text.TextUtils;
@ -11,7 +12,6 @@ import android.view.View;
import android.widget.RemoteViews;
import android.widget.RemoteViewsService;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.astrid.api.Filter;
import com.todoroo.astrid.core.SortHelper;
@ -55,7 +55,7 @@ class ScrollableViewsFactory implements RemoteViewsService.RemoteViewsFactory {
private int textColorPrimary;
private int textColorSecondary;
private TodorooCursor cursor;
private Cursor cursor;
ScrollableViewsFactory(
SubtasksHelper subtasksHelper,
@ -202,7 +202,7 @@ class ScrollableViewsFactory implements RemoteViewsService.RemoteViewsFactory {
return null;
}
private TodorooCursor getCursor() {
private Cursor getCursor() {
String query = getQuery();
return taskDao.fetchFiltered(query, Task.PROPERTIES);
}

Loading…
Cancel
Save