apollo-kotlin
apollo-kotlin copied to clipboard
Normalized cache: handle dangling references
ApolloStore: does remove(key: CacheKey)
method remove ApolloCacheReference
field in related records? I mean a mechanism like "ON DELETE CASCADE SET NULL" in RDBMS.
There is ApolloStore.remove(cacheKey: CacheKey, cascade: Boolean). Would that work?
This method with flag cascade = true
looks for children and deletes them with root record (cacheKey
).
From SqlNormalizedCache
:
override fun remove(cacheKey: CacheKey, cascade: Boolean): Boolean {
val result: Boolean = nextCache?.remove(cacheKey, cascade) ?: false
if (result) {
return true
}
return if (cascade) {
selectRecordForKey(cacheKey.key)
?.referencedFields()
?.all { remove(CacheKey(it.key), cascade = true) }
?: false
} else {
deleteRecord(cacheKey.key)
}
}
From cache.sq
:
recordForKey:
SELECT key, record FROM records WHERE key=?;
So this method loads the record from database, retrieves referencedFields
(children for that loaded record) and deletes them all with given record.
But what about referencing field? There should be a solution to remove references from parent
records to provide consistency of database.
For example:
SELECT key, record FROM records WHERE record LIKE '%ApolloCacheReference{<cache key>}%'
And then clear that referencing field from the record by merge
method or somehow. Without that solution there is no way to fetch parent data from cache, because there occurs MISS field
error (there is still ApolloCacheReference field to a child record that doesn't exists in database).
Hoping to dig into this soon. I'm realizing just now that cascade
wasn't a great naming choice as it's about deleting children, not parents like SQL is doing.
apollo-client
refers to this as dangling references and handles them with readFunctions.
I think something similar would work. Compared to cascade delete, that'd keep the dangling reference around in case it becomes valid again. I think that could be handy?
I tweaked the name of this issue a bit so that it's more clear in https://github.com/apollographql/apollo-kotlin/issues/2331