Realm kotlin session: continue on RoomSummary
This commit is contained in:
parent
a4a4bac75b
commit
184edd9398
@ -129,7 +129,6 @@ internal class RoomSummaryEntity : RealmObject {
|
||||
|
||||
fun tags(): List<RoomTagEntity> = tags
|
||||
|
||||
|
||||
fun updateTags(newTags: List<Pair<String, Double?>>) {
|
||||
val toDelete = mutableListOf<RoomTagEntity>()
|
||||
tags.forEach { existingTag ->
|
||||
@ -240,7 +239,7 @@ internal class RoomSummaryEntity : RealmObject {
|
||||
if (value != field) field = value
|
||||
}
|
||||
|
||||
var flattenParentIds: String? = null
|
||||
var flattenParentIds: RealmList<String> = realmListOf()
|
||||
set(value) {
|
||||
if (value != field) field = value
|
||||
}
|
||||
|
@ -16,69 +16,76 @@
|
||||
|
||||
package org.matrix.android.sdk.internal.database.query
|
||||
|
||||
import io.realm.Realm
|
||||
import io.realm.RealmQuery
|
||||
import io.realm.RealmResults
|
||||
import io.realm.kotlin.createObject
|
||||
import io.realm.kotlin.where
|
||||
import io.realm.kotlin.MutableRealm
|
||||
import io.realm.kotlin.TypedRealm
|
||||
import io.realm.kotlin.query.RealmQuery
|
||||
import io.realm.kotlin.query.RealmResults
|
||||
import org.matrix.android.sdk.internal.database.andIf
|
||||
import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity
|
||||
import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields
|
||||
import org.matrix.android.sdk.internal.database.model.presence.UserPresenceEntity
|
||||
import org.matrix.android.sdk.internal.database.queryNotIn
|
||||
|
||||
internal fun RoomSummaryEntity.Companion.where(realm: Realm, roomId: String? = null): RealmQuery<RoomSummaryEntity> {
|
||||
val query = realm.where<RoomSummaryEntity>()
|
||||
if (roomId != null) {
|
||||
query.equalTo(RoomSummaryEntityFields.ROOM_ID, roomId)
|
||||
}
|
||||
return query
|
||||
internal fun RoomSummaryEntity.Companion.where(realm: TypedRealm, roomId: String? = null): RealmQuery<RoomSummaryEntity> {
|
||||
return realm.query(RoomSummaryEntity::class)
|
||||
.andIf(roomId != null) {
|
||||
query("roomId == $0", roomId!!)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun RoomSummaryEntity.Companion.findByAlias(realm: Realm, roomAlias: String): RoomSummaryEntity? {
|
||||
val roomSummary = realm.where<RoomSummaryEntity>()
|
||||
.equalTo(RoomSummaryEntityFields.CANONICAL_ALIAS, roomAlias)
|
||||
.findFirst()
|
||||
internal fun RoomSummaryEntity.Companion.findByAlias(realm: TypedRealm, roomAlias: String): RoomSummaryEntity? {
|
||||
val roomSummary = realm.query(RoomSummaryEntity::class)
|
||||
.query("canonicalAlias == $0", roomAlias)
|
||||
.first()
|
||||
.find()
|
||||
if (roomSummary != null) {
|
||||
return roomSummary
|
||||
}
|
||||
return realm.where<RoomSummaryEntity>()
|
||||
.contains(RoomSummaryEntityFields.FLAT_ALIASES, "|$roomAlias")
|
||||
.findFirst()
|
||||
return realm.query(RoomSummaryEntity::class)
|
||||
.query("flatAliases CONTAINS |$roomAlias")
|
||||
.first()
|
||||
.find()
|
||||
}
|
||||
|
||||
internal fun RoomSummaryEntity.Companion.getOrCreate(realm: Realm, roomId: String): RoomSummaryEntity {
|
||||
return where(realm, roomId).findFirst() ?: realm.createObject(roomId)
|
||||
private fun RoomSummaryEntity.Companion.create(realm: MutableRealm, roomId: String): RoomSummaryEntity {
|
||||
val roomSummaryEntity = RoomSummaryEntity().apply {
|
||||
this.roomId = roomId
|
||||
}
|
||||
return realm.copyToRealm(roomSummaryEntity)
|
||||
}
|
||||
|
||||
internal fun RoomSummaryEntity.Companion.getOrNull(realm: Realm, roomId: String): RoomSummaryEntity? {
|
||||
return where(realm, roomId).findFirst()
|
||||
internal fun RoomSummaryEntity.Companion.getOrCreate(realm: MutableRealm, roomId: String): RoomSummaryEntity {
|
||||
return getOrNull(realm, roomId) ?: create(realm, roomId)
|
||||
}
|
||||
|
||||
internal fun RoomSummaryEntity.Companion.getOrNull(realm: TypedRealm, roomId: String): RoomSummaryEntity? {
|
||||
return where(realm, roomId).first().find()
|
||||
}
|
||||
|
||||
internal fun RoomSummaryEntity.Companion.getDirectRooms(
|
||||
realm: Realm,
|
||||
realm: TypedRealm,
|
||||
excludeRoomIds: Set<String>? = null
|
||||
): RealmResults<RoomSummaryEntity> {
|
||||
return RoomSummaryEntity.where(realm)
|
||||
.equalTo(RoomSummaryEntityFields.IS_DIRECT, true)
|
||||
.apply {
|
||||
if (!excludeRoomIds.isNullOrEmpty()) {
|
||||
not().`in`(RoomSummaryEntityFields.ROOM_ID, excludeRoomIds.toTypedArray())
|
||||
}
|
||||
.query("isDirect == true")
|
||||
.andIf(!excludeRoomIds.isNullOrEmpty()) {
|
||||
queryNotIn("roomId", excludeRoomIds.orEmpty().toList())
|
||||
}
|
||||
.findAll()
|
||||
.find()
|
||||
}
|
||||
|
||||
internal fun RoomSummaryEntity.Companion.isDirect(realm: Realm, roomId: String): Boolean {
|
||||
internal fun RoomSummaryEntity.Companion.isDirect(realm: TypedRealm, roomId: String): Boolean {
|
||||
return RoomSummaryEntity.where(realm)
|
||||
.equalTo(RoomSummaryEntityFields.ROOM_ID, roomId)
|
||||
.equalTo(RoomSummaryEntityFields.IS_DIRECT, true)
|
||||
.findAll()
|
||||
.query("roomId == $0", roomId)
|
||||
.query("isDirect == true")
|
||||
.find()
|
||||
.isNotEmpty()
|
||||
}
|
||||
|
||||
internal fun RoomSummaryEntity.Companion.updateDirectUserPresence(realm: Realm, directUserId: String, userPresenceEntity: UserPresenceEntity) {
|
||||
internal fun RoomSummaryEntity.Companion.updateDirectUserPresence(realm: MutableRealm, directUserId: String, userPresenceEntity: UserPresenceEntity) {
|
||||
RoomSummaryEntity.where(realm)
|
||||
.equalTo(RoomSummaryEntityFields.IS_DIRECT, true)
|
||||
.equalTo(RoomSummaryEntityFields.DIRECT_USER_ID, directUserId)
|
||||
.findFirst()
|
||||
.query("isDirect == true", true)
|
||||
.query("directUserId == $0", directUserId)
|
||||
.first()
|
||||
.find()
|
||||
?.directUserPresence = userPresenceEntity
|
||||
}
|
||||
|
@ -16,18 +16,11 @@
|
||||
|
||||
package org.matrix.android.sdk.internal.query
|
||||
|
||||
import io.realm.RealmModel
|
||||
import io.realm.RealmQuery
|
||||
import io.realm.kotlin.query.RealmQuery
|
||||
import io.realm.kotlin.types.RealmObject
|
||||
import org.matrix.android.sdk.internal.database.queryIn
|
||||
|
||||
internal fun <T : RealmModel, E : Enum<E>> RealmQuery<T>.process(field: String, enums: List<Enum<E>>): RealmQuery<T> {
|
||||
val lastEnumValue = enums.lastOrNull()
|
||||
beginGroup()
|
||||
for (enumValue in enums) {
|
||||
equalTo(field, enumValue.name)
|
||||
if (enumValue != lastEnumValue) {
|
||||
or()
|
||||
}
|
||||
}
|
||||
endGroup()
|
||||
return this
|
||||
internal fun <T : RealmObject, E : Enum<E>> RealmQuery<T>.process(field: String, enums: List<Enum<E>>): RealmQuery<T> {
|
||||
val enumValues = enums.map { it.name }
|
||||
return queryIn(field, enumValues)
|
||||
}
|
||||
|
@ -16,8 +16,8 @@
|
||||
|
||||
package org.matrix.android.sdk.internal.query
|
||||
|
||||
import io.realm.RealmQuery
|
||||
import io.realm.Sort
|
||||
import io.realm.kotlin.query.RealmQuery
|
||||
import io.realm.kotlin.query.Sort
|
||||
import org.matrix.android.sdk.api.session.room.RoomSortOrder
|
||||
import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity
|
||||
import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields
|
||||
@ -32,12 +32,9 @@ internal fun RealmQuery<RoomSummaryEntity>.process(sortOrder: RoomSortOrder): Re
|
||||
}
|
||||
RoomSortOrder.PRIORITY_AND_ACTIVITY -> {
|
||||
sort(
|
||||
arrayOf(
|
||||
RoomSummaryEntityFields.IS_FAVOURITE,
|
||||
RoomSummaryEntityFields.IS_LOW_PRIORITY,
|
||||
RoomSummaryEntityFields.LAST_ACTIVITY_TIME
|
||||
),
|
||||
arrayOf(Sort.DESCENDING, Sort.ASCENDING, Sort.DESCENDING)
|
||||
RoomSummaryEntityFields.IS_FAVOURITE to Sort.DESCENDING,
|
||||
RoomSummaryEntityFields.IS_LOW_PRIORITY to Sort.ASCENDING,
|
||||
RoomSummaryEntityFields.LAST_ACTIVITY_TIME to Sort.DESCENDING
|
||||
)
|
||||
}
|
||||
RoomSortOrder.NONE -> {
|
||||
|
@ -16,9 +16,8 @@
|
||||
|
||||
package org.matrix.android.sdk.internal.query
|
||||
|
||||
import io.realm.Case
|
||||
import io.realm.RealmModel
|
||||
import io.realm.RealmQuery
|
||||
import io.realm.kotlin.query.RealmQuery
|
||||
import io.realm.kotlin.types.RealmObject
|
||||
import org.matrix.android.sdk.api.query.QueryStringValue
|
||||
import org.matrix.android.sdk.api.query.QueryStringValue.ContentQueryStringValue
|
||||
import org.matrix.android.sdk.internal.util.Normalizer
|
||||
@ -28,16 +27,16 @@ internal class QueryStringValueProcessor @Inject constructor(
|
||||
private val normalizer: Normalizer
|
||||
) {
|
||||
|
||||
fun <T : RealmModel> RealmQuery<T>.process(field: String, queryStringValue: QueryStringValue): RealmQuery<T> {
|
||||
fun <T : RealmObject> RealmQuery<T>.process(field: String, queryStringValue: QueryStringValue): RealmQuery<T> {
|
||||
return when (queryStringValue) {
|
||||
is QueryStringValue.NoCondition -> this
|
||||
is QueryStringValue.IsNotNull -> isNotNull(field)
|
||||
is QueryStringValue.IsNull -> isNull(field)
|
||||
is QueryStringValue.IsEmpty -> isEmpty(field)
|
||||
is QueryStringValue.IsNotEmpty -> isNotEmpty(field)
|
||||
is QueryStringValue.IsNotNull -> query("$field != nil")
|
||||
is QueryStringValue.IsNull -> query("$field == nil")
|
||||
is QueryStringValue.IsEmpty -> query("$field == ''")
|
||||
is QueryStringValue.IsNotEmpty -> query("$field != ''")
|
||||
is ContentQueryStringValue -> when (queryStringValue) {
|
||||
is QueryStringValue.Equals -> equalTo(field, queryStringValue.toRealmValue(), queryStringValue.case.toRealmCase())
|
||||
is QueryStringValue.Contains -> contains(field, queryStringValue.toRealmValue(), queryStringValue.case.toRealmCase())
|
||||
is QueryStringValue.Equals -> query("$field ==${queryStringValue.case.toRealmCase()} ${queryStringValue.toRealmValue()}")
|
||||
is QueryStringValue.Contains -> query("$field CONTAINS${queryStringValue.case.toRealmCase()} ${queryStringValue.toRealmValue()}")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -49,12 +48,13 @@ internal class QueryStringValueProcessor @Inject constructor(
|
||||
QueryStringValue.Case.INSENSITIVE -> string
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun QueryStringValue.Case.toRealmCase(): Case {
|
||||
return when (this) {
|
||||
QueryStringValue.Case.INSENSITIVE -> Case.INSENSITIVE
|
||||
QueryStringValue.Case.SENSITIVE,
|
||||
QueryStringValue.Case.NORMALIZED -> Case.SENSITIVE
|
||||
private fun QueryStringValue.Case.toRealmCase(): String {
|
||||
return when (this) {
|
||||
QueryStringValue.Case.INSENSITIVE -> "[c]"
|
||||
QueryStringValue.Case.SENSITIVE,
|
||||
QueryStringValue.Case.NORMALIZED -> ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -20,12 +20,13 @@ package org.matrix.android.sdk.internal.session.room.summary
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.Transformations
|
||||
import androidx.lifecycle.asLiveData
|
||||
import androidx.paging.LivePagedListBuilder
|
||||
import androidx.paging.PagedList
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import io.realm.Realm
|
||||
import io.realm.RealmQuery
|
||||
import io.realm.kotlin.where
|
||||
import io.realm.kotlin.TypedRealm
|
||||
import io.realm.kotlin.query.RealmQuery
|
||||
import io.realm.kotlin.query.sum
|
||||
import kotlinx.coroutines.flow.map
|
||||
import org.matrix.android.sdk.api.query.QueryStringValue
|
||||
import org.matrix.android.sdk.api.query.RoomCategoryFilter
|
||||
import org.matrix.android.sdk.api.query.SpaceFilter
|
||||
@ -42,69 +43,65 @@ import org.matrix.android.sdk.api.session.room.spaceSummaryQueryParams
|
||||
import org.matrix.android.sdk.api.session.room.summary.RoomAggregateNotificationCount
|
||||
import org.matrix.android.sdk.api.session.space.SpaceSummaryQueryParams
|
||||
import org.matrix.android.sdk.api.util.Optional
|
||||
import org.matrix.android.sdk.api.util.toOptional
|
||||
import org.matrix.android.sdk.internal.database.RealmInstance
|
||||
import org.matrix.android.sdk.internal.database.mapper.RoomSummaryMapper
|
||||
import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity
|
||||
import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields
|
||||
import org.matrix.android.sdk.internal.database.query.findByAlias
|
||||
import org.matrix.android.sdk.internal.database.query.where
|
||||
import org.matrix.android.sdk.internal.database.queryIn
|
||||
import org.matrix.android.sdk.internal.di.SessionDatabase
|
||||
import org.matrix.android.sdk.internal.query.QueryStringValueProcessor
|
||||
import org.matrix.android.sdk.internal.query.process
|
||||
import org.matrix.android.sdk.internal.util.fetchCopyMap
|
||||
import org.matrix.android.sdk.internal.util.mapOptional
|
||||
import javax.inject.Inject
|
||||
|
||||
internal class RoomSummaryDataSource @Inject constructor(
|
||||
@SessionDatabase private val monarchy: Monarchy,
|
||||
@SessionDatabase private val realmInstance: RealmInstance,
|
||||
private val roomSummaryMapper: RoomSummaryMapper,
|
||||
private val queryStringValueProcessor: QueryStringValueProcessor,
|
||||
) {
|
||||
|
||||
fun getRoomSummary(roomIdOrAlias: String): RoomSummary? {
|
||||
return monarchy
|
||||
.fetchCopyMap({
|
||||
if (roomIdOrAlias.startsWith("!")) {
|
||||
// It's a roomId
|
||||
RoomSummaryEntity.where(it, roomId = roomIdOrAlias).findFirst()
|
||||
} else {
|
||||
// Assume it's a room alias
|
||||
RoomSummaryEntity.findByAlias(it, roomIdOrAlias)
|
||||
}
|
||||
}, { entity, _ ->
|
||||
roomSummaryMapper.map(entity)
|
||||
})
|
||||
val realm = realmInstance.getBlockingRealm()
|
||||
return if (roomIdOrAlias.startsWith("!")) {
|
||||
// It's a roomId
|
||||
RoomSummaryEntity.where(realm, roomId = roomIdOrAlias).first().find()
|
||||
} else {
|
||||
// Assume it's a room alias
|
||||
RoomSummaryEntity.findByAlias(realm, roomIdOrAlias)
|
||||
}?.let {
|
||||
roomSummaryMapper.map(it)
|
||||
}
|
||||
}
|
||||
|
||||
fun getRoomSummaryLive(roomId: String): LiveData<Optional<RoomSummary>> {
|
||||
val liveData = monarchy.findAllMappedWithChanges(
|
||||
{ realm -> RoomSummaryEntity.where(realm, roomId).isNotEmpty(RoomSummaryEntityFields.DISPLAY_NAME) },
|
||||
{ roomSummaryMapper.map(it) }
|
||||
)
|
||||
return Transformations.map(liveData) { results ->
|
||||
results.firstOrNull().toOptional()
|
||||
}
|
||||
return realmInstance.queryFirst {
|
||||
RoomSummaryEntity.where(it, roomId).first()
|
||||
}.mapOptional {
|
||||
roomSummaryMapper.map(it)
|
||||
}.asLiveData()
|
||||
}
|
||||
|
||||
fun getRoomSummaries(
|
||||
queryParams: RoomSummaryQueryParams,
|
||||
sortOrder: RoomSortOrder = RoomSortOrder.NONE
|
||||
): List<RoomSummary> {
|
||||
return monarchy.fetchAllMappedSync(
|
||||
{ roomSummariesQuery(it, queryParams).process(sortOrder) },
|
||||
{ roomSummaryMapper.map(it) }
|
||||
)
|
||||
val realm = realmInstance.getBlockingRealm()
|
||||
return roomSummariesQuery(realm, queryParams).process(sortOrder)
|
||||
.find()
|
||||
.map {
|
||||
roomSummaryMapper.map(it)
|
||||
}
|
||||
}
|
||||
|
||||
fun getRoomSummariesLive(
|
||||
queryParams: RoomSummaryQueryParams,
|
||||
sortOrder: RoomSortOrder = RoomSortOrder.NONE
|
||||
): LiveData<List<RoomSummary>> {
|
||||
return monarchy.findAllMappedWithChanges(
|
||||
{
|
||||
roomSummariesQuery(it, queryParams).process(sortOrder)
|
||||
},
|
||||
{ roomSummaryMapper.map(it) }
|
||||
)
|
||||
return realmInstance.queryList(roomSummaryMapper::map) {
|
||||
roomSummariesQuery(it, queryParams).process(sortOrder)
|
||||
}.asLiveData()
|
||||
}
|
||||
|
||||
fun getSpaceSummariesLive(
|
||||
@ -120,19 +117,14 @@ internal class RoomSummaryDataSource @Inject constructor(
|
||||
}
|
||||
|
||||
fun getSpaceSummaryLive(roomId: String): LiveData<Optional<RoomSummary>> {
|
||||
val liveData = monarchy.findAllMappedWithChanges(
|
||||
{ realm ->
|
||||
RoomSummaryEntity.where(realm, roomId)
|
||||
.isNotEmpty(RoomSummaryEntityFields.DISPLAY_NAME)
|
||||
.equalTo(RoomSummaryEntityFields.ROOM_TYPE, RoomType.SPACE)
|
||||
},
|
||||
{
|
||||
roomSummaryMapper.map(it)
|
||||
}
|
||||
)
|
||||
return Transformations.map(liveData) { results ->
|
||||
results.firstOrNull().toOptional()
|
||||
}
|
||||
return realmInstance.queryFirst { realm ->
|
||||
RoomSummaryEntity.where(realm, roomId)
|
||||
.query("displayName != ''")
|
||||
.query("roomType == $0", RoomType.SPACE)
|
||||
.first()
|
||||
}.mapOptional {
|
||||
roomSummaryMapper.map(it)
|
||||
}.asLiveData()
|
||||
}
|
||||
|
||||
fun getSpaceSummaries(
|
||||
@ -160,23 +152,22 @@ internal class RoomSummaryDataSource @Inject constructor(
|
||||
}
|
||||
|
||||
fun getBreadcrumbs(queryParams: RoomSummaryQueryParams): List<RoomSummary> {
|
||||
return monarchy.fetchAllMappedSync(
|
||||
{ breadcrumbsQuery(it, queryParams) },
|
||||
{ roomSummaryMapper.map(it) }
|
||||
)
|
||||
val realm = realmInstance.getBlockingRealm()
|
||||
return breadcrumbsQuery(realm, queryParams)
|
||||
.find()
|
||||
.map { roomSummaryMapper.map(it) }
|
||||
}
|
||||
|
||||
fun getBreadcrumbsLive(queryParams: RoomSummaryQueryParams): LiveData<List<RoomSummary>> {
|
||||
return monarchy.findAllMappedWithChanges(
|
||||
{ breadcrumbsQuery(it, queryParams) },
|
||||
{ roomSummaryMapper.map(it) }
|
||||
)
|
||||
return realmInstance.queryList(roomSummaryMapper::map) { realm ->
|
||||
breadcrumbsQuery(realm, queryParams)
|
||||
}.asLiveData()
|
||||
}
|
||||
|
||||
private fun breadcrumbsQuery(realm: Realm, queryParams: RoomSummaryQueryParams): RealmQuery<RoomSummaryEntity> {
|
||||
private fun breadcrumbsQuery(realm: TypedRealm, queryParams: RoomSummaryQueryParams): RealmQuery<RoomSummaryEntity> {
|
||||
return roomSummariesQuery(realm, queryParams)
|
||||
.greaterThan(RoomSummaryEntityFields.BREADCRUMBS_INDEX, RoomSummary.NOT_IN_BREADCRUMBS)
|
||||
.sort(RoomSummaryEntityFields.BREADCRUMBS_INDEX)
|
||||
.query("breadcrumbsIndex > $0", RoomSummary.NOT_IN_BREADCRUMBS)
|
||||
.sort("breadcrumbsIndex")
|
||||
}
|
||||
|
||||
fun getSortedPagedRoomSummariesLive(
|
||||
@ -184,16 +175,9 @@ internal class RoomSummaryDataSource @Inject constructor(
|
||||
pagedListConfig: PagedList.Config,
|
||||
sortOrder: RoomSortOrder
|
||||
): LiveData<PagedList<RoomSummary>> {
|
||||
val realmDataSourceFactory = monarchy.createDataSourceFactory { realm ->
|
||||
return realmInstance.queryPagedList(pagedListConfig, roomSummaryMapper::map) { realm ->
|
||||
roomSummariesQuery(realm, queryParams).process(sortOrder)
|
||||
}
|
||||
val dataSourceFactory = realmDataSourceFactory.map {
|
||||
roomSummaryMapper.map(it)
|
||||
}
|
||||
return monarchy.findAllPagedWithChanges(
|
||||
realmDataSourceFactory,
|
||||
LivePagedListBuilder(dataSourceFactory, pagedListConfig)
|
||||
)
|
||||
}.asLiveData()
|
||||
}
|
||||
|
||||
fun getUpdatablePagedRoomSummariesLive(
|
||||
@ -246,80 +230,73 @@ internal class RoomSummaryDataSource @Inject constructor(
|
||||
}
|
||||
|
||||
fun getCountLive(queryParams: RoomSummaryQueryParams): LiveData<Int> {
|
||||
val liveRooms = monarchy.findAllManagedWithChanges {
|
||||
return realmInstance.queryResults {
|
||||
roomSummariesQuery(it, queryParams)
|
||||
}
|
||||
return Transformations.map(liveRooms) {
|
||||
it.realmResults.where().count().toInt()
|
||||
}
|
||||
}.map {
|
||||
it.list.count()
|
||||
}.asLiveData()
|
||||
}
|
||||
|
||||
fun getNotificationCountForRooms(queryParams: RoomSummaryQueryParams): RoomAggregateNotificationCount {
|
||||
var notificationCount: RoomAggregateNotificationCount? = null
|
||||
monarchy.doWithRealm { realm ->
|
||||
val roomSummariesQuery = roomSummariesQuery(realm, queryParams)
|
||||
val notifCount = roomSummariesQuery.sum(RoomSummaryEntityFields.NOTIFICATION_COUNT).toInt()
|
||||
val highlightCount = roomSummariesQuery.sum(RoomSummaryEntityFields.HIGHLIGHT_COUNT).toInt()
|
||||
notificationCount = RoomAggregateNotificationCount(
|
||||
notifCount,
|
||||
highlightCount
|
||||
)
|
||||
}
|
||||
return notificationCount!!
|
||||
val realm = realmInstance.getBlockingRealm()
|
||||
val roomSummariesQuery = roomSummariesQuery(realm, queryParams)
|
||||
val notifCount = roomSummariesQuery.sum<Int>("notificationCounts").find()
|
||||
val highlightCount = roomSummariesQuery.sum<Int>("highlightCounts").find()
|
||||
return RoomAggregateNotificationCount(
|
||||
notifCount,
|
||||
highlightCount
|
||||
)
|
||||
}
|
||||
|
||||
private fun roomSummariesQuery(realm: Realm, queryParams: RoomSummaryQueryParams): RealmQuery<RoomSummaryEntity> {
|
||||
val query = with(queryStringValueProcessor) {
|
||||
private fun roomSummariesQuery(realm: TypedRealm, queryParams: RoomSummaryQueryParams): RealmQuery<RoomSummaryEntity> {
|
||||
var query = with(queryStringValueProcessor) {
|
||||
RoomSummaryEntity.where(realm)
|
||||
.process(RoomSummaryEntityFields.ROOM_ID, QueryStringValue.IsNotEmpty)
|
||||
.process(queryParams.displayName.toDisplayNameField(), queryParams.displayName)
|
||||
.process(RoomSummaryEntityFields.CANONICAL_ALIAS, queryParams.canonicalAlias)
|
||||
.process(RoomSummaryEntityFields.MEMBERSHIP_STR, queryParams.memberships)
|
||||
.equalTo(RoomSummaryEntityFields.IS_HIDDEN_FROM_USER, false)
|
||||
.query("isHiddenFromUser == false")
|
||||
}
|
||||
|
||||
queryParams.roomTagQueryFilter?.let {
|
||||
it.isFavorite?.let { fav ->
|
||||
query.equalTo(RoomSummaryEntityFields.IS_FAVOURITE, fav)
|
||||
queryParams.roomTagQueryFilter?.let { tagFilter ->
|
||||
tagFilter.isFavorite?.let { fav ->
|
||||
query = query.query("isFavourite == $0", fav)
|
||||
}
|
||||
it.isLowPriority?.let { lp ->
|
||||
query.equalTo(RoomSummaryEntityFields.IS_LOW_PRIORITY, lp)
|
||||
tagFilter.isLowPriority?.let { lp ->
|
||||
query.query("isLowPriority == $0", lp)
|
||||
}
|
||||
it.isServerNotice?.let { sn ->
|
||||
query.equalTo(RoomSummaryEntityFields.IS_SERVER_NOTICE, sn)
|
||||
tagFilter.isServerNotice?.let { sn ->
|
||||
query = query.query("isServerNotice == $0", sn)
|
||||
}
|
||||
}
|
||||
|
||||
queryParams.excludeType?.forEach {
|
||||
query.notEqualTo(RoomSummaryEntityFields.ROOM_TYPE, it)
|
||||
query = query.query("roomType != $0", it)
|
||||
}
|
||||
queryParams.includeType?.forEach {
|
||||
query.equalTo(RoomSummaryEntityFields.ROOM_TYPE, it)
|
||||
query = query.query("roomType == $0", it)
|
||||
}
|
||||
when (queryParams.roomCategoryFilter) {
|
||||
RoomCategoryFilter.ONLY_DM -> query.equalTo(RoomSummaryEntityFields.IS_DIRECT, true)
|
||||
RoomCategoryFilter.ONLY_ROOMS -> query.equalTo(RoomSummaryEntityFields.IS_DIRECT, false)
|
||||
RoomCategoryFilter.ONLY_WITH_NOTIFICATIONS -> query.greaterThan(RoomSummaryEntityFields.NOTIFICATION_COUNT, 0)
|
||||
null -> Unit
|
||||
query = when (queryParams.roomCategoryFilter) {
|
||||
RoomCategoryFilter.ONLY_DM -> query.query("isDirect == true")
|
||||
RoomCategoryFilter.ONLY_ROOMS -> query.query("isDirect == false")
|
||||
RoomCategoryFilter.ONLY_WITH_NOTIFICATIONS -> query.query("notificationCount > 0")
|
||||
null -> query
|
||||
}
|
||||
|
||||
// Timber.w("VAL: activeSpaceId : ${queryParams.activeSpaceId}")
|
||||
when (queryParams.spaceFilter) {
|
||||
query = when (queryParams.spaceFilter) {
|
||||
SpaceFilter.OrphanRooms -> {
|
||||
// orphan rooms
|
||||
query.isNull(RoomSummaryEntityFields.FLATTEN_PARENT_IDS)
|
||||
query.query("flattenParentIds.@count == 0")
|
||||
}
|
||||
is SpaceFilter.ActiveSpace -> {
|
||||
// It's annoying but for now realm java does not support querying in primitive list :/
|
||||
// https://github.com/realm/realm-java/issues/5361
|
||||
query.contains(RoomSummaryEntityFields.FLATTEN_PARENT_IDS, queryParams.spaceFilter.spaceId)
|
||||
query.query("ANY flattenParentIds == $0", queryParams.spaceFilter.spaceId)
|
||||
}
|
||||
is SpaceFilter.ExcludeSpace -> {
|
||||
query.not().contains(RoomSummaryEntityFields.FLATTEN_PARENT_IDS, queryParams.spaceFilter.spaceId)
|
||||
query.query("NONE flattenParentIds == $0", queryParams.spaceFilter.spaceId)
|
||||
}
|
||||
SpaceFilter.NoFilter -> Unit // nop
|
||||
SpaceFilter.NoFilter -> query // nop
|
||||
}
|
||||
|
||||
return query
|
||||
}
|
||||
|
||||
@ -344,16 +321,12 @@ internal class RoomSummaryDataSource @Inject constructor(
|
||||
val mediatorLiveData = HierarchyLiveDataHelper(spaceId, memberShips, this).liveData()
|
||||
|
||||
return Transformations.switchMap(mediatorLiveData) { allIds ->
|
||||
monarchy.findAllMappedWithChanges(
|
||||
{
|
||||
it.where<RoomSummaryEntity>()
|
||||
.`in`(RoomSummaryEntityFields.ROOM_ID, allIds.toTypedArray())
|
||||
.`in`(RoomSummaryEntityFields.MEMBERSHIP_STR, memberShips.map { it.name }.toTypedArray())
|
||||
.equalTo(RoomSummaryEntityFields.IS_DIRECT, false)
|
||||
},
|
||||
{
|
||||
roomSummaryMapper.map(it)
|
||||
})
|
||||
realmInstance.queryList(roomSummaryMapper::map) {
|
||||
it.query(RoomSummaryEntity::class)
|
||||
.queryIn("roomId", allIds)
|
||||
.process("membershipStr", memberShips)
|
||||
.query("isDirect == false")
|
||||
}.asLiveData()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
package org.matrix.android.sdk.internal.session.room.summary
|
||||
|
||||
import io.realm.Realm
|
||||
import io.realm.kotlin.TypedRealm
|
||||
import org.matrix.android.sdk.api.session.room.summary.RoomSummaryConstants
|
||||
import org.matrix.android.sdk.api.session.room.timeline.EventTypeFilter
|
||||
import org.matrix.android.sdk.api.session.room.timeline.TimelineEventFilters
|
||||
@ -33,7 +33,7 @@ internal object RoomSummaryEventsHelper {
|
||||
filterEdits = true
|
||||
)
|
||||
|
||||
fun getLatestPreviewableEvent(realm: Realm, roomId: String): TimelineEventEntity? {
|
||||
fun getLatestPreviewableEvent(realm: TypedRealm, roomId: String): TimelineEventEntity? {
|
||||
return TimelineEventEntity.latestEvent(
|
||||
realm = realm,
|
||||
roomId = roomId,
|
||||
|
@ -18,6 +18,7 @@ package org.matrix.android.sdk.internal.session.room.summary
|
||||
|
||||
import io.realm.Realm
|
||||
import io.realm.kotlin.MutableRealm
|
||||
import io.realm.kotlin.TypedRealm
|
||||
import io.realm.kotlin.createObject
|
||||
import io.realm.kotlin.deleteFromRealm
|
||||
import kotlinx.coroutines.runBlocking
|
||||
@ -205,13 +206,13 @@ internal class RoomSummaryUpdater @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
private fun RoomSummaryEntity.updateHasFailedSending() {
|
||||
private fun RoomSummaryEntity.updateHasFailedSending(realm: TypedRealm) {
|
||||
hasFailedSending = TimelineEventEntity.findAllInRoomWithSendStates(realm, roomId, SendState.HAS_FAILED_STATES).isNotEmpty()
|
||||
}
|
||||
|
||||
fun updateSendingInformation(realm: Realm, roomId: String) {
|
||||
fun updateSendingInformation(realm: MutableRealm, roomId: String) {
|
||||
val roomSummaryEntity = RoomSummaryEntity.getOrCreate(realm, roomId)
|
||||
roomSummaryEntity.updateHasFailedSending()
|
||||
roomSummaryEntity.updateHasFailedSending(realm)
|
||||
roomSummaryEntity.latestPreviewableEvent = RoomSummaryEventsHelper.getLatestPreviewableEvent(realm, roomId)
|
||||
}
|
||||
|
||||
@ -220,11 +221,12 @@ internal class RoomSummaryUpdater @Inject constructor(
|
||||
*/
|
||||
fun validateSpaceRelationship(realm: MutableRealm) {
|
||||
measureTimeMillis {
|
||||
val lookupMap = realm.where(RoomSummaryEntity::class.java)
|
||||
.process(RoomSummaryEntityFields.MEMBERSHIP_STR, Membership.activeMemberships())
|
||||
val lookupMap = realm.query(RoomSummaryEntity::class)
|
||||
.process("membershipStr", Membership.activeMemberships())
|
||||
// we order by roomID to be consistent when breaking parent/child cycles
|
||||
.sort(RoomSummaryEntityFields.ROOM_ID)
|
||||
.findAll().map {
|
||||
.sort("roomId")
|
||||
.find()
|
||||
.map {
|
||||
it.flattenParentIds = null
|
||||
it.directParentNames.clear()
|
||||
it to emptyList<RoomSummaryEntity>().toMutableSet()
|
||||
|
Loading…
x
Reference in New Issue
Block a user