For example I have this case class:
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)
}
Its actually a securesocial identity, now identityId is an object of case class:
case class IdentityId(
var userId:String,
var providerId:String
)
So how do I create a projection class for situations like, this?? If I had to create a projection class datatypes like String,Int it would have been no problem but what about user defined objects and classes??
I did some research and found some very useful answers here Link1 and Link2
The second link didn't have implementations for PasswordInfo so, here I have provided my own implementation, though this approach seems a bit more code, can anyone suggest a more efficient approach that is if there is one:
*Note: And the second link was very helpful, its actually whole working project example Based on Play, Slick and SecureSocial thanks to Lunatech and others.
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))
}
})
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With