Search code examples
scalaslicksangria

Updating table with enum


Trying to insert the information into DB that looks like this:

(UUID, EnumType)

with following logic:

var t = TestTable.query.map(t=> (t.id, t.enumType)) ++= toAdd.map(idTest, enumTest)))

but compiler throws an error for TestTable.query.map(t=> (t.id, t.enumType)) it's interpriting it as type Iteratable[Nothing], am I missing something?


Test table looks like this:

object TestTable {
  val query = TableQuery[TestTable]
}

class TestTable(tag: slick.lifted.Tag) extends Table[TestTable](tag, "test_table") {
  val id = column[UUID]("id")
  val enumType = column[EnumType]("enumType")

  override val * = (id, testType) <> (
    (TestTable.apply _).tupled,
    TestTable.unapply
  )

Solution

  • Suppose you have following data structure:

    object Color extends Enumeration {
      val Blue = Value("Blue")
      val Red = Value("Red")
      val Green = Value("Green")
    }
    
    case class MyType(id: UUID, color: Color.Value)
    

    Define slick schema as following:

    class TestTable(tag: slick.lifted.Tag) extends Table[MyType](tag, "test_table") {
      val id = column[UUID]("id")
      val color = column[Color.Value]("color")
    
      override val * = (id, color) <> ((MyType.apply _).tupled, MyType.unapply)
    }
    
    object TestTable {
      lazy val query = TableQuery[TestTable]
    }
    

    To map enum to SQL data type slick requires implicit MappedColumnType:

    implicit val colorTypeColumnMapper: JdbcType[Color.Value] = MappedColumnType.base[Color.Value, String](
      e => e.toString,
      s => Color.withName(s)
    )
    

    Now you can insert values into DB in this way:

    val singleInsertAction = TestTable.query += MyType(UUID.randomUUID(), Color.Blue)
    
    val batchInsertAction = TestTable.query ++= Seq(
      MyType(UUID.randomUUID(), Color.Blue),
      MyType(UUID.randomUUID(), Color.Red),
      MyType(UUID.randomUUID(), Color.Green)
    )