Language Integrated Query for Kotlin

Dear Kotlin Developers, let’s admit it: deep down, we really hate DSLs, especially SQL DSLs! When we can’t do “person.name == ‘joe’” and need to do “person.name eq ‘joe’” we’ll grin and bear it, but when it turns into “Case.When(addr.zipCode eq 14562).Then(‘J’).Else(‘Y’) instead of “if (addr.zipCode == 14562) ‘J’ else ‘Y’” we start to question whether any of these abstractions are worth their semantic weight.

Unfortunately we Kotlin developers are not lucky enough to have a language with for-comprehensions (a.k.a. do-notation), so there is nothing to absorb the natural “punishment” that comes from stringing together multiple joins. Instead we go on a journey learning about table-alises, as is the case in Exposed, Ktorm, JOOQ and similar systems. Frequently, we take long walks pondering why we can’t use simple constructs like “person.name ?: ‘default’” the second we drop down into DSL land! In the end, we find ourselves frequently throwing in the towel and switching to a system like SQLDelight, just like Scala people abandoned SLICK in favor of Doobie years ago.

Well, what I told you that I have a unique system where you CAN do all of these above things? What if I told you that you could use `==` to create normal comparisons in SQL. What if I told you could use simple `if` and `when` statements that seamlessly translate into SQL Case statements? What if I told you can use Elvis-operators in SQL queries to seamlessly handle nullable columns? What if I told you you’ll never need to deal with another Table-alias object again!?

<br />

<iframe width="560" height="315" src="https://www.youtube.com/embed/6DgCLeu8In8?si=u0ZD7KqFC14qhN4E" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

https://www.youtube.com/watch?v=6DgCLeu8In8&t=6s

<br />

What if I told you that you can write an SQL query as simply as this:

<br />

case class Person(id: Int, name: String, age: Int)

case class Address(ownerId: Int, street: String, zip: Int)

capture.select {

 val p = from(Table<Person>())

 val a = join(Table<Address>()) { a -> a.ownerId == p.id }

 p to a

}

<br />

<br />

This is called Language Integrated Query and I’ve been doing it for nearly 10 years now.

Now I’m doing it in Kotlin with a new library called ExoQuery.

Get ready!

Starting from: $536

Renew Your Mind at LambdaConf 2025

Buy tickets