A high-performance Kotlin Native database driver for PostgreSQL, MySQL, and SQLite.
MIT License
A high-performance, non-blocking database driver for PostgreSQL, MySQL, and SQLite, written for Kotlin Native. Looking to build efficient, cross-platform applications with Kotlin Native.
[!IMPORTANT] The project is in a very early stage; thus, breaking changes should be expected.
🏠 Homepage (under construction)
Currently, the driver supports:
PostgreSQL
MySQL
SQLite
implementation("io.github.smyrgeorge:sqlx4k-postgres:x.y.z")
// or for MySQL
implementation("io.github.smyrgeorge:sqlx4k-mysql:x.y.z")
// or for SQLite
implementation("io.github.smyrgeorge:sqlx4k-sqlite:x.y.z")
We support the following targets:
The driver fully supports non-blocking io.
You can set the maxConnections
from the driver constructor:
val db = PostgreSQL(
host = "localhost",
port = 15432,
username = "postgres",
password = "postgres",
database = "test",
maxConnections = 10 // set the max-pool-size here
)
val db = MySQL(
host = "localhost",
port = 13306,
username = "mysql",
password = "mysql",
database = "test",
maxConnections = 10
)
val db = SQLite(
database = "test.db",
maxConnections = 10
)
// With named parameters:
val st1 = Statement
.create("select * from sqlx4k where id = :id")
.bind("id", 65)
db.fetchAll(st1).getOrThrow().map {
val id: ResultSet.Row.Column = it.get("id")
Test(id = id.asInt())
}
// With positional parameters:
val st2 = Statement
.create("select * from sqlx4k where id = ?")
.bind(0, 65)
db.fetchAll(st2).getOrThrow().map {
val id: ResultSet.Row.Column = it.get("id")
Test(id = id.asInt())
}
val tx1: Transaction = db.begin().getOrThrow()
tx1.execute("delete from sqlx4k;").getOrThrow()
val res: ResultSet = tx1.fetchAll("select * from sqlx4k;").getOrThrow().forEach {
println(debug())
}
tx1.commit().getOrThrow()
insert/update/delete
queriesFor this operation you will need to include the KSP
plugin to your project.
plugins {
alias(libs.plugins.ksp)
}
// Then you need to configure the processor (will generate the necessary code files).
ksp {
arg("output-package", "io.github.smyrgeorge.sqlx4k.examples.postgres")
arg("output-filename", "GeneratedQueries")
}
dependencies {
ksp(implementation("io.github.smyrgeorge:sqlx4k-codegen:x.y.z")) // Will generate code for all available targets.
}
Then create your data class that will be mapped to a table:
@Table("sqlx4k")
data class Sqlx4k(
@Id(insert = true) // Will be included in the insert query.
val id: Int,
val test: String
)
We also need to create the function definitions for the generated code:
// Filename: GeneratedQueries (same as `output-filename`).
// Also the package should be the same as `output-package`.
package io.github.smyrgeorge.sqlx4k.examples.postgres
import io.github.smyrgeorge.sqlx4k.Statement
// We only need to declare the functions,
// the actual code will be auto-generated.
expect fun Sqlx4k.insert(): Statement
expect fun Sqlx4k.update(): Statement
expect fun Sqlx4k.delete(): Statement
Then in your code you can use it like:
val insert: Statement = Sqlx4k(id = 66, test = "test").insert()
val affected = db.execute(insert).getOrThrow()
println("AFFECTED: $affected")
For more details take a look at the postgres
example.
db.listen("chan0") { notification: Postgres.Notification ->
println(notification)
}
(1..10).forEach {
db.notify("chan0", "Hello $it")
delay(1000)
}
Check here: https://github.com/smyrgeorge/sqlx4k-sqldelight
You will need the Rust
toolchain to build this project.
Check here: https://rustup.rs/
[!NOTE] By default the project will build only for your system architecture-os (e.g.
macosArm64
,linuxArm64
, etc.)
Also, make sure that you have installed all the necessary targets (only if you want to build for all targets):
rustup target add aarch64-apple-ios
rustup target add x86_64-linux-android
rustup target add aarch64-linux-android
rustup target add aarch64-apple-darwin
rustup target add x86_64-apple-darwin
rustup target add aarch64-unknown-linux-gnu
rustup target add x86_64-unknown-linux-gnu
rustup target add x86_64-pc-windows-gnu
We also need to install cross
(tool that helps with cross-compiling)
cargo install cross --git https://github.com/cross-rs/cross
Then, run the build.
# will build only for macosArm64 target
./gradlew build
You can also build for specific targets.
./gradlew build -Ptargets=macosArm64,macosX64
To build for all available target run:
./gradlew build -Ptargets=all
./gradlew publishAllPublicationsToMavenCentralRepository -Ptargets=all
First you need to run start-up the postgres instance.
docker compose up -d
Then run the main
method.
./sqlx4k-postgres-examples/build/bin/macosArm64/releaseExecutable/sqlx4k-postgres-examples.kexe
See Main.kt
file for more examples (examples modules).
// Initialize the connection pool.
val db = PostgreSQL(
host = "localhost",
port = 15432,
username = "postgres",
password = "postgres",
database = "test",
maxConnections = 10
)
db.execute("drop table if exists sqlx4k;").getOrThrow()
// Make a simple query.
data class Test(val id: Int)
// You can also use RowMappers(s) to map your objects.
object TestRowMapper : RowMapper<Test> {
override fun map(rs: ResultSet, row: ResultSet.Row): Test {
val id: ResultSet.Row.Column = row.get("id")
return Test(id = id.asInt())
}
}
val res: List<Test> = db.fetchAll("select * from sqlx4k;", TestRowMapper).getOrThrow()
println(test)
Check for memory leaks with the leaks
tool.
First sign you binary:
codesign -s - -v -f --entitlements =(echo -n '<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "https://www.apple.com/DTDs/PropertyList-1.0.dtd"\>
<plist version="1.0">
<dict>
<key>com.apple.security.get-task-allow</key>
<true/>
</dict>
</plist>') ./sqlx4k-postgres-examples/build/bin/macosArm64/releaseExecutable/sqlx4k-postgres-examples.kexe
Then run the tool:
leaks -atExit -- ./sqlx4k-postgres-examples/build/bin/macosArm64/releaseExecutable/sqlx4k-postgres-examples.kexe
Sample output:
Process: sqlx4k-postgres-examples.kexe [32353]
Path: /Users/USER/*/sqlx4k-postgres-examples.kexe
Load Address: 0x102904000
Identifier: examples.kexe
Version: 0
Code Type: ARM64
Platform: macOS
Parent Process: leaks [32351]
Date/Time: 2024-07-05 16:14:03.515 +0200
Launch Time: 2024-07-05 16:13:45.848 +0200
OS Version: macOS 14.5 (23F79)
Report Version: 7
Analysis Tool: /Applications/Xcode.app/Contents/Developer/usr/bin/leaks
Analysis Tool Version: Xcode 15.4 (15F31d)
Physical footprint: 213.8M
Physical footprint (peak): 213.8M
Idle exit: untracked
----
leaks Report Version: 4.0, multi-line stacks
Process 32353: 125349 nodes malloced for 8520 KB
Process 32353: 0 leaks for 0 total leaked bytes.