From 83201ac42e2b3ce5d1b27d3d900d3509b7fa15b0 Mon Sep 17 00:00:00 2001 From: cbullinger Date: Mon, 9 Oct 2023 21:01:14 -0400 Subject: [PATCH] Add snippets --- .../realm/realmkmmapp/DataTypesTest.kt | 75 +---- .../mongodb/realm/realmkmmapp/DeleteTest.kt | 290 +++++++++++++----- ...ypesTest.snippet.update-embedded-object.kt | 4 +- ...eteTest.snippet.chain-delete-realm-list.kt | 17 + .../kotlin/DeleteTest.snippet.clear-set.kt | 11 +- ...teTest.snippet.delete-all-realm-objects.kt | 7 + ...leteTest.snippet.delete-embedded-object.kt | 15 + ...t.snippet.delete-multiple-realm-objects.kt | 8 + ...eteTest.snippet.delete-one-realm-object.kt | 9 + ...eteTest.snippet.delete-realm-dictionary.kt | 9 +- ...elete-realm-object-with-related-objects.kt | 13 + ...t.snippet.fetch-latest-to-delete-object.kt | 11 + .../kotlin/DeleteTest.snippet.list-clear.kt | 10 + ...DeleteTest.snippet.remove-item-from-set.kt | 16 +- ...leteTest.snippet.remove-items-from-list.kt | 20 ++ .../includes/kotlin-write-to-synced-realm.rst | 6 + source/includes/kotlin-write-transactions.rst | 40 +++ .../sdk/kotlin/realm-database/crud/delete.txt | 247 ++++++++------- 18 files changed, 528 insertions(+), 280 deletions(-) create mode 100644 source/examples/generated/kotlin/DeleteTest.snippet.chain-delete-realm-list.kt create mode 100644 source/examples/generated/kotlin/DeleteTest.snippet.delete-all-realm-objects.kt create mode 100644 source/examples/generated/kotlin/DeleteTest.snippet.delete-embedded-object.kt create mode 100644 source/examples/generated/kotlin/DeleteTest.snippet.delete-multiple-realm-objects.kt create mode 100644 source/examples/generated/kotlin/DeleteTest.snippet.delete-one-realm-object.kt create mode 100644 source/examples/generated/kotlin/DeleteTest.snippet.delete-realm-object-with-related-objects.kt create mode 100644 source/examples/generated/kotlin/DeleteTest.snippet.fetch-latest-to-delete-object.kt create mode 100644 source/examples/generated/kotlin/DeleteTest.snippet.list-clear.kt create mode 100644 source/examples/generated/kotlin/DeleteTest.snippet.remove-items-from-list.kt create mode 100644 source/includes/kotlin-write-to-synced-realm.rst create mode 100644 source/includes/kotlin-write-transactions.rst diff --git a/examples/kotlin/shared/src/commonTest/kotlin/com/mongodb/realm/realmkmmapp/DataTypesTest.kt b/examples/kotlin/shared/src/commonTest/kotlin/com/mongodb/realm/realmkmmapp/DataTypesTest.kt index fb3bb1eacef..7b7d002b750 100644 --- a/examples/kotlin/shared/src/commonTest/kotlin/com/mongodb/realm/realmkmmapp/DataTypesTest.kt +++ b/examples/kotlin/shared/src/commonTest/kotlin/com/mongodb/realm/realmkmmapp/DataTypesTest.kt @@ -17,7 +17,7 @@ import kotlin.test.assertEquals /* -** Leaving these here until the Read, Update, and Delete pages are updated +** Leaving these here until the Read and Update pages are updated * to use the new object model and this page can be deleted * * See the Schema.kt file for the new object model and CreateTest.kt for new tested Create snippets @@ -66,8 +66,8 @@ class DataTypesTest : RealmTest() { // Modify embedded object properties in a write transaction realm.write { // Fetch the objects - val addressToUpdate = findLatest(address)?: error("Cannot find latest version of embedded object") - val contactToUpdate = findLatest(contact)?: error("Cannot find latest version of parent object") + val addressToUpdate = findLatest(address) ?: error("Cannot find latest version of embedded object") + val contactToUpdate = findLatest(contact) ?: error("Cannot find latest version of parent object") // Update a single embedded object property directly addressToUpdate.street = "100 10th St N" @@ -152,72 +152,5 @@ class DataTypesTest : RealmTest() { Realm.deleteRealm(config) } } +} - @Test - fun deleteEmbeddedObject() { - val realmName = getRandom() - - runBlocking { - val config = RealmConfiguration.Builder(setOf(Contact::class, EmbeddedAddress::class)) - .name(realmName) - .build() - val realm = Realm.open(config) - - realm.write { - val contact1 = copyToRealm(Contact()) - contact1.apply { - name = "Marvin Monroe" - address = EmbeddedAddress().apply { - street = "123 Fake St" - city = "Some Town" - state = "MA" - postalCode = "12345" - } - } - val contact2 = copyToRealm(Contact()) - contact2.apply { - name = "Nick Riviera" - address = EmbeddedAddress().apply { - street = "999 Imaginary Blvd" - city = "Some Town" - state = "FL" - postalCode = "55555" - } - } - } - - // :snippet-start: delete-embedded-object - // Delete an embedded object directly - realm.write { - val addressToDelete: EmbeddedAddress = - this.query("street == '123 Fake St'").find().first() - - // Delete the embedded object (nullifies the parent property) - delete(addressToDelete) - } - - // Delete an embedded object through the parent - realm.write { - val propertyToClear: Contact = - this.query("name == 'Nick Riviera'").find().first() - - // Clear the parent property (deletes the embedded object instance) - propertyToClear.address = null - } - - // Delete parent object (deletes all embedded objects) - realm.write { - val contactToDelete: Contact = - this.query("name == 'Nick Riviera'").find().first() - delete(contactToDelete) - } - // :snippet-end: - - assertEquals(0, realm.query().find().size) - assertEquals(0, realm.query("name == 'Nick Riviera'").find().size) - - realm.close() - Realm.deleteRealm(config) - } - } -} \ No newline at end of file diff --git a/examples/kotlin/shared/src/commonTest/kotlin/com/mongodb/realm/realmkmmapp/DeleteTest.kt b/examples/kotlin/shared/src/commonTest/kotlin/com/mongodb/realm/realmkmmapp/DeleteTest.kt index 67c5236212e..2b24827461b 100644 --- a/examples/kotlin/shared/src/commonTest/kotlin/com/mongodb/realm/realmkmmapp/DeleteTest.kt +++ b/examples/kotlin/shared/src/commonTest/kotlin/com/mongodb/realm/realmkmmapp/DeleteTest.kt @@ -6,22 +6,25 @@ import io.realm.kotlin.ext.* import io.realm.kotlin.internal.platform.runBlocking import io.realm.kotlin.query.RealmResults import org.mongodb.kbson.ObjectId -import kotlin.test.Test -import kotlin.test.assertEquals -import kotlin.test.assertFalse -import kotlin.test.assertTrue +import kotlin.test.* // :replace-start: { // "terms": { // "ExampleRealmObject_": "", +// "RealmObjectProperties_": "", +// "ExampleEmbeddedObject_": "", // "ExampleRelationship_": "", -// "ExampleEmbeddedRelationship_": "", -// "RealmDictionary_": "", -// "RealmSet_": "" +// "ExampleRealmList_": "", +// "ExampleRealmDictionary_": "", +// "ExampleRealmSet_": "", +// "RealmEmbeddedObject_": "" // } // } - +/* +** Snippets used on Delete page ** +** Object models defined in Schema.kt ** +*/ class DeleteTest: RealmTest() { @Test @@ -114,7 +117,8 @@ class DeleteTest: RealmTest() { // Open a write transaction realm.write { // Query the Frog type and filter by primary key value - val frogToDelete: ExampleRealmObject_Frog = query("_id == $0", PRIMARY_KEY_VALUE).find().first() + val frogToDelete: ExampleRealmObject_Frog = + query("_id == $0", PRIMARY_KEY_VALUE).find().first() assertEquals(PRIMARY_KEY_VALUE, frogToDelete._id) // :remove: // Pass the query results to delete() delete(frogToDelete) @@ -126,7 +130,8 @@ class DeleteTest: RealmTest() { // Open a write transaction realm.write { // Query by species and limit to 3 results - val bullfrogsToDelete: RealmResults = query("species == 'bullfrog' LIMIT(3)").find() + val bullfrogsToDelete: RealmResults = + query("species == 'bullfrog' LIMIT(3)").find() // Pass the query results to delete() delete(bullfrogsToDelete) assertTrue(query("species == 'bullfrog'").find().size == 3) // :remove: @@ -149,7 +154,13 @@ class DeleteTest: RealmTest() { @Test fun deleteRealmObjectWithRelationship() { runBlocking { - val config = RealmConfiguration.Builder(setOf(ExampleRelationship_Frog::class, ExampleRelationship_Pond::class)) + val config = RealmConfiguration.Builder( + setOf( + ExampleRealmList_Frog::class, + ExampleRealmList_Pond::class, + ExampleEmbeddedObject_EmbeddedForest::class + ) + ) .inMemory() .build() val realm = Realm.open(config) @@ -158,29 +169,32 @@ class DeleteTest: RealmTest() { val PRIMARY_KEY_VALUE = ObjectId() realm.write { deleteAll() - copyToRealm(ExampleRelationship_Frog().apply { + copyToRealm(ExampleRealmList_Frog().apply { _id = PRIMARY_KEY_VALUE name = "Kermit" - age = 12 - favoritePond = ExampleRelationship_Pond().apply { name = "Picnic Pond" } + favoritePonds.addAll( + realmListOf( + ExampleRealmList_Pond().apply { name = "Picnic Pond" }, + ExampleRealmList_Pond().apply { name = "Big Pond" }, + ) + ) }) } // :snippet-start: delete-realm-object-with-related-objects // Open a write transaction realm.write { - // Query for the parent frog object - val frogWithAPond = query("_id == $0", PRIMARY_KEY_VALUE).find().first() - assertEquals(PRIMARY_KEY_VALUE, frogWithAPond._id) // :remove: - // Confirm pond is available through the favoritePond property - assertEquals("Picnic Pond", frogWithAPond.favoritePond?.name) + // Query for the parent frog object with ponds + val parentObject = query("_id == $0", PRIMARY_KEY_VALUE).find().first() + assertEquals(PRIMARY_KEY_VALUE, parentObject._id) // :remove: + assertEquals(2, parentObject.favoritePonds.size) // Delete the frog - delete(frogWithAPond) - assertFalse(frogWithAPond.isValid()) + delete(parentObject) + assertFalse(parentObject.isValid()) // :remove: - // Confirm the pond is still in the realm - val pondsLeftInTheRealm = query().find() - assertEquals("Picnic Pond", pondsLeftInTheRealm.first().name) + // Confirm all ponds are still in the realm + val ponds = query().find() + assertEquals(2, ponds.size) deleteAll() // :remove: } // :snippet-end: @@ -191,7 +205,13 @@ class DeleteTest: RealmTest() { @Test fun deleteRealmList() { runBlocking { - val config = RealmConfiguration.Builder(setOf(ExampleRelationship_Forest::class, ExampleRelationship_Frog::class, ExampleRelationship_Pond::class)) + val config = RealmConfiguration.Builder( + setOf( + ExampleRelationship_Forest::class, + ExampleRelationship_Frog::class, + ExampleRelationship_Pond::class + ) + ) .inMemory() .build() val realm = Realm.open(config) @@ -234,13 +254,8 @@ class DeleteTest: RealmTest() { // :snippet-end: realm.write { val forest = query("name == $0", "Hundred Acre Wood").find().first() - forest.nearbyPonds.addAll(realmListOf( - ExampleRelationship_Pond().apply { name = "Frog Corner" }, - ExampleRelationship_Pond().apply { name = "The Pond" }, - ExampleRelationship_Pond().apply { name = "Enchanted Pool" }, - ExampleRelationship_Pond().apply { name = "Bubbling Spring" }, - ExampleRelationship_Pond().apply { name = "Big Spring" } - )) + val ponds = query().find() + forest.nearbyPonds.addAll(ponds) } // :snippet-start: list-clear // Open a write transaction @@ -267,8 +282,9 @@ class DeleteTest: RealmTest() { val realm = Realm.open(config) Log.v("Successfully opened realm: ${realm.configuration.path}") - realm.write { copyToRealm( - RealmSet_Frog().apply { + realm.write { + deleteAll() + copyToRealm(RealmSet_Frog().apply { name = "Kermit" favoriteSnacks.add(RealmSet_Snack().apply { name = "Flies" }) favoriteSnacks.add(RealmSet_Snack().apply { name = "Crickets" }) @@ -276,16 +292,18 @@ class DeleteTest: RealmTest() { }) } // :snippet-start: remove-item-from-set + // Open a write transaction realm.write { + // Query for the parent frog object val myFrog = query("name == $0", "Kermit").find().first() - val snackSet = findLatest(myFrog)!!.favoriteSnacks + val snackSet = myFrog.favoriteSnacks + assertEquals(3, snackSet.size) - // Remove the Flies snack from the set - val fliesSnack = snackSet.first { it.name == "Flies" } - snackSet.remove(fliesSnack) - assertFalse(snackSet.contains(fliesSnack)) // :remove: + // Remove one snack from the set + snackSet.remove(snackSet.first { it.name == "Flies" }) + assertEquals(2, snackSet.size) - // Remove all snacks from the set + // Remove the remaining two snacks from the set val allSnacks = findLatest(myFrog)!!.favoriteSnacks snackSet.removeAll(allSnacks) // :remove-start: @@ -293,32 +311,22 @@ class DeleteTest: RealmTest() { // assertTrue(set.isEmpty()) snackSet.removeAll(allSnacks) // have to call twice to actually remove all items until bug is fixed // :remove-end: - val snacks = query().find() - Log.v("There are ${snacks.size} snacks left in the realm") + assertEquals(0, snackSet.size) } // :snippet-end: + // :snippet-start: clear-set realm.write { val myFrog = realm.query("name == $0", "Kermit").find().first() val snackSet = findLatest(myFrog)!!.favoriteSnacks - val snack1 = this.copyToRealm(RealmSet_Snack().apply { - name = "snack1" - }) - val snack2 = this.copyToRealm(RealmSet_Snack().apply { - name = "snack2" - }) - val snack3 = this.copyToRealm(RealmSet_Snack().apply { - name = "snack3" - }) - - snackSet.addAll(setOf(snack1, snack2, snack3)) + snackSet.addAll(query().find()) // :remove: assertEquals(3, snackSet.size) - // :snippet-start: clear-set // Clear all snacks from the set snackSet.clear() - // :snippet-end: - assertTrue(snackSet.isEmpty()) + assertEquals(0, snackSet.size) + deleteAll() // :remove: } + // :snippet-end: realm.close() } } @@ -326,35 +334,23 @@ class DeleteTest: RealmTest() { @Test fun deleteRealmDictionaryType() { runBlocking { - val config = RealmConfiguration.Builder( - schema = setOf(RealmDictionary_Frog::class) // Pass the defined class as the object schema - ) - .directory("/tmp/") // default location for jvm is... in the project root + val config = RealmConfiguration.Builder(setOf(RealmDictionary_Frog::class)) + .inMemory() .build() val realm = Realm.open(config) Log.v("Successfully opened realm: ${realm.configuration.name}") - // Delete frogs to make this test successful on consecutive reruns realm.write { - // fetch all frogs from the realm - val frogs: RealmResults = this.query().find() - // call delete on the results of a query to delete those objects permanently - delete(frogs) - assertEquals(0, frogs.size) - } - - // Create an object with a dictionary property to set up the test - realm.write { - this.copyToRealm(RealmDictionary_Frog().apply { + deleteAll() + copyToRealm(RealmDictionary_Frog().apply { name = "Kermit" - favoritePondsByForest = realmDictionaryOf("Hundred Acre Wood" to "Picnic Pond", "Lothlorien" to "Linya") + favoritePondsByForest = + realmDictionaryOf("Hundred Acre Wood" to "Picnic Pond", "Lothlorien" to "Linya") }) } // :snippet-start: delete-realm-dictionary // Find frogs who have forests with favorite ponds - val frogs = realm.query().find() - val frogsWithFavoritePonds = frogs.query("favoritePondsByForest.@count > 1").find() - val thisFrog = frogsWithFavoritePonds.first() + val thisFrog = realm.query("favoritePondsByForest.@count > 1").find().first() // :remove-start: assertEquals(2, thisFrog.favoritePondsByForest.size) assertTrue(thisFrog.favoritePondsByForest.containsKey("Hundred Acre Wood")) @@ -369,15 +365,149 @@ class DeleteTest: RealmTest() { } } } - // Remove a key and its value realm.write { + // Remove a key and its value findLatest(thisFrog)?.favoritePondsByForest?.remove("Lothlorien") + // :remove-start: + val thisFrogUpdated = query().find().first() + assertFalse(thisFrogUpdated.favoritePondsByForest.containsKey("Lothlorien")) + assertTrue(thisFrogUpdated.favoritePondsByForest.containsKey("Hundred Acre Wood")) + assertFalse(thisFrogUpdated.favoritePondsByForest.containsValue("Picnic Pond")) + // :remove-end: + // Remove all keys and values + findLatest(thisFrog)?.favoritePondsByForest?.clear() + assertTrue(thisFrogUpdated.favoritePondsByForest.isEmpty()) + deleteAll() // :remove: } // :snippet-end: - val thisFrogUpdated = realm.query().find().first() - assertFalse(thisFrogUpdated.favoritePondsByForest.containsKey("Lothlorien")) - assertTrue(thisFrogUpdated.favoritePondsByForest.containsKey("Hundred Acre Wood")) - assertFalse(thisFrogUpdated.favoritePondsByForest.containsValue("Picnic Pond")) + realm.close() + } + } + + @Test + fun deleteEmbeddedObject() { + runBlocking { + val config = RealmConfiguration.Builder( + setOf( + ExampleRelationship_Business::class, + ExampleRelationship_Contact::class, + ExampleRelationship_EmbeddedCountry::class, + ExampleRelationship_EmbeddedAddress::class + ) + ) + .inMemory() + .build() + val realm = Realm.open(config) + Log.v("Successfully opened realm: ${realm.configuration.path}") + realm.write { + deleteAll() + copyToRealm(ExampleRelationship_Contact().apply { + name = "Kermit" + address = ExampleRelationship_EmbeddedAddress().apply { + propertyOwner = ExampleRelationship_Contact().apply { name = "Mr. Frog" } + street = "123 Pond St" + country = ExampleRelationship_EmbeddedCountry().apply { name = "United States" } + } + }) + val localOffice = ExampleRelationship_EmbeddedAddress().apply { + propertyOwner = ExampleRelationship_Contact().apply { name = "Michigan J. Frog" } + street = "456 Lily Pad Ln" + country = ExampleRelationship_EmbeddedCountry().apply { name = "United States" } + } + val remoteOffice = ExampleRelationship_EmbeddedAddress().apply { + propertyOwner = ExampleRelationship_Contact().apply { name = "Mr. Toad" } + street = "789 Leaping Frog Ave" + country = ExampleRelationship_EmbeddedCountry().apply { name = "Ireland" } + } + val business = ExampleRelationship_Business().apply { + name = "Big Frog Corp." + addresses = realmListOf(localOffice, remoteOffice) + } + copyToRealm(business) + } + // :snippet-start: delete-embedded-object + realm.write { + // Delete an embedded object directly + val addressToDelete = query("street == $0", "123 Pond St").find().first() + // Delete the embedded object (nullifies the parent property) + delete(addressToDelete) + assertFalse(addressToDelete.isValid()) // :remove: + + // Delete an embedded object through the parent + val propertyToClear = query("name == $0", "Kermit").find().first() + // Clear the parent property (deletes the embedded object instance) + propertyToClear.address = null + assertNull(propertyToClear.address) // :remove: + + // Delete the parent object (deletes all embedded objects) + val businessToDelete = query("name == $0", "Big Frog Corp.").find().first() + delete(businessToDelete) + assertFalse(businessToDelete.isValid()) // :remove: + } + // :snippet-end: + realm.write { + deleteAll() + } + realm.close() + } + } + + @Test + fun chainDeleteRealmList() { + runBlocking { + val config = RealmConfiguration.Builder( + setOf( + ExampleRealmList_Frog::class, + ExampleRealmList_Pond::class, + ExampleEmbeddedObject_EmbeddedForest::class + ) + ) + .inMemory() + .build() + val realm = Realm.open(config) + Log.v("Successfully opened realm: ${realm.configuration.path}") + + realm.write { + deleteAll() + copyToRealm(ExampleRealmList_Frog().apply { + name = "Kermit" + favoritePonds.addAll( + realmListOf( + ExampleRealmList_Pond().apply { name = "Picnic Pond" }, + ExampleRealmList_Pond().apply { name = "Big Pond" }, + ExampleRealmList_Pond().apply { name = "Small Pond" }, + ExampleRealmList_Pond().apply { name = "Huge Pond" }, + ) + ) + }) + } + // :snippet-start: chain-delete-realm-list + realm.write { + // Query for the parent frog object + val frog = query("name == $0", "Kermit").find().first() + val ponds = frog.favoritePonds + assertEquals(4, ponds.size) + // Iterate over the list and delete each pond + if (ponds.isNotEmpty()) { + ponds.forEach { pond -> + delete(pond) + } + } + // Delete the parent frog object + val frogToDelete = findLatest(frog) + if (frogToDelete != null) { + delete(frogToDelete) + } + } + // :snippet-end: + realm.write { + val frogs = query().find() + Log.v("Frogs: ${frogs.size}") + delete(frogs) + val ponds = query().find() + Log.v("Ponds: ${ponds.size}") + delete(ponds) + } realm.close() } } diff --git a/source/examples/generated/kotlin/DataTypesTest.snippet.update-embedded-object.kt b/source/examples/generated/kotlin/DataTypesTest.snippet.update-embedded-object.kt index 93ea3db235a..965e8bdb586 100644 --- a/source/examples/generated/kotlin/DataTypesTest.snippet.update-embedded-object.kt +++ b/source/examples/generated/kotlin/DataTypesTest.snippet.update-embedded-object.kt @@ -1,8 +1,8 @@ // Modify embedded object properties in a write transaction realm.write { // Fetch the objects - val addressToUpdate = findLatest(address)?: error("Cannot find latest version of embedded object") - val contactToUpdate = findLatest(contact)?: error("Cannot find latest version of parent object") + val addressToUpdate = findLatest(address) ?: error("Cannot find latest version of embedded object") + val contactToUpdate = findLatest(contact) ?: error("Cannot find latest version of parent object") // Update a single embedded object property directly addressToUpdate.street = "100 10th St N" diff --git a/source/examples/generated/kotlin/DeleteTest.snippet.chain-delete-realm-list.kt b/source/examples/generated/kotlin/DeleteTest.snippet.chain-delete-realm-list.kt new file mode 100644 index 00000000000..e4da54d7784 --- /dev/null +++ b/source/examples/generated/kotlin/DeleteTest.snippet.chain-delete-realm-list.kt @@ -0,0 +1,17 @@ +realm.write { + // Query for the parent frog object + val frog = query("name == $0", "Kermit").find().first() + val ponds = frog.favoritePonds + assertEquals(4, ponds.size) + // Iterate over the list and delete each pond + if (ponds.isNotEmpty()) { + ponds.forEach { pond -> + delete(pond) + } + } + // Delete the parent frog object + val frogToDelete = findLatest(frog) + if (frogToDelete != null) { + delete(frogToDelete) + } +} diff --git a/source/examples/generated/kotlin/DeleteTest.snippet.clear-set.kt b/source/examples/generated/kotlin/DeleteTest.snippet.clear-set.kt index c6c5f7eb731..cf0a55f62ae 100644 --- a/source/examples/generated/kotlin/DeleteTest.snippet.clear-set.kt +++ b/source/examples/generated/kotlin/DeleteTest.snippet.clear-set.kt @@ -1,2 +1,9 @@ -// Clear all snacks from the set -snackSet.clear() +realm.write { + val myFrog = realm.query("name == $0", "Kermit").find().first() + val snackSet = findLatest(myFrog)!!.favoriteSnacks + assertEquals(3, snackSet.size) + + // Clear all snacks from the set + snackSet.clear() + assertEquals(0, snackSet.size) +} diff --git a/source/examples/generated/kotlin/DeleteTest.snippet.delete-all-realm-objects.kt b/source/examples/generated/kotlin/DeleteTest.snippet.delete-all-realm-objects.kt new file mode 100644 index 00000000000..add288b2ac1 --- /dev/null +++ b/source/examples/generated/kotlin/DeleteTest.snippet.delete-all-realm-objects.kt @@ -0,0 +1,7 @@ +// Open a write transaction +realm.write { + // Query Frog type with no filter to return all frog objects + val frogsLeftInTheRealm = query().find() + delete(frogsLeftInTheRealm) + assertTrue(frogsLeftInTheRealm.size == 0) +} diff --git a/source/examples/generated/kotlin/DeleteTest.snippet.delete-embedded-object.kt b/source/examples/generated/kotlin/DeleteTest.snippet.delete-embedded-object.kt new file mode 100644 index 00000000000..44da013c4f3 --- /dev/null +++ b/source/examples/generated/kotlin/DeleteTest.snippet.delete-embedded-object.kt @@ -0,0 +1,15 @@ +realm.write { + // Delete an embedded object directly + val addressToDelete = query("street == $0", "123 Pond St").find().first() + // Delete the embedded object (nullifies the parent property) + delete(addressToDelete) + + // Delete an embedded object through the parent + val propertyToClear = query("name == $0", "Kermit").find().first() + // Clear the parent property (deletes the embedded object instance) + propertyToClear.address = null + + // Delete the parent object (deletes all embedded objects) + val businessToDelete = query("name == $0", "Big Frog Corp.").find().first() + delete(businessToDelete) +} diff --git a/source/examples/generated/kotlin/DeleteTest.snippet.delete-multiple-realm-objects.kt b/source/examples/generated/kotlin/DeleteTest.snippet.delete-multiple-realm-objects.kt new file mode 100644 index 00000000000..e13b82eaa4c --- /dev/null +++ b/source/examples/generated/kotlin/DeleteTest.snippet.delete-multiple-realm-objects.kt @@ -0,0 +1,8 @@ +// Open a write transaction +realm.write { + // Query by species and limit to 3 results + val bullfrogsToDelete: RealmResults = + query("species == 'bullfrog' LIMIT(3)").find() + // Pass the query results to delete() + delete(bullfrogsToDelete) +} diff --git a/source/examples/generated/kotlin/DeleteTest.snippet.delete-one-realm-object.kt b/source/examples/generated/kotlin/DeleteTest.snippet.delete-one-realm-object.kt new file mode 100644 index 00000000000..a5286bcbb37 --- /dev/null +++ b/source/examples/generated/kotlin/DeleteTest.snippet.delete-one-realm-object.kt @@ -0,0 +1,9 @@ +// Open a write transaction +realm.write { + // Query the Frog type and filter by primary key value + val frogToDelete: Frog = + query("_id == $0", PRIMARY_KEY_VALUE).find().first() + // Pass the query results to delete() + delete(frogToDelete) + assertFalse(frogToDelete.isValid()) +} diff --git a/source/examples/generated/kotlin/DeleteTest.snippet.delete-realm-dictionary.kt b/source/examples/generated/kotlin/DeleteTest.snippet.delete-realm-dictionary.kt index ff9b8cdb133..026191d410c 100644 --- a/source/examples/generated/kotlin/DeleteTest.snippet.delete-realm-dictionary.kt +++ b/source/examples/generated/kotlin/DeleteTest.snippet.delete-realm-dictionary.kt @@ -1,7 +1,5 @@ // Find frogs who have forests with favorite ponds -val frogs = realm.query().find() -val frogsWithFavoritePonds = frogs.query("favoritePondsByForest.@count > 1").find() -val thisFrog = frogsWithFavoritePonds.first() +val thisFrog = realm.query("favoritePondsByForest.@count > 1").find().first() // Set an optional value for a key to null if the key exists if (thisFrog.favoritePondsByForest.containsKey("Hundred Acre Wood")) { realm.write { @@ -11,7 +9,10 @@ if (thisFrog.favoritePondsByForest.containsKey("Hundred Acre Wood")) { } } } -// Remove a key and its value realm.write { + // Remove a key and its value findLatest(thisFrog)?.favoritePondsByForest?.remove("Lothlorien") + // Remove all keys and values + findLatest(thisFrog)?.favoritePondsByForest?.clear() + assertTrue(thisFrogUpdated.favoritePondsByForest.isEmpty()) } diff --git a/source/examples/generated/kotlin/DeleteTest.snippet.delete-realm-object-with-related-objects.kt b/source/examples/generated/kotlin/DeleteTest.snippet.delete-realm-object-with-related-objects.kt new file mode 100644 index 00000000000..88321a50303 --- /dev/null +++ b/source/examples/generated/kotlin/DeleteTest.snippet.delete-realm-object-with-related-objects.kt @@ -0,0 +1,13 @@ +// Open a write transaction +realm.write { + // Query for the parent frog object with ponds + val parentObject = query("_id == $0", PRIMARY_KEY_VALUE).find().first() + assertEquals(2, parentObject.favoritePonds.size) + + // Delete the frog + delete(parentObject) + + // Confirm all ponds are still in the realm + val ponds = query().find() + assertEquals(2, ponds.size) +} diff --git a/source/examples/generated/kotlin/DeleteTest.snippet.fetch-latest-to-delete-object.kt b/source/examples/generated/kotlin/DeleteTest.snippet.fetch-latest-to-delete-object.kt new file mode 100644 index 00000000000..c917aab6604 --- /dev/null +++ b/source/examples/generated/kotlin/DeleteTest.snippet.fetch-latest-to-delete-object.kt @@ -0,0 +1,11 @@ +// Frog object is outside of the write transaction, so it is frozen +val frozenFrog = realm.query("name == $0", "Kermit").find().first() +assertTrue(frozenFrog.isFrozen()) + +// Open a write transaction +realm.writeBlocking { + // Get the live frog object with findLatest() to delete it + findLatest(frozenFrog)?.let { liveFrog -> + delete(liveFrog) + } +} diff --git a/source/examples/generated/kotlin/DeleteTest.snippet.list-clear.kt b/source/examples/generated/kotlin/DeleteTest.snippet.list-clear.kt new file mode 100644 index 00000000000..041c2d92d3c --- /dev/null +++ b/source/examples/generated/kotlin/DeleteTest.snippet.list-clear.kt @@ -0,0 +1,10 @@ +// Open a write transaction +realm.write { + val forest = query("name == $0", "Hundred Acre Wood").find().first() + val forestPonds = forest.nearbyPonds + assertEquals(5, forestPonds.size) + + // Clear all ponds from the list + forestPonds.clear() + assertEquals(0, forestPonds.size) +} diff --git a/source/examples/generated/kotlin/DeleteTest.snippet.remove-item-from-set.kt b/source/examples/generated/kotlin/DeleteTest.snippet.remove-item-from-set.kt index a3689fcfa30..da35584c5c8 100644 --- a/source/examples/generated/kotlin/DeleteTest.snippet.remove-item-from-set.kt +++ b/source/examples/generated/kotlin/DeleteTest.snippet.remove-item-from-set.kt @@ -1,12 +1,16 @@ +// Open a write transaction realm.write { - val myFrog = realm.query("name == $0", "Kermit").find().first() - val snackSet = findLatest(myFrog)!!.favoriteSnacks + // Query for the parent frog object + val myFrog = query("name == $0", "Kermit").find().first() + val snackSet = myFrog.favoriteSnacks + assertEquals(3, snackSet.size) - // Remove the Flies snack from the set - val fliesSnack = snackSet.first { it.name == "Flies" } - snackSet.remove(fliesSnack) + // Remove one snack from the set + snackSet.remove(snackSet.first { it.name == "Flies" }) + assertEquals(2, snackSet.size) - // Remove all snacks from the set + // Remove the remaining two snacks from the set val allSnacks = findLatest(myFrog)!!.favoriteSnacks snackSet.removeAll(allSnacks) + assertEquals(0, snackSet.size) } diff --git a/source/examples/generated/kotlin/DeleteTest.snippet.remove-items-from-list.kt b/source/examples/generated/kotlin/DeleteTest.snippet.remove-items-from-list.kt new file mode 100644 index 00000000000..c7ed7cd2a51 --- /dev/null +++ b/source/examples/generated/kotlin/DeleteTest.snippet.remove-items-from-list.kt @@ -0,0 +1,20 @@ +// Open a write transaction +realm.write { + // Query for the parent forest object + val forest = query("name == $0", "Hundred Acre Wood").find().first() + val forestPonds = forest.nearbyPonds + assertEquals(5, forestPonds.size) + + // Remove the first pond in the list + val removeFirstPond = forestPonds.first() + forestPonds.remove(removeFirstPond) + assertEquals(4, forestPonds.size) + + // Remove the pond at index 2 in the list + forestPonds.removeAt(2) + assertEquals(3, forestPonds.size) + + // Remove the remaining three ponds in the list + forestPonds.removeAll(forestPonds) + assertEquals(0, forestPonds.size) +} diff --git a/source/includes/kotlin-write-to-synced-realm.rst b/source/includes/kotlin-write-to-synced-realm.rst new file mode 100644 index 00000000000..9c11b7e2456 --- /dev/null +++ b/source/includes/kotlin-write-to-synced-realm.rst @@ -0,0 +1,6 @@ +.. note:: Write to a Synced Realm + + The syntax to write to a realm is the same for a local or + a synced realm. However, there are additional considerations that determine + whether the write operation in a synced realm is successful. For more + information, refer to :ref:``. \ No newline at end of file diff --git a/source/includes/kotlin-write-transactions.rst b/source/includes/kotlin-write-transactions.rst new file mode 100644 index 00000000000..b1c107d8625 --- /dev/null +++ b/source/includes/kotlin-write-transactions.rst @@ -0,0 +1,40 @@ +Realm handles writes in terms of transactions. All writes must happen +within a transaction. A **transaction** is a list of read and write operations +that Realm treats as a single indivisible operation: either *all* of the +operations succeed or *none* of the operations in the transaction +take effect. + +Realm represents each transaction as a callback function +that contains zero or more read and write operations. To run +a transaction, you define a transaction callback and pass it to +the realm's +`write() <{+kotlin-local-prefix+}io.realm.kotlin/-realm/write.html>`__ +or +`writeBlocking() <{+kotlin-local-prefix+}io.realm.kotlin/-realm/write-blocking.html>`__ +method. Within this callback, you can access a +`MutableRealm <{+kotlin-local-prefix+}io.realm.kotlin/-mutable-realm/index.html>`__ +instance and then create, read, update, and delete objects within the realm. +The **mutable realm** represents the writeable state of a Realm file. +Mutable realms are provided and managed automatically through the +``realm.write`` or ``realm.writeBlocking`` methods. + +A realm allows only one open write transaction at a time. Realm +blocks other writes on other threads until the open +transaction on the mutable realm is complete. Consequently, there is no race +condition when reading values from the realm within a +transaction. + +When you are done with your transaction, Realm either +commits it or cancels it: + +- When Realm commits a transaction, Realm writes + all changes to disk. For synced realms, the SDK queues the change + for synchronization with the backend. +- When Realm cancels a write transaction or an operation in + the transaction causes an error, all changes are discarded. + +.. note:: Frozen Objects + + Objects returned from a write closure become frozen objects when the + write transaction completes. For more information, refer to + :ref:``. \ No newline at end of file diff --git a/source/sdk/kotlin/realm-database/crud/delete.txt b/source/sdk/kotlin/realm-database/crud/delete.txt index 08b764f9d06..752364f560b 100644 --- a/source/sdk/kotlin/realm-database/crud/delete.txt +++ b/source/sdk/kotlin/realm-database/crud/delete.txt @@ -10,84 +10,65 @@ Delete Realm Objects - Kotlin SDK :depth: 1 :class: singlecol -This page describes how to delete managed objects from a local or synced realm +This page describes how to delete objects from a local or synced realm using the Kotlin SDK. You can choose to delete a single object, multiple objects, or all objects from the realm. After you delete an object, you can no longer access or modify it. If you try to use a deleted object, Realm throws an error. -.. note:: Deleting Objects Does NOT Delete the Realm File +Deleting objects from a realm *does not* delete the realm file +or affect the realm schema. It only deletes the object instance from the +realm. If you want to delete the realm file itself, +refer to :ref:``. - Deleting objects from a realm *does not* delete the realm file - or affect the realm schema. It only deletes the object instance from the - realm. If you want to delete the realm file itself, - refer to :ref:``. +.. literalinclude:: /includes/kotlin-write-to-synced-realm.rst -.. _kotlin-delete-operations: +Write Transactions +------------------ -Delete Operations ------------------ +.. literalinclude:: /includes/kotlin-write-transactions.rst -Like :ref:`update ` operations, which also modify -the state of the realm, delete operations require the following: +You can only delete live objects, which are only accessible inside of a +write transaction. You can convert a frozen object to a +live object in a transaction with `mutableRealm.findLatest() +<{+kotlin-local-prefix+}io.realm.kotlin/-mutable-realm/find-latest.html>`__. -- You can only perform a delete operation on a ``mutableRealm`` accessed - within a :ref:`write transaction `. -- You can only delete live objects, which are only accessible inside of a - write transaction. You can convert a frozen object to a - live object in a transaction with `mutableRealm.findLatest() - <{+kotlin-local-prefix+}io.realm.kotlin/-mutable-realm/find-latest.html>`__. - For more information, refer to :ref:``. +.. example:: Convert Frozen Object Before Deleting - .. example:: Convert Frozen Object Before Deleting - - .. literalinclude:: /examples/generated/kotlin/DeleteTest.snippet.delete-an-object.kt - :language: kotlin - -Realm supports the deletion of one or more ``RealmObject`` or -``EmbeddedRealmObject`` instances, a ``RealmList`` or ``RealmSet`` collection, -``RealmQuery``, or ``RealmResults`` instances. - -Generally, you delete objects from a realm by querying for the one or more -objects that you want to delete, and then passing the results to ``delete()``. -For more information on querying with the Kotlin SDK, refer to -:ref:``. - - - - - - -You cannot directly add or remove items from a backlinks collection. The collection automatically updates itself when relationships are changed. +.. literalinclude:: /examples/generated/kotlin/DeleteTest.snippet.fetch-latest-to-delete-object.kt + :language: kotlin Related Objects and References ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Realm supports :ref:`relationships ` between an -objects. In general, if you delete an -object with a property that references another object, -Realm only deletes the object reference (or pointer). Realm *does not* -delete the instance of the related object for you unless the -related object is :ref:`embedded `. Refer to the -:ref:`` section for -more information. - -If you you want to delete any related objects when you delete a parent object, -you can manually perform what we call a **chaining delete**. If you do not -delete the related objects yourself, they remain orphaned in your realm. -Whether or not this is a problem depends on your application's needs. - -We recommend deleting dependent objects by iterating through the +When you delete an object that has a :ref:`relationship ` +property with another object, Realm *does not* automatically delete the +instance of the related object. Instead, Realm only +deletes the reference to the other object. The referenced object remains in the +realm, but it can no longer be queried through the parent property. +The only exception is if the related object is +:ref:`embedded `. For more +information on cascading deletes with embedded objects, refer to the +:ref:`` section on this page. + +If you want to delete any related objects when you delete a parent object, +we recommend performing a **chaining delete**. A chaining delete consists +of manually deleting dependent objects by iterating through the dependencies and deleting them before deleting the parent object. -Refer to the :ref:`` section for more information. +For more information on chaining deletes, refer to the +:ref:`` section on this page. + +If you do not delete the related objects yourself, they remain +orphaned in your realm. Whether or not this is a problem depends on +your application's needs. .. _kotlin-delete-an-object: Delete Realm Objects -------------------- -To delete objects from a realm: +To delete specific objects from a realm: 1. Open a write transaction with `realm.write() <{+kotlin-local-prefix+}io.realm.kotlin/-realm/write.html>`__ or @@ -95,17 +76,17 @@ To delete objects from a realm: <{+kotlin-local-prefix+}io.realm.kotlin/-realm/write-blocking.html>`__. #. Get the live objects by querying the transaction's mutable realm - for the one or more objects that you want to delete using + for the objects that you want to delete using `query() <{+kotlin-local-prefix+}io.realm.kotlin.query/-realm-query/query.html>`__: #. Specify the object type as a type parameter passed to ``query()``. #. (Optional) Filter the set of returned objects by specifying a query. If you don't include a query filter, you return all objects of the - specified type. + specified type. For more information on querying with the Kotlin SDK, refer to :ref:``. .. important:: Objects Must Be Live - You can only delete live objects. If your query occurred outside of the + You can only delete live objects. If your query occurs outside of the write transaction, you must convert the frozen objects to live objects in the transaction with ``mutableRealm.findLatest()``. @@ -116,7 +97,13 @@ To delete objects from a realm: `mutableRealm.delete() <{+kotlin-local-prefix+}io.realm.kotlin/-mutable-realm/delete.html>`__. #. The specified objects are deleted from the realm and can no longer be accessed - or modified. + or modified. If you try to use a deleted object, Realm throws an error. + + If any deleted objects had a relationship with another object, Realm + only deletes the reference to the other object. The referenced object + remains in the realm, but it can no longer be queried through the deleted + parent property. Refer to the :ref:`` section + for more information. .. tip:: @@ -142,18 +129,7 @@ In the following example, we query for a ``Frog`` object named "Kermit", and then pass the returned object to ``mutableRealm.delete()`` to delete it from the realm: -.. literalinclude:: /examples/generated/kotlin/DeleteTest.snippet.delete-an-object.kt - :language: kotlin - -If the object has a relationship property with another object, Realm only -deletes the reference to the other object. The referenced object remains in the -realm, but it can no longer be queried through the parent property. - -In the following example, we query for a ``Frog`` object contains -a ``favoritePond`` property that contains a ``Pond`` object. -When we delete the ``Frog`` object, the ``Pond`` object remains in the realm: - -.. literalinclude:: /examples/generated/kotlin/DeleteTest.snippet.delete-realm-object-with-related-objects.kt +.. literalinclude:: /examples/generated/kotlin/DeleteTest.snippet.delete-one-realm-object.kt :language: kotlin .. _kotlin-delete-multiple-objects: @@ -162,13 +138,14 @@ Delete Multiple Objects ~~~~~~~~~~~~~~~~~~~~~~~ To delete multiple objects at the same time, pass the object type to -``query()`` and specify a query that returns the objects that you want to delete. +``query()`` and specify a query that returns all objects that you want +to delete. In the following example, we query for the first 3 ``Frog`` objects whose ``species`` is "bullfrog", and then pass the results to ``mutableRealm.delete()`` to delete them from the realm: -.. literalinclude:: /examples/generated/kotlin/DeleteTest.snippet.delete-an-object.kt +.. literalinclude:: /examples/generated/kotlin/DeleteTest.snippet.delete-multiple-realm-objects.kt :language: kotlin .. _kotlin-delete-all-objects-of-a-type: @@ -176,14 +153,14 @@ In the following example, we query for the first 3 ``Frog`` objects whose Delete All Objects of a Type ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -To delete all objects of a type from a realm at the same time, pass the +To delete all objects of a specific type from a realm at the same time, pass the object type to ``query()`` and leave the query filter empty to return all objects of that type. In the following example, we query for all ``Frog`` objects, and then pass the results to ``mutableRealm.delete()`` to delete them all from the realm: -.. literalinclude:: /examples/generated/kotlin/DeleteTest.snippet.delete-an-object.kt +.. literalinclude:: /examples/generated/kotlin/DeleteTest.snippet.delete-all-realm-objects.kt :language: kotlin .. _kotlin-delete-all-objects-in-the-realm: @@ -208,42 +185,39 @@ To delete *all* objects from the realm at the same time, call Remove Elements from Collections -------------------------------- -Realm collection instances that contain Realm objects only store -references to those objects. Realm only removes the references to the -objects. It does not delete the objects themselves. - -When you delete an object that contains a collection property such as a -``RealmList`` or ``RealmSet``, Realm only deletes the object references. - -To delete the collection elements themselves, you must delete them -manually. +Realm collection instances that contain objects only store +references to those objects. You can remove one or more referenced +objects from a collection without deleting the objects themselves. +The objects that you remove from a collection remain in the realm +until you manually delete them. +For more information on chaining deletes with related objects, refer to the +:ref:`` section on this page. Remove Items from a RealmList ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +You can remove one or more items from a ``RealmList`` at a time: - -You can delete one or more items from a ``RealmSet`` at a time: - -- To remove one item from a ``RealmSet``, pass the element - you want to delete to +- To remove one item from the list, pass the element to `list.remove() <{+kotlin-local-prefix+}io.realm.kotlin.types/-realm-list/index.html#731697687%2FFunctions%2F878332154>`__. -- To remove multiple items from a ``RealmSet``, pass the - elements you want to delete to +- To remove one item at a specified index in the list, pass the index to + `list.removeAt() <{+kotlin-local-prefix+}io.realm.kotlin.types/-realm-list/index.html#-209439875%2FFunctions%2F878332154>`__. +- To remove multiple items from the list, pass the elements to `list.removeAll() <{+kotlin-local-prefix+}io.realm.kotlin.types/-realm-list/index.html#1522148962%2FFunctions%2F878332154>`__. - `list.removeAt() <{+kotlin-local-prefix+}io.realm.kotlin.types/-realm-list/index.html#-1899070414%2FFunctions%2F878332154>`__. +In the following example, we have a ``Forest`` object with a list of +``Pond`` objects. We remove the list elements in a series of operations until the +list is empty: .. literalinclude:: /examples/generated/kotlin/DeleteTest.snippet.remove-items-from-list.kt :language: kotlin +You can also remove *all* list elements at once by calling +`list.clear() <{+kotlin-local-prefix+}io.realm.kotlin.types/-realm-list/index.html#-35526398%2FFunctions%2F878332154>`__. In the following example, we have a ``Forest`` object with a list of -``Pond`` objects: - -You can also remove all list elements at once by calling -`list.clear() <{+kotlin-local-prefix+}io.realm.kotlin.types/-realm-list/index.html#-35526398%2FFunctions%2F878332154>`__: +``Pond`` objects. We remove all list elements with the ``list.clear()`` method: .. literalinclude:: /examples/generated/kotlin/DeleteTest.snippet.list-clear.kt :language: kotlin @@ -258,42 +232,83 @@ the object. You can delete one or more items from a ``RealmSet`` at a time: -- To remove one item from a ``RealmSet``, pass the element +- To remove one item from the set, pass the element you want to delete to `set.remove() <{+kotlin-local-prefix+}io.realm.kotlin.types/-realm-set/index.html#-1503494415%2FFunctions%2F-1651551339>`__. -- To remove multiple items from a ``RealmSet``, pass the +- To remove multiple items from the set, pass the elements you want to delete to `set.removeAll() <{+kotlin-local-prefix+}io.realm.kotlin.types/-realm-set/index.html#430447804%2FFunctions%2F-1651551339>`__. +In the following example, we have a ``Frog`` object with a set of +``Snack`` objects. We remove the set elements in a series of operations until the +set is empty: + .. literalinclude:: /examples/generated/kotlin/DeleteTest.snippet.remove-item-from-set.kt :language: kotlin -Alternatively, you can use -`set.clear() <{+kotlin-local-prefix+}io.realm.kotlin.types/-realm-set/index.html#-767459876%2FFunctions%2F878332154>`__ -to clear all items from a ``RealmSet``: +You can also remove *all* set elements at once by calling +`set.clear() <{+kotlin-local-prefix+}io.realm.kotlin.types/-realm-set/index.html#-767459876%2FFunctions%2F878332154>`__. + +In the following example, we have a ``Frog`` object with a set of +``Snack`` objects. We remove all set elements with the ``set.clear()`` method: .. literalinclude:: /examples/generated/kotlin/DeleteTest.snippet.clear-set.kt :language: kotlin .. _kotlin-delete-dictionary-keys-values: -Delete Dictionary Keys/Values +Remove Dictionary Keys/Values ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -You can delete -`RealmDictionary <{+kotlin-local-prefix+}io.realm.kotlin.types/-realm-dictionary/index.html>`__ -entries in a few ways: +You can remove ``RealmDictionary`` entries in a few ways: -- Use ``remove()`` to remove the key and the value -- If the dictionary's value is nullable, you can set the value of the key to ``null`` to keep the key. -- Use ``clear()`` to remove all keys and values +- If the dictionary's value is nullable, set the value of the key to ``null`` to keep the key +- Use `remove() <{+kotlin-local-prefix+}io.realm.kotlin.types/-realm-dictionary/index.html#-2016920067%2FFunctions%2F878332154>`__ + to remove the key and the value +- Use `clear() <{+kotlin-local-prefix+}io.realm.kotlin.types/-realm-dictionary/index.html#1264776610%2FFunctions%2F878332154>`__ + to remove all keys and values + +In the following example, we have a ``Frog`` object with a dictionary of +``String`` values. We remove the dictionary elements in a series of operations +until the dictionary is empty: .. literalinclude:: /examples/generated/kotlin/DeleteTest.snippet.delete-realm-dictionary.kt :language: kotlin +.. _kotlin-delete-related-objects: + Delete Related Objects ---------------------- +Deleting a parent object *does not* automatically delete any objects that are +related to it unless the related object is embedded. +Instead, Realm only deletes the reference to the related object. + +In the following example, we have a ``Frog`` object with a list of +``Pond`` objects. After we delete the ``Frog`` object, we confirm that all +``Pond`` objects still remain in the realm: + +.. literalinclude:: /examples/generated/kotlin/DeleteTest.snippet.delete-realm-object-with-related-objects.kt + :language: kotlin + +Chaining Deletes +~~~~~~~~~~~~~~~~ + +We recommend performing a **chaining delete** if you want to delete related +objects. To perform a chaining delete, you first query for the parent object +that you want to delete, then iterate through the parent object's +relationships and delete each related object. Finally, delete the parent +object itself. + +In the following example, we query for a ``Frog`` object named "Kermit", then +iterate through the object's ``favoritePonds`` property, and delete +each ``Pond`` object. Finally, we delete the ``Frog`` object itself: + +.. literalinclude:: /examples/generated/kotlin/DeleteTest.snippet.chain-delete-realm-list.kt + :language: kotlin + +.. _kotlin-delete-embedded-objects: + Delete an Embedded Object ------------------------- @@ -305,15 +320,17 @@ Delete an Embedded Object parent object, use a regular Realm object with a :ref:`to-one relationship ` instead. -You can delete an -`EmbeddedRealmObject.parent() <{+kotlin-local-prefix+}io.realm.kotlin.ext/parent.html>`__ -directly or through the parent object. +You can delete an embedded object directly: + +- Fetch and delete a specific embedded object +- Clear the parent's reference to the embedded object, which also deletes the embedded object instance. -To delete only an embedded object, you can fetch and delete a specific -embedded object or clear the parent's reference to the embedded object, -which also deletes the embedded object instance. +Alternatively, you can delete the parent object, whic automatically deletes all +of its embedded objects. -Deleting the parent object automatically deletes all of its embedded objects. +In the following example, we have a ``Frog`` object with an embedded +``Pond`` object. We delete the ``Pond`` object directly by fetching it from the +realm and then deleting it. We also delete the ``Pond`` object indirectly by .. literalinclude:: /examples/generated/kotlin/DataTypesTest.snippet.delete-embedded-object.kt :language: kotlin