In my scenario there is a one-to-one relationship between transactions and categories.
In order to query the list of transactions and corresponding categories, documentation tells me i must first model the one-to-one relationship between the two entities (https://developer.android.com/training/data-storage/room/relationships) by creating a TransactionAndCategory
class
I really don't want to do this, it is not clean and it really is bad coding imo. Therefore i tried associating these objects by myself but i haven't found a way to do it. Here's what i tried to do:
class TransactionRepositoryImpl(private val transactionDao: TransactionDao, private val categoryDao: CategoryDao) : TransactionRepository {
override fun getAll(): Flow<List<Transaction>> {
return transactionDao
.getAll()
.mapIterable{
Transaction(it, categoryDao.get(it.categoryId))
}
}
}
This results in an error because categoryDao.get(it.categoryId)
returns a flow itself:
@Dao
interface CategoryDao {
@Query("SELECT * FROM categories WHERE uid = :id")
fun get(id: Int): Flow<DatabaseCategory>
}
The mapIterable function is just an extension to 'unwrap' the list:
inline fun <T, R> Flow<Iterable<T>>.mapIterable(crossinline transform: (T) -> R): Flow<List<R>> =
map { it.map(transform) }
Transactions itself are retrieved like this from the TransactionDao
:
fun getAll(): Flow<List<DatabaseTransaction>>
The constructor of my Transaction domain model takes two database models as arguments:
constructor(databaseTransaction: DatabaseTransaction, databaseCategory: DatabaseCategory)
I'm hoping someone with more Kotlin Flow experience than me has encountered the same issue and can provide me some ideas/insights/solutions on how to link these objects in a clean way without creating a TransactionAndCategory class.
EDIT: I tried suspending the categoryDao.get method:
@Query("SELECT * FROM categories WHERE uid = :id")
suspend fun get(id: Int): DatabaseCategory
override suspend fun getAll(): Flow<List<Transaction>> {
return transactionDao
.getAll()
.mapIterable{
Transaction(it, categoryDao.get(it.categoryId))
}
}
Unfortunatly it's not possible to call categoryDao.get
inside mapIterable
, so i'm still stuck on this
compilation error: "suspension functions can only be called only within coroutine body"