Implement TopicDao

pull/1323/head
lihenggui 2 years ago
parent 147baf2043
commit ef2fe0252d

@ -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)
}
}

@ -16,11 +16,11 @@ SELECT * FROM topic;
getOneOffTopicEntities:
SELECT * FROM topic;
insertOrIgnoreTopics:
insertOrIgnoreTopic:
INSERT OR IGNORE INTO topic(id, name, short_description, long_description, url, image_url)
VALUES (?, ?, ?, ?, ?, ?);
upsertTopics:
upsertTopic:
INSERT INTO topic(id, name, short_description, long_description, url, image_url)
VALUES (?, ?, ?, ?, ?, ?)
ON CONFLICT(id) DO UPDATE SET
@ -31,4 +31,4 @@ url = excluded.url,
image_url = excluded.image_url;
deleteTopics:
DELETE FROM topic WHERE id IN (:ids);
DELETE FROM topic WHERE id IN :ids;

Loading…
Cancel
Save