slickless icon indicating copy to clipboard operation
slickless copied to clipboard

Support for extensible records

Open rfuerst87 opened this issue 6 years ago • 3 comments

I've been playing around with slickless for the past few days. I'm particularly interested in getting extensible records to work with slick. A "record projection" would be a nice feature IMHO. Either by providing a RecordShape or by a MappedProjection.

class Users(tag: Tag) extends Table[Long :: String :: HNil](tag, "users") {
  def id    = column[Long]( "id", O.PrimaryKey, O.AutoInc )
  def email = column[String]("email")

  def * = ('id ->> id) :: ('email ->> email) :: HNil    // support by RecordShape
  // or
  def * = (id :: email :: HNil).mappedWithRecord('id :: 'email :: HNil)  // support by MappedProjection
}

As I just started my journey with shapeless, I could not get any of these two approaches to work. The closest I could come up with is a non working MappedProjection:

def mappedWithRecord[R <: HList : ClassTag, U <: HList, K <: HList](keys: K)
  (implicit
    shape: Shape[_ <: FlatShapeLevel, T, U, _]) =
  new MappedProjection[R, U](
    shape.toNode(hlist),
    MappedScalaType.Mapper(
      ((f: HList) => f.zipWithKeys(keys)).asInstanceOf[Any => Any], // compiler error: could not find implicit value for parameter withKeys: shapeless.ops.hlist.ZipWithKeys[K,shapeless.HList]

      ((g: HList) => ???).asInstanceOf[Any => Any],
      None
    ),
    implicitly[ClassTag[R]]
  )
}

So basically my two questions are:

  1. Would it even be possible to provide a RecordShape? Unfortunately I could not even figure out where to start...
  2. Why can't the compile find the implicit parameter withKeys in the code above? What am I missing?

rfuerst87 avatar Dec 06 '17 19:12 rfuerst87

Hello @rfuerst87 - just wanted to let you know that Dave, Miles, and I are mostly going to be tied up on work and conference preparation for a while. So just wanted to say hi 👋 and let you know we'll try to look into this, but it may be quiet for at least a couple of weeks.

d6y avatar Dec 06 '17 21:12 d6y

Hi @d6y, no worries. I'd be super happy if you could look into this once you have some spare time. Meanwhile I'll post my progress here (if there is any).

rfuerst87 avatar Dec 07 '17 07:12 rfuerst87

I've been (manually) seeing what a simple record might look like with slickless in a branch. Nothing much to see: https://github.com/underscoreio/slickless/compare/feature/18-records-experiments (but everything is in RecordShapeSpec.scala)

From what I recall the mappedWith code uses existing case class mapping to do the work. I guess that could be an option for records too. I think it depends on what we want the T to be in a Slick Table[T]: a record? a case class? I've been assuming working in terms of records is the way forward, but that might be a false assumption.

d6y avatar Jan 01 '18 18:01 d6y