From 460babe93097a2d202c14071e3664c256b604310 Mon Sep 17 00:00:00 2001 From: jubb Date: Fri, 30 Apr 2021 14:19:37 +1000 Subject: [PATCH] fix: deletion fixed up --- .../attachments/DatabaseAttachmentProvider.kt | 1 + .../conversation/ConversationFragment.java | 7 +- .../loki/database/LokiMessageDatabase.kt | 70 +++++++++++++------ .../messaging/open_groups/OpenGroupAPIV2.kt | 8 ++- 4 files changed, 59 insertions(+), 27 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/attachments/DatabaseAttachmentProvider.kt b/app/src/main/java/org/thoughtcrime/securesms/attachments/DatabaseAttachmentProvider.kt index 91040365c5..40981b5cc7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/attachments/DatabaseAttachmentProvider.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/attachments/DatabaseAttachmentProvider.kt @@ -150,6 +150,7 @@ class DatabaseAttachmentProvider(context: Context, helper: SQLCipherOpenHelper) val db = DatabaseFactory.getMmsDatabase(context) db.delete(messageID) } + DatabaseFactory.getLokiMessageDatabase(context).deleteMessage(messageID, isSms) } override fun getDatabaseAttachment(attachmentId: Long): DatabaseAttachment? { diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationFragment.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationFragment.java index 38cb56be5b..53ab9de4ed 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationFragment.java @@ -57,6 +57,7 @@ import androidx.recyclerview.widget.RecyclerView.OnScrollListener; import com.annimon.stream.Stream; +import org.session.libsession.messaging.MessagingModuleConfiguration; import org.session.libsession.messaging.messages.control.DataExtractionNotification; import org.session.libsession.messaging.messages.signal.OutgoingMediaMessage; import org.session.libsession.messaging.messages.signal.OutgoingTextMessage; @@ -570,11 +571,7 @@ public class ConversationFragment extends Fragment for (MessageRecord messageRecord : messageRecords) { Long serverID = DatabaseFactory.getLokiMessageDatabase(getContext()).getServerID(messageRecord.id, !messageRecord.isMms()); if (serverID != null && serverID.equals(serverId)) { - if (messageRecord.isMms()) { - DatabaseFactory.getMmsDatabase(getContext()).delete(messageRecord.getId()); - } else { - DatabaseFactory.getSmsDatabase(getContext()).deleteMessage(messageRecord.getId()); - } + MessagingModuleConfiguration.shared.getMessageDataProvider().deleteMessage(messageRecord.id, !messageRecord.isMms()); break; } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/database/LokiMessageDatabase.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/database/LokiMessageDatabase.kt index 85481432d7..78a1b91051 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/database/LokiMessageDatabase.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/database/LokiMessageDatabase.kt @@ -2,11 +2,11 @@ package org.thoughtcrime.securesms.loki.database import android.content.ContentValues import android.content.Context -import org.session.libsession.messaging.threads.Address +import org.session.libsignal.service.loki.database.LokiMessageDatabaseProtocol +import org.session.libsignal.utilities.logging.Log import org.thoughtcrime.securesms.database.Database import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper -import org.session.libsignal.service.loki.database.LokiMessageDatabaseProtocol import org.thoughtcrime.securesms.loki.utilities.* class LokiMessageDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(context, helper), LokiMessageDatabaseProtocol { @@ -21,11 +21,16 @@ class LokiMessageDatabase(context: Context, helper: SQLCipherOpenHelper) : Datab private val threadID = "thread_id" private val errorMessage = "error_message" private val messageType = "message_type" - @JvmStatic val createMessageIDTableCommand = "CREATE TABLE $messageIDTable ($messageID INTEGER PRIMARY KEY, $serverID INTEGER DEFAULT 0, $friendRequestStatus INTEGER DEFAULT 0);" - @JvmStatic val createMessageToThreadMappingTableCommand = "CREATE TABLE IF NOT EXISTS $messageThreadMappingTable ($messageID INTEGER PRIMARY KEY, $threadID INTEGER);" - @JvmStatic val createErrorMessageTableCommand = "CREATE TABLE IF NOT EXISTS $errorMessageTable ($messageID INTEGER PRIMARY KEY, $errorMessage STRING);" - @JvmStatic val updateMessageIDTableForType = "ALTER TABLE $messageIDTable ADD COLUMN $messageType INTEGER DEFAULT 0; ALTER TABLE $messageIDTable ADD CONSTRAINT PK_$messageIDTable PRIMARY KEY ($messageID, $serverID);" - @JvmStatic val updateMessageMappingTable = "ALTER TABLE $messageThreadMappingTable ADD COLUMN $serverID INTEGER DEFAULT 0; ALTER TABLE $messageThreadMappingTable ADD CONSTRAINT PK_$messageThreadMappingTable PRIMARY KEY ($messageID, $serverID);" + @JvmStatic + val createMessageIDTableCommand = "CREATE TABLE $messageIDTable ($messageID INTEGER PRIMARY KEY, $serverID INTEGER DEFAULT 0, $friendRequestStatus INTEGER DEFAULT 0);" + @JvmStatic + val createMessageToThreadMappingTableCommand = "CREATE TABLE IF NOT EXISTS $messageThreadMappingTable ($messageID INTEGER PRIMARY KEY, $threadID INTEGER);" + @JvmStatic + val createErrorMessageTableCommand = "CREATE TABLE IF NOT EXISTS $errorMessageTable ($messageID INTEGER PRIMARY KEY, $errorMessage STRING);" + @JvmStatic + val updateMessageIDTableForType = "ALTER TABLE $messageIDTable ADD COLUMN $messageType INTEGER DEFAULT 0; ALTER TABLE $messageIDTable ADD CONSTRAINT PK_$messageIDTable PRIMARY KEY ($messageID, $serverID);" + @JvmStatic + val updateMessageMappingTable = "ALTER TABLE $messageThreadMappingTable ADD COLUMN $serverID INTEGER DEFAULT 0; ALTER TABLE $messageThreadMappingTable ADD CONSTRAINT PK_$messageThreadMappingTable PRIMARY KEY ($messageID, $serverID);" const val SMS_TYPE = 0 const val MMS_TYPE = 1 @@ -39,31 +44,56 @@ class LokiMessageDatabase(context: Context, helper: SQLCipherOpenHelper) : Datab fun getServerID(messageID: Long): Long? { val database = databaseHelper.readableDatabase - return database.get(messageIDTable, "${Companion.messageID} = ?", arrayOf( messageID.toString() )) { cursor -> + return database.get(messageIDTable, "${Companion.messageID} = ?", arrayOf(messageID.toString())) { cursor -> cursor.getInt(serverID) }?.toLong() } fun getServerID(messageID: Long, isSms: Boolean): Long? { val database = databaseHelper.readableDatabase - return database.get(messageIDTable, "${Companion.messageID} = ? AND $messageType = ?", arrayOf( messageID.toString(), if (isSms) SMS_TYPE.toString() else MMS_TYPE.toString() )) { cursor -> + return database.get(messageIDTable, "${Companion.messageID} = ? AND $messageType = ?", arrayOf(messageID.toString(), if (isSms) SMS_TYPE.toString() else MMS_TYPE.toString())) { cursor -> cursor.getInt(serverID) }?.toLong() } fun getMessageID(serverID: Long): Long? { val database = databaseHelper.readableDatabase - return database.get(messageIDTable, "${Companion.serverID} = ?", arrayOf( serverID.toString() )) { cursor -> + return database.get(messageIDTable, "${Companion.serverID} = ?", arrayOf(serverID.toString())) { cursor -> cursor.getInt(messageID) }?.toLong() } - fun getMessageID(serverID: Long, threadID: Long): Pair? { + fun deleteMessage(messageID: Long, isSms: Boolean) { + val database = databaseHelper.writableDatabase + + val serverID = database.get(messageIDTable, + "${Companion.messageID} = ? AND ${Companion.messageType} = ?", + arrayOf(messageID.toString(), (if (isSms) SMS_TYPE else MMS_TYPE).toString())) { cursor -> + cursor.getInt(Companion.serverID).toLong() + } ?: return + + database.beginTransaction() + + database.delete(messageIDTable, "${Companion.messageID} = ? AND ${Companion.serverID} = ?", arrayOf(messageID.toString(), serverID.toString())) + database.delete(messageThreadMappingTable, "${Companion.messageID} = ? AND ${Companion.serverID} = ?", arrayOf(messageID.toString(), serverID.toString())) + + database.setTransactionSuccessful() + database.endTransaction() + } + + fun getMessageID(serverID: Long, threadID: Long): Pair? { val database = databaseHelper.readableDatabase - return database.get("$messageIDTable INNER JOIN $messageThreadMappingTable ON $messageIDTable.$messageID = $messageThreadMappingTable.$messageID AND $messageIDTable.${Companion.serverID} = $messageThreadMappingTable.${Companion.serverID}", - "${Companion.serverID} = ? AND ${Companion.threadID} = ?", - arrayOf(serverID.toString(),threadID.toString())) { cursor -> - cursor.getLong(messageID) to (cursor.getInt(messageType) == SMS_TYPE) + val mappingResult = database.get(messageThreadMappingTable, "${Companion.serverID} = ? AND ${Companion.threadID} = ?", + arrayOf(serverID.toString(), threadID.toString())) { cursor -> + cursor.getInt(messageID) to cursor.getInt(Companion.serverID) + } ?: return null + + val (mappedID, mappedServerID) = mappingResult + + return database.get(messageIDTable, + "$messageID = ? AND ${Companion.serverID} = ?", + arrayOf(mappedID.toString(), mappedServerID.toString())) { cursor -> + cursor.getInt(Companion.messageID).toLong() to (cursor.getInt(messageType) == SMS_TYPE) } } @@ -73,12 +103,12 @@ class LokiMessageDatabase(context: Context, helper: SQLCipherOpenHelper) : Datab contentValues.put(Companion.messageID, messageID) contentValues.put(Companion.serverID, serverID) contentValues.put(messageType, if (isSms) SMS_TYPE else MMS_TYPE) - database.insertOrUpdate(messageIDTable, contentValues, "${Companion.messageID} = ? AND ${Companion.serverID} = ?", arrayOf( messageID.toString(), serverID.toString() )) + database.insertOrUpdate(messageIDTable, contentValues, "${Companion.messageID} = ? AND ${Companion.serverID} = ?", arrayOf(messageID.toString(), serverID.toString())) } fun getOriginalThreadID(messageID: Long): Long { val database = databaseHelper.readableDatabase - return database.get(messageThreadMappingTable, "${Companion.messageID} = ?", arrayOf( messageID.toString() )) { cursor -> + return database.get(messageThreadMappingTable, "${Companion.messageID} = ?", arrayOf(messageID.toString())) { cursor -> cursor.getInt(threadID) }?.toLong() ?: -1L } @@ -89,12 +119,12 @@ class LokiMessageDatabase(context: Context, helper: SQLCipherOpenHelper) : Datab contentValues.put(Companion.messageID, messageID) contentValues.put(Companion.serverID, serverID) contentValues.put(Companion.threadID, threadID) - database.insertOrUpdate(messageThreadMappingTable, contentValues, "${Companion.messageID} = ? AND ${Companion.serverID} = ?", arrayOf( messageID.toString(), serverID.toString() )) + database.insertOrUpdate(messageThreadMappingTable, contentValues, "${Companion.messageID} = ? AND ${Companion.serverID} = ?", arrayOf(messageID.toString(), serverID.toString())) } fun getErrorMessage(messageID: Long): String? { val database = databaseHelper.readableDatabase - return database.get(errorMessageTable, "${Companion.messageID} = ?", arrayOf( messageID.toString() )) { cursor -> + return database.get(errorMessageTable, "${Companion.messageID} = ?", arrayOf(messageID.toString())) { cursor -> cursor.getString(errorMessage) } } @@ -104,6 +134,6 @@ class LokiMessageDatabase(context: Context, helper: SQLCipherOpenHelper) : Datab val contentValues = ContentValues(2) contentValues.put(Companion.messageID, messageID) contentValues.put(Companion.errorMessage, errorMessage) - database.insertOrUpdate(errorMessageTable, contentValues, "${Companion.messageID} = ?", arrayOf( messageID.toString() )) + database.insertOrUpdate(errorMessageTable, contentValues, "${Companion.messageID} = ?", arrayOf(messageID.toString())) } } \ No newline at end of file diff --git a/libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroupAPIV2.kt b/libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroupAPIV2.kt index f58b76ad17..c0f5a62786 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroupAPIV2.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroupAPIV2.kt @@ -78,7 +78,11 @@ object OpenGroupAPIV2 { @JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy::class) data class MessageDeletion @JvmOverloads constructor(val id: Long = 0, val deletedMessageId: Long = 0 - ) + ) { + companion object { + val EMPTY = MessageDeletion() + } + } data class Request( val verb: HTTP.Verb, @@ -309,7 +313,7 @@ object OpenGroupAPIV2 { val idsAsString = JsonUtil.toJson(json["ids"]) val serverIDs = JsonUtil.fromJson>(idsAsString, type) ?: throw Error.PARSING_FAILED val lastMessageServerId = storage.getLastDeletionServerId(room, server) ?: 0 - val serverID = serverIDs.maxByOrNull {it.id } ?: serverIDs.first() + val serverID = serverIDs.maxByOrNull {it.id } ?: MessageDeletion.EMPTY if (serverID.id > lastMessageServerId) { storage.setLastDeletionServerId(room, server, serverID.id) }