commonMain.io.realm.kotlin.internal.RealmObjectUtil.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of library-base-jvm Show documentation
Show all versions of library-base-jvm Show documentation
Library code for Realm Kotlin. This artifact is not supposed to be consumed directly, but through 'io.realm.kotlin:gradle-plugin:1.11.1' instead.
/*
* Copyright 2021 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.internal
import io.realm.kotlin.VersionId
import io.realm.kotlin.dynamic.DynamicRealmObject
import io.realm.kotlin.internal.interop.ClassKey
import io.realm.kotlin.internal.interop.Link
import io.realm.kotlin.internal.interop.ObjectKey
import io.realm.kotlin.internal.interop.RealmInterop
import io.realm.kotlin.internal.interop.RealmObjectPointer
import io.realm.kotlin.internal.platform.realmObjectCompanionOrNull
import io.realm.kotlin.internal.platform.realmObjectCompanionOrThrow
import io.realm.kotlin.types.BaseRealmObject
import kotlin.reflect.KClass
internal fun RealmObjectInternal.manage(
realm: RealmReference,
mediator: Mediator,
type: KClass,
objectPointer: RealmObjectPointer
): T {
this.io_realm_kotlin_objectReference = RealmObjectReference(
type = type,
owner = realm,
mediator = mediator,
objectPointer = objectPointer,
className = if (this@manage is DynamicRealmObject) {
RealmInterop.realm_get_class(
realm.dbPointer,
RealmInterop.realm_object_get_table(objectPointer)
).name
} else {
realmObjectCompanionOrThrow(type).io_realm_kotlin_className
}
)
@Suppress("UNCHECKED_CAST")
return this as T
}
internal fun RealmObjectInternal.link(
realm: RealmReference,
mediator: Mediator,
type: KClass,
link: Link
): T {
val objectPointer = RealmInterop.realm_get_object(realm.dbPointer, link)
return this.manage(realm, mediator, type, objectPointer)
}
/**
* Instantiates a [BaseRealmObject] from its Core [Link] representation. For internal use only.
*/
internal fun Link.toRealmObject(
clazz: KClass,
mediator: Mediator,
realm: RealmReference
): T = mediator.createInstanceOf(clazz).link(
realm = realm,
mediator = mediator,
type = clazz,
link = this
)
/**
* Instantiates a [BaseRealmObject] from its Core [NativePointer] representation. For internal use only.
*/
internal fun RealmObjectPointer.toRealmObject(
clazz: KClass,
mediator: Mediator,
realm: RealmReference
): T = mediator.createInstanceOf(clazz).manage(
realm = realm,
mediator = mediator,
type = clazz,
objectPointer = this
)
/**
* Instantiates a [BaseRealmObject] from its Core [RealmObjectReference] representation. For internal use only.
*/
internal fun RealmObjectReference.toRealmObject(): T =
mediator.createInstanceOf(type)
.manage(
realm = owner,
mediator = mediator,
type = type,
objectPointer = objectPointer,
)
/**
* Returns the [RealmObjectCompanion] associated with a given [BaseRealmObject]'s [KClass].
*/
@Suppress("NOTHING_TO_INLINE")
internal inline fun KClass<*>.realmObjectCompanionOrNull(): RealmObjectCompanion? {
@Suppress("invisible_reference", "invisible_member")
return realmObjectCompanionOrNull(this)
}
/**
* Returns the [RealmObjectCompanion] associated with a given [BaseRealmObject]'s [KClass].
*/
internal inline fun KClass.realmObjectCompanionOrThrow(): RealmObjectCompanion {
@Suppress("invisible_reference", "invisible_member")
return realmObjectCompanionOrThrow(this)
}
/**
* Convenience property to get easy access to the RealmObjectReference of a BaseRealmObject.
*
* This will be `null` for unmanaged objects.
*/
internal val T.realmObjectReference: RealmObjectReference?
@Suppress("UNCHECKED_CAST")
get() = (this as RealmObjectInternal).io_realm_kotlin_objectReference as RealmObjectReference?
/**
* If the Realm Object is managed it calls the specified function block and returns its result,
* otherwise returns null.
*/
internal inline fun T.runIfManaged(block: RealmObjectReference.() -> R): R? =
realmObjectReference?.run(block)
/**
* Returns an identifier that uniquely identifies a RealmObject. This includes the version of the
* object, so the same RealmObject at two different versions must have different identifiers,
* even if all data inside the object is otherwise equal.
*/
internal fun BaseRealmObject.getIdentifier(): RealmObjectIdentifier {
return runIfManaged {
val classKey: ClassKey = metadata.classKey
val objKey: ObjectKey = RealmInterop.realm_object_get_key(objectPointer)
val version: VersionId = version()
val path: String = owner.owner.configuration.path
return RealmObjectIdentifier(classKey, objKey, version, path)
} ?: throw IllegalStateException("Identifier can only be calculated for managed objects.")
}
public fun BaseRealmObject.getIdentifierOrNull(): RealmObjectIdentifier? {
return runIfManaged {
getIdentifier()
}
}
/**
* Checks whether [this] and [other] represent the same underlying object or not. It allows to check
* if two object from different frozen realms share their object key, and thus represent the same
* object at different points in time (= at two different frozen realm versions).
*/
internal fun BaseRealmObject.hasSameObjectKey(other: BaseRealmObject?): Boolean {
if (other == null) return false
return runIfManaged {
val otherObjectPointer = this.objectPointer
other.runIfManaged {
val thisKey = RealmInterop.realm_object_get_key(this.objectPointer)
val otherKey = RealmInterop.realm_object_get_key(otherObjectPointer)
thisKey == otherKey
}
} ?: throw IllegalStateException("Cannot compare unmanaged objects.")
}
@Suppress("LongParameterList")
internal fun createDetachedCopy(
mediator: Mediator,
realmObject: T,
currentDepth: UInt,
maxDepth: UInt,
closeAfterCopy: Boolean,
cache: ManagedToUnmanagedObjectCache,
): T {
val id = realmObject.getIdentifier()
@Suppress("UNCHECKED_CAST")
val result: BaseRealmObject = cache[id] as T? ?: run {
val unmanagedObject = mediator.companionOf(realmObject::class).`io_realm_kotlin_newInstance`() as BaseRealmObject
cache[id] = unmanagedObject
RealmObjectHelper.assignValuesOnUnmanagedObject(
unmanagedObject,
realmObject,
mediator,
currentDepth,
maxDepth,
closeAfterCopy,
cache
)
unmanagedObject
}
if (closeAfterCopy) {
realmObject.realmObjectReference!!.objectPointer.release()
}
@Suppress("UNCHECKED_CAST")
return result as T
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy