2

In my previous question: How to create a filter that does the SQL equivalent of WHERE ... IN for SQLite.Swift

I asked how to how to do a WHERE...IN in swift.

Now, how do I filter optional Expressions?

I have a versioned database that allows me to add columns to tables after it was created. And to achieve that, I created the column with

static let timeTag = Expression<String?>("timeTag")

and then called

try DB.run("PRAGMA user_version = 2")
let query = table.addColumn(timeTag)
let _ = try DB.run(query)

all that works and the table does indeed have that column and I can add data to the column and etc.

usually when I need to filter in other columns, I do

table.filter(self.id == id && self.name == name)

and when I need to do a where in,

table.filter((myNameArray.contains(self.name))

now I want to filter for the timeTag column with an array timeTagArray which is an array of wanted timeTags to look for. I tried

table.filter(timeTagArray.contains(self.timeTag))

and the table example:

+----+-------+-----------+
| id | name  | timetag   |
+----+-------+-----------+
| 1  | Joe   | Morning   |
+----+-------+-----------+
| 2  | Alan  | Afternoon |
+----+-------+-----------+
| 3  | Brad  | Morning   |
+----+-------+-----------+
| 4  | Ian   | Evening   |
+----+-------+-----------+
| 5  | Louis | Midnight  |
+----+-------+-----------+

if my timeTagArray = ["Morning", "Midnight"] then I should get back rows 1, 3, 5.

but it gives me the error that says Cannot assign value of type 'Expression<Bool?>' (aka 'Expression<Optional<Bool>>') to type 'Expression<Bool>'

Community
  • 1
  • 1
stephw
  • 513
  • 1
  • 4
  • 19
  • 1
    It's telling you one of your parameters is optional. `Bool?` and `Bool` are not equal. You should just need to unwrap the optional (but I don't see where the actual comparison is taking place). – DJohnson Jun 07 '16 at 11:19
  • I know that but it's an `Expression` and I'm not sure how that works... I believe the error comes from the part `timeTagArray.contains(self.timeTag)` as `self.timeTag` is a `Expression` and so doing the contains gives a `Expression` which cannot be used in the `.filter` function – stephw Jun 07 '16 at 14:56
  • Have a look at GRDB query interface https://github.com/groue/GRDB.swift#the-query-interface . You'd just write `filter(timeTagArray.contains(self.timeTag))` as well, but without any error this time. – Gwendal Roué Jun 08 '16 at 07:07
  • But I am using SQLite.swift. I would only change to GRDB if there is absolutely no other alternatives as it would be too much trouble at this point. – stephw Jun 08 '16 at 07:38
  • @apikurious Sure, you're right :-) Next time, maybe - you'll have even less trouble. – Gwendal Roué Jun 08 '16 at 07:44
  • @apikurious Are you on the latest version of SQLite.swift? `[String].contains` should take an `Expression`. I tested the following in the playground and it seemed to work: `let timeTag = Expression("timeTag"); let table = Table("table"); let timeTagArray = ["Morning", "Midnight"]; table.filter(timeTagArray.contains(timeTag))` – stephencelis Jun 09 '16 at 13:55

0 Answers0