Hello Everyone! :wave: Four optional filters. Six...
# feed
a
Hello Everyone! 👋 Four optional filters. Sixteen DAO methods. We've all written that file. *Just released RoomQL 1.0.0 — one
query { }
block instead.*
Copy code
val q = query {
    from(UserEntityTable)
    where {
        UserEntityTable.age gte minAge      // gone when minAge is null
        UserEntityTable.status eq status    // gone when status is null
    }
    orderBy(UserEntityTable.age, SortDirection.DESC)
}
dao.search(q.toQuery())
Copy code
(18, "active") → SELECT * FROM users WHERE age >= ? AND status = ? ORDER BY age DESC
(18,  null   ) → SELECT * FROM users WHERE age >= ? ORDER BY age DESC
(null, null  ) → SELECT * FROM users ORDER BY age DESC
A
null
filter doesn't match
NULL
— it never reaches the SQL. No
if
ladders. No
(:x IS NULL OR col = :x)
. No 2ⁿ overloads.
UserEntityTable.age
is generated by KSP from your
@Entity
, so renaming a column breaks the build, not production. Args bind as positional
?
. Nothing reflects at runtime, so R8 needs no keep rules. The catch, since you'd find it in five minutes anyway: it's
@RawQuery
underneath, so Room no longer verifies the whole statement at compile time. Column references are checked; query logic isn't. Static query? Keep using
@Query
— it gives you more. This is for the ones
@Query
can't express, like an ``ORDER BY`` column chosen at runtime. I didn't want to just claim the alternatives are worse, so the demo app implements the same search four ways — RoomQL,
IS NULL OR
, 16 overloaded DAOs, raw string concat — and a test asserts all four return identical rows across all 16 filter combinations. A subtly wrong baseline would have made the whole comparison a lie. Kotlin 2.0.x · Room 2.6–2.7 · minSdk 21 · Apache 2.0 github.com/ahmednobii/RoomQL Tell me where it breaks — especially query shapes it can't build yet. Whole-row selects only today, so no projections or subqueries.
👀 1
c
IMO the "if it's
null
ignore the constraint" is too implicit and risks being surprising. I would prefer separate
gte
(doesn't compile if
null
) and
gteNotNull
operators (ignore if
null
). It's what I've done in KtMongo: ktmongo.opensavvy.dev/features/optional-filters.html
plus1 2
a
Noted, I will add that to the roadmap of that.