Refactor tag metadata to contain more information like task and tag uuids

pull/14/head
Sam Bosley 12 years ago
parent c6968c9264
commit 465307be34

@ -79,6 +79,10 @@ public class Metadata extends AbstractModel {
public static final LongProperty CREATION_DATE = new LongProperty( public static final LongProperty CREATION_DATE = new LongProperty(
TABLE, "created"); TABLE, "created");
/** Unixtime metadata was deleted/tombstoned */
public static final LongProperty DELETION_DATE = new LongProperty(
TABLE, "deleted");
/** List of all properties for this model */ /** List of all properties for this model */
public static final Property<?>[] PROPERTIES = generateProperties(Metadata.class); public static final Property<?>[] PROPERTIES = generateProperties(Metadata.class);
@ -87,6 +91,10 @@ public class Metadata extends AbstractModel {
/** Default values container */ /** Default values container */
private static final ContentValues defaultValues = new ContentValues(); private static final ContentValues defaultValues = new ContentValues();
static {
defaultValues.put(DELETION_DATE.name, 0L);
}
@Override @Override
public ContentValues getDefaultValues() { public ContentValues getDefaultValues() {
return defaultValues; return defaultValues;

@ -73,6 +73,7 @@ import com.todoroo.astrid.service.TagDataService;
import com.todoroo.astrid.service.TaskService; import com.todoroo.astrid.service.TaskService;
import com.todoroo.astrid.service.ThemeService; import com.todoroo.astrid.service.ThemeService;
import com.todoroo.astrid.service.abtesting.ABChooser; import com.todoroo.astrid.service.abtesting.ABChooser;
import com.todoroo.astrid.tags.TagMetadata;
import com.todoroo.astrid.tags.TagService; import com.todoroo.astrid.tags.TagService;
import com.todoroo.astrid.ui.PeopleContainer; import com.todoroo.astrid.ui.PeopleContainer;
import com.todoroo.astrid.ui.PeopleContainer.OnAddNewPersonListener; import com.todoroo.astrid.ui.PeopleContainer.OnAddNewPersonListener;
@ -252,7 +253,7 @@ public class EditPeopleControlSet extends PopupControlSet {
Metadata metadata = new Metadata(); Metadata metadata = new Metadata();
for(tags.moveToFirst(); !tags.isAfterLast(); tags.moveToNext()) { for(tags.moveToFirst(); !tags.isAfterLast(); tags.moveToNext()) {
metadata.readFromCursor(tags); metadata.readFromCursor(tags);
final String tag = metadata.getValue(TagService.TAG); final String tag = metadata.getValue(TagMetadata.TAG_NAME);
TagData tagData = tagDataService.getTag(tag, TagData.MEMBER_COUNT, TagData.MEMBERS, TagData.USER); TagData tagData = tagDataService.getTag(tag, TagData.MEMBER_COUNT, TagData.MEMBERS, TagData.USER);
if(tagData != null && tagData.getValue(TagData.MEMBER_COUNT) > 0) { if(tagData != null && tagData.getValue(TagData.MEMBER_COUNT) > 0) {
try { try {

@ -33,6 +33,7 @@ import com.todoroo.astrid.data.User;
import com.todoroo.astrid.notes.NoteMetadata; import com.todoroo.astrid.notes.NoteMetadata;
import com.todoroo.astrid.service.MetadataService; import com.todoroo.astrid.service.MetadataService;
import com.todoroo.astrid.service.TagDataService; import com.todoroo.astrid.service.TagDataService;
import com.todoroo.astrid.tags.TagMetadata;
import com.todoroo.astrid.tags.TagService; import com.todoroo.astrid.tags.TagService;
public final class ActFmDataService { public final class ActFmDataService {
@ -132,7 +133,7 @@ public final class ActFmDataService {
metadataService.synchronizeMetadata(task.task.getId(), task.metadata, metadataService.synchronizeMetadata(task.task.getId(), task.metadata,
Criterion.or(Criterion.and(MetadataCriteria.withKey(NoteMetadata.METADATA_KEY), Criterion.or(Criterion.and(MetadataCriteria.withKey(NoteMetadata.METADATA_KEY),
NoteMetadata.EXT_PROVIDER.eq(NOTE_PROVIDER)), NoteMetadata.EXT_PROVIDER.eq(NOTE_PROVIDER)),
MetadataCriteria.withKey(TagService.KEY))); MetadataCriteria.withKey(TagMetadata.KEY)));
} }
/** /**
@ -147,7 +148,7 @@ public final class ActFmDataService {
ArrayList<Metadata> metadata = new ArrayList<Metadata>(); ArrayList<Metadata> metadata = new ArrayList<Metadata>();
TodorooCursor<Metadata> metadataCursor = metadataService.query(Query.select(Metadata.PROPERTIES). TodorooCursor<Metadata> metadataCursor = metadataService.query(Query.select(Metadata.PROPERTIES).
where(Criterion.and(MetadataCriteria.byTask(task.getId()), where(Criterion.and(MetadataCriteria.byTask(task.getId()),
Criterion.or(MetadataCriteria.withKey(TagService.KEY), Criterion.or(MetadataCriteria.withKey(TagMetadata.KEY),
MetadataCriteria.withKey(NoteMetadata.METADATA_KEY))))); MetadataCriteria.withKey(NoteMetadata.METADATA_KEY)))));
try { try {
for(metadataCursor.moveToFirst(); !metadataCursor.isAfterLast(); metadataCursor.moveToNext()) { for(metadataCursor.moveToFirst(); !metadataCursor.isAfterLast(); metadataCursor.moveToNext()) {

@ -75,6 +75,7 @@ import com.todoroo.astrid.service.TagDataService;
import com.todoroo.astrid.service.TaskService; import com.todoroo.astrid.service.TaskService;
import com.todoroo.astrid.service.abtesting.ABTestEventReportingService; import com.todoroo.astrid.service.abtesting.ABTestEventReportingService;
import com.todoroo.astrid.sync.SyncV2Provider.SyncExceptionHandler; import com.todoroo.astrid.sync.SyncV2Provider.SyncExceptionHandler;
import com.todoroo.astrid.tags.TagMetadata;
import com.todoroo.astrid.tags.TagService; import com.todoroo.astrid.tags.TagService;
import com.todoroo.astrid.utility.Flags; import com.todoroo.astrid.utility.Flags;
@ -448,13 +449,13 @@ public final class ActFmSyncService {
Metadata metadata = new Metadata(); Metadata metadata = new Metadata();
for(cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) { for(cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
metadata.readFromCursor(cursor); metadata.readFromCursor(cursor);
if(metadata.containsNonNullValue(TagService.REMOTE_ID) && if(metadata.containsNonNullValue(TagMetadata.TAG_UUID) &&
metadata.getValue(TagService.REMOTE_ID) > 0) { metadata.getValue(TagMetadata.TAG_UUID) > 0) {
params.add("tag_ids[]"); params.add("tag_ids[]");
params.add(metadata.getValue(TagService.REMOTE_ID)); params.add(metadata.getValue(TagMetadata.TAG_UUID));
} else { } else {
params.add("tags[]"); params.add("tags[]");
params.add(metadata.getValue(TagService.TAG)); params.add(metadata.getValue(TagMetadata.TAG_NAME));
} }
} }
} }
@ -817,7 +818,7 @@ public final class ActFmSyncService {
JsonHelper.taskFromJson(result, task, metadata); JsonHelper.taskFromJson(result, task, metadata);
task.putTransitory(SyncFlags.ACTFM_SUPPRESS_SYNC, true); task.putTransitory(SyncFlags.ACTFM_SUPPRESS_SYNC, true);
taskService.save(task); taskService.save(task);
metadataService.synchronizeMetadata(task.getId(), metadata, Metadata.KEY.eq(TagService.KEY)); metadataService.synchronizeMetadata(task.getId(), metadata, Metadata.KEY.eq(TagMetadata.KEY));
synchronizeAttachments(result, task); synchronizeAttachments(result, task);
} }
@ -1252,7 +1253,7 @@ public final class ActFmSyncService {
} }
ids.add(remote.getId()); ids.add(remote.getId());
metadataService.synchronizeMetadata(remote.getId(), metadata, MetadataCriteria.withKey(TagService.KEY)); metadataService.synchronizeMetadata(remote.getId(), metadata, MetadataCriteria.withKey(TagMetadata.KEY));
synchronizeAttachments(item, remote); synchronizeAttachments(item, remote);
remote.clear(); remote.clear();
} }
@ -1574,9 +1575,9 @@ public final class ActFmSyncService {
if(TextUtils.isEmpty(name)) if(TextUtils.isEmpty(name))
continue; continue;
Metadata tagMetadata = new Metadata(); Metadata tagMetadata = new Metadata();
tagMetadata.setValue(Metadata.KEY, TagService.KEY); tagMetadata.setValue(Metadata.KEY, TagMetadata.KEY);
tagMetadata.setValue(TagService.TAG, name); tagMetadata.setValue(TagMetadata.TAG_NAME, name);
tagMetadata.setValue(TagService.REMOTE_ID, tag.getLong("id")); tagMetadata.setValue(TagMetadata.TAG_UUID, tag.getLong("id"));
metadata.add(tagMetadata); metadata.add(tagMetadata);
} }
} }

@ -40,6 +40,7 @@ import com.todoroo.astrid.service.TagDataService;
import com.todoroo.astrid.service.TaskService; import com.todoroo.astrid.service.TaskService;
import com.todoroo.astrid.sync.SyncResultCallback; import com.todoroo.astrid.sync.SyncResultCallback;
import com.todoroo.astrid.sync.SyncV2Provider; import com.todoroo.astrid.sync.SyncV2Provider;
import com.todoroo.astrid.tags.TagMetadata;
import com.todoroo.astrid.tags.TagService; import com.todoroo.astrid.tags.TagService;
/** /**
@ -515,8 +516,8 @@ public class ActFmSyncV2Provider extends SyncV2Provider {
private void pushQueuedTasksByTag(TagData tagData, SyncResultCallback callback, AtomicInteger finisher) { private void pushQueuedTasksByTag(TagData tagData, SyncResultCallback callback, AtomicInteger finisher) {
Long[] ids; Long[] ids;
TodorooCursor<Metadata> allTagged = metadataService.query(Query.select(Metadata.TASK).where(Criterion.and(Metadata.KEY.eq(TagService.KEY), TodorooCursor<Metadata> allTagged = metadataService.query(Query.select(Metadata.TASK).where(Criterion.and(Metadata.KEY.eq(TagMetadata.KEY),
TagService.TAG.eqCaseInsensitive(tagData.getValue(TagData.NAME))))); TagMetadata.TAG_NAME.eqCaseInsensitive(tagData.getValue(TagData.NAME)))));
try { try {
ids = new Long[allTagged.getCount()]; ids = new Long[allTagged.getCount()];
Metadata m = new Metadata(); Metadata m = new Metadata();
@ -531,8 +532,8 @@ public class ActFmSyncV2Provider extends SyncV2Provider {
} }
TodorooCursor<Task> taskCursor = taskService.query(Query.select(Task.PROPERTIES) TodorooCursor<Task> taskCursor = taskService.query(Query.select(Task.PROPERTIES)
.join(Join.inner(Metadata.TABLE, Criterion.and(Metadata.KEY.eq(TagService.KEY), Metadata.TASK.eq(Task.ID), .join(Join.inner(Metadata.TABLE, Criterion.and(Metadata.KEY.eq(TagMetadata.KEY), Metadata.TASK.eq(Task.ID),
TagService.TAG.eqCaseInsensitive(tagData.getValue(TagData.NAME))))) TagMetadata.TAG_NAME.eqCaseInsensitive(tagData.getValue(TagData.NAME)))))
.where(Criterion.or( .where(Criterion.or(
Criterion.and(TaskCriteria.isActive(), Criterion.and(TaskCriteria.isActive(),
Task.REMOTE_ID.isNull()), Task.REMOTE_ID.isNull()),

@ -26,7 +26,7 @@ import com.todoroo.astrid.data.Metadata;
import com.todoroo.astrid.data.Task; import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.data.TaskApiDao.TaskCriteria; import com.todoroo.astrid.data.TaskApiDao.TaskCriteria;
import com.todoroo.astrid.service.ThemeService; import com.todoroo.astrid.service.ThemeService;
import com.todoroo.astrid.tags.TagService; import com.todoroo.astrid.tags.TagMetadata;
/** /**
* Exposes Astrid's built in filters to the {@link FilterListFragment} * Exposes Astrid's built in filters to the {@link FilterListFragment}
@ -66,8 +66,8 @@ public final class CoreFilterExposer extends BroadcastReceiver implements Astrid
new QueryTemplate().where( new QueryTemplate().where(
Criterion.and(TaskCriteria.activeVisibleMine(), Criterion.and(TaskCriteria.activeVisibleMine(),
Criterion.not(Task.ID.in(Query.select(Metadata.TASK).from(Metadata.TABLE).where( Criterion.not(Task.ID.in(Query.select(Metadata.TASK).from(Metadata.TABLE).where(
Criterion.and(MetadataCriteria.withKey(TagService.KEY), Criterion.and(MetadataCriteria.withKey(TagMetadata.KEY),
TagService.TAG.like("x_%", "x"))))))), //$NON-NLS-1$ //$NON-NLS-2$ TagMetadata.TAG_NAME.like("x_%", "x"))))))), //$NON-NLS-1$ //$NON-NLS-2$
null); null);
int themeFlags = ThemeService.getFilterThemeFlags(); int themeFlags = ThemeService.getFilterThemeFlags();
inbox.listingIcon = ((BitmapDrawable)r.getDrawable( inbox.listingIcon = ((BitmapDrawable)r.getDrawable(

@ -43,7 +43,7 @@ import com.todoroo.astrid.data.TagData;
import com.todoroo.astrid.data.Task; import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.data.User; import com.todoroo.astrid.data.User;
import com.todoroo.astrid.service.ThemeService; import com.todoroo.astrid.service.ThemeService;
import com.todoroo.astrid.tags.TagService; import com.todoroo.astrid.tags.TagMetadata;
import com.todoroo.astrid.utility.AstridPreferences; import com.todoroo.astrid.utility.AstridPreferences;
public class PeopleFilterExposer extends BroadcastReceiver { public class PeopleFilterExposer extends BroadcastReceiver {
@ -148,8 +148,8 @@ public class PeopleFilterExposer extends BroadcastReceiver {
String title = context.getString(R.string.actfm_my_shared_tasks_title); String title = context.getString(R.string.actfm_my_shared_tasks_title);
QueryTemplate template = new QueryTemplate().join(Join.inner(Metadata.TABLE.as("mtags"), QueryTemplate template = new QueryTemplate().join(Join.inner(Metadata.TABLE.as("mtags"),
Criterion.and(Task.ID.eq(Field.field("mtags." + Metadata.TASK.name)), Criterion.and(Task.ID.eq(Field.field("mtags." + Metadata.TASK.name)),
Field.field("mtags." + Metadata.KEY.name).eq(TagService.KEY), Field.field("mtags." + Metadata.KEY.name).eq(TagMetadata.KEY),
Field.field("mtags." + TagService.TAG.name).in(names), Field.field("mtags." + TagMetadata.TAG_NAME.name).in(names),
TaskCriteria.activeVisibleMine()))); TaskCriteria.activeVisibleMine())));
FilterWithCustomIntent filter = new FilterWithCustomIntent(title, title, template, null); FilterWithCustomIntent filter = new FilterWithCustomIntent(title, title, template, null);

@ -35,7 +35,7 @@ import com.todoroo.astrid.notes.NoteMetadata;
import com.todoroo.astrid.producteev.ProducteevUtilities; import com.todoroo.astrid.producteev.ProducteevUtilities;
import com.todoroo.astrid.producteev.api.ApiUtilities; import com.todoroo.astrid.producteev.api.ApiUtilities;
import com.todoroo.astrid.service.MetadataService; import com.todoroo.astrid.service.MetadataService;
import com.todoroo.astrid.tags.TagService; import com.todoroo.astrid.tags.TagMetadata;
public final class ProducteevDataService { public final class ProducteevDataService {
@ -157,7 +157,7 @@ public final class ProducteevDataService {
// note we don't include note metadata, since we only receive deltas // note we don't include note metadata, since we only receive deltas
metadataService.synchronizeMetadata(task.task.getId(), task.metadata, metadataService.synchronizeMetadata(task.task.getId(), task.metadata,
Criterion.or(MetadataCriteria.withKey(ProducteevTask.METADATA_KEY), Criterion.or(MetadataCriteria.withKey(ProducteevTask.METADATA_KEY),
MetadataCriteria.withKey(TagService.KEY))); MetadataCriteria.withKey(TagMetadata.KEY)));
} }
/** /**
@ -172,7 +172,7 @@ public final class ProducteevDataService {
ArrayList<Metadata> metadata = new ArrayList<Metadata>(); ArrayList<Metadata> metadata = new ArrayList<Metadata>();
TodorooCursor<Metadata> metadataCursor = metadataService.query(Query.select(Metadata.PROPERTIES). TodorooCursor<Metadata> metadataCursor = metadataService.query(Query.select(Metadata.PROPERTIES).
where(Criterion.and(MetadataCriteria.byTask(task.getId()), where(Criterion.and(MetadataCriteria.byTask(task.getId()),
Criterion.or(MetadataCriteria.withKey(TagService.KEY), Criterion.or(MetadataCriteria.withKey(TagMetadata.KEY),
MetadataCriteria.withKey(ProducteevTask.METADATA_KEY), MetadataCriteria.withKey(ProducteevTask.METADATA_KEY),
MetadataCriteria.withKey(NoteMetadata.METADATA_KEY))))); MetadataCriteria.withKey(NoteMetadata.METADATA_KEY)))));
try { try {

@ -57,7 +57,7 @@ import com.todoroo.astrid.service.StatisticsService;
import com.todoroo.astrid.sync.SyncContainer; import com.todoroo.astrid.sync.SyncContainer;
import com.todoroo.astrid.sync.SyncProvider; import com.todoroo.astrid.sync.SyncProvider;
import com.todoroo.astrid.sync.SyncProviderUtilities; import com.todoroo.astrid.sync.SyncProviderUtilities;
import com.todoroo.astrid.tags.TagService; import com.todoroo.astrid.tags.TagMetadata;
import com.todoroo.astrid.utility.Constants; import com.todoroo.astrid.utility.Constants;
@SuppressWarnings("nls") @SuppressWarnings("nls")
@ -394,8 +394,8 @@ public class ProducteevSyncProvider extends SyncProvider<ProducteevTaskContainer
continue; continue;
Metadata tagData = new Metadata(); Metadata tagData = new Metadata();
tagData.setValue(Metadata.KEY, TagService.KEY); tagData.setValue(Metadata.KEY, TagMetadata.KEY);
tagData.setValue(TagService.TAG, ApiUtilities.decode(label.getString("title"))); tagData.setValue(TagMetadata.TAG_NAME, ApiUtilities.decode(label.getString("title")));
metadata.add(tagData); metadata.add(tagData);
} }
@ -572,12 +572,12 @@ public class ProducteevSyncProvider extends SyncProvider<ProducteevTaskContainer
HashSet<String> localTags = new HashSet<String>(); HashSet<String> localTags = new HashSet<String>();
HashSet<String> remoteTags = new HashSet<String>(); HashSet<String> remoteTags = new HashSet<String>();
for(Metadata item : local.metadata) for(Metadata item : local.metadata)
if(TagService.KEY.equals(item.getValue(Metadata.KEY))) if(TagMetadata.KEY.equals(item.getValue(Metadata.KEY)))
localTags.add(item.getValue(TagService.TAG)); localTags.add(item.getValue(TagMetadata.TAG_NAME));
if(remote != null && remote.metadata != null) { if(remote != null && remote.metadata != null) {
for(Metadata item : remote.metadata) for(Metadata item : remote.metadata)
if(TagService.KEY.equals(item.getValue(Metadata.KEY))) if(TagMetadata.KEY.equals(item.getValue(Metadata.KEY)))
remoteTags.add(item.getValue(TagService.TAG)); remoteTags.add(item.getValue(TagMetadata.TAG_NAME));
} }
if(!localTags.equals(remoteTags)) { if(!localTags.equals(remoteTags)) {

@ -47,8 +47,8 @@ public class Astrid44SyncMigrator {
// First assert that a TagData object exists for each tag metadata // First assert that a TagData object exists for each tag metadata
// -------------- // --------------
Query noTagDataQuery = Query.select(Metadata.PROPERTIES).where(Criterion.and( Query noTagDataQuery = Query.select(Metadata.PROPERTIES).where(Criterion.and(
MetadataCriteria.withKey(TagService.KEY), MetadataCriteria.withKey(TagMetadata.KEY),
Criterion.not(TagService.TAG.in(Query.select(TagData.NAME).from(TagData.TABLE))))).groupBy(TagService.TAG); Criterion.not(TagMetadata.TAG_NAME.in(Query.select(TagData.NAME).from(TagData.TABLE))))).groupBy(TagMetadata.TAG_NAME);
TodorooCursor<Metadata> noTagData = metadataService.query(noTagDataQuery); TodorooCursor<Metadata> noTagData = metadataService.query(noTagDataQuery);
try { try {
@ -57,10 +57,10 @@ public class Astrid44SyncMigrator {
tag.readFromCursor(noTagData); tag.readFromCursor(noTagData);
if (Constants.DEBUG) if (Constants.DEBUG)
Log.w("tag-link-migrate", "CREATING TAG DATA " + tag.getValue(TagService.TAG)); Log.w("tag-link-migrate", "CREATING TAG DATA " + tag.getValue(TagMetadata.TAG_NAME));
TagData newTagData = new TagData(); TagData newTagData = new TagData();
newTagData.setValue(TagData.NAME, tag.getValue(TagService.TAG)); newTagData.setValue(TagData.NAME, tag.getValue(TagMetadata.TAG_NAME));
tagDataService.save(newTagData); tagDataService.save(newTagData);
} }
} finally { } finally {

@ -113,14 +113,14 @@ public class TagCaseMigrator {
try { try {
for (tasks.moveToFirst(); !tasks.isAfterLast(); tasks.moveToNext()) { for (tasks.moveToFirst(); !tasks.isAfterLast(); tasks.moveToNext()) {
Task curr = new Task(tasks); Task curr = new Task(tasks);
TodorooCursor<Metadata> tagMetadata = metadataService.query(Query.select(TagService.TAG) TodorooCursor<Metadata> tagMetadata = metadataService.query(Query.select(TagMetadata.TAG_NAME)
.where(Criterion.and(TagService.TAG.eq(target), Metadata.KEY.eq(TagService.KEY), Metadata.TASK.eq(curr.getId())))); .where(Criterion.and(TagMetadata.TAG_NAME.eq(target), Metadata.KEY.eq(TagMetadata.KEY), Metadata.TASK.eq(curr.getId()))));
try { try {
if (tagMetadata.getCount() == 0) { if (tagMetadata.getCount() == 0) {
Metadata newTag = new Metadata(); Metadata newTag = new Metadata();
newTag.setValue(Metadata.KEY, TagService.KEY); newTag.setValue(Metadata.KEY, TagMetadata.KEY);
newTag.setValue(Metadata.TASK, curr.getId()); newTag.setValue(Metadata.TASK, curr.getId());
newTag.setValue(TagService.TAG, target); newTag.setValue(TagMetadata.TAG_NAME, target);
metadataService.save(newTag); metadataService.save(newTag);
} // else already exists for some weird reason } // else already exists for some weird reason
} finally { } finally {

@ -45,16 +45,16 @@ public class TagCustomFilterCriteriaExposer extends BroadcastReceiver {
for(int i = 0; i < tags.length; i++) for(int i = 0; i < tags.length; i++)
tagNames[i] = tags[i].tag; tagNames[i] = tags[i].tag;
ContentValues values = new ContentValues(); ContentValues values = new ContentValues();
values.put(Metadata.KEY.name, TagService.KEY); values.put(Metadata.KEY.name, TagMetadata.KEY);
values.put(TagService.TAG.name, "?"); values.put(TagMetadata.TAG_NAME.name, "?");
CustomFilterCriterion criterion = new MultipleSelectCriterion( CustomFilterCriterion criterion = new MultipleSelectCriterion(
IDENTIFIER_TAG_IS, IDENTIFIER_TAG_IS,
context.getString(R.string.CFC_tag_text), context.getString(R.string.CFC_tag_text),
Query.select(Metadata.TASK).from(Metadata.TABLE).join(Join.inner( Query.select(Metadata.TASK).from(Metadata.TABLE).join(Join.inner(
Task.TABLE, Metadata.TASK.eq(Task.ID))).where(Criterion.and( Task.TABLE, Metadata.TASK.eq(Task.ID))).where(Criterion.and(
TaskDao.TaskCriteria.activeAndVisible(), TaskDao.TaskCriteria.activeAndVisible(),
MetadataDao.MetadataCriteria.withKey(TagService.KEY), MetadataDao.MetadataCriteria.withKey(TagMetadata.KEY),
TagService.TAG.eq("?"))).toString(), TagMetadata.TAG_NAME.eq("?"))).toString(),
values, tagNames, tagNames, values, tagNames, tagNames,
((BitmapDrawable)r.getDrawable(TagService.getDefaultImageIDForTag(0))).getBitmap(), ((BitmapDrawable)r.getDrawable(TagService.getDefaultImageIDForTag(0))).getBitmap(),
context.getString(R.string.CFC_tag_name)); context.getString(R.string.CFC_tag_name));
@ -69,8 +69,8 @@ public class TagCustomFilterCriteriaExposer extends BroadcastReceiver {
Query.select(Metadata.TASK).from(Metadata.TABLE).join(Join.inner( Query.select(Metadata.TASK).from(Metadata.TABLE).join(Join.inner(
Task.TABLE, Metadata.TASK.eq(Task.ID))).where(Criterion.and( Task.TABLE, Metadata.TASK.eq(Task.ID))).where(Criterion.and(
TaskDao.TaskCriteria.activeAndVisible(), TaskDao.TaskCriteria.activeAndVisible(),
MetadataDao.MetadataCriteria.withKey(TagService.KEY), MetadataDao.MetadataCriteria.withKey(TagMetadata.KEY),
TagService.TAG.like("%?%"))).toString(), TagMetadata.TAG_NAME.like("%?%"))).toString(),
null, context.getString(R.string.CFC_tag_contains_name), "", null, context.getString(R.string.CFC_tag_contains_name), "",
((BitmapDrawable)r.getDrawable(TagService.getDefaultImageIDForTag(0))).getBitmap(), ((BitmapDrawable)r.getDrawable(TagService.getDefaultImageIDForTag(0))).getBitmap(),
context.getString(R.string.CFC_tag_contains_name)); context.getString(R.string.CFC_tag_contains_name));

@ -71,8 +71,8 @@ public class TagFilterExposer extends BroadcastReceiver implements AstridFilterE
String title = tag.tag; String title = tag.tag;
QueryTemplate tagTemplate = tag.queryTemplate(criterion); QueryTemplate tagTemplate = tag.queryTemplate(criterion);
ContentValues contentValues = new ContentValues(); ContentValues contentValues = new ContentValues();
contentValues.put(Metadata.KEY.name, TagService.KEY); contentValues.put(Metadata.KEY.name, TagMetadata.KEY);
contentValues.put(TagService.TAG.name, tag.tag); contentValues.put(TagMetadata.TAG_NAME.name, tag.tag);
FilterWithUpdate filter = new FilterWithUpdate(tag.tag, FilterWithUpdate filter = new FilterWithUpdate(tag.tag,
title, tagTemplate, title, tagTemplate,

@ -0,0 +1,48 @@
package com.todoroo.astrid.tags;
import com.todoroo.andlib.data.Property.LongProperty;
import com.todoroo.andlib.data.Property.StringProperty;
import com.todoroo.astrid.data.Metadata;
import com.todoroo.astrid.data.Task;
public class TagMetadata {
/** Metadata key for tag data */
public static final String KEY = "tags-tag"; //$NON-NLS-1$
/** Property for reading tag values */
public static final StringProperty TAG_NAME = Metadata.VALUE1;
/** Tag uuid */
public static final LongProperty TAG_UUID = new LongProperty(
Metadata.TABLE, Metadata.VALUE2.name);
/** Task uuid */
public static final LongProperty TASK_UUID = new LongProperty(
Metadata.TABLE, Metadata.VALUE3.name);
/** Pushed at time */
public static final LongProperty PUSHED_AT = new LongProperty(
Metadata.TABLE, Metadata.VALUE4.name);
// Creation date and deletion date are already included as part of the normal metadata entity
/**
* New metadata object for linking a task to the specified tag. The task
* object should be saved and have the remote_id property. All parameters
* are manditory
* @param task
* @param tagName
* @param tagUuid
* @return
*/
public static Metadata newTagMetadata(Task task, String tagName, long tagUuid) {
Metadata link = new Metadata();
link.setValue(Metadata.KEY, KEY);
link.setValue(Metadata.TASK, task.getId());
link.setValue(TASK_UUID, task.getValue(Task.REMOTE_ID));
link.setValue(TAG_UUID, tagUuid);
return link;
}
}

@ -19,8 +19,6 @@ import android.widget.Toast;
import com.timsu.astrid.R; import com.timsu.astrid.R;
import com.todoroo.andlib.data.Property.CountProperty; import com.todoroo.andlib.data.Property.CountProperty;
import com.todoroo.andlib.data.Property.LongProperty;
import com.todoroo.andlib.data.Property.StringProperty;
import com.todoroo.andlib.data.TodorooCursor; import com.todoroo.andlib.data.TodorooCursor;
import com.todoroo.andlib.service.Autowired; import com.todoroo.andlib.service.Autowired;
import com.todoroo.andlib.service.DependencyInjectionService; import com.todoroo.andlib.service.DependencyInjectionService;
@ -59,17 +57,6 @@ public final class TagService {
public static final String TOKEN_TAG_SQL = "tagSql"; //$NON-NLS-1$ public static final String TOKEN_TAG_SQL = "tagSql"; //$NON-NLS-1$
public static final String SHOW_ACTIVE_TASKS = "show_main_task_view"; //$NON-NLS-1$ public static final String SHOW_ACTIVE_TASKS = "show_main_task_view"; //$NON-NLS-1$
// --- public constants
/** Metadata key for tag data */
public static final String KEY = "tags-tag";
/** Property for reading tag values */
public static final StringProperty TAG = Metadata.VALUE1;
/** Property for astrid.com remote id */
public static final LongProperty REMOTE_ID = new LongProperty(Metadata.TABLE, Metadata.VALUE2.name);
// --- singleton // --- singleton
private static TagService instance = null; private static TagService instance = null;
@ -103,7 +90,7 @@ public final class TagService {
* Property for retrieving count of aggregated rows * Property for retrieving count of aggregated rows
*/ */
private static final CountProperty COUNT = new CountProperty(); private static final CountProperty COUNT = new CountProperty();
public static final Order GROUPED_TAGS_BY_ALPHA = Order.asc(Functions.upper(TAG)); public static final Order GROUPED_TAGS_BY_ALPHA = Order.asc(Functions.upper(TagMetadata.TAG_NAME));
public static final Order GROUPED_TAGS_BY_SIZE = Order.desc(COUNT); public static final Order GROUPED_TAGS_BY_SIZE = Order.desc(COUNT);
/** /**
@ -151,8 +138,6 @@ public final class TagService {
return tag; return tag;
} }
private static final String TABLE_ALIAS = "taglinks";
/** /**
* Return SQL selector query for getting tasks with a given tagData * Return SQL selector query for getting tasks with a given tagData
* *
@ -160,30 +145,28 @@ public final class TagService {
* @return * @return
*/ */
public QueryTemplate queryTemplate(Criterion criterion) { public QueryTemplate queryTemplate(Criterion criterion) {
// String prefix = TABLE_ALIAS + "."; return new QueryTemplate().join(Join.inner(Metadata.TABLE.as("mtags"),
// return new QueryTemplate().join(Join.inner(TaskToTag.TABLE.as(TABLE_ALIAS), Criterion.and(Task.ID.eq(Field.field("mtags." + Metadata.TASK.name)),
// Criterion.and( Field.field("mtags." + Metadata.KEY.name).eq(TagMetadata.KEY),
// Criterion.or(Task.ID.eq(Field.field(prefix + TaskToTag.TASK_ID.name)), Task.REMOTE_ID.eq(Field.field(prefix + TaskToTag.TASK_REMOTEID.name))), Field.field("mtags." + TagMetadata.TAG_NAME.name).eqCaseInsensitive(tag)))).where(criterion);
// Criterion.or(Field.field(prefix + TaskToTag.TAG_ID.name).eq(id), Field.field(prefix + TaskToTag.TAG_REMOTEID.name).eq(remoteId)))))
// .where(criterion);
} }
} }
public static Criterion memberOfTagData(long tagDataRemoteId) { public static Criterion memberOfTagData(long tagDataRemoteId) {
return Task.ID.in(Query.select(Metadata.TASK).from(Metadata.TABLE).where( return Task.ID.in(Query.select(Metadata.TASK).from(Metadata.TABLE).where(
Criterion.and(Metadata.KEY.eq(KEY), REMOTE_ID.eq(tagDataRemoteId)))); Criterion.and(Metadata.KEY.eq(TagMetadata.KEY), TagMetadata.TAG_UUID.eq(tagDataRemoteId))));
} }
public static Criterion tagEq(String tag, Criterion additionalCriterion) { public static Criterion tagEq(String tag, Criterion additionalCriterion) {
return Criterion.and( return Criterion.and(
MetadataCriteria.withKey(KEY), TAG.eq(tag), MetadataCriteria.withKey(TagMetadata.KEY), TagMetadata.TAG_NAME.eq(tag),
additionalCriterion); additionalCriterion);
} }
public static Criterion tagEqIgnoreCase(String tag, Criterion additionalCriterion) { public static Criterion tagEqIgnoreCase(String tag, Criterion additionalCriterion) {
return Criterion.and( return Criterion.and(
MetadataCriteria.withKey(KEY), TAG.eqCaseInsensitive(tag), MetadataCriteria.withKey(TagMetadata.KEY), TagMetadata.TAG_NAME.eqCaseInsensitive(tag),
additionalCriterion); additionalCriterion);
} }
@ -191,7 +174,7 @@ public final class TagService {
String[] emergentTags = getEmergentTags(); String[] emergentTags = getEmergentTags();
return new QueryTemplate().where(Criterion.and( return new QueryTemplate().where(Criterion.and(
Criterion.not(Task.ID.in(Query.select(Metadata.TASK).from(Metadata.TABLE).where(Criterion.and(MetadataCriteria.withKey(KEY), Criterion.not(TAG.in(emergentTags)))))), Criterion.not(Task.ID.in(Query.select(Metadata.TASK).from(Metadata.TABLE).where(Criterion.and(MetadataCriteria.withKey(TagMetadata.KEY), Criterion.not(TagMetadata.TAG_NAME.in(emergentTags)))))),
TaskCriteria.isActive(), TaskCriteria.isActive(),
TaskApiDao.TaskCriteria.ownedByMe(), TaskApiDao.TaskCriteria.ownedByMe(),
TaskCriteria.isVisible())); TaskCriteria.isVisible()));
@ -208,19 +191,19 @@ public final class TagService {
public Tag[] getGroupedTags(Order order, Criterion activeStatus, boolean includeEmergent) { public Tag[] getGroupedTags(Order order, Criterion activeStatus, boolean includeEmergent) {
Criterion criterion; Criterion criterion;
if (includeEmergent) if (includeEmergent)
criterion = Criterion.and(activeStatus, MetadataCriteria.withKey(KEY)); criterion = Criterion.and(activeStatus, MetadataCriteria.withKey(TagMetadata.KEY));
else else
criterion = Criterion.and(activeStatus, MetadataCriteria.withKey(KEY), Criterion.not(TAG.in(getEmergentTags()))); criterion = Criterion.and(activeStatus, MetadataCriteria.withKey(TagMetadata.KEY), Criterion.not(TagMetadata.TAG_NAME.in(getEmergentTags())));
Query query = Query.select(TAG, REMOTE_ID, COUNT). Query query = Query.select(TagMetadata.TAG_NAME, TagMetadata.TAG_UUID, COUNT).
join(Join.inner(Task.TABLE, Metadata.TASK.eq(Task.ID))). join(Join.inner(Task.TABLE, Metadata.TASK.eq(Task.ID))).
where(criterion). where(criterion).
orderBy(order).groupBy(TAG); orderBy(order).groupBy(TagMetadata.TAG_NAME);
TodorooCursor<Metadata> cursor = metadataDao.query(query); TodorooCursor<Metadata> cursor = metadataDao.query(query);
try { try {
ArrayList<Tag> array = new ArrayList<Tag>(); ArrayList<Tag> array = new ArrayList<Tag>();
for (int i = 0; i < cursor.getCount(); i++) { for (int i = 0; i < cursor.getCount(); i++) {
cursor.moveToNext(); cursor.moveToNext();
Tag tag = Tag.tagFromRemoteId(cursor.get(REMOTE_ID)); Tag tag = Tag.tagFromRemoteId(cursor.get(TagMetadata.TAG_UUID));
if (tag != null) if (tag != null)
array.add(tag); array.add(tag);
} }
@ -264,6 +247,21 @@ public final class TagService {
} }
} }
public void createLink(Task task, String tagName, long tagUuid) {
TodorooCursor<Metadata> existing = metadataDao.query(Query.select(Metadata.PROPERTIES)
.where(Criterion.and(MetadataCriteria.withKey(TagMetadata.KEY),
TagMetadata.TASK_UUID.eq(task.getValue(Task.REMOTE_ID)),
TagMetadata.TAG_UUID.eq(tagUuid))));
try {
if (existing.getCount() == 0) {
Metadata link = TagMetadata.newTagMetadata(task, tagName, tagUuid);
metadataDao.createNew(link);
}
} finally {
existing.close();
}
}
/** /**
* Return tags on the given task * Return tags on the given task
* *
@ -273,12 +271,12 @@ public final class TagService {
public TodorooCursor<Metadata> getTags(long taskId, boolean includeEmergent) { public TodorooCursor<Metadata> getTags(long taskId, boolean includeEmergent) {
Criterion criterion; Criterion criterion;
if (includeEmergent) if (includeEmergent)
criterion = Criterion.and(MetadataCriteria.withKey(KEY), criterion = Criterion.and(MetadataCriteria.withKey(TagMetadata.KEY),
MetadataCriteria.byTask(taskId)); MetadataCriteria.byTask(taskId));
else else
criterion = Criterion.and(MetadataCriteria.withKey(KEY), criterion = Criterion.and(MetadataCriteria.withKey(TagMetadata.KEY),
MetadataCriteria.byTask(taskId), Criterion.not(TAG.in(getEmergentTags()))); MetadataCriteria.byTask(taskId), Criterion.not(TagMetadata.TAG_NAME.in(getEmergentTags())));
Query query = Query.select(TAG, REMOTE_ID).where(criterion).orderBy(Order.asc(Functions.upper(TAG))); Query query = Query.select(TagMetadata.TAG_NAME, TagMetadata.TAG_UUID).where(criterion).orderBy(Order.asc(Functions.upper(TagMetadata.TAG_NAME)));
return metadataDao.query(query); return metadataDao.query(query);
} }
@ -307,7 +305,7 @@ public final class TagService {
for (int i = 0; i < length; i++) { for (int i = 0; i < length; i++) {
tags.moveToNext(); tags.moveToNext();
metadata.readFromCursor(tags); metadata.readFromCursor(tags);
tagBuilder.append(metadata.getValue(TAG)); tagBuilder.append(metadata.getValue(TagMetadata.TAG_NAME));
if (i < length - 1) if (i < length - 1)
tagBuilder.append(separator); tagBuilder.append(separator);
} }
@ -408,16 +406,16 @@ public final class TagService {
continue; continue;
addedTags.add(tagWithCase); addedTags.add(tagWithCase);
Metadata item = new Metadata(); Metadata item = new Metadata();
item.setValue(Metadata.KEY, KEY); item.setValue(Metadata.KEY, TagMetadata.KEY);
item.setValue(TAG, tagWithCase); item.setValue(TagMetadata.TAG_NAME, tagWithCase);
TagData tagData = tagDataService.getTag(tagWithCase, TagData.REMOTE_ID); TagData tagData = tagDataService.getTag(tagWithCase, TagData.REMOTE_ID);
if(tagData != null) if(tagData != null)
item.setValue(REMOTE_ID, tagData.getValue(TagData.REMOTE_ID)); item.setValue(TagMetadata.TAG_UUID, tagData.getValue(TagData.REMOTE_ID));
metadata.add(item); metadata.add(item);
} }
return service.synchronizeMetadata(taskId, metadata, Metadata.KEY.eq(KEY)); return service.synchronizeMetadata(taskId, metadata, Metadata.KEY.eq(TagMetadata.KEY));
} }
/** /**
@ -429,12 +427,12 @@ public final class TagService {
public String getTagWithCase(String tag) { public String getTagWithCase(String tag) {
MetadataService service = PluginServices.getMetadataService(); MetadataService service = PluginServices.getMetadataService();
String tagWithCase = tag; String tagWithCase = tag;
TodorooCursor<Metadata> tagMetadata = service.query(Query.select(TAG).where(TagService.tagEqIgnoreCase(tag, Criterion.all)).limit(1)); TodorooCursor<Metadata> tagMetadata = service.query(Query.select(TagMetadata.TAG_NAME).where(TagService.tagEqIgnoreCase(tag, Criterion.all)).limit(1));
try { try {
if (tagMetadata.getCount() > 0) { if (tagMetadata.getCount() > 0) {
tagMetadata.moveToFirst(); tagMetadata.moveToFirst();
Metadata tagMatch = new Metadata(tagMetadata); Metadata tagMatch = new Metadata(tagMetadata);
tagWithCase = tagMatch.getValue(TagService.TAG); tagWithCase = tagMatch.getValue(TagMetadata.TAG_NAME);
} else { } else {
TodorooCursor<TagData> tagData = tagDataService.query(Query.select(TagData.NAME).where(TagData.NAME.eqCaseInsensitive(tag))); TodorooCursor<TagData> tagData = tagDataService.query(Query.select(TagData.NAME).where(TagData.NAME.eqCaseInsensitive(tag)));
try { try {
@ -476,7 +474,7 @@ public final class TagService {
// Then rename all instances of oldTag to newTag. // Then rename all instances of oldTag to newTag.
Metadata metadata = new Metadata(); Metadata metadata = new Metadata();
metadata.setValue(TAG, newTag); metadata.setValue(TagMetadata.TAG_NAME, newTag);
int ret; int ret;
if (caseSensitive) if (caseSensitive)
ret = metadataService.update(tagEq(oldTag, Criterion.all), metadata); ret = metadataService.update(tagEq(oldTag, Criterion.all), metadata);

@ -232,7 +232,7 @@ public final class TagsControlSet extends PopupControlSet {
LinkedHashSet<String> tags = new LinkedHashSet<String>(cursor.getCount()); LinkedHashSet<String> tags = new LinkedHashSet<String>(cursor.getCount());
try { try {
for(cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) { for(cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
String tag = cursor.get(TagService.TAG); String tag = cursor.get(TagMetadata.TAG_NAME);
tags.add(tag); tags.add(tag);
} }
} finally { } finally {

@ -26,6 +26,7 @@ import com.todoroo.astrid.data.Metadata;
import com.todoroo.astrid.data.TagData; import com.todoroo.astrid.data.TagData;
import com.todoroo.astrid.data.TaskApiDao.TaskCriteria; import com.todoroo.astrid.data.TaskApiDao.TaskCriteria;
import com.todoroo.astrid.tags.TagFilterExposer; import com.todoroo.astrid.tags.TagFilterExposer;
import com.todoroo.astrid.tags.TagMetadata;
import com.todoroo.astrid.tags.TagService; import com.todoroo.astrid.tags.TagService;
import com.todoroo.astrid.tags.TagService.Tag; import com.todoroo.astrid.tags.TagService.Tag;
@ -45,8 +46,8 @@ public class FeaturedListFilterExposer extends TagFilterExposer {
String title = tag.tag; String title = tag.tag;
QueryTemplate tagTemplate = tag.queryTemplate(criterion); QueryTemplate tagTemplate = tag.queryTemplate(criterion);
ContentValues contentValues = new ContentValues(); ContentValues contentValues = new ContentValues();
contentValues.put(Metadata.KEY.name, TagService.KEY); contentValues.put(Metadata.KEY.name, TagMetadata.KEY);
contentValues.put(TagService.TAG.name, tag.tag); contentValues.put(TagMetadata.TAG_NAME.name, tag.tag);
FilterWithUpdate filter = new FilterWithUpdate(tag.tag, FilterWithUpdate filter = new FilterWithUpdate(tag.tag,
title, tagTemplate, title, tagTemplate,

@ -126,6 +126,9 @@ public class FeaturedTaskListFragment extends TagViewFragment {
if (existing.getCount() > 0) { if (existing.getCount() > 0) {
existing.moveToFirst(); existing.moveToFirst();
clone = new TagData(existing); clone = new TagData(existing);
} else {
clone = new TagData();
clone.setValue(TagData.NAME, localName);
} }
} finally { } finally {
@ -143,7 +146,7 @@ public class FeaturedTaskListFragment extends TagViewFragment {
Task t = new Task(); Task t = new Task();
for (tasks.moveToFirst(); !tasks.isAfterLast(); tasks.moveToNext()) { for (tasks.moveToFirst(); !tasks.isAfterLast(); tasks.moveToNext()) {
t.readFromCursor(tasks); t.readFromCursor(tasks);
taskService.cloneReusableTask(t, finalTagData.getId()); taskService.cloneReusableTask(t, localName, finalTagData.getValue(TagData.REMOTE_ID));
} }
final Activity activity = getActivity(); final Activity activity = getActivity();
if (activity != null) { if (activity != null) {

@ -49,7 +49,7 @@ public class ReusableTaskAdapter extends TaskAdapter {
@Override @Override
public void onClick(View v) { public void onClick(View v) {
ReusableTaskViewHolder holder = (ReusableTaskViewHolder) v.getTag(); ReusableTaskViewHolder holder = (ReusableTaskViewHolder) v.getTag();
taskService.cloneReusableTask(holder.task, 0L); taskService.cloneReusableTask(holder.task, null, 0L);
Toast.makeText(fragment.getActivity(), R.string.actfm_feat_list_task_clone_success, Toast.LENGTH_LONG).show(); Toast.makeText(fragment.getActivity(), R.string.actfm_feat_list_task_clone_success, Toast.LENGTH_LONG).show();
Flags.set(Flags.REFRESH); Flags.set(Flags.REFRESH);
} }

@ -100,6 +100,7 @@ import com.todoroo.astrid.service.ThemeService;
import com.todoroo.astrid.service.UpgradeService; import com.todoroo.astrid.service.UpgradeService;
import com.todoroo.astrid.subtasks.SubtasksListFragment; import com.todoroo.astrid.subtasks.SubtasksListFragment;
import com.todoroo.astrid.sync.SyncProviderPreferences; import com.todoroo.astrid.sync.SyncProviderPreferences;
import com.todoroo.astrid.tags.TagMetadata;
import com.todoroo.astrid.tags.TagService; import com.todoroo.astrid.tags.TagService;
import com.todoroo.astrid.taskrabbit.TaskRabbitMetadata; import com.todoroo.astrid.taskrabbit.TaskRabbitMetadata;
import com.todoroo.astrid.timers.TimerPlugin; import com.todoroo.astrid.timers.TimerPlugin;
@ -902,14 +903,14 @@ public class TaskListFragment extends ListFragment implements OnScrollListener,
tagName = getActiveTagData().getValue(TagData.NAME); tagName = getActiveTagData().getValue(TagData.NAME);
String[] emergentTags = TagService.getInstance().getEmergentTags(); String[] emergentTags = TagService.getInstance().getEmergentTags();
StringProperty tagProperty = new StringProperty(null, TAGS_METADATA_JOIN + "." + TagService.TAG.name); StringProperty tagProperty = new StringProperty(null, TAGS_METADATA_JOIN + "." + TagMetadata.TAG_NAME.name);
Criterion tagsJoinCriterion = Criterion.and( Criterion tagsJoinCriterion = Criterion.and(
Field.field(TAGS_METADATA_JOIN + "." + Metadata.KEY.name).eq(TagService.KEY), //$NON-NLS-1$ Field.field(TAGS_METADATA_JOIN + "." + Metadata.KEY.name).eq(TagMetadata.KEY), //$NON-NLS-1$
Task.ID.eq(Field.field(TAGS_METADATA_JOIN + "." + Metadata.TASK.name)), Task.ID.eq(Field.field(TAGS_METADATA_JOIN + "." + Metadata.TASK.name)),
Criterion.not(tagProperty.in(emergentTags))); Criterion.not(tagProperty.in(emergentTags)));
if (tagName != null) if (tagName != null)
tagsJoinCriterion = Criterion.and(tagsJoinCriterion, Field.field(TAGS_METADATA_JOIN + "." + TagService.TAG.name).neq(tagName)); tagsJoinCriterion = Criterion.and(tagsJoinCriterion, Field.field(TAGS_METADATA_JOIN + "." + TagMetadata.TAG_NAME.name).neq(tagName));
// TODO: For now, we'll modify the query to join and include the task rabbit and tag data here. // TODO: For now, we'll modify the query to join and include the task rabbit and tag data here.
// Eventually, we might consider restructuring things so that this query is constructed elsewhere. // Eventually, we might consider restructuring things so that this query is constructed elsewhere.

@ -91,7 +91,7 @@ import com.todoroo.astrid.service.StatisticsConstants;
import com.todoroo.astrid.service.StatisticsService; import com.todoroo.astrid.service.StatisticsService;
import com.todoroo.astrid.service.TaskService; import com.todoroo.astrid.service.TaskService;
import com.todoroo.astrid.service.ThemeService; import com.todoroo.astrid.service.ThemeService;
import com.todoroo.astrid.tags.TagService; import com.todoroo.astrid.tags.TagMetadata;
import com.todoroo.astrid.timers.TimerDecorationExposer; import com.todoroo.astrid.timers.TimerDecorationExposer;
import com.todoroo.astrid.ui.CheckableImageView; import com.todoroo.astrid.ui.CheckableImageView;
import com.todoroo.astrid.utility.Constants; import com.todoroo.astrid.utility.Constants;
@ -116,7 +116,7 @@ public class TaskAdapter extends CursorAdapter implements Filterable {
Metadata.ID.name).as("taskRabId"); //$NON-NLS-1$ Metadata.ID.name).as("taskRabId"); //$NON-NLS-1$
@SuppressWarnings("nls") @SuppressWarnings("nls")
private static final StringProperty TAGS = new StringProperty(null, "group_concat(" + TaskListFragment.TAGS_METADATA_JOIN + "." + TagService.TAG.name + ", ' | ')").as("tags"); private static final StringProperty TAGS = new StringProperty(null, "group_concat(" + TaskListFragment.TAGS_METADATA_JOIN + "." + TagMetadata.TAG_NAME.name + ", ' | ')").as("tags");
// --- other constants // --- other constants

@ -6,6 +6,7 @@
package com.todoroo.astrid.dao; package com.todoroo.astrid.dao;
import android.database.sqlite.SQLiteException; import android.database.sqlite.SQLiteException;
import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import com.todoroo.andlib.data.AbstractDatabase; import com.todoroo.andlib.data.AbstractDatabase;
@ -338,9 +339,10 @@ public class Database extends AbstractDatabase {
database.execSQL(createTableSql(visitor, TaskOutstanding.TABLE.name, TaskOutstanding.PROPERTIES)); database.execSQL(createTableSql(visitor, TaskOutstanding.TABLE.name, TaskOutstanding.PROPERTIES));
database.execSQL(createTableSql(visitor, TagOutstanding.TABLE.name, TagOutstanding.PROPERTIES)); database.execSQL(createTableSql(visitor, TagOutstanding.TABLE.name, TagOutstanding.PROPERTIES));
database.execSQL(addColumnSql(Task.TABLE, Task.PROOF_TEXT, visitor)); database.execSQL(addColumnSql(Task.TABLE, Task.PROOF_TEXT, visitor, null));
database.execSQL(addColumnSql(TagData.TABLE, TagData.PROOF_TEXT, visitor)); database.execSQL(addColumnSql(TagData.TABLE, TagData.PROOF_TEXT, visitor, null));
database.execSQL(addColumnSql(Update.TABLE, Update.PROOF_TEXT, visitor)); database.execSQL(addColumnSql(Update.TABLE, Update.PROOF_TEXT, visitor, null));
database.execSQL(addColumnSql(Metadata.TABLE, Metadata.DELETION_DATE, visitor, "0"));
} catch (SQLiteException e) { } catch (SQLiteException e) {
Log.e("astrid", "db-upgrade-" + oldVersion + "-" + newVersion, e); Log.e("astrid", "db-upgrade-" + oldVersion + "-" + newVersion, e);
} }
@ -351,8 +353,16 @@ public class Database extends AbstractDatabase {
return false; return false;
} }
private static String addColumnSql(Table table, Property<?> property, SqlConstructorVisitor visitor) { private static String addColumnSql(Table table, Property<?> property, SqlConstructorVisitor visitor, String defaultValue) {
return "ALTER TABLE " + table.name + " ADD " + property.accept(visitor, null); StringBuilder builder = new StringBuilder();
builder.append("ALTER TABLE ")
.append(table.name)
.append(" ADD ")
.append(property.accept(visitor, null));
if (!TextUtils.isEmpty(defaultValue)) {
builder.append(" DEFAULT ").append(defaultValue);
}
return builder.toString();
} }
/** /**

@ -22,7 +22,7 @@ import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.provider.Astrid2TaskProvider; import com.todoroo.astrid.provider.Astrid2TaskProvider;
import com.todoroo.astrid.service.StatisticsConstants; import com.todoroo.astrid.service.StatisticsConstants;
import com.todoroo.astrid.service.StatisticsService; import com.todoroo.astrid.service.StatisticsService;
import com.todoroo.astrid.tags.TagService; import com.todoroo.astrid.tags.TagMetadata;
import com.todoroo.astrid.utility.AstridPreferences; import com.todoroo.astrid.utility.AstridPreferences;
/** /**
@ -75,7 +75,7 @@ public class MetadataDao extends DatabaseDao<Metadata> {
boolean state = super.persist(item); boolean state = super.persist(item);
if(Preferences.getBoolean(AstridPreferences.P_FIRST_LIST, true)) { if(Preferences.getBoolean(AstridPreferences.P_FIRST_LIST, true)) {
if (state && item.containsNonNullValue(Metadata.KEY) && if (state && item.containsNonNullValue(Metadata.KEY) &&
item.getValue(Metadata.KEY).equals(TagService.KEY)) { item.getValue(Metadata.KEY).equals(TagMetadata.KEY)) {
StatisticsService.reportEvent(StatisticsConstants.USER_FIRST_LIST); StatisticsService.reportEvent(StatisticsConstants.USER_FIRST_LIST);
Preferences.setBoolean(AstridPreferences.P_FIRST_LIST, false); Preferences.setBoolean(AstridPreferences.P_FIRST_LIST, false);
} }

@ -33,6 +33,7 @@ import com.todoroo.astrid.service.AstridDependencyInjector;
import com.todoroo.astrid.service.StatisticsConstants; import com.todoroo.astrid.service.StatisticsConstants;
import com.todoroo.astrid.service.StatisticsService; import com.todoroo.astrid.service.StatisticsService;
import com.todoroo.astrid.service.TaskService; import com.todoroo.astrid.service.TaskService;
import com.todoroo.astrid.tags.TagMetadata;
import com.todoroo.astrid.tags.TagService; import com.todoroo.astrid.tags.TagService;
import com.todoroo.astrid.tags.TagService.Tag; import com.todoroo.astrid.tags.TagService.Tag;
@ -203,7 +204,7 @@ public class Astrid2TaskProvider extends ContentProvider {
TodorooCursor<Metadata> tagCursor = TagService.getInstance().getTags(task.getId(), true); TodorooCursor<Metadata> tagCursor = TagService.getInstance().getTags(task.getId(), true);
try { try {
for(tagCursor.moveToFirst(); !tagCursor.isAfterLast(); tagCursor.moveToNext()) for(tagCursor.moveToFirst(); !tagCursor.isAfterLast(); tagCursor.moveToNext())
taskTags.append(tagCursor.get(TagService.TAG)).append(TAG_SEPARATOR); taskTags.append(tagCursor.get(TagMetadata.TAG_NAME)).append(TAG_SEPARATOR);
} finally { } finally {
tagCursor.close(); tagCursor.close();
} }

@ -47,7 +47,7 @@ import com.todoroo.astrid.legacy.LegacyAlertModel;
import com.todoroo.astrid.legacy.LegacyRepeatInfo; import com.todoroo.astrid.legacy.LegacyRepeatInfo;
import com.todoroo.astrid.legacy.LegacyTaskModel; import com.todoroo.astrid.legacy.LegacyTaskModel;
import com.todoroo.astrid.legacy.TransitionalAlarm; import com.todoroo.astrid.legacy.TransitionalAlarm;
import com.todoroo.astrid.tags.TagService; import com.todoroo.astrid.tags.TagMetadata;
public class Astrid2To3UpgradeHelper { public class Astrid2To3UpgradeHelper {
@ -400,7 +400,7 @@ public class Astrid2To3UpgradeHelper {
return; return;
Metadata metadata = new Metadata(); Metadata metadata = new Metadata();
metadata.setValue(Metadata.KEY, TagService.KEY); metadata.setValue(Metadata.KEY, TagMetadata.KEY);
long tagId = -1; long tagId = -1;
String tag = null; String tag = null;
for(mapCursor.moveToFirst(); !mapCursor.isAfterLast(); mapCursor.moveToNext()) { for(mapCursor.moveToFirst(); !mapCursor.isAfterLast(); mapCursor.moveToNext()) {
@ -417,8 +417,8 @@ public class Astrid2To3UpgradeHelper {
tag = tagCursor.getString(1); tag = tagCursor.getString(1);
long task = mapCursor.getLong(1); long task = mapCursor.getLong(1);
metadata.setValue(Metadata.TASK, task); metadata.setValue(Metadata.TASK, task);
metadata.setValue(Metadata.KEY, TagService.KEY); metadata.setValue(Metadata.KEY, TagMetadata.KEY);
metadata.setValue(TagService.TAG, tag); metadata.setValue(TagMetadata.TAG_NAME, tag);
metadataDao.createNew(metadata); metadataDao.createNew(metadata);
metadata.clearValue(Metadata.ID); metadata.clearValue(Metadata.ID);
} }

@ -38,6 +38,7 @@ import com.todoroo.astrid.gcal.GCalHelper;
import com.todoroo.astrid.gtasks.GtasksMetadata; import com.todoroo.astrid.gtasks.GtasksMetadata;
import com.todoroo.astrid.opencrx.OpencrxCoreUtils; import com.todoroo.astrid.opencrx.OpencrxCoreUtils;
import com.todoroo.astrid.producteev.sync.ProducteevTask; import com.todoroo.astrid.producteev.sync.ProducteevTask;
import com.todoroo.astrid.tags.TagMetadata;
import com.todoroo.astrid.tags.TagService; import com.todoroo.astrid.tags.TagService;
import com.todoroo.astrid.utility.TitleParser; import com.todoroo.astrid.utility.TitleParser;
@ -193,7 +194,7 @@ public class TaskService {
return newTask; return newTask;
} }
public Task cloneReusableTask(Task task, long tagId) { public Task cloneReusableTask(Task task, String tagName, long tagUuid) {
Task newTask = fetchById(task.getId(), Task.PROPERTIES); Task newTask = fetchById(task.getId(), Task.PROPERTIES);
if (newTask == null) if (newTask == null)
return new Task(); return new Task();
@ -204,8 +205,8 @@ public class TaskService {
taskDao.save(newTask); taskDao.save(newTask);
if (tagId > 0) { if (tagUuid > 0) {
tagService.createLink(task, tagId); tagService.createLink(task, tagName, tagUuid);
} }
return newTask; return newTask;
} }
@ -430,9 +431,9 @@ public class TaskService {
Metadata metadata = new Metadata(); Metadata metadata = new Metadata();
for(String tag : tags) { for(String tag : tags) {
metadata.setValue(Metadata.KEY, TagService.KEY); metadata.setValue(Metadata.KEY, TagMetadata.KEY);
metadata.setValue(Metadata.TASK, task.getId()); metadata.setValue(Metadata.TASK, task.getId());
metadata.setValue(TagService.TAG, tag); metadata.setValue(TagMetadata.TAG_NAME, tag);
metadataDao.createNew(metadata); metadataDao.createNew(metadata);
} }
} }

Loading…
Cancel
Save