Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: messages migration from proteus to mls [WPB-15149] 🍒 #3219

Merged
merged 3 commits into from
Jan 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,11 @@ internal class OneOnOneMigratorImpl(
return getResolvedMLSOneOnOne(user.id)
.flatMap { mlsConversation ->
if (user.activeOneOnOneConversationId == mlsConversation) {
kaliumLogger.d(
"active one-on-one already resolved to MLS "
+ "${mlsConversation.toLogString()}, "
+ "user = ${user.id.toLogString()}"
)
return@flatMap Either.Right(mlsConversation)
}

Expand Down Expand Up @@ -136,6 +141,10 @@ internal class OneOnOneMigratorImpl(
// We can theoretically have more than one proteus 1-1 conversation with
// team members since there was no backend safeguards against this
proteusOneOnOneConversations.foldToEitherWhileRight(Unit) { proteusOneOnOneConversation, _ ->
kaliumLogger.d(
"migrating proteus ${proteusOneOnOneConversation.toLogString()} " +
"to MLS conv ${targetConversation.toLogString()}"
)
messageRepository.moveMessagesToAnotherConversation(
originalConversation = proteusOneOnOneConversation,
targetConversation = targetConversation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ CREATE TABLE MessageRestrictedAssetContent (
asset_size INTEGER NOT NULL,
asset_name TEXT NOT NULL,

FOREIGN KEY (message_id, conversation_id) REFERENCES Message(id, conversation_id) ON DELETE CASCADE,
FOREIGN KEY (message_id, conversation_id) REFERENCES Message(id, conversation_id) ON DELETE CASCADE ON UPDATE CASCADE,
PRIMARY KEY (message_id, conversation_id)
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ CREATE TABLE Reaction (
sender_id TEXT AS QualifiedIDEntity NOT NULL,
emoji TEXT NOT NULL,
date TEXT NOT NULL,
FOREIGN KEY (message_id, conversation_id) REFERENCES Message(id, conversation_id) ON DELETE CASCADE,
FOREIGN KEY (message_id, conversation_id) REFERENCES Message(id, conversation_id) ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY (sender_id) REFERENCES User(qualified_id) ON DELETE CASCADE,
PRIMARY KEY (message_id, conversation_id, sender_id, emoji)
);
Expand Down
47 changes: 47 additions & 0 deletions persistence/src/commonMain/db_user/migrations/94.sqm
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
CREATE TABLE Reaction_temp AS
SELECT * FROM Reaction;

DROP TABLE Reaction;

CREATE TABLE Reaction (
message_id TEXT NOT NULL,
conversation_id TEXT AS QualifiedIDEntity NOT NULL,
sender_id TEXT AS QualifiedIDEntity NOT NULL,
emoji TEXT NOT NULL,
date TEXT NOT NULL,
FOREIGN KEY (message_id, conversation_id) REFERENCES Message(id, conversation_id) ON DELETE CASCADE ON UPDATE CASCADE,
FOREIGN KEY (sender_id) REFERENCES User(qualified_id) ON DELETE CASCADE,
PRIMARY KEY (message_id, conversation_id, sender_id, emoji)
);

INSERT INTO Reaction(message_id, conversation_id, sender_id, emoji, date)
SELECT message_id, conversation_id, sender_id, emoji, date
FROM Reaction_temp;

DROP TABLE Reaction_temp;

CREATE INDEX reaction_sender_index ON Reaction(sender_id);
CREATE INDEX reaction_emoji_index ON Reaction(emoji);

CREATE TABLE MessageRestrictedAssetContent_temp AS
SELECT * FROM MessageRestrictedAssetContent;

DROP TABLE MessageRestrictedAssetContent;

CREATE TABLE MessageRestrictedAssetContent (
message_id TEXT NOT NULL,
conversation_id TEXT AS QualifiedIDEntity NOT NULL,

asset_mime_type TEXT NOT NULL,
asset_size INTEGER NOT NULL,
asset_name TEXT NOT NULL,

FOREIGN KEY (message_id, conversation_id) REFERENCES Message(id, conversation_id) ON DELETE CASCADE ON UPDATE CASCADE,
PRIMARY KEY (message_id, conversation_id)
);

INSERT INTO MessageRestrictedAssetContent(message_id, conversation_id, asset_mime_type, asset_size, asset_name)
SELECT message_id, conversation_id, asset_mime_type, asset_size, asset_name
FROM MessageRestrictedAssetContent_temp;

DROP TABLE MessageRestrictedAssetContent_temp;
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,12 @@ import com.wire.kalium.persistence.dao.asset.AssetEntity
import com.wire.kalium.persistence.dao.asset.AssetTransferStatusEntity
import com.wire.kalium.persistence.dao.conversation.ConversationDAO
import com.wire.kalium.persistence.dao.conversation.ConversationEntity
import com.wire.kalium.persistence.dao.reaction.ReactionDAO
import com.wire.kalium.persistence.dao.receipt.ReceiptDAO
import com.wire.kalium.persistence.dao.receipt.ReceiptTypeEntity
import com.wire.kalium.persistence.dao.unread.UnreadEventTypeEntity
import com.wire.kalium.persistence.utils.IgnoreIOS
import com.wire.kalium.persistence.utils.stubs.allMessageEntities
import com.wire.kalium.persistence.utils.stubs.newConversationEntity
import com.wire.kalium.persistence.utils.stubs.newRegularMessageEntity
import com.wire.kalium.persistence.utils.stubs.newSystemMessageEntity
Expand All @@ -49,6 +51,7 @@ import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertIs
import kotlin.test.assertNotNull
import kotlin.test.assertNull
import kotlin.test.assertTrue
import kotlin.time.Duration.Companion.days
import kotlin.time.Duration.Companion.seconds
Expand All @@ -61,6 +64,7 @@ class MessageDAOTest : BaseDatabaseTest() {
private lateinit var userDAO: UserDAO
private lateinit var receiptDao: ReceiptDAO
private lateinit var assetDao: AssetDAO
private lateinit var reactionDao: ReactionDAO

private val conversationEntity1 = newConversationEntity("Test1")
private val conversationEntity2 = newConversationEntity("Test2")
Expand All @@ -80,6 +84,7 @@ class MessageDAOTest : BaseDatabaseTest() {
userDAO = db.userDAO
receiptDao = db.receiptDAO
assetDao = db.assetDAO
reactionDao = db.reactionDAO
}

@Test
Expand Down Expand Up @@ -2454,6 +2459,32 @@ class MessageDAOTest : BaseDatabaseTest() {
assertEquals("3", result)
}

@Test
fun givenAllTypesOfMessages_whenMovingToAnotherConversation_thenItSucceeds() = runTest {
// Given
insertInitialData()
val messages = allMessageEntities(conversationId = conversationEntity1.id, senderUserId = userEntity1.id)
val firstEmoji = "🫡"
messageDAO.insertOrIgnoreMessages(messages)
reactionDao.insertReaction(
messages.first().id,
messages.first().conversationId,
userEntity1.id,
Instant.DISTANT_PAST,
firstEmoji
)

// When
val exception = kotlin.runCatching {
messageDAO.moveMessages(conversationEntity1.id, conversationEntity2.id)
}.exceptionOrNull()

// Then
assertNull(exception, "Expected no exception but got: ${exception?.message}")
val result = messageDAO.getMessagesByConversationAndVisibility(conversationEntity2.id, 100, 0).first()
assertEquals(messages.size, result.size)
}

private suspend fun insertInitialData() {
userDAO.upsertUsers(listOf(userEntity1, userEntity2))
conversationDAO.insertConversation(
Expand Down
Loading
Loading