diff --git a/CHANGELOG.md b/CHANGELOG.md index eb46097388..8655c7a2c9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,7 +27,7 @@ This release will bump the Realm file format from version 23 to 24. Opening a fi * Minimum R8: 8.0.34. ### Internal -* None +* Updated to Realm Core 14.0.0-beta, commit 4926641c6cf2948fa494624ee802bb8cbc21387f. ## 1.13.1-SNAPSHOT (YYYY-MM-DD) diff --git a/packages/cinterop/src/commonMain/kotlin/io/realm/kotlin/internal/interop/RealmEnums.kt b/packages/cinterop/src/commonMain/kotlin/io/realm/kotlin/internal/interop/RealmEnums.kt index 3970840586..36f25fa852 100644 --- a/packages/cinterop/src/commonMain/kotlin/io/realm/kotlin/internal/interop/RealmEnums.kt +++ b/packages/cinterop/src/commonMain/kotlin/io/realm/kotlin/internal/interop/RealmEnums.kt @@ -96,6 +96,5 @@ expect enum class ValueType { RLM_TYPE_LINK, RLM_TYPE_UUID, RLM_TYPE_LIST, - RLM_TYPE_SET, RLM_TYPE_DICTIONARY, } diff --git a/packages/cinterop/src/commonMain/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt b/packages/cinterop/src/commonMain/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt index 382f3ae008..55a34904a9 100644 --- a/packages/cinterop/src/commonMain/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt +++ b/packages/cinterop/src/commonMain/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt @@ -291,7 +291,6 @@ expect object RealmInterop { isDefault: Boolean ) fun realm_set_embedded(obj: RealmObjectPointer, key: PropertyKey): RealmObjectPointer - fun realm_set_set(obj: RealmObjectPointer, key: PropertyKey): RealmSetPointer fun realm_set_list(obj: RealmObjectPointer, key: PropertyKey): RealmListPointer fun realm_set_dictionary(obj: RealmObjectPointer, key: PropertyKey): RealmMapPointer fun realm_object_add_int(obj: RealmObjectPointer, key: PropertyKey, value: Long) @@ -305,17 +304,14 @@ expect object RealmInterop { fun realm_get_backlinks(obj: RealmObjectPointer, sourceClassKey: ClassKey, sourcePropertyKey: PropertyKey): RealmResultsPointer fun realm_list_size(list: RealmListPointer): Long fun MemAllocator.realm_list_get(list: RealmListPointer, index: Long): RealmValue - fun realm_list_get_set(list: RealmListPointer, index: Long): RealmSetPointer fun realm_list_get_list(list: RealmListPointer, index: Long): RealmListPointer fun realm_list_get_dictionary(list: RealmListPointer, index: Long): RealmMapPointer fun realm_list_add(list: RealmListPointer, index: Long, transport: RealmValue) fun realm_list_insert_embedded(list: RealmListPointer, index: Long): RealmObjectPointer // Returns the element previously at the specified position fun realm_list_set(list: RealmListPointer, index: Long, inputTransport: RealmValue) - fun realm_list_insert_set(list: RealmListPointer, index: Long): RealmSetPointer fun realm_list_insert_list(list: RealmListPointer, index: Long): RealmListPointer fun realm_list_insert_dictionary(list: RealmListPointer, index: Long): RealmMapPointer - fun realm_list_set_set(list: RealmListPointer, index: Long): RealmSetPointer fun realm_list_set_list(list: RealmListPointer, index: Long): RealmListPointer fun realm_list_set_dictionary(list: RealmListPointer, index: Long): RealmMapPointer @@ -349,10 +345,6 @@ expect object RealmInterop { dictionary: RealmMapPointer, mapKey: RealmValue ): RealmValue - fun realm_dictionary_find_set( - dictionary: RealmMapPointer, - mapKey: RealmValue - ): RealmSetPointer fun realm_dictionary_find_list( dictionary: RealmMapPointer, mapKey: RealmValue @@ -387,7 +379,6 @@ expect object RealmInterop { dictionary: RealmMapPointer, mapKey: RealmValue ): RealmValue - fun realm_dictionary_insert_set(dictionary: RealmMapPointer, mapKey: RealmValue): RealmSetPointer fun realm_dictionary_insert_list(dictionary: RealmMapPointer, mapKey: RealmValue): RealmListPointer fun realm_dictionary_insert_dictionary(dictionary: RealmMapPointer, mapKey: RealmValue): RealmMapPointer fun realm_dictionary_get_keys(dictionary: RealmMapPointer): RealmResultsPointer @@ -454,7 +445,6 @@ expect object RealmInterop { // FIXME OPTIMIZE Get many fun MemAllocator.realm_results_get(results: RealmResultsPointer, index: Long): RealmValue - fun realm_results_get_set(results: RealmResultsPointer, index: Long): RealmSetPointer fun realm_results_get_list(results: RealmResultsPointer, index: Long): RealmListPointer fun realm_results_get_dictionary(results: RealmResultsPointer, index: Long): RealmMapPointer fun realm_results_delete_all(results: RealmResultsPointer) diff --git a/packages/cinterop/src/jvm/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt b/packages/cinterop/src/jvm/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt index 27bd106a11..31c13956f8 100644 --- a/packages/cinterop/src/jvm/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt +++ b/packages/cinterop/src/jvm/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt @@ -500,10 +500,6 @@ actual object RealmInterop { return LongPointerWrapper(realmc.realm_set_embedded(obj.cptr(), key.key)) } - actual fun realm_set_set(obj: RealmObjectPointer, key: PropertyKey): RealmSetPointer { - realmc.realm_set_set(obj.cptr(), key.key) - return realm_get_set(obj, key) - } actual fun realm_set_list(obj: RealmObjectPointer, key: PropertyKey): RealmListPointer { realmc.realm_set_list(obj.cptr(), key.key) return realm_get_list(obj, key) @@ -569,8 +565,6 @@ actual object RealmInterop { realmc.realm_list_get(list.cptr(), index, struct) return RealmValue(struct) } - actual fun realm_list_get_set(list: RealmListPointer, index: Long): RealmSetPointer = - LongPointerWrapper(realmc.realm_list_get_set(list.cptr(), index)) actual fun realm_list_get_list(list: RealmListPointer, index: Long): RealmListPointer = LongPointerWrapper(realmc.realm_list_get_list(list.cptr(), index)) @@ -584,18 +578,12 @@ actual object RealmInterop { actual fun realm_list_insert_embedded(list: RealmListPointer, index: Long): RealmObjectPointer { return LongPointerWrapper(realmc.realm_list_insert_embedded(list.cptr(), index)) } - actual fun realm_list_insert_set(list: RealmListPointer, index: Long): RealmSetPointer { - return LongPointerWrapper(realmc.realm_list_insert_set(list.cptr(), index)) - } actual fun realm_list_insert_list(list: RealmListPointer, index: Long): RealmListPointer { return LongPointerWrapper(realmc.realm_list_insert_list(list.cptr(), index)) } actual fun realm_list_insert_dictionary(list: RealmListPointer, index: Long): RealmMapPointer { return LongPointerWrapper(realmc.realm_list_insert_dictionary(list.cptr(), index)) } - actual fun realm_list_set_set(list: RealmListPointer, index: Long): RealmSetPointer { - return LongPointerWrapper(realmc.realm_list_set_set(list.cptr(), index)) - } actual fun realm_list_set_list(list: RealmListPointer, index: Long): RealmListPointer { return LongPointerWrapper(realmc.realm_list_set_list(list.cptr(), index)) } @@ -758,12 +746,6 @@ actual object RealmInterop { realmc.realm_dictionary_find(dictionary.cptr(), mapKey.value, struct, found) return RealmValue(struct) } - actual fun realm_dictionary_find_set( - dictionary: RealmMapPointer, - mapKey: RealmValue - ): RealmSetPointer { - return LongPointerWrapper(realmc.realm_dictionary_get_set(dictionary.cptr(), mapKey.value)) - } actual fun realm_dictionary_find_list( dictionary: RealmMapPointer, @@ -845,9 +827,6 @@ actual object RealmInterop { } ) } - actual fun realm_dictionary_insert_set(dictionary: RealmMapPointer, mapKey: RealmValue): RealmSetPointer { - return LongPointerWrapper(realmc.realm_dictionary_insert_set(dictionary.cptr(), mapKey.value)) - } actual fun realm_dictionary_insert_list(dictionary: RealmMapPointer, mapKey: RealmValue): RealmListPointer { return LongPointerWrapper(realmc.realm_dictionary_insert_list(dictionary.cptr(), mapKey.value)) @@ -1927,9 +1906,6 @@ actual object RealmInterop { return RealmValue(value) } - actual fun realm_results_get_set(results: RealmResultsPointer, index: Long): RealmSetPointer = - LongPointerWrapper(realmc.realm_results_get_set(results.cptr(), index)) - actual fun realm_results_get_list(results: RealmResultsPointer, index: Long): RealmListPointer = LongPointerWrapper(realmc.realm_results_get_list(results.cptr(), index)) diff --git a/packages/cinterop/src/nativeDarwin/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt b/packages/cinterop/src/nativeDarwin/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt index a03e0b2cd8..5c17053581 100644 --- a/packages/cinterop/src/nativeDarwin/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt +++ b/packages/cinterop/src/nativeDarwin/kotlin/io/realm/kotlin/internal/interop/RealmInterop.kt @@ -966,10 +966,6 @@ actual object RealmInterop { return CPointerWrapper(realm_wrapper.realm_set_embedded(obj.cptr(), key.key)) } - actual fun realm_set_set(obj: RealmObjectPointer, key: PropertyKey): RealmSetPointer { - checkedBooleanResult(realm_wrapper.realm_set_set(obj.cptr(), key.key)) - return realm_get_set(obj, key) - } actual fun realm_set_list(obj: RealmObjectPointer, key: PropertyKey): RealmListPointer { checkedBooleanResult(realm_wrapper.realm_set_list(obj.cptr(), key.key)) return realm_get_list(obj, key) @@ -1031,8 +1027,6 @@ actual object RealmInterop { return RealmValue(struct) } - actual fun realm_list_get_set(list: RealmListPointer, index: Long): RealmSetPointer = - CPointerWrapper(realm_wrapper.realm_list_get_set(list.cptr(), index.toULong())) actual fun realm_list_get_list(list: RealmListPointer, index: Long): RealmListPointer = CPointerWrapper(realm_wrapper.realm_list_get_list(list.cptr(), index.toULong())) @@ -1048,18 +1042,12 @@ actual object RealmInterop { ) ) } - actual fun realm_list_insert_set(list: RealmListPointer, index: Long): RealmSetPointer { - return CPointerWrapper(realm_wrapper.realm_list_insert_set(list.cptr(), index.toULong())) - } actual fun realm_list_insert_list(list: RealmListPointer, index: Long): RealmListPointer { return CPointerWrapper(realm_wrapper.realm_list_insert_list(list.cptr(), index.toULong())) } actual fun realm_list_insert_dictionary(list: RealmListPointer, index: Long): RealmMapPointer { return CPointerWrapper(realm_wrapper.realm_list_insert_dictionary(list.cptr(), index.toULong())) } - actual fun realm_list_set_set(list: RealmListPointer, index: Long): RealmSetPointer { - return CPointerWrapper(realm_wrapper.realm_list_set_set(list.cptr(), index.toULong())) - } actual fun realm_list_set_list(list: RealmListPointer, index: Long): RealmListPointer { return CPointerWrapper(realm_wrapper.realm_list_set_list(list.cptr(), index.toULong())) } @@ -1281,13 +1269,6 @@ actual object RealmInterop { } } - actual fun realm_dictionary_find_set( - dictionary: RealmMapPointer, - mapKey: RealmValue - ): RealmSetPointer { - return CPointerWrapper(realm_wrapper.realm_dictionary_get_set(dictionary.cptr(), mapKey.value.readValue())) - } - actual fun realm_dictionary_find_list( dictionary: RealmMapPointer, mapKey: RealmValue @@ -1422,10 +1403,6 @@ actual object RealmInterop { return RealmValue(outputStruct) } - actual fun realm_dictionary_insert_set(dictionary: RealmMapPointer, mapKey: RealmValue): RealmSetPointer { - return CPointerWrapper(realm_wrapper.realm_dictionary_insert_set(dictionary.cptr(), mapKey.value.readValue())) - } - actual fun realm_dictionary_insert_list(dictionary: RealmMapPointer, mapKey: RealmValue): RealmListPointer { return CPointerWrapper(realm_wrapper.realm_dictionary_insert_list(dictionary.cptr(), mapKey.value.readValue())) } @@ -1689,9 +1666,6 @@ actual object RealmInterop { return RealmValue(value) } - actual fun realm_results_get_set(results: RealmResultsPointer, index: Long): RealmSetPointer = - CPointerWrapper(realm_wrapper.realm_results_get_set(results.cptr(), index.toULong())) - actual fun realm_results_get_list(results: RealmResultsPointer, index: Long): RealmListPointer = CPointerWrapper(realm_wrapper.realm_results_get_list(results.cptr(), index.toULong())) diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/ext/RealmAnyExt.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/ext/RealmAnyExt.kt index b40d27ae9b..58b52eaaaf 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/ext/RealmAnyExt.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/ext/RealmAnyExt.kt @@ -45,7 +45,6 @@ public fun realmAnyOf(value: Any?): RealmAny? { is RealmUUID -> RealmAny.create(value) is RealmObject -> RealmAny.create(value) is DynamicRealmObject -> RealmAny.create(value) - is Set<*> -> RealmAny.create(value.map { realmAnyOf(it) }.toRealmSet()) is List<*> -> RealmAny.create(value.map { realmAnyOf(it) }.toRealmList()) is Map<*, *> -> RealmAny.create( value.map { (mapKey, mapValue) -> @@ -61,15 +60,6 @@ public fun realmAnyOf(value: Any?): RealmAny? { } } -/** - * Create a [RealmAny] containing a [RealmSet] of all arguments wrapped as [RealmAny]s. - * @param values elements of the set. - * - * See [RealmAny.create] for [RealmSet] constraints and examples of usage. - */ -public fun realmAnySetOf(vararg values: Any?): RealmAny = - RealmAny.create(values.map { realmAnyOf(it) }.toRealmSet()) - /** * Create a [RealmAny] containing a [RealmList] of all arguments wrapped as [RealmAny]s. * @param values elements of the set. diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/Converters.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/Converters.kt index e33d020ab9..e13858fc0c 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/Converters.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/Converters.kt @@ -29,7 +29,6 @@ import io.realm.kotlin.internal.interop.RealmQueryArgument import io.realm.kotlin.internal.interop.RealmQueryArgumentList import io.realm.kotlin.internal.interop.RealmQueryListArgument import io.realm.kotlin.internal.interop.RealmQuerySingleArgument -import io.realm.kotlin.internal.interop.RealmSetPointer import io.realm.kotlin.internal.interop.RealmValue import io.realm.kotlin.internal.interop.Timestamp import io.realm.kotlin.internal.interop.ValueType @@ -115,7 +114,6 @@ internal inline fun realmValueToRealmAny( owner: RealmReference, issueDynamicObject: Boolean, issueDynamicMutableObject: Boolean, - getSetFunction: () -> RealmSetPointer = { error("Cannot handled embedded sets") }, getListFunction: () -> RealmListPointer = { error("Cannot handled embedded lists") }, getDictionaryFunction: () -> RealmMapPointer = { error("Cannot handled embedded dictionaries") }, ): RealmAny? { @@ -151,11 +149,6 @@ internal inline fun realmValueToRealmAny( RealmAny.create(realmObject!! as RealmObject, clazz as KClass) } } - ValueType.RLM_TYPE_SET -> { - val nativePointer = getSetFunction() - val operator = realmAnySetOperator(mediator, owner, nativePointer, issueDynamicObject, issueDynamicMutableObject) - return RealmAny.create(ManagedRealmSet(parent, nativePointer, operator)) - } ValueType.RLM_TYPE_LIST -> { val nativePointer = getListFunction() val operator = realmAnyListOperator(mediator, owner, nativePointer, issueDynamicObject, issueDynamicMutableObject) @@ -176,7 +169,6 @@ internal fun MemTrackingAllocator.realmAnyHandler( value: RealmAny?, primitiveValueAsRealmValueHandler: (RealmValue) -> T = { throw IllegalArgumentException("Operation not support for primitive values") }, referenceAsRealmAnyHandler: (RealmAny) -> T = { throw IllegalArgumentException("Operation not support for objects") }, - setAsRealmAnyHandler: (RealmAny) -> T = { throw IllegalArgumentException("Operation not support for sets") }, listAsRealmAnyHandler: (RealmAny) -> T = { throw IllegalArgumentException("Operation not support for lists") }, dictionaryAsRealmAnyHandler: (RealmAny) -> T = { throw IllegalArgumentException("Operation not support for dictionaries") }, ): T { @@ -200,10 +192,6 @@ internal fun MemTrackingAllocator.realmAnyHandler( referenceAsRealmAnyHandler(value) } - io.realm.kotlin.types.RealmAny.Type.SET -> { - setAsRealmAnyHandler(value) - } - io.realm.kotlin.types.RealmAny.Type.LIST -> { listAsRealmAnyHandler(value) } @@ -508,7 +496,6 @@ internal inline fun MemTrackingAllocator.realmAnyToRealmValueWithoutImport(value val objRef = realmObjectToRealmReferenceOrError(value.asRealmObject()) realmObjectTransport(objRef) } - RealmAny.Type.SET, RealmAny.Type.LIST, RealmAny.Type.DICTIONARY -> throw IllegalArgumentException("Cannot pass unmanaged collections as input argument") diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/RealmAnyImpl.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/RealmAnyImpl.kt index 4ff5acf465..a1c1b820b0 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/RealmAnyImpl.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/RealmAnyImpl.kt @@ -22,7 +22,6 @@ import io.realm.kotlin.types.RealmDictionary import io.realm.kotlin.types.RealmInstant import io.realm.kotlin.types.RealmList import io.realm.kotlin.types.RealmObject -import io.realm.kotlin.types.RealmSet import io.realm.kotlin.types.RealmUUID import org.mongodb.kbson.BsonObjectId import org.mongodb.kbson.Decimal128 @@ -93,8 +92,6 @@ internal class RealmAnyImpl constructor( return clazz.cast(getValue) } - override fun asSet(): RealmSet = getValue(RealmAny.Type.SET) as RealmSet - override fun asList(): RealmList = getValue(RealmAny.Type.LIST) as RealmList diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/RealmListInternal.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/RealmListInternal.kt index da323d91da..a1de11c162 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/RealmListInternal.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/RealmListInternal.kt @@ -348,7 +348,6 @@ internal class RealmAnyListOperator( transport, null, mediator, realmReference, issueDynamicObject, issueDynamicMutableObject, - { RealmInterop.realm_list_get_set(nativePointer, index.toLong()) }, { RealmInterop.realm_list_get_list(nativePointer, index.toLong()) }, { RealmInterop.realm_list_get_dictionary(nativePointer, index.toLong()) } ) @@ -376,16 +375,6 @@ internal class RealmAnyListOperator( realmObjectToRealmReferenceWithImport(obj, mediator, realmReference, updatePolicy, cache) RealmInterop.realm_list_add(nativePointer, index.toLong(), realmObjectTransport(objRef)) }, - setAsRealmAnyHandler = { realmValue -> - val nativePointer = RealmInterop.realm_list_insert_set(nativePointer, index.toLong()) - val operator = realmAnySetOperator( - mediator, - realmReference, - nativePointer, - issueDynamicObject, issueDynamicMutableObject - ) - operator.addAll(realmValue.asSet(), updatePolicy, cache) - }, listAsRealmAnyHandler = { realmValue -> val nativePointer = RealmInterop.realm_list_insert_list(nativePointer, index.toLong()) val operator = realmAnyListOperator( @@ -425,18 +414,6 @@ internal class RealmAnyListOperator( realmObjectToRealmReferenceWithImport(realmValue.asRealmObject(), mediator, realmReference, updatePolicy, cache) RealmInterop.realm_list_set(nativePointer, index.toLong(), realmObjectTransport(objRef)) }, - setAsRealmAnyHandler = { realmValue -> - // Have to clear existing elements for core to know if we are updating with a new collection - RealmInterop.realm_list_set(nativePointer, index.toLong(), nullTransport()) - val nativePointer = RealmInterop.realm_list_set_set(nativePointer, index.toLong()) - val operator = realmAnySetOperator( - mediator, - realmReference, - nativePointer, - issueDynamicObject, issueDynamicMutableObject - ) - operator.addAll(realmValue.asSet(), updatePolicy, cache) - }, listAsRealmAnyHandler = { realmValue -> // Have to clear existing elements for core to know if we are updating with a new collection RealmInterop.realm_list_set(nativePointer, index.toLong(), nullTransport()) diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/RealmMapInternal.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/RealmMapInternal.kt index b5e2401ee6..9ee69b254d 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/RealmMapInternal.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/RealmMapInternal.kt @@ -460,7 +460,6 @@ internal class RealmAnyMapOperator constructor( owner = realmReference, issueDynamicObject = issueDynamicObject, issueDynamicMutableObject = issueDynamicMutableObject, - getSetFunction = { RealmInterop.realm_results_get_set(resultsPointer, index.toLong()) }, getListFunction = { RealmInterop.realm_results_get_list(resultsPointer, index.toLong()) }, getDictionaryFunction = { RealmInterop.realm_results_get_dictionary(resultsPointer, index.toLong()) }, ) @@ -492,7 +491,6 @@ internal class RealmAnyMapOperator constructor( valueTransport, null, mediator, realmReference, issueDynamicObject, issueDynamicMutableObject, - { RealmInterop.realm_dictionary_find_set(nativePointer, keyTransport) }, { RealmInterop.realm_dictionary_find_list(nativePointer, keyTransport) } ) { RealmInterop.realm_dictionary_find_dictionary(nativePointer, keyTransport) } @@ -522,20 +520,6 @@ internal class RealmAnyMapOperator constructor( realmAny(result.first, keyTransport) to result.second } }, - setAsRealmAnyHandler = { realmValue -> - // Have to clear existing elements for core to know if we are updating with a new collection - realm_dictionary_insert(nativePointer, keyTransport, nullTransport()) - val previous = getInternal(key) - val nativePointer = RealmInterop.realm_dictionary_insert_set(nativePointer, keyTransport) - val operator = realmAnySetOperator( - mediator, - realmReference, - nativePointer, - issueDynamicObject, issueDynamicMutableObject - ) - operator.addAll(realmValue.asSet(), updatePolicy, cache) - previous to true - }, listAsRealmAnyHandler = { realmValue -> // Have to clear existing elements for core to know if we are updating with a new collection realm_dictionary_insert(nativePointer, keyTransport, nullTransport()) diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/RealmObjectHelper.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/RealmObjectHelper.kt index 13367aa2ca..d844026595 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/RealmObjectHelper.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/RealmObjectHelper.kt @@ -237,18 +237,6 @@ internal object RealmObjectHelper { referenceAsRealmAnyHandler = { realmValue -> setObjectByKey(obj, key, realmValue.asRealmObject(), updatePolicy, cache) }, - setAsRealmAnyHandler = { realmValue -> - RealmInterop.realm_set_value(obj.objectPointer, key, nullTransport(), false) - val nativePointer = RealmInterop.realm_set_set(obj.objectPointer, key) - val operator = realmAnySetOperator( - obj.mediator, - obj.owner, - nativePointer, - false, - false - ) - operator.addAll(value.asSet(), updatePolicy, cache) - }, listAsRealmAnyHandler = { realmValue -> RealmInterop.realm_set_value(obj.objectPointer, key, nullTransport(), false) val nativePointer = RealmInterop.realm_set_list(obj.objectPointer, key) @@ -335,7 +323,6 @@ internal object RealmObjectHelper { it, obj, obj.mediator, obj.owner, false, false, - { RealmInterop.realm_get_set(obj.objectPointer, key) }, { RealmInterop.realm_get_list(obj.objectPointer, key) } ) { RealmInterop.realm_get_dictionary(obj.objectPointer, key) } } @@ -946,7 +933,6 @@ internal object RealmObjectHelper { owner = obj.owner, issueDynamicObject = true, issueDynamicMutableObject = issueDynamicMutableObject, - getSetFunction = { RealmInterop.realm_get_set(obj.objectPointer, propertyInfo.key) }, getListFunction = { RealmInterop.realm_get_list(obj.objectPointer, propertyInfo.key) }, ) { RealmInterop.realm_get_dictionary(obj.objectPointer, propertyInfo.key) } @@ -1150,16 +1136,6 @@ internal object RealmObjectHelper { referenceAsRealmAnyHandler = { realmValue -> setObjectByKey(obj, key, realmValue.asRealmObject(), updatePolicy, cache) }, - setAsRealmAnyHandler = { realmValue -> - val nativePointer = RealmInterop.realm_set_set(obj.objectPointer, key) - val operator = realmAnySetOperator( - obj.mediator, - obj.owner, - nativePointer, - true, - ) - operator.addAll(value.asSet(), updatePolicy, cache) - }, listAsRealmAnyHandler = { realmValue -> val nativePointer = RealmInterop.realm_set_list(obj.objectPointer, key) val operator = diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/RealmSetInternal.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/RealmSetInternal.kt index 6073739455..6f78d00c82 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/RealmSetInternal.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/internal/RealmSetInternal.kt @@ -345,7 +345,6 @@ internal class RealmAnySetOperator( transport, null, mediator, realmReference, issueDynamicObject, issueDynamicMutableObject, - { error("Set should never container sets") }, { error("Set should never container lists") } ) { error("Set should never container dictionaries") } } @@ -371,7 +370,6 @@ internal class RealmAnySetOperator( realmObjectToRealmReferenceWithImport(obj, mediator, realmReference, updatePolicy, cache) RealmInterop.realm_set_insert(nativePointer, realmObjectTransport(objRef)) }, - setAsRealmAnyHandler = { realmValue -> throw IllegalArgumentException("Sets cannot contain other collections") }, listAsRealmAnyHandler = { realmValue -> throw IllegalArgumentException("Sets cannot contain other collections ") }, dictionaryAsRealmAnyHandler = { realmValue -> throw IllegalArgumentException("Sets cannot contain other collections ") }, ) diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/serializers/RealmKSerializers.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/serializers/RealmKSerializers.kt index 664a3e2db6..94a796edc4 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/serializers/RealmKSerializers.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/serializers/RealmKSerializers.kt @@ -379,7 +379,6 @@ public object RealmAnyKSerializer : KSerializer { Type.OBJECT_ID -> RealmAny.create(it.objectId!!) Type.UUID -> RealmAny.create(it.uuid!!) Type.OBJECT -> RealmAny.create(it.realmObject!!) - Type.SET -> RealmAny.create(it.set!!) Type.LIST -> RealmAny.create(it.list!!) Type.DICTIONARY -> RealmAny.create(it.dictionary!!) } @@ -406,7 +405,6 @@ public object RealmAnyKSerializer : KSerializer { ) Type.UUID -> uuid = value.asRealmUUID() Type.OBJECT -> realmObject = value.asRealmObject() - Type.SET -> set = value.asSet() Type.LIST -> list = value.asList() Type.DICTIONARY -> dictionary = value.asDictionary() } diff --git a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/types/RealmAny.kt b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/types/RealmAny.kt index 6eccbd8016..309aa33d7b 100644 --- a/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/types/RealmAny.kt +++ b/packages/library-base/src/commonMain/kotlin/io/realm/kotlin/types/RealmAny.kt @@ -60,7 +60,6 @@ import kotlin.reflect.KClass * OBJECT_ID -> doSomething(realmAny.asObjectId()) * REALM_UUID -> doSomething(realmAny.asRealmUUID()) * REALM_OBJECT -> doSomething(realmAny.asRealmObject()) - * SET -> doSomething(realmAny.asSet()) * LIST -> doSomething(realmAny.asList()) * DICTIONARY -> doSomething(realmAny.asDictionary()) * } @@ -85,25 +84,20 @@ import kotlin.reflect.KClass * ``` * `RealmAny` cannot store [EmbeddedRealmObject]s. * - * `RealmAny` can contain other collections of [RealmAny]. This means that you can build nested - * collections inside a `RealmAny`-field. The only constraint is that sets cannot contain other - * collections, so must be at the leaf of such nested hierarchies. + * `RealmAny` can contain other [RealmList] and [RealmDictionary] of [RealmAny]. This means that + * you can build nested collections inside a `RealmAny`-field. * ``` * realmObjct.realmAnyField = realmAnyListOf( * // Primitive values can be added in collections * 1, - * // Sets are allowed but cannot contain nested collection types - * "realmSetOf(1), * // Lists and dictionaries can contain other nested collection types * realmListOf( - * realmSetOf(), * realmListOf(), * realmDictionaryOf() * ), * realmDictionaryOf( - * "key1" to realmSetOf(), - * "key2" to realmListOf(), - * "key3" to realmDictionaryOf()) + * "key1" to realmListOf(), + * "key2" to realmDictionaryOf()) * ) * ``` * @@ -137,7 +131,7 @@ public interface RealmAny { * Supported Realm data types that can be stored in a `RealmAny` instance. */ public enum class Type { - INT, BOOL, STRING, BINARY, TIMESTAMP, FLOAT, DOUBLE, DECIMAL128, OBJECT_ID, UUID, OBJECT, SET, LIST, DICTIONARY; + INT, BOOL, STRING, BINARY, TIMESTAMP, FLOAT, DOUBLE, DECIMAL128, OBJECT_ID, UUID, OBJECT, LIST, DICTIONARY; } /** @@ -258,12 +252,6 @@ public interface RealmAny { */ public fun asRealmObject(clazz: KClass): T - /** - * Returns the value from this `RealmAny` as a [RealmSet] containing new [RealmAny]s. - * @throws [IllegalStateException] if the stored value is not a set. - */ - public fun asSet(): RealmSet - /** * Returns the value from this `RealmAny` as a [RealmList] containing new [RealmAny]s. * @throws [IllegalStateException] if the stored value is not a list. @@ -387,34 +375,6 @@ public interface RealmAny { public fun create(realmObject: DynamicRealmObject): RealmAny = RealmAnyImpl(Type.OBJECT, DynamicRealmObject::class, realmObject) - /** - * Creates an unmanaged `RealmAny` instance from a [RealmSet] of [RealmAny] values. - * - * To create a [RealmAny] containing a [RealmSet] of arbitrary values wrapped in [RealmAny]s - * use the [io.realm.kotlin.ext.realmAnySetOf]. - * - * **NOTE:** Realm does not support to having other collections ([RealmSet], [RealmList] and - * [RealmDictionary]) in a [RealmSet]. These kind of structures can be built in a [RealmAny] - * but will fail if imported to realm. - * - * Example: - * ``` - * class SampleObject() : RealmObject { - * val realmAnyField: RealmAny? = null - * } - * val realmObject = copyToRealm(SampleObject()) - * - * // Sets with non-collection types can be built and imported into realm. - * realmObject.realmAnyField = realmAnySetOf(1, "Realm", realmObject) - * - * // Sets with collection types can be built but cannot be imported into realm. - * val setsWithCollections = realmAnySetOf(realmSetOf(), realmListOf(), realmDictionaryOf()) - * realmObject.realmAnyField = setsWithCollections // Will throw IllegalArgumentExcception - * ``` - */ - public fun create(value: RealmSet): RealmAny = - RealmAnyImpl(Type.SET, RealmAny::class, value) - /** * Creates an unmanaged `RealmAny` instance from a [RealmList] of [RealmAny] values. * @@ -428,22 +388,19 @@ public interface RealmAny { * } * val realmObject = copyToRealm(SampleObject()) * - * // Lists can contain other collection types, including [RealmSet]s. + * // List can contain other collections, but only `RealmList` and + * // `RealmDictionary`. * realmObject.realmAnyField = realmAnyListOf( * // Primitive values * 1, - * // Sets are allowed but cannot contain nested collection types - * realmSetOf(1), * // Lists and dictionaries can contain other collection types * realmListOf( - * realmSetOf(), * realmListOf(), * realmDictionaryOf() * ), * realmDictionaryOf( - * "key1" to realmSetOf(), - * "key2" to realmListOf(), - * "key3" to realmDictioneryOf()) + * "key1" to realmListOf(), + * "key2" to realmDictioneryOf()) * ) * ``` */ @@ -463,21 +420,18 @@ public interface RealmAny { * } * val realmObject = copyToRealm(SampleObject()) * - * // Dictionaries can contain other collection types, including [RealmSet]s. + * // Dictionaries can contain other collections, but only `RealmList` and + * // `RealmDictionary`. * realmObjct.realmAnyField = realmAnyDictionaryOf( * "int" to 5, - * // Sets are allowed but cannot contain nested collection types - * "set" to "realmSetOf(1), * // Lists and dictionaries can contain other nested collection types * "list" to realmListOf( - * realmSetOf(), * realmListOf(), * realmDictionaryOf() * ), * "dictionary" to realmDictionaryOf( - * "key1" to realmSetOf(), - * "key2" to realmListOf(), - * "key3" to realmDictionaryOf()) + * "key1" to realmListOf(), + * "key2" to realmDictionaryOf()) * ) * ``` */ diff --git a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmAnyNestedCollectionTests.kt b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmAnyNestedCollectionTests.kt index 84057002cc..d377684f94 100644 --- a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmAnyNestedCollectionTests.kt +++ b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmAnyNestedCollectionTests.kt @@ -24,15 +24,12 @@ import io.realm.kotlin.ext.asRealmObject import io.realm.kotlin.ext.query import io.realm.kotlin.ext.realmAnyDictionaryOf import io.realm.kotlin.ext.realmAnyListOf -import io.realm.kotlin.ext.realmAnySetOf import io.realm.kotlin.ext.realmDictionaryOf import io.realm.kotlin.ext.realmListOf -import io.realm.kotlin.ext.realmSetOf import io.realm.kotlin.internal.platform.runBlocking import io.realm.kotlin.test.common.utils.assertFailsWithMessage import io.realm.kotlin.test.platform.PlatformUtils import io.realm.kotlin.types.RealmAny -import org.mongodb.kbson.ObjectId import kotlin.test.AfterTest import kotlin.test.BeforeTest import kotlin.test.Test @@ -67,100 +64,6 @@ class RealmAnyNestedCollectionTests { PlatformUtils.deleteTempDir(tmpDir) } - @Test - fun setInRealmAny_copyToRealm() = runBlocking { - val sample = Sample().apply { stringField = "SAMPLE" } - realm.write { - val instance = JsonStyleRealmObject().apply { - value = RealmAny.create( - realmSetOf( - RealmAny.create(5), - RealmAny.create("Realm"), - RealmAny.create(sample), - ) - ) - } - copyToRealm(instance) - } - val managedSample: Sample = realm.query().find().single() - val anyValue: RealmAny = realm.query().find().single().value!! - assertEquals(RealmAny.Type.SET, anyValue.type) - anyValue.asSet().let { embeddedSet -> - assertEquals(3, embeddedSet.size) - assertTrue { embeddedSet.contains(RealmAny.create(5)) } - assertTrue { embeddedSet.contains(RealmAny.create("Realm")) } - assertTrue { embeddedSet.contains(RealmAny.create(managedSample)) } - } - } - - @Test - fun setInRealmAny_assignment() = runBlocking { - val sample = Sample().apply { stringField = "SAMPLE" } - realm.write { - val managedInstance = copyToRealm(JsonStyleRealmObject()) - managedInstance.value = RealmAny.create( - realmSetOf( - RealmAny.create(5), - RealmAny.create("Realm"), - RealmAny.create(sample), - ) - ) - } - val managedSample: Sample = realm.query().find().single() - val anyValue: RealmAny = realm.query().find().single().value!! - anyValue.asSet().let { embeddedSet -> - assertEquals(3, embeddedSet.size) - assertTrue { embeddedSet.contains(RealmAny.create(5)) } - assertTrue { embeddedSet.contains(RealmAny.create("Realm")) } - assertTrue { embeddedSet.contains(RealmAny.create(managedSample)) } - } - } - - @Test - fun setInRealmAny_throwsOnNestedCollections_copyToRealm() = runBlocking { - realm.write { - JsonStyleRealmObject(ObjectId().toString()).apply { - value = - RealmAny.create(realmSetOf(RealmAny.create(realmListOf(RealmAny.create(5))))) - }.let { - assertFailsWithMessage("Sets cannot contain other collections") { - copyToRealm(it) - } - } - JsonStyleRealmObject(ObjectId().toString()).apply { - value = RealmAny.create( - realmSetOf( - RealmAny.create(realmDictionaryOf("key" to RealmAny.create(5))) - ) - ) - }.let { - assertFailsWithMessage("Sets cannot contain other collections") { - copyToRealm(it) - } - } - } - } - - @Test - fun setInRealmAny_throwsOnNestedCollections_add() = runBlocking { - realm.write { - val instance = copyToRealm( - JsonStyleRealmObject().apply { value = RealmAny.create(realmSetOf()) } - ) - val set = instance.value!!.asSet() - - val realmAnyList = RealmAny.create(realmListOf()) - assertFailsWithMessage("Sets cannot contain other collections") { - set.add(realmAnyList) - } - - val realmAnyDictionary = RealmAny.create(realmDictionaryOf()) - assertFailsWithMessage("Sets cannot contain other collections") { - set.add(realmAnyDictionary) - } - } - } - @Test fun listInRealmAny_copyToRealm() = runBlocking { val sample = Sample().apply { stringField = "SAMPLE" } @@ -206,14 +109,6 @@ class RealmAnyNestedCollectionTests { RealmAny.create(sample), ) ), - // Embedded set - RealmAny.create( - realmSetOf( - RealmAny.create(5), - RealmAny.create("Realm"), - RealmAny.create(sample), - ) - ), // Embedded map RealmAny.create( realmDictionaryOf( @@ -243,13 +138,7 @@ class RealmAnyNestedCollectionTests { assertEquals(RealmAny.create("Realm"), embeddedList[1]) assertEquals("SAMPLE", embeddedList[2]!!.asRealmObject().stringField) } - it[4]!!.asSet().let { embeddedSet -> - assertEquals(3, embeddedSet.size) - assertTrue { embeddedSet.contains(RealmAny.create(5)) } - assertTrue { embeddedSet.contains(RealmAny.create("Realm")) } - assertTrue { embeddedSet.contains(RealmAny.create(managedSample)) } - } - it[5]!!.asDictionary().toMutableMap().let { embeddedDict -> + it[4]!!.asDictionary().toMutableMap().let { embeddedDict -> assertEquals(RealmAny.create(5), embeddedDict["keyInt"]) assertEquals(RealmAny.create("Realm"), embeddedDict["keyString"]) assertEquals( @@ -280,16 +169,6 @@ class RealmAnyNestedCollectionTests { ) ), ) - // Embedded set - add( - RealmAny.create( - realmSetOf( - RealmAny.create(5), - RealmAny.create("Realm"), - RealmAny.create(sample), - ) - ), - ) // Embedded map add( RealmAny.create( @@ -313,13 +192,7 @@ class RealmAnyNestedCollectionTests { assertEquals(RealmAny.create("Realm"), embeddedList[1]) assertEquals("SAMPLE", embeddedList[2]!!.asRealmObject().stringField) } - it[4]!!.asSet().let { embeddedSet -> - assertEquals(3, embeddedSet.size) - assertTrue { embeddedSet.contains(RealmAny.create(5)) } - assertTrue { embeddedSet.contains(RealmAny.create("Realm")) } - assertTrue { embeddedSet.contains(RealmAny.create(managedSample)) } - } - it[5]!!.asDictionary().toMutableMap().let { embeddedDict -> + it[4]!!.asDictionary().toMutableMap().let { embeddedDict -> assertEquals(RealmAny.create(5), embeddedDict["keyInt"]) assertEquals(RealmAny.create("Realm"), embeddedDict["keyString"]) assertEquals( @@ -358,17 +231,6 @@ class RealmAnyNestedCollectionTests { ) ), ) - // Embedded set - set( - 1, - RealmAny.create( - realmSetOf( - RealmAny.create(5), - RealmAny.create("Realm"), - RealmAny.create(sample), - ) - ), - ) // Embedded map set( 2, @@ -390,12 +252,6 @@ class RealmAnyNestedCollectionTests { assertEquals(RealmAny.create(5), embeddedList[0]) assertEquals("SAMPLE", embeddedList[1]!!.asRealmObject().stringField) } - it[1]!!.asSet().let { embeddedSet -> - assertEquals(3, embeddedSet.size) - assertTrue { embeddedSet.contains(RealmAny.create(5)) } - assertTrue { embeddedSet.contains(RealmAny.create("Realm")) } - assertTrue { embeddedSet.contains(RealmAny.create(managedSample)) } - } it[2]!!.asDictionary().toMutableMap().let { embeddedDict -> assertEquals(RealmAny.create(5), embeddedDict["keyInt"]) assertEquals(RealmAny.create("Realm"), embeddedDict["keyString"]) @@ -452,13 +308,6 @@ class RealmAnyNestedCollectionTests { value = RealmAny.create( realmDictionaryOf( "keyInt" to RealmAny.create(5), - "keySet" to RealmAny.create( - realmSetOf( - RealmAny.create(5), - RealmAny.create("Realm"), - RealmAny.create(sample), - ) - ), "keyList" to RealmAny.create( realmListOf( RealmAny.create(5), @@ -486,14 +335,8 @@ class RealmAnyNestedCollectionTests { assertEquals(RealmAny.Type.DICTIONARY, anyValue.type) val managedSample: Sample = realm.query().find().single() anyValue.asDictionary().run { - assertEquals(4, size) + assertEquals(3, size) assertEquals(5, get("keyInt")!!.asInt()) - get("keySet")!!.asSet().let { embeddedSet -> - assertEquals(3, embeddedSet.size) - assertTrue { embeddedSet.contains(RealmAny.create(5)) } - assertTrue { embeddedSet.contains(RealmAny.create("Realm")) } - assertTrue { embeddedSet.contains(RealmAny.create(managedSample)) } - } get("keyList")!!.asList().let { embeddedList -> assertEquals(RealmAny.create(5), embeddedList[0]) assertEquals(RealmAny.create("Realm"), embeddedList[1]) @@ -518,7 +361,6 @@ class RealmAnyNestedCollectionTests { JsonStyleRealmObject().apply { // Assigning dictionary with nested lists and dictionaries value = realmAnyDictionaryOf( - "keySet" to realmAnySetOf(5, "Realm", sample), "keyList" to realmAnyListOf(5, "Realm", sample), "keyDictionary" to realmAnyDictionaryOf( "keyInt" to 5, @@ -536,17 +378,9 @@ class RealmAnyNestedCollectionTests { val anyValue: RealmAny = jsonStyleRealmObject.value!! assertEquals(RealmAny.Type.DICTIONARY, anyValue.type) anyValue.asDictionary().values.run { - assertEquals(3, size) + assertEquals(2, size) forEach { value -> when (value?.type) { - RealmAny.Type.SET -> { - value.asSet().let { embeddedSet -> - assertEquals(3, embeddedSet.size) - assertTrue { embeddedSet.contains(RealmAny.create(5)) } - assertTrue { embeddedSet.contains(RealmAny.create("Realm")) } - assertTrue { embeddedSet.contains(RealmAny.create(managedSample)) } - } - } RealmAny.Type.LIST -> { value.asList().let { embeddedList -> assertEquals(RealmAny.create(5), embeddedList[0]) @@ -583,7 +417,6 @@ class RealmAnyNestedCollectionTests { query().find().single().value!!.asDictionary().run { val sample = copyToRealm(Sample().apply { stringField = "SAMPLE" }) put("keyInt", RealmAny.create(5)) - put("keySet", realmAnySetOf(5, "Realm", sample)) put("keyList", realmAnyListOf(5, "Realm", sample)) put( "keyDictionary", @@ -602,14 +435,8 @@ class RealmAnyNestedCollectionTests { val anyValue: RealmAny = jsonStyleRealmObject.value!! assertEquals(RealmAny.Type.DICTIONARY, anyValue.type) anyValue.asDictionary().run { - assertEquals(4, size) + assertEquals(3, size) assertEquals(5, get("keyInt")!!.asInt()) - get("keySet")!!.asSet().let { embeddedSet -> - assertEquals(3, embeddedSet.size) - assertTrue { embeddedSet.contains(RealmAny.create(5)) } - assertTrue { embeddedSet.contains(RealmAny.create("Realm")) } - assertTrue { embeddedSet.contains(RealmAny.create(managedSample)) } - } get("keyList")!!.asList().let { embeddedList -> assertEquals(RealmAny.create(5), embeddedList[0]) assertEquals(RealmAny.create("Realm"), embeddedList[1]) @@ -695,9 +522,6 @@ class RealmAnyNestedCollectionTests { @Test fun query_ThrowsOnNestedCollectionArguments() { - assertFailsWithMessage("Invalid query argument: Cannot pass unmanaged collections as input argument") { - realm.query("value == $0", RealmAny.create(realmSetOf())) - } assertFailsWithMessage("Invalid query argument: Cannot pass unmanaged collections as input argument") { realm.query("value == $0", RealmAny.create(realmListOf())) } @@ -709,12 +533,6 @@ class RealmAnyNestedCollectionTests { @Test fun query() = runBlocking { realm.write { - copyToRealm( - JsonStyleRealmObject().apply { - id = "SET" - value = realmAnySetOf(1, 2, 3) - } - ) copyToRealm( JsonStyleRealmObject().apply { id = "LIST" @@ -735,7 +553,6 @@ class RealmAnyNestedCollectionTests { JsonStyleRealmObject().apply { id = "EMBEDDED" value = realmAnyListOf( - setOf(1, 2, 3), listOf(4, 5, 6), mapOf( "key1" to 7, @@ -747,7 +564,7 @@ class RealmAnyNestedCollectionTests { ) } - assertEquals(4, realm.query().find().size) + assertEquals(3, realm.query().find().size) // Matching lists realm.query("value[0] == 4").find().single().run { diff --git a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmAnyTests.kt b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmAnyTests.kt index 3601d40551..679aeab20e 100644 --- a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmAnyTests.kt +++ b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmAnyTests.kt @@ -489,6 +489,9 @@ class RealmAnyTests { // Different objects of same type are not equal assertNotEquals(RealmAny.create(Sample()), RealmAny.create(realmObject)) } + // Collections in RealmAny are tested in RealmAnyNestedCollections.kt + RealmAny.Type.LIST, + RealmAny.Type.DICTIONARY -> {} } } } diff --git a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmDictionaryTests.kt b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmDictionaryTests.kt index b98e34baba..fbf739539e 100644 --- a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmDictionaryTests.kt +++ b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmDictionaryTests.kt @@ -3078,9 +3078,9 @@ internal class RealmAnyDictionaryTester( assertEquals(expectedObj.stringField, assertNotNull(actualObj).stringField) } null -> assertNull(actualValue) - RealmAny.Type.SET, + // Collections in RealmAny are tested separately in RealmAnyNestedCollectionTests RealmAny.Type.LIST, - RealmAny.Type.DICTIONARY -> {} // Tested separately in RealmAnyNestedCollectionTests + RealmAny.Type.DICTIONARY -> {} } } } diff --git a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmListTests.kt b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmListTests.kt index eeea0b30b4..7aefea5767 100644 --- a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmListTests.kt +++ b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/RealmListTests.kt @@ -1345,9 +1345,8 @@ internal class RealmAnyListTester constructor( expected.asRealmObject().stringField, actual.asRealmObject().stringField ) - // FIXME Should we rather test nested collections somewhere else? - RealmAny.Type.SET -> TODO() - RealmAny.Type.LIST -> TODO() + // Collections in RealmAny are tested separately in RealmAnyNestedCollectionTests + RealmAny.Type.LIST, RealmAny.Type.DICTIONARY -> TODO() } } else if (expected != null || actual != null) { diff --git a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/SerializationTests.kt b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/SerializationTests.kt index d9c0bf6787..580c8f2a1f 100644 --- a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/SerializationTests.kt +++ b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/SerializationTests.kt @@ -33,7 +33,6 @@ import io.realm.kotlin.entities.SerializableSample import io.realm.kotlin.ext.asRealmObject import io.realm.kotlin.ext.realmAnyDictionaryOf import io.realm.kotlin.ext.realmAnyListOf -import io.realm.kotlin.ext.realmAnySetOf import io.realm.kotlin.internal.restrictToMillisPrecision import io.realm.kotlin.serializers.MutableRealmIntKSerializer import io.realm.kotlin.serializers.RealmAnyKSerializer @@ -338,9 +337,6 @@ class SerializationTests { nullableRealmAnyField = RealmAny.create(it) } } - RealmAny.Type.SET -> SerializableSample().apply { - nullableRealmAnyField = realmAnySetOf(1, 2, 3) - } RealmAny.Type.LIST -> SerializableSample().apply { nullableRealmAnyField = realmAnyListOf(RealmAny.create(1), RealmAny.create(2)) } diff --git a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/dynamic/DynamicMutableRealmObjectTests.kt b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/dynamic/DynamicMutableRealmObjectTests.kt index 9f834b9372..32ee015f45 100644 --- a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/dynamic/DynamicMutableRealmObjectTests.kt +++ b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/dynamic/DynamicMutableRealmObjectTests.kt @@ -1386,47 +1386,6 @@ class DynamicMutableRealmObjectTests { } } - @Test - fun testSetsInRealmAny() { - val dynamicSampleInner = dynamicMutableRealm.copyToRealm( - DynamicMutableRealmObject.create( - "Sample", - "stringField" to "INNER" - ) - ) - dynamicMutableRealm.copyToRealm( - DynamicMutableRealmObject.create( - "Sample", - "nullableRealmAnyField" to RealmAny.create( - realmSetOf( - RealmAny.create( - dynamicSampleInner - ) - ) - ) - ) - ).let { - val set = it.getNullableValue("nullableRealmAnyField")!!.asSet() - // Verify that we get mutable instances out of the set - val setObject = set.first()!!.asRealmObject() - assertIs(setObject) - assertEquals("INNER", setObject.getValue("stringField")) - setObject.set("stringField", "UPDATED_INNER") - // Verify that we can add elements to the set - set.add(RealmAny.create(dynamicSampleInner)) - // Verify that we cannot add nested collections - assertFailsWithMessage("Sets cannot contain other collections") { - set.add(RealmAny.create(realmSetOf())) - } - assertFailsWithMessage("Sets cannot contain other collections") { - set.add(RealmAny.create(realmListOf())) - } - assertFailsWithMessage("Sets cannot contain other collections") { - set.add(RealmAny.create(realmDictionaryOf())) - } - } - } - @Test fun testNestedCollectionsInListInRealmAny() { val dynamicSampleInner = dynamicMutableRealm.copyToRealm( @@ -1437,16 +1396,6 @@ class DynamicMutableRealmObjectTests { "Sample", "nullableRealmAnyField" to RealmAny.create( realmListOf( - RealmAny.create( - realmSetOf( - RealmAny.create( - DynamicMutableRealmObject.create( - "Sample", - "stringField" to "INNER_SET" - ) - ) - ) - ), RealmAny.create( realmListOf( RealmAny.create( @@ -1472,22 +1421,15 @@ class DynamicMutableRealmObjectTests { ) ).let { val list = it.getNullableValue("nullableRealmAnyField")!!.asList() - // Verify that we get mutable instances out of the set - list[0]!!.asSet().let { embeddedSet -> - val o = embeddedSet.first()!! - .asRealmObject() - assertIs(o) - assertEquals("INNER_SET", o.getValue("stringField")) - embeddedSet.add(RealmAny.Companion.create(dynamicSampleInner)) - } - list[1]!!.asList().let { embeddedList -> + // Verify that we get mutable instances out of the collections + list[0]!!.asList().let { embeddedList -> val o = embeddedList.first()!! .asRealmObject() assertIs(o) assertEquals("INNER_LIST", o.getValue("stringField")) embeddedList.add(RealmAny.Companion.create(dynamicSampleInner)) } - list[2]!!.asDictionary().let { embeddedDictionary -> + list[1]!!.asDictionary().let { embeddedDictionary -> val o = embeddedDictionary["key"]!! .asRealmObject() assertIs(o) @@ -1511,16 +1453,6 @@ class DynamicMutableRealmObjectTests { "Sample", "nullableRealmAnyField" to RealmAny.create( realmDictionaryOf( - "set" to RealmAny.create( - realmSetOf( - RealmAny.create( - DynamicMutableRealmObject.create( - "Sample", - "stringField" to "INNER_SET" - ) - ) - ) - ), "list" to RealmAny.create( realmListOf( RealmAny.create( @@ -1546,14 +1478,7 @@ class DynamicMutableRealmObjectTests { ) ).let { val dict = it.getNullableValue("nullableRealmAnyField")!!.asDictionary() - // Verify that we get mutable instances out of the set - dict["set"]!!.asSet().let { embeddedSet -> - val o = embeddedSet.first()!! - .asRealmObject() - assertIs(o) - assertEquals("INNER_SET", o.getValue("stringField")) - embeddedSet.add(RealmAny.Companion.create(dynamicSampleInner)) - } + // Verify that we get mutable instances out of the collections dict["list"]!!.asList().let { embeddedList -> val o = embeddedList.first()!! .asRealmObject() diff --git a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/dynamic/DynamicRealmObjectTests.kt b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/dynamic/DynamicRealmObjectTests.kt index 31195ebad0..e798e4a8b0 100644 --- a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/dynamic/DynamicRealmObjectTests.kt +++ b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/dynamic/DynamicRealmObjectTests.kt @@ -35,7 +35,6 @@ import io.realm.kotlin.ext.asRealmObject import io.realm.kotlin.ext.query import io.realm.kotlin.ext.realmDictionaryOf import io.realm.kotlin.ext.realmListOf -import io.realm.kotlin.ext.realmSetOf import io.realm.kotlin.ext.toRealmSet import io.realm.kotlin.internal.asDynamicRealm import io.realm.kotlin.query.RealmQuery @@ -1551,9 +1550,6 @@ class DynamicRealmObjectTests { RealmAny.create( realmListOf(RealmAny.create(Sample().apply { stringField = "INNER_LIST" })) ), - RealmAny.create( - realmSetOf(RealmAny.create(Sample().apply { stringField = "INNER_SET" })) - ), RealmAny.create( realmDictionaryOf("key" to RealmAny.create(Sample().apply { stringField = "INNER_DICT" })) ), @@ -1577,13 +1573,7 @@ class DynamicRealmObjectTests { assertIs(actualSample) assertEquals("INNER_LIST", actualSample.getValue("stringField")) } - actualList[1]!!.let { innerSet -> - val actualSample = - innerSet.asSet()!!.first()!!.asRealmObject() - assertIs(actualSample) - assertEquals("INNER_SET", actualSample.getValue("stringField")) - } - actualList[2]!!.let { innerDictionary -> + actualList[1]!!.let { innerDictionary -> val actualSample = innerDictionary.asDictionary()!!["key"]!!.asRealmObject() assertIs(actualSample) @@ -1601,7 +1591,7 @@ class DynamicRealmObjectTests { ) val unmanagedSample = Sample().apply { - nullableRealmAnyField = RealmAny.create(realmAnyValues.toRealmSet()) + nullableRealmAnySetField = realmAnyValues.toRealmSet() } realm.writeBlocking { copyToRealm(unmanagedSample) } realm.asDynamicRealm() @@ -1654,61 +1644,6 @@ class DynamicRealmObjectTests { // This should be tested for DynamicMutableRealm instead. } - @Test - fun get_realmAnyNestedSet() { - val realmAnyValues = realmListOf( - null, - RealmAny.create("Hello"), - RealmAny.create(Sample().apply { stringField = "INNER" }), - ) - - val unmanagedSample = Sample().apply { - nullableRealmAnyField = RealmAny.create(realmAnyValues.toRealmSet()) - } - realm.writeBlocking { copyToRealm(unmanagedSample) } - realm.asDynamicRealm() - .also { dynamicRealm -> - val dynamicSample = dynamicRealm.query("Sample") - .find() - .first() - - val actualReifiedSet: RealmSet = - dynamicSample.getNullableValue( - Sample::nullableRealmAnyField.name - )!!.asSet() - - fun assertions(actual: RealmAny?) { - if (actual?.type == RealmAny.Type.OBJECT) { - var assertionSucceeded = false - for (value in realmAnyValues) { - if (value?.type == RealmAny.Type.OBJECT) { - assertEquals( - value.asRealmObject().stringField, - actual.asRealmObject() - .getValue("stringField") - ) - assertionSucceeded = true - return - } - } - assertTrue(assertionSucceeded) - } else { - assertTrue(realmAnyValues.contains(actual)) - } - } - - for (actual in actualReifiedSet) { - assertions(actual) - } - } - - // In case of testing sets we have to skip dynamic managed objects inside a - // RealmSet since the semantics prevent us from writing a DynamicRealmObject - // in this way, rightfully so. The reason for this is that we use the regular realm's - // accessors which go through the non-dynamic path so objects inside the set are expected - // to be non-dynamic - the 'issueDynamicObject' flag is always false following this path. - // This should be tested for DynamicMutableRealm instead. - } @Test fun get_realmAnyDictionary() { val realmAnyValues = realmDictionaryOf( @@ -1786,9 +1721,6 @@ class DynamicRealmObjectTests { "list" to RealmAny.create( realmListOf(RealmAny.create(Sample().apply { stringField = "INNER_LIST" })) ), - "set" to RealmAny.create( - realmSetOf(RealmAny.create(Sample().apply { stringField = "INNER_SET" })) - ), "dict" to RealmAny.create( realmDictionaryOf("key" to RealmAny.create(Sample().apply { stringField = "INNER_DICT" })) ), @@ -1817,17 +1749,6 @@ class DynamicRealmObjectTests { innerSample.asRealmObject() } } - actualDictionary["set"]!!.let { innerSet -> - val innerSample = innerSet.asSet()!!.first()!! - val actualSample = - innerSample.asRealmObject() - assertIs(actualSample) - assertEquals("INNER_SET", actualSample.getValue("stringField")) - - assertFailsWith { - innerSample.asRealmObject() - } - } actualDictionary["dict"]!!.let { innerDictionary -> val innerSample = innerDictionary.asDictionary()!!["key"]!! val actualSample = diff --git a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/notifications/RealmAnyNestedDictionaryNotificationTest.kt b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/notifications/RealmAnyNestedDictionaryNotificationTest.kt index 8ef99181fa..f5b8fa593d 100644 --- a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/notifications/RealmAnyNestedDictionaryNotificationTest.kt +++ b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/notifications/RealmAnyNestedDictionaryNotificationTest.kt @@ -27,7 +27,8 @@ import io.realm.kotlin.notifications.DeletedMap import io.realm.kotlin.notifications.InitialMap import io.realm.kotlin.notifications.MapChange import io.realm.kotlin.notifications.UpdatedMap -import io.realm.kotlin.test.common.utils.RealmEntityNotificationTests +import io.realm.kotlin.test.common.utils.DeletableEntityNotificationTests +import io.realm.kotlin.test.common.utils.FlowableTests import io.realm.kotlin.test.platform.PlatformUtils import io.realm.kotlin.test.util.receiveOrFail import io.realm.kotlin.types.RealmAny @@ -45,7 +46,7 @@ import kotlin.test.assertIs import kotlin.test.assertTrue import kotlin.time.Duration.Companion.seconds -class RealmAnyNestedDictionaryNotificationTest : RealmEntityNotificationTests { +class RealmAnyNestedDictionaryNotificationTest : FlowableTests, DeletableEntityNotificationTests { lateinit var tmpDir: String lateinit var configuration: RealmConfiguration diff --git a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/notifications/RealmAnyNestedListNotificationTest.kt b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/notifications/RealmAnyNestedListNotificationTest.kt index 6fd2814cfa..e2858f7fbd 100644 --- a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/notifications/RealmAnyNestedListNotificationTest.kt +++ b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/notifications/RealmAnyNestedListNotificationTest.kt @@ -26,7 +26,8 @@ import io.realm.kotlin.notifications.DeletedList import io.realm.kotlin.notifications.InitialList import io.realm.kotlin.notifications.ListChange import io.realm.kotlin.notifications.UpdatedList -import io.realm.kotlin.test.common.utils.RealmEntityNotificationTests +import io.realm.kotlin.test.common.utils.DeletableEntityNotificationTests +import io.realm.kotlin.test.common.utils.FlowableTests import io.realm.kotlin.test.platform.PlatformUtils import io.realm.kotlin.test.util.receiveOrFail import io.realm.kotlin.types.RealmAny @@ -44,7 +45,7 @@ import kotlin.test.assertIs import kotlin.test.assertTrue import kotlin.time.Duration.Companion.seconds -class RealmAnyNestedListNotificationTest : RealmEntityNotificationTests { +class RealmAnyNestedListNotificationTest : FlowableTests, DeletableEntityNotificationTests { lateinit var tmpDir: String lateinit var configuration: RealmConfiguration diff --git a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/notifications/RealmAnyNestedSetNotificationTest.kt b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/notifications/RealmAnyNestedSetNotificationTest.kt deleted file mode 100644 index e000ad0a06..0000000000 --- a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/notifications/RealmAnyNestedSetNotificationTest.kt +++ /dev/null @@ -1,249 +0,0 @@ -/* - * Copyright 2023 Realm Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.realm.kotlin.test.common.notifications - -import io.realm.kotlin.Realm -import io.realm.kotlin.RealmConfiguration -import io.realm.kotlin.entities.JsonStyleRealmObject -import io.realm.kotlin.ext.realmAnyListOf -import io.realm.kotlin.ext.realmAnyOf -import io.realm.kotlin.ext.realmAnySetOf -import io.realm.kotlin.internal.platform.runBlocking -import io.realm.kotlin.notifications.DeletedSet -import io.realm.kotlin.notifications.InitialSet -import io.realm.kotlin.notifications.SetChange -import io.realm.kotlin.notifications.UpdatedSet -import io.realm.kotlin.test.common.utils.RealmEntityNotificationTests -import io.realm.kotlin.test.platform.PlatformUtils -import io.realm.kotlin.test.util.receiveOrFail -import io.realm.kotlin.types.RealmAny -import kotlinx.coroutines.async -import kotlinx.coroutines.channels.Channel -import kotlinx.coroutines.flow.first -import kotlinx.coroutines.sync.Mutex -import kotlinx.coroutines.withTimeout -import kotlin.test.AfterTest -import kotlin.test.BeforeTest -import kotlin.test.Ignore -import kotlin.test.Test -import kotlin.test.assertEquals -import kotlin.test.assertIs -import kotlin.test.assertTrue -import kotlin.time.Duration.Companion.seconds - -class RealmAnyNestedSetNotificationTest : RealmEntityNotificationTests { - - lateinit var tmpDir: String - lateinit var configuration: RealmConfiguration - lateinit var realm: Realm - - @BeforeTest - fun setup() { - tmpDir = PlatformUtils.createTempDir() - configuration = RealmConfiguration.Builder( - schema = setOf(JsonStyleRealmObject::class) - ).directory(tmpDir) - .build() - realm = Realm.open(configuration) - } - - @AfterTest - fun tearDown() { - if (this::realm.isInitialized && !realm.isClosed()) { - realm.close() - } - PlatformUtils.deleteTempDir(tmpDir) - } - - @Test - @Ignore // Initial element events are verified as part of the asFlow tests - override fun initialElement() {} - - @Test - override fun asFlow() = runBlocking { - val channel = Channel>() - - val o: JsonStyleRealmObject = realm.write { - copyToRealm( - JsonStyleRealmObject().apply { - id = "SET" - value = realmAnySetOf(1, 2, 3) - } - ) - } - - val set = o.value!!.asSet() - assertEquals(3, set.size) - val listener = async { - set.asFlow().collect { - channel.send(it) - } - } - - channel.receiveOrFail(1.seconds).run { - assertIs>(this) - val expectedSet = mutableSetOf(1, 2, 3) - this.set.forEach { expectedSet.remove(it!!.asInt()) } - assertTrue { expectedSet.isEmpty() } - } - - realm.write { - val liveSet = findLatest(o)!!.value!!.asSet() - liveSet.add(RealmAny.create(4)) - } - - channel.receiveOrFail(1.seconds).run { - assertIs>(this) - val expectedSet = mutableSetOf(1, 2, 3, 4) - this.set.forEach { expectedSet.remove(it!!.asInt()) } - assertTrue { expectedSet.isEmpty() } - } - - realm.write { - findLatest(o)!!.value = realmAnyOf(5) - } - - // Fails due to missing deletion events - channel.receiveOrFail(1.seconds).run { - assertIs>(this) - } - listener.cancel() - channel.close() - } - - @Test - override fun cancelAsFlow() { - kotlinx.coroutines.runBlocking { - val container = realm.write { - copyToRealm(JsonStyleRealmObject().apply { value = realmAnySetOf() }) - } - val channel1 = Channel>(1) - val channel2 = Channel>(1) - val observedSet = container.value!!.asSet() - val observer1 = async { - observedSet.asFlow() - .collect { change -> - channel1.trySend(change) - } - } - val observer2 = async { - observedSet.asFlow() - .collect { change -> - channel2.trySend(change) - } - } - - // Ignore first emission with empty sets - assertTrue { channel1.receiveOrFail(1.seconds).set.isEmpty() } - assertTrue { channel2.receiveOrFail(1.seconds).set.isEmpty() } - - // Trigger an update - realm.write { - val queriedContainer = findLatest(container) - queriedContainer!!.value!!.asSet().add(RealmAny.Companion.create(1)) - } - assertEquals(1, channel1.receiveOrFail().set.size) - assertEquals(1, channel2.receiveOrFail().set.size) - - // Cancel observer 1 - observer1.cancel() - - // Trigger another update - realm.write { - val queriedContainer = findLatest(container) - queriedContainer!!.value!!.asSet().add(RealmAny.create(2)) - } - - // Check channel 1 didn't receive the update - assertTrue(channel1.isEmpty) - // But channel 2 did - assertEquals(2, channel2.receiveOrFail().set.size) - - observer2.cancel() - channel1.close() - channel2.close() - } - } - - @Test - override fun deleteEntity() = runBlocking { - val container = - realm.write { copyToRealm(JsonStyleRealmObject().apply { value = realmAnySetOf() }) } - val mutex = Mutex(true) - val flow = async { - container.value!!.asSet().asFlow().first { - mutex.unlock() - it is DeletedSet<*> - } - } - - // Await that flow is actually running - mutex.lock() - // Update mixed value to overwrite and delete set - realm.write { - findLatest(container)!!.value = realmAnyListOf() - } - - // Await that notifier has signalled the deletion so we are certain that the entity - // has been deleted - withTimeout(10.seconds) { - flow.await() - } - } - - @Test - override fun asFlowOnDeletedEntity() = runBlocking { - val container = - realm.write { copyToRealm(JsonStyleRealmObject().apply { value = realmAnyListOf(realmAnySetOf()) }) } - val mutex = Mutex(true) - val flow = async { - container.value!!.asList()[0]!!.asSet().asFlow().first { - mutex.unlock() - it is DeletedSet<*> - } - } - - // Await that flow is actually running - mutex.lock() - // And delete containing entity - realm.write { delete(findLatest(container)!!) } - - // Await that notifier has signalled the deletion so we are certain that the entity - // has been deleted - withTimeout(10.seconds) { - flow.await() - } - - // Verify that a flow on the deleted entity will signal a deletion and complete gracefully - withTimeout(10.seconds) { - container.value!!.asList()[0]!!.asSet().asFlow().collect { - assertIs>(it) - } - } - } - - @Test - @Ignore - override fun closingRealmDoesNotCancelFlows() { - TODO("Not yet implemented") - } - - @Ignore - override fun closeRealmInsideFlowThrows() { - TODO("Not yet implemented") - } -} diff --git a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/utils/DeletableEntityNotificationTests.kt b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/utils/DeletableEntityNotificationTests.kt new file mode 100644 index 0000000000..08839b3f25 --- /dev/null +++ b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/utils/DeletableEntityNotificationTests.kt @@ -0,0 +1,33 @@ +/* + * Copyright 2023 Realm Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.realm.kotlin.test.common.utils + +/** + * All classes that tests classes that exposes notifications on entities that can be removed from + * the realm (i.e. RealmObject, RealmList, RealmSet, Backlinks but specifically not Realm and + * RealmResults) should implement this interface to be sure that we test common behaviour across + * those classes. + */ +interface DeletableEntityNotificationTests { + // Verify that we get deletion events and close the Flow when the object being observed (or + // containing object) is deleted. + fun deleteEntity() + + // Verify that we emit deletion events and close the flow when registering for notifications on + // an outdated entity. + fun asFlowOnDeletedEntity() +} diff --git a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/utils/RealmEntityNotificationTests.kt b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/utils/RealmEntityNotificationTests.kt index 0f7c8bca96..46aea13298 100644 --- a/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/utils/RealmEntityNotificationTests.kt +++ b/packages/test-base/src/commonTest/kotlin/io/realm/kotlin/test/common/utils/RealmEntityNotificationTests.kt @@ -17,17 +17,10 @@ package io.realm.kotlin.test.common.utils /** - * All classes that tests classes that exposes notifications on entities that can be removed from - * the realm (i.e. RealmObject, RealmList, RealmSet, Backlinks but specifically not Realm and - * RealmResults) should implement this interface to be sure that we test common behaviour across + * Test for top level entities that can be deleted and supports key-path-filtering (i.e. + * RealmObject, RealmList, RealmSet, Backlinks but specifically not Realm, RealmResults and + * RealmAny) should implement this interface to be sure that we test common behaviour across * those classes. */ -interface RealmEntityNotificationTests : FlowableTests, KeyPathFlowableTests { - // Verify that we get deletion events and close the Flow when the object being observed (or - // containing object) is deleted. - fun deleteEntity() - - // Verify that we emit deletion events and close the flow when registering for notifications on - // an outdated entity. - fun asFlowOnDeletedEntity() -} +interface RealmEntityNotificationTests : + FlowableTests, DeletableEntityNotificationTests, KeyPathFlowableTests diff --git a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncedRealmTests.kt b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncedRealmTests.kt index 68f79594cf..e4de142f56 100644 --- a/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncedRealmTests.kt +++ b/packages/test-sync/src/commonTest/kotlin/io/realm/kotlin/test/mongodb/common/SyncedRealmTests.kt @@ -31,7 +31,6 @@ import io.realm.kotlin.entities.sync.flx.FlexParentObject import io.realm.kotlin.ext.query import io.realm.kotlin.ext.realmAnyDictionaryOf import io.realm.kotlin.ext.realmAnyListOf -import io.realm.kotlin.ext.realmAnySetOf import io.realm.kotlin.internal.platform.fileExists import io.realm.kotlin.internal.platform.pathOf import io.realm.kotlin.internal.platform.runBlocking @@ -69,6 +68,8 @@ import io.realm.kotlin.test.util.TestHelper.randomEmail import io.realm.kotlin.test.util.receiveOrFail import io.realm.kotlin.test.util.trySendOrFail import io.realm.kotlin.test.util.use +import io.realm.kotlin.types.BaseRealmObject +import kotlinx.atomicfu.atomic import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.async import kotlinx.coroutines.delay @@ -83,6 +84,7 @@ import okio.Path.Companion.toPath import org.mongodb.kbson.ObjectId import kotlin.random.Random import kotlin.random.nextULong +import kotlin.reflect.KClass import kotlin.test.AfterTest import kotlin.test.BeforeTest import kotlin.test.Ignore @@ -1335,6 +1337,8 @@ class SyncedRealmTests { println("Partition based sync bundled realm is in ${config2.path}") } + // This test cannot run multiple times on the same server instance as the primary + // key of the objects from asset-pbs.realm will not be unique on secondary runs. @Test fun initialRealm_partitionBasedSync() { val (email, password) = randomEmail() to "password1234" @@ -1364,26 +1368,24 @@ class SyncedRealmTests { } } + val initialDataVerified = atomic(false) val config2 = createPartitionSyncConfig( - user = user, partitionValue = partitionValue, name = "db1", + user = user, partitionValue = partitionValue, name = "db2", errorHandler = object : SyncSession.ErrorHandler { override fun onError(session: SyncSession, error: SyncException) { - fail("Realm 1: $error") + fail("Realm 2: $error") } } ) { waitForInitialRemoteData(30.seconds) initialData { - // Verify that initial data is running before data is synced - assertEquals(0, query().find().size) - } - } - Realm.open(config2).use { - runBlocking { - it.syncSession.downloadAllServerChanges(30.seconds) - assertEquals(4, it.query().find().size) + // Verify that initial data is running after data is synced + assertEquals(4, query().find().size) + initialDataVerified.value = true } } + Realm.open(config2).use { } + assertTrue { initialDataVerified.value } } @Test @@ -1535,9 +1537,6 @@ class SyncedRealmTests { Realm.open(local).use { it.write { val obj = copyToRealm(JsonStyleRealmObject()) - assertFailsWithMessage("Cannot sync nested set") { - obj.value = realmAnySetOf() - } assertFailsWithMessage("Cannot sync nested list") { obj.value = realmAnyListOf() } @@ -1898,9 +1897,10 @@ class SyncedRealmTests { encryptionKey: ByteArray? = null, log: LogConfiguration? = null, errorHandler: ErrorHandler? = null, + schema: Set> = PARTITION_BASED_SCHEMA, block: SyncConfiguration.Builder.() -> Unit = {} ): SyncConfiguration = SyncConfiguration.Builder( - schema = PARTITION_BASED_SCHEMA, + schema = schema, user = user, partitionValue = partitionValue ).name(name).also { builder -> @@ -1917,11 +1917,12 @@ class SyncedRealmTests { encryptionKey: ByteArray? = null, log: LogConfiguration? = null, errorHandler: ErrorHandler? = null, + schema: Set> = FLEXIBLE_SYNC_SCHEMA, initialSubscriptions: InitialSubscriptionsCallback? = null, block: SyncConfiguration.Builder.() -> Unit = {}, ): SyncConfiguration = SyncConfiguration.Builder( user = user, - schema = FLEXIBLE_SYNC_SCHEMA + schema = schema ).name(name).also { builder -> if (encryptionKey != null) builder.encryptionKey(encryptionKey) if (errorHandler != null) builder.errorHandler(errorHandler)