Fix invalid constraint handling sql when calling update.

This commit is contained in:
Cody Henthorne
2025-04-29 12:22:40 -04:00
parent 39756fd0d4
commit 2421bbdabb
4 changed files with 39 additions and 25 deletions

View File

@@ -336,7 +336,7 @@ class ChatFolderTables(context: Context?, databaseHelper: SignalDatabase?) : Dat
ChatFolderTable.DELETED_TIMESTAMP_MS to chatFolder.deletedTimestampMs
)
.where("${ChatFolderTable.ID} = ?", chatFolder.id)
.run(SQLiteDatabase.CONFLICT_IGNORE)
.run()
db
.delete(ChatFolderMembershipTable.TABLE_NAME)
@@ -394,7 +394,7 @@ class ChatFolderTables(context: Context?, databaseHelper: SignalDatabase?) : Dat
db.update(ChatFolderTable.TABLE_NAME)
.values(ChatFolderTable.POSITION to folder.position)
.where("${ChatFolderTable.ID} = ?", folder.id)
.run(SQLiteDatabase.CONFLICT_IGNORE)
.run()
}
AppDependencies.databaseObserver.notifyChatFolderObservers()
}
@@ -533,7 +533,7 @@ class ChatFolderTables(context: Context?, databaseHelper: SignalDatabase?) : Dat
ChatFolderTable.STORAGE_SERVICE_PROTO to storageServiceProto
)
.where("${ChatFolderTable.FOLDER_TYPE} = ?", ChatFolderRecord.FolderType.ALL.value)
.run(SQLiteDatabase.CONFLICT_IGNORE)
.run()
}
} else {
createFolder(remoteChatFolderRecordToLocal(record))
@@ -636,7 +636,7 @@ class ChatFolderTables(context: Context?, databaseHelper: SignalDatabase?) : Dat
db.update(ChatFolderTable.TABLE_NAME)
.values(ChatFolderTable.POSITION to index)
.where("${ChatFolderTable.ID} = ?", id)
.run(SQLiteDatabase.CONFLICT_IGNORE)
.run()
}
}
}

View File

@@ -7,6 +7,7 @@ import androidx.core.content.contentValuesOf
import org.signal.core.util.Base64
import org.signal.core.util.CursorUtil
import org.signal.core.util.SqlUtil
import org.signal.core.util.SqlUtil.buildArgs
import org.signal.core.util.delete
import org.signal.core.util.logging.Log
import org.signal.core.util.readToList
@@ -526,13 +527,32 @@ class DistributionListTables constructor(context: Context?, databaseHelper: Sign
}
override fun remapRecipient(fromId: RecipientId, toId: RecipientId) {
val count = writableDatabase
.update(MembershipTable.TABLE_NAME)
.values(MembershipTable.RECIPIENT_ID to toId.serialize())
.where("${MembershipTable.RECIPIENT_ID} = ?", fromId)
.run(SQLiteDatabase.CONFLICT_REPLACE)
// Remap all recipients that would not result in conflicts
writableDatabase.execSQL(
"""
UPDATE ${MembershipTable.TABLE_NAME} AS parent
SET ${MembershipTable.RECIPIENT_ID} = ?
WHERE
${MembershipTable.RECIPIENT_ID} = ?
AND NOT EXISTS (
SELECT 1
FROM ${MembershipTable.TABLE_NAME} child
WHERE
child.${MembershipTable.RECIPIENT_ID} = ?
AND parent.${MembershipTable.LIST_ID} = child.${MembershipTable.LIST_ID}
AND parent.${MembershipTable.PRIVACY_MODE} = child.${MembershipTable.PRIVACY_MODE}
)
""",
buildArgs(toId, fromId, toId)
)
Log.d(TAG, "Remapped $fromId to $toId. count: $count")
// Delete the remaining fromId's (the only remaining ones should be those in lists where the toId is already present)
writableDatabase
.delete(MembershipTable.TABLE_NAME)
.where("${MembershipTable.RECIPIENT_ID} = ?", fromId)
.run()
Log.d(TAG, "Remapped $fromId to $toId.")
}
fun deleteList(distributionListId: DistributionListId, deletionTimestamp: Long = System.currentTimeMillis()) {

View File

@@ -1129,10 +1129,14 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
writableDatabase.withinTransaction {
for ((originalE164, updatedE164) in mapping) {
writableDatabase.update(TABLE_NAME)
.values(E164 to updatedE164)
.where("$E164 = ?", originalE164)
.run(SQLiteDatabase.CONFLICT_IGNORE)
try {
writableDatabase.update(TABLE_NAME)
.values(E164 to updatedE164)
.where("$E164 = ?", originalE164)
.run()
} catch (_: SQLiteConstraintException) {
Log.w(TAG, "Unable to update e164 due to constraint, ignoring")
}
}
}
}