Compare commits

..

12 Commits
6.3.1 ... 6.3.2

Author SHA1 Message Date
John Estropia
1740d168c8 Merge branch 'develop' 2019-08-27 14:38:16 +09:00
John Estropia
d42b397090 version bump 2019-08-27 14:38:05 +09:00
John Estropia
058cc1915b fix optimization issues in release build 2019-08-27 14:21:33 +09:00
John Estropia
02d5bf85ae fix ListMonitor demo for iOS 13 2019-08-20 12:42:34 +09:00
John Estropia
ed3d21db77 WIP: reorganization of keypath utilities (in prep for @propertyWrappers) 2019-07-09 14:50:23 +09:00
John Estropia
67bb9340c7 provide way to check if an object has updated properties 2019-07-05 19:07:25 +09:00
John Estropia
5d49bd79f2 Merge pull request #326 from cool8jay/patch-1
Update README code style.
2019-06-29 13:19:14 +09:00
John Estropia
9f397b4337 Prevent crashing when DataStack is deallocated ahead of ListMonitor and child objects 2019-06-10 18:34:15 +09:00
cool8jay
7508d150d6 Update code style.
Update code style.
2019-06-05 08:43:06 +08:00
John Estropia
239db8168d remove artifacts from Carthage 2019-05-19 01:51:46 +09:00
John Estropia
30ab4386bf Merge branch 'develop' 2019-04-27 17:51:12 +09:00
John Estropia
08053ccb15 change protocol inheritance from class to AnyObject (as per recent Swift recommendation) 2019-04-27 17:50:55 +09:00
40 changed files with 594 additions and 352 deletions

View File

View File

View File

@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "CoreStore"
s.version = "6.3.1"
s.version = "6.3.2"
s.swift_version = "5.0"
s.license = "MIT"
s.homepage = "https://github.com/JohnEstropia/CoreStore"

View File

@@ -94,6 +94,8 @@
B51260941E9B28F100402229 /* EntityIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = B51260921E9B28F100402229 /* EntityIdentifier.swift */; };
B51260951E9B28F100402229 /* EntityIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = B51260921E9B28F100402229 /* EntityIdentifier.swift */; };
B51260961E9B28F100402229 /* EntityIdentifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = B51260921E9B28F100402229 /* EntityIdentifier.swift */; };
B51B5C2B22D43931009FA3BA /* String+KeyPaths.swift in Sources */ = {isa = PBXBuildFile; fileRef = B51B5C2A22D43931009FA3BA /* String+KeyPaths.swift */; };
B51B5C2D22D43E38009FA3BA /* KeyPath+KeyPaths.swift in Sources */ = {isa = PBXBuildFile; fileRef = B51B5C2C22D43E38009FA3BA /* KeyPath+KeyPaths.swift */; };
B51FE5AB1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = B51FE5AA1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift */; };
B51FE5AD1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = B51FE5AA1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift */; };
B51FE5AE1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = B51FE5AA1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift */; };
@@ -526,10 +528,10 @@
B5CA2B091F7E5ACA004B1936 /* WhereClauseType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5CA2B071F7E5ACA004B1936 /* WhereClauseType.swift */; };
B5CA2B0A1F7E5ACA004B1936 /* WhereClauseType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5CA2B071F7E5ACA004B1936 /* WhereClauseType.swift */; };
B5CA2B0B1F7E5ACA004B1936 /* WhereClauseType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5CA2B071F7E5ACA004B1936 /* WhereClauseType.swift */; };
B5CA2B121F81DBFE004B1936 /* DynamicKeyPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5CA2B111F81DBFE004B1936 /* DynamicKeyPath.swift */; };
B5CA2B131F81DBFE004B1936 /* DynamicKeyPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5CA2B111F81DBFE004B1936 /* DynamicKeyPath.swift */; };
B5CA2B141F81DBFE004B1936 /* DynamicKeyPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5CA2B111F81DBFE004B1936 /* DynamicKeyPath.swift */; };
B5CA2B151F81DBFF004B1936 /* DynamicKeyPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5CA2B111F81DBFE004B1936 /* DynamicKeyPath.swift */; };
B5CA2B121F81DBFE004B1936 /* KeyPathStringConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5CA2B111F81DBFE004B1936 /* KeyPathStringConvertible.swift */; };
B5CA2B131F81DBFE004B1936 /* KeyPathStringConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5CA2B111F81DBFE004B1936 /* KeyPathStringConvertible.swift */; };
B5CA2B141F81DBFE004B1936 /* KeyPathStringConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5CA2B111F81DBFE004B1936 /* KeyPathStringConvertible.swift */; };
B5CA2B151F81DBFF004B1936 /* KeyPathStringConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5CA2B111F81DBFE004B1936 /* KeyPathStringConvertible.swift */; };
B5D1E22C19FA9FBC003B2874 /* CoreStoreError.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D1E22B19FA9FBC003B2874 /* CoreStoreError.swift */; };
B5D339B41E925C2B00C880DE /* DynamicModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339B31E925C2B00C880DE /* DynamicModelTests.swift */; };
B5D339B51E925C2B00C880DE /* DynamicModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339B31E925C2B00C880DE /* DynamicModelTests.swift */; };
@@ -770,6 +772,8 @@
B512607E1E97A18000402229 /* CoreStoreObject+Convenience.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CoreStoreObject+Convenience.swift"; sourceTree = "<group>"; };
B51260881E9B252B00402229 /* NSEntityDescription+DynamicModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSEntityDescription+DynamicModel.swift"; sourceTree = "<group>"; };
B51260921E9B28F100402229 /* EntityIdentifier.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EntityIdentifier.swift; sourceTree = "<group>"; };
B51B5C2A22D43931009FA3BA /* String+KeyPaths.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+KeyPaths.swift"; sourceTree = "<group>"; };
B51B5C2C22D43E38009FA3BA /* KeyPath+KeyPaths.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "KeyPath+KeyPaths.swift"; sourceTree = "<group>"; };
B51FE5AA1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CoreStore+CustomDebugStringConvertible.swift"; sourceTree = "<group>"; };
B5202CF91C04688100DED140 /* NSFetchedResultsController+Convenience.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSFetchedResultsController+Convenience.swift"; sourceTree = "<group>"; };
B5215CA31FA47DFD00139E3A /* FetchChainBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FetchChainBuilder.swift; sourceTree = "<group>"; };
@@ -877,7 +881,7 @@
B5C976E21C6C9F6A00B1AF90 /* UnsafeDataTransaction+Observing.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UnsafeDataTransaction+Observing.swift"; sourceTree = "<group>"; };
B5C976E61C6E3A5900B1AF90 /* CoreStoreFetchedResultsController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreStoreFetchedResultsController.swift; sourceTree = "<group>"; };
B5CA2B071F7E5ACA004B1936 /* WhereClauseType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WhereClauseType.swift; sourceTree = "<group>"; };
B5CA2B111F81DBFE004B1936 /* DynamicKeyPath.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DynamicKeyPath.swift; sourceTree = "<group>"; };
B5CA2B111F81DBFE004B1936 /* KeyPathStringConvertible.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyPathStringConvertible.swift; sourceTree = "<group>"; };
B5D1E22B19FA9FBC003B2874 /* CoreStoreError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreStoreError.swift; sourceTree = "<group>"; };
B5D2D5A91F7558CB00A4DE67 /* .cocoapods.yml */ = {isa = PBXFileReference; lastKnownFileType = text; path = .cocoapods.yml; sourceTree = SOURCE_ROOT; };
B5D339B31E925C2B00C880DE /* DynamicModelTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DynamicModelTests.swift; sourceTree = "<group>"; };
@@ -1165,6 +1169,17 @@
name = Observing;
sourceTree = "<group>";
};
B51B5C2922D43854009FA3BA /* KeyPaths */ = {
isa = PBXGroup;
children = (
B5CA2B111F81DBFE004B1936 /* KeyPathStringConvertible.swift */,
B5DAFB492203E01D003FCCD0 /* KeyPathGenericBindings.swift */,
B51B5C2C22D43E38009FA3BA /* KeyPath+KeyPaths.swift */,
B51B5C2A22D43931009FA3BA /* String+KeyPaths.swift */,
);
name = KeyPaths;
sourceTree = "<group>";
};
B5215CA21FA47BF300139E3A /* Chained Clauses */ = {
isa = PBXGroup;
children = (
@@ -1323,8 +1338,6 @@
children = (
B5A1DAC71F111BFA003CF369 /* KeyPath+Querying.swift */,
B5D339EB1E9495E500C880DE /* CoreStoreObject+Querying.swift */,
B5CA2B111F81DBFE004B1936 /* DynamicKeyPath.swift */,
B5DAFB492203E01D003FCCD0 /* KeyPathGenericBindings.swift */,
);
name = "KeyPath Utilities";
sourceTree = "<group>";
@@ -1337,6 +1350,7 @@
B549F6721E56A92800FBAB2D /* CoreDataNativeType.swift */,
B5D339F01E94AF5800C880DE /* CoreStoreStrings.swift */,
B5E84EDA1AFF84500064E85B /* Setup */,
B51B5C2922D43854009FA3BA /* KeyPaths */,
B5E84EE21AFF84610064E85B /* Logging */,
B5E84EE91AFF846E0064E85B /* Transactions */,
B5E834B61B7630BD001D3D50 /* Importing */,
@@ -1902,6 +1916,7 @@
B5C976E31C6C9F6A00B1AF90 /* UnsafeDataTransaction+Observing.swift in Sources */,
B53FBA121CAB63CB00F0D40A /* Progress+ObjectiveC.swift in Sources */,
B5831B751F34AC7A00A9F647 /* RelationshipProtocol.swift in Sources */,
B51B5C2D22D43E38009FA3BA /* KeyPath+KeyPaths.swift in Sources */,
B5E1B5A81CAA49E2007FD580 /* CSDataStack+Migrating.swift in Sources */,
B5D339F11E94AF5800C880DE /* CoreStoreStrings.swift in Sources */,
B56007161B4018AB00A9A8F9 /* MigrationChain.swift in Sources */,
@@ -1991,6 +2006,7 @@
B5E84F201AFF84860064E85B /* DataStack+Observing.swift in Sources */,
B501FDDD1CA8D05000BE22EF /* CSSectionBy.swift in Sources */,
B538BA771D15B3E30003A766 /* CoreStoreBridge.m in Sources */,
B51B5C2B22D43931009FA3BA /* String+KeyPaths.swift in Sources */,
B512607F1E97A18000402229 /* CoreStoreObject+Convenience.swift in Sources */,
B5E84EF81AFF846E0064E85B /* CoreStore+Transaction.swift in Sources */,
B5E84F301AFF849C0064E85B /* NSManagedObjectContext+CoreStore.swift in Sources */,
@@ -2000,7 +2016,7 @@
B549F65E1E569C7400FBAB2D /* QueryableAttributeType.swift in Sources */,
B5E84F211AFF84860064E85B /* CoreStore+Observing.swift in Sources */,
B559CD431CAA8B6300E4D58B /* CSSetupResult.swift in Sources */,
B5CA2B121F81DBFE004B1936 /* DynamicKeyPath.swift in Sources */,
B5CA2B121F81DBFE004B1936 /* KeyPathStringConvertible.swift in Sources */,
B5A991EC1E9DC2CE0091A2E3 /* VersionLock.swift in Sources */,
B5FE4DA71C84FB4400FA6A91 /* InMemoryStore.swift in Sources */,
B52F743D1E9B8724005F3DAC /* DynamicSchema.swift in Sources */,
@@ -2195,7 +2211,7 @@
B549F65F1E569C7400FBAB2D /* QueryableAttributeType.swift in Sources */,
B559CD451CAA8B6300E4D58B /* CSSetupResult.swift in Sources */,
82BA18B81C4BBD4200A0916E /* TypeErasedClauses.swift in Sources */,
B5CA2B131F81DBFE004B1936 /* DynamicKeyPath.swift in Sources */,
B5CA2B131F81DBFE004B1936 /* KeyPathStringConvertible.swift in Sources */,
B5A991ED1E9DC2CE0091A2E3 /* VersionLock.swift in Sources */,
B5ECDBEE1CA6BF2000C7F112 /* CSFrom.swift in Sources */,
B52F743E1E9B8724005F3DAC /* DynamicSchema.swift in Sources */,
@@ -2390,7 +2406,7 @@
B549F6611E569C7400FBAB2D /* QueryableAttributeType.swift in Sources */,
B52DD19B1BE1F92800949AFE /* CoreStoreLogger.swift in Sources */,
B52DD1991BE1F92800949AFE /* DefaultLogger.swift in Sources */,
B5CA2B151F81DBFF004B1936 /* DynamicKeyPath.swift in Sources */,
B5CA2B151F81DBFF004B1936 /* KeyPathStringConvertible.swift in Sources */,
B5A991EF1E9DC2CE0091A2E3 /* VersionLock.swift in Sources */,
B5220E201D130813009BC71E /* CSObjectMonitor.swift in Sources */,
B52F74401E9B8724005F3DAC /* DynamicSchema.swift in Sources */,
@@ -2585,7 +2601,7 @@
B549F6601E569C7400FBAB2D /* QueryableAttributeType.swift in Sources */,
B559CD461CAA8B6300E4D58B /* CSSetupResult.swift in Sources */,
B56321A61BD65216006C9394 /* MigrationType.swift in Sources */,
B5CA2B141F81DBFE004B1936 /* DynamicKeyPath.swift in Sources */,
B5CA2B141F81DBFE004B1936 /* KeyPathStringConvertible.swift in Sources */,
B5A991EE1E9DC2CE0091A2E3 /* VersionLock.swift in Sources */,
B5ECDBEF1CA6BF2000C7F112 /* CSFrom.swift in Sources */,
B52F743F1E9B8724005F3DAC /* DynamicSchema.swift in Sources */,

View File

@@ -17,7 +17,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>6.3.1</string>
<string>6.3.2</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>

View File

@@ -260,9 +260,8 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
}
func listMonitor(_ monitor: ListMonitor<Palette>, didMoveObject object: Palette, fromIndexPath: IndexPath, toIndexPath: IndexPath) {
self.tableView.deleteRows(at: [fromIndexPath], with: .automatic)
self.tableView.insertRows(at: [toIndexPath], with: .automatic)
self.tableView.moveRow(at: fromIndexPath, to: toIndexPath)
}

View File

@@ -8,7 +8,7 @@
import Foundation
protocol OrganismProtocol: class {
protocol OrganismProtocol: AnyObject {
var dna: Int64 { get set }

View File

@@ -766,13 +766,13 @@ While the syntax is straightforward, CoreStore does not just naively insert a ne
- If the entity belongs to multiple stores, an assertion failure will be raised. **This is also a programmer error and should never occur in production code.** Normally, with Core Data you can insert an object in this state but saving the `NSManagedObjectContext` will always fail. CoreStore checks this for you at creation time when it makes sense (not during save).
If the entity exists in multiple configurations, you need to provide the configuration name for the destination persistent store:
let person = transaction.create(Into<MyPersonEntity>("Config1"))
```swift
let person = transaction.create(Into<MyPersonEntity>("Config1"))
```
or if the persistent store is the auto-generated "Default" configuration, specify `nil`:
let person = transaction.create(Into<MyPersonEntity>(nil))
```swift
let person = transaction.create(Into<MyPersonEntity>(nil))
```
Note that if you do explicitly specify the configuration name, CoreStore will only try to insert the created object to that particular store and will fail if that store is not found; it will not fall back to any other configuration that the entity belongs to.
### Updating objects
@@ -964,7 +964,7 @@ You can even use external types from popular 3rd-party JSON libraries, or just s
#### `ImportableObject`
`ImportableObject` is a very simple protocol:
```swift
public protocol ImportableObject: class {
public protocol ImportableObject: AnyObject {
typealias ImportSource
static func shouldInsert(from source: ImportSource, in transaction: BaseDataTransaction) -> Bool
func didInsert(from source: ImportSource, in transaction: BaseDataTransaction) throws

View File

@@ -29,7 +29,7 @@ import CoreData
// MARK: - AttributeProtocol
internal protocol AttributeProtocol: class {
internal protocol AttributeProtocol: AnyObject {
static var attributeType: NSAttributeType { get }

View File

@@ -213,6 +213,25 @@ public /*abstract*/ class BaseDataTransaction {
// MARK: Inspecting Pending Objects
/**
Returns `true` if the object has any property values changed. This method should not be called after the `commit()` method was called.
- parameter entity: the `DynamicObject` instance
- returns: `true` if the object has any property values changed.
*/
public func objectHasPersistentChangedValues<D: DynamicObject>(_ entity: D) -> Bool {
CoreStore.assert(
self.isRunningInAllowedQueue(),
"Attempted to access inserted objects from a \(cs_typeName(self)) outside its designated queue."
)
CoreStore.assert(
!self.isCommitted,
"Attempted to access inserted objects from an already committed \(cs_typeName(self))."
)
return entity.cs_toRaw().hasPersistentChangedValues
}
/**
Returns all pending `DynamicObject`s of the specified type that were inserted to the transaction. This method should not be called after the `commit()` method was called.

View File

@@ -42,7 +42,7 @@ import CoreData
*/
@available(macOS 10.12, *)
@objc
public protocol CSListObserver: class {
public protocol CSListObserver: AnyObject {
/**
Handles processing just before a change to the observed list occurs

View File

@@ -40,7 +40,7 @@ import CoreData
*/
@available(macOS 10.12, *)
@objc
public protocol CSObjectObserver: class {
public protocol CSObjectObserver: AnyObject {
/**
Handles processing just before a change to the observed `object` occurs

View File

@@ -33,7 +33,7 @@ import CoreData
Objective-C Foundation types that are natively supported by Core Data managed attributes all conform to `CoreDataNativeType`.
*/
@objc
public protocol CoreDataNativeType: class, NSObjectProtocol {}
public protocol CoreDataNativeType: AnyObject, NSObjectProtocol {}
// MARK: - NSNumber

View File

@@ -31,7 +31,7 @@ import Foundation
/**
`CoreStoreObjectiveCType`s are Objective-C accessible classes that represent CoreStore's Swift types.
*/
public protocol CoreStoreObjectiveCType: class {
public protocol CoreStoreObjectiveCType: AnyObject {
/**
The corresponding Swift type

View File

@@ -34,7 +34,7 @@ import CoreData
`invalidate()` will be called automatically when an `CoreStoreObjectKeyValueObservation` is deinited.
*/
public protocol CoreStoreObjectKeyValueObservation: class {
public protocol CoreStoreObjectKeyValueObservation: AnyObject {
/**
`invalidate()` will be called automatically when an `CoreStoreObjectKeyValueObservation` is deinited.
@@ -462,8 +462,8 @@ extension AttributeProtocol {
let notification = CoreStoreObjectValueDiff<V>(
kind: kind,
newNativeValue: newValue as! V.QueryableNativeType?,
oldNativeValue: oldValue as! V.QueryableNativeType?,
newNativeValue: newValue as? V.QueryableNativeType,
oldNativeValue: oldValue as? V.QueryableNativeType,
isPrior: isPrior
)
changeHandler(
@@ -485,8 +485,8 @@ extension AttributeProtocol {
let notification = CoreStoreObjectTransformableDiff<V>(
kind: kind,
newValue: newValue as! V?,
oldValue: oldValue as! V?,
newValue: newValue as? V,
oldValue: oldValue as? V,
isPrior: isPrior
)
changeHandler(

View File

@@ -26,7 +26,6 @@
import CoreData
import Foundation
// MARK: - ValueContainer.Required
extension ValueContainer.Required {

View File

@@ -153,9 +153,27 @@ extension DynamicObject where Self: CoreStoreObject {
)
return PartialObject<Self>(self.rawObject!)
}
// MARK: Internal
internal static var meta: Self {
return self.init(asMeta: ())
let key = ObjectIdentifier(self)
if case let meta as Self = Static.metaCache[key] {
return meta
}
let meta = self.init(asMeta: ())
Static.metaCache[key] = meta
return meta
}
}
// MARK: - Static
fileprivate enum Static {
fileprivate static var metaCache: [ObjectIdentifier: Any] = [:]
}

View File

@@ -121,7 +121,7 @@ public class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
// MARK: Equatable
public static func ==(lhs: CustomMapping, rhs: CustomMapping) -> Bool {
public static func == (lhs: CustomMapping, rhs: CustomMapping) -> Bool {
switch (lhs, rhs) {
@@ -324,7 +324,7 @@ public class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
// MARK: Equatable
public static func ==(lhs: CustomSchemaMappingProvider, rhs: CustomSchemaMappingProvider) -> Bool {
public static func == (lhs: CustomSchemaMappingProvider, rhs: CustomSchemaMappingProvider) -> Bool {
return lhs.sourceVersion == rhs.sourceVersion
&& lhs.destinationVersion == rhs.destinationVersion

View File

@@ -1,210 +0,0 @@
//
// DynamicKeyPath.swift
// CoreStore
//
// Copyright © 2018 John Rommel Estropia
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
import Foundation
import CoreData
// MARK: - AnyDynamicKeyPath
public protocol AnyDynamicKeyPath {
/**
The keyPath string
*/
var cs_keyPathString: String { get }
}
// MARK: - DynamicKeyPath
/**
Used only for utility methods.
*/
public protocol DynamicKeyPath: AnyDynamicKeyPath {
/**
The DynamicObject type
*/
associatedtype ObjectType: DynamicObject
/**
The Value type
*/
associatedtype ValueType
}
// MARK: - KeyPathString
extension KeyPathString {
/**
Extracts the keyPath string from the property.
```
let keyPath = String(keyPath: \Person.nickname)
```
*/
public init<O: NSManagedObject, V: AllowedObjectiveCKeyPathValue>(keyPath: KeyPath<O, V>) {
self = keyPath.cs_keyPathString
}
/**
Extracts the keyPath string from the property.
```
let keyPath = String(keyPath: \Person.nickname)
```
*/
public init<O: CoreStoreObject, K: DynamicKeyPath>(keyPath: KeyPath<O, K>) {
self = O.meta[keyPath: keyPath].cs_keyPathString
}
/**
Extracts the keyPath string from the property.
```
let keyPath = String(keyPath: \Person.nickname)
```
*/
public init<O: DynamicObject, T, V>(keyPath: Where<O>.Expression<T, V>) {
self = keyPath.cs_keyPathString
}
}
// MARK: - KeyPath: DynamicKeyPath
extension KeyPath: DynamicKeyPath, AnyDynamicKeyPath where Root: DynamicObject, Value: AllowedObjectiveCKeyPathValue {
public typealias ObjectType = Root
public typealias ValueType = Value
public var cs_keyPathString: String {
return self._kvcKeyPathString!
}
}
// MARK: - ValueContainer.Required: DynamicKeyPath
extension ValueContainer.Required: DynamicKeyPath {
public typealias ObjectType = O
public typealias ValueType = V
public var cs_keyPathString: String {
return self.keyPath
}
}
// MARK: - ValueContainer.Optional: DynamicKeyPath
extension ValueContainer.Optional: DynamicKeyPath {
public typealias ObjectType = O
public typealias ValueType = V
public var cs_keyPathString: String {
return self.keyPath
}
}
// MARK: - TransformableContainer.Required: DynamicKeyPath
extension TransformableContainer.Required: DynamicKeyPath {
public typealias ObjectType = O
public typealias ValueType = V
public var cs_keyPathString: String {
return self.keyPath
}
}
// MARK: - TransformableContainer.Optional: DynamicKeyPath
extension TransformableContainer.Optional: DynamicKeyPath {
public typealias ObjectType = O
public typealias ValueType = V
public var cs_keyPathString: String {
return self.keyPath
}
}
// MARK: - RelationshipContainer.ToOne: DynamicKeyPath
extension RelationshipContainer.ToOne: DynamicKeyPath {
public typealias ObjectType = O
public typealias ValueType = D
public var cs_keyPathString: String {
return self.keyPath
}
}
// MARK: - RelationshipContainer.ToManyOrdered: DynamicKeyPath
extension RelationshipContainer.ToManyOrdered: DynamicKeyPath {
public typealias ObjectType = O
public typealias ValueType = D
public var cs_keyPathString: String {
return self.keyPath
}
}
// MARK: - RelationshipContainer.ToManyUnordered: DynamicKeyPath
extension RelationshipContainer.ToManyUnordered: DynamicKeyPath {
public typealias ObjectType = O
public typealias ValueType = D
public var cs_keyPathString: String {
return self.keyPath
}
}

View File

@@ -32,7 +32,7 @@ import CoreData
/**
All CoreStore's utilities are designed around `DynamicObject` instances. `NSManagedObject` and `CoreStoreObject` instances all conform to `DynamicObject`.
*/
public protocol DynamicObject: class {
public protocol DynamicObject: AnyObject {
/**
Used internally by CoreStore. Do not call directly.

View File

@@ -124,7 +124,7 @@ public final class Entity<O: CoreStoreObject>: DynamicEntity {
return $0.map {
return (meta[keyPath: $0] as! AnyDynamicKeyPath).cs_keyPathString
return (meta[keyPath: $0] as! AnyKeyPathStringConvertible).cs_keyPathString
}
}
super.init(
@@ -156,7 +156,7 @@ public final class Entity<O: CoreStoreObject>: DynamicEntity {
return $0.map {
return (meta[keyPath: $0] as! AnyDynamicKeyPath).cs_keyPathString
return (meta[keyPath: $0] as! AnyKeyPathStringConvertible).cs_keyPathString
}
}
super.init(

View File

@@ -32,7 +32,7 @@ import CoreData
/**
Encapsulates containers which manages an internal `NSManagedObjectContext`, such as `DataStack`s and transactions, that can be used for fetching objects. CoreStore provides implementations for this protocol and should be used as a read-only abstraction.
*/
public protocol FetchableSource: class {
public protocol FetchableSource: AnyObject {
/**
Fetches the `DynamicObject` instance in the `FetchableSource`'s context from a reference created from another managed object context.

View File

@@ -30,7 +30,7 @@ import CoreData
// MARK: - FetchedResultsControllerHandler
@available(macOS 10.12, *)
internal protocol FetchedResultsControllerHandler: class {
internal protocol FetchedResultsControllerHandler: AnyObject {
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChangeObject anObject: Any, atIndexPath indexPath: IndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: IndexPath?)

View File

@@ -140,8 +140,16 @@ public struct From<D: DynamicObject> {
}
internal func applyToFetchRequest<U>(_ fetchRequest: CoreStoreFetchRequest<U>, context: NSManagedObjectContext, applyAffectedStores: Bool = true) throws {
fetchRequest.entity = context.parentStack!.entityDescription(for: EntityIdentifier(self.entityClass))!
guard let parentStack = context.parentStack else {
CoreStore.log(
.warning,
message: "Attempted to perform a fetch but the \(cs_typeName(DataStack.self)) has already been deallocated."
)
throw CoreStoreError.unknown
}
fetchRequest.entity = parentStack.entityDescription(for: EntityIdentifier(self.entityClass))!
guard applyAffectedStores else {
return

View File

@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>6.3.1</string>
<string>6.3.2</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>

View File

@@ -0,0 +1,46 @@
//
// KeyPath+KeyPaths.swift
// CoreStore
//
// Copyright © 2019 John Rommel Estropia
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
import CoreData
import Foundation
// MARK: - KeyPath: AnyKeyPathStringConvertible, KeyPathStringConvertible where Root: NSManagedObject, Value: AllowedObjectiveCKeyPathValue
extension KeyPath: AnyKeyPathStringConvertible, KeyPathStringConvertible where Root: NSManagedObject, Value: AllowedObjectiveCKeyPathValue {
// MARK: AnyKeyPathStringConvertible
public var cs_keyPathString: String {
return self._kvcKeyPathString!
}
// MARK: KeyPathStringConvertible
public typealias ObjectType = Root
public typealias DestinationValueType = Value
}

View File

@@ -92,49 +92,87 @@ extension UUID: AllowedOptionalObjectiveCKeyPathValue {}
extension Optional: AllowedObjectiveCKeyPathValue where Wrapped: AllowedOptionalObjectiveCKeyPathValue {}
// MARK: - AllowedObjectiveCCollectionKeyPathValue
// MARK: - AllowedObjectiveCAttributeKeyPathValue
/**
Used only for utility methods. Types allowed as `Value` generic type to `KeyPath` utilities.
*/
public protocol AllowedObjectiveCCollectionKeyPathValue: AllowedOptionalObjectiveCKeyPathValue {}
public protocol AllowedObjectiveCAttributeKeyPathValue: AllowedObjectiveCKeyPathValue {}
extension NSSet: AllowedObjectiveCCollectionKeyPathValue {}
extension Bool: AllowedObjectiveCAttributeKeyPathValue {}
extension NSOrderedSet: AllowedObjectiveCCollectionKeyPathValue {}
extension CGFloat: AllowedObjectiveCAttributeKeyPathValue {}
extension Optional: AllowedObjectiveCCollectionKeyPathValue, AllowedOptionalObjectiveCKeyPathValue where Wrapped: AllowedObjectiveCCollectionKeyPathValue {}
extension Data: AllowedObjectiveCAttributeKeyPathValue {}
extension Date: AllowedObjectiveCAttributeKeyPathValue {}
extension Double: AllowedObjectiveCAttributeKeyPathValue {}
extension Float: AllowedObjectiveCAttributeKeyPathValue {}
extension Int: AllowedObjectiveCAttributeKeyPathValue {}
extension Int8: AllowedObjectiveCAttributeKeyPathValue {}
extension Int16: AllowedObjectiveCAttributeKeyPathValue {}
extension Int32: AllowedObjectiveCAttributeKeyPathValue {}
extension Int64: AllowedObjectiveCAttributeKeyPathValue {}
extension NSData: AllowedObjectiveCAttributeKeyPathValue {}
extension NSDate: AllowedObjectiveCAttributeKeyPathValue {}
extension NSNumber: AllowedObjectiveCAttributeKeyPathValue {}
extension NSString: AllowedObjectiveCAttributeKeyPathValue {}
extension NSURL: AllowedObjectiveCAttributeKeyPathValue {}
extension NSUUID: AllowedObjectiveCAttributeKeyPathValue {}
extension String: AllowedObjectiveCAttributeKeyPathValue {}
extension URL: AllowedObjectiveCAttributeKeyPathValue {}
extension UUID: AllowedObjectiveCAttributeKeyPathValue {}
extension Optional: AllowedObjectiveCAttributeKeyPathValue where Wrapped: AllowedObjectiveCAttributeKeyPathValue, Wrapped: AllowedOptionalObjectiveCKeyPathValue {}
// MARK: - AllowedCoreStoreObjectKeyPathValue
// MARK: - AllowedObjectiveCRelationshipKeyPathValue
/**
Used only for utility methods. Types allowed as `Value` generic type to `KeyPath` utilities.
*/
public protocol AllowedCoreStoreObjectKeyPathValue: DynamicKeyPath {}
public protocol AllowedObjectiveCRelationshipKeyPathValue: AllowedOptionalObjectiveCKeyPathValue {}
extension ValueContainer.Required: AllowedCoreStoreObjectKeyPathValue {}
extension NSManagedObject: AllowedObjectiveCRelationshipKeyPathValue {}
extension ValueContainer.Optional: AllowedCoreStoreObjectKeyPathValue {}
extension NSSet: AllowedObjectiveCRelationshipKeyPathValue {}
extension TransformableContainer.Required: AllowedCoreStoreObjectKeyPathValue {}
extension NSOrderedSet: AllowedObjectiveCRelationshipKeyPathValue {}
extension TransformableContainer.Optional: AllowedCoreStoreObjectKeyPathValue {}
extension RelationshipContainer.ToOne: AllowedCoreStoreObjectKeyPathValue {}
extension RelationshipContainer.ToManyOrdered: AllowedCoreStoreObjectKeyPathValue {}
extension RelationshipContainer.ToManyUnordered: AllowedCoreStoreObjectKeyPathValue {}
extension Optional: AllowedOptionalObjectiveCKeyPathValue, AllowedObjectiveCRelationshipKeyPathValue where Wrapped: AllowedObjectiveCRelationshipKeyPathValue {}
// MARK: - AllowedCoreStoreObjectCollectionKeyPathValue
// MARK: - AllowedObjectiveCToManyRelationshipKeyPathValue
/**
Used only for utility methods. Types allowed as `Value` generic type to `KeyPath` utilities.
*/
public protocol AllowedCoreStoreObjectCollectionKeyPathValue: AllowedCoreStoreObjectKeyPathValue {}
public protocol AllowedObjectiveCToManyRelationshipKeyPathValue: AllowedOptionalObjectiveCKeyPathValue {}
extension RelationshipContainer.ToManyOrdered: AllowedCoreStoreObjectCollectionKeyPathValue {}
extension NSSet: AllowedObjectiveCToManyRelationshipKeyPathValue {}
extension RelationshipContainer.ToManyUnordered: AllowedCoreStoreObjectCollectionKeyPathValue {}
extension NSOrderedSet: AllowedObjectiveCToManyRelationshipKeyPathValue {}
extension Optional: AllowedObjectiveCToManyRelationshipKeyPathValue where Wrapped: AllowedObjectiveCToManyRelationshipKeyPathValue, Wrapped: AllowedObjectiveCRelationshipKeyPathValue {}
// MARK: - Deprecated
@available(*, deprecated, renamed: "AllowedObjectiveCToManyRelationshipKeyPathValue")
public typealias AllowedCoreStoreObjectCollectionKeyPathValue = AllowedObjectiveCToManyRelationshipKeyPathValue

View File

@@ -0,0 +1,103 @@
//
// KeyPathStringConvertible.swift
// CoreStore
//
// Copyright © 2018 John Rommel Estropia
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
import Foundation
import CoreData
// MARK: - AnyKeyPathStringConvertible
public protocol AnyKeyPathStringConvertible {
/**
The keyPath string
*/
var cs_keyPathString: KeyPathString { get }
}
// MARK: - KeyPathStringConvertible
/**
Used only for utility methods.
*/
public protocol KeyPathStringConvertible: AnyKeyPathStringConvertible {
/**
The DynamicObject type
*/
associatedtype ObjectType: DynamicObject
/**
The destination value type
*/
associatedtype DestinationValueType
}
// MARK: - AttributeKeyPathStringConvertible
/**
Used only for utility methods.
*/
public protocol AttributeKeyPathStringConvertible: KeyPathStringConvertible {
/**
The attribute value type
*/
associatedtype ReturnValueType
}
// MARK: - RelationshipKeyPathStringConvertible
/**
Used only for utility methods.
*/
public protocol RelationshipKeyPathStringConvertible: KeyPathStringConvertible {
/**
The relationship value type
*/
associatedtype ReturnValueType
}
// MARK: - ToManyRelationshipKeyPathStringConvertible
/**
Used only for utility methods.
*/
public protocol ToManyRelationshipKeyPathStringConvertible: RelationshipKeyPathStringConvertible where ReturnValueType: Sequence {}
// MARK: - Deprecated
@available(*, deprecated, renamed: "AnyKeyPathStringConvertible")
public typealias AnyDynamicKeyPath = AnyKeyPathStringConvertible
@available(*, deprecated, renamed: "KeyPathStringConvertible")
public typealias DynamicKeyPath = KeyPathStringConvertible

View File

@@ -963,8 +963,15 @@ public final class ListMonitor<D: DynamicObject>: Hashable {
return
}
try! newFetchedResultsController.performFetchFromSpecifiedStores()
do {
try newFetchedResultsController.performFetchFromSpecifiedStores()
}
catch {
// DataStack may have been deallocated
return
}
self.fetchedResultsControllerDelegate.taskGroup.notify(queue: .main) {
self.fetchedResultsControllerDelegate.enabled = false

View File

@@ -40,7 +40,7 @@ import CoreData
```
*/
@available(macOS 10.12, *)
public protocol ListObserver: class {
public protocol ListObserver: AnyObject {
/**
The `NSManagedObject` type for the observed list

View File

@@ -37,7 +37,7 @@ import CoreData
```
*/
@available(macOS 10.12, *)
public protocol ObjectObserver: class {
public protocol ObjectObserver: AnyObject {
/**
The `DynamicObject` type for the observed object

View File

@@ -265,7 +265,7 @@ extension OrderBy.SortKey where D: CoreStoreObject {
/**
Indicates that the `KeyPathString` should be sorted in ascending order
*/
public static func ascending<K: DynamicKeyPath>(_ attribute: (D) -> K) -> OrderBy<D>.SortKey {
public static func ascending<K: KeyPathStringConvertible>(_ attribute: (D) -> K) -> OrderBy<D>.SortKey {
return .ascending(attribute(D.meta).cs_keyPathString)
}
@@ -273,7 +273,7 @@ extension OrderBy.SortKey where D: CoreStoreObject {
/**
Indicates that the `KeyPathString` should be sorted in descending order
*/
public static func descending<K: DynamicKeyPath>(_ attribute: (D) -> K) -> OrderBy<D>.SortKey {
public static func descending<K: KeyPathStringConvertible>(_ attribute: (D) -> K) -> OrderBy<D>.SortKey {
return .descending(attribute(D.meta).cs_keyPathString)
}

View File

@@ -32,7 +32,7 @@ import CoreData
/**
Encapsulates containers which manages an internal `NSManagedObjectContext`, such as `DataStack`s and transactions, that can be used for querying values. CoreStore provides implementations for this protocol and should be used as a read-only abstraction.
*/
public protocol QueryableSource: class {
public protocol QueryableSource: AnyObject {
/**
Queries aggregate values as specified by the `QueryClause`s. Requires at least a `Select` clause, and optional `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.

View File

@@ -76,7 +76,7 @@ public enum RelationshipContainer<O: CoreStoreObject> {
```
- Important: `Relationship.ToOne` properties are required to be stored properties. Computed properties will be ignored, including `lazy` and `weak` properties.
*/
public final class ToOne<D: CoreStoreObject>: RelationshipProtocol {
public final class ToOne<D: CoreStoreObject>: RelationshipKeyPathStringConvertible, RelationshipProtocol {
/**
Initializes the metadata for the relationship. All relationships require an "inverse", so updates to to this object's relationship are also reflected on its destination object. Make sure to declare this relationship's inverse relationship on its destination object. Due to Swift's compiler limitation, only one of the relationship and its inverse can declare an `inverse:` argument.
@@ -215,11 +215,11 @@ public enum RelationshipContainer<O: CoreStoreObject> {
affectedByKeyPaths: affectedByKeyPaths()
)
}
/**
The relationship destination object.
The relationship value
*/
public var value: D? {
public var value: ReturnValueType {
get {
@@ -230,6 +230,25 @@ public enum RelationshipContainer<O: CoreStoreObject> {
self.nativeValue = newValue?.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: RelationshipProtocol
@@ -319,7 +338,7 @@ public enum RelationshipContainer<O: CoreStoreObject> {
```
- Important: `Relationship.ToManyOrdered` properties are required to be stored properties. Computed properties will be ignored, including `lazy` and `weak` properties.
*/
public final class ToManyOrdered<D: CoreStoreObject>: RelationshipProtocol {
public final class ToManyOrdered<D: CoreStoreObject>: ToManyRelationshipKeyPathStringConvertible, RelationshipProtocol {
/**
Initializes the metadata for the relationship. All relationships require an "inverse", so updates to to this object's relationship are also reflected on its destination object. Make sure to declare this relationship's inverse relationship on its destination object. Due to Swift's compiler limitation, only one of the relationship and its inverse can declare an `inverse:` argument.
@@ -482,11 +501,11 @@ public enum RelationshipContainer<O: CoreStoreObject> {
affectedByKeyPaths: affectedByKeyPaths()
)
}
/**
The relationship ordered objects.
The relationship value
*/
public var value: [D] {
public var value: ReturnValueType {
get {
@@ -497,6 +516,25 @@ public enum RelationshipContainer<O: CoreStoreObject> {
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: RelationshipProtocol
@@ -591,7 +629,7 @@ public enum RelationshipContainer<O: CoreStoreObject> {
```
- Important: `Relationship.ToManyUnordered` properties are required to be stored properties. Computed properties will be ignored, including `lazy` and `weak` properties.
*/
public final class ToManyUnordered<D: CoreStoreObject>: RelationshipProtocol {
public final class ToManyUnordered<D: CoreStoreObject>: ToManyRelationshipKeyPathStringConvertible, RelationshipProtocol {
/**
Initializes the metadata for the relationship. All relationships require an "inverse", so updates to to this object's relationship are also reflected on its destination object. Make sure to declare this relationship's inverse relationship on its destination object. Due to Swift's compiler limitation, only one of the relationship and its inverse can declare an `inverse:` argument.
@@ -755,11 +793,11 @@ public enum RelationshipContainer<O: CoreStoreObject> {
affectedByKeyPaths: affectedByKeyPaths()
)
}
/**
The relationship unordered objects.
The relationship value
*/
public var value: Set<D> {
public var value: ReturnValueType {
get {
@@ -770,6 +808,25 @@ public enum RelationshipContainer<O: CoreStoreObject> {
self.nativeValue = NSSet(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 = Set<DestinationValueType>
// MARK: RelationshipProtocol

View File

@@ -29,7 +29,7 @@ import CoreData
// MARK: - RelationshipProtocol
internal protocol RelationshipProtocol: class {
internal protocol RelationshipProtocol: AnyObject {
var keyPath: KeyPathString { get }
var isToMany: Bool { get }

View File

@@ -31,7 +31,7 @@ import CoreData
/**
The `StorageInterface` represents the data store managed (or to be managed) by the `DataStack`. When added to the `DataStack`, the `StorageInterface` serves as the interface for the `NSPersistentStore`. This may be a database file, an in-memory store, etc.
*/
public protocol StorageInterface: class {
public protocol StorageInterface: AnyObject {
/**
The string identifier for the `NSPersistentStore`'s `type` property. This is the same string CoreStore will use to create the `NSPersistentStore` from the `NSPersistentStoreCoordinator`'s `addPersistentStoreWithType(...)` method.

View File

@@ -0,0 +1,66 @@
//
// String+KeyPaths.swift
// CoreStore
//
// Copyright © 2019 John Rommel Estropia
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
import CoreData
import Foundation
// MARK: - KeyPathString
extension KeyPathString {
/**
Extracts the keyPath string from the property.
```
let keyPath = String(keyPath: \Person.nickname)
```
*/
public init<O: NSManagedObject, V: AllowedObjectiveCKeyPathValue>(keyPath: KeyPath<O, V>) {
self = keyPath.cs_keyPathString
}
/**
Extracts the keyPath string from the property.
```
let keyPath = String(keyPath: \Person.nickname)
```
*/
public init<O: CoreStoreObject, K: KeyPathStringConvertible>(keyPath: KeyPath<O, K>) {
self = O.meta[keyPath: keyPath].cs_keyPathString
}
/**
Extracts the keyPath string from the property.
```
let keyPath = String(keyPath: \Person.nickname)
```
*/
public init<O: DynamicObject, T, V>(keyPath: Where<O>.Expression<T, V>) {
self = keyPath.cs_keyPathString
}
}

View File

@@ -73,7 +73,7 @@ public enum TransformableContainer<O: CoreStoreObject> {
```
- Important: `Transformable.Required` properties are required to be stored properties. Computed properties will be ignored, including `lazy` and `weak` properties.
*/
public final class Required<V: NSCoding & NSCopying>: AttributeProtocol {
public final class Required<V: NSCoding & NSCopying>: AttributeKeyPathStringConvertible, AttributeProtocol {
/**
Initializes the metadata for the property.
@@ -138,9 +138,9 @@ public enum TransformableContainer<O: CoreStoreObject> {
}
/**
The property value.
The attribute value
*/
public var value: V {
public var value: ReturnValueType {
get {
@@ -190,6 +190,25 @@ public enum TransformableContainer<O: CoreStoreObject> {
}
// 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: AttributeProtocol
internal static var attributeType: NSAttributeType {
@@ -270,7 +289,7 @@ public enum TransformableContainer<O: CoreStoreObject> {
```
- Important: `Transformable.Optional` properties are required to be stored properties. Computed properties will be ignored, including `lazy` and `weak` properties.
*/
public final class Optional<V: NSCoding & NSCopying>: AttributeProtocol {
public final class Optional<V: NSCoding & NSCopying>: AttributeKeyPathStringConvertible, AttributeProtocol {
/**
Initializes the metadata for the property.
@@ -332,9 +351,9 @@ public enum TransformableContainer<O: CoreStoreObject> {
}
/**
The property value.
The attribute value
*/
public var value: V? {
public var value: ReturnValueType {
get {
@@ -384,6 +403,25 @@ public enum TransformableContainer<O: CoreStoreObject> {
}
// 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: AttributeProtocol
internal static var attributeType: NSAttributeType {

View File

@@ -73,7 +73,7 @@ public enum ValueContainer<O: CoreStoreObject> {
```
- Important: `Value.Required` properties are required to be stored properties. Computed properties will be ignored, including `lazy` and `weak` properties.
*/
public final class Required<V: ImportableAttributeType>: AttributeProtocol {
public final class Required<V: ImportableAttributeType>: AttributeKeyPathStringConvertible, AttributeProtocol {
/**
Initializes the metadata for the property.
@@ -129,11 +129,11 @@ public enum ValueContainer<O: CoreStoreObject> {
self.customSetter = customSetter
self.affectedByKeyPaths = affectedByKeyPaths
}
/**
The property value.
The attribute value
*/
public var value: V {
public var value: ReturnValueType {
get {
@@ -183,6 +183,25 @@ public enum ValueContainer<O: CoreStoreObject> {
}
}
}
// 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: AttributeProtocol
@@ -265,7 +284,7 @@ public enum ValueContainer<O: CoreStoreObject> {
```
- Important: `Value.Optional` properties are required to be stored properties. Computed properties will be ignored, including `lazy` and `weak` properties.
*/
public final class Optional<V: ImportableAttributeType>: AttributeProtocol {
public final class Optional<V: ImportableAttributeType>: AttributeKeyPathStringConvertible, AttributeProtocol {
/**
Initializes the metadata for the property.
@@ -324,11 +343,11 @@ public enum ValueContainer<O: CoreStoreObject> {
self.customSetter = customSetter
self.affectedByKeyPaths = affectedByKeyPaths
}
/**
The property value.
The attribute value
*/
public var value: V? {
public var value: ReturnValueType {
get {
@@ -377,6 +396,25 @@ public enum ValueContainer<O: CoreStoreObject> {
}
}
}
// 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: AttributeProtocol

View File

@@ -30,7 +30,7 @@ import CoreData
// MARK: - ~
/**
Connects multiple `DynamicKeyPath`s to create a type-safe chain usable in query/fetch expressions
Connects multiple `KeyPathStringConvertible`s to create a type-safe chain usable in query/fetch expressions
```
let owner = CoreStore.fetchOne(
From<Pet>().where(
@@ -65,7 +65,7 @@ extension Where {
)
```
*/
public struct Expression<T: WhereExpressionTrait, V>: CustomStringConvertible, DynamicKeyPath {
public struct Expression<T: WhereExpressionTrait, V>: CustomStringConvertible, KeyPathStringConvertible {
/**
Currently supports `SingleTarget` and `CollectionTarget`.
@@ -73,15 +73,15 @@ extension Where {
public typealias Trait = T
// MARK: AnyDynamicKeyPath
// MARK: AnyKeyPathStringConvertible
public let cs_keyPathString: String
// MARK: DynamicKeyPath
// MARK: KeyPathStringConvertible
public typealias ObjectType = D
public typealias ValueType = V
public typealias DestinationValueType = V
// MARK: CustomStringConvertible
@@ -128,7 +128,7 @@ extension Where {
// MARK: ~ where D: NSManagedObject
/**
Connects multiple `DynamicKeyPath`s to create a type-safe chain usable in query/fetch expressions
Connects multiple `KeyPathStringConvertible`s to create a type-safe chain usable in query/fetch expressions
```
let owner = CoreStore.fetchOne(From<Pet>().where((\.master ~ \.name) == "John"))
```
@@ -139,7 +139,7 @@ public func ~<D: NSManagedObject, O: NSManagedObject, V: AllowedObjectiveCKeyPat
}
/**
Connects multiple `DynamicKeyPath`s to create a type-safe chain usable in query/fetch expressions
Connects multiple `KeyPathStringConvertible`s to create a type-safe chain usable in query/fetch expressions
```
let owner = CoreStore.fetchOne(From<Pet>().where((\.master ~ \.name) == "John"))
```
@@ -150,29 +150,29 @@ public func ~ <D: NSManagedObject, O: NSManagedObject, V: AllowedObjectiveCKeyPa
}
/**
Connects multiple `DynamicKeyPath`s to create a type-safe chain usable in query/fetch expressions
Connects multiple `KeyPathStringConvertible`s to create a type-safe chain usable in query/fetch expressions
```
let happyPets = CoreStore.fetchAll(From<Pet>().where((\.master ~ \.pets).count() > 1))
```
*/
public func ~ <D: NSManagedObject, O: NSManagedObject, V: AllowedObjectiveCCollectionKeyPathValue>(_ lhs: KeyPath<D, O>, _ rhs: KeyPath<O, V>) -> Where<D>.Expression<Where<D>.CollectionTarget, V> {
public func ~ <D: NSManagedObject, O: NSManagedObject, V: AllowedObjectiveCToManyRelationshipKeyPathValue>(_ lhs: KeyPath<D, O>, _ rhs: KeyPath<O, V>) -> Where<D>.Expression<Where<D>.CollectionTarget, V> {
return .init(lhs.cs_keyPathString, rhs.cs_keyPathString)
}
/**
Connects multiple `DynamicKeyPath`s to create a type-safe chain usable in query/fetch expressions
Connects multiple `KeyPathStringConvertible`s to create a type-safe chain usable in query/fetch expressions
```
let happyPets = CoreStore.fetchAll(From<Pet>().where((\.master ~ \.pets).count() > 1))
```
*/
public func ~ <D: NSManagedObject, O: NSManagedObject, V: AllowedObjectiveCCollectionKeyPathValue>(_ lhs: KeyPath<D, O?>, _ rhs: KeyPath<O, V>) -> Where<D>.Expression<Where<D>.CollectionTarget, V> {
public func ~ <D: NSManagedObject, O: NSManagedObject, V: AllowedObjectiveCToManyRelationshipKeyPathValue>(_ lhs: KeyPath<D, O?>, _ rhs: KeyPath<O, V>) -> Where<D>.Expression<Where<D>.CollectionTarget, V> {
return .init(lhs.cs_keyPathString, rhs.cs_keyPathString)
}
/**
Connects multiple `DynamicKeyPath`s to create a type-safe chain usable in query/fetch expressions
Connects multiple `KeyPathStringConvertible`s to create a type-safe chain usable in query/fetch expressions
```
let johnsSonInLaw = CoreStore.fetchOne(From<Person>().where((\.spouse ~ \.father ~ \.name) == "John"))
```
@@ -183,7 +183,7 @@ public func ~ <D: NSManagedObject, O: NSManagedObject, T, V: AllowedObjectiveCKe
}
/**
Connects multiple `DynamicKeyPath`s to create a type-safe chain usable in query/fetch expressions
Connects multiple `KeyPathStringConvertible`s to create a type-safe chain usable in query/fetch expressions
```
let johnsSonInLaw = CoreStore.fetchOne(From<Person>().where((\.spouse ~ \.father ~ \.name) == "John"))
```
@@ -194,34 +194,34 @@ public func ~ <D: NSManagedObject, O: NSManagedObject, T, V: AllowedObjectiveCKe
}
/**
Connects multiple `DynamicKeyPath`s to create a type-safe chain usable in query/fetch expressions
Connects multiple `KeyPathStringConvertible`s to create a type-safe chain usable in query/fetch expressions
```
let spouseHasSiblings = CoreStore.fetchOne(From<Person>().where((\.spouse ~ \.father ~ \.children).count() > 0))
```
*/
public func ~ <D: NSManagedObject, O: NSManagedObject, T, V: AllowedObjectiveCCollectionKeyPathValue>(_ lhs: Where<D>.Expression<T, O>, _ rhs: KeyPath<O, V>) -> Where<D>.Expression<Where<D>.CollectionTarget, V> {
public func ~ <D: NSManagedObject, O: NSManagedObject, T, V: AllowedObjectiveCToManyRelationshipKeyPathValue>(_ lhs: Where<D>.Expression<T, O>, _ rhs: KeyPath<O, V>) -> Where<D>.Expression<Where<D>.CollectionTarget, V> {
return .init(lhs.cs_keyPathString, rhs.cs_keyPathString)
}
/**
Connects multiple `DynamicKeyPath`s to create a type-safe chain usable in query/fetch expressions
Connects multiple `KeyPathStringConvertible`s to create a type-safe chain usable in query/fetch expressions
```
let spouseHasSiblings = CoreStore.fetchOne(From<Person>().where((\.spouse ~ \.father ~ \.children).count() > 0))
```
*/
public func ~ <D: NSManagedObject, O: NSManagedObject, T, V: AllowedObjectiveCCollectionKeyPathValue>(_ lhs: Where<D>.Expression<T, O?>, _ rhs: KeyPath<O, V>) -> Where<D>.Expression<Where<D>.CollectionTarget, V> {
public func ~ <D: NSManagedObject, O: NSManagedObject, T, V: AllowedObjectiveCToManyRelationshipKeyPathValue>(_ lhs: Where<D>.Expression<T, O?>, _ rhs: KeyPath<O, V>) -> Where<D>.Expression<Where<D>.CollectionTarget, V> {
return .init(lhs.cs_keyPathString, rhs.cs_keyPathString)
}
/**
Connects multiple `DynamicKeyPath`s to create a type-safe chain usable in query/fetch expressions
Connects multiple `KeyPathStringConvertible`s to create a type-safe chain usable in query/fetch expressions
```
let spousesWithBadNamingSense = CoreStore.fetchAll(From<Person>().where((\.spouse ~ \.pets ~ \.name).any() == "Spot"))
```
*/
public func ~ <D: NSManagedObject, O: NSManagedObject, T, C: AllowedObjectiveCCollectionKeyPathValue, V: AllowedObjectiveCKeyPathValue>(_ lhs: Where<D>.Expression<T, C>, _ rhs: KeyPath<O, V>) -> Where<D>.Expression<Where<D>.CollectionTarget, V> {
public func ~ <D: NSManagedObject, O: NSManagedObject, T, C: AllowedObjectiveCToManyRelationshipKeyPathValue, V: AllowedObjectiveCKeyPathValue>(_ lhs: Where<D>.Expression<T, C>, _ rhs: KeyPath<O, V>) -> Where<D>.Expression<Where<D>.CollectionTarget, V> {
return .init(lhs.cs_keyPathString, rhs.cs_keyPathString)
}
@@ -230,12 +230,12 @@ public func ~ <D: NSManagedObject, O: NSManagedObject, T, C: AllowedObjectiveCCo
// MARK: - ~ where D: CoreStoreObject
/**
Connects multiple `DynamicKeyPath`s to create a type-safe chain usable in query/fetch expressions
Connects multiple `KeyPathStringConvertible`s to create a type-safe chain usable in query/fetch expressions
```
let owner = CoreStore.fetchOne(From<Pet>().where((\.master ~ \.name) == "John"))
```
*/
public func ~ <D: CoreStoreObject, O: CoreStoreObject, K: AllowedCoreStoreObjectKeyPathValue>(_ lhs: KeyPath<D, RelationshipContainer<D>.ToOne<O>>, _ rhs: KeyPath<O, K>) -> Where<D>.Expression<Where<D>.SingleTarget, K.ValueType> where K.ObjectType == O {
public func ~ <D: CoreStoreObject, O: CoreStoreObject, K: KeyPathStringConvertible>(_ lhs: KeyPath<D, RelationshipContainer<D>.ToOne<O>>, _ rhs: KeyPath<O, K>) -> Where<D>.Expression<Where<D>.SingleTarget, K.DestinationValueType> where K.ObjectType == O {
return .init(
D.meta[keyPath: lhs].cs_keyPathString,
@@ -244,12 +244,12 @@ public func ~ <D: CoreStoreObject, O: CoreStoreObject, K: AllowedCoreStoreObject
}
/**
Connects multiple `DynamicKeyPath`s to create a type-safe chain usable in query/fetch expressions
Connects multiple `KeyPathStringConvertible`s to create a type-safe chain usable in query/fetch expressions
```
let owner = CoreStore.fetchOne(From<Pet>().where((\.master ~ \.name) == "John"))
```
*/
public func ~ <D: CoreStoreObject, O: CoreStoreObject, T, K: AllowedCoreStoreObjectKeyPathValue>(_ lhs: Where<D>.Expression<T, O>, _ rhs: KeyPath<O, K>) -> Where<D>.Expression<T, K.ValueType> where K.ObjectType == O {
public func ~ <D: CoreStoreObject, O: CoreStoreObject, T, K: KeyPathStringConvertible>(_ lhs: Where<D>.Expression<T, O>, _ rhs: KeyPath<O, K>) -> Where<D>.Expression<T, K.DestinationValueType> where K.ObjectType == O {
return .init(
lhs.cs_keyPathString,
@@ -258,12 +258,12 @@ public func ~ <D: CoreStoreObject, O: CoreStoreObject, T, K: AllowedCoreStoreObj
}
/**
Connects multiple `DynamicKeyPath`s to create a type-safe chain usable in query/fetch expressions
Connects multiple `KeyPathStringConvertible`s to create a type-safe chain usable in query/fetch expressions
```
let owner = CoreStore.fetchOne(From<Pet>().where((\.master ~ \.name) == "John"))
```
*/
public func ~ <D: CoreStoreObject, O: CoreStoreObject, T, K: AllowedCoreStoreObjectKeyPathValue>(_ lhs: Where<D>.Expression<T, O?>, _ rhs: KeyPath<O, K>) -> Where<D>.Expression<T, K.ValueType> where K.ObjectType == O {
public func ~ <D: CoreStoreObject, O: CoreStoreObject, T, K: KeyPathStringConvertible>(_ lhs: Where<D>.Expression<T, O?>, _ rhs: KeyPath<O, K>) -> Where<D>.Expression<T, K.DestinationValueType> where K.ObjectType == O {
return .init(
lhs.cs_keyPathString,
@@ -272,12 +272,12 @@ public func ~ <D: CoreStoreObject, O: CoreStoreObject, T, K: AllowedCoreStoreObj
}
/**
Connects multiple `DynamicKeyPath`s to create a type-safe chain usable in query/fetch expressions
Connects multiple `KeyPathStringConvertible`s to create a type-safe chain usable in query/fetch expressions
```
let happyPets = CoreStore.fetchAll(From<Pet>().where((\.master ~ \.pets).count() > 1))
```
*/
public func ~ <D: CoreStoreObject, O: CoreStoreObject, K: AllowedCoreStoreObjectCollectionKeyPathValue>(_ lhs: KeyPath<D, RelationshipContainer<D>.ToOne<O>>, _ rhs: KeyPath<O, K>) -> Where<D>.Expression<Where<D>.CollectionTarget, K.ValueType> where K.ObjectType == O {
public func ~ <D: CoreStoreObject, O: CoreStoreObject, K: ToManyRelationshipKeyPathStringConvertible>(_ lhs: KeyPath<D, RelationshipContainer<D>.ToOne<O>>, _ rhs: KeyPath<O, K>) -> Where<D>.Expression<Where<D>.CollectionTarget, K.DestinationValueType> where K.ObjectType == O {
return .init(
D.meta[keyPath: lhs].cs_keyPathString,
@@ -286,12 +286,12 @@ public func ~ <D: CoreStoreObject, O: CoreStoreObject, K: AllowedCoreStoreObject
}
/**
Connects multiple `DynamicKeyPath`s to create a type-safe chain usable in query/fetch expressions
Connects multiple `KeyPathStringConvertible`s to create a type-safe chain usable in query/fetch expressions
```
let happyPets = CoreStore.fetchAll(From<Pet>().where((\.master ~ \.pets).count() > 1))
```
*/
public func ~ <D: CoreStoreObject, O: CoreStoreObject, T, K: AllowedCoreStoreObjectCollectionKeyPathValue>(_ lhs: Where<D>.Expression<T, O>, _ rhs: KeyPath<O, K>) -> Where<D>.Expression<Where<D>.CollectionTarget, K.ValueType> where K.ObjectType == O {
public func ~ <D: CoreStoreObject, O: CoreStoreObject, T, K: ToManyRelationshipKeyPathStringConvertible>(_ lhs: Where<D>.Expression<T, O>, _ rhs: KeyPath<O, K>) -> Where<D>.Expression<Where<D>.CollectionTarget, K.DestinationValueType> where K.ObjectType == O {
return .init(
lhs.cs_keyPathString,
@@ -300,12 +300,12 @@ public func ~ <D: CoreStoreObject, O: CoreStoreObject, T, K: AllowedCoreStoreObj
}
/**
Connects multiple `DynamicKeyPath`s to create a type-safe chain usable in query/fetch expressions
Connects multiple `KeyPathStringConvertible`s to create a type-safe chain usable in query/fetch expressions
```
let happyPets = CoreStore.fetchAll(From<Pet>().where((\.master ~ \.pets).count() > 1))
```
*/
public func ~ <D: CoreStoreObject, O: CoreStoreObject, T, K: AllowedCoreStoreObjectCollectionKeyPathValue>(_ lhs: Where<D>.Expression<T, O?>, _ rhs: KeyPath<O, K>) -> Where<D>.Expression<Where<D>.CollectionTarget, K.ValueType> where K.ObjectType == O {
public func ~ <D: CoreStoreObject, O: CoreStoreObject, T, K: ToManyRelationshipKeyPathStringConvertible>(_ lhs: Where<D>.Expression<T, O?>, _ rhs: KeyPath<O, K>) -> Where<D>.Expression<Where<D>.CollectionTarget, K.DestinationValueType> where K.ObjectType == O {
return .init(
lhs.cs_keyPathString,
@@ -314,12 +314,12 @@ public func ~ <D: CoreStoreObject, O: CoreStoreObject, T, K: AllowedCoreStoreObj
}
/**
Connects multiple `DynamicKeyPath`s to create a type-safe chain usable in query/fetch expressions
Connects multiple `KeyPathStringConvertible`s to create a type-safe chain usable in query/fetch expressions
```
let spousesWithBadNamingSense = CoreStore.fetchAll(From<Pet>().where((\.master ~ \.pets ~ \.name).any() == "Spot"))
```
*/
public func ~ <D: CoreStoreObject, O: CoreStoreObject, T, KC: AllowedCoreStoreObjectCollectionKeyPathValue, KV: AllowedCoreStoreObjectKeyPathValue>(_ lhs: Where<D>.Expression<T, KC>, _ rhs: KeyPath<O, KV>) -> Where<D>.Expression<Where<D>.CollectionTarget, KV.ValueType> where KC.ObjectType == D, KV.ObjectType == O {
public func ~ <D: CoreStoreObject, O: CoreStoreObject, T, KC: ToManyRelationshipKeyPathStringConvertible, KV: ToManyRelationshipKeyPathStringConvertible>(_ lhs: Where<D>.Expression<T, KC>, _ rhs: KeyPath<O, KV>) -> Where<D>.Expression<Where<D>.CollectionTarget, KV.DestinationValueType> where KC.ObjectType == D, KV.ObjectType == O {
return .init(
lhs.cs_keyPathString,
@@ -516,9 +516,9 @@ public func >= <D, T, V: QueryableAttributeType & Comparable>(_ lhs: Where<D>.Ex
}
// MARK: - KeyPath where Root: NSManagedObject, Value: AllowedObjectiveCCollectionKeyPathValue
// MARK: - KeyPath where Root: NSManagedObject, Value: AllowedObjectiveCToManyRelationshipKeyPathValue
extension KeyPath where Root: NSManagedObject, Value: AllowedObjectiveCCollectionKeyPathValue {
extension KeyPath where Root: NSManagedObject, Value: AllowedObjectiveCToManyRelationshipKeyPathValue {
/**
Creates a `Where.Expression` clause for COUNT
@@ -532,9 +532,9 @@ extension KeyPath where Root: NSManagedObject, Value: AllowedObjectiveCCollectio
}
}
// MARK: - Where.Expression where D: NSManagedObject, T == Where<D>.CollectionTarget, V: AllowedObjectiveCCollectionKeyPathValue
// MARK: - Where.Expression where D: NSManagedObject, T == Where<D>.CollectionTarget, V: AllowedObjectiveCToManyRelationshipKeyPathValue
extension Where.Expression where D: NSManagedObject, T == Where<D>.CollectionTarget, V: AllowedObjectiveCCollectionKeyPathValue {
extension Where.Expression where D: NSManagedObject, T == Where<D>.CollectionTarget, V: AllowedObjectiveCToManyRelationshipKeyPathValue {
/**
Creates a `Where.Expression` clause for COUNT
@@ -588,9 +588,9 @@ extension Where.Expression where D: NSManagedObject, T == Where<D>.CollectionTar
}
// MARK: - KeyPath where Root: CoreStoreObject, Value: AllowedObjectiveCCollectionKeyPathValue
// MARK: - KeyPath where Root: CoreStoreObject, Value: AllowedObjectiveCToManyRelationshipKeyPathValue
extension KeyPath where Root: CoreStoreObject, Value: AllowedCoreStoreObjectCollectionKeyPathValue {
extension KeyPath where Root: CoreStoreObject, Value: ToManyRelationshipKeyPathStringConvertible {
/**
Creates a `Where.Expression` clause for COUNT