Skip to content

Enabling FTS5 #518

Closed
Closed
@gennaios

Description

@gennaios

What did you do?

Hello. Thank you for this wonderful framework. I'm in the process of trying to migrate a macOS app from Realm to GRDB. As I have learned of SQLite and its FTS5 capabilities, I have started to use FTS5 in another app w/o issues. Now trying to integrate GRDB into project, I have some questions and an issue.

What did you expect to happen?

I am unsure of the enabling FTS5 instructions. My Podfile is as such :

target 'Biblia' do
  platform :osx, '10.14'
  use_frameworks!
  pod 'GRDB.swift', :git => 'https://github.com/groue/GRDB.swift.git', :branch => 'GRDB-4.0'

  post_install do |installer|
    installer.pods_project.targets.select { |target| target.name == "GRDB.swift" }.each do |target|
      target.build_configurations.each do |config|
        config.build_settings['OTHER_SWIFT_FLAGS'] = "$(inherited) -D SQLITE_ENABLE_FTS5"
      end
    end
  end
end

The instructions don't specify use_frameworks! but if I leave that out, I get the warning [!] Using Swift static libraries with custom module maps is currently not supported. Please build GRDB.swift as a framework or remove the custom module map. Otherwise I get this error from pod install :

[!] The `Biblia [Debug]` target overrides the `OTHER_LDFLAGS` build setting defined in `Pods/Target Support Files/Pods-Biblia/Pods-Biblia.debug.xcconfig'. This can lead to problems with the CocoaPods installation
    - Use the `$(inherited)` flag, or
    - Remove the build settings from the target.

[!] The `Biblia [Release]` target overrides the `OTHER_LDFLAGS` build setting defined in `Pods/Target Support Files/Pods-Biblia/Pods-Biblia.release.xcconfig'. This can lead to problems with the CocoaPods installation
    - Use the `$(inherited)` flag, or
    - Remove the build settings from the target.

I am not very experienced with macOS development and perhaps it is from some other setting due to using other frameworks with Carthage. I have tried to look for OTHER_LDFLAGS w/o success. Perhaps that's an unrelated issue.

What happened instead?

Perhaps the integration is not correct. Upon trying to run a FTS5 query, I get the following error :

Fatal error: 'try!' expression unexpectedly raised an error: SQLite error 1 with statement SELECT * FROM files JOIN filesindex ON filesindex.rowid = files.id WHERE files.file_extension = 'epub' AND filesindex MATCH 'test' ORDER BY files.date_created DESC: error in tokenizer constructor: file …, line 361

I have tried using sql arguments with and without specifying single quotes after MATCH.

My code looks like the following. Using an NSTableView, results are refetched upon change in a text field :

if searchString != "" {
    var terms = [String]()
    for item in searchString.components(separatedBy: " ") {
        terms.append(item + "*")
    }
    let queryString = terms.joined(separator: " ") // make all terms wildcard

    try! filesController.setRequest(sql: "SELECT * FROM files JOIN filesindex ON filesindex.rowid = files.id WHERE files.file_extension = 'epub' AND filesindex MATCH 'test' ORDER BY files.date_created DESC")
} else {
    try! filesController.setRequest(File.filter(Column("file_extension") == "epub").order(Column("date_created").desc))
}
import GRDB

struct File {
    var id: Int64?
    var path: String
    var file_name: String
    var file_extension: String
    var file_size: Int64
    var file_title: String?
    var file_authors: String?
    var file_subjects: String?
    var file_publisher: String?
    var date_created: Date
    var date_modified: Date?
    var date_accessed: Date?
    var rating: Int64
    var hash: String
}

extension File: Codable, FetchableRecord, TableRecord, MutablePersistableRecord {
    static let databaseTableName = "files"

    private enum CodingKeys: String, CodingKey, ColumnExpression {
        case id, path, file_name, file_extension, file_size, file_title, file_authors, file_subjects, file_publisher, date_created, date_modified, date_accessed, rating, hash
    }

    enum Columns: String, ColumnExpression {
        case id, path, file_name, file_extension, file_size, file_title, file_authors, file_subjects, file_publisher, date_created, date_modified, date_accessed, rating, hash
    }

    mutating func didInsert(with rowID: Int64, for column: String?) {
        id = rowID
    }

    static func orderedByTitle() -> QueryInterfaceRequest<File> {
        return File.order(CodingKeys.file_title)
    }

    static func orderedByDateCreated() -> QueryInterfaceRequest<File> {
        return File.order(CodingKeys.date_created.desc, CodingKeys.date_created)
    }
}

As I am just getting started, there remains some confusion of using Codable, FetchableRecord, TableRecord, and MutablePersistableRecord. Perhaps TableRecord isn't needed though I saw it as the only place to specify a SQLite table name (files rather than file). I am also unsure when to use enum CodingKeys or enum Columns – I have been able to get a NSTableView to load all data, though as I add other queries I'll figure it out –, and as such I have so far specified both. Perhaps that is part of the problem.

The documentation is terrific although I think there remains a bit of ambiguity, as I have hinted at above. Help would be much appreciated. Mille mercis.

Environment

GRDB flavor(s): GRDB
GRDB version: GRDB-4.0 branch
Installation method: CocoaPods
Xcode version: 10.2
Swift version: 4.2
Platform(s) running GRDB: macOS
macOS version running Xcode: 10.14

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions