diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index f786d14..4ed9350 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -23,7 +23,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Start Surreal - run: docker run -d -p 8000:8000 surrealdb/surrealdb:latest start --user root --pass root -- "memory" + run: docker run -d -p 8000:8000 surrealdb/surrealdb:nightly start --user root --pass root -- "memory" - uses: actions/checkout@v3 - name: Set up JDK 11 uses: actions/setup-java@v3 diff --git a/src/commonMain/kotlin/uk/gibby/driver/Surreal.kt b/src/commonMain/kotlin/uk/gibby/driver/Surreal.kt index eef928b..b05a567 100644 --- a/src/commonMain/kotlin/uk/gibby/driver/Surreal.kt +++ b/src/commonMain/kotlin/uk/gibby/driver/Surreal.kt @@ -6,12 +6,12 @@ import io.ktor.util.collections.* import io.ktor.websocket.* import kotlinx.coroutines.* import kotlinx.coroutines.channels.Channel -import kotlinx.coroutines.flow.receiveAsFlow +import kotlinx.coroutines.flow.* import kotlinx.serialization.json.* -import uk.gibby.driver.rpc.model.RpcRequest -import uk.gibby.driver.rpc.model.RpcResponse -import uk.gibby.driver.rpc.model.RpcResponseSerializer -import kotlinx.serialization.encodeToString +import uk.gibby.driver.annotation.SurrealDbNightlyOnlyApi +import uk.gibby.driver.exception.LiveQueryKilledException +import uk.gibby.driver.model.rpc.* +import uk.gibby.driver.rpc.kill /** * SurrealDB driver @@ -25,6 +25,7 @@ class Surreal(private val host: String, private val port: Int = 8000) { private var count = 0L private var connection: DefaultClientWebSocketSession? = null private val requests = ConcurrentMap>() + private val liveQueries = ConcurrentMap>>() private val context = CoroutineScope(Dispatchers.Default) /** @@ -41,31 +42,89 @@ class Surreal(private val host: String, private val port: Int = 8000) { context.launch { it.incoming.receiveAsFlow().collect { it as Frame.Text + println(it.readText()) val response = try { surrealJson.decodeFromString(RpcResponseSerializer, it.readText()) } catch (e: Exception) { + // In theory this could be an error for any request, so we cancel all of them requests.forEach { (_, r) -> r.cancel(CancellationException("Failed to decode incoming response: ${it.readText()}\n${e.message}"))} throw e } - val request = requests[response.id] - if (request == null) requests.forEach { (_, r) -> r.cancel(CancellationException("Received a request with an unknown id: ${response.id} body: $response"))} - else when(response) { - is RpcResponse.Success -> request.send(response.result) - is RpcResponse.Error -> request.cancel(CancellationException("SurrealDB responded with an error: '${response.error}'")) + when(response) { + is RpcResponse.Success -> handleSuccess(response) + is RpcResponse.Error -> handleError(response) + is RpcResponse.Notification -> handleNotification(response) } - requests.remove(response.id) } } } } + private suspend fun handleSuccess(response: RpcResponse.Success) { + val request = requests[response.id] + if (request != null) { + request.send(response.result) + } else { + requests.forEach { + // In theory this could be an error for any request, so we cancel all of them + (_, r) -> + r.cancel(CancellationException("Received a request with an unknown id: ${response.id} body: $response")) + } + } + } + + private fun handleError(response: RpcResponse.Error) { + val request = requests[response.id] + if (request != null) { + request.cancel(CancellationException("SurrealDB responded with an error: '${response.error}'")) + } else { + requests.forEach { + // In theory this could be an error for any request, so we cancel all of them + (_, r) -> + r.cancel(CancellationException("Received a request with an unknown id: ${response.id} body: $response")) + } + } + requests.remove(response.id) + } + + private suspend fun handleNotification(response: RpcResponse.Notification) { + val action = response.result + val liveQuery = liveQueries.getOrPut(action.id) { Channel() } + context.launch { liveQuery.send(response.result) } + } + internal suspend fun sendRequest(method: String, params: JsonArray): JsonElement { val id = count++.toString() val request = RpcRequest(id, method, params) val channel = Channel(1) requests[id] = channel + println(request) (connection ?: throw Exception("SurrealDB: Websocket not connected")).sendSerialized(request) return channel.receive() } -} \ No newline at end of file + @SurrealDbNightlyOnlyApi + fun subscribeAsJson(liveQueryId: String): Flow> { + val channel = liveQueries.getOrPut(liveQueryId) { Channel() } + return channel.receiveAsFlow() + } + + @SurrealDbNightlyOnlyApi + inline fun subscribe(liveQueryId: String): Flow> { + return subscribeAsJson(liveQueryId).map { it.asType() } + } + + @SurrealDbNightlyOnlyApi + fun unsubscribe(liveQueryId: String) { + val channel = liveQueries[liveQueryId] + channel?.cancel(LiveQueryKilledException) + liveQueries.remove(liveQueryId) + } + + @SurrealDbNightlyOnlyApi + internal fun triggerKill(liveQueryId: String) { + context.launch { kill(liveQueryId) } + } + +} + diff --git a/src/commonMain/kotlin/uk/gibby/driver/annotation/SurrealDbNightlyOnlyApi.kt b/src/commonMain/kotlin/uk/gibby/driver/annotation/SurrealDbNightlyOnlyApi.kt new file mode 100644 index 0000000..0914657 --- /dev/null +++ b/src/commonMain/kotlin/uk/gibby/driver/annotation/SurrealDbNightlyOnlyApi.kt @@ -0,0 +1,6 @@ +package uk.gibby.driver.annotation + +@RequiresOptIn(message = "This function is only available while using nightly builds of SurrealDB. See https://surrealdb.com/docs/installation/nightly.") +@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS) +@Retention(AnnotationRetention.BINARY) +annotation class SurrealDbNightlyOnlyApi diff --git a/src/commonMain/kotlin/uk/gibby/driver/api/LiveQueryFlow.kt b/src/commonMain/kotlin/uk/gibby/driver/api/LiveQueryFlow.kt new file mode 100644 index 0000000..7553832 --- /dev/null +++ b/src/commonMain/kotlin/uk/gibby/driver/api/LiveQueryFlow.kt @@ -0,0 +1,56 @@ +package uk.gibby.driver.api + +import io.ktor.utils.io.core.* +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.map +import uk.gibby.driver.Surreal +import uk.gibby.driver.annotation.SurrealDbNightlyOnlyApi +import uk.gibby.driver.model.rpc.LiveQueryAction + +/** + * Live query flow + * + * This class is a wrapper around a flow of [LiveQueryAction]s making it [Closeable]. + * + * @param T The type of the records + * @property flow The flow of [LiveQueryAction]s + * @property id The id of the live query + * @property connection The connection to the database + * @constructor Creates a new live query flow + */ +@SurrealDbNightlyOnlyApi +class LiveQueryFlow( + private val flow: Flow>, + val id: String, + private val connection: Surreal +): Flow> by flow, Closeable { + + /** + * Close + * + * This method will unsubscribe from the live query and trigger the kill RPC request. + */ + + override fun close() { + connection.unsubscribe(id) + connection.triggerKill(id) + } + + /** + * Map + * + * Used to map the records of the live query flow form [T] to [R]. + * + * @param R The type of the records in the new flow + * @param transform The transform function from [T] to [R] + * @receiver The live query flow to map + * @return A new live query flow of [R]s + */ + fun map(transform: (LiveQueryAction) -> LiveQueryAction): LiveQueryFlow { + return LiveQueryFlow( + flow = flow.map { transform(it) }, + id = id, + connection = connection + ) + } +} \ No newline at end of file diff --git a/src/commonMain/kotlin/uk/gibby/driver/api/Observe.kt b/src/commonMain/kotlin/uk/gibby/driver/api/Observe.kt new file mode 100644 index 0000000..9ab9dd7 --- /dev/null +++ b/src/commonMain/kotlin/uk/gibby/driver/api/Observe.kt @@ -0,0 +1,43 @@ +package uk.gibby.driver.api + +import kotlinx.serialization.json.JsonElement +import uk.gibby.driver.Surreal +import uk.gibby.driver.annotation.SurrealDbNightlyOnlyApi +import uk.gibby.driver.rpc.live +import uk.gibby.driver.model.rpc.asType +import kotlin.jvm.JvmName + +/** + * Observe live query as json + * + * Creates a [LiveQueryFlow] for the given table. + * + * @param table Name of the table to 'LIVE SELECT' from + * @return A [LiveQueryFlow] of [JsonElement]s + */ +@JvmName("observeJson") +@SurrealDbNightlyOnlyApi +suspend fun Surreal.observeLiveQueryAsJson(table: String): LiveQueryFlow { + val liveQueryId = live(table) + return LiveQueryFlow( + flow = subscribeAsJson(liveQueryId), + id = liveQueryId, + connection = this + ) +} + + +/** + * Observe live query + * + * Creates a [LiveQueryFlow] for the given table. + * + * @param T The type of the records + * @param table Name of the table to 'LIVE SELECT' from + * @return A [LiveQueryFlow] of [T]s + */ +@SurrealDbNightlyOnlyApi +suspend inline fun Surreal.observeLiveQuery(table: String): LiveQueryFlow { + val jsonFlow = observeLiveQueryAsJson(table) + return jsonFlow.map { it.asType() } +} diff --git a/src/commonMain/kotlin/uk/gibby/driver/exception/LiveQueryKilledException.kt b/src/commonMain/kotlin/uk/gibby/driver/exception/LiveQueryKilledException.kt new file mode 100644 index 0000000..ee831f2 --- /dev/null +++ b/src/commonMain/kotlin/uk/gibby/driver/exception/LiveQueryKilledException.kt @@ -0,0 +1,5 @@ +package uk.gibby.driver.exception + +import kotlinx.coroutines.CancellationException + +object LiveQueryKilledException: CancellationException("Live query has been killed") \ No newline at end of file diff --git a/src/commonMain/kotlin/uk/gibby/driver/rpc/exception/QueryException.kt b/src/commonMain/kotlin/uk/gibby/driver/exception/QueryException.kt similarity index 73% rename from src/commonMain/kotlin/uk/gibby/driver/rpc/exception/QueryException.kt rename to src/commonMain/kotlin/uk/gibby/driver/exception/QueryException.kt index 2b200bb..934be77 100644 --- a/src/commonMain/kotlin/uk/gibby/driver/rpc/exception/QueryException.kt +++ b/src/commonMain/kotlin/uk/gibby/driver/exception/QueryException.kt @@ -1,3 +1,3 @@ -package uk.gibby.driver.rpc.exception +package uk.gibby.driver.exception data class QueryException(val detail: String): Exception("SurrealDB responded with an error: '$detail'") \ No newline at end of file diff --git a/src/commonMain/kotlin/uk/gibby/driver/rpc/model/Patch.kt b/src/commonMain/kotlin/uk/gibby/driver/model/JsonPatch.kt similarity index 98% rename from src/commonMain/kotlin/uk/gibby/driver/rpc/model/Patch.kt rename to src/commonMain/kotlin/uk/gibby/driver/model/JsonPatch.kt index e9d91f4..fa68287 100644 --- a/src/commonMain/kotlin/uk/gibby/driver/rpc/model/Patch.kt +++ b/src/commonMain/kotlin/uk/gibby/driver/model/JsonPatch.kt @@ -1,4 +1,4 @@ -package uk.gibby.driver.rpc.model +package uk.gibby.driver.model import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable diff --git a/src/commonMain/kotlin/uk/gibby/driver/rpc/model/RootAuth.kt b/src/commonMain/kotlin/uk/gibby/driver/model/RootAuth.kt similarity index 85% rename from src/commonMain/kotlin/uk/gibby/driver/rpc/model/RootAuth.kt rename to src/commonMain/kotlin/uk/gibby/driver/model/RootAuth.kt index 3e8899c..0a77e54 100644 --- a/src/commonMain/kotlin/uk/gibby/driver/rpc/model/RootAuth.kt +++ b/src/commonMain/kotlin/uk/gibby/driver/model/RootAuth.kt @@ -1,4 +1,4 @@ -package uk.gibby.driver.rpc.model +package uk.gibby.driver.model import kotlinx.serialization.Serializable import kotlinx.serialization.json.JsonElement diff --git a/src/commonMain/kotlin/uk/gibby/driver/rpc/model/Thing.kt b/src/commonMain/kotlin/uk/gibby/driver/model/Thing.kt similarity index 98% rename from src/commonMain/kotlin/uk/gibby/driver/rpc/model/Thing.kt rename to src/commonMain/kotlin/uk/gibby/driver/model/Thing.kt index 9d8e9a5..a15369f 100644 --- a/src/commonMain/kotlin/uk/gibby/driver/rpc/model/Thing.kt +++ b/src/commonMain/kotlin/uk/gibby/driver/model/Thing.kt @@ -1,4 +1,4 @@ -package uk.gibby.driver.rpc.model +package uk.gibby.driver.model import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.KSerializer diff --git a/src/commonMain/kotlin/uk/gibby/driver/rpc/model/Bind.kt b/src/commonMain/kotlin/uk/gibby/driver/model/query/Bind.kt similarity index 95% rename from src/commonMain/kotlin/uk/gibby/driver/rpc/model/Bind.kt rename to src/commonMain/kotlin/uk/gibby/driver/model/query/Bind.kt index c5d6ab8..0a5a442 100644 --- a/src/commonMain/kotlin/uk/gibby/driver/rpc/model/Bind.kt +++ b/src/commonMain/kotlin/uk/gibby/driver/model/query/Bind.kt @@ -1,4 +1,4 @@ -package uk.gibby.driver.rpc.model +package uk.gibby.driver.model.query import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.encodeToJsonElement diff --git a/src/commonMain/kotlin/uk/gibby/driver/rpc/model/QueryResponse.kt b/src/commonMain/kotlin/uk/gibby/driver/model/query/QueryResponse.kt similarity index 90% rename from src/commonMain/kotlin/uk/gibby/driver/rpc/model/QueryResponse.kt rename to src/commonMain/kotlin/uk/gibby/driver/model/query/QueryResponse.kt index cf38fe5..e2e23be 100644 --- a/src/commonMain/kotlin/uk/gibby/driver/rpc/model/QueryResponse.kt +++ b/src/commonMain/kotlin/uk/gibby/driver/model/query/QueryResponse.kt @@ -1,10 +1,10 @@ -package uk.gibby.driver.rpc.model +package uk.gibby.driver.model.query import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.decodeFromJsonElement -import uk.gibby.driver.rpc.exception.QueryException +import uk.gibby.driver.exception.QueryException import uk.gibby.driver.surrealJson @Serializable diff --git a/src/commonMain/kotlin/uk/gibby/driver/model/rpc/LiveQueryAction.kt b/src/commonMain/kotlin/uk/gibby/driver/model/rpc/LiveQueryAction.kt new file mode 100644 index 0000000..4ac6187 --- /dev/null +++ b/src/commonMain/kotlin/uk/gibby/driver/model/rpc/LiveQueryAction.kt @@ -0,0 +1,42 @@ +package uk.gibby.driver.model.rpc + +import kotlinx.serialization.Serializable +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.decodeFromJsonElement +import uk.gibby.driver.model.rpc.LiveQueryAction.* +import uk.gibby.driver.surrealJson + + +/** + * LiveQueryAction + * + * A live query action. Can be a [Create], [Update] or [Delete]. + * Holds the id of the record and the result if relevant. + * + * @param T The type of the result + */ +@Serializable(with = LiveQueryActionSerializer::class) +sealed class LiveQueryAction { + abstract val id: String + data class Create(override val id: String, val result: T): LiveQueryAction() + data class Update(override val id: String, val result: T): LiveQueryAction() + data class Delete(override val id: String, val deletedId: String): LiveQueryAction() +} + + +/** + * As type + * + * Maps the live query to type [T] using [decodeFromJsonElement] + * + * @param T The new type + * @return The new live query action + */ +inline fun LiveQueryAction.asType(): LiveQueryAction { + return when(this) { + is Delete -> this + is Create -> Create(id, surrealJson.decodeFromJsonElement(result)) + is Update -> Update(id, surrealJson.decodeFromJsonElement(result)) + } +} + diff --git a/src/commonMain/kotlin/uk/gibby/driver/model/rpc/LiveQueryActionSerializer.kt b/src/commonMain/kotlin/uk/gibby/driver/model/rpc/LiveQueryActionSerializer.kt new file mode 100644 index 0000000..0d54858 --- /dev/null +++ b/src/commonMain/kotlin/uk/gibby/driver/model/rpc/LiveQueryActionSerializer.kt @@ -0,0 +1,49 @@ +package uk.gibby.driver.model.rpc + +import kotlinx.serialization.KSerializer +import kotlinx.serialization.SerializationException +import kotlinx.serialization.builtins.serializer +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.descriptors.buildClassSerialDescriptor +import kotlinx.serialization.encoding.CompositeDecoder +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder +import uk.gibby.driver.model.Thing +import uk.gibby.driver.model.ThingSerializer + +class LiveQueryActionSerializer(private val resultSerializer: KSerializer): KSerializer> { + override val descriptor: SerialDescriptor = buildClassSerialDescriptor("LiveQueryAction") { + element("action", String.serializer().descriptor) + element("id", String.serializer().descriptor) + element("result", resultSerializer.descriptor) + } + + override fun deserialize(decoder: Decoder): LiveQueryAction { + val input = decoder.beginStructure(descriptor) + var action: String? = null + var id: String? = null + var result: Thing? = null + loop@ while (true) { + when (val i = input.decodeElementIndex(descriptor)) { + CompositeDecoder.DECODE_DONE -> break@loop + 0 -> action = input.decodeStringElement(descriptor, i) + 1 -> id = input.decodeStringElement(descriptor, i) + 2 -> result = input.decodeSerializableElement(descriptor, i, ThingSerializer(resultSerializer)) + else -> throw SerializationException("Unknown index $i") + } + } + input.endStructure(descriptor) + if (action == null || id == null || result == null) throw SerializationException("Missing fields") + return when(action) { + "CREATE" -> LiveQueryAction.Create(id, (result as Thing.Record).result) + "UPDATE" -> LiveQueryAction.Update(id, (result as Thing.Record).result) + "DELETE" -> LiveQueryAction.Delete(id, (result as Thing.Reference).id) + else -> throw SerializationException("Unknown action $action") + } + } + + override fun serialize(encoder: Encoder, value: LiveQueryAction) { + TODO("Not yet implemented") + } + +} \ No newline at end of file diff --git a/src/commonMain/kotlin/uk/gibby/driver/rpc/model/RpcRequest.kt b/src/commonMain/kotlin/uk/gibby/driver/model/rpc/RpcRequest.kt similarity index 84% rename from src/commonMain/kotlin/uk/gibby/driver/rpc/model/RpcRequest.kt rename to src/commonMain/kotlin/uk/gibby/driver/model/rpc/RpcRequest.kt index fbe933f..5e55258 100644 --- a/src/commonMain/kotlin/uk/gibby/driver/rpc/model/RpcRequest.kt +++ b/src/commonMain/kotlin/uk/gibby/driver/model/rpc/RpcRequest.kt @@ -1,4 +1,4 @@ -package uk.gibby.driver.rpc.model +package uk.gibby.driver.model.rpc import kotlinx.serialization.Serializable import kotlinx.serialization.json.JsonArray diff --git a/src/commonMain/kotlin/uk/gibby/driver/rpc/model/RpcResponse.kt b/src/commonMain/kotlin/uk/gibby/driver/model/rpc/RpcResponse.kt similarity index 68% rename from src/commonMain/kotlin/uk/gibby/driver/rpc/model/RpcResponse.kt rename to src/commonMain/kotlin/uk/gibby/driver/model/rpc/RpcResponse.kt index 2b8deae..c74c96f 100644 --- a/src/commonMain/kotlin/uk/gibby/driver/rpc/model/RpcResponse.kt +++ b/src/commonMain/kotlin/uk/gibby/driver/model/rpc/RpcResponse.kt @@ -1,4 +1,4 @@ -package uk.gibby.driver.rpc.model +package uk.gibby.driver.model.rpc import kotlinx.serialization.Serializable import kotlinx.serialization.json.JsonElement @@ -13,5 +13,10 @@ sealed class RpcResponse { @Serializable data class Error(override val id: String, val error: JsonElement): RpcResponse() + + @Serializable + data class Notification(val result: LiveQueryAction): RpcResponse() { + override val id: String? = null + } } diff --git a/src/commonMain/kotlin/uk/gibby/driver/rpc/model/RpcResponseSerializer.kt b/src/commonMain/kotlin/uk/gibby/driver/model/rpc/RpcResponseSerializer.kt similarity index 83% rename from src/commonMain/kotlin/uk/gibby/driver/rpc/model/RpcResponseSerializer.kt rename to src/commonMain/kotlin/uk/gibby/driver/model/rpc/RpcResponseSerializer.kt index 3b7872b..c24de29 100644 --- a/src/commonMain/kotlin/uk/gibby/driver/rpc/model/RpcResponseSerializer.kt +++ b/src/commonMain/kotlin/uk/gibby/driver/model/rpc/RpcResponseSerializer.kt @@ -1,4 +1,4 @@ -package uk.gibby.driver.rpc.model +package uk.gibby.driver.model.rpc import uk.gibby.driver.surrealJson import kotlinx.serialization.KSerializer @@ -11,6 +11,7 @@ import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder import kotlinx.serialization.encoding.decodeStructure import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.decodeFromJsonElement import kotlinx.serialization.json.encodeToJsonElement object RpcResponseSerializer: KSerializer { @@ -35,7 +36,12 @@ object RpcResponseSerializer: KSerializer { } return if(error != null) { RpcResponse.Error(id!!, surrealJson.encodeToJsonElement(error)) - } else RpcResponse.Success(id!!, result ?: surrealJson.encodeToJsonElement(String.serializer().nullable, null)) + } else if(id != null) { + RpcResponse.Success(id!!, result ?: surrealJson.encodeToJsonElement(String.serializer().nullable, null)) + } + else { + RpcResponse.Notification(surrealJson.decodeFromJsonElement(result!!)) + } } override fun serialize(encoder: Encoder, value: RpcResponse) { diff --git a/src/commonMain/kotlin/uk/gibby/driver/rpc/functions/Authenticate.kt b/src/commonMain/kotlin/uk/gibby/driver/rpc/Authenticate.kt similarity index 91% rename from src/commonMain/kotlin/uk/gibby/driver/rpc/functions/Authenticate.kt rename to src/commonMain/kotlin/uk/gibby/driver/rpc/Authenticate.kt index 89bf017..a73ca80 100644 --- a/src/commonMain/kotlin/uk/gibby/driver/rpc/functions/Authenticate.kt +++ b/src/commonMain/kotlin/uk/gibby/driver/rpc/Authenticate.kt @@ -1,4 +1,4 @@ -package uk.gibby.driver.rpc.functions +package uk.gibby.driver.rpc import kotlinx.serialization.json.add import kotlinx.serialization.json.buildJsonArray diff --git a/src/commonMain/kotlin/uk/gibby/driver/rpc/functions/Create.kt b/src/commonMain/kotlin/uk/gibby/driver/rpc/Create.kt similarity index 98% rename from src/commonMain/kotlin/uk/gibby/driver/rpc/functions/Create.kt rename to src/commonMain/kotlin/uk/gibby/driver/rpc/Create.kt index 894fcff..f432985 100644 --- a/src/commonMain/kotlin/uk/gibby/driver/rpc/functions/Create.kt +++ b/src/commonMain/kotlin/uk/gibby/driver/rpc/Create.kt @@ -1,4 +1,4 @@ -package uk.gibby.driver.rpc.functions +package uk.gibby.driver.rpc import kotlinx.serialization.json.* import uk.gibby.driver.Surreal diff --git a/src/commonMain/kotlin/uk/gibby/driver/rpc/functions/Delete.kt b/src/commonMain/kotlin/uk/gibby/driver/rpc/Delete.kt similarity index 91% rename from src/commonMain/kotlin/uk/gibby/driver/rpc/functions/Delete.kt rename to src/commonMain/kotlin/uk/gibby/driver/rpc/Delete.kt index 35f88a8..3d65ad9 100644 --- a/src/commonMain/kotlin/uk/gibby/driver/rpc/functions/Delete.kt +++ b/src/commonMain/kotlin/uk/gibby/driver/rpc/Delete.kt @@ -1,9 +1,9 @@ -package uk.gibby.driver.rpc.functions +package uk.gibby.driver.rpc import kotlinx.serialization.json.add import kotlinx.serialization.json.buildJsonArray import uk.gibby.driver.Surreal -import uk.gibby.driver.rpc.model.Thing +import uk.gibby.driver.model.Thing /** * Delete diff --git a/src/commonMain/kotlin/uk/gibby/driver/rpc/functions/Info.kt b/src/commonMain/kotlin/uk/gibby/driver/rpc/Info.kt similarity index 95% rename from src/commonMain/kotlin/uk/gibby/driver/rpc/functions/Info.kt rename to src/commonMain/kotlin/uk/gibby/driver/rpc/Info.kt index b953a3e..289d3bf 100644 --- a/src/commonMain/kotlin/uk/gibby/driver/rpc/functions/Info.kt +++ b/src/commonMain/kotlin/uk/gibby/driver/rpc/Info.kt @@ -1,4 +1,4 @@ -package uk.gibby.driver.rpc.functions +package uk.gibby.driver.rpc import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.buildJsonArray diff --git a/src/commonMain/kotlin/uk/gibby/driver/rpc/functions/Invalidate.kt b/src/commonMain/kotlin/uk/gibby/driver/rpc/Invalidate.kt similarity index 87% rename from src/commonMain/kotlin/uk/gibby/driver/rpc/functions/Invalidate.kt rename to src/commonMain/kotlin/uk/gibby/driver/rpc/Invalidate.kt index 6ef1e1c..1556576 100644 --- a/src/commonMain/kotlin/uk/gibby/driver/rpc/functions/Invalidate.kt +++ b/src/commonMain/kotlin/uk/gibby/driver/rpc/Invalidate.kt @@ -1,4 +1,4 @@ -package uk.gibby.driver.rpc.functions +package uk.gibby.driver.rpc import kotlinx.serialization.json.JsonArray import uk.gibby.driver.Surreal diff --git a/src/commonMain/kotlin/uk/gibby/driver/rpc/Kill.kt b/src/commonMain/kotlin/uk/gibby/driver/rpc/Kill.kt new file mode 100644 index 0000000..49e0cf5 --- /dev/null +++ b/src/commonMain/kotlin/uk/gibby/driver/rpc/Kill.kt @@ -0,0 +1,19 @@ +package uk.gibby.driver.rpc + +import kotlinx.serialization.json.add +import kotlinx.serialization.json.buildJsonArray +import uk.gibby.driver.Surreal +import uk.gibby.driver.annotation.SurrealDbNightlyOnlyApi + +/** + * Kill + * + * This method will kill a live query + * + * @param liveQueryId The id of the live query to kill + */ +@SurrealDbNightlyOnlyApi +suspend fun Surreal.kill(liveQueryId: String) { + sendRequest("kill", buildJsonArray { add(liveQueryId) }) +} + diff --git a/src/commonMain/kotlin/uk/gibby/driver/rpc/functions/Let.kt b/src/commonMain/kotlin/uk/gibby/driver/rpc/Let.kt similarity index 96% rename from src/commonMain/kotlin/uk/gibby/driver/rpc/functions/Let.kt rename to src/commonMain/kotlin/uk/gibby/driver/rpc/Let.kt index d8e8dc3..a647bd5 100644 --- a/src/commonMain/kotlin/uk/gibby/driver/rpc/functions/Let.kt +++ b/src/commonMain/kotlin/uk/gibby/driver/rpc/Let.kt @@ -1,4 +1,4 @@ -package uk.gibby.driver.rpc.functions +package uk.gibby.driver.rpc import kotlinx.serialization.json.JsonElement import kotlinx.serialization.json.add diff --git a/src/commonMain/kotlin/uk/gibby/driver/rpc/Live.kt b/src/commonMain/kotlin/uk/gibby/driver/rpc/Live.kt new file mode 100644 index 0000000..6f51ac2 --- /dev/null +++ b/src/commonMain/kotlin/uk/gibby/driver/rpc/Live.kt @@ -0,0 +1,23 @@ +package uk.gibby.driver.rpc + +import kotlinx.serialization.json.add +import kotlinx.serialization.json.buildJsonArray +import kotlinx.serialization.json.decodeFromJsonElement +import uk.gibby.driver.Surreal +import uk.gibby.driver.annotation.SurrealDbNightlyOnlyApi +import uk.gibby.driver.surrealJson + + +/** + * Live + * + * This method will create a live query + * + * @param table Name of the table to 'LIVE SELECT' from + * @return The id of the live query + */ +@SurrealDbNightlyOnlyApi +suspend fun Surreal.live(table: String): String { + val response = sendRequest("live", buildJsonArray { add(table) }) + return surrealJson.decodeFromJsonElement(response) +} \ No newline at end of file diff --git a/src/commonMain/kotlin/uk/gibby/driver/rpc/functions/Query.kt b/src/commonMain/kotlin/uk/gibby/driver/rpc/Query.kt similarity index 89% rename from src/commonMain/kotlin/uk/gibby/driver/rpc/functions/Query.kt rename to src/commonMain/kotlin/uk/gibby/driver/rpc/Query.kt index 446112e..7f0697d 100644 --- a/src/commonMain/kotlin/uk/gibby/driver/rpc/functions/Query.kt +++ b/src/commonMain/kotlin/uk/gibby/driver/rpc/Query.kt @@ -1,9 +1,9 @@ -package uk.gibby.driver.rpc.functions +package uk.gibby.driver.rpc import kotlinx.serialization.json.* import uk.gibby.driver.Surreal -import uk.gibby.driver.rpc.model.Bind -import uk.gibby.driver.rpc.model.QueryResponse +import uk.gibby.driver.model.query.Bind +import uk.gibby.driver.model.query.QueryResponse import uk.gibby.driver.surrealJson /** diff --git a/src/commonMain/kotlin/uk/gibby/driver/rpc/functions/Select.kt b/src/commonMain/kotlin/uk/gibby/driver/rpc/Select.kt similarity index 96% rename from src/commonMain/kotlin/uk/gibby/driver/rpc/functions/Select.kt rename to src/commonMain/kotlin/uk/gibby/driver/rpc/Select.kt index d44a0b3..7330047 100644 --- a/src/commonMain/kotlin/uk/gibby/driver/rpc/functions/Select.kt +++ b/src/commonMain/kotlin/uk/gibby/driver/rpc/Select.kt @@ -1,8 +1,8 @@ -package uk.gibby.driver.rpc.functions +package uk.gibby.driver.rpc import kotlinx.serialization.json.* import uk.gibby.driver.Surreal -import uk.gibby.driver.rpc.model.Thing +import uk.gibby.driver.model.Thing import uk.gibby.driver.surrealJson /** diff --git a/src/commonMain/kotlin/uk/gibby/driver/rpc/functions/SignIn.kt b/src/commonMain/kotlin/uk/gibby/driver/rpc/SignIn.kt similarity index 93% rename from src/commonMain/kotlin/uk/gibby/driver/rpc/functions/SignIn.kt rename to src/commonMain/kotlin/uk/gibby/driver/rpc/SignIn.kt index fac8b24..2fc9a48 100644 --- a/src/commonMain/kotlin/uk/gibby/driver/rpc/functions/SignIn.kt +++ b/src/commonMain/kotlin/uk/gibby/driver/rpc/SignIn.kt @@ -1,9 +1,9 @@ -package uk.gibby.driver.rpc.functions +package uk.gibby.driver.rpc import kotlinx.serialization.json.* import uk.gibby.driver.Surreal -import uk.gibby.driver.rpc.model.Bind -import uk.gibby.driver.rpc.model.RootAuth +import uk.gibby.driver.model.query.Bind +import uk.gibby.driver.model.RootAuth import uk.gibby.driver.surrealJson diff --git a/src/commonMain/kotlin/uk/gibby/driver/rpc/functions/Signup.kt b/src/commonMain/kotlin/uk/gibby/driver/rpc/Signup.kt similarity index 94% rename from src/commonMain/kotlin/uk/gibby/driver/rpc/functions/Signup.kt rename to src/commonMain/kotlin/uk/gibby/driver/rpc/Signup.kt index 9c811d8..860d2ef 100644 --- a/src/commonMain/kotlin/uk/gibby/driver/rpc/functions/Signup.kt +++ b/src/commonMain/kotlin/uk/gibby/driver/rpc/Signup.kt @@ -1,8 +1,8 @@ -package uk.gibby.driver.rpc.functions +package uk.gibby.driver.rpc import kotlinx.serialization.json.* import uk.gibby.driver.Surreal -import uk.gibby.driver.rpc.model.Bind +import uk.gibby.driver.model.query.Bind import uk.gibby.driver.surrealJson diff --git a/src/commonMain/kotlin/uk/gibby/driver/rpc/functions/Unset.kt b/src/commonMain/kotlin/uk/gibby/driver/rpc/Unset.kt similarity index 90% rename from src/commonMain/kotlin/uk/gibby/driver/rpc/functions/Unset.kt rename to src/commonMain/kotlin/uk/gibby/driver/rpc/Unset.kt index f3f66a6..9ef9acc 100644 --- a/src/commonMain/kotlin/uk/gibby/driver/rpc/functions/Unset.kt +++ b/src/commonMain/kotlin/uk/gibby/driver/rpc/Unset.kt @@ -1,4 +1,4 @@ -package uk.gibby.driver.rpc.functions +package uk.gibby.driver.rpc import kotlinx.serialization.json.add import kotlinx.serialization.json.buildJsonArray diff --git a/src/commonMain/kotlin/uk/gibby/driver/rpc/functions/Update.kt b/src/commonMain/kotlin/uk/gibby/driver/rpc/Update.kt similarity index 97% rename from src/commonMain/kotlin/uk/gibby/driver/rpc/functions/Update.kt rename to src/commonMain/kotlin/uk/gibby/driver/rpc/Update.kt index 1d42cba..4fafe9b 100644 --- a/src/commonMain/kotlin/uk/gibby/driver/rpc/functions/Update.kt +++ b/src/commonMain/kotlin/uk/gibby/driver/rpc/Update.kt @@ -1,12 +1,12 @@ -package uk.gibby.driver.rpc.functions +package uk.gibby.driver.rpc import kotlinx.serialization.json.* import uk.gibby.driver.Surreal -import uk.gibby.driver.rpc.model.Bind -import uk.gibby.driver.rpc.model.JsonPatch -import uk.gibby.driver.rpc.model.Thing +import uk.gibby.driver.model.query.Bind +import uk.gibby.driver.model.JsonPatch import uk.gibby.driver.surrealJson import kotlin.jvm.JvmName +import uk.gibby.driver.model.Thing /** @@ -150,6 +150,7 @@ fun Surreal.update(table: String) = UpdateBuilder(table, this) * * This class is used to build update requests affecting a single record in a table. * + * @property table The table to update * @property id The id of the record to update * @property db The database connection to use * @constructor Creates an update builder for the given table and id diff --git a/src/commonMain/kotlin/uk/gibby/driver/rpc/functions/Use.kt b/src/commonMain/kotlin/uk/gibby/driver/rpc/Use.kt similarity index 91% rename from src/commonMain/kotlin/uk/gibby/driver/rpc/functions/Use.kt rename to src/commonMain/kotlin/uk/gibby/driver/rpc/Use.kt index 1782248..722adf5 100644 --- a/src/commonMain/kotlin/uk/gibby/driver/rpc/functions/Use.kt +++ b/src/commonMain/kotlin/uk/gibby/driver/rpc/Use.kt @@ -1,4 +1,4 @@ -package uk.gibby.driver.rpc.functions +package uk.gibby.driver.rpc import kotlinx.serialization.json.add import kotlinx.serialization.json.buildJsonArray diff --git a/src/commonTest/kotlin/AuthenticateTest.kt b/src/commonTest/kotlin/AuthenticateTest.kt index 84af7b5..3e4028c 100644 --- a/src/commonTest/kotlin/AuthenticateTest.kt +++ b/src/commonTest/kotlin/AuthenticateTest.kt @@ -1,9 +1,9 @@ import kotlinx.coroutines.test.runTest import uk.gibby.driver.Surreal -import uk.gibby.driver.rpc.functions.authenticate -import uk.gibby.driver.rpc.functions.info -import uk.gibby.driver.rpc.functions.signup -import uk.gibby.driver.rpc.model.bind +import uk.gibby.driver.rpc.authenticate +import uk.gibby.driver.rpc.info +import uk.gibby.driver.rpc.signup +import uk.gibby.driver.model.query.bind import utils.cleanDatabase import kotlin.test.Test import kotlin.test.assertEquals diff --git a/src/commonTest/kotlin/ConnectionTest.kt b/src/commonTest/kotlin/ConnectionTest.kt index 8f2b8d5..1e6f944 100644 --- a/src/commonTest/kotlin/ConnectionTest.kt +++ b/src/commonTest/kotlin/ConnectionTest.kt @@ -1,7 +1,8 @@ import kotlinx.coroutines.test.runTest import uk.gibby.driver.Surreal -import uk.gibby.driver.rpc.functions.* -import uk.gibby.driver.rpc.model.bind +import uk.gibby.driver.model.query.bind +import uk.gibby.driver.rpc.* +import kotlin.test.Ignore import kotlin.test.Test class ConnectionTest { diff --git a/src/commonTest/kotlin/CreateTest.kt b/src/commonTest/kotlin/CreateTest.kt index 80a6562..96b356d 100644 --- a/src/commonTest/kotlin/CreateTest.kt +++ b/src/commonTest/kotlin/CreateTest.kt @@ -1,21 +1,37 @@ import kotlinx.coroutines.test.runTest import kotlinx.serialization.Serializable import uk.gibby.driver.Surreal -import uk.gibby.driver.rpc.functions.* -import uk.gibby.driver.rpc.model.Thing -import uk.gibby.driver.rpc.model.data -import uk.gibby.driver.rpc.model.unknown +import uk.gibby.driver.model.Thing +import uk.gibby.driver.model.query.data +import uk.gibby.driver.model.unknown +import uk.gibby.driver.rpc.create +import uk.gibby.driver.rpc.query +import uk.gibby.driver.rpc.signin +import uk.gibby.driver.rpc.use import utils.cleanDatabase import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertTrue @Serializable -data class TestClass( +class TestClass( val myText: String, val myNumber: Int, val id: Thing = unknown(), -) +) { + override fun equals(other: Any?): Boolean { + if (other !is TestClass) return false + val idCheck = (id.id == other.id.id || id.id == "unknown" || other.id.id == "unknown") + return myText == other.myText && myNumber == other.myNumber && idCheck + } + + override fun hashCode(): Int { + var result = myText.hashCode() + result = 31 * result + myNumber + result = 31 * result + id.hashCode() + return result + } +} class CreateTest { diff --git a/src/commonTest/kotlin/DeleteTest.kt b/src/commonTest/kotlin/DeleteTest.kt index 841845f..9119122 100644 --- a/src/commonTest/kotlin/DeleteTest.kt +++ b/src/commonTest/kotlin/DeleteTest.kt @@ -1,6 +1,6 @@ import kotlinx.coroutines.test.runTest import uk.gibby.driver.Surreal -import uk.gibby.driver.rpc.functions.* +import uk.gibby.driver.rpc.* import utils.cleanDatabase import kotlin.test.Test import kotlin.test.assertEquals diff --git a/src/commonTest/kotlin/FetchTest.kt b/src/commonTest/kotlin/FetchTest.kt index 1edf555..63c043a 100644 --- a/src/commonTest/kotlin/FetchTest.kt +++ b/src/commonTest/kotlin/FetchTest.kt @@ -1,9 +1,12 @@ import kotlinx.coroutines.test.runTest import kotlinx.serialization.Serializable import uk.gibby.driver.Surreal -import uk.gibby.driver.rpc.functions.* -import uk.gibby.driver.rpc.model.Thing -import uk.gibby.driver.rpc.model.data +import uk.gibby.driver.model.Thing +import uk.gibby.driver.model.query.data +import uk.gibby.driver.rpc.create +import uk.gibby.driver.rpc.query +import uk.gibby.driver.rpc.signin +import uk.gibby.driver.rpc.use import utils.cleanDatabase import kotlin.test.Test import kotlin.test.assertEquals diff --git a/src/commonTest/kotlin/InfoTest.kt b/src/commonTest/kotlin/InfoTest.kt index 1fb393a..8e93eb0 100644 --- a/src/commonTest/kotlin/InfoTest.kt +++ b/src/commonTest/kotlin/InfoTest.kt @@ -1,11 +1,11 @@ import kotlinx.coroutines.test.runTest import kotlinx.serialization.Serializable import uk.gibby.driver.Surreal -import uk.gibby.driver.rpc.functions.info -import uk.gibby.driver.rpc.functions.signup -import uk.gibby.driver.rpc.model.Thing -import uk.gibby.driver.rpc.model.bind -import uk.gibby.driver.rpc.model.unknown +import uk.gibby.driver.rpc.info +import uk.gibby.driver.rpc.signup +import uk.gibby.driver.model.Thing +import uk.gibby.driver.model.query.bind +import uk.gibby.driver.model.unknown import utils.cleanDatabase import kotlin.test.Test import kotlin.test.assertEquals diff --git a/src/commonTest/kotlin/KillTest.kt b/src/commonTest/kotlin/KillTest.kt new file mode 100644 index 0000000..b299f57 --- /dev/null +++ b/src/commonTest/kotlin/KillTest.kt @@ -0,0 +1,23 @@ +import kotlinx.coroutines.test.runTest +import uk.gibby.driver.Surreal +import uk.gibby.driver.annotation.SurrealDbNightlyOnlyApi +import uk.gibby.driver.rpc.kill +import uk.gibby.driver.rpc.live +import uk.gibby.driver.rpc.signin +import uk.gibby.driver.rpc.use +import utils.cleanDatabase +import kotlin.test.Test + +@OptIn(SurrealDbNightlyOnlyApi::class) +class KillTest { + @Test + fun testKill() = runTest { + cleanDatabase() + val connection = Surreal("localhost", 8000) + connection.connect() + connection.signin("root", "root") + connection.use("test", "test") + val liveQueryId = connection.live("test") + connection.kill(liveQueryId) + } +} \ No newline at end of file diff --git a/src/commonTest/kotlin/LetTest.kt b/src/commonTest/kotlin/LetTest.kt index 290ffc5..571ba3a 100644 --- a/src/commonTest/kotlin/LetTest.kt +++ b/src/commonTest/kotlin/LetTest.kt @@ -1,10 +1,10 @@ import kotlinx.coroutines.test.runTest import uk.gibby.driver.Surreal -import uk.gibby.driver.rpc.functions.let -import uk.gibby.driver.rpc.functions.query -import uk.gibby.driver.rpc.functions.signin -import uk.gibby.driver.rpc.functions.use -import uk.gibby.driver.rpc.model.data +import uk.gibby.driver.rpc.let +import uk.gibby.driver.rpc.query +import uk.gibby.driver.rpc.signin +import uk.gibby.driver.rpc.use +import uk.gibby.driver.model.query.data import utils.cleanDatabase import kotlin.test.Test import kotlin.test.assertEquals diff --git a/src/commonTest/kotlin/LiveQueryTest.kt b/src/commonTest/kotlin/LiveQueryTest.kt new file mode 100644 index 0000000..32c851a --- /dev/null +++ b/src/commonTest/kotlin/LiveQueryTest.kt @@ -0,0 +1,116 @@ +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.test.runTest +import uk.gibby.driver.Surreal +import uk.gibby.driver.annotation.SurrealDbNightlyOnlyApi +import uk.gibby.driver.api.observeLiveQuery +import uk.gibby.driver.exception.LiveQueryKilledException +import uk.gibby.driver.model.rpc.LiveQueryAction +import uk.gibby.driver.model.query.bind +import uk.gibby.driver.model.query.data +import uk.gibby.driver.rpc.* +import utils.cleanDatabase +import kotlin.test.* + +@OptIn(SurrealDbNightlyOnlyApi::class) +class LiveQueryTest { + @Test + fun testObserve() = runTest { + cleanDatabase() + val connection = Surreal("localhost", 8000) + connection.connect() + connection.signin("root", "root") + connection.use("test", "test") + + val incoming = connection.observeLiveQuery("test") + connection.create("test", "first").content(TestClass("thing", 1)) + connection.create("test", "second").content(TestClass("thing", 2)) + connection.update("test", "first").patch { + replace("myText", "thing2") + } + connection.delete("test", "second") + + val all = List(4) { incoming.first() } + assertEquals(4, all.size) + val shouldReceive = listOf( + LiveQueryAction.Create(incoming.id, TestClass("thing", 1)), + LiveQueryAction.Create(incoming.id, TestClass("thing", 2)), + LiveQueryAction.Update(incoming.id, TestClass("thing2", 1)), + LiveQueryAction.Delete(incoming.id, "test:second") + ) + shouldReceive.forEach { assertContains(all, it) } + + incoming.close() + assertFailsWith { + incoming.first() + } + } + + @Test + fun testLiveQueryAsPartOfRegularQuery() = runTest { + cleanDatabase() + val connection = Surreal("localhost", 8000) + connection.connect() + connection.signin("root", "root") + connection.use("test", "test") + val result = connection.query("LIVE SELECT * FROM test;") + val liveQueryId = result.first().data() + val incoming = connection.subscribe(liveQueryId) + + connection.create("test", "first").content(TestClass("thing", 1)) + connection.create("test", "second").content(TestClass("thing", 2)) + connection.update("test", "first").patch { + replace("myText", "thing2") + } + connection.delete("test", "second") + + val all = List(4) { incoming.first() } + assertEquals(4, all.size) + val shouldReceive = listOf( + LiveQueryAction.Create(liveQueryId, TestClass("thing", 1)), + LiveQueryAction.Create(liveQueryId, TestClass("thing", 2)), + LiveQueryAction.Update(liveQueryId, TestClass("thing2", 1)), + LiveQueryAction.Delete(liveQueryId, "test:second") + ) + shouldReceive.forEach { assertContains(all, it) } + + connection.query("KILL \$liveQueryId;", bind("liveQueryId", liveQueryId)) + connection.unsubscribe(liveQueryId) + assertFailsWith { + incoming.first() + } + } + + @Test + fun testLiveQueryUsingRpcFunctions() = runTest { + cleanDatabase() + val connection = Surreal("localhost", 8000) + connection.connect() + connection.signin("root", "root") + connection.use("test", "test") + val liveQueryId = connection.live("test") + val incoming = connection.subscribe(liveQueryId) + + connection.create("test", "first").content(TestClass("thing", 1)) + connection.create("test", "second").content(TestClass("thing", 2)) + connection.update("test", "first").patch { + replace("myText", "thing2") + } + connection.delete("test", "second") + + val all = List(4) { incoming.first() } + assertEquals(4, all.size) + val shouldReceive = listOf( + LiveQueryAction.Create(liveQueryId, TestClass("thing", 1)), + LiveQueryAction.Create(liveQueryId, TestClass("thing", 2)), + LiveQueryAction.Update(liveQueryId, TestClass("thing2", 1)), + LiveQueryAction.Delete(liveQueryId, "test:second") + ) + shouldReceive.forEach { assertContains(all, it) } + + connection.kill(liveQueryId) + connection.unsubscribe(liveQueryId) + assertFailsWith { + incoming.first() + } + } +} \ No newline at end of file diff --git a/src/commonTest/kotlin/MergeTest.kt b/src/commonTest/kotlin/MergeTest.kt index baedf2a..141ee5f 100644 --- a/src/commonTest/kotlin/MergeTest.kt +++ b/src/commonTest/kotlin/MergeTest.kt @@ -2,8 +2,11 @@ import kotlinx.coroutines.test.runTest import kotlinx.serialization.json.buildJsonObject import kotlinx.serialization.json.put import uk.gibby.driver.Surreal -import uk.gibby.driver.rpc.functions.* -import uk.gibby.driver.rpc.model.bind +import uk.gibby.driver.model.query.bind +import uk.gibby.driver.rpc.create +import uk.gibby.driver.rpc.signin +import uk.gibby.driver.rpc.update +import uk.gibby.driver.rpc.use import utils.cleanDatabase import kotlin.test.Test import kotlin.test.assertEquals diff --git a/src/commonTest/kotlin/PatchTest.kt b/src/commonTest/kotlin/PatchTest.kt index 86419e9..12e56f4 100644 --- a/src/commonTest/kotlin/PatchTest.kt +++ b/src/commonTest/kotlin/PatchTest.kt @@ -1,6 +1,6 @@ import kotlinx.coroutines.test.runTest import uk.gibby.driver.Surreal -import uk.gibby.driver.rpc.functions.* +import uk.gibby.driver.rpc.* import utils.cleanDatabase import kotlin.test.Test import kotlin.test.assertEquals diff --git a/src/commonTest/kotlin/QueryTest.kt b/src/commonTest/kotlin/QueryTest.kt index b509508..6e6afad 100644 --- a/src/commonTest/kotlin/QueryTest.kt +++ b/src/commonTest/kotlin/QueryTest.kt @@ -1,10 +1,10 @@ import kotlinx.coroutines.test.runTest import uk.gibby.driver.Surreal -import uk.gibby.driver.rpc.functions.query -import uk.gibby.driver.rpc.functions.signin -import uk.gibby.driver.rpc.functions.use -import uk.gibby.driver.rpc.model.bind -import uk.gibby.driver.rpc.model.data +import uk.gibby.driver.rpc.query +import uk.gibby.driver.rpc.signin +import uk.gibby.driver.rpc.use +import uk.gibby.driver.model.query.bind +import uk.gibby.driver.model.query.data import utils.cleanDatabase import kotlin.test.Test import kotlin.test.assertEquals diff --git a/src/commonTest/kotlin/SelectTest.kt b/src/commonTest/kotlin/SelectTest.kt index 8086738..1e7a216 100644 --- a/src/commonTest/kotlin/SelectTest.kt +++ b/src/commonTest/kotlin/SelectTest.kt @@ -1,6 +1,9 @@ import kotlinx.coroutines.test.runTest import uk.gibby.driver.Surreal -import uk.gibby.driver.rpc.functions.* +import uk.gibby.driver.rpc.create +import uk.gibby.driver.rpc.select +import uk.gibby.driver.rpc.signin +import uk.gibby.driver.rpc.use import utils.cleanDatabase import kotlin.test.Test import kotlin.test.assertEquals diff --git a/src/commonTest/kotlin/SignInTest.kt b/src/commonTest/kotlin/SignInTest.kt index 7c9c3ec..11f10df 100644 --- a/src/commonTest/kotlin/SignInTest.kt +++ b/src/commonTest/kotlin/SignInTest.kt @@ -1,7 +1,9 @@ import kotlinx.coroutines.test.runTest import uk.gibby.driver.Surreal -import uk.gibby.driver.rpc.functions.* -import uk.gibby.driver.rpc.model.bind +import uk.gibby.driver.model.query.bind +import uk.gibby.driver.rpc.invalidate +import uk.gibby.driver.rpc.signin +import uk.gibby.driver.rpc.signup import utils.cleanDatabase import kotlin.test.Test diff --git a/src/commonTest/kotlin/SignUpTest.kt b/src/commonTest/kotlin/SignUpTest.kt index 908dc26..1af5be4 100644 --- a/src/commonTest/kotlin/SignUpTest.kt +++ b/src/commonTest/kotlin/SignUpTest.kt @@ -1,7 +1,7 @@ import kotlinx.coroutines.test.runTest import uk.gibby.driver.Surreal -import uk.gibby.driver.rpc.functions.* -import uk.gibby.driver.rpc.model.bind +import uk.gibby.driver.model.query.bind +import uk.gibby.driver.rpc.* import utils.cleanDatabase import kotlin.jvm.JvmStatic import kotlin.test.Test diff --git a/src/commonTest/kotlin/UnsetTest.kt b/src/commonTest/kotlin/UnsetTest.kt index c8d20de..0606b18 100644 --- a/src/commonTest/kotlin/UnsetTest.kt +++ b/src/commonTest/kotlin/UnsetTest.kt @@ -1,7 +1,7 @@ import kotlinx.coroutines.test.runTest import uk.gibby.driver.Surreal -import uk.gibby.driver.rpc.functions.* -import uk.gibby.driver.rpc.model.data +import uk.gibby.driver.model.query.data +import uk.gibby.driver.rpc.* import utils.cleanDatabase import kotlin.test.Test import kotlin.test.assertEquals diff --git a/src/commonTest/kotlin/UpdateTest.kt b/src/commonTest/kotlin/UpdateTest.kt index a44abba..6b5c41f 100644 --- a/src/commonTest/kotlin/UpdateTest.kt +++ b/src/commonTest/kotlin/UpdateTest.kt @@ -1,6 +1,9 @@ import kotlinx.coroutines.test.runTest import uk.gibby.driver.Surreal -import uk.gibby.driver.rpc.functions.* +import uk.gibby.driver.rpc.create +import uk.gibby.driver.rpc.signin +import uk.gibby.driver.rpc.update +import uk.gibby.driver.rpc.use import utils.cleanDatabase import kotlin.test.Test import kotlin.test.assertEquals diff --git a/src/commonTest/kotlin/utils/CleanDatabase.kt b/src/commonTest/kotlin/utils/CleanDatabase.kt index 27b299c..250a2bf 100644 --- a/src/commonTest/kotlin/utils/CleanDatabase.kt +++ b/src/commonTest/kotlin/utils/CleanDatabase.kt @@ -1,10 +1,10 @@ package utils import uk.gibby.driver.Surreal -import uk.gibby.driver.rpc.functions.invalidate -import uk.gibby.driver.rpc.functions.query -import uk.gibby.driver.rpc.functions.signin -import uk.gibby.driver.rpc.functions.use +import uk.gibby.driver.rpc.invalidate +import uk.gibby.driver.rpc.query +import uk.gibby.driver.rpc.signin +import uk.gibby.driver.rpc.use suspend fun cleanDatabase() { val connection = Surreal("localhost")