Tighten migration and remove null peer events.

This commit is contained in:
Alex Hart
2023-05-18 17:39:36 -03:00
committed by Greyson Parrelli
parent 866408f673
commit 7a555d127f
4 changed files with 114 additions and 88 deletions

View File

@@ -65,7 +65,7 @@ class CallTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTabl
$ID INTEGER PRIMARY KEY,
$CALL_ID INTEGER NOT NULL,
$MESSAGE_ID INTEGER DEFAULT NULL REFERENCES ${MessageTable.TABLE_NAME} (${MessageTable.ID}) ON DELETE SET NULL,
$PEER INTEGER DEFAULT NULL REFERENCES ${RecipientTable.TABLE_NAME} (${RecipientTable.ID}) ON DELETE CASCADE,
$PEER INTEGER NOT NULL REFERENCES ${RecipientTable.TABLE_NAME} (${RecipientTable.ID}) ON DELETE CASCADE,
$TYPE INTEGER NOT NULL,
$DIRECTION INTEGER NOT NULL,
$EVENT INTEGER NOT NULL,
@@ -270,18 +270,18 @@ class CallTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTabl
fun insertDeletedGroupCallFromSyncEvent(
callId: Long,
recipientId: RecipientId?,
recipientId: RecipientId,
direction: Direction,
timestamp: Long
) {
val type = if (recipientId != null) Type.GROUP_CALL else Type.AD_HOC_CALL
val type = Type.GROUP_CALL
writableDatabase
.insertInto(TABLE_NAME)
.values(
CALL_ID to callId,
MESSAGE_ID to null,
PEER to recipientId?.toLong(),
PEER to recipientId.toLong(),
EVENT to Event.serialize(Event.DELETE),
TYPE to Type.serialize(type),
DIRECTION to Direction.serialize(direction),
@@ -318,16 +318,16 @@ class CallTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTabl
fun insertAcceptedGroupCall(
callId: Long,
recipientId: RecipientId?,
recipientId: RecipientId,
direction: Direction,
timestamp: Long
) {
val type = if (recipientId != null) Type.GROUP_CALL else Type.AD_HOC_CALL
val type = Type.GROUP_CALL
val event = if (direction == Direction.OUTGOING) Event.OUTGOING_RING else Event.JOINED
val ringer = if (direction == Direction.OUTGOING) Recipient.self().id.toLong() else null
writableDatabase.withinTransaction { db ->
val messageId: MessageId? = if (recipientId != null) {
val messageId: MessageId? = if (type == Type.GROUP_CALL) {
SignalDatabase.messages.insertGroupCall(
groupRecipientId = recipientId,
sender = Recipient.self().id,
@@ -345,7 +345,7 @@ class CallTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTabl
.values(
CALL_ID to callId,
MESSAGE_ID to messageId?.id,
PEER to recipientId?.toLong(),
PEER to recipientId.toLong(),
EVENT to Event.serialize(event),
TYPE to Type.serialize(type),
DIRECTION to Direction.serialize(direction),

View File

@@ -51,6 +51,7 @@ import org.thoughtcrime.securesms.database.helpers.migration.V192_CallLinkTableN
import org.thoughtcrime.securesms.database.helpers.migration.V193_BackCallLinksWithRecipient
import org.thoughtcrime.securesms.database.helpers.migration.V194_KyberPreKeyMigration
import org.thoughtcrime.securesms.database.helpers.migration.V195_GroupMemberForeignKeyMigration
import org.thoughtcrime.securesms.database.helpers.migration.V196_BackCallLinksWithRecipientV2
/**
* Contains all of the database migrations for [SignalDatabase]. Broken into a separate file for cleanliness.
@@ -59,7 +60,7 @@ object SignalDatabaseMigrations {
val TAG: String = Log.tag(SignalDatabaseMigrations.javaClass)
const val DATABASE_VERSION = 195
const val DATABASE_VERSION = 196
@JvmStatic
fun migrate(context: Application, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
@@ -250,6 +251,10 @@ object SignalDatabaseMigrations {
if (oldVersion < 195) {
V195_GroupMemberForeignKeyMigration.migrate(context, db, oldVersion, newVersion)
}
if (oldVersion < 196) {
V196_BackCallLinksWithRecipientV2.migrate(context, db, oldVersion, newVersion)
}
}
@JvmStatic

View File

@@ -7,88 +7,11 @@ package org.thoughtcrime.securesms.database.helpers.migration
import android.app.Application
import net.zetetic.database.sqlcipher.SQLiteDatabase
import org.signal.core.util.SqlUtil
import org.signal.core.util.logging.Log
/**
* Back CallLinks with a Recipient to ease integration and ensure we can support
* different features which would require that relation in the future.
* Due to a bug, this has been replaced by [V196_BackCallLinksWithRecipientV2]
*/
object V193_BackCallLinksWithRecipient : SignalDatabaseMigration {
private val TAG = Log.tag(V193_BackCallLinksWithRecipient::class.java)
override fun migrate(context: Application, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
// add new column to recipient table to store the room id
db.execSQL("ALTER TABLE recipient ADD COLUMN call_link_room_id TEXT DEFAULT NULL")
// recreate the call link table with the new recipient id reference.
db.execSQL("DROP TABLE call_link")
db.execSQL(
"""
CREATE TABLE call_link (
_id INTEGER PRIMARY KEY,
root_key BLOB,
room_id TEXT NOT NULL UNIQUE,
admin_key BLOB,
name TEXT NOT NULL,
restrictions INTEGER NOT NULL,
revoked INTEGER NOT NULL,
expiration INTEGER NOT NULL,
avatar_color TEXT NOT NULL,
recipient_id INTEGER UNIQUE REFERENCES recipient (_id) ON DELETE CASCADE
)
""".trimIndent()
)
// recreate the call table dropping the call_link column
db.execSQL(
"""
CREATE TABLE call_tmp (
_id INTEGER PRIMARY KEY,
call_id INTEGER NOT NULL,
message_id INTEGER DEFAULT NULL REFERENCES message (_id) ON DELETE SET NULL,
peer INTEGER DEFAULT NULL REFERENCES recipient (_id) ON DELETE CASCADE,
type INTEGER NOT NULL,
direction INTEGER NOT NULL,
event INTEGER NOT NULL,
timestamp INTEGER NOT NULL,
ringer INTEGER DEFAULT NULL,
deletion_timestamp INTEGER DEFAULT 0,
UNIQUE (call_id, peer) ON CONFLICT FAIL
)
""".trimIndent()
)
db.execSQL(
"""
INSERT INTO call_tmp
SELECT
_id,
call_id,
message_id,
peer,
type,
direction,
event,
timestamp,
ringer,
deletion_timestamp
FROM call
""".trimIndent()
)
db.execSQL("DROP TABLE call")
db.execSQL("ALTER TABLE call_tmp RENAME TO call")
db.execSQL("CREATE INDEX IF NOT EXISTS call_call_id_index ON call (call_id)")
db.execSQL("CREATE INDEX IF NOT EXISTS call_message_id_index ON call (message_id)")
db.execSQL("CREATE INDEX IF NOT EXISTS call_peer_index ON call (peer)")
val foreignKeyViolations: List<SqlUtil.ForeignKeyViolation> = SqlUtil.getForeignKeyViolations(db, "call")
if (foreignKeyViolations.isNotEmpty()) {
Log.w(TAG, "Foreign key violations!\n${foreignKeyViolations.joinToString(separator = "\n")}")
throw IllegalStateException("Foreign key violations!")
}
}
override fun migrate(context: Application, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) = Unit
}

View File

@@ -0,0 +1,98 @@
/*
* Copyright 2023 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.thoughtcrime.securesms.database.helpers.migration
import android.app.Application
import net.zetetic.database.sqlcipher.SQLiteDatabase
import org.signal.core.util.SqlUtil
import org.signal.core.util.logging.Log
/**
* Cleans up the call events table and restricts peer to non-null.
*/
object V196_BackCallLinksWithRecipientV2 : SignalDatabaseMigration {
private val TAG = Log.tag(V196_BackCallLinksWithRecipientV2::class.java)
override fun migrate(context: Application, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
if (!SqlUtil.columnExists(db, "recipient", "call_link_room_id")) {
// add new column to recipient table to store the room id
db.execSQL("ALTER TABLE recipient ADD COLUMN call_link_room_id TEXT DEFAULT NULL")
// recreate the call link table with the new recipient id reference.
db.execSQL("DROP TABLE call_link")
db.execSQL(
"""
CREATE TABLE call_link (
_id INTEGER PRIMARY KEY,
root_key BLOB,
room_id TEXT NOT NULL UNIQUE,
admin_key BLOB,
name TEXT NOT NULL,
restrictions INTEGER NOT NULL,
revoked INTEGER NOT NULL,
expiration INTEGER NOT NULL,
avatar_color TEXT NOT NULL,
recipient_id INTEGER UNIQUE REFERENCES recipient (_id) ON DELETE CASCADE
)
""".trimIndent()
)
}
// drop all call events with a null peer.
db.execSQL("DELETE FROM call WHERE peer IS NULL")
// recreate the call table dropping the call_link column
db.execSQL(
"""
CREATE TABLE call_tmp (
_id INTEGER PRIMARY KEY,
call_id INTEGER NOT NULL,
message_id INTEGER DEFAULT NULL REFERENCES message (_id) ON DELETE SET NULL,
peer INTEGER NOT NULL REFERENCES recipient (_id) ON DELETE CASCADE,
type INTEGER NOT NULL,
direction INTEGER NOT NULL,
event INTEGER NOT NULL,
timestamp INTEGER NOT NULL,
ringer INTEGER DEFAULT NULL,
deletion_timestamp INTEGER DEFAULT 0,
UNIQUE (call_id, peer) ON CONFLICT FAIL
)
""".trimIndent()
)
db.execSQL(
"""
INSERT INTO call_tmp
SELECT
_id,
call_id,
message_id,
peer,
type,
direction,
event,
timestamp,
ringer,
deletion_timestamp
FROM call
""".trimIndent()
)
db.execSQL("DROP TABLE call")
db.execSQL("ALTER TABLE call_tmp RENAME TO call")
db.execSQL("CREATE INDEX IF NOT EXISTS call_call_id_index ON call (call_id)")
db.execSQL("CREATE INDEX IF NOT EXISTS call_message_id_index ON call (message_id)")
db.execSQL("CREATE INDEX IF NOT EXISTS call_peer_index ON call (peer)")
val foreignKeyViolations: List<SqlUtil.ForeignKeyViolation> = SqlUtil.getForeignKeyViolations(db, "call")
if (foreignKeyViolations.isNotEmpty()) {
Log.w(TAG, "Foreign key violations!\n${foreignKeyViolations.joinToString(separator = "\n")}")
throw IllegalStateException("Foreign key violations!")
}
}
}