forked from GitHub-Mirror/riotX-android
WIP: Start to make permalink works
This commit is contained in:
parent
9f79a5132d
commit
0611661c46
@ -16,8 +16,9 @@ internal fun ChunkEntity.deleteOnCascade() {
|
|||||||
this.deleteFromRealm()
|
this.deleteFromRealm()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// By default if a chunk is empty we consider it unlinked
|
||||||
internal fun ChunkEntity.isUnlinked(): Boolean {
|
internal fun ChunkEntity.isUnlinked(): Boolean {
|
||||||
return events.where().equalTo(EventEntityFields.IS_UNLINKED, true).findAll().isNotEmpty()
|
return events.where().equalTo(EventEntityFields.IS_UNLINKED, false).findAll().isEmpty()
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun ChunkEntity.merge(chunkToMerge: ChunkEntity,
|
internal fun ChunkEntity.merge(chunkToMerge: ChunkEntity,
|
||||||
@ -89,7 +90,7 @@ internal fun ChunkEntity.add(event: Event,
|
|||||||
|
|
||||||
internal fun ChunkEntity.lastStateIndex(direction: PaginationDirection, defaultValue: Int = 0): Int {
|
internal fun ChunkEntity.lastStateIndex(direction: PaginationDirection, defaultValue: Int = 0): Int {
|
||||||
return when (direction) {
|
return when (direction) {
|
||||||
PaginationDirection.FORWARDS -> events.where().sort(EventEntityFields.STATE_INDEX, Sort.DESCENDING).findFirst()?.stateIndex
|
PaginationDirection.FORWARDS -> events.where().sort(EventEntityFields.STATE_INDEX, Sort.DESCENDING).findFirst()?.stateIndex
|
||||||
PaginationDirection.BACKWARDS -> events.where().sort(EventEntityFields.STATE_INDEX, Sort.ASCENDING).findFirst()?.stateIndex
|
PaginationDirection.BACKWARDS -> events.where().sort(EventEntityFields.STATE_INDEX, Sort.ASCENDING).findFirst()?.stateIndex
|
||||||
} ?: defaultValue
|
} ?: defaultValue
|
||||||
}
|
}
|
@ -18,6 +18,12 @@ internal open class EventEntity(var eventId: String = "",
|
|||||||
var isUnlinked: Boolean = false
|
var isUnlinked: Boolean = false
|
||||||
) : RealmObject() {
|
) : RealmObject() {
|
||||||
|
|
||||||
|
enum class LinkFilterMode {
|
||||||
|
LINKED_ONLY,
|
||||||
|
UNLINKED_ONLY,
|
||||||
|
BOTH
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val DEFAULT_STATE_INDEX = Int.MIN_VALUE
|
const val DEFAULT_STATE_INDEX = Int.MIN_VALUE
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import im.vector.matrix.android.internal.database.model.RoomEntityFields
|
|||||||
import io.realm.Realm
|
import io.realm.Realm
|
||||||
import io.realm.RealmQuery
|
import io.realm.RealmQuery
|
||||||
import io.realm.RealmResults
|
import io.realm.RealmResults
|
||||||
|
import io.realm.kotlin.createObject
|
||||||
import io.realm.kotlin.where
|
import io.realm.kotlin.where
|
||||||
|
|
||||||
internal fun ChunkEntity.Companion.where(realm: Realm, roomId: String): RealmQuery<ChunkEntity> {
|
internal fun ChunkEntity.Companion.where(realm: Realm, roomId: String): RealmQuery<ChunkEntity> {
|
||||||
@ -34,4 +35,11 @@ internal fun ChunkEntity.Companion.findAllIncludingEvents(realm: Realm, eventIds
|
|||||||
return realm.where<ChunkEntity>()
|
return realm.where<ChunkEntity>()
|
||||||
.`in`(ChunkEntityFields.EVENTS.EVENT_ID, eventIds.toTypedArray())
|
.`in`(ChunkEntityFields.EVENTS.EVENT_ID, eventIds.toTypedArray())
|
||||||
.findAll()
|
.findAll()
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun ChunkEntity.Companion.create(realm: Realm, prevToken: String?, nextToken: String?): ChunkEntity {
|
||||||
|
return realm.createObject<ChunkEntity>().apply {
|
||||||
|
this.prevToken = prevToken
|
||||||
|
this.nextToken = nextToken
|
||||||
|
}
|
||||||
}
|
}
|
@ -2,6 +2,7 @@ package im.vector.matrix.android.internal.database.query
|
|||||||
|
|
||||||
import im.vector.matrix.android.internal.database.model.ChunkEntityFields
|
import im.vector.matrix.android.internal.database.model.ChunkEntityFields
|
||||||
import im.vector.matrix.android.internal.database.model.EventEntity
|
import im.vector.matrix.android.internal.database.model.EventEntity
|
||||||
|
import im.vector.matrix.android.internal.database.model.EventEntity.LinkFilterMode.*
|
||||||
import im.vector.matrix.android.internal.database.model.EventEntityFields
|
import im.vector.matrix.android.internal.database.model.EventEntityFields
|
||||||
import im.vector.matrix.android.internal.database.model.RoomEntityFields
|
import im.vector.matrix.android.internal.database.model.RoomEntityFields
|
||||||
import io.realm.Realm
|
import io.realm.Realm
|
||||||
@ -15,7 +16,10 @@ internal fun EventEntity.Companion.where(realm: Realm, eventId: String): RealmQu
|
|||||||
.equalTo(EventEntityFields.EVENT_ID, eventId)
|
.equalTo(EventEntityFields.EVENT_ID, eventId)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun EventEntity.Companion.where(realm: Realm, roomId: String? = null, type: String? = null): RealmQuery<EventEntity> {
|
internal fun EventEntity.Companion.where(realm: Realm,
|
||||||
|
roomId: String? = null,
|
||||||
|
type: String? = null,
|
||||||
|
linkFilterMode: EventEntity.LinkFilterMode = LINKED_ONLY): RealmQuery<EventEntity> {
|
||||||
val query = realm.where<EventEntity>()
|
val query = realm.where<EventEntity>()
|
||||||
if (roomId != null) {
|
if (roomId != null) {
|
||||||
query.beginGroup()
|
query.beginGroup()
|
||||||
@ -27,8 +31,11 @@ internal fun EventEntity.Companion.where(realm: Realm, roomId: String? = null, t
|
|||||||
if (type != null) {
|
if (type != null) {
|
||||||
query.equalTo(EventEntityFields.TYPE, type)
|
query.equalTo(EventEntityFields.TYPE, type)
|
||||||
}
|
}
|
||||||
query.notEqualTo(EventEntityFields.IS_UNLINKED, true)
|
return when (linkFilterMode) {
|
||||||
return query
|
LINKED_ONLY -> query.equalTo(EventEntityFields.IS_UNLINKED, false)
|
||||||
|
UNLINKED_ONLY -> query.equalTo(EventEntityFields.IS_UNLINKED, true)
|
||||||
|
BOTH -> query
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun RealmQuery<EventEntity>.next(from: Int? = null, strict: Boolean = true): EventEntity? {
|
internal fun RealmQuery<EventEntity>.next(from: Int? = null, strict: Boolean = true): EventEntity? {
|
||||||
|
@ -16,23 +16,26 @@ internal class RoomMemberExtractor(private val realm: Realm,
|
|||||||
|
|
||||||
fun extractFrom(event: EventEntity): RoomMember? {
|
fun extractFrom(event: EventEntity): RoomMember? {
|
||||||
val sender = event.sender ?: return null
|
val sender = event.sender ?: return null
|
||||||
|
// If the event is unlinked we want to fetch unlinked state events
|
||||||
|
val unlinked = event.isUnlinked
|
||||||
// When stateIndex is negative, we try to get the next stateEvent prevContent()
|
// When stateIndex is negative, we try to get the next stateEvent prevContent()
|
||||||
// If prevContent is null we fallback to the Int.MIN state events content()
|
// If prevContent is null we fallback to the Int.MIN state events content()
|
||||||
val roomMember: RoomMember? = if (event.stateIndex <= 0) {
|
return if (event.stateIndex <= 0) {
|
||||||
baseQuery(realm, roomId, sender).next(from = event.stateIndex)?.asDomain()?.prevContent()
|
baseQuery(realm, roomId, sender, unlinked).next(from = event.stateIndex)?.asDomain()?.prevContent()
|
||||||
?: baseQuery(realm, roomId, sender).last(since = event.stateIndex)?.asDomain()?.content()
|
?: baseQuery(realm, roomId, sender, unlinked).last(since = event.stateIndex)?.asDomain()?.content()
|
||||||
} else {
|
} else {
|
||||||
baseQuery(realm, roomId, sender).last(since = event.stateIndex)?.asDomain()?.content()
|
baseQuery(realm, roomId, sender, unlinked).last(since = event.stateIndex)?.asDomain()?.content()
|
||||||
}
|
}
|
||||||
return roomMember
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun baseQuery(realm: Realm,
|
private fun baseQuery(realm: Realm,
|
||||||
roomId: String,
|
roomId: String,
|
||||||
sender: String): RealmQuery<EventEntity> {
|
sender: String,
|
||||||
|
isUnlinked: Boolean): RealmQuery<EventEntity> {
|
||||||
|
val filterMode = if (isUnlinked) EventEntity.LinkFilterMode.UNLINKED_ONLY else EventEntity.LinkFilterMode.LINKED_ONLY
|
||||||
|
|
||||||
return EventEntity
|
return EventEntity
|
||||||
.where(realm, roomId = roomId, type = EventType.STATE_ROOM_MEMBER)
|
.where(realm, roomId = roomId, type = EventType.STATE_ROOM_MEMBER, linkFilterMode = filterMode)
|
||||||
.equalTo(EventEntityFields.STATE_KEY, sender)
|
.equalTo(EventEntityFields.STATE_KEY, sender)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ import im.vector.matrix.android.internal.database.model.EventEntity
|
|||||||
import im.vector.matrix.android.internal.database.model.EventEntityFields
|
import im.vector.matrix.android.internal.database.model.EventEntityFields
|
||||||
import im.vector.matrix.android.internal.database.query.where
|
import im.vector.matrix.android.internal.database.query.where
|
||||||
import im.vector.matrix.android.internal.session.events.interceptor.MessageEventInterceptor
|
import im.vector.matrix.android.internal.session.events.interceptor.MessageEventInterceptor
|
||||||
|
import im.vector.matrix.android.internal.util.tryTransactionSync
|
||||||
import io.realm.Realm
|
import io.realm.Realm
|
||||||
import io.realm.RealmQuery
|
import io.realm.RealmQuery
|
||||||
|
|
||||||
@ -33,6 +34,7 @@ internal class DefaultTimelineHolder(private val roomId: String,
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun timeline(eventId: String?): LiveData<PagedList<EnrichedEvent>> {
|
override fun timeline(eventId: String?): LiveData<PagedList<EnrichedEvent>> {
|
||||||
|
clearUnlinkedEvents()
|
||||||
if (eventId != null) {
|
if (eventId != null) {
|
||||||
fetchEventIfNeeded(eventId)
|
fetchEventIfNeeded(eventId)
|
||||||
}
|
}
|
||||||
@ -62,6 +64,16 @@ internal class DefaultTimelineHolder(private val roomId: String,
|
|||||||
return monarchy.findAllPagedWithChanges(realmDataSourceFactory, livePagedListBuilder)
|
return monarchy.findAllPagedWithChanges(realmDataSourceFactory, livePagedListBuilder)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun clearUnlinkedEvents() {
|
||||||
|
monarchy.tryTransactionSync { realm ->
|
||||||
|
val unlinkedEvents = EventEntity
|
||||||
|
.where(realm, roomId = roomId)
|
||||||
|
.equalTo(EventEntityFields.IS_UNLINKED, true)
|
||||||
|
.findAll()
|
||||||
|
unlinkedEvents.deleteAllFromRealm()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun fetchEventIfNeeded(eventId: String) {
|
private fun fetchEventIfNeeded(eventId: String) {
|
||||||
if (!isEventPersisted(eventId)) {
|
if (!isEventPersisted(eventId)) {
|
||||||
contextOfEventRequest.execute(roomId, eventId, object : MatrixCallback<EventContextResponse> {})
|
contextOfEventRequest.execute(roomId, eventId, object : MatrixCallback<EventContextResponse> {})
|
||||||
@ -79,11 +91,11 @@ internal class DefaultTimelineHolder(private val roomId: String,
|
|||||||
private fun buildDataSourceFactoryQuery(realm: Realm, eventId: String?): RealmQuery<EventEntity> {
|
private fun buildDataSourceFactoryQuery(realm: Realm, eventId: String?): RealmQuery<EventEntity> {
|
||||||
val query = if (eventId == null) {
|
val query = if (eventId == null) {
|
||||||
EventEntity
|
EventEntity
|
||||||
.where(realm, roomId = roomId)
|
.where(realm, roomId = roomId, linkFilterMode = EventEntity.LinkFilterMode.LINKED_ONLY)
|
||||||
.equalTo("${EventEntityFields.CHUNK}.${ChunkEntityFields.IS_LAST}", true)
|
.equalTo("${EventEntityFields.CHUNK}.${ChunkEntityFields.IS_LAST}", true)
|
||||||
} else {
|
} else {
|
||||||
EventEntity
|
EventEntity
|
||||||
.where(realm, roomId = roomId)
|
.where(realm, roomId = roomId, linkFilterMode = EventEntity.LinkFilterMode.BOTH)
|
||||||
.`in`("${EventEntityFields.CHUNK}.${ChunkEntityFields.EVENTS.EVENT_ID}", arrayOf(eventId))
|
.`in`("${EventEntityFields.CHUNK}.${ChunkEntityFields.EVENTS.EVENT_ID}", arrayOf(eventId))
|
||||||
}
|
}
|
||||||
return query.sort(EventEntityFields.DISPLAY_INDEX)
|
return query.sort(EventEntityFields.DISPLAY_INDEX)
|
||||||
|
@ -7,10 +7,10 @@ import im.vector.matrix.android.api.session.events.model.Event
|
|||||||
@JsonClass(generateAdapter = true)
|
@JsonClass(generateAdapter = true)
|
||||||
data class EventContextResponse(
|
data class EventContextResponse(
|
||||||
@Json(name = "event") val event: Event,
|
@Json(name = "event") val event: Event,
|
||||||
@Json(name = "start") override val prevToken: String? = null,
|
@Json(name = "start") override val start: String? = null,
|
||||||
@Json(name = "events_before") val eventsBefore: List<Event> = emptyList(),
|
@Json(name = "events_before") val eventsBefore: List<Event> = emptyList(),
|
||||||
@Json(name = "events_after") val eventsAfter: List<Event> = emptyList(),
|
@Json(name = "events_after") val eventsAfter: List<Event> = emptyList(),
|
||||||
@Json(name = "end") override val nextToken: String? = null,
|
@Json(name = "end") override val end: String? = null,
|
||||||
@Json(name = "state") override val stateEvents: List<Event> = emptyList()
|
@Json(name = "state") override val stateEvents: List<Event> = emptyList()
|
||||||
) : TokenChunkEvent {
|
) : TokenChunkEvent {
|
||||||
|
|
||||||
|
@ -6,8 +6,8 @@ import im.vector.matrix.android.api.session.events.model.Event
|
|||||||
|
|
||||||
@JsonClass(generateAdapter = true)
|
@JsonClass(generateAdapter = true)
|
||||||
internal data class PaginationResponse(
|
internal data class PaginationResponse(
|
||||||
@Json(name = "start") override val nextToken: String? = null,
|
@Json(name = "start") override val start: String? = null,
|
||||||
@Json(name = "end") override val prevToken: String? = null,
|
@Json(name = "end") override val end: String? = null,
|
||||||
@Json(name = "chunk") override val events: List<Event> = emptyList(),
|
@Json(name = "chunk") override val events: List<Event> = emptyList(),
|
||||||
@Json(name = "state") override val stateEvents: List<Event> = emptyList()
|
@Json(name = "state") override val stateEvents: List<Event> = emptyList()
|
||||||
) : TokenChunkEvent
|
) : TokenChunkEvent
|
@ -3,8 +3,8 @@ package im.vector.matrix.android.internal.session.room.timeline
|
|||||||
import im.vector.matrix.android.api.session.events.model.Event
|
import im.vector.matrix.android.api.session.events.model.Event
|
||||||
|
|
||||||
internal interface TokenChunkEvent {
|
internal interface TokenChunkEvent {
|
||||||
val nextToken: String?
|
val start: String?
|
||||||
val prevToken: String?
|
val end: String?
|
||||||
val events: List<Event>
|
val events: List<Event>
|
||||||
val stateEvents: List<Event>
|
val stateEvents: List<Event>
|
||||||
}
|
}
|
@ -5,11 +5,11 @@ import com.zhuinden.monarchy.Monarchy
|
|||||||
import im.vector.matrix.android.internal.database.helper.*
|
import im.vector.matrix.android.internal.database.helper.*
|
||||||
import im.vector.matrix.android.internal.database.model.ChunkEntity
|
import im.vector.matrix.android.internal.database.model.ChunkEntity
|
||||||
import im.vector.matrix.android.internal.database.model.RoomEntity
|
import im.vector.matrix.android.internal.database.model.RoomEntity
|
||||||
|
import im.vector.matrix.android.internal.database.query.create
|
||||||
import im.vector.matrix.android.internal.database.query.find
|
import im.vector.matrix.android.internal.database.query.find
|
||||||
import im.vector.matrix.android.internal.database.query.findAllIncludingEvents
|
import im.vector.matrix.android.internal.database.query.findAllIncludingEvents
|
||||||
import im.vector.matrix.android.internal.database.query.where
|
import im.vector.matrix.android.internal.database.query.where
|
||||||
import im.vector.matrix.android.internal.util.tryTransactionSync
|
import im.vector.matrix.android.internal.util.tryTransactionSync
|
||||||
import io.realm.kotlin.createObject
|
|
||||||
|
|
||||||
|
|
||||||
internal class TokenChunkEventPersistor(private val monarchy: Monarchy) {
|
internal class TokenChunkEventPersistor(private val monarchy: Monarchy) {
|
||||||
@ -23,51 +23,67 @@ internal class TokenChunkEventPersistor(private val monarchy: Monarchy) {
|
|||||||
val roomEntity = RoomEntity.where(realm, roomId).findFirst()
|
val roomEntity = RoomEntity.where(realm, roomId).findFirst()
|
||||||
?: throw IllegalStateException("You shouldn't use this method without a room")
|
?: throw IllegalStateException("You shouldn't use this method without a room")
|
||||||
|
|
||||||
// We create a new chunk with prev and next token as a base
|
val nextToken: String?
|
||||||
// In case of permalink, we may not encounter other chunks, so it can be added
|
val prevToken: String?
|
||||||
// By default, it's an unlinked chunk
|
if (direction == PaginationDirection.FORWARDS) {
|
||||||
val newChunk = realm.createObject<ChunkEntity>().apply {
|
nextToken = receivedChunk.end
|
||||||
prevToken = receivedChunk.prevToken
|
prevToken = receivedChunk.start
|
||||||
nextToken = receivedChunk.nextToken
|
} else {
|
||||||
|
nextToken = receivedChunk.start
|
||||||
|
prevToken = receivedChunk.end
|
||||||
}
|
}
|
||||||
newChunk.addAll(receivedChunk.events, direction, isUnlinked = true)
|
val prevChunk = ChunkEntity.find(realm, roomId, nextToken = prevToken)
|
||||||
|
val nextChunk = ChunkEntity.find(realm, roomId, prevToken = nextToken)
|
||||||
|
|
||||||
// The current chunk is the one we will keep all along the merge process.
|
// The current chunk is the one we will keep all along the merge process.
|
||||||
var currentChunk = newChunk
|
// We try to look for a chunk next to the token,
|
||||||
val prevChunk = ChunkEntity.find(realm, roomId, nextToken = receivedChunk.prevToken)
|
// otherwise we create a whole new one
|
||||||
val nextChunk = ChunkEntity.find(realm, roomId, prevToken = receivedChunk.nextToken)
|
|
||||||
|
|
||||||
// We always merge the bottom chunk into top chunk, so we are always merging backwards
|
var currentChunk = if (direction == PaginationDirection.FORWARDS) {
|
||||||
if (prevChunk != null) {
|
prevChunk?.apply { this.nextToken = nextToken }
|
||||||
newChunk.merge(prevChunk, PaginationDirection.BACKWARDS)
|
?: ChunkEntity.create(realm, prevToken, nextToken)
|
||||||
roomEntity.deleteOnCascade(prevChunk)
|
} else {
|
||||||
|
nextChunk?.apply { this.prevToken = prevToken }
|
||||||
|
?: ChunkEntity.create(realm, prevToken, nextToken)
|
||||||
}
|
}
|
||||||
if (nextChunk != null) {
|
|
||||||
nextChunk.merge(newChunk, PaginationDirection.BACKWARDS)
|
|
||||||
roomEntity.deleteOnCascade(newChunk)
|
|
||||||
currentChunk = nextChunk
|
|
||||||
}
|
|
||||||
val newEventIds = receivedChunk.events.mapNotNull { it.eventId }
|
|
||||||
ChunkEntity
|
|
||||||
.findAllIncludingEvents(realm, newEventIds)
|
|
||||||
.filter { it != currentChunk }
|
|
||||||
.forEach { overlapped ->
|
|
||||||
if (direction == PaginationDirection.BACKWARDS) {
|
|
||||||
currentChunk.merge(overlapped, PaginationDirection.BACKWARDS)
|
|
||||||
roomEntity.deleteOnCascade(overlapped)
|
|
||||||
} else {
|
|
||||||
overlapped.merge(currentChunk, PaginationDirection.BACKWARDS)
|
|
||||||
roomEntity.deleteOnCascade(currentChunk)
|
|
||||||
currentChunk = overlapped
|
|
||||||
}
|
|
||||||
}
|
|
||||||
roomEntity.addOrUpdate(currentChunk)
|
|
||||||
|
|
||||||
// TODO : there is an issue with the pagination sending unwanted room member events
|
|
||||||
val isUnlinked = currentChunk.isUnlinked()
|
val isUnlinked = currentChunk.isUnlinked()
|
||||||
|
currentChunk.addAll(receivedChunk.events, direction, isUnlinked = isUnlinked)
|
||||||
|
|
||||||
|
// Then we merge chunks if needed
|
||||||
|
if (currentChunk != prevChunk && prevChunk != null) {
|
||||||
|
currentChunk = handleMerge(roomEntity, direction, currentChunk, prevChunk)
|
||||||
|
} else if (currentChunk != nextChunk && nextChunk != null) {
|
||||||
|
currentChunk = handleMerge(roomEntity, direction, currentChunk, nextChunk)
|
||||||
|
} else {
|
||||||
|
val newEventIds = receivedChunk.events.mapNotNull { it.eventId }
|
||||||
|
ChunkEntity
|
||||||
|
.findAllIncludingEvents(realm, newEventIds)
|
||||||
|
.filter { it != currentChunk }
|
||||||
|
.forEach { overlapped ->
|
||||||
|
currentChunk = handleMerge(roomEntity, direction, currentChunk, overlapped)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
roomEntity.addOrUpdate(currentChunk)
|
||||||
roomEntity.addStateEvents(receivedChunk.stateEvents, isUnlinked = isUnlinked)
|
roomEntity.addStateEvents(receivedChunk.stateEvents, isUnlinked = isUnlinked)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun handleMerge(roomEntity: RoomEntity,
|
||||||
|
direction: PaginationDirection,
|
||||||
|
currentChunk: ChunkEntity,
|
||||||
|
otherChunk: ChunkEntity): ChunkEntity {
|
||||||
|
|
||||||
|
// We always merge the bottom chunk into top chunk, so we are always merging backwards
|
||||||
|
return if (direction == PaginationDirection.BACKWARDS) {
|
||||||
|
currentChunk.merge(otherChunk, PaginationDirection.BACKWARDS)
|
||||||
|
roomEntity.deleteOnCascade(otherChunk)
|
||||||
|
currentChunk
|
||||||
|
} else {
|
||||||
|
otherChunk.merge(currentChunk, PaginationDirection.BACKWARDS)
|
||||||
|
roomEntity.deleteOnCascade(currentChunk)
|
||||||
|
otherChunk
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user