mirror of
https://github.com/JohnEstropia/CoreStore.git
synced 2026-01-12 06:40:29 +01:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0376ac6908 | ||
|
|
b3421888a6 | ||
|
|
7b3f4ae0a4 | ||
|
|
b4e12cc922 | ||
|
|
6c282b18af | ||
|
|
ebbde8b7b6 | ||
|
|
a1407e4121 | ||
|
|
99b871b97a | ||
|
|
1cd3c4fcf4 | ||
|
|
e09ac9ee00 | ||
|
|
4b0d134acb |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -8,3 +8,4 @@ CoreStore.xcworkspace/xcuserdata
|
||||
DerivedData
|
||||
*.orig
|
||||
build
|
||||
Playground_macOS.playground/playground.xcworkspace/xcuserdata
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Pod::Spec.new do |s|
|
||||
s.name = "CoreStore"
|
||||
s.version = "6.0.0"
|
||||
s.version = "6.2.1"
|
||||
s.swift_version = "4.2"
|
||||
s.license = "MIT"
|
||||
s.homepage = "https://github.com/JohnEstropia/CoreStore"
|
||||
|
||||
@@ -293,6 +293,10 @@
|
||||
B546F9741C9C553300D5AC55 /* SetupResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B546F9721C9C553300D5AC55 /* SetupResult.swift */; };
|
||||
B546F9751C9C553300D5AC55 /* SetupResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B546F9721C9C553300D5AC55 /* SetupResult.swift */; };
|
||||
B546F9761C9C553300D5AC55 /* SetupResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B546F9721C9C553300D5AC55 /* SetupResult.swift */; };
|
||||
B5474D152227C08700B21FEC /* CoreStoreFetchRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5474D142227C08700B21FEC /* CoreStoreFetchRequest.swift */; };
|
||||
B5474D162227C08700B21FEC /* CoreStoreFetchRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5474D142227C08700B21FEC /* CoreStoreFetchRequest.swift */; };
|
||||
B5474D172227C08700B21FEC /* CoreStoreFetchRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5474D142227C08700B21FEC /* CoreStoreFetchRequest.swift */; };
|
||||
B5474D182227C08700B21FEC /* CoreStoreFetchRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5474D142227C08700B21FEC /* CoreStoreFetchRequest.swift */; };
|
||||
B5489F3F1CF5EEBC008B4978 /* TestEntity1.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5489F3D1CF5EEBC008B4978 /* TestEntity1.swift */; };
|
||||
B5489F401CF5EEBC008B4978 /* TestEntity1.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5489F3D1CF5EEBC008B4978 /* TestEntity1.swift */; };
|
||||
B5489F411CF5EEBC008B4978 /* TestEntity1.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5489F3D1CF5EEBC008B4978 /* TestEntity1.swift */; };
|
||||
@@ -823,6 +827,7 @@
|
||||
B546F95C1C9A12B800D5AC55 /* CSSQliteStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSSQliteStore.swift; sourceTree = "<group>"; };
|
||||
B546F9681C9AF26D00D5AC55 /* CSInMemoryStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSInMemoryStore.swift; sourceTree = "<group>"; };
|
||||
B546F9721C9C553300D5AC55 /* SetupResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SetupResult.swift; sourceTree = "<group>"; };
|
||||
B5474D142227C08700B21FEC /* CoreStoreFetchRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreStoreFetchRequest.swift; sourceTree = "<group>"; };
|
||||
B5489F3D1CF5EEBC008B4978 /* TestEntity1.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestEntity1.swift; sourceTree = "<group>"; };
|
||||
B5489F3E1CF5EEBC008B4978 /* TestEntity2.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestEntity2.swift; sourceTree = "<group>"; };
|
||||
B5489F451CF5F017008B4978 /* TransactionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionTests.swift; sourceTree = "<group>"; };
|
||||
@@ -880,6 +885,8 @@
|
||||
B5A1DAC71F111BFA003CF369 /* KeyPath+Querying.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "KeyPath+Querying.swift"; sourceTree = "<group>"; };
|
||||
B5A261201B64BFDB006EB6D3 /* MigrationType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MigrationType.swift; sourceTree = "<group>"; };
|
||||
B5A5F2651CAEC50F004AB9AF /* CSSelect.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSSelect.swift; sourceTree = "<group>"; };
|
||||
B5A80DF42212C1AB006096AA /* Playground_macOS.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; path = Playground_macOS.playground; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
|
||||
B5A80DF52212C1BC006096AA /* Playground_iOS.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; path = Playground_iOS.playground; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
|
||||
B5A991EB1E9DC2CE0091A2E3 /* VersionLock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VersionLock.swift; sourceTree = "<group>"; };
|
||||
B5A9921E1EA898710091A2E3 /* UserInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserInfo.swift; sourceTree = "<group>"; };
|
||||
B5AD60CD1C90141E00F2B2E8 /* Package.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Package.swift; sourceTree = SOURCE_ROOT; };
|
||||
@@ -961,7 +968,6 @@
|
||||
B5E84F351AFF85470064E85B /* NSManagedObjectContext+Querying.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSManagedObjectContext+Querying.swift"; sourceTree = "<group>"; };
|
||||
B5E84F401AFF8CCD0064E85B /* TypeErasedClauses.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TypeErasedClauses.swift; sourceTree = "<group>"; };
|
||||
B5E8A71F21C1015300EF006A /* CoreStoreObject+Observing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CoreStoreObject+Observing.swift"; sourceTree = "<group>"; };
|
||||
B5E8A72621C3B85000EF006A /* Playground.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; path = Playground.playground; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
|
||||
B5ECDBDE1CA6BB2B00C7F112 /* CSBaseDataTransaction+Querying.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CSBaseDataTransaction+Querying.swift"; sourceTree = "<group>"; };
|
||||
B5ECDBE41CA6BEA300C7F112 /* CSClauseTypes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSClauseTypes.swift; sourceTree = "<group>"; };
|
||||
B5ECDBEB1CA6BF2000C7F112 /* CSFrom.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSFrom.swift; sourceTree = "<group>"; };
|
||||
@@ -1052,7 +1058,8 @@
|
||||
2F03A52619C5C6DA005002A5 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B5E8A72621C3B85000EF006A /* Playground.playground */,
|
||||
B5A80DF52212C1BC006096AA /* Playground_iOS.playground */,
|
||||
B5A80DF42212C1AB006096AA /* Playground_macOS.playground */,
|
||||
2F291E3119C6D4D3007AF63F /* Frameworks */,
|
||||
2F03A53219C5C6DA005002A5 /* Sources */,
|
||||
2F03A53C19C5C6DA005002A5 /* CoreStoreTests */,
|
||||
@@ -1537,6 +1544,7 @@
|
||||
children = (
|
||||
B5831B6F1F34AC3400A9F647 /* AttributeProtocol.swift */,
|
||||
B5831B741F34AC7A00A9F647 /* RelationshipProtocol.swift */,
|
||||
B5474D142227C08700B21FEC /* CoreStoreFetchRequest.swift */,
|
||||
B5C976E61C6E3A5900B1AF90 /* CoreStoreFetchedResultsController.swift */,
|
||||
B53B275E1EE3B92E00E9B352 /* CoreStoreManagedObject.swift */,
|
||||
B533C4DA1D7D4BFA001383CB /* DispatchQueue+CoreStore.swift */,
|
||||
@@ -2026,6 +2034,7 @@
|
||||
B5FE4DA71C84FB4400FA6A91 /* InMemoryStore.swift in Sources */,
|
||||
B52F743D1E9B8724005F3DAC /* DynamicSchema.swift in Sources */,
|
||||
B5E8A72021C1015300EF006A /* CoreStoreObject+Observing.swift in Sources */,
|
||||
B5474D152227C08700B21FEC /* CoreStoreFetchRequest.swift in Sources */,
|
||||
B56923FF1EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift in Sources */,
|
||||
B5215CAE1FA4812500139E3A /* SectionMonitorBuilder.swift in Sources */,
|
||||
B5ECDBEC1CA6BF2000C7F112 /* CSFrom.swift in Sources */,
|
||||
@@ -2224,6 +2233,7 @@
|
||||
B5ECDBEE1CA6BF2000C7F112 /* CSFrom.swift in Sources */,
|
||||
B52F743E1E9B8724005F3DAC /* DynamicSchema.swift in Sources */,
|
||||
B5E8A72121C1015300EF006A /* CoreStoreObject+Observing.swift in Sources */,
|
||||
B5474D162227C08700B21FEC /* CoreStoreFetchRequest.swift in Sources */,
|
||||
B56924001EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift in Sources */,
|
||||
B5215CAF1FA4812500139E3A /* SectionMonitorBuilder.swift in Sources */,
|
||||
82BA18D61C4BBD7100A0916E /* NSManagedObjectContext+Transaction.swift in Sources */,
|
||||
@@ -2422,6 +2432,7 @@
|
||||
B5220E201D130813009BC71E /* CSObjectMonitor.swift in Sources */,
|
||||
B52F74401E9B8724005F3DAC /* DynamicSchema.swift in Sources */,
|
||||
B5E8A72321C1015300EF006A /* CoreStoreObject+Observing.swift in Sources */,
|
||||
B5474D182227C08700B21FEC /* CoreStoreFetchRequest.swift in Sources */,
|
||||
B56924021EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift in Sources */,
|
||||
B5215CB11FA4812500139E3A /* SectionMonitorBuilder.swift in Sources */,
|
||||
B5220E171D1306DF009BC71E /* UnsafeDataTransaction+Observing.swift in Sources */,
|
||||
@@ -2620,6 +2631,7 @@
|
||||
B5ECDBEF1CA6BF2000C7F112 /* CSFrom.swift in Sources */,
|
||||
B52F743F1E9B8724005F3DAC /* DynamicSchema.swift in Sources */,
|
||||
B5E8A72221C1015300EF006A /* CoreStoreObject+Observing.swift in Sources */,
|
||||
B5474D172227C08700B21FEC /* CoreStoreFetchRequest.swift in Sources */,
|
||||
B56924011EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift in Sources */,
|
||||
B5215CB01FA4812500139E3A /* SectionMonitorBuilder.swift in Sources */,
|
||||
B56321B41BD6521C006C9394 /* NSManagedObjectContext+Transaction.swift in Sources */,
|
||||
|
||||
@@ -313,6 +313,7 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
|
||||
|
||||
@IBAction private dynamic func shuffleBarButtonItemTouched(_ sender: AnyObject?) {
|
||||
|
||||
self.setTable(enabled: false)
|
||||
ColorsDemo.stack.perform(
|
||||
asynchronous: { (transaction) in
|
||||
|
||||
@@ -322,12 +323,16 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
|
||||
palette.colorName .= nil
|
||||
}
|
||||
},
|
||||
completion: { _ in }
|
||||
completion: { _ in
|
||||
|
||||
self.setTable(enabled: true)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private func setTable(enabled: Bool) {
|
||||
|
||||
|
||||
tableView.isUserInteractionEnabled = enabled
|
||||
UIView.animate(
|
||||
withDuration: 0.2,
|
||||
delay: 0,
|
||||
@@ -337,7 +342,6 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
|
||||
if let tableView = self.tableView {
|
||||
|
||||
tableView.alpha = enabled ? 1.0 : 0.5
|
||||
tableView.isUserInteractionEnabled = enabled
|
||||
}
|
||||
},
|
||||
completion: nil
|
||||
|
||||
@@ -141,10 +141,8 @@ class DynamicModelTests: BaseTestDataTestCase {
|
||||
let k1 = String(keyPath: \Animal.species)
|
||||
XCTAssertEqual(k1, "species")
|
||||
|
||||
#if swift(<5.0)
|
||||
let k2 = String(keyPath: \Dog.species)
|
||||
XCTAssertEqual(k2, "species")
|
||||
#endif
|
||||
|
||||
let k3 = String(keyPath: \Dog.nickname)
|
||||
XCTAssertEqual(k3, "nickname")
|
||||
@@ -325,9 +323,7 @@ class DynamicModelTests: BaseTestDataTestCase {
|
||||
dynamic func test_ThatDynamicModelKeyPaths_CanBeCreated() {
|
||||
|
||||
XCTAssertEqual(String(keyPath: \Animal.species), "species")
|
||||
#if swift(<5.0)
|
||||
XCTAssertEqual(String(keyPath: \Dog.species), "species")
|
||||
#endif
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
|
||||
@@ -74,31 +74,31 @@ final class FromTests: BaseTestCase {
|
||||
|
||||
let from = From<TestEntity1>()
|
||||
|
||||
let request = NSFetchRequest<NSFetchRequestResult>()
|
||||
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
try from.applyToFetchRequest(request, context: dataStack.mainContext)
|
||||
XCTAssertNotNil(request.entity)
|
||||
XCTAssertNotNil(request.affectedStores)
|
||||
XCTAssertNotNil(request.safeAffectedStores())
|
||||
|
||||
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
|
||||
|
||||
let affectedConfigurations = request.affectedStores?.map { $0.configurationName } ?? []
|
||||
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
|
||||
XCTAssertEqual(affectedConfigurations, ["PF_DEFAULT_CONFIGURATION_NAME"])
|
||||
}
|
||||
do {
|
||||
|
||||
let from = From<TestEntity1>("Config1")
|
||||
|
||||
let request = NSFetchRequest<NSFetchRequestResult>()
|
||||
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
self.expectError(code: .persistentStoreNotFound) {
|
||||
|
||||
try from.applyToFetchRequest(request, context: dataStack.mainContext)
|
||||
}
|
||||
XCTAssertNotNil(request.entity)
|
||||
XCTAssertNil(request.affectedStores)
|
||||
XCTAssertNotNil(request.safeAffectedStores())
|
||||
|
||||
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
|
||||
|
||||
let affectedConfigurations = request.affectedStores?.map { $0.configurationName } ?? []
|
||||
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
|
||||
XCTAssertTrue(affectedConfigurations.isEmpty)
|
||||
}
|
||||
}
|
||||
@@ -113,98 +113,98 @@ final class FromTests: BaseTestCase {
|
||||
|
||||
let from = From<TestEntity1>()
|
||||
|
||||
let request = NSFetchRequest<NSFetchRequestResult>()
|
||||
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
|
||||
XCTAssertNotNil(storesFound)
|
||||
XCTAssertNotNil(request.entity)
|
||||
XCTAssertNotNil(request.affectedStores)
|
||||
XCTAssertNotNil(request.safeAffectedStores())
|
||||
|
||||
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
|
||||
|
||||
let affectedConfigurations = request.affectedStores?.map { $0.configurationName } ?? []
|
||||
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
|
||||
XCTAssertEqual(affectedConfigurations, ["Config1"])
|
||||
}
|
||||
do {
|
||||
|
||||
let from = From<TestEntity1>("Config1")
|
||||
|
||||
let request = NSFetchRequest<NSFetchRequestResult>()
|
||||
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
|
||||
XCTAssertNotNil(storesFound)
|
||||
XCTAssertNotNil(request.entity)
|
||||
XCTAssertNotNil(request.affectedStores)
|
||||
XCTAssertNotNil(request.safeAffectedStores())
|
||||
|
||||
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
|
||||
|
||||
let affectedConfigurations = request.affectedStores?.map { $0.configurationName } ?? []
|
||||
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
|
||||
XCTAssertEqual(affectedConfigurations, ["Config1"])
|
||||
}
|
||||
do {
|
||||
|
||||
let from = From<TestEntity1>("Config2")
|
||||
|
||||
let request = NSFetchRequest<NSFetchRequestResult>()
|
||||
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
self.expectError(code: .persistentStoreNotFound) {
|
||||
|
||||
try from.applyToFetchRequest(request, context: dataStack.mainContext)
|
||||
}
|
||||
XCTAssertNotNil(request.entity)
|
||||
XCTAssertNil(request.affectedStores)
|
||||
XCTAssertNotNil(request.safeAffectedStores())
|
||||
|
||||
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
|
||||
|
||||
let affectedConfigurations = request.affectedStores?.map { $0.configurationName } ?? []
|
||||
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
|
||||
XCTAssertTrue(affectedConfigurations.isEmpty)
|
||||
}
|
||||
do {
|
||||
|
||||
let from = From<TestEntity2>()
|
||||
|
||||
let request = NSFetchRequest<NSFetchRequestResult>()
|
||||
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
self.expectError(code: .persistentStoreNotFound) {
|
||||
|
||||
try from.applyToFetchRequest(request, context: dataStack.mainContext)
|
||||
}
|
||||
XCTAssertNotNil(request.entity)
|
||||
XCTAssertNil(request.affectedStores)
|
||||
XCTAssertNotNil(request.safeAffectedStores())
|
||||
|
||||
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
|
||||
|
||||
let affectedConfigurations = request.affectedStores?.map { $0.configurationName } ?? []
|
||||
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
|
||||
XCTAssertTrue(affectedConfigurations.isEmpty)
|
||||
}
|
||||
do {
|
||||
|
||||
let from = From<TestEntity2>("Config1")
|
||||
|
||||
let request = NSFetchRequest<NSFetchRequestResult>()
|
||||
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
self.expectError(code: .persistentStoreNotFound) {
|
||||
|
||||
try from.applyToFetchRequest(request, context: dataStack.mainContext)
|
||||
}
|
||||
XCTAssertNotNil(request.entity)
|
||||
XCTAssertNil(request.affectedStores)
|
||||
XCTAssertNotNil(request.safeAffectedStores())
|
||||
|
||||
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
|
||||
|
||||
let affectedConfigurations = request.affectedStores?.map { $0.configurationName } ?? []
|
||||
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
|
||||
XCTAssertTrue(affectedConfigurations.isEmpty)
|
||||
}
|
||||
do {
|
||||
|
||||
let from = From<TestEntity2>("Config2")
|
||||
|
||||
let request = NSFetchRequest<NSFetchRequestResult>()
|
||||
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
self.expectError(code: .persistentStoreNotFound) {
|
||||
|
||||
try from.applyToFetchRequest(request, context: dataStack.mainContext)
|
||||
}
|
||||
XCTAssertNotNil(request.entity)
|
||||
XCTAssertNil(request.affectedStores)
|
||||
XCTAssertNotNil(request.safeAffectedStores())
|
||||
|
||||
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
|
||||
|
||||
let affectedConfigurations = request.affectedStores?.map { $0.configurationName } ?? []
|
||||
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
|
||||
XCTAssertTrue(affectedConfigurations.isEmpty)
|
||||
}
|
||||
}
|
||||
@@ -219,96 +219,96 @@ final class FromTests: BaseTestCase {
|
||||
|
||||
let from = From<TestEntity1>()
|
||||
|
||||
let request = NSFetchRequest<NSFetchRequestResult>()
|
||||
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
|
||||
XCTAssertNotNil(storesFound)
|
||||
XCTAssertNotNil(request.entity)
|
||||
XCTAssertNotNil(request.affectedStores)
|
||||
XCTAssertNotNil(request.safeAffectedStores())
|
||||
|
||||
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
|
||||
|
||||
let affectedConfigurations = request.affectedStores?.map { $0.configurationName } ?? []
|
||||
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
|
||||
XCTAssertEqual(Set(affectedConfigurations), ["PF_DEFAULT_CONFIGURATION_NAME", "Config1"] as Set)
|
||||
}
|
||||
do {
|
||||
|
||||
let from = From<TestEntity1>("Config1")
|
||||
|
||||
let request = NSFetchRequest<NSFetchRequestResult>()
|
||||
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
|
||||
XCTAssertNotNil(storesFound)
|
||||
XCTAssertNotNil(request.entity)
|
||||
XCTAssertNotNil(request.affectedStores)
|
||||
XCTAssertNotNil(request.safeAffectedStores())
|
||||
|
||||
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
|
||||
|
||||
let affectedConfigurations = request.affectedStores?.map { $0.configurationName } ?? []
|
||||
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
|
||||
XCTAssertEqual(affectedConfigurations, ["Config1"])
|
||||
}
|
||||
do {
|
||||
|
||||
let from = From<TestEntity1>("Config2")
|
||||
|
||||
let request = NSFetchRequest<NSFetchRequestResult>()
|
||||
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
self.expectError(code: .persistentStoreNotFound) {
|
||||
|
||||
try from.applyToFetchRequest(request, context: dataStack.mainContext)
|
||||
}
|
||||
XCTAssertNotNil(request.entity)
|
||||
XCTAssertNil(request.affectedStores)
|
||||
XCTAssertNotNil(request.safeAffectedStores())
|
||||
|
||||
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
|
||||
|
||||
let affectedConfigurations = request.affectedStores?.map { $0.configurationName } ?? []
|
||||
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
|
||||
XCTAssertTrue(affectedConfigurations.isEmpty)
|
||||
}
|
||||
do {
|
||||
|
||||
let from = From<TestEntity2>()
|
||||
|
||||
let request = NSFetchRequest<NSFetchRequestResult>()
|
||||
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
|
||||
XCTAssertNotNil(storesFound)
|
||||
XCTAssertNotNil(request.entity)
|
||||
XCTAssertNotNil(request.affectedStores)
|
||||
XCTAssertNotNil(request.safeAffectedStores())
|
||||
|
||||
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
|
||||
|
||||
let affectedConfigurations = request.affectedStores?.map { $0.configurationName } ?? []
|
||||
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
|
||||
XCTAssertEqual(affectedConfigurations, ["PF_DEFAULT_CONFIGURATION_NAME"])
|
||||
}
|
||||
do {
|
||||
|
||||
let from = From<TestEntity2>("Config1")
|
||||
|
||||
let request = NSFetchRequest<NSFetchRequestResult>()
|
||||
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
self.expectError(code: .persistentStoreNotFound) {
|
||||
|
||||
try from.applyToFetchRequest(request, context: dataStack.mainContext)
|
||||
}
|
||||
XCTAssertNotNil(request.entity)
|
||||
XCTAssertNil(request.affectedStores)
|
||||
XCTAssertNotNil(request.safeAffectedStores())
|
||||
|
||||
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
|
||||
|
||||
let affectedConfigurations = request.affectedStores?.map { $0.configurationName } ?? []
|
||||
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
|
||||
XCTAssertTrue(affectedConfigurations.isEmpty)
|
||||
}
|
||||
do {
|
||||
|
||||
let from = From<TestEntity2>("Config2")
|
||||
|
||||
let request = NSFetchRequest<NSFetchRequestResult>()
|
||||
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
self.expectError(code: .persistentStoreNotFound) {
|
||||
|
||||
try from.applyToFetchRequest(request, context: dataStack.mainContext)
|
||||
}
|
||||
XCTAssertNotNil(request.entity)
|
||||
XCTAssertNil(request.affectedStores)
|
||||
XCTAssertNotNil(request.safeAffectedStores())
|
||||
|
||||
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
|
||||
|
||||
let affectedConfigurations = request.affectedStores?.map { $0.configurationName } ?? []
|
||||
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
|
||||
XCTAssertTrue(affectedConfigurations.isEmpty)
|
||||
}
|
||||
}
|
||||
@@ -323,94 +323,94 @@ final class FromTests: BaseTestCase {
|
||||
|
||||
let from = From<TestEntity1>()
|
||||
|
||||
let request = NSFetchRequest<NSFetchRequestResult>()
|
||||
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
|
||||
XCTAssertNotNil(storesFound)
|
||||
XCTAssertNotNil(request.entity)
|
||||
XCTAssertNotNil(request.affectedStores)
|
||||
XCTAssertNotNil(request.safeAffectedStores())
|
||||
|
||||
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
|
||||
|
||||
let affectedConfigurations = request.affectedStores?.map { $0.configurationName } ?? []
|
||||
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
|
||||
XCTAssertEqual(affectedConfigurations, ["Config1"])
|
||||
}
|
||||
do {
|
||||
|
||||
let from = From<TestEntity1>("Config1")
|
||||
|
||||
let request = NSFetchRequest<NSFetchRequestResult>()
|
||||
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
|
||||
XCTAssertNotNil(storesFound)
|
||||
XCTAssertNotNil(request.entity)
|
||||
XCTAssertNotNil(request.affectedStores)
|
||||
XCTAssertNotNil(request.safeAffectedStores())
|
||||
|
||||
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
|
||||
|
||||
let affectedConfigurations = request.affectedStores?.map { $0.configurationName } ?? []
|
||||
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
|
||||
XCTAssertEqual(affectedConfigurations, ["Config1"])
|
||||
}
|
||||
do {
|
||||
|
||||
let from = From<TestEntity1>("Config2")
|
||||
|
||||
let request = NSFetchRequest<NSFetchRequestResult>()
|
||||
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
self.expectError(code: .persistentStoreNotFound) {
|
||||
|
||||
try from.applyToFetchRequest(request, context: dataStack.mainContext)
|
||||
}
|
||||
XCTAssertNotNil(request.entity)
|
||||
XCTAssertNil(request.affectedStores)
|
||||
XCTAssertNotNil(request.safeAffectedStores())
|
||||
|
||||
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
|
||||
|
||||
let affectedConfigurations = request.affectedStores?.map { $0.configurationName } ?? []
|
||||
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
|
||||
XCTAssertTrue(affectedConfigurations.isEmpty)
|
||||
}
|
||||
do {
|
||||
|
||||
let from = From<TestEntity2>()
|
||||
|
||||
let request = NSFetchRequest<NSFetchRequestResult>()
|
||||
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
|
||||
XCTAssertNotNil(storesFound)
|
||||
XCTAssertNotNil(request.entity)
|
||||
XCTAssertNotNil(request.affectedStores)
|
||||
XCTAssertNotNil(request.safeAffectedStores())
|
||||
|
||||
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
|
||||
|
||||
let affectedConfigurations = request.affectedStores?.map { $0.configurationName } ?? []
|
||||
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
|
||||
XCTAssertEqual(affectedConfigurations, ["Config2"])
|
||||
}
|
||||
do {
|
||||
|
||||
let from = From<TestEntity2>("Config1")
|
||||
|
||||
let request = NSFetchRequest<NSFetchRequestResult>()
|
||||
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
self.expectError(code: .persistentStoreNotFound) {
|
||||
|
||||
try from.applyToFetchRequest(request, context: dataStack.mainContext)
|
||||
}
|
||||
XCTAssertNotNil(request.entity)
|
||||
XCTAssertNil(request.affectedStores)
|
||||
XCTAssertNotNil(request.safeAffectedStores())
|
||||
|
||||
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
|
||||
|
||||
let affectedConfigurations = request.affectedStores?.map { $0.configurationName } ?? []
|
||||
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
|
||||
XCTAssertTrue(affectedConfigurations.isEmpty)
|
||||
}
|
||||
do {
|
||||
|
||||
let from = From<TestEntity2>("Config2")
|
||||
|
||||
let request = NSFetchRequest<NSFetchRequestResult>()
|
||||
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
|
||||
XCTAssertNotNil(storesFound)
|
||||
XCTAssertNotNil(request.entity)
|
||||
XCTAssertNotNil(request.affectedStores)
|
||||
XCTAssertNotNil(request.safeAffectedStores())
|
||||
|
||||
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
|
||||
|
||||
let affectedConfigurations = request.affectedStores?.map { $0.configurationName } ?? []
|
||||
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
|
||||
XCTAssertEqual(affectedConfigurations, ["Config2"])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ final class GroupByTests: BaseTestCase {
|
||||
|
||||
let groupBy = GroupBy<NSManagedObject>(#keyPath(TestEntity1.testString))
|
||||
|
||||
let request = NSFetchRequest<NSFetchRequestResult>()
|
||||
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
try From<TestEntity1>().applyToFetchRequest(request, context: dataStack.mainContext)
|
||||
groupBy.applyToFetchRequest(request)
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>6.0.0</string>
|
||||
<string>6.2.1</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
|
||||
@@ -179,7 +179,7 @@ final class OrderByTests: XCTestCase {
|
||||
dynamic func test_ThatOrderByClauses_ApplyToFetchRequestsCorrectly() {
|
||||
|
||||
let orderBy = OrderBy<NSManagedObject>(.ascending("key"))
|
||||
let request = NSFetchRequest<NSFetchRequestResult>()
|
||||
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
orderBy.applyToFetchRequest(request)
|
||||
XCTAssertNotNil(request.sortDescriptors)
|
||||
XCTAssertEqual(request.sortDescriptors ?? [], orderBy.sortDescriptors)
|
||||
|
||||
@@ -43,7 +43,7 @@ final class TweakTests: XCTestCase {
|
||||
$0.fetchLimit = 200
|
||||
$0.predicate = predicate
|
||||
}
|
||||
let request = NSFetchRequest<NSFetchRequestResult>()
|
||||
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
tweak.applyToFetchRequest(request)
|
||||
XCTAssertEqual(request.fetchOffset, 100)
|
||||
XCTAssertEqual(request.fetchLimit, 200)
|
||||
|
||||
@@ -583,7 +583,7 @@ final class WhereTests: XCTestCase {
|
||||
dynamic func test_ThatWhereClauses_ApplyToFetchRequestsCorrectly() {
|
||||
|
||||
let whereClause = Where<NSManagedObject>("key", isEqualTo: "value")
|
||||
let request = NSFetchRequest<NSFetchRequestResult>()
|
||||
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
|
||||
whereClause.applyToFetchRequest(request)
|
||||
XCTAssertNotNil(request.predicate)
|
||||
XCTAssertEqual(request.predicate, whereClause.predicate)
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
import UIKit
|
||||
import CoreStore
|
||||
|
||||
/// Model Declaration =====
|
||||
class Animal: CoreStoreObject {
|
||||
let species = Value.Required<String>("species", initial: "Swift")
|
||||
let master = Relationship.ToOne<Person>("master")
|
||||
let color = Transformable.Optional<UIColor>("color", initial: .orange)
|
||||
}
|
||||
|
||||
class Person: CoreStoreObject {
|
||||
let name = Value.Optional<String>("name")
|
||||
let pets = Relationship.ToManyUnordered<Animal>("pets", inverse: { $0.master })
|
||||
}
|
||||
/// =======================
|
||||
|
||||
/// Stack setup ===========
|
||||
let dataStack = DataStack(
|
||||
CoreStoreSchema(
|
||||
modelVersion: "V1",
|
||||
entities: [
|
||||
Entity<Animal>("Animal"),
|
||||
Entity<Person>("Person")
|
||||
]
|
||||
)
|
||||
)
|
||||
try dataStack.addStorageAndWait(SQLiteStore(fileName: "data.sqlite"))
|
||||
/// =======================
|
||||
|
||||
/// Transactions ==========
|
||||
dataStack.perform(synchronous: { transaction in
|
||||
|
||||
let animal = transaction.create(Into<Animal>())
|
||||
animal.species .= "Sparrow"
|
||||
animal.color .= .yellow
|
||||
|
||||
let person = transaction.create(Into<Person>())
|
||||
person.name .= "John"
|
||||
person.pets.value.insert(animal)
|
||||
})
|
||||
/// =======================
|
||||
|
||||
/// Accessing Objects =====
|
||||
let bird = dataStack.fetchOne(From<Animal>().where(\.species == "Sparrow"))!
|
||||
bird.species.value
|
||||
bird.color.value
|
||||
print(bird)
|
||||
|
||||
let owner = bird.master.value!
|
||||
owner.name.value
|
||||
owner.pets.count
|
||||
print(owner)
|
||||
/// =======================
|
||||
79
Playground_iOS.playground/Contents.swift
Normal file
79
Playground_iOS.playground/Contents.swift
Normal file
@@ -0,0 +1,79 @@
|
||||
import UIKit
|
||||
import CoreStore
|
||||
import PlaygroundSupport
|
||||
|
||||
PlaygroundPage.current.needsIndefiniteExecution = true
|
||||
|
||||
/// Model Declaration =====
|
||||
class Animal: CoreStoreObject {
|
||||
let species = Value.Required<String>("species", initial: "Swift")
|
||||
let master = Relationship.ToOne<Person>("master")
|
||||
let color = Transformable.Optional<UIColor>("color", initial: .orange)
|
||||
}
|
||||
|
||||
class Person: CoreStoreObject {
|
||||
let name = Value.Optional<String>("name")
|
||||
let pets = Relationship.ToManyUnordered<Animal>("pets", inverse: { $0.master })
|
||||
}
|
||||
/// =======================
|
||||
|
||||
/// Stack setup ===========
|
||||
let dataStack = DataStack(
|
||||
CoreStoreSchema(
|
||||
modelVersion: "V1",
|
||||
entities: [
|
||||
Entity<Animal>("Animal"),
|
||||
Entity<Person>("Person")
|
||||
]
|
||||
)
|
||||
)
|
||||
dataStack.addStorage(
|
||||
SQLiteStore(fileName: "data.sqlite"),
|
||||
completion: { result in
|
||||
|
||||
switch result {
|
||||
|
||||
case .failure(let error):
|
||||
print(error)
|
||||
|
||||
case .success:
|
||||
/// Transactions ==========
|
||||
dataStack.perform(
|
||||
asynchronous: { transaction in
|
||||
|
||||
let animal = transaction.create(Into<Animal>())
|
||||
animal.species .= "Sparrow"
|
||||
animal.color .= .yellow
|
||||
|
||||
let person = transaction.create(Into<Person>())
|
||||
person.name .= "John"
|
||||
person.pets.value.insert(animal)
|
||||
},
|
||||
completion: { result in
|
||||
|
||||
switch result {
|
||||
|
||||
case .failure(let error):
|
||||
print(error)
|
||||
|
||||
case .success:
|
||||
/// Accessing Objects =====
|
||||
let bird = try! dataStack.fetchOne(From<Animal>().where(\.species == "Sparrow"))!
|
||||
print(bird.species.value)
|
||||
print(bird.color.value as Any)
|
||||
print(bird)
|
||||
|
||||
let owner = bird.master.value!
|
||||
print(owner.name.value as Any)
|
||||
print(owner.pets.count)
|
||||
print(owner)
|
||||
/// =======================
|
||||
}
|
||||
}
|
||||
)
|
||||
/// =======================
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
77
Playground_macOS.playground/Contents.swift
Normal file
77
Playground_macOS.playground/Contents.swift
Normal file
@@ -0,0 +1,77 @@
|
||||
import AppKit
|
||||
import CoreStore
|
||||
import PlaygroundSupport
|
||||
|
||||
PlaygroundPage.current.needsIndefiniteExecution = true
|
||||
|
||||
/// Model Declaration =====
|
||||
class Animal: CoreStoreObject {
|
||||
let species = Value.Required<String>("species", initial: "Swift")
|
||||
let master = Relationship.ToOne<Person>("master")
|
||||
let color = Transformable.Optional<NSColor>("color", initial: .orange)
|
||||
}
|
||||
|
||||
class Person: CoreStoreObject {
|
||||
let name = Value.Optional<String>("name")
|
||||
let pets = Relationship.ToManyUnordered<Animal>("pets", inverse: { $0.master })
|
||||
}
|
||||
/// =======================
|
||||
|
||||
/// Stack setup ===========
|
||||
let dataStack = DataStack(
|
||||
CoreStoreSchema(
|
||||
modelVersion: "V1",
|
||||
entities: [
|
||||
Entity<Animal>("Animal"),
|
||||
Entity<Person>("Person")
|
||||
]
|
||||
)
|
||||
)
|
||||
dataStack.addStorage(
|
||||
SQLiteStore(fileName: "data.sqlite"),
|
||||
completion: { result in
|
||||
|
||||
switch result {
|
||||
|
||||
case .failure(let error):
|
||||
print(error)
|
||||
|
||||
case .success:
|
||||
/// Transactions ==========
|
||||
dataStack.perform(
|
||||
asynchronous: { transaction in
|
||||
|
||||
let animal = transaction.create(Into<Animal>())
|
||||
animal.species .= "Sparrow"
|
||||
animal.color .= .yellow
|
||||
|
||||
let person = transaction.create(Into<Person>())
|
||||
person.name .= "John"
|
||||
person.pets.value.insert(animal)
|
||||
},
|
||||
completion: { result in
|
||||
|
||||
switch result {
|
||||
|
||||
case .failure(let error):
|
||||
print(error)
|
||||
|
||||
case .success:
|
||||
/// Accessing Objects =====
|
||||
let bird = try! dataStack.fetchOne(From<Animal>().where(\.species == "Sparrow"))!
|
||||
print(bird.species.value)
|
||||
print(bird.color.value as Any)
|
||||
print(bird)
|
||||
|
||||
let owner = bird.master.value!
|
||||
print(owner.name.value as Any)
|
||||
print(owner.pets.count)
|
||||
print(owner)
|
||||
/// =======================
|
||||
}
|
||||
}
|
||||
)
|
||||
/// =======================
|
||||
}
|
||||
}
|
||||
)
|
||||
4
Playground_macOS.playground/contents.xcplayground
Normal file
4
Playground_macOS.playground/contents.xcplayground
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<playground version='5.0' target-platform='macos' executeOnSourceChanges='false'>
|
||||
<timeline fileName='timeline.xctimeline'/>
|
||||
</playground>
|
||||
7
Playground_macOS.playground/playground.xcworkspace/contents.xcworkspacedata
generated
Normal file
7
Playground_macOS.playground/playground.xcworkspace/contents.xcworkspacedata
generated
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -1872,7 +1872,7 @@ Once the version lock is set, any changes in the properties or to the model will
|
||||
### Install with CocoaPods
|
||||
In your `Podfile`, add
|
||||
```
|
||||
pod 'CoreStore', '~> 6.0'
|
||||
pod 'CoreStore', '~> 6.1'
|
||||
```
|
||||
and run
|
||||
```
|
||||
@@ -1883,7 +1883,7 @@ This installs CoreStore as a framework. Declare `import CoreStore` in your swift
|
||||
### Install with Carthage
|
||||
In your `Cartfile`, add
|
||||
```
|
||||
github "JohnEstropia/CoreStore" >= 6.0.0
|
||||
github "JohnEstropia/CoreStore" >= 6.2.1
|
||||
```
|
||||
and run
|
||||
```
|
||||
@@ -1894,7 +1894,7 @@ This installs CoreStore as a framework. Declare `import CoreStore` in your swift
|
||||
#### Install with Swift Package Manager:
|
||||
```swift
|
||||
dependencies: [
|
||||
.package(url: "https://github.com/JohnEstropia/CoreStore.git", from: "6.0.0"))
|
||||
.package(url: "https://github.com/JohnEstropia/CoreStore.git", from: "6.2.1"))
|
||||
]
|
||||
```
|
||||
Declare `import CoreStore` in your swift file to use the library.
|
||||
|
||||
@@ -68,7 +68,7 @@ extension CSDataStack {
|
||||
sectionBy: nil,
|
||||
applyFetchClauses: { (fetchRequest) in
|
||||
|
||||
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest as! NSFetchRequest<NSFetchRequestResult>) }
|
||||
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
|
||||
}
|
||||
).bridgeToObjectiveC
|
||||
}
|
||||
@@ -97,7 +97,7 @@ extension CSDataStack {
|
||||
sectionBy: nil,
|
||||
applyFetchClauses: { (fetchRequest) in
|
||||
|
||||
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest as! NSFetchRequest<NSFetchRequestResult>) }
|
||||
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
|
||||
},
|
||||
createAsynchronously: {
|
||||
|
||||
@@ -131,7 +131,7 @@ extension CSDataStack {
|
||||
sectionBy: sectionBy.bridgeToSwift,
|
||||
applyFetchClauses: { (fetchRequest) in
|
||||
|
||||
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest as! NSFetchRequest<NSFetchRequestResult>) }
|
||||
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
|
||||
}
|
||||
).bridgeToObjectiveC
|
||||
}
|
||||
@@ -160,7 +160,7 @@ extension CSDataStack {
|
||||
sectionBy: sectionBy.bridgeToSwift,
|
||||
applyFetchClauses: { (fetchRequest) in
|
||||
|
||||
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest as! NSFetchRequest<NSFetchRequestResult>) }
|
||||
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
|
||||
},
|
||||
createAsynchronously: {
|
||||
|
||||
|
||||
@@ -503,7 +503,7 @@ public final class CSListMonitor: NSObject {
|
||||
|
||||
self.bridgeToSwift.refetch { (fetchRequest) in
|
||||
|
||||
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest as! NSFetchRequest<NSFetchRequestResult>) }
|
||||
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
91
Sources/CoreStoreFetchRequest.swift
Normal file
91
Sources/CoreStoreFetchRequest.swift
Normal file
@@ -0,0 +1,91 @@
|
||||
//
|
||||
// CoreStoreFetchRequest.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 Foundation
|
||||
import CoreData
|
||||
import ObjectiveC
|
||||
|
||||
|
||||
// MARK: - CoreStoreFetchRequest
|
||||
|
||||
// Bugfix for NSFetchRequest messing up memory management for `affectedStores`
|
||||
// http://stackoverflow.com/questions/14396375/nsfetchedresultscontroller-crashes-in-ios-6-if-affectedstores-is-specified
|
||||
internal final class CoreStoreFetchRequest<T: NSFetchRequestResult>: NSFetchRequest<NSFetchRequestResult> {
|
||||
|
||||
@nonobjc
|
||||
internal func safeAffectedStores() -> [NSPersistentStore]? {
|
||||
|
||||
return self.copiedAffectedStores as! [NSPersistentStore]?
|
||||
}
|
||||
|
||||
@nonobjc @inline(__always)
|
||||
internal func staticCast() -> NSFetchRequest<T> {
|
||||
|
||||
return unsafeBitCast(self, to: NSFetchRequest<T>.self)
|
||||
}
|
||||
|
||||
@nonobjc @inline(__always)
|
||||
internal func dynamicCast<U>() -> NSFetchRequest<U> {
|
||||
|
||||
return unsafeBitCast(self, to: NSFetchRequest<U>.self)
|
||||
}
|
||||
|
||||
|
||||
// MARK: NSFetchRequest
|
||||
|
||||
@objc dynamic
|
||||
override var affectedStores: [NSPersistentStore]? {
|
||||
|
||||
get {
|
||||
|
||||
return super.affectedStores
|
||||
}
|
||||
set {
|
||||
|
||||
if #available(iOS 11.0, macOS 10.13, watchOS 4.0, tvOS 11.0, *) {
|
||||
|
||||
self.copiedAffectedStores = (newValue as NSArray?)?.copy() as! NSArray?
|
||||
super.affectedStores = newValue
|
||||
return
|
||||
}
|
||||
// Bugfix for NSFetchRequest messing up memory management for `affectedStores`
|
||||
// http://stackoverflow.com/questions/14396375/nsfetchedresultscontroller-crashes-in-ios-6-if-affectedstores-is-specified
|
||||
if let releaseArray = self.releaseArray {
|
||||
|
||||
releaseArray.release()
|
||||
self.releaseArray = nil
|
||||
}
|
||||
self.copiedAffectedStores = (newValue as NSArray?)?.copy() as! NSArray?
|
||||
super.affectedStores = newValue
|
||||
self.releaseArray = (super.affectedStores as NSArray?).map(Unmanaged<NSArray>.passRetained(_:))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private var copiedAffectedStores: NSArray?
|
||||
private var releaseArray: Unmanaged<NSArray>?
|
||||
}
|
||||
@@ -33,10 +33,13 @@ import CoreData
|
||||
internal final class CoreStoreFetchedResultsController: NSFetchedResultsController<NSManagedObject> {
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
@nonobjc
|
||||
internal let typedFetchRequest: CoreStoreFetchRequest<NSManagedObject>
|
||||
|
||||
@nonobjc
|
||||
internal convenience init<D>(dataStack: DataStack, fetchRequest: NSFetchRequest<NSManagedObject>, from: From<D>, sectionBy: SectionBy<D>? = nil, applyFetchClauses: @escaping (_ fetchRequest: NSFetchRequest<NSManagedObject>) -> Void) {
|
||||
|
||||
internal convenience init<D>(dataStack: DataStack, fetchRequest: CoreStoreFetchRequest<NSManagedObject>, from: From<D>, sectionBy: SectionBy<D>? = nil, applyFetchClauses: @escaping (_ fetchRequest: CoreStoreFetchRequest<NSManagedObject>) -> Void) {
|
||||
|
||||
self.init(
|
||||
context: dataStack.mainContext,
|
||||
fetchRequest: fetchRequest,
|
||||
@@ -47,7 +50,7 @@ internal final class CoreStoreFetchedResultsController: NSFetchedResultsControll
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
internal init<D>(context: NSManagedObjectContext, fetchRequest: NSFetchRequest<NSManagedObject>, from: From<D>, sectionBy: SectionBy<D>? = nil, applyFetchClauses: @escaping (_ fetchRequest: NSFetchRequest<NSManagedObject>) -> Void) {
|
||||
internal init<D>(context: NSManagedObjectContext, fetchRequest: CoreStoreFetchRequest<NSManagedObject>, from: From<D>, sectionBy: SectionBy<D>? = nil, applyFetchClauses: @escaping (_ fetchRequest: CoreStoreFetchRequest<NSManagedObject>) -> Void) {
|
||||
|
||||
_ = try? from.applyToFetchRequest(
|
||||
fetchRequest,
|
||||
@@ -55,14 +58,15 @@ internal final class CoreStoreFetchedResultsController: NSFetchedResultsControll
|
||||
applyAffectedStores: false
|
||||
)
|
||||
applyFetchClauses(fetchRequest)
|
||||
|
||||
|
||||
self.typedFetchRequest = fetchRequest
|
||||
self.reapplyAffectedStores = { fetchRequest, context in
|
||||
|
||||
try from.applyAffectedStoresForFetchedRequest(fetchRequest, context: context)
|
||||
}
|
||||
|
||||
super.init(
|
||||
fetchRequest: fetchRequest,
|
||||
fetchRequest: fetchRequest.staticCast(),
|
||||
managedObjectContext: context,
|
||||
sectionNameKeyPath: sectionBy?.sectionKeyPath,
|
||||
cacheName: nil
|
||||
@@ -72,7 +76,7 @@ internal final class CoreStoreFetchedResultsController: NSFetchedResultsControll
|
||||
@nonobjc
|
||||
internal func performFetchFromSpecifiedStores() throws {
|
||||
|
||||
try self.reapplyAffectedStores(self.fetchRequest, self.managedObjectContext)
|
||||
try self.reapplyAffectedStores(self.typedFetchRequest, self.managedObjectContext)
|
||||
try self.performFetch()
|
||||
}
|
||||
|
||||
@@ -91,5 +95,5 @@ internal final class CoreStoreFetchedResultsController: NSFetchedResultsControll
|
||||
// MARK: Private
|
||||
|
||||
@nonobjc
|
||||
private let reapplyAffectedStores: (_ fetchRequest: NSFetchRequest<NSManagedObject>, _ context: NSManagedObjectContext) throws -> Void
|
||||
private let reapplyAffectedStores: (_ fetchRequest: CoreStoreFetchRequest<NSManagedObject>, _ context: NSManagedObjectContext) throws -> Void
|
||||
}
|
||||
|
||||
@@ -100,8 +100,7 @@ public final class Entity<O: CoreStoreObject>: DynamicEntity {
|
||||
entityName,
|
||||
isAbstract: isAbstract,
|
||||
versionHashModifier: versionHashModifier,
|
||||
indexes: indexes,
|
||||
uniqueConstraints: []
|
||||
indexes: indexes
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -86,6 +86,14 @@ internal final class FetchedResultsControllerDelegate: NSObject, NSFetchedResult
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if #available(iOS 11.0, tvOS 11.0, watchOS 4.0, macOS 10.13, *) {}
|
||||
else {
|
||||
|
||||
self.deletedSections = []
|
||||
self.insertedSections = []
|
||||
}
|
||||
|
||||
self.handler?.controllerWillChangeContent(controller)
|
||||
}
|
||||
|
||||
@@ -100,6 +108,7 @@ internal final class FetchedResultsControllerDelegate: NSObject, NSFetchedResult
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
self.handler?.controllerDidChangeContent(controller)
|
||||
}
|
||||
|
||||
@@ -110,11 +119,102 @@ internal final class FetchedResultsControllerDelegate: NSObject, NSFetchedResult
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if #available(iOS 11.0, tvOS 11.0, watchOS 4.0, macOS 10.13, *) {
|
||||
|
||||
self.handler?.controller(
|
||||
controller,
|
||||
didChangeObject: anObject,
|
||||
atIndexPath: indexPath,
|
||||
forChangeType: type,
|
||||
newIndexPath: newIndexPath
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
guard var actualType = NSFetchedResultsChangeType(rawValue: type.rawValue) else {
|
||||
|
||||
// This fix is for a bug where iOS passes 0 for NSFetchedResultsChangeType, but this is not a valid enum case.
|
||||
// Swift will then always execute the first case of the switch causing strange behaviour.
|
||||
// https://forums.developer.apple.com/thread/12184#31850
|
||||
return
|
||||
}
|
||||
|
||||
// This whole dance is a workaround for a nasty bug introduced in XCode 7 targeted at iOS 8 devices
|
||||
// http://stackoverflow.com/questions/31383760/ios-9-attempt-to-delete-and-reload-the-same-index-path/31384014#31384014
|
||||
// https://forums.developer.apple.com/message/9998#9998
|
||||
// https://forums.developer.apple.com/message/31849#31849
|
||||
|
||||
if case .update = actualType,
|
||||
indexPath != nil,
|
||||
newIndexPath != nil {
|
||||
|
||||
actualType = .move
|
||||
}
|
||||
|
||||
switch actualType {
|
||||
|
||||
case .update:
|
||||
guard let section = indexPath?[0] else {
|
||||
|
||||
return
|
||||
}
|
||||
if self.deletedSections.contains(section)
|
||||
|| self.insertedSections.contains(section) {
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
case .move:
|
||||
guard let indexPath = indexPath, let newIndexPath = newIndexPath else {
|
||||
|
||||
return
|
||||
}
|
||||
guard indexPath == newIndexPath else {
|
||||
|
||||
break
|
||||
}
|
||||
if self.insertedSections.contains(indexPath[0]) {
|
||||
|
||||
// Observers that handle the .Move change are advised to delete then reinsert the object instead of just moving. This is especially true when indexPath and newIndexPath are equal. For example, calling tableView.moveRowAtIndexPath(_:toIndexPath) when both indexPaths are the same will crash the tableView.
|
||||
self.handler?.controller(
|
||||
controller,
|
||||
didChangeObject: anObject,
|
||||
atIndexPath: indexPath,
|
||||
forChangeType: .move,
|
||||
newIndexPath: newIndexPath
|
||||
)
|
||||
return
|
||||
}
|
||||
if self.deletedSections.contains(indexPath[0]) {
|
||||
|
||||
self.handler?.controller(
|
||||
controller,
|
||||
didChangeObject: anObject,
|
||||
atIndexPath: nil,
|
||||
forChangeType: .insert,
|
||||
newIndexPath: indexPath
|
||||
)
|
||||
return
|
||||
}
|
||||
self.handler?.controller(
|
||||
controller,
|
||||
didChangeObject: anObject,
|
||||
atIndexPath: indexPath,
|
||||
forChangeType: .update,
|
||||
newIndexPath: nil
|
||||
)
|
||||
return
|
||||
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
self.handler?.controller(
|
||||
controller,
|
||||
didChangeObject: anObject,
|
||||
atIndexPath: indexPath,
|
||||
forChangeType: type,
|
||||
forChangeType: actualType,
|
||||
newIndexPath: newIndexPath
|
||||
)
|
||||
}
|
||||
@@ -126,6 +226,18 @@ internal final class FetchedResultsControllerDelegate: NSObject, NSFetchedResult
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if #available(iOS 11.0, tvOS 11.0, watchOS 4.0, macOS 10.13, *) {}
|
||||
else {
|
||||
|
||||
switch type {
|
||||
|
||||
case .delete: self.deletedSections.insert(sectionIndex)
|
||||
case .insert: self.insertedSections.insert(sectionIndex)
|
||||
default: break
|
||||
}
|
||||
}
|
||||
|
||||
self.handler?.controller(
|
||||
controller,
|
||||
didChangeSection: sectionInfo,
|
||||
@@ -142,4 +254,13 @@ internal final class FetchedResultsControllerDelegate: NSObject, NSFetchedResult
|
||||
sectionIndexTitleForSectionName: sectionName
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
// MARK: Private
|
||||
|
||||
@nonobjc
|
||||
private var deletedSections = Set<Int>()
|
||||
|
||||
@nonobjc
|
||||
private var insertedSections = Set<Int>()
|
||||
}
|
||||
|
||||
@@ -139,7 +139,7 @@ public struct From<D: DynamicObject> {
|
||||
self.findPersistentStores = findPersistentStores
|
||||
}
|
||||
|
||||
internal func applyToFetchRequest<U>(_ fetchRequest: NSFetchRequest<U>, context: NSManagedObjectContext, applyAffectedStores: Bool = true) throws {
|
||||
internal func applyToFetchRequest<U>(_ fetchRequest: CoreStoreFetchRequest<U>, context: NSManagedObjectContext, applyAffectedStores: Bool = true) throws {
|
||||
|
||||
fetchRequest.entity = context.parentStack!.entityDescription(for: EntityIdentifier(self.entityClass))!
|
||||
guard applyAffectedStores else {
|
||||
@@ -164,7 +164,7 @@ public struct From<D: DynamicObject> {
|
||||
}
|
||||
}
|
||||
|
||||
internal func applyAffectedStoresForFetchedRequest<U>(_ fetchRequest: NSFetchRequest<U>, context: NSManagedObjectContext) throws {
|
||||
internal func applyAffectedStoresForFetchedRequest<U>(_ fetchRequest: CoreStoreFetchRequest<U>, context: NSManagedObjectContext) throws {
|
||||
|
||||
let stores = self.findPersistentStores(context)
|
||||
fetchRequest.affectedStores = stores
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>6.0.0</string>
|
||||
<string>6.2.1</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
|
||||
@@ -628,7 +628,7 @@ public final class ListMonitor<D: DynamicObject>: Hashable {
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
internal convenience init(dataStack: DataStack, from: From<ObjectType>, sectionBy: SectionBy<ObjectType>?, applyFetchClauses: @escaping (_ fetchRequest: NSFetchRequest<NSManagedObject>) -> Void) {
|
||||
internal convenience init(dataStack: DataStack, from: From<ObjectType>, sectionBy: SectionBy<ObjectType>?, applyFetchClauses: @escaping (_ fetchRequest: CoreStoreFetchRequest<NSManagedObject>) -> Void) {
|
||||
|
||||
self.init(
|
||||
context: dataStack.mainContext,
|
||||
@@ -640,7 +640,7 @@ public final class ListMonitor<D: DynamicObject>: Hashable {
|
||||
)
|
||||
}
|
||||
|
||||
internal convenience init(dataStack: DataStack, from: From<ObjectType>, sectionBy: SectionBy<ObjectType>?, applyFetchClauses: @escaping (_ fetchRequest: NSFetchRequest<NSManagedObject>) -> Void, createAsynchronously: @escaping (ListMonitor<ObjectType>) -> Void) {
|
||||
internal convenience init(dataStack: DataStack, from: From<ObjectType>, sectionBy: SectionBy<ObjectType>?, applyFetchClauses: @escaping (_ fetchRequest: CoreStoreFetchRequest<NSManagedObject>) -> Void, createAsynchronously: @escaping (ListMonitor<ObjectType>) -> Void) {
|
||||
|
||||
self.init(
|
||||
context: dataStack.mainContext,
|
||||
@@ -652,7 +652,7 @@ public final class ListMonitor<D: DynamicObject>: Hashable {
|
||||
)
|
||||
}
|
||||
|
||||
internal convenience init(unsafeTransaction: UnsafeDataTransaction, from: From<ObjectType>, sectionBy: SectionBy<ObjectType>?, applyFetchClauses: @escaping (_ fetchRequest: NSFetchRequest<NSManagedObject>) -> Void) {
|
||||
internal convenience init(unsafeTransaction: UnsafeDataTransaction, from: From<ObjectType>, sectionBy: SectionBy<ObjectType>?, applyFetchClauses: @escaping (_ fetchRequest: CoreStoreFetchRequest<NSManagedObject>) -> Void) {
|
||||
|
||||
self.init(
|
||||
context: unsafeTransaction.context,
|
||||
@@ -664,7 +664,7 @@ public final class ListMonitor<D: DynamicObject>: Hashable {
|
||||
)
|
||||
}
|
||||
|
||||
internal convenience init(unsafeTransaction: UnsafeDataTransaction, from: From<ObjectType>, sectionBy: SectionBy<ObjectType>?, applyFetchClauses: @escaping (_ fetchRequest: NSFetchRequest<NSManagedObject>) -> Void, createAsynchronously: @escaping (ListMonitor<ObjectType>) -> Void) {
|
||||
internal convenience init(unsafeTransaction: UnsafeDataTransaction, from: From<ObjectType>, sectionBy: SectionBy<ObjectType>?, applyFetchClauses: @escaping (_ fetchRequest: CoreStoreFetchRequest<NSManagedObject>) -> Void, createAsynchronously: @escaping (ListMonitor<ObjectType>) -> Void) {
|
||||
|
||||
self.init(
|
||||
context: unsafeTransaction.context,
|
||||
@@ -923,7 +923,7 @@ public final class ListMonitor<D: DynamicObject>: Hashable {
|
||||
cs_setAssociatedRetainedObject(nilValue, forKey: &self.didDeleteSectionKey, inObject: observer)
|
||||
}
|
||||
|
||||
internal func refetch(_ applyFetchClauses: @escaping (_ fetchRequest: NSFetchRequest<NSManagedObject>) -> Void) {
|
||||
internal func refetch(_ applyFetchClauses: @escaping (_ fetchRequest: CoreStoreFetchRequest<NSManagedObject>) -> Void) {
|
||||
|
||||
CoreStore.assert(
|
||||
Thread.isMainThread,
|
||||
@@ -1022,7 +1022,7 @@ public final class ListMonitor<D: DynamicObject>: Hashable {
|
||||
private var observerForWillChangePersistentStore: NotificationObserver!
|
||||
private var observerForDidChangePersistentStore: NotificationObserver!
|
||||
private let transactionQueue: DispatchQueue
|
||||
private var applyFetchClauses: (_ fetchRequest: NSFetchRequest<NSManagedObject>) -> Void
|
||||
private var applyFetchClauses: (_ fetchRequest: CoreStoreFetchRequest<NSManagedObject>) -> Void
|
||||
|
||||
private var isPersistentStoreChanging: Bool = false {
|
||||
|
||||
@@ -1045,9 +1045,9 @@ public final class ListMonitor<D: DynamicObject>: Hashable {
|
||||
}
|
||||
}
|
||||
|
||||
private static func recreateFetchedResultsController(context: NSManagedObjectContext, from: From<ObjectType>, sectionBy: SectionBy<ObjectType>?, applyFetchClauses: @escaping (_ fetchRequest: NSFetchRequest<NSManagedObject>) -> Void) -> (controller: CoreStoreFetchedResultsController, delegate: FetchedResultsControllerDelegate) {
|
||||
private static func recreateFetchedResultsController(context: NSManagedObjectContext, from: From<ObjectType>, sectionBy: SectionBy<ObjectType>?, applyFetchClauses: @escaping (_ fetchRequest: CoreStoreFetchRequest<NSManagedObject>) -> Void) -> (controller: CoreStoreFetchedResultsController, delegate: FetchedResultsControllerDelegate) {
|
||||
|
||||
let fetchRequest = NSFetchRequest<NSManagedObject>()
|
||||
let fetchRequest = CoreStoreFetchRequest<NSManagedObject>()
|
||||
fetchRequest.fetchLimit = 0
|
||||
fetchRequest.resultType = .managedObjectResultType
|
||||
fetchRequest.fetchBatchSize = 20
|
||||
@@ -1071,7 +1071,7 @@ public final class ListMonitor<D: DynamicObject>: Hashable {
|
||||
private let from: From<ObjectType>
|
||||
private let sectionBy: SectionBy<ObjectType>?
|
||||
|
||||
private init(context: NSManagedObjectContext, transactionQueue: DispatchQueue, from: From<ObjectType>, sectionBy: SectionBy<ObjectType>?, applyFetchClauses: @escaping (_ fetchRequest: NSFetchRequest<NSManagedObject>) -> Void, createAsynchronously: ((ListMonitor<ObjectType>) -> Void)?) {
|
||||
private init(context: NSManagedObjectContext, transactionQueue: DispatchQueue, from: From<ObjectType>, sectionBy: SectionBy<ObjectType>?, applyFetchClauses: @escaping (_ fetchRequest: CoreStoreFetchRequest<NSManagedObject>) -> Void, createAsynchronously: ((ListMonitor<ObjectType>) -> Void)?) {
|
||||
|
||||
self.isSectioned = (sectionBy != nil)
|
||||
self.from = from
|
||||
@@ -1114,7 +1114,7 @@ public final class ListMonitor<D: DynamicObject>: Hashable {
|
||||
self.isPersistentStoreChanging = true
|
||||
|
||||
guard let removedStores = (note.userInfo?[NSRemovedPersistentStoresKey] as? [NSPersistentStore]).flatMap(Set.init),
|
||||
!Set(self.fetchedResultsController.fetchRequest.affectedStores ?? []).intersection(removedStores).isEmpty else {
|
||||
!Set(self.fetchedResultsController.typedFetchRequest.safeAffectedStores() ?? []).intersection(removedStores).isEmpty else {
|
||||
|
||||
return
|
||||
}
|
||||
@@ -1135,7 +1135,7 @@ public final class ListMonitor<D: DynamicObject>: Hashable {
|
||||
|
||||
if !self.isPendingRefetch {
|
||||
|
||||
let previousStores = Set(self.fetchedResultsController.fetchRequest.affectedStores ?? [])
|
||||
let previousStores = Set(self.fetchedResultsController.typedFetchRequest.safeAffectedStores() ?? [])
|
||||
let currentStores = previousStores
|
||||
.subtracting(note.userInfo?[NSRemovedPersistentStoresKey] as? [NSPersistentStore] ?? [])
|
||||
.union(note.userInfo?[NSAddedPersistentStoresKey] as? [NSPersistentStore] ?? [])
|
||||
|
||||
@@ -205,12 +205,12 @@ fileprivate func createFRC<D: NSManagedObject>(fromContext context: NSManagedObj
|
||||
|
||||
let controller = CoreStoreFetchedResultsController(
|
||||
context: context,
|
||||
fetchRequest: NSFetchRequest<NSManagedObject>(),
|
||||
fetchRequest: CoreStoreFetchRequest(),
|
||||
from: from,
|
||||
sectionBy: sectionBy,
|
||||
applyFetchClauses: { (fetchRequest) in
|
||||
|
||||
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest as! NSFetchRequest<NSFetchRequestResult>) }
|
||||
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
|
||||
|
||||
CoreStore.assert(
|
||||
fetchRequest.sortDescriptors?.isEmpty == false,
|
||||
|
||||
@@ -72,12 +72,12 @@ fileprivate func createFRC(fromContext context: NSManagedObjectContext, from: CS
|
||||
|
||||
let controller = CoreStoreFetchedResultsController(
|
||||
context: context,
|
||||
fetchRequest: NSFetchRequest<NSManagedObject>(),
|
||||
fetchRequest: CoreStoreFetchRequest(),
|
||||
from: from.bridgeToSwift,
|
||||
sectionBy: sectionBy?.bridgeToSwift,
|
||||
applyFetchClauses: { (fetchRequest) in
|
||||
|
||||
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest as! NSFetchRequest<NSFetchRequestResult>) }
|
||||
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
|
||||
|
||||
CoreStore.assert(
|
||||
fetchRequest.sortDescriptors?.isEmpty == false,
|
||||
|
||||
@@ -36,12 +36,12 @@ extension NSManagedObjectContext {
|
||||
@nonobjc
|
||||
internal func fetchOne(_ from: CSFrom, _ fetchClauses: [CSFetchClause]) throws -> NSManagedObject? {
|
||||
|
||||
let fetchRequest = NSFetchRequest<NSManagedObject>()
|
||||
let fetchRequest = CoreStoreFetchRequest<NSManagedObject>()
|
||||
try from.bridgeToSwift.applyToFetchRequest(fetchRequest, context: self)
|
||||
|
||||
fetchRequest.fetchLimit = 1
|
||||
fetchRequest.resultType = .managedObjectResultType
|
||||
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest as! NSFetchRequest<NSFetchRequestResult>) }
|
||||
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
|
||||
|
||||
return try self.fetchOne(fetchRequest)
|
||||
}
|
||||
@@ -49,12 +49,12 @@ extension NSManagedObjectContext {
|
||||
@nonobjc
|
||||
internal func fetchAll<T: NSManagedObject>(_ from: CSFrom, _ fetchClauses: [CSFetchClause]) throws -> [T] {
|
||||
|
||||
let fetchRequest = NSFetchRequest<T>()
|
||||
let fetchRequest = CoreStoreFetchRequest<T>()
|
||||
try from.bridgeToSwift.applyToFetchRequest(fetchRequest, context: self)
|
||||
|
||||
fetchRequest.fetchLimit = 0
|
||||
fetchRequest.resultType = .managedObjectResultType
|
||||
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest as! NSFetchRequest<NSFetchRequestResult>) }
|
||||
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
|
||||
|
||||
return try self.fetchAll(fetchRequest)
|
||||
}
|
||||
@@ -62,11 +62,11 @@ extension NSManagedObjectContext {
|
||||
@nonobjc
|
||||
internal func fetchCount(_ from: CSFrom, _ fetchClauses: [CSFetchClause]) throws -> Int {
|
||||
|
||||
let fetchRequest = NSFetchRequest<NSNumber>()
|
||||
let fetchRequest = CoreStoreFetchRequest<NSNumber>()
|
||||
try from.bridgeToSwift.applyToFetchRequest(fetchRequest, context: self)
|
||||
|
||||
fetchRequest.resultType = .countResultType
|
||||
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest as! NSFetchRequest<NSFetchRequestResult>) }
|
||||
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
|
||||
|
||||
return try self.fetchCount(fetchRequest)
|
||||
}
|
||||
@@ -74,12 +74,12 @@ extension NSManagedObjectContext {
|
||||
@nonobjc
|
||||
internal func fetchObjectID(_ from: CSFrom, _ fetchClauses: [CSFetchClause]) throws -> NSManagedObjectID? {
|
||||
|
||||
let fetchRequest = NSFetchRequest<NSManagedObjectID>()
|
||||
let fetchRequest = CoreStoreFetchRequest<NSManagedObjectID>()
|
||||
try from.bridgeToSwift.applyToFetchRequest(fetchRequest, context: self)
|
||||
|
||||
fetchRequest.fetchLimit = 1
|
||||
fetchRequest.resultType = .managedObjectIDResultType
|
||||
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest as! NSFetchRequest<NSFetchRequestResult>) }
|
||||
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
|
||||
|
||||
return try self.fetchObjectID(fetchRequest)
|
||||
}
|
||||
@@ -87,12 +87,12 @@ extension NSManagedObjectContext {
|
||||
@nonobjc
|
||||
internal func fetchObjectIDs(_ from: CSFrom, _ fetchClauses: [CSFetchClause]) throws -> [NSManagedObjectID] {
|
||||
|
||||
let fetchRequest = NSFetchRequest<NSManagedObjectID>()
|
||||
let fetchRequest = CoreStoreFetchRequest<NSManagedObjectID>()
|
||||
try from.bridgeToSwift.applyToFetchRequest(fetchRequest, context: self)
|
||||
|
||||
fetchRequest.fetchLimit = 0
|
||||
fetchRequest.resultType = .managedObjectIDResultType
|
||||
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest as! NSFetchRequest<NSFetchRequestResult>) }
|
||||
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
|
||||
|
||||
return try self.fetchObjectIDs(fetchRequest)
|
||||
}
|
||||
@@ -100,14 +100,14 @@ extension NSManagedObjectContext {
|
||||
@nonobjc
|
||||
internal func deleteAll(_ from: CSFrom, _ deleteClauses: [CSDeleteClause]) throws -> Int {
|
||||
|
||||
let fetchRequest = NSFetchRequest<NSManagedObject>()
|
||||
let fetchRequest = CoreStoreFetchRequest<NSManagedObject>()
|
||||
try from.bridgeToSwift.applyToFetchRequest(fetchRequest, context: self)
|
||||
|
||||
fetchRequest.fetchLimit = 0
|
||||
fetchRequest.resultType = .managedObjectResultType
|
||||
fetchRequest.returnsObjectsAsFaults = true
|
||||
fetchRequest.includesPropertyValues = false
|
||||
deleteClauses.forEach { $0.applyToFetchRequest(fetchRequest as! NSFetchRequest<NSFetchRequestResult>) }
|
||||
deleteClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
|
||||
|
||||
return try self.deleteAll(fetchRequest)
|
||||
}
|
||||
@@ -115,13 +115,13 @@ extension NSManagedObjectContext {
|
||||
@nonobjc
|
||||
internal func queryValue(_ from: CSFrom, _ selectClause: CSSelect, _ queryClauses: [CSQueryClause]) throws -> Any? {
|
||||
|
||||
let fetchRequest = NSFetchRequest<NSDictionary>()
|
||||
let fetchRequest = CoreStoreFetchRequest<NSDictionary>()
|
||||
try from.bridgeToSwift.applyToFetchRequest(fetchRequest, context: self)
|
||||
|
||||
fetchRequest.fetchLimit = 0
|
||||
|
||||
selectClause.applyToFetchRequest(fetchRequest as! NSFetchRequest<NSFetchRequestResult>)
|
||||
queryClauses.forEach { $0.applyToFetchRequest(fetchRequest as! NSFetchRequest<NSFetchRequestResult>) }
|
||||
selectClause.applyToFetchRequest(fetchRequest)
|
||||
queryClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
|
||||
|
||||
return try self.queryValue(selectClause.selectTerms, fetchRequest: fetchRequest)
|
||||
}
|
||||
@@ -129,13 +129,13 @@ extension NSManagedObjectContext {
|
||||
@nonobjc
|
||||
internal func queryAttributes(_ from: CSFrom, _ selectClause: CSSelect, _ queryClauses: [CSQueryClause]) throws -> [[String: Any]] {
|
||||
|
||||
let fetchRequest = NSFetchRequest<NSDictionary>()
|
||||
let fetchRequest = CoreStoreFetchRequest<NSDictionary>()
|
||||
try from.bridgeToSwift.applyToFetchRequest(fetchRequest, context: self)
|
||||
|
||||
fetchRequest.fetchLimit = 0
|
||||
|
||||
selectClause.applyToFetchRequest(fetchRequest as! NSFetchRequest<NSFetchRequestResult>)
|
||||
queryClauses.forEach { $0.applyToFetchRequest(fetchRequest as! NSFetchRequest<NSFetchRequestResult>) }
|
||||
selectClause.applyToFetchRequest(fetchRequest)
|
||||
queryClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
|
||||
|
||||
return try self.queryAttributes(fetchRequest)
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ extension NSManagedObjectContext: FetchableSource, QueryableSource {
|
||||
@nonobjc
|
||||
public func fetchOne<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) throws -> D? {
|
||||
|
||||
let fetchRequest = NSFetchRequest<NSManagedObject>()
|
||||
let fetchRequest = CoreStoreFetchRequest<NSManagedObject>()
|
||||
try from.applyToFetchRequest(fetchRequest, context: self)
|
||||
|
||||
fetchRequest.fetchLimit = 1
|
||||
@@ -134,7 +134,7 @@ extension NSManagedObjectContext: FetchableSource, QueryableSource {
|
||||
@nonobjc
|
||||
public func fetchAll<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) throws -> [D] {
|
||||
|
||||
let fetchRequest = NSFetchRequest<NSManagedObject>()
|
||||
let fetchRequest = CoreStoreFetchRequest<NSManagedObject>()
|
||||
try from.applyToFetchRequest(fetchRequest, context: self)
|
||||
|
||||
fetchRequest.fetchLimit = 0
|
||||
@@ -160,7 +160,7 @@ extension NSManagedObjectContext: FetchableSource, QueryableSource {
|
||||
@nonobjc
|
||||
public func fetchCount<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) throws -> Int {
|
||||
|
||||
let fetchRequest = NSFetchRequest<NSNumber>()
|
||||
let fetchRequest = CoreStoreFetchRequest<NSNumber>()
|
||||
try from.applyToFetchRequest(fetchRequest, context: self)
|
||||
|
||||
fetchRequest.resultType = .countResultType
|
||||
@@ -184,7 +184,7 @@ extension NSManagedObjectContext: FetchableSource, QueryableSource {
|
||||
@nonobjc
|
||||
public func fetchObjectID<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) throws -> NSManagedObjectID? {
|
||||
|
||||
let fetchRequest = NSFetchRequest<NSManagedObjectID>()
|
||||
let fetchRequest = CoreStoreFetchRequest<NSManagedObjectID>()
|
||||
try from.applyToFetchRequest(fetchRequest, context: self)
|
||||
|
||||
fetchRequest.fetchLimit = 1
|
||||
@@ -209,7 +209,7 @@ extension NSManagedObjectContext: FetchableSource, QueryableSource {
|
||||
@nonobjc
|
||||
public func fetchObjectIDs<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) throws -> [NSManagedObjectID] {
|
||||
|
||||
let fetchRequest = NSFetchRequest<NSManagedObjectID>()
|
||||
let fetchRequest = CoreStoreFetchRequest<NSManagedObjectID>()
|
||||
try from.applyToFetchRequest(fetchRequest, context: self)
|
||||
|
||||
fetchRequest.fetchLimit = 0
|
||||
@@ -226,7 +226,7 @@ extension NSManagedObjectContext: FetchableSource, QueryableSource {
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
internal func fetchObjectIDs(_ fetchRequest: NSFetchRequest<NSManagedObjectID>) throws -> [NSManagedObjectID] {
|
||||
internal func fetchObjectIDs(_ fetchRequest: CoreStoreFetchRequest<NSManagedObjectID>) throws -> [NSManagedObjectID] {
|
||||
|
||||
var fetchResults: [NSManagedObjectID]?
|
||||
var fetchError: Error?
|
||||
@@ -234,7 +234,7 @@ extension NSManagedObjectContext: FetchableSource, QueryableSource {
|
||||
|
||||
do {
|
||||
|
||||
fetchResults = try self.fetch(fetchRequest)
|
||||
fetchResults = try self.fetch(fetchRequest.dynamicCast())
|
||||
}
|
||||
catch {
|
||||
|
||||
@@ -265,12 +265,12 @@ extension NSManagedObjectContext: FetchableSource, QueryableSource {
|
||||
@nonobjc
|
||||
public func queryValue<D, U: QueryableAttributeType>(_ from: From<D>, _ selectClause: Select<D, U>, _ queryClauses: [QueryClause]) throws -> U? {
|
||||
|
||||
let fetchRequest = NSFetchRequest<NSDictionary>()
|
||||
let fetchRequest = CoreStoreFetchRequest<NSDictionary>()
|
||||
try from.applyToFetchRequest(fetchRequest, context: self)
|
||||
|
||||
fetchRequest.fetchLimit = 0
|
||||
|
||||
selectClause.applyToFetchRequest(fetchRequest)
|
||||
selectClause.applyToFetchRequest(fetchRequest.staticCast())
|
||||
queryClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
|
||||
|
||||
return try self.queryValue(selectClause.selectTerms, fetchRequest: fetchRequest)
|
||||
@@ -291,12 +291,12 @@ extension NSManagedObjectContext: FetchableSource, QueryableSource {
|
||||
@nonobjc
|
||||
public func queryAttributes<D>(_ from: From<D>, _ selectClause: Select<D, NSDictionary>, _ queryClauses: [QueryClause]) throws -> [[String: Any]] {
|
||||
|
||||
let fetchRequest = NSFetchRequest<NSDictionary>()
|
||||
let fetchRequest = CoreStoreFetchRequest<NSDictionary>()
|
||||
try from.applyToFetchRequest(fetchRequest, context: self)
|
||||
|
||||
fetchRequest.fetchLimit = 0
|
||||
|
||||
selectClause.applyToFetchRequest(fetchRequest)
|
||||
selectClause.applyToFetchRequest(fetchRequest.staticCast())
|
||||
queryClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
|
||||
|
||||
return try self.queryAttributes(fetchRequest)
|
||||
@@ -322,7 +322,7 @@ extension NSManagedObjectContext: FetchableSource, QueryableSource {
|
||||
@nonobjc
|
||||
internal func deleteAll<D>(_ from: From<D>, _ deleteClauses: [FetchClause]) throws -> Int {
|
||||
|
||||
let fetchRequest = NSFetchRequest<NSManagedObject>()
|
||||
let fetchRequest = CoreStoreFetchRequest<NSManagedObject>()
|
||||
try from.applyToFetchRequest(fetchRequest, context: self)
|
||||
|
||||
fetchRequest.fetchLimit = 0
|
||||
@@ -352,7 +352,7 @@ extension NSManagedObjectContext {
|
||||
// MARK: Fetching
|
||||
|
||||
@nonobjc
|
||||
internal func fetchOne<D: NSManagedObject>(_ fetchRequest: NSFetchRequest<D>) throws -> D? {
|
||||
internal func fetchOne<D: NSManagedObject>(_ fetchRequest: CoreStoreFetchRequest<D>) throws -> D? {
|
||||
|
||||
var fetchResults: [D]?
|
||||
var fetchError: Error?
|
||||
@@ -360,7 +360,7 @@ extension NSManagedObjectContext {
|
||||
|
||||
do {
|
||||
|
||||
fetchResults = try self.fetch(fetchRequest)
|
||||
fetchResults = try self.fetch(fetchRequest.staticCast())
|
||||
}
|
||||
catch {
|
||||
|
||||
@@ -380,7 +380,7 @@ extension NSManagedObjectContext {
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
internal func fetchAll<D: NSManagedObject>(_ fetchRequest: NSFetchRequest<D>) throws -> [D] {
|
||||
internal func fetchAll<D: NSManagedObject>(_ fetchRequest: CoreStoreFetchRequest<D>) throws -> [D] {
|
||||
|
||||
var fetchResults: [D]?
|
||||
var fetchError: Error?
|
||||
@@ -388,7 +388,7 @@ extension NSManagedObjectContext {
|
||||
|
||||
do {
|
||||
|
||||
fetchResults = try self.fetch(fetchRequest)
|
||||
fetchResults = try self.fetch(fetchRequest.staticCast())
|
||||
}
|
||||
catch {
|
||||
|
||||
@@ -408,7 +408,7 @@ extension NSManagedObjectContext {
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
internal func fetchCount(_ fetchRequest: NSFetchRequest<NSNumber>) throws -> Int {
|
||||
internal func fetchCount(_ fetchRequest: CoreStoreFetchRequest<NSNumber>) throws -> Int {
|
||||
|
||||
var count = 0
|
||||
var countError: Error?
|
||||
@@ -416,7 +416,7 @@ extension NSManagedObjectContext {
|
||||
|
||||
do {
|
||||
|
||||
count = try self.count(for: fetchRequest)
|
||||
count = try self.count(for: fetchRequest.staticCast())
|
||||
}
|
||||
catch {
|
||||
|
||||
@@ -436,7 +436,7 @@ extension NSManagedObjectContext {
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
internal func fetchObjectID(_ fetchRequest: NSFetchRequest<NSManagedObjectID>) throws -> NSManagedObjectID? {
|
||||
internal func fetchObjectID(_ fetchRequest: CoreStoreFetchRequest<NSManagedObjectID>) throws -> NSManagedObjectID? {
|
||||
|
||||
var fetchResults: [NSManagedObjectID]?
|
||||
var fetchError: Error?
|
||||
@@ -444,7 +444,7 @@ extension NSManagedObjectContext {
|
||||
|
||||
do {
|
||||
|
||||
fetchResults = try self.fetch(fetchRequest)
|
||||
fetchResults = try self.fetch(fetchRequest.staticCast())
|
||||
}
|
||||
catch {
|
||||
|
||||
@@ -467,7 +467,7 @@ extension NSManagedObjectContext {
|
||||
// MARK: Querying
|
||||
|
||||
@nonobjc
|
||||
internal func queryValue<D, U: QueryableAttributeType>(_ selectTerms: [SelectTerm<D>], fetchRequest: NSFetchRequest<NSDictionary>) throws -> U? {
|
||||
internal func queryValue<D, U: QueryableAttributeType>(_ selectTerms: [SelectTerm<D>], fetchRequest: CoreStoreFetchRequest<NSDictionary>) throws -> U? {
|
||||
|
||||
var fetchResults: [Any]?
|
||||
var fetchError: Error?
|
||||
@@ -475,7 +475,7 @@ extension NSManagedObjectContext {
|
||||
|
||||
do {
|
||||
|
||||
fetchResults = try self.fetch(fetchRequest)
|
||||
fetchResults = try self.fetch(fetchRequest.staticCast())
|
||||
}
|
||||
catch {
|
||||
|
||||
@@ -500,7 +500,7 @@ extension NSManagedObjectContext {
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
internal func queryValue<D>(_ selectTerms: [SelectTerm<D>], fetchRequest: NSFetchRequest<NSDictionary>) throws -> Any? {
|
||||
internal func queryValue<D>(_ selectTerms: [SelectTerm<D>], fetchRequest: CoreStoreFetchRequest<NSDictionary>) throws -> Any? {
|
||||
|
||||
var fetchResults: [Any]?
|
||||
var fetchError: Error?
|
||||
@@ -508,7 +508,7 @@ extension NSManagedObjectContext {
|
||||
|
||||
do {
|
||||
|
||||
fetchResults = try self.fetch(fetchRequest)
|
||||
fetchResults = try self.fetch(fetchRequest.staticCast())
|
||||
}
|
||||
catch {
|
||||
|
||||
@@ -533,7 +533,7 @@ extension NSManagedObjectContext {
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
internal func queryAttributes(_ fetchRequest: NSFetchRequest<NSDictionary>) throws -> [[String: Any]] {
|
||||
internal func queryAttributes(_ fetchRequest: CoreStoreFetchRequest<NSDictionary>) throws -> [[String: Any]] {
|
||||
|
||||
var fetchResults: [Any]?
|
||||
var fetchError: Error?
|
||||
@@ -541,7 +541,7 @@ extension NSManagedObjectContext {
|
||||
|
||||
do {
|
||||
|
||||
fetchResults = try self.fetch(fetchRequest)
|
||||
fetchResults = try self.fetch(fetchRequest.staticCast())
|
||||
}
|
||||
catch {
|
||||
|
||||
@@ -564,7 +564,7 @@ extension NSManagedObjectContext {
|
||||
// MARK: Deleting
|
||||
|
||||
@nonobjc
|
||||
internal func deleteAll<D: NSManagedObject>(_ fetchRequest: NSFetchRequest<D>) throws -> Int {
|
||||
internal func deleteAll<D: NSManagedObject>(_ fetchRequest: CoreStoreFetchRequest<D>) throws -> Int {
|
||||
|
||||
var numberOfDeletedObjects: Int?
|
||||
var fetchError: Error?
|
||||
@@ -574,7 +574,7 @@ extension NSManagedObjectContext {
|
||||
|
||||
do {
|
||||
|
||||
let fetchResults = try self.fetch(fetchRequest)
|
||||
let fetchResults = try self.fetch(fetchRequest.staticCast())
|
||||
for object in fetchResults {
|
||||
|
||||
self.delete(object)
|
||||
|
||||
@@ -261,7 +261,7 @@ public final class ObjectMonitor<D: DynamicObject>: Equatable {
|
||||
private init(context: NSManagedObjectContext, object: ObjectType) {
|
||||
|
||||
let objectID = object.cs_id()
|
||||
let fetchRequest = NSFetchRequest<NSManagedObject>()
|
||||
let fetchRequest = CoreStoreFetchRequest<NSManagedObject>()
|
||||
fetchRequest.entity = objectID.entity
|
||||
fetchRequest.fetchLimit = 0
|
||||
fetchRequest.resultType = .managedObjectResultType
|
||||
|
||||
@@ -29,11 +29,24 @@ import CoreData
|
||||
|
||||
// MARK: - ~
|
||||
|
||||
/**
|
||||
Connects multiple `DynamicKeyPath`s to create a type-safe chain usable in query/fetch expressions
|
||||
```
|
||||
let owner = CoreStore.fetchOne(
|
||||
From<Pet>().where(
|
||||
(\.master ~ \.name) == "John"
|
||||
)
|
||||
)
|
||||
```
|
||||
*/
|
||||
infix operator ~ : AdditionPrecedence
|
||||
|
||||
|
||||
// MARK: - WhereExpressionTrait
|
||||
|
||||
/**
|
||||
Used only for `Where.Expression` type constraints. Currently supports `SingleTarget` and `CollectionTarget`.
|
||||
*/
|
||||
public protocol WhereExpressionTrait {}
|
||||
|
||||
|
||||
@@ -43,8 +56,20 @@ extension Where {
|
||||
|
||||
// MARK: - Expression
|
||||
|
||||
/**
|
||||
Type-safe keyPath chain usable in query/fetch expressions.
|
||||
```
|
||||
let expression: Where<Pet>.Expression = (\.master ~ \.name)
|
||||
let owner = CoreStore.fetchOne(
|
||||
From<Pet>().where(expression == "John")
|
||||
)
|
||||
```
|
||||
*/
|
||||
public struct Expression<T: WhereExpressionTrait, V>: CustomStringConvertible, DynamicKeyPath {
|
||||
|
||||
/**
|
||||
Currently supports `SingleTarget` and `CollectionTarget`.
|
||||
*/
|
||||
public typealias Trait = T
|
||||
|
||||
|
||||
@@ -83,10 +108,17 @@ extension Where {
|
||||
|
||||
// MARK: - SingleTarget
|
||||
|
||||
/**
|
||||
Used only for `Where.Expression` type constraints. Specifies that this `Where.Expression` type pertains to an attribute property expression.
|
||||
*/
|
||||
public enum SingleTarget: WhereExpressionTrait {}
|
||||
|
||||
|
||||
// MARK: - CollectionTarget
|
||||
|
||||
/**
|
||||
Used only for `Where.Expression` type constraints. Specifies that this `Where.Expression` type pertains to a to-many relationship expression.
|
||||
*/
|
||||
public enum CollectionTarget: WhereExpressionTrait {}
|
||||
}
|
||||
|
||||
@@ -95,47 +127,101 @@ extension Where {
|
||||
|
||||
// MARK: ~ where D: NSManagedObject
|
||||
|
||||
/**
|
||||
Connects multiple `DynamicKeyPath`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: NSManagedObject, O: NSManagedObject, V: AllowedObjectiveCKeyPathValue>(_ lhs: KeyPath<D, O>, _ rhs: KeyPath<O, V>) -> Where<D>.Expression<Where<D>.SingleTarget, V> {
|
||||
|
||||
return .init(lhs.cs_keyPathString, rhs.cs_keyPathString)
|
||||
}
|
||||
|
||||
public func ~<D: NSManagedObject, O: NSManagedObject, V: AllowedObjectiveCKeyPathValue>(_ lhs: KeyPath<D, O?>, _ rhs: KeyPath<O, V>) -> Where<D>.Expression<Where<D>.SingleTarget, V> {
|
||||
/**
|
||||
Connects multiple `DynamicKeyPath`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: NSManagedObject, O: NSManagedObject, V: AllowedObjectiveCKeyPathValue>(_ lhs: KeyPath<D, O?>, _ rhs: KeyPath<O, V>) -> Where<D>.Expression<Where<D>.SingleTarget, V> {
|
||||
|
||||
return .init(lhs.cs_keyPathString, rhs.cs_keyPathString)
|
||||
}
|
||||
|
||||
public func ~<D: NSManagedObject, O: NSManagedObject, V: AllowedObjectiveCCollectionKeyPathValue>(_ lhs: KeyPath<D, O>, _ rhs: KeyPath<O, V>) -> Where<D>.Expression<Where<D>.CollectionTarget, V> {
|
||||
/**
|
||||
Connects multiple `DynamicKeyPath`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> {
|
||||
|
||||
return .init(lhs.cs_keyPathString, rhs.cs_keyPathString)
|
||||
}
|
||||
|
||||
public func ~<D: NSManagedObject, O: NSManagedObject, V: AllowedObjectiveCCollectionKeyPathValue>(_ lhs: KeyPath<D, O?>, _ rhs: KeyPath<O, V>) -> Where<D>.Expression<Where<D>.CollectionTarget, V> {
|
||||
/**
|
||||
Connects multiple `DynamicKeyPath`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> {
|
||||
|
||||
return .init(lhs.cs_keyPathString, rhs.cs_keyPathString)
|
||||
}
|
||||
|
||||
public func ~<D: NSManagedObject, O: NSManagedObject, T, V: AllowedObjectiveCKeyPathValue>(_ lhs: Where<D>.Expression<T, O>, _ rhs: KeyPath<O, V>) -> Where<D>.Expression<T, V> {
|
||||
/**
|
||||
Connects multiple `DynamicKeyPath`s to create a type-safe chain usable in query/fetch expressions
|
||||
```
|
||||
let johnsSonInLaw = CoreStore.fetchOne(From<Person>().where((\.spouse ~ \.father ~ \.name) == "John"))
|
||||
```
|
||||
*/
|
||||
public func ~ <D: NSManagedObject, O: NSManagedObject, T, V: AllowedObjectiveCKeyPathValue>(_ lhs: Where<D>.Expression<T, O>, _ rhs: KeyPath<O, V>) -> Where<D>.Expression<T, V> {
|
||||
|
||||
return .init(lhs.cs_keyPathString, rhs.cs_keyPathString)
|
||||
}
|
||||
|
||||
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> {
|
||||
/**
|
||||
Connects multiple `DynamicKeyPath`s to create a type-safe chain usable in query/fetch expressions
|
||||
```
|
||||
let johnsSonInLaw = CoreStore.fetchOne(From<Person>().where((\.spouse ~ \.father ~ \.name) == "John"))
|
||||
```
|
||||
*/
|
||||
public func ~ <D: NSManagedObject, O: NSManagedObject, T, V: AllowedObjectiveCKeyPathValue>(_ lhs: Where<D>.Expression<T, O?>, _ rhs: KeyPath<O, V>) -> Where<D>.Expression<T, V> {
|
||||
|
||||
return .init(lhs.cs_keyPathString, rhs.cs_keyPathString)
|
||||
}
|
||||
|
||||
public func ~<D: NSManagedObject, O: NSManagedObject, T, V: AllowedObjectiveCKeyPathValue>(_ lhs: Where<D>.Expression<T, O?>, _ rhs: KeyPath<O, V>) -> Where<D>.Expression<T, V> {
|
||||
/**
|
||||
Connects multiple `DynamicKeyPath`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> {
|
||||
|
||||
return .init(lhs.cs_keyPathString, rhs.cs_keyPathString)
|
||||
}
|
||||
|
||||
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> {
|
||||
/**
|
||||
Connects multiple `DynamicKeyPath`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> {
|
||||
|
||||
return .init(lhs.cs_keyPathString, rhs.cs_keyPathString)
|
||||
}
|
||||
|
||||
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> {
|
||||
/**
|
||||
Connects multiple `DynamicKeyPath`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> {
|
||||
|
||||
return .init(lhs.cs_keyPathString, rhs.cs_keyPathString)
|
||||
}
|
||||
@@ -143,7 +229,13 @@ public func ~<D: NSManagedObject, O: NSManagedObject, T, C: AllowedObjectiveCCol
|
||||
|
||||
// MARK: - ~ where D: CoreStoreObject
|
||||
|
||||
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 {
|
||||
/**
|
||||
Connects multiple `DynamicKeyPath`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 {
|
||||
|
||||
return .init(
|
||||
D.meta[keyPath: lhs].cs_keyPathString,
|
||||
@@ -151,7 +243,41 @@ public func ~<D: CoreStoreObject, O: CoreStoreObject, K: AllowedCoreStoreObjectK
|
||||
)
|
||||
}
|
||||
|
||||
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 {
|
||||
/**
|
||||
Connects multiple `DynamicKeyPath`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 {
|
||||
|
||||
return .init(
|
||||
lhs.cs_keyPathString,
|
||||
O.meta[keyPath: rhs].cs_keyPathString
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
Connects multiple `DynamicKeyPath`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 {
|
||||
|
||||
return .init(
|
||||
lhs.cs_keyPathString,
|
||||
O.meta[keyPath: rhs].cs_keyPathString
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
Connects multiple `DynamicKeyPath`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 {
|
||||
|
||||
return .init(
|
||||
D.meta[keyPath: lhs].cs_keyPathString,
|
||||
@@ -159,7 +285,13 @@ public func ~<D: CoreStoreObject, O: CoreStoreObject, K: AllowedCoreStoreObjectC
|
||||
)
|
||||
}
|
||||
|
||||
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 {
|
||||
/**
|
||||
Connects multiple `DynamicKeyPath`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 {
|
||||
|
||||
return .init(
|
||||
lhs.cs_keyPathString,
|
||||
@@ -167,7 +299,13 @@ public func ~<D: CoreStoreObject, O: CoreStoreObject, T, K: AllowedCoreStoreObje
|
||||
)
|
||||
}
|
||||
|
||||
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 {
|
||||
/**
|
||||
Connects multiple `DynamicKeyPath`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 {
|
||||
|
||||
return .init(
|
||||
lhs.cs_keyPathString,
|
||||
@@ -175,23 +313,13 @@ public func ~<D: CoreStoreObject, O: CoreStoreObject, T, K: AllowedCoreStoreObje
|
||||
)
|
||||
}
|
||||
|
||||
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 {
|
||||
|
||||
return .init(
|
||||
lhs.cs_keyPathString,
|
||||
O.meta[keyPath: rhs].cs_keyPathString
|
||||
)
|
||||
}
|
||||
|
||||
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 {
|
||||
|
||||
return .init(
|
||||
lhs.cs_keyPathString,
|
||||
O.meta[keyPath: rhs].cs_keyPathString
|
||||
)
|
||||
}
|
||||
|
||||
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 {
|
||||
/**
|
||||
Connects multiple `DynamicKeyPath`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 {
|
||||
|
||||
return .init(
|
||||
lhs.cs_keyPathString,
|
||||
@@ -202,16 +330,34 @@ public func ~<D: CoreStoreObject, O: CoreStoreObject, T, KC: AllowedCoreStoreObj
|
||||
|
||||
// MARK: - Where.Expression where V: QueryableAttributeType
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if an expression is equal to a value
|
||||
```
|
||||
let dog = CoreStore.fetchOne(From<Dog>().where((\.master ~ \.name) == "John"))
|
||||
```
|
||||
*/
|
||||
public func == <D, T, V: QueryableAttributeType>(_ lhs: Where<D>.Expression<T, V>, _ rhs: V) -> Where<D> {
|
||||
|
||||
return Where<D>(lhs.cs_keyPathString, isEqualTo: rhs)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if an expression is not equal to a value
|
||||
```
|
||||
let dog = CoreStore.fetchOne(From<Dog>().where((\.master ~ \.name) != "John"))
|
||||
```
|
||||
*/
|
||||
public func != <D, T, V: QueryableAttributeType>(_ lhs: Where<D>.Expression<T, V>, _ rhs: V) -> Where<D> {
|
||||
|
||||
return !Where<D>(lhs.cs_keyPathString, isEqualTo: rhs)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by checking if a sequence contains a value
|
||||
```
|
||||
let dog = CoreStore.fetchOne(From<Dog>().where(["John", "Joe"] ~= (\.master ~ \.name))
|
||||
```
|
||||
*/
|
||||
public func ~= <D, T, V: QueryableAttributeType, S: Sequence>(_ sequence: S, _ expression: Where<D>.Expression<T, V>) -> Where<D> where S.Iterator.Element == V {
|
||||
|
||||
return Where<D>(expression.cs_keyPathString, isMemberOf: sequence)
|
||||
@@ -220,21 +366,45 @@ public func ~= <D, T, V: QueryableAttributeType, S: Sequence>(_ sequence: S, _ e
|
||||
|
||||
// MARK: - Where.Expression where V: QueryableAttributeType & Comparable
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if an expression is less than a value
|
||||
```
|
||||
let lonelyDog = CoreStore.fetchOne(From<Dog>().where((\.master ~ \.pets).count() < 2))
|
||||
```
|
||||
*/
|
||||
public func < <D, T, V: QueryableAttributeType & Comparable>(_ lhs: Where<D>.Expression<T, V>, _ rhs: V) -> Where<D> {
|
||||
|
||||
return Where<D>(expression: lhs, function: "<", operand: rhs)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if an expression is less than or equal to a value
|
||||
```
|
||||
let lonelyDog = CoreStore.fetchOne(From<Dog>().where((\.master ~ \.pets).count() <= 1)
|
||||
```
|
||||
*/
|
||||
public func <= <D, T, V: QueryableAttributeType & Comparable>(_ lhs: Where<D>.Expression<T, V>, _ rhs: V) -> Where<D> {
|
||||
|
||||
return Where<D>(expression: lhs, function: "<=", operand: rhs)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if an expression is greater than a value
|
||||
```
|
||||
let happyDog = CoreStore.fetchOne(From<Dog>().where((\.master ~ \.pets).count() > 1)
|
||||
```
|
||||
*/
|
||||
public func > <D, T, V: QueryableAttributeType & Comparable>(_ lhs: Where<D>.Expression<T, V>, _ rhs: V) -> Where<D> {
|
||||
|
||||
return Where<D>(expression: lhs, function: ">", operand: rhs)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if an expression is greater than or equal to a value
|
||||
```
|
||||
let happyDog = CoreStore.fetchOne(From<Dog>().where((\.master ~ \.pets).count() >= 2)
|
||||
```
|
||||
*/
|
||||
public func >= <D, T, V: QueryableAttributeType & Comparable>(_ lhs: Where<D>.Expression<T, V>, _ rhs: V) -> Where<D> {
|
||||
|
||||
return Where<D>(expression: lhs, function: ">=", operand: rhs)
|
||||
@@ -243,26 +413,56 @@ public func >= <D, T, V: QueryableAttributeType & Comparable>(_ lhs: Where<D>.Ex
|
||||
|
||||
// MARK: - Where.Expression where V: Optional<QueryableAttributeType>
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if an expression is equal to a value
|
||||
```
|
||||
let dog = CoreStore.fetchOne(From<Dog>().where((\.master ~ \.name) == "John"))
|
||||
```
|
||||
*/
|
||||
public func == <D, T, V: QueryableAttributeType>(_ lhs: Where<D>.Expression<T, V?>, _ rhs: V) -> Where<D> {
|
||||
|
||||
return Where<D>(lhs.cs_keyPathString, isEqualTo: rhs)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if an expression is equal to a value
|
||||
```
|
||||
let dog = CoreStore.fetchOne(From<Dog>().where((\.master ~ \.name) == "John"))
|
||||
```
|
||||
*/
|
||||
public func == <D, T, V: QueryableAttributeType>(_ lhs: Where<D>.Expression<T, V?>, _ rhs: V?) -> Where<D> {
|
||||
|
||||
return Where<D>(lhs.cs_keyPathString, isEqualTo: rhs)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if an expression is equal to a value
|
||||
```
|
||||
let dog = CoreStore.fetchOne(From<Dog>().where((\.master ~ \.name) != "John"))
|
||||
```
|
||||
*/
|
||||
public func != <D, T, V: QueryableAttributeType>(_ lhs: Where<D>.Expression<T, V?>, _ rhs: V) -> Where<D> {
|
||||
|
||||
return !Where<D>(lhs.cs_keyPathString, isEqualTo: rhs)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if an expression is equal to a value
|
||||
```
|
||||
let dog = CoreStore.fetchOne(From<Dog>().where((\.master ~ \.name) != "John"))
|
||||
```
|
||||
*/
|
||||
public func != <D, T, V: QueryableAttributeType>(_ lhs: Where<D>.Expression<T, V?>, _ rhs: V?) -> Where<D> {
|
||||
|
||||
return !Where<D>(lhs.cs_keyPathString, isEqualTo: rhs)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by checking if a sequence contains a value
|
||||
```
|
||||
let dog = CoreStore.fetchOne(From<Dog>().where(["John", "Joe"] ~= (\.master ~ \.name))
|
||||
```
|
||||
*/
|
||||
public func ~= <D, T, V: QueryableAttributeType, S: Sequence>(_ sequence: S, _ expression: Where<D>.Expression<T, V?>) -> Where<D> where S.Iterator.Element == V {
|
||||
|
||||
return Where<D>(expression.cs_keyPathString, isMemberOf: sequence)
|
||||
@@ -271,21 +471,45 @@ public func ~= <D, T, V: QueryableAttributeType, S: Sequence>(_ sequence: S, _ e
|
||||
|
||||
// MARK: - Where.Expression where V: Optional<QueryableAttributeType & Comparable>
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if an expression is less than a value
|
||||
```
|
||||
let childsPet = CoreStore.fetchOne(From<Dog>().where((\.master ~ \.age) < 10))
|
||||
```
|
||||
*/
|
||||
public func < <D, T, V: QueryableAttributeType & Comparable>(_ lhs: Where<D>.Expression<T, V?>, _ rhs: V) -> Where<D> {
|
||||
|
||||
return Where<D>(expression: lhs, function: "<", operand: rhs)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if an expression is less than or equal to a value
|
||||
```
|
||||
let childsPet = CoreStore.fetchOne(From<Dog>().where((\.master ~ \.age) <= 10))
|
||||
```
|
||||
*/
|
||||
public func <= <D, T, V: QueryableAttributeType & Comparable>(_ lhs: Where<D>.Expression<T, V?>, _ rhs: V?) -> Where<D> {
|
||||
|
||||
return Where<D>(expression: lhs, function: "<=", operand: rhs)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if an expression is greater than a value
|
||||
```
|
||||
let teensPet = CoreStore.fetchOne(From<Dog>().where((\.master ~ \.age) > 10))
|
||||
```
|
||||
*/
|
||||
public func > <D, T, V: QueryableAttributeType & Comparable>(_ lhs: Where<D>.Expression<T, V?>, _ rhs: V) -> Where<D> {
|
||||
|
||||
return Where<D>(expression: lhs, function: ">", operand: rhs)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if an expression is greater than or equal to a value
|
||||
```
|
||||
let teensPet = CoreStore.fetchOne(From<Dog>().where((\.master ~ \.age) >= 10))
|
||||
```
|
||||
*/
|
||||
public func >= <D, T, V: QueryableAttributeType & Comparable>(_ lhs: Where<D>.Expression<T, V?>, _ rhs: V?) -> Where<D> {
|
||||
|
||||
return Where<D>(expression: lhs, function: ">=", operand: rhs)
|
||||
@@ -296,6 +520,12 @@ public func >= <D, T, V: QueryableAttributeType & Comparable>(_ lhs: Where<D>.Ex
|
||||
|
||||
extension KeyPath where Root: NSManagedObject, Value: AllowedObjectiveCCollectionKeyPathValue {
|
||||
|
||||
/**
|
||||
Creates a `Where.Expression` clause for COUNT
|
||||
```
|
||||
let dogsWithPlaymates = CoreStore.fetchAll(From<Dog>().where((\.master ~ \.pets).count() > 1))
|
||||
```
|
||||
*/
|
||||
public func count() -> Where<Root>.Expression<Where<Root>.CollectionTarget, Int> {
|
||||
|
||||
return .init(self.cs_keyPathString, "@count")
|
||||
@@ -306,6 +536,12 @@ extension KeyPath where Root: NSManagedObject, Value: AllowedObjectiveCCollectio
|
||||
|
||||
extension Where.Expression where D: NSManagedObject, T == Where<D>.CollectionTarget, V: AllowedObjectiveCCollectionKeyPathValue {
|
||||
|
||||
/**
|
||||
Creates a `Where.Expression` clause for COUNT
|
||||
```
|
||||
let dogsWithPlaymates = CoreStore.fetchAll(From<Dog>().where((\.master ~ \.pets).count() > 1))
|
||||
```
|
||||
*/
|
||||
public func count() -> Where<D>.Expression<T, Int> {
|
||||
|
||||
return .init(self.cs_keyPathString, "@count")
|
||||
@@ -317,16 +553,34 @@ extension Where.Expression where D: NSManagedObject, T == Where<D>.CollectionTar
|
||||
|
||||
extension Where.Expression where D: NSManagedObject, T == Where<D>.CollectionTarget, V: AllowedObjectiveCKeyPathValue {
|
||||
|
||||
/**
|
||||
Creates a `Where.Expression` clause for ANY
|
||||
```
|
||||
let dogsWithBadNamingSense = CoreStore.fetchAll(From<Dog>().where((\.master ~ \.pets ~ \.name).any() > "Spot"))
|
||||
```
|
||||
*/
|
||||
public func any() -> Where<D>.Expression<T, V> {
|
||||
|
||||
return .init("ANY " + self.cs_keyPathString)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where.Expression` clause for ALL
|
||||
```
|
||||
let allPlaymatePuppies = CoreStore.fetchAll(From<Dog>().where((\.master ~ \.pets ~ \.age).all() > 5))
|
||||
```
|
||||
*/
|
||||
public func all() -> Where<D>.Expression<T, V> {
|
||||
|
||||
return .init("ALL " + self.cs_keyPathString)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where.Expression` clause for NONE
|
||||
```
|
||||
let dogs = CoreStore.fetchAll(From<Dog>().where((\.master ~ \.pets ~ \.name).any() > "Spot"))
|
||||
```
|
||||
*/
|
||||
public func none() -> Where<D>.Expression<T, V> {
|
||||
|
||||
return .init("NONE " + self.cs_keyPathString)
|
||||
@@ -338,6 +592,12 @@ extension Where.Expression where D: NSManagedObject, T == Where<D>.CollectionTar
|
||||
|
||||
extension KeyPath where Root: CoreStoreObject, Value: AllowedCoreStoreObjectCollectionKeyPathValue {
|
||||
|
||||
/**
|
||||
Creates a `Where.Expression` clause for COUNT
|
||||
```
|
||||
let dogsWithPlaymates = CoreStore.fetchAll(From<Dog>().where((\.master ~ \.pets).count() > 1))
|
||||
```
|
||||
*/
|
||||
public func count() -> Where<Root>.Expression<Where<Root>.CollectionTarget, Int> {
|
||||
|
||||
return .init(Root.meta[keyPath: self].cs_keyPathString, "@count")
|
||||
@@ -349,21 +609,45 @@ extension KeyPath where Root: CoreStoreObject, Value: AllowedCoreStoreObjectColl
|
||||
|
||||
extension Where.Expression where D: CoreStoreObject, T == Where<D>.CollectionTarget {
|
||||
|
||||
/**
|
||||
Creates a `Where.Expression` clause for COUNT
|
||||
```
|
||||
let dogsWithPlaymates = CoreStore.fetchAll(From<Dog>().where((\.master ~ \.pets).count() > 1))
|
||||
```
|
||||
*/
|
||||
public func count() -> Where<D>.Expression<T, Int> {
|
||||
|
||||
return .init(self.cs_keyPathString, "@count")
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where.Expression` clause for ANY
|
||||
```
|
||||
let dogsWithBadNamingSense = CoreStore.fetchAll(From<Dog>().where((\.master ~ \.pets ~ \.name).any() > "Spot"))
|
||||
```
|
||||
*/
|
||||
public func any() -> Where<D>.Expression<T, V> {
|
||||
|
||||
return .init("ANY " + self.cs_keyPathString)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where.Expression` clause for ALL
|
||||
```
|
||||
let allPlaymatePuppies = CoreStore.fetchAll(From<Dog>().where((\.master ~ \.pets ~ \.age).all() > 5))
|
||||
```
|
||||
*/
|
||||
public func all() -> Where<D>.Expression<T, V> {
|
||||
|
||||
return .init("ALL " + self.cs_keyPathString)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where.Expression` clause for NONE
|
||||
```
|
||||
let dogs = CoreStore.fetchAll(From<Dog>().where((\.master ~ \.pets ~ \.name).any() > "Spot"))
|
||||
```
|
||||
*/
|
||||
public func none() -> Where<D>.Expression<T, V> {
|
||||
|
||||
return .init("NONE " + self.cs_keyPathString)
|
||||
|
||||
@@ -29,7 +29,7 @@ import Foundation
|
||||
// MARK: - WhereClauseType
|
||||
|
||||
/**
|
||||
Abstracts the `Where` clause for protocol utilities.
|
||||
Abstracts the `Where` clause for protocol utilities. Typically used only for utility method generic constraints.
|
||||
*/
|
||||
public protocol WhereClauseType: AnyWhereClause {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user