From 4736e6c86b40a7b01dc444af85cd50ab739a8a91 Mon Sep 17 00:00:00 2001 From: Brandon Williams Date: Wed, 4 Feb 2026 14:43:09 -0600 Subject: [PATCH 1/3] Support for draft identifiers. --- .../StructuredQueriesCore/PrimaryKeyed.swift | 28 +++++++++ .../StructuredQueriesMacros/TableMacro.swift | 13 ++++ .../TableMacroTests.swift | 60 +++++++++++++++++++ Tests/StructuredQueriesTests/TableTests.swift | 26 ++++---- 4 files changed, 115 insertions(+), 12 deletions(-) diff --git a/Sources/StructuredQueriesCore/PrimaryKeyed.swift b/Sources/StructuredQueriesCore/PrimaryKeyed.swift index cc0b9467..8150282a 100644 --- a/Sources/StructuredQueriesCore/PrimaryKeyed.swift +++ b/Sources/StructuredQueriesCore/PrimaryKeyed.swift @@ -299,3 +299,31 @@ extension Delete where From: TableDraft { self.where { $0.primaryKey.in(primaryKeys) } } } + +import Foundation +public struct _DraftIdentifier: Hashable, CustomReflectable { + public let rawValue: AnyHashable + public init() { + rawValue = UUID() + } + public static func == (lhs: Self, rhs: Self) -> Bool { + true + } + public func hash(into hasher: inout Hasher) { + } + public var customMirror: Mirror { + Mirror(self, children: []) + } +} +public struct DraftIdentifier: Hashable { + private let rawValue: _DraftIdentifier + public init(_ draftIdentifier: _DraftIdentifier) { + rawValue = draftIdentifier + } + public static func == (lhs: Self, rhs: Self) -> Bool { + lhs.rawValue.rawValue == rhs.rawValue.rawValue + } + public func hash(into hasher: inout Hasher) { + hasher.combine(rawValue.rawValue) + } +} diff --git a/Sources/StructuredQueriesMacros/TableMacro.swift b/Sources/StructuredQueriesMacros/TableMacro.swift index 934158d0..6e0e64f3 100644 --- a/Sources/StructuredQueriesMacros/TableMacro.swift +++ b/Sources/StructuredQueriesMacros/TableMacro.swift @@ -723,6 +723,11 @@ extension TableMacro: ExtensionMacro { @_Draft(\(type).self) public struct Draft { \(draftProperties, separator: "\n") + + @Ephemeral + private let _draftIdentifier = _DraftIdentifier() + public var draftIdentifier: some Hashable { + DraftIdentifier(_draftIdentifier) } """ @@ -810,6 +815,10 @@ extension TableMacro: ExtensionMacro { \(draftProperties, separator: "\n") \(memberBlocks, separator: "\n") \(memberwiseInit) + private let _draftIdentifier = _DraftIdentifier() + public var draftIdentifier: some Hashable { + DraftIdentifier(_draftIdentifier) + } } """ // NB: End of workaround @@ -1400,6 +1409,10 @@ extension TableMacro: MemberMacro { \(draftProperties, separator: "\n") \(memberBlocks, separator: "\n") \(memberwiseInit) + private let _draftIdentifier = _DraftIdentifier() + public var draftIdentifier: some Hashable { + DraftIdentifier(_draftIdentifier) + } } """ // NB: End of workaround diff --git a/Tests/StructuredQueriesMacrosTests/TableMacroTests.swift b/Tests/StructuredQueriesMacrosTests/TableMacroTests.swift index 720c24b9..739ad6b4 100644 --- a/Tests/StructuredQueriesMacrosTests/TableMacroTests.swift +++ b/Tests/StructuredQueriesMacrosTests/TableMacroTests.swift @@ -335,6 +335,10 @@ extension SnapshotTests { self.email = email self.age = age } + private let _draftIdentifier = _DraftIdentifier() + public var draftIdentifier: some Hashable { + DraftIdentifier(_draftIdentifier) + } } } @@ -1189,6 +1193,10 @@ extension SnapshotTests { self.id = id self.name = name } + private let _draftIdentifier = _DraftIdentifier() + public var draftIdentifier: some Hashable { + DraftIdentifier(_draftIdentifier) + } } } @@ -1706,6 +1714,10 @@ extension SnapshotTests { self.id = id self.referrerID = referrerID } + private let _draftIdentifier = _DraftIdentifier() + public var draftIdentifier: some Hashable { + DraftIdentifier(_draftIdentifier) + } } } @@ -1939,6 +1951,10 @@ extension SnapshotTests { self.id = id self.name = name } + private let _draftIdentifier = _DraftIdentifier() + public var draftIdentifier: some Hashable { + DraftIdentifier(_draftIdentifier) + } } } @@ -2114,6 +2130,10 @@ extension SnapshotTests { self.id = id self.seconds = seconds } + private let _draftIdentifier = _DraftIdentifier() + public var draftIdentifier: some Hashable { + DraftIdentifier(_draftIdentifier) + } } } @@ -2288,6 +2308,10 @@ extension SnapshotTests { self.color = color self.name = name } + private let _draftIdentifier = _DraftIdentifier() + public var draftIdentifier: some Hashable { + DraftIdentifier(_draftIdentifier) + } } } @@ -3149,6 +3173,10 @@ extension SnapshotTests { ) { self.id = id } + private let _draftIdentifier = _DraftIdentifier() + public var draftIdentifier: some Hashable { + DraftIdentifier(_draftIdentifier) + } } } @@ -3423,6 +3451,10 @@ extension SnapshotTests { self.id = id self.name = name } + private let _draftIdentifier = _DraftIdentifier() + public var draftIdentifier: some Hashable { + DraftIdentifier(_draftIdentifier) + } } } @@ -3619,6 +3651,10 @@ extension SnapshotTests { self.date = date self.priority = priority } + private let _draftIdentifier = _DraftIdentifier() + public var draftIdentifier: some Hashable { + DraftIdentifier(_draftIdentifier) + } } } @@ -3761,6 +3797,10 @@ extension SnapshotTests { ) { self.id = id } + private let _draftIdentifier = _DraftIdentifier() + public var draftIdentifier: some Hashable { + DraftIdentifier(_draftIdentifier) + } } } @@ -3985,6 +4025,10 @@ extension SnapshotTests { self.id = id self.title = title } + private let _draftIdentifier = _DraftIdentifier() + public var draftIdentifier: some Hashable { + DraftIdentifier(_draftIdentifier) + } } } @@ -4141,6 +4185,10 @@ extension SnapshotTests { self.id = id self.timestamps = timestamps } + private let _draftIdentifier = _DraftIdentifier() + public var draftIdentifier: some Hashable { + DraftIdentifier(_draftIdentifier) + } } } @@ -4283,6 +4331,10 @@ extension SnapshotTests { ) { self.id = id } + private let _draftIdentifier = _DraftIdentifier() + public var draftIdentifier: some Hashable { + DraftIdentifier(_draftIdentifier) + } } } @@ -4463,6 +4515,10 @@ extension SnapshotTests { self.reminderTitle = reminderTitle self.remindersListTitle = remindersListTitle } + private let _draftIdentifier = _DraftIdentifier() + public var draftIdentifier: some Hashable { + DraftIdentifier(_draftIdentifier) + } } } @@ -4632,6 +4688,10 @@ extension SnapshotTests { self.id = id self.userModificationDate = userModificationDate } + private let _draftIdentifier = _DraftIdentifier() + public var draftIdentifier: some Hashable { + DraftIdentifier(_draftIdentifier) + } } } diff --git a/Tests/StructuredQueriesTests/TableTests.swift b/Tests/StructuredQueriesTests/TableTests.swift index 46d9db3d..5c721feb 100644 --- a/Tests/StructuredQueriesTests/TableTests.swift +++ b/Tests/StructuredQueriesTests/TableTests.swift @@ -63,12 +63,13 @@ extension SnapshotTests { """ } results: { """ - ┌───────────────────────────────────────────────────┐ - │ SnapshotTests.TableTests.DefaultSelect.Row.Draft( │ - │ id: 1, │ - │ isDeleted: false │ - │ ) │ - └───────────────────────────────────────────────────┘ + ┌────────────────────────────────────────────────────────────┐ + │ SnapshotTests.TableTests.DefaultSelect.Row.Draft( │ + │ id: 1, │ + │ isDeleted: false, │ + │ _draftIdentifier: StructuredQueriesCore._DraftIdentifier │ + │ ) │ + └────────────────────────────────────────────────────────────┘ """ } assertQuery(Row.select(\.id)) { @@ -386,12 +387,13 @@ extension SnapshotTests { """ } results: { """ - ┌──────────────────────────────────────────────────┐ - │ SnapshotTests.TableTests.DefaultWhere.Row.Draft( │ - │ id: 1, │ - │ isDeleted: false │ - │ ) │ - └──────────────────────────────────────────────────┘ + ┌────────────────────────────────────────────────────────────┐ + │ SnapshotTests.TableTests.DefaultWhere.Row.Draft( │ + │ id: 1, │ + │ isDeleted: false, │ + │ _draftIdentifier: StructuredQueriesCore._DraftIdentifier │ + │ ) │ + └────────────────────────────────────────────────────────────┘ """ } assertQuery(Row.unscoped) { From 28a58f60a852641b145148231222a9c912a77d34 Mon Sep 17 00:00:00 2001 From: Brandon Williams Date: Wed, 4 Feb 2026 14:44:56 -0600 Subject: [PATCH 2/3] wip --- Sources/StructuredQueriesMacros/TableMacro.swift | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Sources/StructuredQueriesMacros/TableMacro.swift b/Sources/StructuredQueriesMacros/TableMacro.swift index 6e0e64f3..d0678a17 100644 --- a/Sources/StructuredQueriesMacros/TableMacro.swift +++ b/Sources/StructuredQueriesMacros/TableMacro.swift @@ -723,11 +723,6 @@ extension TableMacro: ExtensionMacro { @_Draft(\(type).self) public struct Draft { \(draftProperties, separator: "\n") - - @Ephemeral - private let _draftIdentifier = _DraftIdentifier() - public var draftIdentifier: some Hashable { - DraftIdentifier(_draftIdentifier) } """ From 281162bc9eef2d6dbf21101baa301282aacfa835 Mon Sep 17 00:00:00 2001 From: Brandon Williams Date: Wed, 4 Feb 2026 14:51:47 -0600 Subject: [PATCH 3/3] sendable --- Sources/StructuredQueriesCore/PrimaryKeyed.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Sources/StructuredQueriesCore/PrimaryKeyed.swift b/Sources/StructuredQueriesCore/PrimaryKeyed.swift index 8150282a..f2ce5621 100644 --- a/Sources/StructuredQueriesCore/PrimaryKeyed.swift +++ b/Sources/StructuredQueriesCore/PrimaryKeyed.swift @@ -301,8 +301,8 @@ extension Delete where From: TableDraft { } import Foundation -public struct _DraftIdentifier: Hashable, CustomReflectable { - public let rawValue: AnyHashable +public struct _DraftIdentifier: Hashable, CustomReflectable, Sendable { + public let rawValue: UUID public init() { rawValue = UUID() } @@ -315,7 +315,7 @@ public struct _DraftIdentifier: Hashable, CustomReflectable { Mirror(self, children: []) } } -public struct DraftIdentifier: Hashable { +public struct DraftIdentifier: Hashable, Sendable { private let rawValue: _DraftIdentifier public init(_ draftIdentifier: _DraftIdentifier) { rawValue = draftIdentifier