Stefan Oltmann
08/31/2025, 12:32 PMStefan Oltmann
08/31/2025, 2:14 PMStefan Oltmann
08/31/2025, 2:14 PMCarter
08/31/2025, 2:25 PM// <https://github.com/cloudflare/workerd/blob/3c85053b83a5200dffc5be5ae26cbe7577cd5ea5/types/defines/d1.d.ts#L26>
external interface D1Database {
fun prepare(sql: String): D1PreparedStatement
/**
* <https://developers.cloudflare.com/d1/how-to/query-databases/#dbbatch>
*
* Executes an array of prepared statements in a transaction.
*
* @return a promise that resolves to an array of statement results.
*/
fun batch(statements: Array<D1PreparedStatement>): Promise<Array<D1Result>>
}
object D1DatabaseFactory {
fun new(
databaseName: String,
env: dynamic
): D1Database {
require(env[databaseName] != null) { "Database $databaseName not found in env" }
@Suppress("UNCHECKED_CAST_TO_EXTERNAL_INTERFACE")
return env[databaseName] as D1Database
}
}
I found working with the external declarations a pain in terms of having the code look and act like Kotlin, so I ended up writing Kotlin objects to wrap the external declarations so I could hide some of the painful parts. I smurf-named the external declarations as D1* e.g D1Database, then just more basic names like Database for my Kotlin classes around the D1 objects.
class Database internal constructor(
private val externalDatabase: D1Database
) {
fun prepare(sql: String) = PreparedStatement(externalDatabase.prepare(sql))
fun prepareAndBind(statement: Statement): PreparedStatement {
val preparedStatement = prepare(statement.sql)
return if (statement.args.isEmpty()) {
preparedStatement
} else {
preparedStatement.bind(statement.args)
}
}
fun batch(statements: Array<PreparedStatement>) =
externalDatabase
.batch(statements.mapToArray<PreparedStatement, D1PreparedStatement> { it.externalPreparedStatement })
.then { externalQueryResults -> externalQueryResults.mapToArray<D1Result, QueryResult> { QueryResult.new(it) } }
}
object DatabaseFactory {
fun new(
databaseName: String,
env: dynamic
): Database = Database(D1DatabaseFactory.new(databaseName, env))
}
This was all before the JS Plain Object gradle plugin, so that might make some of this less bad.Stefan Oltmann
08/31/2025, 8:44 PMCarter
08/31/2025, 8:46 PMCarter
08/31/2025, 8:46 PMStefan Oltmann
09/01/2025, 3:38 AM