Structs

The following structs are available globally.

  • An index on a database table.

    See Database.indexes(on:)

    See more

    Declaration

    Swift

    public struct IndexInfo
  • You get primary keys from table names, with the Database.primaryKey(_) method.

    Primary key is nil when table has no primary key:

    // CREATE TABLE items (name TEXT)
    let itemPk = try db.primaryKey("items") // nil
    

    Primary keys have one or several columns. When the primary key has a single column, it may contain the row id:

    // CREATE TABLE persons (
    //   id INTEGER PRIMARY KEY,
    //   name TEXT
    // )
    let personPk = try db.primaryKey("persons")!
    personPk.columns     // ["id"]
    personPk.rowIDColumn // "id"
    
    // CREATE TABLE countries (
    //   isoCode TEXT NOT NULL PRIMARY KEY
    //   name TEXT
    // )
    let countryPk = db.primaryKey("countries")!
    countryPk.columns     // ["isoCode"]
    countryPk.rowIDColumn // nil
    
    // CREATE TABLE citizenships (
    //   personID INTEGER NOT NULL REFERENCES persons(id)
    //   countryIsoCode TEXT NOT NULL REFERENCES countries(isoCode)
    //   PRIMARY KEY (personID, countryIsoCode)
    // )
    let citizenshipsPk = db.primaryKey("citizenships")!
    citizenshipsPk.columns     // ["personID", "countryIsoCode"]
    citizenshipsPk.rowIDColumn // nil
    
    See more

    Declaration

    Swift

    public struct PrimaryKeyInfo
  • A DatabaseMigrator registers and applies database migrations.

    Migrations are named blocks of SQL statements that are guaranteed to be applied in order, once and only once.

    When a user upgrades your application, only non-applied migration are run.

    Usage:

    var migrator = DatabaseMigrator()
    
    // v1.0 database
    migrator.registerMigration("createPersons") { db in
        try db.execute(
            "CREATE TABLE persons (" +
                "id INTEGER PRIMARY KEY, " +
                "creationDate TEXT, " +
                "name TEXT NOT NULL" +
            ")")
    }
    
    migrator.registerMigration("createBooks") { db in
        try db.execute(
            "CREATE TABLE books (" +
                "uuid TEXT PRIMARY KEY, " +
                "ownerID INTEGER NOT NULL " +
                "        REFERENCES persons(id) " +
                "        ON DELETE CASCADE ON UPDATE CASCADE, " +
                "title TEXT NOT NULL" +
            ")")
    }
    
    // v2.0 database
    migrator.registerMigration("AddAgeToPersons") { db in
        try db.execute("ALTER TABLE persons ADD COLUMN age INT")
    }
    
    try migrator.migrate(dbQueue)
    
    See more

    Declaration

    Swift

    public struct DatabaseMigrator
  • FTS3 lets you define fts3 virtual tables.

    // CREATE VIRTUAL TABLE documents USING fts3(content)
    try db.create(virtualTable: "documents", using: FTS3()) { t in
        t.column("content")
    }
    
    See more

    Declaration

    Swift

    public struct FTS3 : VirtualTableModule
  • Indexes to (columnName, databaseValue) pairs in a database row.

    See more

    Declaration

    Swift

    public struct RowIndex : Comparable
  • LayoutedColumnMapping is a type that supports the RowAdapter protocol.

    See more

    Declaration

    Swift

    public struct LayoutedColumnMapping
  • ColumnMapping is a row adapter that maps column names.

    let adapter = ColumnMapping(["foo": "bar"])
    let sql = "SELECT 'foo' AS foo, 'bar' AS bar, 'baz' AS baz"
    
    // <Row foo:"bar">
    try Row.fetchOne(db, sql, adapter: adapter)
    
    See more

    Declaration

    Swift

    public struct ColumnMapping : RowAdapter
  • SuffixRowAdapter is a row adapter that hides the first columns in a row.

    let adapter = SuffixRowAdapter(fromIndex: 2)
    let sql = "SELECT 1 AS foo, 2 AS bar, 3 AS baz"
    
    // <Row baz:3>
    try Row.fetchOne(db, sql, adapter: adapter)
    
    See more

    Declaration

    Swift

    public struct SuffixRowAdapter : RowAdapter
  • RangeRowAdapter is a row adapter that only exposes a range of columns.

    let adapter = RangeRowAdapter(1..<3)
    let sql = "SELECT 1 AS foo, 2 AS bar, 3 AS baz, 4 as qux"
    
    // <Row bar:2 baz: 3>
    try Row.fetchOne(db, sql, adapter: adapter)
    
    See more

    Declaration

    Swift

    public struct RangeRowAdapter : RowAdapter
  • ScopeAdapter is a row adapter that lets you define scopes on rows.

    // Two adapters
    let fooAdapter = ColumnMapping(["value": "foo"])
    let barAdapter = ColumnMapping(["value": "bar"])
    
    // Define scopes
    let adapter = ScopeAdapter([
        "foo": fooAdapter,
        "bar": barAdapter])
    
    // Fetch
    let sql = "SELECT 'foo' AS foo, 'bar' AS bar"
    let row = try Row.fetchOne(db, sql, adapter: adapter)!
    
    // Scoped rows:
    if let fooRow = row.scoped(on: "foo") {
        fooRow.value(named: "value")    // "foo"
    }
    if let barRow = row.scopeed(on: "bar") {
        barRow.value(named: "value")    // "bar"
    }
    
    See more

    Declaration

    Swift

    public struct ScopeAdapter : RowAdapter
  • SQLCollatedExpression taints an expression so that every derived expression is eventually evaluated using an SQLite collation.

    You create one by calling the SQLSpecificExpressible.collating() method.

    let email: SQLCollatedExpression = Column("email").collating(.nocase)
    
    // SELECT * FROM persons WHERE email = 'arthur@example.com' COLLATE NOCASE
    Persons.filter(email == "arthur@example.com")
    
    See more

    Declaration

    Swift

    public struct SQLCollatedExpression
  • This type is an implementation detail of the query interface. Do not use it directly.

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

    Low Level Query Interface

    SQLExpressionLiteral is an expression built from a raw SQL snippet.

    SQLExpressionLiteral("1 + 2")
    

    The SQL literal may contain ? and colon-prefixed tokens:

    SQLExpressionLiteral("? + ?", arguments: [1, 2])
    SQLExpressionLiteral(":one + :two", arguments: ["one": 1, "two": 2])
    
    See more

    Declaration

    Swift

    public struct SQLExpressionLiteral : SQLExpression
  • StatementArguments provide values to argument placeholders in raw SQL queries.

    Placeholders can take several forms (see https://www.sqlite.org/lang_expr.html#varparam for more information):

    • ?NNN (e.g. ?2): the NNN-th argument (starts at 1)
    • ?: the N-th argument, where N is one greater than the largest argument number already assigned
    • :AAAA (e.g. :name): named argument

    • $AAAA (e.g. $name): named argument

    Positional Arguments

    To fill question marks placeholders, feed StatementArguments with an array:

    db.execute(
        "INSERT ... (?, ?)",
        arguments: StatementArguments(["Arthur", 41]))
    
    // Array literals are automatically converted:
    db.execute(
        "INSERT ... (?, ?)",
        arguments: ["Arthur", 41])
    

    Named Arguments

    To fill named arguments, feed StatementArguments with a dictionary:

    db.execute(
        "INSERT ... (:name, :age)",
        arguments: StatementArguments(["name": "Arthur", "age": 41]))
    
    // Dictionary literals are automatically converted:
    db.execute(
        "INSERT ... (:name, :age)",
        arguments: ["name": "Arthur", "age": 41])
    

    Concatenating Arguments

    Several arguments can be concatenated and mixed with the append(contentsOf:) method and the +, &+, += operators:

    var arguments: StatementArguments = ["Arthur"]
    arguments += [41]
    db.execute("INSERT ... (?, ?)", arguments: arguments)
    

    + and += operators consider that overriding named arguments is a programmer error:

    var arguments: StatementArguments = ["name": "Arthur"]
    arguments += ["name": "Barbara"]
    // fatal error: already defined statement argument: name
    

    &+ and append(contentsOf:) allow overriding named arguments:

    var arguments: StatementArguments = ["name": "Arthur"]
    arguments = arguments &+ ["name": "Barbara"]
    print(arguments)
    // Prints ["name": "Barbara"]
    

    Mixed Arguments

    When a statement consumes a mix of named and positional arguments, it prefers named arguments over positional ones. For example:

    let sql = "SELECT ?2 AS two, :foo AS foo, ?1 AS one, :foo AS foo2, :bar AS bar"
    let row = try Row.fetchOne(db, sql, arguments: [1, 2, "bar"] + ["foo": "foo"])!
    print(row)
    // Prints <Row two:2 foo:"foo" one:1 foo2:"foo" bar:"bar">
    
    See more

    Declaration

    Swift

    public struct StatementArguments