Skip to content

Commit

Permalink
Initial draft
Browse files Browse the repository at this point in the history
  • Loading branch information
cbullinger committed Nov 18, 2023
1 parent 30e51bd commit e499184
Show file tree
Hide file tree
Showing 10 changed files with 1,225 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package com.mongodb.realm.realmkmmapp

import io.realm.kotlin.ext.backlinks
import io.realm.kotlin.ext.realmListOf
import io.realm.kotlin.query.RealmResults
import io.realm.kotlin.types.EmbeddedRealmObject
import io.realm.kotlin.types.RealmInstant
import io.realm.kotlin.types.RealmList
import io.realm.kotlin.types.RealmObject
Expand All @@ -10,6 +13,10 @@ import org.mongodb.kbson.ObjectId
// :replace-start: {
// "terms": {
// "ExampleSyncObject_": "",
// "ExampleSyncRelationship_": "",
// "_1": "",
// "_2": "",
// "_3": "",
// "SyncTask": "Task"
// }
// }
Expand Down Expand Up @@ -44,10 +51,106 @@ class Team : RealmObject {
}
// :snippet-end:

/*
****** Used on Model Data with Device Sync page ******
** Tested on SchemaSyncTest.kt **
*/

// :snippet-start: sync-define-realm-object
// Maps to `Frog` collection
class ExampleSyncObject_Frog : RealmObject {
@PrimaryKey
var _id: ObjectId = ObjectId()
var name: String = ""
var age: Int? = null
}

// Maps to `Pond` collection
class ExampleSyncObject_Pond : RealmObject {
@PrimaryKey
var _id: ObjectId = ObjectId()
var name: String = ""
}
// :snippet-end:

// :snippet-start: sync-define-to-one-relationship
class ExampleSyncRelationship_Pond : RealmObject {
@PrimaryKey
var _id: ObjectId = ObjectId()
var name: String = ""
}

class ExampleSyncRelationship_Frog : RealmObject {
@PrimaryKey
var _id: ObjectId = ObjectId()
var name: String = ""
var age: Int? = null
// To-one relationship (MUST be optional)
var favoritePond: ExampleSyncRelationship_Pond? = null
}
// :snippet-end:

// :snippet-start: sync-define-to-many-relationship
class ExampleSyncRelationship_Pond_1 : RealmObject {
@PrimaryKey
var _id: ObjectId = ObjectId()
var name: String = ""
}

class ExampleSyncRelationship_Frog_1 : RealmObject {
@PrimaryKey
var _id: ObjectId = ObjectId()
var name: String = ""
var age: Int? = null
// To-many relationship (can have many ponds)
var favoritePonds: RealmList<ExampleSyncRelationship_Pond_1> = realmListOf()
}
// :snippet-end:

// :snippet-start: sync-define-inverse-relationship
class ExampleSyncRelationship_Pond_2 : RealmObject {
@PrimaryKey
var _id: ObjectId = ObjectId()
var name: String = ""
// Backlink to the `Frog` that has this `Pond` as its favorite
val frog: RealmResults<ExampleSyncRelationship_Frog_2> by backlinks(ExampleSyncRelationship_Frog_2::favoritePonds)
}
class ExampleSyncRelationship_Frog_2 : RealmObject {
@PrimaryKey
var _id: ObjectId = ObjectId()
var name: String = ""
var age: Int? = null
// To-many relationship (can have many ponds)
var favoritePonds: RealmList<ExampleSyncRelationship_Pond_2> = realmListOf()
}
// :snippet-end:

// :snippet-start: sync-define-embedded-object
class ExampleSyncRelationship_Frog_3 : RealmObject {
@PrimaryKey
var _id: ObjectId = ObjectId()
var name: String = ""
var age: Int? = null
// Embed a single object (MUST be optional)
var favoritePond: ExampleSyncRelationship_EmbeddedPond? = null
}

class ExampleSyncRelationship_Forest : RealmObject {
@PrimaryKey
var _id: ObjectId = ObjectId()
var name: String = ""
// Embed multiple objects (can have many ponds)
var forestPonds: RealmList<ExampleSyncRelationship_EmbeddedPond> = realmListOf()
}

class ExampleSyncRelationship_EmbeddedPond : EmbeddedRealmObject {
var name: String? = null
}
// :snippet-end:

/*
** Used on Add Sync to App page **
*/
****** Used on Add Sync to App page ******
*/

// :snippet-start: sync-to-do-model
class ExampleSyncObject_List : RealmObject {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
package com.mongodb.realm.realmkmmapp

import io.realm.kotlin.Realm
import io.realm.kotlin.ext.query
import io.realm.kotlin.ext.realmListOf
import io.realm.kotlin.mongodb.App
import io.realm.kotlin.mongodb.Credentials
import io.realm.kotlin.mongodb.sync.SyncConfiguration
import io.realm.kotlin.mongodb.syncSession
import kotlinx.coroutines.runBlocking
import org.mongodb.kbson.ObjectId
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.time.Duration.Companion.seconds

class SchemaSyncTest : RealmTest() {
/*
** Object types defined in SchemaSync.kt **
*/
@Test
fun syncRealmObjectTest() {
val credentials = Credentials.anonymous(reuseExisting = false)
runBlocking {
val app = App.create(FLEXIBLE_APP_ID)
val user = app.login(credentials)
val flexSyncConfig = SyncConfiguration.Builder(user, setOf(ExampleSyncObject_Frog::class, ExampleSyncObject_Pond::class))
.initialSubscriptions { realm ->
add(realm.query<ExampleSyncObject_Frog>(), "all-frogs")
add(realm.query<ExampleSyncObject_Pond>(), "all-ponds")
}
.build()
val syncRealm = Realm.open(flexSyncConfig)
Log.v("Successfully opened realm: ${syncRealm.configuration}")

val frogId = ObjectId()
val pondId = ObjectId()
syncRealm.write {
val existingFrogs = query<ExampleSyncObject_Frog>().find()
delete(existingFrogs)
val existingPonds = query<ExampleSyncObject_Pond>().find()
delete(existingPonds)
copyToRealm(ExampleSyncObject_Frog().apply {
_id = frogId
name = "Kermit"
age = 42
})
copyToRealm(ExampleSyncObject_Pond().apply {
_id = pondId
name = "Frog Pond"

})
}
syncRealm.syncSession.uploadAllLocalChanges(30.seconds)
syncRealm.write {
val frog = query<ExampleSyncObject_Frog>("_id == $0", frogId).find().first()
val pond = query<ExampleSyncObject_Pond>("_id == $0", pondId).find().first()
delete(frog)
delete(pond)
}
user.delete()
syncRealm.close()
}
}

@Test
fun syncToOneRelationshipTest() {
val credentials = Credentials.anonymous(reuseExisting = false)
runBlocking {
val app = App.create(FLEXIBLE_APP_ID)
val user = app.login(credentials)
val flexSyncConfig = SyncConfiguration.Builder(user, setOf(ExampleSyncRelationship_Frog::class, ExampleSyncRelationship_Pond::class))
.initialSubscriptions { realm ->
add(realm.query<ExampleSyncRelationship_Frog>())
add(realm.query<ExampleSyncRelationship_Pond>())
}
.build()
val syncRealm = Realm.open(flexSyncConfig)
Log.v("Successfully opened realm: ${syncRealm.configuration}")

val frogId = ObjectId()
val pondId = ObjectId()
syncRealm.write {
val existingFrogs = query<ExampleSyncRelationship_Frog>().find()
delete(existingFrogs)
val existingPonds = query<ExampleSyncRelationship_Pond>().find()
delete(existingPonds)
copyToRealm(ExampleSyncRelationship_Frog().apply {
_id = frogId
name = "Kermit"
age = 42
favoritePond = copyToRealm(ExampleSyncRelationship_Pond().apply {
_id = pondId
name = "Frog Pond"
})
})
}
syncRealm.syncSession.uploadAllLocalChanges(30.seconds)
syncRealm.write {
val frog = query<ExampleSyncRelationship_Frog>("_id == $0", frogId).find().first()
val pond = query<ExampleSyncRelationship_Pond>("_id == $0", pondId).find().first()
delete(frog)
delete(pond)
}
user.delete()
syncRealm.close()
}
}

@Test
fun syncToManyRelationshipTest() {
val credentials = Credentials.anonymous(reuseExisting = false)
runBlocking {
val app = App.create(FLEXIBLE_APP_ID)
val user = app.login(credentials)
val flexSyncConfig = SyncConfiguration.Builder(user, setOf(ExampleSyncRelationship_Frog_1::class, ExampleSyncRelationship_Pond_1::class))
.initialSubscriptions { realm ->
add(realm.query<ExampleSyncRelationship_Frog_1>())
add(realm.query<ExampleSyncRelationship_Pond_1>())
}
.build()
val syncRealm = Realm.open(flexSyncConfig)
Log.v("Successfully opened realm: ${syncRealm.configuration}")

val frogId = ObjectId()
val pondId = ObjectId()
syncRealm.write {
val existingFrogs = query<ExampleSyncRelationship_Frog_1>().find()
delete(existingFrogs)
val existingPonds = query<ExampleSyncRelationship_Pond_1>().find()
delete(existingPonds)
copyToRealm(ExampleSyncRelationship_Frog_1().apply {
_id = frogId
name = "Kermit"
age = 42
favoritePonds = realmListOf(copyToRealm(ExampleSyncRelationship_Pond_1().apply {
_id = pondId
name = "Frog Pond"
}))
})
}
syncRealm.syncSession.uploadAllLocalChanges(30.seconds)
syncRealm.write {
val frog = query<ExampleSyncRelationship_Frog_1>("_id == $0", frogId).find().first()
val pond = query<ExampleSyncRelationship_Pond_1>("_id == $0", pondId).find().first()
delete(frog)
delete(pond)
}
user.delete()
syncRealm.close()
}
}

@Test
fun syncInverseRelationshipTest() {
val credentials = Credentials.anonymous(reuseExisting = false)
runBlocking {
val app = App.create(FLEXIBLE_APP_ID)
val user = app.login(credentials)
val flexSyncConfig = SyncConfiguration.Builder(user, setOf(ExampleSyncRelationship_Frog_2::class, ExampleSyncRelationship_Pond_2::class))
.initialSubscriptions { realm ->
add(realm.query<ExampleSyncRelationship_Frog_2>())
add(realm.query<ExampleSyncRelationship_Pond_2>())
}
.build()
val syncRealm = Realm.open(flexSyncConfig)
Log.v("Successfully opened realm: ${syncRealm.configuration}")

val frogId = ObjectId()
val pondId = ObjectId()
syncRealm.write {
val existingFrogs = query<ExampleSyncRelationship_Frog_2>().find()
delete(existingFrogs)
val existingPonds = query<ExampleSyncRelationship_Pond_2>().find()
delete(existingPonds)
copyToRealm(ExampleSyncRelationship_Frog_2().apply {
_id = frogId
name = "Kermit"
age = 42
favoritePonds = realmListOf(copyToRealm(ExampleSyncRelationship_Pond_2().apply {
_id = pondId
name = "Frog Pond"
}))
})
}
syncRealm.syncSession.uploadAllLocalChanges(30.seconds)
syncRealm.write {
val frog = query<ExampleSyncRelationship_Frog_2>("_id == $0", frogId).find().first()
val pond = query<ExampleSyncRelationship_Pond_2>("_id == $0", pondId).find().first()
assertEquals(pond.frog.first(), frog)
delete(frog)
delete(pond)
}
user.delete()
syncRealm.close()
}
}

@Test
fun syncEmbeddedRelationshipTest() {
val credentials = Credentials.anonymous(reuseExisting = false)
runBlocking {
val app = App.create(FLEXIBLE_APP_ID)
val user = app.login(credentials)
val flexSyncConfig = SyncConfiguration.Builder(user, setOf(ExampleSyncRelationship_Frog_3::class, ExampleSyncRelationship_Forest::class, ExampleSyncRelationship_EmbeddedPond::class))
.initialSubscriptions { realm ->
add(realm.query<ExampleSyncRelationship_Frog_3>())
add(realm.query<ExampleSyncRelationship_Forest>())
}
.build()
val syncRealm = Realm.open(flexSyncConfig)
Log.v("Successfully opened realm: ${syncRealm.configuration}")

val frogId = ObjectId()
val forestId = ObjectId()
syncRealm.write {
val existingFrogs = query<ExampleSyncRelationship_Frog_3>().find()
delete(existingFrogs)
val existingForests = query<ExampleSyncRelationship_Forest>().find()
delete(existingForests)
val existingPonds = query<ExampleSyncRelationship_EmbeddedPond>().find()
delete(existingPonds)
copyToRealm(ExampleSyncRelationship_Frog_3().apply {
_id = frogId
name = "Kermit"
age = 42
favoritePond = ExampleSyncRelationship_EmbeddedPond().apply {
name = "Frog Pond"
}
})
copyToRealm(ExampleSyncRelationship_Forest().apply {
_id = forestId
name = "Frog Forest"
forestPonds = realmListOf(ExampleSyncRelationship_EmbeddedPond().apply {
name = "Frog Pond"
})
})
}
syncRealm.syncSession.uploadAllLocalChanges(30.seconds)
syncRealm.write {
val frog = query<ExampleSyncRelationship_Frog_3>("_id == $0", frogId).find().first()
val forest = query<ExampleSyncRelationship_Forest>("_id == $0", forestId).find().first()
assertEquals(frog.favoritePond?.name, "Frog Pond")
assertEquals(forest.forestPonds.first().name, "Frog Pond")
delete(frog)
delete(forest)
}
user.delete()
syncRealm.close()
}
}
}
Loading

0 comments on commit e499184

Please sign in to comment.