Better clearing of RealmLists

This commit is contained in:
Benoit Marty 2021-02-03 09:07:41 +01:00 committed by Benoit Marty
parent 3b65761110
commit 424035f56f
8 changed files with 24 additions and 11 deletions

View File

@ -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)

View File

@ -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()
}

View File

@ -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()
}

View File

@ -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()
}
}

View File

@ -41,7 +41,7 @@ internal open class PushRuleEntity(
companion object
fun deleteOnCascade() {
conditions?.forEach { it.deleteFromRealm() }
conditions?.deleteAllFromRealm()
deleteFromRealm()
}
}

View File

@ -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()
}
}

View File

@ -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 <T> RealmList<T>.clearWith(delete: (T) -> Unit) {
while (!isEmpty()) {
first()?.let { delete.invoke(it) }
}
}

View File

@ -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)