1

I have the need to perform some queries that may depend on external supplied parameters via a REST interface. For instance a client may require an URL of the form

some/entities?foo=12&bar=17

The parameters, say foo, bar and quux are all optional. So I start from designing some queries with Squeryl, like

object Entity {
  def byFoo(id: Long) = from(DB.entities)(e =>
    where(e.foo === id)
    select(e)
  )
  // more criteria
}

But of course I want to avoid the combinatorial explosion that arises, so I only design three queries, which in turn may take their data from another query:

object Entity {
  def byFoo(id: Long, source: Query[Entity] = DB.entites) = from(source)(e =>
    where(e.foo === id)
    select(e)
  )
  def byBar(id: Long, source: Query[Entity] = DB.entites) = from(source)(e =>
    where(e.bar === id)
    select(e)
  )
  // more criteria
}

Now I can combine them and run a query like

val result = Entity.byFoo(12,
  source = Entity.byBar(17)
)

The only problem I have with this approach is that behind the scenes Squeryl is going to generate a subquery, which may be inefficient. With a more typical query builder, I would be able to combine the queries and get the equivalent of the following:

from(DB.entities)(e =>
  where(
    e.foo === 12 and
    e.bar === 17
  )
  select(e)
)

Is there a different way to dynamically combine queries in Squeryl that will lead to this more efficient form?

Andrea
  • 20,253
  • 23
  • 114
  • 183

1 Answers1

2

The first thing I think you should look into is inhibitWhen, which you can find in the documentation. The gist of it is that you model your query like:

var foo: Option[Int] = None
var bar: Option[Int] = None

from(DB.entities)(e =>
  where(
    e.foo === foo.? and
    e.bar === bar.?)
  select(e))

The ? operator in the first expression is equivalent to (e.foo === foo).inhibitWhen(foo == None)

Dave Whittaker
  • 3,102
  • 13
  • 14
  • Thank you very much! I will have a look after the weekend, as I do not have the source available now. – Andrea Nov 24 '12 at 16:24
  • Thank you, it is exactly what I needed. I somehow managed not to notice that chapter of the docs. – Andrea Nov 30 '12 at 09:59