Overview
When a sync adapter calls delete that targets exception rows
(RECURID IS NOT NULL), SyncContentProvider silently excludes those rows by appending
AND RECURID IS NULL to the WHERE clause. The provider returns 0 and throws no error.
Related code:
|
CODE_ICALOBJECTS_DIR -> queryString += "$TABLE_NAME_ICALOBJECT WHERE $COLUMN_ID IN ($subquery) AND $COLUMN_RECURID IS NULL " // recur instances must never be deleted by SyncContentProvider in bulk |
Steps to reproduce
// Precondition: at least one exception row with the given UID exists in the database
// we explicitly want to delete all exceptions
val rowsDeleted = client.delete(
collectionUri,
"${JtxContract.JtxICalObject.UID}=? AND ${JtxContract.JtxICalObject.RECURID} IS NOT NULL",
arrayOf(uid)
)
// rowsDeleted == 0, exception rows NOT deleted, no exception thrown
Result
Actual: returns 0, exception rows remain, no error.
Expected: rows deleted, or an exception so the caller knows the operation was refused.
ContentProvider.delete() returning 0 normally means "nothing matched" — a sync adapter cannot
distinguish this from "rows were silently excluded".
Overview
When a sync adapter calls delete that targets exception rows
(
RECURID IS NOT NULL),SyncContentProvidersilently excludes those rows by appendingAND RECURID IS NULLto the WHERE clause. The provider returns 0 and throws no error.Related code:
jtxBoard/app/src/main/java/at/techbee/jtx/SyncContentProvider.kt
Line 197 in 65ff0e4
Steps to reproduce
Result
Actual: returns 0, exception rows remain, no error.
Expected: rows deleted, or an exception so the caller knows the operation was refused.
ContentProvider.delete()returning 0 normally means "nothing matched" — a sync adapter cannotdistinguish this from "rows were silently excluded".