我想使用 SQLDelight 作为我的应用程序中的缓存层,并使用协程扩展来从 SQL 查询返回流,并在本地数据库中的条目发生更改时收到通知。
但是因为 SQLDelight 为存储的实体生成它自己的类并在流中发出它们,所以我在将存储的类转换为在我的应用程序的其余部分中使用的类时遇到了麻烦。
下面您可以找到我的 FriendEntity
SQL 类型和查询函数的摘录,SQLDelight 使用它来生成 FriendEntity
数据类和 kotlin 函数(生成的输出位于问题底部)
// SQLDelight queries
CREATE TABLE FriendEntity (
id TEXT NOT NULL PRIMARY KEY,
username TEXT NOT NULL,
firstname TEXT NOT NULL,
lastname TEXT,
phone TEXT,
picture TEXT,
accepted INTEGER AS Boolean DEFAULT 0 NOT NULL
getFriendById:
SELECT * FROM FriendEntity
WHERE id = :id;
);
下面我想创建一个缓存服务,它也发出 flow
但类型为 Friend
而不是 FriendEntity
所以我必须以某种方式进行转换将 FriendEntity
类添加到我的 Friend
类,同时仍返回流。
如果不先收集流量,这是否可能?
override fun get(id: String): Flow<Friend>? {
return try {
return queries.getFriendById(id = id).asFlow() //returns Flow<Query<FriendEntity>>
} catch (e: NullPointerException) {
null
}
}
data class Friend(
var profile: Profile,
var accepted: Boolean
)
data class Profile(
var id: String,
var username: String,
var firstname: String,
var lastname: String?,
var phone: String? = null,
var picture: String? = null,
)
由 SQLDelight 生成:
public fun <T : Any> getFriendById(id: String, mapper: (
id: String,
username: String,
firstname: String,
lastname: String?,
phone: String?,
picture: String?,
accepted: Boolean
) -> T): Query<T>
public fun getFriendById(id: String): Query<FriendEntity>
public data class FriendEntity(
public val id: String,
public val username: String,
public val firstname: String,
public val lastname: String?,
public val phone: String?,
public val picture: String?,
public val accepted: Boolean
) {
public override fun toString(): String = """
|FriendEntity [
| id: $id
| username: $username
| firstname: $firstname
| lastname: $lastname
| phone: $phone
| picture: $picture
| accepted: $accepted
|]
""".trimMargin()
}
最佳答案
我在他们的 Github 讨论中提出了这个问题,并得到了一个不依赖扩展的很好答案。您可以在调用查询时使用自定义映射器参数:
override fun get(id: Long): Flow<Query<Friend>>? {
return try {
return queries.getFriendById(
id = id,
mapper = { friendId, username, firstname, lastname, phone, picture, accepted ->
Friend(
Profile(friendId, username, firstname, lastname, phone, picture),
accepted
)
}).asFlow()
} catch (e: NullPointerException) {
null
}
}
抄送:亚历克·斯特朗
https://github.com/cashapp/sqldelight/discussions/2782
关于kotlin - 使用流时 SQLDelight 转换查询返回类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70717634/