ColumnExpression

Adopt the ColumnExpression protocol when you define a column type.

You can, for example, define a String-based column enum:

enum Columns: String, ColumnExpression {
    case id, name, score
}
let arthur = try Player.filter(Columns.name == "Arthur").fetchOne(db)

You can also define a genuine column type:

struct MyColumn: ColumnExpression {
    var name: String
    var sqlType: String
}
let nameColumn = MyColumn(name: "name", sqlType: "VARCHAR")
let arthur = try Player.filter(nameColumn == "Arthur").fetchOne(db)

See https://github.com/groue/GRDB.swift#the-query-interface

  • name Default implementation

    The unqualified name of a database column.

    “score” is a valid unqualified name. “player.score” is not.

    Default Implementation

  • match(_:) Extension method

    A matching SQL expression with the MATCH SQL operator.

    // content MATCH '...'
    Column("content").match(pattern)
    

    If the search pattern is nil, SQLite will evaluate the expression to false.

ColumnAssignment

  • set(to:) Extension method

    Creates an assignment to a value.

    Column("valid").set(to: true)
    Column("score").set(to: 0)
    Column("score").set(to: nil)
    Column("score").set(to: Column("score") + Column("bonus"))
    
    try dbQueue.write { db in
        // UPDATE player SET score = 0
        try Player.updateAll(db, Column("score").set(to: 0))
    }
    
  • noOverwrite Extension method

    Returns an assignment that does not modify this column.

  • sqlExpression Extension method
  • detached Extension method

    Returns a “detached column”, which is never qualified with any table name in the SQL generated by the query interface. A detached column allows you to refer to an aliased column (expression AS alias).

    For example, see how Column("total").detached makes it possible to sort this query, when a raw Column("total") could not:

    // SELECT player.*,
    //        (player.score + player.bonus) AS total,
    //        team.*
    // FROM player
    // JOIN team ON team.id = player.teamID
    // ORDER BY total, player.name
    //          ~~~~~
    let request = Player
        .annotated(with: (Column("score") + Column("bonus")).forKey("total"))
        .including(required: Book.team)
        .order(Column("total").detached, Column("name"))
    
  • rowID Extension method

    The hidden rowID column