From a923ff23d49197deeaaf3ab1a2976d7d04838773 Mon Sep 17 00:00:00 2001 From: Stephen Celis Date: Tue, 13 Jan 2026 11:50:17 -0800 Subject: [PATCH 1/2] Expose SyncEngine.isSynchronizing as Swift/database function pair This deprecates the existing query expression API for a `@DatabaseFunction` with a projected query expression: ```swift // Before: SyncEngine.isSynchronizingChanges() // some QueryExpression // After: SyncEngine.isSynchronizing // Bool SyncEngine.$isSynchronizing // some QueryExpression ``` --- .../xcshareddata/swiftpm/Package.resolved | 4 ++-- Package.swift | 3 ++- .../CloudKit/Internal/CloudKitFunctions.swift | 5 ----- Sources/SQLiteData/CloudKit/Internal/Triggers.swift | 12 ++++++------ Sources/SQLiteData/CloudKit/SyncEngine.swift | 13 +++++++++---- .../Documentation.docc/Articles/CloudKit.md | 6 +++--- 6 files changed, 22 insertions(+), 21 deletions(-) diff --git a/Examples/Examples.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Examples/Examples.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 1f540899..95bef7bd 100644 --- a/Examples/Examples.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Examples/Examples.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -123,8 +123,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/pointfreeco/swift-structured-queries", "state" : { - "revision" : "9c84335373bae5f5c9f7b5f0adf3ae10f2cab5b9", - "version" : "0.25.2" + "branch" : "database-function-vars", + "revision" : "7c65021d46fc1632e357125f3156e22db23a9849" } }, { diff --git a/Package.swift b/Package.swift index 8e87eb48..1168cdd0 100644 --- a/Package.swift +++ b/Package.swift @@ -37,7 +37,8 @@ let package = Package( .package(url: "https://github.com/pointfreeco/swift-snapshot-testing", from: "1.18.4"), .package( url: "https://github.com/pointfreeco/swift-structured-queries", - from: "0.24.0", + // from: "0.24.0", + branch: "database-function-vars", traits: [ .trait(name: "StructuredQueriesTagged", condition: .when(traits: ["SQLiteDataTagged"])) ] diff --git a/Sources/SQLiteData/CloudKit/Internal/CloudKitFunctions.swift b/Sources/SQLiteData/CloudKit/Internal/CloudKitFunctions.swift index 5d166e16..afab5b52 100644 --- a/Sources/SQLiteData/CloudKit/Internal/CloudKitFunctions.swift +++ b/Sources/SQLiteData/CloudKit/Internal/CloudKitFunctions.swift @@ -18,9 +18,4 @@ return share.publicPermission == .readWrite || share.currentUserParticipant?.permission == .readWrite } - - @DatabaseFunction("sqlitedata_icloud_syncEngineIsSynchronizingChanges") - func syncEngineIsSynchronizingChanges() -> Bool { - _isSynchronizingChanges - } #endif diff --git a/Sources/SQLiteData/CloudKit/Internal/Triggers.swift b/Sources/SQLiteData/CloudKit/Internal/Triggers.swift index 186b1f08..5085b05a 100644 --- a/Sources/SQLiteData/CloudKit/Internal/Triggers.swift +++ b/Sources/SQLiteData/CloudKit/Internal/Triggers.swift @@ -141,7 +141,7 @@ } .update { $0._isDeleted = true } } when: { _ in - !SyncEngine.isSynchronizingChanges() + !SyncEngine.$isSynchronizing } ) } @@ -158,7 +158,7 @@ } .delete() } when: { _ in - SyncEngine.isSynchronizingChanges() + SyncEngine.$isSynchronizing } ) } @@ -263,7 +263,7 @@ ) ) } when: { _ in - !SyncEngine.isSynchronizingChanges() + !SyncEngine.$isSynchronizing } ) } @@ -323,7 +323,7 @@ ) ) } when: { old, new in - old._isDeleted.eq(new._isDeleted) && !SyncEngine.isSynchronizingChanges() + old._isDeleted.eq(new._isDeleted) && !SyncEngine.$isSynchronizing } ) } @@ -344,7 +344,7 @@ ) ) } when: { old, new in - !old._isDeleted && new._isDeleted && !SyncEngine.isSynchronizingChanges() + !old._isDeleted && new._isDeleted && !SyncEngine.$isSynchronizing } ) } @@ -453,7 +453,7 @@ ) } .where { - !SyncEngine.isSynchronizingChanges() + !SyncEngine.$isSynchronizing && $0.parentRecordName.is(nil) && !$hasPermission($0.share) } diff --git a/Sources/SQLiteData/CloudKit/SyncEngine.swift b/Sources/SQLiteData/CloudKit/SyncEngine.swift index a6c77d35..efc0fec1 100644 --- a/Sources/SQLiteData/CloudKit/SyncEngine.swift +++ b/Sources/SQLiteData/CloudKit/SyncEngine.swift @@ -349,7 +349,7 @@ .execute(db) } db.add(function: $currentTime) - db.add(function: $syncEngineIsSynchronizingChanges) + db.add(function: SyncEngine.$isSynchronizing) db.add(function: $didUpdate) db.add(function: $didDelete) db.add(function: $hasPermission) @@ -864,12 +864,17 @@ ) } - /// A query expression that can be used in SQL queries to determine if the ``SyncEngine`` - /// is currently writing changes to the database. + /// Whether or not the ``SyncEngine`` is currently writing changes to the database. /// /// See for more info. + @DatabaseFunction("sqlitedata_icloud_syncEngineIsSynchronizingChanges") + public static var isSynchronizing: Bool { + _isSynchronizingChanges + } + + @available(*, deprecated, message: "Use 'SyncEngine.$isSynchronizing', instead.") public static func isSynchronizingChanges() -> some QueryExpression { - $syncEngineIsSynchronizingChanges() + $isSynchronizing } private var sendingChangesCount: Int { diff --git a/Sources/SQLiteData/Documentation.docc/Articles/CloudKit.md b/Sources/SQLiteData/Documentation.docc/Articles/CloudKit.md index bc1a32b6..43b71f13 100644 --- a/Sources/SQLiteData/Documentation.docc/Articles/CloudKit.md +++ b/Sources/SQLiteData/Documentation.docc/Articles/CloudKit.md @@ -749,7 +749,7 @@ or CloudKit is updating the data. [FTS]: https://sqlite.org/fts5.html -To customize this behavior you can use the ``SyncEngine/isSynchronizingChanges()`` SQL expression. +To customize this behavior you can use the projected ``SyncEngine/isSynchronizing`` SQL expression. It represents a custom database function that is installed in your database connection, and it will return true if the write to your database originates from the sync engine. You can use it in a trigger like so: @@ -759,7 +759,7 @@ trigger like so: """ CREATE TEMPORARY TRIGGER "…" AFTER DELETE ON "…" - FOR EACH ROW WHEN NOT \(SyncEngine.isSynchronizingChanges()) + FOR EACH ROW WHEN NOT \(SyncEngine.$isSynchronizing) BEGIN … END @@ -776,7 +776,7 @@ Model.createTemporaryTrigger( after: .insert { new in // ... } when: { _ in - !SyncEngine.isSynchronizingChanges() + !SyncEngine.$isSynchronizing } ) ``` From 62d742037551ac5a55b2b5279ba7c88195b42c38 Mon Sep 17 00:00:00 2001 From: Stephen Celis Date: Tue, 13 Jan 2026 12:13:14 -0800 Subject: [PATCH 2/2] wip --- Package.resolved | 6 +++--- Package.swift | 3 +-- Package@swift-6.0.swift | 2 +- .../CloudKitTests/SchemaChangeTests.swift | 16 ++++++++-------- 4 files changed, 13 insertions(+), 14 deletions(-) diff --git a/Package.resolved b/Package.resolved index 419fc30f..6c09d839 100644 --- a/Package.resolved +++ b/Package.resolved @@ -1,5 +1,5 @@ { - "originHash" : "41f93013537f670f4fe1a235c318bee33b54528c76e4b1dd2a7675bea6c0bcde", + "originHash" : "6cd14013e211dd746d8c9744f0a929fb46d1bd7f15becd1b00ebde3fa03d255a", "pins" : [ { "identity" : "combine-schedulers", @@ -123,8 +123,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/pointfreeco/swift-structured-queries", "state" : { - "revision" : "3a95b70a81b7027b8a5117e7dd08188837e5f54e", - "version" : "0.24.0" + "revision" : "862802b5a66aec04219b7c2a10e06a5681da86ee", + "version" : "0.27.0" } }, { diff --git a/Package.swift b/Package.swift index 1168cdd0..8ac697dc 100644 --- a/Package.swift +++ b/Package.swift @@ -37,8 +37,7 @@ let package = Package( .package(url: "https://github.com/pointfreeco/swift-snapshot-testing", from: "1.18.4"), .package( url: "https://github.com/pointfreeco/swift-structured-queries", - // from: "0.24.0", - branch: "database-function-vars", + from: "0.27.0", traits: [ .trait(name: "StructuredQueriesTagged", condition: .when(traits: ["SQLiteDataTagged"])) ] diff --git a/Package@swift-6.0.swift b/Package@swift-6.0.swift index fc886e60..5ff5be38 100644 --- a/Package@swift-6.0.swift +++ b/Package@swift-6.0.swift @@ -28,7 +28,7 @@ let package = Package( .package(url: "https://github.com/pointfreeco/swift-dependencies", from: "1.9.0"), .package(url: "https://github.com/pointfreeco/swift-sharing", from: "2.3.0"), .package(url: "https://github.com/pointfreeco/swift-snapshot-testing", from: "1.18.4"), - .package(url: "https://github.com/pointfreeco/swift-structured-queries", from: "0.24.0"), + .package(url: "https://github.com/pointfreeco/swift-structured-queries", from: "0.27.0"), .package(url: "https://github.com/pointfreeco/xctest-dynamic-overlay", from: "1.5.0"), ], targets: [ diff --git a/Tests/SQLiteDataTests/CloudKitTests/SchemaChangeTests.swift b/Tests/SQLiteDataTests/CloudKitTests/SchemaChangeTests.swift index a0cde527..aebc26ab 100644 --- a/Tests/SQLiteDataTests/CloudKitTests/SchemaChangeTests.swift +++ b/Tests/SQLiteDataTests/CloudKitTests/SchemaChangeTests.swift @@ -163,8 +163,8 @@ │ ), │ │ share: nil, │ │ _isDeleted: false, │ - │ hasLastKnownServerRecord: true, │ - │ isShared: false, │ + │ _hasLastKnownServerRecord: true, │ + │ _isShared: false, │ │ userModificationTime: 0 │ │ ) │ └────────────────────────────────────────────────────────────────────┘ @@ -251,8 +251,8 @@ │ ), │ │ share: nil, │ │ _isDeleted: false, │ - │ hasLastKnownServerRecord: true, │ - │ isShared: false, │ + │ _hasLastKnownServerRecord: true, │ + │ _isShared: false, │ │ userModificationTime: 1 │ │ ) │ └────────────────────────────────────────────────────────────────────┘ @@ -363,8 +363,8 @@ │ ), │ │ share: nil, │ │ _isDeleted: false, │ - │ hasLastKnownServerRecord: true, │ - │ isShared: false, │ + │ _hasLastKnownServerRecord: true, │ + │ _isShared: false, │ │ userModificationTime: 0 │ │ ) │ └────────────────────────────────────────────────────────────────────┘ @@ -410,8 +410,8 @@ │ ), │ │ share: nil, │ │ _isDeleted: false, │ - │ hasLastKnownServerRecord: true, │ - │ isShared: false, │ + │ _hasLastKnownServerRecord: true, │ + │ _isShared: false, │ │ userModificationTime: 0 │ │ ) │ └────────────────────────────────────────────────────────────────────┘