scalazioquill-scala

ZIO Quill: How to generalize operations shared by different entities?


Let's say we have two following case classes:

case class Person(name:String, age:Int, createdAt:LocalDate, lastModified:LocalDate)
case class Address(street:String, zip:Int, createdAt:LocalDate, lastModified:LocalDate)

I want to be able to do as follows:

for {
    p <- query[Person]
           .changedAfter(lift(LocalDate.of(2022,1,1)))
    a <- query[Address].join(a => a.ownerId == p.id)
            .changedAfter(lift(LocalDate.of(2022,1,1)))
} yield (p, a)

Where .changedAfter() will work for any entity containing createdAt and lastModified fields.

How would I go on to create such a modification?


Solution

  • Your can create a extension method like this.

    import io.getquill._
    import java.time._
    
    val ctx = new SqlMirrorContext(PostgresDialect, SnakeCase)
    
    import ctx._
    
    trait EntityLike {
      val createAt: LocalDate
      val lastModified: LocalDate
    }
    
    case class Person(name: String, age: Int, createAt: LocalDate, lastModified: LocalDate) extends EntityLike
    
    
    implicit class EntityOps[A <: EntityLike](q: Query[A]) {
      val changeAfter = quote { (d: LocalDate) =>
        q.filter(e => infix"${e.createAt} < ${d}".as[Boolean])
      }
    }
    val d = LocalDate.of(2000, 1, 1)
    val m = ctx.run(query[Person].changeAfter(lift(d)))
    
    println(m)