Skip to content

Commit 0049685

Browse files
committed
Update more documentation with the closure syntax
1 parent f635aea commit 0049685

10 files changed

+400
-111
lines changed

GRDB/QueryInterface/ForeignKey.swift

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,14 @@
2525
///
2626
/// ```swift
2727
/// struct Book: TableRecord {
28+
/// enum Columns {
29+
/// static let authorId = Column("authorId")
30+
/// static let translatorId = Column("translatorId")
31+
/// }
32+
///
2833
/// // Define foreign keys
29-
/// static let authorForeignKey = ForeignKey(["authorId"]))
30-
/// static let translatorForeignKey = ForeignKey(["translatorId"]))
34+
/// static let authorForeignKey = ForeignKey([Columns.authorId]))
35+
/// static let translatorForeignKey = ForeignKey([Columns.translatorId]))
3136
///
3237
/// // Use foreign keys to define associations:
3338
/// static let author = belongsTo(
@@ -41,20 +46,6 @@
4146
/// }
4247
/// ```
4348
///
44-
/// Foreign keys can also be defined from query interface columns:
45-
///
46-
/// ```swift
47-
/// struct Book: TableRecord {
48-
/// enum Columns {
49-
/// static let authorId = Column("authorId")
50-
/// static let translatorId = Column("translatorId")
51-
/// }
52-
///
53-
/// static let authorForeignKey = ForeignKey([Columns.authorId]))
54-
/// static let translatorForeignKey = ForeignKey([Columns.translatorId]))
55-
/// }
56-
/// ```
57-
///
5849
/// When the destination table does not define any primary key, you need to
5950
/// provide the destination columns:
6051
///

GRDB/QueryInterface/Request/QueryInterfaceRequest.swift

Lines changed: 54 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,20 @@
2323
/// ``Table`` instance. For example:
2424
///
2525
/// ```swift
26-
/// struct Player: TableRecord, FetchableRecord, DecodableRecord { }
26+
/// struct Player: TableRecord, FetchableRecord, DecodableRecord {
27+
/// enum Columns {
28+
/// static let name = Column("name")
29+
/// static let score = Column("score")
30+
/// }
31+
/// }
2732
///
2833
/// try dbQueue.read { db in
2934
/// // SELECT * FROM player
3035
/// // WHERE name = 'O''Reilly'
3136
/// // ORDER BY score DESC
3237
/// let request = Player
33-
/// .filter(Column("name") == "O'Reilly")
34-
/// .order(Column("score").desc)
38+
/// .filter { $0.name == "O'Reilly" }
39+
/// .order(\.score.desc)
3540
/// let players: [Player] = try request.fetchAll(db)
3641
/// }
3742
/// ```
@@ -399,15 +404,27 @@ extension QueryInterfaceRequest: OrderedRequest {
399404

400405
/// Creates a request that reverses applied orderings.
401406
///
402-
/// // SELECT * FROM player ORDER BY name DESC
403-
/// var request = Player.all().order(Column("name"))
404-
/// request = request.reversed()
407+
/// For example:
408+
///
409+
/// ```swift
410+
/// struct Player: TableRecord {
411+
/// enum Columns {
412+
/// static let name = Column("name")
413+
/// }
414+
/// }
415+
///
416+
/// // SELECT * FROM player ORDER BY name DESC
417+
/// var request = Player.all().order(\.name)
418+
/// request = request.reversed()
419+
/// ```
405420
///
406421
/// If no ordering was applied, the returned request is identical.
407422
///
408-
/// // SELECT * FROM player
409-
/// var request = Player.all()
410-
/// request = request.reversed()
423+
/// ```swift
424+
/// // SELECT * FROM player
425+
/// var request = Player.all()
426+
/// request = request.reversed()
427+
/// ```
411428
public func reversed() -> Self {
412429
with {
413430
$0.relation = $0.relation.reversed()
@@ -416,9 +433,18 @@ extension QueryInterfaceRequest: OrderedRequest {
416433

417434
/// Creates a request without any ordering.
418435
///
419-
/// // SELECT * FROM player
420-
/// var request = Player.all().order(Column("name"))
421-
/// request = request.unordered()
436+
/// ```swift
437+
/// struct Player: TableRecord {
438+
/// enum Columns {
439+
/// static let name = Column("name")
440+
/// }
441+
/// }
442+
///
443+
/// // SELECT * FROM player
444+
/// let request = Player.all()
445+
/// .order(\.name)
446+
/// .unordered()
447+
/// ```
422448
public func unordered() -> Self {
423449
with {
424450
$0.relation = $0.relation.unordered()
@@ -567,9 +593,15 @@ extension QueryInterfaceRequest {
567593
/// For example:
568594
///
569595
/// ```swift
596+
/// struct Player: TableRecord {
597+
/// enum Columns {
598+
/// static let name = Column("name")
599+
/// }
600+
/// }
601+
///
570602
/// try dbQueue.read { db in
571603
/// let arthurIsMissing = try Player
572-
/// .filter(Column("name") == "Arthur")
604+
/// .filter { $0.name == "Arthur" }
573605
/// .isEmpty(db)
574606
/// }
575607
/// ```
@@ -1757,10 +1789,17 @@ extension QueryInterfaceRequest {
17571789
/// such as ``ColumnExpression/set(to:)`` or `+=`:
17581790
///
17591791
/// ```swift
1792+
/// struct Player: TableRecord {
1793+
/// enum Columns {
1794+
/// static let score = Column("score")
1795+
/// }
1796+
/// }
1797+
///
17601798
/// try dbQueue.write { db in
17611799
/// // UPDATE player SET score = 0
1762-
/// let assignment = Column("score").set(to: 0)
1763-
/// try Player.updateAll(db, assignment)
1800+
/// try Player.updateAll(db) { [
1801+
/// $0.score.set(to: 0)
1802+
/// ] }
17641803
/// }
17651804
/// ```
17661805
public struct ColumnAssignment {

GRDB/QueryInterface/Request/RequestProtocols.swift

Lines changed: 62 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1282,9 +1282,15 @@ public protocol OrderedRequest {
12821282
/// For example:
12831283
///
12841284
/// ```swift
1285+
/// struct Player: TableRecord {
1286+
/// enum Columns {
1287+
/// static let name = Column("name")
1288+
/// }
1289+
/// }
1290+
///
12851291
/// // SELECT * FROM player ORDER BY name DESC
12861292
/// let request = Player.all()
1287-
/// .order(Column("name"))
1293+
/// .order(\.name)
12881294
/// .reversed()
12891295
/// ```
12901296
///
@@ -1298,12 +1304,16 @@ public protocol OrderedRequest {
12981304

12991305
/// Returns a request without any ordering.
13001306
///
1301-
/// For example:
1302-
///
13031307
/// ```swift
1308+
/// struct Player: TableRecord {
1309+
/// enum Columns {
1310+
/// static let name = Column("name")
1311+
/// }
1312+
/// }
1313+
///
13041314
/// // SELECT * FROM player
13051315
/// let request = Player.all()
1306-
/// .order(Column("name"))
1316+
/// .order(\.name)
13071317
/// .unordered()
13081318
/// ```
13091319
func unordered() -> Self
@@ -1608,12 +1618,17 @@ extension JoinableRequest {
16081618
/// For example, we can fetch only books whose author is French:
16091619
///
16101620
/// ```swift
1611-
/// struct Author: TableRecord, FetchableRecord, Decodable { }
1612-
/// struct Book: TableRecord, FetchableRecord, Decodable {
1621+
/// struct Author: TableRecord {
1622+
/// enum Columns {
1623+
/// static let countryCode = Column("countryCode")
1624+
/// }
1625+
/// }
1626+
///
1627+
/// struct Book: TableRecord, FetchableRecord {
16131628
/// static let author = belongsTo(Author.self)
16141629
/// }
16151630
///
1616-
/// let frenchAuthors = Book.author.filter(Column("countryCode") == "FR")
1631+
/// let frenchAuthors = Book.author.filter { $0.countryCode == "FR" }
16171632
/// let bookInfos = try Book.all()
16181633
/// .joining(required: frenchAuthors)
16191634
/// .fetchAll(db)
@@ -1630,9 +1645,19 @@ extension JoinableRequest where Self: SelectionRequest {
16301645
/// For example:
16311646
///
16321647
/// ```swift
1648+
/// struct Team: TableRecord {
1649+
/// enum Columns {
1650+
/// static let countryCode = Column("countryCode")
1651+
/// }
1652+
/// }
1653+
///
1654+
/// struct Player: Decodable, TableRecord, FetchableRecord {
1655+
/// static let team = belongsTo(Team.self)
1656+
/// }
1657+
///
16331658
/// // SELECT player.*, team.color
16341659
/// // FROM player LEFT JOIN team ...
1635-
/// let teamColor = Player.team.select(Column("color"))
1660+
/// let teamColor = Player.team.select(\.color)
16361661
/// let request = Player.all().annotated(withOptional: teamColor)
16371662
/// ```
16381663
///
@@ -1682,17 +1707,19 @@ extension JoinableRequest where Self: SelectionRequest {
16821707
/// For example:
16831708
///
16841709
/// ```swift
1685-
/// struct Player: TableRecord { }
1686-
///
16871710
/// struct Team: TableRecord {
16881711
/// enum Columns {
16891712
/// static let color = Column("color")
16901713
/// }
16911714
/// }
16921715
///
1716+
/// struct Player: Decodable, FetchableRecord, TableRecord {
1717+
/// static let team = belongsTo(Team.self)
1718+
/// }
1719+
///
16931720
/// // SELECT player.*, team.color
16941721
/// // FROM player JOIN team ...
1695-
/// let teamColor = Player.team.select { $0.color }
1722+
/// let teamColor = Player.team.select(\.color)
16961723
/// let request = Player.all().annotated(withRequired: teamColor)
16971724
/// ```
16981725
///
@@ -1852,11 +1879,17 @@ public protocol DerivableRequest<RowDecoder>: AggregatingRequest, FilteredReques
18521879
/// For example:
18531880
///
18541881
/// ```swift
1882+
/// struct Player: TableRecord {
1883+
/// enum Columns {
1884+
/// static let name = Column("name")
1885+
/// }
1886+
/// }
1887+
///
18551888
/// // SELECT DISTINCT * FROM player
18561889
/// let request = Player.all().distinct()
18571890
///
18581891
/// // SELECT DISTINCT name FROM player
1859-
/// let request = Player.select(Column("name")).distinct()
1892+
/// let request = Player.select(\.name).distinct()
18601893
/// ```
18611894
func distinct() -> Self
18621895

@@ -1869,18 +1902,31 @@ public protocol DerivableRequest<RowDecoder>: AggregatingRequest, FilteredReques
18691902
/// latest message:
18701903
///
18711904
/// ```swift
1905+
/// struct Chat: TableRecord {
1906+
/// enum Columns {
1907+
/// static let id = Column("id")
1908+
/// }
1909+
/// }
1910+
///
1911+
/// struct Message: TableRecord {
1912+
/// enum Columns {
1913+
/// static let date = Column("date")
1914+
/// static let chatId = Column("chatId")
1915+
/// }
1916+
/// }
1917+
///
18721918
/// let latestMessageRequest = Message
1873-
/// .annotated(with: max(Column("date")))
1874-
/// .group(Column("chatID"))
1919+
/// .annotated { max($0.date) }
1920+
/// .group(\.chatId)
18751921
///
1876-
/// let latestMessageCTE = CommonTableExpression(
1922+
/// let latestMessageCTE = CommonTableExpression<Message>(
18771923
/// named: "latestMessage",
18781924
/// request: latestMessageRequest)
18791925
///
18801926
/// let latestMessageAssociation = Chat.association(
18811927
/// to: latestMessageCTE,
18821928
/// on: { chat, latestMessage in
1883-
/// chat[Column("id")] == latestMessage[Column("chatID")]
1929+
/// chat.id == latestMessage.chatId
18841930
/// })
18851931
///
18861932
/// // WITH latestMessage AS

GRDB/QueryInterface/SQL/Column.swift

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,18 @@ extension ColumnExpression {
3939
/// SQL generated by the query interface.
4040
///
4141
/// For example, see how `Column("total").detached` makes it possible to
42-
/// sort this query, when a raw `Column("total")` could not:
42+
/// sort this query:
4343
///
4444
/// ```swift
45+
/// struct Player: TableRecord {
46+
/// static let team = belongsTo(Team.self)
47+
///
48+
/// enum Columns {
49+
/// static let score = Column("score")
50+
/// static let bonus = Column("bonus")
51+
/// }
52+
/// }
53+
///
4554
/// // SELECT player.*,
4655
/// // (player.score + player.bonus) AS total,
4756
/// // team.*
@@ -50,9 +59,9 @@ extension ColumnExpression {
5059
/// // ORDER BY total, player.name
5160
/// // ~~~~~
5261
/// let request = Player
53-
/// .annotated(with: (Column("score") + Column("bonus")).forKey("total"))
62+
/// .annotated { ($0.score + $0.bonus).forKey("total") }
5463
/// .including(required: Player.team)
55-
/// .order(Column("total").detached, Column("name"))
64+
/// .order { [Column("total").detached, $0.name] }
5665
/// ```
5766
public var detached: SQLExpression {
5867
SQL(sql: name.quotedDatabaseIdentifier).sqlExpression
@@ -76,14 +85,29 @@ extension ColumnExpression where Self == Column {
7685
/// For example:
7786
///
7887
/// ```swift
79-
/// struct Player: TableRecord {
88+
/// struct Player: FetchableRecord, TableRecord {
8089
/// var score: Int
90+
///
91+
/// enum Columns {
92+
/// static let score = Column("score")
93+
/// }
8194
/// }
8295
///
83-
/// let maximumScore = try dbQueue.read { db in
84-
/// // SELECT MAX(score) FROM player
96+
/// try dbQueue.read { db in
97+
/// // DELETE FROM player WHERE score = 0
8598
/// try Player
86-
/// .select(max(Column("score")), as: Int.self)
99+
/// .filter { $0.score == 0 }
100+
/// .deleteAll(db)
101+
///
102+
/// // SELECT * FROM player ORDER BY score DESC LIMIT 10
103+
/// let bestPlayers = try Player
104+
/// .order(\.score)
105+
/// .limit(10)
106+
/// .fetchAll(db)
107+
///
108+
/// // SELECT MAX(score) FROM player
109+
/// let maximumScore = try Player
110+
/// .select({ max($0.score) }, as: Int.self)
87111
/// .fetchOne(db)
88112
/// }
89113
/// ```

0 commit comments

Comments
 (0)