Skip to content

Commit

Permalink
Updating readme.md
Browse files Browse the repository at this point in the history
  • Loading branch information
mnbjhu committed Aug 14, 2023
1 parent cf94d62 commit 748739f
Show file tree
Hide file tree
Showing 10 changed files with 122 additions and 30 deletions.
13 changes: 13 additions & 0 deletions .github/workflows/gradle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
1 change: 1 addition & 0 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 Down
94 changes: 86 additions & 8 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ A simple Kotlin Multiplatform driver for SurrealDB.

## Usage
### Dependency
build.gradle.kts
<b>build.gradle.kts</b>
```kotlin
repositories {
mavenCentral()
Expand All @@ -16,7 +16,7 @@ dependencies {
implementation("uk.gibby:surrealdb-kotlin-driver:$kotlin_driver_version")
}
```
build.gradle
<b>build.gradle</b>
```groovy
repositories {
mavenCentral()
Expand All @@ -28,7 +28,7 @@ dependencies {
```

### Example
Connecting to a SurrealDB instance
<b>Connecting to a SurrealDB instance</b>
```kotlin
val db = Surreal("localhost", 8000)
db.connect()
Expand All @@ -37,7 +37,7 @@ db.signin("root", "root")
db.use("ns", "db")
```

Creating a records
<b>Creating a records</b>
```kotlin
// Create a record from a JSON object
db.create("user").content(buildJsonObject( put("username", "John"), put("password", "1234")))
Expand All @@ -48,8 +48,9 @@ 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.

Reading records
<b>Reading records</b>
```kotlin
// Select a record by ID
val record = db.select<User>("user", "123")
Expand All @@ -63,22 +64,99 @@ assert(records[0].username == "John")
assert(records[0].password == "1234")
```

Updating records
<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
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
4 changes: 2 additions & 2 deletions src/commonTest/kotlin/LetTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ 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.result
import uk.gibby.driver.rpc.model.data
import utils.cleanDatabase
import kotlin.test.Test
import kotlin.test.assertEquals
Expand All @@ -20,6 +20,6 @@ class LetTest {
connection.use("test", "test")
connection.let("myKey", "myValue")
val result = connection.query("RETURN \$myKey;")
assertEquals("myValue", result.first().result())
assertEquals("myValue", result.first().data())
}
}
6 changes: 3 additions & 3 deletions src/commonTest/kotlin/QueryTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ 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.result
import uk.gibby.driver.rpc.model.data
import utils.cleanDatabase
import kotlin.test.Test
import kotlin.test.assertEquals
Expand All @@ -21,7 +21,7 @@ class QueryTest {
connection.use("test", "test")
val response = connection.query("RETURN 'Success';")
assertEquals(1, response.size)
assertEquals("Success", response[0].result())
assertEquals("Success", response[0].data())
}

@Test
Expand All @@ -33,7 +33,7 @@ class QueryTest {
connection.use("test", "test")
val response = connection.query("RETURN \$test;", bind("test", "test"))
assertEquals(1, response.size)
assertEquals("test", response[0].result())
assertEquals("test", response[0].data())
}

@Test
Expand Down
6 changes: 3 additions & 3 deletions src/commonTest/kotlin/UnsetTest.kt
Original file line number Diff line number Diff line change
@@ -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.result
import uk.gibby.driver.rpc.model.data
import utils.cleanDatabase
import kotlin.test.Test
import kotlin.test.assertEquals
Expand All @@ -17,11 +17,11 @@ class UnsetTest {
connection.use("test", "test")
connection.let("myKey", "myValue")
val firstResult = connection.query("RETURN \$myKey;")
val myKey = firstResult.first().result<String?>()
val myKey = firstResult.first().data<String?>()
assertEquals("myValue", myKey)
connection.unset("myKey")
val secondResult = connection.query("RETURN \$myKey;")
val myKeyDeleted = secondResult.first().result<String?>()
val myKeyDeleted = secondResult.first().data<String?>()
assertEquals(null, myKeyDeleted)
}
}

0 comments on commit 748739f

Please sign in to comment.