我有一个enum
的PostgreSQL表,它由:
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 required:Int
为什么需要Int?是因为TypeMapper吗?我也试过
...
f => f.toString
// type mismatch; found : String required: models.Files.FileStatus
f => f
// type mismatch; found : String required: models.Files.FileStatus
感谢您帮助我理解这种映射的任何指示。
答案 0 :(得分:10)
引用文档(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)
)
答案 1 :(得分:2)
Slick 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
...
}
)