5

There are apparently Kotlin coroutines extension functions for SqlDelight, but I don't know how to implement them since I can't find documentation.

I have a normal query that looks like this:

val allItems
  get() = itemQueries.selectAll().mapToList()

Can I turn this into a suspend function?

Jacques.S
  • 3,262
  • 2
  • 21
  • 27

2 Answers2

10

There is currently (v1.2.1) no suspend function support for SqlDelight queries, however you can consume a Coroutines Flow object, which is even better. To do this you need to add the coroutines extension library in your app gradle:

dependencies {
  implementation "com.squareup.sqldelight:coroutines-extensions:1.2.1"
}

Then turn your query into this:

val allItems: Flow<List<Item>> = 
  itemQueries.selectAll()
    .asFlow()
    .mapToList()

This flow emits the query result, and emits a new result every time the database changes for that query.

You can then .collect{} the results inside a coroutine scope.

Jacques.S
  • 3,262
  • 2
  • 21
  • 27
  • 1
    Addition to this excellent answer for multiplatform projects: add dependency in commonMain and use latest lib version (which is 1.3.0 currently) `commonMain.dependencies { implementation ....}` – Myroslav Jun 26 '20 at 10:32
  • 1
    Official documentation: https://cashapp.github.io/sqldelight/multiplatform_sqlite/coroutines/ – Myroslav Jun 26 '20 at 12:53
  • Without suspend function support, doesn't it mean that all queries are blocking? It seems the other answer (https://stackoverflow.com/a/65988279/1729795) is the good one. – codependent Jan 09 '23 at 01:04
5

For single-shot queries, you don't need the coroutine extension library. Instead, just do:

suspend fun getAllItems() = withContext(Dispatchers.IO) {
    itemQueries.selectAll().mapToList()
}

The other answer is specific to when you want to react to changes in the database.

Mark
  • 7,446
  • 5
  • 55
  • 75