首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用流时SQLDelight转换查询返回类型

使用流时SQLDelight转换查询返回类型
EN

Stack Overflow用户
提问于 2022-01-14 23:30:18
回答 2查看 549关注 0票数 1

我希望在我的应用程序中使用SQLDelight作为缓存层,并在coroutines扩展中返回来自我的SQL查询的流,并在本地数据库中的条目发生变化时得到通知。

但是由于SQLDelight为存储的实体生成自己的类,并在流中发布它们,所以在我的应用程序的其余部分中,我很难将存储的类转换为使用的类。

下面可以找到我的FriendEntity SQL类型和查询函数的摘录,SQLDelight用来生成FriendEntity数据类和kotlin函数(生成的输出位于问题的底部)。

代码语言:javascript
复制
// 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类。

如果不先收集流量,这可能吗?

代码语言:javascript
复制
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生成:

代码语言:javascript
复制
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>
代码语言:javascript
复制
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()
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-01-28 11:12:55

我在他们的Github讨论中问了这个问题,得到了一个不依赖于扩展的create答案。在调用查询时,可以使用自定义映射器参数:

代码语言:javascript
复制
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
  }
}

CC: Alec Strong

https://github.com/cashapp/sqldelight/discussions/2782

票数 0
EN

Stack Overflow用户

发布于 2022-01-28 08:32:52

您必须在源集中使用此扩展实现。

代码语言:javascript
复制
kotlin {
  sourceSets.commonMain.dependencies {
    implementation "com.squareup.sqldelight:coroutines-extensions:1.5.3"
  }
}

现在您可以获得如下的数据

代码语言:javascript
复制
val data: Flow<List<//YourDataClass>> = 
  query.selectAll()
    .asFlow()
    .mapToList()

参考文献:流SQLDelight

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70717634

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档