Skip to content

Commit 26fade5

Browse files
committed
wip
1 parent af54a84 commit 26fade5

File tree

2 files changed

+103
-45
lines changed

2 files changed

+103
-45
lines changed

Sources/StructuredQueriesCore/Statements/Insert.swift

Lines changed: 83 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,14 @@ extension Table {
5555
_ columns: (TableColumns) -> TableColumns = { $0 },
5656
@InsertValuesBuilder<Self> values: () -> [Self],
5757
onConflictDoUpdate updates: ((inout Updates<Self>) -> Void)? = nil,
58-
where updateFilter: ((TableColumns) -> any QueryExpression<Bool>)? = nil
58+
@QueryFragmentBuilder<Bool>
59+
where updateFilter: (TableColumns) -> [QueryFragment] = { _ in [] }
5960
) -> InsertOf<Self> {
6061
_insert(
6162
or: conflictResolution,
6263
values: values,
6364
onConflict: { _ -> ()? in nil },
64-
where: nil,
65+
where: { _ in return [] },
6566
doUpdate: updates,
6667
where: updateFilter
6768
)
@@ -86,9 +87,11 @@ extension Table {
8687
onConflict conflictTargets: (TableColumns) -> (
8788
TableColumn<Self, T1>, repeat TableColumn<Self, each T2>
8889
),
89-
where targetFilter: ((TableColumns) -> any QueryExpression<Bool>)? = nil,
90+
@QueryFragmentBuilder<Bool>
91+
where targetFilter: (TableColumns) -> [QueryFragment] = { _ in [] },
9092
doUpdate updates: (inout Updates<Self>) -> Void = { _ in },
91-
where updateFilter: ((TableColumns) -> any QueryExpression<Bool>)? = nil
93+
@QueryFragmentBuilder<Bool>
94+
where updateFilter: (TableColumns) -> [QueryFragment] = { _ in [] }
9295
) -> InsertOf<Self> {
9396
withoutActuallyEscaping(updates) { updates in
9497
_insert(
@@ -106,9 +109,11 @@ extension Table {
106109
or conflictResolution: ConflictResolution?,
107110
@InsertValuesBuilder<Self> values: () -> [Self],
108111
onConflict conflictTargets: (TableColumns) -> (repeat TableColumn<Self, each ConflictTarget>)?,
109-
where targetFilter: ((TableColumns) -> any QueryExpression<Bool>)?,
112+
@QueryFragmentBuilder<Bool>
113+
where targetFilter: (TableColumns) -> [QueryFragment] = { _ in [] },
110114
doUpdate updates: ((inout Updates<Self>) -> Void)?,
111-
where updateFilter: ((TableColumns) -> any QueryExpression<Bool>)?
115+
@QueryFragmentBuilder<Bool>
116+
where updateFilter: (TableColumns) -> [QueryFragment] = { _ in [] }
112117
) -> InsertOf<Self> {
113118
var valueFragments: [[QueryFragment]] = []
114119
for value in values() {
@@ -193,14 +198,15 @@ extension Table {
193198
@InsertValuesBuilder<(V1.QueryOutput, repeat (each V2).QueryOutput)>
194199
values: () -> [(V1.QueryOutput, repeat (each V2).QueryOutput)],
195200
onConflictDoUpdate updates: ((inout Updates<Self>) -> Void)? = nil,
196-
where updateFilter: ((TableColumns) -> any QueryExpression<Bool>)? = nil
201+
@QueryFragmentBuilder<Bool>
202+
where updateFilter: (TableColumns) -> [QueryFragment] = { _ in [] }
197203
) -> InsertOf<Self> {
198204
_insert(
199205
or: conflictResolution,
200206
columns,
201207
values: values,
202208
onConflict: { _ -> ()? in nil },
203-
where: nil,
209+
where: { _ in return [] },
204210
doUpdate: updates,
205211
where: updateFilter
206212
)
@@ -226,9 +232,11 @@ extension Table {
226232
onConflict conflictTargets: (TableColumns) -> (
227233
TableColumn<Self, T1>, repeat TableColumn<Self, each T2>
228234
),
229-
where targetFilter: ((TableColumns) -> any QueryExpression<Bool>)? = nil,
235+
@QueryFragmentBuilder<Bool>
236+
where targetFilter: (TableColumns) -> [QueryFragment] = { _ in [] },
230237
doUpdate updates: (inout Updates<Self>) -> Void = { _ in },
231-
where updateFilter: ((TableColumns) -> any QueryExpression<Bool>)? = nil
238+
@QueryFragmentBuilder<Bool>
239+
where updateFilter: (TableColumns) -> [QueryFragment] = { _ in [] }
232240
) -> InsertOf<Self> {
233241
withoutActuallyEscaping(updates) { updates in
234242
_insert(
@@ -249,9 +257,11 @@ extension Table {
249257
@InsertValuesBuilder<(repeat (each Value).QueryOutput)>
250258
values: () -> [(repeat (each Value).QueryOutput)],
251259
onConflict conflictTargets: (TableColumns) -> (repeat TableColumn<Self, each ConflictTarget>)?,
252-
where targetFilter: ((TableColumns) -> any QueryExpression<Bool>)?,
260+
@QueryFragmentBuilder<Bool>
261+
where targetFilter: (TableColumns) -> [QueryFragment] = { _ in [] },
253262
doUpdate updates: ((inout Updates<Self>) -> Void)?,
254-
where updateFilter: ((TableColumns) -> any QueryExpression<Bool>)?
263+
@QueryFragmentBuilder<Bool>
264+
where updateFilter: (TableColumns) -> [QueryFragment] = { _ in [] }
255265
) -> InsertOf<Self> {
256266
var columnNames: [String] = []
257267
for column in repeat each columns(Self.columns) {
@@ -290,21 +300,27 @@ extension Table {
290300
/// - updateFilter: A filter to apply to the update clause.
291301
/// - Returns: An insert statement.
292302
public static func insert<
293-
V1, each V2, C1: QueryExpression, each C2: QueryExpression, From, Joins
303+
V1,
304+
each V2,
305+
C1: QueryExpression,
306+
each C2: QueryExpression,
307+
From,
308+
Joins
294309
>(
295310
or conflictResolution: ConflictResolution? = nil,
296311
_ columns: (TableColumns) -> (TableColumn<Self, V1>, repeat TableColumn<Self, each V2>),
297312
select selection: () -> Select<(C1, repeat each C2), From, Joins>,
298313
onConflictDoUpdate updates: ((inout Updates<Self>) -> Void)? = nil,
299-
where updateFilter: ((TableColumns) -> any QueryExpression<Bool>)? = nil
314+
@QueryFragmentBuilder<Bool>
315+
where updateFilter: (TableColumns) -> [QueryFragment] = { _ in [] }
300316
) -> InsertOf<Self>
301317
where C1.QueryValue == V1, (repeat (each C2).QueryValue) == (repeat each V2) {
302318
_insert(
303319
or: conflictResolution,
304320
columns,
305321
select: selection,
306322
onConflict: { _ -> ()? in nil },
307-
where: nil,
323+
where: { _ in return [] },
308324
doUpdate: updates,
309325
where: updateFilter
310326
)
@@ -326,17 +342,26 @@ extension Table {
326342
/// - updateFilter: A filter to apply to the update clause.
327343
/// - Returns: An insert statement.
328344
public static func insert<
329-
V1, each V2, C1: QueryExpression, each C2: QueryExpression, From, Joins, T1, each T2
345+
V1,
346+
each V2,
347+
C1: QueryExpression,
348+
each C2: QueryExpression,
349+
From,
350+
Joins,
351+
T1,
352+
each T2
330353
>(
331354
or conflictResolution: ConflictResolution? = nil,
332355
_ columns: (TableColumns) -> (TableColumn<Self, V1>, repeat TableColumn<Self, each V2>),
333356
select selection: () -> Select<(C1, repeat each C2), From, Joins>,
334357
onConflict conflictTargets: (TableColumns) -> (
335358
TableColumn<Self, T1>, repeat TableColumn<Self, each T2>
336359
),
337-
where targetFilter: ((TableColumns) -> any QueryExpression<Bool>)? = nil,
360+
@QueryFragmentBuilder<Bool>
361+
where targetFilter: (TableColumns) -> [QueryFragment] = { _ in [] },
338362
doUpdate updates: (inout Updates<Self>) -> Void = { _ in },
339-
where updateFilter: ((TableColumns) -> any QueryExpression<Bool>)? = nil
363+
@QueryFragmentBuilder<Bool>
364+
where updateFilter: (TableColumns) -> [QueryFragment] = { _ in [] }
340365
) -> InsertOf<Self>
341366
where C1.QueryValue == V1, (repeat (each C2).QueryValue) == (repeat each V2) {
342367
withoutActuallyEscaping(updates) { updates in
@@ -353,15 +378,21 @@ extension Table {
353378
}
354379

355380
private static func _insert<
356-
each Value, each ResultColumn: QueryExpression, From, Joins, each ConflictTarget
381+
each Value,
382+
each ResultColumn: QueryExpression,
383+
From,
384+
Joins,
385+
each ConflictTarget
357386
>(
358387
or conflictResolution: ConflictResolution? = nil,
359388
_ columns: (TableColumns) -> (repeat TableColumn<Self, each Value>),
360389
select selection: () -> Select<(repeat each ResultColumn), From, Joins>,
361390
onConflict conflictTargets: (TableColumns) -> (repeat TableColumn<Self, each ConflictTarget>)?,
362-
where targetFilter: ((TableColumns) -> any QueryExpression<Bool>)?,
391+
@QueryFragmentBuilder<Bool>
392+
where targetFilter: (TableColumns) -> [QueryFragment] = { _ in [] },
363393
doUpdate updates: ((inout Updates<Self>) -> Void)?,
364-
where updateFilter: ((TableColumns) -> any QueryExpression<Bool>)?
394+
@QueryFragmentBuilder<Bool>
395+
where updateFilter: (TableColumns) -> [QueryFragment] = { _ in [] }
365396
) -> InsertOf<Self>
366397
where (repeat (each ResultColumn).QueryValue) == (repeat each Value) {
367398
var columnNames: [String] = []
@@ -398,9 +429,9 @@ extension Table {
398429
columnNames: [],
399430
values: .default,
400431
onConflict: { _ -> ()? in nil },
401-
where: nil,
432+
where: { _ in return [] },
402433
doUpdate: nil,
403-
where: nil
434+
where: { _ in return [] }
404435
)
405436
}
406437

@@ -409,9 +440,11 @@ extension Table {
409440
columnNames: [String],
410441
values: InsertValues,
411442
onConflict conflictTargets: (TableColumns) -> (repeat TableColumn<Self, each ConflictTarget>)?,
412-
where targetFilter: ((TableColumns) -> any QueryExpression<Bool>)?,
443+
@QueryFragmentBuilder<Bool>
444+
where targetFilter: (TableColumns) -> [QueryFragment] = { _ in [] },
413445
doUpdate updates: ((inout Updates<Self>) -> Void)?,
414-
where updateFilter: ((TableColumns) -> any QueryExpression<Bool>)?
446+
@QueryFragmentBuilder<Bool>
447+
where updateFilter: (TableColumns) -> [QueryFragment] = { _ in [] }
415448
) -> InsertOf<Self> {
416449
var conflictTargetColumnNames: [String] = []
417450
if let conflictTargets = conflictTargets(Self.columns) {
@@ -423,10 +456,10 @@ extension Table {
423456
conflictResolution: conflictResolution,
424457
columnNames: columnNames,
425458
conflictTargetColumnNames: conflictTargetColumnNames,
426-
conflictTargetFilter: targetFilter?(Self.columns).queryFragment,
459+
conflictTargetFilter: targetFilter(Self.columns),
427460
values: values,
428461
updates: updates.map(Updates.init),
429-
updateFilter: updateFilter?(Self.columns).queryFragment,
462+
updateFilter: updateFilter(Self.columns),
430463
returning: []
431464
)
432465
}
@@ -450,13 +483,14 @@ extension PrimaryKeyedTable {
450483
_ columns: (Draft.TableColumns) -> Draft.TableColumns = { $0 },
451484
@InsertValuesBuilder<Draft> values: () -> [Draft],
452485
onConflictDoUpdate updates: ((inout Updates<Self>) -> Void)? = nil,
453-
where updateFilter: ((TableColumns) -> any QueryExpression<Bool>)? = nil
486+
@QueryFragmentBuilder<Bool>
487+
where updateFilter: (TableColumns) -> [QueryFragment] = { _ in [] }
454488
) -> InsertOf<Self> {
455489
_insert(
456490
or: conflictResolution,
457491
values: values,
458492
onConflict: { _ -> ()? in nil },
459-
where: nil,
493+
where: { _ in return [] },
460494
doUpdate: updates,
461495
where: updateFilter
462496
)
@@ -482,9 +516,11 @@ extension PrimaryKeyedTable {
482516
onConflict conflictTargets: (TableColumns) -> (
483517
TableColumn<Self, T1>, repeat TableColumn<Self, each T2>
484518
),
485-
where targetFilter: ((TableColumns) -> any QueryExpression<Bool>)? = nil,
519+
@QueryFragmentBuilder<Bool>
520+
where targetFilter: (TableColumns) -> [QueryFragment] = { _ in [] },
486521
doUpdate updates: (inout Updates<Self>) -> Void = { _ in },
487-
where updateFilter: ((TableColumns) -> any QueryExpression<Bool>)? = nil
522+
@QueryFragmentBuilder<Bool>
523+
where updateFilter: (TableColumns) -> [QueryFragment] = { _ in [] }
488524
) -> InsertOf<Self> {
489525
withoutActuallyEscaping(updates) { updates in
490526
_insert(
@@ -533,9 +569,11 @@ extension PrimaryKeyedTable {
533569
or conflictResolution: ConflictResolution?,
534570
@InsertValuesBuilder<Draft> values: () -> [Draft],
535571
onConflict conflictTargets: (TableColumns) -> (repeat TableColumn<Self, each ConflictTarget>)?,
536-
where targetFilter: ((TableColumns) -> any QueryExpression<Bool>)?,
572+
@QueryFragmentBuilder<Bool>
573+
where targetFilter: (TableColumns) -> [QueryFragment] = { _ in [] },
537574
doUpdate updates: ((inout Updates<Self>) -> Void)?,
538-
where updateFilter: ((TableColumns) -> any QueryExpression<Bool>)?
575+
@QueryFragmentBuilder<Bool>
576+
where updateFilter: (TableColumns) -> [QueryFragment] = { _ in [] }
539577
) -> InsertOf<Self> {
540578
var valueFragments: [[QueryFragment]] = []
541579
for value in values() {
@@ -577,20 +615,20 @@ public struct Insert<Into: Table, Returning> {
577615
var conflictResolution: ConflictResolution?
578616
var columnNames: [String]
579617
var conflictTargetColumnNames: [String]
580-
var conflictTargetFilter: QueryFragment?
618+
var conflictTargetFilter: [QueryFragment]
581619
fileprivate var values: InsertValues
582620
var updates: Updates<Into>?
583-
var updateFilter: QueryFragment?
621+
var updateFilter: [QueryFragment]
584622
var returning: [QueryFragment]
585623

586624
fileprivate init(
587625
conflictResolution: ConflictResolution?,
588626
columnNames: [String],
589627
conflictTargetColumnNames: [String],
590-
conflictTargetFilter: QueryFragment?,
628+
conflictTargetFilter: [QueryFragment],
591629
values: InsertValues,
592630
updates: Updates<Into>?,
593-
updateFilter: QueryFragment?,
631+
updateFilter: [QueryFragment],
594632
returning: [QueryFragment]
595633
) {
596634
self.conflictResolution = conflictResolution
@@ -700,30 +738,30 @@ extension Insert: Statement {
700738
query.append("(")
701739
query.append(conflictTargetColumnNames.map { "\(quote: $0)" }.joined(separator: ", "))
702740
query.append(")\(.newlineOrSpace)")
703-
if let conflictTargetFilter {
704-
query.append("WHERE \(conflictTargetFilter)\(.newlineOrSpace)")
741+
if !conflictTargetFilter.isEmpty {
742+
query.append("WHERE \(conflictTargetFilter.joined(separator: " AND "))\(.newlineOrSpace)")
705743
}
706744
}
707745
query.append("DO ")
708746
if updates.isEmpty {
709747
query.append("NOTHING")
710-
hasInvalidWhere = updateFilter != nil
748+
hasInvalidWhere = !updateFilter.isEmpty
711749
} else {
712750
query.append("UPDATE \(bind: updates)")
713-
if let updateFilter {
714-
query.append("\(.newlineOrSpace)WHERE \(updateFilter)")
751+
if !updateFilter.isEmpty {
752+
query.append("\(.newlineOrSpace)WHERE \(updateFilter.joined(separator: " AND "))")
715753
}
716754
}
717755
} else {
718-
hasInvalidWhere = updateFilter != nil
756+
hasInvalidWhere = !updateFilter.isEmpty
719757
}
720758
if !returning.isEmpty {
721759
query.append("\(.newlineOrSpace)RETURNING \(returning.joined(separator: ", "))")
722760
}
723-
if hasInvalidWhere, let updateFilter {
761+
if hasInvalidWhere {
724762
reportIssue(
725763
"""
726-
Insert statement has invalid update 'where': \(updateFilter)
764+
Insert statement has invalid update 'where': \(updateFilter.joined(separator: " AND "))
727765
728766
\(query)
729767
"""

Tests/StructuredQueriesTests/InsertTests.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,26 @@ extension SnapshotTests {
599599
}
600600
}
601601
}
602+
603+
@Test func onConflict_conditionalWhere() {
604+
let condition = false
605+
assertQuery(
606+
Reminder.insert {
607+
Reminder.Draft(remindersListID: 1)
608+
} where: {
609+
if condition {
610+
$0.isFlagged
611+
}
612+
}
613+
) {
614+
"""
615+
INSERT INTO "reminders"
616+
("id", "assignedUserID", "dueDate", "isCompleted", "isFlagged", "notes", "priority", "remindersListID", "title")
617+
VALUES
618+
(NULL, NULL, NULL, 0, 0, '', NULL, 1, '')
619+
"""
620+
}
621+
}
602622
}
603623
}
604624

0 commit comments

Comments
 (0)