scala - Reference compound primary key -


i'm new slick , first attempt of creating application it.

i have case class user(userid: uuid, firstname: string, lastname: string).

users can log in. case class logininfo(providerid: string, providerkey: string) comes in (i'm using silhouette authentication).

i'd associate every user logininfo using slick table:

class userswithlogininfos(tag:tag) extends table[(primarykey, uuid)](tag, "users_with_login_infos"){   def logininfoid = tablequery[logininfos].shaped.value.logininfoid   def userid = column[uuid]("user_id")   def * = (logininfoid, userid) <>(userwithlogininfo.tupled, userwithlogininfo.unapply) } 

this corresponding case class userwithlogininfo(logininfoid: primarykey, userid: uuid).

my tables users , logininfos straightforward:

class logininfos(tag: tag) extends table[logininfo](tag, "login_infos") {    // primary key of table compound: consists of provider's id , key   def logininfoid = primarykey("login_info_id", (providerid, providerkey))    // "credentials" example   def providerid = column[string]("provider_id")    // "admin@nowhere.com" example   def providerkey = column[string]("provider_key")    def * = (providerid, providerkey) <>(logininfo.tupled, logininfo.unapply) } class users(tag: tag) extends table[user](tag, "users") {    def id = column[uuid]("id", o.primarykey)    def firstname = column[string]("first_name")    def lastname = column[string]("last_name")    def * = (id, firstname, lastname) <>(user.tupled, user.unapply) } 

unfortunately, doesn't typecheck:

def * = (logininfoid, userid) <>(userwithlogininfo.tupled, userwithlogininfo.unapply) 

expression of type mappedprojection[userwithlogininfo, (primarykey, uuid)] doesn't conform expected type provenshape[(primarykey, uuid)]

i work around introducing case class logininfowithid(info: logininfo, id: uuid) hope away referencing logininfo's compound primary key directly.

is there way this? or on wrong track entirely?

i'm using slick 3.0.0.

i'm not quite sure trying achieve here, if user associated loginfinfo (untested code ahead):

class logininfos(tag: tag) extends table[logininfo](tag, "login_infos") {   def providerid = column[string]("provider_id")   def providerkey = column[string]("provider_key")    def * = (providerid, providerkey) <>(logininfo.tupled, logininfo.unapply)   def pk = primarykey("pk_login_info_id", (providerid, providerkey)) }  class users(tag: tag) extends table[user](tag, "users") {   def id = column[uuid]("id", o.primarykey)   def firstname = column[string]("first_name")   def lastname = column[string]("last_name")    def * = (id, firstname, lastname) <>(user.tupled, user.unapply) }  class userswithlogininfos(tag:tag) extends table[(providerid: string, providerkey: string, uuid: string)](tag, "users_with_login_infos"){   def providerid = column[string]("user_provider_id")   //  column name assumption   def providerkey = column[string]("user_provider_key") //  column name assumption   def userid = column[uuid]("user_id")    def pk = primarykey("pk_user_with_login_info_id", (providerid, providerkey)) }   case class userwithlogininfo(user: user, logininfo: logininfo) 

you can optionally wrap tuple3 in userswithlogininfosin case class if to. however, example query user joined logininfo:

def finduserwithlogininfo(providerid: string, providerkey: string): future[option[userwithlogininfo]] = {   val query = (for {     user <- tablequery[users] if user.providerid === providerid && user.providerkey === providerkey     usertologininfo <- tablequery[userswithlogininfos] if usertologininfo.userid === user.id     logininfo <- tablequery[logininfos] if usertologininfo.providerid === logininfo.providerid && usertologininfo.providerid === logininfo.providerkey   } yield userwithlogininfo(user, logininfo))    db.run(query.result.headoption) } 

instead of writing rather verbose query above, can define foreign key constraint described here slick documentation, constraints.

also found coming orm slick useful when started using slick. remember, slick not orm , things quite different :)


Comments

Popular posts from this blog

c++ - llvm function pass ReplaceInstWithInst malloc -

java.lang.NoClassDefFoundError When Creating New Android Project -

Decoding a Python 2 `tempfile` with python-future -