Fix dangling call ringers.

This commit is contained in:
Greyson Parrelli 2024-12-17 13:44:17 -05:00
parent a96c8867ae
commit 68d4eafedd
4 changed files with 74 additions and 9 deletions

View file

@ -527,11 +527,7 @@ class CallLinkTable(context: Context, databaseHelper: SignalDatabase) : Database
override fun remapRecipient(fromId: RecipientId, toId: RecipientId) {
val count = writableDatabase.update(TABLE_NAME)
.values(
contentValuesOf(
RECIPIENT_ID to toId.toLong()
)
)
.values(RECIPIENT_ID to toId.toLong())
.where("$RECIPIENT_ID = ?", fromId.toLong())
.run()

View file

@ -1489,13 +1489,18 @@ class CallTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTabl
}
override fun remapRecipient(fromId: RecipientId, toId: RecipientId) {
val count = writableDatabase
val peerCount = writableDatabase
.update(TABLE_NAME)
.values(PEER to toId.serialize())
.where("$PEER = ?", fromId)
.run()
Log.d(TAG, "Remapped $fromId to $toId. count: $count")
val ringerCount = writableDatabase.update(CallLinkTable.TABLE_NAME)
.values(RINGER to toId.toLong())
.where("$RINGER = ?", fromId.toLong())
.run()
Log.d(TAG, "Remapped $fromId to $toId. peerCount: $peerCount, ringerCount: $ringerCount")
}
/**

View file

@ -117,6 +117,7 @@ import org.thoughtcrime.securesms.database.helpers.migration.V257_CreateBackupMe
import org.thoughtcrime.securesms.database.helpers.migration.V258_FixGroupRevokedInviteeUpdate
import org.thoughtcrime.securesms.database.helpers.migration.V259_AdjustNotificationProfileMidnightEndTimes
import org.thoughtcrime.securesms.database.helpers.migration.V260_RemapQuoteAuthors
import org.thoughtcrime.securesms.database.helpers.migration.V261_RemapCallRingers
/**
* Contains all of the database migrations for [SignalDatabase]. Broken into a separate file for cleanliness.
@ -236,10 +237,11 @@ object SignalDatabaseMigrations {
257 to V257_CreateBackupMediaSyncTable,
258 to V258_FixGroupRevokedInviteeUpdate,
259 to V259_AdjustNotificationProfileMidnightEndTimes,
260 to V260_RemapQuoteAuthors
260 to V260_RemapQuoteAuthors,
261 to V261_RemapCallRingers
)
const val DATABASE_VERSION = 260
const val DATABASE_VERSION = 261
@JvmStatic
fun migrate(context: Application, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {

View file

@ -0,0 +1,62 @@
package org.thoughtcrime.securesms.database.helpers.migration
import android.app.Application
import net.zetetic.database.sqlcipher.SQLiteDatabase
import org.signal.core.util.logging.Log
import org.signal.core.util.readToSingleLong
import org.signal.core.util.select
/**
* Previously, we weren't properly remapping call ringers when recipients were remapped. This repairs those scenarios the best we can.
*/
@Suppress("ClassName")
object V261_RemapCallRingers : SignalDatabaseMigration {
private val TAG = Log.tag(V261_RemapCallRingers::class)
private const val TEMP_INDEX = "tmp_call_ringer"
override fun migrate(context: Application, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
// The following queries are really expensive without an index. So we create a temporary one.
db.execSQL("CREATE INDEX $TEMP_INDEX ON call (ringer)")
try {
doMigration(db)
} finally {
db.execSQL("DROP INDEX IF EXISTS $TEMP_INDEX")
}
}
private fun doMigration(db: SQLiteDatabase) {
// Even with an index, the updates can be a little expensive, so we try to figure out if we need them at all by using a quick check.
val invalidRingerCount = db
.select("count(*)")
.from("call INDEXED BY $TEMP_INDEX")
.where("ringer != 0 AND ringer NOT IN (SELECT _id FROM recipient)")
.run()
.readToSingleLong()
if (invalidRingerCount == 0L) {
Log.i(TAG, "No invalid call ringers, can skip migration.")
return
}
// Remap all call ringers using a remapped recipient
db.execSQL(
"""
UPDATE
call INDEXED BY $TEMP_INDEX
SET
ringer = (SELECT new_id FROM remapped_recipients WHERE old_id = call.ringer)
WHERE
ringer IN (SELECT old_id FROM remapped_recipients)
"""
)
// If there are any remaining call ringers that don't reference a real recipient, we have no choice but to delete the call
db.execSQL(
"""
DELETE FROM call INDEXED BY $TEMP_INDEX
WHERE ringer != 0 AND ringer NOT IN (SELECT _id FROM recipient)
"""
)
}
}