Multiplatform setup with the Web Worker Driver¶
First apply the gradle plugin in your project. Make sure to set generateAsync
to
true
when creating your database.
plugins {
id("app.cash.sqldelight") version "2.0.2"
}
repositories {
google()
mavenCentral()
}
sqldelight {
databases {
create("Database") {
packageName.set("com.example")
generateAsync.set(true)
}
}
}
plugins {
id "app.cash.sqldelight" version "2.0.2"
}
repositories {
google()
mavenCentral()
}
sqldelight {
databases {
Database { // This will be the name of the generated database class.
packageName = "com.example"
generateAsync = true
}
}
}
Defining the Schema¶
Write your SQL statements in a .sq
file under src/main/sqldelight
.
Typically the first statement in the .sq
file creates a table, but you can also create indexes
or set up default content.
CREATE TABLE hockeyPlayer (
player_number INTEGER PRIMARY KEY NOT NULL,
full_name TEXT NOT NULL
);
CREATE INDEX hockeyPlayer_full_name ON hockeyPlayer(full_name);
INSERT INTO hockeyPlayer (player_number, full_name)
VALUES (15, 'Ryan Getzlaf');
From these statements, SQLDelight will generate a Database
class with an associated Schema
object that can be used to create your database and execute statements on it. The Database
class
is generated by the generateSqlDelightInterface
Gradle task which is run automatically by the
SQLDelight IDE plugin when you edit a .sq
file, and also as part of a normal Gradle build.
kotlin {
// The drivers needed will change depending on what platforms you target:
sourceSets.androidMain.dependencies {
implementation "app.cash.sqldelight:android-driver:2.0.2"
}
// or sourceSets.iosMain, sourceSets.windowsMain, etc.
sourceSets.nativeMain.dependencies {
implementation "app.cash.sqldelight:native-driver:2.0.2"
}
sourceSets.jvmMain.dependencies {
implementation "app.cash.sqldelight:sqlite-driver:2.0.2"
}
sourceSets.jsMain.dependencies {
implementation "app.cash.sqldelight:sqljs-driver:2.0.2"
implementation npm("sql.js", "1.6.2")
implementation devNpm("copy-webpack-plugin", "9.1.0")
}
}
Creating Drivers¶
First set up a way to create a driver in your common code. This can be done using expect
/actual
,
or simply with a common interface a platform-specific implementations of the interface.
expect suspend fun provideDbDriver(
schema: SqlSchema<QueryResult.AsyncValue<Unit>>
): SqlDriver
SqlSchema
interface contains a generic QueryResult
type argument which is used to differentiate
schema code that is generated with the generateAsync
configuration option set to true
.
Some drivers rely on synchronous behaviours when creating or migrating the schema, so to use an
asynchronous schema you can use the synchronous()
extension method to adapt it for use with synchronous drivers.
actual suspend fun provideDbDriver(
schema: SqlSchema<QueryResult.AsyncValue<Unit>>
): SqlDriver {
return WebWorkerDriver(
Worker(
js("""new URL("@cashapp/sqldelight-sqljs-worker/sqljs.worker.js", import.meta.url)""")
)
).also { schema.create(it).await() }
}
actual suspend fun provideDbDriver(
schema: SqlSchema<QueryResult.AsyncValue<Unit>>
): SqlDriver {
return JdbcSqliteDriver(JdbcSqliteDriver.IN_MEMORY)
.also { schema.create(it).await() }
}
actual suspend fun provideDbDriver(
schema: SqlSchema<QueryResult.AsyncValue<Unit>>
): SqlDriver {
return AndroidSqliteDriver(schema.synchronous(), context, "test.db")
}
actual suspend fun provideDbDriver(
schema: SqlSchema<QueryResult.AsyncValue<Unit>>
): SqlDriver {
return NativeSqliteDriver(schema.synchronous(), "test.db")
}