diff --git a/WorldBuilder/Models/Utils/DeleteModel.swift b/WorldBuilder/Models/Utils/DeleteModel.swift new file mode 100644 index 0000000..9e03651 --- /dev/null +++ b/WorldBuilder/Models/Utils/DeleteModel.swift @@ -0,0 +1,121 @@ +import SwiftData +import Foundation + +struct DeleteModel { + let modelContext: ModelContext + + // MARK: - Entity + + func delete(_ entity: Entity) { + deleteRelations(.entity(id: entity.id)) + modelContext.delete(entity) + } + + + // MARK: - WorldEntityType + + func delete(_ worldEntityType: WorldEntityType) { + deleteRelations(.worldEntityType(id: worldEntityType.id)) + + let entities = fetchEntities(for: worldEntityType) + + for entity in entities { + delete(entity) + } + + modelContext.delete(worldEntityType) + } + + + // MARK: - EntityType + + func delete(_ entityType: EntityType) { + deleteRelations(.entityType(id: entityType.id)) + + let worldEntityTypes = fetchWorldEntityTypes(using: entityType) + + for worldEntityType in worldEntityTypes { + delete(worldEntityType) + } + + modelContext.delete(entityType) + } + + + // MARK: - World + + func delete(_ world: World) { + for relation in world.relations { + modelContext.delete(relation) + } + + let worldEntityTypes = fetchWorldEntityTypes(in: world) + + for worldEntityType in worldEntityTypes { + delete(worldEntityType) + } + + modelContext.delete(world) + } + + + // MARK: - Relations + + private func deleteRelations(_ endpoint: RelationEndpoint) { + let relations = fetchAllRelations() + + for relation in relations { + if relation.source == endpoint || relation.target == endpoint { + modelContext.delete(relation) + } + } + } + + + // MARK: - Fetch + + private func fetchAllRelations() -> [Relation] { + let descriptor = FetchDescriptor() + + return (try? modelContext.fetch(descriptor)) ?? [] + } + + + private func fetchEntities(for worldEntityType: WorldEntityType) -> [Entity] { + let worldEntityTypeID = worldEntityType.id + + let descriptor = FetchDescriptor( + predicate: #Predicate { + $0.worldEntityType.id == worldEntityTypeID + } + ) + + return (try? modelContext.fetch(descriptor)) ?? [] + } + + + private func fetchWorldEntityTypes(in world: World) -> [WorldEntityType] { + let worldID = world.id + + let descriptor = FetchDescriptor( + predicate: #Predicate { + $0.world.id == worldID + } + ) + + return (try? modelContext.fetch(descriptor)) ?? [] + } + + + private func fetchWorldEntityTypes(using entityType: EntityType) -> [WorldEntityType] { + let entityTypeID = entityType.id + + let descriptor = FetchDescriptor( + predicate: #Predicate { + $0.entityType.id == entityTypeID + } + ) + + return (try? modelContext.fetch(descriptor)) ?? [] + } +}