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 788f8f27..f59d733a 100644 --- a/Examples/Reminders/Schema.swift +++ b/Examples/Reminders/Schema.swift @@ -9,9 +9,12 @@ 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 defaultColor: Color { Color(red: 0x4a / 255, green: 0x99 / 255, blue: 0xef / 255) } + static var defaultTitle: String { "Personal" } } extension RemindersList.Draft: Identifiable {} @@ -123,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: 0x4a99_ef00), + "color" INTEGER NOT NULL DEFAULT \(raw: defaultListColor ?? 0), "position" INTEGER NOT NULL DEFAULT 0, "title" TEXT NOT NULL ) STRICT @@ -178,49 +182,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 + .find(new.id) + .update { $0.position = RemindersList.select { ($0.position.max() ?? -1) + 1} } + }) .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 + .find(new.id) + .update { $0.position = Reminder.select { ($0.position.max() ?? -1) + 1} } + }) .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: RemindersList.defaultColor, + title: RemindersList.defaultTitle + ) + } + } when: { _ in + !RemindersList.exists() + }) .execute(db) } 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) { """