如何在光滑的情况下为复杂的案例类创建投影类?

时间:2014-08-16 12:07:41

标签: 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)

}

它实际上是一个secSecocial标识,现在identityId是案例类的对象:

case class IdentityId(
var userId:String,
var providerId:String
)

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

1 个答案:

答案 0 :(得分:6)

我做了一些研究,并在这里找到了一些非常有用的答案 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))
        }
    })
  }
}