I customized the code generator to use case classes not HLists even for many columns

19 views
Skip to first unread message

Naftoli Gugenheim

unread,
Nov 14, 2017, 12:51:57 AM11/14/17
to scala...@googlegroups.com
trait FixedSourceCodeGenerator extends SourceCodeGenerator {
override def Table = new TableDef(_) {
override def hlistEnabled = false
override def compoundType(types: Seq[String]) = compoundValue(types)
override def compoundValue(values: Seq[String]): String = values match {
case Seq(one) => one
case xs => xs.mkString("(", ", ", ")")
}

def tupleValue(values: Seq[String]): String = values match {
case Seq(one) => one
case _ =>
val (a, b) = values.splitAt(22)
val aStr = a.mkString("(", ", ", ")")
tupleValue(aStr +: b)
}

def tupleIndexes(count: Int, add: Int = 0, agg: Seq[List[Int]] = Nil): Seq[List[Int]] =
count match {
case 0 => agg
case _ =>
val a = count min 22 - add
val b = count - a
val as = (1 to a).map(_ + add :: Nil)
if (b == 0) agg ++ as
else tupleIndexes(b, 1, (agg ++ as).map(1 :: _))
}

override def TableClass = new TableClassDef {
override def optionEnabled = false
override def star = {
val fac = if (columns.size <= 22) factory
else
"tuple => " + TableClass.elementType +
"(" +
tupleIndexes(columns.size).map(p => "tuple." + p.map("_" + _).mkString(".")).mkString(", ") +
")"
val ex =
if (columns.size <= 22) extractor
else s"(value: ${TableClass.elementType}) => Some(" + tupleValue(columns.map("value." + _.name)) + ")"

val struct = tupleValue(columns.map(c => if (c.asOption) s"Rep.Some(${c.name})" else s"${c.name}"))
val rhs = if (mappingEnabled) s"$struct <> ($fac, $ex)" else struct
s"def * = $rhs"
}
}
override def PlainSqlMapper = new PlainSqlMapperDef {
override def code = if (!mappingEnabled) super.code else {
val positional = columnsPositional.map { c =>
if (c.asOption || c.model.nullable) s"<<?[${c.rawType}]" else s"<<[${c.rawType}]"
}
val dependencies = columns.map(_.exposedType).distinct.zipWithIndex.map { case (t, i) => s"""e$i: GR[$t]""" }.mkString(", ")
val rearranged = desiredColumnOrder.map(i => if (hlistEnabled) s"r($i)" else tuple(i))

def result(args: Seq[String]) = s"${TableClass.elementType}(${args.mkString(", ")})"

val body = {
if (autoIncLast && columns.size > 1) {
s"val r = ${compoundValue(positional)}\n" +
"import r._\n" +
s"${result(rearranged)} // putting AutoInc last".trim
} else
result(positional)
}

s"""
implicit def $name(implicit $dependencies): GR[${TableClass.elementType}] = GR{
prs => import prs._
${indent(body)}
}
""".trim
}
}
}
}

Reply all
Reply to author
Forward
0 new messages