Deprecation of legacy ValueContainer and RelationshipContainer properties in favor of @Field propertyWrapper counterpart

This commit is contained in:
John Estropia
2024-01-28 22:11:21 +09:00
parent 4b6d9a54e7
commit 7c2129e38f
38 changed files with 936 additions and 2861 deletions

View File

@@ -70,180 +70,6 @@ public protocol CoreStoreObjectKeyValueObservation: AnyObject {
} }
// MARK: - ValueContainer.Required
extension ValueContainer.Required {
/**
Observes changes in the receiver value. When the returned `CoreStoreObjectKeyValueObservation` is deinited or invalidated, it will stop observing.
- parameter options: The flags indicating which values to include in the change dictionary.
- parameter: changeHandler: The closure called when the value is updated.
*/
public func observe(options: NSKeyValueObservingOptions = [], changeHandler: @escaping (O, CoreStoreObjectValueDiff<V>) -> Void) -> CoreStoreObjectKeyValueObservation {
return self.observe(with: options, changeHandler: changeHandler)
}
}
// MARK: - ValueContainer.Optional
extension ValueContainer.Optional {
/**
Observes changes in the receiver value. When the returned `CoreStoreObjectKeyValueObservation` is deinited or invalidated, it will stop observing.
- parameter options: The flags indicating which values to include in the change dictionary.
- parameter: changeHandler: The closure called when the value is updated.
*/
public func observe(options: NSKeyValueObservingOptions = [], changeHandler: @escaping (O, CoreStoreObjectValueDiff<V>) -> Void) -> CoreStoreObjectKeyValueObservation {
return self.observe(with: options, changeHandler: changeHandler)
}
}
// MARK: - TransformableContainer.Required
extension TransformableContainer.Required {
/**
Observes changes in the receiver value. When the returned `CoreStoreObjectKeyValueObservation` is deinited or invalidated, it will stop observing.
- parameter options: The flags indicating which values to include in the change dictionary.
- parameter: changeHandler: The closure called when the value is updated.
*/
public func observe(options: NSKeyValueObservingOptions = [], changeHandler: @escaping (O, CoreStoreObjectTransformableDiff<V>) -> Void) -> CoreStoreObjectKeyValueObservation {
return self.observe(with: options, changeHandler: changeHandler)
}
}
// MARK: - TransformableContainer.Optional
extension TransformableContainer.Optional {
/**
Observes changes in the receiver value. When the returned `CoreStoreObjectKeyValueObservation` is deinited or invalidated, it will stop observing.
- parameter options: The flags indicating which values to include in the change dictionary.
- parameter: changeHandler: The closure called when the value is updated.
*/
public func observe(options: NSKeyValueObservingOptions = [], changeHandler: @escaping (O, CoreStoreObjectTransformableDiff<V>) -> Void) -> CoreStoreObjectKeyValueObservation {
return self.observe(with: options, changeHandler: changeHandler)
}
}
// MARK: - RelationshipContainer.ToOne
extension RelationshipContainer.ToOne {
/**
Observes changes in the receiver value. When the returned `CoreStoreObjectKeyValueObservation` is deinited or invalidated, it will stop observing.
- parameter options: The flags indicating which values to include in the change dictionary.
- parameter: changeHandler: The closure called when the value is updated.
*/
public func observe(options: NSKeyValueObservingOptions = [], changeHandler: @escaping (O, CoreStoreObjectObjectDiff<D>) -> Void) -> CoreStoreObjectKeyValueObservation {
let result = _CoreStoreObjectKeyValueObservation(
object: self.rawObject!,
keyPath: self.keyPath,
callback: { (object, kind, newValue, oldValue, _, isPrior) in
let notification = CoreStoreObjectObjectDiff<D>(
kind: kind,
newNativeValue: newValue as! CoreStoreManagedObject?,
oldNativeValue: oldValue as! CoreStoreManagedObject?,
isPrior: isPrior
)
changeHandler(
O.cs_fromRaw(object: object),
notification
)
}
)
result.start(options)
return result
}
}
// MARK: - RelationshipContainer.ToManyUnordered
extension RelationshipContainer.ToManyUnordered {
/**
Observes changes in the receiver value. When the returned `CoreStoreObjectKeyValueObservation` is deinited or invalidated, it will stop observing.
- parameter options: The flags indicating which values to include in the change dictionary.
- parameter: changeHandler: The closure called when the value is updated.
*/
public func observe(options: NSKeyValueObservingOptions = [], changeHandler: @escaping (O, CoreStoreObjectUnorderedDiff<D>) -> Void) -> CoreStoreObjectKeyValueObservation {
let result = _CoreStoreObjectKeyValueObservation(
object: self.rawObject!,
keyPath: self.keyPath,
callback: { (object, kind, newValue, oldValue, _, isPrior) in
let notification = CoreStoreObjectUnorderedDiff<D>(
kind: kind,
newNativeValue: newValue as! NSOrderedSet?,
oldNativeValue: oldValue as! NSOrderedSet?,
isPrior: isPrior
)
changeHandler(
O.cs_fromRaw(object: object),
notification
)
}
)
result.start(options)
return result
}
}
// MARK: - RelationshipContainer.ToManyOrdered
extension RelationshipContainer.ToManyOrdered {
/**
Observes changes in the receiver value. When the returned `CoreStoreObjectKeyValueObservation` is deinited or invalidated, it will stop observing.
- parameter options: The flags indicating which values to include in the change dictionary.
- parameter: changeHandler: The closure called when the value is updated.
*/
public func observe(options: NSKeyValueObservingOptions = [], changeHandler: @escaping (O, CoreStoreObjectOrderedDiff<D>) -> Void) -> CoreStoreObjectKeyValueObservation {
let result = _CoreStoreObjectKeyValueObservation(
object: self.rawObject!,
keyPath: self.keyPath,
callback: { (object, kind, newValue, oldValue, indexes, isPrior) in
let notification = CoreStoreObjectOrderedDiff<D>(
kind: kind,
newNativeValue: newValue as! NSArray?,
oldNativeValue: oldValue as! NSArray?,
indexes: indexes ?? IndexSet(),
isPrior: isPrior
)
changeHandler(
O.cs_fromRaw(object: object),
notification
)
}
)
result.start(options)
return result
}
}
// MARK: - CoreStoreObjectValueDiff // MARK: - CoreStoreObjectValueDiff
/** /**
@@ -616,3 +442,138 @@ fileprivate final class _CoreStoreObjectKeyValueObservation: NSObject, CoreStore
) )
} }
} }
// MARK: - Deprecated
@available(*, deprecated, message: """
Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
""")
extension ValueContainer.Required {
public func observe(options: NSKeyValueObservingOptions = [], changeHandler: @escaping (O, CoreStoreObjectValueDiff<V>) -> Void) -> CoreStoreObjectKeyValueObservation {
return self.observe(with: options, changeHandler: changeHandler)
}
}
@available(*, deprecated, message: """
Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
""")
extension ValueContainer.Optional {
public func observe(options: NSKeyValueObservingOptions = [], changeHandler: @escaping (O, CoreStoreObjectValueDiff<V>) -> Void) -> CoreStoreObjectKeyValueObservation {
return self.observe(with: options, changeHandler: changeHandler)
}
}
@available(*, deprecated, message: """
Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
""")
extension TransformableContainer.Required {
public func observe(options: NSKeyValueObservingOptions = [], changeHandler: @escaping (O, CoreStoreObjectTransformableDiff<V>) -> Void) -> CoreStoreObjectKeyValueObservation {
return self.observe(with: options, changeHandler: changeHandler)
}
}
@available(*, deprecated, message: """
Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
""")
extension TransformableContainer.Optional {
public func observe(options: NSKeyValueObservingOptions = [], changeHandler: @escaping (O, CoreStoreObjectTransformableDiff<V>) -> Void) -> CoreStoreObjectKeyValueObservation {
return self.observe(with: options, changeHandler: changeHandler)
}
}
@available(*, deprecated, message: """
Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
""")
extension RelationshipContainer.ToOne {
public func observe(options: NSKeyValueObservingOptions = [], changeHandler: @escaping (O, CoreStoreObjectObjectDiff<D>) -> Void) -> CoreStoreObjectKeyValueObservation {
let result = _CoreStoreObjectKeyValueObservation(
object: self.rawObject!,
keyPath: self.keyPath,
callback: { (object, kind, newValue, oldValue, _, isPrior) in
let notification = CoreStoreObjectObjectDiff<D>(
kind: kind,
newNativeValue: newValue as! CoreStoreManagedObject?,
oldNativeValue: oldValue as! CoreStoreManagedObject?,
isPrior: isPrior
)
changeHandler(
O.cs_fromRaw(object: object),
notification
)
}
)
result.start(options)
return result
}
}
@available(*, deprecated, message: """
Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
""")
extension RelationshipContainer.ToManyUnordered {
public func observe(options: NSKeyValueObservingOptions = [], changeHandler: @escaping (O, CoreStoreObjectUnorderedDiff<D>) -> Void) -> CoreStoreObjectKeyValueObservation {
let result = _CoreStoreObjectKeyValueObservation(
object: self.rawObject!,
keyPath: self.keyPath,
callback: { (object, kind, newValue, oldValue, _, isPrior) in
let notification = CoreStoreObjectUnorderedDiff<D>(
kind: kind,
newNativeValue: newValue as! NSOrderedSet?,
oldNativeValue: oldValue as! NSOrderedSet?,
isPrior: isPrior
)
changeHandler(
O.cs_fromRaw(object: object),
notification
)
}
)
result.start(options)
return result
}
}
@available(*, deprecated, message: """
Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
""")
extension RelationshipContainer.ToManyOrdered {
public func observe(options: NSKeyValueObservingOptions = [], changeHandler: @escaping (O, CoreStoreObjectOrderedDiff<D>) -> Void) -> CoreStoreObjectKeyValueObservation {
let result = _CoreStoreObjectKeyValueObservation(
object: self.rawObject!,
keyPath: self.keyPath,
callback: { (object, kind, newValue, oldValue, indexes, isPrior) in
let notification = CoreStoreObjectOrderedDiff<D>(
kind: kind,
newNativeValue: newValue as! NSArray?,
oldNativeValue: oldValue as! NSArray?,
indexes: indexes ?? IndexSet(),
isPrior: isPrior
)
changeHandler(
O.cs_fromRaw(object: object),
notification
)
}
)
result.start(options)
return result
}
}

View File

@@ -108,121 +108,64 @@ extension FieldContainer.Stored {
} }
} }
// MARK: - ValueContainer.Required // MARK: - Deprecated
@available(*, deprecated, message: """
Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
""")
extension ValueContainer.Required { extension ValueContainer.Required {
/**
Creates a `Where` clause by comparing if a property is equal to a value
```
let person = dataStack.fetchOne(From<Person>().where({ $0.nickname == "John" }))
```
*/
public static func == (_ attribute: ValueContainer<O>.Required<V>, _ value: V) -> Where<O> { public static func == (_ attribute: ValueContainer<O>.Required<V>, _ value: V) -> Where<O> {
return Where(attribute.keyPath, isEqualTo: value) return Where(attribute.keyPath, isEqualTo: value)
} }
/**
Creates a `Where` clause by comparing if a property is not equal to a value
```
let person = dataStack.fetchOne(From<Person>().where({ $0.nickname != "John" }))
```
*/
public static func != (_ attribute: ValueContainer<O>.Required<V>, _ value: V) -> Where<O> { public static func != (_ attribute: ValueContainer<O>.Required<V>, _ value: V) -> Where<O> {
return !Where(attribute.keyPath, isEqualTo: value) return !Where(attribute.keyPath, isEqualTo: value)
} }
/**
Creates a `Where` clause by comparing if a property is less than a value
```
let person = dataStack.fetchOne(From<Person>().where({ $0.age < 20 }))
```
*/
public static func < (_ attribute: ValueContainer<O>.Required<V>, _ value: V) -> Where<O> { public static func < (_ attribute: ValueContainer<O>.Required<V>, _ value: V) -> Where<O> {
return Where("%K < %@", attribute.keyPath, value.cs_toQueryableNativeType()) return Where("%K < %@", attribute.keyPath, value.cs_toQueryableNativeType())
} }
/**
Creates a `Where` clause by comparing if a property is greater than a value
```
let person = dataStack.fetchOne(From<Person>().where({ $0.age > 20 }))
```
*/
public static func > (_ attribute: ValueContainer<O>.Required<V>, _ value: V) -> Where<O> { public static func > (_ attribute: ValueContainer<O>.Required<V>, _ value: V) -> Where<O> {
return Where("%K > %@", attribute.keyPath, value.cs_toQueryableNativeType()) return Where("%K > %@", attribute.keyPath, value.cs_toQueryableNativeType())
} }
/**
Creates a `Where` clause by comparing if a property is less than or equal to a value
```
let person = dataStack.fetchOne(From<Person>().where({ $0.age <= 20 }))
```
*/
public static func <= (_ attribute: ValueContainer<O>.Required<V>, _ value: V) -> Where<O> { public static func <= (_ attribute: ValueContainer<O>.Required<V>, _ value: V) -> Where<O> {
return Where("%K <= %@", attribute.keyPath, value.cs_toQueryableNativeType()) return Where("%K <= %@", attribute.keyPath, value.cs_toQueryableNativeType())
} }
/**
Creates a `Where` clause by comparing if a property is greater than or equal to a value
```
let person = dataStack.fetchOne(From<Person>().where({ $0.age >= 20 }))
```
*/
public static func >= (_ attribute: ValueContainer<O>.Required<V>, _ value: V) -> Where<O> { public static func >= (_ attribute: ValueContainer<O>.Required<V>, _ value: V) -> Where<O> {
return Where("%K >= %@", attribute.keyPath, value.cs_toQueryableNativeType()) return Where("%K >= %@", attribute.keyPath, value.cs_toQueryableNativeType())
} }
/**
Creates a `Where` clause by checking if a sequence contains the value of a property
```
let dog = dataStack.fetchOne(From<Dog>().where({ ["Pluto", "Snoopy", "Scooby"] ~= $0.nickname }))
```
*/
public static func ~= <S: Sequence>(_ sequence: S, _ attribute: ValueContainer<O>.Required<V>) -> Where<O> where S.Iterator.Element == V { public static func ~= <S: Sequence>(_ sequence: S, _ attribute: ValueContainer<O>.Required<V>) -> Where<O> where S.Iterator.Element == V {
return Where(attribute.keyPath, isMemberOf: sequence) return Where(attribute.keyPath, isMemberOf: sequence)
} }
} }
@available(*, deprecated, message: """
// MARK: - ValueContainer.Optional Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
""")
extension ValueContainer.Optional { extension ValueContainer.Optional {
/**
Creates a `Where` clause by comparing if a property is equal to a value
```
let person = dataStack.fetchOne(From<Person>().where({ $0.nickname == "John" }))
```
*/
public static func == (_ attribute: ValueContainer<O>.Optional<V>, _ value: V?) -> Where<O> { public static func == (_ attribute: ValueContainer<O>.Optional<V>, _ value: V?) -> Where<O> {
return Where(attribute.keyPath, isEqualTo: value) return Where(attribute.keyPath, isEqualTo: value)
} }
/**
Creates a `Where` clause by comparing if a property is not equal to a value
```
let person = dataStack.fetchOne(From<Person>().where({ $0.nickname != "John" }))
```
*/
public static func != (_ attribute: ValueContainer<O>.Optional<V>, _ value: V?) -> Where<O> { public static func != (_ attribute: ValueContainer<O>.Optional<V>, _ value: V?) -> Where<O> {
return !Where(attribute.keyPath, isEqualTo: value) return !Where(attribute.keyPath, isEqualTo: value)
} }
/**
Creates a `Where` clause by comparing if a property is less than a value
```
let person = dataStack.fetchOne(From<Person>().where({ $0.age < 20 }))
```
*/
public static func < (_ attribute: ValueContainer<O>.Optional<V>, _ value: V?) -> Where<O> { public static func < (_ attribute: ValueContainer<O>.Optional<V>, _ value: V?) -> Where<O> {
if let value = value { if let value = value {
@@ -235,12 +178,6 @@ extension ValueContainer.Optional {
} }
} }
/**
Creates a `Where` clause by comparing if a property is greater than a value
```
let person = dataStack.fetchOne(From<Person>().where({ $0.age > 20 }))
```
*/
public static func > (_ attribute: ValueContainer<O>.Optional<V>, _ value: V?) -> Where<O> { public static func > (_ attribute: ValueContainer<O>.Optional<V>, _ value: V?) -> Where<O> {
if let value = value { if let value = value {
@@ -253,12 +190,6 @@ extension ValueContainer.Optional {
} }
} }
/**
Creates a `Where` clause by comparing if a property is less than or equal to a value
```
let person = dataStack.fetchOne(From<Person>().where({ $0.age <= 20 }))
```
*/
public static func <= (_ attribute: ValueContainer<O>.Optional<V>, _ value: V?) -> Where<O> { public static func <= (_ attribute: ValueContainer<O>.Optional<V>, _ value: V?) -> Where<O> {
if let value = value { if let value = value {
@@ -271,12 +202,6 @@ extension ValueContainer.Optional {
} }
} }
/**
Creates a `Where` clause by comparing if a property is greater than or equal to a value
```
let person = dataStack.fetchOne(From<Person>().where({ $0.age >= 20 }))
```
*/
public static func >= (_ attribute: ValueContainer<O>.Optional<V>, _ value: V?) -> Where<O> { public static func >= (_ attribute: ValueContainer<O>.Optional<V>, _ value: V?) -> Where<O> {
if let value = value { if let value = value {
@@ -289,51 +214,27 @@ extension ValueContainer.Optional {
} }
} }
/**
Creates a `Where` clause by checking if a sequence contains the value of a property
```
let dog = dataStack.fetchOne(From<Dog>().where({ ["Pluto", "Snoopy", "Scooby"] ~= $0.nickname }))
```
*/
public static func ~= <S: Sequence>(_ sequence: S, _ attribute: ValueContainer<O>.Optional<V>) -> Where<O> where S.Iterator.Element == V { public static func ~= <S: Sequence>(_ sequence: S, _ attribute: ValueContainer<O>.Optional<V>) -> Where<O> where S.Iterator.Element == V {
return Where(attribute.keyPath, isMemberOf: sequence) return Where(attribute.keyPath, isMemberOf: sequence)
} }
} }
@available(*, deprecated, message: """
// MARK: - RelationshipContainer.ToOne Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
""")
extension RelationshipContainer.ToOne { extension RelationshipContainer.ToOne {
/**
Creates a `Where` clause by comparing if a property is equal to a value
```
let dog = dataStack.fetchOne(From<Dog>().where({ $0.master == me }))
```
*/
public static func == (_ relationship: RelationshipContainer<O>.ToOne<D>, _ object: D?) -> Where<O> { public static func == (_ relationship: RelationshipContainer<O>.ToOne<D>, _ object: D?) -> Where<O> {
return Where(relationship.keyPath, isEqualTo: object) return Where(relationship.keyPath, isEqualTo: object)
} }
/**
Creates a `Where` clause by comparing if a property is not equal to a value
```
let dog = dataStack.fetchOne(From<Dog>().where({ $0.master != me }))
```
*/
public static func != (_ relationship: RelationshipContainer<O>.ToOne<D>, _ object: D?) -> Where<O> { public static func != (_ relationship: RelationshipContainer<O>.ToOne<D>, _ object: D?) -> Where<O> {
return !Where(relationship.keyPath, isEqualTo: object) return !Where(relationship.keyPath, isEqualTo: object)
} }
/**
Creates a `Where` clause by checking if a sequence contains the value of a property
```
let dog = dataStack.fetchOne(From<Dog>().where({ [john, joe, bob] ~= $0.master }))
```
*/
public static func ~= <S: Sequence>(_ sequence: S, _ relationship: RelationshipContainer<O>.ToOne<D>) -> Where<O> where S.Iterator.Element == D { public static func ~= <S: Sequence>(_ sequence: S, _ relationship: RelationshipContainer<O>.ToOne<D>) -> Where<O> where S.Iterator.Element == D {
return Where(relationship.keyPath, isMemberOf: sequence) return Where(relationship.keyPath, isMemberOf: sequence)

View File

@@ -636,13 +636,6 @@ public final class CoreStoreSchema: DynamicSchema {
} }
let managedObjectClass: AnyClass = className.withCString { let managedObjectClass: AnyClass = className.withCString {
// Xcode 10.1+ users: You may find this comment due to a crash while debugging on an iPhone XR device (or any A12 device).
// This is a known issue that should not occur in archived builds, as the AppStore strips away arm64e build architectures from the binary. So while it crashes on DEBUG, it shouldn't be an issue for live users.
// In the meantime, please submit a bug report to Apple and refer to similar discussions here:
// - https://github.com/realm/realm-cocoa/issues/6013
// - https://github.com/wordpress-mobile/WordPress-iOS/pull/10400
// - https://github.com/JohnEstropia/CoreStore/issues/291
// If you wish to debug with A12 devices, please use Xcode 10.0 for now.
return objc_allocateClassPair(superClass, $0, 0)! return objc_allocateClassPair(superClass, $0, 0)!
} }
defer { defer {

View File

@@ -189,51 +189,6 @@ extension DataStack {
} }
) )
} }
// MARK: Deprecated
@available(*, deprecated, renamed: "publishObject(_:)")
public func objectPublisher<O: DynamicObject>(_ object: O) -> ObjectPublisher<O> {
return self.publishObject(object)
}
@available(*, deprecated, renamed: "publishList(_:_:)")
public func listPublisher<O>(_ from: From<O>, _ fetchClauses: FetchClause...) -> ListPublisher<O> {
return self.publishList(from, fetchClauses)
}
@available(*, deprecated, renamed: "publishList(_:_:)")
public func listPublisher<O>(_ from: From<O>, _ fetchClauses: [FetchClause]) -> ListPublisher<O> {
return self.publishList(from, fetchClauses)
}
@available(*, deprecated, renamed: "publishList(_:)")
public func listPublisher<B: FetchChainableBuilderType>(_ clauseChain: B) -> ListPublisher<B.ObjectType> {
return self.publishList(clauseChain)
}
@available(*, deprecated, renamed: "publishList(_:_:_:)")
public func listPublisher<O>(_ from: From<O>, _ sectionBy: SectionBy<O>, _ fetchClauses: FetchClause...) -> ListPublisher<O> {
return self.publishList(from, sectionBy, fetchClauses)
}
@available(*, deprecated, renamed: "publishList(_:_:_:)")
public func listPublisher<O>(_ from: From<O>, _ sectionBy: SectionBy<O>, _ fetchClauses: [FetchClause]) -> ListPublisher<O> {
return self.publishList(from, sectionBy, fetchClauses)
}
@available(*, deprecated, renamed: "publishList(_:)")
public func listPublisher<B: SectionMonitorBuilderType>(_ clauseChain: B) -> ListPublisher<B.ObjectType> {
return self.publishList(clauseChain)
}
} }
#endif #endif

View File

@@ -182,12 +182,6 @@ extension DataStack {
private let storage: Storage private let storage: Storage
private var subscriber: S? private var subscriber: S?
} }
// MARK: Deprecated
@available(*, deprecated, renamed: "MigrationProgress")
public typealias MigrationProgress = CoreStore.MigrationProgress<Storage>
} }
} }

View File

@@ -237,13 +237,4 @@ extension DiffableDataSource {
} }
// MARK: Deprecated
extension DiffableDataSource {
@available(*, deprecated, renamed: "CollectionViewAdapter")
public typealias CollectionView = CollectionViewAdapter
}
#endif #endif

View File

@@ -240,13 +240,4 @@ extension DiffableDataSource {
} }
} }
// MARK: Deprecated
extension DiffableDataSource {
@available(*, deprecated, renamed: "CollectionViewAdapter")
public typealias CollectionView = CollectionViewAdapter
}
#endif #endif

View File

@@ -299,13 +299,4 @@ extension DiffableDataSource {
} }
} }
// MARK: Deprecated
extension DiffableDataSource {
@available(*, deprecated, renamed: "TableViewAdapter")
public typealias TableView = TableViewAdapter
}
#endif #endif

View File

@@ -47,12 +47,6 @@ public struct FetchChainBuilder<O: DynamicObject>: FetchChainableBuilderType {
public var from: From<O> public var from: From<O>
public var fetchClauses: [FetchClause] = [] public var fetchClauses: [FetchClause] = []
// MARK: Deprecated
@available(*, deprecated, renamed: "O")
public typealias D = O
} }

View File

@@ -276,21 +276,6 @@ extension From {
return .init(from: self, fetchClauses: Array(clauses)) return .init(from: self, fetchClauses: Array(clauses))
} }
// MARK: Deprecated
@available(*, deprecated, renamed: "sectionBy(_:sectionIndexTransformer:)")
public func sectionBy(
_ sectionKeyPath: KeyPathString,
_ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?
) -> SectionMonitorChainBuilder<O> {
return self.sectionBy(
sectionKeyPath,
sectionIndexTransformer: sectionIndexTransformer
)
}
} }
@@ -341,21 +326,6 @@ extension From where O: NSManagedObject {
sectionIndexTransformer: sectionIndexTransformer sectionIndexTransformer: sectionIndexTransformer
) )
} }
// MARK: Deprecated
@available(*, deprecated, renamed: "sectionBy(_:sectionIndexTransformer:)")
public func sectionBy<T>(
_ sectionKeyPath: KeyPath<O, T>,
_ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?
) -> SectionMonitorChainBuilder<O> {
return self.sectionBy(
sectionKeyPath._kvcKeyPathString!,
sectionIndexTransformer: sectionIndexTransformer
)
}
} }
@@ -374,50 +344,6 @@ extension From where O: CoreStoreObject {
return self.fetchChain(appending: clause(O.meta)) return self.fetchChain(appending: clause(O.meta))
} }
/**
Creates a `QueryChainBuilder` that starts with a `Select` clause created from the specified key path
- parameter keyPath: the keyPath to query the value for
- returns: a `QueryChainBuilder` that starts with a `Select` clause created from the specified key path
*/
public func select<R>(_ keyPath: KeyPath<O, ValueContainer<O>.Required<R>>) -> QueryChainBuilder<O, R> {
return self.select(R.self, [SelectTerm<O>.attribute(keyPath)])
}
/**
Creates a `QueryChainBuilder` that starts with a `Select` clause created from the specified key path
- parameter keyPath: the keyPath to query the value for
- returns: a `QueryChainBuilder` that starts with a `Select` clause created from the specified key path
*/
public func select<R>(_ keyPath: KeyPath<O, ValueContainer<O>.Optional<R>>) -> QueryChainBuilder<O, R> {
return self.select(R.self, [SelectTerm<O>.attribute(keyPath)])
}
/**
Creates a `QueryChainBuilder` that starts with a `Select` clause created from the specified key path
- parameter keyPath: the keyPath to query the value for
- returns: a `QueryChainBuilder` that starts with a `Select` clause created from the specified key path
*/
public func select<R>(_ keyPath: KeyPath<O, TransformableContainer<O>.Required<R>>) -> QueryChainBuilder<O, R> {
return self.select(R.self, [SelectTerm<O>.attribute(keyPath)])
}
/**
Creates a `QueryChainBuilder` that starts with a `Select` clause created from the specified key path
- parameter keyPath: the keyPath to query the value for
- returns: a `QueryChainBuilder` that starts with a `Select` clause created from the specified key path
*/
public func select<R>(_ keyPath: KeyPath<O, TransformableContainer<O>.Optional<R>>) -> QueryChainBuilder<O, R> {
return self.select(R.self, [SelectTerm<O>.attribute(keyPath)])
}
/** /**
Creates a `SectionMonitorChainBuilder` with the key path to use to group `ListMonitor` objects into sections Creates a `SectionMonitorChainBuilder` with the key path to use to group `ListMonitor` objects into sections
@@ -459,62 +385,6 @@ extension From where O: CoreStoreObject {
sectionIndexTransformer: { _ in nil } sectionIndexTransformer: { _ in nil }
) )
} }
/**
Creates a `SectionMonitorChainBuilder` with the key path to use to group `ListMonitor` objects into sections
- parameter sectionKeyPath: the `KeyPath` to use to group the objects into sections
- returns: a `SectionMonitorChainBuilder` that is sectioned by the specified key path
*/
public func sectionBy<T>(_ sectionKeyPath: KeyPath<O, ValueContainer<O>.Required<T>>) -> SectionMonitorChainBuilder<O> {
return self.sectionBy(
O.meta[keyPath: sectionKeyPath].keyPath,
sectionIndexTransformer: { _ in nil }
)
}
/**
Creates a `SectionMonitorChainBuilder` with the key path to use to group `ListMonitor` objects into sections
- parameter sectionKeyPath: the `KeyPath` to use to group the objects into sections
- returns: a `SectionMonitorChainBuilder` that is sectioned by the specified key path
*/
public func sectionBy<T>(_ sectionKeyPath: KeyPath<O, ValueContainer<O>.Optional<T>>) -> SectionMonitorChainBuilder<O> {
return self.sectionBy(
O.meta[keyPath: sectionKeyPath].keyPath,
sectionIndexTransformer: { _ in nil }
)
}
/**
Creates a `SectionMonitorChainBuilder` with the key path to use to group `ListMonitor` objects into sections
- parameter sectionKeyPath: the `KeyPath` to use to group the objects into sections
- returns: a `SectionMonitorChainBuilder` that is sectioned by the specified key path
*/
public func sectionBy<T>(_ sectionKeyPath: KeyPath<O, TransformableContainer<O>.Required<T>>) -> SectionMonitorChainBuilder<O> {
return self.sectionBy(
O.meta[keyPath: sectionKeyPath].keyPath,
sectionIndexTransformer: { _ in nil }
)
}
/**
Creates a `SectionMonitorChainBuilder` with the key path to use to group `ListMonitor` objects into sections
- parameter sectionKeyPath: the `KeyPath` to use to group the objects into sections
- returns: a `SectionMonitorChainBuilder` that is sectioned by the specified key path
*/
public func sectionBy<T>(_ sectionKeyPath: KeyPath<O, TransformableContainer<O>.Optional<T>>) -> SectionMonitorChainBuilder<O> {
return self.sectionBy(
O.meta[keyPath: sectionKeyPath].keyPath,
sectionIndexTransformer: { _ in nil }
)
}
/** /**
Creates a `SectionMonitorChainBuilder` with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section index title Creates a `SectionMonitorChainBuilder` with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section index title
@@ -572,169 +442,6 @@ extension From where O: CoreStoreObject {
sectionIndexTransformer: sectionIndexTransformer sectionIndexTransformer: sectionIndexTransformer
) )
} }
/**
Creates a `SectionMonitorChainBuilder` with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section index title
- Important: Some utilities (such as `ListMonitor`s) may keep `SectionBy`s in memory and may thus introduce retain cycles if reference captures are not handled properly.
- parameter sectionKeyPath: the `KeyPath` to use to group the objects into sections
- parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section index title
- returns: a `SectionMonitorChainBuilder` that is sectioned by the specified key path
*/
public func sectionBy<T>(
_ sectionKeyPath: KeyPath<O, ValueContainer<O>.Required<T>>,
sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?
) -> SectionMonitorChainBuilder<O> {
return self.sectionBy(
O.meta[keyPath: sectionKeyPath].keyPath,
sectionIndexTransformer: sectionIndexTransformer
)
}
/**
Creates a `SectionMonitorChainBuilder` with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section index title
- Important: Some utilities (such as `ListMonitor`s) may keep `SectionBy`s in memory and may thus introduce retain cycles if reference captures are not handled properly.
- parameter sectionKeyPath: the `KeyPath` to use to group the objects into sections
- parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section index title
- returns: a `SectionMonitorChainBuilder` that is sectioned by the specified key path
*/
public func sectionBy<T>(
_ sectionKeyPath: KeyPath<O, ValueContainer<O>.Optional<T>>,
sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?
) -> SectionMonitorChainBuilder<O> {
return self.sectionBy(
O.meta[keyPath: sectionKeyPath].keyPath,
sectionIndexTransformer: sectionIndexTransformer
)
}
/**
Creates a `SectionMonitorChainBuilder` with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section index title
- Important: Some utilities (such as `ListMonitor`s) may keep `SectionBy`s in memory and may thus introduce retain cycles if reference captures are not handled properly.
- parameter sectionKeyPath: the `KeyPath` to use to group the objects into sections
- parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section index title
- returns: a `SectionMonitorChainBuilder` that is sectioned by the specified key path
*/
public func sectionBy<T>(
_ sectionKeyPath: KeyPath<O, TransformableContainer<O>.Required<T>>,
sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?
) -> SectionMonitorChainBuilder<O> {
return self.sectionBy(
O.meta[keyPath: sectionKeyPath].keyPath,
sectionIndexTransformer: sectionIndexTransformer
)
}
/**
Creates a `SectionMonitorChainBuilder` with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section index title
- Important: Some utilities (such as `ListMonitor`s) may keep `SectionBy`s in memory and may thus introduce retain cycles if reference captures are not handled properly.
- parameter sectionKeyPath: the `KeyPath` to use to group the objects into sections
- parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section index title
- returns: a `SectionMonitorChainBuilder` that is sectioned by the specified key path
*/
public func sectionBy<T>(
_ sectionKeyPath: KeyPath<O, TransformableContainer<O>.Optional<T>>,
sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?
) -> SectionMonitorChainBuilder<O> {
return self.sectionBy(
O.meta[keyPath: sectionKeyPath].keyPath,
sectionIndexTransformer: sectionIndexTransformer
)
}
// MARK: Deprecated
@available(*, deprecated, renamed: "sectionBy(_:sectionIndexTransformer:)")
public func sectionBy<T>(
_ sectionKeyPath: KeyPath<O, FieldContainer<O>.Stored<T>>,
_ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?
) -> SectionMonitorChainBuilder<O> {
return self.sectionBy(
sectionKeyPath,
sectionIndexTransformer: sectionIndexTransformer
)
}
@available(*, deprecated, renamed: "sectionBy(_:sectionIndexTransformer:)")
public func sectionBy<T>(
_ sectionKeyPath: KeyPath<O, FieldContainer<O>.Virtual<T>>,
_ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?
) -> SectionMonitorChainBuilder<O> {
return self.sectionBy(
sectionKeyPath,
sectionIndexTransformer: sectionIndexTransformer
)
}
@available(*, deprecated, renamed: "sectionBy(_:sectionIndexTransformer:)")
public func sectionBy<T>(
_ sectionKeyPath: KeyPath<O, FieldContainer<O>.Coded<T>>,
_ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?
) -> SectionMonitorChainBuilder<O> {
return self.sectionBy(
sectionKeyPath,
sectionIndexTransformer: sectionIndexTransformer
)
}
@available(*, deprecated, renamed: "sectionBy(_:sectionIndexTransformer:)")
public func sectionBy<T>(
_ sectionKeyPath: KeyPath<O, ValueContainer<O>.Required<T>>,
_ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?
) -> SectionMonitorChainBuilder<O> {
return self.sectionBy(
sectionKeyPath,
sectionIndexTransformer: sectionIndexTransformer
)
}
@available(*, deprecated, renamed: "sectionBy(_:sectionIndexTransformer:)")
public func sectionBy<T>(
_ sectionKeyPath: KeyPath<O, ValueContainer<O>.Optional<T>>,
_ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?
) -> SectionMonitorChainBuilder<O> {
return self.sectionBy(
sectionKeyPath,
sectionIndexTransformer: sectionIndexTransformer
)
}
@available(*, deprecated, renamed: "sectionBy(_:sectionIndexTransformer:)")
public func sectionBy<T>(
_ sectionKeyPath: KeyPath<O, TransformableContainer<O>.Required<T>>,
_ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?
) -> SectionMonitorChainBuilder<O> {
return self.sectionBy(
sectionKeyPath,
sectionIndexTransformer: sectionIndexTransformer
)
}
@available(*, deprecated, renamed: "sectionBy(_:sectionIndexTransformer:)")
public func sectionBy<T>(
_ sectionKeyPath: KeyPath<O, TransformableContainer<O>.Optional<T>>,
_ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?
) -> SectionMonitorChainBuilder<O> {
return self.sectionBy(
sectionKeyPath,
sectionIndexTransformer: sectionIndexTransformer
)
}
} }
@@ -1147,50 +854,6 @@ extension QueryChainBuilder where O: CoreStoreObject {
return self.groupBy(GroupBy<O>(keyPath)) return self.groupBy(GroupBy<O>(keyPath))
} }
/**
Adds a `GroupBy` clause to the `QueryChainBuilder`
- parameter keyPath: a key path to group the query results with
- returns: a new `QueryChainBuilder` containing the `GroupBy` clause
*/
public func groupBy<T>(_ keyPath: KeyPath<O, ValueContainer<O>.Required<T>>) -> QueryChainBuilder<O, R> {
return self.groupBy(GroupBy<O>(keyPath))
}
/**
Adds a `GroupBy` clause to the `QueryChainBuilder`
- parameter keyPath: a key path to group the query results with
- returns: a new `QueryChainBuilder` containing the `GroupBy` clause
*/
public func groupBy<T>(_ keyPath: KeyPath<O, ValueContainer<O>.Optional<T>>) -> QueryChainBuilder<O, R> {
return self.groupBy(GroupBy<O>(keyPath))
}
/**
Adds a `GroupBy` clause to the `QueryChainBuilder`
- parameter keyPath: a key path to group the query results with
- returns: a new `QueryChainBuilder` containing the `GroupBy` clause
*/
public func groupBy<T>(_ keyPath: KeyPath<O, TransformableContainer<O>.Required<T>>) -> QueryChainBuilder<O, R> {
return self.groupBy(GroupBy<O>(keyPath))
}
/**
Adds a `GroupBy` clause to the `QueryChainBuilder`
- parameter keyPath: a key path to group the query results with
- returns: a new `QueryChainBuilder` containing the `GroupBy` clause
*/
public func groupBy<T>(_ keyPath: KeyPath<O, TransformableContainer<O>.Optional<T>>) -> QueryChainBuilder<O, R> {
return self.groupBy(GroupBy<O>(keyPath))
}
} }
@@ -1360,3 +1023,134 @@ extension SectionMonitorChainBuilder where O: CoreStoreObject {
return self.sectionMonitorChain(appending: clause(O.meta)) return self.sectionMonitorChain(appending: clause(O.meta))
} }
} }
// MARK: - Deprecated
@available(*, deprecated, message: """
Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
""")
extension From where O: CoreStoreObject {
public func select<R>(_ keyPath: KeyPath<O, ValueContainer<O>.Required<R>>) -> QueryChainBuilder<O, R> {
return self.select(R.self, [SelectTerm<O>.attribute(keyPath)])
}
public func select<R>(_ keyPath: KeyPath<O, ValueContainer<O>.Optional<R>>) -> QueryChainBuilder<O, R> {
return self.select(R.self, [SelectTerm<O>.attribute(keyPath)])
}
public func select<R>(_ keyPath: KeyPath<O, TransformableContainer<O>.Required<R>>) -> QueryChainBuilder<O, R> {
return self.select(R.self, [SelectTerm<O>.attribute(keyPath)])
}
public func select<R>(_ keyPath: KeyPath<O, TransformableContainer<O>.Optional<R>>) -> QueryChainBuilder<O, R> {
return self.select(R.self, [SelectTerm<O>.attribute(keyPath)])
}
public func sectionBy<T>(_ sectionKeyPath: KeyPath<O, ValueContainer<O>.Required<T>>) -> SectionMonitorChainBuilder<O> {
return self.sectionBy(
O.meta[keyPath: sectionKeyPath].keyPath,
sectionIndexTransformer: { _ in nil }
)
}
public func sectionBy<T>(_ sectionKeyPath: KeyPath<O, ValueContainer<O>.Optional<T>>) -> SectionMonitorChainBuilder<O> {
return self.sectionBy(
O.meta[keyPath: sectionKeyPath].keyPath,
sectionIndexTransformer: { _ in nil }
)
}
public func sectionBy<T>(_ sectionKeyPath: KeyPath<O, TransformableContainer<O>.Required<T>>) -> SectionMonitorChainBuilder<O> {
return self.sectionBy(
O.meta[keyPath: sectionKeyPath].keyPath,
sectionIndexTransformer: { _ in nil }
)
}
public func sectionBy<T>(_ sectionKeyPath: KeyPath<O, TransformableContainer<O>.Optional<T>>) -> SectionMonitorChainBuilder<O> {
return self.sectionBy(
O.meta[keyPath: sectionKeyPath].keyPath,
sectionIndexTransformer: { _ in nil }
)
}
public func sectionBy<T>(
_ sectionKeyPath: KeyPath<O, ValueContainer<O>.Required<T>>,
sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?
) -> SectionMonitorChainBuilder<O> {
return self.sectionBy(
O.meta[keyPath: sectionKeyPath].keyPath,
sectionIndexTransformer: sectionIndexTransformer
)
}
public func sectionBy<T>(
_ sectionKeyPath: KeyPath<O, ValueContainer<O>.Optional<T>>,
sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?
) -> SectionMonitorChainBuilder<O> {
return self.sectionBy(
O.meta[keyPath: sectionKeyPath].keyPath,
sectionIndexTransformer: sectionIndexTransformer
)
}
public func sectionBy<T>(
_ sectionKeyPath: KeyPath<O, TransformableContainer<O>.Required<T>>,
sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?
) -> SectionMonitorChainBuilder<O> {
return self.sectionBy(
O.meta[keyPath: sectionKeyPath].keyPath,
sectionIndexTransformer: sectionIndexTransformer
)
}
public func sectionBy<T>(
_ sectionKeyPath: KeyPath<O, TransformableContainer<O>.Optional<T>>,
sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?
) -> SectionMonitorChainBuilder<O> {
return self.sectionBy(
O.meta[keyPath: sectionKeyPath].keyPath,
sectionIndexTransformer: sectionIndexTransformer
)
}
}
@available(*, deprecated, message: """
Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
""")
extension QueryChainBuilder where O: CoreStoreObject {
public func groupBy<T>(_ keyPath: KeyPath<O, ValueContainer<O>.Required<T>>) -> QueryChainBuilder<O, R> {
return self.groupBy(GroupBy<O>(keyPath))
}
public func groupBy<T>(_ keyPath: KeyPath<O, ValueContainer<O>.Optional<T>>) -> QueryChainBuilder<O, R> {
return self.groupBy(GroupBy<O>(keyPath))
}
public func groupBy<T>(_ keyPath: KeyPath<O, TransformableContainer<O>.Required<T>>) -> QueryChainBuilder<O, R> {
return self.groupBy(GroupBy<O>(keyPath))
}
public func groupBy<T>(_ keyPath: KeyPath<O, TransformableContainer<O>.Optional<T>>) -> QueryChainBuilder<O, R> {
return self.groupBy(GroupBy<O>(keyPath))
}
}

View File

@@ -211,10 +211,4 @@ public struct From<O: DynamicObject> {
} }
} }
} }
// MARK: Deprecated
@available(*, deprecated, renamed: "O")
public typealias D = O
} }

View File

@@ -101,12 +101,6 @@ public struct GroupBy<O: DynamicObject>: GroupByClause, QueryClause, Hashable {
hasher.combine(self.keyPaths) hasher.combine(self.keyPaths)
} }
// MARK: Deprecated
@available(*, deprecated, renamed: "O")
public typealias D = O
} }
extension GroupBy where O: NSManagedObject { extension GroupBy where O: NSManagedObject {
@@ -153,46 +147,6 @@ extension GroupBy where O: CoreStoreObject {
self.init([O.meta[keyPath: keyPath].keyPath]) self.init([O.meta[keyPath: keyPath].keyPath])
} }
/**
Initializes a `GroupBy` clause with a key path
- parameter keyPath: a key path to group results with
*/
public init<T>(_ keyPath: KeyPath<O, ValueContainer<O>.Required<T>>) {
self.init([O.meta[keyPath: keyPath].keyPath])
}
/**
Initializes a `GroupBy` clause with a key path
- parameter keyPath: a key path to group results with
*/
public init<T>(_ keyPath: KeyPath<O, ValueContainer<O>.Optional<T>>) {
self.init([O.meta[keyPath: keyPath].keyPath])
}
/**
Initializes a `GroupBy` clause with a key path
- parameter keyPath: a key path to group results with
*/
public init<T>(_ keyPath: KeyPath<O, TransformableContainer<O>.Required<T>>) {
self.init([O.meta[keyPath: keyPath].keyPath])
}
/**
Initializes a `GroupBy` clause with a key path
- parameter keyPath: a key path to group results with
*/
public init<T>(_ keyPath: KeyPath<O, TransformableContainer<O>.Optional<T>>) {
self.init([O.meta[keyPath: keyPath].keyPath])
}
} }
@@ -213,3 +167,32 @@ public protocol GroupByClause {
*/ */
var keyPaths: [KeyPathString] { get } var keyPaths: [KeyPathString] { get }
} }
// MARK: - Deprecated
@available(*, deprecated, message: """
Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
""")
extension GroupBy where O: CoreStoreObject {
public init<T>(_ keyPath: KeyPath<O, ValueContainer<O>.Required<T>>) {
self.init([O.meta[keyPath: keyPath].keyPath])
}
public init<T>(_ keyPath: KeyPath<O, ValueContainer<O>.Optional<T>>) {
self.init([O.meta[keyPath: keyPath].keyPath])
}
public init<T>(_ keyPath: KeyPath<O, TransformableContainer<O>.Required<T>>) {
self.init([O.meta[keyPath: keyPath].keyPath])
}
public init<T>(_ keyPath: KeyPath<O, TransformableContainer<O>.Optional<T>>) {
self.init([O.meta[keyPath: keyPath].keyPath])
}
}

View File

@@ -131,10 +131,4 @@ public struct Into<O: DynamicObject>: Hashable {
self.configuration = configuration self.configuration = configuration
self.inferStoreIfPossible = inferStoreIfPossible self.inferStoreIfPossible = inferStoreIfPossible
} }
// MARK: Deprecated
@available(*, deprecated, renamed: "O")
public typealias D = O
} }

View File

@@ -588,133 +588,91 @@ public func ~= <O, D: FieldRelationshipToOneType, S: Sequence>(_ sequence: S, _
} }
// MARK: - KeyPath where Root: CoreStoreObject, Value: ValueContainer<Root>.Required<QueryableAttributeType & Equatable> // MARK: - Deprecated
/** @available(*, deprecated, message: """
Creates a `Where` clause by comparing if a property is equal to a value Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
``` """)
let person = dataStack.fetchOne(From<Person>().where(\.nickname == "John"))
```
*/
public func == <O, V>(_ keyPath: KeyPath<O, ValueContainer<O>.Required<V>>, _ value: V) -> Where<O> { public func == <O, V>(_ keyPath: KeyPath<O, ValueContainer<O>.Required<V>>, _ value: V) -> Where<O> {
return Where<O>(O.meta[keyPath: keyPath].keyPath, isEqualTo: value) return Where<O>(O.meta[keyPath: keyPath].keyPath, isEqualTo: value)
} }
/** @available(*, deprecated, message: """
Creates a `Where` clause by comparing if a property is not equal to a value Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
``` """)
let person = dataStack.fetchOne(From<Person>().where(\.nickname != "John"))
```
*/
public func != <O, V>(_ keyPath: KeyPath<O, ValueContainer<O>.Required<V>>, _ value: V) -> Where<O> { public func != <O, V>(_ keyPath: KeyPath<O, ValueContainer<O>.Required<V>>, _ value: V) -> Where<O> {
return !Where<O>(O.meta[keyPath: keyPath].keyPath, isEqualTo: value) return !Where<O>(O.meta[keyPath: keyPath].keyPath, isEqualTo: value)
} }
/** @available(*, deprecated, message: """
Creates a `Where` clause by checking if a sequence contains the value of a property Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
``` """)
let dog = dataStack.fetchOne(From<Dog>().where(["Pluto", "Snoopy", "Scooby"] ~= \.nickname))
```
*/
public func ~= <O, V, S: Sequence>(_ sequence: S, _ keyPath: KeyPath<O, ValueContainer<O>.Required<V>>) -> Where<O> where S.Iterator.Element == V { public func ~= <O, V, S: Sequence>(_ sequence: S, _ keyPath: KeyPath<O, ValueContainer<O>.Required<V>>) -> Where<O> where S.Iterator.Element == V {
return Where<O>(O.meta[keyPath: keyPath].keyPath, isMemberOf: sequence) return Where<O>(O.meta[keyPath: keyPath].keyPath, isMemberOf: sequence)
} }
@available(*, deprecated, message: """
// MARK: - KeyPath where Root: CoreStoreObject, Value: ValueContainer<Root>.Optional<QueryableAttributeType & Equatable> Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
""")
/**
Creates a `Where` clause by comparing if a property is equal to a value
```
let person = dataStack.fetchOne(From<Person>().where(\.nickname == "John"))
```
*/
public func == <O, V>(_ keyPath: KeyPath<O, ValueContainer<O>.Optional<V>>, _ value: V?) -> Where<O> { public func == <O, V>(_ keyPath: KeyPath<O, ValueContainer<O>.Optional<V>>, _ value: V?) -> Where<O> {
return Where<O>(O.meta[keyPath: keyPath].keyPath, isEqualTo: value) return Where<O>(O.meta[keyPath: keyPath].keyPath, isEqualTo: value)
} }
/** @available(*, deprecated, message: """
Creates a `Where` clause by comparing if a property is not equal to a value Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
``` """)
let person = dataStack.fetchOne(From<Person>().where(\.nickname != "John"))
```
*/
public func != <O, V>(_ keyPath: KeyPath<O, ValueContainer<O>.Optional<V>>, _ value: V?) -> Where<O> { public func != <O, V>(_ keyPath: KeyPath<O, ValueContainer<O>.Optional<V>>, _ value: V?) -> Where<O> {
return !Where<O>(O.meta[keyPath: keyPath].keyPath, isEqualTo: value) return !Where<O>(O.meta[keyPath: keyPath].keyPath, isEqualTo: value)
} }
/** @available(*, deprecated, message: """
Creates a `Where` clause by checking if a sequence contains the value of a property Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
``` """)
let dog = dataStack.fetchOne(From<Dog>().where(["Pluto", "Snoopy", "Scooby"] ~= \.nickname))
```
*/
public func ~= <O, V, S: Sequence>(_ sequence: S, _ keyPath: KeyPath<O, ValueContainer<O>.Optional<V>>) -> Where<O> where S.Iterator.Element == V { public func ~= <O, V, S: Sequence>(_ sequence: S, _ keyPath: KeyPath<O, ValueContainer<O>.Optional<V>>) -> Where<O> where S.Iterator.Element == V {
return Where<O>(O.meta[keyPath: keyPath].keyPath, isMemberOf: sequence) return Where<O>(O.meta[keyPath: keyPath].keyPath, isMemberOf: sequence)
} }
@available(*, deprecated, message: """
// MARK: - KeyPath where Root: CoreStoreObject, Value: ValueContainer<Root>.Required<QueryableAttributeType & Comparable> Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
""")
/**
Creates a `Where` clause by comparing if a property is less than a value
```
let person = dataStack.fetchOne(From<Person>().where(\.age < 20))
```
*/
public func < <O, V: Comparable>(_ keyPath: KeyPath<O, ValueContainer<O>.Required<V>>, _ value: V) -> Where<O> { public func < <O, V: Comparable>(_ keyPath: KeyPath<O, ValueContainer<O>.Required<V>>, _ value: V) -> Where<O> {
return Where<O>("%K < %@", O.meta[keyPath: keyPath].keyPath, value.cs_toQueryableNativeType()) return Where<O>("%K < %@", O.meta[keyPath: keyPath].keyPath, value.cs_toQueryableNativeType())
} }
/** @available(*, deprecated, message: """
Creates a `Where` clause by comparing if a property is greater than a value Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
``` """)
let person = dataStack.fetchOne(From<Person>().where(\.age > 20))
```
*/
public func > <O, V: Comparable>(_ keyPath: KeyPath<O, ValueContainer<O>.Required<V>>, _ value: V) -> Where<O> { public func > <O, V: Comparable>(_ keyPath: KeyPath<O, ValueContainer<O>.Required<V>>, _ value: V) -> Where<O> {
return Where<O>("%K > %@", O.meta[keyPath: keyPath].keyPath, value.cs_toQueryableNativeType()) return Where<O>("%K > %@", O.meta[keyPath: keyPath].keyPath, value.cs_toQueryableNativeType())
} }
/** @available(*, deprecated, message: """
Creates a `Where` clause by comparing if a property is less than or equal to a value Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
``` """)
let person = dataStack.fetchOne(From<Person>().where(\.age <= 20))
```
*/
public func <= <O, V: Comparable>(_ keyPath: KeyPath<O, ValueContainer<O>.Required<V>>, _ value: V) -> Where<O> { public func <= <O, V: Comparable>(_ keyPath: KeyPath<O, ValueContainer<O>.Required<V>>, _ value: V) -> Where<O> {
return Where<O>("%K <= %@", O.meta[keyPath: keyPath].keyPath, value.cs_toQueryableNativeType()) return Where<O>("%K <= %@", O.meta[keyPath: keyPath].keyPath, value.cs_toQueryableNativeType())
} }
/** @available(*, deprecated, message: """
Creates a `Where` clause by comparing if a property is greater than or equal to a value Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
``` """)
let person = dataStack.fetchOne(From<Person>().where(\.age >= 20))
```
*/
public func >= <O, V: Comparable>(_ keyPath: KeyPath<O, ValueContainer<O>.Required<V>>, _ value: V) -> Where<O> { public func >= <O, V: Comparable>(_ keyPath: KeyPath<O, ValueContainer<O>.Required<V>>, _ value: V) -> Where<O> {
return Where<O>("%K >= %@", O.meta[keyPath: keyPath].keyPath, value.cs_toQueryableNativeType()) return Where<O>("%K >= %@", O.meta[keyPath: keyPath].keyPath, value.cs_toQueryableNativeType())
} }
@available(*, deprecated, message: """
// MARK: - KeyPath where Root: CoreStoreObject, Value: ValueContainer<Root>.Optional<QueryableAttributeType & Comparable> Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
""")
/**
Creates a `Where` clause by comparing if a property is less than a value
```
let person = dataStack.fetchOne(From<Person>().where(\.age < 20))
```
*/
public func < <O, V>(_ keyPath: KeyPath<O, ValueContainer<O>.Optional<V>>, _ value: V?) -> Where<O> { public func < <O, V>(_ keyPath: KeyPath<O, ValueContainer<O>.Optional<V>>, _ value: V?) -> Where<O> {
if let value = value { if let value = value {
@@ -727,12 +685,9 @@ public func < <O, V>(_ keyPath: KeyPath<O, ValueContainer<O>.Optional<V>>, _ val
} }
} }
/** @available(*, deprecated, message: """
Creates a `Where` clause by comparing if a property is greater than a value Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
``` """)
let person = dataStack.fetchOne(From<Person>().where(\.age > 20))
```
*/
public func > <O, V>(_ keyPath: KeyPath<O, ValueContainer<O>.Optional<V>>, _ value: V?) -> Where<O> { public func > <O, V>(_ keyPath: KeyPath<O, ValueContainer<O>.Optional<V>>, _ value: V?) -> Where<O> {
if let value = value { if let value = value {
@@ -745,12 +700,9 @@ public func > <O, V>(_ keyPath: KeyPath<O, ValueContainer<O>.Optional<V>>, _ val
} }
} }
/** @available(*, deprecated, message: """
Creates a `Where` clause by comparing if a property is less than or equal to a value Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
``` """)
let person = dataStack.fetchOne(From<Person>().where(\.age <= 20))
```
*/
public func <= <O, V>(_ keyPath: KeyPath<O, ValueContainer<O>.Optional<V>>, _ value: V?) -> Where<O> { public func <= <O, V>(_ keyPath: KeyPath<O, ValueContainer<O>.Optional<V>>, _ value: V?) -> Where<O> {
if let value = value { if let value = value {
@@ -763,12 +715,9 @@ public func <= <O, V>(_ keyPath: KeyPath<O, ValueContainer<O>.Optional<V>>, _ va
} }
} }
/** @available(*, deprecated, message: """
Creates a `Where` clause by comparing if a property is greater than or equal to a value Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
``` """)
let person = dataStack.fetchOne(From<Person>().where(\.age >= 20))
```
*/
public func >= <O, V>(_ keyPath: KeyPath<O, ValueContainer<O>.Optional<V>>, _ value: V?) -> Where<O> { public func >= <O, V>(_ keyPath: KeyPath<O, ValueContainer<O>.Optional<V>>, _ value: V?) -> Where<O> {
if let value = value { if let value = value {
@@ -781,59 +730,41 @@ public func >= <O, V>(_ keyPath: KeyPath<O, ValueContainer<O>.Optional<V>>, _ va
} }
} }
@available(*, deprecated, message: """
// MARK: - KeyPath where Root: CoreStoreObject, Value: RelationshipContainer<Root>.ToOne<CoreStoreObject> Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
""")
/**
Creates a `Where` clause by comparing if a property is equal to a value
```
let dog = dataStack.fetchOne(From<Dog>().where(\.master == john))
```
*/
public func == <O, D>(_ keyPath: KeyPath<O, RelationshipContainer<O>.ToOne<D>>, _ object: D) -> Where<O> { public func == <O, D>(_ keyPath: KeyPath<O, RelationshipContainer<O>.ToOne<D>>, _ object: D) -> Where<O> {
return Where<O>(O.meta[keyPath: keyPath].keyPath, isEqualTo: object) return Where<O>(O.meta[keyPath: keyPath].keyPath, isEqualTo: object)
} }
/** @available(*, deprecated, message: """
Creates a `Where` clause by comparing if a property is equal to a value Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
``` """)
let dog = dataStack.fetchOne(From<Dog>().where(\.master == john))
```
*/
public func == <O, D>(_ keyPath: KeyPath<O, RelationshipContainer<O>.ToOne<D>>, _ object: D?) -> Where<O> { public func == <O, D>(_ keyPath: KeyPath<O, RelationshipContainer<O>.ToOne<D>>, _ object: D?) -> Where<O> {
return Where<O>(O.meta[keyPath: keyPath].keyPath, isEqualTo: object) return Where<O>(O.meta[keyPath: keyPath].keyPath, isEqualTo: object)
} }
/** @available(*, deprecated, message: """
Creates a `Where` clause by comparing if a property is not equal to a value Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
``` """)
let dog = dataStack.fetchOne(From<Dog>().where(\.master != john))
```
*/
public func != <O, D>(_ keyPath: KeyPath<O, RelationshipContainer<O>.ToOne<D>>, _ object: D) -> Where<O> { public func != <O, D>(_ keyPath: KeyPath<O, RelationshipContainer<O>.ToOne<D>>, _ object: D) -> Where<O> {
return !Where<O>(O.meta[keyPath: keyPath].keyPath, isEqualTo: object) return !Where<O>(O.meta[keyPath: keyPath].keyPath, isEqualTo: object)
} }
/** @available(*, deprecated, message: """
Creates a `Where` clause by comparing if a property is not equal to a value Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
``` """)
let dog = dataStack.fetchOne(From<Dog>().where(\.master != john))
```
*/
public func != <O, D>(_ keyPath: KeyPath<O, RelationshipContainer<O>.ToOne<D>>, _ object: D?) -> Where<O> { public func != <O, D>(_ keyPath: KeyPath<O, RelationshipContainer<O>.ToOne<D>>, _ object: D?) -> Where<O> {
return !Where<O>(O.meta[keyPath: keyPath].keyPath, isEqualTo: object) return !Where<O>(O.meta[keyPath: keyPath].keyPath, isEqualTo: object)
} }
/** @available(*, deprecated, message: """
Creates a `Where` clause by checking if a sequence contains a value of a property Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
``` """)
let dog = dataStack.fetchOne(From<Dog>().where([john, bob, joe] ~= \.master))
```
*/
public func ~= <O, D, S: Sequence>(_ sequence: S, _ keyPath: KeyPath<O, RelationshipContainer<O>.ToOne<D>>) -> Where<O> where S.Iterator.Element == D { public func ~= <O, D, S: Sequence>(_ sequence: S, _ keyPath: KeyPath<O, RelationshipContainer<O>.ToOne<D>>) -> Where<O> where S.Iterator.Element == D {
return Where<O>(O.meta[keyPath: keyPath].keyPath, isMemberOf: sequence) return Where<O>(O.meta[keyPath: keyPath].keyPath, isMemberOf: sequence)

View File

@@ -317,9 +317,3 @@ extension NSSet: AllowedObjectiveCToManyRelationshipKeyPathValue {}
extension NSOrderedSet: AllowedObjectiveCToManyRelationshipKeyPathValue {} extension NSOrderedSet: AllowedObjectiveCToManyRelationshipKeyPathValue {}
extension Optional: AllowedObjectiveCToManyRelationshipKeyPathValue where Wrapped: AllowedObjectiveCToManyRelationshipKeyPathValue, Wrapped: AllowedObjectiveCRelationshipKeyPathValue {} extension Optional: AllowedObjectiveCToManyRelationshipKeyPathValue where Wrapped: AllowedObjectiveCToManyRelationshipKeyPathValue, Wrapped: AllowedObjectiveCRelationshipKeyPathValue {}
// MARK: - Deprecated
@available(*, deprecated, renamed: "AllowedObjectiveCToManyRelationshipKeyPathValue")
public typealias AllowedCoreStoreObjectCollectionKeyPathValue = AllowedObjectiveCToManyRelationshipKeyPathValue

View File

@@ -92,12 +92,3 @@ public protocol RelationshipKeyPathStringConvertible: KeyPathStringConvertible {
*/ */
public protocol ToManyRelationshipKeyPathStringConvertible: RelationshipKeyPathStringConvertible where ReturnValueType: Sequence {} public protocol ToManyRelationshipKeyPathStringConvertible: RelationshipKeyPathStringConvertible where ReturnValueType: Sequence {}
// MARK: - Deprecated
@available(*, deprecated, renamed: "AnyKeyPathStringConvertible")
public typealias AnyDynamicKeyPath = AnyKeyPathStringConvertible
@available(*, deprecated, renamed: "KeyPathStringConvertible")
public typealias DynamicKeyPath = KeyPathStringConvertible

View File

@@ -1440,21 +1440,6 @@ extension ListMonitor where O: NSManagedObject {
return self.sectionInfo(safelyAt: section)?.objects as! [O]? return self.sectionInfo(safelyAt: section)?.objects as! [O]?
} }
// MARK: Deprecated
@available(*, deprecated, renamed: "objects(in:)")
public func objectsInSection(_ section: Int) -> [O] {
return self.objects(in: section)
}
@available(*, deprecated, renamed: "objects(safelyIn:)")
public func objectsInSection(safeSectionIndex section: Int) -> [O]? {
return self.objects(safelyIn: section)
}
} }
@@ -1500,12 +1485,6 @@ extension ListMonitor where O: CoreStoreObject {
return (self.sectionInfo(safelyAt: section)?.objects)? return (self.sectionInfo(safelyAt: section)?.objects)?
.map({ O.cs_fromRaw(object: $0 as! NSManagedObject) }) .map({ O.cs_fromRaw(object: $0 as! NSManagedObject) })
} }
// MARK: Deprecated
@available(*, deprecated, renamed: "O")
public typealias D = O
} }

View File

@@ -408,12 +408,6 @@ public final class ObjectMonitor<O: DynamicObject>: Hashable, ObjectRepresentati
inObject: observer inObject: observer
) )
} }
// MARK: Deprecated
@available(*, deprecated, renamed: "O")
public typealias D = O
} }

View File

@@ -333,15 +333,6 @@ extension ObjectPublisher where O: NSManagedObject {
return self.snapshot?[dynamicMember: member] return self.snapshot?[dynamicMember: member]
} }
// MARK: Deprecated
@available(*, deprecated, message: "Accessing the property directly now works")
public func value<V: AllowedObjectiveCKeyPathValue>(forKeyPath keyPath: KeyPath<O, V>) -> V! {
return self[dynamicMember: keyPath]
}
} }
@@ -432,62 +423,6 @@ extension ObjectPublisher where O: CoreStoreObject {
return V.cs_toPublishedType(from: snapshotValue, in: self.context) return V.cs_toPublishedType(from: snapshotValue, in: self.context)
} }
/**
Returns the value for the property identified by a given key.
*/
public subscript<OBase, V>(dynamicMember member: KeyPath<O, ValueContainer<OBase>.Required<V>>) -> V? {
return self.object?[keyPath: member].value
}
/**
Returns the value for the property identified by a given key.
*/
public subscript<OBase, V>(dynamicMember member: KeyPath<O, ValueContainer<OBase>.Optional<V>>) -> V? {
return self.object?[keyPath: member].value
}
/**
Returns the value for the property identified by a given key.
*/
public subscript<OBase, V>(dynamicMember member: KeyPath<O, TransformableContainer<OBase>.Required<V>>) -> V? {
return self.object?[keyPath: member].value
}
/**
Returns the value for the property identified by a given key.
*/
public subscript<OBase, V>(dynamicMember member: KeyPath<O, TransformableContainer<OBase>.Optional<V>>) -> V? {
return self.object?[keyPath: member].value
}
/**
Returns the value for the property identified by a given key.
*/
public subscript<OBase, D>(dynamicMember member: KeyPath<O, RelationshipContainer<OBase>.ToOne<D>>) -> D? {
return self.object?[keyPath: member].value
}
/**
Returns the value for the property identified by a given key.
*/
public subscript<OBase, D>(dynamicMember member: KeyPath<O, RelationshipContainer<OBase>.ToManyOrdered<D>>) -> [D]? {
return self.object?[keyPath: member].value
}
/**
Returns the value for the property identified by a given key.
*/
public subscript<OBase, D>(dynamicMember member: KeyPath<O, RelationshipContainer<OBase>.ToManyUnordered<D>>) -> Set<D>? {
return self.object?[keyPath: member].value
}
/** /**
Returns the value for the property identified by a given key. Returns the value for the property identified by a given key.
*/ */
@@ -496,3 +431,48 @@ extension ObjectPublisher where O: CoreStoreObject {
return self.object?[keyPath: member] return self.object?[keyPath: member]
} }
} }
// MARK: - Deprecated
@available(*, deprecated, message: """
Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
""")
extension ObjectPublisher where O: CoreStoreObject {
public subscript<OBase, V>(dynamicMember member: KeyPath<O, ValueContainer<OBase>.Required<V>>) -> V? {
return self.object?[keyPath: member].value
}
public subscript<OBase, V>(dynamicMember member: KeyPath<O, ValueContainer<OBase>.Optional<V>>) -> V? {
return self.object?[keyPath: member].value
}
public subscript<OBase, V>(dynamicMember member: KeyPath<O, TransformableContainer<OBase>.Required<V>>) -> V? {
return self.object?[keyPath: member].value
}
public subscript<OBase, V>(dynamicMember member: KeyPath<O, TransformableContainer<OBase>.Optional<V>>) -> V? {
return self.object?[keyPath: member].value
}
public subscript<OBase, D>(dynamicMember member: KeyPath<O, RelationshipContainer<OBase>.ToOne<D>>) -> D? {
return self.object?[keyPath: member].value
}
public subscript<OBase, D>(dynamicMember member: KeyPath<O, RelationshipContainer<OBase>.ToManyOrdered<D>>) -> [D]? {
return self.object?[keyPath: member].value
}
public subscript<OBase, D>(dynamicMember member: KeyPath<O, RelationshipContainer<OBase>.ToManyUnordered<D>>) -> Set<D>? {
return self.object?[keyPath: member].value
}
}

View File

@@ -189,7 +189,9 @@ extension ObjectSnapshot where O: CoreStoreObject {
/** /**
Returns the value for the property identified by a given key. Returns the value for the property identified by a given key.
*/ */
public subscript<OBase, V>(dynamicMember member: KeyPath<O, FieldContainer<OBase>.Stored<V>>) -> V { public subscript<OBase, V>(
dynamicMember member: KeyPath<O, FieldContainer<OBase>.Stored<V>>
) -> V {
get { get {
@@ -206,7 +208,9 @@ extension ObjectSnapshot where O: CoreStoreObject {
/** /**
Returns the value for the property identified by a given key. Returns the value for the property identified by a given key.
*/ */
public subscript<OBase, V>(dynamicMember member: KeyPath<O, FieldContainer<OBase>.Virtual<V>>) -> V { public subscript<OBase, V>(
dynamicMember member: KeyPath<O, FieldContainer<OBase>.Virtual<V>>
) -> V {
get { get {
@@ -223,7 +227,9 @@ extension ObjectSnapshot where O: CoreStoreObject {
/** /**
Returns the value for the property identified by a given key. Returns the value for the property identified by a given key.
*/ */
public subscript<OBase, V>(dynamicMember member: KeyPath<O, FieldContainer<OBase>.Coded<V>>) -> V { public subscript<OBase, V>(
dynamicMember member: KeyPath<O, FieldContainer<OBase>.Coded<V>>
) -> V {
get { get {
@@ -240,7 +246,9 @@ extension ObjectSnapshot where O: CoreStoreObject {
/** /**
Returns the value for the property identified by a given key. Returns the value for the property identified by a given key.
*/ */
public subscript<OBase, V>(dynamicMember member: KeyPath<O, FieldContainer<OBase>.Relationship<V>>) -> V.PublishedType { public subscript<OBase, V>(
dynamicMember member: KeyPath<O, FieldContainer<OBase>.Relationship<V>>
) -> V.PublishedType {
get { get {
@@ -255,11 +263,19 @@ extension ObjectSnapshot where O: CoreStoreObject {
self.values[key] = V.cs_toSnapshotType(from: newValue) self.values[key] = V.cs_toSnapshotType(from: newValue)
} }
} }
}
/**
Returns the value for the property identified by a given key. // MARK: - Deprecated
*/
public subscript<OBase, V>(dynamicMember member: KeyPath<O, ValueContainer<OBase>.Required<V>>) -> V { @available(*, deprecated, message: """
Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
""")
extension ObjectSnapshot where O: CoreStoreObject {
public subscript<OBase, V>(
dynamicMember member: KeyPath<O, ValueContainer<OBase>.Required<V>>
) -> V {
get { get {
@@ -273,10 +289,9 @@ extension ObjectSnapshot where O: CoreStoreObject {
} }
} }
/** public subscript<OBase, V>(
Returns the value for the property identified by a given key. dynamicMember member: KeyPath<O, ValueContainer<OBase>.Optional<V>>
*/ ) -> V? {
public subscript<OBase, V>(dynamicMember member: KeyPath<O, ValueContainer<OBase>.Optional<V>>) -> V? {
get { get {
@@ -289,11 +304,10 @@ extension ObjectSnapshot where O: CoreStoreObject {
self.values[key] = newValue self.values[key] = newValue
} }
} }
/** public subscript<OBase, V>(
Returns the value for the property identified by a given key. dynamicMember member: KeyPath<O, TransformableContainer<OBase>.Required<V>>
*/ ) -> V {
public subscript<OBase, V>(dynamicMember member: KeyPath<O, TransformableContainer<OBase>.Required<V>>) -> V {
get { get {
@@ -306,11 +320,10 @@ extension ObjectSnapshot where O: CoreStoreObject {
self.values[key] = newValue self.values[key] = newValue
} }
} }
/** public subscript<OBase, V>(
Returns the value for the property identified by a given key. dynamicMember member: KeyPath<O, TransformableContainer<OBase>.Optional<V>>
*/ ) -> V? {
public subscript<OBase, V>(dynamicMember member: KeyPath<O, TransformableContainer<OBase>.Optional<V>>) -> V? {
get { get {
@@ -323,11 +336,10 @@ extension ObjectSnapshot where O: CoreStoreObject {
self.values[key] = newValue self.values[key] = newValue
} }
} }
/** public subscript<OBase, D>(
Returns the value for the property identified by a given key. dynamicMember member: KeyPath<O, RelationshipContainer<OBase>.ToOne<D>>
*/ ) -> ObjectPublisher<D>? {
public subscript<OBase, D>(dynamicMember member: KeyPath<O, RelationshipContainer<OBase>.ToOne<D>>) -> ObjectPublisher<D>? {
get { get {
@@ -344,11 +356,10 @@ extension ObjectSnapshot where O: CoreStoreObject {
self.values[key] = newValue?.objectID() self.values[key] = newValue?.objectID()
} }
} }
/** public subscript<OBase, D>(
Returns the value for the property identified by a given key. dynamicMember member: KeyPath<O, RelationshipContainer<OBase>.ToManyOrdered<D>>
*/ ) -> [ObjectPublisher<D>] {
public subscript<OBase, D>(dynamicMember member: KeyPath<O, RelationshipContainer<OBase>.ToManyOrdered<D>>) -> [ObjectPublisher<D>] {
get { get {
@@ -363,11 +374,10 @@ extension ObjectSnapshot where O: CoreStoreObject {
self.values[key] = newValue.map({ $0.objectID() }) self.values[key] = newValue.map({ $0.objectID() })
} }
} }
/** public subscript<OBase, D>(
Returns the value for the property identified by a given key. dynamicMember member: KeyPath<O, RelationshipContainer<OBase>.ToManyUnordered<D>>
*/ ) -> Set<ObjectPublisher<D>> {
public subscript<OBase, D>(dynamicMember member: KeyPath<O, RelationshipContainer<OBase>.ToManyUnordered<D>>) -> Set<ObjectPublisher<D>> {
get { get {

View File

@@ -151,7 +151,7 @@ public struct OrderBy<O: DynamicObject>: OrderByClause, FetchClause, QueryClause
/** /**
Indicates that the `KeyPathString` should be sorted in ascending order Indicates that the `KeyPathString` should be sorted in ascending order
*/ */
public static func ascending(_ keyPath: KeyPathString) -> SortKey { public static func ascending(_ keyPath: KeyPathString) -> Self {
return SortKey(descriptor: .init(key: keyPath, ascending: true)) return SortKey(descriptor: .init(key: keyPath, ascending: true))
} }
@@ -159,7 +159,7 @@ public struct OrderBy<O: DynamicObject>: OrderByClause, FetchClause, QueryClause
/** /**
Indicates that the `KeyPathString` should be sorted in descending order Indicates that the `KeyPathString` should be sorted in descending order
*/ */
public static func descending(_ keyPath: KeyPathString) -> SortKey { public static func descending(_ keyPath: KeyPathString) -> Self {
return SortKey(descriptor: .init(key: keyPath, ascending: false)) return SortKey(descriptor: .init(key: keyPath, ascending: false))
} }
@@ -170,7 +170,7 @@ public struct OrderBy<O: DynamicObject>: OrderByClause, FetchClause, QueryClause
/** /**
Indicates that the `KeyPathString` should be sorted in ascending order Indicates that the `KeyPathString` should be sorted in ascending order
*/ */
public static func ascending<T>(_ keyPath: KeyPath<O, T>) -> SortKey where O: NSManagedObject { public static func ascending<T>(_ keyPath: KeyPath<O, T>) -> Self where O: NSManagedObject {
return .ascending(keyPath._kvcKeyPathString!) return .ascending(keyPath._kvcKeyPathString!)
} }
@@ -178,7 +178,7 @@ public struct OrderBy<O: DynamicObject>: OrderByClause, FetchClause, QueryClause
/** /**
Indicates that the `KeyPathString` should be sorted in descending order Indicates that the `KeyPathString` should be sorted in descending order
*/ */
public static func descending<T>(_ keyPath: KeyPath<O, T>) -> SortKey where O: NSManagedObject { public static func descending<T>(_ keyPath: KeyPath<O, T>) -> Self where O: NSManagedObject {
return .descending(keyPath._kvcKeyPathString!) return .descending(keyPath._kvcKeyPathString!)
} }
@@ -189,94 +189,24 @@ public struct OrderBy<O: DynamicObject>: OrderByClause, FetchClause, QueryClause
/** /**
Indicates that the `KeyPathString` should be sorted in ascending order Indicates that the `KeyPathString` should be sorted in ascending order
*/ */
public static func ascending<T>(_ attribute: KeyPath<O, FieldContainer<O>.Stored<T>>) -> SortKey { public static func ascending<T>(_ attribute: KeyPath<O, FieldContainer<O>.Stored<T>>) -> Self {
return .ascending(O.meta[keyPath: attribute].keyPath) return .ascending(O.meta[keyPath: attribute].keyPath)
} }
/**
Indicates that the `KeyPathString` should be sorted in ascending order
*/
public static func ascending<T>(_ attribute: KeyPath<O, ValueContainer<O>.Required<T>>) -> SortKey {
return .ascending(O.meta[keyPath: attribute].keyPath)
}
/**
Indicates that the `KeyPathString` should be sorted in ascending order
*/
public static func ascending<T>(_ attribute: KeyPath<O, ValueContainer<O>.Optional<T>>) -> SortKey {
return .ascending(O.meta[keyPath: attribute].keyPath)
}
/**
Indicates that the `KeyPathString` should be sorted in ascending order
*/
public static func ascending<T>(_ attribute: KeyPath<O, TransformableContainer<O>.Required<T>>) -> SortKey {
return .ascending(O.meta[keyPath: attribute].keyPath)
}
/**
Indicates that the `KeyPathString` should be sorted in ascending order
*/
public static func ascending<T>(_ attribute: KeyPath<O, TransformableContainer<O>.Optional<T>>) -> SortKey {
return .ascending(O.meta[keyPath: attribute].keyPath)
}
/** /**
Indicates that the `KeyPathString` should be sorted in descending order Indicates that the `KeyPathString` should be sorted in descending order
*/ */
public static func descending<T>(_ attribute: KeyPath<O, FieldContainer<O>.Stored<T>>) -> SortKey { public static func descending<T>(_ attribute: KeyPath<O, FieldContainer<O>.Stored<T>>) -> Self {
return .descending(O.meta[keyPath: attribute].keyPath) return .descending(O.meta[keyPath: attribute].keyPath)
} }
/**
Indicates that the `KeyPathString` should be sorted in descending order
*/
public static func descending<T>(_ attribute: KeyPath<O, ValueContainer<O>.Required<T>>) -> SortKey {
return .descending(O.meta[keyPath: attribute].keyPath)
}
/**
Indicates that the `KeyPathString` should be sorted in descending order
*/
public static func descending<T>(_ attribute: KeyPath<O, ValueContainer<O>.Optional<T>>) -> SortKey {
return .descending(O.meta[keyPath: attribute].keyPath)
}
/**
Indicates that the `KeyPathString` should be sorted in descending order
*/
public static func descending<T>(_ attribute: KeyPath<O, TransformableContainer<O>.Required<T>>) -> SortKey {
return .descending(O.meta[keyPath: attribute].keyPath)
}
/**
Indicates that the `KeyPathString` should be sorted in descending order
*/
public static func descending<T>(_ attribute: KeyPath<O, TransformableContainer<O>.Optional<T>>) -> SortKey {
return .descending(O.meta[keyPath: attribute].keyPath)
}
// MARK: Private // MARK: Private
fileprivate let descriptor: NSSortDescriptor fileprivate let descriptor: NSSortDescriptor
} }
// MARK: Deprecated
@available(*, deprecated, renamed: "O")
public typealias D = O
} }
@@ -287,7 +217,7 @@ extension OrderBy.SortKey where O: CoreStoreObject {
/** /**
Indicates that the `KeyPathString` should be sorted in ascending order Indicates that the `KeyPathString` should be sorted in ascending order
*/ */
public static func ascending<K: KeyPathStringConvertible>(_ attribute: (O) -> K) -> OrderBy<O>.SortKey { public static func ascending<K: KeyPathStringConvertible>(_ attribute: (O) -> K) -> Self {
return .ascending(attribute(O.meta).cs_keyPathString) return .ascending(attribute(O.meta).cs_keyPathString)
} }
@@ -295,7 +225,7 @@ extension OrderBy.SortKey where O: CoreStoreObject {
/** /**
Indicates that the `KeyPathString` should be sorted in descending order Indicates that the `KeyPathString` should be sorted in descending order
*/ */
public static func descending<K: KeyPathStringConvertible>(_ attribute: (O) -> K) -> OrderBy<O>.SortKey { public static func descending<K: KeyPathStringConvertible>(_ attribute: (O) -> K) -> Self {
return .descending(attribute(O.meta).cs_keyPathString) return .descending(attribute(O.meta).cs_keyPathString)
} }
@@ -333,3 +263,52 @@ extension Sequence where Iterator.Element: OrderByClause {
return OrderBy(self.flatMap({ $0.sortDescriptors })) return OrderBy(self.flatMap({ $0.sortDescriptors }))
} }
} }
// MARK: - Deprecated
@available(*, deprecated, message: """
Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
""")
extension OrderBy.SortKey where O: CoreStoreObject {
public static func ascending<T>(_ attribute: KeyPath<O, ValueContainer<O>.Required<T>>) -> Self {
return .ascending(O.meta[keyPath: attribute].keyPath)
}
public static func ascending<T>(_ attribute: KeyPath<O, ValueContainer<O>.Optional<T>>) -> Self {
return .ascending(O.meta[keyPath: attribute].keyPath)
}
public static func ascending<T>(_ attribute: KeyPath<O, TransformableContainer<O>.Required<T>>) -> Self {
return .ascending(O.meta[keyPath: attribute].keyPath)
}
public static func ascending<T>(_ attribute: KeyPath<O, TransformableContainer<O>.Optional<T>>) -> Self {
return .ascending(O.meta[keyPath: attribute].keyPath)
}
public static func descending<T>(_ attribute: KeyPath<O, ValueContainer<O>.Required<T>>) -> Self {
return .descending(O.meta[keyPath: attribute].keyPath)
}
public static func descending<T>(_ attribute: KeyPath<O, ValueContainer<O>.Optional<T>>) -> Self {
return .descending(O.meta[keyPath: attribute].keyPath)
}
public static func descending<T>(_ attribute: KeyPath<O, TransformableContainer<O>.Required<T>>) -> Self {
return .descending(O.meta[keyPath: attribute].keyPath)
}
public static func descending<T>(_ attribute: KeyPath<O, TransformableContainer<O>.Optional<T>>) -> Self {
return .descending(O.meta[keyPath: attribute].keyPath)
}
}

View File

@@ -154,192 +154,6 @@ public struct PartialObject<O: CoreStoreObject> {
} }
// MARK: Value.Required accessors/mutators
/**
Returns the value for the property identified by a given key.
*/
public func value<V>(for property: (O) -> ValueContainer<O>.Required<V>) -> V {
return V.cs_fromQueryableNativeType(
self.rawObject.value(forKey: property(O.meta).keyPath)! as! V.QueryableNativeType
)!
}
/**
Sets the property of the receiver specified by a given key to a given value.
*/
public func setValue<V>(_ value: V, for property: (O) -> ValueContainer<O>.Required<V>) {
self.rawObject.setValue(
value.cs_toQueryableNativeType(),
forKey: property(O.meta).keyPath
)
}
/**
Returns the value for the specified property from the managed objects private internal storage.
This method does not invoke the access notification methods (`willAccessValue(forKey:)` and `didAccessValue(forKey:)`). This method is used primarily by subclasses that implement custom accessor methods that need direct access to the receivers private storage.
*/
public func primitiveValue<V>(for property: (O) -> ValueContainer<O>.Required<V>) -> V {
return V.cs_fromQueryableNativeType(
self.rawObject.primitiveValue(forKey: property(O.meta).keyPath)! as! V.QueryableNativeType
)!
}
/**
Sets in the object's private internal storage the value of a given property.
Sets in the receivers private internal storage the value of the property specified by key to value.
*/
public func setPrimitiveValue<V>(_ value: V, for property: (O) -> ValueContainer<O>.Required<V>) {
self.rawObject.setPrimitiveValue(
value.cs_toQueryableNativeType(),
forKey: property(O.meta).keyPath
)
}
// MARK: Value.Optional utilities
/**
Returns the value for the property identified by a given key.
*/
public func value<V>(for property: (O) -> ValueContainer<O>.Optional<V>) -> V? {
return (self.rawObject.value(forKey: property(O.meta).keyPath) as! V.QueryableNativeType?)
.flatMap(V.cs_fromQueryableNativeType)
}
/**
Sets the property of the receiver specified by a given key to a given value.
*/
public func setValue<V>(_ value: V?, for property: (O) -> ValueContainer<O>.Optional<V>) {
self.rawObject.setValue(
value?.cs_toQueryableNativeType(),
forKey: property(O.meta).keyPath
)
}
/**
Returns the value for the specified property from the managed objects private internal storage.
This method does not invoke the access notification methods (`willAccessValue(forKey:)` and `didAccessValue(forKey:)`). This method is used primarily by subclasses that implement custom accessor methods that need direct access to the receivers private storage.
*/
public func primitiveValue<V>(for property: (O) -> ValueContainer<O>.Optional<V>) -> V? {
return (self.rawObject.primitiveValue(forKey: property(O.meta).keyPath) as! V.QueryableNativeType?)
.flatMap(V.cs_fromQueryableNativeType)
}
/**
Sets in the object's private internal storage the value of a given property.
Sets in the receivers private internal storage the value of the property specified by key to value.
*/
public func setPrimitiveValue<V>(_ value: V?, for property: (O) -> ValueContainer<O>.Optional<V>) {
self.rawObject.setPrimitiveValue(
value?.cs_toQueryableNativeType(),
forKey: property(O.meta).keyPath
)
}
// MARK: Transformable.Required utilities
/**
Returns the value for the property identified by a given key.
*/
public func value<V>(for property: (O) -> TransformableContainer<O>.Required<V>) -> V {
return self.rawObject.value(forKey: property(O.meta).keyPath)! as! V
}
/**
Sets the property of the receiver specified by a given key to a given value.
*/
public func setValue<V>(_ value: V, for property: (O) -> TransformableContainer<O>.Required<V>) {
self.rawObject.setValue(
value,
forKey: property(O.meta).keyPath
)
}
/**
Returns the value for the specified property from the managed objects private internal storage.
This method does not invoke the access notification methods (`willAccessValue(forKey:)` and `didAccessValue(forKey:)`). This method is used primarily by subclasses that implement custom accessor methods that need direct access to the receivers private storage.
*/
public func primitiveValue<V>(for property: (O) -> TransformableContainer<O>.Required<V>) -> V {
return self.rawObject.primitiveValue(forKey: property(O.meta).keyPath)! as! V
}
/**
Sets in the object's private internal storage the value of a given property.
Sets in the receivers private internal storage the value of the property specified by key to value.
*/
public func setPrimitiveValue<V>(_ value: V, for property: (O) -> TransformableContainer<O>.Required<V>) {
self.rawObject.setPrimitiveValue(
value,
forKey: property(O.meta).keyPath
)
}
// MARK: Transformable.Optional utilities
/**
Returns the value for the property identified by a given key.
*/
public func value<V>(for property: (O) -> TransformableContainer<O>.Optional<V>) -> V? {
return self.rawObject.value(forKey: property(O.meta).keyPath) as! V?
}
/**
Sets the property of the receiver specified by a given key to a given value.
*/
public func setValue<V>(_ value: V?, for property: (O) -> TransformableContainer<O>.Optional<V>) {
self.rawObject.setValue(
value,
forKey: property(O.meta).keyPath
)
}
/**
Returns the value for the specified property from the managed objects private internal storage.
This method does not invoke the access notification methods (`willAccessValue(forKey:)` and `didAccessValue(forKey:)`). This method is used primarily by subclasses that implement custom accessor methods that need direct access to the receivers private storage.
*/
public func primitiveValue<V>(for property: (O) -> TransformableContainer<O>.Optional<V>) -> V? {
return self.rawObject.primitiveValue(forKey: property(O.meta).keyPath) as! V?
}
/**
Sets in the object's private internal storage the value of a given property.
Sets in the receivers private internal storage the value of the property specified by key to value.
*/
public func setPrimitiveValue<V>(_ value: V?, for property: (O) -> TransformableContainer<O>.Optional<V>) {
self.rawObject.setPrimitiveValue(
value,
forKey: property(O.meta).keyPath
)
}
// MARK: Internal // MARK: Internal
internal let rawObject: NSManagedObject internal let rawObject: NSManagedObject
@@ -349,3 +163,122 @@ public struct PartialObject<O: CoreStoreObject> {
self.rawObject = rawObject self.rawObject = rawObject
} }
} }
// MARK: - Deprecated
@available(*, deprecated, message: """
Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
""")
extension PartialObject {
public func value<V>(for property: (O) -> ValueContainer<O>.Required<V>) -> V {
return V.cs_fromQueryableNativeType(
self.rawObject.value(forKey: property(O.meta).keyPath)! as! V.QueryableNativeType
)!
}
public func setValue<V>(_ value: V, for property: (O) -> ValueContainer<O>.Required<V>) {
self.rawObject.setValue(
value.cs_toQueryableNativeType(),
forKey: property(O.meta).keyPath
)
}
public func primitiveValue<V>(for property: (O) -> ValueContainer<O>.Required<V>) -> V {
return V.cs_fromQueryableNativeType(
self.rawObject.primitiveValue(forKey: property(O.meta).keyPath)! as! V.QueryableNativeType
)!
}
public func setPrimitiveValue<V>(_ value: V, for property: (O) -> ValueContainer<O>.Required<V>) {
self.rawObject.setPrimitiveValue(
value.cs_toQueryableNativeType(),
forKey: property(O.meta).keyPath
)
}
public func value<V>(for property: (O) -> ValueContainer<O>.Optional<V>) -> V? {
return (self.rawObject.value(forKey: property(O.meta).keyPath) as! V.QueryableNativeType?)
.flatMap(V.cs_fromQueryableNativeType)
}
public func setValue<V>(_ value: V?, for property: (O) -> ValueContainer<O>.Optional<V>) {
self.rawObject.setValue(
value?.cs_toQueryableNativeType(),
forKey: property(O.meta).keyPath
)
}
public func primitiveValue<V>(for property: (O) -> ValueContainer<O>.Optional<V>) -> V? {
return (self.rawObject.primitiveValue(forKey: property(O.meta).keyPath) as! V.QueryableNativeType?)
.flatMap(V.cs_fromQueryableNativeType)
}
public func setPrimitiveValue<V>(_ value: V?, for property: (O) -> ValueContainer<O>.Optional<V>) {
self.rawObject.setPrimitiveValue(
value?.cs_toQueryableNativeType(),
forKey: property(O.meta).keyPath
)
}
public func value<V>(for property: (O) -> TransformableContainer<O>.Required<V>) -> V {
return self.rawObject.value(forKey: property(O.meta).keyPath)! as! V
}
public func setValue<V>(_ value: V, for property: (O) -> TransformableContainer<O>.Required<V>) {
self.rawObject.setValue(
value,
forKey: property(O.meta).keyPath
)
}
public func primitiveValue<V>(for property: (O) -> TransformableContainer<O>.Required<V>) -> V {
return self.rawObject.primitiveValue(forKey: property(O.meta).keyPath)! as! V
}
public func setPrimitiveValue<V>(_ value: V, for property: (O) -> TransformableContainer<O>.Required<V>) {
self.rawObject.setPrimitiveValue(
value,
forKey: property(O.meta).keyPath
)
}
public func value<V>(for property: (O) -> TransformableContainer<O>.Optional<V>) -> V? {
return self.rawObject.value(forKey: property(O.meta).keyPath) as! V?
}
public func setValue<V>(_ value: V?, for property: (O) -> TransformableContainer<O>.Optional<V>) {
self.rawObject.setValue(
value,
forKey: property(O.meta).keyPath
)
}
public func primitiveValue<V>(for property: (O) -> TransformableContainer<O>.Optional<V>) -> V? {
return self.rawObject.primitiveValue(forKey: property(O.meta).keyPath) as! V?
}
public func setPrimitiveValue<V>(_ value: V?, for property: (O) -> TransformableContainer<O>.Optional<V>) {
self.rawObject.setPrimitiveValue(
value,
forKey: property(O.meta).keyPath
)
}
}

View File

@@ -49,12 +49,6 @@ public struct QueryChainBuilder<O: DynamicObject, R: SelectResultType>: QueryCha
public var from: From<O> public var from: From<O>
public var select: Select<O, R> public var select: Select<O, R>
public var queryClauses: [QueryClause] = [] public var queryClauses: [QueryClause] = []
// MARK: Deprecated
@available(*, deprecated, renamed: "O")
public typealias D = O
} }

View File

@@ -27,44 +27,15 @@ import CoreData
import Foundation import Foundation
// MARK: - RelationshipContainer // MARK: - Deprecated
@available(*, deprecated, message: """
Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
""")
extension RelationshipContainer { extension RelationshipContainer {
// MARK: - ToManyOrdered
/**
The containing type for to-many ordered relationships. Any `CoreStoreObject` subclass can be a destination type. Inverse relationships should be declared from the destination type as well, using the `inverse:` argument for the relationship.
```
class Dog: CoreStoreObject {
let master = Relationship.ToOne<Person>("master")
}
class Person: CoreStoreObject {
let pets = Relationship.ToManyOrdered<Dog>("pets", inverse: { $0.master })
}
```
- Important: `Relationship.ToManyOrdered` properties are required to be stored properties. Computed properties will be ignored, including `lazy` and `weak` properties.
*/
public final class ToManyOrdered<D: CoreStoreObject>: ToManyRelationshipKeyPathStringConvertible, RelationshipProtocol { public final class ToManyOrdered<D: CoreStoreObject>: ToManyRelationshipKeyPathStringConvertible, RelationshipProtocol {
/**
Initializes the metadata for the relationship. All relationships require an "inverse", so updates to to this object's relationship are also reflected on its destination object. Make sure to declare this relationship's inverse relationship on its destination object. Due to Swift's compiler limitation, only one of the relationship and its inverse can declare an `inverse:` argument.
```
class Dog: CoreStoreObject {
let master = Relationship.ToOne<Person>("master")
}
class Person: CoreStoreObject {
let pets = Relationship.ToManyOrdered<Dog>("pets", inverse: { $0.master })
}
```
- parameter keyPath: the permanent name for this relationship.
- parameter minCount: the minimum number of objects in this relationship UNLESS THE RELATIONSHIP IS EMPTY. This means there might be zero objects in the relationship, which might be less than `minCount`. If the number of objects in the relationship do not satisfy `minCount` and `maxCount`, the transaction's commit (or auto-commit) would fail with a validation error.
- parameter maxCount: the maximum number of objects in this relationship. If the number of objects in the relationship do not satisfy `minCount` and `maxCount`, the transaction's commit (or auto-commit) would fail with a validation error.
- parameter deleteRule: defines what happens to relationship when an object is deleted. Valid values are `.nullify`, `.cascade`, and `.delete`. Defaults to `.nullify`.
- parameter versionHashModifier: used to mark or denote a relationship as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where the properties are unchanged but the format or content of its data are changed.)
- parameter renamingIdentifier: used to resolve naming conflicts between models. When creating an entity mapping between entities in two managed object models, a source entity property and a destination entity property that share the same identifier indicate that a property mapping should be configured to migrate from the source to the destination. If unset, the identifier will be the property's name.
- parameter affectedByKeyPaths: a set of key paths for properties whose values affect the value of the receiver. This is similar to `NSManagedObject.keyPathsForValuesAffectingValue(forKey:)`.
*/
public convenience init( public convenience init(
_ keyPath: KeyPathString, _ keyPath: KeyPathString,
minCount: Int = 0, minCount: Int = 0,
@@ -85,26 +56,7 @@ extension RelationshipContainer {
affectedByKeyPaths: affectedByKeyPaths() affectedByKeyPaths: affectedByKeyPaths()
) )
} }
/**
Initializes the metadata for the relationship. All relationships require an "inverse", so updates to to this object's relationship are also reflected on its destination object. Make sure to declare this relationship's inverse relationship on its destination object. Due to Swift's compiler limitation, only one of the relationship and its inverse can declare an `inverse:` argument.
```
class Dog: CoreStoreObject {
let master = Relationship.ToOne<Person>("master")
}
class Person: CoreStoreObject {
let pets = Relationship.ToManyOrdered<Dog>("pets", inverse: { $0.master })
}
```
- parameter keyPath: the permanent name for this relationship.
- parameter minCount: the minimum number of objects in this relationship UNLESS THE RELATIONSHIP IS EMPTY. This means there might be zero objects in the relationship, which might be less than `minCount`. If the number of objects in the relationship do not satisfy `minCount` and `maxCount`, the transaction's commit (or auto-commit) would fail with a validation error.
- parameter maxCount: the maximum number of objects in this relationship. If the number of objects in the relationship do not satisfy `minCount` and `maxCount`, the transaction's commit (or auto-commit) would fail with a validation error.
- parameter inverse: the inverse relationship that is declared for the destination object. All relationships require an "inverse", so updates to to this object's relationship are also reflected on its destination object.
- parameter deleteRule: defines what happens to relationship when an object is deleted. Valid values are `.nullify`, `.cascade`, and `.delete`. Defaults to `.nullify`.
- parameter versionHashModifier: used to mark or denote a relationship as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where the properties are unchanged but the format or content of its data are changed.)
- parameter renamingIdentifier: used to resolve naming conflicts between models. When creating an entity mapping between entities in two managed object models, a source entity property and a destination entity property that share the same identifier indicate that a property mapping should be configured to migrate from the source to the destination. If unset, the identifier will be the property's name.
- parameter affectedByKeyPaths: a set of key paths for properties whose values affect the value of the receiver. This is similar to `NSManagedObject.keyPathsForValuesAffectingValue(forKey:)`.
*/
public convenience init( public convenience init(
_ keyPath: KeyPathString, _ keyPath: KeyPathString,
minCount: Int = 0, minCount: Int = 0,
@@ -126,26 +78,7 @@ extension RelationshipContainer {
affectedByKeyPaths: affectedByKeyPaths() affectedByKeyPaths: affectedByKeyPaths()
) )
} }
/**
Initializes the metadata for the relationship. All relationships require an "inverse", so updates to to this object's relationship are also reflected on its destination object. Make sure to declare this relationship's inverse relationship on its destination object. Due to Swift's compiler limitation, only one of the relationship and its inverse can declare an `inverse:` argument.
```
class Dog: CoreStoreObject {
let master = Relationship.ToOne<Person>("master")
}
class Person: CoreStoreObject {
let pets = Relationship.ToManyOrdered<Dog>("pets", inverse: { $0.master })
}
```
- parameter keyPath: the permanent name for this relationship.
- parameter minCount: the minimum number of objects in this relationship UNLESS THE RELATIONSHIP IS EMPTY. This means there might be zero objects in the relationship, which might be less than `minCount`. If the number of objects in the relationship do not satisfy `minCount` and `maxCount`, the transaction's commit (or auto-commit) would fail with a validation error.
- parameter maxCount: the maximum number of objects in this relationship. If the number of objects in the relationship do not satisfy `minCount` and `maxCount`, the transaction's commit (or auto-commit) would fail with a validation error.
- parameter inverse: the inverse relationship that is declared for the destination object. All relationships require an "inverse", so updates to to this object's relationship are also reflected on its destination object.
- parameter deleteRule: defines what happens to relationship when an object is deleted. Valid values are `.nullify`, `.cascade`, and `.delete`. Defaults to `.nullify`.
- parameter versionHashModifier: used to mark or denote a relationship as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where the properties are unchanged but the format or content of its data are changed.)
- parameter renamingIdentifier: used to resolve naming conflicts between models. When creating an entity mapping between entities in two managed object models, a source entity property and a destination entity property that share the same identifier indicate that a property mapping should be configured to migrate from the source to the destination. If unset, the identifier will be the property's name.
- parameter affectedByKeyPaths: a set of key paths for properties whose values affect the value of the receiver. This is similar to `NSManagedObject.keyPathsForValuesAffectingValue(forKey:)`.
*/
public convenience init( public convenience init(
_ keyPath: KeyPathString, _ keyPath: KeyPathString,
minCount: Int = 0, minCount: Int = 0,
@@ -167,26 +100,7 @@ extension RelationshipContainer {
affectedByKeyPaths: affectedByKeyPaths() affectedByKeyPaths: affectedByKeyPaths()
) )
} }
/**
Initializes the metadata for the relationship. All relationships require an "inverse", so updates to to this object's relationship are also reflected on its destination object. Make sure to declare this relationship's inverse relationship on its destination object. Due to Swift's compiler limitation, only one of the relationship and its inverse can declare an `inverse:` argument.
```
class Dog: CoreStoreObject {
let master = Relationship.ToOne<Person>("master")
}
class Person: CoreStoreObject {
let pets = Relationship.ToManyOrdered<Dog>("pets", inverse: { $0.master })
}
```
- parameter keyPath: the permanent name for this relationship.
- parameter minCount: the minimum number of objects in this relationship UNLESS THE RELATIONSHIP IS EMPTY. This means there might be zero objects in the relationship, which might be less than `minCount`. If the number of objects in the relationship do not satisfy `minCount` and `maxCount`, the transaction's commit (or auto-commit) would fail with a validation error.
- parameter maxCount: the maximum number of objects in this relationship. If the number of objects in the relationship do not satisfy `minCount` and `maxCount`, the transaction's commit (or auto-commit) would fail with a validation error.
- parameter inverse: the inverse relationship that is declared for the destination object. All relationships require an "inverse", so updates to to this object's relationship are also reflected on its destination object.
- parameter deleteRule: defines what happens to relationship when an object is deleted. Valid values are `.nullify`, `.cascade`, and `.delete`. Defaults to `.nullify`.
- parameter versionHashModifier: used to mark or denote a relationship as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where the properties are unchanged but the format or content of its data are changed.)
- parameter renamingIdentifier: used to resolve naming conflicts between models. When creating an entity mapping between entities in two managed object models, a source entity property and a destination entity property that share the same identifier indicate that a property mapping should be configured to migrate from the source to the destination. If unset, the identifier will be the property's name.
- parameter affectedByKeyPaths: a set of key paths for properties whose values affect the value of the receiver. This is similar to `NSManagedObject.keyPathsForValuesAffectingValue(forKey:)`.
*/
public convenience init( public convenience init(
_ keyPath: KeyPathString, _ keyPath: KeyPathString,
minCount: Int = 0, minCount: Int = 0,
@@ -208,10 +122,7 @@ extension RelationshipContainer {
affectedByKeyPaths: affectedByKeyPaths() affectedByKeyPaths: affectedByKeyPaths()
) )
} }
/**
The relationship value
*/
public var value: ReturnValueType { public var value: ReturnValueType {
get { get {
@@ -223,34 +134,19 @@ extension RelationshipContainer {
self.nativeValue = NSOrderedSet(array: newValue.map({ $0.rawObject! })) self.nativeValue = NSOrderedSet(array: newValue.map({ $0.rawObject! }))
} }
} }
// MARK: AnyKeyPathStringConvertible
public var cs_keyPathString: String { public var cs_keyPathString: String {
return self.keyPath return self.keyPath
} }
// MARK: KeyPathStringConvertible
public typealias ObjectType = O public typealias ObjectType = O
public typealias DestinationValueType = D public typealias DestinationValueType = D
// MARK: RelationshipKeyPathStringConvertible
public typealias ReturnValueType = [DestinationValueType] public typealias ReturnValueType = [DestinationValueType]
// MARK: PropertyProtocol
internal let keyPath: KeyPathString internal let keyPath: KeyPathString
// MARK: RelationshipProtocol
internal let entityDescriptionValues: () -> RelationshipProtocol.EntityDescriptionValues internal let entityDescriptionValues: () -> RelationshipProtocol.EntityDescriptionValues
internal var rawObject: CoreStoreManagedObject? internal var rawObject: CoreStoreManagedObject?
@@ -303,9 +199,6 @@ extension RelationshipContainer {
return self.value.map({ $0.objectID() }) return self.value.map({ $0.objectID() })
} }
// MARK: Private
private init(keyPath: String, minCount: Int, maxCount: Int, inverseKeyPath: @escaping () -> String?, deleteRule: DeleteRule, versionHashModifier: @autoclosure @escaping () -> String?, renamingIdentifier: @autoclosure @escaping () -> String?, affectedByKeyPaths: @autoclosure @escaping () -> Set<String>) { private init(keyPath: String, minCount: Int, maxCount: Int, inverseKeyPath: @escaping () -> String?, deleteRule: DeleteRule, versionHashModifier: @autoclosure @escaping () -> String?, renamingIdentifier: @autoclosure @escaping () -> String?, affectedByKeyPaths: @autoclosure @escaping () -> Set<String>) {
self.keyPath = keyPath self.keyPath = keyPath
@@ -327,13 +220,11 @@ extension RelationshipContainer {
} }
} }
@available(*, deprecated, message: """
// MARK: - Convenience Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
""")
extension RelationshipContainer.ToManyOrdered: RandomAccessCollection { extension RelationshipContainer.ToManyOrdered: RandomAccessCollection {
// MARK: Sequence
public typealias Iterator = AnyIterator<D> public typealias Iterator = AnyIterator<D>
public func makeIterator() -> Iterator { public func makeIterator() -> Iterator {
@@ -342,9 +233,6 @@ extension RelationshipContainer.ToManyOrdered: RandomAccessCollection {
return AnyIterator({ iterator.next().flatMap({ D.cs_fromRaw(object: $0 as! NSManagedObject) }) }) return AnyIterator({ iterator.next().flatMap({ D.cs_fromRaw(object: $0 as! NSManagedObject) }) })
} }
// MARK: Collection
public typealias Index = Int public typealias Index = Int
public var startIndex: Index { public var startIndex: Index {
@@ -368,51 +256,21 @@ extension RelationshipContainer.ToManyOrdered: RandomAccessCollection {
} }
} }
@available(*, deprecated, message: """
// MARK: - Operations Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
""")
extension RelationshipContainer.ToManyOrdered { extension RelationshipContainer.ToManyOrdered {
/**
Assigns a sequence of objects to the relationship. The operation
```
person.pets .= [dog, cat]
```
is equivalent to
```
person.pets.value = [dog, cat]
```
*/
public static func .= <S: Sequence>(_ relationship: RelationshipContainer<O>.ToManyOrdered<D>, _ newValue: S) where S.Iterator.Element == D { public static func .= <S: Sequence>(_ relationship: RelationshipContainer<O>.ToManyOrdered<D>, _ newValue: S) where S.Iterator.Element == D {
relationship.nativeValue = NSOrderedSet(array: newValue.map({ $0.rawObject! })) relationship.nativeValue = NSOrderedSet(array: newValue.map({ $0.rawObject! }))
} }
/**
Assigns a sequence of objects to the relationship. The operation
```
person.pets .= anotherPerson.pets
```
is equivalent to
```
person.pets.value = anotherPerson.pets.value
```
*/
public static func .= <O2>(_ relationship: RelationshipContainer<O>.ToManyOrdered<D>, _ relationship2: RelationshipContainer<O2>.ToManyOrdered<D>) { public static func .= <O2>(_ relationship: RelationshipContainer<O>.ToManyOrdered<D>, _ relationship2: RelationshipContainer<O2>.ToManyOrdered<D>) {
relationship.nativeValue = relationship2.nativeValue relationship.nativeValue = relationship2.nativeValue
} }
/**
Compares equality between a relationship's objects and a collection of objects
```
if person.pets .== [dog, cat] { ... }
```
is equivalent to
```
if person.pets.value == [dog, cat] { ... }
```
*/
public static func .== <C: Collection>(_ relationship: RelationshipContainer<O>.ToManyOrdered<D>, _ collection: C) -> Bool where C.Iterator.Element == D { public static func .== <C: Collection>(_ relationship: RelationshipContainer<O>.ToManyOrdered<D>, _ collection: C) -> Bool where C.Iterator.Element == D {
return relationship.nativeValue.elementsEqual( return relationship.nativeValue.elementsEqual(
@@ -420,17 +278,7 @@ extension RelationshipContainer.ToManyOrdered {
by: { ($0 as! NSManagedObject) == $1 } by: { ($0 as! NSManagedObject) == $1 }
) )
} }
/**
Compares equality between a collection of objects and a relationship's objects
```
if [dog, cat] .== person.pets { ... }
```
is equivalent to
```
if [dog, cat] == person.pets.value { ... }
```
*/
public static func .== <C: Collection>(_ collection: C, _ relationship: RelationshipContainer<O>.ToManyOrdered<D>) -> Bool where C.Iterator.Element == D { public static func .== <C: Collection>(_ collection: C, _ relationship: RelationshipContainer<O>.ToManyOrdered<D>) -> Bool where C.Iterator.Element == D {
return relationship.nativeValue.elementsEqual( return relationship.nativeValue.elementsEqual(
@@ -438,17 +286,7 @@ extension RelationshipContainer.ToManyOrdered {
by: { ($0 as! NSManagedObject) == $1 } by: { ($0 as! NSManagedObject) == $1 }
) )
} }
/**
Compares equality between a relationship's objects and a collection of objects
```
if person.pets .== anotherPerson.pets { ... }
```
is equivalent to
```
if person.pets.value == anotherPerson.pets.value { ... }
```
*/
public static func .== <O2>(_ relationship: RelationshipContainer<O>.ToManyOrdered<D>, _ relationship2: RelationshipContainer<O2>.ToManyOrdered<D>) -> Bool { public static func .== <O2>(_ relationship: RelationshipContainer<O>.ToManyOrdered<D>, _ relationship2: RelationshipContainer<O2>.ToManyOrdered<D>) -> Bool {
return relationship.nativeValue == relationship2.nativeValue return relationship.nativeValue == relationship2.nativeValue

View File

@@ -27,45 +27,15 @@ import CoreData
import Foundation import Foundation
// MARK: - RelationshipContainer // MARK: - Deprecated
@available(*, deprecated, message: """
Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
""")
extension RelationshipContainer { extension RelationshipContainer {
// MARK: - ToManyUnordered
/**
The containing type for to-many unordered relationships. Any `CoreStoreObject` subclass can be a destination type. Inverse relationships should be declared from the destination type as well, using the `inverse:` argument for the relationship.
```
class Dog: CoreStoreObject {
let master = Relationship.ToOne<Person>("master")
}
class Person: CoreStoreObject {
let pets = Relationship.ToManyUnordered<Dog>("pets", inverse: { $0.master })
}
```
- Important: `Relationship.ToManyUnordered` properties are required to be stored properties. Computed properties will be ignored, including `lazy` and `weak` properties.
*/
public final class ToManyUnordered<D: CoreStoreObject>: ToManyRelationshipKeyPathStringConvertible, RelationshipProtocol { public final class ToManyUnordered<D: CoreStoreObject>: ToManyRelationshipKeyPathStringConvertible, RelationshipProtocol {
/**
Initializes the metadata for the relationship. All relationships require an "inverse", so updates to to this object's relationship are also reflected on its destination object. Make sure to declare this relationship's inverse relationship on its destination object. Due to Swift's compiler limitation, only one of the relationship and its inverse can declare an `inverse:` argument.
```
class Dog: CoreStoreObject {
let master = Relationship.ToOne<Person>("master")
}
class Person: CoreStoreObject {
let pets = Relationship.ToManyOrdered<Dog>("pets", inverse: { $0.master })
}
```
- parameter keyPath: the permanent name for this relationship.
- parameter minCount: the minimum number of objects in this relationship UNLESS THE RELATIONSHIP IS EMPTY. This means there might be zero objects in the relationship, which might be less than `minCount`. If the number of objects in the relationship do not satisfy `minCount` and `maxCount`, the transaction's commit (or auto-commit) would fail with a validation error.
- parameter maxCount: the maximum number of objects in this relationship. If the number of objects in the relationship do not satisfy `minCount` and `maxCount`, the transaction's commit (or auto-commit) would fail with a validation error.
- parameter inverse: the inverse relationship that is declared for the destination object. All relationships require an "inverse", so updates to to this object's relationship are also reflected on its destination object.
- parameter deleteRule: defines what happens to relationship when an object is deleted. Valid values are `.nullify`, `.cascade`, and `.delete`. Defaults to `.nullify`.
- parameter versionHashModifier: used to mark or denote a relationship as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where the properties are unchanged but the format or content of its data are changed.)
- parameter renamingIdentifier: used to resolve naming conflicts between models. When creating an entity mapping between entities in two managed object models, a source entity property and a destination entity property that share the same identifier indicate that a property mapping should be configured to migrate from the source to the destination. If unset, the identifier will be the property's name.
- parameter affectedByKeyPaths: a set of key paths for properties whose values affect the value of the receiver. This is similar to `NSManagedObject.keyPathsForValuesAffectingValue(forKey:)`.
*/
public convenience init( public convenience init(
_ keyPath: KeyPathString, _ keyPath: KeyPathString,
deleteRule: DeleteRule = .nullify, deleteRule: DeleteRule = .nullify,
@@ -86,26 +56,7 @@ extension RelationshipContainer {
affectedByKeyPaths: affectedByKeyPaths() affectedByKeyPaths: affectedByKeyPaths()
) )
} }
/**
Initializes the metadata for the relationship. All relationships require an "inverse", so updates to to this object's relationship are also reflected on its destination object. Make sure to declare this relationship's inverse relationship on its destination object. Due to Swift's compiler limitation, only one of the relationship and its inverse can declare an `inverse:` argument.
```
class Dog: CoreStoreObject {
let master = Relationship.ToOne<Person>("master")
}
class Person: CoreStoreObject {
let pets = Relationship.ToManyOrdered<Dog>("pets", inverse: { $0.master })
}
```
- parameter keyPath: the permanent name for this relationship.
- parameter minCount: the minimum number of objects in this relationship UNLESS THE RELATIONSHIP IS EMPTY. This means there might be zero objects in the relationship, which might be less than `minCount`. If the number of objects in the relationship do not satisfy `minCount` and `maxCount`, the transaction's commit (or auto-commit) would fail with a validation error.
- parameter maxCount: the maximum number of objects in this relationship. If the number of objects in the relationship do not satisfy `minCount` and `maxCount`, the transaction's commit (or auto-commit) would fail with a validation error.
- parameter inverse: the inverse relationship that is declared for the destination object. All relationships require an "inverse", so updates to to this object's relationship are also reflected on its destination object.
- parameter deleteRule: defines what happens to relationship when an object is deleted. Valid values are `.nullify`, `.cascade`, and `.delete`. Defaults to `.nullify`.
- parameter versionHashModifier: used to mark or denote a relationship as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where the properties are unchanged but the format or content of its data are changed.)
- parameter renamingIdentifier: used to resolve naming conflicts between models. When creating an entity mapping between entities in two managed object models, a source entity property and a destination entity property that share the same identifier indicate that a property mapping should be configured to migrate from the source to the destination. If unset, the identifier will be the property's name.
- parameter affectedByKeyPaths: a set of key paths for properties whose values affect the value of the receiver. This is similar to `NSManagedObject.keyPathsForValuesAffectingValue(forKey:)`.
*/
public convenience init( public convenience init(
_ keyPath: KeyPathString, _ keyPath: KeyPathString,
inverse: @escaping (D) -> RelationshipContainer<D>.ToOne<O>, inverse: @escaping (D) -> RelationshipContainer<D>.ToOne<O>,
@@ -127,26 +78,7 @@ extension RelationshipContainer {
affectedByKeyPaths: affectedByKeyPaths() affectedByKeyPaths: affectedByKeyPaths()
) )
} }
/**
Initializes the metadata for the relationship. All relationships require an "inverse", so updates to to this object's relationship are also reflected on its destination object. Make sure to declare this relationship's inverse relationship on its destination object. Due to Swift's compiler limitation, only one of the relationship and its inverse can declare an `inverse:` argument.
```
class Dog: CoreStoreObject {
let master = Relationship.ToOne<Person>("master")
}
class Person: CoreStoreObject {
let pets = Relationship.ToManyOrdered<Dog>("pets", inverse: { $0.master })
}
```
- parameter keyPath: the permanent name for this relationship.
- parameter minCount: the minimum number of objects in this relationship UNLESS THE RELATIONSHIP IS EMPTY. This means there might be zero objects in the relationship, which might be less than `minCount`. If the number of objects in the relationship do not satisfy `minCount` and `maxCount`, the transaction's commit (or auto-commit) would fail with a validation error.
- parameter maxCount: the maximum number of objects in this relationship. If the number of objects in the relationship do not satisfy `minCount` and `maxCount`, the transaction's commit (or auto-commit) would fail with a validation error.
- parameter inverse: the inverse relationship that is declared for the destination object. All relationships require an "inverse", so updates to to this object's relationship are also reflected on its destination object.
- parameter deleteRule: defines what happens to relationship when an object is deleted. Valid values are `.nullify`, `.cascade`, and `.delete`. Defaults to `.nullify`.
- parameter versionHashModifier: used to mark or denote a relationship as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where the properties are unchanged but the format or content of its data are changed.)
- parameter renamingIdentifier: used to resolve naming conflicts between models. When creating an entity mapping between entities in two managed object models, a source entity property and a destination entity property that share the same identifier indicate that a property mapping should be configured to migrate from the source to the destination. If unset, the identifier will be the property's name.
- parameter affectedByKeyPaths: a set of key paths for properties whose values affect the value of the receiver. This is similar to `NSManagedObject.keyPathsForValuesAffectingValue(forKey:)`.
*/
public convenience init( public convenience init(
_ keyPath: KeyPathString, _ keyPath: KeyPathString,
inverse: @escaping (D) -> RelationshipContainer<D>.ToManyOrdered<O>, inverse: @escaping (D) -> RelationshipContainer<D>.ToManyOrdered<O>,
@@ -168,26 +100,7 @@ extension RelationshipContainer {
affectedByKeyPaths: affectedByKeyPaths() affectedByKeyPaths: affectedByKeyPaths()
) )
} }
/**
Initializes the metadata for the relationship. All relationships require an "inverse", so updates to to this object's relationship are also reflected on its destination object. Make sure to declare this relationship's inverse relationship on its destination object. Due to Swift's compiler limitation, only one of the relationship and its inverse can declare an `inverse:` argument.
```
class Dog: CoreStoreObject {
let master = Relationship.ToOne<Person>("master")
}
class Person: CoreStoreObject {
let pets = Relationship.ToManyOrdered<Dog>("pets", inverse: { $0.master })
}
```
- parameter keyPath: the permanent name for this relationship.
- parameter minCount: the minimum number of objects in this relationship UNLESS THE RELATIONSHIP IS EMPTY. This means there might be zero objects in the relationship, which might be less than `minCount`. If the number of objects in the relationship do not satisfy `minCount` and `maxCount`, the transaction's commit (or auto-commit) would fail with a validation error.
- parameter maxCount: the maximum number of objects in this relationship. If the number of objects in the relationship do not satisfy `minCount` and `maxCount`, the transaction's commit (or auto-commit) would fail with a validation error.
- parameter inverse: the inverse relationship that is declared for the destination object. All relationships require an "inverse", so updates to to this object's relationship are also reflected on its destination object.
- parameter deleteRule: defines what happens to relationship when an object is deleted. Valid values are `.nullify`, `.cascade`, and `.delete`. Defaults to `.nullify`.
- parameter versionHashModifier: used to mark or denote a relationship as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where the properties are unchanged but the format or content of its data are changed.)
- parameter renamingIdentifier: used to resolve naming conflicts between models. When creating an entity mapping between entities in two managed object models, a source entity property and a destination entity property that share the same identifier indicate that a property mapping should be configured to migrate from the source to the destination. If unset, the identifier will be the property's name.
- parameter affectedByKeyPaths: a set of key paths for properties whose values affect the value of the receiver. This is similar to `NSManagedObject.keyPathsForValuesAffectingValue(forKey:)`.
*/
public convenience init( public convenience init(
_ keyPath: KeyPathString, _ keyPath: KeyPathString,
inverse: @escaping (D) -> RelationshipContainer<D>.ToManyUnordered<O>, inverse: @escaping (D) -> RelationshipContainer<D>.ToManyUnordered<O>,
@@ -209,10 +122,7 @@ extension RelationshipContainer {
affectedByKeyPaths: affectedByKeyPaths() affectedByKeyPaths: affectedByKeyPaths()
) )
} }
/**
The relationship value
*/
public var value: ReturnValueType { public var value: ReturnValueType {
get { get {
@@ -225,33 +135,18 @@ extension RelationshipContainer {
} }
} }
// MARK: AnyKeyPathStringConvertible
public var cs_keyPathString: String { public var cs_keyPathString: String {
return self.keyPath return self.keyPath
} }
// MARK: KeyPathStringConvertible
public typealias ObjectType = O public typealias ObjectType = O
public typealias DestinationValueType = D public typealias DestinationValueType = D
// MARK: RelationshipKeyPathStringConvertible
public typealias ReturnValueType = Set<DestinationValueType> public typealias ReturnValueType = Set<DestinationValueType>
// MARK: PropertyProtocol
internal let keyPath: KeyPathString internal let keyPath: KeyPathString
// MARK: RelationshipProtocol
internal let entityDescriptionValues: () -> RelationshipProtocol.EntityDescriptionValues internal let entityDescriptionValues: () -> RelationshipProtocol.EntityDescriptionValues
internal var rawObject: CoreStoreManagedObject? internal var rawObject: CoreStoreManagedObject?
@@ -304,9 +199,6 @@ extension RelationshipContainer {
return Set(self.value.map({ $0.objectID() })) return Set(self.value.map({ $0.objectID() }))
} }
// MARK: Private
private init(keyPath: KeyPathString, inverseKeyPath: @escaping () -> KeyPathString?, deleteRule: DeleteRule, minCount: Int, maxCount: Int, versionHashModifier: @autoclosure @escaping () -> String?, renamingIdentifier: @autoclosure @escaping () -> String?, affectedByKeyPaths: @autoclosure @escaping () -> Set<String>) { private init(keyPath: KeyPathString, inverseKeyPath: @escaping () -> KeyPathString?, deleteRule: DeleteRule, minCount: Int, maxCount: Int, versionHashModifier: @autoclosure @escaping () -> String?, renamingIdentifier: @autoclosure @escaping () -> String?, affectedByKeyPaths: @autoclosure @escaping () -> Set<String>) {
self.keyPath = keyPath self.keyPath = keyPath
@@ -328,30 +220,21 @@ extension RelationshipContainer {
} }
} }
@available(*, deprecated, message: """
// MARK: - Convenience Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
""")
extension RelationshipContainer.ToManyUnordered: Sequence { extension RelationshipContainer.ToManyUnordered: Sequence {
/**
The number of elements in the set.
*/
public var count: Int { public var count: Int {
return self.nativeValue.count return self.nativeValue.count
} }
/**
A Boolean value indicating whether the range contains no elements.
*/
public var isEmpty: Bool { public var isEmpty: Bool {
return self.nativeValue.count == 0 return self.nativeValue.count == 0
} }
// MARK: Sequence
public typealias Iterator = AnyIterator<D> public typealias Iterator = AnyIterator<D>
public func makeIterator() -> Iterator { public func makeIterator() -> Iterator {
@@ -361,96 +244,36 @@ extension RelationshipContainer.ToManyUnordered: Sequence {
} }
} }
@available(*, deprecated, message: """
// MARK: - Operations Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
""")
extension RelationshipContainer.ToManyUnordered { extension RelationshipContainer.ToManyUnordered {
/**
Assigns a sequence of objects to the relationship. The operation
```
person.pets .= [dog, cat]
```
is equivalent to
```
person.pets.value = [dog, cat]
```
*/
public static func .= <S: Sequence>(_ relationship: RelationshipContainer<O>.ToManyUnordered<D>, _ newValue: S) where S.Iterator.Element == D { public static func .= <S: Sequence>(_ relationship: RelationshipContainer<O>.ToManyUnordered<D>, _ newValue: S) where S.Iterator.Element == D {
relationship.nativeValue = NSSet(array: newValue.map({ $0.rawObject! })) relationship.nativeValue = NSSet(array: newValue.map({ $0.rawObject! }))
} }
/**
Assigns a sequence of objects to the relationship. The operation
```
person.pets .= anotherPerson.pets
```
is equivalent to
```
person.pets.value = anotherPerson.pets.value
```
*/
public static func .= <O2>(_ relationship: RelationshipContainer<O>.ToManyUnordered<D>, _ relationship2: RelationshipContainer<O2>.ToManyUnordered<D>) { public static func .= <O2>(_ relationship: RelationshipContainer<O>.ToManyUnordered<D>, _ relationship2: RelationshipContainer<O2>.ToManyUnordered<D>) {
relationship.nativeValue = relationship2.nativeValue relationship.nativeValue = relationship2.nativeValue
} }
/**
Assigns a sequence of objects to the relationship. The operation
```
person.pets .= anotherPerson.pets
```
is equivalent to
```
person.pets.value = anotherPerson.pets.value
```
*/
public static func .= <O2>(_ relationship: RelationshipContainer<O>.ToManyUnordered<D>, _ relationship2: RelationshipContainer<O2>.ToManyOrdered<D>) { public static func .= <O2>(_ relationship: RelationshipContainer<O>.ToManyUnordered<D>, _ relationship2: RelationshipContainer<O2>.ToManyOrdered<D>) {
relationship.nativeValue = NSSet(set: relationship2.nativeValue.set) relationship.nativeValue = NSSet(set: relationship2.nativeValue.set)
} }
/**
Compares the if the relationship's objects and a set of objects have the same elements.
```
if person.pets .== Set<Animal>([dog, cat]) { ... }
```
is equivalent to
```
if person.pets.value == Set<Animal>([dog, cat]) { ... }
```
*/
public static func .== (_ relationship: RelationshipContainer<O>.ToManyUnordered<D>, _ set: Set<D>) -> Bool { public static func .== (_ relationship: RelationshipContainer<O>.ToManyUnordered<D>, _ set: Set<D>) -> Bool {
return relationship.nativeValue.isEqual(to: Set(set.map({ $0.rawObject! }))) return relationship.nativeValue.isEqual(to: Set(set.map({ $0.rawObject! })))
} }
/**
Compares if a set of objects and a relationship's objects have the same elements.
```
if Set<Animal>([dog, cat]) .== person.pets { ... }
```
is equivalent to
```
if Set<Animal>([dog, cat]) == person.pets.value { ... }
```
*/
public static func .== (_ set: Set<D>, _ relationship: RelationshipContainer<O>.ToManyUnordered<D>) -> Bool { public static func .== (_ set: Set<D>, _ relationship: RelationshipContainer<O>.ToManyUnordered<D>) -> Bool {
return relationship.nativeValue.isEqual(to: Set(set.map({ $0.rawObject! }))) return relationship.nativeValue.isEqual(to: Set(set.map({ $0.rawObject! })))
} }
/**
Compares if a relationship's objects and another relationship's objects have the same elements.
```
if person.pets .== anotherPerson.pets { ... }
```
is equivalent to
```
if person.pets.value == anotherPerson.pets.value { ... }
```
*/
public static func .== <O2>(_ relationship: RelationshipContainer<O>.ToManyUnordered<D>, _ relationship2: RelationshipContainer<O2>.ToManyUnordered<D>) -> Bool { public static func .== <O2>(_ relationship: RelationshipContainer<O>.ToManyUnordered<D>, _ relationship2: RelationshipContainer<O2>.ToManyUnordered<D>) -> Bool {
return relationship.nativeValue.isEqual(relationship2.nativeValue) return relationship.nativeValue.isEqual(relationship2.nativeValue)

View File

@@ -27,42 +27,15 @@ import CoreData
import Foundation import Foundation
// MARK: - RelationshipContainer // MARK: - Deprecated
@available(*, deprecated, message: """
Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
""")
extension RelationshipContainer { extension RelationshipContainer {
// MARK: - ToOne
/**
The containing type for to-one relationships. Any `CoreStoreObject` subclass can be a destination type. Inverse relationships should be declared from the destination type as well, using the `inverse:` argument for the relationship.
```
class Dog: CoreStoreObject {
let master = Relationship.ToOne<Person>("master")
}
class Person: CoreStoreObject {
let pets = Relationship.ToManyUnordered<Dog>("pets", inverse: { $0.master })
}
```
- Important: `Relationship.ToOne` properties are required to be stored properties. Computed properties will be ignored, including `lazy` and `weak` properties.
*/
public final class ToOne<D: CoreStoreObject>: RelationshipKeyPathStringConvertible, RelationshipProtocol { public final class ToOne<D: CoreStoreObject>: RelationshipKeyPathStringConvertible, RelationshipProtocol {
/**
Initializes the metadata for the relationship. All relationships require an "inverse", so updates to to this object's relationship are also reflected on its destination object. Make sure to declare this relationship's inverse relationship on its destination object. Due to Swift's compiler limitation, only one of the relationship and its inverse can declare an `inverse:` argument.
```
class Dog: CoreStoreObject {
let master = Relationship.ToOne<Person>("master")
}
class Person: CoreStoreObject {
let pets = Relationship.ToManyUnordered<Dog>("pets", inverse: { $0.master })
}
```
- parameter keyPath: the permanent name for this relationship.
- parameter deleteRule: defines what happens to relationship when an object is deleted. Valid values are `.nullify`, `.cascade`, and `.delete`. Defaults to `.nullify`.
- parameter versionHashModifier: used to mark or denote a relationship as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where the properties are unchanged but the format or content of its data are changed.)
- parameter renamingIdentifier: used to resolve naming conflicts between models. When creating an entity mapping between entities in two managed object models, a source entity property and a destination entity property that share the same identifier indicate that a property mapping should be configured to migrate from the source to the destination. If unset, the identifier will be the property's name.
- parameter affectedByKeyPaths: a set of key paths for properties whose values affect the value of the receiver. This is similar to `NSManagedObject.keyPathsForValuesAffectingValue(forKey:)`.
*/
public convenience init( public convenience init(
_ keyPath: KeyPathString, _ keyPath: KeyPathString,
deleteRule: DeleteRule = .nullify, deleteRule: DeleteRule = .nullify,
@@ -80,23 +53,6 @@ extension RelationshipContainer {
) )
} }
/**
Initializes the metadata for the relationship. All relationships require an "inverse", so updates to to this object's relationship are also reflected on its destination object. Make sure to declare this relationship's inverse relationship on its destination object. Due to Swift's compiler limitation, only one of the relationship and its inverse can declare an `inverse:` argument.
```
class Dog: CoreStoreObject {
let master = Relationship.ToOne<Person>("master")
}
class Person: CoreStoreObject {
let pets = Relationship.ToManyUnordered<Dog>("pets", inverse: { $0.master })
}
```
- parameter keyPath: the permanent name for this relationship.
- parameter inverse: the inverse relationship that is declared for the destination object. All relationships require an "inverse", so updates to to this object's relationship are also reflected on its destination object.
- parameter deleteRule: defines what happens to relationship when an object is deleted. Valid values are `.nullify`, `.cascade`, and `.delete`. Defaults to `.nullify`.
- parameter versionHashModifier: used to mark or denote a relationship as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where the properties are unchanged but the format or content of its data are changed.)
- parameter renamingIdentifier: used to resolve naming conflicts between models. When creating an entity mapping between entities in two managed object models, a source entity property and a destination entity property that share the same identifier indicate that a property mapping should be configured to migrate from the source to the destination. If unset, the identifier will be the property's name.
- parameter affectedByKeyPaths: a set of key paths for properties whose values affect the value of the receiver. This is similar to `NSManagedObject.keyPathsForValuesAffectingValue(forKey:)`.
*/
public convenience init( public convenience init(
_ keyPath: KeyPathString, _ keyPath: KeyPathString,
inverse: @escaping (D) -> RelationshipContainer<D>.ToOne<O>, inverse: @escaping (D) -> RelationshipContainer<D>.ToOne<O>,
@@ -114,24 +70,7 @@ extension RelationshipContainer {
affectedByKeyPaths: affectedByKeyPaths() affectedByKeyPaths: affectedByKeyPaths()
) )
} }
/**
Initializes the metadata for the relationship. All relationships require an "inverse", so updates to to this object's relationship are also reflected on its destination object. Make sure to declare this relationship's inverse relationship on its destination object. Due to Swift's compiler limitation, only one of the relationship and its inverse can declare an `inverse:` argument.
```
class Dog: CoreStoreObject {
let master = Relationship.ToOne<Person>("master")
}
class Person: CoreStoreObject {
let pets = Relationship.ToManyUnordered<Dog>("pets", inverse: { $0.master })
}
```
- parameter keyPath: the permanent name for this relationship.
- parameter inverse: the inverse relationship that is declared for the destination object. All relationships require an "inverse", so updates to to this object's relationship are also reflected on its destination object.
- parameter deleteRule: defines what happens to relationship when an object is deleted. Valid values are `.nullify`, `.cascade`, and `.delete`. Defaults to `.nullify`.
- parameter versionHashModifier: used to mark or denote a relationship as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where the properties are unchanged but the format or content of its data are changed.)
- parameter renamingIdentifier: used to resolve naming conflicts between models. When creating an entity mapping between entities in two managed object models, a source entity property and a destination entity property that share the same identifier indicate that a property mapping should be configured to migrate from the source to the destination. If unset, the identifier will be the property's name.
- parameter affectedByKeyPaths: a set of key paths for properties whose values affect the value of the receiver. This is similar to `NSManagedObject.keyPathsForValuesAffectingValue(forKey:)`.
*/
public convenience init( public convenience init(
_ keyPath: KeyPathString, _ keyPath: KeyPathString,
inverse: @escaping (D) -> RelationshipContainer<D>.ToManyOrdered<O>, inverse: @escaping (D) -> RelationshipContainer<D>.ToManyOrdered<O>,
@@ -149,24 +88,7 @@ extension RelationshipContainer {
affectedByKeyPaths: affectedByKeyPaths() affectedByKeyPaths: affectedByKeyPaths()
) )
} }
/**
Initializes the metadata for the relationship. All relationships require an "inverse", so updates to to this object's relationship are also reflected on its destination object. Make sure to declare this relationship's inverse relationship on its destination object. Due to Swift's compiler limitation, only one of the relationship and its inverse can declare an `inverse:` argument.
```
class Dog: CoreStoreObject {
let master = Relationship.ToOne<Person>("master")
}
class Person: CoreStoreObject {
let pets = Relationship.ToManyUnordered<Dog>("pets", inverse: { $0.master })
}
```
- parameter keyPath: the permanent name for this relationship.
- parameter inverse: the inverse relationship that is declared for the destination object. All relationships require an "inverse", so updates to to this object's relationship are also reflected on its destination object.
- parameter deleteRule: defines what happens to relationship when an object is deleted. Valid values are `.nullify`, `.cascade`, and `.delete`. Defaults to `.nullify`.
- parameter versionHashModifier: used to mark or denote a relationship as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where the properties are unchanged but the format or content of its data are changed.)
- parameter renamingIdentifier: used to resolve naming conflicts between models. When creating an entity mapping between entities in two managed object models, a source entity property and a destination entity property that share the same identifier indicate that a property mapping should be configured to migrate from the source to the destination. If unset, the identifier will be the property's name.
- parameter affectedByKeyPaths: a set of key paths for properties whose values affect the value of the receiver. This is similar to `NSManagedObject.keyPathsForValuesAffectingValue(forKey:)`.
*/
public convenience init( public convenience init(
_ keyPath: KeyPathString, _ keyPath: KeyPathString,
inverse: @escaping (D) -> RelationshipContainer<D>.ToManyUnordered<O>, inverse: @escaping (D) -> RelationshipContainer<D>.ToManyUnordered<O>,
@@ -184,10 +106,7 @@ extension RelationshipContainer {
affectedByKeyPaths: affectedByKeyPaths() affectedByKeyPaths: affectedByKeyPaths()
) )
} }
/**
The relationship value
*/
public var value: ReturnValueType { public var value: ReturnValueType {
get { get {
@@ -200,33 +119,18 @@ extension RelationshipContainer {
} }
} }
// MARK: AnyKeyPathStringConvertible
public var cs_keyPathString: String { public var cs_keyPathString: String {
return self.keyPath return self.keyPath
} }
// MARK: KeyPathStringConvertible
public typealias ObjectType = O public typealias ObjectType = O
public typealias DestinationValueType = D public typealias DestinationValueType = D
// MARK: RelationshipKeyPathStringConvertible
public typealias ReturnValueType = DestinationValueType? public typealias ReturnValueType = DestinationValueType?
// MARK: PropertyProtocol
internal let keyPath: KeyPathString internal let keyPath: KeyPathString
// MARK: RelationshipProtocol
internal let entityDescriptionValues: () -> RelationshipProtocol.EntityDescriptionValues internal let entityDescriptionValues: () -> RelationshipProtocol.EntityDescriptionValues
internal var rawObject: CoreStoreManagedObject? internal var rawObject: CoreStoreManagedObject?
@@ -302,80 +206,31 @@ extension RelationshipContainer {
} }
} }
@available(*, deprecated, message: """
// MARK: - Operations Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
""")
extension RelationshipContainer.ToOne { extension RelationshipContainer.ToOne {
/**
Assigns an object to the relationship. The operation
```
dog.master .= person
```
is equivalent to
```
dog.master.value = person
```
*/
public static func .= (_ relationship: RelationshipContainer<O>.ToOne<D>, _ newObject: D?) { public static func .= (_ relationship: RelationshipContainer<O>.ToOne<D>, _ newObject: D?) {
relationship.nativeValue = newObject?.cs_toRaw() relationship.nativeValue = newObject?.cs_toRaw()
} }
/**
Assigns an object from another relationship. The operation
```
dog.master .= anotherDog.master
```
is equivalent to
```
dog.master.value = anotherDog.master.value
```
*/
public static func .= <O2>(_ relationship: RelationshipContainer<O>.ToOne<D>, _ relationship2: RelationshipContainer<O2>.ToOne<D>) { public static func .= <O2>(_ relationship: RelationshipContainer<O>.ToOne<D>, _ relationship2: RelationshipContainer<O2>.ToOne<D>) {
relationship.nativeValue = relationship2.nativeValue relationship.nativeValue = relationship2.nativeValue
} }
/**
Compares equality between a relationship's object and another object
```
if dog.master .== person { ... }
```
is equivalent to
```
if dog.master.value == person { ... }
```
*/
public static func .== (_ relationship: RelationshipContainer<O>.ToOne<D>, _ object: D?) -> Bool { public static func .== (_ relationship: RelationshipContainer<O>.ToOne<D>, _ object: D?) -> Bool {
return relationship.nativeValue == object?.cs_toRaw() return relationship.nativeValue == object?.cs_toRaw()
} }
/**
Compares equality between an object and a relationship's object
```
if dog.master .== person { ... }
```
is equivalent to
```
if dog.master.value == person { ... }
```
*/
public static func .== (_ object: D?, _ relationship: RelationshipContainer<O>.ToOne<D>) -> Bool { public static func .== (_ object: D?, _ relationship: RelationshipContainer<O>.ToOne<D>) -> Bool {
return object?.cs_toRaw() == relationship.nativeValue return object?.cs_toRaw() == relationship.nativeValue
} }
/**
Compares equality between a relationship's object and another relationship's object
```
if dog.master .== person { ... }
```
is equivalent to
```
if dog.master.value == person { ... }
```
*/
public static func .== <O2>(_ relationship: RelationshipContainer<O>.ToOne<D>, _ relationship2: RelationshipContainer<O2>.ToOne<D>) -> Bool { public static func .== <O2>(_ relationship: RelationshipContainer<O>.ToOne<D>, _ relationship2: RelationshipContainer<O2>.ToOne<D>) -> Bool {
return relationship.nativeValue == relationship2.nativeValue return relationship.nativeValue == relationship2.nativeValue

View File

@@ -27,46 +27,21 @@ import CoreData
import Foundation import Foundation
// MARK: - DynamicObject // MARK: - Deprecated
extension DynamicObject where Self: CoreStoreObject { extension DynamicObject where Self: CoreStoreObject {
/** @available(*, deprecated, message: """
The containing type for relationships. `Relationship`s can be any `CoreStoreObject` subclass. Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
``` """)
class Dog: CoreStoreObject {
let master = Relationship.ToOne<Person>("master")
}
class Person: CoreStoreObject {
let pets = Relationship.ToManyUnordered<Dog>("pets", inverse: { $0.master })
}
```
- Important: `Relationship` properties are required to be stored properties. Computed properties will be ignored, including `lazy` and `weak` properties.
*/
public typealias Relationship = RelationshipContainer<Self> public typealias Relationship = RelationshipContainer<Self>
} }
@available(*, deprecated, message: """
// MARK: - RelationshipContainer Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
""")
/**
The containing type for relationships. Use the `DynamicObject.Relationship` typealias instead for shorter syntax.
```
class Dog: CoreStoreObject {
let master = Relationship.ToOne<Person>("master")
}
class Person: CoreStoreObject {
let pets = Relationship.ToManyUnordered<Dog>("pets", inverse: { $0.master })
}
```
*/
public enum RelationshipContainer<O: CoreStoreObject> { public enum RelationshipContainer<O: CoreStoreObject> {
// MARK: - DeleteRule
/**
These constants define what happens to relationships when an object is deleted.
*/
public enum DeleteRule { public enum DeleteRule {
// MARK: Public // MARK: Public

View File

@@ -75,24 +75,6 @@ public struct SectionBy<O: DynamicObject> {
internal let sectionKeyPath: KeyPathString internal let sectionKeyPath: KeyPathString
internal let sectionIndexTransformer: (_ sectionName: String?) -> String? internal let sectionIndexTransformer: (_ sectionName: String?) -> String?
// MARK: Deprecated
@available(*, deprecated, renamed: "O")
public typealias D = O
@available(*, deprecated, renamed: "init(_:sectionIndexTransformer:)")
public init(
_ sectionKeyPath: KeyPathString,
_ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?
) {
self.init(
sectionKeyPath,
sectionIndexTransformer: sectionIndexTransformer
)
}
} }
@@ -130,21 +112,6 @@ extension SectionBy where O: NSManagedObject {
sectionIndexTransformer: sectionIndexTransformer sectionIndexTransformer: sectionIndexTransformer
) )
} }
// MARK: Deprecated
@available(*, deprecated, renamed: "init(_:sectionIndexTransformer:)")
public init<T>(
_ sectionKeyPath: KeyPath<O, T>,
_ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?
) {
self.init(
sectionKeyPath._kvcKeyPathString!,
sectionIndexTransformer: sectionIndexTransformer
)
}
} }
@@ -190,12 +157,70 @@ extension SectionBy where O: CoreStoreObject {
sectionIndexTransformer: { _ in nil } sectionIndexTransformer: { _ in nil }
) )
} }
/** /**
Initializes a `SectionBy` clause with the key path to use to group `ListMonitor` objects into sections Initializes a `SectionBy` clause with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section index title
- Important: Some utilities (such as `ListMonitor`s) may keep `SectionBy`s in memory and may thus introduce retain cycles if reference captures are not handled properly.
- parameter sectionKeyPath: the key path to use to group the objects into sections - parameter sectionKeyPath: the key path to use to group the objects into sections
- parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section index title
*/ */
public init<T>(
_ sectionKeyPath: KeyPath<O, FieldContainer<O>.Stored<T>>,
sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?
) {
self.init(
O.meta[keyPath: sectionKeyPath].keyPath,
sectionIndexTransformer: sectionIndexTransformer
)
}
/**
Initializes a `SectionBy` clause with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section index title
- Important: Some utilities (such as `ListMonitor`s) may keep `SectionBy`s in memory and may thus introduce retain cycles if reference captures are not handled properly.
- parameter sectionKeyPath: the key path to use to group the objects into sections
- parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section index title
*/
public init<T>(
_ sectionKeyPath: KeyPath<O, FieldContainer<O>.Virtual<T>>,
sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?
) {
self.init(
O.meta[keyPath: sectionKeyPath].keyPath,
sectionIndexTransformer: sectionIndexTransformer
)
}
/**
Initializes a `SectionBy` clause with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section index title
- Important: Some utilities (such as `ListMonitor`s) may keep `SectionBy`s in memory and may thus introduce retain cycles if reference captures are not handled properly.
- parameter sectionKeyPath: the key path to use to group the objects into sections
- parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section index title
*/
public init<T>(
_ sectionKeyPath: KeyPath<O, FieldContainer<O>.Coded<T>>,
sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?
) {
self.init(
O.meta[keyPath: sectionKeyPath].keyPath,
sectionIndexTransformer: sectionIndexTransformer
)
}
}
// MARK: - Deprecated
@available(*, deprecated, message: """
Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
""")
extension SectionBy {
public init<T>(_ sectionKeyPath: KeyPath<O, ValueContainer<O>.Required<T>>) { public init<T>(_ sectionKeyPath: KeyPath<O, ValueContainer<O>.Required<T>>) {
self.init( self.init(
@@ -204,11 +229,6 @@ extension SectionBy where O: CoreStoreObject {
) )
} }
/**
Initializes a `SectionBy` clause with the key path to use to group `ListMonitor` objects into sections
- parameter sectionKeyPath: the key path to use to group the objects into sections
*/
public init<T>(_ sectionKeyPath: KeyPath<O, ValueContainer<O>.Optional<T>>) { public init<T>(_ sectionKeyPath: KeyPath<O, ValueContainer<O>.Optional<T>>) {
self.init( self.init(
@@ -217,11 +237,6 @@ extension SectionBy where O: CoreStoreObject {
) )
} }
/**
Initializes a `SectionBy` clause with the key path to use to group `ListMonitor` objects into sections
- parameter sectionKeyPath: the key path to use to group the objects into sections
*/
public init<T>(_ sectionKeyPath: KeyPath<O, TransformableContainer<O>.Required<T>>) { public init<T>(_ sectionKeyPath: KeyPath<O, TransformableContainer<O>.Required<T>>) {
self.init( self.init(
@@ -230,11 +245,6 @@ extension SectionBy where O: CoreStoreObject {
) )
} }
/**
Initializes a `SectionBy` clause with the key path to use to group `ListMonitor` objects into sections
- parameter sectionKeyPath: the key path to use to group the objects into sections
*/
public init<T>(_ sectionKeyPath: KeyPath<O, TransformableContainer<O>.Optional<T>>) { public init<T>(_ sectionKeyPath: KeyPath<O, TransformableContainer<O>.Optional<T>>) {
self.init( self.init(
@@ -243,13 +253,6 @@ extension SectionBy where O: CoreStoreObject {
) )
} }
/**
Initializes a `SectionBy` clause with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section index title
- Important: Some utilities (such as `ListMonitor`s) may keep `SectionBy`s in memory and may thus introduce retain cycles if reference captures are not handled properly.
- parameter sectionKeyPath: the key path to use to group the objects into sections
- parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section index title
*/
public init<T>( public init<T>(
_ sectionKeyPath: KeyPath<O, ValueContainer<O>.Required<T>>, _ sectionKeyPath: KeyPath<O, ValueContainer<O>.Required<T>>,
sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?
@@ -260,68 +263,7 @@ extension SectionBy where O: CoreStoreObject {
sectionIndexTransformer: sectionIndexTransformer sectionIndexTransformer: sectionIndexTransformer
) )
} }
/**
Initializes a `SectionBy` clause with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section index title
- Important: Some utilities (such as `ListMonitor`s) may keep `SectionBy`s in memory and may thus introduce retain cycles if reference captures are not handled properly.
- parameter sectionKeyPath: the key path to use to group the objects into sections
- parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section index title
*/
public init<T>(
_ sectionKeyPath: KeyPath<O, FieldContainer<O>.Stored<T>>,
sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?
) {
self.init(
O.meta[keyPath: sectionKeyPath].keyPath,
sectionIndexTransformer: sectionIndexTransformer
)
}
/**
Initializes a `SectionBy` clause with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section index title
- Important: Some utilities (such as `ListMonitor`s) may keep `SectionBy`s in memory and may thus introduce retain cycles if reference captures are not handled properly.
- parameter sectionKeyPath: the key path to use to group the objects into sections
- parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section index title
*/
public init<T>(
_ sectionKeyPath: KeyPath<O, FieldContainer<O>.Virtual<T>>,
sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?
) {
self.init(
O.meta[keyPath: sectionKeyPath].keyPath,
sectionIndexTransformer: sectionIndexTransformer
)
}
/**
Initializes a `SectionBy` clause with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section index title
- Important: Some utilities (such as `ListMonitor`s) may keep `SectionBy`s in memory and may thus introduce retain cycles if reference captures are not handled properly.
- parameter sectionKeyPath: the key path to use to group the objects into sections
- parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section index title
*/
public init<T>(
_ sectionKeyPath: KeyPath<O, FieldContainer<O>.Coded<T>>,
sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?
) {
self.init(
O.meta[keyPath: sectionKeyPath].keyPath,
sectionIndexTransformer: sectionIndexTransformer
)
}
/**
Initializes a `SectionBy` clause with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section index title
- Important: Some utilities (such as `ListMonitor`s) may keep `SectionBy`s in memory and may thus introduce retain cycles if reference captures are not handled properly.
- parameter sectionKeyPath: the key path to use to group the objects into sections
- parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section index title
*/
public init<T>( public init<T>(
_ sectionKeyPath: KeyPath<O, ValueContainer<O>.Optional<T>>, _ sectionKeyPath: KeyPath<O, ValueContainer<O>.Optional<T>>,
sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?
@@ -333,13 +275,6 @@ extension SectionBy where O: CoreStoreObject {
) )
} }
/**
Initializes a `SectionBy` clause with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section index title
- Important: Some utilities (such as `ListMonitor`s) may keep `SectionBy`s in memory and may thus introduce retain cycles if reference captures are not handled properly.
- parameter sectionKeyPath: the key path to use to group the objects into sections
- parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section index title
*/
public init<T>( public init<T>(
_ sectionKeyPath: KeyPath<O, TransformableContainer<O>.Required<T>>, _ sectionKeyPath: KeyPath<O, TransformableContainer<O>.Required<T>>,
sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?
@@ -351,13 +286,6 @@ extension SectionBy where O: CoreStoreObject {
) )
} }
/**
Initializes a `SectionBy` clause with the key path to use to group `ListMonitor` objects into sections, and a closure to transform the value for the key path to an appropriate section index title
- Important: Some utilities (such as `ListMonitor`s) may keep `SectionBy`s in memory and may thus introduce retain cycles if reference captures are not handled properly.
- parameter sectionKeyPath: the key path to use to group the objects into sections
- parameter sectionIndexTransformer: a closure to transform the value for the key path to an appropriate section index title
*/
public init<T>( public init<T>(
_ sectionKeyPath: KeyPath<O, TransformableContainer<O>.Optional<T>>, _ sectionKeyPath: KeyPath<O, TransformableContainer<O>.Optional<T>>,
sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?
@@ -368,91 +296,4 @@ extension SectionBy where O: CoreStoreObject {
sectionIndexTransformer: sectionIndexTransformer sectionIndexTransformer: sectionIndexTransformer
) )
} }
// MARK: Deprecated
@available(*, deprecated, renamed: "init(_:sectionIndexTransformer:)")
public init<T>(
_ sectionKeyPath: KeyPath<O, ValueContainer<O>.Required<T>>,
_ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?
) {
self.init(
sectionKeyPath,
sectionIndexTransformer: sectionIndexTransformer
)
}
@available(*, deprecated, renamed: "init(_:sectionIndexTransformer:)")
public init<T>(
_ sectionKeyPath: KeyPath<O, FieldContainer<O>.Stored<T>>,
_ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?
) {
self.init(
O.meta[keyPath: sectionKeyPath].keyPath,
sectionIndexTransformer: sectionIndexTransformer
)
}
@available(*, deprecated, renamed: "init(_:sectionIndexTransformer:)")
public init<T>(
_ sectionKeyPath: KeyPath<O, FieldContainer<O>.Virtual<T>>,
_ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?
) {
self.init(
sectionKeyPath,
sectionIndexTransformer: sectionIndexTransformer
)
}
@available(*, deprecated, renamed: "init(_:sectionIndexTransformer:)")
public init<T>(
_ sectionKeyPath: KeyPath<O, FieldContainer<O>.Coded<T>>,
_ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?
) {
self.init(
sectionKeyPath,
sectionIndexTransformer: sectionIndexTransformer
)
}
@available(*, deprecated, renamed: "init(_:sectionIndexTransformer:)")
public init<T>(
_ sectionKeyPath: KeyPath<O, ValueContainer<O>.Optional<T>>,
_ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?
) {
self.init(
sectionKeyPath,
sectionIndexTransformer: sectionIndexTransformer
)
}
@available(*, deprecated, renamed: "init(_:sectionIndexTransformer:)")
public init<T>(
_ sectionKeyPath: KeyPath<O, TransformableContainer<O>.Required<T>>,
_ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?
) {
self.init(
sectionKeyPath,
sectionIndexTransformer: sectionIndexTransformer
)
}
@available(*, deprecated, renamed: "init(_:sectionIndexTransformer:)")
public init<T>(
_ sectionKeyPath: KeyPath<O, TransformableContainer<O>.Optional<T>>,
_ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?
) {
self.init(
sectionKeyPath,
sectionIndexTransformer: sectionIndexTransformer
)
}
} }

View File

@@ -47,12 +47,6 @@ public struct SectionMonitorChainBuilder<O: DynamicObject>: SectionMonitorBuilde
public var from: From<O> public var from: From<O>
public var sectionBy: SectionBy<O> public var sectionBy: SectionBy<O>
public var fetchClauses: [FetchClause] = [] public var fetchClauses: [FetchClause] = []
// MARK: Deprecated
@available(*, deprecated, renamed: "O")
public typealias D = O
} }

View File

@@ -296,12 +296,6 @@ public enum SelectTerm<O: DynamicObject>: ExpressibleByStringLiteral, Hashable {
case ._identity(let alias, _): return alias case ._identity(let alias, _): return alias
} }
} }
// MARK: Deprecated
@available(*, deprecated, renamed: "O")
public typealias D = O
} }
@@ -611,12 +605,6 @@ public struct Select<O: DynamicObject, T: SelectResultType>: SelectClause, Hasha
fetchRequest.propertiesToFetch = propertiesToFetch fetchRequest.propertiesToFetch = propertiesToFetch
} }
// MARK: Deprecated
@available(*, deprecated, renamed: "O")
public typealias D = O
} }
extension Select where T: NSManagedObjectID { extension Select where T: NSManagedObjectID {
@@ -642,48 +630,6 @@ extension Select where O: NSManagedObject {
} }
} }
extension Select where O: CoreStoreObject, T: ImportableAttributeType {
/**
Initializes a `Select` that queries the value of an attribute pertained by a keyPath
- parameter keyPath: the keyPath for the attribute
*/
public init(_ keyPath: KeyPath<O, ValueContainer<O>.Required<T>>) {
self.init(.attribute(keyPath))
}
/**
Initializes a `Select` that queries the value of an attribute pertained by a keyPath
- parameter keyPath: the keyPath for the attribute
*/
public init(_ keyPath: KeyPath<O, ValueContainer<O>.Optional<T>>) {
self.init(.attribute(keyPath))
}
}
extension Select where O: CoreStoreObject, T: ImportableAttributeType & NSCoding & NSCopying {
/**
Initializes a `Select` that queries the value of an attribute pertained by a keyPath
- parameter keyPath: the keyPath for the attribute
*/
public init(_ keyPath: KeyPath<O, TransformableContainer<O>.Required<T>>) {
self.init(.attribute(keyPath))
}
/**
Initializes a `Select` that queries the value of an attribute pertained by a keyPath
- parameter keyPath: the keyPath for the attribute
*/
public init(_ keyPath: KeyPath<O, TransformableContainer<O>.Optional<T>>) {
self.init(.attribute(keyPath))
}
}
// MARK: - SelectClause // MARK: - SelectClause
@@ -720,3 +666,38 @@ extension NSDictionary: SelectAttributesResultType {
return result as! [[String: Any]] return result as! [[String: Any]]
} }
} }
// MARK: - Deprecated
@available(*, deprecated, message: """
Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
""")
extension Select where O: CoreStoreObject, T: ImportableAttributeType {
public init(_ keyPath: KeyPath<O, ValueContainer<O>.Required<T>>) {
self.init(.attribute(keyPath))
}
public init(_ keyPath: KeyPath<O, ValueContainer<O>.Optional<T>>) {
self.init(.attribute(keyPath))
}
}
@available(*, deprecated, message: """
Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
""")
extension Select where O: CoreStoreObject, T: ImportableAttributeType & NSCoding & NSCopying {
public init(_ keyPath: KeyPath<O, TransformableContainer<O>.Required<T>>) {
self.init(.attribute(keyPath))
}
public init(_ keyPath: KeyPath<O, TransformableContainer<O>.Optional<T>>) {
self.init(.attribute(keyPath))
}
}

View File

@@ -27,62 +27,15 @@ import CoreData
import Foundation import Foundation
// MARK: - TransformableContainer // MARK: - Deprecated
@available(*, deprecated, message: """
Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
""")
extension TransformableContainer { extension TransformableContainer {
// MARK: - Optional
/**
The containing type for optional transformable properties. Any type that conforms to `NSCoding & NSCopying` are supported.
```
class Animal: CoreStoreObject {
let species = Value.Required<String>("species", initial: "")
let nickname = Value.Optional<String>("nickname")
let color = Transformable.Optional<UIColor>("color")
}
```
- Important: `Transformable.Optional` properties are required to be stored properties. Computed properties will be ignored, including `lazy` and `weak` properties.
*/
public final class Optional<V: NSCoding & NSCopying>: AttributeKeyPathStringConvertible, AttributeProtocol { public final class Optional<V: NSCoding & NSCopying>: AttributeKeyPathStringConvertible, AttributeProtocol {
/**
Initializes the metadata for the property.
```
class Animal: CoreStoreObject {
let species = Value.Required<String>("species", initial: "")
let color = Transformable.Optional<UIColor>(
"color",
isTransient: true,
customGetter: Animal.getColor(_:)
)
}
private static func getColor(_ partialObject: PartialObject<Animal>) -> UIColor? {
if let cachedColor = partialObject.primitiveValue(for: { $0.color }) {
return cachedColor
}
let color: UIColor?
switch partialObject.value(for: { $0.species }) {
case "Swift": color = UIColor.orange
case "Bulbasaur": color = UIColor.green
default: return nil
}
partialObject.setPrimitiveValue(color, for: { $0.color })
return color
}
```
- parameter keyPath: the permanent attribute name for this property.
- parameter initial: the initial value for the property that is shared for all instances of this object. Note that this is evaluated during `DataStack` setup, not during object creation. Defaults to the `ImportableAttributeType`'s empty value if not specified.
- parameter isTransient: `true` if the property is transient, otherwise `false`. Defaults to `false` if not specified. The transient flag specifies whether or not a property's value is ignored when an object is saved to a persistent store. Transient properties are not saved to the persistent store, but are still managed for undo, redo, validation, and so on.
- parameter allowsExternalBinaryDataStorage: `true` if the attribute allows external binary storage, otherwise `false`.
- parameter versionHashModifier: used to mark or denote a property as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where the properties are unchanged but the format or content of its data are changed.)
- parameter renamingIdentifier: used to resolve naming conflicts between models. When creating an entity mapping between entities in two managed object models, a source entity property and a destination entity property that share the same identifier indicate that a property mapping should be configured to migrate from the source to the destination. If unset, the identifier will be the property's name.
- parameter customGetter: use this closure as an "override" for the default property getter. The closure receives a `PartialObject<O>`, which acts as a fast, type-safe KVC interface for `CoreStoreObject`. The reason a `CoreStoreObject` instance is not passed directly is because the Core Data runtime is not aware of `CoreStoreObject` properties' static typing, and so loading those info everytime KVO invokes this accessor method incurs a cumulative performance hit (especially in KVO-heavy operations such as `ListMonitor` observing.) When accessing the property value from `PartialObject<O>`, make sure to use `PartialObject<O>.primitiveValue(for:)` instead of `PartialObject<O>.value(for:)`, which would unintentionally execute the same closure again recursively.
- parameter customSetter: use this closure as an "override" for the default property setter. The closure receives a `PartialObject<O>`, which acts as a fast, type-safe KVC interface for `CoreStoreObject`. The reason a `CoreStoreObject` instance is not passed directly is because the Core Data runtime is not aware of `CoreStoreObject` properties' static typing, and so loading those info everytime KVO invokes this accessor method incurs a cumulative performance hit (especially in KVO-heavy operations such as `ListMonitor` observing.) When accessing the property value from `PartialObject<O>`, make sure to use `PartialObject<O>.setPrimitiveValue(_:for:)` instead of `PartialObject<O>.setValue(_:for:)`, which would unintentionally execute the same closure again recursively.
- parameter affectedByKeyPaths: a set of key paths for properties whose values affect the value of the receiver. This is similar to `NSManagedObject.keyPathsForValuesAffectingValue(forKey:)`.
*/
public init( public init(
_ keyPath: KeyPathString, _ keyPath: KeyPathString,
initial: @autoclosure @escaping () -> V? = nil, initial: @autoclosure @escaping () -> V? = nil,
@@ -110,10 +63,7 @@ extension TransformableContainer {
self.customGetter = customGetter self.customGetter = customGetter
self.customSetter = customSetter self.customSetter = customSetter
} }
/**
The attribute value
*/
public var value: ReturnValueType { public var value: ReturnValueType {
get { get {
@@ -163,28 +113,16 @@ extension TransformableContainer {
} }
} }
// MARK: AnyKeyPathStringConvertible
public var cs_keyPathString: String { public var cs_keyPathString: String {
return self.keyPath return self.keyPath
} }
// MARK: KeyPathStringConvertible
public typealias ObjectType = O public typealias ObjectType = O
public typealias DestinationValueType = V public typealias DestinationValueType = V
// MARK: AttributeKeyPathStringConvertible
public typealias ReturnValueType = DestinationValueType? public typealias ReturnValueType = DestinationValueType?
// MARK: PropertyProtocol
internal let keyPath: KeyPathString internal let keyPath: KeyPathString
@@ -240,59 +178,26 @@ extension TransformableContainer {
return self.value return self.value
} }
// MARK: Private
private let customGetter: ((_ partialObject: PartialObject<O>) -> V?)? private let customGetter: ((_ partialObject: PartialObject<O>) -> V?)?
private let customSetter: ((_ partialObject: PartialObject<O>, _ newValue: V?) -> Void)? private let customSetter: ((_ partialObject: PartialObject<O>, _ newValue: V?) -> Void)?
} }
} }
@available(*, deprecated, message: """
// MARK: - Operations Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
""")
extension TransformableContainer.Optional { extension TransformableContainer.Optional {
/**
Assigns an optional transformable value to the property. The operation
```
animal.color .= UIColor.red
```
is equivalent to
```
animal.color.value = UIColor.red
```
*/
public static func .= (_ property: TransformableContainer<O>.Optional<V>, _ newValue: V?) { public static func .= (_ property: TransformableContainer<O>.Optional<V>, _ newValue: V?) {
property.value = newValue property.value = newValue
} }
/**
Assigns an optional transformable value from another property. The operation
```
animal.color .= anotherAnimal.color
```
is equivalent to
```
animal.color.value = anotherAnimal.color.value
```
*/
public static func .= <O2>(_ property: TransformableContainer<O>.Optional<V>, _ property2: TransformableContainer<O2>.Optional<V>) { public static func .= <O2>(_ property: TransformableContainer<O>.Optional<V>, _ property2: TransformableContainer<O2>.Optional<V>) {
property.value = property2.value property.value = property2.value
} }
/**
Assigns a transformable value from another property. The operation
```
animal.color .= anotherAnimal.color
```
is equivalent to
```
animal.color.value = anotherAnimal.color.value
```
*/
public static func .= <O2>(_ property: TransformableContainer<O>.Optional<V>, _ property2: TransformableContainer<O2>.Required<V>) { public static func .= <O2>(_ property: TransformableContainer<O>.Optional<V>, _ property2: TransformableContainer<O2>.Required<V>) {
property.value = property2.value property.value = property2.value

View File

@@ -27,65 +27,15 @@ import CoreData
import Foundation import Foundation
// MARK: - TransformableContainer // MARK: - Deprecated
@available(*, deprecated, message: """
Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
""")
extension TransformableContainer { extension TransformableContainer {
// MARK: - Required
/**
The containing type for transformable properties. Any type that conforms to `NSCoding & NSCopying` are supported.
```
class Animal: CoreStoreObject {
let species = Value.Required<String>("species", initial: "")
let nickname = Value.Optional<String>("nickname")
let color = Transformable.Optional<UIColor>("color")
}
```
- Important: `Transformable.Required` properties are required to be stored properties. Computed properties will be ignored, including `lazy` and `weak` properties.
*/
public final class Required<V: NSCoding & NSCopying>: AttributeKeyPathStringConvertible, AttributeProtocol { public final class Required<V: NSCoding & NSCopying>: AttributeKeyPathStringConvertible, AttributeProtocol {
/**
Initializes the metadata for the property.
```
class Animal: CoreStoreObject {
let species = Value.Required<String>("species", initial: "")
let color = Transformable.Required<UIColor>(
"color",
initial: UIColor.clear,
isTransient: true,
customGetter: Animal.getColor(_:)
)
}
private static func getColor(_ partialObject: PartialObject<Animal>) -> UIColor {
let cachedColor = partialObject.primitiveValue(for: { $0.color })
if cachedColor != UIColor.clear {
return cachedColor
}
let color: UIColor
switch partialObject.value(for: { $0.species }) {
case "Swift": color = UIColor.orange
case "Bulbasaur": color = UIColor.green
default: color = UIColor.black
}
partialObject.setPrimitiveValue(color, for: { $0.color })
return color
}
```
- parameter keyPath: the permanent attribute name for this property.
- parameter initial: the initial value for the property that is shared for all instances of this object. Note that this is evaluated during `DataStack` setup, not during object creation. Defaults to the `ImportableAttributeType`'s empty value if not specified.
- parameter isTransient: `true` if the property is transient, otherwise `false`. Defaults to `false` if not specified. The transient flag specifies whether or not a property's value is ignored when an object is saved to a persistent store. Transient properties are not saved to the persistent store, but are still managed for undo, redo, validation, and so on.
- parameter allowsExternalBinaryDataStorage: `true` if the attribute allows external binary storage, otherwise `false`.
- parameter versionHashModifier: used to mark or denote a property as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where the properties are unchanged but the format or content of its data are changed.)
- parameter renamingIdentifier: used to resolve naming conflicts between models. When creating an entity mapping between entities in two managed object models, a source entity property and a destination entity property that share the same identifier indicate that a property mapping should be configured to migrate from the source to the destination. If unset, the identifier will be the property's name.
- parameter customGetter: use this closure as an "override" for the default property getter. The closure receives a `PartialObject<O>`, which acts as a fast, type-safe KVC interface for `CoreStoreObject`. The reason a `CoreStoreObject` instance is not passed directly is because the Core Data runtime is not aware of `CoreStoreObject` properties' static typing, and so loading those info everytime KVO invokes this accessor method incurs a cumulative performance hit (especially in KVO-heavy operations such as `ListMonitor` observing.) When accessing the property value from `PartialObject<O>`, make sure to use `PartialObject<O>.primitiveValue(for:)` instead of `PartialObject<O>.value(for:)`, which would unintentionally execute the same closure again recursively.
- parameter customSetter: use this closure as an "override" for the default property setter. The closure receives a `PartialObject<O>`, which acts as a fast, type-safe KVC interface for `CoreStoreObject`. The reason a `CoreStoreObject` instance is not passed directly is because the Core Data runtime is not aware of `CoreStoreObject` properties' static typing, and so loading those info everytime KVO invokes this accessor method incurs a cumulative performance hit (especially in KVO-heavy operations such as `ListMonitor` observing.) When accessing the property value from `PartialObject<O>`, make sure to use `PartialObject<O>.setPrimitiveValue(_:for:)` instead of `PartialObject<O>.setValue(_:for:)`, which would unintentionally execute the same closure again recursively.
- parameter affectedByKeyPaths: a set of key paths for properties whose values affect the value of the receiver. This is similar to `NSManagedObject.keyPathsForValuesAffectingValue(forKey:)`.
*/
public init( public init(
_ keyPath: KeyPathString, _ keyPath: KeyPathString,
initial: @autoclosure @escaping () -> V, initial: @autoclosure @escaping () -> V,
@@ -113,10 +63,7 @@ extension TransformableContainer {
self.customGetter = customGetter self.customGetter = customGetter
self.customSetter = customSetter self.customSetter = customSetter
} }
/**
The attribute value
*/
public var value: ReturnValueType { public var value: ReturnValueType {
get { get {
@@ -166,33 +113,18 @@ extension TransformableContainer {
} }
} }
// MARK: AnyKeyPathStringConvertible
public var cs_keyPathString: String { public var cs_keyPathString: String {
return self.keyPath return self.keyPath
} }
// MARK: KeyPathStringConvertible
public typealias ObjectType = O public typealias ObjectType = O
public typealias DestinationValueType = V public typealias DestinationValueType = V
// MARK: AttributeKeyPathStringConvertible
public typealias ReturnValueType = DestinationValueType public typealias ReturnValueType = DestinationValueType
// MARK: PropertyProtocol
internal let keyPath: KeyPathString internal let keyPath: KeyPathString
// MARK: AttributeProtocol
internal let entityDescriptionValues: () -> AttributeProtocol.EntityDescriptionValues internal let entityDescriptionValues: () -> AttributeProtocol.EntityDescriptionValues
internal var rawObject: CoreStoreManagedObject? internal var rawObject: CoreStoreManagedObject?
@@ -243,44 +175,21 @@ extension TransformableContainer {
return self.value return self.value
} }
// MARK: Private
private let customGetter: ((_ partialObject: PartialObject<O>) -> V)? private let customGetter: ((_ partialObject: PartialObject<O>) -> V)?
private let customSetter: ((_ partialObject: PartialObject<O>, _ newValue: V) -> Void)? private let customSetter: ((_ partialObject: PartialObject<O>, _ newValue: V) -> Void)?
} }
} }
@available(*, deprecated, message: """
// MARK: - Operations Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
""")
extension TransformableContainer.Required { extension TransformableContainer.Required {
/**
Assigns a transformable value to the property. The operation
```
animal.color .= UIColor.red
```
is equivalent to
```
animal.color.value = UIColor.red
```
*/
public static func .= (_ property: TransformableContainer<O>.Required<V>, _ newValue: V) { public static func .= (_ property: TransformableContainer<O>.Required<V>, _ newValue: V) {
property.value = newValue property.value = newValue
} }
/**
Assigns a transformable value from another property. The operation
```
animal.nickname .= anotherAnimal.species
```
is equivalent to
```
animal.nickname.value = anotherAnimal.species.value
```
*/
public static func .= <O2>(_ property: TransformableContainer<O>.Required<V>, _ property2: TransformableContainer<O2>.Required<V>) { public static func .= <O2>(_ property: TransformableContainer<O>.Required<V>, _ property2: TransformableContainer<O2>.Required<V>) {
property.value = property2.value property.value = property2.value

View File

@@ -27,35 +27,17 @@ import CoreData
import Foundation import Foundation
// MARK: - DynamicObject // MARK: - Deprecated
extension DynamicObject where Self: CoreStoreObject { extension DynamicObject where Self: CoreStoreObject {
/** @available(*, deprecated, message: """
The containing type for transformable properties. `Transformable` properties support types that conforms to `NSCoding & NSCopying`. Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
``` """)
class Animal: CoreStoreObject {
let species = Value.Required<String>("species", initial: "")
let nickname = Value.Optional<String>("nickname")
let color = Transformable.Optional<UIColor>("color")
}
```
- Important: `Transformable` properties are required to be stored properties. Computed properties will be ignored, including `lazy` and `weak` properties.
*/
public typealias Transformable = TransformableContainer<Self> public typealias Transformable = TransformableContainer<Self>
} }
@available(*, deprecated, message: """
// MARK: - TransformableContainer Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
""")
/**
The containing type for transformable properties. Use the `DynamicObject.Transformable` typealias instead for shorter syntax.
```
class Animal: CoreStoreObject {
let species = Value.Required<String>("species", initial: "")
let nickname = Value.Optional<String>("nickname")
let color = Transformable.Optional<UIColor>("color")
}
```
*/
public enum TransformableContainer<O: CoreStoreObject> {} public enum TransformableContainer<O: CoreStoreObject> {}

View File

@@ -27,63 +27,15 @@ import CoreData
import Foundation import Foundation
// MARK: - ValueContainer // MARK: - Deprecated
@available(*, deprecated, message: """
Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
""")
extension ValueContainer { extension ValueContainer {
// MARK: - Optional
/**
The containing type for optional value properties. Any type that conforms to `ImportableAttributeType` are supported.
```
class Animal: CoreStoreObject {
let species = Value.Required<String>("species", initial: "")
let nickname = Value.Optional<String>("nickname")
let color = Transformable.Optional<UIColor>("color")
}
```
- Important: `Value.Optional` properties are required to be stored properties. Computed properties will be ignored, including `lazy` and `weak` properties.
*/
public final class Optional<V: ImportableAttributeType>: AttributeKeyPathStringConvertible, AttributeProtocol { public final class Optional<V: ImportableAttributeType>: AttributeKeyPathStringConvertible, AttributeProtocol {
/**
Initializes the metadata for the property.
```
class Person: CoreStoreObject {
let title = Value.Optional<String>("title", initial: "Mr.")
let name = Value.Optional<String>("name")
let displayName = Value.Optional<String>(
"displayName",
isTransient: true,
customGetter: Person.getName(_:)
)
private static func getName(_ partialObject: PartialObject<Person>) -> String? {
if let cachedDisplayName = partialObject.primitiveValue(for: { $0.displayName }) {
return cachedDisplayName
}
let title = partialObject.value(for: { $0.title })
let name = partialObject.value(for: { $0.name })
let displayName = "\(title) \(name)"
partialObject.setPrimitiveValue(displayName, for: { $0.displayName })
return displayName
}
}
```
- parameter keyPath: the permanent attribute name for this property.
- parameter initial: the initial value for the property that is shared for all instances of this object. Note that this is evaluated during `DataStack` setup, not during object creation. Defaults to `nil` if not specified.
- parameter isTransient: `true` if the property is transient, otherwise `false`. Defaults to `false` if not specified. The transient flag specifies whether or not a property's value is ignored when an object is saved to a persistent store. Transient properties are not saved to the persistent store, but are still managed for undo, redo, validation, and so on.
- parameter versionHashModifier: used to mark or denote a property as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where the properties are unchanged but the format or content of its data are changed.)
- parameter renamingIdentifier: used to resolve naming conflicts between models. When creating an entity mapping between entities in two managed object models, a source entity property and a destination entity property that share the same identifier indicate that a property mapping should be configured to migrate from the source to the destination. If unset, the identifier will be the property's name.
- parameter customGetter: use this closure to make final transformations to the property's value before returning from the getter.
- parameter self: the `CoreStoreObject`
- parameter getValue: the original getter for the property
- parameter customSetter: use this closure to make final transformations to the new value before assigning to the property.
- parameter setValue: the original setter for the property
- parameter finalNewValue: the transformed new value
- parameter originalNewValue: the original new value
- parameter affectedByKeyPaths: a set of key paths for properties whose values affect the value of the receiver. This is similar to `NSManagedObject.keyPathsForValuesAffectingValue(forKey:)`.
*/
public init( public init(
_ keyPath: KeyPathString, _ keyPath: KeyPathString,
initial: @autoclosure @escaping () -> V? = nil, initial: @autoclosure @escaping () -> V? = nil,
@@ -110,10 +62,7 @@ extension ValueContainer {
self.customGetter = customGetter self.customGetter = customGetter
self.customSetter = customSetter self.customSetter = customSetter
} }
/**
The attribute value
*/
public var value: ReturnValueType { public var value: ReturnValueType {
get { get {
@@ -164,33 +113,18 @@ extension ValueContainer {
} }
} }
// MARK: AnyKeyPathStringConvertible
public var cs_keyPathString: String { public var cs_keyPathString: String {
return self.keyPath return self.keyPath
} }
// MARK: KeyPathStringConvertible
public typealias ObjectType = O public typealias ObjectType = O
public typealias DestinationValueType = V public typealias DestinationValueType = V
// MARK: AttributeKeyPathStringConvertible
public typealias ReturnValueType = DestinationValueType? public typealias ReturnValueType = DestinationValueType?
// MARK: PropertyProtocol
internal let keyPath: KeyPathString internal let keyPath: KeyPathString
// MARK: AttributeProtocol
internal let entityDescriptionValues: () -> AttributeProtocol.EntityDescriptionValues internal let entityDescriptionValues: () -> AttributeProtocol.EntityDescriptionValues
internal var rawObject: CoreStoreManagedObject? internal var rawObject: CoreStoreManagedObject?
@@ -241,119 +175,46 @@ extension ValueContainer {
return self.value return self.value
} }
// MARK: Private
private let customGetter: ((_ partialObject: PartialObject<O>) -> V?)? private let customGetter: ((_ partialObject: PartialObject<O>) -> V?)?
private let customSetter: ((_ partialObject: PartialObject<O>, _ newValue: V?) -> Void)? private let customSetter: ((_ partialObject: PartialObject<O>, _ newValue: V?) -> Void)?
} }
} }
@available(*, deprecated, message: """
// MARK: - Operations Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
""")
extension ValueContainer.Optional { extension ValueContainer.Optional {
/**
Assigns an optional value to the property. The operation
```
animal.nickname .= "Taylor"
```
is equivalent to
```
animal.nickname.value = "Taylor"
```
*/
public static func .= (_ property: ValueContainer<O>.Optional<V>, _ newValue: V?) { public static func .= (_ property: ValueContainer<O>.Optional<V>, _ newValue: V?) {
property.value = newValue property.value = newValue
} }
/**
Assigns an optional value from another property. The operation
```
animal.nickname .= anotherAnimal.nickname
```
is equivalent to
```
animal.nickname.value = anotherAnimal.nickname.value
```
*/
public static func .= <O2>(_ property: ValueContainer<O>.Optional<V>, _ property2: ValueContainer<O2>.Optional<V>) { public static func .= <O2>(_ property: ValueContainer<O>.Optional<V>, _ property2: ValueContainer<O2>.Optional<V>) {
property.value = property2.value property.value = property2.value
} }
/**
Assigns a value from another property. The operation
```
animal.nickname .= anotherAnimal.species
```
is equivalent to
```
animal.nickname.value = anotherAnimal.species.value
```
*/
public static func .= <O2>(_ property: ValueContainer<O>.Optional<V>, _ property2: ValueContainer<O2>.Required<V>) { public static func .= <O2>(_ property: ValueContainer<O>.Optional<V>, _ property2: ValueContainer<O2>.Required<V>) {
property.value = property2.value property.value = property2.value
} }
/**
Compares equality between a property's value and another value
```
if animal.species .== "Swift" { ... }
```
is equivalent to
```
if animal.species.value == "Swift" { ... }
```
*/
public static func .== (_ property: ValueContainer<O>.Optional<V>, _ value: V?) -> Bool { public static func .== (_ property: ValueContainer<O>.Optional<V>, _ value: V?) -> Bool {
return property.value == value return property.value == value
} }
/**
Compares equality between a property's value and another property's value
```
if "Swift" .== animal.species { ... }
```
is equivalent to
```
if "Swift" == animal.species.value { ... }
```
*/
public static func .== (_ value: V?, _ property: ValueContainer<O>.Optional<V>) -> Bool { public static func .== (_ value: V?, _ property: ValueContainer<O>.Optional<V>) -> Bool {
return value == property.value return value == property.value
} }
/**
Compares equality between a property's value and another property's value
```
if animal.species .== anotherAnimal.species { ... }
```
is equivalent to
```
if animal.species.value == anotherAnimal.species.value { ... }
```
*/
public static func .== (_ property: ValueContainer<O>.Optional<V>, _ property2: ValueContainer<O>.Optional<V>) -> Bool { public static func .== (_ property: ValueContainer<O>.Optional<V>, _ property2: ValueContainer<O>.Optional<V>) -> Bool {
return property.value == property2.value return property.value == property2.value
} }
/**
Compares equality between a property's value and another property's value
```
if animal.species .== anotherAnimal.species { ... }
```
is equivalent to
```
if animal.species.value == anotherAnimal.species.value { ... }
```
*/
public static func .== (_ property: ValueContainer<O>.Optional<V>, _ property2: ValueContainer<O>.Required<V>) -> Bool { public static func .== (_ property: ValueContainer<O>.Optional<V>, _ property2: ValueContainer<O>.Required<V>) -> Bool {
return property.value == property2.value return property.value == property2.value

View File

@@ -27,60 +27,15 @@ import CoreData
import Foundation import Foundation
// MARK: - ValueContainer // MARK: - Deprecated
@available(*, deprecated, message: """
Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
""")
extension ValueContainer { extension ValueContainer {
// MARK: - Required
/**
The containing type for required value properties. Any type that conforms to `ImportableAttributeType` are supported.
```
class Animal: CoreStoreObject {
let species = Value.Required<String>("species", initial: "")
let nickname = Value.Optional<String>("nickname")
let color = Transformable.Optional<UIColor>("color")
}
```
- Important: `Value.Required` properties are required to be stored properties. Computed properties will be ignored, including `lazy` and `weak` properties.
*/
public final class Required<V: ImportableAttributeType>: AttributeKeyPathStringConvertible, AttributeProtocol { public final class Required<V: ImportableAttributeType>: AttributeKeyPathStringConvertible, AttributeProtocol {
/**
Initializes the metadata for the property.
```
class Person: CoreStoreObject {
let title = Value.Required<String>("title", initial: "Mr.")
let name = Value.Required<String>("name", initial: "")
let displayName = Value.Required<String>(
"displayName",
initial: "",
isTransient: true,
customGetter: Person.getName(_:)
)
private static func getName(_ partialObject: PartialObject<Person>) -> String {
let cachedDisplayName = partialObject.primitiveValue(for: { $0.displayName })
if !cachedDisplayName.isEmpty {
return cachedDisplayName
}
let title = partialObject.value(for: { $0.title })
let name = partialObject.value(for: { $0.name })
let displayName = "\(title) \(name)"
partialObject.setPrimitiveValue(displayName, for: { $0.displayName })
return displayName
}
}
```
- parameter keyPath: the permanent attribute name for this property.
- parameter initial: the initial value for the property when the object is first created
- parameter isTransient: `true` if the property is transient, otherwise `false`. Defaults to `false` if not specified. The transient flag specifies whether or not a property's value is ignored when an object is saved to a persistent store. Transient properties are not saved to the persistent store, but are still managed for undo, redo, validation, and so on.
- parameter versionHashModifier: used to mark or denote a property as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where the properties are unchanged but the format or content of its data are changed.)
- parameter renamingIdentifier: used to resolve naming conflicts between models. When creating an entity mapping between entities in two managed object models, a source entity property and a destination entity property that share the same identifier indicate that a property mapping should be configured to migrate from the source to the destination. If unset, the identifier will be the property's name.
- parameter customGetter: use this closure as an "override" for the default property getter. The closure receives a `PartialObject<O>`, which acts as a fast, type-safe KVC interface for `CoreStoreObject`. The reason a `CoreStoreObject` instance is not passed directly is because the Core Data runtime is not aware of `CoreStoreObject` properties' static typing, and so loading those info everytime KVO invokes this accessor method incurs a cumulative performance hit (especially in KVO-heavy operations such as `ListMonitor` observing.) When accessing the property value from `PartialObject<O>`, make sure to use `PartialObject<O>.primitiveValue(for:)` instead of `PartialObject<O>.value(for:)`, which would unintentionally execute the same closure again recursively.
- parameter customSetter: use this closure as an "override" for the default property setter. The closure receives a `PartialObject<O>`, which acts as a fast, type-safe KVC interface for `CoreStoreObject`. The reason a `CoreStoreObject` instance is not passed directly is because the Core Data runtime is not aware of `CoreStoreObject` properties' static typing, and so loading those info everytime KVO invokes this accessor method incurs a cumulative performance hit (especially in KVO-heavy operations such as `ListMonitor` observing.) When accessing the property value from `PartialObject<O>`, make sure to use `PartialObject<O>.setPrimitiveValue(_:for:)` instead of `PartialObject<O>.setValue(_:for:)`, which would unintentionally execute the same closure again recursively.
- parameter affectedByKeyPaths: a set of key paths for properties whose values affect the value of the receiver. This is similar to `NSManagedObject.keyPathsForValuesAffectingValue(forKey:)`.
*/
public init( public init(
_ keyPath: KeyPathString, _ keyPath: KeyPathString,
initial: @autoclosure @escaping () -> V, initial: @autoclosure @escaping () -> V,
@@ -107,10 +62,7 @@ extension ValueContainer {
self.customGetter = customGetter self.customGetter = customGetter
self.customSetter = customSetter self.customSetter = customSetter
} }
/**
The attribute value
*/
public var value: ReturnValueType { public var value: ReturnValueType {
get { get {
@@ -162,33 +114,18 @@ extension ValueContainer {
} }
} }
// MARK: AnyKeyPathStringConvertible
public var cs_keyPathString: String { public var cs_keyPathString: String {
return self.keyPath return self.keyPath
} }
// MARK: KeyPathStringConvertible
public typealias ObjectType = O public typealias ObjectType = O
public typealias DestinationValueType = V public typealias DestinationValueType = V
// MARK: AttributeKeyPathStringConvertible
public typealias ReturnValueType = DestinationValueType public typealias ReturnValueType = DestinationValueType
// MARK: PropertyProtocol
internal let keyPath: KeyPathString internal let keyPath: KeyPathString
// MARK: AttributeProtocol
internal let entityDescriptionValues: () -> AttributeProtocol.EntityDescriptionValues internal let entityDescriptionValues: () -> AttributeProtocol.EntityDescriptionValues
internal var rawObject: CoreStoreManagedObject? internal var rawObject: CoreStoreManagedObject?
@@ -239,104 +176,41 @@ extension ValueContainer {
return self.value return self.value
} }
// MARK: Private
private let customGetter: ((_ partialObject: PartialObject<O>) -> V)? private let customGetter: ((_ partialObject: PartialObject<O>) -> V)?
private let customSetter: ((_ partialObject: PartialObject<O>, _ newValue: V) -> Void)? private let customSetter: ((_ partialObject: PartialObject<O>, _ newValue: V) -> Void)?
} }
} }
@available(*, deprecated, message: """
// MARK: - Operations Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
""")
extension ValueContainer.Required { extension ValueContainer.Required {
/**
Assigns a value to the property. The operation
```
animal.species .= "Swift"
```
is equivalent to
```
animal.species.value = "Swift"
```
*/
public static func .= (_ property: ValueContainer<O>.Required<V>, _ newValue: V) { public static func .= (_ property: ValueContainer<O>.Required<V>, _ newValue: V) {
property.value = newValue property.value = newValue
} }
/**
Assigns a value from another property. The operation
```
animal.species .= anotherAnimal.species
```
is equivalent to
```
animal.species.value = anotherAnimal.species.value
```
*/
public static func .= <O2>(_ property: ValueContainer<O>.Required<V>, _ property2: ValueContainer<O2>.Required<V>) { public static func .= <O2>(_ property: ValueContainer<O>.Required<V>, _ property2: ValueContainer<O2>.Required<V>) {
property.value = property2.value property.value = property2.value
} }
/**
Compares equality between a property's value and another value
```
if animal.species .== "Swift" { ... }
```
is equivalent to
```
if animal.species.value == "Swift" { ... }
```
*/
public static func .== (_ property: ValueContainer<O>.Required<V>, _ value: V?) -> Bool { public static func .== (_ property: ValueContainer<O>.Required<V>, _ value: V?) -> Bool {
return property.value == value return property.value == value
} }
/**
Compares equality between a value and a property's value
```
if "Swift" .== animal.species { ... }
```
is equivalent to
```
if "Swift" == animal.species.value { ... }
```
*/
public static func .== (_ value: V?, _ property: ValueContainer<O>.Required<V>) -> Bool { public static func .== (_ value: V?, _ property: ValueContainer<O>.Required<V>) -> Bool {
return value == property.value return value == property.value
} }
/**
Compares equality between a property's value and another property's value
```
if animal.species .== anotherAnimal.species { ... }
```
is equivalent to
```
if animal.species.value == anotherAnimal.species.value { ... }
```
*/
public static func .== (_ property: ValueContainer<O>.Required<V>, _ property2: ValueContainer<O>.Required<V>) -> Bool { public static func .== (_ property: ValueContainer<O>.Required<V>, _ property2: ValueContainer<O>.Required<V>) -> Bool {
return property.value == property2.value return property.value == property2.value
} }
/**
Compares equality between a property's value and another property's value
```
if animal.species .== anotherAnimal.species { ... }
```
is equivalent to
```
if animal.species.value == anotherAnimal.species.value { ... }
```
*/
public static func .== (_ property: ValueContainer<O>.Required<V>, _ property2: ValueContainer<O>.Optional<V>) -> Bool { public static func .== (_ property: ValueContainer<O>.Required<V>, _ property2: ValueContainer<O>.Optional<V>) -> Bool {
return property.value == property2.value return property.value == property2.value

View File

@@ -27,35 +27,17 @@ import CoreData
import Foundation import Foundation
// MARK: - DynamicObject // MARK: - Deprecated
extension DynamicObject where Self: CoreStoreObject { extension DynamicObject where Self: CoreStoreObject {
/** @available(*, deprecated, message: """
The containing type for value propertiess. `Value` properties support any type that conforms to `ImportableAttributeType`. Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
``` """)
class Animal: CoreStoreObject {
let species = Value.Required<String>("species", initial: "")
let nickname = Value.Optional<String>("nickname")
let color = Transformable.Optional<UIColor>("color")
}
```
- Important: `Value` properties are required to be stored properties. Computed properties will be ignored, including `lazy` and `weak` properties.
*/
public typealias Value = ValueContainer<Self> public typealias Value = ValueContainer<Self>
} }
@available(*, deprecated, message: """
// MARK: - ValueContainer Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
""")
/**
The containing type for value properties. Use the `DynamicObject.Value` typealias instead for shorter syntax.
```
class Animal: CoreStoreObject {
let species = Value.Required<String>("species", initial: "")
let nickname = Value.Optional<String>("nickname")
let color = Transformable.Optional<UIColor>("color")
}
```
*/
public enum ValueContainer<O: CoreStoreObject> {} public enum ValueContainer<O: CoreStoreObject> {}

View File

@@ -88,12 +88,6 @@ extension Where {
self.cs_keyPathString = component1 + "." + component2 self.cs_keyPathString = component1 + "." + component2
} }
// MARK: Deprecated
@available(*, deprecated, renamed: "O")
public typealias D = O
} }
@@ -234,20 +228,6 @@ public func ~ <O: CoreStoreObject, D: FieldRelationshipToOneType, K: KeyPathStri
) )
} }
/**
Connects multiple `KeyPathStringConvertible`s to create a type-safe chain usable in query/fetch expressions
```
let owner = dataStack.fetchOne(From<Pet>().where((\.master ~ \.name) == "John"))
```
*/
public func ~ <O: CoreStoreObject, D: CoreStoreObject, K: KeyPathStringConvertible>(_ lhs: KeyPath<O, RelationshipContainer<O>.ToOne<D>>, _ rhs: KeyPath<D, K>) -> Where<O>.Expression<Where<O>.SingleTarget, K.DestinationValueType> where K.ObjectType == D {
return .init(
O.meta[keyPath: lhs].cs_keyPathString,
D.meta[keyPath: rhs].cs_keyPathString
)
}
/** /**
Connects multiple `KeyPathStringConvertible`s to create a type-safe chain usable in query/fetch expressions Connects multiple `KeyPathStringConvertible`s to create a type-safe chain usable in query/fetch expressions
``` ```
@@ -290,20 +270,6 @@ public func ~ <O: CoreStoreObject, D: FieldRelationshipToOneType, K: ToManyRelat
) )
} }
/**
Connects multiple `KeyPathStringConvertible`s to create a type-safe chain usable in query/fetch expressions
```
let happyPets = dataStack.fetchAll(From<Pet>().where((\.master ~ \.pets).count() > 1))
```
*/
public func ~ <O: CoreStoreObject, D: CoreStoreObject, K: ToManyRelationshipKeyPathStringConvertible>(_ lhs: KeyPath<O, RelationshipContainer<O>.ToOne<D>>, _ rhs: KeyPath<D, K>) -> Where<O>.Expression<Where<O>.CollectionTarget, K.DestinationValueType> where K.ObjectType == D {
return .init(
O.meta[keyPath: lhs].cs_keyPathString,
D.meta[keyPath: rhs].cs_keyPathString
)
}
/** /**
Connects multiple `KeyPathStringConvertible`s to create a type-safe chain usable in query/fetch expressions Connects multiple `KeyPathStringConvertible`s to create a type-safe chain usable in query/fetch expressions
``` ```
@@ -714,3 +680,28 @@ extension Where {
} }
} }
} }
// MARK: - Deprecated
@available(*, deprecated, message: """
Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
""")
public func ~ <O: CoreStoreObject, D: CoreStoreObject, K: KeyPathStringConvertible>(_ lhs: KeyPath<O, RelationshipContainer<O>.ToOne<D>>, _ rhs: KeyPath<D, K>) -> Where<O>.Expression<Where<O>.SingleTarget, K.DestinationValueType> where K.ObjectType == D {
return .init(
O.meta[keyPath: lhs].cs_keyPathString,
D.meta[keyPath: rhs].cs_keyPathString
)
}
@available(*, deprecated, message: """
Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
""")
public func ~ <O: CoreStoreObject, D: CoreStoreObject, K: ToManyRelationshipKeyPathStringConvertible>(_ lhs: KeyPath<O, RelationshipContainer<O>.ToOne<D>>, _ rhs: KeyPath<D, K>) -> Where<O>.Expression<Where<O>.CollectionTarget, K.DestinationValueType> where K.ObjectType == D {
return .init(
O.meta[keyPath: lhs].cs_keyPathString,
D.meta[keyPath: rhs].cs_keyPathString
)
}

View File

@@ -360,12 +360,6 @@ public struct Where<O: DynamicObject>: WhereClauseType, FetchClause, QueryClause
hasher.combine(self.predicate) hasher.combine(self.predicate)
} }
// MARK: Deprecated
@available(*, deprecated, renamed: "O")
public typealias D = O
} }
@@ -544,116 +538,6 @@ extension Where where O: CoreStoreObject {
self.init(O.meta[keyPath: keyPath].keyPath, isMemberOf: list) self.init(O.meta[keyPath: keyPath].keyPath, isMemberOf: list)
} }
/**
Initializes a `Where` clause that compares equality
- parameter keyPath: the keyPath to compare with
- parameter value: the arguments for the `==` operator
*/
public init<V>(_ keyPath: KeyPath<O, ValueContainer<O>.Required<V>>, isEqualTo value: V?) {
self.init(O.meta[keyPath: keyPath].keyPath, isEqualTo: value)
}
/**
Initializes a `Where` clause that compares equality
- parameter keyPath: the keyPath to compare with
- parameter value: the arguments for the `==` operator
*/
public init<V>(_ keyPath: KeyPath<O, ValueContainer<O>.Optional<V>>, isEqualTo value: V?) {
self.init(O.meta[keyPath: keyPath].keyPath, isEqualTo: value)
}
/**
Initializes a `Where` clause that compares equality to `nil`
- parameter keyPath: the keyPath to compare with
- parameter null: the arguments for the `==` operator
*/
public init<V>(_ keyPath: KeyPath<O, ValueContainer<O>.Optional<V>>, isEqualTo null: Void?) {
self.init(O.meta[keyPath: keyPath].keyPath, isEqualTo: null)
}
/**
Initializes a `Where` clause that compares equality to `nil`
- parameter keyPath: the keyPath to compare with
- parameter null: the arguments for the `==` operator
*/
public init<D>(_ keyPath: KeyPath<O, RelationshipContainer<O>.ToOne<D>>, isEqualTo null: Void?) {
self.init(O.meta[keyPath: keyPath].keyPath, isEqualTo: null)
}
/**
Initializes a `Where` clause that compares equality
- parameter keyPath: the keyPath to compare with
- parameter value: the arguments for the `==` operator
*/
public init<D>(_ keyPath: KeyPath<O, RelationshipContainer<O>.ToOne<D>>, isEqualTo value: D?) {
self.init(O.meta[keyPath: keyPath].keyPath, isEqualTo: value)
}
/**
Initializes a `Where` clause that compares equality
- parameter keyPath: the keyPath to compare with
- parameter objectID: the arguments for the `==` operator
*/
public init<D>(_ keyPath: KeyPath<O, RelationshipContainer<O>.ToOne<D>>, isEqualTo objectID: NSManagedObjectID) {
self.init(O.meta[keyPath: keyPath].keyPath, isEqualTo: objectID)
}
/**
Initializes a `Where` clause that compares membership
- parameter keyPath: the keyPath to compare with
- parameter list: the sequence to check membership of
*/
public init<V, S: Sequence>(_ keyPath: KeyPath<O, ValueContainer<O>.Required<V>>, isMemberOf list: S) where S.Iterator.Element == V {
self.init(O.meta[keyPath: keyPath].keyPath, isMemberOf: list)
}
/**
Initializes a `Where` clause that compares membership
- parameter keyPath: the keyPath to compare with
- parameter list: the sequence to check membership of
*/
public init<V, S: Sequence>(_ keyPath: KeyPath<O, ValueContainer<O>.Optional<V>>, isMemberOf list: S) where S.Iterator.Element == V {
self.init(O.meta[keyPath: keyPath].keyPath, isMemberOf: list)
}
/**
Initializes a `Where` clause that compares membership
- parameter keyPath: the keyPath to compare with
- parameter list: the sequence to check membership of
*/
public init<D, S: Sequence>(_ keyPath: KeyPath<O, RelationshipContainer<O>.ToOne<D>>, isMemberOf list: S) where S.Iterator.Element == D {
self.init(O.meta[keyPath: keyPath].keyPath, isMemberOf: list)
}
/**
Initializes a `Where` clause that compares membership
- parameter keyPath: the keyPath to compare with
- parameter list: the sequence to check membership of
*/
public init<D, S: Sequence>(_ keyPath: KeyPath<O, RelationshipContainer<O>.ToOne<D>>, isMemberOf list: S) where S.Iterator.Element: NSManagedObjectID {
self.init(O.meta[keyPath: keyPath].keyPath, isMemberOf: list)
}
/** /**
Initializes a `Where` clause from a closure Initializes a `Where` clause from a closure
@@ -686,3 +570,62 @@ extension Sequence where Iterator.Element: WhereClauseType {
return Where(NSCompoundPredicate(type: .or, subpredicates: self.map({ $0.predicate }))) return Where(NSCompoundPredicate(type: .or, subpredicates: self.map({ $0.predicate })))
} }
} }
// MARK: - Deprecated
@available(*, deprecated, message: """
Legacy `Value.*`, `Transformable.*`, and `Relationship.*` declarations will soon be obsoleted. Please migrate your models and stores to new models that use `@Field.*` property wrappers. See: https://github.com/JohnEstropia/CoreStore?tab=readme-ov-file#new-field-property-wrapper-syntax
""")
extension Where where O: CoreStoreObject {
public init<V>(_ keyPath: KeyPath<O, ValueContainer<O>.Required<V>>, isEqualTo value: V?) {
self.init(O.meta[keyPath: keyPath].keyPath, isEqualTo: value)
}
public init<V>(_ keyPath: KeyPath<O, ValueContainer<O>.Optional<V>>, isEqualTo value: V?) {
self.init(O.meta[keyPath: keyPath].keyPath, isEqualTo: value)
}
public init<V>(_ keyPath: KeyPath<O, ValueContainer<O>.Optional<V>>, isEqualTo null: Void?) {
self.init(O.meta[keyPath: keyPath].keyPath, isEqualTo: null)
}
public init<D>(_ keyPath: KeyPath<O, RelationshipContainer<O>.ToOne<D>>, isEqualTo null: Void?) {
self.init(O.meta[keyPath: keyPath].keyPath, isEqualTo: null)
}
public init<D>(_ keyPath: KeyPath<O, RelationshipContainer<O>.ToOne<D>>, isEqualTo value: D?) {
self.init(O.meta[keyPath: keyPath].keyPath, isEqualTo: value)
}
public init<D>(_ keyPath: KeyPath<O, RelationshipContainer<O>.ToOne<D>>, isEqualTo objectID: NSManagedObjectID) {
self.init(O.meta[keyPath: keyPath].keyPath, isEqualTo: objectID)
}
public init<V, S: Sequence>(_ keyPath: KeyPath<O, ValueContainer<O>.Required<V>>, isMemberOf list: S) where S.Iterator.Element == V {
self.init(O.meta[keyPath: keyPath].keyPath, isMemberOf: list)
}
public init<V, S: Sequence>(_ keyPath: KeyPath<O, ValueContainer<O>.Optional<V>>, isMemberOf list: S) where S.Iterator.Element == V {
self.init(O.meta[keyPath: keyPath].keyPath, isMemberOf: list)
}
public init<D, S: Sequence>(_ keyPath: KeyPath<O, RelationshipContainer<O>.ToOne<D>>, isMemberOf list: S) where S.Iterator.Element == D {
self.init(O.meta[keyPath: keyPath].keyPath, isMemberOf: list)
}
public init<D, S: Sequence>(_ keyPath: KeyPath<O, RelationshipContainer<O>.ToOne<D>>, isMemberOf list: S) where S.Iterator.Element: NSManagedObjectID {
self.init(O.meta[keyPath: keyPath].keyPath, isMemberOf: list)
}
}