How to create a projection class for a complex case class in slick?

For example, I have a 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) } 

This is actually a securesocial identity, now identityId is an object of the 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 design class data types such as String, Int, that would not be a problem, but what about user-defined objects and classes?

+6
source share
1 answer

I did some research and found here very useful answers Link1 and Link2

The second link had no implementations for PasswordInfo, so here I presented my own implementation, although this approach looks a bit more code, can anyone suggest a more efficient approach, which is, if there is one:

* Note. And the second link was very useful, its practically the whole working example of the project. 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)) } }) } } 
+5
source

Source: https://habr.com/ru/post/973895/


All Articles