-
Notifications
You must be signed in to change notification settings - Fork 517
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
Implement a JS driver #1486
Implement a JS driver #1486
Conversation
package com.squareup.sqldelight.drivers.sqljs | ||
|
||
import org.khronos.webgl.Uint8Array | ||
import kotlin.js.* |
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.
nit no * imports, you can search for star imports in intellij preferences to turn off
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.
Fixed
|
||
external interface QueryResults { | ||
var columns: Array<String> | ||
var values: Array<Array<dynamic /* Number | String | Uint8Array | Nothing? */>> |
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.
how does this work O_O
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.
Not sure what you mean
You declare the interface you expect from the JS lib, and then you can use it from Kotlin with type checking etc
return js("new (Function.prototype.bind.apply(type, argsArray))") | ||
} | ||
|
||
suspend fun initSql(config: Config? = js("{}")): SqlJsStatic = initSqlJs(config).await() |
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.
is there a way we can remove the dependency on coroutines from the driver? It should ideally be all blocking straightforward APIs that we can wrap in coroutines if necessary
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.
We would have to expose this as a Promise, which I think is fine. The consumer could then await()
using the built-in extension for it if they're using coroutines.
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.
yea I like that more
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.
does Promise
have a normal blocking await()
? if so you could probably just use that then in your tests @tokou to get around the issues you're currently seeing
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.
No. You would have to do something like
@Test fun myTest() = initDb().then {
test stuff
}
which returns the Promise
to the test runner which it will then wait on.
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.
Done, indeed it's much better now
README.md
Outdated
```kotlin | ||
val sql = initSql() | ||
val db = sql.Database() | ||
val driver: SqlDriver = JsSqlDriver(db) |
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.
can the constructor for JsSqlDriver()
just initSql
and get the database itself instead of doing these three steps explicitly? Or is the expectation that consumers would use the results of initSql
and Database()
multiple times
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.
I added some helper functions to initialize the driver directly
this is impressive I'm going to update the sample code to 1.2.0 today and then we'll need to rebase this pr on that. It should at least clean up the diff that amount. Really love that you also created a sample for the web side, thank you |
With regard to publishing we're going to do the kotlin 1.3.60 release, then merge all these new drivers for windows mac and js then fix the publishing/travis story because its a nightmare, then do another release so it might be a while before this all gets released because theres a lot of work that has to go into it |
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.
Overall great stuff 👍
drivers/sqljs-driver/build.gradle
Outdated
@@ -0,0 +1,79 @@ | |||
apply plugin: 'org.jetbrains.kotlin.multiplatform' |
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.
Is there any reason to use multiplatform in this module instead of only the js plugin?
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.
Hmm no, I just switched to the js plugin
drivers/sqljs-driver/build.gradle
Outdated
dependsOn 'publishJsPublicationToTestRepository' | ||
} | ||
// NOTE: We do not alias uploadArchives because CI runs it on Linux and we only want to run it on Mac OS. | ||
//tasks.register('uploadArchives').dependsOn('publishKotlinMultiplatformPublicationToMavenRepository') |
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.
Don't think we need this commented out since it should work on all host OSs.
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.
I removed all publishing related code for now, as per Alec's comment
drivers/sqljs-driver/build.gradle
Outdated
kotlin { | ||
|
||
js { | ||
useCommonJs() |
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.
I'm pretty sure this prevents use in a module system and we should be using UMD (since Kotlin can't emit ES6 module files).
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.
Done
tearDown() | ||
} | ||
|
||
@JsName("SqlResultSet_getters_return_null_if_the_column_values_are_NULL") |
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.
You can just name the tests like this directly. They only run on JS, so there's no point duplicating them.
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.
Fixed
7865f4c
to
03c08a2
Compare
@AlecStrong Just rebased on the latest master.
|
i thought stately was only a dep of the native artifact - interesting that it fails the js runtime compilation |
|
I could simply replace the class with an |
if possible i think that makes sense |
I fixed the CI and updated the README |
dope, will review shortly. We can figure out publishing later |
@@ -4,6 +4,7 @@ import kotlin.test.Test | |||
import kotlin.test.assertTrue | |||
|
|||
class SchemaTest : BaseTest() { | |||
/* |
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.
does this still need to be commented out?
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.
No. I missed these. Just pushed a fix. There's no way do disable running common tests on a specific target apparently so I duplicated the tests (the alternative would be to expect a boolean from each target to decide if we should run the test or not).
huge contribution. thanks for doing this |
targets { | ||
targetFromPreset(presets.jvm, 'jvm') | ||
targetFromPreset(presets.js, 'js') { | ||
tasks.getByName(compilations.main.compileKotlinTaskName).kotlinOptions { | ||
moduleKind = 'umd' |
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.
Why was this removed?
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.
It was replaced with the js
block to define the target
Sorry I'm not sure why I did this
This is a tentative implementation of a JS driver. It uses sql.js as it looked like the most used and efficient solution.
This is still a WIP and will not pass CI.
The implementation is done.
I also added a web sample (and fixed the other samples). (Run
./gradlew :sample:web:jsBrowserWebpack
and then serve thesample/web/build/distributions/index.html
file)The main issue I have is with tests. I duplicated all the tests and adapted them (quite naively).
The database can only be created in an asynchronous fashion in sql.js. This requires adapting all the tests to run with async code.
In the duplicated tests, I implemented the workaround descibed here to run async tests. However there's still an issue as
@BeforeTest
and@AfterTest
are not handled properly as reported here.Edit: I just submitted a PR in order to fix this and make possible asynchronous beofre and after methods.
Tests in
:drivers:sqljs-driver:jsTest
pass but they are duplicated.Some tests in
:sample:common:jsTest
fail because I don't think it's possible to ignore common tests for a particular target. I duplicated them and fixed them for async code and they pass.I also duplicated the
runTest
method in a couple of files for now.What approach do you recommend for fixing the tests ?
Also, I am not very familiar with publishing of artifacts. I'm sure some steps are missing or maybe wrong to ensure the proper publishing of the JS driver and also some CI steps maybe.
Fixes #1350
Fixes #1294
Closes #1302