Swift GRDB Array of SQL Arguments interpolation not working

83 Views Asked by At

I'm using the latest version of GRDB and I'm trying to pass to a SQLRequest an array of arguments like this:

class GamesDao {

private var dbQueue: DatabaseQueue?

init(dbQueue: DatabaseQueue) {
    self.dbQueue = dbQueue
}

func getAllExcluding(excluded: [String]) throws -> [GameAndStuff] {
    let params = excluded.joined(separator: "', '")

    return try dbQueue!.read { db in
        return try SQLRequest(
             """
        SELECT
        g._id as g__id
        FROM games as g
        WHERE g._id NOT IN (\(params))
        """
        ).fetchAll(db)
    }
}

}

However, GRDB library is processing wrong the string interpolation as follows:

SELECT
   g._id as g__id
FROM games as g
WHERE g._id NOT IN (?)`, arguments: ["game1\', \'game2\', \'game3\', \'game4\', \'game5'"]

And is not injecting the actual arguments into the IN clause, it looks like the interpolation is not working.

Any hint about how can I fix this?

1

There are 1 best solutions below

0
Gwendal Roué On

When using SQL interpolation, just pass in the raw array:

func getAllExcluding(excluded: [String]) throws -> [GameAndStuff] {
    try dbQueue!.read { db in
        try SQLRequest("""
            SELECT g._id as g__id
            FROM games as g
            WHERE g._id NOT IN \(excluded)
            """).fetchAll(db)
    }
}

Note how the array is not wrapped in parenthesis in the Swift SQL literal: IN \(excluded).

Parenthesis are added during interpolation: IN \(["1", "2", "3"]) is interpolated as the IN (?, ?, ?) SQL snippet, with 1, 2 and 3 as statement arguments for the ? placeholders.