Skip to content

Commit b947d38

Browse files
authored
Support finding multiple rows by primary key. (pointfreeco#181)
* Support finding multiple rows by primary key. * wip * wip
1 parent 1340ecb commit b947d38

File tree

4 files changed

+170
-38
lines changed

4 files changed

+170
-38
lines changed

Sources/StructuredQueriesCore/PrimaryKeyed.swift

Lines changed: 111 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,17 @@ extension PrimaryKeyedTable {
8888
public static func find(
8989
_ primaryKey: some QueryExpression<TableColumns.PrimaryKey>
9090
) -> Where<Self> {
91-
Self.where { $0.primaryKey.eq(primaryKey) }
91+
Self.find([primaryKey])
92+
}
93+
94+
/// A where clause filtered by primary keys.
95+
///
96+
/// - Parameter primaryKey: Primary keys identifying table rows.
97+
/// - Returns: A `WHERE` clause.
98+
public static func find(
99+
_ primaryKeys: some Sequence<some QueryExpression<TableColumns.PrimaryKey>>
100+
) -> Where<Self> {
101+
Self.where { $0.primaryKey.in(primaryKeys) }
92102
}
93103

94104
public var primaryKey: PrimaryKey.QueryOutput {
@@ -104,9 +114,17 @@ extension TableDraft {
104114
public static func find(
105115
_ primaryKey: some QueryExpression<PrimaryTable.TableColumns.PrimaryKey>
106116
) -> Where<Self> {
107-
Self.where { _ in
108-
PrimaryTable.columns.primaryKey.eq(primaryKey)
109-
}
117+
Self.find([primaryKey])
118+
}
119+
120+
/// A where clause filtered by primary keys.
121+
///
122+
/// - Parameter primaryKeys: Primary keys identifying table rows.
123+
/// - Returns: A `WHERE` clause.
124+
public static func find(
125+
_ primaryKeys: some Sequence<some QueryExpression<PrimaryTable.TableColumns.PrimaryKey>>
126+
) -> Where<Self> {
127+
Self.where { $0.primaryKey.in(primaryKeys) }
110128
}
111129
}
112130

@@ -116,7 +134,17 @@ extension Where where From: PrimaryKeyedTable {
116134
/// - Parameter primaryKey: A primary key.
117135
/// - Returns: A where clause with the added primary key.
118136
public func find(_ primaryKey: some QueryExpression<From.TableColumns.PrimaryKey>) -> Self {
119-
self.where { $0.primaryKey.eq(primaryKey) }
137+
self.find([primaryKey])
138+
}
139+
140+
/// Adds a primary key condition to a where clause.
141+
///
142+
/// - Parameter primaryKeys: A sequence of primary keys.
143+
/// - Returns: A where clause with the added primary keys condition.
144+
public func find(
145+
_ primaryKeys: some Sequence<some QueryExpression<From.TableColumns.PrimaryKey>>
146+
) -> Self {
147+
Self.where { $0.primaryKey.in(primaryKeys) }
120148
}
121149
}
122150

@@ -125,12 +153,18 @@ extension Where where From: TableDraft {
125153
///
126154
/// - Parameter primaryKey: A primary key.
127155
/// - Returns: A where clause with the added primary key.
128-
public func find(_ primaryKey: From.PrimaryTable.TableColumns.PrimaryKey.QueryOutput) -> Self {
129-
self.where { _ in
130-
From.PrimaryTable.columns.primaryKey.eq(
131-
From.PrimaryTable.TableColumns.PrimaryKey(queryOutput: primaryKey)
132-
)
133-
}
156+
public func find(_ primaryKey: some QueryExpression<From.PrimaryTable.TableColumns.PrimaryKey>) -> Self {
157+
self.find([primaryKey])
158+
}
159+
160+
/// Adds a primary key condition to a where clause.
161+
///
162+
/// - Parameter primaryKeys: A sequence of primary keys.
163+
/// - Returns: A where clause with the added primary keys condition.
164+
public func find(
165+
_ primaryKeys: some Sequence<some QueryExpression<From.PrimaryTable.TableColumns.PrimaryKey>>
166+
) -> Self {
167+
Self.where { $0.primaryKey.in(primaryKeys) }
134168
}
135169
}
136170

@@ -142,6 +176,16 @@ extension Select where From: PrimaryKeyedTable {
142176
public func find(_ primaryKey: some QueryExpression<From.TableColumns.PrimaryKey>) -> Self {
143177
self.and(From.find(primaryKey))
144178
}
179+
180+
/// A select statement filtered by a sequence of primary keys.
181+
///
182+
/// - Parameter primaryKeys: A sequence of primary keys.
183+
/// - Returns: A select statement filtered by the given keys.
184+
public func find(
185+
_ primaryKeys: some Sequence<some QueryExpression<From.TableColumns.PrimaryKey>>
186+
) -> Self {
187+
self.and(From.find(primaryKeys))
188+
}
145189
}
146190

147191
extension Select where From: TableDraft {
@@ -154,6 +198,16 @@ extension Select where From: TableDraft {
154198
) -> Self {
155199
self.and(From.find(primaryKey))
156200
}
201+
202+
/// A select statement filtered by a sequence of primary keys.
203+
///
204+
/// - Parameter primaryKeys: A sequence of primary keys.
205+
/// - Returns: A select statement filtered by the given keys.
206+
public func find(
207+
_ primaryKeys: some Sequence<some QueryExpression<From.PrimaryTable.TableColumns.PrimaryKey>>
208+
) -> Self {
209+
self.and(From.find(primaryKeys))
210+
}
157211
}
158212

159213
extension Update where From: PrimaryKeyedTable {
@@ -162,7 +216,17 @@ extension Update where From: PrimaryKeyedTable {
162216
/// - Parameter primaryKey: A primary key identifying a table row.
163217
/// - Returns: An update statement filtered by the given key.
164218
public func find(_ primaryKey: some QueryExpression<From.TableColumns.PrimaryKey>) -> Self {
165-
self.where { $0.primaryKey.eq(primaryKey) }
219+
self.find([primaryKey])
220+
}
221+
222+
/// An update statement filtered by a sequence of primary keys.
223+
///
224+
/// - Parameter primaryKeys: A sequence of primary keys.
225+
/// - Returns: An update statement filtered by the given keys.
226+
public func find(
227+
_ primaryKeys: some Sequence<some QueryExpression<From.TableColumns.PrimaryKey>>
228+
) -> Self {
229+
self.where { $0.primaryKey.in(primaryKeys) }
166230
}
167231
}
168232

@@ -171,12 +235,18 @@ extension Update where From: TableDraft {
171235
///
172236
/// - Parameter primaryKey: A primary key identifying a table row.
173237
/// - Returns: An update statement filtered by the given key.
174-
public func find(_ primaryKey: From.PrimaryTable.TableColumns.PrimaryKey.QueryOutput) -> Self {
175-
self.where { _ in
176-
From.PrimaryTable.columns.primaryKey.eq(
177-
From.PrimaryTable.TableColumns.PrimaryKey(queryOutput: primaryKey)
178-
)
179-
}
238+
public func find(_ primaryKey: some QueryExpression<From.PrimaryTable.TableColumns.PrimaryKey>) -> Self {
239+
self.find([primaryKey])
240+
}
241+
242+
/// An update statement filtered by a sequence of primary keys.
243+
///
244+
/// - Parameter primaryKeys: A sequence of primary keys.
245+
/// - Returns: An update statement filtered by the given keys.
246+
public func find(
247+
_ primaryKeys: some Sequence<some QueryExpression<From.PrimaryTable.TableColumns.PrimaryKey>>
248+
) -> Self {
249+
self.where { $0.primaryKey.in(primaryKeys) }
180250
}
181251
}
182252

@@ -186,7 +256,17 @@ extension Delete where From: PrimaryKeyedTable {
186256
/// - Parameter primaryKey: A primary key identifying a table row.
187257
/// - Returns: A delete statement filtered by the given key.
188258
public func find(_ primaryKey: some QueryExpression<From.TableColumns.PrimaryKey>) -> Self {
189-
self.where { $0.primaryKey.eq(primaryKey) }
259+
self.find([primaryKey])
260+
}
261+
262+
/// A delete statement filtered by a sequence of primary keys.
263+
///
264+
/// - Parameter primaryKeys: A sequence of primary keys.
265+
/// - Returns: A delete statement filtered by the given keys.
266+
public func find(
267+
_ primaryKeys: some Sequence<some QueryExpression<From.TableColumns.PrimaryKey>>
268+
) -> Self {
269+
self.where { $0.primaryKey.in(primaryKeys) }
190270
}
191271
}
192272

@@ -195,11 +275,17 @@ extension Delete where From: TableDraft {
195275
///
196276
/// - Parameter primaryKey: A primary key identifying a table row.
197277
/// - Returns: A delete statement filtered by the given key.
198-
public func find(_ primaryKey: From.PrimaryTable.TableColumns.PrimaryKey.QueryOutput) -> Self {
199-
self.where { _ in
200-
From.PrimaryTable.columns.primaryKey.eq(
201-
From.PrimaryTable.TableColumns.PrimaryKey(queryOutput: primaryKey)
202-
)
203-
}
278+
public func find(_ primaryKey: some QueryExpression<From.PrimaryTable.TableColumns.PrimaryKey>) -> Self {
279+
self.find([primaryKey])
280+
}
281+
282+
/// A delete statement filtered by a sequence of primary keys.
283+
///
284+
/// - Parameter primaryKeys: A sequence of primary keys.
285+
/// - Returns: A delete statement filtered by the given keys.
286+
public func find(
287+
_ primaryKeys: some Sequence<some QueryExpression<From.PrimaryTable.TableColumns.PrimaryKey>>
288+
) -> Self {
289+
self.where { $0.primaryKey.in(primaryKeys) }
204290
}
205291
}

Tests/StructuredQueriesTests/PrimaryKeyedTableTests.swift

Lines changed: 56 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ extension SnapshotTests {
3232
"""
3333
UPDATE "reminders"
3434
SET "title" = ("reminders"."title" || '!!!')
35-
WHERE ("reminders"."id" = 1)
35+
WHERE ("reminders"."id" IN (1))
3636
RETURNING "title"
3737
"""
3838
} results: {
@@ -50,7 +50,7 @@ extension SnapshotTests {
5050
"""
5151
UPDATE "reminders"
5252
SET "title" = ("reminders"."title" || '???')
53-
WHERE ("reminders"."id" = 1)
53+
WHERE ("reminders"."id" IN (1))
5454
RETURNING "title"
5555
"""
5656
} results: {
@@ -69,7 +69,7 @@ extension SnapshotTests {
6969
) {
7070
"""
7171
DELETE FROM "reminders"
72-
WHERE ("reminders"."id" = 1)
72+
WHERE ("reminders"."id" IN (1))
7373
RETURNING "reminders"."id"
7474
"""
7575
} results: {
@@ -86,7 +86,7 @@ extension SnapshotTests {
8686
) {
8787
"""
8888
DELETE FROM "reminders"
89-
WHERE ("reminders"."id" = 2)
89+
WHERE ("reminders"."id" IN (2))
9090
RETURNING "reminders"."id"
9191
"""
9292
} results: {
@@ -105,7 +105,7 @@ extension SnapshotTests {
105105
"""
106106
SELECT "reminders"."id", "reminders"."title"
107107
FROM "reminders"
108-
WHERE ("reminders"."id" = 1)
108+
WHERE ("reminders"."id" IN (1))
109109
"""
110110
} results: {
111111
"""
@@ -121,7 +121,7 @@ extension SnapshotTests {
121121
"""
122122
SELECT "reminders"."id", "reminders"."title"
123123
FROM "reminders"
124-
WHERE ("reminders"."id" = 1)
124+
WHERE ("reminders"."id" IN (1))
125125
"""
126126
} results: {
127127
"""
@@ -137,7 +137,7 @@ extension SnapshotTests {
137137
"""
138138
SELECT "reminders"."id", "reminders"."title"
139139
FROM "reminders"
140-
WHERE ("reminders"."id" = 2)
140+
WHERE ("reminders"."id" IN (2))
141141
"""
142142
} results: {
143143
"""
@@ -147,13 +147,59 @@ extension SnapshotTests {
147147
"""
148148
}
149149

150+
assertQuery(
151+
Reminder.select { ($0.id, $0.title) }.find([2, 4, 6])
152+
) {
153+
"""
154+
SELECT "reminders"."id", "reminders"."title"
155+
FROM "reminders"
156+
WHERE ("reminders"."id" IN (2, 4, 6))
157+
"""
158+
} results: {
159+
"""
160+
┌───┬────────────────────────────┐
161+
│ 2 │ "Haircut"
162+
│ 4 │ "Take a walk"
163+
│ 6 │ "Pick up kids from school"
164+
└───┴────────────────────────────┘
165+
"""
166+
}
167+
168+
assertQuery(
169+
Reminder.select { ($0.id, $0.title) }.find(Reminder.select(\.id))
170+
) {
171+
"""
172+
SELECT "reminders"."id", "reminders"."title"
173+
FROM "reminders"
174+
WHERE ("reminders"."id" IN ((
175+
SELECT "reminders"."id"
176+
FROM "reminders"
177+
)))
178+
"""
179+
} results: {
180+
"""
181+
┌────┬────────────────────────────┐
182+
│ 1 │ "Groceries"
183+
│ 2 │ "Haircut"
184+
│ 3 │ "Doctor appointment"
185+
│ 4 │ "Take a walk"
186+
│ 5 │ "Buy concert tickets"
187+
│ 6 │ "Pick up kids from school"
188+
│ 7 │ "Get laundry"
189+
│ 8 │ "Take out trash"
190+
│ 9 │ "Call accountant"
191+
│ 10 │ "Send weekly emails"
192+
└────┴────────────────────────────┘
193+
"""
194+
}
195+
150196
assertQuery(
151197
Reminder.Draft.select { ($0.id, $0.title) }.find(2)
152198
) {
153199
"""
154200
SELECT "reminders"."id", "reminders"."title"
155201
FROM "reminders"
156-
WHERE ("reminders"."id" = 2)
202+
WHERE ("reminders"."id" IN (2))
157203
"""
158204
} results: {
159205
"""
@@ -175,7 +221,7 @@ extension SnapshotTests {
175221
SELECT "reminders"."title", "remindersLists"."title"
176222
FROM "reminders"
177223
JOIN "remindersLists" ON ("reminders"."remindersListID" = "remindersLists"."id")
178-
WHERE ("reminders"."id" = 2)
224+
WHERE ("reminders"."id" IN (2))
179225
"""
180226
} results: {
181227
"""
@@ -214,7 +260,7 @@ extension SnapshotTests {
214260
"""
215261
SELECT "rows"."id", "rows"."isDeleted", "rows"."isNotDeleted"
216262
FROM "rows"
217-
WHERE ("rows"."id" = '00000000-0000-0000-0000-000000000001')
263+
WHERE ("rows"."id" IN ('00000000-0000-0000-0000-000000000001'))
218264
"""
219265
} results: {
220266
"""

Tests/StructuredQueriesTests/UpdateTests.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ extension SnapshotTests {
365365
"""
366366
UPDATE "reminders"
367367
SET "dueDate" = CASE WHEN ("reminders"."dueDate" IS NULL) THEN '2018-01-29 00:08:00.000' END
368-
WHERE ("reminders"."id" = 1)
368+
WHERE ("reminders"."id" IN (1))
369369
RETURNING "dueDate"
370370
"""
371371
} results: {
@@ -383,7 +383,7 @@ extension SnapshotTests {
383383
"""
384384
UPDATE "reminders"
385385
SET "dueDate" = CASE WHEN ("reminders"."dueDate" IS NULL) THEN '2018-01-29 00:08:00.000' END
386-
WHERE ("reminders"."id" = 1)
386+
WHERE ("reminders"."id" IN (1))
387387
RETURNING "dueDate"
388388
"""
389389
} results: {

Tests/StructuredQueriesTests/WhereTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ extension SnapshotTests {
225225
SELECT "remindersLists"."id", "remindersLists"."color", "remindersLists"."title", "remindersLists"."position", "reminders"."id", "reminders"."assignedUserID", "reminders"."dueDate", "reminders"."isCompleted", "reminders"."isFlagged", "reminders"."notes", "reminders"."priority", "reminders"."remindersListID", "reminders"."title", "reminders"."updatedAt"
226226
FROM "remindersLists"
227227
LEFT JOIN "reminders" ON ("remindersLists"."id" = "reminders"."remindersListID")
228-
WHERE ("remindersLists"."id" = 4) AND "reminders"."isCompleted"
228+
WHERE ("remindersLists"."id" IN (4)) AND "reminders"."isCompleted"
229229
"""
230230
} results: {
231231
"""

0 commit comments

Comments
 (0)