In room, it seems to be impossible to use annotation based setups in a generic class with variable based data or with provided classes - the result is that there is no workaround to define queries with Flow inside an abstract generic base class.
Is that really try?
Examples 1 - CAN BE SOLVED
Define a query which contains a table name that is defined by a class variable
@Dao
abstract class BaseDao<Item : IItem, ItemWithRef> {
abstract val tableName: String
// DOES NOT WORK - because table name is not compile-time constant
@Transaction
@Query("select * from ${tableName}")
abstract suspend fun loadAll(): List<ItemWithRef>
// SOLUTION
private val rawQueryLoadAll
get() = "SELECT * FROM $tableName"
@Transaction
@RawQuery
protected abstract suspend fun loadAll(query: SimpleSQLiteQuery): List<ItemWithRef>
suspend fun loadAll(): List<ItemWithRef> = loadAll(queryLoadAll)
}
Examples 2 - CAN NOT BE SOLVED?
Define flow queries which contains a table name that is defined by a class variable
Here the problem is, that @RawQuery needs to know the queries classes - can this somehow be solved as well?
@Dao
abstract class BaseDao<Item : IItem, ItemWithRef> {
abstract val tableName: String
// all 3 possibilities DO NOT WORK
// - because `@RawQuery` needs to know that it handles `ItemWithRef::class`
// - because the table name is not constant
// DOES NOT WORK
@Transaction
@Query("select * from ${tableName}")
abstract suspend fun flowAll(): Flow<List<ItemWithRef>>
// DOES NOT WORK
@Transaction
@RawQuery
protected abstract fun flowAll(query: SimpleSQLiteQuery): Flow<List<ItemWithRef>>
fun flowAll(): Flow<List<ItemWithRef>> = flowAll(queryLoadAll)
// DOES NOT WORK
@Transaction
@RawQuery(observedEntities = arrayOf(ItemWithRef::class))
protected abstract fun flowAll(query: SimpleSQLiteQuery): Flow<List<ItemWithRef>>
fun flowAll(): Flow<List<ItemWithRef>> = flowAll(queryLoadAll)
}
Question
I'm fine with the workaround for example 1 but is there any workaround to also define a Flow raw query in a base class somehow?