Hide remaining Metadata cursors

pull/189/head
Alex Baker 10 years ago
parent 8299b1aa0e
commit c1273f6b97

@ -26,7 +26,6 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Map.Entry;

@ -14,7 +14,6 @@ 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.Table;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.astrid.api.AstridApiConstants;
/**
@ -99,16 +98,6 @@ public class Metadata extends AbstractModel {
return defaultValues;
}
// --- data access boilerplate
public Metadata() {
super();
}
public Metadata(TodorooCursor<Metadata> cursor) {
super(cursor);
}
@Override
public long getId() {
return getIdHelper(ID);

@ -6,13 +6,14 @@
package com.todoroo.astrid.dao;
import com.todoroo.andlib.data.Property;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.sql.Query;
import com.todoroo.astrid.dao.MetadataDao.MetadataCriteria;
import com.todoroo.astrid.data.Metadata;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.test.DatabaseTestCase;
import java.util.List;
import javax.inject.Inject;
public class MetadataDaoTests extends DatabaseTestCase {
@ -34,20 +35,14 @@ public class MetadataDaoTests extends DatabaseTestCase {
* Test basic creation, fetch, and save
*/
public void testCrud() throws Exception {
TodorooCursor<Metadata> cursor = metadataDao.query(
Query.select(Metadata.ID));
assertEquals(0, cursor.getCount());
cursor.close();
assertTrue(metadataDao.toList(Query.select(Metadata.ID)).isEmpty());
// create "happy"
Metadata metadata = new Metadata();
metadata.setTask(1L);
metadata.setKey("happy");
assertTrue(metadataDao.persist(metadata));
cursor = metadataDao.query(
Query.select(Metadata.ID));
assertEquals(1, cursor.getCount());
cursor.close();
assertEquals(1, metadataDao.toList(Query.select(Metadata.ID)).size());
long happyId = metadata.getId();
assertNotSame(Metadata.NO_ID, happyId);
metadata = metadataDao.fetch(happyId, KEYS);
@ -58,19 +53,14 @@ public class MetadataDaoTests extends DatabaseTestCase {
metadata.setTask(1L);
metadata.setKey("sad");
assertTrue(metadataDao.persist(metadata));
cursor = metadataDao.query(Query.select(Metadata.ID));
assertEquals(2, cursor.getCount());
cursor.close();
assertEquals(2, metadataDao.toList(Query.select(Metadata.ID)).size());
// rename sad to melancholy
long sadId = metadata.getId();
assertNotSame(Metadata.NO_ID, sadId);
metadata.setKey("melancholy");
assertTrue(metadataDao.persist(metadata));
cursor = metadataDao.query(
Query.select(Metadata.ID));
assertEquals(2, cursor.getCount());
cursor.close();
assertEquals(2, metadataDao.toList(Query.select(Metadata.ID)).size());
// check state
metadata = metadataDao.fetch(happyId, KEYS);
@ -80,13 +70,9 @@ public class MetadataDaoTests extends DatabaseTestCase {
// delete sad
assertTrue(metadataDao.delete(sadId));
cursor = metadataDao.query(
Query.select(KEYS));
assertEquals(1, cursor.getCount());
cursor.moveToFirst();
metadata = new Metadata(cursor);
assertEquals("happy", metadata.getKey());
cursor.close();
List<Metadata> metadataList = metadataDao.toList(Query.select(KEYS));
assertEquals(1, metadataList.size());
assertEquals("happy", metadataList.get(0).getKey());
}
/**
@ -109,29 +95,15 @@ public class MetadataDaoTests extends DatabaseTestCase {
metadata.setTask(1L);
assertTrue(metadataDao.persist(metadata));
List<Metadata> metadataList = metadataDao.toList(Query.select(KEYS).where(MetadataCriteria.byTask(1)));
assertEquals(2, metadataList.size());
assertEquals("with1", metadataList.get(0).getKey());
assertEquals("with1", metadataList.get(1).getKey());
assertTrue(metadataDao.toList(Query.select(KEYS).where(MetadataCriteria.byTask(3))).isEmpty());
TodorooCursor<Metadata> cursor = metadataDao.query(
Query.select(KEYS).where(MetadataCriteria.byTask(1)));
assertEquals(2, cursor.getCount());
cursor.moveToFirst();
metadata = new Metadata(cursor);
assertEquals("with1", metadata.getKey());
cursor.moveToNext();
metadata = new Metadata(cursor);
assertEquals("with1", metadata.getKey());
cursor.close();
cursor = metadataDao.query(
Query.select(KEYS).where(MetadataCriteria.byTask(3)));
assertEquals(0, cursor.getCount());
cursor.close();
int deleted = metadataDao.deleteWhere(MetadataCriteria.byTask(1));
assertEquals(2, deleted);
cursor = metadataDao.query(
Query.select(KEYS));
assertEquals(1, cursor.getCount());
cursor.close();
assertEquals(2, metadataDao.deleteWhere(MetadataCriteria.byTask(1)));
assertEquals(1, metadataDao.toList(Query.select(KEYS)).size());
}
public void testDontSaveMetadataWithoutTaskId() {

@ -7,9 +7,9 @@ package com.todoroo.astrid.gtasks;
import android.text.TextUtils;
import com.todoroo.andlib.data.Callback;
import com.todoroo.andlib.data.Property.IntegerProperty;
import com.todoroo.andlib.data.Property.LongProperty;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.sql.Criterion;
import com.todoroo.andlib.sql.Functions;
import com.todoroo.andlib.sql.Order;
@ -26,6 +26,7 @@ import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
@ -149,31 +150,26 @@ public class GtasksTaskListUpdater extends OrderedMetadataListUpdater<StoreObjec
new HashSet<Long>());
}
private void orderAndIndentHelper(String listId, AtomicLong order, long parent, int indentLevel,
HashSet<Long> alreadyChecked) {
TodorooCursor<Metadata> metadata = metadataDao.query(Query.select(Metadata.PROPERTIES)
.where(Criterion.and(Metadata.KEY.eq(GtasksMetadata.METADATA_KEY),
GtasksMetadata.LIST_ID.eq(listId), GtasksMetadata.PARENT_TASK.eq(parent)))
.orderBy(Order.asc(Functions.cast(GtasksMetadata.GTASKS_ORDER, "INTEGER")))); //$NON-NLS-1$
try {
if (metadata.getCount() > 0) {
for (metadata.moveToFirst(); !metadata.isAfterLast(); metadata.moveToNext()) {
Metadata curr = new Metadata(metadata);
if(alreadyChecked.contains(curr.getTask())) {
continue;
private void orderAndIndentHelper(final String listId, final AtomicLong order, final long parent, final int indentLevel, final Set<Long> alreadyChecked) {
Query query = Query.select(Metadata.PROPERTIES).where(Criterion.and(
Metadata.KEY.eq(GtasksMetadata.METADATA_KEY),
GtasksMetadata.LIST_ID.eq(listId),
GtasksMetadata.PARENT_TASK.eq(parent)))
.orderBy(Order.asc(Functions.cast(GtasksMetadata.GTASKS_ORDER, "INTEGER")));
metadataDao.query(query, new Callback<Metadata>() {
@Override
public void apply(Metadata curr) {
if (!alreadyChecked.contains(curr.getTask())) {
curr.setValue(GtasksMetadata.INDENT, indentLevel);
curr.setValue(GtasksMetadata.ORDER, order.getAndIncrement());
metadataDao.saveExisting(curr);
alreadyChecked.add(curr.getTask());
orderAndIndentHelper(listId, order, curr.getTask(), indentLevel + 1, alreadyChecked);
}
}
curr.setValue(GtasksMetadata.INDENT, indentLevel);
curr.setValue(GtasksMetadata.ORDER, order.getAndIncrement());
metadataDao.saveExisting(curr);
alreadyChecked.add(curr.getTask());
orderAndIndentHelper(listId, order, curr.getTask(), indentLevel + 1, alreadyChecked);
}
}
} finally {
metadata.close();
}
);
}
void updateParentSiblingMapsFor(StoreObject list) {

@ -32,8 +32,6 @@ import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
import com.todoroo.andlib.data.Callback;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.sql.Query;
import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.astrid.actfm.ActFmCameraModule;
import com.todoroo.astrid.actfm.ActFmCameraModule.CameraResultCallback;
@ -41,7 +39,6 @@ import com.todoroo.astrid.actfm.ActFmCameraModule.ClearImageCallback;
import com.todoroo.astrid.activity.AstridActivity;
import com.todoroo.astrid.activity.TaskEditFragment;
import com.todoroo.astrid.dao.MetadataDao;
import com.todoroo.astrid.dao.MetadataDao.MetadataCriteria;
import com.todoroo.astrid.dao.UserActivityDao;
import com.todoroo.astrid.data.Metadata;
import com.todoroo.astrid.data.RemoteModel;
@ -260,18 +257,12 @@ public class EditNoteActivity extends LinearLayout implements TimerActionListene
private void setUpListAdapter() {
items.clear();
this.removeAllViews();
TodorooCursor<Metadata> notes = metadataDao.query(
Query.select(Metadata.PROPERTIES).where(
MetadataCriteria.byTaskAndwithKey(task.getId(),
NoteMetadata.METADATA_KEY)));
try {
for(notes.moveToFirst(); !notes.isAfterLast(); notes.moveToNext()) {
Metadata metadata = new Metadata(notes);
metadataDao.byTaskAndKey(task.getId(), NoteMetadata.METADATA_KEY, new Callback<Metadata>() {
@Override
public void apply(Metadata metadata) {
items.add(NoteOrUpdate.fromMetadata(metadata));
}
} finally {
notes.close();
}
});
userActivityDao.getCommentsForTask(task.getUuid(), new Callback<UserActivity>() {
@Override

@ -12,18 +12,17 @@ import android.database.Cursor;
import android.database.MatrixCursor;
import android.net.Uri;
import com.google.common.base.Joiner;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.sql.Criterion;
import com.todoroo.andlib.sql.Query;
import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.astrid.core.SortHelper;
import com.todoroo.astrid.dao.TaskDao.TaskCriteria;
import com.todoroo.astrid.data.Metadata;
import com.todoroo.astrid.data.TagData;
import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.service.TaskService;
import com.todoroo.astrid.tags.TagService;
import com.todoroo.astrid.tags.TaskToTagMetadata;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -271,21 +270,6 @@ public class Astrid2TaskProvider extends InjectingContentProvider {
* @return empty string if no tags, otherwise string
*/
private String getTagsAsString(long taskId, String separator) {
StringBuilder tagBuilder = new StringBuilder();
TodorooCursor<Metadata> tags = tagService.get().getTags(taskId);
try {
int length = tags.getCount();
for (int i = 0; i < length; i++) {
tags.moveToNext();
Metadata metadata = new Metadata(tags);
tagBuilder.append(metadata.getValue(TaskToTagMetadata.TAG_NAME));
if (i < length - 1) {
tagBuilder.append(separator);
}
}
} finally {
tags.close();
}
return tagBuilder.toString();
return Joiner.on(separator).join(tagService.get().getTagNames(taskId));
}
}

@ -1,6 +1,5 @@
package com.todoroo.astrid.service;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.sql.Query;
import com.todoroo.andlib.utility.DateUtilities;
import com.todoroo.astrid.dao.MetadataDao;
@ -10,6 +9,8 @@ import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.gcal.GCalHelper;
import com.todoroo.astrid.gtasks.GtasksMetadata;
import java.util.List;
import javax.inject.Inject;
public class TaskDuplicator {
@ -50,31 +51,26 @@ public class TaskDuplicator {
}
newTask.clearValue(Task.ID);
newTask.clearValue(Task.UUID);
TodorooCursor<Metadata> cursor = metadataDao.query(
Query.select(Metadata.PROPERTIES).where(MetadataDao.MetadataCriteria.byTask(task.getId())));
try {
if(cursor.getCount() > 0) {
newTask.putTransitory(SyncFlags.GTASKS_SUPPRESS_SYNC, true);
taskService.save(newTask);
long newId = newTask.getId();
for(cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
Metadata metadata = new Metadata(cursor);
if(!metadata.containsNonNullValue(Metadata.KEY)) {
continue;
}
List<Metadata> metadataList = metadataDao.toList(Query.select(Metadata.PROPERTIES).where(MetadataDao.MetadataCriteria.byTask(task.getId())));
if(GtasksMetadata.METADATA_KEY.equals(metadata.getKey())) {
metadata.setValue(GtasksMetadata.ID, ""); //$NON-NLS-1$
}
if (!metadataList.isEmpty()) {
newTask.putTransitory(SyncFlags.GTASKS_SUPPRESS_SYNC, true);
taskService.save(newTask);
long newId = newTask.getId();
for (Metadata metadata : metadataList) {
if(!metadata.containsNonNullValue(Metadata.KEY)) {
continue;
}
metadata.setTask(newId);
metadata.clearValue(Metadata.ID);
metadataDao.createNew(metadata);
if(GtasksMetadata.METADATA_KEY.equals(metadata.getKey())) {
metadata.setValue(GtasksMetadata.ID, ""); //$NON-NLS-1$
}
metadata.setTask(newId);
metadata.clearValue(Metadata.ID);
metadataDao.createNew(metadata);
}
} finally {
cursor.close();
}
return newTask;
}

@ -9,7 +9,6 @@ import android.text.TextUtils;
import com.todoroo.andlib.data.Callback;
import com.todoroo.andlib.data.Property.CountProperty;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.sql.Criterion;
import com.todoroo.andlib.sql.Functions;
import com.todoroo.andlib.sql.Join;
@ -60,41 +59,44 @@ public final class TagService {
* @return empty array if no tags, otherwise array
*/
public TagData[] getGroupedTags(Order order, Criterion activeStatus) {
Criterion criterion = Criterion.and(activeStatus, MetadataCriteria.withKey(TaskToTagMetadata.KEY));
Query query = Query.select(TaskToTagMetadata.TAG_NAME, TaskToTagMetadata.TAG_UUID, COUNT).
join(Join.inner(Task.TABLE, Metadata.TASK.eq(Task.ID))).
where(criterion).
orderBy(order).groupBy(TaskToTagMetadata.TAG_NAME);
TodorooCursor<Metadata> cursor = metadataDao.query(query);
try {
ArrayList<TagData> array = new ArrayList<>();
for (int i = 0; i < cursor.getCount(); i++) {
cursor.moveToNext();
TagData tag = tagFromUUID(cursor.get(TaskToTagMetadata.TAG_UUID));
join(Join.inner(Task.TABLE, Metadata.TASK.eq(Task.ID))).
where(Criterion.and(
activeStatus,
MetadataCriteria.withKey(TaskToTagMetadata.KEY))).
orderBy(order).groupBy(TaskToTagMetadata.TAG_NAME);
final List<TagData> array = new ArrayList<>();
metadataDao.query(query, new Callback<Metadata>() {
@Override
public void apply(Metadata metadata) {
TagData tag = tagFromUUID(metadata.getValue(TaskToTagMetadata.TAG_UUID));
if (tag != null) {
array.add(tag);
}
}
return (TagData[]) array.toArray();
} finally {
cursor.close();
}
});
return (TagData[]) array.toArray();
}
private TagData tagFromUUID(String uuid) {
return tagDataDao.getByUuid(uuid, TagData.PROPERTIES);
}
/**
* Return tags on the given task
* @return cursor. PLEASE CLOSE THE CURSOR!
*/
public TodorooCursor<Metadata> getTags(long taskId) {
Criterion criterion = Criterion.and(MetadataCriteria.withKey(TaskToTagMetadata.KEY),
public List<String> getTagNames(long taskId) {
Query query = Query.select(TaskToTagMetadata.TAG_NAME, TaskToTagMetadata.TAG_UUID).where(
Criterion.and(
MetadataCriteria.withKey(TaskToTagMetadata.KEY),
Metadata.DELETION_DATE.eq(0),
MetadataCriteria.byTask(taskId));
Query query = Query.select(TaskToTagMetadata.TAG_NAME, TaskToTagMetadata.TAG_UUID).where(criterion).orderBy(Order.asc(Functions.upper(TaskToTagMetadata.TAG_NAME)));
return metadataDao.query(query);
MetadataCriteria.byTask(taskId)))
.orderBy(Order.asc(Functions.upper(TaskToTagMetadata.TAG_NAME)));
final List<String> tagNames = new ArrayList<>();
metadataDao.query(query, new Callback<Metadata>() {
@Override
public void apply(Metadata entry) {
tagNames.add(entry.getValue(TaskToTagMetadata.TAG_NAME));
}
});
return tagNames;
}
/**
@ -118,23 +120,16 @@ public final class TagService {
* given tag, return that. Otherwise, return the argument
*/
public String getTagWithCase(String tag) {
String tagWithCase = tag;
TodorooCursor<Metadata> tagMetadata = metadataDao.query(Query.select(TaskToTagMetadata.TAG_NAME).where(TagService.tagEqIgnoreCase(tag, Criterion.all)).limit(1));
try {
if (tagMetadata.getCount() > 0) {
tagMetadata.moveToFirst();
Metadata tagMatch = new Metadata(tagMetadata);
tagWithCase = tagMatch.getValue(TaskToTagMetadata.TAG_NAME);
} else {
TagData tagData = tagDataDao.getTagByName(tag, TagData.NAME);
if (tagData != null) {
tagWithCase = tagData.getName();
}
}
} finally {
tagMetadata.close();
Metadata tagMetadata = metadataDao.getFirst(Query.select(TaskToTagMetadata.TAG_NAME).where(tagEqIgnoreCase(tag, Criterion.all)).limit(1));
if (tagMetadata != null) {
return tagMetadata.getValue(TaskToTagMetadata.TAG_NAME);
}
TagData tagData = tagDataDao.getTagByName(tag, TagData.NAME);
if (tagData != null) {
return tagData.getName();
}
return tagWithCase;
return tag;
}
private static Criterion tagEqIgnoreCase(String tag, Criterion additionalCriterion) {

@ -24,7 +24,7 @@ import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
import com.todoroo.andlib.data.AbstractModel;
import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.data.Callback;
import com.todoroo.andlib.sql.Criterion;
import com.todoroo.andlib.sql.Query;
import com.todoroo.andlib.utility.DateUtilities;
@ -248,17 +248,7 @@ public final class TagsControlSet extends PopupControlSet {
public void readFromTask(Task task) {
super.readFromTask(task);
if(model.getId() != AbstractModel.NO_ID) {
TodorooCursor<Metadata> cursor = tagService.getTags(model.getId());
LinkedHashSet<String> tags = new LinkedHashSet<>(cursor.getCount());
try {
for(cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
String tag = cursor.get(TaskToTagMetadata.TAG_NAME);
tags.add(tag);
}
} finally {
cursor.close();
}
model.putTransitory(TRANSITORY_TAGS, tags);
model.putTransitory(TRANSITORY_TAGS, new LinkedHashSet<>(tagService.getTagNames(model.getId())));
refreshDisplayView();
}
}
@ -339,17 +329,18 @@ public final class TagsControlSet extends PopupControlSet {
* Save the given array of tags into the database
*/
private void synchronizeTags(long taskId, String taskUuid, Set<String> tags) {
HashSet<String> existingLinks = new HashSet<>();
TodorooCursor<Metadata> links = metadataDao.query(Query.select(Metadata.PROPERTIES)
.where(Criterion.and(TaskToTagMetadata.TASK_UUID.eq(taskUuid), Metadata.DELETION_DATE.eq(0))));
try {
for (links.moveToFirst(); !links.isAfterLast(); links.moveToNext()) {
Metadata link = new Metadata(links);
Query query = Query.select(Metadata.PROPERTIES).where(
Criterion.and(
TaskToTagMetadata.TASK_UUID.eq(taskUuid),
Metadata.DELETION_DATE.eq(0))
);
final HashSet<String> existingLinks = new HashSet<>();
metadataDao.query(query, new Callback<Metadata>() {
@Override
public void apply(Metadata link) {
existingLinks.add(link.getValue(TaskToTagMetadata.TAG_UUID));
}
} finally {
links.close();
}
});
for (String tag : tags) {
TagData tagData = tagDataDao.getTagByName(tag, TagData.NAME, TagData.UUID);

Loading…
Cancel
Save