Home > Enterprise >  How to define an empty query
How to define an empty query

Time:09-17

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)
  • Related