scala - In Slick 3.0, how to simplify nested `db.run`? -
i'm using slick 3.0, , following codes:
def registermember(newmember: teammember): future[long] = { db.run( teamprofiletable.filter(u => u.id === newmember.id).result.headoption ).flatmap { case none => future(-1) case _ => db.run( (teamprofiletable returning teamprofiletable.map(_.staffid)) += newmember.toteamrecord ) } }
this may ok. when there more layers of callback, codes may become hard read. tried simplify codes using for-expression
or andthen
.. due pattern matching part, can use flatmap
implement this..
does have ideas how refactor this?
i think comprehension should okay here, need conditional handling of option
in result of first future
. should work (note did not compile check this):
def registermember(newmember: teammember): future[long] = { for{ r1opt <- db.run(teamprofiletable.filter(u => u.id === newmember.id).result.headoption r2 <- r1opt.fold(future.successful(-1l))(r1 => db.run((teamprofiletable returning teamprofiletable.map(_.staffid)) += newmember.toteamrecord) } yield r2 }
you can see on right side of fold
have access result of first future
if some
(as r1
).
i take step further , create separate methods steps of comprehension clean things up, so:
def registermember(newmember: teammember): future[long] = { def findmember = db.run(teamprofiletable.filter(u => u.id === newmember.id).result.headoption def addmember(r1opt:option[teammember]) = { r1opt.fold(future.successful(-1l)){r1 => db.run((teamprofiletable returning teamprofiletable.map(_.staffid)) += newmember.toteamrecord) } } for{ r1opt <- findmember r2 <- addmember(r1opt) } yield r2 }
Comments
Post a Comment