From 3dddf9f8cf656be08825cb37afa86b29317f25a7 Mon Sep 17 00:00:00 2001 From: Cedrick Cooke Date: Wed, 2 Nov 2022 11:10:13 -0700 Subject: [PATCH] Allow for manual cursor control (#77) --- core/src/jsMain/kotlin/Cursor.kt | 16 +++++++++++ core/src/jsMain/kotlin/Transaction.kt | 39 ++++++++++++++++++++++++--- core/src/jsTest/kotlin/Samples.kt | 6 ++--- 3 files changed, 55 insertions(+), 6 deletions(-) diff --git a/core/src/jsMain/kotlin/Cursor.kt b/core/src/jsMain/kotlin/Cursor.kt index 4e0d36d..b5d288f 100644 --- a/core/src/jsMain/kotlin/Cursor.kt +++ b/core/src/jsMain/kotlin/Cursor.kt @@ -12,6 +12,22 @@ public open class Cursor internal constructor( public val primaryKey: dynamic get() = cursor.primaryKey + public fun `continue`() { + cursor.`continue`() + } + + public fun advance(count: Int) { + cursor.advance(count) + } + + public fun `continue`(key: Key) { + cursor.`continue`(key.toJs()) + } + + public fun continuePrimaryKey(key: Key, primaryKey: Key) { + cursor.continuePrimaryKey(key.toJs(), primaryKey.toJs()) + } + public enum class Direction(internal val constant: String) { Next("next"), NextUnique("nextunique"), diff --git a/core/src/jsMain/kotlin/Transaction.kt b/core/src/jsMain/kotlin/Transaction.kt index 8a5203d..494c835 100644 --- a/core/src/jsMain/kotlin/Transaction.kt +++ b/core/src/jsMain/kotlin/Transaction.kt @@ -3,7 +3,6 @@ package com.juul.indexeddb import com.juul.indexeddb.external.IDBCursor import com.juul.indexeddb.external.IDBRequest import com.juul.indexeddb.external.IDBTransaction -import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.callbackFlow @@ -46,37 +45,71 @@ public open class Transaction internal constructor( } } + @Deprecated( + "In the future, `autoContinue` will be a required parameter.", + ReplaceWith("openCursor(query, direction, cursorStart, autoContinue = true)"), + ) + public suspend fun Queryable.openCursor( + query: Key? = null, + direction: Cursor.Direction = Cursor.Direction.Next, + cursorStart: CursorStart? = null, + ): Flow = openCursor( + query, + direction, + cursorStart, + autoContinue = true, + ) + public suspend fun Queryable.openCursor( query: Key? = null, direction: Cursor.Direction = Cursor.Direction.Next, cursorStart: CursorStart? = null, + autoContinue: Boolean, ): Flow = openCursorImpl( query, direction, cursorStart, open = this::requestOpenCursor, wrap = ::CursorWithValue, + autoContinue, + ) + + @Deprecated( + "In the future, `autoContinue` will be a required parameter.", + ReplaceWith("openKeyCursor(query, direction, cursorStart, autoContinue = true)"), + ) + public suspend fun Queryable.openKeyCursor( + query: Key? = null, + direction: Cursor.Direction = Cursor.Direction.Next, + cursorStart: CursorStart? = null, + ): Flow = openKeyCursor( + query, + direction, + cursorStart, + autoContinue = true, ) public suspend fun Queryable.openKeyCursor( query: Key? = null, direction: Cursor.Direction = Cursor.Direction.Next, cursorStart: CursorStart? = null, + autoContinue: Boolean, ): Flow = openCursorImpl( query, direction, cursorStart, open = this::requestOpenKeyCursor, wrap = ::Cursor, + autoContinue, ) - @OptIn(ExperimentalCoroutinesApi::class) private suspend fun openCursorImpl( query: Key?, direction: Cursor.Direction, cursorStart: CursorStart?, open: (Key?, Cursor.Direction) -> Request, wrap: (U) -> T, + autoContinue: Boolean, ): Flow = callbackFlow { var cursorStartAction = cursorStart val request = open(query, direction).request @@ -89,7 +122,7 @@ public open class Transaction internal constructor( } else if (cursor != null) { val result = trySend(wrap(cursor)) when { - result.isSuccess -> cursor.`continue`() + result.isSuccess -> if (autoContinue) cursor.`continue`() result.isFailure -> channel.close(IllegalStateException("Send failed. Did you suspend illegally?")) result.isClosed -> channel.close() } diff --git a/core/src/jsTest/kotlin/Samples.kt b/core/src/jsTest/kotlin/Samples.kt index 974fc31..6760068 100644 --- a/core/src/jsTest/kotlin/Samples.kt +++ b/core/src/jsTest/kotlin/Samples.kt @@ -54,7 +54,7 @@ class Samples { val charlie = database.transaction("customers") { objectStore("customers") .index("name") - .openCursor() + .openCursor(autoContinue = true) .map { it.value as Customer } .first { it.age < 32 } } @@ -73,7 +73,7 @@ class Samples { val skipTwoYoungest = database.transaction("customers") { objectStore("customers") .index("age") - .openCursor(cursorStart = CursorStart.Advance(2)) + .openCursor(cursorStart = CursorStart.Advance(2), autoContinue = true) .map { it.value as Customer } .map { it.name } .toList() @@ -83,7 +83,7 @@ class Samples { val skipUntil33 = database.transaction("customers") { objectStore("customers") .index("age") - .openCursor(cursorStart = CursorStart.Continue(Key(33))) + .openCursor(cursorStart = CursorStart.Continue(Key(33)), autoContinue = true) .map { it.value as Customer } .map { it.name } .toList()