|
|
|
|
@ -16,61 +16,123 @@
|
|
|
|
|
|
|
|
|
|
package com.google.samples.apps.nowinandroid.core.database.dao
|
|
|
|
|
|
|
|
|
|
import androidx.room.Dao
|
|
|
|
|
import androidx.room.Insert
|
|
|
|
|
import androidx.room.OnConflictStrategy
|
|
|
|
|
import androidx.room.Query
|
|
|
|
|
import androidx.room.Upsert
|
|
|
|
|
import app.cash.sqldelight.coroutines.asFlow
|
|
|
|
|
import app.cash.sqldelight.coroutines.mapToList
|
|
|
|
|
import app.cash.sqldelight.coroutines.mapToOne
|
|
|
|
|
import com.google.samples.apps.nowinandroid.core.database.NiaDatabase
|
|
|
|
|
import com.google.samples.apps.nowinandroid.core.database.model.TopicEntity
|
|
|
|
|
import kotlinx.coroutines.CoroutineDispatcher
|
|
|
|
|
import kotlinx.coroutines.flow.Flow
|
|
|
|
|
import kotlinx.coroutines.flow.map
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* DAO for [TopicEntity] access
|
|
|
|
|
*/
|
|
|
|
|
@Dao
|
|
|
|
|
interface TopicDao {
|
|
|
|
|
@Query(
|
|
|
|
|
value = """
|
|
|
|
|
SELECT * FROM topics
|
|
|
|
|
WHERE id = :topicId
|
|
|
|
|
""",
|
|
|
|
|
)
|
|
|
|
|
fun getTopicEntity(topicId: String): Flow<TopicEntity>
|
|
|
|
|
|
|
|
|
|
@Query(value = "SELECT * FROM topics")
|
|
|
|
|
fun getTopicEntities(): Flow<List<TopicEntity>>
|
|
|
|
|
class TopicDao(db: NiaDatabase, private val dispatcher: CoroutineDispatcher) {
|
|
|
|
|
|
|
|
|
|
@Query(value = "SELECT * FROM topics")
|
|
|
|
|
suspend fun getOneOffTopicEntities(): List<TopicEntity>
|
|
|
|
|
private val query = db.topicsQueries
|
|
|
|
|
|
|
|
|
|
@Query(
|
|
|
|
|
value = """
|
|
|
|
|
SELECT * FROM topics
|
|
|
|
|
WHERE id IN (:ids)
|
|
|
|
|
""",
|
|
|
|
|
)
|
|
|
|
|
fun getTopicEntities(ids: Set<String>): Flow<List<TopicEntity>>
|
|
|
|
|
fun getTopicEntity(topicId: String): Flow<TopicEntity> {
|
|
|
|
|
return query.getTopicEntity(topicId) { id, name, shortDescription, longDescription, url, imageUrl ->
|
|
|
|
|
TopicEntity(
|
|
|
|
|
id = id,
|
|
|
|
|
name = name,
|
|
|
|
|
shortDescription = shortDescription,
|
|
|
|
|
longDescription = longDescription,
|
|
|
|
|
url = url,
|
|
|
|
|
imageUrl = imageUrl,
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
.asFlow()
|
|
|
|
|
.mapToOne(dispatcher)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fun getTopicEntities(): Flow<List<TopicEntity>> {
|
|
|
|
|
return query.getOneOffTopicEntities { id, name, shortDescription, longDescription, url, imageUrl ->
|
|
|
|
|
TopicEntity(
|
|
|
|
|
id = id,
|
|
|
|
|
name = name,
|
|
|
|
|
shortDescription = shortDescription,
|
|
|
|
|
longDescription = longDescription,
|
|
|
|
|
url = url,
|
|
|
|
|
imageUrl = imageUrl,
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
.asFlow()
|
|
|
|
|
.mapToList(dispatcher)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
suspend fun getOneOffTopicEntities(): List<TopicEntity> {
|
|
|
|
|
// TODO: Use flow?
|
|
|
|
|
return query.getOneOffTopicEntities { id, name, shortDescription, longDescription, url, imageUrl ->
|
|
|
|
|
TopicEntity(
|
|
|
|
|
id = id,
|
|
|
|
|
name = name,
|
|
|
|
|
shortDescription = shortDescription,
|
|
|
|
|
longDescription = longDescription,
|
|
|
|
|
url = url,
|
|
|
|
|
imageUrl = imageUrl,
|
|
|
|
|
)
|
|
|
|
|
}.executeAsList()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fun getTopicEntities(ids: Set<String>): Flow<List<TopicEntity>> {
|
|
|
|
|
return query.getTopicEntities { id, name, shortDescription, longDescription, url, imageUrl ->
|
|
|
|
|
TopicEntity(
|
|
|
|
|
id = id,
|
|
|
|
|
name = name,
|
|
|
|
|
shortDescription = shortDescription,
|
|
|
|
|
longDescription = longDescription,
|
|
|
|
|
url = url,
|
|
|
|
|
imageUrl = imageUrl,
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
.asFlow()
|
|
|
|
|
.mapToList(dispatcher)
|
|
|
|
|
.map {
|
|
|
|
|
it.filter { topic -> topic.id in ids }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Inserts [topicEntities] into the db if they don't exist, and ignores those that do
|
|
|
|
|
*/
|
|
|
|
|
@Insert(onConflict = OnConflictStrategy.IGNORE)
|
|
|
|
|
suspend fun insertOrIgnoreTopics(topicEntities: List<TopicEntity>): List<Long>
|
|
|
|
|
suspend fun insertOrIgnoreTopics(topicEntities: List<TopicEntity>): List<Long> {
|
|
|
|
|
topicEntities.map {
|
|
|
|
|
query.insertOrIgnoreTopic(
|
|
|
|
|
id = it.id,
|
|
|
|
|
name = it.name,
|
|
|
|
|
short_description = it.shortDescription,
|
|
|
|
|
long_description = it.longDescription,
|
|
|
|
|
url = it.url,
|
|
|
|
|
image_url = it.imageUrl,
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
// TODO return the ids of the inserted topics
|
|
|
|
|
return topicEntities.mapNotNull { it.id.toLongOrNull() }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Inserts or updates [entities] in the db under the specified primary keys
|
|
|
|
|
*/
|
|
|
|
|
@Upsert
|
|
|
|
|
suspend fun upsertTopics(entities: List<TopicEntity>)
|
|
|
|
|
suspend fun upsertTopics(entities: List<TopicEntity>) {
|
|
|
|
|
entities.forEach {
|
|
|
|
|
query.upsertTopic(
|
|
|
|
|
id = it.id,
|
|
|
|
|
name = it.name,
|
|
|
|
|
short_description = it.shortDescription,
|
|
|
|
|
long_description = it.longDescription,
|
|
|
|
|
url = it.url,
|
|
|
|
|
image_url = it.imageUrl,
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Deletes rows in the db matching the specified [ids]
|
|
|
|
|
*/
|
|
|
|
|
@Query(
|
|
|
|
|
value = """
|
|
|
|
|
DELETE FROM topics
|
|
|
|
|
WHERE id in (:ids)
|
|
|
|
|
""",
|
|
|
|
|
)
|
|
|
|
|
suspend fun deleteTopics(ids: List<String>)
|
|
|
|
|
suspend fun deleteTopics(ids: List<String>) {
|
|
|
|
|
query.deleteTopics(ids)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|