Skip to content

Instantly share code, notes, and snippets.

@aholland
Last active March 23, 2017 09:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aholland/0845bf29d836d672d006ab58f5f1c73c to your computer and use it in GitHub Desktop.
Save aholland/0845bf29d836d672d006ab58f5f1c73c to your computer and use it in GitHub Desktop.
Some Slick/ Shapeless code that nearly works.
//This method works but it is verbose and is specific to the firstNames column
def updatePD_FirstNames(id: ids.PersonalDetailsId, firstNames: StringLtd30): Future[Int] = {
val q1: Query[tables.PersonalDetails, PersonalDetailsRow, Seq] = for {
row: tables.PersonalDetails <- tables.PersonalDetails if row.id === id
} yield {
row
}
//This mapper can instead be put into the parameter list. That works and is what I have done in updatePD_SL, on line 19 below.
val mapper: tables.PersonalDetails => tables.profile.api.Rep[StringLtd30] = (pdTable: tables.PersonalDetails) => {
val r: tables.profile.api.Rep[StringLtd30] = pdTable.firstNames
r
}
val q2: Query[tables.profile.api.Rep[StringLtd30], StringLtd30, Seq] = q1.map(mapper)
vnLog.info("updatePD_FirstNames: SQL=" + q1.updateStatement)
db.run(q2.update(firstNames))
}
// This version of the method takes parameter mappper and works fine. It can be used for any column of type StringLtd30 as
// in def updatePD_Surname and def updatePD_FirstNames2 below
def updatePD_SL(id: ids.PersonalDetailsId, mapper: tables.PersonalDetails => tables.profile.api.Rep[StringLtd30], sl: StringLtd30): Future[Int] = {
val q1: Query[tables.PersonalDetails, PersonalDetailsRow, Seq] = for {
row: tables.PersonalDetails <- tables.PersonalDetails if row.id === id
} yield {
row
}
val q2: Query[tables.profile.api.Rep[StringLtd30], StringLtd30, Seq] = q1.map(mapper)
db.run(q2.update(sl))
}
//This vesrion of the method takes it a step further by trying to replace StringLtd30 with type parameter X. This does not compile.
//It gives the shapeless error shown at the bottom.
def updatePD_X[X](id: ids.PersonalDetailsId, mapper: tables.PersonalDetails => tables.profile.api.Rep[X], sl: X): Future[Int] = {
val q1: Query[tables.PersonalDetails, PersonalDetailsRow, Seq] = for {
row: tables.PersonalDetails <- tables.PersonalDetails if row.id === id
} yield {
row
}
val q2: Query[tables.profile.api.Rep[X], X, Seq] = q1.map(mapper)
db.run(q2.update(sl))
}
def updatePD_FirstNames2(id: ids.PersonalDetailsId, firstNames: StringLtd30): Future[Int] = {
val mapper: tables.PersonalDetails => tables.profile.api.Rep[StringLtd30] = (pdTable: tables.PersonalDetails) => {
val r: tables.profile.api.Rep[StringLtd30] = pdTable.firstNames
r
}
updatePD_SL(id, mapper,firstNames)
}
def updatePD_Surname(id: ids.PersonalDetailsId, surname: StringLtd30): Future[Int] = {
updatePD_SL(id, (t: tables.PersonalDetails) => t.surname, surname)
}
def updatePD_Email(id: ids.PersonalDetailsId, emailAddress: Email254): Future[Int] = {
updatePD_X(id, (t: tables.PersonalDetails) => t.email, emailAddress)
}
/*
[server] $ compile
[info] Compiling 1 Scala source to C:\Workspace\IdeaProjects\Vintur\play\server\target\scala-2.12\classes...
[error] C:\Workspace\IdeaProjects\Vintur\play\server\app\schema\DbProxy.scala:688: No matching Shape found.
[error] Slick does not know how to map the given types.
[error] Possible causes: T in Table[T] does not match your * projection,
[error] you use an unsupported type in a Query (e.g. scala List),
[error] or you forgot to import a driver api into scope.
[error] Required level: slick.lifted.FlatShapeLevel
[error] Source type: slick.lifted.Rep[X]
[error] Unpacked type: T
[error] Packed type: G
[error] val q2: Query[tables.profile.api.Rep[X], X, Seq] = q1.map(mapper)
[error] ^
[error] one error found
[error] (server/compile:compileIncremental) Compilation failed
[error] Total time: 4 s, completed 23-Mar-2017 11:15:47
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment