Skip to content

Commit

Permalink
Merge pull request #2 from mnbjhu/Fixing_ios
Browse files Browse the repository at this point in the history
Fixing ios and updating readme
  • Loading branch information
mnbjhu committed Aug 14, 2023
2 parents bfdeca1 + f036f2a commit c16b6b4
Show file tree
Hide file tree
Showing 13 changed files with 189 additions and 59 deletions.
15 changes: 14 additions & 1 deletion .github/workflows/gradle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Start Surreal
run: docker run -d -p 8000:8000 surrealdb/surrealdb:nightly start --user root --pass root -- "memory"
run: docker run -d -p 8000:8000 surrealdb/surrealdb:latest start --user root --pass root -- "memory"
- uses: actions/checkout@v3
- name: Set up JDK 11
uses: actions/setup-java@v3
Expand All @@ -33,3 +33,16 @@ jobs:
uses: gradle/gradle-build-action@bd5760595778326ba7f1441bcf7e88b49de61a25 # v2.6.0
with:
arguments: build
- name: Generate API documentation
if: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request' }}
run: |
VERSION=$(git tag --sort=committerdate | tail -1)
echo Generating API documentation for version $VERSION
./gradlew -Pversion=$VERSION dokkaHtml
- name: Deploy API documentation to Github Pages
if: ${{ github.ref == 'refs/heads/master' && github.event_name != 'pull_request' }}
uses: JamesIves/github-pages-deploy-action@v4
with:
branch: gh-pages
folder: build/dokka/html
target-folder: api
25 changes: 13 additions & 12 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ plugins {
kotlin("multiplatform") version "1.8.21"
kotlin("plugin.serialization") version "1.8.21"
id("com.vanniktech.maven.publish") version "0.25.3"
id("org.jetbrains.dokka") version "1.8.20"
signing
}

Expand All @@ -23,11 +24,10 @@ buildscript {
kotlin {
jvm()

ios {
binaries {
framework("SurrealDB")
}
}

iosX64()
iosArm64()
iosSimulatorArm64()

macosX64()
mingwX64()
Expand All @@ -41,7 +41,6 @@ kotlin {
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.0")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.2")
implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.4.0")
implementation("io.ktor:ktor-client-websockets:2.2.2")
implementation("io.ktor:ktor-serialization-kotlinx-json:2.2.2")
implementation("io.ktor:ktor-client-core:2.2.2")
Expand All @@ -56,7 +55,6 @@ kotlin {
}
val jvmMain by getting {
dependencies {
implementation(kotlin("stdlib-jdk8"))
implementation("io.ktor:ktor-client-cio:2.2.2")
}
}
Expand All @@ -66,13 +64,18 @@ kotlin {
implementation(kotlin("test-junit"))
}
}
val iosMain by getting {
val iosX64Main by getting
val iosArm64Main by getting
val iosSimulatorArm64Main by getting
val iosMain by creating {
dependsOn(commonMain)
iosX64Main.dependsOn(this)
iosArm64Main.dependsOn(this)
iosSimulatorArm64Main.dependsOn(this)
dependencies {
implementation("io.ktor:ktor-client-ios:2.2.2")
}
}
val iosTest by getting {
}
val macosX64Main by getting {
dependencies {
implementation("io.ktor:ktor-client-cio:2.2.2")
Expand All @@ -96,12 +99,10 @@ kotlin {
}
val jsMain by getting {
dependencies {
implementation(kotlin("stdlib-js"))
}
}
val jsTest by getting {
dependencies {
implementation(kotlin("test-js"))
}
}
}
Expand Down
5 changes: 0 additions & 5 deletions kotlin-js-store/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,6 @@
"@jridgewell/resolve-uri" "3.1.0"
"@jridgewell/sourcemap-codec" "1.4.14"

"@js-joda/[email protected]":
version "3.2.0"
resolved "https://registry.yarnpkg.com/@js-joda/core/-/core-3.2.0.tgz#3e61e21b7b2b8a6be746df1335cf91d70db2a273"
integrity sha512-PMqgJ0sw5B7FKb2d5bWYIoxjri+QlW/Pys7+Rw82jSH0QN3rB05jZ/VrrsUdh1w4+i2kw9JOejXGq/KhDOX7Kg==

"@rollup/plugin-commonjs@^21.0.1":
version "21.1.0"
resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-21.1.0.tgz#45576d7b47609af2db87f55a6d4b46e44fc3a553"
Expand Down
146 changes: 139 additions & 7 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,161 @@
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/uk.gibby/surrealdb-kotlin-driver/badge.svg)](https://maven-badges.herokuapp.com/maven-central/uk.gibby/surrealdb-kotlin-driver)
[![Java CI with Gradle](https://github.com/mnbjhu/surrealdb-kotlin-driver/actions/workflows/gradle.yml/badge.svg)](https://github.com/mnbjhu/surrealdb-kotlin-driver/actions/workflows/gradle.yml)
## Overview
A simple Kotlin Multiplatform driver for SurrealDB. This driver is a work in progress and is not yet ready for production use.
A simple Kotlin Multiplatform driver for SurrealDB.

## Usage
### Gradle
build.gradle
### Dependency
<b>build.gradle.kts</b>
```kotlin
repositories {
mavenCentral()
}

dependencies {
implementation("uk.gibby:surrealdb-kotlin-driver:0.1.0")
implementation("uk.gibby:surrealdb-kotlin-driver:$kotlin_driver_version")
}
```
build.gradle.kts
<b>build.gradle</b>
```groovy
repositories {
mavenCentral()
}
dependencies {
implementation "uk.gibby:surrealdb-kotlin-driver:0.1.0"
implementation "uk.gibby:surrealdb-kotlin-driver:$kotlin_driver_version"
}
```

###
### Example
<b>Connecting to a SurrealDB instance</b>
```kotlin
val db = Surreal("localhost", 8000)
db.connect()
db.signin("root", "root")
// db.signin("ns", "db", "scope", bind("username", "John"), bind("password", "1234"))
db.use("ns", "db")
```

<b>Creating a records</b>
```kotlin
// Create a record from a JSON object
db.create("user").content(buildJsonObject( put("username", "John"), put("password", "1234")))

// Create a record from a @Serializable object
@Serializable
data class User(val username: String, val password: String)

db.create("user").content(User("John", "1234"))
```
Note: All functions have both a JsonObject and @Serializable variant so you can interact with SurrealDB in both a shemafull and schemaless way.

<b>Reading records</b>
```kotlin
// Select a record by ID
val record = db.select<User>("user", "123")
assert(record.username == "John")
assert(record.password == "1234")

// Select all records
val records = db.select<User>("user")
assert(records.size == 1)
assert(records[0].username == "John")
assert(records[0].password == "1234")
```

<b>Updating records</b>
```kotlin
// Update a record by ID
db.update("user", "123").content(User("John Updated", "1234"))

// Update all records
db.update("user").content(User("John Updated", "1234"))

// Update with a merge
db.update("user", "123").merge(
bind(username, "John Updated"),
)

// Update with a Json patch
db.update("John", "123").patch {
// Json patch builder
replace("username", "John Updated")
}
```

<b>Deleting records</b>
```kotlin
// Delete a record by ID
db.delete("user", "123")

// Delete all records
db.delete("user")
```

<b>Querying records</b>
```kotlin
val result = db.query(
"SELECT * FROM user WHERE username = $username AND password = $password\n" +
"ORDER BY username;",
bind("username", "John"),
bind("password", "1234")
)
assert(result.size == 1)
val users = result.first().data<List<User>>()
```

<b>Using Record Links</b>
In order to interact with id's in a type safe way, you can use `Thing` type.

```kotlin

import java.time.ZoneId

@Serializable
data class User(
val id: Thing<User> = unknown(),
val username: String,
val password: String
)

@Serializable
data class Post(
val id: Thing<Post> = unknown(),
val author: Thing<User>,
val content: String,
)

val user = create("user").content(User(username = "John", password = "1234"))
val post = create("post").content(Post(author = user.id, content = "Hello World!"))
```
A `Thing` can be a `Reference` (an id) or a `Record` (a full record). You can use SurrealDB's 'FETCH' statement to fetch a record from a reference.

```kotlin
// By default, a Thing is a reference
val post = select<Post>("post", "123")

assert(post.author is Thing.Reference<User>)
assert(post.author.id == "user:123")

// You can fetch a record from a reference
val queryResult = query(
"SELECT * FROM post WHERE author = $author\n" +
"FETCH author LIMIT 1;",
bind("author", "John")
)
val post = queryResult.first().data<List<Post>>()[0]

assert(post.author is Thing.Record<User>)

post as Thing.Record<User>
val author = post.author.data<User>()

assert(author.username == "John")
assert(author.password == "1234")
```

## Links
- [SurrealDB](https://surrealdb.com/)
- [Api Documentation]()
- [Installing SurrealDB](https://surrealdb.com/docs/installation)
- [Kotlinx Serialization](https://github.com/Kotlin/kotlinx.serialization)
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ sealed class QueryResponse {
data class Error(override val time: String, val detail: String): QueryResponse()
}

inline fun <reified T> QueryResponse.result(): T {
inline fun <reified T> QueryResponse.data(): T {
return when (this) {
is QueryResponse.Success -> surrealJson.decodeFromJsonElement(result)
is QueryResponse.Error -> throw QueryException(detail)
Expand Down
8 changes: 4 additions & 4 deletions src/commonMain/kotlin/uk/gibby/driver/rpc/model/Thing.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import kotlinx.serialization.encoding.decodeStructure
*
* A helper class for representing a reference to a Thing.
* This is used to represent a reference to a Thing in a record class.
* This is useful when using the 'FETCH' statement as when a Thing is fetched it is returned as an [Actual] rather than a [Reference].
* This is useful when using the 'FETCH' statement as when a Thing is fetched it is returned as an [Record] rather than a [Reference].
*
* @param T the type of the thing
* @property id the id of the thing
Expand All @@ -25,7 +25,7 @@ import kotlinx.serialization.encoding.decodeStructure
sealed class Thing<T> {
abstract val id: String
data class Reference<T>(override val id: String): Thing<T>()
data class Actual<T>(override val id: String, val result: T): Thing<T>()
data class Record<T>(override val id: String, val result: T): Thing<T>()
}

/**
Expand Down Expand Up @@ -55,7 +55,7 @@ class ThingSerializer<T: Any>(
decoder.decodeStructure(descriptor) {
id = decodeStringElement(descriptor, 0)
}
Thing.Actual(id!!, result)
Thing.Record(id!!, result)
} catch (e: Exception) {
Thing.Reference(decoder.decodeString())
}
Expand All @@ -64,7 +64,7 @@ class ThingSerializer<T: Any>(
override fun serialize(encoder: Encoder, value: Thing<T>) {
when(value) {
is Thing.Reference -> encoder.encodeString(value.id)
is Thing.Actual -> {
is Thing.Record -> {
encoder.encodeSerializableValue(tSerializer, value.result)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import utils.cleanDatabase
import kotlin.test.Test
import kotlin.test.assertEquals

class Authenticate {
class AuthenticateTest {

@Test
fun testBasicAuthenticate() = runTest {
Expand Down
8 changes: 4 additions & 4 deletions src/commonTest/kotlin/CreateTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ 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.result
import uk.gibby.driver.rpc.model.data
import uk.gibby.driver.rpc.model.unknown
import utils.cleanDatabase
import kotlin.test.Test
Expand Down Expand Up @@ -68,10 +68,10 @@ class CreateTest {
val result = connection.query("SELECT * FROM other FETCH linked;")
val other = result
.first()
.result<List<OtherTest>>()
.data<List<OtherTest>>()
.first()
assertTrue { other.linked is Thing.Actual }
val linked = other.linked as Thing.Actual<TestClass>
assertTrue { other.linked is Thing.Record }
val linked = other.linked as Thing.Record<TestClass>
assertEquals("test", linked.result.myText)
assertEquals(1, linked.result.myNumber)

Expand Down
10 changes: 5 additions & 5 deletions src/commonTest/kotlin/FetchTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ 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.result
import uk.gibby.driver.rpc.model.data
import utils.cleanDatabase
import kotlin.test.Test
import kotlin.test.assertEquals
Expand All @@ -26,10 +26,10 @@ class FetchTest {
val result = connection.query("SELECT * FROM other FETCH linked;")
val other = result
.first()
.result<List<OtherTest>>()
.data<List<OtherTest>>()
.first()
assertTrue { other.linked is Thing.Actual }
val linked = other.linked as Thing.Actual<TestClass>
assertTrue { other.linked is Thing.Record }
val linked = other.linked as Thing.Record<TestClass>
assertEquals("first", linked.result.myText)
assertEquals(1, linked.result.myNumber)

Expand All @@ -47,7 +47,7 @@ class FetchTest {
val result = connection.query("SELECT * FROM other;")
val other = result
.first()
.result<List<OtherTest>>()
.data<List<OtherTest>>()
.first()
assertTrue { other.linked is Thing.Reference }
val linked = other.linked as Thing.Reference<TestClass>
Expand Down
Loading

0 comments on commit c16b6b4

Please sign in to comment.