Room sending: fix again loss of number type

This commit is contained in:
ganfra 2020-09-18 18:33:49 +02:00
parent 72f8c8ef72
commit 2717cca267
4 changed files with 24 additions and 11 deletions

View file

@ -20,21 +20,34 @@ package org.matrix.android.sdk.internal.database.mapper
import org.matrix.android.sdk.api.session.events.model.Content import org.matrix.android.sdk.api.session.events.model.Content
import org.matrix.android.sdk.api.util.JSON_DICT_PARAMETERIZED_TYPE import org.matrix.android.sdk.api.util.JSON_DICT_PARAMETERIZED_TYPE
import org.matrix.android.sdk.internal.di.MoshiProvider import org.matrix.android.sdk.internal.di.MoshiProvider
import org.matrix.android.sdk.internal.network.parsing.CheckNumberType
internal object ContentMapper { internal object ContentMapper {
private val moshi = MoshiProvider.providesMoshi() private val moshi = MoshiProvider.providesMoshi()
private val adapter = moshi.adapter<Content>(JSON_DICT_PARAMETERIZED_TYPE) private val castJsonNumberMoshi by lazy {
// We are adding the CheckNumberType as we are serializing/deserializing multiple time in a row
// and we lost typing information doing so.
// We don't want this check to be done on all adapters, so we create a new moshi just for that.
MoshiProvider.providesMoshi()
.newBuilder()
.add(CheckNumberType.JSON_ADAPTER_FACTORY)
.build()
}
fun map(content: String?): Content? { fun map(content: String?, castJsonNumbers: Boolean = false): Content? {
return content?.let { return content?.let {
adapter.fromJson(it) if (castJsonNumbers) {
castJsonNumberMoshi
} else {
moshi
}.adapter<Content>(JSON_DICT_PARAMETERIZED_TYPE).fromJson(it)
} }
} }
fun map(content: Content?): String? { fun map(content: Content?): String? {
return content?.let { return content?.let {
adapter.toJson(it) moshi.adapter<Content>(JSON_DICT_PARAMETERIZED_TYPE).toJson(it)
} }
} }
} }

View file

@ -54,7 +54,7 @@ internal object EventMapper {
return eventEntity return eventEntity
} }
fun map(eventEntity: EventEntity): Event { fun map(eventEntity: EventEntity, castJsonNumbers: Boolean = false): Event {
val ud = eventEntity.unsignedData val ud = eventEntity.unsignedData
?.takeIf { it.isNotBlank() } ?.takeIf { it.isNotBlank() }
?.let { ?.let {
@ -69,8 +69,8 @@ internal object EventMapper {
return Event( return Event(
type = eventEntity.type, type = eventEntity.type,
eventId = eventEntity.eventId, eventId = eventEntity.eventId,
content = ContentMapper.map(eventEntity.content), content = ContentMapper.map(eventEntity.content, castJsonNumbers),
prevContent = ContentMapper.map(eventEntity.prevContent), prevContent = ContentMapper.map(eventEntity.prevContent, castJsonNumbers),
originServerTs = eventEntity.originServerTs, originServerTs = eventEntity.originServerTs,
senderId = eventEntity.sender, senderId = eventEntity.sender,
stateKey = eventEntity.stateKey, stateKey = eventEntity.stateKey,
@ -96,8 +96,8 @@ internal object EventMapper {
} }
} }
internal fun EventEntity.asDomain(): Event { internal fun EventEntity.asDomain(castJsonNumbers: Boolean = false): Event {
return EventMapper.map(this) return EventMapper.map(this, castJsonNumbers)
} }
internal fun Event.toEntity(roomId: String, sendState: SendState, ageLocalTs: Long?): EventEntity { internal fun Event.toEntity(roomId: String, sendState: SendState, ageLocalTs: Long?): EventEntity {

View file

@ -49,7 +49,7 @@ interface CheckNumberType {
val numberAsString = reader.nextString() val numberAsString = reader.nextString()
val decimal = BigDecimal(numberAsString) val decimal = BigDecimal(numberAsString)
if (decimal.scale() <= 0) { if (decimal.scale() <= 0) {
decimal.intValueExact() decimal.longValueExact()
} else { } else {
decimal.toDouble() decimal.toDouble()
} }

View file

@ -122,7 +122,7 @@ internal class LocalEchoRepository @Inject constructor(@SessionDatabase private
suspend fun getUpToDateEcho(eventId: String): Event? { suspend fun getUpToDateEcho(eventId: String): Event? {
// We are using awaitTransaction here to make sure this executes after other transactions // We are using awaitTransaction here to make sure this executes after other transactions
return monarchy.awaitTransaction { realm -> return monarchy.awaitTransaction { realm ->
EventEntity.where(realm, eventId).findFirst()?.asDomain() EventEntity.where(realm, eventId).findFirst()?.asDomain(castJsonNumbers = true)
} }
} }