Skip to content

Commit

Permalink
Allow construction of OffsetQueryPagingSource with Long (#3409)
Browse files Browse the repository at this point in the history
  • Loading branch information
veyndan authored and AlecKazakova committed Aug 5, 2022
1 parent 5f3519e commit 2622779
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 3 deletions.
Expand Up @@ -629,14 +629,40 @@ class OffsetQueryPagingSourceTest {
assertTrue(pagingSource.jumpingSupported)
}

private fun query(limit: Int, offset: Int) = object : Query<TestItem>(
@Test
fun load_initialEmptyLoad_QueryPagingSourceLong() = runTest {
val pagingSource = QueryPagingSource(
countQueryLong(),
transacter,
EmptyCoroutineContext,
::queryLong,
)
val result = pagingSource.refresh() as LoadResult.Page

assertTrue(result.data.isEmpty())

// now add items
insertItems(ITEMS_LIST)

// invalidate pagingSource to imitate invalidation from running refreshVersionSync
pagingSource.invalidate()
assertTrue(pagingSource.invalid)

// this refresh should check pagingSource's invalid status, realize it is invalid, and
// return a LoadResult.Invalid
assertThat(pagingSource.refresh()).isInstanceOf(LoadResult.Invalid::class.java)
}

private fun query(limit: Int, offset: Int) = queryLong(limit.toLong(), offset.toLong())

private fun queryLong(limit: Long, offset: Long) = object : Query<TestItem>(
{ cursor ->
TestItem(cursor.getLong(0)!!)
},
) {
override fun <R> execute(mapper: (SqlCursor) -> R) = driver.executeQuery(1, "SELECT id FROM TestItem LIMIT ? OFFSET ?", mapper, 2) {
bindLong(0, limit.toLong())
bindLong(1, offset.toLong())
bindLong(0, limit)
bindLong(1, offset)
}

override fun addListener(listener: Listener) = driver.addListener(listener, arrayOf("TestItem"))
Expand All @@ -653,6 +679,16 @@ class OffsetQueryPagingSourceTest {
{ it.getLong(0)!!.toInt() },
)

private fun countQueryLong() = Query(
2,
arrayOf("TestItem"),
driver,
"Test.sq",
"count",
"SELECT count(*) FROM TestItem",
{ it.getLong(0)!! },
)

private fun insertItems(items: List<TestItem>) {
items.forEach {
driver.execute(0, "INSERT INTO TestItem (id) VALUES (?)", 1) {
Expand Down
Expand Up @@ -19,6 +19,7 @@ import androidx.paging.PagingConfig
import androidx.paging.PagingSource
import app.cash.sqldelight.Query
import app.cash.sqldelight.Transacter
import app.cash.sqldelight.db.SqlCursor
import kotlinx.coroutines.Dispatchers
import kotlin.coroutines.CoroutineContext
import kotlin.properties.Delegates
Expand Down Expand Up @@ -58,6 +59,7 @@ internal abstract class QueryPagingSource<Key : Any, RowType : Any> :
* Queries will be executed on [context].
*/
@Suppress("FunctionName")
@JvmName("QueryPagingSourceInt")
fun <RowType : Any> QueryPagingSource(
countQuery: Query<Int>,
transacter: Transacter,
Expand All @@ -70,6 +72,36 @@ fun <RowType : Any> QueryPagingSource(
context,
)

/**
* Variant of [QueryPagingSource] that accepts a [Long] instead of an [Int] for [countQuery]
* and [queryProvider].
*
* If the result of [countQuery] exceeds [Int.MAX_VALUE], then the count will be truncated
* to the least significant 32 bits of this [Long] value.
*
* @see toInt
*/
@Suppress("FunctionName")
@JvmName("QueryPagingSourceLong")
fun <RowType : Any> QueryPagingSource(
countQuery: Query<Long>,
transacter: Transacter,
context: CoroutineContext = Dispatchers.IO,
queryProvider: (limit: Long, offset: Long) -> Query<RowType>,
): PagingSource<Int, RowType> = OffsetQueryPagingSource(
{ limit, offset -> queryProvider(limit.toLong(), offset.toLong()) },
countQuery.toInt(),
transacter,
context,
)

private fun Query<Long>.toInt(): Query<Int> =
object : Query<Int>({ cursor -> mapper(cursor).toInt() }) {
override fun <R> execute(mapper: (SqlCursor) -> R) = this@toInt.execute(mapper)
override fun addListener(listener: Listener) = this@toInt.addListener(listener)
override fun removeListener(listener: Listener) = this@toInt.removeListener(listener)
}

/**
* Create a [PagingSource] that pages through results according to queries generated by
* [queryProvider]. Queries returned by [queryProvider] should expected to do keyset paging.
Expand Down

0 comments on commit 2622779

Please sign in to comment.