scala - 如何为复杂的案例类创建投影类?

标签 scala slick slick-2.0 play-slick

例如我有这个案例类:

case class User(
  var identityId: IdentityId, //Its a user created class
  var firstName: String,
  var lastName: String,
  var fullName: String,
  var email: Option[String],
  var avatarUrl: Option[String],
  var authMethod: AuthenticationMethod,
  var oAuth1Info: Option[OAuth1Info] = None,
  var oAuth2Info: Option[OAuth2Info] = None,
  var passwordInfo: Option[PasswordInfo] = None) extends Identity {

  def this() = this(null, "", "", "", None, None, null, None, None, None)

}

它实际上是一个安全的社会身份,现在 identityId 是 case 类的对象:
case class IdentityId(
var userId:String,
var providerId:String
)

那么我如何为这种情况创建一个投影类?如果我必须创建一个像 String,Int 这样的投影类数据类型,那没有问题,但是用户定义的对象和类呢??

最佳答案

我做了一些研究,在这里找到了一些非常有用的答案
Link1Link2

第二个链接没有 PasswordInfo 的实现,所以,在这里我提供了我自己的实现,虽然这种方法看起来更多的代码,但任何人都可以提出一种更有效的方法,如果有的话:

*注意:第二个链接非常有用,它实际上是基于 Play、Slick 和 SecureSocial 的整个工作项目示例,感谢 Lunatech 和其他人。

class Users(tag: Tag) extends Table[User](tag, "user") {

  implicit def string2AuthenticationMethod = MappedColumnType.base[AuthenticationMethod, String](
    authenticationMethod => authenticationMethod.method,
    string => AuthenticationMethod(string))

  implicit def tuple2OAuth1Info(tuple: (Option[String], Option[String])): Option[OAuth1Info] = tuple match {
    case (Some(token), Some(secret)) => Some(OAuth1Info(token, secret))
    case _ => None
  }

  implicit def tuple2OAuth2Info(tuple: (Option[String], Option[String], Option[Int], Option[String])): Option[OAuth2Info] = tuple match {
    case (Some(token), tokenType, expiresIn, refreshToken) => Some(OAuth2Info(token, tokenType, expiresIn, refreshToken))
    case _ => None
  }

  implicit def tuple2PasswordInfo(tuple: (Option[String], Option[String], Option[String])) = tuple match {
    case (Some(hasher), Some(password), salt) =>
      Some(PasswordInfo(hasher, password, salt))
    case _ => None
  }

  implicit def tuple2IdentityId(tuple: (String, String)): IdentityId = tuple match {
    case (userId, providerId) => IdentityId(userId, providerId)
  }

  def uid = column[Long]("id", O.PrimaryKey, O.AutoInc)
  def userId = column[String]("userId")
  def providerId = column[String]("providerId")
  def email = column[Option[String]]("email")
  def firstName = column[String]("firstName")
  def lastName = column[String]("lastName")
  def fullName = column[String]("fullName")
  def authMethod = column[AuthenticationMethod]("authMethod")
  def avatarUrl = column[Option[String]]("avatarUrl")
  // oAuth 1
  def token = column[Option[String]]("token")
  def secret = column[Option[String]]("secret")
  // oAuth 2
  def accessToken = column[Option[String]]("accessToken")
  def tokenType = column[Option[String]]("tokenType")
  def expiresIn = column[Option[Int]]("expiresIn")
  def refreshToken = column[Option[String]]("refreshToken")
  //PasswordInfo
  def hasher = column[Option[String]]("hasher")
  def password = column[Option[String]]("password")
  def salt = column[Option[String]]("salt")

  def * : ProvenShape[User] = {
    val shapedValue = (
      userId,
      providerId,
      firstName,
      lastName,
      fullName,
      email,
      avatarUrl,
      authMethod,
      token,
      secret,
      accessToken,
      tokenType,
      expiresIn,
      refreshToken,
      hasher,
      password,
      salt).shaped
    shapedValue.<>({
      tuple =>
        User.apply(
          identityId = tuple2IdentityId(tuple._1, tuple._2),
          firstName = tuple._3,
          lastName = tuple._4,
          fullName = tuple._5,
          email = tuple._6,
          avatarUrl = tuple._7,
          authMethod = tuple._8,
          oAuth1Info = (tuple._9, tuple._10),
          oAuth2Info = (tuple._11, tuple._12, tuple._13, tuple._14),
          passwordInfo = (tuple._15, tuple._16, tuple._17))
    }, {
      (u: User) =>
        Some {
          (u.identityId.userId,
            u.identityId.providerId,
            u.firstName,
            u.lastName,
            u.fullName,
            u.email,
            u.avatarUrl,
            u.authMethod,
            u.oAuth1Info.map(_.token),
            u.oAuth1Info.map(_.secret),
            u.oAuth2Info.map(_.accessToken),
            u.oAuth2Info.flatMap(_.tokenType),
            u.oAuth2Info.flatMap(_.expiresIn),
            u.oAuth2Info.flatMap(_.refreshToken),
            u.passwordInfo.map(_.hasher),
            u.passwordInfo.map(_.password),
            u.passwordInfo.flatMap(_.salt))
        }
    })
  }
}

关于scala - 如何为复杂的案例类创建投影类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25339983/

相关文章:

scala - 如何将列作为要加入的键的集合加入数据集?

scala - 隐式 val GetResult 中的发散式隐式扩展

Java 玩!框架开发

java - 在编译时限制对象类型路径

java - 将带有样本的数组转换为字节数组

scala - "right"在 Play Framework 中使用 write Slick 3.0 Scala 查询的方法

scala:运行一个 play-slick 示例导致导入错误

scala - Slick "==="仅编译用于理解

scala - Slick - 使用动态 sortBy 编译