Comments (7)
@Aleks67B @jilen Can you please give a concrete example of code before/after maybe? I'm also suffering from long compilation times with Quill and I'm not sure to understand @jilen suggestion
Also, I think that it'd be good to document this trick. Lots of people are suffering from these compilation times. (I can make the PR to document it, no worries)
from zio-quill.
Sure, taking the example from the initial comment regarding the ProductId
, our previous implicit mapping was:
case class ProductId(id: Long)
protected implicit val productIdDecoder: MappedEncoding[Long, ProductId] = MappedEncoding(ProductId.apply)
protected implicit val productIdEncoder: MappedEncoding[ProductId, Long] = MappedEncoding(_.id)
Updated with explicit Encoder
s and Decoder
s:
protected val ctx: PostgresMonixJdbcContext[SnakeCase.type]
protected implicit val productIdDecoder: ctx.Decoder[ProductId] = ctx.mappedDecoder(MappedEncoding(ProductId.apply), ctx.longDecoder)
protected implicit val productIdEncoder: ctx.Encoder[ProductId] = ctx.mappedEncoder(MappedEncoding(_.id), ctx.longEncoder)
from zio-quill.
BTW, if anyone is reading this, here's a generic implementation of this trick for zio-prelude newtypes:
// File: `io.example.extensions.scala`
import zio.prelude._
import io.getquill.MappedEncoding
import io.getquill.context.jdbc.JdbcContextTypes
object extensions {
trait QuillEncoding[A] {
self: Newtype[A] =>
def quillEncoder(ctx: JdbcContextTypes[?, ?])(implicit encoder: ctx.Encoder[A]): ctx.Encoder[Type] =
ctx.mappedEncoder[Type, A](MappedEncoding(unwrap), encoder)
def quillDecoder(ctx: JdbcContextTypes[?, ?])(implicit decoder: ctx.Decoder[A]): ctx.Decoder[Type] =
ctx.mappedDecoder[A, Type](MappedEncoding(wrap), decoder)
}
}
// File: `io.example.domain.scala`
import zio.prelude._
import io.example.extensions._
object domain {
// Subtype example
type ProductId = ProductId.Type
object ProductId extends Subtype[Long] with QuillEncoding[Long]
// Newtype example
type AnotherId = AnotherId.Type
object AnotherId extends Newtype[String] with QuillEncoding[String]
}
// File: `io.example.db.Codecs.scala`
import io.getquill.context.jdbc.*
import io.example.domain._
/**
* Note that I'm using PG. Some of the traits I extend here come from the PG extensions of Quill.
* If you're not using PG, you might need to replace/remove some of them.
*/
trait Codecs
extends Encoders
with Decoders
with ObjectGenericTimeEncoders
with ObjectGenericTimeDecoders
with BooleanObjectEncoding
with UUIDObjectEncoding
with ArrayDecoders
with ArrayEncoders { self: JdbcContextTypes[?, ?] =>
// IntelliJ might not be happy with the implicits required by the `quillEncoder` and `quillDecoder` methods so we tell it to shut up with the following weird comment:
/*_*/
implicit val encoderProductId: Encoder[ProductId] = ProductId.quillEncoder(self)
implicit val decoderProductId: Decoder[ProductId] = ProductId.quillDecoder(self)
implicit val encoderAnotherId: Encoder[AnotherId] = AnotherId.quillEncoder(self)
implicit val decoderAnotherId: Decoder[AnotherId] = AnotherId.quillDecoder(self)
/*_*/
}
// Finally, you need to mixin this `Codecs` trait to your Quill context. Here's an example:
// File: `io.example.db.DBLive.scala`
import io.getquill.context.jdbc.*
import io.getquill.*
import io.example.domain._
trait DB {
...
}
object DB {
def live: ULayer[DB] = ...
}
final class DBLive(dataSource: DataSource) extends DB {
import DBLive.Context.*
...
}
object DBLive {
/**
* Note the `with Codecs` here. That's what you need to add to your context
*/
// noinspection TypeAnnotation
@SuppressWarnings(Array("scalafix:ExplicitResultTypes"))
private[db] object Context extends PostgresZioJdbcContext(naming = Literal) with Codecs {
import extras.*
private[db] def products = quote(querySchema[Product]("products"))
def selectProductsById(id: ProductId) =
quote {
products.filter(_.id === lift(id))
}
}
}
(Note that the above code wasn't written in an IDE nor was compiled so it might be slightly incorrect but you have the general idea. The QuillEncoding
and its methods are correct. It's copy/pasted from my project)
from zio-quill.
You may first try to use the -Yprofile-trace to get some insights. (Note seems only works on jdk 8, higher version may need some java9 module system tweak )
We have some evidence that replacing the strongly-typed IDs with bare longs improves query compilation time
And if you can confirm MappedEncoding
cause the slow down.
You can just define the val xidEncoder: Encoder[Xid] = mappedEncoder ...
directly to reduce the implicit resolution time.
from zio-quill.
Thank you for the suggestion @jilen . We have removed our implicit MappedEncoding
s and changed to defining Encoder
s and Decoder
s directly. This has resulted in a ~30% reduction in compile time.
from zio-quill.
Thanks a lot @Aleks67B
from zio-quill.
@Aleks67B Sidenote question: why are you using case classes to implement your typesafe ids and not zio-prelude newtypes? AFAIK, case classes have an overhead at runtime (instantiation) which newtypes don't have
Example:
import zio.prelude._
type ProductId = ProductId.Type
object ProductId extends Subtype[Long] // Can also be `... extends Newtype[Long]` depending on your needs
from zio-quill.
Related Issues (20)
- SQLServerDialect does not wrap TOP statement in parenthesis
- Returning generated and embedded case classes HOT 1
- io.getquill.quat.Quat memory leak HOT 2
- Compilation time issue when having a lot of requests in a project HOT 7
- Problem with Aliasing columns with with sql keywords HOT 1
- Enhancement: support JSON operations for SQLite HOT 1
- Can't use quill if project is using scalatags (scala 3) HOT 14
- Documentation is not showing up on the website HOT 3
- Query: `contains` doesn't compiles HOT 2
- create ilike query in postgres via quill-jdbc HOT 3
- The Link to contributing guid is not working HOT 1
- Broken reference to Contributing guideline HOT 2
- "Found more then one type of Query" Warning
- Question about migration to Quill HOT 2
- [Question to the community] Removing `jasync` modules? HOT 7
- SQL syntax when call delete method HOT 4
- io.getquill.context.jdbc.Decoders#dateDecoder creates java.util.Calendar for every request HOT 1
- SQL Query Generation Error: Unquoted Keywords Causes Statement Errors with Postgres
- Error with Batch Update HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from zio-quill.