Skip to content

Commit 8d4288d

Browse files
committed
wip
1 parent 68966b4 commit 8d4288d

File tree

2 files changed

+355
-4
lines changed

2 files changed

+355
-4
lines changed

Sources/StructuredQueriesCore/Statements/Select+DynamicMemberLookup.swift

Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,4 +187,237 @@
187187
self + From.self[keyPath: keyPath]
188188
}
189189
}
190+
191+
extension Select where From: TableDraft {
192+
public subscript<
193+
each C: QueryRepresentable,
194+
each J: Table,
195+
S: SelectStatement<(), From.PrimaryTable, ()>
196+
>(
197+
dynamicMember keyPath: KeyPath<From.PrimaryTable.Type, S>
198+
) -> Select<(repeat each C), From, (repeat each J)>
199+
where Columns == (repeat each C), Joins == (repeat each J) {
200+
self
201+
+ unsafeBitCast(
202+
From.PrimaryTable.self[keyPath: keyPath].asSelect(),
203+
to: Select<(), From, ()>.self
204+
)
205+
}
206+
207+
public subscript<
208+
each C1: QueryRepresentable,
209+
C2: QueryRepresentable,
210+
each J: Table
211+
>(
212+
dynamicMember keyPath: KeyPath<From.PrimaryTable.Type, Select<C2, From.PrimaryTable, ()>>
213+
) -> Select<(repeat each C1, C2), From, (repeat each J)>
214+
where Columns == (repeat each C1), Joins == (repeat each J) {
215+
self
216+
+ unsafeBitCast(
217+
From.PrimaryTable.self[keyPath: keyPath],
218+
to: Select<C2, From, ()>.self
219+
)
220+
}
221+
222+
public subscript<
223+
each C1: QueryRepresentable,
224+
C2: QueryRepresentable,
225+
C3: QueryRepresentable,
226+
each J: Table
227+
>(
228+
dynamicMember keyPath: KeyPath<
229+
From.PrimaryTable.Type, Select<(C2, C3), From.PrimaryTable, ()>
230+
>
231+
) -> Select<(repeat each C1, C2, C3), From, (repeat each J)>
232+
where Columns == (repeat each C1), Joins == (repeat each J) {
233+
self
234+
+ unsafeBitCast(
235+
From.PrimaryTable.self[keyPath: keyPath],
236+
to: Select<(C2, C3), From, ()>.self
237+
)
238+
}
239+
240+
public subscript<
241+
each C1: QueryRepresentable,
242+
C2: QueryRepresentable,
243+
C3: QueryRepresentable,
244+
C4: QueryRepresentable,
245+
each J: Table
246+
>(
247+
dynamicMember keyPath: KeyPath<
248+
From.PrimaryTable.Type, Select<(C2, C3, C4), From.PrimaryTable, ()>
249+
>
250+
) -> Select<(repeat each C1, C2, C3, C4), From, (repeat each J)>
251+
where Columns == (repeat each C1), Joins == (repeat each J) {
252+
self
253+
+ unsafeBitCast(
254+
From.PrimaryTable.self[keyPath: keyPath],
255+
to: Select<(C2, C3, C4), From, ()>.self
256+
)
257+
}
258+
259+
public subscript<
260+
each C1: QueryRepresentable,
261+
C2: QueryRepresentable,
262+
C3: QueryRepresentable,
263+
C4: QueryRepresentable,
264+
C5: QueryRepresentable,
265+
each J: Table
266+
>(
267+
dynamicMember keyPath: KeyPath<
268+
From.PrimaryTable.Type, Select<(C2, C3, C4, C5), From.PrimaryTable, ()>
269+
>
270+
) -> Select<(repeat each C1, C2, C3, C4, C5), From, (repeat each J)>
271+
where Columns == (repeat each C1), Joins == (repeat each J) {
272+
self
273+
+ unsafeBitCast(
274+
From.PrimaryTable.self[keyPath: keyPath],
275+
to: Select<(C2, C3, C4, C5), From, ()>.self
276+
)
277+
}
278+
279+
public subscript<
280+
each C1: QueryRepresentable,
281+
C2: QueryRepresentable,
282+
each J1: Table,
283+
J2: Table
284+
>(
285+
dynamicMember keyPath: KeyPath<From.PrimaryTable.Type, Select<C2, From.PrimaryTable, J2>>
286+
) -> Select<(repeat each C1, C2), From, (repeat each J1, J2)>
287+
where Columns == (repeat each C1), Joins == (repeat each J1) {
288+
self
289+
+ unsafeBitCast(
290+
From.PrimaryTable.self[keyPath: keyPath],
291+
to: Select<C2, From, J2>.self
292+
)
293+
}
294+
295+
public subscript<
296+
each C1: QueryRepresentable,
297+
C2: QueryRepresentable,
298+
C3: QueryRepresentable,
299+
each J1: Table,
300+
J2: Table
301+
>(
302+
dynamicMember keyPath: KeyPath<
303+
From.PrimaryTable.Type, Select<(C2, C3), From.PrimaryTable, J2>
304+
>
305+
) -> Select<(repeat each C1, C2, C3), From, (repeat each J1, J2)>
306+
where Columns == (repeat each C1), Joins == (repeat each J1) {
307+
self
308+
+ unsafeBitCast(
309+
From.PrimaryTable.self[keyPath: keyPath],
310+
to: Select<(C2, C3), From, J2>.self
311+
)
312+
}
313+
314+
public subscript<
315+
each C1: QueryRepresentable,
316+
C2: QueryRepresentable,
317+
C3: QueryRepresentable,
318+
C4: QueryRepresentable,
319+
each J1: Table,
320+
J2: Table
321+
>(
322+
dynamicMember keyPath: KeyPath<
323+
From.PrimaryTable.Type, Select<(C2, C3, C4), From.PrimaryTable, J2>
324+
>
325+
) -> Select<(repeat each C1, C2, C3, C4), From, (repeat each J1, J2)>
326+
where Columns == (repeat each C1), Joins == (repeat each J1) {
327+
self
328+
+ unsafeBitCast(
329+
From.PrimaryTable.self[keyPath: keyPath],
330+
to: Select<(C2, C3, C4), From, J2>.self
331+
)
332+
}
333+
334+
public subscript<
335+
each C1: QueryRepresentable,
336+
C2: QueryRepresentable,
337+
C3: QueryRepresentable,
338+
C4: QueryRepresentable,
339+
C5: QueryRepresentable,
340+
each J1: Table,
341+
J2: Table
342+
>(
343+
dynamicMember
344+
keyPath: KeyPath<From.PrimaryTable.Type, Select<(C2, C3, C4, C5), From.PrimaryTable, J2>>
345+
) -> Select<(repeat each C1, C2, C3, C4, C5), From, (repeat each J1, J2)>
346+
where Columns == (repeat each C1), Joins == (repeat each J1) {
347+
self + unsafeBitCast(
348+
From.PrimaryTable.self[keyPath: keyPath],
349+
to: Select<(C2, C3, C4, C5), From, J2>.self
350+
)
351+
}
352+
353+
// public subscript<
354+
// each C: QueryRepresentable,
355+
// each J1: Table,
356+
// J2: Table,
357+
// J3: Table
358+
// >(
359+
// dynamicMember keyPath: KeyPath<From.PrimaryTable.Type, Select<(), From, (J2, J3)>>
360+
// ) -> Select<(repeat each C), From, (repeat each J1, J2, J3)>
361+
// where Columns == (repeat each C), Joins == (repeat each J1) {
362+
// self + From.PrimaryTable.self[keyPath: keyPath]
363+
// }
364+
//
365+
// public subscript<
366+
// each C1: QueryRepresentable,
367+
// C2: QueryRepresentable,
368+
// each J1: Table,
369+
// J2: Table,
370+
// J3: Table
371+
// >(
372+
// dynamicMember keyPath: KeyPath<From.PrimaryTable.Type, Select<C2, From, (J2, J3)>>
373+
// ) -> Select<(repeat each C1, C2), From, (repeat each J1, J2, J3)>
374+
// where Columns == (repeat each C1), Joins == (repeat each J1) {
375+
// self + From.PrimaryTable.self[keyPath: keyPath]
376+
// }
377+
//
378+
// public subscript<
379+
// each C1: QueryRepresentable,
380+
// C2: QueryRepresentable,
381+
// C3: QueryRepresentable,
382+
// each J1: Table,
383+
// J2: Table,
384+
// J3: Table
385+
// >(
386+
// dynamicMember keyPath: KeyPath<From.PrimaryTable.Type, Select<(C2, C3), From, (J2, J3)>>
387+
// ) -> Select<(repeat each C1, C2, C3), From, (repeat each J1, J2, J3)>
388+
// where Columns == (repeat each C1), Joins == (repeat each J1) {
389+
// self + From.PrimaryTable.self[keyPath: keyPath]
390+
// }
391+
//
392+
// public subscript<
393+
// each C1: QueryRepresentable,
394+
// C2: QueryRepresentable,
395+
// C3: QueryRepresentable,
396+
// C4: QueryRepresentable,
397+
// each J1: Table,
398+
// J2: Table,
399+
// J3: Table
400+
// >(
401+
// dynamicMember keyPath: KeyPath<From.PrimaryTable.Type, Select<(C2, C3, C4), From, (J2, J3)>>
402+
// ) -> Select<(repeat each C1, C2, C3, C4), From, (repeat each J1, J2, J3)>
403+
// where Columns == (repeat each C1), Joins == (repeat each J1) {
404+
// self + From.PrimaryTable.self[keyPath: keyPath]
405+
// }
406+
//
407+
// public subscript<
408+
// each C1: QueryRepresentable,
409+
// C2: QueryRepresentable,
410+
// C3: QueryRepresentable,
411+
// C4: QueryRepresentable,
412+
// C5: QueryRepresentable,
413+
// each J1: Table,
414+
// J2: Table,
415+
// J3: Table
416+
// >(
417+
// dynamicMember keyPath: KeyPath<From.PrimaryTable.Type, Select<(C2, C3, C4, C5), From, (J2, J3)>>
418+
// ) -> Select<(repeat each C1, C2, C3, C4, C5), From, (repeat each J1, J2, J3)>
419+
// where Columns == (repeat each C1), Joins == (repeat each J1) {
420+
// self + From.PrimaryTable.self[keyPath: keyPath]
421+
// }
422+
}
190423
#endif

Tests/StructuredQueriesTests/SelectTests.swift

Lines changed: 122 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1214,10 +1214,128 @@ extension SnapshotTests {
12141214
└───┘
12151215
"""
12161216
}
1217-
// TODO: Compile
1218-
// assertQuery(
1219-
// Reminder.Draft.select(\.id).incomplete
1220-
// )
1217+
assertQuery(
1218+
Reminder.Draft.select(\.id).incomplete.select(\.id)
1219+
) {
1220+
"""
1221+
SELECT "reminders"."id", "reminders"."id"
1222+
FROM "reminders"
1223+
WHERE NOT ("reminders"."isCompleted")
1224+
"""
1225+
} results: {
1226+
"""
1227+
┌───┬───┐
1228+
│ 1 │ 1 │
1229+
│ 2 │ 2 │
1230+
│ 3 │ 3 │
1231+
│ 5 │ 5 │
1232+
│ 6 │ 6 │
1233+
│ 8 │ 8 │
1234+
│ 9 │ 9 │
1235+
└───┴───┘
1236+
"""
1237+
}
1238+
assertQuery(
1239+
Reminder.Draft.all.incomplete
1240+
) {
1241+
"""
1242+
SELECT "reminders"."id", "reminders"."assignedUserID", "reminders"."dueDate", "reminders"."isCompleted", "reminders"."isFlagged", "reminders"."notes", "reminders"."priority", "reminders"."remindersListID", "reminders"."title"
1243+
FROM "reminders"
1244+
WHERE NOT ("reminders"."isCompleted")
1245+
"""
1246+
} results: {
1247+
#"""
1248+
┌────────────────────────────────────────────┐
1249+
│ Reminder.Draft( │
1250+
│ id: 1, │
1251+
│ assignedUserID: 1, │
1252+
│ dueDate: Date(2001-01-01T00:00:00.000Z), │
1253+
│ isCompleted: false, │
1254+
│ isFlagged: false, │
1255+
│ notes: "Milk, Eggs, Apples", │
1256+
│ priority: nil, │
1257+
│ remindersListID: 1, │
1258+
│ title: "Groceries" │
1259+
│ ) │
1260+
├────────────────────────────────────────────┤
1261+
│ Reminder.Draft( │
1262+
│ id: 2, │
1263+
│ assignedUserID: nil, │
1264+
│ dueDate: Date(2000-12-30T00:00:00.000Z), │
1265+
│ isCompleted: false, │
1266+
│ isFlagged: true, │
1267+
│ notes: "", │
1268+
│ priority: nil, │
1269+
│ remindersListID: 1, │
1270+
│ title: "Haircut" │
1271+
│ ) │
1272+
├────────────────────────────────────────────┤
1273+
│ Reminder.Draft( │
1274+
│ id: 3, │
1275+
│ assignedUserID: nil, │
1276+
│ dueDate: Date(2001-01-01T00:00:00.000Z), │
1277+
│ isCompleted: false, │
1278+
│ isFlagged: false, │
1279+
│ notes: "Ask about diet", │
1280+
│ priority: .high, │
1281+
│ remindersListID: 1, │
1282+
│ title: "Doctor appointment" │
1283+
│ ) │
1284+
├────────────────────────────────────────────┤
1285+
│ Reminder.Draft( │
1286+
│ id: 5, │
1287+
│ assignedUserID: nil, │
1288+
│ dueDate: nil, │
1289+
│ isCompleted: false, │
1290+
│ isFlagged: false, │
1291+
│ notes: "", │
1292+
│ priority: nil, │
1293+
│ remindersListID: 1, │
1294+
│ title: "Buy concert tickets" │
1295+
│ ) │
1296+
├────────────────────────────────────────────┤
1297+
│ Reminder.Draft( │
1298+
│ id: 6, │
1299+
│ assignedUserID: nil, │
1300+
│ dueDate: Date(2001-01-03T00:00:00.000Z), │
1301+
│ isCompleted: false, │
1302+
│ isFlagged: true, │
1303+
│ notes: "", │
1304+
│ priority: .high, │
1305+
│ remindersListID: 2, │
1306+
│ title: "Pick up kids from school" │
1307+
│ ) │
1308+
├────────────────────────────────────────────┤
1309+
│ Reminder.Draft( │
1310+
│ id: 8, │
1311+
│ assignedUserID: nil, │
1312+
│ dueDate: Date(2001-01-05T00:00:00.000Z), │
1313+
│ isCompleted: false, │
1314+
│ isFlagged: false, │
1315+
│ notes: "", │
1316+
│ priority: .high, │
1317+
│ remindersListID: 2, │
1318+
│ title: "Take out trash" │
1319+
│ ) │
1320+
├────────────────────────────────────────────┤
1321+
│ Reminder.Draft( │
1322+
│ id: 9, │
1323+
│ assignedUserID: nil, │
1324+
│ dueDate: Date(2001-01-03T00:00:00.000Z), │
1325+
│ isCompleted: false, │
1326+
│ isFlagged: false, │
1327+
│ notes: """ │
1328+
│ Status of tax return │
1329+
│ Expenses for next year │
1330+
│ Changing payroll company │
1331+
│ """, │
1332+
│ priority: nil, │
1333+
│ remindersListID: 3, │
1334+
│ title: "Call accountant" │
1335+
│ ) │
1336+
└────────────────────────────────────────────┘
1337+
"""#
1338+
}
12211339
}
12221340

12231341
@Test func reusableColumnHelperOnDraft() {

0 commit comments

Comments
 (0)