4 ms·
Just glanced through the article; biggest difference I'd say between the two libraries would be, one composes, the other doesn't. val base = for { ur
by virtualwhys 9y ago
Just glanced through the article; biggest difference I'd say between the two libraries would be, one composes, the other doesn't.
val base = for {
ur <- UserRole
u <- ur.user
r <- ur.role
} yield (ur, u, r)
val withManager = for {
(ur, u, r) <- base
ts <- TeamStaff if u.id === ts.userId
} yield (ur, u, r, ts)
val teams = for {
(_, _, _, ts) <- withManager
t <- Team if t.id === ts.teamId
} yield (ts, t)
You can slice and dice a schema however you like, building up queries from other queries, none of which are run until you execute them. Basically you get semantically the same query plans as you'd get writing plain sql, but it's all type checked, sql injection safe, and compiled (queries generally are generated at compile time, not run time).
Quill, another Scala FRM library, is worth checking out in this regard, as is Haskell's Esqueleto.
- rabidferret 9y agoCan you elaborate on how Diesel doesn't compose in this way? Composition is one of the main goals of Diesel.
- virtualwhys 9y agoDidn't see anything in the article, assumed query composition wasn't possible. I don't see anything offhand in the Diesel docs, are there examples that illustrate composition along the lines of the above?
- steveklabnik 9y agoUntil you do something to cause the query to be evaluated, it's a value like any other, and you can combine them together however you want.