Skip to content

Commit

Permalink
Merge pull request #1716 from realm/next-major
Browse files Browse the repository at this point in the history
[RKOTLIN-838] Collections in mixed
  • Loading branch information
rorbech authored Apr 15, 2024
2 parents d8c839d + 2e893c7 commit 77512f7
Show file tree
Hide file tree
Showing 51 changed files with 3,295 additions and 700 deletions.
10 changes: 6 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
## 1.15.0-SNAPSHOT (YYYY-MM-DD)

[!NOTE]
This release will bump the Realm file format from version 23 to 24. Opening a file with an older format will automatically upgrade it from file format v10. If you want to upgrade from an earlier file format version you will have to use Realm Kotlin v1.13.1 or earlier. Downgrading to a previous file format is not possible.
> [!NOTE]
> This release will bump the Realm file format from version 23 to 24. Opening a file with an older format will automatically upgrade it from file format v10. If you want to upgrade from an earlier file format version you will have to use Realm Kotlin v1.13.1 or earlier. Downgrading to a previous file format is not possible.
### Breaking changes
* If you want to query using `@type` operation, you must use 'objectlink' to match links to objects. 'object' is reserved for dictionary types.
* Binary data and String data are now strongly typed for comparisons and queries. This change is especially relevant when querying for a string constant on a RealmAny property, as now only strings will be returned. If searching for Binary data is desired, then that type must be specified by the constant. In RQL the new way to specify a binary constant is to use `mixed = bin('xyz')` or `mixed = binary('xyz')`. (Core issue [realm/realm-core#6407](https://github.com/realm/realm-core/issues/6407)).

### Enhancements
* Support for RealmLists and RealmDictionaries in `RealmAny`. (Issue [#1434](https://github.com/realm/realm-kotlin/issues/1434))
* Add support for using aggregate operations on RealmAny properties in queries (Core issue [realm/realm-core#7398](https://github.com/realm/realm-core/pull/7398))
* Property keypath in RQL can be substituted with value given as argument. Use '$P<i>' in query string. (Core issue [realm/realm-core#7033](https://github.com/realm/realm-core/issues/7033))
* You can now use query substitution for the @type argument (Core issue [realm/realm-core#7289](https://github.com/realm/realm-core/issues/7289))
Expand All @@ -16,7 +17,8 @@ This release will bump the Realm file format from version 23 to 24. Opening a fi
* Index on list of strings property now supported (Core issue [realm/realm-core#7142](https://github.com/realm/realm-core/pull/7142))
* Improved performance of RQL (parsed) queries on a non-linked string property using: >, >=, <, <=, operators and fixed behaviour that a null string should be evaulated as less than everything, previously nulls were not matched. (Core issue [realm/realm-core#3939](https://github.com/realm/realm-core/issues/3939).
* Updated bundled OpenSSL version to 3.2.0 (Core issue [realm/realm-core#7303](https://github.com/realm/realm-core/pull/7303))
* The default base url in `AppConfiguration` has been updated to point to `services.cloud.mongodb.com`. See https://www.mongodb.com/docs/atlas/app-services/domain-migration/ for more information. (Issue [#1685](https://github.com/realm/realm-kotlin/issues/1685))
* Optimized `RealmList.indexOf()` and `RealmList.contains()` using Core implementation of operations instead of iterating elements and comparing them in Kotlin. (Issue [#1625](https://github.com/realm/realm-kotlin/pull/1666) [RKOTLIN-995](https://jira.mongodb.org/browse/RKOTLIN-995)).
* [Sync] The default base url in `AppConfiguration` has been updated to point to `services.cloud.mongodb.com`. See https://www.mongodb.com/docs/atlas/app-services/domain-migration/ for more information. (Issue [#1685](https://github.com/realm/realm-kotlin/issues/1685))

### Fixed
* Sorting order of strings has changed to use standard unicode codepoint order instead of grouping similar english letters together. A noticeable change will be from "aAbBzZ" to "ABZabz". (Core issue [realm/realm-core#2573](https://github.com/realm/realm-core/issues/2573))
Expand Down Expand Up @@ -49,7 +51,7 @@ This release will bump the Realm file format from version 23 to 24. Opening a fi
* Minimum R8: 8.0.34.

### Internal
* Updated to Realm Core 14.4.1 commit 374dd672af357732dccc135fecc905406fec3223.
* Updated to Realm Core 14.5.1 commit 316889b967f845fbc10b4422f96c7eadd47136f2.
* Deprecated Jenkins and switching to Github Action ([JIRA]https://jira.mongodb.org/browse/RKOTLIN-825).
- Remove CMake required version.
* Updated URL to documentation.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ expect enum class ErrorCode : CodeDescription {
RLM_ERR_MAINTENANCE_IN_PROGRESS,
RLM_ERR_USERPASS_TOKEN_INVALID,
RLM_ERR_INVALID_SERVER_RESPONSE,
REALM_ERR_APP_SERVER_ERROR,
RLM_ERR_APP_SERVER_ERROR,
RLM_ERR_CALLBACK,
RLM_ERR_UNKNOWN;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,6 @@ expect enum class ValueType {
RLM_TYPE_OBJECT_ID,
RLM_TYPE_LINK,
RLM_TYPE_UUID,
RLM_TYPE_LIST,
RLM_TYPE_DICTIONARY,
}
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ expect val INVALID_PROPERTY_KEY: PropertyKey
const val OBJECT_ID_BYTES_SIZE = 12
const val UUID_BYTES_SIZE = 16

const val INDEX_NOT_FOUND = -1L

// Pure marker interfaces corresponding to the C-API realm_x_t struct types
interface CapiT
interface RealmConfigT : CapiT
Expand Down Expand Up @@ -304,6 +306,8 @@ expect object RealmInterop {
isDefault: Boolean
)
fun realm_set_embedded(obj: RealmObjectPointer, key: PropertyKey): RealmObjectPointer
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)
fun <T> realm_object_get_parent(
obj: RealmObjectPointer,
Expand All @@ -315,10 +319,17 @@ 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_find(list: RealmListPointer, value: RealmValue): Long
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_list(list: RealmListPointer, index: Long): RealmListPointer
fun realm_list_insert_dictionary(list: RealmListPointer, index: Long): RealmMapPointer
fun realm_list_set_list(list: RealmListPointer, index: Long): RealmListPointer
fun realm_list_set_dictionary(list: RealmListPointer, index: Long): RealmMapPointer

// Returns the newly inserted element as the previous embedded element is automatically delete
// by this operation
Expand Down Expand Up @@ -350,10 +361,19 @@ expect object RealmInterop {
dictionary: RealmMapPointer,
mapKey: RealmValue
): RealmValue
fun realm_dictionary_find_list(
dictionary: RealmMapPointer,
mapKey: RealmValue
): RealmListPointer
fun realm_dictionary_find_dictionary(
dictionary: RealmMapPointer,
mapKey: RealmValue
): RealmMapPointer
fun MemAllocator.realm_dictionary_get(
dictionary: RealmMapPointer,
pos: Int
): Pair<RealmValue, RealmValue>

fun MemAllocator.realm_dictionary_insert(
dictionary: RealmMapPointer,
mapKey: RealmValue,
Expand All @@ -375,6 +395,8 @@ expect object RealmInterop {
dictionary: RealmMapPointer,
mapKey: RealmValue
): RealmValue
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
fun realm_dictionary_resolve_in(
dictionary: RealmMapPointer,
Expand Down Expand Up @@ -439,6 +461,8 @@ expect object RealmInterop {

// FIXME OPTIMIZE Get many
fun MemAllocator.realm_results_get(results: RealmResultsPointer, index: Long): RealmValue
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)

fun realm_get_object(realm: RealmPointer, link: Link): RealmObjectPointer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ actual enum class ErrorCode(override val description: String, override val nativ
RLM_ERR_MAINTENANCE_IN_PROGRESS("MaintenanceInProgress", realm_errno_e.RLM_ERR_MAINTENANCE_IN_PROGRESS),
RLM_ERR_USERPASS_TOKEN_INVALID("UserpassTokenInvalid", realm_errno_e.RLM_ERR_USERPASS_TOKEN_INVALID),
RLM_ERR_INVALID_SERVER_RESPONSE("InvalidServerResponse", realm_errno_e.RLM_ERR_INVALID_SERVER_RESPONSE),
REALM_ERR_APP_SERVER_ERROR("AppServerError", realm_errno_e.RLM_ERR_APP_SERVER_ERROR),
RLM_ERR_APP_SERVER_ERROR("AppServerError", realm_errno_e.RLM_ERR_APP_SERVER_ERROR),
RLM_ERR_CALLBACK("Callback", realm_errno_e.RLM_ERR_CALLBACK),
RLM_ERR_UNKNOWN("Unknown", realm_errno_e.RLM_ERR_UNKNOWN);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,15 @@ actual object RealmInterop {
return LongPointerWrapper(realmc.realm_set_embedded(obj.cptr(), key.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)
}
actual fun realm_set_dictionary(obj: RealmObjectPointer, key: PropertyKey): RealmMapPointer {
realmc.realm_set_dictionary(obj.cptr(), key.key)
return realm_get_dictionary(obj, key)
}

actual fun realm_object_add_int(obj: RealmObjectPointer, key: PropertyKey, value: Long) {
realmc.realm_object_add_int(obj.cptr(), key.key, value)
}
Expand Down Expand Up @@ -560,13 +569,42 @@ actual object RealmInterop {
return RealmValue(struct)
}

actual fun realm_list_find(list: RealmListPointer, value: RealmValue): Long {
val index = LongArray(1)
val found = BooleanArray(1)
realmc.realm_list_find(list.cptr(), value.value, index, found)
return if (found[0]) {
index[0]
} else {
INDEX_NOT_FOUND
}
}

actual fun realm_list_get_list(list: RealmListPointer, index: Long): RealmListPointer =
LongPointerWrapper(realmc.realm_list_get_list(list.cptr(), index))

actual fun realm_list_get_dictionary(list: RealmListPointer, index: Long): RealmMapPointer =
LongPointerWrapper(realmc.realm_list_get_dictionary(list.cptr(), index))

actual fun realm_list_add(list: RealmListPointer, index: Long, transport: RealmValue) {
realmc.realm_list_insert(list.cptr(), index, transport.value)
}

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_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_list(list: RealmListPointer, index: Long): RealmListPointer {
return LongPointerWrapper(realmc.realm_list_set_list(list.cptr(), index))
}
actual fun realm_list_set_dictionary(list: RealmListPointer, index: Long): RealmMapPointer {
return LongPointerWrapper(realmc.realm_list_set_dictionary(list.cptr(), index))
}

actual fun realm_list_set(
list: RealmListPointer,
Expand Down Expand Up @@ -724,6 +762,19 @@ actual object RealmInterop {
return RealmValue(struct)
}

actual fun realm_dictionary_find_list(
dictionary: RealmMapPointer,
mapKey: RealmValue
): RealmListPointer {
return LongPointerWrapper(realmc.realm_dictionary_get_list(dictionary.cptr(), mapKey.value))
}
actual fun realm_dictionary_find_dictionary(
dictionary: RealmMapPointer,
mapKey: RealmValue
): RealmMapPointer {
return LongPointerWrapper(realmc.realm_dictionary_get_dictionary(dictionary.cptr(), mapKey.value))
}

actual fun MemAllocator.realm_dictionary_get(
dictionary: RealmMapPointer,
pos: Int
Expand Down Expand Up @@ -792,6 +843,14 @@ actual object RealmInterop {
)
}

actual fun realm_dictionary_insert_list(dictionary: RealmMapPointer, mapKey: RealmValue): RealmListPointer {
return LongPointerWrapper(realmc.realm_dictionary_insert_list(dictionary.cptr(), mapKey.value))
}

actual fun realm_dictionary_insert_dictionary(dictionary: RealmMapPointer, mapKey: RealmValue): RealmMapPointer {
return LongPointerWrapper(realmc.realm_dictionary_insert_dictionary(dictionary.cptr(), mapKey.value))
}

actual fun realm_dictionary_get_keys(dictionary: RealmMapPointer): RealmResultsPointer {
val size = LongArray(1)
val keysPointer = longArrayOf(0)
Expand Down Expand Up @@ -1053,7 +1112,7 @@ actual object RealmInterop {
deletions,
insertions,
modifications,
collectionWasDeleted
collectionWasDeleted,
)

val deletionStructs = realmc.new_valueArray(deletions[0].toInt())
Expand Down Expand Up @@ -1861,6 +1920,12 @@ actual object RealmInterop {
return RealmValue(value)
}

actual fun realm_results_get_list(results: RealmResultsPointer, index: Long): RealmListPointer =
LongPointerWrapper(realmc.realm_results_get_list(results.cptr(), index))

actual fun realm_results_get_dictionary(results: RealmResultsPointer, index: Long): RealmMapPointer =
LongPointerWrapper(realmc.realm_results_get_dictionary(results.cptr(), index))

actual fun realm_get_object(realm: RealmPointer, link: Link): RealmObjectPointer {
return LongPointerWrapper(realmc.realm_get_object(realm.cptr(), link.classKey.key, link.objKey))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ actual enum class ValueType(override val nativeValue: Int) : NativeEnumerated {
RLM_TYPE_DECIMAL128(realm_value_type_e.RLM_TYPE_DECIMAL128),
RLM_TYPE_OBJECT_ID(realm_value_type_e.RLM_TYPE_OBJECT_ID),
RLM_TYPE_LINK(realm_value_type_e.RLM_TYPE_LINK),
RLM_TYPE_UUID(realm_value_type_e.RLM_TYPE_UUID);
RLM_TYPE_UUID(realm_value_type_e.RLM_TYPE_UUID),
RLM_TYPE_LIST(realm_value_type_e.RLM_TYPE_LIST),
RLM_TYPE_DICTIONARY(realm_value_type_e.RLM_TYPE_DICTIONARY);

companion object {
fun from(nativeValue: Int): ValueType = values().find {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ actual enum class ErrorCode(
RLM_ERR_MAINTENANCE_IN_PROGRESS("MaintenanceInProgress", realm_errno.RLM_ERR_MAINTENANCE_IN_PROGRESS),
RLM_ERR_USERPASS_TOKEN_INVALID("UserpassTokenInvalid", realm_errno.RLM_ERR_USERPASS_TOKEN_INVALID),
RLM_ERR_INVALID_SERVER_RESPONSE("InvalidServerResponse", realm_errno.RLM_ERR_INVALID_SERVER_RESPONSE),
REALM_ERR_APP_SERVER_ERROR("AppServerError", realm_errno.RLM_ERR_APP_SERVER_ERROR),
RLM_ERR_APP_SERVER_ERROR("AppServerError", realm_errno.RLM_ERR_APP_SERVER_ERROR),
RLM_ERR_CALLBACK("Callback", realm_errno.RLM_ERR_CALLBACK),
RLM_ERR_UNKNOWN("Unknown", realm_errno.RLM_ERR_UNKNOWN);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,10 @@ actual enum class ValueType(
RLM_TYPE_DECIMAL128(realm_value_type_e.RLM_TYPE_DECIMAL128),
RLM_TYPE_OBJECT_ID(realm_value_type_e.RLM_TYPE_OBJECT_ID),
RLM_TYPE_LINK(realm_value_type_e.RLM_TYPE_LINK),
RLM_TYPE_UUID(realm_value_type_e.RLM_TYPE_UUID);
RLM_TYPE_UUID(realm_value_type_e.RLM_TYPE_UUID),
RLM_TYPE_LIST(realm_value_type_e.RLM_TYPE_LIST),
RLM_TYPE_DICTIONARY(realm_value_type_e.RLM_TYPE_DICTIONARY),
;

companion object {
fun from(nativeValue: realm_value_type): ValueType = values().find {
Expand Down
Loading

0 comments on commit 77512f7

Please sign in to comment.