Merge pull request #527 from greenart7c3/ccr-b10b912f-l5n5kv

Skip permission inserts whose application no longer exists
This commit is contained in:
greenart7c3
2026-10-05 07:13:45 -03:00
committed by GitHub
2 changed files with 22 additions and 2 deletions
@@ -188,12 +188,30 @@ interface ApplicationDao {
@Transaction @Transaction
suspend fun insertPermissions2Raw(permissions: List<ApplicationPermissionsEntity>): List<Long>? suspend fun insertPermissions2Raw(permissions: List<ApplicationPermissionsEntity>): List<Long>?
suspend fun insertPermissions2(permissions: List<ApplicationPermissionsEntity>): List<Long>? = insertPermissions2Raw(permissions) @Query("SELECT `key` FROM application WHERE `key` IN (:keys)")
suspend fun getExistingApplicationKeys(keys: List<String>): List<String>
/**
* Inserts permissions, skipping rows whose parent application no longer
* exists. `OnConflictStrategy.IGNORE` does not cover foreign-key failures,
* so a permission written after its application was deleted (e.g. a toggle
* racing an app delete/reset) would otherwise crash with
* `SQLITE_CONSTRAINT_FOREIGNKEY`.
*/
@Transaction
suspend fun insertPermissions2(permissions: List<ApplicationPermissionsEntity>): List<Long>? {
if (permissions.isEmpty()) return emptyList()
val existingKeys = getExistingApplicationKeys(permissions.map { it.pkKey }.distinct()).toSet()
val valid = permissions.filter { it.pkKey in existingKeys }
if (valid.isEmpty()) return emptyList()
return insertPermissions2Raw(valid)
}
@Insert(onConflict = OnConflictStrategy.REPLACE) @Insert(onConflict = OnConflictStrategy.REPLACE)
@Transaction @Transaction
suspend fun insertPermissionsRaw(permissions: List<ApplicationPermissionsEntity>): List<Long>? suspend fun insertPermissionsRaw(permissions: List<ApplicationPermissionsEntity>): List<Long>?
@Transaction
suspend fun insertPermissions(permissions: List<ApplicationPermissionsEntity>): List<Long>? { suspend fun insertPermissions(permissions: List<ApplicationPermissionsEntity>): List<Long>? {
permissions.forEach { permissions.forEach {
if (it.kind != null) { if (it.kind != null) {
@@ -212,7 +230,7 @@ interface ApplicationDao {
deletePermissions(it.pkKey, it.type) deletePermissions(it.pkKey, it.type)
} }
} }
return insertPermissions2Raw(permissions) return insertPermissions2(permissions)
} }
@Transaction @Transaction
@@ -308,6 +308,8 @@ class CachingApplicationDao(
override suspend fun insertPermissions2Raw(permissions: List<ApplicationPermissionsEntity>): List<Long>? = delegate.insertPermissions2Raw(permissions) override suspend fun insertPermissions2Raw(permissions: List<ApplicationPermissionsEntity>): List<Long>? = delegate.insertPermissions2Raw(permissions)
override suspend fun getExistingApplicationKeys(keys: List<String>): List<String> = delegate.getExistingApplicationKeys(keys)
override suspend fun insertPermissionsRaw(permissions: List<ApplicationPermissionsEntity>): List<Long>? = delegate.insertPermissionsRaw(permissions) override suspend fun insertPermissionsRaw(permissions: List<ApplicationPermissionsEntity>): List<Long>? = delegate.insertPermissionsRaw(permissions)
override suspend fun deleteRaw(entity: ApplicationEntity) = delegate.deleteRaw(entity) override suspend fun deleteRaw(entity: ApplicationEntity) = delegate.deleteRaw(entity)