Skip to content

Commit 7a37be3

Browse files
authored
Merge pull request #25 from roanutil/feature/add-method-for-custom-operations-in-context
Add method for custom operations in context
2 parents 33fa804 + a92d69d commit 7a37be3

4 files changed

Lines changed: 34 additions & 17 deletions

File tree

Sources/CoreDataRepository/CoreDataRepository+CRUD.swift

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ extension CoreDataRepository {
9999
let readContext = context.childContext()
100100
return AsyncStream { continuation in
101101
let provider: ReadSubscription<Model>
102-
switch Self.getObjectId(fromUrl: url, context: readContext) {
102+
switch readContext.objectId(from: url) {
103103
case let .success(objectId):
104104
provider = ReadSubscription<Model>(
105105
objectId: objectId,
@@ -126,7 +126,7 @@ extension CoreDataRepository {
126126
let readContext = context.childContext()
127127
return AsyncThrowingStream { continuation in
128128
let provider: ReadThrowingSubscription<Model>
129-
switch Self.getObjectId(fromUrl: url, context: readContext) {
129+
switch readContext.objectId(from: url) {
130130
case let .success(objectId):
131131
provider = ReadThrowingSubscription<Model>(
132132
objectId: objectId,
@@ -145,14 +145,4 @@ extension CoreDataRepository {
145145
}
146146
}
147147
}
148-
149-
private static func getObjectId(
150-
fromUrl url: URL,
151-
context: NSManagedObjectContext
152-
) -> Result<NSManagedObjectID, CoreDataError> {
153-
guard let objectId = context.persistentStoreCoordinator?.managedObjectID(forURIRepresentation: url) else {
154-
return Result.failure(.failedToGetObjectIdFromUrl(url))
155-
}
156-
return .success(objectId)
157-
}
158148
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// CoreDataRepository+Custom.swift
2+
// CoreDataRepository
3+
//
4+
//
5+
// MIT License
6+
//
7+
// Copyright © 2024 Andrew Roan
8+
9+
import CoreData
10+
import Foundation
11+
12+
extension CoreDataRepository {
13+
/// Escape hatch method for performing arbitrary operations inside a 'scratchpad' `NSManagedObjectContext` where
14+
/// changes will be discarded if not saved.
15+
///
16+
/// The caller is responsible for saving the contexts and cleaning up if needed.
17+
/// All this method provides is the contexts and mapping `Error` into ``CoreDataError``.
18+
public func custom<T>(
19+
schedule: NSManagedObjectContext.ScheduledTaskType = .enqueued,
20+
block: @escaping (
21+
_ parentContext: NSManagedObjectContext,
22+
_ scratchPadContext: NSManagedObjectContext
23+
) throws -> T
24+
) async -> Result<T, CoreDataError> {
25+
await context.performInScratchPad(schedule: schedule) { [context] scratchPad in try block(context, scratchPad) }
26+
}
27+
}

Sources/CoreDataRepository/Internal/NSManagedObject+CRUDHelpers.swift renamed to Sources/CoreDataRepository/NSManagedObject+Helpers.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// NSManagedObject+CRUDHelpers.swift
1+
// NSManagedObject+Helpers.swift
22
// CoreDataRepository
33
//
44
//
@@ -11,7 +11,7 @@ import Foundation
1111

1212
extension NSManagedObject {
1313
/// Helper function to handle casting ``NSManagedObject`` to a sub-class.
14-
func asManagedModel<T>() throws -> T where T: NSManagedObject {
14+
public func asManagedModel<T>() throws -> T where T: NSManagedObject {
1515
guard let repoManaged = self as? T else {
1616
throw CoreDataError.fetchedObjectFailedToCastToExpectedType
1717
}

Sources/CoreDataRepository/Internal/NSManagedObjectContext+CRUDHelpers.swift renamed to Sources/CoreDataRepository/NSManagedObjectContext+Helpers.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// NSManagedObjectContext+CRUDHelpers.swift
1+
// NSManagedObjectContext+Helpers.swift
22
// CoreDataRepository
33
//
44
//
@@ -11,15 +11,15 @@ import Foundation
1111

1212
extension NSManagedObjectContext {
1313
/// Helper function for getting the ``NSManagedObjectID`` from an ``URL``
14-
func objectId(from url: URL) -> Result<NSManagedObjectID, CoreDataError> {
14+
public func objectId(from url: URL) -> Result<NSManagedObjectID, CoreDataError> {
1515
guard let objectId = persistentStoreCoordinator?.managedObjectID(forURIRepresentation: url) else {
1616
return .failure(CoreDataError.failedToGetObjectIdFromUrl(url))
1717
}
1818
return .success(objectId)
1919
}
2020

2121
/// Helper function for checking that a managed object is not deleted in the store
22-
func notDeletedObject(for id: NSManagedObjectID) throws -> NSManagedObject {
22+
public func notDeletedObject(for id: NSManagedObjectID) throws -> NSManagedObject {
2323
let object: NSManagedObject = try existingObject(with: id)
2424
guard !object.isDeleted else {
2525
throw CoreDataError.fetchedObjectIsFlaggedAsDeleted

0 commit comments

Comments
 (0)