1
0
mirror of https://github.com/etesync/android synced 2025-02-02 10:51:10 +00:00

Handle dirty flag of exceptions of recurring events

* mark events as dirty when its exceptions are dirty/deleted
* when (mass-)deleting events, delete corresponding exceptions too
This commit is contained in:
Ricki Hirner 2015-04-28 11:08:22 +02:00
parent a405d07baf
commit f6eee6c910
2 changed files with 72 additions and 17 deletions

View File

@ -206,6 +206,24 @@ public class LocalCalendar extends LocalCollection<Event> {
}
}
@Override
public long[] findUpdated() throws LocalStorageException {
// mark (recurring) events with changed/deleted exceptions as dirty
String where = entryColumnID() + " IN (SELECT DISTINCT " + Events.ORIGINAL_ID + " FROM events WHERE " +
Events.ORIGINAL_ID + " IS NOT NULL AND (" + Events.DIRTY + "=1 OR " + Events.DELETED + "=1))";
Log.i(TAG, where);
ContentValues dirty = new ContentValues(1);
dirty.put(CalendarContract.Events.DIRTY, 1);
try {
providerClient.update(entriesURI(), dirty, where, null);
} catch (RemoteException e) {
Log.e(TAG, "Couldn't mark events with updated exceptions as dirty", e);
}
// new find and return updated (master) events
return super.findUpdated();
}
/* create/update/delete */
@ -214,23 +232,57 @@ public class LocalCalendar extends LocalCollection<Event> {
}
public void deleteAllExceptRemoteNames(Resource[] remoteResources) {
List<String> sqlFileNames = new LinkedList<>();
for (Resource res : remoteResources)
sqlFileNames.add(DatabaseUtils.sqlEscapeString(res.getName()));
// delete master events
String where = entryColumnParentID() + "=?";
if (remoteResources.length != 0) {
List<String> sqlFileNames = new LinkedList<String>();
for (Resource res : remoteResources)
sqlFileNames.add(DatabaseUtils.sqlEscapeString(res.getName()));
where += " AND " + entryColumnRemoteName() + " NOT IN (" + StringUtils.join(sqlFileNames, ",") + ")";
} else
where += " AND " + entryColumnRemoteName() + " IS NOT NULL";
where += sqlFileNames.isEmpty() ?
" AND " + entryColumnRemoteName() + " IS NOT NULL" : // don't retain anything (delete all)
" AND " + entryColumnRemoteName() + " NOT IN (" + StringUtils.join(sqlFileNames, ",") + ")"; // retain by remote file name
if (sqlFilter != null)
where += " AND (" + sqlFilter + ")";
Builder builder = ContentProviderOperation.newDelete(entriesURI())
.withSelection(where, new String[] { String.valueOf(id) });
pendingOperations.add(builder
.withYieldAllowed(true)
pendingOperations.add(ContentProviderOperation.newDelete(entriesURI())
.withSelection(where, new String[] { String.valueOf(id) })
.build());
// delete exceptions, too
where = entryColumnParentID() + "=?";
where += sqlFileNames.isEmpty() ?
" AND " + Events.ORIGINAL_SYNC_ID + " IS NOT NULL" : // don't retain anything (delete all)
" AND " + Events.ORIGINAL_SYNC_ID + " NOT IN (" + StringUtils.join(sqlFileNames, ",") + ")"; // retain by remote file name
pendingOperations.add(ContentProviderOperation
.newDelete(entriesURI())
.withSelection(where, new String[] { String.valueOf(id) })
.withYieldAllowed(true)
.build()
);
}
@Override
public void delete(Resource resource) {
super.delete(resource);
// delete all exceptions of this event, too
pendingOperations.add(ContentProviderOperation
.newDelete(entriesURI())
.withSelection(Events.ORIGINAL_ID+"=?", new String[] { Long.toString(resource.getLocalID()) })
.build()
);
}
@Override
public void clearDirty(Resource resource) {
super.clearDirty(resource);
// clear dirty flag of all exceptions of this event
pendingOperations.add(ContentProviderOperation
.newUpdate(entriesURI())
.withValue(Events.DIRTY, 0)
.withSelection(Events.ORIGINAL_ID+"=?", new String[] { Long.toString(resource.getLocalID()) })
.build()
);
}
@ -478,7 +530,7 @@ public class LocalCalendar extends LocalCollection<Event> {
e.getAlarms().add(alarm);
}
}
/* content builder methods */

View File

@ -92,6 +92,7 @@ public abstract class LocalCollection<T extends Resource> {
/**
* Finds new resources (resources which haven't been uploaded yet).
* New resources are 1) dirty, and 2) don't have an ETag yet.
* Only records matching sqlFilter will be returned.
*
* @return IDs of new resources
* @throws LocalStorageException when the content provider couldn't be queried
@ -132,7 +133,8 @@ public abstract class LocalCollection<T extends Resource> {
/**
* Finds updated resources (resources which have already been uploaded, but have changed locally).
* Updated resources are 1) dirty, and 2) already have an ETag.
* Updated resources are 1) dirty, and 2) already have an ETag. Only records matching sqlFilter
* will be returned.
*
* @return IDs of updated resources
* @throws LocalStorageException when the content provider couldn't be queried
@ -162,6 +164,7 @@ public abstract class LocalCollection<T extends Resource> {
/**
* Finds deleted resources (resources which have been marked for deletion).
* Deleted resources have the "deleted" flag set.
* Only records matching sqlFilter will be returned.
*
* @return IDs of deleted resources
* @throws LocalStorageException when the content provider couldn't be queried
@ -189,7 +192,7 @@ public abstract class LocalCollection<T extends Resource> {
}
/**
* Finds a specific resource by ID.
* Finds a specific resource by ID. Only records matching sqlFilter are taken into account.
* @param localID ID of the resource
* @param populate true: populates all data fields (for instance, contact or event details);
* false: only remote file name and ETag are populated
@ -214,7 +217,7 @@ public abstract class LocalCollection<T extends Resource> {
}
/**
* Finds a specific resource by remote file name.
* Finds a specific resource by remote file name. Only records matching sqlFilter are taken into account.
* @param localID remote file name of the resource
* @param populate true: populates all data fields (for instance, contact or event details);
* false: only remote file name and ETag are populated