Fix potential constraint violation during thread merge.

This commit is contained in:
Greyson Parrelli
2025-03-21 11:20:25 -04:00
parent df4c6b59cd
commit 2b1f71d3b6

View File

@@ -4931,11 +4931,43 @@ open class MessageTable(context: Context?, databaseHelper: SignalDatabase) : Dat
}
override fun remapThread(fromId: Long, toId: Long) {
writableDatabase
.update(TABLE_NAME)
.values(THREAD_ID to toId)
.where("$THREAD_ID = ?", fromId)
.run()
try {
writableDatabase
.update(TABLE_NAME)
.values(THREAD_ID to toId)
.where("$THREAD_ID = ?", fromId)
.run()
} catch (e: SQLiteException) {
Log.w(TAG, "Failed to remap threadId, likely causes a unique constraint violation. Fixing.", e)
// Looks at all of the messages where the fromRecipient is either fromId or toId, then
// finds all messages where the threadId and dateSent match, but the fromRecipients do not.
// Deletes the more recent of the messages to prevent duplicates.
val deleteCount = writableDatabase
.delete(TABLE_NAME)
.where(
"""
$ID IN (
SELECT $ID FROM $TABLE_NAME AS m1
WHERE $THREAD_ID IN ($fromId, $toId)
AND EXISTS (
SELECT 1 FROM $TABLE_NAME AS m2
WHERE m1.$FROM_RECIPIENT_ID = m2.$FROM_RECIPIENT_ID
AND m1.$DATE_SENT = m2.$DATE_SENT
AN m1.$THREAD_ID != m2.$THREAD_ID
AND m1.$ID > m2.$ID
)
)
"""
)
.run()
Log.w(TAG, "Deleted $deleteCount duplicates. Retrying the remap.", e)
writableDatabase
.update(TABLE_NAME)
.values(THREAD_ID to toId)
.where("$THREAD_ID = ?", fromId)
.run()
}
}
/**