Room - queries in generic base class (especially flow queries)

Viewed 198

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?

0 Answers
Related