Slick 3 offers DBIOAction composition by using flatMap method. Also, we can do some calculations in back-end between two DBIOActions. That's works fine in most cases, but what I should do when calculations result is in the monad like Future? There is code with blocking way:
val fooQuery = TableQuery[FooTable]
val barQuery = TableQuery[BarTable]
def requestService(content: Iterable[String]): Future[Iterable[Long]] = ???
def modify(ids: Iterable[Long], change: String) = {
val query = fooQuery.filter(_.id inSet ids).result.flatMap{ fooSeq =>
val content = fooSeq.map(_.contentField)
val requestServiceFuture = requestService(content)
val serviceResult = Await.result(requestServiceFuture, 1.minute)
barQuery.filter(_.id inSet serviceResult).delete //or other action
}
db.run(query.transactionally)
}
Is there way to perform this code asynchronously, without Await?
You can create DBIO
from Future
using DBIOAction.from
and then compose with other DBIOs using flatMap
val query = for {
fooSeq <- fooQuery.filter(_.id inSet ids).result
content = fooSeq.map(_.contentField)
serviceResult <- DBIOAction.from(requestService(content))
result <- barQuery.filter(_.id inSet serviceResult).delete
} yield result
db.run(query.transactionally)
http://slick.lightbend.com/doc/3.1.1/api/index.html#slick.dbio.DBIOAction$
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With