scala - SLICK 3.0 - multiple queries depending on one another - db.run(action) -


i new slick 3 , far have understood db.run asynchronous call. .map or .flatmap run once future returned.

the problem in code below sub queries not work (nested db.run).

conceptually speaking, not getting? valid kind of code below? in .map of first query actions depending on first query.

i see everywhere for loops yield, way go? problem in code related returned future value?

val enterprises = tablequery[enterprise] val salaries = tablequery[salary]  //check if entered enterprise exists  val enterpriseqs = enterprises.filter(p => p.name.touppercase.trim === salaryitem.enterprisename.touppercase.trim).result  val result=db.run(enterpriseqs.headoption).map(_ match  {     case some(n) => {       //if enterprise exists use id enterprise (n.id) when adding record salary table       val addsalary1 = salaries += new salaryrow(0, n.id, salaryitem.worker)       db.run(addsalary1)     }     case none =>  {         //if enterprise salaryitem.enterprisename doesn't exist, new enterprise inserted in db         val enterpriseid = (enterprises returning enterprises.map(_.id)) += enterpriserow(0, salaryitem.enterprisename)         db.run(enterpriseid).map{             e => {                 val salaryadd2 = salaries += new salaryrow(0, e, salaryitem.worker)                 db.run(salaryadd2)             }         }     } }) 

the problem in code below sub queries not work (nested db.run)

i suspect you're ending nested future[r] results. i've not investigated though. because...

conceptually speaking, not getting?

the way i'd tackle @ combining dbio[r]. might concept helps.

what you're doing trying run each action (query, insert...) individually. instead, combine individual actions single action , run that.

i'd re-write main logic this:

  val action: dbio[int] = {     existingenterprise <- enterpriseqs.headoption     rowsaffected       <- existingenterprise match {       case some(n) => salaries += new salaryrow(0, n.id, salaryitem.worker)       case none    => createnewenterprise(salaryitem)     }   } yield rowsaffected 

for none case i'd create helper method:

  def createnewenterprise(salaryitem: salaryitem): dbio[int] = {     eid          <- (enterprises returning enterprises.map(_.id)) += enterpriserow(0, salaryitem.enterprisename)     rowsaffected <- salaries += new salaryrow(0, eid, salaryitem.worker)   } yield rowsaffected 

finally, can run that:

  val future: future[int] = db.run(action)   // or db.run(action.transactionally)        val result = await.result(future, 2 seconds)    println(s"result of action is: $result") 

the second half of blog post i've written talks more this.

the code i've used is: https://github.com/d6y/so-31471590


Comments