or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

column-adapters.mddatabase-driver.mdindex.mdlogging-utilities.mdquery-system.mdschema-management.mdtransaction-management.md

index.mddocs/

0

# SQLDelight Runtime

1

2

SQLDelight Runtime is the multiplatform runtime library for SQLDelight, providing typesafe Kotlin APIs from SQL statements. It serves as the foundational layer that enables compile-time schema verification, reactive query results, and thread-safe database operations across JVM, Android, Native, and JavaScript platforms.

3

4

## Package Information

5

6

- **Package Name**: app.cash.sqldelight:runtime

7

- **Package Type**: Maven/Gradle

8

- **Language**: Kotlin (Multiplatform)

9

- **Installation**: `implementation "app.cash.sqldelight:runtime:2.1.0"`

10

11

## Core Imports

12

13

```kotlin

14

import app.cash.sqldelight.Query

15

import app.cash.sqldelight.Transacter

16

import app.cash.sqldelight.SuspendingTransacter

17

import app.cash.sqldelight.ColumnAdapter

18

import app.cash.sqldelight.EnumColumnAdapter

19

import app.cash.sqldelight.db.SqlDriver

20

import app.cash.sqldelight.db.SqlCursor

21

import app.cash.sqldelight.db.QueryResult

22

import app.cash.sqldelight.db.SqlSchema

23

import app.cash.sqldelight.db.AfterVersion

24

import app.cash.sqldelight.logs.LogSqliteDriver

25

import app.cash.sqldelight.logs.StatementParameterInterceptor

26

```

27

28

## Basic Usage

29

30

```kotlin

31

import app.cash.sqldelight.Query

32

import app.cash.sqldelight.Transacter

33

import app.cash.sqldelight.db.SqlDriver

34

35

// Execute a query and get results

36

val users: List<User> = userQueries.selectAll().executeAsList()

37

38

// Execute a single result query

39

val user: User? = userQueries.selectById(123).executeAsOneOrNull()

40

41

// Listen to query result changes

42

userQueries.selectAll().addListener(object : Query.Listener {

43

override fun queryResultsChanged() {

44

// Handle query result updates

45

updateUI()

46

}

47

})

48

49

// Execute operations in a transaction

50

database.transaction {

51

userQueries.insertUser("Alice", 25)

52

userQueries.insertUser("Bob", 30)

53

// Both inserts succeed or both are rolled back

54

}

55

```

56

57

## Architecture

58

59

SQLDelight Runtime is built around several key components:

60

61

- **Query System**: Type-safe query execution with reactive result updates via the observer pattern

62

- **Transaction Management**: ACID transaction support with nested transaction capabilities and automatic resource cleanup

63

- **Driver Abstraction**: Platform-agnostic database driver interface supporting both synchronous and asynchronous operations

64

- **Type Adaptation**: Bidirectional type conversion system for mapping between Kotlin types and database column types

65

- **Multiplatform Design**: Common API surface with platform-specific implementations using expect/actual declarations

66

- **Resource Management**: Automatic cleanup and proper lifecycle management through Closeable pattern

67

68

## Capabilities

69

70

### Query Execution and Management

71

72

Core query functionality for executing SQL statements and managing result sets. Provides type-safe query execution with reactive updates and lifecycle management.

73

74

```kotlin { .api }

75

abstract class Query<out RowType : Any>(

76

mapper: (SqlCursor) -> RowType

77

) : ExecutableQuery<RowType>(mapper) {

78

abstract fun addListener(listener: Listener)

79

abstract fun removeListener(listener: Listener)

80

81

fun interface Listener {

82

fun queryResultsChanged()

83

}

84

}

85

86

abstract class ExecutableQuery<out RowType : Any>(

87

val mapper: (SqlCursor) -> RowType

88

) {

89

abstract fun <R> execute(mapper: (SqlCursor) -> QueryResult<R>): QueryResult<R>

90

fun executeAsList(): List<RowType>

91

fun executeAsOne(): RowType

92

fun executeAsOneOrNull(): RowType?

93

}

94

95

// Factory functions for creating queries

96

fun <RowType : Any> Query(

97

identifier: Int,

98

queryKeys: Array<out String>,

99

driver: SqlDriver,

100

query: String,

101

mapper: (SqlCursor) -> RowType

102

): Query<RowType>

103

```

104

105

[Query System](./query-system.md)

106

107

### Transaction Management

108

109

Comprehensive transaction support with ACID guarantees, nested transactions, and automatic resource management. Supports both synchronous and coroutine-based asynchronous operations.

110

111

```kotlin { .api }

112

interface Transacter : TransacterBase {

113

fun <R> transactionWithResult(

114

noEnclosing: Boolean = false,

115

bodyWithReturn: TransactionWithReturn<R>.() -> R

116

): R

117

118

fun transaction(

119

noEnclosing: Boolean = false,

120

body: TransactionWithoutReturn.() -> Unit

121

)

122

}

123

124

interface SuspendingTransacter : TransacterBase {

125

suspend fun <R> transactionWithResult(

126

noEnclosing: Boolean = false,

127

bodyWithReturn: suspend SuspendingTransactionWithReturn<R>.() -> R

128

): R

129

130

suspend fun transaction(

131

noEnclosing: Boolean = false,

132

body: suspend SuspendingTransactionWithoutReturn.() -> Unit

133

)

134

}

135

136

abstract class Transacter.Transaction : TransactionCallbacks {

137

protected abstract val enclosingTransaction: Transaction?

138

fun afterCommit(function: () -> Unit)

139

fun afterRollback(function: () -> Unit)

140

protected abstract fun endTransaction(successful: Boolean): QueryResult<Unit>

141

}

142

```

143

144

[Transaction Management](./transaction-management.md)

145

146

### Database Driver Interface

147

148

Platform-agnostic database driver abstraction that provides SQL execution, connection management, and query result handling. Supports both synchronous and asynchronous operation modes.

149

150

```kotlin { .api }

151

interface SqlDriver : Closeable {

152

fun <R> executeQuery(

153

identifier: Int?,

154

sql: String,

155

mapper: (SqlCursor) -> QueryResult<R>,

156

parameters: Int,

157

binders: (SqlPreparedStatement.() -> Unit)? = null

158

): QueryResult<R>

159

160

fun execute(

161

identifier: Int?,

162

sql: String,

163

parameters: Int,

164

binders: (SqlPreparedStatement.() -> Unit)? = null

165

): QueryResult<Long>

166

167

fun newTransaction(): QueryResult<Transacter.Transaction>

168

fun currentTransaction(): Transacter.Transaction?

169

fun addListener(vararg queryKeys: String, listener: Query.Listener)

170

fun removeListener(vararg queryKeys: String, listener: Query.Listener)

171

fun notifyListeners(vararg queryKeys: String)

172

}

173

174

interface SqlCursor {

175

fun next(): QueryResult<Boolean>

176

fun getString(index: Int): String?

177

fun getLong(index: Int): Long?

178

fun getBytes(index: Int): ByteArray?

179

fun getDouble(index: Int): Double?

180

fun getBoolean(index: Int): Boolean?

181

}

182

183

sealed interface QueryResult<T> {

184

val value: T

185

suspend fun await(): T

186

187

value class Value<T>(override val value: T) : QueryResult<T>

188

value class AsyncValue<T>(private val getter: suspend () -> T) : QueryResult<T>

189

}

190

```

191

192

[Database Driver Interface](./database-driver.md)

193

194

### Column Type Adapters

195

196

Type conversion system for mapping between Kotlin types and database column types. Enables custom type serialization and provides built-in adapters for common use cases.

197

198

```kotlin { .api }

199

interface ColumnAdapter<T : Any, S> {

200

fun decode(databaseValue: S): T

201

fun encode(value: T): S

202

}

203

204

class EnumColumnAdapter<T : Enum<T>>(

205

private val enumValues: Array<out T>

206

) : ColumnAdapter<T, String> {

207

override fun decode(databaseValue: String): T

208

override fun encode(value: T): String

209

}

210

211

// Factory function for enum adapters

212

inline fun <reified T : Enum<T>> EnumColumnAdapter(): EnumColumnAdapter<T>

213

```

214

215

[Column Type Adapters](./column-adapters.md)

216

217

### Logging and Debugging Utilities

218

219

Comprehensive logging and debugging tools for monitoring database operations, troubleshooting issues, and performance analysis.

220

221

```kotlin { .api }

222

class LogSqliteDriver(

223

private val sqlDriver: SqlDriver,

224

private val logger: (String) -> Unit

225

) : SqlDriver {

226

// Logs all SQL operations including queries, executions, transactions

227

override fun <R> executeQuery(

228

identifier: Int?,

229

sql: String,

230

mapper: (SqlCursor) -> QueryResult<R>,

231

parameters: Int,

232

binders: (SqlPreparedStatement.() -> Unit)?

233

): QueryResult<R>

234

235

override fun execute(

236

identifier: Int?,

237

sql: String,

238

parameters: Int,

239

binders: (SqlPreparedStatement.() -> Unit)?

240

): QueryResult<Long>

241

}

242

243

class StatementParameterInterceptor : SqlPreparedStatement {

244

fun getAndClearParameters(): List<Any?>

245

// Intercepts and stores parameter values for debugging

246

}

247

```

248

249

[Logging and Utilities](./logging-utilities.md)

250

251

### Schema Management

252

253

Database schema creation, migration, and version management system. Provides APIs for initializing databases and handling schema changes across application versions.

254

255

```kotlin { .api }

256

interface SqlSchema<T : QueryResult<Unit>> {

257

val version: Long

258

fun create(driver: SqlDriver): T

259

fun migrate(

260

driver: SqlDriver,

261

oldVersion: Long,

262

newVersion: Long,

263

vararg callbacks: AfterVersion

264

): T

265

}

266

267

class AfterVersion(

268

val afterVersion: Long,

269

val block: (SqlDriver) -> Unit

270

)

271

```

272

273

[Schema Management](./schema-management.md)

274

275

## Types

276

277

```kotlin { .api }

278

// Core interfaces

279

sealed interface TransacterBase {

280

// Base interface for all transaction-capable components

281

// Implemented by Transacter and SuspendingTransacter

282

}

283

interface TransactionCallbacks {

284

fun afterCommit(function: () -> Unit)

285

fun afterRollback(function: () -> Unit)

286

}

287

288

// Transaction context interfaces

289

interface TransactionWithReturn<R> : TransactionCallbacks {

290

fun rollback(returnValue: R): Nothing

291

fun <R> transaction(body: TransactionWithReturn<R>.() -> R): R

292

}

293

294

interface TransactionWithoutReturn : TransactionCallbacks {

295

fun rollback(): Nothing

296

fun transaction(body: TransactionWithoutReturn.() -> Unit)

297

}

298

299

interface SuspendingTransactionWithReturn<R> : TransactionCallbacks {

300

fun rollback(returnValue: R): Nothing

301

suspend fun <R> transaction(body: suspend SuspendingTransactionWithReturn<R>.() -> R): R

302

}

303

304

interface SuspendingTransactionWithoutReturn : TransactionCallbacks {

305

fun rollback(): Nothing

306

suspend fun transactionWithResult(body: suspend SuspendingTransactionWithoutReturn.() -> Unit)

307

}

308

309

// Prepared statement interface

310

interface SqlPreparedStatement {

311

fun bindBytes(index: Int, bytes: ByteArray?)

312

fun bindLong(index: Int, long: Long?)

313

fun bindDouble(index: Int, double: Double?)

314

fun bindString(index: Int, string: String?)

315

fun bindBoolean(index: Int, boolean: Boolean?)

316

}

317

318

// Platform abstraction

319

expect interface Closeable {

320

fun close()

321

}

322

323

expect inline fun <T : Closeable?, R> T.use(body: (T) -> R): R

324

325

// Exception types

326

class OptimisticLockException(

327

message: String?,

328

cause: Throwable? = null

329

) : IllegalStateException(message, cause)

330

331

// Internal APIs

332

internal expect fun currentThreadId(): Long

333

```