TableRecord
public protocol TableRecord
Types that adopt TableRecord declare a particular relationship with a database table.
Types that adopt both TableRecord and FetchableRecord are granted with built-in methods that allow to fetch instances identified by key:
try Player.fetchOne(db, key: 123) // Player?
try Citizenship.fetchOne(db, key: ["citizenId": 12, "countryId": 45]) // Citizenship?
TableRecord is adopted by Record.
-
databaseTableName
Default implementationThe name of the database table used to build requests.
struct Player : TableRecord { static var databaseTableName = "player" } // SELECT * FROM player try Player.fetchAll(db)
Default Implementation
The default name of the database table used to build requests.
- Player ->
player
- Place ->
place
- PostalAddress ->
postalAddress
- HTTPRequest ->
httpRequest
- TOEFL ->
toefl
Declaration
Swift
static var databaseTableName: String { get }
- Player ->
-
databaseSelection
Default implementationThe default request selection.
Unless said otherwise, requests select all columns:
// SELECT * FROM player try Player.fetchAll(db)
You can provide a custom implementation and provide an explicit list of columns:
struct RestrictedPlayer : TableRecord { static var databaseTableName = "player" static var databaseSelection = [Column("id"), Column("name")] } // SELECT id, name FROM player try RestrictedPlayer.fetchAll(db)
You can also add extra columns such as the
rowid
column:struct ExtendedPlayer : TableRecord { static var databaseTableName = "player" static let databaseSelection: [SQLSelectable] = [AllColumns(), Column.rowID] } // SELECT *, rowid FROM player try ExtendedPlayer.fetchAll(db)
Default Implementation
Default value:
[AllColumns()]
.Declaration
Swift
static var databaseSelection: [SQLSelectable] { get }
-
matching(_:)
Extension methodReturns a QueryInterfaceRequest with a matching predicate.
// SELECT * FROM book WHERE book MATCH '...' var request = Book.matching(pattern)
If the search pattern is nil, the request does not match any database row.
The selection defaults to all columns. This default can be changed for all requests by the
TableRecord.databaseSelection
property, or for individual requests with theTableRecord.select
method.Declaration
Swift
public static func matching(_ pattern: FTS3Pattern?) -> QueryInterfaceRequest<Self>
-
belongsTo(_:key:using:)
Extension methodCreates a
Belongs To
association between Self and the destination type.struct Author: TableRecord { ... } struct Book: TableRecord { static let author = belongsTo(Author.self) }
The association will let you define requests that load both the source and the destination type:
// A request for all books with their authors: let request = Book.including(optional: Book.author)
To consume those requests, define a type that adopts both the FetchableRecord and Decodable protocols:
struct BookInfo: FetchableRecord, Decodable { var book: Book var author: Author? } let bookInfos = try dbQueue.read { db in return try BookInfo.fetchAll(db, request) } for bookInfo in bookInfos { print("\(bookInfo.book.title) by \(bookInfo.author.name)") }
It is recommended that you define, alongside the static association, a property with the same name:
struct Book: TableRecord, EncodableRecord { static let author = belongsTo(Author.self) var author: QueryInterfaceRequest<Author> { return request(for: Book.author) } }
This property will let you navigate from the source type to the destination type:
try dbQueue.read { db in let book: Book = ... let author = try book.author.fetchOne(db) // Author? }
Declaration
Swift
public static func belongsTo<Destination>( _ destination: Destination.Type, key: String? = nil, using foreignKey: ForeignKey? = nil) -> BelongsToAssociation<Self, Destination>
Parameters
destination
The record type at the other side of the association.
key
An eventual decoding key for the association. By default, it is
destination.databaseTableName
.foreignKey
An eventual foreign key. You need to provide an explicit foreign key when GRDB can’t infer one from the database schema. This happens when the schema does not define any foreign key to the destination table, or when the schema defines several foreign keys to the destination table.
-
hasMany(_:key:using:)
Extension methodCreates a
Has many
association between Self and the destination type.struct Book: TableRecord { ... } struct Author: TableRecord { static let books = hasMany(Book.self) }
The association will let you define requests that load both the source and the destination type:
// A request for all (author, book) pairs: let request = Author.including(required: Author.books)
To consume those requests, define a type that adopts both the FetchableRecord and Decodable protocols:
struct Authorship: FetchableRecord, Decodable { var author: Author var book: Book } let authorships = try dbQueue.read { db in return try Authorship.fetchAll(db, request) } for authorship in authorships { print("\(authorship.author.name) wrote \(authorship.book.title)") }
It is recommended that you define, alongside the static association, a property with the same name:
struct Author: TableRecord, EncodableRecord { static let books = hasMany(Book.self) var books: QueryInterfaceRequest<Book> { return request(for: Author.books) } }
This property will let you navigate from the source type to the destination type:
try dbQueue.read { db in let author: Author = ... let books = try author.books.fetchAll(db) // [Book] }
Declaration
Swift
public static func hasMany<Destination>( _ destination: Destination.Type, key: String? = nil, using foreignKey: ForeignKey? = nil) -> HasManyAssociation<Self, Destination>
Parameters
destination
The record type at the other side of the association.
key
An eventual decoding key for the association. By default, it is
destination.databaseTableName
.foreignKey
An eventual foreign key. You need to provide an explicit foreign key when GRDB can’t infer one from the database schema. This happens when the schema does not define any foreign key from the destination table, or when the schema defines several foreign keys from the destination table.
-
hasMany(_:through:using:key:)
Extension methodCreates a
Has Many Through
association between Self and the destination type.struct Country: TableRecord { static let passports = hasMany(Passport.self) static let citizens = hasMany(Citizen.self, through: passports, using: Passport.citizen) } struct Passport: TableRecord { static let citizen = belongsTo(Citizen.self) } struct Citizen: TableRecord { }
The association will let you define requests that load both the source and the destination type:
// A request for all (country, citizen) pairs: let request = Country.including(required: Coutry.citizens)
To consume those requests, define a type that adopts both the FetchableRecord and Decodable protocols:
struct Citizenship: FetchableRecord, Decodable { var country: Country var citizen: Citizen } let citizenships = try dbQueue.read { db in return try Citizenship.fetchAll(db, request) } for citizenship in citizenships { print("\(citizenship.citizen.name) is a citizen of \(citizenship.country.name)") }
It is recommended that you define, alongside the static association, a property with the same name:
struct Country: TableRecord, EncodableRecord { static let passports = hasMany(Passport.self) static let citizens = hasMany(Citizen.self, through: passports, using: Passport.citizen) var citizens: QueryInterfaceRequest<Citizen> { return request(for: Country.citizens) } }
This property will let you navigate from the source type to the destination type:
try dbQueue.read { db in let country: Country = ... let citizens = try country.citizens.fetchAll(db) // [Country] }
Declaration
Swift
public static func hasMany<Pivot, Target>( _ destination: Target.RowDecoder.Type, through pivot: Pivot, using target: Target, key: String? = nil) -> HasManyThroughAssociation<Self, Target.RowDecoder> where Pivot: Association, Target: Association, Pivot.OriginRowDecoder == Self, Pivot.RowDecoder == Target.OriginRowDecoder
Parameters
destination
The record type at the other side of the association.
pivot
An association from Self to the intermediate type.
target
A target association from the intermediate type to the destination type.
key
An eventual decoding key for the association. By default, it is the same key as the target.
-
hasOne(_:key:using:)
Extension methodCreates a
Has one
association between Self and the destination type.struct Demographics: TableRecord { ... } struct Country: TableRecord { static let demographics = hasOne(Demographics.self) }
The association will let you define requests that load both the source and the destination type:
// A request for all countries with their demographic profile: let request = Country.including(optional: Country.demographics)
To consume those requests, define a type that adopts both the FetchableRecord and Decodable protocols:
struct CountryInfo: FetchableRecord, Decodable { var country: Country var demographics: Demographics? } let countryInfos = try dbQueue.read { db in return try CountryInfo.fetchAll(db, request) } for countryInfo in countryInfos { print("\(countryInfo.country.name) has \(countryInfo.demographics.population) citizens") }
It is recommended that you define, alongside the static association, a property with the same name:
struct Country: TableRecord, EncodableRecord { static let demographics = hasOne(Demographics.self) var demographics: QueryInterfaceRequest<Demographics> { return request(for: Country.demographics) } }
This property will let you navigate from the source type to the destination type:
try dbQueue.read { db in let country: Country = ... let demographics = try country.demographics.fetchOne(db) // Demographics? }
Declaration
Swift
public static func hasOne<Destination>( _ destination: Destination.Type, key: String? = nil, using foreignKey: ForeignKey? = nil) -> HasOneAssociation<Self, Destination>
Parameters
destination
The record type at the other side of the association.
key
An eventual decoding key for the association. By default, it is
destination.databaseTableName
.foreignKey
An eventual foreign key. You need to provide an explicit foreign key when GRDB can’t infer one from the database schema. This happens when the schema does not define any foreign key from the destination table, or when the schema defines several foreign keys from the destination table.
-
hasOne(_:through:using:key:)
Extension methodCreates a
Has One Through
association between Self and the destination type.struct Book: TableRecord { static let library = belongsTo(Library.self) static let returnAddress = hasOne(Address.self, through: library, using: library.address) } struct Library: TableRecord { static let address = hasOne(Address.self) } struct Address: TableRecord { ... }
The association will let you define requests that load both the source and the destination type:
// A request for all (book, returnAddress) pairs: let request = Book.including(required: Book.returnAddress)
To consume those requests, define a type that adopts both the FetchableRecord and Decodable protocols:
struct Todo: FetchableRecord, Decodable { var book: Book var address: Address } let todos = try dbQueue.read { db in return try Todo.fetchAll(db, request) } for todo in todos { print("Please return \(todo.book) to \(todo.address)") }
It is recommended that you define, alongside the static association, a property with the same name:
struct Book: TableRecord, EncodableRecord { static let library = belongsTo(Library.self) static let returnAddress = hasOne(Address.self, through: library, using: library.address) var returnAddress: QueryInterfaceRequest<Address> { return request(for: Book.returnAddress) } }
This property will let you navigate from the source type to the destination type:
try dbQueue.read { db in let book: Book = ... let address = try book.returnAddress.fetchOne(db) // Address? }
Declaration
Swift
public static func hasOne<Pivot, Target>( _ destination: Target.RowDecoder.Type, through pivot: Pivot, using target: Target, key: String? = nil) -> HasOneThroughAssociation<Self, Target.RowDecoder> where Pivot: AssociationToOne, Target: AssociationToOne, Pivot.OriginRowDecoder == Self, Pivot.RowDecoder == Target.OriginRowDecoder
Parameters
destination
The record type at the other side of the association.
pivot
An association from Self to the intermediate type.
target
A target association from the intermediate type to the destination type.
key
An eventual decoding key for the association. By default, it is the same key as the target.
-
request(for:)
Extension methodCreates a request that fetches the associated record(s).
For example:
struct Team: TableRecord, EncodableRecord { static let players = hasMany(Player.self) var players: QueryInterfaceRequest<Player> { return request(for: Team.players) } } let team: Team = ... let players = try team.players.fetchAll(db) // [Player]
Declaration
Swift
public func request<A: Association>(for association: A) -> QueryInterfaceRequest<A.RowDecoder> where A.OriginRowDecoder == Self
-
including(all:)
Extension methodCreates a request that prefetches an association.
Declaration
Swift
public static func including<A: AssociationToMany>(all association: A) -> QueryInterfaceRequest<Self> where A.OriginRowDecoder == Self
-
including(optional:)
Extension methodCreates a request that includes an association. The columns of the associated record are selected. The returned association does not require that the associated database table contains a matching row.
Declaration
Swift
public static func including<A: Association>(optional association: A) -> QueryInterfaceRequest<Self> where A.OriginRowDecoder == Self
-
including(required:)
Extension methodCreates a request that includes an association. The columns of the associated record are selected. The returned association requires that the associated database table contains a matching row.
Declaration
Swift
public static func including<A: Association>(required association: A) -> QueryInterfaceRequest<Self> where A.OriginRowDecoder == Self
-
joining(optional:)
Extension methodCreates a request that includes an association. The columns of the associated record are not selected. The returned association does not require that the associated database table contains a matching row.
Declaration
Swift
public static func joining<A: Association>(optional association: A) -> QueryInterfaceRequest<Self> where A.OriginRowDecoder == Self
-
joining(required:)
Extension methodCreates a request that includes an association. The columns of the associated record are not selected. The returned association requires that the associated database table contains a matching row.
Declaration
Swift
public static func joining<A: Association>(required association: A) -> QueryInterfaceRequest<Self> where A.OriginRowDecoder == Self
-
annotated(with:)
Extension methodCreates a request with aggregates appended to the selection.
// SELECT player.*, COUNT(DISTINCT book.rowid) AS bookCount // FROM player LEFT JOIN book ... var request = Player.annotated(with: Player.books.count)
Declaration
Swift
public static func annotated(with aggregates: AssociationAggregate<Self>...) -> QueryInterfaceRequest<Self>
-
annotated(with:)
Extension methodCreates a request with aggregates appended to the selection.
// SELECT player.*, COUNT(DISTINCT book.rowid) AS bookCount // FROM player LEFT JOIN book ... var request = Player.annotated(with: [Player.books.count])
Declaration
Swift
public static func annotated(with aggregates: [AssociationAggregate<Self>]) -> QueryInterfaceRequest<Self>
-
having(_:)
Extension methodCreates a request with the provided aggregate predicate.
// SELECT player.* // FROM player LEFT JOIN book ... // HAVING COUNT(DISTINCT book.rowid) = 0 var request = Player.all() request = request.having(Player.books.isEmpty)
The selection defaults to all columns. This default can be changed for all requests by the
TableRecord.databaseSelection
property, or for individual requests with theTableRecord.select
method.Declaration
Swift
public static func having(_ predicate: AssociationAggregate<Self>) -> QueryInterfaceRequest<Self>
-
all()
Extension methodCreates a request which fetches all records.
// SELECT * FROM player let request = Player.all()
The selection defaults to all columns. This default can be changed for all requests by the
TableRecord.databaseSelection
property, or for individual requests with theTableRecord.select
method.Declaration
Swift
public static func all() -> QueryInterfaceRequest<Self>
-
none()
Extension methodCreates a request which fetches no record.
Declaration
Swift
public static func none() -> QueryInterfaceRequest<Self>
-
select(_:)
Extension methodCreates a request which selects selection.
// SELECT id, email FROM player let request = Player.select(Column("id"), Column("email"))
Declaration
Swift
public static func select(_ selection: SQLSelectable...) -> QueryInterfaceRequest<Self>
-
select(_:)
Extension methodCreates a request which selects selection.
// SELECT id, email FROM player let request = Player.select([Column("id"), Column("email")])
Declaration
Swift
public static func select(_ selection: [SQLSelectable]) -> QueryInterfaceRequest<Self>
-
select(sql:arguments:)
Extension methodCreates a request which selects sql.
// SELECT id, email FROM player let request = Player.select(sql: "id, email")
Declaration
Swift
public static func select( sql: String, arguments: StatementArguments = StatementArguments()) -> QueryInterfaceRequest<Self>
-
select(literal:)
Extension methodCreates a request which selects an SQL literal.
// SELECT id, email FROM player let request = Player.select(literal: SQLLiteral(sql: "id, email"))
Declaration
Swift
public static func select(literal sqlLiteral: SQLLiteral) -> QueryInterfaceRequest<Self>
-
select(_:as:)
Extension methodCreates a request which selects selection, and fetches values of type type.
try dbQueue.read { db in // SELECT max(score) FROM player let request = Player.select([max(Column("score"))], as: Int.self) let maxScore: Int? = try request.fetchOne(db) }
Declaration
Swift
public static func select<RowDecoder>( _ selection: [SQLSelectable], as type: RowDecoder.Type) -> QueryInterfaceRequest<RowDecoder>
-
select(_:as:)
Extension methodCreates a request which selects selection, and fetches values of type type.
try dbQueue.read { db in // SELECT max(score) FROM player let request = Player.select(max(Column("score")), as: Int.self) let maxScore: Int? = try request.fetchOne(db) }
Declaration
Swift
public static func select<RowDecoder>( _ selection: SQLSelectable..., as type: RowDecoder.Type) -> QueryInterfaceRequest<RowDecoder>
-
select(sql:arguments:as:)
Extension methodCreates a request which selects sql, and fetches values of type type.
try dbQueue.read { db in // SELECT max(score) FROM player let request = Player.select(sql: "max(score)", as: Int.self) let maxScore: Int? = try request.fetchOne(db) }
Declaration
Swift
public static func select<RowDecoder>( sql: String, arguments: StatementArguments = StatementArguments(), as type: RowDecoder.Type) -> QueryInterfaceRequest<RowDecoder>
-
select(literal:as:)
Extension methodCreates a request which selects an SQL literal, and fetches values of type type.
try dbQueue.read { db in // SELECT max(score) FROM player let request = Player.select(literal: SQLLiteral(sql: "max(score)"), as: Int.self) let maxScore: Int? = try request.fetchOne(db) }
Declaration
Swift
public static func select<RowDecoder>( literal sqlLiteral: SQLLiteral, as type: RowDecoder.Type) -> QueryInterfaceRequest<RowDecoder>
-
annotated(with:)
Extension methodCreates a request which appends selection.
// SELECT id, email, name FROM player le request = Player .select([Column("id"), Column("email")]) .annotated(with: [Column("name")])
Declaration
Swift
public static func annotated(with selection: [SQLSelectable]) -> QueryInterfaceRequest<Self>
-
annotated(with:)
Extension methodCreates a request which appends selection.
// SELECT id, email, name FROM player le request = Player .select([Column("id"), Column("email")]) .annotated(with: Column("name"))
Declaration
Swift
public static func annotated(with selection: SQLSelectable...) -> QueryInterfaceRequest<Self>
-
filter(_:)
Extension methodCreates a request with the provided predicate.
// SELECT * FROM player WHERE email = 'arthur@example.com' let request = Player.filter(Column("email") == "arthur@example.com")
The selection defaults to all columns. This default can be changed for all requests by the
TableRecord.databaseSelection
property, or for individual requests with theTableRecord.select
method.Declaration
Swift
public static func filter(_ predicate: SQLExpressible) -> QueryInterfaceRequest<Self>
-
filter(key:)
Extension methodCreates a request with the provided primary key predicate.
// SELECT * FROM player WHERE id = 1 let request = Player.filter(key: 1)
The selection defaults to all columns. This default can be changed for all requests by the
TableRecord.databaseSelection
property, or for individual requests with theTableRecord.select
method.Declaration
Swift
public static func filter<PrimaryKeyType>(key: PrimaryKeyType?) -> QueryInterfaceRequest<Self> where PrimaryKeyType: DatabaseValueConvertible
-
filter(keys:)
Extension methodCreates a request with the provided primary key predicate.
// SELECT * FROM player WHERE id IN (1, 2, 3) let request = Player.filter(keys: [1, 2, 3])
The selection defaults to all columns. This default can be changed for all requests by the
TableRecord.databaseSelection
property, or for individual requests with theTableRecord.select
method.Declaration
Swift
public static func filter<Sequence>(keys: Sequence) -> QueryInterfaceRequest<Self> where Sequence: Swift.Sequence, Sequence.Element: DatabaseValueConvertible
-
filter(key:)
Extension methodCreates a request with the provided primary key predicate.
// SELECT * FROM passport WHERE personId = 1 AND countryCode = 'FR' let request = Passport.filter(key: ["personId": 1, "countryCode": "FR"])
When executed, this request raises a fatal error if there is no unique index on the key columns.
The selection defaults to all columns. This default can be changed for all requests by the
TableRecord.databaseSelection
property, or for individual requests with theTableRecord.select
method.Declaration
Swift
public static func filter(key: [String : DatabaseValueConvertible?]?) -> QueryInterfaceRequest<Self>
-
filter(keys:)
Extension methodCreates a request with the provided primary key predicate.
// SELECT * FROM passport WHERE (personId = 1 AND countryCode = 'FR') OR ... let request = Passport.filter(keys: [["personId": 1, "countryCode": "FR"], ...])
When executed, this request raises a fatal error if there is no unique index on the key columns.
The selection defaults to all columns. This default can be changed for all requests by the
TableRecord.databaseSelection
property, or for individual requests with theTableRecord.select
method.Declaration
Swift
public static func filter(keys: [[String : DatabaseValueConvertible?]]) -> QueryInterfaceRequest<Self>
-
filter(sql:arguments:)
Extension methodCreates a request with the provided predicate.
// SELECT * FROM player WHERE email = 'arthur@example.com' let request = Player.filter(sql: "email = ?", arguments: ["arthur@example.com"])
The selection defaults to all columns. This default can be changed for all requests by the
TableRecord.databaseSelection
property, or for individual requests with theTableRecord.select
method.Declaration
Swift
public static func filter( sql: String, arguments: StatementArguments = StatementArguments()) -> QueryInterfaceRequest<Self>
-
filter(literal:)
Extension methodCreates a request with the provided predicate.
// SELECT * FROM player WHERE email = 'arthur@example.com' let request = Player.filter(literal: SQLLiteral(sql: "email = ?", arguments: ["arthur@example.com"]))
With Swift 5, you can safely embed raw values in your SQL queries, without any risk of syntax errors or SQL injection:
let request = Player.filter(literal: "name = \("O'Brien"))
The selection defaults to all columns. This default can be changed for all requests by the
TableRecord.databaseSelection
property, or for individual requests with theTableRecord.select
method.Declaration
Swift
public static func filter(literal sqlLiteral: SQLLiteral) -> QueryInterfaceRequest<Self>
-
order(_:)
Extension methodCreates a request sorted according to the provided orderings.
// SELECT * FROM player ORDER BY name let request = Player.order(Column("name"))
The selection defaults to all columns. This default can be changed for all requests by the
TableRecord.databaseSelection
property, or for individual requests with theTableRecord.select
method.Declaration
Swift
public static func order(_ orderings: SQLOrderingTerm...) -> QueryInterfaceRequest<Self>
-
order(_:)
Extension methodCreates a request sorted according to the provided orderings.
// SELECT * FROM player ORDER BY name let request = Player.order([Column("name")])
The selection defaults to all columns. This default can be changed for all requests by the
TableRecord.databaseSelection
property, or for individual requests with theTableRecord.select
method.Declaration
Swift
public static func order(_ orderings: [SQLOrderingTerm]) -> QueryInterfaceRequest<Self>
-
orderByPrimaryKey()
Extension methodCreates a request sorted by primary key.
// SELECT * FROM player ORDER BY id let request = Player.orderByPrimaryKey() // SELECT * FROM country ORDER BY code let request = Country.orderByPrimaryKey()
The selection defaults to all columns. This default can be changed for all requests by the
TableRecord.databaseSelection
property, or for individual requests with theTableRecord.select
method.Declaration
Swift
public static func orderByPrimaryKey() -> QueryInterfaceRequest<Self>
-
order(sql:arguments:)
Extension methodCreates a request sorted according to sql.
// SELECT * FROM player ORDER BY name let request = Player.order(sql: "name")
The selection defaults to all columns. This default can be changed for all requests by the
TableRecord.databaseSelection
property, or for individual requests with theTableRecord.select
method.Declaration
Swift
public static func order( sql: String, arguments: StatementArguments = StatementArguments()) -> QueryInterfaceRequest<Self>
-
order(literal:)
Extension methodCreates a request sorted according to an SQL literal.
// SELECT * FROM player ORDER BY name let request = Player.order(literal: SQLLiteral(sql: "name"))
With Swift 5, you can safely embed raw values in your SQL queries, without any risk of syntax errors or SQL injection:
// SELECT * FROM player ORDER BY name let request = Player.order(literal: "name"))
The selection defaults to all columns. This default can be changed for all requests by the
TableRecord.databaseSelection
property, or for individual requests with theTableRecord.select
method.Declaration
Swift
public static func order(literal sqlLiteral: SQLLiteral) -> QueryInterfaceRequest<Self>
-
limit(_:offset:)
Extension methodCreates a request which fetches limit rows, starting at offset.
// SELECT * FROM player LIMIT 1 let request = Player.limit(1)
The selection defaults to all columns. This default can be changed for all requests by the
TableRecord.databaseSelection
property, or for individual requests with theTableRecord.select
method.Declaration
Swift
public static func limit(_ limit: Int, offset: Int? = nil) -> QueryInterfaceRequest<Self>
-
aliased(_:)
Extension methodCreates a request that allows you to define expressions that target a specific database table.
In the example below, the
team.avgScore < player.score
condition in the ON clause could be not achieved without table aliases.struct Player: TableRecord { static let team = belongsTo(Team.self) } // SELECT player.*, team.* // JOIN team ON ... AND team.avgScore < player.score let playerAlias = TableAlias() let request = Player .aliased(playerAlias) .including(required: Player.team.filter(Column("avgScore") < playerAlias[Column("score")])
Declaration
Swift
public static func aliased(_ alias: TableAlias) -> QueryInterfaceRequest<Self>
-
fetchCount(_:)
Extension methodThe number of records.
Declaration
Swift
public static func fetchCount(_ db: Database) throws -> Int
Parameters
db
A database connection.
-
selectionSQL(alias:)
Extension methodThe selection as an SQL String.
For example:
struct Player: TableRecord { static let databaseTableName = "player" } // SELECT "player".* FROM player let sql = "SELECT \(Player.selectionSQL()) FROM player" // SELECT "p".* FROM player AS p let sql = "SELECT \(Player.selectionSQL(alias: "p")) FROM player p"
Declaration
Swift
public static func selectionSQL(alias: String? = nil) -> String
-
numberOfSelectedColumns(_:)
Extension methodReturns the number of selected columns.
For example:
struct Player: TableRecord { static let databaseTableName = "player" } try dbQueue.write { db in try db.create(table: "player") { t in t.autoIncrementedPrimaryKey("id") t.column("name", .text) t.column("score", .integer) } // 3 try Player.numberOfSelectedColumns(db) }
Declaration
Swift
public static func numberOfSelectedColumns(_ db: Database) throws -> Int
-
observationForCount()
Extension methodCreates a ValueObservation which observes the record table, and notifies its count whenever it is modified by a database transaction.
For example:
let observation = Player.observationForCount() let observer = try observation.start(in: dbQueue) { count: Int in print("Number of players has changed") }
The returned observation has the default configuration:
- When started with the
start(in:onError:onChange:)
method, a fresh value is immediately notified on the main queue. - Upon subsequent database changes, fresh values are notified on the main queue.
The observation lasts until the observer returned by
start
is deallocated.
Declaration
Swift
public static func observationForCount() -> ValueObservation<ValueReducers.RemoveDuplicates<ValueReducers.Fetch<Int>>>
Return Value
a ValueObservation.
- When started with the
-
observationForAll()
Extension methodCreates a ValueObservation which observes the record table, and notifies fresh records whenever the request is modified by a database transaction.
For example:
let observation = Player.observationForAll() let observer = try observation.start(in: dbQueue) { players: [Player] in print("Players have changed") }
The returned observation has the default configuration:
- When started with the
start(in:onError:onChange:)
method, a fresh value is immediately notified on the main queue. - Upon subsequent database changes, fresh values are notified on the main queue.
The observation lasts until the observer returned by
start
is deallocated.
Declaration
Swift
public static func observationForAll() -> ValueObservation<ValueReducers.AllRecords<Self>>
Return Value
a ValueObservation.
- When started with the
-
observationForFirst()
Extension methodCreates a ValueObservation which observes the table record, and notifies a fresh record whenever the request is modified by a database transaction.
For example:
let observation = Player.observationForFirst() let observer = try observation.start(in: dbQueue) { player: Player? in print("Player has changed") }
The returned observation has the default configuration:
- When started with the
start(in:onError:onChange:)
method, a fresh value is immediately notified on the main queue. - Upon subsequent database changes, fresh values are notified on the main queue.
The observation lasts until the observer returned by
start
is deallocated.
Declaration
Swift
public static func observationForFirst() -> ValueObservation<ValueReducers.OneRecord<Self>>
Return Value
a ValueObservation.
- When started with the