Slick codegen & tables with > 22 columns

后端 未结 4 933
囚心锁ツ
囚心锁ツ 2020-12-09 13:28

I\'m new to Slick. I\'m creating a test suite for a Java application with Scala, ScalaTest and Slick. I\'m using slick to prepare data before the test and to do assertions o

4条回答
  •  醉话见心
    2020-12-09 14:19

    There are few options available as you have already found out - nested tuples, conversion from Slick HList to Shapeless HList and then to case classes and so on.

    I found all those options too complicated for the task and went with customised Slick Codegen to generate simple wrapper class with accessors.

    Have a look at this gist.

    class MyCodegenCustomisations(model: Model) extends slick.codegen.SourceCodeGenerator(model){
    import ColumnDetection._
    
    
    override def Table = new Table(_){
        table =>
    
        val columnIndexByName = columns.map(_.name).zipWithIndex.toMap
        def getColumnIndex(columnName: String): Option[Int] = {
            columnIndexByName.get(columnName)
    
        }
    
        private def getWrapperCode: Seq[String] = {
            if (columns.length <= 22) {
                //do not generate wrapper for tables which get case class generated by Slick
                Seq.empty[String]
            } else {
                val lines =
                    columns.map{c =>
                        getColumnIndex(c.name) match {
                            case Some(colIndex) =>
                                //lazy val firstname: Option[String] = row.productElement(1).asInstanceOf[Option[String]]
                                val colType = c.exposedType
                                val line = s"lazy val ${c.name}: $colType = values($colIndex).asInstanceOf[$colType]"
                                line
                            case None => ""
                        }
                    }
                Seq("",
                    "/*",
                    "case class Wrapper(private val row: Row) {",
                    "// addressing HList by index is very slow, let's convert it to vector",
                    "private lazy val values = row.toList.toVector",
                    ""
    
                ) ++ lines ++ Seq("}", "*/", "")
    
            }
        }
    
    
        override def code: Seq[String] = {
            val originalCode = super.code
            originalCode ++ this.getWrapperCode
        }
    
    
    }
    

    }

提交回复
热议问题