From 23a3d78deb8efb1921ba3a3e9ceae30cffa57954 Mon Sep 17 00:00:00 2001 From: Clark Date: Mon, 17 Apr 2023 10:18:27 -0400 Subject: [PATCH] Merge v186 and v185 migrations. --- .../helpers/SignalDatabaseMigrations.kt | 11 +- ...ssageRecipientsAndEditMessageMigration.kt} | 24 ++- .../V186_AddEditMessageColumnsMigration.kt | 189 ------------------ 3 files changed, 23 insertions(+), 201 deletions(-) rename app/src/main/java/org/thoughtcrime/securesms/database/helpers/migration/{V185_MessageRecipientsMigration.kt => V185_MessageRecipientsAndEditMessageMigration.kt} (87%) delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/database/helpers/migration/V186_AddEditMessageColumnsMigration.kt 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 b5b29379f3e..2346e13df6e 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 @@ -40,8 +40,7 @@ import org.thoughtcrime.securesms.database.helpers.migration.V181_ThreadTableFor import org.thoughtcrime.securesms.database.helpers.migration.V182_CallTableMigration import org.thoughtcrime.securesms.database.helpers.migration.V183_CallLinkTableMigration import org.thoughtcrime.securesms.database.helpers.migration.V184_CallLinkReplaceIndexMigration -import org.thoughtcrime.securesms.database.helpers.migration.V185_MessageRecipientsMigration -import org.thoughtcrime.securesms.database.helpers.migration.V186_AddEditMessageColumnsMigration +import org.thoughtcrime.securesms.database.helpers.migration.V185_MessageRecipientsAndEditMessageMigration /** * Contains all of the database migrations for [SignalDatabase]. Broken into a separate file for cleanliness. @@ -50,7 +49,7 @@ object SignalDatabaseMigrations { val TAG: String = Log.tag(SignalDatabaseMigrations.javaClass) - const val DATABASE_VERSION = 186 + const val DATABASE_VERSION = 185 @JvmStatic fun migrate(context: Application, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) { @@ -199,11 +198,7 @@ object SignalDatabaseMigrations { } if (oldVersion < 185) { - V185_MessageRecipientsMigration.migrate(context, db, oldVersion, newVersion) - } - - if (oldVersion < 186) { - V186_AddEditMessageColumnsMigration.migrate(context, db, oldVersion, newVersion) + V185_MessageRecipientsAndEditMessageMigration.migrate(context, db, oldVersion, newVersion) } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/migration/V185_MessageRecipientsMigration.kt b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/migration/V185_MessageRecipientsAndEditMessageMigration.kt similarity index 87% rename from app/src/main/java/org/thoughtcrime/securesms/database/helpers/migration/V185_MessageRecipientsMigration.kt rename to app/src/main/java/org/thoughtcrime/securesms/database/helpers/migration/V185_MessageRecipientsAndEditMessageMigration.kt index 3d5941df316..f421ec202c8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/migration/V185_MessageRecipientsMigration.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/migration/V185_MessageRecipientsAndEditMessageMigration.kt @@ -18,12 +18,20 @@ import org.thoughtcrime.securesms.recipients.RecipientId import org.whispersystems.signalservice.api.push.ACI /** + * This is a combination of the edit message and message recipient migrations (would have been V185 and v186), but as they + * both require recreating the message table, they are merged into one. + * + * Original V185: * Our current column setup for knowing is the the sender/receiver of a message is both confusing and non-optimal from a performance perspective. * This moves to a world where instead of tracking a single recipient, we track two: a sender and receiver. + * + * Original V186: + * Changes needed for edit message. New foreign keys require recreating the table. + * */ -object V185_MessageRecipientsMigration : SignalDatabaseMigration { +object V185_MessageRecipientsAndEditMessageMigration : SignalDatabaseMigration { - private val TAG = Log.tag(V185_MessageRecipientsMigration::class.java) + private val TAG = Log.tag(V185_MessageRecipientsAndEditMessageMigration::class.java) private val outgoingClause = "(" + listOf(21, 23, 22, 24, 25, 26, 2, 11) .map { "type & ${0x1F} = $it" } @@ -106,7 +114,10 @@ object V185_MessageRecipientsMigration : SignalDatabaseMigration { parent_story_id INTEGER DEFAULT 0, export_state BLOB DEFAULT NULL, exported INTEGER DEFAULT 0, - scheduled_date INTEGER DEFAULT -1 + scheduled_date INTEGER DEFAULT -1, + latest_revision_id INTEGER DEFAULT NULL REFERENCES message (_id) ON DELETE CASCADE, + original_message_id INTEGER DEFAULT NULL REFERENCES message (_id) ON DELETE CASCADE, + revision_number INTEGER DEFAULT 0 ) """ ) @@ -164,7 +175,10 @@ object V185_MessageRecipientsMigration : SignalDatabaseMigration { parent_story_id, export_state, exported, - scheduled_date + scheduled_date, + NULL AS latest_revision_id, + NULL AS original_message_id, + 0 as revision_number FROM message """ ) @@ -194,6 +208,8 @@ object V185_MessageRecipientsMigration : SignalDatabaseMigration { dependentItems.forEach { item -> val sql = when (item.name) { + "mms_thread_story_parent_story_scheduled_date_index" -> "CREATE INDEX message_thread_story_parent_story_scheduled_date_latest_revision_id_index ON message (thread_id, date_received, story_type, parent_story_id, scheduled_date, latest_revision_id)" + "mms_quote_id_quote_author_scheduled_date_index" -> "CREATE INDEX message_quote_id_quote_author_scheduled_date_latest_revision_id_index ON message (quote_id, quote_author, scheduled_date, latest_revision_id)" "mms_date_sent_index" -> "CREATE INDEX message_date_sent_from_to_thread_index ON message (date_sent, from_recipient_id, to_recipient_id, thread_id)" else -> item.createStatement.replace(Regex.fromLiteral("CREATE INDEX mms_"), "CREATE INDEX message_") } diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/migration/V186_AddEditMessageColumnsMigration.kt b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/migration/V186_AddEditMessageColumnsMigration.kt deleted file mode 100644 index 16f84c5a0dc..00000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/migration/V186_AddEditMessageColumnsMigration.kt +++ /dev/null @@ -1,189 +0,0 @@ -package org.thoughtcrime.securesms.database.helpers.migration - -import android.app.Application -import net.zetetic.database.sqlcipher.SQLiteDatabase -import org.signal.core.util.Stopwatch -import org.signal.core.util.logging.Log -import org.signal.core.util.readToList -import org.signal.core.util.requireNonNullString - -/** - * Changes needed for edit message. New foreign keys require recreating the table. - */ -@Suppress("ClassName") -object V186_AddEditMessageColumnsMigration : SignalDatabaseMigration { - - private val TAG = Log.tag(V186_AddEditMessageColumnsMigration::class.java) - - override fun migrate(context: Application, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) { - val stopwatch = Stopwatch("migration") - - val dependentItems: List = getAllDependentItems(db, "message") - dependentItems.forEach { item -> - val sql = "DROP ${item.type} IF EXISTS ${item.name}" - Log.d(TAG, "Executing: $sql") - db.execSQL(sql) - } - - stopwatch.split("drop-dependents") - - db.execSQL( - """ - CREATE TABLE message_tmp ( - _id INTEGER PRIMARY KEY AUTOINCREMENT, - date_sent INTEGER NOT NULL, - date_received INTEGER NOT NULL, - date_server INTEGER DEFAULT -1, - thread_id INTEGER NOT NULL REFERENCES thread (_id) ON DELETE CASCADE, - from_recipient_id INTEGER NOT NULL REFERENCES recipient (_id) ON DELETE CASCADE, - from_device_id INTEGER, - to_recipient_id INTEGER NOT NULL REFERENCES recipient (_id) ON DELETE CASCADE, - type INTEGER NOT NULL, - body TEXT, - read INTEGER DEFAULT 0, - ct_l TEXT, - exp INTEGER, - m_type INTEGER, - m_size INTEGER, - st INTEGER, - tr_id TEXT, - subscription_id INTEGER DEFAULT -1, - receipt_timestamp INTEGER DEFAULT -1, - delivery_receipt_count INTEGER DEFAULT 0, - read_receipt_count INTEGER DEFAULT 0, - viewed_receipt_count INTEGER DEFAULT 0, - mismatched_identities TEXT DEFAULT NULL, - network_failures TEXT DEFAULT NULL, - expires_in INTEGER DEFAULT 0, - expire_started INTEGER DEFAULT 0, - notified INTEGER DEFAULT 0, - quote_id INTEGER DEFAULT 0, - quote_author INTEGER DEFAULT 0, - quote_body TEXT DEFAULT NULL, - quote_missing INTEGER DEFAULT 0, - quote_mentions BLOB DEFAULT NULL, - quote_type INTEGER DEFAULT 0, - shared_contacts TEXT DEFAULT NULL, - unidentified INTEGER DEFAULT 0, - link_previews TEXT DEFAULT NULL, - view_once INTEGER DEFAULT 0, - reactions_unread INTEGER DEFAULT 0, - reactions_last_seen INTEGER DEFAULT -1, - remote_deleted INTEGER DEFAULT 0, - mentions_self INTEGER DEFAULT 0, - notified_timestamp INTEGER DEFAULT 0, - server_guid TEXT DEFAULT NULL, - message_ranges BLOB DEFAULT NULL, - story_type INTEGER DEFAULT 0, - parent_story_id INTEGER DEFAULT 0, - export_state BLOB DEFAULT NULL, - exported INTEGER DEFAULT 0, - scheduled_date INTEGER DEFAULT -1, - latest_revision_id INTEGER DEFAULT NULL REFERENCES message (_id) ON DELETE CASCADE, - original_message_id INTEGER DEFAULT NULL REFERENCES message (_id) ON DELETE CASCADE, - revision_number INTEGER DEFAULT 0 - ) - """ - ) - stopwatch.split("create-table") - - db.execSQL( - """ - INSERT INTO message_tmp - SELECT - _id, - date_sent, - date_received, - date_server, - thread_id, - from_recipient_id, - from_device_id, - to_recipient_id, - type, - body, - read, - ct_l, - exp, - m_type, - m_size, - st, - tr_id, - subscription_id, - receipt_timestamp, - delivery_receipt_count, - read_receipt_count, - viewed_receipt_count, - mismatched_identities, - network_failures, - expires_in, - expire_started, - notified, - quote_id, - quote_author, - quote_body, - quote_missing, - quote_mentions, - quote_type, - shared_contacts, - unidentified, - link_previews, - view_once, - reactions_unread, - reactions_last_seen, - remote_deleted, - mentions_self, - notified_timestamp, - server_guid, - message_ranges, - story_type, - parent_story_id, - export_state, - exported, - scheduled_date, - NULL AS latest_revision_id, - NULL AS original_message_id, - 0 as revision_number - FROM message - """ - ) - stopwatch.split("copy-data") - - db.execSQL("DROP TABLE message") - stopwatch.split("drop-old") - - db.execSQL("ALTER TABLE message_tmp RENAME TO message") - stopwatch.split("rename-table") - - dependentItems.forEach { item -> - val sql = when (item.name) { - "message_thread_story_parent_story_scheduled_date_index" -> "CREATE INDEX message_thread_story_parent_story_scheduled_date_latest_revision_id_index ON message (thread_id, date_received, story_type, parent_story_id, scheduled_date, latest_revision_id)" - "message_quote_id_quote_author_scheduled_date_index" -> "CREATE INDEX message_quote_id_quote_author_scheduled_date_latest_revision_id_index ON message (quote_id, quote_author, scheduled_date, latest_revision_id)" - else -> item.createStatement - } - Log.d(TAG, "Executing: $sql") - db.execSQL(sql) - } - stopwatch.split("recreate-dependents") - - db.execSQL("PRAGMA foreign_key_check") - stopwatch.split("fk-check") - - stopwatch.stop(TAG) - } - - private fun getAllDependentItems(db: SQLiteDatabase, tableName: String): List { - return db.rawQuery("SELECT type, name, sql FROM sqlite_schema WHERE tbl_name='$tableName' AND type != 'table'").readToList { cursor -> - SqlItem( - type = cursor.requireNonNullString("type"), - name = cursor.requireNonNullString("name"), - createStatement = cursor.requireNonNullString("sql") - ) - } - } - - data class SqlItem( - val type: String, - val name: String, - val createStatement: String - ) -}