Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions Sources/StructuredQueriesCore/Internal/Deprecations.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ extension Table {
public static func insert(
or conflictResolution: ConflictResolution? = nil,
_ row: Self,
onConflict doUpdate: ((inout Updates<Self>) -> Void)? = nil
onConflict doUpdate: ((inout Upsert<Self>) -> Void)? = nil
) -> InsertOf<Self> {
insert(or: conflictResolution, [row], onConflict: doUpdate)
}
Expand All @@ -56,7 +56,7 @@ extension Table {
public static func insert(
or conflictResolution: ConflictResolution? = nil,
_ rows: [Self],
onConflict doUpdate: ((inout Updates<Self>) -> Void)? = nil
onConflict doUpdate: ((inout Upsert<Self>) -> Void)? = nil
) -> InsertOf<Self> {
insert(or: conflictResolution, values: { rows }, onConflict: doUpdate)
}
Expand All @@ -66,7 +66,7 @@ extension Table {
or conflictResolution: ConflictResolution? = nil,
_ columns: (TableColumns) -> TableColumns = { $0 },
@InsertValuesBuilder<Self> values: () -> [Self],
onConflict updates: ((inout Updates<Self>) -> Void)?
onConflict updates: ((inout Upsert<Self>) -> Void)?
) -> InsertOf<Self> {
insert(or: conflictResolution, columns, values: values, onConflictDoUpdate: updates)
}
Expand All @@ -77,7 +77,7 @@ extension Table {
_ columns: (TableColumns) -> (TableColumn<Self, V1>, repeat TableColumn<Self, each V2>),
@InsertValuesBuilder<(V1.QueryOutput, repeat (each V2).QueryOutput)>
values: () -> [(V1.QueryOutput, repeat (each V2).QueryOutput)],
onConflict updates: ((inout Updates<Self>) -> Void)?
onConflict updates: ((inout Upsert<Self>) -> Void)?
) -> InsertOf<Self> {
insert(or: conflictResolution, columns, values: values, onConflictDoUpdate: updates)
}
Expand All @@ -89,7 +89,7 @@ extension Table {
or conflictResolution: ConflictResolution? = nil,
_ columns: (TableColumns) -> (TableColumn<Self, V1>, repeat TableColumn<Self, each V2>),
select selection: () -> Select<(V1, repeat each V2), From, Joins>,
onConflict updates: ((inout Updates<Self>) -> Void)?
onConflict updates: ((inout Upsert<Self>) -> Void)?
) -> InsertOf<Self> {
insert(or: conflictResolution, columns, select: selection, onConflictDoUpdate: updates)
}
Expand All @@ -102,7 +102,7 @@ extension PrimaryKeyedTable {
public static func insert(
or conflictResolution: ConflictResolution? = nil,
_ row: Draft,
onConflict updates: ((inout Updates<Self>) -> Void)? = nil
onConflict updates: ((inout Upsert<Self>) -> Void)? = nil
) -> InsertOf<Self> {
insert(or: conflictResolution, values: { row }, onConflictDoUpdate: updates)
}
Expand All @@ -113,7 +113,7 @@ extension PrimaryKeyedTable {
public static func insert(
or conflictResolution: ConflictResolution? = nil,
_ rows: [Draft],
onConflict updates: ((inout Updates<Self>) -> Void)? = nil
onConflict updates: ((inout Upsert<Self>) -> Void)? = nil
) -> InsertOf<Self> {
insert(or: conflictResolution, values: { rows }, onConflictDoUpdate: updates)
}
Expand Down
77 changes: 60 additions & 17 deletions Sources/StructuredQueriesCore/Statements/Insert.swift
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ extension Table {
or conflictResolution: ConflictResolution? = nil,
_ columns: (TableColumns) -> TableColumns = { $0 },
@InsertValuesBuilder<Self> values: () -> [Self],
onConflictDoUpdate updates: ((inout Updates<Self>) -> Void)? = nil,
onConflictDoUpdate updates: ((inout Upsert<Self>) -> Void)? = nil,
@QueryFragmentBuilder<Bool>
where updateFilter: (TableColumns) -> [QueryFragment] = { _ in [] }
) -> InsertOf<Self> {
Expand Down Expand Up @@ -89,7 +89,7 @@ extension Table {
),
@QueryFragmentBuilder<Bool>
where targetFilter: (TableColumns) -> [QueryFragment] = { _ in [] },
doUpdate updates: (inout Updates<Self>) -> Void = { _ in },
doUpdate updates: (inout Upsert<Self>) -> Void = { _ in },
@QueryFragmentBuilder<Bool>
where updateFilter: (TableColumns) -> [QueryFragment] = { _ in [] }
) -> InsertOf<Self> {
Expand All @@ -111,7 +111,7 @@ extension Table {
onConflict conflictTargets: (TableColumns) -> (repeat TableColumn<Self, each ConflictTarget>)?,
@QueryFragmentBuilder<Bool>
where targetFilter: (TableColumns) -> [QueryFragment] = { _ in [] },
doUpdate updates: ((inout Updates<Self>) -> Void)?,
doUpdate updates: ((inout Upsert<Self>) -> Void)?,
@QueryFragmentBuilder<Bool>
where updateFilter: (TableColumns) -> [QueryFragment] = { _ in [] }
) -> InsertOf<Self> {
Expand Down Expand Up @@ -197,7 +197,7 @@ extension Table {
_ columns: (TableColumns) -> (TableColumn<Self, V1>, repeat TableColumn<Self, each V2>),
@InsertValuesBuilder<(V1.QueryOutput, repeat (each V2).QueryOutput)>
values: () -> [(V1.QueryOutput, repeat (each V2).QueryOutput)],
onConflictDoUpdate updates: ((inout Updates<Self>) -> Void)? = nil,
onConflictDoUpdate updates: ((inout Upsert<Self>) -> Void)? = nil,
@QueryFragmentBuilder<Bool>
where updateFilter: (TableColumns) -> [QueryFragment] = { _ in [] }
) -> InsertOf<Self> {
Expand Down Expand Up @@ -234,7 +234,7 @@ extension Table {
),
@QueryFragmentBuilder<Bool>
where targetFilter: (TableColumns) -> [QueryFragment] = { _ in [] },
doUpdate updates: (inout Updates<Self>) -> Void = { _ in },
doUpdate updates: (inout Upsert<Self>) -> Void = { _ in },
@QueryFragmentBuilder<Bool>
where updateFilter: (TableColumns) -> [QueryFragment] = { _ in [] }
) -> InsertOf<Self> {
Expand All @@ -259,7 +259,7 @@ extension Table {
onConflict conflictTargets: (TableColumns) -> (repeat TableColumn<Self, each ConflictTarget>)?,
@QueryFragmentBuilder<Bool>
where targetFilter: (TableColumns) -> [QueryFragment] = { _ in [] },
doUpdate updates: ((inout Updates<Self>) -> Void)?,
doUpdate updates: ((inout Upsert<Self>) -> Void)?,
@QueryFragmentBuilder<Bool>
where updateFilter: (TableColumns) -> [QueryFragment] = { _ in [] }
) -> InsertOf<Self> {
Expand Down Expand Up @@ -306,7 +306,7 @@ extension Table {
or conflictResolution: ConflictResolution? = nil,
_ columns: (TableColumns) -> (TableColumn<Self, V1>, repeat TableColumn<Self, each V2>),
select selection: () -> some PartialSelectStatement<(V1, repeat each V2)>,
onConflictDoUpdate updates: ((inout Updates<Self>) -> Void)? = nil,
onConflictDoUpdate updates: ((inout Upsert<Self>) -> Void)? = nil,
@QueryFragmentBuilder<Bool>
where updateFilter: (TableColumns) -> [QueryFragment] = { _ in [] }
) -> InsertOf<Self> {
Expand Down Expand Up @@ -350,7 +350,7 @@ extension Table {
),
@QueryFragmentBuilder<Bool>
where targetFilter: (TableColumns) -> [QueryFragment] = { _ in [] },
doUpdate updates: (inout Updates<Self>) -> Void = { _ in },
doUpdate updates: (inout Upsert<Self>) -> Void = { _ in },
@QueryFragmentBuilder<Bool>
where updateFilter: (TableColumns) -> [QueryFragment] = { _ in [] }
) -> InsertOf<Self> {
Expand All @@ -377,7 +377,7 @@ extension Table {
onConflict conflictTargets: (TableColumns) -> (repeat TableColumn<Self, each ConflictTarget>)?,
@QueryFragmentBuilder<Bool>
where targetFilter: (TableColumns) -> [QueryFragment] = { _ in [] },
doUpdate updates: ((inout Updates<Self>) -> Void)?,
doUpdate updates: ((inout Upsert<Self>) -> Void)?,
@QueryFragmentBuilder<Bool>
where updateFilter: (TableColumns) -> [QueryFragment] = { _ in [] }
) -> InsertOf<Self> {
Expand Down Expand Up @@ -428,7 +428,7 @@ extension Table {
onConflict conflictTargets: (TableColumns) -> (repeat TableColumn<Self, each ConflictTarget>)?,
@QueryFragmentBuilder<Bool>
where targetFilter: (TableColumns) -> [QueryFragment] = { _ in [] },
doUpdate updates: ((inout Updates<Self>) -> Void)?,
doUpdate updates: ((inout Upsert<Self>) -> Void)?,
@QueryFragmentBuilder<Bool>
where updateFilter: (TableColumns) -> [QueryFragment] = { _ in [] }
) -> InsertOf<Self> {
Expand All @@ -444,7 +444,7 @@ extension Table {
conflictTargetColumnNames: conflictTargetColumnNames,
conflictTargetFilter: targetFilter(Self.columns),
values: values,
updates: updates.map { Updates($0) },
updates: updates.map { Upsert($0) },
updateFilter: updateFilter(Self.columns),
returning: []
)
Expand All @@ -468,7 +468,7 @@ extension PrimaryKeyedTable {
or conflictResolution: ConflictResolution? = nil,
_ columns: (Draft.TableColumns) -> Draft.TableColumns = { $0 },
@InsertValuesBuilder<Draft> values: () -> [Draft],
onConflictDoUpdate updates: ((inout Updates<Self>) -> Void)? = nil,
onConflictDoUpdate updates: ((inout Upsert<Self>) -> Void)? = nil,
@QueryFragmentBuilder<Bool>
where updateFilter: (TableColumns) -> [QueryFragment] = { _ in [] }
) -> InsertOf<Self> {
Expand Down Expand Up @@ -504,7 +504,7 @@ extension PrimaryKeyedTable {
),
@QueryFragmentBuilder<Bool>
where targetFilter: (TableColumns) -> [QueryFragment] = { _ in [] },
doUpdate updates: (inout Updates<Self>) -> Void = { _ in },
doUpdate updates: (inout Upsert<Self>) -> Void = { _ in },
@QueryFragmentBuilder<Bool>
where updateFilter: (TableColumns) -> [QueryFragment] = { _ in [] }
) -> InsertOf<Self> {
Expand Down Expand Up @@ -545,7 +545,7 @@ extension PrimaryKeyedTable {
onConflict: { $0.primaryKey },
doUpdate: { updates in
for column in Draft.TableColumns.allColumns where column.name != columns.primaryKey.name {
updates.set(column, #""excluded".\#(quote: column.name)"#)
updates.updates.set(column, #""excluded".\#(quote: column.name)"#)
}
}
)
Expand All @@ -557,7 +557,7 @@ extension PrimaryKeyedTable {
onConflict conflictTargets: (TableColumns) -> (repeat TableColumn<Self, each ConflictTarget>)?,
@QueryFragmentBuilder<Bool>
where targetFilter: (TableColumns) -> [QueryFragment] = { _ in [] },
doUpdate updates: ((inout Updates<Self>) -> Void)?,
doUpdate updates: ((inout Upsert<Self>) -> Void)?,
@QueryFragmentBuilder<Bool>
where updateFilter: (TableColumns) -> [QueryFragment] = { _ in [] }
) -> InsertOf<Self> {
Expand Down Expand Up @@ -590,6 +590,49 @@ private enum InsertValues {
case select(QueryFragment)
}

@dynamicMemberLookup
public struct Upsert<Base: Table>: QueryExpression {
public typealias QueryValue = Never

public struct Excluded: AliasName {
public static var aliasName: String {
"excluded"
}
}

init(_ body: (inout Self) -> Void) {
body(&self)
}

fileprivate var updates = Updates<Base>()

public var excluded: TableAlias<Base, Excluded>.TableColumns {
Base.as(Excluded.self).columns
}

public subscript<Member>(dynamicMember keyPath: KeyPath<Updates<Base>, Member>) -> Member {
updates[keyPath: keyPath]
}

public subscript<Member>(
dynamicMember keyPath: WritableKeyPath<Updates<Base>, Member>
) -> Member {
get { updates[keyPath: keyPath] }
set { updates[keyPath: keyPath] = newValue }
}

public subscript<Value>(
dynamicMember keyPath: KeyPath<Base.TableColumns, TableColumn<Base, Value>>
) -> any QueryExpression<Value> {
get { updates[dynamicMember: keyPath] }
set { updates[dynamicMember: keyPath] = newValue }
}

public var queryFragment: QueryFragment {
updates.queryFragment
}
}

/// An `INSERT` statement.
///
/// This type of statement is returned from the
Expand All @@ -603,7 +646,7 @@ public struct Insert<Into: Table, Returning> {
var conflictTargetColumnNames: [String]
var conflictTargetFilter: [QueryFragment]
fileprivate var values: InsertValues
var updates: Updates<Into>?
var updates: Upsert<Into>?
var updateFilter: [QueryFragment]
var returning: [QueryFragment]

Expand All @@ -613,7 +656,7 @@ public struct Insert<Into: Table, Returning> {
conflictTargetColumnNames: [String],
conflictTargetFilter: [QueryFragment],
values: InsertValues,
updates: Updates<Into>?,
updates: Upsert<Into>?,
updateFilter: [QueryFragment],
returning: [QueryFragment]
) {
Expand Down
3 changes: 3 additions & 0 deletions Sources/StructuredQueriesCore/Updates.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
public struct Updates<Base: Table> {
private var updates: [(String, QueryFragment)] = []

init() {
}

init(_ body: (inout Self) -> Void) {
body(&self)
}
Expand Down
4 changes: 2 additions & 2 deletions Tests/StructuredQueriesTests/InsertTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -579,7 +579,7 @@ extension SnapshotTests {
} where: {
!$0.isCompleted
} doUpdate: {
$0.isCompleted = true
$0.isCompleted = $0.excluded.isCompleted
} where: {
$0.isFlagged
}
Expand All @@ -591,7 +591,7 @@ extension SnapshotTests {
(NULL, NULL, NULL, 0, 0, '', NULL, 1, '')
ON CONFLICT ("id")
WHERE NOT ("reminders"."isCompleted")
DO UPDATE SET "isCompleted" = 1
DO UPDATE SET "isCompleted" = "excluded"."isCompleted"
WHERE "reminders"."isFlagged"
"""
}
Expand Down