-
Notifications
You must be signed in to change notification settings - Fork 510
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for async drivers #3168
Conversation
Add async drivers for R2DBC and sqljs workers
Have only done a skim, but this is heading in the right direction. We should create a new module for the async runtime (
|
I've split the runtime module up to separate the async code and also extracted a few classes into a shared module that I don't think would make sense to duplicate (like There's also |
yep, module structure looks good |
Update async runtime to use suspend functions Add Closeable to async runtime Update sqljs worker and r2dbc drivers
tests are failing because this code will need to be updated to publish the new runtime modules |
sqldelight-compiler/src/main/kotlin/app/cash/sqldelight/core/compiler/SqlDelightCompiler.kt
Outdated
Show resolved
Hide resolved
In terms of tests, many of the existing test suites can be duplicated and updated to check for |
yea i wouldn't worry about duplicating all tests, its fine to just test that specific behavior once and rely on the normal tests for everything else |
Add other async codegen compiler tests
Remove async extensions from coroutines-extensions (to revisit later)
Fix sample builds with new runtime modules
Add some brief documentation on implementing async drivers
I think this now covers the core of what's needed for async drivers at least in terms of codegen and runtime API. The sqljs worker driver is incomplete (lacks prepared statements and transactions) but I think it might be better to leave that as a separate PR since it'll be pretty involved on its own. The R2DBC driver isn't very polished and has limited actual driver support, and as mentioned earlier it's kind of unclear what the demand for it is so I'm not sure if we even want to keep it right now? I'll add other small components like But for now I think it's ready for some real reviews! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Worked my way through the codegen, will review the runtime bits tomorrow
test-util/src/main/kotlin/app/cash/sqldelight/test/util/FixtureCompiler.kt
Outdated
Show resolved
Hide resolved
dialects/sqlite-3-18/src/main/kotlin/app/cash/sqldelight/dialects/sqlite_3_18/SqliteDialect.kt
Outdated
Show resolved
Hide resolved
...t/integration-mysql-async/src/test/kotlin/app/cash/sqldelight/mysql/integration/MySqlTest.kt
Outdated
Show resolved
Hide resolved
...t/integration-mysql-async/src/test/kotlin/app/cash/sqldelight/mysql/integration/MySqlTest.kt
Outdated
Show resolved
Hide resolved
...t/integration-mysql-async/src/test/kotlin/app/cash/sqldelight/mysql/integration/MySqlTest.kt
Outdated
Show resolved
Hide resolved
sqldelight-compiler/src/test/kotlin/app/cash/sqldelight/core/AsyncTest.kt
Outdated
Show resolved
Hide resolved
sqldelight-compiler/src/main/kotlin/app/cash/sqldelight/core/compiler/QueryGenerator.kt
Outdated
Show resolved
Hide resolved
sqldelight-compiler/src/main/kotlin/app/cash/sqldelight/core/compiler/QueryGenerator.kt
Outdated
Show resolved
Hide resolved
sqldelight-compiler/src/main/kotlin/app/cash/sqldelight/core/compiler/DatabaseGenerator.kt
Outdated
Show resolved
Hide resolved
...elight-compiler/dialect/src/main/kotlin/app/cash/sqldelight/dialect/api/SqlDelightDialect.kt
Outdated
Show resolved
Hide resolved
Co-authored-by: Alec Strong <AlecStrong@users.noreply.github.com>
As a side note (and potential nerd snipe) the jvm async driver I'm familiar with that appears to be getting traction is jasync which has built in support for coroutines so might integrate easier - and potentially it just already does the right thing™ for dates? |
Add RuntimeTypes class for codegen types Add default async runtime types Remove suspend modifier from generated functions that return an `AsyncQuery`
runtime/runtime-async/src/commonMain/kotlin/app/cash/sqldelight/async/db/Closeable.kt
Outdated
Show resolved
Hide resolved
I didn't realize how tightly-coupled the |
yea lets just remove it, we can revisit the existing driver test stuff along with potentially adding an async one later |
Run spotless again again again
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks good, fantastic stuff
dialects/hsql/src/main/kotlin/app/cash/sqldelight/dialects/hsql/HsqlDialect.kt
Show resolved
Hide resolved
drivers/r2dbc-driver/src/main/kotlin/app/cash/sqldelight/driver/r2dbc/R2dbcDriver.kt
Outdated
Show resolved
Hide resolved
drivers/r2dbc-driver/src/main/kotlin/app/cash/sqldelight/driver/r2dbc/R2dbcDriver.kt
Outdated
Show resolved
Hide resolved
drivers/r2dbc-driver/src/main/kotlin/app/cash/sqldelight/driver/r2dbc/R2dbcDriver.kt
Outdated
Show resolved
Hide resolved
drivers/r2dbc-driver/src/main/kotlin/app/cash/sqldelight/driver/r2dbc/R2dbcDriver.kt
Outdated
Show resolved
Hide resolved
drivers/r2dbc-driver/src/main/kotlin/app/cash/sqldelight/driver/r2dbc/R2dbcDriver.kt
Outdated
Show resolved
Hide resolved
drivers/r2dbc-driver/src/main/kotlin/app/cash/sqldelight/driver/r2dbc/R2dbcDriver.kt
Show resolved
Hide resolved
} | ||
|
||
private suspend fun <R> transactionWithWrapper(noEnclosing: Boolean, wrapperBody: suspend AsyncTransactionWrapper<R>.() -> R): R { | ||
val transaction = driver.newTransaction() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
probably we should figure out how to share this logic between the sync/async transacter types, but we can do that in a follow up
runtime/runtime-async/src/commonMain/kotlin/app/cash/sqldelight/async/logs/LogAsyncSqlDriver.kt
Outdated
Show resolved
Hide resolved
runtime/runtime/src/commonMain/kotlin/app/cash/sqldelight/Transacter.kt
Outdated
Show resolved
Hide resolved
Co-authored-by: Alec Strong <AlecStrong@users.noreply.github.com>
Disable async codegen for HSQL Remove unused functions in R2DBC driver Move LogAsyncSqlDriver to tests
# Conflicts: # sqldelight-compiler/src/main/kotlin/app/cash/sqldelight/core/compiler/DatabaseGenerator.kt
Regarding #1942
This adds the main codegen changes along with a minimal runtime needed to support async driver implementations, along with some basic (and incomplete) implementations of an R2DBC driver and a driver for running sql.js in a web worker. There's still a lot of work (and cleanup) to be done on it, but I'm hoping to get some feedback on the design of the runtime before going any further.
To summarize how it works, async code generation is enabled in the gradle config:
SQLdelight will then generate queries (and related code) that return anAsyncSqlDriver.Callback<R>
object that can be used to observe the result/errors. This object can be easily adapted to other reactive/async frameworks, like these coroutine extensions.Drivers implement the
AsyncSqlDriver
interface which is pretty similar toSqlDriver
except most of the methodsnow return the callback objectare nowsuspend
functions.Open Questions
transactionWithResult
could become trouble since we would presumably want to be able to support the semantics of whatever reactive library is being used which currently isn't possible (related to Expose Transacter.Transaction components to be used from a SqlDriver #1856)e.g. for coroutines we'd want something like
SqlCursor
interface, and my current workaround in the R2DBC driver implementation is to read all the rows into a map and then hand that to aSqlCursor
implementation. Not ideal. Adapting all of the mapper code to follow the asynchronous semantics would require a lot more effort to change the codegen.$1, $2
format instead of?, ?
so they don't work with the currentR2dbcDriver
, only mysql works. Special sqldelight driver implementations could probably work around it? But I also don't know how much demand there is for R2DBC in sqldelight, I mainly implemented it just to help inform the design of the async runtime.Lastly, I threw together a quick sample project that shows the sql.js worker driver in action: https://github.com/dellisd/sqldelight-js-worker