From 1a320d38524819a6e34a22d0ad8e9b268ec0463f Mon Sep 17 00:00:00 2001 From: Leo Dion Date: Fri, 4 Oct 2024 16:12:41 -0400 Subject: [PATCH 1/3] added auto-save and improved monitoring --- Sources/DataThespian/BackgroundDatabase.swift | 4 ++-- .../DataThespian/ManagedObjectMetadata.swift | 7 +++++- Sources/DataThespian/ModelActorDatabase.swift | 23 ++++++++++++++++++- 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/Sources/DataThespian/BackgroundDatabase.swift b/Sources/DataThespian/BackgroundDatabase.swift index 1cc930a..60d86f3 100644 --- a/Sources/DataThespian/BackgroundDatabase.swift +++ b/Sources/DataThespian/BackgroundDatabase.swift @@ -90,10 +90,10 @@ private var database: any Database { get async { await container.database } } - public convenience init(modelContainer: ModelContainer) { + public convenience init(modelContainer: ModelContainer, autosaveEnabled: Bool = false) { self.init { assert(isMainThread: false) - return ModelActorDatabase(modelContainer: modelContainer) + return ModelActorDatabase(modelContainer: modelContainer, autosaveEnabled: autosaveEnabled) } } diff --git a/Sources/DataThespian/ManagedObjectMetadata.swift b/Sources/DataThespian/ManagedObjectMetadata.swift index 0a09ce7..6596303 100644 --- a/Sources/DataThespian/ManagedObjectMetadata.swift +++ b/Sources/DataThespian/ManagedObjectMetadata.swift @@ -51,8 +51,13 @@ assertionFailure(error: error) return nil } + guard let entityName = managedObject.entity.name else { + assertionFailure("Missing entity name.") + return nil + } + self.init( - entityName: managedObject.entity.managedObjectClassName, + entityName: entityName, persistentIdentifier: persistentIdentifier ) } diff --git a/Sources/DataThespian/ModelActorDatabase.swift b/Sources/DataThespian/ModelActorDatabase.swift index c064398..9699fba 100644 --- a/Sources/DataThespian/ModelActorDatabase.swift +++ b/Sources/DataThespian/ModelActorDatabase.swift @@ -33,7 +33,7 @@ public import SwiftData - @ModelActor public actor ModelActorDatabase: Database, Loggable { +public actor ModelActorDatabase: Database, Loggable { public func delete(_: T.Type, withID id: PersistentIdentifier) async -> Bool { guard let model: T = self.modelContext.registeredModel(for: id) else { return false } @@ -88,6 +88,27 @@ try block(modelContext) } } + + + public nonisolated let modelExecutor: any SwiftData.ModelExecutor + + public nonisolated let modelContainer: SwiftData.ModelContainer + + public init(modelContainer: SwiftData.ModelContainer, autosaveEnabled: Bool = false) { + let modelContext = ModelContext(modelContainer) + modelContext.autosaveEnabled = autosaveEnabled + let modelExecutor = DefaultSerialModelExecutor(modelContext: modelContext) + self.init(modelExecutor: modelExecutor, modelContainer: modelContainer) } + + private init(modelExecutor: any ModelExecutor, modelContainer: ModelContainer) { + self.modelExecutor = modelExecutor + self.modelContainer = modelContainer + } +} + +extension ModelActorDatabase: SwiftData.ModelActor { +} + #endif From d91c9bce3fbe805b32a318e5a18ce1822cab2971 Mon Sep 17 00:00:00 2001 From: Leo Dion Date: Fri, 4 Oct 2024 20:23:01 -0400 Subject: [PATCH 2/3] fixing recent documents --- Sources/DataThespian/BackgroundDatabase.swift | 5 ++++- Sources/DataThespian/Database.swift | 2 ++ Sources/DataThespian/DatabaseKey.swift | 5 +++++ Sources/DataThespian/ModelActorDatabase.swift | 4 ++++ 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/Sources/DataThespian/BackgroundDatabase.swift b/Sources/DataThespian/BackgroundDatabase.swift index 60d86f3..f2f180c 100644 --- a/Sources/DataThespian/BackgroundDatabase.swift +++ b/Sources/DataThespian/BackgroundDatabase.swift @@ -42,7 +42,10 @@ public func delete(where predicate: Predicate?) async throws { try await self.database.delete(where: predicate) } - + + public func save () async throws { + try await self.database.save() + } public func insert(_ closuer: @escaping @Sendable () -> some PersistentModel) async -> PersistentIdentifier { await self.database.insert(closuer) } diff --git a/Sources/DataThespian/Database.swift b/Sources/DataThespian/Database.swift index 7ce6e95..caf5172 100644 --- a/Sources/DataThespian/Database.swift +++ b/Sources/DataThespian/Database.swift @@ -34,6 +34,8 @@ public import SwiftData public protocol Database: Sendable { + func save () async throws + @discardableResult func delete( _ modelType: T.Type, withID id: PersistentIdentifier diff --git a/Sources/DataThespian/DatabaseKey.swift b/Sources/DataThespian/DatabaseKey.swift index df46658..d2e0055 100644 --- a/Sources/DataThespian/DatabaseKey.swift +++ b/Sources/DataThespian/DatabaseKey.swift @@ -36,6 +36,11 @@ public import SwiftUI fileprivate struct DefaultDatabase: Database { + + public func save () async throws { + assertionFailure("No Database Set.") + throw NotImplmentedError.instance + } func delete(_: (some PersistentModel).Type, withID _: PersistentIdentifier) async -> Bool { assertionFailure("No Database Set.") return false diff --git a/Sources/DataThespian/ModelActorDatabase.swift b/Sources/DataThespian/ModelActorDatabase.swift index 9699fba..94e876f 100644 --- a/Sources/DataThespian/ModelActorDatabase.swift +++ b/Sources/DataThespian/ModelActorDatabase.swift @@ -89,6 +89,10 @@ public actor ModelActorDatabase: Database, Loggable { } } + public func save () throws { + assert(isMainThread: false) + try self.modelContext.save() + } public nonisolated let modelExecutor: any SwiftData.ModelExecutor From 01e05b7a34046853816203b2e006dd6096a343be Mon Sep 17 00:00:00 2001 From: Leo Dion Date: Fri, 4 Oct 2024 20:40:15 -0400 Subject: [PATCH 3/3] linting fixes --- Sources/DataThespian/BackgroundDatabase.swift | 5 +-- Sources/DataThespian/Database.swift | 3 +- Sources/DataThespian/DatabaseKey.swift | 3 +- .../DataThespian/ManagedObjectMetadata.swift | 6 +-- Sources/DataThespian/ModelActorDatabase.swift | 43 ++++++++----------- 5 files changed, 22 insertions(+), 38 deletions(-) diff --git a/Sources/DataThespian/BackgroundDatabase.swift b/Sources/DataThespian/BackgroundDatabase.swift index f2f180c..e7edaac 100644 --- a/Sources/DataThespian/BackgroundDatabase.swift +++ b/Sources/DataThespian/BackgroundDatabase.swift @@ -42,10 +42,7 @@ public func delete(where predicate: Predicate?) async throws { try await self.database.delete(where: predicate) } - - public func save () async throws { - try await self.database.save() - } + public func save() async throws { try await self.database.save() } public func insert(_ closuer: @escaping @Sendable () -> some PersistentModel) async -> PersistentIdentifier { await self.database.insert(closuer) } diff --git a/Sources/DataThespian/Database.swift b/Sources/DataThespian/Database.swift index caf5172..93a0a69 100644 --- a/Sources/DataThespian/Database.swift +++ b/Sources/DataThespian/Database.swift @@ -34,8 +34,7 @@ public import SwiftData public protocol Database: Sendable { - func save () async throws - + func save() async throws @discardableResult func delete( _ modelType: T.Type, withID id: PersistentIdentifier diff --git a/Sources/DataThespian/DatabaseKey.swift b/Sources/DataThespian/DatabaseKey.swift index d2e0055..6ca2a39 100644 --- a/Sources/DataThespian/DatabaseKey.swift +++ b/Sources/DataThespian/DatabaseKey.swift @@ -36,8 +36,7 @@ public import SwiftUI fileprivate struct DefaultDatabase: Database { - - public func save () async throws { + public func save() async throws { assertionFailure("No Database Set.") throw NotImplmentedError.instance } diff --git a/Sources/DataThespian/ManagedObjectMetadata.swift b/Sources/DataThespian/ManagedObjectMetadata.swift index 6596303..be45fd3 100644 --- a/Sources/DataThespian/ManagedObjectMetadata.swift +++ b/Sources/DataThespian/ManagedObjectMetadata.swift @@ -55,11 +55,7 @@ assertionFailure("Missing entity name.") return nil } - - self.init( - entityName: entityName, - persistentIdentifier: persistentIdentifier - ) + self.init(entityName: entityName, persistentIdentifier: persistentIdentifier) } } #endif diff --git a/Sources/DataThespian/ModelActorDatabase.swift b/Sources/DataThespian/ModelActorDatabase.swift index 94e876f..09532ad 100644 --- a/Sources/DataThespian/ModelActorDatabase.swift +++ b/Sources/DataThespian/ModelActorDatabase.swift @@ -33,7 +33,7 @@ public import SwiftData -public actor ModelActorDatabase: Database, Loggable { + public actor ModelActorDatabase: Database, Loggable { public func delete(_: T.Type, withID id: PersistentIdentifier) async -> Bool { guard let model: T = self.modelContext.registeredModel(for: id) else { return false } @@ -88,31 +88,24 @@ public actor ModelActorDatabase: Database, Loggable { try block(modelContext) } } - - public func save () throws { - assert(isMainThread: false) - try self.modelContext.save() - } - - public nonisolated let modelExecutor: any SwiftData.ModelExecutor - - public nonisolated let modelContainer: SwiftData.ModelContainer - - public init(modelContainer: SwiftData.ModelContainer, autosaveEnabled: Bool = false) { - let modelContext = ModelContext(modelContainer) - modelContext.autosaveEnabled = autosaveEnabled - let modelExecutor = DefaultSerialModelExecutor(modelContext: modelContext) - self.init(modelExecutor: modelExecutor, modelContainer: modelContainer) - } - - private init(modelExecutor: any ModelExecutor, modelContainer: ModelContainer) { - self.modelExecutor = modelExecutor - self.modelContainer = modelContainer + public func save() throws { + assert(isMainThread: false) + try self.modelContext.save() + } + public nonisolated let modelExecutor: any SwiftData.ModelExecutor + public nonisolated let modelContainer: SwiftData.ModelContainer + public init(modelContainer: SwiftData.ModelContainer, autosaveEnabled: Bool = false) { + let modelContext = ModelContext(modelContainer) + modelContext.autosaveEnabled = autosaveEnabled + let modelExecutor = DefaultSerialModelExecutor(modelContext: modelContext) + self.init(modelExecutor: modelExecutor, modelContainer: modelContainer) + } + private init(modelExecutor: any ModelExecutor, modelContainer: ModelContainer) { + self.modelExecutor = modelExecutor + self.modelContainer = modelContainer + } } -} - -extension ModelActorDatabase: SwiftData.ModelActor { -} + extension ModelActorDatabase: SwiftData.ModelActor {} #endif