2

I have 1 table with multiple columns. On the app, we are looking forward to add 4 dynamic filters like (cat, size, color,shape).

We know we can create a filter to sqllite like so:

user = user.select(name) 
        .filter((color == "Blue") && (size = "Big") && (cat="a") && (shape="round")) 
        .order(name.asc, name) // ORDER BY "email" DESC, "name"
        .limit(5, offset: 0)

But what happens if a filter, let's say that for color we want to search for all colors. Then,

.filter((color == "?????") && (size = "Big") && (cat="a") && (shape="round"))

Any ideas on how to create dynamic filters for this case?

danielsalare
  • 335
  • 3
  • 14

1 Answers1

10

The filter() method takes an Expression<Bool> argument, and compound expressions can be created dynamically with the logical operators &&, ||, etc.

Simple example:

// Start with "true" expression (matches all records):
var myFilter = Expression<Bool>(value: true)

// Dynamically add boolean expressions:
if shouldFilterColor {
    myFilter = myFilter && (color == "Blue")
}
if shouldFilterSize {
    myFilter = myFilter && (size == "Big")
}
// ... etc ...

// Use compound filter:
query = user.select(name) 
        .filter(myFilter) 
        .order(name.asc, name)
        .limit(5, offset: 0)
Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • For some reason the filter is not working on my side, it's not marking errors or warnings and seems to be a good way to go. I've tried this (removed ifs) but no luck. var myFilter = Expression(value: true) myFilter = myFilter && (name == "Facebook") – danielsalare Jul 23 '15 at 20:59
  • @edse: It worked in my simple test, that's all I can say. Note that you can inspect the generated SQL code with `println(myFilter.SQL)` and `println(myFilter.bindings)`, perhaps that helps to isolate the problem. – Martin R Jul 23 '15 at 21:04
  • not doubting it works, it's clear that is the solution but I can't seem to make it work properly. This is the code I have, but don't know why when filtering it wont work. :S https://gist.githubusercontent.com/edse83/e03df13150eaf8e0c193/raw/751ba4fdd5ba8c10106ced595e3be6bef80451dd/Sqlite%20dynamic%20filters – danielsalare Jul 23 '15 at 21:54
  • 1
    Because the filter is being built up dynamically, you can avoid the `true` expression by setting up a base query: `let base = users.select(name).order(name.asc).limit(5); let filtered: Query; if shouldFilterColor { filtered = base.filter(color == "Blue") }…`. – stephencelis Aug 05 '15 at 11:36