1

我想在我的应用程序中使用 SQLDelight 作为缓存层和协程扩展,以从我的 SQL 查询中返回一个流,并在本地数据库中的条目发生更改时得到通知。
但是因为 SQLDelight 为存储的实体生成它自己的类并在流中发出它们,所以我无法将存储的类转换为在我的应用程序的其余部分使用的类。

您可以在下面找到我的FriendEntitySQL 类型和查询函数的摘录,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()
}
4

2 回答 2

0

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

kotlin {
  sourceSets.commonMain.dependencies {
    implementation "com.squareup.sqldelight:coroutines-extensions:1.5.3"
  }
}

现在你可以得到像

val data: Flow<List<//YourDataClass>> = 
  query.selectAll()
    .asFlow()
    .mapToList()

参考:SQLDelight with flow

于 2022-01-28T08:32:52.033 回答
0

我在他们的 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

于 2022-01-28T11:12:55.743 回答