Merge v186 and v185 migrations.

This commit is contained in:
Clark
2023-04-17 10:18:27 -04:00
committed by Cody Henthorne
parent 47ebcc0f05
commit 23a3d78deb
3 changed files with 23 additions and 201 deletions

View File

@@ -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.V182_CallTableMigration
import org.thoughtcrime.securesms.database.helpers.migration.V183_CallLinkTableMigration 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.V184_CallLinkReplaceIndexMigration
import org.thoughtcrime.securesms.database.helpers.migration.V185_MessageRecipientsMigration import org.thoughtcrime.securesms.database.helpers.migration.V185_MessageRecipientsAndEditMessageMigration
import org.thoughtcrime.securesms.database.helpers.migration.V186_AddEditMessageColumnsMigration
/** /**
* Contains all of the database migrations for [SignalDatabase]. Broken into a separate file for cleanliness. * 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) val TAG: String = Log.tag(SignalDatabaseMigrations.javaClass)
const val DATABASE_VERSION = 186 const val DATABASE_VERSION = 185
@JvmStatic @JvmStatic
fun migrate(context: Application, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) { fun migrate(context: Application, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
@@ -199,11 +198,7 @@ object SignalDatabaseMigrations {
} }
if (oldVersion < 185) { if (oldVersion < 185) {
V185_MessageRecipientsMigration.migrate(context, db, oldVersion, newVersion) V185_MessageRecipientsAndEditMessageMigration.migrate(context, db, oldVersion, newVersion)
}
if (oldVersion < 186) {
V186_AddEditMessageColumnsMigration.migrate(context, db, oldVersion, newVersion)
} }
} }

View File

@@ -18,12 +18,20 @@ import org.thoughtcrime.securesms.recipients.RecipientId
import org.whispersystems.signalservice.api.push.ACI 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. * 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. * 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) private val outgoingClause = "(" + listOf(21, 23, 22, 24, 25, 26, 2, 11)
.map { "type & ${0x1F} = $it" } .map { "type & ${0x1F} = $it" }
@@ -106,7 +114,10 @@ object V185_MessageRecipientsMigration : SignalDatabaseMigration {
parent_story_id INTEGER DEFAULT 0, parent_story_id INTEGER DEFAULT 0,
export_state BLOB DEFAULT NULL, export_state BLOB DEFAULT NULL,
exported INTEGER DEFAULT 0, 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, parent_story_id,
export_state, export_state,
exported, exported,
scheduled_date scheduled_date,
NULL AS latest_revision_id,
NULL AS original_message_id,
0 as revision_number
FROM message FROM message
""" """
) )
@@ -194,6 +208,8 @@ object V185_MessageRecipientsMigration : SignalDatabaseMigration {
dependentItems.forEach { item -> dependentItems.forEach { item ->
val sql = when (item.name) { 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)" "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_") else -> item.createStatement.replace(Regex.fromLiteral("CREATE INDEX mms_"), "CREATE INDEX message_")
} }

View File

@@ -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<SqlItem> = 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<SqlItem> {
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
)
}