scalaslick-3.0

combining slick queries into single query


Using Slick 3.1, how do I combine multiple Queries into a single query for the same type? This is not a join or a union, but combining query "segments" to create a single query request. These "segments" can be any individually valid query.

val query = TableQuery[SomeThingValid]

// build up pieces of the query in various parts of the application logic
val q1 = query.filter(_.value > 10)
val q2 = query.filter(_.value < 40)
val q3 = query.sortBy(_.date.desc)
val q4 = query.take(5)

// how to combine these into a single query ?
val finalQ = ??? q1 q2 q3 q4 ???

// in order to run in a single request
val result = DB.connection.run(finalQ.result)

EDIT: the expected sql should be something like:

SELECT * FROM "SomeThingValid" WHERE "SomeThingValid"."value" > 10 AND "SomeThingValid"."valid" < 40 ORDER BY "MemberFeedItem"."date" DESC LIMIT 5

Solution

  • val q1 = query.filter(_.value > 10)
    val q2 = q1.filter(_.value < 40)
    val q3 = q2.sortBy(_.date.desc)
    val q4 = q3.take(5)
    

    I think you should do something like the above (and pass around Querys) but if you insist on passing around query "segments", something like this could work:

    type QuerySegment = Query[SomeThingValid, SomeThingValid, Seq] => Query[SomeThingValid, SomeThingValid, Seq]
    
    val q1: QuerySegment = _.filter(_.value > 10)
    val q2: QuerySegment = _.filter(_.value < 40)
    val q3: QuerySegment = _.sortBy(_.date.desc)
    val q4: QuerySegment = _.take(5)
    
    val finalQ = Function.chain(Seq(q1, q2, q3, q4))(query)