Context :
- Some content (Sheet, Category, etc.) are protected by groups. (Content class has 2 RealmLists of groups, the first "groupsOneOf" an the second "groupsAllOf")
- Users can be in groups (User has one RealmList "groups")
- Some content is available only for user which is at least in one of the content's group.
- Some content is available only for user which is in all of content's group.
For "at least in one of the content's group", I found 'in' operator in documentation :
This allows you to test if objects match any value in an array of values.
But for the second, no way to perform this kind of query. I searched solution in other posts but some people seems to say that's not supported right now. In iOS, it seems to be available with NSPredicate but not in java.
Here is my code :
fun <E: RealmObject> RealmQuery<E>.groupsAllowed(): RealmQuery<E>{
val userGroupsIds = realm.queryUserConnected()?.findFirst()?.groups?.toGroupIds()
if(userGroupsIds == null || userGroupsIds.isEmpty()){
isEmpty("groupsAllOf")
isEmpty("groupsOneOf")
}else{
beginGroup()
beginGroup()
isEmpty("groupsOneOf")
or()
`in`("groupsOneOf.id", userGroupsIds.toTypedArray())
endGroup()
//beginGroup()
//isEmpty("groupsAllOf")
//or()
//TODO
//endGroup()
endGroup()
}
return this
}
Currently I'm performing a post filter when I get the RealmResults for groupsAllOf :
fun <E: RealmObject> E.groupsAllowed(userGroupIds: List<String>): E?{
val groupsAllOf: RealmList<Group>? = when(this){
is Sheet -> groupsAllOf
is Category -> groupsAllOf
else -> null
}
if(groupsAllOf == null || groupsAllOf.isEmpty()){
return this
}else{
return if(userGroupIds.containsAll(groupsAllOf.toGroupIds())) this else null
}
}
fun <E: RealmObject> RealmResults<E>.groupsAllowed(): List<E>{
val userGroupIds = realm.queryUserConnected().findFirst()?.groups?.toGroupIds()?: emptyList()
val listAllowed = arrayListOf<E>()
this.forEach { it.groupsAllowed(userGroupIds)?.let { contentAllowed -> listAllowed.add(contentAllowed) } }
return listAllowed
}
fun RealmList<Group>.toGroupIds(): List<String> = arrayListOf<String>().apply { this@toGroupIds.forEach { group -> this.add(group.id) } }
But this is annoying because I have to no forget to call this function when I get the RealmResults :/
Some help would be greatly appreciated.