diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt index 8dbccb061b..bb14180baa 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt @@ -94,6 +94,7 @@ import org.matrix.android.sdk.internal.di.CryptoDatabase import org.matrix.android.sdk.internal.di.DeviceId import org.matrix.android.sdk.internal.di.MoshiProvider import org.matrix.android.sdk.internal.di.UserId +import org.matrix.android.sdk.internal.extensions.clearWith import org.matrix.android.sdk.internal.session.SessionScope import org.matrix.olm.OlmAccount import org.matrix.olm.OlmException @@ -293,8 +294,7 @@ internal class RealmCryptoStore @Inject constructor( realm.insertOrUpdate(entity) } // Ensure all other devices are deleted - u.devices.toList().forEach { it.deleteOnCascade() } - u.devices.clear() + u.devices.clearWith { it.deleteOnCascade() } u.devices.addAll(new) } } @@ -1634,8 +1634,7 @@ internal class RealmCryptoStore @Inject constructor( } else { // Just override existing, caller should check and untrust id needed val existing = CrossSigningInfoEntity.getOrCreate(realm, userId) - existing.crossSigningKeys.toList().forEach { it.deleteOnCascade() } - existing.crossSigningKeys.clear() + existing.crossSigningKeys.clearWith { it.deleteOnCascade() } existing.crossSigningKeys.addAll( info.crossSigningKeys.map { crossSigningKeysMapper.map(it) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/CrossSigningInfoEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/CrossSigningInfoEntity.kt index 5a14ede0ad..2d91c32d90 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/CrossSigningInfoEntity.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/CrossSigningInfoEntity.kt @@ -20,6 +20,7 @@ import io.realm.RealmList import io.realm.RealmObject import io.realm.annotations.PrimaryKey import org.matrix.android.sdk.internal.crypto.model.KeyUsage +import org.matrix.android.sdk.internal.extensions.clearWith internal open class CrossSigningInfoEntity( @PrimaryKey @@ -30,7 +31,7 @@ internal open class CrossSigningInfoEntity( companion object fun deleteOnCascade() { - crossSigningKeys.toList().forEach { it.deleteOnCascade() } + crossSigningKeys.clearWith { it.deleteOnCascade() } deleteFromRealm() } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/UserEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/UserEntity.kt index a5336ea848..a815efd8cb 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/UserEntity.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/UserEntity.kt @@ -19,6 +19,7 @@ package org.matrix.android.sdk.internal.crypto.store.db.model import io.realm.RealmList import io.realm.RealmObject import io.realm.annotations.PrimaryKey +import org.matrix.android.sdk.internal.extensions.clearWith internal open class UserEntity( @PrimaryKey var userId: String? = null, @@ -30,7 +31,7 @@ internal open class UserEntity( companion object fun deleteOnCascade() { - devices.toList().forEach { it.deleteOnCascade() } + devices.clearWith { it.deleteOnCascade() } crossSigningInfoEntity?.deleteOnCascade() deleteFromRealm() } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/ChunkEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/ChunkEntity.kt index de7333bef2..567cb3ca32 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/ChunkEntity.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/ChunkEntity.kt @@ -22,6 +22,7 @@ import io.realm.RealmResults import io.realm.annotations.Index import io.realm.annotations.LinkingObjects import org.matrix.android.sdk.internal.extensions.assertIsManaged +import org.matrix.android.sdk.internal.extensions.clearWith internal open class ChunkEntity(@Index var prevToken: String? = null, // Because of gaps we can have several chunks with nextToken == null @@ -49,7 +50,7 @@ internal open class ChunkEntity(@Index var prevToken: String? = null, if (deleteStateEvents) { stateEvents.deleteAllFromRealm() } - timelineEvents.forEach { it.deleteOnCascade(canDeleteRoot) } + timelineEvents.clearWith { it.deleteOnCascade(canDeleteRoot) } deleteFromRealm() } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/PushRuleEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/PushRuleEntity.kt index 2a24208d97..cf824ba85d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/PushRuleEntity.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/PushRuleEntity.kt @@ -41,7 +41,7 @@ internal open class PushRuleEntity( companion object fun deleteOnCascade() { - conditions?.forEach { it.deleteFromRealm() } + conditions?.deleteAllFromRealm() deleteFromRealm() } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/PushRulesEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/PushRulesEntity.kt index 52fd97b408..3728856663 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/PushRulesEntity.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/PushRulesEntity.kt @@ -18,6 +18,7 @@ package org.matrix.android.sdk.internal.database.model import org.matrix.android.sdk.api.pushrules.RuleKind import io.realm.RealmList import io.realm.RealmObject +import org.matrix.android.sdk.internal.extensions.clearWith internal open class PushRulesEntity( var scope: String = "", @@ -36,7 +37,7 @@ internal open class PushRulesEntity( companion object fun deleteOnCascade() { - pushRules.toList().forEach { it.deleteOnCascade() } + pushRules.clearWith { it.deleteOnCascade() } deleteFromRealm() } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/extensions/RealmExtensions.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/extensions/RealmExtensions.kt index 0718096fd5..e52e32e16a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/extensions/RealmExtensions.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/extensions/RealmExtensions.kt @@ -16,8 +16,18 @@ package org.matrix.android.sdk.internal.extensions +import io.realm.RealmList import io.realm.RealmObject internal fun RealmObject.assertIsManaged() { check(isManaged) { "${javaClass.simpleName} entity should be managed to use this function" } } + +/** + * Clear a RealmList by deleting all its items calling the provided lambda + */ +internal fun RealmList.clearWith(delete: (T) -> Unit) { + while (!isEmpty()) { + first()?.let { delete.invoke(it) } + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomSyncHandler.kt index 4fb7708ed1..2daaf5d81c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomSyncHandler.kt @@ -47,6 +47,7 @@ import org.matrix.android.sdk.internal.database.query.getOrNull import org.matrix.android.sdk.internal.database.query.where import org.matrix.android.sdk.internal.di.MoshiProvider import org.matrix.android.sdk.internal.di.UserId +import org.matrix.android.sdk.internal.extensions.clearWith import org.matrix.android.sdk.internal.session.DefaultInitialSyncProgressService import org.matrix.android.sdk.internal.session.mapWithProgress import org.matrix.android.sdk.internal.session.room.membership.RoomChangeMembershipStateDataSource @@ -262,8 +263,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle val leftMember = RoomMemberSummaryEntity.where(realm, roomId, userId).findFirst() val membership = leftMember?.membership ?: Membership.LEAVE roomEntity.membership = membership - roomEntity.chunks.forEach { it.deleteOnCascade(deleteStateEvents = true, canDeleteRoot = true) } - roomEntity.chunks.clear() + roomEntity.chunks.clearWith { it.deleteOnCascade(deleteStateEvents = true, canDeleteRoot = true) } roomTypingUsersHandler.handle(realm, roomId, null) roomChangeMembershipStateDataSource.setMembershipFromSync(roomId, Membership.LEAVE) roomSummaryUpdater.update(realm, roomId, membership, roomSync.summary, roomSync.unreadNotifications)