cognophile
cognophile

Reputation: 917

SQLite.swift: Can't retrieve table count due to unrecognized token: ":"

I'm trying to retrieve a count of records in a table using SQLite.swift and Swift in a Cocoa macOS application. According to the README, this can be achieved using the following:

let users = Table("users")
...
let count = try db.scalar(users.count)

However, when this code is executed (from a button click event handler), the following exception is thrown:

Fatal error: 'try!' expression unexpectedly raised an error: unrecognized token: ":" (code: 1): file...

The offending code is the db access line below. The db object is assigned with a Connection object returned from a separate Database struct function when the view loads. I believe this is valid and unrelated as other areas of code are using the same method to open connections to the database successfully.

let login = Login()
var db : Connection?
...
let count = try! db?.scalar(login.table.count)

Here's the query expression it produces. In text, this appears to be SELECT count(_:)(*) FROM login.

enter image description here

However, interestingly, if I use the following line, the correct result is returned.

let count = try! db?.scalar(“SELECT COUNT(*) FROM login”)

The model for this Login object is:

import SQLite

public struct Login {
    let table = Table("login")

    // Bunch of properties for various record fields
    init() {}
}

Any and all help would be appreciated. Thanks in advance!

Upvotes: 2

Views: 1064

Answers (1)

cognophile
cognophile

Reputation: 917

It turned out to have been an issue in SQLite.swift itself, as I suspected. I found the following SQLite.swift issues on GitHub reporting this issue a few days ago.

The issue was the following, as described by the reporter, tanzolone:

In Xcode 10.2 beta 4 the macro#functionshows a different behaviour. As SQLite.swift relies on #function in different subroutines for the composition of SQLite queries, several bugs linked to invalid SQLite statements seem to be introduced.

I have just run the SQLite.swift tests with Xcode 10.2 beta 4 and there are several failures linked to this issue.

An example as follows: In the following helper function (Helpers.swift line 107):

func wrap<T>(_ expression: Expressible, function: String = #function) -> Expression<T> {
    return function.wrap(expression)
}

when called from

static func count(_ star: Star) -> Expression<UnderlyingType>

the value of the function when running in Xcode 10.2 beta 4 is count(_:) instead of count. This leads to invalid SQLite statements of the type SELECT count(_:)(*) myTable.

The project maintainers have now resolved this issue at the latest HEAD of master (currently 1a908a7da11852f252e7c6b6366a4d9f8a7d5272).

In my project, the line which required updating was the following in my Podfile:

pod 'SQLite.swift/SQLCipher', :git => 'https://github.com/stephencelis/SQLite.swift.git', :commit => 'ed8f603f856e9f1f4adb76b63b7234547257ec5a'

This was updated to:

pod 'SQLite.swift/SQLCipher', :git => 'https://github.com/stephencelis/SQLite.swift.git', :branch => 'master'

Alternatively, one can reference the commit itself:

pod 'SQLite.swift/SQLCipher', :git => 'https://github.com/stephencelis/SQLite.swift.git', :commit => '1a908a7da11852f252e7c6b6366a4d9f8a7d5272'

To update this reference, I took the following CLI steps in my project root to remove, update, and install the projects pods:

$ pod cache clean --all
$ rm -rf Pods/
$ rm Podfile.lock
$ open -a Xcode Podfile   # Updated the SQLite.swift project ref to the above
$ pod install

This then resolved the issue and the exception is no longer thrown.

Upvotes: 2

Related Questions