From d8eac87219e766f56c226eaa1320e236f4d4258b Mon Sep 17 00:00:00 2001 From: Greyson Parrelli Date: Thu, 9 Feb 2023 13:41:32 -0500 Subject: [PATCH] Cleanup dangling MSL rows. --- .../securesms/backup/FullBackupImporter.java | 28 ++++++++++++++++++- .../helpers/SignalDatabaseMigrations.kt | 7 ++++- ..._CleanupDanglingMessageSendLogMigration.kt | 14 ++++++++++ 3 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 app/src/main/java/org/thoughtcrime/securesms/database/helpers/migration/V179_CleanupDanglingMessageSendLogMigration.kt diff --git a/app/src/main/java/org/thoughtcrime/securesms/backup/FullBackupImporter.java b/app/src/main/java/org/thoughtcrime/securesms/backup/FullBackupImporter.java index 0f6e7e3ba..b2a27bc09 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/backup/FullBackupImporter.java +++ b/app/src/main/java/org/thoughtcrime/securesms/backup/FullBackupImporter.java @@ -11,6 +11,7 @@ import android.util.Pair; import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; +import net.zetetic.database.sqlcipher.SQLiteConstraintException; import net.zetetic.database.sqlcipher.SQLiteDatabase; import org.greenrobot.eventbus.EventBus; @@ -91,7 +92,7 @@ public class FullBackupImporter extends FullBackupBase { count++; if (frame.hasVersion()) processVersion(db, frame.getVersion()); - else if (frame.hasStatement()) processStatement(db, frame.getStatement()); + else if (frame.hasStatement()) tryProcessStatement(db, frame.getStatement()); else if (frame.hasPreference()) processPreference(context, frame.getPreference()); else if (frame.hasAttachment()) processAttachment(context, attachmentSecret, db, frame.getAttachment(), inputStream); else if (frame.hasSticker()) processSticker(context, attachmentSecret, db, frame.getSticker(), inputStream); @@ -126,6 +127,31 @@ public class FullBackupImporter extends FullBackupBase { db.setVersion(version.getVersion()); } + private static void tryProcessStatement(@NonNull SQLiteDatabase db, SqlStatement statement) { + try { + processStatement(db, statement); + } catch (SQLiteConstraintException e) { + String tableName = "?"; + String statementString = statement.getStatement(); + + if (statementString.startsWith("INSERT INTO ")) { + int nameStart = "INSERT INTO ".length(); + int nameEnd = statementString.indexOf(" ", "INSERT INTO ".length()); + + if (nameStart < statementString.length() && nameEnd > nameStart) { + tableName = statementString.substring(nameStart, nameEnd); + } + } + + if (tableName.startsWith("msl_")) { + Log.w(TAG, "Constraint failed when inserting into " + tableName + ". Ignoring."); + } else { + Log.w(TAG, "Constraint failed when inserting into " + tableName + ". Throwing!"); + throw e; + } + } + } + private static void processStatement(@NonNull SQLiteDatabase db, SqlStatement statement) { boolean isForMmsFtsSecretTable = statement.getStatement().contains(SearchTable.FTS_TABLE_NAME + "_"); boolean isForEmojiSecretTable = statement.getStatement().contains(EmojiSearchTable.TABLE_NAME + "_"); diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SignalDatabaseMigrations.kt b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SignalDatabaseMigrations.kt index 10287a7fb..e47153f0e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SignalDatabaseMigrations.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SignalDatabaseMigrations.kt @@ -34,6 +34,7 @@ import org.thoughtcrime.securesms.database.helpers.migration.V175_FixFullTextSea import org.thoughtcrime.securesms.database.helpers.migration.V176_AddScheduledDateToQuoteIndex import org.thoughtcrime.securesms.database.helpers.migration.V177_MessageSendLogTableCleanupMigration import org.thoughtcrime.securesms.database.helpers.migration.V178_ReportingTokenColumnMigration +import org.thoughtcrime.securesms.database.helpers.migration.V179_CleanupDanglingMessageSendLogMigration /** * Contains all of the database migrations for [SignalDatabase]. Broken into a separate file for cleanliness. @@ -42,7 +43,7 @@ object SignalDatabaseMigrations { val TAG: String = Log.tag(SignalDatabaseMigrations.javaClass) - const val DATABASE_VERSION = 178 + const val DATABASE_VERSION = 179 @JvmStatic fun migrate(context: Application, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) { @@ -165,6 +166,10 @@ object SignalDatabaseMigrations { if (oldVersion < 178) { V178_ReportingTokenColumnMigration.migrate(context, db, oldVersion, newVersion) } + + if (oldVersion < 179) { + V179_CleanupDanglingMessageSendLogMigration.migrate(context, db, oldVersion, newVersion) + } } @JvmStatic diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/migration/V179_CleanupDanglingMessageSendLogMigration.kt b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/migration/V179_CleanupDanglingMessageSendLogMigration.kt new file mode 100644 index 000000000..6ff95407c --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/migration/V179_CleanupDanglingMessageSendLogMigration.kt @@ -0,0 +1,14 @@ +package org.thoughtcrime.securesms.database.helpers.migration + +import android.app.Application +import net.zetetic.database.sqlcipher.SQLiteDatabase + +/** + * This cleans up some MSL entries that we left behind during a bad past migration. + */ +object V179_CleanupDanglingMessageSendLogMigration : SignalDatabaseMigration { + override fun migrate(context: Application, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) { + db.execSQL("DELETE FROM msl_message WHERE payload_id NOT IN (SELECT _id FROM msl_payload)") + db.execSQL("DELETE FROM msl_recipient WHERE payload_id NOT IN (SELECT _id FROM msl_payload)") + } +}