From 7c2129e38f785c91d428603bf0c0c0b8861d3c18 Mon Sep 17 00:00:00 2001 From: John Estropia Date: Sun, 28 Jan 2024 22:11:21 +0900 Subject: [PATCH] Deprecation of legacy ValueContainer and RelationshipContainer properties in favor of @Field propertyWrapper counterpart --- Sources/CoreStoreObject+Observing.swift | 309 +++++------- Sources/CoreStoreObject+Querying.swift | 119 +---- Sources/CoreStoreSchema.swift | 7 - Sources/DataStack+DataSources.swift | 45 -- Sources/DataStack.AddStoragePublisher.swift | 6 - ...aSource.CollectionViewAdapter-AppKit.swift | 9 - ...taSource.CollectionViewAdapter-UIKit.swift | 9 - ...bleDataSource.TableViewAdapter-UIKit.swift | 9 - Sources/FetchChainBuilder.swift | 6 - Sources/From+Querying.swift | 468 +++++------------- Sources/From.swift | 6 - Sources/GroupBy.swift | 69 +-- Sources/Into.swift | 6 - Sources/KeyPath+Querying.swift | 185 +++---- Sources/KeyPathGenericBindings.swift | 6 - Sources/KeyPathStringConvertible.swift | 9 - Sources/ListMonitor.swift | 21 - Sources/ObjectMonitor.swift | 6 - Sources/ObjectPublisher.swift | 62 +-- Sources/ObjectSnapshot.swift | 84 ++-- Sources/OrderBy.swift | 135 +++-- Sources/PartialObject.swift | 101 +--- Sources/QueryChainBuilder.swift | 6 - Sources/Relationship.ToManyOrdered.swift | 200 +------- Sources/Relationship.ToManyUnordered.swift | 219 +------- Sources/Relationship.ToOne.swift | 169 +------ Sources/Relationship.swift | 39 +- Sources/SectionBy.swift | 217 ++------ Sources/SectionMonitorBuilder.swift | 6 - Sources/Select.swift | 89 ++-- Sources/Transformable.Optional.swift | 119 +---- Sources/Transformable.Required.swift | 113 +---- Sources/Transformable.swift | 32 +- Sources/Value.Optional.swift | 171 +------ Sources/Value.Required.swift | 152 +----- Sources/Value.swift | 32 +- Sources/Where.Expression.swift | 59 +-- Sources/Where.swift | 133 ++--- 38 files changed, 754 insertions(+), 2679 deletions(-) diff --git a/Sources/CoreStoreObject+Observing.swift b/Sources/CoreStoreObject+Observing.swift index a04f8391..ae46f59e 100644 --- a/Sources/CoreStoreObject+Observing.swift +++ b/Sources/CoreStoreObject+Observing.swift @@ -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) -> 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) -> 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) -> 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) -> 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) -> Void) -> CoreStoreObjectKeyValueObservation { - - let result = _CoreStoreObjectKeyValueObservation( - object: self.rawObject!, - keyPath: self.keyPath, - callback: { (object, kind, newValue, oldValue, _, isPrior) in - - let notification = CoreStoreObjectObjectDiff( - 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) -> Void) -> CoreStoreObjectKeyValueObservation { - - let result = _CoreStoreObjectKeyValueObservation( - object: self.rawObject!, - keyPath: self.keyPath, - callback: { (object, kind, newValue, oldValue, _, isPrior) in - - let notification = CoreStoreObjectUnorderedDiff( - 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) -> Void) -> CoreStoreObjectKeyValueObservation { - - let result = _CoreStoreObjectKeyValueObservation( - object: self.rawObject!, - keyPath: self.keyPath, - callback: { (object, kind, newValue, oldValue, indexes, isPrior) in - - let notification = CoreStoreObjectOrderedDiff( - 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 /** @@ -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) -> 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) -> 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) -> 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) -> 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) -> Void) -> CoreStoreObjectKeyValueObservation { + + let result = _CoreStoreObjectKeyValueObservation( + object: self.rawObject!, + keyPath: self.keyPath, + callback: { (object, kind, newValue, oldValue, _, isPrior) in + + let notification = CoreStoreObjectObjectDiff( + 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) -> Void) -> CoreStoreObjectKeyValueObservation { + + let result = _CoreStoreObjectKeyValueObservation( + object: self.rawObject!, + keyPath: self.keyPath, + callback: { (object, kind, newValue, oldValue, _, isPrior) in + + let notification = CoreStoreObjectUnorderedDiff( + 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) -> Void) -> CoreStoreObjectKeyValueObservation { + + let result = _CoreStoreObjectKeyValueObservation( + object: self.rawObject!, + keyPath: self.keyPath, + callback: { (object, kind, newValue, oldValue, indexes, isPrior) in + + let notification = CoreStoreObjectOrderedDiff( + 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 + } +} diff --git a/Sources/CoreStoreObject+Querying.swift b/Sources/CoreStoreObject+Querying.swift index e4026f23..71063e92 100644 --- a/Sources/CoreStoreObject+Querying.swift +++ b/Sources/CoreStoreObject+Querying.swift @@ -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 { - /** - Creates a `Where` clause by comparing if a property is equal to a value - ``` - let person = dataStack.fetchOne(From().where({ $0.nickname == "John" })) - ``` - */ public static func == (_ attribute: ValueContainer.Required, _ value: V) -> Where { 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().where({ $0.nickname != "John" })) - ``` - */ public static func != (_ attribute: ValueContainer.Required, _ value: V) -> Where { 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().where({ $0.age < 20 })) - ``` - */ public static func < (_ attribute: ValueContainer.Required, _ value: V) -> Where { 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().where({ $0.age > 20 })) - ``` - */ public static func > (_ attribute: ValueContainer.Required, _ value: V) -> Where { 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().where({ $0.age <= 20 })) - ``` - */ public static func <= (_ attribute: ValueContainer.Required, _ value: V) -> Where { 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().where({ $0.age >= 20 })) - ``` - */ public static func >= (_ attribute: ValueContainer.Required, _ value: V) -> Where { 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().where({ ["Pluto", "Snoopy", "Scooby"] ~= $0.nickname })) - ``` - */ public static func ~= (_ sequence: S, _ attribute: ValueContainer.Required) -> Where where S.Iterator.Element == V { return Where(attribute.keyPath, isMemberOf: sequence) } } - -// MARK: - ValueContainer.Optional - +@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 { - /** - Creates a `Where` clause by comparing if a property is equal to a value - ``` - let person = dataStack.fetchOne(From().where({ $0.nickname == "John" })) - ``` - */ public static func == (_ attribute: ValueContainer.Optional, _ value: V?) -> Where { 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().where({ $0.nickname != "John" })) - ``` - */ public static func != (_ attribute: ValueContainer.Optional, _ value: V?) -> Where { 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().where({ $0.age < 20 })) - ``` - */ public static func < (_ attribute: ValueContainer.Optional, _ value: V?) -> Where { 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().where({ $0.age > 20 })) - ``` - */ public static func > (_ attribute: ValueContainer.Optional, _ value: V?) -> Where { 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().where({ $0.age <= 20 })) - ``` - */ public static func <= (_ attribute: ValueContainer.Optional, _ value: V?) -> Where { 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().where({ $0.age >= 20 })) - ``` - */ public static func >= (_ attribute: ValueContainer.Optional, _ value: V?) -> Where { 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().where({ ["Pluto", "Snoopy", "Scooby"] ~= $0.nickname })) - ``` - */ public static func ~= (_ sequence: S, _ attribute: ValueContainer.Optional) -> Where where S.Iterator.Element == V { return Where(attribute.keyPath, isMemberOf: sequence) } } - -// MARK: - RelationshipContainer.ToOne - +@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 { - /** - Creates a `Where` clause by comparing if a property is equal to a value - ``` - let dog = dataStack.fetchOne(From().where({ $0.master == me })) - ``` - */ public static func == (_ relationship: RelationshipContainer.ToOne, _ object: D?) -> Where { 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().where({ $0.master != me })) - ``` - */ public static func != (_ relationship: RelationshipContainer.ToOne, _ object: D?) -> Where { 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().where({ [john, joe, bob] ~= $0.master })) - ``` - */ public static func ~= (_ sequence: S, _ relationship: RelationshipContainer.ToOne) -> Where where S.Iterator.Element == D { return Where(relationship.keyPath, isMemberOf: sequence) diff --git a/Sources/CoreStoreSchema.swift b/Sources/CoreStoreSchema.swift index dd26d941..2e842f94 100644 --- a/Sources/CoreStoreSchema.swift +++ b/Sources/CoreStoreSchema.swift @@ -636,13 +636,6 @@ public final class CoreStoreSchema: DynamicSchema { } 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)! } defer { diff --git a/Sources/DataStack+DataSources.swift b/Sources/DataStack+DataSources.swift index d6cc5e17..3c82eb27 100644 --- a/Sources/DataStack+DataSources.swift +++ b/Sources/DataStack+DataSources.swift @@ -189,51 +189,6 @@ extension DataStack { } ) } - - - // MARK: Deprecated - - @available(*, deprecated, renamed: "publishObject(_:)") - public func objectPublisher(_ object: O) -> ObjectPublisher { - - return self.publishObject(object) - } - - @available(*, deprecated, renamed: "publishList(_:_:)") - public func listPublisher(_ from: From, _ fetchClauses: FetchClause...) -> ListPublisher { - - return self.publishList(from, fetchClauses) - } - - @available(*, deprecated, renamed: "publishList(_:_:)") - public func listPublisher(_ from: From, _ fetchClauses: [FetchClause]) -> ListPublisher { - - return self.publishList(from, fetchClauses) - } - - @available(*, deprecated, renamed: "publishList(_:)") - public func listPublisher(_ clauseChain: B) -> ListPublisher { - - return self.publishList(clauseChain) - } - - @available(*, deprecated, renamed: "publishList(_:_:_:)") - public func listPublisher(_ from: From, _ sectionBy: SectionBy, _ fetchClauses: FetchClause...) -> ListPublisher { - - return self.publishList(from, sectionBy, fetchClauses) - } - - @available(*, deprecated, renamed: "publishList(_:_:_:)") - public func listPublisher(_ from: From, _ sectionBy: SectionBy, _ fetchClauses: [FetchClause]) -> ListPublisher { - - return self.publishList(from, sectionBy, fetchClauses) - } - - @available(*, deprecated, renamed: "publishList(_:)") - public func listPublisher(_ clauseChain: B) -> ListPublisher { - - return self.publishList(clauseChain) - } } #endif diff --git a/Sources/DataStack.AddStoragePublisher.swift b/Sources/DataStack.AddStoragePublisher.swift index 69ea6649..237be98f 100644 --- a/Sources/DataStack.AddStoragePublisher.swift +++ b/Sources/DataStack.AddStoragePublisher.swift @@ -182,12 +182,6 @@ extension DataStack { private let storage: Storage private var subscriber: S? } - - - // MARK: Deprecated - - @available(*, deprecated, renamed: "MigrationProgress") - public typealias MigrationProgress = CoreStore.MigrationProgress } } diff --git a/Sources/DiffableDataSource.CollectionViewAdapter-AppKit.swift b/Sources/DiffableDataSource.CollectionViewAdapter-AppKit.swift index 39fb38a2..fb27d34c 100644 --- a/Sources/DiffableDataSource.CollectionViewAdapter-AppKit.swift +++ b/Sources/DiffableDataSource.CollectionViewAdapter-AppKit.swift @@ -237,13 +237,4 @@ extension DiffableDataSource { } -// MARK: Deprecated - -extension DiffableDataSource { - - @available(*, deprecated, renamed: "CollectionViewAdapter") - public typealias CollectionView = CollectionViewAdapter -} - - #endif diff --git a/Sources/DiffableDataSource.CollectionViewAdapter-UIKit.swift b/Sources/DiffableDataSource.CollectionViewAdapter-UIKit.swift index 4c22f4e4..108cdd04 100644 --- a/Sources/DiffableDataSource.CollectionViewAdapter-UIKit.swift +++ b/Sources/DiffableDataSource.CollectionViewAdapter-UIKit.swift @@ -240,13 +240,4 @@ extension DiffableDataSource { } } - -// MARK: Deprecated - -extension DiffableDataSource { - - @available(*, deprecated, renamed: "CollectionViewAdapter") - public typealias CollectionView = CollectionViewAdapter -} - #endif diff --git a/Sources/DiffableDataSource.TableViewAdapter-UIKit.swift b/Sources/DiffableDataSource.TableViewAdapter-UIKit.swift index 3747d966..690d8923 100644 --- a/Sources/DiffableDataSource.TableViewAdapter-UIKit.swift +++ b/Sources/DiffableDataSource.TableViewAdapter-UIKit.swift @@ -299,13 +299,4 @@ extension DiffableDataSource { } } - -// MARK: Deprecated - -extension DiffableDataSource { - - @available(*, deprecated, renamed: "TableViewAdapter") - public typealias TableView = TableViewAdapter -} - #endif diff --git a/Sources/FetchChainBuilder.swift b/Sources/FetchChainBuilder.swift index 1071e08f..7d7d0613 100644 --- a/Sources/FetchChainBuilder.swift +++ b/Sources/FetchChainBuilder.swift @@ -47,12 +47,6 @@ public struct FetchChainBuilder: FetchChainableBuilderType { public var from: From public var fetchClauses: [FetchClause] = [] - - - // MARK: Deprecated - - @available(*, deprecated, renamed: "O") - public typealias D = O } diff --git a/Sources/From+Querying.swift b/Sources/From+Querying.swift index d092e1b8..8d787c75 100644 --- a/Sources/From+Querying.swift +++ b/Sources/From+Querying.swift @@ -276,21 +276,6 @@ extension From { 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 { - - return self.sectionBy( - sectionKeyPath, - sectionIndexTransformer: sectionIndexTransformer - ) - } } @@ -341,21 +326,6 @@ extension From where O: NSManagedObject { sectionIndexTransformer: sectionIndexTransformer ) } - - - // MARK: Deprecated - - @available(*, deprecated, renamed: "sectionBy(_:sectionIndexTransformer:)") - public func sectionBy( - _ sectionKeyPath: KeyPath, - _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? - ) -> SectionMonitorChainBuilder { - - return self.sectionBy( - sectionKeyPath._kvcKeyPathString!, - sectionIndexTransformer: sectionIndexTransformer - ) - } } @@ -374,50 +344,6 @@ extension From where O: CoreStoreObject { 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(_ keyPath: KeyPath.Required>) -> QueryChainBuilder { - - return self.select(R.self, [SelectTerm.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(_ keyPath: KeyPath.Optional>) -> QueryChainBuilder { - - return self.select(R.self, [SelectTerm.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(_ keyPath: KeyPath.Required>) -> QueryChainBuilder { - - return self.select(R.self, [SelectTerm.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(_ keyPath: KeyPath.Optional>) -> QueryChainBuilder { - - return self.select(R.self, [SelectTerm.attribute(keyPath)]) - } - /** 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 } ) } - - /** - 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(_ sectionKeyPath: KeyPath.Required>) -> SectionMonitorChainBuilder { - - 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(_ sectionKeyPath: KeyPath.Optional>) -> SectionMonitorChainBuilder { - - 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(_ sectionKeyPath: KeyPath.Required>) -> SectionMonitorChainBuilder { - - 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(_ sectionKeyPath: KeyPath.Optional>) -> SectionMonitorChainBuilder { - - 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 @@ -572,169 +442,6 @@ extension From where O: CoreStoreObject { 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( - _ sectionKeyPath: KeyPath.Required>, - sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? - ) -> SectionMonitorChainBuilder { - - 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( - _ sectionKeyPath: KeyPath.Optional>, - sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? - ) -> SectionMonitorChainBuilder { - - 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( - _ sectionKeyPath: KeyPath.Required>, - sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? - ) -> SectionMonitorChainBuilder { - - 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( - _ sectionKeyPath: KeyPath.Optional>, - sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? - ) -> SectionMonitorChainBuilder { - - return self.sectionBy( - O.meta[keyPath: sectionKeyPath].keyPath, - sectionIndexTransformer: sectionIndexTransformer - ) - } - - - // MARK: Deprecated - - @available(*, deprecated, renamed: "sectionBy(_:sectionIndexTransformer:)") - public func sectionBy( - _ sectionKeyPath: KeyPath.Stored>, - _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? - ) -> SectionMonitorChainBuilder { - - return self.sectionBy( - sectionKeyPath, - sectionIndexTransformer: sectionIndexTransformer - ) - } - - @available(*, deprecated, renamed: "sectionBy(_:sectionIndexTransformer:)") - public func sectionBy( - _ sectionKeyPath: KeyPath.Virtual>, - _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? - ) -> SectionMonitorChainBuilder { - - return self.sectionBy( - sectionKeyPath, - sectionIndexTransformer: sectionIndexTransformer - ) - } - - @available(*, deprecated, renamed: "sectionBy(_:sectionIndexTransformer:)") - public func sectionBy( - _ sectionKeyPath: KeyPath.Coded>, - _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? - ) -> SectionMonitorChainBuilder { - - return self.sectionBy( - sectionKeyPath, - sectionIndexTransformer: sectionIndexTransformer - ) - } - - @available(*, deprecated, renamed: "sectionBy(_:sectionIndexTransformer:)") - public func sectionBy( - _ sectionKeyPath: KeyPath.Required>, - _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? - ) -> SectionMonitorChainBuilder { - - return self.sectionBy( - sectionKeyPath, - sectionIndexTransformer: sectionIndexTransformer - ) - } - - @available(*, deprecated, renamed: "sectionBy(_:sectionIndexTransformer:)") - public func sectionBy( - _ sectionKeyPath: KeyPath.Optional>, - _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? - ) -> SectionMonitorChainBuilder { - - return self.sectionBy( - sectionKeyPath, - sectionIndexTransformer: sectionIndexTransformer - ) - } - - @available(*, deprecated, renamed: "sectionBy(_:sectionIndexTransformer:)") - public func sectionBy( - _ sectionKeyPath: KeyPath.Required>, - _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? - ) -> SectionMonitorChainBuilder { - - return self.sectionBy( - sectionKeyPath, - sectionIndexTransformer: sectionIndexTransformer - ) - } - - @available(*, deprecated, renamed: "sectionBy(_:sectionIndexTransformer:)") - public func sectionBy( - _ sectionKeyPath: KeyPath.Optional>, - _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? - ) -> SectionMonitorChainBuilder { - - return self.sectionBy( - sectionKeyPath, - sectionIndexTransformer: sectionIndexTransformer - ) - } } @@ -1147,50 +854,6 @@ extension QueryChainBuilder where O: CoreStoreObject { return self.groupBy(GroupBy(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(_ keyPath: KeyPath.Required>) -> QueryChainBuilder { - - return self.groupBy(GroupBy(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(_ keyPath: KeyPath.Optional>) -> QueryChainBuilder { - - return self.groupBy(GroupBy(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(_ keyPath: KeyPath.Required>) -> QueryChainBuilder { - - return self.groupBy(GroupBy(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(_ keyPath: KeyPath.Optional>) -> QueryChainBuilder { - - return self.groupBy(GroupBy(keyPath)) - } } @@ -1360,3 +1023,134 @@ extension SectionMonitorChainBuilder where O: CoreStoreObject { 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(_ keyPath: KeyPath.Required>) -> QueryChainBuilder { + + return self.select(R.self, [SelectTerm.attribute(keyPath)]) + } + + public func select(_ keyPath: KeyPath.Optional>) -> QueryChainBuilder { + + return self.select(R.self, [SelectTerm.attribute(keyPath)]) + } + + public func select(_ keyPath: KeyPath.Required>) -> QueryChainBuilder { + + return self.select(R.self, [SelectTerm.attribute(keyPath)]) + } + + public func select(_ keyPath: KeyPath.Optional>) -> QueryChainBuilder { + + return self.select(R.self, [SelectTerm.attribute(keyPath)]) + } + + public func sectionBy(_ sectionKeyPath: KeyPath.Required>) -> SectionMonitorChainBuilder { + + return self.sectionBy( + O.meta[keyPath: sectionKeyPath].keyPath, + sectionIndexTransformer: { _ in nil } + ) + } + + public func sectionBy(_ sectionKeyPath: KeyPath.Optional>) -> SectionMonitorChainBuilder { + + return self.sectionBy( + O.meta[keyPath: sectionKeyPath].keyPath, + sectionIndexTransformer: { _ in nil } + ) + } + + public func sectionBy(_ sectionKeyPath: KeyPath.Required>) -> SectionMonitorChainBuilder { + + return self.sectionBy( + O.meta[keyPath: sectionKeyPath].keyPath, + sectionIndexTransformer: { _ in nil } + ) + } + + public func sectionBy(_ sectionKeyPath: KeyPath.Optional>) -> SectionMonitorChainBuilder { + + return self.sectionBy( + O.meta[keyPath: sectionKeyPath].keyPath, + sectionIndexTransformer: { _ in nil } + ) + } + + public func sectionBy( + _ sectionKeyPath: KeyPath.Required>, + sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? + ) -> SectionMonitorChainBuilder { + + return self.sectionBy( + O.meta[keyPath: sectionKeyPath].keyPath, + sectionIndexTransformer: sectionIndexTransformer + ) + } + + public func sectionBy( + _ sectionKeyPath: KeyPath.Optional>, + sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? + ) -> SectionMonitorChainBuilder { + + return self.sectionBy( + O.meta[keyPath: sectionKeyPath].keyPath, + sectionIndexTransformer: sectionIndexTransformer + ) + } + + public func sectionBy( + _ sectionKeyPath: KeyPath.Required>, + sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? + ) -> SectionMonitorChainBuilder { + + return self.sectionBy( + O.meta[keyPath: sectionKeyPath].keyPath, + sectionIndexTransformer: sectionIndexTransformer + ) + } + + public func sectionBy( + _ sectionKeyPath: KeyPath.Optional>, + sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? + ) -> SectionMonitorChainBuilder { + + 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(_ keyPath: KeyPath.Required>) -> QueryChainBuilder { + + return self.groupBy(GroupBy(keyPath)) + } + + public func groupBy(_ keyPath: KeyPath.Optional>) -> QueryChainBuilder { + + return self.groupBy(GroupBy(keyPath)) + } + + public func groupBy(_ keyPath: KeyPath.Required>) -> QueryChainBuilder { + + return self.groupBy(GroupBy(keyPath)) + } + + public func groupBy(_ keyPath: KeyPath.Optional>) -> QueryChainBuilder { + + return self.groupBy(GroupBy(keyPath)) + } +} diff --git a/Sources/From.swift b/Sources/From.swift index c12bbefb..cc9de01d 100644 --- a/Sources/From.swift +++ b/Sources/From.swift @@ -211,10 +211,4 @@ public struct From { } } } - - - // MARK: Deprecated - - @available(*, deprecated, renamed: "O") - public typealias D = O } diff --git a/Sources/GroupBy.swift b/Sources/GroupBy.swift index c17067d8..6aa347f0 100644 --- a/Sources/GroupBy.swift +++ b/Sources/GroupBy.swift @@ -101,12 +101,6 @@ public struct GroupBy: GroupByClause, QueryClause, Hashable { hasher.combine(self.keyPaths) } - - - // MARK: Deprecated - - @available(*, deprecated, renamed: "O") - public typealias D = O } extension GroupBy where O: NSManagedObject { @@ -153,63 +147,52 @@ extension GroupBy where O: CoreStoreObject { self.init([O.meta[keyPath: keyPath].keyPath]) } +} + + +// MARK: - GroupByClause + +/** + Abstracts the `GroupBy` clause for protocol utilities. + */ +public protocol GroupByClause { /** - Initializes a `GroupBy` clause with a key path - - - parameter keyPath: a key path to group results with + The `DynamicObject` type associated with the clause */ + associatedtype ObjectType: DynamicObject + + /** + The list of key path strings to group results with + */ + 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(_ keyPath: KeyPath.Required>) { 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(_ keyPath: KeyPath.Optional>) { 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(_ keyPath: KeyPath.Required>) { 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(_ keyPath: KeyPath.Optional>) { self.init([O.meta[keyPath: keyPath].keyPath]) } } - - -// MARK: - GroupByClause - -/** - Abstracts the `GroupBy` clause for protocol utilities. - */ -public protocol GroupByClause { - - /** - The `DynamicObject` type associated with the clause - */ - associatedtype ObjectType: DynamicObject - - /** - The list of key path strings to group results with - */ - var keyPaths: [KeyPathString] { get } -} diff --git a/Sources/Into.swift b/Sources/Into.swift index 73c87055..b3e97fda 100644 --- a/Sources/Into.swift +++ b/Sources/Into.swift @@ -131,10 +131,4 @@ public struct Into: Hashable { self.configuration = configuration self.inferStoreIfPossible = inferStoreIfPossible } - - - // MARK: Deprecated - - @available(*, deprecated, renamed: "O") - public typealias D = O } diff --git a/Sources/KeyPath+Querying.swift b/Sources/KeyPath+Querying.swift index a70491e6..e916213f 100644 --- a/Sources/KeyPath+Querying.swift +++ b/Sources/KeyPath+Querying.swift @@ -588,133 +588,91 @@ public func ~= (_ sequence: S, _ } -// MARK: - KeyPath where Root: CoreStoreObject, Value: ValueContainer.Required +// MARK: - Deprecated -/** - Creates a `Where` clause by comparing if a property is equal to a value - ``` - let person = dataStack.fetchOne(From().where(\.nickname == "John")) - ``` - */ +@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 == (_ keyPath: KeyPath.Required>, _ value: V) -> Where { return Where(O.meta[keyPath: keyPath].keyPath, isEqualTo: value) } -/** - Creates a `Where` clause by comparing if a property is not equal to a value - ``` - let person = dataStack.fetchOne(From().where(\.nickname != "John")) - ``` - */ +@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 != (_ keyPath: KeyPath.Required>, _ value: V) -> Where { return !Where(O.meta[keyPath: keyPath].keyPath, isEqualTo: value) } -/** - Creates a `Where` clause by checking if a sequence contains the value of a property - ``` - let dog = dataStack.fetchOne(From().where(["Pluto", "Snoopy", "Scooby"] ~= \.nickname)) - ``` - */ +@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 ~= (_ sequence: S, _ keyPath: KeyPath.Required>) -> Where where S.Iterator.Element == V { return Where(O.meta[keyPath: keyPath].keyPath, isMemberOf: sequence) } - -// MARK: - KeyPath where Root: CoreStoreObject, Value: ValueContainer.Optional - -/** - Creates a `Where` clause by comparing if a property is equal to a value - ``` - let person = dataStack.fetchOne(From().where(\.nickname == "John")) - ``` - */ +@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 == (_ keyPath: KeyPath.Optional>, _ value: V?) -> Where { return Where(O.meta[keyPath: keyPath].keyPath, isEqualTo: value) } -/** - Creates a `Where` clause by comparing if a property is not equal to a value - ``` - let person = dataStack.fetchOne(From().where(\.nickname != "John")) - ``` - */ +@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 != (_ keyPath: KeyPath.Optional>, _ value: V?) -> Where { return !Where(O.meta[keyPath: keyPath].keyPath, isEqualTo: value) } -/** - Creates a `Where` clause by checking if a sequence contains the value of a property - ``` - let dog = dataStack.fetchOne(From().where(["Pluto", "Snoopy", "Scooby"] ~= \.nickname)) - ``` - */ +@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 ~= (_ sequence: S, _ keyPath: KeyPath.Optional>) -> Where where S.Iterator.Element == V { return Where(O.meta[keyPath: keyPath].keyPath, isMemberOf: sequence) } - -// MARK: - KeyPath where Root: CoreStoreObject, Value: ValueContainer.Required - -/** - Creates a `Where` clause by comparing if a property is less than a value - ``` - let person = dataStack.fetchOne(From().where(\.age < 20)) - ``` - */ +@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 < (_ keyPath: KeyPath.Required>, _ value: V) -> Where { return Where("%K < %@", O.meta[keyPath: keyPath].keyPath, value.cs_toQueryableNativeType()) } -/** - Creates a `Where` clause by comparing if a property is greater than a value - ``` - let person = dataStack.fetchOne(From().where(\.age > 20)) - ``` - */ +@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 > (_ keyPath: KeyPath.Required>, _ value: V) -> Where { return Where("%K > %@", O.meta[keyPath: keyPath].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().where(\.age <= 20)) - ``` - */ +@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 <= (_ keyPath: KeyPath.Required>, _ value: V) -> Where { return Where("%K <= %@", O.meta[keyPath: keyPath].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().where(\.age >= 20)) - ``` - */ +@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 >= (_ keyPath: KeyPath.Required>, _ value: V) -> Where { return Where("%K >= %@", O.meta[keyPath: keyPath].keyPath, value.cs_toQueryableNativeType()) } - -// MARK: - KeyPath where Root: CoreStoreObject, Value: ValueContainer.Optional - -/** - Creates a `Where` clause by comparing if a property is less than a value - ``` - let person = dataStack.fetchOne(From().where(\.age < 20)) - ``` - */ +@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 < (_ keyPath: KeyPath.Optional>, _ value: V?) -> Where { if let value = value { @@ -727,12 +685,9 @@ public func < (_ keyPath: KeyPath.Optional>, _ val } } -/** - Creates a `Where` clause by comparing if a property is greater than a value - ``` - let person = dataStack.fetchOne(From().where(\.age > 20)) - ``` - */ +@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 > (_ keyPath: KeyPath.Optional>, _ value: V?) -> Where { if let value = value { @@ -745,12 +700,9 @@ public func > (_ keyPath: KeyPath.Optional>, _ val } } -/** - Creates a `Where` clause by comparing if a property is less than or equal to a value - ``` - let person = dataStack.fetchOne(From().where(\.age <= 20)) - ``` - */ +@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 <= (_ keyPath: KeyPath.Optional>, _ value: V?) -> Where { if let value = value { @@ -763,12 +715,9 @@ public func <= (_ keyPath: KeyPath.Optional>, _ va } } -/** - Creates a `Where` clause by comparing if a property is greater than or equal to a value - ``` - let person = dataStack.fetchOne(From().where(\.age >= 20)) - ``` - */ +@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 >= (_ keyPath: KeyPath.Optional>, _ value: V?) -> Where { if let value = value { @@ -781,59 +730,41 @@ public func >= (_ keyPath: KeyPath.Optional>, _ va } } - -// MARK: - KeyPath where Root: CoreStoreObject, Value: RelationshipContainer.ToOne - -/** - Creates a `Where` clause by comparing if a property is equal to a value - ``` - let dog = dataStack.fetchOne(From().where(\.master == john)) - ``` - */ +@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 == (_ keyPath: KeyPath.ToOne>, _ object: D) -> Where { return Where(O.meta[keyPath: keyPath].keyPath, isEqualTo: object) } -/** - Creates a `Where` clause by comparing if a property is equal to a value - ``` - let dog = dataStack.fetchOne(From().where(\.master == john)) - ``` - */ +@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 == (_ keyPath: KeyPath.ToOne>, _ object: D?) -> Where { return Where(O.meta[keyPath: keyPath].keyPath, isEqualTo: object) } -/** - Creates a `Where` clause by comparing if a property is not equal to a value - ``` - let dog = dataStack.fetchOne(From().where(\.master != john)) - ``` - */ +@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 != (_ keyPath: KeyPath.ToOne>, _ object: D) -> Where { return !Where(O.meta[keyPath: keyPath].keyPath, isEqualTo: object) } -/** - Creates a `Where` clause by comparing if a property is not equal to a value - ``` - let dog = dataStack.fetchOne(From().where(\.master != john)) - ``` - */ +@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 != (_ keyPath: KeyPath.ToOne>, _ object: D?) -> Where { return !Where(O.meta[keyPath: keyPath].keyPath, isEqualTo: object) } -/** - Creates a `Where` clause by checking if a sequence contains a value of a property - ``` - let dog = dataStack.fetchOne(From().where([john, bob, joe] ~= \.master)) - ``` - */ +@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 ~= (_ sequence: S, _ keyPath: KeyPath.ToOne>) -> Where where S.Iterator.Element == D { return Where(O.meta[keyPath: keyPath].keyPath, isMemberOf: sequence) diff --git a/Sources/KeyPathGenericBindings.swift b/Sources/KeyPathGenericBindings.swift index a7cd4835..a63a6544 100644 --- a/Sources/KeyPathGenericBindings.swift +++ b/Sources/KeyPathGenericBindings.swift @@ -317,9 +317,3 @@ extension NSSet: AllowedObjectiveCToManyRelationshipKeyPathValue {} extension NSOrderedSet: AllowedObjectiveCToManyRelationshipKeyPathValue {} extension Optional: AllowedObjectiveCToManyRelationshipKeyPathValue where Wrapped: AllowedObjectiveCToManyRelationshipKeyPathValue, Wrapped: AllowedObjectiveCRelationshipKeyPathValue {} - - -// MARK: - Deprecated - -@available(*, deprecated, renamed: "AllowedObjectiveCToManyRelationshipKeyPathValue") -public typealias AllowedCoreStoreObjectCollectionKeyPathValue = AllowedObjectiveCToManyRelationshipKeyPathValue diff --git a/Sources/KeyPathStringConvertible.swift b/Sources/KeyPathStringConvertible.swift index dfb3fa45..5f624e25 100644 --- a/Sources/KeyPathStringConvertible.swift +++ b/Sources/KeyPathStringConvertible.swift @@ -92,12 +92,3 @@ public protocol RelationshipKeyPathStringConvertible: KeyPathStringConvertible { */ 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 - diff --git a/Sources/ListMonitor.swift b/Sources/ListMonitor.swift index 9153cdf1..efd0e8af 100644 --- a/Sources/ListMonitor.swift +++ b/Sources/ListMonitor.swift @@ -1440,21 +1440,6 @@ extension ListMonitor where O: NSManagedObject { 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)? .map({ O.cs_fromRaw(object: $0 as! NSManagedObject) }) } - - - // MARK: Deprecated - - @available(*, deprecated, renamed: "O") - public typealias D = O } diff --git a/Sources/ObjectMonitor.swift b/Sources/ObjectMonitor.swift index e1fa37b8..2d7bf576 100644 --- a/Sources/ObjectMonitor.swift +++ b/Sources/ObjectMonitor.swift @@ -408,12 +408,6 @@ public final class ObjectMonitor: Hashable, ObjectRepresentati inObject: observer ) } - - - // MARK: Deprecated - - @available(*, deprecated, renamed: "O") - public typealias D = O } diff --git a/Sources/ObjectPublisher.swift b/Sources/ObjectPublisher.swift index 2e0ebacf..32b11b32 100644 --- a/Sources/ObjectPublisher.swift +++ b/Sources/ObjectPublisher.swift @@ -333,15 +333,6 @@ extension ObjectPublisher where O: NSManagedObject { return self.snapshot?[dynamicMember: member] } - - - // MARK: Deprecated - - @available(*, deprecated, message: "Accessing the property directly now works") - public func value(forKeyPath keyPath: KeyPath) -> V! { - - return self[dynamicMember: keyPath] - } } @@ -435,64 +426,53 @@ extension ObjectPublisher where O: CoreStoreObject { /** Returns the value for the property identified by a given key. */ + public subscript(dynamicMember member: KeyPath) -> V? { + + 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(dynamicMember member: KeyPath.Required>) -> V? { return self.object?[keyPath: member].value } - - /** - Returns the value for the property identified by a given key. - */ + + public subscript(dynamicMember member: KeyPath.Optional>) -> V? { return self.object?[keyPath: member].value } - - /** - Returns the value for the property identified by a given key. - */ + public subscript(dynamicMember member: KeyPath.Required>) -> V? { return self.object?[keyPath: member].value } - - /** - Returns the value for the property identified by a given key. - */ + public subscript(dynamicMember member: KeyPath.Optional>) -> V? { return self.object?[keyPath: member].value } - - /** - Returns the value for the property identified by a given key. - */ + public subscript(dynamicMember member: KeyPath.ToOne>) -> D? { return self.object?[keyPath: member].value } - - /** - Returns the value for the property identified by a given key. - */ + public subscript(dynamicMember member: KeyPath.ToManyOrdered>) -> [D]? { return self.object?[keyPath: member].value } - - /** - Returns the value for the property identified by a given key. - */ + public subscript(dynamicMember member: KeyPath.ToManyUnordered>) -> Set? { return self.object?[keyPath: member].value } - - /** - Returns the value for the property identified by a given key. - */ - public subscript(dynamicMember member: KeyPath) -> V? { - - return self.object?[keyPath: member] - } } diff --git a/Sources/ObjectSnapshot.swift b/Sources/ObjectSnapshot.swift index c3d0d1e3..b4b93ad0 100644 --- a/Sources/ObjectSnapshot.swift +++ b/Sources/ObjectSnapshot.swift @@ -189,7 +189,9 @@ extension ObjectSnapshot where O: CoreStoreObject { /** Returns the value for the property identified by a given key. */ - public subscript(dynamicMember member: KeyPath.Stored>) -> V { + public subscript( + dynamicMember member: KeyPath.Stored> + ) -> V { get { @@ -206,7 +208,9 @@ extension ObjectSnapshot where O: CoreStoreObject { /** Returns the value for the property identified by a given key. */ - public subscript(dynamicMember member: KeyPath.Virtual>) -> V { + public subscript( + dynamicMember member: KeyPath.Virtual> + ) -> V { get { @@ -223,7 +227,9 @@ extension ObjectSnapshot where O: CoreStoreObject { /** Returns the value for the property identified by a given key. */ - public subscript(dynamicMember member: KeyPath.Coded>) -> V { + public subscript( + dynamicMember member: KeyPath.Coded> + ) -> V { get { @@ -240,7 +246,9 @@ extension ObjectSnapshot where O: CoreStoreObject { /** Returns the value for the property identified by a given key. */ - public subscript(dynamicMember member: KeyPath.Relationship>) -> V.PublishedType { + public subscript( + dynamicMember member: KeyPath.Relationship> + ) -> V.PublishedType { get { @@ -255,11 +263,19 @@ extension ObjectSnapshot where O: CoreStoreObject { self.values[key] = V.cs_toSnapshotType(from: newValue) } } +} - /** - Returns the value for the property identified by a given key. - */ - public subscript(dynamicMember member: KeyPath.Required>) -> V { + +// 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 ObjectSnapshot where O: CoreStoreObject { + + public subscript( + dynamicMember member: KeyPath.Required> + ) -> V { get { @@ -273,10 +289,9 @@ extension ObjectSnapshot where O: CoreStoreObject { } } - /** - Returns the value for the property identified by a given key. - */ - public subscript(dynamicMember member: KeyPath.Optional>) -> V? { + public subscript( + dynamicMember member: KeyPath.Optional> + ) -> V? { get { @@ -289,11 +304,10 @@ extension ObjectSnapshot where O: CoreStoreObject { self.values[key] = newValue } } - - /** - Returns the value for the property identified by a given key. - */ - public subscript(dynamicMember member: KeyPath.Required>) -> V { + + public subscript( + dynamicMember member: KeyPath.Required> + ) -> V { get { @@ -306,11 +320,10 @@ extension ObjectSnapshot where O: CoreStoreObject { self.values[key] = newValue } } - - /** - Returns the value for the property identified by a given key. - */ - public subscript(dynamicMember member: KeyPath.Optional>) -> V? { + + public subscript( + dynamicMember member: KeyPath.Optional> + ) -> V? { get { @@ -323,11 +336,10 @@ extension ObjectSnapshot where O: CoreStoreObject { self.values[key] = newValue } } - - /** - Returns the value for the property identified by a given key. - */ - public subscript(dynamicMember member: KeyPath.ToOne>) -> ObjectPublisher? { + + public subscript( + dynamicMember member: KeyPath.ToOne> + ) -> ObjectPublisher? { get { @@ -344,11 +356,10 @@ extension ObjectSnapshot where O: CoreStoreObject { self.values[key] = newValue?.objectID() } } - - /** - Returns the value for the property identified by a given key. - */ - public subscript(dynamicMember member: KeyPath.ToManyOrdered>) -> [ObjectPublisher] { + + public subscript( + dynamicMember member: KeyPath.ToManyOrdered> + ) -> [ObjectPublisher] { get { @@ -363,11 +374,10 @@ extension ObjectSnapshot where O: CoreStoreObject { self.values[key] = newValue.map({ $0.objectID() }) } } - - /** - Returns the value for the property identified by a given key. - */ - public subscript(dynamicMember member: KeyPath.ToManyUnordered>) -> Set> { + + public subscript( + dynamicMember member: KeyPath.ToManyUnordered> + ) -> Set> { get { diff --git a/Sources/OrderBy.swift b/Sources/OrderBy.swift index 9e4dd5cd..d1225f6d 100644 --- a/Sources/OrderBy.swift +++ b/Sources/OrderBy.swift @@ -151,7 +151,7 @@ public struct OrderBy: OrderByClause, FetchClause, QueryClause /** 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)) } @@ -159,7 +159,7 @@ public struct OrderBy: OrderByClause, FetchClause, QueryClause /** 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)) } @@ -170,7 +170,7 @@ public struct OrderBy: OrderByClause, FetchClause, QueryClause /** Indicates that the `KeyPathString` should be sorted in ascending order */ - public static func ascending(_ keyPath: KeyPath) -> SortKey where O: NSManagedObject { + public static func ascending(_ keyPath: KeyPath) -> Self where O: NSManagedObject { return .ascending(keyPath._kvcKeyPathString!) } @@ -178,7 +178,7 @@ public struct OrderBy: OrderByClause, FetchClause, QueryClause /** Indicates that the `KeyPathString` should be sorted in descending order */ - public static func descending(_ keyPath: KeyPath) -> SortKey where O: NSManagedObject { + public static func descending(_ keyPath: KeyPath) -> Self where O: NSManagedObject { return .descending(keyPath._kvcKeyPathString!) } @@ -189,94 +189,24 @@ public struct OrderBy: OrderByClause, FetchClause, QueryClause /** Indicates that the `KeyPathString` should be sorted in ascending order */ - public static func ascending(_ attribute: KeyPath.Stored>) -> SortKey { + public static func ascending(_ attribute: KeyPath.Stored>) -> Self { return .ascending(O.meta[keyPath: attribute].keyPath) } - - /** - Indicates that the `KeyPathString` should be sorted in ascending order - */ - public static func ascending(_ attribute: KeyPath.Required>) -> SortKey { - - return .ascending(O.meta[keyPath: attribute].keyPath) - } - - /** - Indicates that the `KeyPathString` should be sorted in ascending order - */ - public static func ascending(_ attribute: KeyPath.Optional>) -> SortKey { - - return .ascending(O.meta[keyPath: attribute].keyPath) - } - - /** - Indicates that the `KeyPathString` should be sorted in ascending order - */ - public static func ascending(_ attribute: KeyPath.Required>) -> SortKey { - - return .ascending(O.meta[keyPath: attribute].keyPath) - } - - /** - Indicates that the `KeyPathString` should be sorted in ascending order - */ - public static func ascending(_ attribute: KeyPath.Optional>) -> SortKey { - - return .ascending(O.meta[keyPath: attribute].keyPath) - } /** Indicates that the `KeyPathString` should be sorted in descending order */ - public static func descending(_ attribute: KeyPath.Stored>) -> SortKey { + public static func descending(_ attribute: KeyPath.Stored>) -> Self { return .descending(O.meta[keyPath: attribute].keyPath) } - /** - Indicates that the `KeyPathString` should be sorted in descending order - */ - public static func descending(_ attribute: KeyPath.Required>) -> SortKey { - - return .descending(O.meta[keyPath: attribute].keyPath) - } - - /** - Indicates that the `KeyPathString` should be sorted in descending order - */ - public static func descending(_ attribute: KeyPath.Optional>) -> SortKey { - - return .descending(O.meta[keyPath: attribute].keyPath) - } - - /** - Indicates that the `KeyPathString` should be sorted in descending order - */ - public static func descending(_ attribute: KeyPath.Required>) -> SortKey { - - return .descending(O.meta[keyPath: attribute].keyPath) - } - - /** - Indicates that the `KeyPathString` should be sorted in descending order - */ - public static func descending(_ attribute: KeyPath.Optional>) -> SortKey { - - return .descending(O.meta[keyPath: attribute].keyPath) - } - // MARK: Private 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 */ - public static func ascending(_ attribute: (O) -> K) -> OrderBy.SortKey { + public static func ascending(_ attribute: (O) -> K) -> Self { 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 */ - public static func descending(_ attribute: (O) -> K) -> OrderBy.SortKey { + public static func descending(_ attribute: (O) -> K) -> Self { return .descending(attribute(O.meta).cs_keyPathString) } @@ -333,3 +263,52 @@ extension Sequence where Iterator.Element: OrderByClause { 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(_ attribute: KeyPath.Required>) -> Self { + + return .ascending(O.meta[keyPath: attribute].keyPath) + } + + public static func ascending(_ attribute: KeyPath.Optional>) -> Self { + + return .ascending(O.meta[keyPath: attribute].keyPath) + } + + public static func ascending(_ attribute: KeyPath.Required>) -> Self { + + return .ascending(O.meta[keyPath: attribute].keyPath) + } + + public static func ascending(_ attribute: KeyPath.Optional>) -> Self { + + return .ascending(O.meta[keyPath: attribute].keyPath) + } + + public static func descending(_ attribute: KeyPath.Required>) -> Self { + + return .descending(O.meta[keyPath: attribute].keyPath) + } + + public static func descending(_ attribute: KeyPath.Optional>) -> Self { + + return .descending(O.meta[keyPath: attribute].keyPath) + } + + public static func descending(_ attribute: KeyPath.Required>) -> Self { + + return .descending(O.meta[keyPath: attribute].keyPath) + } + + public static func descending(_ attribute: KeyPath.Optional>) -> Self { + + return .descending(O.meta[keyPath: attribute].keyPath) + } +} diff --git a/Sources/PartialObject.swift b/Sources/PartialObject.swift index e9ad3643..acf7a2f8 100644 --- a/Sources/PartialObject.swift +++ b/Sources/PartialObject.swift @@ -154,11 +154,24 @@ public struct PartialObject { } - // MARK: Value.Required accessors/mutators + // MARK: Internal + + internal let rawObject: NSManagedObject + + internal init(_ rawObject: NSManagedObject) { + + 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 { - /** - Returns the value for the property identified by a given key. - */ public func value(for property: (O) -> ValueContainer.Required) -> V { return V.cs_fromQueryableNativeType( @@ -166,9 +179,6 @@ public struct PartialObject { )! } - /** - Sets the property of the receiver specified by a given key to a given value. - */ public func setValue(_ value: V, for property: (O) -> ValueContainer.Required) { self.rawObject.setValue( @@ -177,11 +187,6 @@ public struct PartialObject { ) } - /** - Returns the value for the specified property from the managed object’s 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 receiver’s private storage. - */ public func primitiveValue(for property: (O) -> ValueContainer.Required) -> V { return V.cs_fromQueryableNativeType( @@ -189,11 +194,6 @@ public struct PartialObject { )! } - /** - Sets in the object's private internal storage the value of a given property. - - Sets in the receiver’s private internal storage the value of the property specified by key to value. - */ public func setPrimitiveValue(_ value: V, for property: (O) -> ValueContainer.Required) { self.rawObject.setPrimitiveValue( @@ -202,21 +202,12 @@ public struct PartialObject { ) } - - // MARK: Value.Optional utilities - - /** - Returns the value for the property identified by a given key. - */ public func value(for property: (O) -> ValueContainer.Optional) -> 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(_ value: V?, for property: (O) -> ValueContainer.Optional) { self.rawObject.setValue( @@ -225,22 +216,12 @@ public struct PartialObject { ) } - /** - Returns the value for the specified property from the managed object’s 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 receiver’s private storage. - */ public func primitiveValue(for property: (O) -> ValueContainer.Optional) -> 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 receiver’s private internal storage the value of the property specified by key to value. - */ public func setPrimitiveValue(_ value: V?, for property: (O) -> ValueContainer.Optional) { self.rawObject.setPrimitiveValue( @@ -249,20 +230,11 @@ public struct PartialObject { ) } - - // MARK: Transformable.Required utilities - - /** - Returns the value for the property identified by a given key. - */ public func value(for property: (O) -> TransformableContainer.Required) -> 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(_ value: V, for property: (O) -> TransformableContainer.Required) { self.rawObject.setValue( @@ -271,21 +243,11 @@ public struct PartialObject { ) } - /** - Returns the value for the specified property from the managed object’s 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 receiver’s private storage. - */ public func primitiveValue(for property: (O) -> TransformableContainer.Required) -> 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 receiver’s private internal storage the value of the property specified by key to value. - */ public func setPrimitiveValue(_ value: V, for property: (O) -> TransformableContainer.Required) { self.rawObject.setPrimitiveValue( @@ -294,20 +256,11 @@ public struct PartialObject { ) } - - // MARK: Transformable.Optional utilities - - /** - Returns the value for the property identified by a given key. - */ public func value(for property: (O) -> TransformableContainer.Optional) -> 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(_ value: V?, for property: (O) -> TransformableContainer.Optional) { self.rawObject.setValue( @@ -316,21 +269,11 @@ public struct PartialObject { ) } - /** - Returns the value for the specified property from the managed object’s 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 receiver’s private storage. - */ public func primitiveValue(for property: (O) -> TransformableContainer.Optional) -> 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 receiver’s private internal storage the value of the property specified by key to value. - */ public func setPrimitiveValue(_ value: V?, for property: (O) -> TransformableContainer.Optional) { self.rawObject.setPrimitiveValue( @@ -338,14 +281,4 @@ public struct PartialObject { forKey: property(O.meta).keyPath ) } - - - // MARK: Internal - - internal let rawObject: NSManagedObject - - internal init(_ rawObject: NSManagedObject) { - - self.rawObject = rawObject - } } diff --git a/Sources/QueryChainBuilder.swift b/Sources/QueryChainBuilder.swift index 8b0d5c46..9c4158ad 100644 --- a/Sources/QueryChainBuilder.swift +++ b/Sources/QueryChainBuilder.swift @@ -49,12 +49,6 @@ public struct QueryChainBuilder: QueryCha public var from: From public var select: Select public var queryClauses: [QueryClause] = [] - - - // MARK: Deprecated - - @available(*, deprecated, renamed: "O") - public typealias D = O } diff --git a/Sources/Relationship.ToManyOrdered.swift b/Sources/Relationship.ToManyOrdered.swift index 83b7b782..26bb8800 100644 --- a/Sources/Relationship.ToManyOrdered.swift +++ b/Sources/Relationship.ToManyOrdered.swift @@ -27,44 +27,15 @@ import CoreData 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 { - // 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("master") - } - class Person: CoreStoreObject { - let pets = Relationship.ToManyOrdered("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: 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("master") - } - class Person: CoreStoreObject { - let pets = Relationship.ToManyOrdered("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( _ keyPath: KeyPathString, minCount: Int = 0, @@ -85,26 +56,7 @@ extension RelationshipContainer { 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("master") - } - class Person: CoreStoreObject { - let pets = Relationship.ToManyOrdered("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( _ keyPath: KeyPathString, minCount: Int = 0, @@ -126,26 +78,7 @@ extension RelationshipContainer { 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("master") - } - class Person: CoreStoreObject { - let pets = Relationship.ToManyOrdered("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( _ keyPath: KeyPathString, minCount: Int = 0, @@ -167,26 +100,7 @@ extension RelationshipContainer { 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("master") - } - class Person: CoreStoreObject { - let pets = Relationship.ToManyOrdered("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( _ keyPath: KeyPathString, minCount: Int = 0, @@ -208,10 +122,7 @@ extension RelationshipContainer { affectedByKeyPaths: affectedByKeyPaths() ) } - - /** - The relationship value - */ + public var value: ReturnValueType { get { @@ -223,34 +134,19 @@ extension RelationshipContainer { self.nativeValue = NSOrderedSet(array: newValue.map({ $0.rawObject! })) } } - - - // MARK: AnyKeyPathStringConvertible - + public var cs_keyPathString: String { return self.keyPath } - - // MARK: KeyPathStringConvertible - public typealias ObjectType = O public typealias DestinationValueType = D - - // MARK: RelationshipKeyPathStringConvertible - public typealias ReturnValueType = [DestinationValueType] - - // MARK: PropertyProtocol - internal let keyPath: KeyPathString - - // MARK: RelationshipProtocol - internal let entityDescriptionValues: () -> RelationshipProtocol.EntityDescriptionValues internal var rawObject: CoreStoreManagedObject? @@ -303,9 +199,6 @@ extension RelationshipContainer { 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) { self.keyPath = keyPath @@ -327,13 +220,11 @@ extension RelationshipContainer { } } - -// MARK: - Convenience - +@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: RandomAccessCollection { - // MARK: Sequence - public typealias Iterator = AnyIterator public func makeIterator() -> Iterator { @@ -342,9 +233,6 @@ extension RelationshipContainer.ToManyOrdered: RandomAccessCollection { return AnyIterator({ iterator.next().flatMap({ D.cs_fromRaw(object: $0 as! NSManagedObject) }) }) } - - // MARK: Collection - public typealias Index = Int public var startIndex: Index { @@ -368,51 +256,21 @@ extension RelationshipContainer.ToManyOrdered: RandomAccessCollection { } } - -// MARK: - Operations - +@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 { - /** - 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 .= (_ relationship: RelationshipContainer.ToManyOrdered, _ newValue: S) where S.Iterator.Element == D { 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 .= (_ relationship: RelationshipContainer.ToManyOrdered, _ relationship2: RelationshipContainer.ToManyOrdered) { 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 .== (_ relationship: RelationshipContainer.ToManyOrdered, _ collection: C) -> Bool where C.Iterator.Element == D { return relationship.nativeValue.elementsEqual( @@ -420,17 +278,7 @@ extension RelationshipContainer.ToManyOrdered { 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 .== (_ collection: C, _ relationship: RelationshipContainer.ToManyOrdered) -> Bool where C.Iterator.Element == D { return relationship.nativeValue.elementsEqual( @@ -438,17 +286,7 @@ extension RelationshipContainer.ToManyOrdered { 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 .== (_ relationship: RelationshipContainer.ToManyOrdered, _ relationship2: RelationshipContainer.ToManyOrdered) -> Bool { return relationship.nativeValue == relationship2.nativeValue diff --git a/Sources/Relationship.ToManyUnordered.swift b/Sources/Relationship.ToManyUnordered.swift index 2f502862..f07ca917 100644 --- a/Sources/Relationship.ToManyUnordered.swift +++ b/Sources/Relationship.ToManyUnordered.swift @@ -27,45 +27,15 @@ import CoreData 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 { - // 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("master") - } - class Person: CoreStoreObject { - let pets = Relationship.ToManyUnordered("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: 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("master") - } - class Person: CoreStoreObject { - let pets = Relationship.ToManyOrdered("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( _ keyPath: KeyPathString, deleteRule: DeleteRule = .nullify, @@ -86,26 +56,7 @@ extension RelationshipContainer { 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("master") - } - class Person: CoreStoreObject { - let pets = Relationship.ToManyOrdered("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( _ keyPath: KeyPathString, inverse: @escaping (D) -> RelationshipContainer.ToOne, @@ -127,26 +78,7 @@ extension RelationshipContainer { 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("master") - } - class Person: CoreStoreObject { - let pets = Relationship.ToManyOrdered("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( _ keyPath: KeyPathString, inverse: @escaping (D) -> RelationshipContainer.ToManyOrdered, @@ -168,26 +100,7 @@ extension RelationshipContainer { 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("master") - } - class Person: CoreStoreObject { - let pets = Relationship.ToManyOrdered("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( _ keyPath: KeyPathString, inverse: @escaping (D) -> RelationshipContainer.ToManyUnordered, @@ -209,10 +122,7 @@ extension RelationshipContainer { affectedByKeyPaths: affectedByKeyPaths() ) } - - /** - The relationship value - */ + public var value: ReturnValueType { get { @@ -225,33 +135,18 @@ extension RelationshipContainer { } } - - // MARK: AnyKeyPathStringConvertible - public var cs_keyPathString: String { return self.keyPath } - - // MARK: KeyPathStringConvertible - public typealias ObjectType = O public typealias DestinationValueType = D - - // MARK: RelationshipKeyPathStringConvertible - public typealias ReturnValueType = Set - - // MARK: PropertyProtocol - internal let keyPath: KeyPathString - - // MARK: RelationshipProtocol - internal let entityDescriptionValues: () -> RelationshipProtocol.EntityDescriptionValues internal var rawObject: CoreStoreManagedObject? @@ -304,9 +199,6 @@ extension RelationshipContainer { 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) { self.keyPath = keyPath @@ -328,30 +220,21 @@ extension RelationshipContainer { } } - -// MARK: - Convenience - +@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: Sequence { - /** - The number of elements in the set. - */ public var count: Int { return self.nativeValue.count } - - /** - A Boolean value indicating whether the range contains no elements. - */ + public var isEmpty: Bool { return self.nativeValue.count == 0 } - - // MARK: Sequence - public typealias Iterator = AnyIterator public func makeIterator() -> Iterator { @@ -361,96 +244,36 @@ extension RelationshipContainer.ToManyUnordered: Sequence { } } - -// MARK: - Operations - +@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 { - /** - 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 .= (_ relationship: RelationshipContainer.ToManyUnordered, _ newValue: S) where S.Iterator.Element == D { 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 .= (_ relationship: RelationshipContainer.ToManyUnordered, _ relationship2: RelationshipContainer.ToManyUnordered) { 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 .= (_ relationship: RelationshipContainer.ToManyUnordered, _ relationship2: RelationshipContainer.ToManyOrdered) { 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([dog, cat]) { ... } - ``` - is equivalent to - ``` - if person.pets.value == Set([dog, cat]) { ... } - ``` - */ + public static func .== (_ relationship: RelationshipContainer.ToManyUnordered, _ set: Set) -> Bool { 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([dog, cat]) .== person.pets { ... } - ``` - is equivalent to - ``` - if Set([dog, cat]) == person.pets.value { ... } - ``` - */ + public static func .== (_ set: Set, _ relationship: RelationshipContainer.ToManyUnordered) -> Bool { 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 .== (_ relationship: RelationshipContainer.ToManyUnordered, _ relationship2: RelationshipContainer.ToManyUnordered) -> Bool { return relationship.nativeValue.isEqual(relationship2.nativeValue) diff --git a/Sources/Relationship.ToOne.swift b/Sources/Relationship.ToOne.swift index 3bc7b91a..fb5d47d4 100644 --- a/Sources/Relationship.ToOne.swift +++ b/Sources/Relationship.ToOne.swift @@ -27,42 +27,15 @@ import CoreData 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 { - // 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("master") - } - class Person: CoreStoreObject { - let pets = Relationship.ToManyUnordered("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: 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("master") - } - class Person: CoreStoreObject { - let pets = Relationship.ToManyUnordered("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( _ keyPath: KeyPathString, 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("master") - } - class Person: CoreStoreObject { - let pets = Relationship.ToManyUnordered("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( _ keyPath: KeyPathString, inverse: @escaping (D) -> RelationshipContainer.ToOne, @@ -114,24 +70,7 @@ extension RelationshipContainer { 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("master") - } - class Person: CoreStoreObject { - let pets = Relationship.ToManyUnordered("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( _ keyPath: KeyPathString, inverse: @escaping (D) -> RelationshipContainer.ToManyOrdered, @@ -149,24 +88,7 @@ extension RelationshipContainer { 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("master") - } - class Person: CoreStoreObject { - let pets = Relationship.ToManyUnordered("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( _ keyPath: KeyPathString, inverse: @escaping (D) -> RelationshipContainer.ToManyUnordered, @@ -184,10 +106,7 @@ extension RelationshipContainer { affectedByKeyPaths: affectedByKeyPaths() ) } - - /** - The relationship value - */ + public var value: ReturnValueType { get { @@ -200,33 +119,18 @@ extension RelationshipContainer { } } - - // MARK: AnyKeyPathStringConvertible - public var cs_keyPathString: String { return self.keyPath } - - // MARK: KeyPathStringConvertible - public typealias ObjectType = O public typealias DestinationValueType = D - - // MARK: RelationshipKeyPathStringConvertible - public typealias ReturnValueType = DestinationValueType? - - // MARK: PropertyProtocol - internal let keyPath: KeyPathString - - // MARK: RelationshipProtocol - internal let entityDescriptionValues: () -> RelationshipProtocol.EntityDescriptionValues internal var rawObject: CoreStoreManagedObject? @@ -302,80 +206,31 @@ extension RelationshipContainer { } } - -// MARK: - Operations +@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 { - /** - Assigns an object to the relationship. The operation - ``` - dog.master .= person - ``` - is equivalent to - ``` - dog.master.value = person - ``` - */ public static func .= (_ relationship: RelationshipContainer.ToOne, _ newObject: D?) { 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 .= (_ relationship: RelationshipContainer.ToOne, _ relationship2: RelationshipContainer.ToOne) { 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.ToOne, _ object: D?) -> Bool { 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.ToOne) -> Bool { 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 .== (_ relationship: RelationshipContainer.ToOne, _ relationship2: RelationshipContainer.ToOne) -> Bool { return relationship.nativeValue == relationship2.nativeValue diff --git a/Sources/Relationship.swift b/Sources/Relationship.swift index b61052e9..47bfff4c 100644 --- a/Sources/Relationship.swift +++ b/Sources/Relationship.swift @@ -27,46 +27,21 @@ import CoreData import Foundation -// MARK: - DynamicObject +// MARK: - Deprecated extension DynamicObject where Self: CoreStoreObject { - /** - The containing type for relationships. `Relationship`s can be any `CoreStoreObject` subclass. - ``` - class Dog: CoreStoreObject { - let master = Relationship.ToOne("master") - } - class Person: CoreStoreObject { - let pets = Relationship.ToManyUnordered("pets", inverse: { $0.master }) - } - ``` - - Important: `Relationship` properties are required to be stored properties. Computed properties will be ignored, including `lazy` and `weak` properties. - */ + @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 typealias Relationship = RelationshipContainer } - -// MARK: - RelationshipContainer - -/** - The containing type for relationships. Use the `DynamicObject.Relationship` typealias instead for shorter syntax. - ``` - class Dog: CoreStoreObject { - let master = Relationship.ToOne("master") - } - class Person: CoreStoreObject { - let pets = Relationship.ToManyUnordered("pets", inverse: { $0.master }) - } - ``` - */ +@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 enum RelationshipContainer { - // MARK: - DeleteRule - - /** - These constants define what happens to relationships when an object is deleted. - */ public enum DeleteRule { // MARK: Public diff --git a/Sources/SectionBy.swift b/Sources/SectionBy.swift index 07659455..7b00e352 100644 --- a/Sources/SectionBy.swift +++ b/Sources/SectionBy.swift @@ -75,24 +75,6 @@ public struct SectionBy { internal let sectionKeyPath: KeyPathString 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 ) } - - - // MARK: Deprecated - - @available(*, deprecated, renamed: "init(_:sectionIndexTransformer:)") - public init( - _ sectionKeyPath: KeyPath, - _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? - ) { - - self.init( - sectionKeyPath._kvcKeyPathString!, - sectionIndexTransformer: sectionIndexTransformer - ) - } } @@ -190,76 +157,6 @@ extension SectionBy where O: CoreStoreObject { sectionIndexTransformer: { _ in nil } ) } - - /** - 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(_ sectionKeyPath: KeyPath.Required>) { - - self.init( - sectionKeyPath, - sectionIndexTransformer: { _ in nil } - ) - } - - /** - 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(_ sectionKeyPath: KeyPath.Optional>) { - - self.init( - sectionKeyPath, - sectionIndexTransformer: { _ in nil } - ) - } - - /** - 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(_ sectionKeyPath: KeyPath.Required>) { - - self.init( - sectionKeyPath, - sectionIndexTransformer: { _ in nil } - ) - } - - /** - 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(_ sectionKeyPath: KeyPath.Optional>) { - - self.init( - sectionKeyPath, - sectionIndexTransformer: { _ in nil } - ) - } - - /** - 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( - _ sectionKeyPath: KeyPath.Required>, - 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 @@ -314,144 +211,88 @@ extension SectionBy where O: CoreStoreObject { 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 { - /** - 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( - _ sectionKeyPath: KeyPath.Optional>, - sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? - ) { + public init(_ sectionKeyPath: KeyPath.Required>) { self.init( - O.meta[keyPath: sectionKeyPath].keyPath, - sectionIndexTransformer: sectionIndexTransformer + sectionKeyPath, + sectionIndexTransformer: { _ in nil } ) } - /** - 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( - _ sectionKeyPath: KeyPath.Required>, - sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? - ) { + public init(_ sectionKeyPath: KeyPath.Optional>) { self.init( - O.meta[keyPath: sectionKeyPath].keyPath, - sectionIndexTransformer: sectionIndexTransformer + sectionKeyPath, + sectionIndexTransformer: { _ in nil } ) } - /** - 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( - _ sectionKeyPath: KeyPath.Optional>, - sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? - ) { + public init(_ sectionKeyPath: KeyPath.Required>) { self.init( - O.meta[keyPath: sectionKeyPath].keyPath, - sectionIndexTransformer: sectionIndexTransformer + sectionKeyPath, + sectionIndexTransformer: { _ in nil } ) } - - // MARK: Deprecated - - @available(*, deprecated, renamed: "init(_:sectionIndexTransformer:)") - public init( - _ sectionKeyPath: KeyPath.Required>, - _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? - ) { + public init(_ sectionKeyPath: KeyPath.Optional>) { self.init( sectionKeyPath, - sectionIndexTransformer: sectionIndexTransformer + sectionIndexTransformer: { _ in nil } ) } - @available(*, deprecated, renamed: "init(_:sectionIndexTransformer:)") public init( - _ sectionKeyPath: KeyPath.Stored>, - _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? + _ sectionKeyPath: KeyPath.Required>, + sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? ) { - + self.init( O.meta[keyPath: sectionKeyPath].keyPath, sectionIndexTransformer: sectionIndexTransformer ) } - @available(*, deprecated, renamed: "init(_:sectionIndexTransformer:)") - public init( - _ sectionKeyPath: KeyPath.Virtual>, - _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? - ) { - - self.init( - sectionKeyPath, - sectionIndexTransformer: sectionIndexTransformer - ) - } - - @available(*, deprecated, renamed: "init(_:sectionIndexTransformer:)") - public init( - _ sectionKeyPath: KeyPath.Coded>, - _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? - ) { - - self.init( - sectionKeyPath, - sectionIndexTransformer: sectionIndexTransformer - ) - } - - @available(*, deprecated, renamed: "init(_:sectionIndexTransformer:)") public init( _ sectionKeyPath: KeyPath.Optional>, - _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? + sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? ) { self.init( - sectionKeyPath, + O.meta[keyPath: sectionKeyPath].keyPath, sectionIndexTransformer: sectionIndexTransformer ) } - @available(*, deprecated, renamed: "init(_:sectionIndexTransformer:)") public init( _ sectionKeyPath: KeyPath.Required>, - _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? + sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? ) { self.init( - sectionKeyPath, + O.meta[keyPath: sectionKeyPath].keyPath, sectionIndexTransformer: sectionIndexTransformer ) } - @available(*, deprecated, renamed: "init(_:sectionIndexTransformer:)") public init( _ sectionKeyPath: KeyPath.Optional>, - _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? + sectionIndexTransformer: @escaping (_ sectionName: String?) -> String? ) { self.init( - sectionKeyPath, + O.meta[keyPath: sectionKeyPath].keyPath, sectionIndexTransformer: sectionIndexTransformer ) } diff --git a/Sources/SectionMonitorBuilder.swift b/Sources/SectionMonitorBuilder.swift index de1efd3b..a07f96d5 100644 --- a/Sources/SectionMonitorBuilder.swift +++ b/Sources/SectionMonitorBuilder.swift @@ -47,12 +47,6 @@ public struct SectionMonitorChainBuilder: SectionMonitorBuilde public var from: From public var sectionBy: SectionBy public var fetchClauses: [FetchClause] = [] - - - // MARK: Deprecated - - @available(*, deprecated, renamed: "O") - public typealias D = O } diff --git a/Sources/Select.swift b/Sources/Select.swift index 79e987c7..ca68559e 100644 --- a/Sources/Select.swift +++ b/Sources/Select.swift @@ -296,12 +296,6 @@ public enum SelectTerm: ExpressibleByStringLiteral, Hashable { case ._identity(let alias, _): return alias } } - - - // MARK: Deprecated - - @available(*, deprecated, renamed: "O") - public typealias D = O } @@ -611,12 +605,6 @@ public struct Select: SelectClause, Hasha fetchRequest.propertiesToFetch = propertiesToFetch } - - - // MARK: Deprecated - - @available(*, deprecated, renamed: "O") - public typealias D = O } 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.Required>) { - - 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.Optional>) { - - 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.Required>) { - - 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.Optional>) { - - self.init(.attribute(keyPath)) - } -} - // MARK: - SelectClause @@ -720,3 +666,38 @@ extension NSDictionary: SelectAttributesResultType { 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.Required>) { + + self.init(.attribute(keyPath)) + } + + public init(_ keyPath: KeyPath.Optional>) { + + 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.Required>) { + + self.init(.attribute(keyPath)) + } + + public init(_ keyPath: KeyPath.Optional>) { + + self.init(.attribute(keyPath)) + } +} diff --git a/Sources/Transformable.Optional.swift b/Sources/Transformable.Optional.swift index e0b49819..ee748c16 100644 --- a/Sources/Transformable.Optional.swift +++ b/Sources/Transformable.Optional.swift @@ -27,62 +27,15 @@ import CoreData 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 { - - // 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("species", initial: "") - let nickname = Value.Optional("nickname") - let color = Transformable.Optional("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: AttributeKeyPathStringConvertible, AttributeProtocol { - - /** - Initializes the metadata for the property. - ``` - class Animal: CoreStoreObject { - let species = Value.Required("species", initial: "") - let color = Transformable.Optional( - "color", - isTransient: true, - customGetter: Animal.getColor(_:) - ) - } - - private static func getColor(_ partialObject: PartialObject) -> 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`, 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`, make sure to use `PartialObject.primitiveValue(for:)` instead of `PartialObject.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`, 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`, make sure to use `PartialObject.setPrimitiveValue(_:for:)` instead of `PartialObject.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( _ keyPath: KeyPathString, initial: @autoclosure @escaping () -> V? = nil, @@ -110,10 +63,7 @@ extension TransformableContainer { self.customGetter = customGetter self.customSetter = customSetter } - - /** - The attribute value - */ + public var value: ReturnValueType { get { @@ -163,28 +113,16 @@ extension TransformableContainer { } } - - // MARK: AnyKeyPathStringConvertible - public var cs_keyPathString: String { return self.keyPath } - - // MARK: KeyPathStringConvertible - public typealias ObjectType = O public typealias DestinationValueType = V - - // MARK: AttributeKeyPathStringConvertible - public typealias ReturnValueType = DestinationValueType? - - // MARK: PropertyProtocol - internal let keyPath: KeyPathString @@ -240,59 +178,26 @@ extension TransformableContainer { return self.value } - - // MARK: Private - private let customGetter: ((_ partialObject: PartialObject) -> V?)? private let customSetter: ((_ partialObject: PartialObject, _ newValue: V?) -> Void)? } } - -// MARK: - Operations - +@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 { - /** - 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.Optional, _ newValue: V?) { 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 .= (_ property: TransformableContainer.Optional, _ property2: TransformableContainer.Optional) { 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 .= (_ property: TransformableContainer.Optional, _ property2: TransformableContainer.Required) { property.value = property2.value diff --git a/Sources/Transformable.Required.swift b/Sources/Transformable.Required.swift index f473c98f..e75b6a70 100644 --- a/Sources/Transformable.Required.swift +++ b/Sources/Transformable.Required.swift @@ -27,65 +27,15 @@ import CoreData 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 { - // MARK: - Required - - /** - The containing type for transformable properties. Any type that conforms to `NSCoding & NSCopying` are supported. - ``` - class Animal: CoreStoreObject { - let species = Value.Required("species", initial: "") - let nickname = Value.Optional("nickname") - let color = Transformable.Optional("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: AttributeKeyPathStringConvertible, AttributeProtocol { - - /** - Initializes the metadata for the property. - ``` - class Animal: CoreStoreObject { - let species = Value.Required("species", initial: "") - let color = Transformable.Required( - "color", - initial: UIColor.clear, - isTransient: true, - customGetter: Animal.getColor(_:) - ) - } - - private static func getColor(_ partialObject: PartialObject) -> 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`, 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`, make sure to use `PartialObject.primitiveValue(for:)` instead of `PartialObject.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`, 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`, make sure to use `PartialObject.setPrimitiveValue(_:for:)` instead of `PartialObject.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( _ keyPath: KeyPathString, initial: @autoclosure @escaping () -> V, @@ -113,10 +63,7 @@ extension TransformableContainer { self.customGetter = customGetter self.customSetter = customSetter } - - /** - The attribute value - */ + public var value: ReturnValueType { get { @@ -166,33 +113,18 @@ extension TransformableContainer { } } - - // MARK: AnyKeyPathStringConvertible - public var cs_keyPathString: String { return self.keyPath } - - // MARK: KeyPathStringConvertible - public typealias ObjectType = O public typealias DestinationValueType = V - - // MARK: AttributeKeyPathStringConvertible - public typealias ReturnValueType = DestinationValueType - - // MARK: PropertyProtocol - internal let keyPath: KeyPathString - - // MARK: AttributeProtocol - internal let entityDescriptionValues: () -> AttributeProtocol.EntityDescriptionValues internal var rawObject: CoreStoreManagedObject? @@ -243,44 +175,21 @@ extension TransformableContainer { return self.value } - - // MARK: Private - private let customGetter: ((_ partialObject: PartialObject) -> V)? private let customSetter: ((_ partialObject: PartialObject, _ newValue: V) -> Void)? } } - -// MARK: - Operations - +@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 { - - /** - 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.Required, _ newValue: V) { 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 .= (_ property: TransformableContainer.Required, _ property2: TransformableContainer.Required) { property.value = property2.value diff --git a/Sources/Transformable.swift b/Sources/Transformable.swift index 89eb9d95..c69c323b 100644 --- a/Sources/Transformable.swift +++ b/Sources/Transformable.swift @@ -27,35 +27,17 @@ import CoreData import Foundation -// MARK: - DynamicObject +// MARK: - Deprecated extension DynamicObject where Self: CoreStoreObject { - /** - The containing type for transformable properties. `Transformable` properties support types that conforms to `NSCoding & NSCopying`. - ``` - class Animal: CoreStoreObject { - let species = Value.Required("species", initial: "") - let nickname = Value.Optional("nickname") - let color = Transformable.Optional("color") - } - ``` - - Important: `Transformable` properties are required to be stored properties. Computed properties will be ignored, including `lazy` and `weak` properties. - */ + @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 typealias Transformable = TransformableContainer } - -// MARK: - TransformableContainer - -/** - The containing type for transformable properties. Use the `DynamicObject.Transformable` typealias instead for shorter syntax. - ``` - class Animal: CoreStoreObject { - let species = Value.Required("species", initial: "") - let nickname = Value.Optional("nickname") - let color = Transformable.Optional("color") - } - ``` - */ +@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 enum TransformableContainer {} diff --git a/Sources/Value.Optional.swift b/Sources/Value.Optional.swift index 7ead42f8..5170d718 100644 --- a/Sources/Value.Optional.swift +++ b/Sources/Value.Optional.swift @@ -27,63 +27,15 @@ import CoreData 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 { - - // MARK: - Optional - - /** - The containing type for optional value properties. Any type that conforms to `ImportableAttributeType` are supported. - ``` - class Animal: CoreStoreObject { - let species = Value.Required("species", initial: "") - let nickname = Value.Optional("nickname") - let color = Transformable.Optional("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: AttributeKeyPathStringConvertible, AttributeProtocol { - - /** - Initializes the metadata for the property. - ``` - class Person: CoreStoreObject { - let title = Value.Optional("title", initial: "Mr.") - let name = Value.Optional("name") - let displayName = Value.Optional( - "displayName", - isTransient: true, - customGetter: Person.getName(_:) - ) - - private static func getName(_ partialObject: PartialObject) -> 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( _ keyPath: KeyPathString, initial: @autoclosure @escaping () -> V? = nil, @@ -110,10 +62,7 @@ extension ValueContainer { self.customGetter = customGetter self.customSetter = customSetter } - - /** - The attribute value - */ + public var value: ReturnValueType { get { @@ -164,33 +113,18 @@ extension ValueContainer { } } - - // MARK: AnyKeyPathStringConvertible - public var cs_keyPathString: String { return self.keyPath } - - // MARK: KeyPathStringConvertible - public typealias ObjectType = O public typealias DestinationValueType = V - - // MARK: AttributeKeyPathStringConvertible - public typealias ReturnValueType = DestinationValueType? - - // MARK: PropertyProtocol - internal let keyPath: KeyPathString - - // MARK: AttributeProtocol - internal let entityDescriptionValues: () -> AttributeProtocol.EntityDescriptionValues internal var rawObject: CoreStoreManagedObject? @@ -241,119 +175,46 @@ extension ValueContainer { return self.value } - - // MARK: Private - private let customGetter: ((_ partialObject: PartialObject) -> V?)? private let customSetter: ((_ partialObject: PartialObject, _ newValue: V?) -> Void)? } } - -// MARK: - Operations - +@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 { - /** - Assigns an optional value to the property. The operation - ``` - animal.nickname .= "Taylor" - ``` - is equivalent to - ``` - animal.nickname.value = "Taylor" - ``` - */ public static func .= (_ property: ValueContainer.Optional, _ newValue: V?) { 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 .= (_ property: ValueContainer.Optional, _ property2: ValueContainer.Optional) { 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 .= (_ property: ValueContainer.Optional, _ property2: ValueContainer.Required) { 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.Optional, _ value: V?) -> Bool { 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.Optional) -> Bool { 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.Optional, _ property2: ValueContainer.Optional) -> Bool { 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.Optional, _ property2: ValueContainer.Required) -> Bool { return property.value == property2.value diff --git a/Sources/Value.Required.swift b/Sources/Value.Required.swift index b26b480a..0b29c5cf 100644 --- a/Sources/Value.Required.swift +++ b/Sources/Value.Required.swift @@ -27,60 +27,15 @@ import CoreData 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 { - // MARK: - Required - - /** - The containing type for required value properties. Any type that conforms to `ImportableAttributeType` are supported. - ``` - class Animal: CoreStoreObject { - let species = Value.Required("species", initial: "") - let nickname = Value.Optional("nickname") - let color = Transformable.Optional("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: AttributeKeyPathStringConvertible, AttributeProtocol { - /** - Initializes the metadata for the property. - ``` - class Person: CoreStoreObject { - let title = Value.Required("title", initial: "Mr.") - let name = Value.Required("name", initial: "") - let displayName = Value.Required( - "displayName", - initial: "", - isTransient: true, - customGetter: Person.getName(_:) - ) - - private static func getName(_ partialObject: PartialObject) -> 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`, 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`, make sure to use `PartialObject.primitiveValue(for:)` instead of `PartialObject.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`, 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`, make sure to use `PartialObject.setPrimitiveValue(_:for:)` instead of `PartialObject.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( _ keyPath: KeyPathString, initial: @autoclosure @escaping () -> V, @@ -107,10 +62,7 @@ extension ValueContainer { self.customGetter = customGetter self.customSetter = customSetter } - - /** - The attribute value - */ + public var value: ReturnValueType { get { @@ -162,33 +114,18 @@ extension ValueContainer { } } - - // MARK: AnyKeyPathStringConvertible - public var cs_keyPathString: String { return self.keyPath } - - // MARK: KeyPathStringConvertible - public typealias ObjectType = O public typealias DestinationValueType = V - - // MARK: AttributeKeyPathStringConvertible - public typealias ReturnValueType = DestinationValueType - - // MARK: PropertyProtocol - internal let keyPath: KeyPathString - - // MARK: AttributeProtocol - internal let entityDescriptionValues: () -> AttributeProtocol.EntityDescriptionValues internal var rawObject: CoreStoreManagedObject? @@ -239,104 +176,41 @@ extension ValueContainer { return self.value } - - // MARK: Private - private let customGetter: ((_ partialObject: PartialObject) -> V)? private let customSetter: ((_ partialObject: PartialObject, _ newValue: V) -> Void)? } } - -// MARK: - Operations - +@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 { - /** - Assigns a value to the property. The operation - ``` - animal.species .= "Swift" - ``` - is equivalent to - ``` - animal.species.value = "Swift" - ``` - */ public static func .= (_ property: ValueContainer.Required, _ newValue: V) { 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 .= (_ property: ValueContainer.Required, _ property2: ValueContainer.Required) { 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.Required, _ value: V?) -> Bool { 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.Required) -> Bool { 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.Required, _ property2: ValueContainer.Required) -> Bool { 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.Required, _ property2: ValueContainer.Optional) -> Bool { return property.value == property2.value diff --git a/Sources/Value.swift b/Sources/Value.swift index 34df6bca..0b8b9678 100644 --- a/Sources/Value.swift +++ b/Sources/Value.swift @@ -27,35 +27,17 @@ import CoreData import Foundation -// MARK: - DynamicObject +// MARK: - Deprecated extension DynamicObject where Self: CoreStoreObject { - /** - The containing type for value propertiess. `Value` properties support any type that conforms to `ImportableAttributeType`. - ``` - class Animal: CoreStoreObject { - let species = Value.Required("species", initial: "") - let nickname = Value.Optional("nickname") - let color = Transformable.Optional("color") - } - ``` - - Important: `Value` properties are required to be stored properties. Computed properties will be ignored, including `lazy` and `weak` properties. - */ + @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 typealias Value = ValueContainer } - -// MARK: - ValueContainer - -/** - The containing type for value properties. Use the `DynamicObject.Value` typealias instead for shorter syntax. - ``` - class Animal: CoreStoreObject { - let species = Value.Required("species", initial: "") - let nickname = Value.Optional("nickname") - let color = Transformable.Optional("color") - } - ``` - */ +@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 enum ValueContainer {} diff --git a/Sources/Where.Expression.swift b/Sources/Where.Expression.swift index 4f8b06b5..198f800a 100644 --- a/Sources/Where.Expression.swift +++ b/Sources/Where.Expression.swift @@ -88,12 +88,6 @@ extension Where { self.cs_keyPathString = component1 + "." + component2 } - - - // MARK: Deprecated - - @available(*, deprecated, renamed: "O") - public typealias D = O } @@ -234,20 +228,6 @@ public func ~ ().where((\.master ~ \.name) == "John")) - ``` - */ -public func ~ (_ lhs: KeyPath.ToOne>, _ rhs: KeyPath) -> Where.Expression.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 ``` @@ -290,20 +270,6 @@ public func ~ ().where((\.master ~ \.pets).count() > 1)) - ``` - */ -public func ~ (_ lhs: KeyPath.ToOne>, _ rhs: KeyPath) -> Where.Expression.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 ``` @@ -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 ~ (_ lhs: KeyPath.ToOne>, _ rhs: KeyPath) -> Where.Expression.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 ~ (_ lhs: KeyPath.ToOne>, _ rhs: KeyPath) -> Where.Expression.CollectionTarget, K.DestinationValueType> where K.ObjectType == D { + + return .init( + O.meta[keyPath: lhs].cs_keyPathString, + D.meta[keyPath: rhs].cs_keyPathString + ) +} diff --git a/Sources/Where.swift b/Sources/Where.swift index dd0f9cf8..93a66291 100644 --- a/Sources/Where.swift +++ b/Sources/Where.swift @@ -360,12 +360,6 @@ public struct Where: WhereClauseType, FetchClause, QueryClause hasher.combine(self.predicate) } - - - // MARK: Deprecated - - @available(*, deprecated, renamed: "O") - public typealias D = O } @@ -545,144 +539,93 @@ extension Where where O: CoreStoreObject { } /** - Initializes a `Where` clause that compares equality + Initializes a `Where` clause from a closure - - parameter keyPath: the keyPath to compare with - - parameter value: the arguments for the `==` operator + - parameter condition: closure that returns the `Where` clause */ - public init(_ keyPath: KeyPath.Required>, isEqualTo value: V?) { + public init(_ condition: (O) -> Where) { - self.init(O.meta[keyPath: keyPath].keyPath, isEqualTo: value) + self = condition(O.meta) } +} + + +// MARK: - Sequence where Iterator.Element: WhereClauseType + +extension Sequence where Iterator.Element: WhereClauseType { /** - Initializes a `Where` clause that compares equality - - - parameter keyPath: the keyPath to compare with - - parameter value: the arguments for the `==` operator + Combines multiple `Where` predicates together using `AND` operator */ - public init(_ keyPath: KeyPath.Optional>, isEqualTo value: V?) { + public func combinedByAnd() -> Where { - self.init(O.meta[keyPath: keyPath].keyPath, isEqualTo: value) + return Where(NSCompoundPredicate(type: .and, subpredicates: self.map({ $0.predicate }))) } /** - Initializes a `Where` clause that compares equality to `nil` - - - parameter keyPath: the keyPath to compare with - - parameter null: the arguments for the `==` operator + Combines multiple `Where` predicates together using `OR` operator */ + public func combinedByOr() -> Where { + + 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(_ keyPath: KeyPath.Required>, isEqualTo value: V?) { + + self.init(O.meta[keyPath: keyPath].keyPath, isEqualTo: value) + } + + public init(_ keyPath: KeyPath.Optional>, isEqualTo value: V?) { + + self.init(O.meta[keyPath: keyPath].keyPath, isEqualTo: value) + } + public init(_ keyPath: KeyPath.Optional>, 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(_ keyPath: KeyPath.ToOne>, 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(_ keyPath: KeyPath.ToOne>, 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(_ keyPath: KeyPath.ToOne>, 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(_ keyPath: KeyPath.Required>, 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(_ keyPath: KeyPath.Optional>, 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(_ keyPath: KeyPath.ToOne>, 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(_ keyPath: KeyPath.ToOne>, isMemberOf list: S) where S.Iterator.Element: NSManagedObjectID { self.init(O.meta[keyPath: keyPath].keyPath, isMemberOf: list) } - - /** - Initializes a `Where` clause from a closure - - - parameter condition: closure that returns the `Where` clause - */ - public init(_ condition: (O) -> Where) { - - self = condition(O.meta) - } -} - - -// MARK: - Sequence where Iterator.Element: WhereClauseType - -extension Sequence where Iterator.Element: WhereClauseType { - - /** - Combines multiple `Where` predicates together using `AND` operator - */ - public func combinedByAnd() -> Where { - - return Where(NSCompoundPredicate(type: .and, subpredicates: self.map({ $0.predicate }))) - } - - /** - Combines multiple `Where` predicates together using `OR` operator - */ - public func combinedByOr() -> Where { - - return Where(NSCompoundPredicate(type: .or, subpredicates: self.map({ $0.predicate }))) - } }