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
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
name: macOS
strategy:
matrix:
xcode: ['16.3']
xcode: ['16.4']
config: ['debug', 'release']
runs-on: macos-15
steps:
Expand All @@ -32,7 +32,7 @@ jobs:
name: Examples
strategy:
matrix:
xcode: ['16.3']
xcode: ['16.4']
config: ['debug']
scheme: ['Reminders', 'CaseStudies', 'SyncUps']
runs-on: macos-15
Expand Down
2 changes: 1 addition & 1 deletion Examples/Reminders/ReminderForm.swift
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ struct ReminderFormView: View {
selectedTags = try await database.read { db in
try Tag
.order(by: \.title)
.join(ReminderTag.all) { $0.id.eq($1.tagID) }
.join(ReminderTag.all) { $0.primaryKey.eq($1.tagID) }
.where { $1.reminderID.eq(reminderID) }
.select { tag, _ in tag }
.fetchAll(db)
Expand Down
4 changes: 2 additions & 2 deletions Examples/Reminders/RemindersDetail.swift
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ class RemindersDetailModel: HashableObject {
case .flagged: reminder.isFlagged
case .remindersList(let list): reminder.remindersListID.eq(list.id)
case .scheduled: reminder.isScheduled
case .tags(let tags): tag.id.ifnull(UUID(0)).in(tags.map(\.id))
case .tags(let tags): tag.primaryKey.ifnull("").in(tags.map(\.primaryKey))
case .today: reminder.isToday
}
}
Expand All @@ -101,7 +101,7 @@ class RemindersDetailModel: HashableObject {
remindersList: $3,
isPastDue: $0.isPastDue,
notes: $0.inlineNotes.substr(0, 200),
tags: #sql("\($2.jsonNames)")
tags: #sql("\($2.jsonTitles)")
)
}
return query
Expand Down
67 changes: 30 additions & 37 deletions Examples/Reminders/Schema.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@ extension Reminder.Draft: Identifiable {}

@Table
struct Tag: Hashable, Identifiable {
let id: UUID
var title = ""
@Column(primaryKey: true)
var title: String
var id: String { title }
}

enum Priority: Int, Codable, QueryBindable {
Expand All @@ -56,7 +57,7 @@ extension Reminder {
}
static let withTags = group(by: \.id)
.leftJoin(ReminderTag.all) { $0.id.eq($1.reminderID) }
.leftJoin(Tag.all) { $1.tagID.eq($2.id) }
.leftJoin(Tag.all) { $1.tagID.eq($2.primaryKey) }
}

extension Reminder.TableColumns {
Expand All @@ -77,13 +78,13 @@ extension Reminder.TableColumns {
}

extension Tag {
static let withReminders = group(by: \.id)
.leftJoin(ReminderTag.all) { $0.id.eq($1.tagID) }
static let withReminders = group(by: \.primaryKey)
.leftJoin(ReminderTag.all) { $0.primaryKey.eq($1.tagID) }
.leftJoin(Reminder.all) { $1.reminderID.eq($2.id) }
}

extension Tag.TableColumns {
var jsonNames: some QueryExpression<[String].JSONRepresentation> {
var jsonTitles: some QueryExpression<[String].JSONRepresentation> {
self.title.jsonGroupArray(filter: self.title.isNot(nil))
}
}
Expand Down Expand Up @@ -148,19 +149,16 @@ func appDatabase() throws -> any DatabaseWriter {
"notes" TEXT,
"position" INTEGER NOT NULL DEFAULT 0,
"priority" INTEGER,
"remindersListID" TEXT NOT NULL,
"title" TEXT NOT NULL,

FOREIGN KEY("remindersListID") REFERENCES "remindersLists"("id") ON DELETE CASCADE
"remindersListID" TEXT NOT NULL REFERENCES "remindersLists"("id") ON DELETE CASCADE,
"title" TEXT NOT NULL
) STRICT
"""
)
.execute(db)
try #sql(
"""
CREATE TABLE "tags" (
"id" TEXT PRIMARY KEY NOT NULL ON CONFLICT REPLACE DEFAULT (uuid()),
"title" TEXT NOT NULL COLLATE NOCASE
"title" TEXT COLLATE NOCASE PRIMARY KEY NOT NULL
) STRICT
"""
)
Expand All @@ -169,11 +167,8 @@ func appDatabase() throws -> any DatabaseWriter {
"""
CREATE TABLE "remindersTags" (
"id" TEXT PRIMARY KEY NOT NULL ON CONFLICT REPLACE DEFAULT (uuid()),
"reminderID" TEXT NOT NULL,
"tagID" TEXT NOT NULL,

FOREIGN KEY("reminderID") REFERENCES "reminders"("id") ON DELETE CASCADE,
FOREIGN KEY("tagID") REFERENCES "tags"("id") ON DELETE CASCADE
"reminderID" TEXT NOT NULL REFERENCES "reminders"("id") ON DELETE CASCADE,
"tagID" TEXT NOT NULL REFERENCES "tags"("title") ON DELETE CASCADE ON UPDATE CASCADE
) STRICT
"""
)
Expand Down Expand Up @@ -220,9 +215,10 @@ private let logger = Logger(subsystem: "Reminders", category: "Database")
#if DEBUG
extension Database {
func seedSampleData() throws {
let remindersListIDs = (0...2).map { _ in UUID() }
let reminderIDs = (0...10).map { _ in UUID() }
let tagIDs = (0...6).map { _ in UUID() }
@Dependency(\.date.now) var now
@Dependency(\.uuid) var uuid
let remindersListIDs = (0...2).map { _ in uuid() }
let reminderIDs = (0...10).map { _ in uuid() }
try seed {
RemindersList(
id: remindersListIDs[0],
Expand All @@ -247,59 +243,59 @@ private let logger = Logger(subsystem: "Reminders", category: "Database")
)
Reminder(
id: reminderIDs[1],
dueDate: Date().addingTimeInterval(-60 * 60 * 24 * 2),
dueDate: now.addingTimeInterval(-60 * 60 * 24 * 2),
isFlagged: true,
remindersListID: remindersListIDs[0],
title: "Haircut"
)
Reminder(
id: reminderIDs[2],
dueDate: Date(),
dueDate: now,
notes: "Ask about diet",
priority: .high,
remindersListID: remindersListIDs[0],
title: "Doctor appointment"
)
Reminder(
id: reminderIDs[3],
dueDate: Date().addingTimeInterval(-60 * 60 * 24 * 190),
dueDate: now.addingTimeInterval(-60 * 60 * 24 * 190),
isCompleted: true,
remindersListID: remindersListIDs[0],
title: "Take a walk"
)
Reminder(
id: reminderIDs[4],
dueDate: Date(),
dueDate: now,
remindersListID: remindersListIDs[0],
title: "Buy concert tickets"
)
Reminder(
id: reminderIDs[5],
dueDate: Date().addingTimeInterval(60 * 60 * 24 * 2),
dueDate: now.addingTimeInterval(60 * 60 * 24 * 2),
isFlagged: true,
priority: .high,
remindersListID: remindersListIDs[1],
title: "Pick up kids from school"
)
Reminder(
id: reminderIDs[6],
dueDate: Date().addingTimeInterval(-60 * 60 * 24 * 2),
dueDate: now.addingTimeInterval(-60 * 60 * 24 * 2),
isCompleted: true,
priority: .low,
remindersListID: remindersListIDs[1],
title: "Get laundry"
)
Reminder(
id: reminderIDs[7],
dueDate: Date().addingTimeInterval(60 * 60 * 24 * 4),
dueDate: now.addingTimeInterval(60 * 60 * 24 * 4),
isCompleted: false,
priority: .high,
remindersListID: remindersListIDs[1],
title: "Take out trash"
)
Reminder(
id: reminderIDs[8],
dueDate: Date().addingTimeInterval(60 * 60 * 24 * 2),
dueDate: now.addingTimeInterval(60 * 60 * 24 * 2),
notes: """
Status of tax return
Expenses for next year
Expand All @@ -310,26 +306,23 @@ private let logger = Logger(subsystem: "Reminders", category: "Database")
)
Reminder(
id: reminderIDs[9],
dueDate: Date().addingTimeInterval(-60 * 60 * 24 * 2),
dueDate: now.addingTimeInterval(-60 * 60 * 24 * 2),
isCompleted: true,
priority: .medium,
remindersListID: remindersListIDs[2],
title: "Send weekly emails"
)
Reminder(
id: reminderIDs[10],
dueDate: Date().addingTimeInterval(60 * 60 * 24 * 2),
dueDate: now.addingTimeInterval(60 * 60 * 24 * 2),
isCompleted: false,
remindersListID: remindersListIDs[2],
title: "Prepare for WWDC"
)
Tag(id: tagIDs[0], title: "car")
Tag(id: tagIDs[1], title: "kids")
Tag(id: tagIDs[2], title: "someday")
Tag(id: tagIDs[3], title: "optional")
Tag(id: tagIDs[4], title: "social")
Tag(id: tagIDs[5], title: "night")
Tag(id: tagIDs[6], title: "adulting")
let tagIDs = ["car", "kids", "someday", "optional", "social", "night", "adulting"]
for tagID in tagIDs {
Tag(title: tagID)
}
ReminderTag.Draft(reminderID: reminderIDs[0], tagID: tagIDs[2])
ReminderTag.Draft(reminderID: reminderIDs[0], tagID: tagIDs[3])
ReminderTag.Draft(reminderID: reminderIDs[0], tagID: tagIDs[6])
Expand Down
2 changes: 1 addition & 1 deletion Examples/Reminders/SearchReminders.swift
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ class SearchRemindersModel {
notes: $0.inlineNotes,
reminder: $0,
remindersList: $3,
tags: #sql("\($2.jsonNames)")
tags: #sql("\($2.jsonTitles)")
)
},
animation: .default
Expand Down
2 changes: 1 addition & 1 deletion Examples/Reminders/TagRow.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ struct TagRow: View {
#Preview {
NavigationStack {
List {
TagRow(tag: Tag(id: UUID(1), title: "optional"))
TagRow(tag: Tag(title: "optional"))
}
}
}
2 changes: 1 addition & 1 deletion Examples/Reminders/TagsForm.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ struct TagsView: View {

let rest =
try Tag
.where { !$0.id.in(top.map(\.id)) }
.where { !$0.primaryKey.in(top.map(\.primaryKey)) }
.order(by: \.title)
.fetchAll(db)

Expand Down
Loading