quote
block. Quill parses each quoted block of code (quotation) at compile time and translates them to an internal Abstract Syntax Tree (AST)db.run
call reads the quotation's AST and translates it to the target language at compile time, emitting the SQL string as a compilation message. As the query string is known at compile time, the runtime overhead is very low and similar to using the database driver directly.Very interesting! Is this an academic/commercial/open-source project?
--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to scala-user+...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Alright, thanks for the information. How does it compare to Slick?
--
--
> What was the reasoning behind the explicit quoting requirement (instead of making e. g. query the method that does that)?I'm not sure I understand the question, could you give an example?
--
2. Functions can be declared using the normal syntax within quotations. The second approach would require something like `param[Int].map(i => ...)`.
3. The slowest part of the compilation is lifting/unlifting the quotation's AST. The second approach requires lifting/unlifting for each method call, while using `quote` lifting/unlifting is required only when a quotation is used as part of another quotation.
quote{
(id: UserId) => query[User].filter(_.id == userId)
}
Parameters[UserId].flatMap{
id=> User.filter(_.id === id)
}
query[T]
s and get the bare T syntax that Slick gets through implicit conversion. Would need to tag the case classes with a marker trait for that to happen though since Quill by default doesn't use table mappings. On that note, would be nice to include foreign key relationships thereby gaining that concise Slick implicit join syntax:for{
ur <- UserRole; u <- ur.userFk; r <- ur.roleFk
} yield(u,ur,r)
quote{
(t,p) <- Team join Player on $(_.teamFk)
(_,s) <- p join Scoring on $(_.playerFk)
} yield(t,p,s)
> Functions can be declared using the normal syntax within quotations. The second approach would require something like `param[Int].map(i => ...)`.
think he means you can do:
quote{
(id: UserId) => query[User].filter(_.id == userId)
}
instead of Slick's (legacy) approach to generating a prepared statement:
Parameters[UserId].flatMap{
id=> User.filter(_.id === id)
}
Quill's approach is appealing, though it would be great to somehow get rid of all thequery[T]
s and get the bare T syntax that Slick gets through implicit conversion. Would need to tag the case classes with a marker trait for that to happen though since Quill by default doesn't use table mappings.
On that note, would be nice to include foreign key relationships thereby gaining that concise Slick implicit join syntax:
for{
ur <- UserRole; u <- ur.userFk; r <- ur.roleFk
} yield(u,ur,r)
ideally extended to joins*:
quote{
(t,p) <- Team join Player on $(_.teamFk)
(_,s) <- p join Scoring on $(_.playerFk)
} yield(t,p,s)
but the latter is just me wanting to concise all the things ;-)
Quill author, inner join seems to be missing in the library, reason for this??
On Thursday, December 3, 2015 at 3:06:20 AM UTC-5, Simon Ochsenreither wrote:2. Functions can be declared using the normal syntax within quotations. The second approach would require something like `param[Int].map(i => ...)`.
Mhh, could you expand on that?
3. The slowest part of the compilation is lifting/unlifting the quotation's AST. The second approach requires lifting/unlifting for each method call, while using `quote` lifting/unlifting is required only when a quotation is used as part of another quotation.
Interesting, I didn't expect it to have such an impact. Do you have a rough estimation of the difference?
My motivation is largely that I'm looking into having a sane, common API for these "bulk-operations" (for the lack of a better description), so that we can write the same code once, apply it to different sources of data (databases, collections, Spark, ...) and execute it efficiently.
That sane API is actually quite close to what you are doing, by letting all operations compose against a generic type first (without executing it), instead of carrying large type-signatures to rebuild the data-strcuture after every step eagerly.
--
2. Functions can be declared using the normal syntax within quotations. The second approach would require something like `param[Int].map(i => ...)`.
Mhh, could you expand on that?
3. The slowest part of the compilation is lifting/unlifting the quotation's AST. The second approach requires lifting/unlifting for each method call, while using `quote` lifting/unlifting is required only when a quotation is used as part of another quotation.
Interesting, I didn't expect it to have such an impact. Do you have a rough estimation of the difference?
My motivation is largely that I'm looking into having a sane, common API for these "bulk-operations" (for the lack of a better description), so that we can write the same code once, apply it to different sources of data (databases, collections, Spark, ...) and execute it efficiently.
That sane API is actually quite close to what you are doing, by letting all operations compose against a generic type first (without executing it), instead of carrying large type-signatures to rebuild the data-strcuture after every step eagerly.
--
Wouldn't the issue of retaining information go away completely with TASTY? I think one wouldn't even need a custom AST to represent the query (at least not as input, but as a transformation step it might be useful).
--