Thanks.
That worked in this simple project, but not in my full project. I'm not yet sure what the difference is, but it throws the instance was invalidated error when setting object.relationship = nil
I've resorted to using sqlite directly (with the SQLite.swift package) and then setting to nil with a separate query:
class IntegrityCheck {
var model: String
var relationship: String
var relationshipType: String
var count: Int64 = 0
var checked: Bool = false
var orphanedObjectPKs: [Int64] = []
init(model: String, relationship: String, relationshipType: String) {
self.model = model
self.relationship = relationship
self.relationshipType = relationshipType
}
init(model: String, relationship: String) {
self.model = model
self.relationship = relationship
self.relationshipType = relationship
}
func run(modelContext: ModelContext) {
guard let db = modelContext.sqliteDatabase else {
print("could not get sqlite database")
return
}
do {
let query = try db.prepare(sql)
count = try query.scalar() as! Int64
checked = true
if count > 0 {
let orphanedQuery = try db.prepare(orpahnedObjectSQL)
for row in orphanedQuery {
orphanedObjectPKs.append(row[0] as! Int64)
}
}
} catch {
print(error)
}
}
private var modelTable: String {
"Z\(model.uppercased())"
}
private var relationshipColumn: String {
"Z\(relationship.uppercased())"
}
private var relationshipTable: String {
"Z\(relationshipType.uppercased())"
}
var sql: String {
"""
select
count(*)
from
\(modelTable)
left join \(relationshipTable) on \(relationshipTable).Z_PK = \(modelTable).\(relationshipColumn)
where
\(modelTable).\(relationshipColumn) is not null
and \(relationshipTable).Z_PK is null
"""
}
var orpahnedObjectSQL: String {
"""
select
distinct(\(modelTable).\(relationshipColumn))
from
\(modelTable)
left join \(relationshipTable) on \(relationshipTable).Z_PK = \(modelTable).\(relationshipColumn)
where
\(modelTable).\(relationshipColumn) is not null
and \(relationshipTable).Z_PK is null
"""
}
}
extension ModelContext {
var sqliteUrl: URL? {
return container.configurations.first?.url
}
var sqliteDatabase: Connection? {
guard let url = sqliteUrl else {
return nil
}
print(url.path)
do {
return try SQLite.Connection(url.path)
} catch {
print("Error opening database: \(error)")
return nil
}
}
}
Topic:
App & System Services
SubTopic:
iCloud & Data
Tags: