Skip to content

Commit

Permalink
validate issue dependencies before inserting into DB
Browse files Browse the repository at this point in the history
foreign key constrain violations crash the app
  • Loading branch information
Julian Dunskus committed Jun 23, 2024
1 parent 190254a commit 0d35161
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 0 deletions.
26 changes: 26 additions & 0 deletions Issue Manager/Back End/Concrete Requests/Sync.swift
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,25 @@ extension SyncContext {
}

private func pullChangedIssues(for site: ConstructionSite) async throws {
let knownMaps = repository.ids(for: site.maps)
let knownCraftsmen = repository.ids(for: site.craftsmen)
let knownManagers = repository.ids(for: ConstructionManager.all())

func validate(_ issue: Issue) throws {
func check<Object: StoredObject>(_ id: Object.ID?, against known: Set<Object.ID>) throws {
guard let id else { return }
guard known.contains(id) else {
throw MissingIssueDependency(id: id, knownIDs: known, issue: issue)
}
}
try check(issue.mapID, against: knownMaps)
try check(issue.craftsmanID, against: knownCraftsmen)
try check(issue.status.createdBy, against: knownManagers)
try check(issue.status.registeredBy, against: knownManagers)
try check(issue.status.resolvedBy, against: knownCraftsmen)
try check(issue.status.closedBy, against: knownManagers)
}

var itemsPerPage = 1000
var lastChangeTime = Date.distantPast
while true {
Expand All @@ -345,13 +364,20 @@ extension SyncContext {
))

let issues = collection.makeObjects(context: site.id)
try issues.forEach(validate) // validate that foreign key constraints will hold before inserting into DB with a `try!`
repository.update(changing: issues)

guard collection.view.nextPage != nil else { break } // done
}
}
}

struct MissingIssueDependency<Object: StoredObject>: Error {
var id: Object.ID
var knownIDs: Set<Object.ID>
var issue: Issue
}

enum SyncError: Error {
case siteAccessRemoved
}
Expand Down
4 changes: 4 additions & 0 deletions Issue Manager/Back End/Storage/Repository.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ final class Repository: Sendable {
func object<Object>(_ id: Object.ID) -> Object? where Object: StoredObject {
read(id.get)
}

func ids<Object>(for objects: QueryInterfaceRequest<Object>) -> Set<ObjectID<Object>> where Object: StoredObject {
Set(read(objects.select(ObjectMeta<Object>.Columns.id).fetchAll))
}

/// saves modifications to an issue
func save(_ issue: Issue) {
Expand Down

0 comments on commit 0d35161

Please sign in to comment.