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:
parent
a405d07baf
commit
f6eee6c910
@ -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 */
|
/* create/update/delete */
|
||||||
|
|
||||||
@ -214,23 +232,57 @@ public class LocalCalendar extends LocalCollection<Event> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void deleteAllExceptRemoteNames(Resource[] remoteResources) {
|
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() + "=?";
|
String where = entryColumnParentID() + "=?";
|
||||||
|
where += sqlFileNames.isEmpty() ?
|
||||||
if (remoteResources.length != 0) {
|
" AND " + entryColumnRemoteName() + " IS NOT NULL" : // don't retain anything (delete all)
|
||||||
List<String> sqlFileNames = new LinkedList<String>();
|
" AND " + entryColumnRemoteName() + " NOT IN (" + StringUtils.join(sqlFileNames, ",") + ")"; // retain by remote file name
|
||||||
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";
|
|
||||||
if (sqlFilter != null)
|
if (sqlFilter != null)
|
||||||
where += " AND (" + sqlFilter + ")";
|
where += " AND (" + sqlFilter + ")";
|
||||||
|
pendingOperations.add(ContentProviderOperation.newDelete(entriesURI())
|
||||||
Builder builder = ContentProviderOperation.newDelete(entriesURI())
|
.withSelection(where, new String[] { String.valueOf(id) })
|
||||||
.withSelection(where, new String[] { String.valueOf(id) });
|
|
||||||
pendingOperations.add(builder
|
|
||||||
.withYieldAllowed(true)
|
|
||||||
.build());
|
.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);
|
e.getAlarms().add(alarm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* content builder methods */
|
/* content builder methods */
|
||||||
|
|
||||||
|
@ -92,6 +92,7 @@ public abstract class LocalCollection<T extends Resource> {
|
|||||||
/**
|
/**
|
||||||
* Finds new resources (resources which haven't been uploaded yet).
|
* Finds new resources (resources which haven't been uploaded yet).
|
||||||
* New resources are 1) dirty, and 2) don't have an ETag 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
|
* @return IDs of new resources
|
||||||
* @throws LocalStorageException when the content provider couldn't be queried
|
* @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).
|
* 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
|
* @return IDs of updated resources
|
||||||
* @throws LocalStorageException when the content provider couldn't be queried
|
* @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).
|
* Finds deleted resources (resources which have been marked for deletion).
|
||||||
* Deleted resources have the "deleted" flag set.
|
* Deleted resources have the "deleted" flag set.
|
||||||
|
* Only records matching sqlFilter will be returned.
|
||||||
*
|
*
|
||||||
* @return IDs of deleted resources
|
* @return IDs of deleted resources
|
||||||
* @throws LocalStorageException when the content provider couldn't be queried
|
* @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 localID ID of the resource
|
||||||
* @param populate true: populates all data fields (for instance, contact or event details);
|
* @param populate true: populates all data fields (for instance, contact or event details);
|
||||||
* false: only remote file name and ETag are populated
|
* 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 localID remote file name of the resource
|
||||||
* @param populate true: populates all data fields (for instance, contact or event details);
|
* @param populate true: populates all data fields (for instance, contact or event details);
|
||||||
* false: only remote file name and ETag are populated
|
* false: only remote file name and ETag are populated
|
||||||
|
Loading…
Reference in New Issue
Block a user