Skip to content

Commit e450a52

Browse files
authored
Dicts - add support for insert or update on collections (#7462)
1 parent 57defe2 commit e450a52

File tree

8 files changed

+858
-373
lines changed

8 files changed

+858
-373
lines changed

realm/realm-annotations-processor/src/main/java/io/realm/processor/RealmProxyClassGenerator.kt

Lines changed: 206 additions & 341 deletions
Large diffs are not rendered by default.

realm/realm-annotations-processor/src/test/resources/io/realm/some_test_AllTypesRealmProxy.java

Lines changed: 591 additions & 11 deletions
Large diffs are not rendered by default.

realm/realm-annotations-processor/src/test/resources/io/realm/some_test_EmbeddedClassSimpleParentRealmProxy.java

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -669,30 +669,16 @@ public static void insertOrUpdate(Realm realm, Iterator<? extends RealmModel> ob
669669

670670
OsList childrenOsList = new OsList(table.getUncheckedRow(objKey), columnInfo.childrenColKey);
671671
RealmList<some.test.EmbeddedClass> childrenList = ((some_test_EmbeddedClassSimpleParentRealmProxyInterface) object).realmGet$children();
672-
if (childrenList != null && childrenList.size() == childrenOsList.size()) {
673-
// For lists of equal lengths, we need to set each element directly as clearing the receiver list can be wrong if the input and target list are the same.
674-
int objectCount = childrenList.size();
675-
for (int i = 0; i < objectCount; i++) {
676-
some.test.EmbeddedClass childrenItem = childrenList.get(i);
672+
childrenOsList.removeAll();
673+
if (childrenList != null) {
674+
for (some.test.EmbeddedClass childrenItem : childrenList) {
677675
Long cacheItemIndexchildren = cache.get(childrenItem);
678676
if (cacheItemIndexchildren != null) {
679677
throw new IllegalArgumentException("Embedded objects can only have one parent pointing to them. This object was already copied, so another object is pointing to it: " + cacheItemIndexchildren.toString());
680678
} else {
681679
cacheItemIndexchildren = some_test_EmbeddedClassRealmProxy.insertOrUpdate(realm, table, columnInfo.childrenColKey, objKey, childrenItem, cache);
682680
}
683681
}
684-
} else {
685-
childrenOsList.removeAll();
686-
if (childrenList != null) {
687-
for (some.test.EmbeddedClass childrenItem : childrenList) {
688-
Long cacheItemIndexchildren = cache.get(childrenItem);
689-
if (cacheItemIndexchildren != null) {
690-
throw new IllegalArgumentException("Embedded objects can only have one parent pointing to them. This object was already copied, so another object is pointing to it: " + cacheItemIndexchildren.toString());
691-
} else {
692-
cacheItemIndexchildren = some_test_EmbeddedClassRealmProxy.insertOrUpdate(realm, table, columnInfo.childrenColKey, objKey, childrenItem, cache);
693-
}
694-
}
695-
}
696682
}
697683

698684
}

realm/realm-library/src/androidTest/kotlin/io/realm/DictionaryTester.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ interface DictionaryTester : GenericTester {
4242
fun insert()
4343
fun insertList()
4444
fun insertOrUpdate()
45+
fun insertOrUpdateList()
4546
fun copyToRealm()
4647
fun copyToRealmOrUpdate()
4748
fun copyFromRealm()

realm/realm-library/src/androidTest/kotlin/io/realm/ManagedDictionaryTesters.kt

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,56 @@ class ManagedDictionaryTester<T : Any>(
553553
}
554554
}
555555

556+
override fun insertOrUpdateList() {
557+
// Instantiate container and set dictionary on container
558+
val manualInstance = PrimaryKeyDictionaryContainer().apply {
559+
name = "manual"
560+
primaryKeyDictionaryProperty.get(this).putAll(initializedDictionary)
561+
}
562+
val emptyInstance = PrimaryKeyDictionaryContainer().apply {
563+
name = "empty"
564+
}
565+
566+
// insert into Realm
567+
realm.executeTransaction {
568+
realm.insertOrUpdate(listOf(emptyInstance, manualInstance))
569+
}
570+
571+
// Get dictionary from container from Realm
572+
val primaryKeyDictionaryContainer = realm.where<PrimaryKeyDictionaryContainer>()
573+
.equalTo("name", "manual")
574+
.findFirst()
575+
assertNotNull(primaryKeyDictionaryContainer)
576+
val dictionary = primaryKeyDictionaryProperty.get(primaryKeyDictionaryContainer)
577+
assertFalse(dictionary.isEmpty())
578+
initializedDictionary.forEach { key, value ->
579+
typeAsserter.assertEqualsHelper(realm, value, dictionary[key])
580+
}
581+
582+
if (testerClass == "String-NonLatin" || testerClass == "RealmAny-NonLatin") {
583+
primaryKeyDictionaryProperty.get(manualInstance)[NEW_KEY_NON_LATIN] = alternativeDictionary[KEY_BYE_NON_LATIN]
584+
} else {
585+
primaryKeyDictionaryProperty.get(manualInstance)[NEW_KEY] = alternativeDictionary[KEY_BYE]
586+
}
587+
588+
// Insert to Realm with non managed updated model
589+
realm.executeTransaction {
590+
realm.insertOrUpdate(listOf(emptyInstance, manualInstance))
591+
}
592+
593+
val updatedContainer = realm.where<PrimaryKeyDictionaryContainer>()
594+
.equalTo("name", "manual")
595+
.findFirst()
596+
assertNotNull(updatedContainer)
597+
val updatedDictinary = primaryKeyDictionaryProperty.get(primaryKeyDictionaryContainer)
598+
assertEquals(initializedDictionary.size + 1, updatedDictinary.size)
599+
if (testerClass == "String-NonLatin" || testerClass == "RealmAny-NonLatin") {
600+
typeAsserter.assertEqualsHelper(realm, alternativeDictionary[KEY_BYE_NON_LATIN], updatedDictinary[NEW_KEY_NON_LATIN])
601+
} else {
602+
typeAsserter.assertEqualsHelper(realm, alternativeDictionary[KEY_BYE], updatedDictinary[NEW_KEY])
603+
}
604+
}
605+
556606
override fun copyFromRealm() {
557607
val allTypesObject = createCollectionAllTypesManagedContainerAndAssert(realm)
558608
assertNotNull(allTypesObject)

realm/realm-library/src/androidTest/kotlin/io/realm/ParameterizedDictionaryTests.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,11 @@ class ParameterizedDictionaryTests(
184184
tester.insertOrUpdate()
185185
}
186186

187+
@Test
188+
fun insertOrUpdatedList() {
189+
tester.insertOrUpdateList()
190+
}
191+
187192
@Test
188193
fun copyToRealm() {
189194
tester.copyToRealm()

realm/realm-library/src/androidTest/kotlin/io/realm/UnmanagedDictionaryTesters.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ class UnmanagedDictionaryTester<T : Any>(
212212
override fun insert() = Unit // Not applicable
213213
override fun insertList() = Unit // Not applicable
214214
override fun insertOrUpdate() = Unit // Not applicable
215+
override fun insertOrUpdateList() = Unit // Not applicable
215216
override fun copyToRealm() = Unit // Not applicable
216217
override fun copyToRealmOrUpdate() = Unit // Not applicable
217218
override fun copyFromRealm() = Unit // Not applicable

realm/realm-library/src/main/java/io/realm/Realm.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1320,12 +1320,9 @@ public void insert(RealmModel object) {
13201320
* transaction.
13211321
* @throws io.realm.exceptions.RealmPrimaryKeyConstraintException if two objects with the same primary key is
13221322
* inserted or if a primary key value already exists in the Realm.
1323-
* @throws UnsupportedOperationException if the object to insert contains a {@link RealmDictionary} or
1324-
* a {@link RealmSet}.
1323+
* @throws UnsupportedOperationException if the object to insert contains a {@link RealmSet}.
13251324
* @see #copyToRealmOrUpdate(Iterable, ImportFlag...)
13261325
* @see RealmSet
1327-
* @see RealmDictionary
1328-
* @see RealmMap
13291326
*/
13301327
public void insertOrUpdate(Collection<? extends RealmModel> objects) {
13311328
checkIfValidAndInTransaction();

0 commit comments

Comments
 (0)