Skip to content

Commit 6822454

Browse files
committed
Major refactor
feature/add-unmanaged-protocol-for-types-that-prefer-a-unique-id-other-than-ObjectID
1 parent a472822 commit 6822454

67 files changed

Lines changed: 7970 additions & 1722 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.benchmarkBaselines/coredata-repository-benchmarks/main/results.json

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

.benchmarkBaselines/coredata-repository-benchmarks/v3/results.json

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

.benchmarkBaselines/coredata-repository-benchmarks/v4/results.json

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

Benchmarks/coredata-repository-benchmarks/coredata-repository-benchmarks.swift

Lines changed: 423 additions & 0 deletions
Large diffs are not rendered by default.

Package.resolved

Lines changed: 78 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Package.swift

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
1-
// swift-tools-version:5.8
1+
// swift-tools-version:5.10
22

33
import PackageDescription
44

55
let package = Package(
66
name: "CoreDataRepository",
77
defaultLocalization: "en",
88
platforms: [
9-
.iOS(.v15),
10-
.macOS(.v12),
11-
.tvOS(.v15),
12-
.watchOS(.v8),
13-
.macCatalyst(.v15),
9+
.iOS(.v16),
10+
.macOS(.v13),
11+
.tvOS(.v16),
12+
.watchOS(.v9),
13+
.macCatalyst(.v16),
14+
.visionOS(.v1),
1415
],
1516
products: [
1617
.library(
@@ -19,6 +20,10 @@ let package = Package(
1920
),
2021
],
2122
dependencies: [
23+
.package(
24+
url: "https://github.com/ordo-one/package-benchmark.git",
25+
from: "1.23.5"
26+
),
2227
.package(
2328
url: "https://github.com/pointfreeco/swift-custom-dump.git",
2429
from: "1.0.0"
@@ -35,6 +40,14 @@ let package = Package(
3540
dependencies: [
3641
"CoreDataRepository",
3742
.product(name: "CustomDump", package: "swift-custom-dump"),
43+
"Internal",
44+
],
45+
swiftSettings: .swiftSix
46+
),
47+
.target(
48+
name: "Internal",
49+
dependencies: [
50+
"CoreDataRepository",
3851
],
3952
swiftSettings: .swiftSix
4053
),
@@ -52,3 +65,19 @@ extension [SwiftSetting] {
5265
.enableExperimentalFeature("StrictConcurrency"),
5366
]
5467
}
68+
69+
// Benchmark of coredata-repository-benchmarks
70+
package.targets += [
71+
.executableTarget(
72+
name: "coredata-repository-benchmarks",
73+
dependencies: [
74+
.product(name: "Benchmark", package: "package-benchmark"),
75+
"CoreDataRepository",
76+
"Internal",
77+
],
78+
path: "Benchmarks/coredata-repository-benchmarks",
79+
plugins: [
80+
.plugin(name: "BenchmarkPlugin", package: "package-benchmark"),
81+
]
82+
),
83+
]

Sources/CoreDataRepository/CoreDataBatchError.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import Foundation
1313
/// Batch operations that do not use `NSBatch*Request` are not atomic. Some operations may succeed while others fail. If
1414
/// multiple errors are returned, it would
1515
/// be helpful if each error is associated with the input data for the operation.
16-
public struct CoreDataBatchError<T>: Error {
16+
public struct CoreDataBatchError<T>: Error where T: Sendable {
1717
/// The input data used for the batched operation. Usually an ``UnmanagedModel`` instance or URL encoded
1818
/// NSManagedObjectID.
1919
public let item: T

Sources/CoreDataRepository/CoreDataError.swift

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,18 @@ import Foundation
1111

1212
/// An error that models all the possible error conditions of CoreDataRepository.
1313
///
14-
/// CoreDataError also conforms to CustomNSError so that it cleanly casts to NSError
14+
/// ``CoreDataError`` also conforms to `CustomNSError` so that it cleanly casts to `NSError`
1515
public enum CoreDataError: Error, Hashable, Sendable {
1616
/// UnmanagedModels store the ``CoreData.NSManagedObjectID`` of their respective RepositoryManagedModels as a URL.
1717
/// This URL
1818
/// must be mapped back into a ``NSManagedObjectID`` for most transactions. If it fails, this error is returned.
1919
case failedToGetObjectIdFromUrl(URL)
2020

21-
/// For some aggregate functions, a NSAttributeDescription is required so that a NSFetchRequest can be constructed
21+
/// For some aggregate functions, a `NSAttributeDescription` is required so that a `NSFetchRequest` can be
22+
/// constructed
2223
/// against the correct property.
23-
/// If the NSAttributeDescription is not for the correct or expected NSEntityDescription, this error is returned.
24+
/// If the `NSAttributeDescription` is not for the correct or expected `NSEntityDescription`, this error is
25+
/// returned.
2426
case propertyDoesNotMatchEntity
2527

2628
/// CoreData may return a value of a related type to what is actually needed. If casting the value CoreData returns
@@ -31,23 +33,31 @@ public enum CoreDataError: Error, Hashable, Sendable {
3133
/// is returned.
3234
case fetchedObjectIsFlaggedAsDeleted
3335

34-
/// If CoreData throws a CocoaError, it is embedded here.
36+
/// If CoreData throws a `CocoaError`, it is embedded here.
3537
case cocoa(CocoaError)
3638

37-
/// If the type of an error is unknown, it is cast to NSError and embedded here.
39+
/// If the type of an error is unknown, it is cast to `NSError` and embedded here.
3840
case unknown(NSError)
3941

40-
/// If a NSEntityDescription is malformed by not having a name, this error is returned.
42+
/// If a `NSEntityDescription` is malformed by not having a name, this error is returned.
4143
case noEntityNameFound
4244

43-
/// The count aggregate function requires at least one NSAttributeDescription on the NSEntityDescription. If there
45+
/// The count aggregate function requires at least one `NSAttributeDescription` on the `NSEntityDescription`. If
46+
/// there
4447
/// is none, this error is returned.
4548
case atLeastOneAttributeDescRequired
4649

47-
/// If an UnmanagedModel is used in a transaction where it is expected to already be persisted but has no URL
50+
/// If a ``ManagedIdUrlReferencable`` value is used in a transaction where it is expected to already be persisted
51+
/// but has no `URL`
4852
/// representing the ``NSManagedObjectID``, this error is returned.
4953
case noUrlOnItemToMapToObjectId
5054

55+
/// If a ``ManagedIdReferencable`` value is used in a transaction where it is expected to already be persisted but
56+
/// has no `NSManagedObjectID`, this error is returned.
57+
case noObjectIdOnItem
58+
59+
case noMatchFoundWhenReadingItem
60+
5161
public var localizedDescription: String {
5262
switch self {
5363
case .failedToGetObjectIdFromUrl:
@@ -96,10 +106,23 @@ public enum CoreDataError: Error, Hashable, Sendable {
96106
)
97107
case .noUrlOnItemToMapToObjectId:
98108
return NSLocalizedString(
99-
"No object ID URL found on the unmanaged model for an operation against an existing managed object.",
109+
"No object ID URL found on the model for an operation against an existing managed object.",
110+
bundle: .module,
111+
comment: "Error for performing an operation against an existing NSManagedObject but the "
112+
+ "ManagedIdUrlReferencable instance has no managedIdUrl for looking up the NSManagedOjbectID."
113+
)
114+
case .noObjectIdOnItem:
115+
return NSLocalizedString(
116+
"No object ID found on the model for an operation against an existing managed object.",
100117
bundle: .module,
101-
comment: "Error for performing an operation against an existing NSManagedObject but the UnmanagedModel "
102-
+ "instance has no ManagedRepoUrl for looking up the NSManagedOjbectID."
118+
comment: "Error for performing an operation against an existing NSManagedObject but the "
119+
+ "ManagedIdReferencable instance has no managedId."
120+
)
121+
case .noMatchFoundWhenReadingItem:
122+
return NSLocalizedString(
123+
"No match found when attempting to read an instance from CoreData.",
124+
bundle: .module,
125+
comment: "Error for reading an instance from CoreData but no instance was found."
103126
)
104127
}
105128
}
@@ -129,6 +152,10 @@ extension CoreDataError: CustomNSError {
129152
return 8
130153
case .noUrlOnItemToMapToObjectId:
131154
return 9
155+
case .noObjectIdOnItem:
156+
return 10
157+
case .noMatchFoundWhenReadingItem:
158+
return 11
132159
}
133160
}
134161

@@ -155,6 +182,10 @@ extension CoreDataError: CustomNSError {
155182
return [:]
156183
case .noUrlOnItemToMapToObjectId:
157184
return [:]
185+
case .noObjectIdOnItem:
186+
return [:]
187+
case .noMatchFoundWhenReadingItem:
188+
return [:]
158189
}
159190
}
160191
}

0 commit comments

Comments
 (0)