Skip to content

Commit 827ce4e

Browse files
authored
Dicts - Support insert operation (#7459)
1 parent cf8a07c commit 827ce4e

File tree

9 files changed

+555
-27
lines changed

9 files changed

+555
-27
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* None.
55

66
### Enhancements
7-
* None.
7+
* Allow `insert` RealmObject's containing RealmDictionaries.
88

99
### Fixed
1010
* Removed wrong `@Nullable` annotation on `RealmQuery.maxRealmAny()`.

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

Lines changed: 66 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1446,14 +1446,6 @@ class RealmProxyClassGenerator(private val processingEnvironment: ProcessingEnvi
14461446
val args = if (metadata.embedded) embeddedArgs else topLevelArgs
14471447
beginMethod("long","insert", EnumSet.of(Modifier.PUBLIC, Modifier.STATIC), *args)
14481448

1449-
// Throw if model contains a dictionary field until we add support for it
1450-
if (containsDictionary(metadata.fields)) {
1451-
emitStatement("throw new UnsupportedOperationException(\"Calls to 'insert' with RealmModels containing RealmDictionary properties are not supported yet.\")")
1452-
endMethod()
1453-
emitEmptyLine()
1454-
return@apply
1455-
}
1456-
14571449
// Throw if model contains a set field until we add support for it
14581450
if (containsSet(metadata.fields)) {
14591451
emitStatement("throw new UnsupportedOperationException(\"Calls to 'insert' with RealmModels containing RealmSet properties are not supported yet.\")")
@@ -1565,9 +1557,72 @@ class RealmProxyClassGenerator(private val processingEnvironment: ProcessingEnvi
15651557
endControlFlow()
15661558
endControlFlow()
15671559
}
1568-
Utils.isRealmDictionary(field) -> {
1569-
// TODO: dictionary
1570-
emitSingleLineComment("TODO: Dictionary")
1560+
Utils.isRealmValueDictionary(field) -> {
1561+
val genericType = Utils.getGenericTypeQualifiedName(field)
1562+
val elementTypeMirror = TypeMirrors.getRealmDictionaryElementTypeMirror(field)
1563+
emitEmptyLine()
1564+
emitStatement("RealmDictionary<${genericType}> ${fieldName}UnmanagedDictionary = ((${interfaceName}) object).${getter}()")
1565+
beginControlFlow("if (${fieldName}UnmanagedDictionary != null)", fieldName)
1566+
emitStatement("OsMap ${fieldName}OsMap = new OsMap(table.getUncheckedRow(objKey), columnInfo.${fieldName}ColKey)")
1567+
1568+
emitStatement("java.util.Set<java.util.Map.Entry<String, ${genericType}>> entries = ${fieldName}UnmanagedDictionary.entrySet()")
1569+
beginControlFlow("for (java.util.Map.Entry<String, ${genericType}> entry : entries)")
1570+
emitStatement("String entryKey = entry.getKey()")
1571+
emitStatement("$genericType ${fieldName}UnmanagedEntryValue = entry.getValue()")
1572+
emitStatement("${fieldName}OsMap.put(entryKey, ${fieldName}UnmanagedEntryValue)")
1573+
endControlFlow()
1574+
endControlFlow()
1575+
}
1576+
Utils.isRealmAnyDictionary(field) -> {
1577+
val genericType = Utils.getGenericTypeQualifiedName(field)
1578+
emitStatement("RealmDictionary<RealmAny> ${fieldName}UnmanagedDictionary = ((${interfaceName}) object).${getter}()")
1579+
beginControlFlow("if (${fieldName}UnmanagedDictionary != null)")
1580+
emitStatement("OsMap ${fieldName}OsMap = new OsMap(table.getUncheckedRow(objKey), columnInfo.${fieldName}ColKey)")
1581+
emitStatement("java.util.Set<java.util.Map.Entry<String, ${genericType}>> entries = ${fieldName}UnmanagedDictionary.entrySet()")
1582+
emitStatement("java.util.List<String> keys = new java.util.ArrayList<>()")
1583+
emitStatement("java.util.List<Long> realmAnyPointers = new java.util.ArrayList<>()")
1584+
beginControlFlow("for (java.util.Map.Entry<String, ${genericType}> entry : entries)")
1585+
emitStatement("RealmAny realmAnyItem = entry.getValue()")
1586+
emitStatement("realmAnyItem = ProxyUtils.insert(realmAnyItem, realm, cache)")
1587+
emitStatement("${fieldName}OsMap.putRealmAny(entry.getKey(), realmAnyItem.getNativePtr())")
1588+
endControlFlow()
1589+
endControlFlow()
1590+
emitEmptyLine()
1591+
}
1592+
Utils.isRealmModelDictionary(field) -> {
1593+
val genericType: QualifiedClassName = Utils.getGenericTypeQualifiedName(field)!!
1594+
val listElementType: TypeMirror = Utils.getGenericType(field)!!
1595+
val isEmbedded = Utils.isFieldTypeEmbedded(listElementType, classCollection)
1596+
val linkedProxyClass: SimpleClassName = Utils.getDictionaryGenericProxyClassSimpleName(field)
1597+
1598+
emitStatement("RealmDictionary<${genericType}> ${fieldName}UnmanagedDictionary = ((${interfaceName}) object).${getter}()")
1599+
beginControlFlow("if (${fieldName}UnmanagedDictionary != null)")
1600+
emitStatement("OsMap ${fieldName}OsMap = new OsMap(table.getUncheckedRow(objKey), columnInfo.${fieldName}ColKey)")
1601+
emitStatement("java.util.Set<java.util.Map.Entry<String, ${genericType}>> entries = ${fieldName}UnmanagedDictionary.entrySet()")
1602+
beginControlFlow("for (java.util.Map.Entry<String, ${genericType}> entry : entries)")
1603+
emitStatement("String entryKey = entry.getKey()")
1604+
emitStatement("$genericType ${fieldName}UnmanagedEntryValue = entry.getValue()")
1605+
beginControlFlow("if(${fieldName}UnmanagedEntryValue == null)")
1606+
emitStatement("${fieldName}OsMap.put(entryKey, null)")
1607+
nextControlFlow("else")
1608+
// here goes the rest
1609+
emitStatement("Long cacheItemIndex${fieldName} = cache.get(${fieldName}UnmanagedEntryValue)")
1610+
if (isEmbedded) {
1611+
beginControlFlow("if (cacheItemIndex${fieldName} != null)")
1612+
emitStatement("""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: cache${fieldName}.toString()")""")
1613+
nextControlFlow("else")
1614+
emitStatement("cacheItemIndex${fieldName} = ${linkedProxyClass}.insert(realm, table, columnInfo.${fieldName}ColKey, objKey, ${fieldName}UnmanagedEntryValue, cache)")
1615+
endControlFlow()
1616+
emitStatement("${fieldName}OsMap.putRow(entryKey, cacheItemIndex${fieldName})")
1617+
} else {
1618+
beginControlFlow("if (cacheItemIndex${fieldName} == null)")
1619+
emitStatement("cacheItemIndex${fieldName} = ${linkedProxyClass}.insert(realm, ${fieldName}UnmanagedEntryValue, cache)")
1620+
endControlFlow()
1621+
emitStatement("${fieldName}OsMap.putRow(entryKey, cacheItemIndex${fieldName})")
1622+
}
1623+
endControlFlow()
1624+
endControlFlow()
1625+
endControlFlow()
15711626
}
15721627
Utils.isRealmSet(field) -> {
15731628
// TODO: sets

0 commit comments

Comments
 (0)