Use separate tables for mms and sms in LokiMessageDatabase

This commit is contained in:
andrew
2023-10-11 01:51:09 +10:30
parent c86b229200
commit 77f951cadf
10 changed files with 68 additions and 67 deletions

View File

@@ -186,7 +186,7 @@ class DatabaseAttachmentProvider(context: Context, helper: SQLCipherOpenHelper)
else DatabaseComponent.get(context).mmsDatabase()
messagingDatabase.deleteMessage(messageID)
DatabaseComponent.get(context).lokiMessageDatabase().deleteMessage(messageID, isSms)
DatabaseComponent.get(context).lokiMessageDatabase().deleteMessageServerHash(messageID)
DatabaseComponent.get(context).lokiMessageDatabase().deleteMessageServerHash(messageID, mms = !isSms)
}
override fun deleteMessages(messageIDs: List<Long>, threadId: Long, isSms: Boolean) {
@@ -195,7 +195,7 @@ class DatabaseAttachmentProvider(context: Context, helper: SQLCipherOpenHelper)
messagingDatabase.deleteMessages(messageIDs.toLongArray(), threadId)
DatabaseComponent.get(context).lokiMessageDatabase().deleteMessages(messageIDs)
DatabaseComponent.get(context).lokiMessageDatabase().deleteMessageServerHashes(messageIDs)
DatabaseComponent.get(context).lokiMessageDatabase().deleteMessageServerHashes(messageIDs, mms = !isSms)
}
override fun updateMessageAsDeleted(timestamp: Long, author: String): Long? {
@@ -212,15 +212,12 @@ class DatabaseAttachmentProvider(context: Context, helper: SQLCipherOpenHelper)
return message.id
}
override fun getServerHashForMessage(messageID: Long): String? {
val messageDB = DatabaseComponent.get(context).lokiMessageDatabase()
return messageDB.getMessageServerHash(messageID)
}
override fun getServerHashForMessage(messageID: Long, mms: Boolean): String? =
DatabaseComponent.get(context).lokiMessageDatabase().getMessageServerHash(messageID, mms)
override fun getDatabaseAttachment(attachmentId: Long): DatabaseAttachment? {
val attachmentDatabase = DatabaseComponent.get(context).attachmentDatabase()
return attachmentDatabase.getAttachment(AttachmentId(attachmentId, 0))
}
override fun getDatabaseAttachment(attachmentId: Long): DatabaseAttachment? =
DatabaseComponent.get(context).attachmentDatabase()
.getAttachment(AttachmentId(attachmentId, 0))
private fun scaleAndStripExif(attachmentDatabase: AttachmentDatabase, constraints: MediaConstraints, attachment: Attachment): Attachment? {
return try {

View File

@@ -1813,7 +1813,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
override fun deleteMessages(messages: Set<MessageRecord>) {
val recipient = viewModel.recipient ?: return
val allSentByCurrentUser = messages.all { it.isOutgoing }
val allHasHash = messages.all { lokiMessageDb.getMessageServerHash(it.id) != null }
val allHasHash = messages.all { lokiMessageDb.getMessageServerHash(it.id, it.isMms) != null }
if (recipient.isOpenGroupRecipient) {
val messageCount = 1

View File

@@ -207,52 +207,52 @@ class LokiMessageDatabase(context: Context, helper: SQLCipherOpenHelper) : Datab
messages.add(cursor.getLong(messageID) to cursor.getLong(serverID))
}
}
var deletedCount = 0L
database.beginTransaction()
messages.forEach { (messageId, serverId) ->
deletedCount += database.delete(messageIDTable, "$messageID = ? AND $serverID = ?", arrayOf(messageId.toString(), serverId.toString()))
database.delete(messageIDTable, "$messageID = ? AND $serverID = ?", arrayOf(messageId.toString(), serverId.toString()))
}
val mappingDeleted = database.delete(messageThreadMappingTable, "$threadID = ?", arrayOf(threadId.toString()))
database.delete(messageThreadMappingTable, "$threadID = ?", arrayOf(threadId.toString()))
database.setTransactionSuccessful()
} finally {
database.endTransaction()
}
}
fun getMessageServerHash(messageID: Long): String? {
val database = databaseHelper.readableDatabase
return database.get(messageHashTable, "${Companion.messageID} = ?", arrayOf(messageID.toString())) { cursor ->
fun getMessageServerHash(messageID: Long, mms: Boolean): String? = getMessageTables(mms).firstNotNullOfOrNull {
databaseHelper.readableDatabase.get(it, "${Companion.messageID} = ?", arrayOf(messageID.toString())) { cursor ->
cursor.getString(serverHash)
}
}
fun setMessageServerHash(messageID: Long, serverHash: String) {
val database = databaseHelper.writableDatabase
val contentValues = ContentValues(2)
contentValues.put(Companion.messageID, messageID)
contentValues.put(Companion.serverHash, serverHash)
database.insertOrUpdate(messageHashTable, contentValues, "${Companion.messageID} = ?", arrayOf(messageID.toString()))
fun setMessageServerHash(messageID: Long, mms: Boolean, serverHash: String) {
val contentValues = ContentValues(2).apply {
put(Companion.messageID, messageID)
put(Companion.serverHash, serverHash)
}
databaseHelper.writableDatabase.apply {
insertOrUpdate(getMessageTable(mms), contentValues, "${Companion.messageID} = ?", arrayOf(messageID.toString()))
}
}
fun deleteMessageServerHash(messageID: Long) {
val database = databaseHelper.writableDatabase
database.delete(messageHashTable, "${Companion.messageID} = ?", arrayOf(messageID.toString()))
fun deleteMessageServerHash(messageID: Long, mms: Boolean) {
getMessageTables(mms).firstOrNull {
databaseHelper.writableDatabase.delete(it, "${Companion.messageID} = ?", arrayOf(messageID.toString())) > 0
}
}
fun deleteMessageServerHashes(messageIDs: List<Long>) {
val database = databaseHelper.writableDatabase
database.delete(
messageHashTable,
"${Companion.messageID} IN (${messageIDs.map { "?" }.joinToString(",")})",
fun deleteMessageServerHashes(messageIDs: List<Long>, mms: Boolean) {
databaseHelper.writableDatabase.delete(
getMessageTable(mms),
"${Companion.messageID} IN (${messageIDs.joinToString(",") { "?" }})",
messageIDs.map { "$it" }.toTypedArray()
)
}
fun migrateThreadId(legacyThreadId: Long, newThreadId: Long) {
val database = databaseHelper.writableDatabase
val contentValues = ContentValues(1)
contentValues.put(threadID, newThreadId)
database.update(messageThreadMappingTable, contentValues, "$threadID = ?", arrayOf(legacyThreadId.toString()))
}
private fun getMessageTables(mms: Boolean) = sequenceOf(
getMessageTable(mms),
messageHashTable
)
private fun getMessageTable(mms: Boolean) = if (mms) mmsHashTable else smsHashTable
}

View File

@@ -376,7 +376,7 @@ open class Storage(
}
message.serverHash?.let { serverHash ->
messageID?.let { id ->
DatabaseComponent.get(context).lokiMessageDatabase().setMessageServerHash(id, serverHash)
DatabaseComponent.get(context).lokiMessageDatabase().setMessageServerHash(id, message.isMediaMessage(), serverHash)
}
}
if (expiryMode is ExpiryMode.AfterSend) {
@@ -756,10 +756,10 @@ open class Storage(
SessionMetaProtocol.removeTimestamps(timestamps)
}
override fun getMessageIdInDatabase(timestamp: Long, author: String): Long? {
override fun getMessageIdInDatabase(timestamp: Long, author: String): Pair<Long, Boolean>? {
val database = DatabaseComponent.get(context).mmsSmsDatabase()
val address = fromSerialized(author)
return database.getMessageFor(timestamp, address)?.getId()
return database.getMessageFor(timestamp, address)?.run { getId() to isMms }
}
override fun updateSentTimestamp(
@@ -878,8 +878,8 @@ open class Storage(
db.clearErrorMessage(messageID)
}
override fun setMessageServerHash(messageID: Long, serverHash: String) {
DatabaseComponent.get(context).lokiMessageDatabase().setMessageServerHash(messageID, serverHash)
override fun setMessageServerHash(messageID: Long, mms: Boolean, serverHash: String) {
DatabaseComponent.get(context).lokiMessageDatabase().setMessageServerHash(messageID, mms, serverHash)
}
override fun getGroup(groupID: String): GroupRecord? {

View File

@@ -61,7 +61,9 @@ class MarkReadReceiver : BroadcastReceiver() {
val loki = DatabaseComponent.get(context).lokiMessageDatabase()
task {
val hashToInfo = markedReadMessages.associateByNotNull { loki.getMessageServerHash(it.expirationInfo.id) }
val hashToInfo = markedReadMessages.associateByNotNull {
it.expirationInfo.run { loki.getMessageServerHash(id, isMms) }
}
if (hashToInfo.isEmpty()) return@task
@Suppress("UNCHECKED_CAST")

View File

@@ -202,7 +202,7 @@ class DefaultConversationRepository @Inject constructor(
}
} else {
messageDataProvider.deleteMessage(message.id, !message.isMms)
messageDataProvider.getServerHashForMessage(message.id)?.let { serverHash ->
messageDataProvider.getServerHashForMessage(message.id, message.isMms)?.let { serverHash ->
var publicKey = recipient.address.serialize()
if (recipient.isClosedGroupRecipient) {
publicKey = GroupUtil.doubleDecodeGroupID(publicKey).toHexString()
@@ -219,16 +219,15 @@ class DefaultConversationRepository @Inject constructor(
override fun buildUnsendRequest(recipient: Recipient, message: MessageRecord): UnsendRequest? {
if (recipient.isOpenGroupRecipient) return null
messageDataProvider.getServerHashForMessage(message.id) ?: return null
val unsendRequest = UnsendRequest()
if (message.isOutgoing) {
unsendRequest.author = textSecurePreferences.getLocalNumber()
} else {
unsendRequest.author = message.individualRecipient.address.contactIdentifier()
messageDataProvider.getServerHashForMessage(message.id, message.isMms) ?: return null
return UnsendRequest().apply {
author = if (message.isOutgoing) {
textSecurePreferences.getLocalNumber()
} else {
message.individualRecipient.address.contactIdentifier()
}
timestamp = message.timestamp
}
unsendRequest.timestamp = message.timestamp
return unsendRequest
}
override suspend fun deleteMessageWithoutUnsendRequest(
@@ -243,7 +242,7 @@ class DefaultConversationRepository @Inject constructor(
lokiMessageDb.getServerID(message.id, !message.isMms) ?: continue
messageServerIDs[messageServerID] = message
}
for ((messageServerID, message) in messageServerIDs) {
messageServerIDs.forEach { (messageServerID, message) ->
OpenGroupApi.deleteMessage(messageServerID, openGroup.room, openGroup.server)
.success {
messageDataProvider.deleteMessage(message.id, !message.isMms)