New release: GRDB 4.0.0

Hello Swift Community,

Version 4.0.0 of GRDB, the toolkit for SQLite databases, is out!

This release is focused on Swift 5, and enhancements on associations between record types.

What's new?

  • Associations, which let you define links between record types, are now able to eager load "to-many" relationships.

    Given this database schema:

    You can now fetch all authors along with their books with a single request:

    // Setup
    struct Author: TableRecord, Decodable {
        static let books = hasMany(Book.self)
        var id: Int64
        var name: String
    }
    
    struct Book: TableRecord, Decodable {
        var id: Int64
        var authorId: String
        var title: String
    }
    
    // Fetch all authors with their respective books
    struct AuthorInfo: FetchableRecord, Decodable {
        var author: Author
        var books: [Book]
    }
    let request = Author.including(all: Author.books)
    let authorInfos: [AuthorInfo] = try dbQueue.read { db in
        try AuthorInfo.fetchAll(db, request)
    }
    
  • Associations have also improved their support for many-to-many relationships:

    You can now express that a country has many citizens through its passports:

    // Setup
    struct Country: TableRecord, EncodableRecord {
        static let passports = hasMany(Passport.self)
        static let citizens = hasMany(
            Citizen.self,
            through: passports,
            using: Passport.citizen)
    
        var code: String
        var name: String
    
        var citizens: QueryInterfaceRequest<Citizen> {
            return request(for: Country.citizens)
        }
    }
    
    struct Passport: TableRecord {
        static let citizen = belongsTo(Citizen.self)
    }
    
    struct Citizen: TableRecord, FetchableRecord, Decodable {
        var id: Int64
        var name: String
    }
    
    // Fetch citizens from a country
    let country: Country = ...
    let citizens: [Citizen] = try dbQueue.read { db in
        try country.citizens.fetchAll(db)
    }
    

    Note that this sample code and the previous one have not been redacted: they are fully functional. GRDB infers all the necessary information right from the database schema. You don't have to declare anything in the Swift code, but the associations themselves. It is also worth mentioning that any kind of primary key is supported, including composite ones.

    GRDB associations are quite like Ruby's Active Record Associations, but with a thick layer of type safety.

  • SQL Interpolation, based on SE-0228, lets you write SQL queries with a natural syntax. For example:

    // Executes `UPDATE player SET name = 'O''Brien' WHERE id = 42`
    let name = "O'Brien"
    let id = 42
    try db.execute(literal: """
        UPDATE player
        SET name = \(name)
        WHERE id = \(id)
        """)
    
  • Check the Release Notes for a full list of improvements and other changes.

Happy GRDB!

9 Likes

Version 4.0.1 is already out, with a bugfix, support for CocoaPods 1.7.0, and an enhanced Good Practices for Designing Record Types guide.