diff --git a/api/src/com/todoroo/astrid/data/TagMetadata.java b/api/src/com/todoroo/astrid/data/TagMetadata.java index fe9879aba..56dcef837 100644 --- a/api/src/com/todoroo/astrid/data/TagMetadata.java +++ b/api/src/com/todoroo/astrid/data/TagMetadata.java @@ -16,6 +16,9 @@ public class TagMetadata extends AbstractModel { public static final Table TABLE = new Table("tag_metadata", TagMetadata.class); + /** changes to metadata (specifically members) are recorded in the tag outstanding table */ + public static final Class> OUTSTANDING_MODEL = TagOutstanding.class; + /** content uri for this model */ public static final Uri CONTENT_URI = Uri.parse("content://" + AstridApiConstants.API_PACKAGE + "/" + TABLE.name); @@ -26,6 +29,10 @@ public class TagMetadata extends AbstractModel { public static final LongProperty ID = new LongProperty( TABLE, ID_PROPERTY_NAME); + /** Tag local id */ + public static final LongProperty TAG_ID = new LongProperty( + TABLE, "tag_id"); + /** Tag uuid */ public static final StringProperty TAG_UUID = new StringProperty( TABLE, "tag_uuid"); diff --git a/astrid/plugin-src/com/todoroo/astrid/actfm/sync/messages/ChangesHappened.java b/astrid/plugin-src/com/todoroo/astrid/actfm/sync/messages/ChangesHappened.java index 3dadef9b2..81117542c 100644 --- a/astrid/plugin-src/com/todoroo/astrid/actfm/sync/messages/ChangesHappened.java +++ b/astrid/plugin-src/com/todoroo/astrid/actfm/sync/messages/ChangesHappened.java @@ -99,6 +99,12 @@ public class ChangesHappened localProperty = NameMaps.localColumnNameToProperty(table, localColumn); if (localProperty == null) diff --git a/astrid/plugin-src/com/todoroo/astrid/actfm/sync/messages/MakeChanges.java b/astrid/plugin-src/com/todoroo/astrid/actfm/sync/messages/MakeChanges.java index 26e737175..231c70ef3 100644 --- a/astrid/plugin-src/com/todoroo/astrid/actfm/sync/messages/MakeChanges.java +++ b/astrid/plugin-src/com/todoroo/astrid/actfm/sync/messages/MakeChanges.java @@ -11,6 +11,7 @@ import org.json.JSONObject; import android.text.TextUtils; import android.util.Log; +import com.todoroo.andlib.data.AbstractModel; import com.todoroo.andlib.data.Property; import com.todoroo.andlib.data.Property.LongProperty; import com.todoroo.andlib.data.Property.StringProperty; @@ -144,6 +145,17 @@ public class MakeChanges extends ServerToClientMessage } public abstract void performChanges(); + + protected long getLocalId() { + long localId; + if (!model.isSaved()) { // We don't have the local task id + localId = dao.localIdFromUuid(uuid); + model.setId(localId); + } else { + localId = model.getId(); + } + return localId; + } } private class BeforeSaveTaskChanges extends ChangeHooks { @@ -189,13 +201,9 @@ public class MakeChanges extends ServerToClientMessage if (!tagsAdded && !tagsRemoved) return; - long localId; - if (!model.isSaved()) { // We don't have the local task id - localId = dao.localIdFromUuid(uuid); - model.setId(localId); - } else { - localId = model.getId(); - } + long localId = AbstractModel.NO_ID; + if (tagsAdded || tagsRemoved) + localId = getLocalId(); if (tagsAdded) { if (model.isSaved()) { @@ -251,11 +259,15 @@ public class MakeChanges extends ServerToClientMessage boolean membersAdded = (addMembers != null && addMembers.length() > 0); boolean membersRemoved = (removeMembers != null && removeMembers.length() > 0); + long localId = AbstractModel.NO_ID; + if (membersAdded || membersRemoved) + localId = getLocalId(); + if (membersAdded) { for (int i = 0; i < addMembers.length(); i++) { try { String memberId = addMembers.getString(i); - tagMetadataDao.createMemberLink(uuid, memberId); + tagMetadataDao.createMemberLink(localId, uuid, memberId, true); } catch (JSONException e) { // } @@ -272,7 +284,7 @@ public class MakeChanges extends ServerToClientMessage // } } - tagMetadataDao.removeMemberLinks(uuid, toRemove.toArray(new String[toRemove.size()]), true); + tagMetadataDao.removeMemberLinks(localId, uuid, toRemove.toArray(new String[toRemove.size()]), true); } } } diff --git a/astrid/plugin-src/com/todoroo/astrid/actfm/sync/messages/NameMaps.java b/astrid/plugin-src/com/todoroo/astrid/actfm/sync/messages/NameMaps.java index 14beeab38..e56ca60b3 100644 --- a/astrid/plugin-src/com/todoroo/astrid/actfm/sync/messages/NameMaps.java +++ b/astrid/plugin-src/com/todoroo/astrid/actfm/sync/messages/NameMaps.java @@ -63,6 +63,10 @@ public class NameMaps { excludedFromOutstandingSet.add(property.name); } + // ---------- + // Tasks + // ---------- + private static final Map, String> TASK_PROPERTIES_LOCAL_TO_SERVER; private static final Map> TASK_COLUMN_NAMES_TO_PROPERTIES; private static final Map TASK_COLUMNS_LOCAL_TO_SERVER; @@ -107,6 +111,10 @@ public class NameMaps { public static final String TAG_REMOVED_COLUMN = "tag_removed"; + // ---------- + // TagData + // ---------- + private static final Map, String> TAG_DATA_PROPERTIES_LOCAL_TO_SERVER; private static final Map> TAG_DATA_COLUMN_NAMES_TO_PROPERTIES; private static final Map TAG_DATA_COLUMNS_LOCAL_TO_SERVER; @@ -139,6 +147,14 @@ public class NameMaps { TAG_DATA_PROPERTIES_SERVER_TO_LOCAL = AndroidUtilities.reverseMap(TAG_DATA_PROPERTIES_LOCAL_TO_SERVER); } + public static final String MEMBER_ADDED_COLUMN = "member_added"; + public static final String MEMBER_REMOVED_COLUMN = "member_removed"; + + + + // ---------- + // Users + // ---------- private static final Map, String> USER_PROPERTIES_LOCAL_TO_SERVER; private static final Map> USER_COLUMN_NAMES_TO_PROPERTIES; private static final Map USER_COLUMNS_LOCAL_TO_SERVER; diff --git a/astrid/plugin-src/com/todoroo/astrid/tags/TagMemberMetadata.java b/astrid/plugin-src/com/todoroo/astrid/tags/TagMemberMetadata.java index 854a779dd..5c8b638b8 100644 --- a/astrid/plugin-src/com/todoroo/astrid/tags/TagMemberMetadata.java +++ b/astrid/plugin-src/com/todoroo/astrid/tags/TagMemberMetadata.java @@ -10,8 +10,9 @@ public class TagMemberMetadata { public static final StringProperty USER_UUID = new StringProperty( TagMetadata.TABLE, TagMetadata.VALUE1.name); - public static TagMetadata newMemberMetadata(String tagUuid, String userUuid) { + public static TagMetadata newMemberMetadata(long tagId, String tagUuid, String userUuid) { TagMetadata m = new TagMetadata(); + m.setValue(TagMetadata.TAG_ID, tagId); m.setValue(TagMetadata.TAG_UUID, tagUuid); m.setValue(USER_UUID, userUuid); m.setValue(TagMetadata.DELETION_DATE, 0L); diff --git a/astrid/src/com/todoroo/astrid/dao/MetadataDao.java b/astrid/src/com/todoroo/astrid/dao/MetadataDao.java index f9d906f0b..bd9eefb63 100644 --- a/astrid/src/com/todoroo/astrid/dao/MetadataDao.java +++ b/astrid/src/com/todoroo/astrid/dao/MetadataDao.java @@ -91,17 +91,17 @@ public class MetadataDao extends DatabaseDao { if (taskId == null || taskId == AbstractModel.NO_ID || RemoteModel.isUuidEmpty(tagUuid)) return false; - TaskOutstanding m = new TaskOutstanding(); - m.setValue(OutstandingEntry.ENTITY_ID_PROPERTY, taskId); - m.setValue(OutstandingEntry.CREATED_AT_PROPERTY, DateUtilities.now()); + TaskOutstanding to = new TaskOutstanding(); + to.setValue(OutstandingEntry.ENTITY_ID_PROPERTY, taskId); + to.setValue(OutstandingEntry.CREATED_AT_PROPERTY, DateUtilities.now()); String addedOrRemoved = NameMaps.TAG_ADDED_COLUMN; if (deletionDate != null && deletionDate > 0) addedOrRemoved = NameMaps.TAG_REMOVED_COLUMN; - m.setValue(OutstandingEntry.COLUMN_STRING_PROPERTY, addedOrRemoved); - m.setValue(OutstandingEntry.VALUE_STRING_PROPERTY, tagUuid); - database.insert(outstandingTable.name, null, m.getSetValues()); + to.setValue(OutstandingEntry.COLUMN_STRING_PROPERTY, addedOrRemoved); + to.setValue(OutstandingEntry.VALUE_STRING_PROPERTY, tagUuid); + database.insert(outstandingTable.name, null, to.getSetValues()); return true; } diff --git a/astrid/src/com/todoroo/astrid/dao/TagMetadataDao.java b/astrid/src/com/todoroo/astrid/dao/TagMetadataDao.java index 3974eda04..4a133398b 100644 --- a/astrid/src/com/todoroo/astrid/dao/TagMetadataDao.java +++ b/astrid/src/com/todoroo/astrid/dao/TagMetadataDao.java @@ -5,14 +5,21 @@ */ package com.todoroo.astrid.dao; +import android.content.ContentValues; + +import com.todoroo.andlib.data.AbstractModel; import com.todoroo.andlib.data.DatabaseDao; import com.todoroo.andlib.service.Autowired; import com.todoroo.andlib.service.DependencyInjectionService; import com.todoroo.andlib.sql.Criterion; import com.todoroo.andlib.utility.DateUtilities; +import com.todoroo.astrid.actfm.sync.messages.NameMaps; import com.todoroo.astrid.data.Metadata; +import com.todoroo.astrid.data.OutstandingEntry; +import com.todoroo.astrid.data.RemoteModel; import com.todoroo.astrid.data.SyncFlags; import com.todoroo.astrid.data.TagMetadata; +import com.todoroo.astrid.data.TagOutstanding; import com.todoroo.astrid.tags.TagMemberMetadata; /** @@ -50,17 +57,53 @@ public class TagMetadataDao extends DatabaseDao { } } - public void createMemberLink(String tagUuid, String memberId) { - TagMetadata newMetadata = TagMemberMetadata.newMemberMetadata(tagUuid, memberId); + @Override + protected boolean shouldRecordOutstanding(TagMetadata item) { + ContentValues cv = item.getSetValues(); + return super.shouldRecordOutstanding(item) && cv != null && + ((cv.containsKey(TagMetadata.KEY.name) && + TagMemberMetadata.KEY.equals(item.getValue(TagMetadata.KEY))) || + (cv.containsKey(TagMetadata.DELETION_DATE.name) && + item.getValue(TagMetadata.DELETION_DATE) > 0)); + } + + @Override + protected boolean createOutstandingEntries(long modelId, ContentValues modelSetValues) { + Long tagDataId = modelSetValues.getAsLong(TagMetadata.TAG_ID.name); + String memberId = modelSetValues.getAsString(TagMemberMetadata.USER_UUID.name); + Long deletionDate = modelSetValues.getAsLong(TagMetadata.DELETION_DATE.name); + if (tagDataId == null || tagDataId == AbstractModel.NO_ID || RemoteModel.isUuidEmpty(memberId)) + return false; + + TagOutstanding to = new TagOutstanding(); + to.setValue(OutstandingEntry.ENTITY_ID_PROPERTY, tagDataId); + to.setValue(OutstandingEntry.CREATED_AT_PROPERTY, DateUtilities.now()); + + String addedOrRemoved = NameMaps.MEMBER_ADDED_COLUMN; + if (deletionDate != null && deletionDate > 0) + addedOrRemoved = NameMaps.MEMBER_REMOVED_COLUMN; + + to.setValue(OutstandingEntry.COLUMN_STRING_PROPERTY, addedOrRemoved); + to.setValue(OutstandingEntry.VALUE_STRING_PROPERTY, memberId); + database.insert(outstandingTable.name, null, to.getSetValues()); + return true; + } + + public void createMemberLink(long tagId, String tagUuid, String memberId, boolean suppressOutstanding) { + TagMetadata newMetadata = TagMemberMetadata.newMemberMetadata(tagId, tagUuid, memberId); + if (suppressOutstanding) + newMetadata.putTransitory(SyncFlags.ACTFM_SUPPRESS_OUTSTANDING_ENTRIES, true); if (update(Criterion.and(TagMetadataCriteria.byTagAndWithKey(tagUuid, TagMemberMetadata.KEY), TagMemberMetadata.USER_UUID.eq(memberId)), newMetadata) <= 0) { + if (suppressOutstanding) + newMetadata.putTransitory(SyncFlags.ACTFM_SUPPRESS_OUTSTANDING_ENTRIES, true); createNew(newMetadata); } } - public void removeMemberLinks(String tagUuid, String[] memberIds, boolean suppressOutstanding) { + public void removeMemberLinks(long tagId, String tagUuid, String[] memberIds, boolean suppressOutstanding) { TagMetadata deleteTemplate = new TagMetadata(); - deleteTemplate.setValue(TagMetadata.TAG_UUID, tagUuid); // Need this for recording changes in outstanding table + deleteTemplate.setValue(TagMetadata.TAG_ID, tagId); // Need this for recording changes in outstanding table deleteTemplate.setValue(Metadata.DELETION_DATE, DateUtilities.now()); if (memberIds != null) { for (String uuid : memberIds) {