blob: 3a11b73ca4c5bd7505dfdd811b58f54dcad3b205 [file] [log] [blame]
/*
* Copyright 2024 The Android Open Source Project
*
* 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.
*/
@file:JvmMultifileClass
@file:JvmName("RelationUtil")
package androidx.room.util
import androidx.annotation.RestrictTo
import kotlin.jvm.JvmMultifileClass
import kotlin.jvm.JvmName
/**
* Utility function used in generated code to recursively fetch relationships when the amount of
* keys exceed [MAX_BIND_PARAMETER_CNT].
*
* @param map - The map containing the relationship keys to fill-in.
* @param isRelationCollection - True if [V] is a [Collection] which means it is non null.
* @param fetchBlock - A lambda for calling the generated _fetchRelationship function.
*/
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP_PREFIX)
fun <K : Any, V> recursiveFetchMap(
map: MutableMap<K, V>,
isRelationCollection: Boolean,
fetchBlock: (MutableMap<K, V>) -> Unit
) {
val tmpMap = mutableMapOf<K, V>()
var count = 0
for (key in map.keys) {
// Safe because `V` is a nullable type arg when isRelationCollection == false and vice versa
@Suppress("UNCHECKED_CAST")
if (isRelationCollection) {
tmpMap[key] = map[key] as V
} else {
tmpMap[key] = null as V
}
count++
if (count == MAX_BIND_PARAMETER_CNT) {
// recursively load that batch
fetchBlock(tmpMap)
// for non collection relation, put the loaded batch in the original map,
// not needed when dealing with collections since references are passed
if (!isRelationCollection) {
map.putAll(tmpMap)
}
tmpMap.clear()
count = 0
}
}
if (count > 0) {
// load the last batch
fetchBlock(tmpMap)
// for non collection relation, put the last batch in the original map
if (!isRelationCollection) {
map.putAll(tmpMap)
}
}
}
/**
* Unfortunately, we cannot read this value so we are only setting it to the SQLite default.
*/
internal const val MAX_BIND_PARAMETER_CNT = 999