Inside a for-comp
I need to set up some queries that will be then run in a single shot later... say, something like:
val queries = for {
_ <- query1
_ <- query2
id <- someInsertQuery
} yield id
db.run(queries.transactionally)
Now, I need to set up conditions on the first 2 queries. If a condition is met, the queries should run, nothing otherwise. So I thought:
val queries = for {
_ <- if (condition1) query1 else Query.empty
_ <- if (condition2) query2 else Query.empty
id <- someInsertQuery
} yield id
db.run(queries.transactionally)
But this doesn't work:
value flatMap is not a member of Object
[error] _ <- if (condition1) query1 else Query.empty
[error] ^
So I bet what I am trying to do is not this way. What would be the proper way to achieve this?
CodePudding user response:
The best way I have been able to solve it til now is by getting the condition inside a filter
. Roughly:
val queries = for {
_ <- query1.filter(condition1)
_ <- query2.filter(condition2)
id <- someInsertQuery
} yield id
db.run(queries.transactionally)
Let me know if you have other ideas.
CodePudding user response:
I think you have some misunderstanding with for-yield construction.
In the scala, for-yield is just syntactic sugar under some combinations of flatMap
, map
functions. When you write:
val queries = for {
_ <- if (condition1) query1 else Query.empty
_ <- if (condition2) query2 else Query.empty
res <- someInsertQuery
} yield res
for the compiler it is the same as:
query1.flatMap(_ => query2.flatMap(_ => someInsertQuery.map(res => res)))
The compiler said you what you have something wrong on the place query1
because it thinks what it is an Object
and can't find flatMap
in this object. You should check what is query1
and make it something like Query
This code compilable:
import slick.jdbc.JdbcBackend
import slick.lifted.Query
import slick.jdbc.PostgresProfile.api._
val db: JdbcBackend.Database = ???
val query1: Query[Unit, Unit, Seq] = ???
val query2: Query[Unit, Unit, Seq] = ???
val someInsertQuery: Query[Unit, Unit, Seq] = ???
val condition1 = false
val condition2 = true
val queries = for {
_ <- if (condition1) query1 else Query.empty
_ <- if (condition2) query2 else Query.empty
res <- someInsertQuery
} yield res
db.run(queries.result.transactionally)