Skip to content

kotlin: remove runtime dependency #774

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

Merged
merged 1 commit into from
Nov 14, 2020

Conversation

mightyguava
Copy link
Contributor

@mightyguava mightyguava commented Nov 9, 2020

The runtime in #368 turned out to be a bad idea. It's pretty much unnecessary and adds quite a bit to the complexity of the generated code. It's possible a runtime would be useful in the future. At that point we can add that back in

The runtime in sqlc-dev#368 turned out to
be a bad idea. It's pretty much unnecessary and adds quite a bit to the
complexity of the generated code. It's _possible_ a runtime would be
useful in the future. At that point we can add that back in
@mightyguava mightyguava mentioned this pull request Nov 10, 2020
7 tasks
@@ -36,91 +32,71 @@ ORDER BY name
class QueriesImpl(private val conn: Connection) : Queries {
Copy link

@tirsen tirsen Nov 10, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally I try to avoid the Impl suffix because it doesn't say anything about the implementation which feels like a missed opportunity. Maybe GeneratedQueries?

(I assume this is generated right?)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But it’s the Java way! I agree. But since naming didn’t change in this PR I’d like to leave it for a follow up if you feel strongly? Also all of this code is generated. Maybe RealQueries which isn’t anymore meaningful but seems like the Kotlin way.

I think you’ve been corrupted by Go

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Impl suffix is afaict never used in the JDK so while it's common in some Java projects it's not really a "sanctioned" convention. :-) I don't care about it strongly but something to think about.

val results = stmt.executeQuery()
val ret = mutableListOf<BooksByTagsRow>()
while (results.next()) {
ret.add(BooksByTagsRow(
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know how JDBC implementations are implemented these days but the JDBC API has been built to encourage "streaming" where not the entire result set has to be sent over the wire before it can start being processed by the application. This implementation seems to break that. I think you can build a list implementation on top of ResultSet using AbstractSequentialList quite easily? You would have to convert the checked SQLException to unchecked exceptions though so that might be a problem...

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, doesn't Kotlin not have checked exceptions?

Copy link
Contributor Author

@mightyguava mightyguava Nov 10, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "streaming" method is supported in Go too. It's a lower level usage that sqlc doesn't currently handle because it wants to abstract away row parsing. I think if @kyleconroy adds a command for the Go version, like :execstream, we can replicate it for Kotlin. Otherwise this should match the Go impl to always parse the results first.

And no, Kotlin doesn't have checked exceptions...

ret
}
if (results.next()) {
throw SQLException("expected one row in result set, but got many")
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you support a Book? type such that the generated code can return a null instead of throwing an exception?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So that's an interesting question. In Go one usually would get a sql.ErrNoRows when querying for a single row but the resultset is empty. In Kotlin this throws an exception that needs to be caught. Except there's no such canonical exception (I think), so we need to create one and stick it in a runtime library.

Or, maybe the :one and :many commands for sqlc which return 1 row or a list of rows respectively, should actually continue to return a RowResults and ListResults class? The RowResults could have .get() which throws and getOrNull() which does not. While the ListResults class could have a getList() to get the full list or next() to get the next item in the list.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oooo or return an Iterator() 😱

stmt.setString(1, title)
bookId: Int) {
conn.prepareStatement(updateBook).use { stmt ->
stmt.setString(1, title)
stmt.setArray(2, conn.createArrayOf("pg_catalog.varchar", tags.toTypedArray()))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume this doesn't work on mysql? (Your other PR?)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope. This field was changed to a comma delimitered varchar in the mysql version

import sqlc.runtime.ExecuteQuery
import sqlc.runtime.ListQuery
import sqlc.runtime.RowQuery

interface Queries {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This API feels a lot more idiomatic now!

@kyleconroy kyleconroy merged commit e231bca into sqlc-dev:master Nov 14, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants