Skip to content

Commit c7cac92

Browse files
committed
wip
1 parent 7d434e2 commit c7cac92

File tree

4 files changed

+255
-84
lines changed

4 files changed

+255
-84
lines changed

Sources/StructuredQueriesCore/Statements/Insert.swift

Lines changed: 144 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -144,12 +144,10 @@ extension Table {
144144
/// existing row.
145145
/// - updateFilter: A filter to apply to the update clause.
146146
/// - Returns: An insert statement.
147-
public static func insert<T1, each T2>(
147+
public static func insert<T1: _TableColumnExpression, each T2: _TableColumnExpression>(
148148
_ columns: (TableColumns) -> TableColumns = { $0 },
149149
@InsertValuesBuilder<Self> values: () -> [[QueryFragment]],
150-
onConflict conflictTargets: (TableColumns) -> (
151-
TableColumn<Self, T1>, repeat TableColumn<Self, each T2>
152-
),
150+
onConflict conflictTargets: (TableColumns) -> (T1, repeat each T2),
153151
@QueryFragmentBuilder<Bool>
154152
where targetFilter: (TableColumns) -> [QueryFragment] = { _ in [] },
155153
doUpdate updates: (inout Updates<Self>, Excluded) -> Void = { _, _ in },
@@ -179,12 +177,10 @@ extension Table {
179177
/// existing row.
180178
/// - updateFilter: A filter to apply to the update clause.
181179
/// - Returns: An insert statement.
182-
public static func insert<T1, each T2>(
180+
public static func insert<T1: _TableColumnExpression, each T2: _TableColumnExpression>(
183181
_ columns: (TableColumns) -> TableColumns = { $0 },
184182
@InsertValuesBuilder<Self> values: () -> [[QueryFragment]],
185-
onConflict conflictTargets: (TableColumns) -> (
186-
TableColumn<Self, T1>, repeat TableColumn<Self, each T2>
187-
),
183+
onConflict conflictTargets: (TableColumns) -> (T1, repeat each T2),
188184
@QueryFragmentBuilder<Bool>
189185
where targetFilter: (TableColumns) -> [QueryFragment] = { _ in [] },
190186
doUpdate updates: (inout Updates<Self>) -> Void,
@@ -255,9 +251,9 @@ extension Table {
255251
/// existing row.
256252
/// - updateFilter: A filter to apply to the update clause.
257253
/// - Returns: An insert statement.
258-
public static func insert<V1, each V2>(
259-
_ columns: (TableColumns) -> (TableColumn<Self, V1>, repeat TableColumn<Self, each V2>),
260-
@InsertValuesBuilder<(V1, repeat each V2)>
254+
public static func insert<V1: _TableColumnExpression, each V2: _TableColumnExpression>(
255+
_ columns: (TableColumns) -> (V1, repeat each V2),
256+
@InsertValuesBuilder<(V1.Value, repeat (each V2).Value)>
261257
values: () -> [[QueryFragment]],
262258
onConflictDoUpdate updates: ((inout Updates<Self>, Excluded) -> Void)? = nil,
263259
@QueryFragmentBuilder<Bool>
@@ -282,9 +278,9 @@ extension Table {
282278
/// existing row.
283279
/// - updateFilter: A filter to apply to the update clause.
284280
/// - Returns: An insert statement.
285-
public static func insert<V1, each V2>(
286-
_ columns: (TableColumns) -> (TableColumn<Self, V1>, repeat TableColumn<Self, each V2>),
287-
@InsertValuesBuilder<(V1, repeat each V2)>
281+
public static func insert<V1: _TableColumnExpression, each V2: _TableColumnExpression>(
282+
_ columns: (TableColumns) -> (V1, repeat each V2),
283+
@InsertValuesBuilder<(V1.Value, repeat (each V2).Value)>
288284
values: () -> [[QueryFragment]],
289285
onConflictDoUpdate updates: ((inout Updates<Self>) -> Void)?,
290286
@QueryFragmentBuilder<Bool>
@@ -309,13 +305,16 @@ extension Table {
309305
/// existing row.
310306
/// - updateFilter: A filter to apply to the update clause.
311307
/// - Returns: An insert statement.
312-
public static func insert<V1, each V2, T1, each T2>(
313-
_ columns: (TableColumns) -> (TableColumn<Self, V1>, repeat TableColumn<Self, each V2>),
314-
@InsertValuesBuilder<(V1, repeat each V2)>
308+
public static func insert<
309+
V1: _TableColumnExpression,
310+
each V2: _TableColumnExpression,
311+
T1: _TableColumnExpression,
312+
each T2: _TableColumnExpression
313+
>(
314+
_ columns: (TableColumns) -> (V1, repeat each V2),
315+
@InsertValuesBuilder<(V1.Value, repeat (each V2).Value)>
315316
values: () -> [[QueryFragment]],
316-
onConflict conflictTargets: (TableColumns) -> (
317-
TableColumn<Self, T1>, repeat TableColumn<Self, each T2>
318-
),
317+
onConflict conflictTargets: (TableColumns) -> (T1, repeat each T2),
319318
@QueryFragmentBuilder<Bool>
320319
where targetFilter: (TableColumns) -> [QueryFragment] = { _ in [] },
321320
doUpdate updates: (inout Updates<Self>, Excluded) -> Void = { _, _ in },
@@ -345,13 +344,16 @@ extension Table {
345344
/// existing row.
346345
/// - updateFilter: A filter to apply to the update clause.
347346
/// - Returns: An insert statement.
348-
public static func insert<V1, each V2, T1, each T2>(
349-
_ columns: (TableColumns) -> (TableColumn<Self, V1>, repeat TableColumn<Self, each V2>),
350-
@InsertValuesBuilder<(V1, repeat each V2)>
347+
public static func insert<
348+
V1: _TableColumnExpression,
349+
each V2: _TableColumnExpression,
350+
T1: _TableColumnExpression,
351+
each T2: _TableColumnExpression
352+
>(
353+
_ columns: (TableColumns) -> (V1, repeat each V2),
354+
@InsertValuesBuilder<(V1.Value, repeat (each V2).Value)>
351355
values: () -> [[QueryFragment]],
352-
onConflict conflictTargets: (TableColumns) -> (
353-
TableColumn<Self, T1>, repeat TableColumn<Self, each T2>
354-
),
356+
onConflict conflictTargets: (TableColumns) -> (T1, repeat each T2),
355357
@QueryFragmentBuilder<Bool>
356358
where targetFilter: (TableColumns) -> [QueryFragment] = { _ in [] },
357359
doUpdate updates: (inout Updates<Self>) -> Void,
@@ -368,11 +370,14 @@ extension Table {
368370
)
369371
}
370372

371-
private static func _insert<each Value, each ConflictTarget>(
372-
_ columns: (TableColumns) -> (repeat TableColumn<Self, each Value>),
373-
@InsertValuesBuilder<(repeat each Value)>
373+
private static func _insert<
374+
each Value: _TableColumnExpression,
375+
each ConflictTarget: _TableColumnExpression
376+
>(
377+
_ columns: (TableColumns) -> (repeat each Value),
378+
@InsertValuesBuilder<(repeat (each Value).Value)>
374379
values: () -> [[QueryFragment]],
375-
onConflict conflictTargets: (TableColumns) -> (repeat TableColumn<Self, each ConflictTarget>)?,
380+
onConflict conflictTargets: (TableColumns) -> (repeat each ConflictTarget)?,
376381
@QueryFragmentBuilder<Bool>
377382
where targetFilter: (TableColumns) -> [QueryFragment] = { _ in [] },
378383
doUpdate updates: ((inout Updates<Self>, Excluded) -> Void)?,
@@ -381,7 +386,7 @@ extension Table {
381386
) -> InsertOf<Self> {
382387
var columnNames: [String] = []
383388
for column in repeat each columns(Self.columns) {
384-
columnNames.append(column.name)
389+
columnNames.append(contentsOf: column._names)
385390
}
386391
return _insert(
387392
columnNames: columnNames,
@@ -406,11 +411,29 @@ extension Table {
406411
/// - updateFilter: A filter to apply to the update clause.
407412
/// - Returns: An insert statement.
408413
public static func insert<
409-
V1,
410-
each V2
414+
V1: _TableColumnExpression,
415+
each V2: _TableColumnExpression
411416
>(
412-
_ columns: (TableColumns) -> (TableColumn<Self, V1>, repeat TableColumn<Self, each V2>),
413-
select selection: () -> some PartialSelectStatement<(V1, repeat each V2)>,
417+
_ columns: (TableColumns) -> (V1, repeat each V2),
418+
select selection: () -> some PartialSelectStatement<(V1.Value, repeat (each V2).Value)>,
419+
onConflictDoUpdate updates: ((inout Updates<Self>, Excluded) -> Void)? = nil,
420+
@QueryFragmentBuilder<Bool>
421+
where updateFilter: (TableColumns) -> [QueryFragment] = { _ in [] }
422+
) -> InsertOf<Self> {
423+
_insert(
424+
columns,
425+
select: selection,
426+
onConflict: { _ -> ()? in nil },
427+
where: { _ in return [] },
428+
doUpdate: updates,
429+
where: updateFilter
430+
)
431+
}
432+
433+
// NB: This overload is required due to a parameter pack bug.
434+
public static func insert<V1: _TableColumnExpression>(
435+
_ columns: (TableColumns) -> V1,
436+
select selection: () -> some PartialSelectStatement<V1.Value>,
414437
onConflictDoUpdate updates: ((inout Updates<Self>, Excluded) -> Void)? = nil,
415438
@QueryFragmentBuilder<Bool>
416439
where updateFilter: (TableColumns) -> [QueryFragment] = { _ in [] }
@@ -438,11 +461,11 @@ extension Table {
438461
/// - updateFilter: A filter to apply to the update clause.
439462
/// - Returns: An insert statement.
440463
public static func insert<
441-
V1,
442-
each V2
464+
V1: _TableColumnExpression,
465+
each V2: _TableColumnExpression
443466
>(
444-
_ columns: (TableColumns) -> (TableColumn<Self, V1>, repeat TableColumn<Self, each V2>),
445-
select selection: () -> some PartialSelectStatement<(V1, repeat each V2)>,
467+
_ columns: (TableColumns) -> (V1, repeat each V2),
468+
select selection: () -> some PartialSelectStatement<(V1.Value, repeat (each V2).Value)>,
446469
onConflictDoUpdate updates: ((inout Updates<Self>) -> Void)?,
447470
@QueryFragmentBuilder<Bool>
448471
where updateFilter: (TableColumns) -> [QueryFragment] = { _ in [] }
@@ -470,16 +493,41 @@ extension Table {
470493
/// - updateFilter: A filter to apply to the update clause.
471494
/// - Returns: An insert statement.
472495
public static func insert<
473-
V1,
474-
each V2,
475-
T1,
476-
each T2
496+
V1: _TableColumnExpression,
497+
each V2: _TableColumnExpression,
498+
T1: _TableColumnExpression,
499+
each T2: _TableColumnExpression
477500
>(
478-
_ columns: (TableColumns) -> (TableColumn<Self, V1>, repeat TableColumn<Self, each V2>),
479-
select selection: () -> some PartialSelectStatement<(V1, repeat each V2)>,
480-
onConflict conflictTargets: (TableColumns) -> (
481-
TableColumn<Self, T1>, repeat TableColumn<Self, each T2>
482-
),
501+
_ columns: (TableColumns) -> (V1, repeat each V2),
502+
select selection: () -> some PartialSelectStatement<(V1.Value, repeat (each V2).Value)>,
503+
onConflict conflictTargets: (TableColumns) -> (T1, repeat each T2),
504+
@QueryFragmentBuilder<Bool>
505+
where targetFilter: (TableColumns) -> [QueryFragment] = { _ in [] },
506+
doUpdate updates: (inout Updates<Self>, Excluded) -> Void = { _, _ in },
507+
@QueryFragmentBuilder<Bool>
508+
where updateFilter: (TableColumns) -> [QueryFragment] = { _ in [] }
509+
) -> InsertOf<Self> {
510+
withoutActuallyEscaping(updates) { updates in
511+
_insert(
512+
columns,
513+
select: selection,
514+
onConflict: conflictTargets,
515+
where: targetFilter,
516+
doUpdate: updates,
517+
where: updateFilter
518+
)
519+
}
520+
}
521+
522+
// NB: This overload is required due to a parameter pack bug.
523+
public static func insert<
524+
V1: _TableColumnExpression,
525+
T1: _TableColumnExpression,
526+
each T2: _TableColumnExpression
527+
>(
528+
_ columns: (TableColumns) -> V1,
529+
select selection: () -> some PartialSelectStatement<V1.Value>,
530+
onConflict conflictTargets: (TableColumns) -> (T1, repeat each T2),
483531
@QueryFragmentBuilder<Bool>
484532
where targetFilter: (TableColumns) -> [QueryFragment] = { _ in [] },
485533
doUpdate updates: (inout Updates<Self>, Excluded) -> Void = { _, _ in },
@@ -513,16 +561,39 @@ extension Table {
513561
/// - updateFilter: A filter to apply to the update clause.
514562
/// - Returns: An insert statement.
515563
public static func insert<
516-
V1,
517-
each V2,
518-
T1,
519-
each T2
564+
V1: _TableColumnExpression,
565+
each V2: _TableColumnExpression,
566+
T1: _TableColumnExpression,
567+
each T2: _TableColumnExpression
568+
>(
569+
_ columns: (TableColumns) -> (V1, repeat each V2),
570+
select selection: () -> some PartialSelectStatement<(V1.Value, repeat (each V2).Value)>,
571+
onConflict conflictTargets: (TableColumns) -> (T1, repeat each T2),
572+
@QueryFragmentBuilder<Bool>
573+
where targetFilter: (TableColumns) -> [QueryFragment] = { _ in [] },
574+
doUpdate updates: (inout Updates<Self>) -> Void,
575+
@QueryFragmentBuilder<Bool>
576+
where updateFilter: (TableColumns) -> [QueryFragment] = { _ in [] }
577+
) -> InsertOf<Self> {
578+
insert(
579+
columns,
580+
select: selection,
581+
onConflict: conflictTargets,
582+
where: targetFilter,
583+
doUpdate: { row, _ in updates(&row) },
584+
where: updateFilter
585+
)
586+
}
587+
588+
// NB: This overload is required due to a parameter pack bug.
589+
public static func insert<
590+
V1: _TableColumnExpression,
591+
T1: _TableColumnExpression,
592+
each T2: _TableColumnExpression
520593
>(
521-
_ columns: (TableColumns) -> (TableColumn<Self, V1>, repeat TableColumn<Self, each V2>),
522-
select selection: () -> some PartialSelectStatement<(V1, repeat each V2)>,
523-
onConflict conflictTargets: (TableColumns) -> (
524-
TableColumn<Self, T1>, repeat TableColumn<Self, each T2>
525-
),
594+
_ columns: (TableColumns) -> V1,
595+
select selection: () -> some PartialSelectStatement<V1.Value>,
596+
onConflict conflictTargets: (TableColumns) -> (T1, repeat each T2),
526597
@QueryFragmentBuilder<Bool>
527598
where targetFilter: (TableColumns) -> [QueryFragment] = { _ in [] },
528599
doUpdate updates: (inout Updates<Self>) -> Void,
@@ -539,13 +610,15 @@ extension Table {
539610
)
540611
}
541612

613+
// NB: We should constrain these generics `where Root == Self` when Swift supports same-type
614+
// constraints in parameter packs.
542615
private static func _insert<
543-
each Value,
544-
each ConflictTarget
616+
each Value: _TableColumnExpression,
617+
each ConflictTarget: _TableColumnExpression
545618
>(
546-
_ columns: (TableColumns) -> (repeat TableColumn<Self, each Value>),
547-
select selection: () -> some PartialSelectStatement<(repeat each Value)>,
548-
onConflict conflictTargets: (TableColumns) -> (repeat TableColumn<Self, each ConflictTarget>)?,
619+
_ columns: (TableColumns) -> (repeat each Value),
620+
select selection: () -> some PartialSelectStatement<(repeat (each Value).Value)>,
621+
onConflict conflictTargets: (TableColumns) -> (repeat each ConflictTarget)?,
549622
@QueryFragmentBuilder<Bool>
550623
where targetFilter: (TableColumns) -> [QueryFragment] = { _ in [] },
551624
doUpdate updates: ((inout Updates<Self>, Excluded) -> Void)?,
@@ -554,7 +627,7 @@ extension Table {
554627
) -> InsertOf<Self> {
555628
var columnNames: [String] = []
556629
for column in repeat each columns(Self.columns) {
557-
columnNames.append(column.name)
630+
columnNames.append(contentsOf: column._names)
558631
}
559632
return _insert(
560633
columnNames: columnNames,
@@ -587,10 +660,10 @@ extension Table {
587660
)
588661
}
589662

590-
fileprivate static func _insert<each ConflictTarget>(
663+
fileprivate static func _insert<each ConflictTarget: _TableColumnExpression>(
591664
columnNames: [String],
592665
values: InsertValues,
593-
onConflict conflictTargets: (TableColumns) -> (repeat TableColumn<Self, each ConflictTarget>)?,
666+
onConflict conflictTargets: (TableColumns) -> (repeat each ConflictTarget)?,
594667
@QueryFragmentBuilder<Bool>
595668
where targetFilter: (TableColumns) -> [QueryFragment] = { _ in [] },
596669
doUpdate updates: ((inout Updates<Self>, Excluded) -> Void)?,
@@ -600,7 +673,7 @@ extension Table {
600673
var conflictTargetColumnNames: [String] = []
601674
if let conflictTargets = conflictTargets(Self.columns) {
602675
for column in repeat each conflictTargets {
603-
conflictTargetColumnNames.append(column.name)
676+
conflictTargetColumnNames.append(contentsOf: column._names)
604677
}
605678
}
606679
return Insert(
@@ -635,20 +708,15 @@ extension PrimaryKeyedTable {
635708
public static func upsert(
636709
@InsertValuesBuilder<Self> values: () -> [[QueryFragment]]
637710
) -> InsertOf<Self> {
638-
Insert(
639-
conflictResolution: nil,
640-
columnNames: TableColumns.writableColumns.map(\.name),
641-
conflictTargetColumnNames: columns.primaryKey._names,
642-
conflictTargetFilter: [],
643-
values: .values(values()),
644-
updates: Updates { updates in
711+
insert(
712+
values: values,
713+
onConflict: { $0.primaryKey },
714+
doUpdate: { updates, _ in
645715
for (column, excluded) in zip(Draft.TableColumns.writableColumns, Excluded.writableColumns)
646716
where !columns.primaryKey._names.contains(column.name) {
647717
updates.set(column, excluded.queryFragment)
648718
}
649-
},
650-
updateFilter: [],
651-
returning: []
719+
}
652720
)
653721
}
654722
}

Sources/StructuredQueriesCore/Table.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ extension Table {
120120
/// #sql("SELECT \(Reminder.id) FROM \(Reminder.self)", as: Int.self)
121121
/// // SELECT "reminders"."id" FROM "reminders
122122
/// ```
123+
@_disfavoredOverload
123124
public static subscript<Member>(
124125
dynamicMember keyPath: KeyPath<TableColumns, TableColumn<Self, Member>>
125126
) -> TableColumn<Self, Member> {

0 commit comments

Comments
 (0)