9

我有一个 PostgreSQL 表enum,它由以下人员创建:

CREATE TYPE file_status AS ENUM ('new', 'uploading', 'queued', 'processing', 'done', 'failed');

和相关的字段

CREATE TABLE files ( ...
    status file_status NOT NULL,
    ...
);

使用 Scala 2.10 和 Typesafe Slick 1.0.1,我创建了到我的 Files 表的映射,除了status字段之外,它需要自定义file_status类型,一个字符串。

def status = column[FileStatus]("status")

我一直在玩 Slick 的 TypeMapper,但不太明白如何让它工作:

sealed trait FileStatus

implicit val fileStatusMapper: TypeMapper[String] = base[FileStatus, String](
  s => s.toString,
  f => f(FileStatus)
) 

我收到错误:类型不匹配;找到:models.Files.FileStatus.type 需要:Int

为什么需要 Int?是因为TypeMapper吗?我也试过

...
f => f.toString
// type mismatch; found : String required: models.Files.FileStatus

f => f
// type mismatch; found : String required: models.Files.FileStatus

感谢您提供任何帮助我理解此映射的指示。

4

2 回答 2

12

引用文档(http://slick.typesafe.com/doc/1.0.1/lifted-embedding.html#user-defined-functions-and-types):

// An algebraic data type for booleans
sealed trait Bool
case object True extends Bool
case object False extends Bool

// And a TypeMapper that maps it to Int values 1 and 0
implicit val boolTypeMapper = MappedTypeMapper.base[Bool, Int](
  { b => if(b == True) 1 else 0 },    // map Bool to Int
  { i => if(i == 1) True else False } // map Int to Bool
)

将此适应文件状态:

sealed trait FileStatus
case object New extends FileStatus
case object Uploading extends FileStatus
...

implicit val fileStatusTypeMapper = MappedTypeMapper.base[FileStatus, String](
  {
    case New => "new"
    case Uploading => "uploading"
    ...
  },{
    case "new" => New
    case "uploading" => Uploading
    ...
  }
)

更新:

另一个不太冗余但也可能不太清晰的版本:

sealed trait FileStatus
case object New extends FileStatus
case object Uploading extends FileStatus
...

val statusMap = Map(
    New -> "new",
    Uploading -> "uploading",
    ...
)

implicit val fileStatusTypeMapper = MappedTypeMapper.base[FileStatus, String](
  statusMap,
  statusMap.map(_.swap)
)
于 2013-09-26T23:04:57.033 回答
3

光滑的 3.x 版本:

    sealed trait FileStatus
    case object New extends FileStatus
    case object Uploading extends FileStatus
    ...

   implicit val fileStatusColumnType = MappedColumnType.base[FileStatus, String](
   {
     case New => "new"
     case Uploading => "uploading"
     ...
    },{
     case "new" => New
     case "uploading" => Uploading
     ...
   }
 )
于 2016-09-22T11:27:42.570 回答