SurrealDB Kotlin Driver

Overview
A simple Kotlin Multiplatform driver for SurrealDB.
- Covers all of the SurrealDB Websocket endpoints: Websocket Docs.
- Support for kotlinx.serialization meaning seamless integration between Kotlin and SurrealDB types.
- Database calls can be made asynchronously
Usage
Dependency
build.gradle.kts
repositories {
mavenCentral()
}
dependencies {
implementation("uk.gibby:surrealdb-kotlin-driver:$kotlin_driver_version")
}
build.gradle
repositories {
mavenCentral()
}
dependencies {
implementation "uk.gibby:surrealdb-kotlin-driver:$kotlin_driver_version"
}
Example
Connecting to a SurrealDB instance
val db = Surreal("localhost", 8000)
db.connect()
db.signin("root", "root")
db.use("ns", "db")
Creating a records
db.create("user").content(buildJsonObject{ put("username", "John"); put("password", "1234")})
@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.
Reading records
val record = db.select<User>("user", "123")
assert(record.username == "John")
assert(record.password == "1234")
val records = db.select<User>("user")
assert(records.size == 1)
assert(records[0].username == "John")
assert(records[0].password == "1234")
Updating records
db.update("user", "123").content(User("John Updated", "1234"))
db.update("user").content(User("John Updated", "1234"))
db.update(, ).merge(
bind(username, ),
)
db.update(, ).patch {
replace(, )
}
Deleting records
db.delete("user", "123")
db.delete("user")
Querying records
val result = db.query(
"""
SELECT *
FROM user
WHERE username = $username AND password = $password
ORDER BY username;
""",
bind("username", "John"),
bind("password", "1234")
)
assert(result.size == 1)
val users = result.first().data<List<User>>()
Using Record Links
In order to interact with id's in a type safe way, you can use Thing type.
@Serializable
data class User(
val id: Thing<User> = unknown(),
val username: String,
val password: String
)
(
id: Thing<Post> = unknown(),
author: Thing<User>,
content: String,
)
user = create().content(User(username = , password = ))
post = create().content(Post(author = user.id, content = ))
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.
val post = select<Post>("post", "123")
assert(post.author Thing.Reference<User>)
assert(post.author.id == )
queryResult = query(
,
bind(, )
)
post = queryResult.first().<List<Post>>()[]
assert(post.author Thing.Record<User>)
post Thing.Record<User>
author = post.author.<User>()
assert(author.username == )
assert(author.password == )
Live Queries
Basic Usage:
val incoming: LiveQueryFlow<User> = db.observeLiveQuery("user")
incoming.collect { frame ->
when (frame) {
is LiveQueryAction.Create -> {
println("New record created")
}
is LiveQueryAction.Update -> {
println("Record updated")
}
is LiveQueryAction.Delete -> {
println("Record deleted")
}
}
}
incoming.close()
For more control you can use the regular query method and subscribe to updates manually:
val result = db.query(
"LIVE SELECT * FROM user WHERE username = \$username",
bind("username", "John")
)
val liveQueryId = result.first().data<String>()
val incoming = db.subscribe<TestClass>(liveQueryId)
db.kill(liveQueryId)
db.unsubscribe(liveQueryId)
Links