diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/CallTable.kt b/app/src/main/java/org/thoughtcrime/securesms/database/CallTable.kt index b0cac3e72f..71aa071b85 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/CallTable.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/CallTable.kt @@ -104,13 +104,15 @@ class CallTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTabl ) """ + const val CALL_LOG_INDEX = "call_log_index" + val CREATE_INDEXES = arrayOf( "CREATE INDEX call_call_id_index ON $TABLE_NAME ($CALL_ID)", "CREATE INDEX call_message_id_index ON $TABLE_NAME ($MESSAGE_ID)", - "CREATE INDEX call_peer_index ON $TABLE_NAME ($PEER)" + "CREATE INDEX call_peer_index ON $TABLE_NAME ($PEER)", + "CREATE INDEX $CALL_LOG_INDEX ON $TABLE_NAME ($TIMESTAMP, $PEER, $EVENT, $TYPE, $DELETION_TIMESTAMP)" ) } - fun markAllCallEventsRead(timestamp: Long = Long.MAX_VALUE) { val updateCount = writableDatabase .update(TABLE_NAME) @@ -1269,9 +1271,28 @@ class CallTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTabl } val projection = if (isCount) { - "COUNT(*) OVER() as count," + "COUNT(*) OVER() as count" } else { - "p.$ID, p.$TIMESTAMP, $EVENT, $DIRECTION, $PEER, p.$TYPE, $CALL_ID, $MESSAGE_ID, $RINGER, $LOCAL_JOINED, $GROUP_CALL_ACTIVE, children, in_period, ${MessageTable.BODY}," + "p.$ID, p.$TIMESTAMP, $EVENT, $DIRECTION, $PEER, p.$TYPE, $CALL_ID, $MESSAGE_ID, $RINGER, $LOCAL_JOINED, $GROUP_CALL_ACTIVE, children, in_period, ${MessageTable.BODY}" + } + + val recipientSearchProjection = if (searchTerm.isNullOrEmpty()) { + "" + } else { + """ + ,LOWER( + COALESCE( + NULLIF(${GroupTable.TABLE_NAME}.${GroupTable.TITLE}, ''), + NULLIF(${RecipientTable.TABLE_NAME}.${RecipientTable.NICKNAME_JOINED_NAME}, ''), + NULLIF(${RecipientTable.TABLE_NAME}.${RecipientTable.NICKNAME_GIVEN_NAME}, ''), + NULLIF(${RecipientTable.TABLE_NAME}.${RecipientTable.SYSTEM_JOINED_NAME}, ''), + NULLIF(${RecipientTable.TABLE_NAME}.${RecipientTable.SYSTEM_GIVEN_NAME}, ''), + NULLIF(${RecipientTable.TABLE_NAME}.${RecipientTable.PROFILE_JOINED_NAME}, ''), + NULLIF(${RecipientTable.TABLE_NAME}.${RecipientTable.PROFILE_GIVEN_NAME}, ''), + NULLIF(${RecipientTable.TABLE_NAME}.${RecipientTable.USERNAME}, '') + ) + ) AS sort_name + """.trimIndent() } val join = if (isCount) { @@ -1305,18 +1326,7 @@ class CallTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTabl //language=sql val statement = """ SELECT $projection - LOWER( - COALESCE( - NULLIF(${GroupTable.TABLE_NAME}.${GroupTable.TITLE}, ''), - NULLIF(${RecipientTable.TABLE_NAME}.${RecipientTable.NICKNAME_JOINED_NAME}, ''), - NULLIF(${RecipientTable.TABLE_NAME}.${RecipientTable.NICKNAME_GIVEN_NAME}, ''), - NULLIF(${RecipientTable.TABLE_NAME}.${RecipientTable.SYSTEM_JOINED_NAME}, ''), - NULLIF(${RecipientTable.TABLE_NAME}.${RecipientTable.SYSTEM_GIVEN_NAME}, ''), - NULLIF(${RecipientTable.TABLE_NAME}.${RecipientTable.PROFILE_JOINED_NAME}, ''), - NULLIF(${RecipientTable.TABLE_NAME}.${RecipientTable.PROFILE_GIVEN_NAME}, ''), - NULLIF(${RecipientTable.TABLE_NAME}.${RecipientTable.USERNAME}, '') - ) - ) AS sort_name + $recipientSearchProjection FROM ( WITH cte AS ( SELECT @@ -1360,7 +1370,7 @@ class CallTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTabl AND ${filterClause.where} ) as in_period FROM - $TABLE_NAME c + $TABLE_NAME c INDEXED BY $CALL_LOG_INDEX WHERE ${filterClause.where} ORDER BY $TIMESTAMP DESC @@ -1427,7 +1437,7 @@ class CallTable(context: Context, databaseHelper: SignalDatabase) : DatabaseTabl } fun getCallsCount(searchTerm: String?, filter: CallLogFilter): Int { - return getCallsCursor(true, 0, 0, searchTerm, filter).use { + return getCallsCursor(true, 0, 1, searchTerm, filter).use { if (it.moveToFirst()) { it.getInt(0) } else { 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 e8fceb8aed..d7e30a8f25 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 @@ -111,6 +111,7 @@ import org.thoughtcrime.securesms.database.helpers.migration.V251_ArchiveTransfe import org.thoughtcrime.securesms.database.helpers.migration.V252_AttachmentOffloadRestoredAtColumn import org.thoughtcrime.securesms.database.helpers.migration.V253_CreateChatFolderTables import org.thoughtcrime.securesms.database.helpers.migration.V254_AddChatFolderConstraint +import org.thoughtcrime.securesms.database.helpers.migration.V255_AddCallTableLogIndex /** * Contains all of the database migrations for [SignalDatabase]. Broken into a separate file for cleanliness. @@ -224,10 +225,11 @@ object SignalDatabaseMigrations { 251 to V251_ArchiveTransferStateIndex, 252 to V252_AttachmentOffloadRestoredAtColumn, 253 to V253_CreateChatFolderTables, - 254 to V254_AddChatFolderConstraint + 254 to V254_AddChatFolderConstraint, + 255 to V255_AddCallTableLogIndex ) - const val DATABASE_VERSION = 254 + const val DATABASE_VERSION = 255 @JvmStatic fun migrate(context: Application, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/migration/V255_AddCallTableLogIndex.kt b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/migration/V255_AddCallTableLogIndex.kt new file mode 100644 index 0000000000..1bc29ec603 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/migration/V255_AddCallTableLogIndex.kt @@ -0,0 +1,19 @@ +/* + * Copyright 2024 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 + +/** + * Adds timestamp index to call table to speed up queries. + */ +@Suppress("ClassName") +object V255_AddCallTableLogIndex : SignalDatabaseMigration { + override fun migrate(context: Application, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) { + db.execSQL("CREATE INDEX IF NOT EXISTS call_log_index ON call (timestamp, peer, event, type, deletion_timestamp)") + } +}