From 15deb1fa962cf5953d5f6f05763ff5016ff70e0c Mon Sep 17 00:00:00 2001 From: Ilya Laryionau Date: Tue, 5 Aug 2025 18:52:48 +0200 Subject: [PATCH 1/3] Migrate to triggers, add RemindersList Defaults --- Examples/Reminders/Schema.swift | 65 +++++++++++++-------------------- 1 file changed, 26 insertions(+), 39 deletions(-) diff --git a/Examples/Reminders/Schema.swift b/Examples/Reminders/Schema.swift index 788f8f27..7c74855a 100644 --- a/Examples/Reminders/Schema.swift +++ b/Examples/Reminders/Schema.swift @@ -12,6 +12,9 @@ struct RemindersList: Hashable, Identifiable { var color = Color(red: 0x4a / 255, green: 0x99 / 255, blue: 0xef / 255) var position = 0 var title = "" + + static var defaultColorHex: Int64 { 0x4a99_ef00 } + static var defaultTitle: String { "Personal" } } extension RemindersList.Draft: Identifiable {} @@ -127,7 +130,7 @@ func appDatabase() throws -> any DatabaseWriter { """ CREATE TABLE "remindersLists" ( "id" TEXT PRIMARY KEY NOT NULL ON CONFLICT REPLACE DEFAULT (uuid()), - "color" INTEGER NOT NULL DEFAULT \(raw: 0x4a99_ef00), + "color" INTEGER NOT NULL DEFAULT \(raw: RemindersLists.defaultColorHex), "position" INTEGER NOT NULL DEFAULT 0, "title" TEXT NOT NULL ) STRICT @@ -178,49 +181,33 @@ func appDatabase() throws -> any DatabaseWriter { try migrator.migrate(database) - if context == .preview { - try database.write { db in + try database.write { db in + if context == .preview { try db.seedSampleData() } - } - try database.write { db in - try #sql( - """ - CREATE TEMPORARY TRIGGER "default_position_reminders_lists" - AFTER INSERT ON "remindersLists" - FOR EACH ROW BEGIN - UPDATE "remindersLists" - SET "position" = (SELECT max("position") + 1 FROM "remindersLists") - WHERE "id" = NEW."id"; - END - """ - ) + try RemindersList.createTemporaryTrigger(after: .insert { new in + RemindersList + .update { $0.position = RemindersList.select { ($0.position.max() ?? -1) + 1} } + .where { $0.id.eq(new.id) } + }) .execute(db) - try #sql( - """ - CREATE TEMPORARY TRIGGER "default_position_reminders" - AFTER INSERT ON "reminders" - FOR EACH ROW BEGIN - UPDATE "reminders" - SET "position" = (SELECT max("position") + 1 FROM "reminders") - WHERE "id" = NEW."id"; - END - """ - ) + try Reminder.createTemporaryTrigger(after: .insert { new in + Reminder + .update { $0.position = Reminder.select { ($0.position.max() ?? -1) + 1} } + .where { $0.id.eq(new.id) } + }) .execute(db) - try #sql( - """ - CREATE TEMPORARY TRIGGER "non_empty_reminders_lists" - AFTER DELETE ON "remindersLists" - FOR EACH ROW BEGIN - INSERT INTO "remindersLists" - ("title", "color") - SELECT 'Personal', \(raw: 0x4a99ef) - WHERE (SELECT count(*) FROM "remindersLists") = 0; - END - """ - ) + try RemindersList.createTemporaryTrigger(after: .delete { _ in + RemindersList.insert { + RemindersList.Draft( + color: RemindersLists.defaultColorHex, + title: RemindersLists.defaultTitle + ) + } + } when: { _ in + RemindersList.count().eq(0) + }) .execute(db) } From e683ac47081f14c3b0cf8213e77ae91cc9e1f34f Mon Sep 17 00:00:00 2001 From: Stephen Celis Date: Tue, 5 Aug 2025 12:45:06 -0700 Subject: [PATCH 2/3] wip --- .../xcshareddata/swiftpm/Package.resolved | 13 +++++++++++-- Examples/Reminders/Helpers.swift | 18 +++++++++++------- Examples/Reminders/Schema.swift | 17 +++++++++-------- 3 files changed, 31 insertions(+), 17 deletions(-) diff --git a/Examples/Examples.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Examples/Examples.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 59541a19..e53dc108 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" : "6bd870099083ef269eeee8835808cb6233151654", - "version" : "0.7.0" + "revision" : "6b3f436f4da7fd2ea304742d936ac8205e5ef8f8", + "version" : "0.10.0" } }, { @@ -136,6 +136,15 @@ "version" : "601.0.1" } }, + { + "identity" : "swift-tagged", + "kind" : "remoteSourceControl", + "location" : "https://github.com/pointfreeco/swift-tagged", + "state" : { + "revision" : "3907a9438f5b57d317001dc99f3f11b46882272b", + "version" : "0.10.0" + } + }, { "identity" : "xctest-dynamic-overlay", "kind" : "remoteSourceControl", diff --git a/Examples/Reminders/Helpers.swift b/Examples/Reminders/Helpers.swift index 21310bce..97fdea7f 100644 --- a/Examples/Reminders/Helpers.swift +++ b/Examples/Reminders/Helpers.swift @@ -5,16 +5,11 @@ extension Color { public struct HexRepresentation: QueryBindable, QueryRepresentable { public var queryOutput: Color public var queryBinding: QueryBinding { - guard let components = UIColor(queryOutput).cgColor.components - else { + guard let hexValue else { struct InvalidColor: Error {} return .invalid(InvalidColor()) } - let r = Int64(components[0] * 0xFF) << 24 - let g = Int64(components[1] * 0xFF) << 16 - let b = Int64(components[2] * 0xFF) << 8 - let a = Int64((components.indices.contains(3) ? components[3] : 1) * 0xFF) - return .int(r | g | b | a) + return .int(hexValue) } public init(queryOutput: Color) { self.queryOutput = queryOutput @@ -30,5 +25,14 @@ extension Color { ) ) } + public var hexValue: Int64? { + guard let components = UIColor(queryOutput).cgColor.components + else { return nil } + let r = Int64(components[0] * 0xFF) << 24 + let g = Int64(components[1] * 0xFF) << 16 + let b = Int64(components[2] * 0xFF) << 8 + let a = Int64((components.indices.contains(3) ? components[3] : 1) * 0xFF) + return r | g | b | a + } } } diff --git a/Examples/Reminders/Schema.swift b/Examples/Reminders/Schema.swift index 7c74855a..f59d733a 100644 --- a/Examples/Reminders/Schema.swift +++ b/Examples/Reminders/Schema.swift @@ -9,11 +9,11 @@ import SwiftUI struct RemindersList: Hashable, Identifiable { let id: UUID @Column(as: Color.HexRepresentation.self) - var color = Color(red: 0x4a / 255, green: 0x99 / 255, blue: 0xef / 255) + var color: Color = Self.defaultColor var position = 0 var title = "" - static var defaultColorHex: Int64 { 0x4a99_ef00 } + static var defaultColor: Color { Color(red: 0x4a / 255, green: 0x99 / 255, blue: 0xef / 255) } static var defaultTitle: String { "Personal" } } @@ -126,11 +126,12 @@ func appDatabase() throws -> any DatabaseWriter { migrator.eraseDatabaseOnSchemaChange = true #endif migrator.registerMigration("Create initial tables") { db in + let defaultListColor = Color.HexRepresentation(queryOutput: RemindersList.defaultColor).hexValue try #sql( """ CREATE TABLE "remindersLists" ( "id" TEXT PRIMARY KEY NOT NULL ON CONFLICT REPLACE DEFAULT (uuid()), - "color" INTEGER NOT NULL DEFAULT \(raw: RemindersLists.defaultColorHex), + "color" INTEGER NOT NULL DEFAULT \(raw: defaultListColor ?? 0), "position" INTEGER NOT NULL DEFAULT 0, "title" TEXT NOT NULL ) STRICT @@ -188,25 +189,25 @@ func appDatabase() throws -> any DatabaseWriter { try RemindersList.createTemporaryTrigger(after: .insert { new in RemindersList + .find(new.id) .update { $0.position = RemindersList.select { ($0.position.max() ?? -1) + 1} } - .where { $0.id.eq(new.id) } }) .execute(db) try Reminder.createTemporaryTrigger(after: .insert { new in Reminder + .find(new.id) .update { $0.position = Reminder.select { ($0.position.max() ?? -1) + 1} } - .where { $0.id.eq(new.id) } }) .execute(db) try RemindersList.createTemporaryTrigger(after: .delete { _ in RemindersList.insert { RemindersList.Draft( - color: RemindersLists.defaultColorHex, - title: RemindersLists.defaultTitle + color: RemindersList.defaultColor, + title: RemindersList.defaultTitle ) } } when: { _ in - RemindersList.count().eq(0) + !RemindersList.exists() }) .execute(db) } From 434a797621d79fabdb1f93daee4d34e960ae2386 Mon Sep 17 00:00:00 2001 From: Stephen Celis Date: Tue, 5 Aug 2025 13:40:42 -0700 Subject: [PATCH 3/3] Bump sleep for CI --- Examples/RemindersTests/SearchRemindersTests.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Examples/RemindersTests/SearchRemindersTests.swift b/Examples/RemindersTests/SearchRemindersTests.swift index 5fbb99ed..de0c53c5 100644 --- a/Examples/RemindersTests/SearchRemindersTests.swift +++ b/Examples/RemindersTests/SearchRemindersTests.swift @@ -26,7 +26,7 @@ extension BaseTestSuite { model.searchText = "Take" try await model.$reminders.load() try await model.$completedCount.load() - try await Task.sleep(for: .seconds(0.1)) + try await Task.sleep(for: .seconds(0.5)) #expect(model.completedCount == 1) assertInlineSnapshot(of: model.reminders, as: .customDump) { """