Skip to content

Commit 96d8a34

Browse files
Keypaths for managed object set manipulation
1 parent 621e0b8 commit 96d8a34

6 files changed

Lines changed: 82 additions & 22 deletions

Sources/ProgrammaticCoreData/EntityDescriptionAttribute/EntityDescriptionAttribute+Initialization.swift

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public extension EntityDescriptionAttribute {
2323

2424
// TODO: allow to pass in min/max.
2525
static func relationship<InverseCoreDataType, InverseT>(
26-
_ keyPath: KeyPath<CoreDataEntity, NSSet?>,
26+
_ keyPath: KeyPath<CoreDataEntity, T>,
2727
inverse: KeyPath<InverseCoreDataType, InverseT>,
2828
deleteRule: NSDeleteRule = .noActionDeleteRule
2929
) -> Self
@@ -41,15 +41,15 @@ public extension EntityDescriptionAttribute {
4141

4242
// TODO: allow to pass in min/max.
4343
static func relationship<InverseCoreDataType, InverseT>(
44-
_ keyPath: KeyPath<CoreDataEntity, NSSet>,
44+
_ keyPath: KeyPath<CoreDataEntity, T>,
4545
inverse: KeyPath<InverseCoreDataType, InverseT>,
4646
is type: RelationshipProperties.RelationshipType = .toOne,
4747
deleteRule: NSDeleteRule = .noActionDeleteRule
4848
) -> Self
4949
where
5050
CoreDataEntity: SelfDescribingCoreDataEntity,
5151
InverseCoreDataType: SelfDescribingCoreDataEntity,
52-
T == NSSet
52+
T: NSSet
5353
{
5454
.relationship(keyPath, RelationshipProperties(
5555
inverse: inverse,
@@ -61,14 +61,14 @@ public extension EntityDescriptionAttribute {
6161
static func undefined(_ keyPath: KeyPath<CoreDataEntity, T>, defaultValue: Any? = nil) -> Self {
6262
.undefined(keyPath, AttributeProperties(defaultValue: defaultValue))
6363
}
64-
static func integer16(_ keyPath: KeyPath<CoreDataEntity, T>, defaultValue: Int16? = nil) -> Self {
65-
.integer16(keyPath, AttributeProperties(defaultValue: defaultValue))
64+
static func int16(_ keyPath: KeyPath<CoreDataEntity, T>, defaultValue: Int16? = nil) -> Self {
65+
.int16(keyPath, AttributeProperties(defaultValue: defaultValue))
6666
}
67-
static func integer32(_ keyPath: KeyPath<CoreDataEntity, T>, defaultValue: Int32? = nil) -> Self {
68-
.integer32(keyPath, AttributeProperties(defaultValue: defaultValue))
67+
static func int32(_ keyPath: KeyPath<CoreDataEntity, T>, defaultValue: Int32? = nil) -> Self {
68+
.int32(keyPath, AttributeProperties(defaultValue: defaultValue))
6969
}
70-
static func integer64(_ keyPath: KeyPath<CoreDataEntity, T>, defaultValue: Int64? = nil) -> Self {
71-
.integer64(keyPath, AttributeProperties(defaultValue: defaultValue))
70+
static func int64(_ keyPath: KeyPath<CoreDataEntity, T>, defaultValue: Int64? = nil) -> Self {
71+
.int64(keyPath, AttributeProperties(defaultValue: defaultValue))
7272
}
7373
static func decimal(_ keyPath: KeyPath<CoreDataEntity, T>, defaultValue: Decimal? = nil) -> Self {
7474
.decimal(keyPath, AttributeProperties(defaultValue: defaultValue))

Sources/ProgrammaticCoreData/EntityDescriptionAttribute/EntityDescriptionAttribute.swift

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ public enum EntityDescriptionAttribute<CoreDataEntity, T> {
1111
}
1212

1313
case undefined(KeyPath<CoreDataEntity, T>, AttributeProperties)
14-
case integer16(KeyPath<CoreDataEntity, T>, AttributeProperties)
15-
case integer32(KeyPath<CoreDataEntity, T>, AttributeProperties)
16-
case integer64(KeyPath<CoreDataEntity, T>, AttributeProperties)
14+
case int16(KeyPath<CoreDataEntity, T>, AttributeProperties)
15+
case int32(KeyPath<CoreDataEntity, T>, AttributeProperties)
16+
case int64(KeyPath<CoreDataEntity, T>, AttributeProperties)
1717
case decimal(KeyPath<CoreDataEntity, T>, AttributeProperties)
1818
case double(KeyPath<CoreDataEntity, T>, AttributeProperties)
1919
case float(KeyPath<CoreDataEntity, T>, AttributeProperties)
@@ -36,9 +36,9 @@ public enum EntityDescriptionAttribute<CoreDataEntity, T> {
3636
switch self {
3737
case
3838
.undefined(let keyPath, _),
39-
.integer16(let keyPath, _),
40-
.integer32(let keyPath, _),
41-
.integer64(let keyPath, _),
39+
.int16(let keyPath, _),
40+
.int32(let keyPath, _),
41+
.int64(let keyPath, _),
4242
.decimal(let keyPath, _),
4343
.double(let keyPath, _),
4444
.float(let keyPath, _),
@@ -62,9 +62,9 @@ public enum EntityDescriptionAttribute<CoreDataEntity, T> {
6262
return .relationship(properties)
6363
case
6464
.undefined(_, let properties),
65-
.integer16(_, let properties),
66-
.integer32(_, let properties),
67-
.integer64(_, let properties),
65+
.int16(_, let properties),
66+
.int32(_, let properties),
67+
.int64(_, let properties),
6868
.decimal(_, let properties),
6969
.double(_, let properties),
7070
.float(_, let properties),

Sources/ProgrammaticCoreData/EntityDescriptionAttribute/NSAttributeType+EntityDescriptionAttribute.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@ extension NSAttributeType {
88
switch entityDescriptionAttribute {
99
case .undefined:
1010
self = .undefinedAttributeType
11-
case .integer16:
11+
case .int16:
1212
self = .integer16AttributeType
13-
case .integer32:
13+
case .int32:
1414
self = .integer32AttributeType
15-
case .integer64:
15+
case .int64:
1616
self = .integer64AttributeType
1717
case .decimal:
1818
self = .decimalAttributeType
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// Created by Axel Ancona Esselmann on 3/23/24.
2+
//
3+
4+
import Foundation
5+
import CoreData
6+
7+
public extension NSManagedObject {
8+
enum SetInsertionError: Swift.Error {
9+
case itemAlreadyInSet
10+
case itemNotInSet
11+
}
12+
13+
func add<ManagedObject, SelfType>(
14+
_ value: ManagedObject,
15+
keyPath: KeyPath<SelfType, NSSet>
16+
) throws
17+
where
18+
ManagedObject: NSManagedObject,
19+
SelfType: NSManagedObject
20+
21+
{
22+
let items = try self.mutableSetValue(keyPath)
23+
guard !items.contains(value) else {
24+
throw SetInsertionError.itemAlreadyInSet
25+
}
26+
items.add(value)
27+
}
28+
29+
func remove<ManagedObject, SelfType>(_ value: ManagedObject, keyPath: KeyPath<SelfType, NSSet>) throws
30+
where
31+
ManagedObject: NSManagedObject,
32+
SelfType: NSManagedObject
33+
{
34+
let items = try self.mutableSetValue(keyPath)
35+
guard items.contains(value) else {
36+
throw SetInsertionError.itemNotInSet
37+
}
38+
items.remove(value)
39+
}
40+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Created by Axel Ancona Esselmann on 3/23/24.
2+
//
3+
4+
import Foundation
5+
6+
public extension NSObject {
7+
8+
enum NSObjectExtensionError: Error {
9+
case nilKeypathString
10+
}
11+
12+
func mutableSetValue<SelfType>(_ keyPath: KeyPath<SelfType, NSSet>) throws -> NSMutableSet
13+
where SelfType: NSObject
14+
{
15+
guard let key = keyPath._kvcKeyPathString else {
16+
throw NSObjectExtensionError.nilKeypathString
17+
}
18+
return self.mutableSetValue(forKey: key)
19+
}
20+
}

Sources/ProgrammaticCoreData/SelfDescribingCoreDataEntity.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ public protocol SelfDescribingCoreDataEntity: NSManagedObject {
99

1010
public extension SelfDescribingCoreDataEntity {
1111

12-
static func fetchRequest() throws -> NSFetchRequest<Self> {
12+
static func fetchRequest() -> NSFetchRequest<Self> {
1313
NSFetchRequest<Self>(entityName: "\(Self.self)")
1414
}
1515

0 commit comments

Comments
 (0)