0

Following code works as expected (Laptop is a case class) :

def main(args: Array[String]): 

 implicit val ctx = new SqlMirrorContext(MirrorSqlDialect, Literal)
 import ctx._

 val laptops = quote {
   querySchema[Laptop]("laptops")
 }

 implicit val laptopInsertMeta = insertMeta[Laptop](_.id)

 val q = quote {
   laptops.insert(lift(Laptop(...)))
 }
 ctx.run(q)

}

But this (on-the-way-to-refactoring) version fails to compile:

class LaptopDaoQuill[I <: Idiom, N <: NamingStrategy](implicit ctx: Context[I, N])  {

 import ctx._

 def insert(obj: Laptop) = {
 val laptops = quote {
   querySchema[Laptop]("laptops")
 }
 implicit val personInsertMeta = insertMeta[Laptop](_.id)

 val q = quote {
    laptops.insert(lift(obj))
 }
 ctx.run(q)
 }
}

object Main {
def main(args: Array[String]): Unit = {
  implicit val ctx = new SqlMirrorContext(MirrorSqlDialect, Literal)

  val laptopDao = new LaptopDaoQuill

  laptopDao.insert(Laptop(...))
}

With following errors:

Error:(29, 55) Can't find implicit Encoder[Long]. Please, do one of the following things: 1. ensure that implicit Encoder[Long] is provided and there are no other conflicting implicits; 2. make Long Embedded case class or AnyVal. implicit val personInsertMeta = insertMetaLaptop

Error:(32, 21) Can't find an implicit InsertMeta for type com.training.entity.Laptop laptops.insert(lift(obj))

Would work in that case (sure with PostgresJdbcContext in main):

class LaptopDaoQuill[N <: NamingStrategy : TypeTag](implicit ctx: PostgresJdbcContext[N]) {...}

BUT not if :

class LaptopDaoQuill[I <: Idiom : TypeTag, N <: NamingStrategy: TypeTag](implicit ctx: Context[I, N])

Thanks in advance!

1 Answers1

0

Replace I <: Idiom with I <: SqlIdiom and implicit ctx: Context[I, N] with implicit ctx: JdbcContext[I, N].

The following code compiles:

import io.getquill._
import io.getquill.context.jdbc.JdbcContext
import io.getquill.context.sql.idiom.SqlIdiom

case class Laptop(id: Long, name: String)

class LaptopDaoQuill[I <: SqlIdiom, N <: NamingStrategy](implicit ctx: JdbcContext[I, N]) {

  import ctx._

  def insert(obj: Laptop) = {
    val laptops = quote {
      querySchema[Laptop]("laptops")
    }
    implicit val personInsertMeta = insertMeta[Laptop](_.id)

    val q = quote {
      laptops.insert(lift(obj))
    }
    ctx.run(q)
  }
}

object Main {
  def main(args: Array[String]): Unit = {
//    implicit val ctx = new SqlMirrorContext(MirrorSqlDialect, Literal)
    implicit val ctx = new PostgresJdbcContext(SnakeCase, "ctx")

    val laptopDao = new LaptopDaoQuill

    laptopDao.insert(Laptop(10L, "laptop"))
  }
}
Dmytro Mitin
  • 48,194
  • 3
  • 28
  • 66
  • Still, why class Context[I, N] doesn't work, if JdbcContext[Dialect <: SqlIdiom, Naming <: NamingStrategy](dataSource: DataSource with Closeable) extends Context[Dialect, Naming] ? –  Nov 12 '17 at 09:16
  • Because on contrary to more specific contexts (PostgresJdbcContext or JdbcContext) for general Context necessary implicits (Encoder, InsertMeta) are not defined. For example for JdbcContext they are defined [here](https://github.com/getquill/quill/blob/master/quill-jdbc/src/main/scala/io/getquill/context/jdbc/Encoders.scala#L51) and [here](https://github.com/getquill/quill/blob/master/quill-core/src/main/scala/io/getquill/dsl/MetaDsl.scala#L10). Besides `JdbcContext <: Context`, also `JdbcContext <: Encoders`. So regarding Encoder difference between JdbcContext and Context is clear. – Dmytro Mitin Nov 12 '17 at 09:41
  • Regarding InsertMeta both `JdbcContext <: SqlContext <: Context <: CoreDsl <: MetaDsl` and `Context <: CoreDsl <: MetaDsl` so it's necessary to read macros what the difference is. – Dmytro Mitin Nov 12 '17 at 09:42