mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-02-24 03:35:58 +00:00
Remove old thread remappings.
This commit is contained in:
@@ -37,6 +37,7 @@ import org.thoughtcrime.securesms.database.MessageTable;
|
||||
import org.thoughtcrime.securesms.database.OneTimePreKeyTable;
|
||||
import org.thoughtcrime.securesms.database.PendingRetryReceiptTable;
|
||||
import org.thoughtcrime.securesms.database.ReactionTable;
|
||||
import org.thoughtcrime.securesms.database.RemappedRecordTables;
|
||||
import org.thoughtcrime.securesms.database.SearchTable;
|
||||
import org.thoughtcrime.securesms.database.SenderKeyTable;
|
||||
import org.thoughtcrime.securesms.database.SenderKeySharedTable;
|
||||
@@ -92,7 +93,9 @@ public class FullBackupExporter extends FullBackupBase {
|
||||
SenderKeyTable.TABLE_NAME,
|
||||
SenderKeySharedTable.TABLE_NAME,
|
||||
PendingRetryReceiptTable.TABLE_NAME,
|
||||
AvatarPickerDatabase.TABLE_NAME
|
||||
AvatarPickerDatabase.TABLE_NAME,
|
||||
RemappedRecordTables.Recipients.TABLE_NAME,
|
||||
RemappedRecordTables.Threads.TABLE_NAME
|
||||
);
|
||||
|
||||
public static BackupEvent export(@NonNull Context context,
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.thoughtcrime.securesms.database
|
||||
import android.content.Context
|
||||
import android.database.Cursor
|
||||
import androidx.core.content.contentValuesOf
|
||||
import org.signal.core.util.delete
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.signal.core.util.readToList
|
||||
import org.signal.core.util.requireLong
|
||||
@@ -30,7 +31,7 @@ class RemappedRecordTables internal constructor(context: Context?, databaseHelpe
|
||||
const val NEW_ID = "new_id"
|
||||
}
|
||||
|
||||
private object Recipients {
|
||||
object Recipients {
|
||||
const val TABLE_NAME = "remapped_recipients"
|
||||
const val CREATE_TABLE = """
|
||||
CREATE TABLE $TABLE_NAME (
|
||||
@@ -41,7 +42,7 @@ class RemappedRecordTables internal constructor(context: Context?, databaseHelpe
|
||||
"""
|
||||
}
|
||||
|
||||
private object Threads {
|
||||
object Threads {
|
||||
const val TABLE_NAME = "remapped_threads"
|
||||
const val CREATE_TABLE = """
|
||||
CREATE TABLE $TABLE_NAME (
|
||||
@@ -56,6 +57,9 @@ class RemappedRecordTables internal constructor(context: Context?, databaseHelpe
|
||||
val recipientMap: MutableMap<RecipientId, RecipientId> = HashMap()
|
||||
|
||||
readableDatabase.withinTransaction { db ->
|
||||
trimInvalidRecipientEntries(db)
|
||||
trimInvalidThreadEntries(db)
|
||||
|
||||
val mappings = getAllMappings(db, Recipients.TABLE_NAME)
|
||||
for (mapping in mappings) {
|
||||
val oldId = RecipientId.from(mapping.oldId)
|
||||
@@ -102,6 +106,32 @@ class RemappedRecordTables internal constructor(context: Context?, databaseHelpe
|
||||
.run()
|
||||
}
|
||||
|
||||
fun deleteThreadMapping(oldId: Long) {
|
||||
writableDatabase.delete(Threads.TABLE_NAME)
|
||||
.where("$OLD_ID = ?", oldId)
|
||||
.run()
|
||||
}
|
||||
|
||||
private fun trimInvalidRecipientEntries(db: SQLiteDatabase) {
|
||||
val count = db.delete(Recipients.TABLE_NAME)
|
||||
.where("$OLD_ID IN (SELECT $ID FROM ${RecipientTable.TABLE_NAME})")
|
||||
.run()
|
||||
|
||||
if (count > 0) {
|
||||
Log.w(TAG, "Trimmed $count invalid recipient entries.", true)
|
||||
}
|
||||
}
|
||||
|
||||
private fun trimInvalidThreadEntries(db: SQLiteDatabase) {
|
||||
val count = db.delete(Threads.TABLE_NAME)
|
||||
.where("$OLD_ID IN (SELECT $ID FROM ${ThreadTable.TABLE_NAME})")
|
||||
.run()
|
||||
|
||||
if (count > 0) {
|
||||
Log.w(TAG, "Trimmed $count invalid thread entries.", true)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getAllMappings(db: SQLiteDatabase, table: String): List<Mapping> {
|
||||
return db.select()
|
||||
.from(table)
|
||||
|
||||
@@ -49,27 +49,18 @@ class RemappedRecords {
|
||||
return Optional.ofNullable(threadMap.get(oldId));
|
||||
}
|
||||
|
||||
void deleteThread(long oldId) {
|
||||
ensureInTransaction();
|
||||
ensureThreadMapIsPopulated();
|
||||
threadMap.remove(oldId);
|
||||
SignalDatabase.remappedRecords().deleteThreadMapping(oldId);
|
||||
}
|
||||
|
||||
boolean areAnyRemapped(@NonNull Collection<RecipientId> recipientIds) {
|
||||
ensureRecipientMapIsPopulated();
|
||||
return recipientIds.stream().anyMatch(id -> recipientMap.containsKey(id));
|
||||
}
|
||||
|
||||
@NonNull Set<RecipientId> remap(@NonNull Collection<RecipientId> recipientIds) {
|
||||
ensureRecipientMapIsPopulated();
|
||||
|
||||
Set<RecipientId> remapped = new LinkedHashSet<>();
|
||||
|
||||
for (RecipientId original : recipientIds) {
|
||||
if (recipientMap.containsKey(original)) {
|
||||
remapped.add(recipientMap.get(original));
|
||||
} else {
|
||||
remapped.add(original);
|
||||
}
|
||||
}
|
||||
|
||||
return remapped;
|
||||
}
|
||||
|
||||
@NonNull String buildRemapDescription(@NonNull Collection<RecipientId> recipientIds) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
|
||||
@@ -1141,15 +1141,23 @@ class ThreadTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTa
|
||||
|
||||
fun getOrCreateValidThreadId(recipient: Recipient, candidateId: Long, distributionType: Int): Long {
|
||||
return if (candidateId != -1L) {
|
||||
val remapped = RemappedRecords.getInstance().getThread(candidateId)
|
||||
if (remapped.isPresent) {
|
||||
Log.i(TAG, "Using remapped threadId: " + candidateId + " -> " + remapped.get())
|
||||
remapped.get()
|
||||
if (areThreadIdAndRecipientAssociated(candidateId, recipient)) {
|
||||
candidateId
|
||||
} else {
|
||||
if (areThreadIdAndRecipientAssociated(candidateId, recipient)) {
|
||||
candidateId
|
||||
val remapped = RemappedRecords.getInstance().getThread(candidateId)
|
||||
if (remapped.isPresent) {
|
||||
if (areThreadIdAndRecipientAssociated(remapped.get(), recipient)) {
|
||||
Log.i(TAG, "Using remapped threadId: $candidateId -> ${remapped.get()}")
|
||||
remapped.get()
|
||||
} else {
|
||||
Log.i(TAG, "There's a remap for $candidateId -> ${remapped.get()}, but it's not associated with $recipient. Deleting old remap and throwing.")
|
||||
writableDatabase.withinTransaction {
|
||||
RemappedRecords.getInstance().deleteThread(candidateId)
|
||||
}
|
||||
throw IllegalArgumentException("Candidate threadId ($candidateId) is not associated with recipient ($recipient)")
|
||||
}
|
||||
} else {
|
||||
throw IllegalArgumentException()
|
||||
throw IllegalArgumentException("Candidate threadId ($candidateId) is not associated with recipient ($recipient)")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user