Skip to content

Commit

Permalink
Add option for automatic resolution of embedded object constraints du…
Browse files Browse the repository at this point in the history
…ring migration (#1473)
  • Loading branch information
rorbech authored Aug 15, 2023
1 parent 273fd31 commit 64f1096
Show file tree
Hide file tree
Showing 13 changed files with 274 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

### Enhancements
* Support for performing geospatial queries using the new classes: `GeoPoint`, `GeoCircle`, `GeoBox`, and `GeoPolygon`. See `GeoPoint` documentation on how to persist locations. (Issue [#1403](https://github.com/realm/realm-kotlin/pull/1403))
* Support for automatic resolution of embedded object constraints during migration through `RealmConfiguration.Builder.migration(migration: AutomaticSchemaMigration, resolveEmbeddedObjectConstraints: Boolean)`. (Issue [#1464](https://github.com/realm/realm-kotlin/issues/1464)
* [Sync] Add support for customizing authorization headers and adding additional custom headers to all Atlas App service requests with `AppConfiguration.Builder.authorizationHeaderName()` and `AppConfiguration.Builder.addCustomRequestHeader(...)`. (Issue [#1453](https://github.com/realm/realm-kotlin/pull/1453))

### Fixed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ expect object RealmInterop {
fun realm_config_get_encryption_key(config: RealmConfigurationPointer): ByteArray?
fun realm_config_set_should_compact_on_launch_function(config: RealmConfigurationPointer, callback: CompactOnLaunchCallback)
fun realm_config_set_migration_function(config: RealmConfigurationPointer, callback: MigrationCallback)
fun realm_config_set_automatic_backlink_handling(config: RealmConfigurationPointer, enabled: Boolean)
fun realm_config_set_data_initialization_function(config: RealmConfigurationPointer, callback: DataInitializationCallback)
fun realm_config_set_in_memory(config: RealmConfigurationPointer, inMemory: Boolean)
fun realm_schema_validate(schema: RealmSchemaPointer, mode: SchemaValidationMode): Boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,10 @@ actual object RealmInterop {
realmc.realm_config_set_migration_function(config.cptr(), callback)
}

actual fun realm_config_set_automatic_backlink_handling(config: RealmConfigurationPointer, enabled: Boolean) {
realmc.realm_config_set_automatic_backlink_handling(config.cptr(), enabled)
}

actual fun realm_config_set_data_initialization_function(config: RealmConfigurationPointer, callback: DataInitializationCallback) {
realmc.realm_config_set_data_initialization_function(config.cptr(), callback)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,15 @@ actual object RealmInterop {
)
}

actual fun realm_config_set_automatic_backlink_handling(
config: RealmConfigurationPointer,
enabled: Boolean
) {
realm_wrapper.realm_config_set_automatic_backlink_handling(
config.cptr(),
enabled,
)
}
actual fun realm_config_set_migration_function(
config: RealmConfigurationPointer,
callback: MigrationCallback
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import io.realm.kotlin.internal.platform.appFilesDirectory
import io.realm.kotlin.internal.util.CoroutineDispatcherFactory
import io.realm.kotlin.log.RealmLog
import io.realm.kotlin.log.RealmLogger
import io.realm.kotlin.migration.AutomaticSchemaMigration
import io.realm.kotlin.migration.RealmMigration
import io.realm.kotlin.types.TypedRealmObject
import kotlin.reflect.KClass
Expand Down Expand Up @@ -55,6 +56,7 @@ public interface RealmConfiguration : Configuration {
private var directory: String = appFilesDirectory()
private var deleteRealmIfMigrationNeeded: Boolean = false
private var migration: RealmMigration? = null
private var automaticEmbeddedObjectConstraintsResolution = false

/**
* Sets the path to the directory that contains the realm file. If the directory does not
Expand Down Expand Up @@ -109,6 +111,29 @@ public interface RealmConfiguration : Configuration {
public fun migration(migration: RealmMigration): Builder =
apply { this.migration = migration }

/**
* Sets the migration to handle schema updates with automatic migration of data.
*
* @param migration the [AutomaticSchemaMigration] instance to handle schema and data
* migration in the event of a schema update.
* @param resolveEmbeddedObjectConstraints a flag to indicate whether realm should resolve
* embedded object constraints after migration. If this is `true` then all embedded objects
* without a parent will be deleted and every embedded object with multiple references to it
* will be duplicated so that every referencing object will hold its own copy of the
* embedded object.
*
* @see RealmMigration
* @see AutomaticSchemaMigration
*/
public fun migration(
migration: AutomaticSchemaMigration,
resolveEmbeddedObjectConstraints: Boolean = false
): Builder =
apply {
this.migration = migration
this.automaticEmbeddedObjectConstraintsResolution = resolveEmbeddedObjectConstraints
}

override fun name(name: String): Builder = apply {
checkName(name)
this.name = name
Expand Down Expand Up @@ -163,6 +188,7 @@ public interface RealmConfiguration : Configuration {
deleteRealmIfMigrationNeeded,
compactOnLaunchCallback,
migration,
automaticEmbeddedObjectConstraintsResolution,
initialDataCallback,
inMemory,
initialRealmFileConfiguration,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ import kotlin.reflect.KClass

// TODO Public due to being accessed from `library-sync`
@Suppress("LongParameterList")
public open class ConfigurationImpl constructor(
public open class ConfigurationImpl(
directory: String,
name: String,
schema: Set<KClass<out BaseRealmObject>>,
Expand All @@ -60,6 +60,7 @@ public open class ConfigurationImpl constructor(
private val userEncryptionKey: ByteArray?,
compactOnLaunchCallback: CompactOnLaunchCallback?,
private val userMigration: RealmMigration?,
automaticBacklinkHandling: Boolean,
initialDataCallback: InitialDataCallback?,
override val isFlexibleSyncConfiguration: Boolean,
inMemory: Boolean,
Expand Down Expand Up @@ -218,6 +219,7 @@ public open class ConfigurationImpl constructor(
migrationCallback?.let {
RealmInterop.realm_config_set_migration_function(nativeConfig, it)
}
RealmInterop.realm_config_set_automatic_backlink_handling(nativeConfig, automaticBacklinkHandling)

userEncryptionKey?.let { key: ByteArray ->
RealmInterop.realm_config_set_encryption_key(nativeConfig, key)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import kotlin.reflect.KClass
public const val REALM_FILE_EXTENSION: String = ".realm"

@Suppress("LongParameterList")
internal class RealmConfigurationImpl constructor(
internal class RealmConfigurationImpl(
directory: String,
name: String,
schema: Set<KClass<out BaseRealmObject>>,
Expand All @@ -43,6 +43,7 @@ internal class RealmConfigurationImpl constructor(
override val deleteRealmIfMigrationNeeded: Boolean,
compactOnLaunchCallback: CompactOnLaunchCallback?,
migration: RealmMigration?,
automaticBacklinkHandling: Boolean,
initialDataCallback: InitialDataCallback?,
inMemory: Boolean,
override val initialRealmFileConfiguration: InitialRealmFileConfiguration?,
Expand All @@ -63,6 +64,7 @@ internal class RealmConfigurationImpl constructor(
encryptionKey,
compactOnLaunchCallback,
migration,
automaticBacklinkHandling,
initialDataCallback,
false,
inMemory,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,7 @@ public interface SyncConfiguration : Configuration {
encryptionKey,
compactOnLaunchCallback,
null, // migration is not relevant for sync,
false, // automatic backlink handling is not relevant for sync
initialDataCallback,
partitionValue == null,
inMemory,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* 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.entities.migration.embedded.after

import io.realm.kotlin.types.EmbeddedRealmObject

class EmbeddedMigrationChild : EmbeddedRealmObject {
var id: String = "child"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* 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.entities.migration.embedded.after

import io.realm.kotlin.types.RealmObject

class EmbeddedMigrationParent : RealmObject {
var id: String = "parent"
var child: EmbeddedMigrationChild? = null
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* 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.entities.migration.embedded.before

import io.realm.kotlin.types.RealmObject

class EmbeddedMigrationChild : RealmObject {
var id: String = "child"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* 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.entities.migration.embedded.before

import io.realm.kotlin.types.RealmObject

class EmbeddedMigrationParent : RealmObject {
var id: String = "parent"
var child: EmbeddedMigrationChild? = null
}
Loading

0 comments on commit 64f1096

Please sign in to comment.