Compare commits

..

23 Commits
6.0.0 ... 6.2.1

Author SHA1 Message Date
John Estropia
0376ac6908 bump 2019-02-28 18:57:28 +09:00
John Estropia
b3421888a6 version bump 2019-02-28 18:55:32 +09:00
John Estropia
7b3f4ae0a4 fix compile error 2019-02-28 17:58:17 +09:00
John Estropia
b4e12cc922 restore NSPersistentStore.affectedStores ARC bug workaround 2019-02-28 17:57:34 +09:00
John Estropia
6c282b18af version bump 2019-02-28 13:14:27 +09:00
John Estropia
ebbde8b7b6 minor fix in demo app 2019-02-28 13:13:01 +09:00
John Estropia
a1407e4121 Revert workaround for iOS 10 NSFetchedResultsController (#100) 2019-02-28 13:07:47 +09:00
John Estropia
99b871b97a add missing documentations for Where.Expression, updated playgrounds 2019-02-20 18:47:29 +09:00
John Estropia
1cd3c4fcf4 fix compile error 2019-02-12 18:18:44 +09:00
John Estropia
e09ac9ee00 add macOS playground 2019-02-12 18:05:06 +09:00
John Estropia
4b0d134acb remove swift 5 annotation 2019-02-12 18:03:59 +09:00
John Estropia
eeec3979ee SwiftPM support 2019-02-12 15:48:50 +09:00
John Estropia
5b365c642d add tests for expressio evaluations 2019-02-08 18:42:19 +09:00
John Estropia
635201868a add comparison operators for Where.Expression 2019-02-08 17:16:56 +09:00
John Estropia
db4426e6b9 Swift 5 support. WIP: Support type-safe predicate expressions 2019-02-01 18:32:22 +09:00
John Estropia
41902fee2e fix compiler errors 2019-01-31 16:50:43 +09:00
John Estropia
9239370793 Added reference comment explaining crashes on A12 devices #291 2019-01-29 14:15:01 +09:00
John Estropia
a4d2f326a5 Improve perfomance by bypassing bridging (similar to https://github.com/JohnEstropia/CoreStore/pull/288) 2019-01-28 20:12:18 +09:00
John Estropia
9f54ec26e2 add Where initializer that can accept another Where clause 2019-01-28 20:10:15 +09:00
John Estropia
9425cb56d7 update documentation for -[CSListMonitor refetch:] to reflect actual behavior 2019-01-28 19:04:46 +09:00
John Estropia
1de56d2776 add missing From.orderBy(_:) overloads 2019-01-25 17:30:11 +09:00
John Estropia
b3261ea930 Update README.md 2019-01-24 16:12:12 +09:00
John Estropia
88dd7aef72 updated README 2019-01-24 15:32:54 +09:00
113 changed files with 2223 additions and 614 deletions

1
.gitignore vendored
View File

@@ -8,3 +8,4 @@ CoreStore.xcworkspace/xcuserdata
DerivedData
*.orig
build
Playground_macOS.playground/playground.xcworkspace/xcuserdata

View File

@@ -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"

View File

@@ -165,10 +165,6 @@
B52557881D02DE8100E51965 /* FetchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52557871D02DE8100E51965 /* FetchTests.swift */; };
B52557891D02DE8100E51965 /* FetchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52557871D02DE8100E51965 /* FetchTests.swift */; };
B525578A1D02DE8100E51965 /* FetchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52557871D02DE8100E51965 /* FetchTests.swift */; };
B52661401CADD585007B85D9 /* CoreStoreFetchRequest+CoreStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B526613F1CADD585007B85D9 /* CoreStoreFetchRequest+CoreStore.swift */; };
B52661421CADD585007B85D9 /* CoreStoreFetchRequest+CoreStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B526613F1CADD585007B85D9 /* CoreStoreFetchRequest+CoreStore.swift */; };
B52661431CADD585007B85D9 /* CoreStoreFetchRequest+CoreStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B526613F1CADD585007B85D9 /* CoreStoreFetchRequest+CoreStore.swift */; };
B52661441CADD585007B85D9 /* CoreStoreFetchRequest+CoreStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B526613F1CADD585007B85D9 /* CoreStoreFetchRequest+CoreStore.swift */; };
B529C2041CA4A2DB007E7EBD /* CSSaveResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B529C2031CA4A2DB007E7EBD /* CSSaveResult.swift */; };
B529C2061CA4A2DB007E7EBD /* CSSaveResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B529C2031CA4A2DB007E7EBD /* CSSaveResult.swift */; };
B529C2071CA4A2DC007E7EBD /* CSSaveResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B529C2031CA4A2DB007E7EBD /* CSSaveResult.swift */; };
@@ -297,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 */; };
@@ -477,6 +477,12 @@
B5831B7B1F34ACBA00A9F647 /* Transformable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5831B791F34ACBA00A9F647 /* Transformable.swift */; };
B5831B7C1F34ACBA00A9F647 /* Transformable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5831B791F34ACBA00A9F647 /* Transformable.swift */; };
B5831B7D1F34ACBA00A9F647 /* Transformable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5831B791F34ACBA00A9F647 /* Transformable.swift */; };
B5831F4022126FEC00D8604C /* KeyPathGenericBindings.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DAFB492203E01D003FCCD0 /* KeyPathGenericBindings.swift */; };
B5831F4122126FEC00D8604C /* KeyPathGenericBindings.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DAFB492203E01D003FCCD0 /* KeyPathGenericBindings.swift */; };
B5831F4222126FED00D8604C /* KeyPathGenericBindings.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DAFB492203E01D003FCCD0 /* KeyPathGenericBindings.swift */; };
B5831F432212700400D8604C /* Where.Expression.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DAFB472203D9F8003FCCD0 /* Where.Expression.swift */; };
B5831F442212700500D8604C /* Where.Expression.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DAFB472203D9F8003FCCD0 /* Where.Expression.swift */; };
B5831F452212700500D8604C /* Where.Expression.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DAFB472203D9F8003FCCD0 /* Where.Expression.swift */; };
B58B22F51C93C1BA00521925 /* CoreStore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2F03A53019C5C6DA005002A5 /* CoreStore.framework */; };
B58D0C631EAA0C7E003EDD87 /* NSManagedObject+DynamicModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B58D0C621EAA0C7E003EDD87 /* NSManagedObject+DynamicModel.swift */; };
B58D0C641EAA0C7E003EDD87 /* NSManagedObject+DynamicModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B58D0C621EAA0C7E003EDD87 /* NSManagedObject+DynamicModel.swift */; };
@@ -578,6 +584,8 @@
B5D7A5B81CA3BF8F005C752B /* CSInto.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D7A5B51CA3BF8F005C752B /* CSInto.swift */; };
B5D7A5B91CA3BF8F005C752B /* CSInto.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D7A5B51CA3BF8F005C752B /* CSInto.swift */; };
B5D7A5BA1CA3BF8F005C752B /* CSInto.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D7A5B51CA3BF8F005C752B /* CSInto.swift */; };
B5DAFB482203D9F8003FCCD0 /* Where.Expression.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DAFB472203D9F8003FCCD0 /* Where.Expression.swift */; };
B5DAFB4A2203E01D003FCCD0 /* KeyPathGenericBindings.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DAFB492203E01D003FCCD0 /* KeyPathGenericBindings.swift */; };
B5DBE2CD1C9914A900B5CEFA /* CSCoreStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DBE2CC1C9914A900B5CEFA /* CSCoreStore.swift */; };
B5DBE2CE1C9914A900B5CEFA /* CSCoreStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DBE2CC1C9914A900B5CEFA /* CSCoreStore.swift */; };
B5DBE2CF1C9914A900B5CEFA /* CSCoreStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5DBE2CC1C9914A900B5CEFA /* CSCoreStore.swift */; };
@@ -796,7 +804,6 @@
B525577F1D029D2500E51965 /* TweakTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TweakTests.swift; sourceTree = "<group>"; };
B52557831D02A07400E51965 /* SectionByTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SectionByTests.swift; sourceTree = "<group>"; };
B52557871D02DE8100E51965 /* FetchTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FetchTests.swift; sourceTree = "<group>"; };
B526613F1CADD585007B85D9 /* CoreStoreFetchRequest+CoreStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CoreStoreFetchRequest+CoreStore.swift"; sourceTree = "<group>"; };
B529C2031CA4A2DB007E7EBD /* CSSaveResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSSaveResult.swift; sourceTree = "<group>"; };
B52DD1741BE1F8CC00949AFE /* CoreStore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = CoreStore.framework; sourceTree = BUILT_PRODUCTS_DIR; };
B52DD17D1BE1F8CC00949AFE /* CoreStoreTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CoreStoreTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -820,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>"; };
@@ -860,7 +868,7 @@
B56923F41EB828BF007C4DC9 /* CSDynamicSchema.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSDynamicSchema.swift; sourceTree = "<group>"; };
B56923F91EB82956007C4DC9 /* CSXcodeDataModelSchema.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSXcodeDataModelSchema.swift; sourceTree = "<group>"; };
B56923FE1EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSUnsafeDataModelSchema.swift; sourceTree = "<group>"; };
B56964D31B22FFAD0075EE4A /* DataStack+Migration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "DataStack+Migration.swift"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
B56964D31B22FFAD0075EE4A /* DataStack+Migration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "DataStack+Migration.swift"; sourceTree = "<group>"; };
B56965231B356B820075EE4A /* MigrationResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MigrationResult.swift; sourceTree = "<group>"; };
B57D27BD1D0BBE8200539C58 /* BaseTestDataTestCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseTestDataTestCase.swift; sourceTree = "<group>"; };
B57D27C11D0BC20100539C58 /* QueryTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QueryTests.swift; sourceTree = "<group>"; };
@@ -877,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; };
@@ -902,6 +912,8 @@
B5D3F6441C887C0A00C7492A /* LegacySQLiteStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LegacySQLiteStore.swift; sourceTree = "<group>"; };
B5D7A5B51CA3BF8F005C752B /* CSInto.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSInto.swift; sourceTree = "<group>"; };
B5D9C8F61B160ED200E64F0E /* CoreStore.podspec */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; path = CoreStore.podspec; sourceTree = SOURCE_ROOT; };
B5DAFB472203D9F8003FCCD0 /* Where.Expression.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Where.Expression.swift; sourceTree = "<group>"; };
B5DAFB492203E01D003FCCD0 /* KeyPathGenericBindings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyPathGenericBindings.swift; sourceTree = "<group>"; };
B5DBE2CC1C9914A900B5CEFA /* CSCoreStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSCoreStore.swift; sourceTree = "<group>"; };
B5DBE2D11C991B3E00B5CEFA /* CSDataStack.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSDataStack.swift; sourceTree = "<group>"; };
B5DBE2DA1C9939E100B5CEFA /* CoreStoreTests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "CoreStoreTests-Bridging-Header.h"; sourceTree = "<group>"; };
@@ -956,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>"; };
@@ -1047,7 +1058,8 @@
2F03A52619C5C6DA005002A5 = {
isa = PBXGroup;
children = (
B5E8A72621C3B85000EF006A /* Playground.playground */,
B5A80DF52212C1BC006096AA /* Playground_iOS.playground */,
B5A80DF42212C1AB006096AA /* Playground_macOS.playground */,
2F291E3119C6D4D3007AF63F /* Frameworks */,
2F03A53219C5C6DA005002A5 /* Sources */,
2F03A53C19C5C6DA005002A5 /* CoreStoreTests */,
@@ -1333,6 +1345,7 @@
B5A1DAC71F111BFA003CF369 /* KeyPath+Querying.swift */,
B5D339EB1E9495E500C880DE /* CoreStoreObject+Querying.swift */,
B5CA2B111F81DBFE004B1936 /* DynamicKeyPath.swift */,
B5DAFB492203E01D003FCCD0 /* KeyPathGenericBindings.swift */,
);
name = "KeyPath Utilities";
sourceTree = "<group>";
@@ -1480,6 +1493,7 @@
B5E84F011AFF847B0064E85B /* From.swift */,
B5E84F031AFF847B0064E85B /* Select.swift */,
B5E84F051AFF847B0064E85B /* Where.swift */,
B5DAFB472203D9F8003FCCD0 /* Where.Expression.swift */,
B5E84F041AFF847B0064E85B /* OrderBy.swift */,
B5E84F021AFF847B0064E85B /* GroupBy.swift */,
B5E84F001AFF847B0064E85B /* Tweak.swift */,
@@ -1530,8 +1544,8 @@
children = (
B5831B6F1F34AC3400A9F647 /* AttributeProtocol.swift */,
B5831B741F34AC7A00A9F647 /* RelationshipProtocol.swift */,
B5474D142227C08700B21FEC /* CoreStoreFetchRequest.swift */,
B5C976E61C6E3A5900B1AF90 /* CoreStoreFetchedResultsController.swift */,
B526613F1CADD585007B85D9 /* CoreStoreFetchRequest+CoreStore.swift */,
B53B275E1EE3B92E00E9B352 /* CoreStoreManagedObject.swift */,
B533C4DA1D7D4BFA001383CB /* DispatchQueue+CoreStore.swift */,
B51260921E9B28F100402229 /* EntityIdentifier.swift */,
@@ -1896,6 +1910,7 @@
B5ECDBFF1CA80CBA00C7F112 /* CSWhere.swift in Sources */,
B5ECDC051CA8138100C7F112 /* CSOrderBy.swift in Sources */,
B5E1B5981CAA0C23007FD580 /* CSObjectObserver.swift in Sources */,
B5DAFB4A2203E01D003FCCD0 /* KeyPathGenericBindings.swift in Sources */,
B5519A5F1CA21954002BEF78 /* CSAsynchronousDataTransaction.swift in Sources */,
B52FD3AA1E3B3EF10001D919 /* NSManagedObject+Logging.swift in Sources */,
B52F74411E9B8724005F3DAC /* UnsafeDataModelSchema.swift in Sources */,
@@ -1935,11 +1950,11 @@
B56007111B3F6BD500A9A8F9 /* Into.swift in Sources */,
B5E84F111AFF847B0064E85B /* Select.swift in Sources */,
B51260931E9B28F100402229 /* EntityIdentifier.swift in Sources */,
B5DAFB482203D9F8003FCCD0 /* Where.Expression.swift in Sources */,
B5FE4DA21C8481E100FA6A91 /* StorageInterface.swift in Sources */,
B53FB9FE1CAB2D2F00F0D40A /* CSMigrationResult.swift in Sources */,
B5DBE2D21C991B3E00B5CEFA /* CSDataStack.swift in Sources */,
B50392F91C478FF3009900CA /* NSManagedObject+Transaction.swift in Sources */,
B52661401CADD585007B85D9 /* CoreStoreFetchRequest+CoreStore.swift in Sources */,
B53FBA181CAB63E200F0D40A /* NSManagedObject+ObjectiveC.swift in Sources */,
B5202CFA1C04688100DED140 /* NSFetchedResultsController+Convenience.swift in Sources */,
B5519A591CA2008C002BEF78 /* CSBaseDataTransaction.swift in Sources */,
@@ -2019,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 */,
@@ -2128,9 +2144,11 @@
82BA18A31C4BBD2200A0916E /* DataStack.swift in Sources */,
82BA18C81C4BBD5900A0916E /* MigrationChain.swift in Sources */,
B546F9741C9C553300D5AC55 /* SetupResult.swift in Sources */,
B5831F4022126FEC00D8604C /* KeyPathGenericBindings.swift in Sources */,
B53CA9A31EF1EF1600E0F440 /* PartialObject.swift in Sources */,
82BA18B11C4BBD3100A0916E /* SaveResult.swift in Sources */,
82BA18DD1C4BBE1400A0916E /* NSFetchedResultsController+Convenience.swift in Sources */,
B5831F432212700400D8604C /* Where.Expression.swift in Sources */,
B51260941E9B28F100402229 /* EntityIdentifier.swift in Sources */,
B5FE4DA81C84FB4400FA6A91 /* InMemoryStore.swift in Sources */,
B53FBA001CAB2D2F00F0D40A /* CSMigrationResult.swift in Sources */,
@@ -2138,7 +2156,6 @@
82BA18B41C4BBD3900A0916E /* BaseDataTransaction+Importing.swift in Sources */,
B53FBA1A1CAB63E200F0D40A /* NSManagedObject+ObjectiveC.swift in Sources */,
82BA18CA1C4BBD5900A0916E /* MigrationResult.swift in Sources */,
B52661421CADD585007B85D9 /* CoreStoreFetchRequest+CoreStore.swift in Sources */,
B5519A5A1CA2008C002BEF78 /* CSBaseDataTransaction.swift in Sources */,
B5ECDBE11CA6BB2B00C7F112 /* CSBaseDataTransaction+Querying.swift in Sources */,
82BA18C11C4BBD5300A0916E /* CoreStore+Observing.swift in Sources */,
@@ -2216,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 */,
@@ -2325,9 +2343,11 @@
B52DD1961BE1F92500949AFE /* DataStack.swift in Sources */,
B5ECDBFD1CA804FD00C7F112 /* NSManagedObjectContext+ObjectiveC.swift in Sources */,
B52DD1BD1BE1F94300949AFE /* NSManagedObject+Convenience.swift in Sources */,
B5831F4222126FED00D8604C /* KeyPathGenericBindings.swift in Sources */,
B53CA9A51EF1EF1600E0F440 /* PartialObject.swift in Sources */,
B52DD1AD1BE1F93900949AFE /* Where.swift in Sources */,
B53FBA1C1CAB63E200F0D40A /* NSManagedObject+ObjectiveC.swift in Sources */,
B5831F452212700500D8604C /* Where.Expression.swift in Sources */,
B51260961E9B28F100402229 /* EntityIdentifier.swift in Sources */,
B5ECDBE31CA6BB2B00C7F112 /* CSBaseDataTransaction+Querying.swift in Sources */,
B5ECDC031CA80CBA00C7F112 /* CSWhere.swift in Sources */,
@@ -2336,7 +2356,6 @@
B52DD1C71BE1F94600949AFE /* NSManagedObjectContext+Querying.swift in Sources */,
B52DD1C81BE1F94600949AFE /* NSManagedObjectContext+Setup.swift in Sources */,
B52DD1C31BE1F94600949AFE /* NotificationObserver.swift in Sources */,
B52661441CADD585007B85D9 /* CoreStoreFetchRequest+CoreStore.swift in Sources */,
B52DD1A81BE1F93200949AFE /* DataStack+Querying.swift in Sources */,
B5220E221D130818009BC71E /* CSSectionBy.swift in Sources */,
B52DD1BC1BE1F94000949AFE /* MigrationResult.swift in Sources */,
@@ -2413,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 */,
@@ -2522,14 +2542,15 @@
B56321A81BD65219006C9394 /* NSManagedObject+Convenience.swift in Sources */,
B546F9751C9C553300D5AC55 /* SetupResult.swift in Sources */,
B56321981BD65216006C9394 /* Where.swift in Sources */,
B5831F4122126FEC00D8604C /* KeyPathGenericBindings.swift in Sources */,
B53CA9A41EF1EF1600E0F440 /* PartialObject.swift in Sources */,
B5202CFD1C046E8400DED140 /* NSFetchedResultsController+Convenience.swift in Sources */,
B5FE4DA91C84FB4400FA6A91 /* InMemoryStore.swift in Sources */,
B5831F442212700500D8604C /* Where.Expression.swift in Sources */,
B51260951E9B28F100402229 /* EntityIdentifier.swift in Sources */,
B53FBA011CAB2D2F00F0D40A /* CSMigrationResult.swift in Sources */,
B5DBE2D41C991B3E00B5CEFA /* CSDataStack.swift in Sources */,
B50392FA1C47963F009900CA /* NSManagedObject+Transaction.swift in Sources */,
B52661431CADD585007B85D9 /* CoreStoreFetchRequest+CoreStore.swift in Sources */,
B53FBA1B1CAB63E200F0D40A /* NSManagedObject+ObjectiveC.swift in Sources */,
B5519A5B1CA2008C002BEF78 /* CSBaseDataTransaction.swift in Sources */,
B5ECDBE21CA6BB2B00C7F112 /* CSBaseDataTransaction+Querying.swift in Sources */,
@@ -2610,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 */,
@@ -2796,7 +2818,6 @@
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 4.2;
};
name = Debug;
};
@@ -2815,7 +2836,6 @@
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 4.2;
};
name = Release;
};
@@ -2836,7 +2856,6 @@
SWIFT_OBJC_BRIDGING_HEADER = "CoreStoreTests/CoreStoreTests-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 4.2;
};
name = Debug;
};
@@ -2852,7 +2871,6 @@
SDKROOT = iphoneos;
SWIFT_OBJC_BRIDGING_HEADER = "CoreStoreTests/CoreStoreTests-Bridging-Header.h";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 4.2;
};
name = Release;
};
@@ -2873,7 +2891,6 @@
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 4.2;
TARGETED_DEVICE_FAMILY = 3;
};
name = Debug;
@@ -2895,7 +2912,6 @@
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 4.2;
TARGETED_DEVICE_FAMILY = 3;
};
name = Release;
@@ -2914,7 +2930,6 @@
SWIFT_OBJC_BRIDGING_HEADER = "CoreStoreTests/CoreStoreTests-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 4.2;
TARGETED_DEVICE_FAMILY = 3;
};
name = Debug;
@@ -2933,7 +2948,6 @@
SDKROOT = appletvos;
SWIFT_OBJC_BRIDGING_HEADER = "CoreStoreTests/CoreStoreTests-Bridging-Header.h";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 4.2;
TARGETED_DEVICE_FAMILY = 3;
};
name = Release;
@@ -2958,7 +2972,6 @@
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 4.2;
};
name = Debug;
};
@@ -2983,7 +2996,6 @@
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 4.2;
};
name = Release;
};
@@ -3004,7 +3016,6 @@
SWIFT_OBJC_BRIDGING_HEADER = "CoreStoreTests/CoreStoreTests-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 4.2;
};
name = Debug;
};
@@ -3025,7 +3036,6 @@
SDKROOT = macosx;
SWIFT_OBJC_BRIDGING_HEADER = "CoreStoreTests/CoreStoreTests-Bridging-Header.h";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 4.2;
};
name = Release;
};
@@ -3047,7 +3057,6 @@
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 4.2;
TARGETED_DEVICE_FAMILY = 4;
};
name = Debug;
@@ -3071,7 +3080,6 @@
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-O";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 4.2;
TARGETED_DEVICE_FAMILY = 4;
};
name = Release;

View File

@@ -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

View File

@@ -30,9 +30,10 @@ import CoreStore
#if os(macOS)
typealias Color = NSColor
#else
typealias Color = UIColor
#endif
class Animal: CoreStoreObject {
@@ -70,8 +71,13 @@ class Person: CoreStoreObject {
customGetter: Person.getDisplayName(_:),
affectedByKeyPaths: Person.keyPathsAffectingDisplayName()
)
let spouse = Relationship.ToOne<Person>("spouse")
let pets = Relationship.ToManyUnordered<Animal>("pets", inverse: { $0.master })
private let _spouse = Relationship.ToOne<Person>("_spouseInverse", inverse: { $0.spouse })
private static func setTitle(_ partialObject: PartialObject<Person>, _ newValue: String) {
@@ -126,7 +132,7 @@ class DynamicModelTests: BaseTestDataTestCase {
versionLock: [
"Animal": [0x1b59d511019695cf, 0xdeb97e86c5eff179, 0x1cfd80745646cb3, 0x4ff99416175b5b9a],
"Dog": [0xe3f0afeb109b283a, 0x29998d292938eb61, 0x6aab788333cfc2a3, 0x492ff1d295910ea7],
"Person": [0x66d8bbfd8b21561f, 0xcecec69ecae3570f, 0xc4b73d71256214ef, 0x89b99bfe3e013e8b]
"Person": [0x2831cf046084d96d, 0xbe19b13ace54641, 0x635a082728b0f6f0, 0x3d4ef2dd4b74a87c]
]
)
)
@@ -134,7 +140,7 @@ class DynamicModelTests: BaseTestDataTestCase {
let k1 = String(keyPath: \Animal.species)
XCTAssertEqual(k1, "species")
let k2 = String(keyPath: \Dog.species)
XCTAssertEqual(k2, "species")
@@ -272,11 +278,11 @@ class DynamicModelTests: BaseTestDataTestCase {
_ = try transaction.fetchAll(
From<Dog>()
.where(\Animal.species == "Dog" && \.age == 10)
.where(\Animal.species == "Dog" && \Dog.age == 10)
)
_ = try transaction.fetchAll(
From<Dog>()
.where(\.age == 10 && \Animal.species == "Dog")
.where(\Dog.age == 10 && \Animal.species == "Dog")
.orderBy(.ascending({ $0.species }))
)
_ = try transaction.fetchAll(

View File

@@ -74,31 +74,31 @@ final class FromTests: BaseTestCase {
let from = From<TestEntity1>()
let request = CoreStoreFetchRequest()
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
try from.applyToFetchRequest(request, context: dataStack.mainContext)
XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores)
XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertEqual(affectedConfigurations, ["PF_DEFAULT_CONFIGURATION_NAME"])
}
do {
let from = From<TestEntity1>("Config1")
let request = CoreStoreFetchRequest()
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
self.expectError(code: .persistentStoreNotFound) {
try from.applyToFetchRequest(request, context: dataStack.mainContext)
}
XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores)
XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.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 = CoreStoreFetchRequest()
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
XCTAssertNotNil(storesFound)
XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores)
XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertEqual(affectedConfigurations, ["Config1"])
}
do {
let from = From<TestEntity1>("Config1")
let request = CoreStoreFetchRequest()
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
XCTAssertNotNil(storesFound)
XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores)
XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertEqual(affectedConfigurations, ["Config1"])
}
do {
let from = From<TestEntity1>("Config2")
let request = CoreStoreFetchRequest()
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
self.expectError(code: .persistentStoreNotFound) {
try from.applyToFetchRequest(request, context: dataStack.mainContext)
}
XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores)
XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertTrue(affectedConfigurations.isEmpty)
}
do {
let from = From<TestEntity2>()
let request = CoreStoreFetchRequest()
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
self.expectError(code: .persistentStoreNotFound) {
try from.applyToFetchRequest(request, context: dataStack.mainContext)
}
XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores)
XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertTrue(affectedConfigurations.isEmpty)
}
do {
let from = From<TestEntity2>("Config1")
let request = CoreStoreFetchRequest()
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
self.expectError(code: .persistentStoreNotFound) {
try from.applyToFetchRequest(request, context: dataStack.mainContext)
}
XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores)
XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertTrue(affectedConfigurations.isEmpty)
}
do {
let from = From<TestEntity2>("Config2")
let request = CoreStoreFetchRequest()
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
self.expectError(code: .persistentStoreNotFound) {
try from.applyToFetchRequest(request, context: dataStack.mainContext)
}
XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores)
XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.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 = CoreStoreFetchRequest()
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
XCTAssertNotNil(storesFound)
XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores)
XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.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 = CoreStoreFetchRequest()
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
XCTAssertNotNil(storesFound)
XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores)
XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertEqual(affectedConfigurations, ["Config1"])
}
do {
let from = From<TestEntity1>("Config2")
let request = CoreStoreFetchRequest()
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
self.expectError(code: .persistentStoreNotFound) {
try from.applyToFetchRequest(request, context: dataStack.mainContext)
}
XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores)
XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertTrue(affectedConfigurations.isEmpty)
}
do {
let from = From<TestEntity2>()
let request = CoreStoreFetchRequest()
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
XCTAssertNotNil(storesFound)
XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores)
XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertEqual(affectedConfigurations, ["PF_DEFAULT_CONFIGURATION_NAME"])
}
do {
let from = From<TestEntity2>("Config1")
let request = CoreStoreFetchRequest()
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
self.expectError(code: .persistentStoreNotFound) {
try from.applyToFetchRequest(request, context: dataStack.mainContext)
}
XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores)
XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertTrue(affectedConfigurations.isEmpty)
}
do {
let from = From<TestEntity2>("Config2")
let request = CoreStoreFetchRequest()
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
self.expectError(code: .persistentStoreNotFound) {
try from.applyToFetchRequest(request, context: dataStack.mainContext)
}
XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores)
XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.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 = CoreStoreFetchRequest()
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
XCTAssertNotNil(storesFound)
XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores)
XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertEqual(affectedConfigurations, ["Config1"])
}
do {
let from = From<TestEntity1>("Config1")
let request = CoreStoreFetchRequest()
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
XCTAssertNotNil(storesFound)
XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores)
XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertEqual(affectedConfigurations, ["Config1"])
}
do {
let from = From<TestEntity1>("Config2")
let request = CoreStoreFetchRequest()
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
self.expectError(code: .persistentStoreNotFound) {
try from.applyToFetchRequest(request, context: dataStack.mainContext)
}
XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores)
XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertTrue(affectedConfigurations.isEmpty)
}
do {
let from = From<TestEntity2>()
let request = CoreStoreFetchRequest()
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
XCTAssertNotNil(storesFound)
XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores)
XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertEqual(affectedConfigurations, ["Config2"])
}
do {
let from = From<TestEntity2>("Config1")
let request = CoreStoreFetchRequest()
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
self.expectError(code: .persistentStoreNotFound) {
try from.applyToFetchRequest(request, context: dataStack.mainContext)
}
XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores)
XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertTrue(affectedConfigurations.isEmpty)
}
do {
let from = From<TestEntity2>("Config2")
let request = CoreStoreFetchRequest()
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
let storesFound: Void? = try? from.applyToFetchRequest(request, context: dataStack.mainContext)
XCTAssertNotNil(storesFound)
XCTAssertNotNil(request.entity)
XCTAssertNotNil(request.safeAffectedStores)
XCTAssertNotNil(request.safeAffectedStores())
XCTAssert(from.entityClass == NSClassFromString(request.entity!.managedObjectClassName))
let affectedConfigurations = request.safeAffectedStores!.map { $0.configurationName }
let affectedConfigurations = request.safeAffectedStores()?.map { $0.configurationName } ?? []
XCTAssertEqual(affectedConfigurations, ["Config2"])
}
}

View File

@@ -68,7 +68,7 @@ final class GroupByTests: BaseTestCase {
let groupBy = GroupBy<NSManagedObject>(#keyPath(TestEntity1.testString))
let request = CoreStoreFetchRequest()
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
try From<TestEntity1>().applyToFetchRequest(request, context: dataStack.mainContext)
groupBy.applyToFetchRequest(request)

View File

@@ -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>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="11759" systemVersion="16C67" minimumToolsVersion="Xcode 4.3" sourceLanguage="Objective-C" userDefinedModelVersionIdentifier="">
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="14460.32" systemVersion="17G2307" minimumToolsVersion="Xcode 4.3" sourceLanguage="Objective-C" userDefinedModelVersionIdentifier="">
<entity name="TestEntity1AAA" representedClassName="CoreStoreTests.TestEntity1" syncable="YES">
<attribute name="testBoolean" optional="YES" attributeType="Boolean" usesScalarValueType="NO" syncable="YES"/>
<attribute name="testData" optional="YES" attributeType="Binary" syncable="YES"/>
@@ -9,6 +9,8 @@
<attribute name="testNil" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="testNumber" optional="YES" attributeType="Integer 32" usesScalarValueType="NO" syncable="YES"/>
<attribute name="testString" optional="YES" attributeType="String" syncable="YES"/>
<relationship name="testToManyUnordered" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="TestEntity1AAA" inverseName="testToOne" inverseEntity="TestEntity1AAA" syncable="YES"/>
<relationship name="testToOne" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="TestEntity1AAA" inverseName="testToManyUnordered" inverseEntity="TestEntity1AAA" syncable="YES"/>
</entity>
<entity name="TestEntity2" representedClassName="CoreStoreTests.TestEntity2" syncable="YES">
<attribute name="testBoolean" optional="YES" attributeType="Boolean" usesScalarValueType="NO" syncable="YES"/>
@@ -19,6 +21,8 @@
<attribute name="testNil" optional="YES" attributeType="String" syncable="YES"/>
<attribute name="testNumber" optional="YES" attributeType="Integer 32" usesScalarValueType="NO" syncable="YES"/>
<attribute name="testString" optional="YES" attributeType="String" syncable="YES"/>
<relationship name="testToManyOrdered" optional="YES" toMany="YES" deletionRule="Nullify" ordered="YES" destinationEntity="TestEntity2" inverseName="testToOne" inverseEntity="TestEntity2" syncable="YES"/>
<relationship name="testToOne" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="TestEntity2" inverseName="testToManyOrdered" inverseEntity="TestEntity2" syncable="YES"/>
</entity>
<configuration name="Config1">
<memberEntity name="TestEntity1AAA"/>
@@ -27,7 +31,7 @@
<memberEntity name="TestEntity2"/>
</configuration>
<elements>
<element name="TestEntity1AAA" positionX="-63" positionY="-18" width="128" height="165"/>
<element name="TestEntity2" positionX="-63" positionY="9" width="128" height="165"/>
<element name="TestEntity1AAA" positionX="-63" positionY="-18" width="128" height="195"/>
<element name="TestEntity2" positionX="-63" positionY="9" width="128" height="195"/>
</elements>
</model>

View File

@@ -179,7 +179,7 @@ final class OrderByTests: XCTestCase {
dynamic func test_ThatOrderByClauses_ApplyToFetchRequestsCorrectly() {
let orderBy = OrderBy<NSManagedObject>(.ascending("key"))
let request = CoreStoreFetchRequest()
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
orderBy.applyToFetchRequest(request)
XCTAssertNotNil(request.sortDescriptors)
XCTAssertEqual(request.sortDescriptors ?? [], orderBy.sortDescriptors)

View File

@@ -330,7 +330,14 @@ class SetupTests: BaseTestDataTestCase {
xcodeModelName: "Model",
bundle: Bundle(for: type(of: self))
)
try! stack.addStorageAndWait(sqliteStore)
try! stack.addStorageAndWait(
SQLiteStore.legacy(
fileName: sqliteStore.fileURL.lastPathComponent,
configuration: sqliteStore.configuration,
migrationMappingProviders: sqliteStore.migrationMappingProviders,
localStorageOptions: .recreateStoreOnModelMismatch
)
)
self.prepareTestDataForStack(stack)
}
XCTAssertTrue(fileManager.fileExists(atPath: sqliteStore.fileURL.path))

View File

@@ -36,4 +36,6 @@ class TestEntity1: NSManagedObject {
@NSManaged var testDecimal: NSDecimalNumber?
@NSManaged var testData: Data?
@NSManaged var testNil: String?
@NSManaged var testToOne: TestEntity1?
@NSManaged var testToManyUnordered: NSSet?
}

View File

@@ -36,4 +36,6 @@ class TestEntity2: NSManagedObject {
@NSManaged var testDecimal: NSDecimalNumber?
@NSManaged var testData: Data?
@NSManaged var testNil: String?
@NSManaged var testToOne: TestEntity2?
@NSManaged var testToManyOrdered: NSOrderedSet?
}

View File

@@ -303,8 +303,8 @@ final class TransactionTests: BaseTestCase {
do {
let createExpectation = self.expectation(description: "create")
let dataPrepared: Void? = try? stack.perform(
synchronous: { (transaction) in
try stack.perform(
synchronous: { (transaction) -> Void in
let object = transaction.create(Into<TestEntity1>())
object.testEntityID = NSNumber(value: 1)
@@ -313,10 +313,7 @@ final class TransactionTests: BaseTestCase {
object.testDate = testDate
}
)
if dataPrepared != nil {
createExpectation.fulfill()
}
createExpectation.fulfill()
self.checkExpectationsImmediately()
}
do {

View File

@@ -43,7 +43,7 @@ final class TweakTests: XCTestCase {
$0.fetchLimit = 200
$0.predicate = predicate
}
let request = CoreStoreFetchRequest()
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
tweak.applyToFetchRequest(request)
XCTAssertEqual(request.fetchOffset, 100)
XCTAssertEqual(request.fetchLimit, 200)

View File

@@ -56,6 +56,275 @@ final class WhereTests: XCTestCase {
dynamic func test_ThatDynamicModelKeyPaths_CanBeCreated() {
XCTAssertEqual(String(keyPath: \TestEntity1.testEntityID), "testEntityID")
XCTAssertEqual(String(keyPath: \Animal.color), "color")
}
@objc
dynamic func test_ThatExpressions_HaveCorrectKeyPaths() {
do {
do {
XCTAssertEqual(
#keyPath(TestEntity1.testToOne.testEntityID),
(\TestEntity1.testToOne ~ \.testEntityID).description,
String(keyPath: \TestEntity1.testToOne ~ \.testEntityID)
)
XCTAssertEqual(
#keyPath(TestEntity1.testToOne.testToOne.testToManyUnordered),
(\TestEntity1.testToOne ~ \.testToOne ~ \.testToManyUnordered).description,
String(keyPath: \TestEntity1.testToOne ~ \.testToOne ~ \.testToManyUnordered)
)
XCTAssertEqual(
#keyPath(TestEntity2.testToOne.testToOne.testToManyOrdered),
(\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).description,
String(keyPath: \TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered)
)
}
do {
XCTAssertEqual(
"master.pets",
(\Animal.master ~ \.pets).description,
String(keyPath: \Animal.master ~ \.pets)
)
XCTAssertEqual(
"master.pets.species",
(\Animal.master ~ \.pets ~ \.species).description,
String(keyPath: \Animal.master ~ \.pets ~ \.species)
)
XCTAssertEqual(
"master.pets.master",
(\Animal.master ~ \.pets ~ \.master).description,
String(keyPath: \Animal.master ~ \.pets ~ \.master)
)
}
}
do {
do {
XCTAssertEqual(
#keyPath(TestEntity1.testToOne.testToManyUnordered) + ".@count",
(\TestEntity1.testToOne ~ \.testToManyUnordered).count().description,
String(keyPath: (\TestEntity1.testToOne ~ \.testToManyUnordered).count())
)
XCTAssertEqual(
#keyPath(TestEntity2.testToOne.testToOne.testToManyOrdered) + ".@count",
(\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).count().description,
String(keyPath: (\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).count())
)
}
do {
XCTAssertEqual(
"master.pets.@count",
(\Animal.master ~ \.pets).count().description,
String(keyPath: (\Animal.master ~ \.pets).count())
)
}
}
do {
do {
XCTAssertEqual(
"ANY " + #keyPath(TestEntity1.testToOne.testToManyUnordered),
(\TestEntity1.testToOne ~ \.testToManyUnordered).any().description,
String(keyPath: (\TestEntity1.testToOne ~ \.testToManyUnordered).any())
)
XCTAssertEqual(
"ANY " + #keyPath(TestEntity2.testToOne.testToOne.testToManyOrdered),
(\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).any().description,
String(keyPath: (\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).any())
)
}
do {
XCTAssertEqual(
"ANY master.pets",
(\Animal.master ~ \.pets).any().description,
String(keyPath: (\Animal.master ~ \.pets).any())
)
XCTAssertEqual(
"ANY master.pets.species",
(\Animal.master ~ \.pets ~ \.species).any().description,
String(keyPath: (\Animal.master ~ \.pets ~ \.species).any())
)
}
}
do {
do {
XCTAssertEqual(
"ALL " + #keyPath(TestEntity1.testToOne.testToManyUnordered),
(\TestEntity1.testToOne ~ \.testToManyUnordered).all().description,
String(keyPath: (\TestEntity1.testToOne ~ \.testToManyUnordered).all())
)
XCTAssertEqual(
"ALL " + #keyPath(TestEntity2.testToOne.testToOne.testToManyOrdered),
(\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).all().description,
String(keyPath: (\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).all())
)
}
do {
XCTAssertEqual(
"ALL master.pets",
(\Animal.master ~ \.pets).all().description,
String(keyPath: (\Animal.master ~ \.pets).all())
)
XCTAssertEqual(
"ALL master.pets.species",
(\Animal.master ~ \.pets ~ \.species).all().description,
String(keyPath: (\Animal.master ~ \.pets ~ \.species).all())
)
}
}
do {
do {
XCTAssertEqual(
"NONE " + #keyPath(TestEntity1.testToOne.testToManyUnordered),
(\TestEntity1.testToOne ~ \.testToManyUnordered).none().description,
String(keyPath: (\TestEntity1.testToOne ~ \.testToManyUnordered).none())
)
XCTAssertEqual(
"NONE " + #keyPath(TestEntity2.testToOne.testToOne.testToManyOrdered),
(\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).none().description,
String(keyPath: (\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).none())
)
}
do {
XCTAssertEqual(
"NONE master.pets",
(\Animal.master ~ \.pets).none().description,
String(keyPath: (\Animal.master ~ \.pets).none())
)
XCTAssertEqual(
"NONE master.pets.species",
(\Animal.master ~ \.pets ~ \.species).none().description,
String(keyPath: (\Animal.master ~ \.pets ~ \.species).none())
)
}
}
}
@objc
dynamic func test_ThatWhereClauses_CanBeCreatedFromExpressionsCorrectly() {
do {
let dummy = "dummy"
do {
let whereClause: Where<TestEntity1> = (\.testToOne ~ \.testString) == dummy
let predicate = NSPredicate(format: "\(#keyPath(TestEntity1.testToOne.testString)) == %@", dummy)
XCTAssertEqual(whereClause, Where<TestEntity1>(predicate))
XCTAssertEqual(whereClause.predicate, predicate)
}
do {
let whereClause: Where<Animal> = (\.master ~ \.name) == dummy
let predicate = NSPredicate(format: "master.name == %@", dummy)
XCTAssertEqual(whereClause, Where<Animal>(predicate))
XCTAssertEqual(whereClause.predicate, predicate)
}
}
do {
let dummy = "dummy"
do {
let whereClause: Where<TestEntity1> = (\.testToOne ~ \.testToOne ~ \.testString) == dummy
let predicate = NSPredicate(format: "\(#keyPath(TestEntity1.testToOne.testToOne.testString)) == %@", dummy)
XCTAssertEqual(whereClause, Where<TestEntity1>(predicate))
XCTAssertEqual(whereClause.predicate, predicate)
}
do {
let whereClause: Where<Animal> = (\.master ~ \.spouse ~ \.name) == dummy
let predicate = NSPredicate(format: "master.spouse.name == %@", dummy)
XCTAssertEqual(whereClause, Where<Animal>(predicate))
XCTAssertEqual(whereClause.predicate, predicate)
}
}
do {
let count = 3
do {
let whereClause: Where<TestEntity1> = (\.testToOne ~ \.testToManyUnordered).count() == count
let predicate = NSPredicate(format: "\(#keyPath(TestEntity1.testToOne.testToManyUnordered)).@count == %d", count)
XCTAssertEqual(whereClause, Where<TestEntity1>(predicate))
XCTAssertEqual(whereClause.predicate, predicate)
}
do {
let whereClause: Where<Animal> = (\.master ~ \.pets).count() == count
let predicate = NSPredicate(format: "master.pets.@count == %d", count)
XCTAssertEqual(whereClause, Where<Animal>(predicate))
XCTAssertEqual(whereClause.predicate, predicate)
}
}
do {
let dummy = "dummy"
do {
let whereClause: Where<TestEntity1> = (\.testToOne ~ \.testToManyUnordered ~ \TestEntity1.testString).any() == dummy
let predicate = NSPredicate(format: "ANY \(#keyPath(TestEntity1.testToOne.testToManyUnordered)).\(#keyPath(TestEntity1.testString)) == %@", dummy)
XCTAssertEqual(whereClause, Where<TestEntity1>(predicate))
XCTAssertEqual(whereClause.predicate, predicate)
}
do {
let whereClause: Where<Animal> = (\.master ~ \.pets ~ \.species).any() == dummy
let predicate = NSPredicate(format: "ANY master.pets.species == %@", dummy)
XCTAssertEqual(whereClause, Where<Animal>(predicate))
XCTAssertEqual(whereClause.predicate, predicate)
}
}
do {
let dummy = "dummy"
do {
let whereClause: Where<TestEntity1> = (\.testToOne ~ \.testToManyUnordered ~ \TestEntity1.testString).all() == dummy
let predicate = NSPredicate(format: "ALL \(#keyPath(TestEntity1.testToOne.testToManyUnordered)).\(#keyPath(TestEntity1.testString)) == %@", dummy)
XCTAssertEqual(whereClause, Where<TestEntity1>(predicate))
XCTAssertEqual(whereClause.predicate, predicate)
}
do {
let whereClause: Where<Animal> = (\.master ~ \.pets ~ \.species).all() == dummy
let predicate = NSPredicate(format: "ALL master.pets.species == %@", dummy)
XCTAssertEqual(whereClause, Where<Animal>(predicate))
XCTAssertEqual(whereClause.predicate, predicate)
}
}
do {
let dummy = "dummy"
do {
let whereClause: Where<TestEntity1> = (\.testToOne ~ \.testToManyUnordered ~ \TestEntity1.testString).none() == dummy
let predicate = NSPredicate(format: "NONE \(#keyPath(TestEntity1.testToOne.testToManyUnordered)).\(#keyPath(TestEntity1.testString)) == %@", dummy)
XCTAssertEqual(whereClause, Where<TestEntity1>(predicate))
XCTAssertEqual(whereClause.predicate, predicate)
}
do {
let whereClause: Where<Animal> = (\.master ~ \.pets ~ \.species).none() == dummy
let predicate = NSPredicate(format: "NONE master.pets.species == %@", dummy)
XCTAssertEqual(whereClause, Where<Animal>(predicate))
XCTAssertEqual(whereClause.predicate, predicate)
}
}
}
@objc
@@ -314,7 +583,7 @@ final class WhereTests: XCTestCase {
dynamic func test_ThatWhereClauses_ApplyToFetchRequestsCorrectly() {
let whereClause = Where<NSManagedObject>("key", isEqualTo: "value")
let request = CoreStoreFetchRequest()
let request = CoreStoreFetchRequest<NSFetchRequestResult>()
whereClause.applyToFetchRequest(request)
XCTAssertNotNil(request.predicate)
XCTAssertEqual(request.predicate, whereClause.predicate)

View File

@@ -1,3 +1,4 @@
// swift-tools-version:4.2
//
// Package.swift
// CoreStore
@@ -25,21 +26,18 @@
import PackageDescription
let targets: [Target]
#if os(iOS)
targets = [Target(name: "CoreStore iOS")]
#elseif os(macOS)
targets = [Target(name: "CoreStore OSX")]
#elseif os(watchOS)
targets = [Target(name: "CoreStore watchOS")]
#elseif os(tvOS)
targets = [Target(name: "CoreStore tvOS")]
#else
targets = []
#endif
let package = Package(
name: "CoreStore",
targets: targets,
exclude: ["Carthage", "CoreStoreDemo", "Sources/libA/images"]
products: [
.library(name: "CoreStore", type: .static, targets: ["CoreStore"])
],
dependencies: [],
targets: [
.target(
name: "CoreStore",
dependencies: [],
path: "Sources",
exclude: ["CoreStoreBridge.h", "CoreStoreBridge.m"]
)
]
)

View File

@@ -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)
/// =======================

View 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)
/// =======================
}
}
)
/// =======================
}
}
)

View 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)
/// =======================
}
}
)
/// =======================
}
}
)

View 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>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>

View File

@@ -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>

113
README.md
View File

@@ -6,22 +6,23 @@ Unleashing the real power of Core Data with the elegance and safety of Swift
<br />
<br />
<a href="https://travis-ci.org/JohnEstropia/CoreStore"><img alt="Build Status" src="https://img.shields.io/travis/JohnEstropia/CoreStore/master.svg?style=flat" /></a>
<a href="https://github.com/JohnEstropia/CoreStore/commits"><img alt="Last Commit" src="https://img.shields.io/github/last-commit/johnestropia/corestore.svg?style=flat" /></a>
<a href="http://cocoadocs.org/docsets/CoreStore"><img alt="Platform" src="https://img.shields.io/cocoapods/p/CoreStore.svg?style=flat" /></a>
<a href="https://raw.githubusercontent.com/JohnEstropia/CoreStore/master/LICENSE"><img alt="License" src="https://img.shields.io/cocoapods/l/CoreStore.svg?style=flat" /></a>
<br /><br />Dependency managers<br />
<a href="https://cocoapods.org/pods/CoreStore"><img alt="Cocoapods compatible" src="https://img.shields.io/cocoapods/v/CoreStore.svg?style=flat&label=Cocoapods" /></a>
<a href="https://github.com/Carthage/Carthage"><img alt="Carthage compatible" src="https://img.shields.io/badge/Carthage-compatible-16a085.svg?style=flat" /></a>
<a href="https://swiftpkgs.ng.bluemix.net/package/JohnEstropia/CoreStore"><img alt="Swift Package Manager compatible" src="https://img.shields.io/badge/Swift_Package_Manager-compatible-orange.svg?style=flat" /></a>
<a href="https://swift.org/source-compatibility/#current-list-of-projects"><img alt="Swift Package Manager compatible" src="https://img.shields.io/badge/Swift_Package_Manager-compatible-orange.svg?style=flat" /></a>
<br /><br />Contact<br />
<a href="http://swift-corestore-slack.herokuapp.com/"><img alt="Join us on Slack!" src="http://swift-corestore-slack.herokuapp.com/badge.svg" /></a>
<a href="https://twitter.com/JohnEstropia"><img alt="Reach me on Twitter!" src="https://img.shields.io/badge/twitter-%40JohnEstropia-3498db.svg" /></a>
<br />
</p>
* **Swift 4.2:** iOS 9+ / macOS 10.10+ / watchOS 2.0+ / tvOS 9.0+
* **Swift 4.2:** iOS 10+ / macOS 10.12+ / watchOS 3.0+ / tvOS 10.0+
* Other Swift versions: [Swift 3.2(version 4.2.3)](https://github.com/JohnEstropia/CoreStore/tree/4.2.3)
Upgrading from CoreStore 4.2 (Swift 3.2) to 5.x (Swift 4.x)? Check out the [new features](#features) and make sure to read the [Change logs](https://github.com/JohnEstropia/CoreStore/releases).
Upgrading from CoreStore 5.x (min iOS 9) to 6.x (min iOS 10)? Check out the [new features](#features) and make sure to read the [Change logs](https://github.com/JohnEstropia/CoreStore/releases).
CoreStore is now part of the [Swift Source Compatibility projects](https://swift.org/source-compatibility/#current-list-of-projects).
@@ -86,6 +87,7 @@ CoreStore was (and is) heavily shaped by real-world needs of developing data-dep
- [`GroupBy` clause](#groupby-clause)
- [Logging and error reporting](#logging-and-error-reporting)
- [Observing changes and notifications](#observing-changes-and-notifications)
- [Observe a single property](#observe-a-single-property)
- [Observe a single object](#observe-a-single-object)
- [Observe a list of objects](#observe-a-list-of-objects)
- [Objective-C support](#objective-c-support)
@@ -139,12 +141,12 @@ CoreStore.perform(
Fetching objects (simple):
```swift
let people = CoreStore.fetchAll(From<MyPersonEntity>())
let people = try CoreStore.fetchAll(From<MyPersonEntity>())
```
Fetching objects (complex):
```swift
let people = CoreStore.fetchAll(
let people = try CoreStore.fetchAll(
From<MyPersonEntity>()
.where(\.age > 30),
.orderBy(.ascending(\.name), .descending(.\age)),
@@ -154,7 +156,7 @@ let people = CoreStore.fetchAll(
Querying values:
```swift
let maxAge = CoreStore.queryValue(
let maxAge = try CoreStore.queryValue(
From<MyPersonEntity>()
.select(Int.self, .maximum(\.age))
)
@@ -851,7 +853,7 @@ To update an existing object, fetch the object's instance from the transaction:
```swift
CoreStore.perform(
asynchronous: { (transaction) -> Void in
let person = transaction.fetchOne(
let person = try transaction.fetchOne(
From<MyPersonEntity>()
.where(\.name == "Jane Smith")
)
@@ -913,8 +915,8 @@ let jane: MyPersonEntity = // ...
CoreStore.perform(
asynchronous: { (transaction) -> Void in
transaction.delete(john, jane)
// transaction.delete([john, jane]) is also allowed
try transaction.delete(john, jane)
// try transaction.delete([john, jane]) is also allowed
},
completion: { _ in }
)
@@ -923,7 +925,7 @@ If you do not have references yet to the objects to be deleted, transactions hav
```swift
CoreStore.perform(
asynchronous: { (transaction) -> Void in
transaction.deleteAll(
try transaction.deleteAll(
From<MyPersonEntity>()
.where(\.age > 30)
)
@@ -971,7 +973,7 @@ var peopleIDs: [NSManagedObjectID] = // ...
CoreStore.perform(
asynchronous: { (transaction) -> Void in
let jane = transaction.fetchOne(
let jane = try transaction.fetchOne(
From<MyPersonEntity>()
.where(\.name == "Jane Smith")
)
@@ -1184,17 +1186,17 @@ Before we dive in, be aware that CoreStore distinguishes between *fetching* and
#### `From` clause
The search conditions for fetches and queries are specified using *clauses*. All fetches and queries require a `From` clause that indicates the target entity type:
```swift
let people = CoreStore.fetchAll(From<MyPersonEntity>())
let people = try CoreStore.fetchAll(From<MyPersonEntity>())
```
`people` in the example above will be of type `[MyPersonEntity]`. The `From<MyPersonEntity>()` clause indicates a fetch to all persistent stores that `MyPersonEntity` belong to.
If the entity exists in multiple configurations and you need to only search from a particular configuration, indicate in the `From` clause the configuration name for the destination persistent store:
```swift
let people = CoreStore.fetchAll(From<MyPersonEntity>("Config1")) // ignore objects in persistent stores other than the "Config1" configuration
let people = try CoreStore.fetchAll(From<MyPersonEntity>("Config1")) // ignore objects in persistent stores other than the "Config1" configuration
```
or if the persistent store is the auto-generated "Default" configuration, specify `nil`:
```swift
let person = CoreStore.fetchAll(From<MyPersonEntity>(nil))
let person = try CoreStore.fetchAll(From<MyPersonEntity>(nil))
```
Now we know how to use a `From` clause, let's move on to fetching and querying.
@@ -1214,11 +1216,11 @@ Each method's purpose is straightforward, but we need to understand how to set t
The `Where` clause is CoreStore's `NSPredicate` wrapper. It specifies the search filter to use when fetching (or querying). It implements all initializers that `NSPredicate` does (except for `-predicateWithBlock:`, which Core Data does not support):
```swift
var people = CoreStore.fetchAll(
var people = try CoreStore.fetchAll(
From<MyPersonEntity>(),
Where<MyPersonEntity>("%K > %d", "age", 30) // string format initializer
)
people = CoreStore.fetchAll(
people = try CoreStore.fetchAll(
From<MyPersonEntity>(),
Where<MyPersonEntity>(true) // boolean initializer
)
@@ -1233,14 +1235,14 @@ var people = CoreStore.fetchAll(
```
Starting CoreStore 5.0, `Where` clauses became more type-safe and are now generic types. To avoid verbose repetition of the generic object type, fetch methods now support **Fetch Chain builders**. We can also use Swift's Smart KeyPaths as the `Where` clause expression:
```swift
var people = CoreStore.fetchAll(
var people = try CoreStore.fetchAll(
From<MyPersonEntity>()
.where(\.age > 30) // Type-safe!
)
```
`Where` clauses also implement the `&&`, `||`, and `!` logic operators, so you can provide logical conditions without writing too much `AND`, `OR`, and `NOT` strings:
```swift
var people = CoreStore.fetchAll(
var people = try CoreStore.fetchAll(
From<MyPersonEntity>()
.where(\.age > 30 && \.gender == "M")
)
@@ -1251,7 +1253,7 @@ If you do not provide a `Where` clause, all objects that belong to the specified
The `OrderBy` clause is CoreStore's `NSSortDescriptor` wrapper. Use it to specify attribute keys in which to sort the fetch (or query) results with.
```swift
var mostValuablePeople = CoreStore.fetchAll(
var mostValuablePeople = try CoreStore.fetchAll(
From<MyPersonEntity>(),
OrderBy<MyPersonEntity>(.descending("rating"), .ascending("surname"))
)
@@ -1259,7 +1261,7 @@ var mostValuablePeople = CoreStore.fetchAll(
As seen above, `OrderBy` accepts a list of `SortKey` enumeration values, which can be either `.ascending` or `.descending`.
As with `Where` clauses, CoreStore 5.0 turned `OrderBy` clauses into generic types. To avoid verbose repetition of the generic object type, fetch methods now support **Fetch Chain builders**. We can also use Swift's Smart KeyPaths as the `OrderBy` clause expression:
```swift
var people = CoreStore.fetchAll(
var people = try CoreStore.fetchAll(
From<MyPersonEntity>()
.orderBy(.descending(\.rating), .ascending(\.surname)) // Type-safe!
)
@@ -1271,7 +1273,7 @@ var orderBy = OrderBy<MyPersonEntity>(.descending(\.rating))
if sortFromYoungest {
orderBy += OrderBy(.ascending(\.age))
}
var mostValuablePeople = CoreStore.fetchAll(
var mostValuablePeople = try CoreStore.fetchAll(
From<MyPersonEntity>(),
orderBy
)
@@ -1281,7 +1283,7 @@ var mostValuablePeople = CoreStore.fetchAll(
The `Tweak` clause lets you, uh, *tweak* the fetch (or query). `Tweak` exposes the `NSFetchRequest` in a closure where you can make changes to its properties:
```swift
var people = CoreStore.fetchAll(
var people = try CoreStore.fetchAll(
From<MyPersonEntity>(),
Where<MyPersonEntity>("age > %d", 30),
OrderBy<MyPersonEntity>(.ascending("surname")),
@@ -1294,7 +1296,7 @@ var people = CoreStore.fetchAll(
```
`Tweak` also supports **Fetch Chain builders**:
```swift
var people = CoreStore.fetchAll(
var people = try CoreStore.fetchAll(
From<MyPersonEntity>(),
.where(\.age > 30)
.orderBy(.ascending(\.surname))
@@ -1325,7 +1327,7 @@ Setting up the `From`, `Where`, `OrderBy`, and `Tweak` clauses is similar to how
The `Select<T>` clause specifies the target attribute/aggregate key, as well as the expected return type:
```swift
let johnsAge = CoreStore.queryValue(
let johnsAge = try CoreStore.queryValue(
From<MyPersonEntity>(),
Select<Int>("age"),
Where("name == %@", "John Smith")
@@ -1335,14 +1337,14 @@ The example above queries the "age" property for the first object that matches t
For `queryAttributes(...)`, only `NSDictionary` is valid for `Select`, thus you are allowed to omit the generic type:
```swift
let allAges = CoreStore.queryAttributes(
let allAges = try CoreStore.queryAttributes(
From<MyPersonEntity>(),
Select("age")
)
```
Starting CoreStore 5.0, query methods now support **Query Chain builders**. We can also use Swift's Smart KeyPaths to use in the expressions:
```swift
let johnsAge = CoreStore.queryValue(
let johnsAge = try CoreStore.queryValue(
From<MyPersonEntity>()
.select(\.age) // binds the result to Int
.where(\.name == "John Smith")
@@ -1357,7 +1359,7 @@ If you only need a value for a particular attribute, you can just specify the ke
- `.sum(...)`
```swift
let oldestAge = CoreStore.queryValue(
let oldestAge = try CoreStore.queryValue(
From<MyPersonEntity>(),
Select<Int>(.maximum("age"))
)
@@ -1365,7 +1367,7 @@ let oldestAge = CoreStore.queryValue(
For `queryAttributes(...)` which returns an array of dictionaries, you can specify multiple attributes/aggregates to `Select`:
```swift
let personJSON = CoreStore.queryAttributes(
let personJSON = try CoreStore.queryAttributes(
From<MyPersonEntity>(),
Select("name", "age")
)
@@ -1385,7 +1387,7 @@ let personJSON = CoreStore.queryAttributes(
```
You can also include an aggregate as well:
```swift
let personJSON = CoreStore.queryAttributes(
let personJSON = try CoreStore.queryAttributes(
From<MyPersonEntity>(),
Select("name", .count("friends"))
)
@@ -1405,7 +1407,7 @@ which returns:
```
The `"count(friends)"` key name was automatically used by CoreStore, but you can specify your own key alias if you need:
```swift
let personJSON = CoreStore.queryAttributes(
let personJSON = try CoreStore.queryAttributes(
From<MyPersonEntity>(),
Select("name", .count("friends", as: "friendsCount"))
)
@@ -1428,7 +1430,7 @@ which now returns:
The `GroupBy` clause lets you group results by a specified attribute/aggregate. This is useful only for `queryAttributes(...)` since `queryValue(...)` just returns the first value.
```swift
let personJSON = CoreStore.queryAttributes(
let personJSON = try CoreStore.queryAttributes(
From<MyPersonEntity>(),
Select("age", .count("age", as: "count")),
GroupBy("age")
@@ -1436,7 +1438,7 @@ let personJSON = CoreStore.queryAttributes(
```
Starting CoreStore 5.0, `GroupBy` clauses are now also generic types and now support **Query Chain builders**. We can also use Swift's Smart KeyPaths to use in the expressions:
```swift
let personJSON = CoreStore.queryAttributes(
let personJSON = try CoreStore.queryAttributes(
From<MyPersonEntity>()
.select(.attribute(\.age), .count(\.age, as: "count"))
.groupBy(\.age)
@@ -1491,16 +1493,35 @@ A couple of examples, `ListMonitor`:
These are all implemented with `CustomDebugStringConvertible.debugDescription`, so they work with lldb's `po` command as well.
## Observing changes and notifications
> (unavailable on macOS versions below 10.12)
CoreStore provides type-safe wrappers for observing managed objects:
- `ObjectMonitor`: use to monitor changes to a single `NSManagedObject` or `CoreStoreObject` instance (instead of Key-Value Observing)
- `ListMonitor`: use to monitor changes to a list of `NSManagedObject` or `CoreStoreObject` instances (instead of `NSFetchedResultsController`)
### Observe a single property
To get notifications for single property changes in an object, there are two methods depending on the object's base class.
- For `NSManagedObject` subclasses: Use the standard KVO method:
```swift
let observer = person.observe(\.age, options: [.new]) { (person, change)
print("Happy \(change.newValue)th birthday!")
}
```
- For `CoreStoreObject` subclasses: Call the `observe(...)` method directly on the property. You'll notice that the API itself is a bit similar to the KVO method:
```swift
let observer = person.age.observe(options: [.new]) { (person, change)
print("Happy \(change.newValue)th birthday!")
}
```
For both methods, you will need to keep a reference to the returned `observer` for the duration of the observation.
### Observe a single object
To observe an object, implement the `ObjectObserver` protocol and specify the `EntityType`:
To observe an object itself as a whole, implement the `ObjectObserver` protocol and specify the `EntityType`:
```swift
class MyViewController: UIViewController, ObjectObserver {
func objectMonitor(monitor: ObjectMonitor<MyPersonEntity>, willUpdateObject object: MyPersonEntity) {
@@ -1796,7 +1817,7 @@ let keyPath: String = Dog.keyPath { $0.nickname }
```
as well as `Where` and `OrderBy` clauses
```swift
let puppies = CoreStore.fetchAll(
let puppies = try CoreStore.fetchAll(
From<Dog>()
.where(\.age < 1)
.orderBy(.ascending(\.age))
@@ -1841,8 +1862,8 @@ Once the version lock is set, any changes in the properties or to the model will
# Installation
- Requires:
- iOS 8 SDK and above
- Swift 4 (Xcode 9+)
- iOS 10 SDK and above
- Swift 4.2 (Xcode 10+)
- Dependencies:
- *None*
- Other notes:
@@ -1851,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', '~> 5.0'
pod 'CoreStore', '~> 6.1'
```
and run
```
@@ -1862,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" >= 5.0.0
github "JohnEstropia/CoreStore" >= 6.2.1
```
and run
```
@@ -1870,18 +1891,20 @@ carthage update
```
This installs CoreStore as a framework. Declare `import CoreStore` in your swift file to use the library.
#### Install with Swift Package Manager:
```swift
dependencies: [
.package(url: "https://github.com/JohnEstropia/CoreStore.git", from: "6.2.1"))
]
```
Declare `import CoreStore` in your swift file to use the library.
### Install as Git Submodule
```
git submodule add https://github.com/JohnEstropia/CoreStore.git <destination directory>
```
Drag and drop **CoreStore.xcodeproj** to your project.
#### To install as a framework:
Drag and drop **CoreStore.xcodeproj** to your project.
#### To include directly in your app module:
Add all *.swift* files to your project.
### Objective-C support

View File

@@ -29,7 +29,7 @@ import CoreData
// MARK: - BaseDataTransaction
public extension BaseDataTransaction {
extension BaseDataTransaction {
/**
Creates an `ImportableObject` by importing from the specified import source.

View File

@@ -565,7 +565,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
// MARK: Obsoleted
@available(*, obsoleted: 3.1, renamed: "unsafeContext()")
@available(swift, obsoleted: 3.1, renamed: "unsafeContext()")
public func internalContext() -> NSManagedObjectContext {
fatalError()

View File

@@ -29,7 +29,7 @@ import CoreData
// MARK: - CSBaseDataTransaction
public extension CSBaseDataTransaction {
extension CSBaseDataTransaction {
/**
Fetches the `NSManagedObject` instance in the transaction's context from a reference created from a transaction or from a different managed object context.

View File

@@ -29,7 +29,7 @@ import CoreData
// MARK: - CSCoreStore
public extension CSCoreStore {
extension CSCoreStore {
/**
Asynchronously adds a `CSInMemoryStore` to the `defaultStack`. Migrations are also initiated by default.

View File

@@ -30,7 +30,7 @@ import CoreData
// MARK: - CSCoreStore
@available(macOS 10.12, *)
public extension CSCoreStore {
extension CSCoreStore {
/**
Using the `defaultStack`, creates an `CSObjectMonitor` for the specified `NSManagedObject`. Multiple `CSObjectObserver`s may then register themselves to be notified when changes are made to the `NSManagedObject`.

View File

@@ -29,7 +29,7 @@ import CoreData
// MARK: - CSCoreStore
public extension CSCoreStore {
extension CSCoreStore {
/**
Using the `defaultStack`, fetches the `NSManagedObject` instance in the transaction's context from a reference created from a transaction or from a different managed object context.

View File

@@ -29,7 +29,7 @@ import CoreData
// MARK: - CSCoreStore
public extension CSCoreStore {
extension CSCoreStore {
/**
Returns the `defaultStack`'s model version. The version string is the same as the name of the version-specific .xcdatamodeld file.

View File

@@ -28,7 +28,7 @@ import Foundation
// MARK: - CSCoreStore
public extension CSCoreStore {
extension CSCoreStore {
/**
Using the `defaultStack`, begins a transaction asynchronously where `NSManagedObject` creates, updates, and deletes can be made.

View File

@@ -29,7 +29,7 @@ import CoreData
// MARK: - CSDataStack
public extension CSDataStack {
extension CSDataStack {
/**
Asynchronously adds a `CSInMemoryStore` to the stack. Migrations are also initiated by default.

View File

@@ -30,7 +30,7 @@ import CoreData
// MARK: - CSDataStack
@available(macOS 10.12, *)
public extension CSDataStack {
extension CSDataStack {
/**
Creates a `CSObjectMonitor` for the specified `NSManagedObject`. Multiple `ObjectObserver`s may then register themselves to be notified when changes are made to the `NSManagedObject`.
@@ -68,7 +68,7 @@ public 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 @@ public 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 @@ public 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 @@ public extension CSDataStack {
sectionBy: sectionBy.bridgeToSwift,
applyFetchClauses: { (fetchRequest) in
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest as! NSFetchRequest<NSFetchRequestResult>) }
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
},
createAsynchronously: {

View File

@@ -29,7 +29,7 @@ import CoreData
// MARK: - CSDataStack
public extension CSDataStack {
extension CSDataStack {
/**
Fetches the `NSManagedObject` instance in the transaction's context from a reference created from a transaction or from a different managed object context.

View File

@@ -28,7 +28,7 @@ import Foundation
// MARK: - CSDataStack
public extension CSDataStack {
extension CSDataStack {
/**
Begins a transaction asynchronously where `NSManagedObject` creates, updates, and deletes can be made.

View File

@@ -262,7 +262,7 @@ extension CoreStoreError: CoreStoreSwiftType, _ObjectiveCBridgeableError {
// MARK: Internal
internal extension Error {
extension Error {
internal var bridgeToSwift: CoreStoreError {

View File

@@ -495,14 +495,15 @@ public final class CSListMonitor: NSObject {
`refetch(...)` broadcasts `listMonitorWillRefetch(...)` to its observers immediately, and then `listMonitorDidRefetch(...)` after the new fetch request completes.
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses. Note that only specified clauses will be changed; unspecified clauses will use previous values.
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
- Important: Starting CoreStore 4.0, all `CSFetchClause`s required by the `CSListMonitor` should be provided in the arguments list of `refetch(...)`.
*/
@objc
public func refetch(_ fetchClauses: [CSFetchClause]) {
self.bridgeToSwift.refetch { (fetchRequest) in
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest as! NSFetchRequest<NSFetchRequestResult>) }
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
}
}

View File

@@ -195,14 +195,14 @@ public final class CSSQLiteStore: NSObject, CSLocalStorage, CoreStoreObjectiveCT
// MARK: Obsoleted
@available(*, obsoleted: 3.1, message: "The `mappingModelBundles` argument of this method is ignored. Use the new -[CSSQLiteStore initWithFileURL:configuration:localStorageOptions:]) initializer instead.")
@available(swift, obsoleted: 3.1, message: "The `mappingModelBundles` argument of this method is ignored. Use the new -[CSSQLiteStore initWithFileURL:configuration:localStorageOptions:]) initializer instead.")
@objc
public convenience init(fileURL: URL, configuration: ModelConfiguration, mappingModelBundles: [Bundle]?, localStorageOptions: Int) {
fatalError()
}
@available(*, obsoleted: 3.1, message: "The `mappingModelBundles` argument of this method is ignored. Use the new -[CSSQLiteStore initWithFileName:configuration:localStorageOptions:]) initializer instead.")
@available(swift, obsoleted: 3.1, message: "The `mappingModelBundles` argument of this method is ignored. Use the new -[CSSQLiteStore initWithFileName:configuration:localStorageOptions:]) initializer instead.")
@objc
public convenience init(fileName: String, configuration: ModelConfiguration, mappingModelBundles: [Bundle]?, localStorageOptions: Int) {

View File

@@ -1111,7 +1111,7 @@ private func createFormattedString(_ firstLine: String, _ lastLine: String, _ in
return string
}
fileprivate extension String {
extension String {
fileprivate static func indention(_ level: Int = 1) -> String {
@@ -1232,6 +1232,8 @@ extension NSAttributeType: CoreStoreDebugStringConvertible {
case .objectIDAttributeType: return ".objectIDAttributeType"
case .UUIDAttributeType: return ".UUIDAttributeType"
case .URIAttributeType: return ".URIAttributeType"
@unknown default:
fatalError()
}
}
}
@@ -1254,6 +1256,8 @@ extension NSDeleteRule: CoreStoreDebugStringConvertible {
case .nullifyDeleteRule: return ".nullifyDeleteRule"
case .cascadeDeleteRule: return ".cascadeDeleteRule"
case .denyDeleteRule: return ".denyDeleteRule"
@unknown default:
fatalError()
}
}
}
@@ -1282,7 +1286,10 @@ extension NSEntityDescription: CoreStoreDebugStringConvertible {
info.append(("compoundIndexes", self.compoundIndexes))
}
info.append(("uniquenessConstraints", self.uniquenessConstraints))
if #available(macOS 10.11, *) {
info.append(("uniquenessConstraints", self.uniquenessConstraints))
}
return createFormattedString(
"(", ")",
info

View File

@@ -28,7 +28,7 @@ import Foundation
// MARK: - CoreStore
public extension CoreStore {
extension CoreStore {
/**
The `CoreStoreLogger` instance to be used. The default logger is an instance of a `DefaultLogger`.
@@ -66,8 +66,8 @@ public extension CoreStore {
internal static func assert( _ condition: @autoclosure () -> Bool, _ message: @autoclosure () -> String, fileName: StaticString = #file, lineNumber: Int = #line, functionName: StaticString = #function) {
self.logger.assert(
condition,
message: message,
condition(),
message: message(),
fileName: fileName,
lineNumber: lineNumber,
functionName: functionName

View File

@@ -29,7 +29,7 @@ import CoreData
// MARK: - CoreStore
public extension CoreStore {
extension CoreStore {
/**
Asynchronously adds a `StorageInterface` to the `defaultStack`. Migrations are also initiated by default.

View File

@@ -30,7 +30,7 @@ import CoreData
// MARK: - CoreStore
@available(macOS 10.12, *)
public extension CoreStore {
extension CoreStore {
/**
Using the `defaultStack`, creates an `ObjectMonitor` for the specified `DynamicObject`. Multiple `ObjectObserver`s may then register themselves to be notified when changes are made to the `DynamicObject`.

View File

@@ -29,7 +29,7 @@ import CoreData
// MARK: - CoreStore
public extension CoreStore {
extension CoreStore {
/**
Using the `defaultStack`, fetches the `DynamicObject` instance in the `DataStack`'s context from a reference created from a transaction or from a different managed object context.

View File

@@ -29,7 +29,7 @@ import CoreData
// MARK: - CoreStore
public extension CoreStore {
extension CoreStore {
/**
Returns the `defaultStack`'s model version. The version string is the same as the name of a version-specific .xcdatamodeld file or `CoreStoreSchema`.
@@ -152,7 +152,7 @@ public extension CoreStore {
// MARK: Obsolete
@available(*, obsoleted: 3.1, renamed: "entityDescription(for:)")
@available(swift, obsoleted: 3.1, renamed: "entityDescription(for:)")
public static func entityDescriptionForType(_ type: NSManagedObject.Type) -> NSEntityDescription? {
return self.entityDescription(for: type)

View File

@@ -28,7 +28,7 @@ import Foundation
// MARK: - CoreStore
public extension CoreStore {
extension CoreStore {
/**
Using the `defaultStack`, performs a transaction asynchronously where `NSManagedObject` or `CoreStoreObject` creates, updates, and deletes can be made. The changes are commited automatically after the `task` closure returns. On success, the value returned from closure will be the wrapped as `.success(userInfo: T)` in the `completion`'s `Result<T>`. Any errors thrown from inside the `task` will be reported as `.failure(error: CoreStoreError)`. To cancel/rollback changes, call `try transaction.cancel()`, which throws a `CoreStoreError.userCancelled`.

View File

@@ -564,16 +564,4 @@ CORESTORE_EXTERN
CSWhere *_Nonnull CSWherePredicate(NSPredicate *_Nonnull predicate) CORESTORE_RETURNS_RETAINED;
#pragma 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
NS_SWIFT_NAME(CoreStoreFetchRequest)
@interface _CSFetchRequest: NSFetchRequest
@property (nullable, nonatomic, copy, readonly) NSArray<NSPersistentStore *> *safeAffectedStores;
@end
#endif /* CoreStoreBridge_h */

View File

@@ -218,40 +218,3 @@ CSWhere *_Nonnull CSWherePredicate(NSPredicate *_Nonnull predicate) CORESTORE_RE
return [[CSWhere alloc] initWithPredicate:predicate];
}
#pragma mark CoreStoreFetchRequest
@interface _CSFetchRequest ()
@property (nullable, nonatomic, copy) NSArray<NSPersistentStore *> *safeAffectedStores;
@property (nullable, nonatomic, assign) CFArrayRef releaseArray;
@end
@implementation _CSFetchRequest
// MARK: NSFetchRequest
- (void)setAffectedStores:(NSArray<NSPersistentStore *> *_Nullable)affectedStores {
if (NSFoundationVersionNumber < NSFoundationVersionNumber10_0
|| [[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion){ 11, 0, 0 }]) {
self.safeAffectedStores = affectedStores;
[super setAffectedStores:affectedStores];
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 (self.releaseArray != NULL) {
CFRelease(self.releaseArray);
self.releaseArray = NULL;
}
self.safeAffectedStores = affectedStores;
[super setAffectedStores:affectedStores];
self.releaseArray = CFBridgingRetain([super affectedStores]);
}
@end

View File

@@ -332,7 +332,7 @@ public enum CoreStoreErrorCode: Int {
// MARK: - NSError
internal extension NSError {
extension NSError {
// MARK: Internal

View File

@@ -1,41 +0,0 @@
//
// CoreStoreFetchRequest+CoreStore.swift
// CoreStore
//
// Copyright © 2018 John Rommel Estropia
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
import Foundation
import CoreData
// MARK: - CoreStoreFetchRequest
internal extension CoreStoreFetchRequest {
// MARK: Internal
@nonobjc @inline(__always)
internal func dynamicCast<U>() -> NSFetchRequest<U> {
return unsafeBitCast(self, to: NSFetchRequest<U>.self)
}
}

View 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>?
}

View File

@@ -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
}

View File

@@ -29,7 +29,7 @@ import CoreData
// MARK: - CoreStoreObject
public extension CoreStoreObject {
extension CoreStoreObject {
/**
Exposes a `FetchableSource` that can fetch sibling objects of this `CoreStoreObject` instance. This may be the `DataStack`, a `BaseDataTransaction`, the `NSManagedObjectContext` itself, or `nil` if the obejct's parent is already deallocated.

View File

@@ -29,7 +29,7 @@ import Foundation
// MARK: - ValueContainer.Required
public extension ValueContainer.Required {
extension ValueContainer.Required {
/**
Creates a `Where` clause by comparing if a property is equal to a value
@@ -112,7 +112,7 @@ public extension ValueContainer.Required {
// MARK: - ValueContainer.Optional
public extension ValueContainer.Optional {
extension ValueContainer.Optional {
/**
Creates a `Where` clause by comparing if a property is equal to a value
@@ -223,7 +223,7 @@ public extension ValueContainer.Optional {
// MARK: - RelationshipContainer.ToOne
public extension RelationshipContainer.ToOne {
extension RelationshipContainer.ToOne {
/**
Creates a `Where` clause by comparing if a property is equal to a value

View File

@@ -140,7 +140,7 @@ open /*abstract*/ class CoreStoreObject: DynamicObject, Hashable {
// MARK: - DynamicObject where Self: CoreStoreObject
public extension DynamicObject where Self: CoreStoreObject {
extension DynamicObject where Self: CoreStoreObject {
/**
Returns the `PartialObject` instance for the object, which acts as a fast, type-safe KVC interface for `CoreStoreObject`.

View File

@@ -450,15 +450,18 @@ public final class CoreStoreSchema: DynamicSchema {
)
}
for (entity, entityDescription) in entityDescriptionsByEntity {
let uniqueConstraints = entity.uniqueConstraints.filter({ !$0.isEmpty })
if !uniqueConstraints.isEmpty {
if #available(macOS 10.11, *) {
CoreStore.assert(
entityDescription.superentity == nil,
"Uniqueness constraints must be defined at the highest level possible."
)
entityDescription.uniquenessConstraints = entity.uniqueConstraints.map { $0.map { $0 as NSString } }
let uniqueConstraints = entity.uniqueConstraints.filter({ !$0.isEmpty })
if !uniqueConstraints.isEmpty {
CoreStore.assert(
entityDescription.superentity == nil,
"Uniqueness constraints must be defined at the highest level possible."
)
entityDescription.uniquenessConstraints = entity.uniqueConstraints.map { $0.map { $0 as NSString } }
}
}
guard !entity.indexes.isEmpty else {
@@ -525,7 +528,14 @@ public final class CoreStoreSchema: DynamicSchema {
return CoreStoreManagedObject.self
}
let managedObjectClass: AnyClass = className.withCString {
// Xcode 10.1+ users: You may find this comment due to a crash while debugging on an iPhone XR device (or any A12 device).
// This is a known issue that should not occur in archived builds, as the AppStore strips away arm64e build architectures from the binary. So while it crashes on DEBUG, it shouldn't be an issue for live users.
// In the meantime, please submit a bug report to Apple and refer to similar discussions here:
// - https://github.com/realm/realm-cocoa/issues/6013
// - https://github.com/wordpress-mobile/WordPress-iOS/pull/10400
// - https://github.com/JohnEstropia/CoreStore/issues/291
// If you wish to debug with A12 devices, please use Xcode 10.0 for now.
return objc_allocateClassPair(superClass, $0, 0)!
}
defer {

View File

@@ -29,7 +29,7 @@ import CoreData
// MARK: - DataStack
public extension DataStack {
extension DataStack {
/**
Asynchronously adds a `StorageInterface` to the stack. Migrations are also initiated by default.
@@ -749,7 +749,16 @@ public extension DataStack {
}
}
let fileManager = FileManager.default
let temporaryDirectoryURL = fileManager.temporaryDirectory
let systemTemporaryDirectoryURL: URL
if #available(macOS 10.12, *) {
systemTemporaryDirectoryURL = fileManager.temporaryDirectory
}
else {
systemTemporaryDirectoryURL = URL(fileURLWithPath: NSTemporaryDirectory())
}
let temporaryDirectoryURL = systemTemporaryDirectoryURL
.appendingPathComponent(Bundle.main.bundleIdentifier ?? "com.CoreStore.DataStack")
.appendingPathComponent(ProcessInfo().globallyUniqueString)
@@ -837,7 +846,7 @@ public extension DataStack {
// MARK: - FilePrivate
fileprivate extension Array where Element == SchemaMappingProvider {
extension Array where Element == SchemaMappingProvider {
func findMapping(sourceSchema: DynamicSchema, destinationSchema: DynamicSchema, storage: LocalStorage) throws -> (mappingModel: NSMappingModel, migrationType: MigrationType) {

View File

@@ -30,7 +30,7 @@ import CoreData
// MARK: - DataStack
@available(macOS 10.12, *)
public extension DataStack {
extension DataStack {
/**
Creates an `ObjectMonitor` for the specified `DynamicObject`. Multiple `ObjectObserver`s may then register themselves to be notified when changes are made to the `DynamicObject`.

View File

@@ -511,7 +511,7 @@ extension DataStack: FetchableSource, QueryableSource {
// MARK: Obsoleted
@available(*, obsoleted: 3.1, renamed: "unsafeContext()")
@available(swift, obsoleted: 3.1, renamed: "unsafeContext()")
public func internalContext() -> NSManagedObjectContext {
fatalError()

View File

@@ -29,7 +29,7 @@ import CoreData
// MARK: - DataStack
public extension DataStack {
extension DataStack {
/**
Performs a transaction asynchronously where `NSManagedObject` or `CoreStoreObject` creates, updates, and deletes can be made. The changes are commited automatically after the `task` closure returns. On success, the value returned from closure will be the wrapped as `.success(userInfo: T)` in the `completion`'s `Result<T>`. Any errors thrown from inside the `task` will be reported as `.failure(error: CoreStoreError)`. To cancel/rollback changes, call `try transaction.cancel()`, which throws a `CoreStoreError.userCancelled`.

View File

@@ -656,13 +656,13 @@ public final class DataStack: Equatable {
// MARK: Obsolete
@available(*, obsoleted: 3.1, renamed: "entityDescription(for:)")
@available(swift, obsoleted: 3.1, renamed: "entityDescription(for:)")
public func entityDescriptionForType(_ type: NSManagedObject.Type) -> NSEntityDescription? {
return self.entityDescription(for: type)
}
@available(*, obsoleted: 3.1, renamed: "objectID(forURIRepresentation:)")
@available(swift, obsoleted: 3.1, renamed: "objectID(forURIRepresentation:)")
public func objectIDForURIRepresentation(_ url: URL) -> NSManagedObjectID? {
return self.objectID(forURIRepresentation: url)

View File

@@ -28,7 +28,7 @@ import Foundation
// MARK: - DispatchQueue
internal extension DispatchQueue {
extension DispatchQueue {
@nonobjc @inline(__always)
internal static func serial(_ label: String, qos: DispatchQoS = .default) -> DispatchQueue {

View File

@@ -24,6 +24,7 @@
//
import Foundation
import CoreData
// MARK: - AnyDynamicKeyPath
@@ -47,7 +48,7 @@ public protocol DynamicKeyPath: AnyDynamicKeyPath {
/**
The DynamicObject type
*/
associatedtype ObjectType
associatedtype ObjectType: DynamicObject
/**
The Value type
@@ -58,7 +59,7 @@ public protocol DynamicKeyPath: AnyDynamicKeyPath {
// MARK: - KeyPathString
public extension KeyPathString {
extension KeyPathString {
/**
Extracts the keyPath string from the property.
@@ -66,7 +67,7 @@ public extension KeyPathString {
let keyPath = String(keyPath: \Person.nickname)
```
*/
public init<O: NSManagedObject, V>(keyPath: KeyPath<O, V>) {
public init<O: NSManagedObject, V: AllowedObjectiveCKeyPathValue>(keyPath: KeyPath<O, V>) {
self = keyPath.cs_keyPathString
}
@@ -78,21 +79,27 @@ public extension KeyPathString {
```
*/
public init<O: CoreStoreObject, K: DynamicKeyPath>(keyPath: KeyPath<O, K>) {
self = O.meta[keyPath: keyPath].cs_keyPathString
}
/**
Extracts the keyPath string from the property.
```
let keyPath = String(keyPath: \Person.nickname)
```
*/
public init<O: DynamicObject, T, V>(keyPath: Where<O>.Expression<T, V>) {
self = keyPath.cs_keyPathString
}
}
// MARK: - KeyPath: DynamicKeyPath
// TODO: SE-0143 (https://github.com/apple/swift-evolution/blob/master/proposals/0143-conditional-conformances.md) is implemented but multiple conformances for the same type currently cannot be declared.
//extension KeyPath: DynamicKeyPath where Root: NSManagedObject, Value: ImportableAttributeType
//extension KeyPath: DynamicKeyPath where Root: NSManagedObject, Value: ImportableAttributeType?
//extension KeyPath: DynamicKeyPath where Root: NSManagedObject, Value: NSManagedObject?
//extension KeyPath: DynamicKeyPath where Root: NSManagedObject, Value: NSSet
//extension KeyPath: DynamicKeyPath where Root: NSManagedObject, Value: NSOrderedSet
extension KeyPath: DynamicKeyPath {
extension KeyPath: DynamicKeyPath, AnyDynamicKeyPath where Root: DynamicObject, Value: AllowedObjectiveCKeyPathValue {
public typealias ObjectType = Root
public typealias ValueType = Value

View File

@@ -24,6 +24,7 @@
//
import Foundation
import CoreData
// MARK: - DynamicObject

View File

@@ -29,7 +29,7 @@ import Foundation
// MARK: - DynamicSchema
public extension DynamicSchema {
extension DynamicSchema {
/**
Prints the `DynamicSchema` as their corresponding `CoreStoreObject` Swift declarations. This is useful for converting current `XcodeDataModelSchema`-based models into the new `CoreStoreSchema` framework. Additional adjustments may need to be done to the generated source code; for example: `Transformable` concrete types need to be provided, as well as `default` values.

View File

@@ -70,7 +70,8 @@ public final class Entity<O: CoreStoreObject>: DynamicEntity {
- parameter indexes: the compound indexes for the entity as an array of arrays. The arrays contained in the returned array contain `KeyPath`s to properties of the entity.
- parameter uniqueConstraints: sets uniqueness constraints for the entity. A uniqueness constraint is a set of one or more `KeyPath`s whose value must be unique over the set of instances of that entity. This value forms part of the entity's version hash. Uniqueness constraint violations can be computationally expensive to handle. It is highly suggested that there be only one uniqueness constraint per entity hierarchy. Uniqueness constraints must be defined at the highest level possible, and CoreStore will raise an assertion failure if unique constraints are added to a sub entity.
*/
public convenience init(_ entityName: String, isAbstract: Bool = false, versionHashModifier: String? = nil, indexes: [[PartialKeyPath<O>]] = [], uniqueConstraints: [[PartialKeyPath<O>]] = []) {
@available(macOS 10.11, *)
public convenience init(_ entityName: String, isAbstract: Bool = false, versionHashModifier: String? = nil, indexes: [[PartialKeyPath<O>]] = [], uniqueConstraints: [[PartialKeyPath<O>]]) {
self.init(
O.self,
@@ -81,6 +82,27 @@ public final class Entity<O: CoreStoreObject>: DynamicEntity {
uniqueConstraints: uniqueConstraints
)
}
/**
Initializes an `Entity`. Always provide a concrete generic type to `Entity`.
```
Entity<Animal>("Animal")
```
- parameter entityName: the `NSEntityDescription` name to use for the entity
- parameter isAbstract: set to `true` if the entity is meant to be an abstract class and can only be initialized with subclass types.
- parameter versionHashModifier: the version hash modifier for the entity. Used to mark or denote an entity as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where, for example, the structure of an entity is unchanged but the format or content of data has changed.)
- parameter indexes: the compound indexes for the entity as an array of arrays. The arrays contained in the returned array contain `KeyPath`s to properties of the entity.
*/
public convenience init(_ entityName: String, isAbstract: Bool = false, versionHashModifier: String? = nil, indexes: [[PartialKeyPath<O>]] = []) {
self.init(
O.self,
entityName,
isAbstract: isAbstract,
versionHashModifier: versionHashModifier,
indexes: indexes
)
}
/**
Initializes an `Entity`.
@@ -94,7 +116,8 @@ public final class Entity<O: CoreStoreObject>: DynamicEntity {
- parameter indexes: the compound indexes for the entity as an array of arrays. The arrays contained in the returned array contain KeyPath's to properties of the entity.
- parameter uniqueConstraints: sets uniqueness constraints for the entity. A uniqueness constraint is a set of one or more `KeyPath`s whose value must be unique over the set of instances of that entity. This value forms part of the entity's version hash. Uniqueness constraint violations can be computationally expensive to handle. It is highly suggested that there be only one uniqueness constraint per entity hierarchy. Uniqueness constraints must be defined at the highest level possible, and CoreStore will raise an assertion failure if unique constraints are added to a sub entity.
*/
public init(_ type: O.Type, _ entityName: String, isAbstract: Bool = false, versionHashModifier: String? = nil, indexes: [[PartialKeyPath<O>]] = [], uniqueConstraints: [[PartialKeyPath<O>]] = []) {
@available(macOS 10.11, *)
public init(_ type: O.Type, _ entityName: String, isAbstract: Bool = false, versionHashModifier: String? = nil, indexes: [[PartialKeyPath<O>]] = [], uniqueConstraints: [[PartialKeyPath<O>]]) {
let meta = O.meta
let toStringArray: ([PartialKeyPath<O>]) -> [KeyPathString] = {
@@ -113,6 +136,38 @@ public final class Entity<O: CoreStoreObject>: DynamicEntity {
uniqueConstraints: uniqueConstraints.map(toStringArray)
)
}
/**
Initializes an `Entity`.
```
Entity(Animal.self, "Animal")
```
- parameter type: the `DynamicObject` type associated with the entity
- parameter entityName: the `NSEntityDescription` name to use for the entity
- parameter isAbstract: set to `true` if the entity is meant to be an abstract class and can only be initialized with subclass types.
- parameter versionHashModifier: the version hash modifier for the entity. Used to mark or denote an entity as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where, for example, the structure of an entity is unchanged but the format or content of data has changed.)
- parameter indexes: the compound indexes for the entity as an array of arrays. The arrays contained in the returned array contain KeyPath's to properties of the entity.
- parameter uniqueConstraints: sets uniqueness constraints for the entity. A uniqueness constraint is a set of one or more `KeyPath`s whose value must be unique over the set of instances of that entity. This value forms part of the entity's version hash. Uniqueness constraint violations can be computationally expensive to handle. It is highly suggested that there be only one uniqueness constraint per entity hierarchy. Uniqueness constraints must be defined at the highest level possible, and CoreStore will raise an assertion failure if unique constraints are added to a sub entity.
*/
public init(_ type: O.Type, _ entityName: String, isAbstract: Bool = false, versionHashModifier: String? = nil, indexes: [[PartialKeyPath<O>]] = []) {
let meta = O.meta
let toStringArray: ([PartialKeyPath<O>]) -> [KeyPathString] = {
return $0.map {
return (meta[keyPath: $0] as! AnyDynamicKeyPath).cs_keyPathString
}
}
super.init(
type: type,
entityName: entityName,
isAbstract: isAbstract,
versionHashModifier: versionHashModifier,
indexes: indexes.map(toStringArray),
uniqueConstraints: []
)
}
}

View File

@@ -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>()
}

View File

@@ -29,7 +29,7 @@ import CoreData
// MARK: - From
public extension From {
extension From {
/**
Creates a `FetchChainBuilder` that starts with the specified `Where` clause
@@ -65,6 +65,17 @@ public extension From {
return self.fetchChain(appending: Where<D>(format, argumentArray: argumentArray))
}
/**
Creates a `FetchChainBuilder` that starts with the specified `OrderBy` clause.
- parameter clause: the `OrderBy` clause to create a `FetchChainBuilder` with
- returns: a `FetchChainBuilder` that starts with the specified `OrderBy` clause
*/
public func orderBy(_ clause: OrderBy<D>) -> FetchChainBuilder<D> {
return self.fetchChain(appending: clause)
}
/**
Creates a `FetchChainBuilder` with a series of `SortKey`s
@@ -77,6 +88,17 @@ public extension From {
return self.fetchChain(appending: OrderBy<D>([sortKey] + sortKeys))
}
/**
Creates a `FetchChainBuilder` with a series of `SortKey`s
- parameter sortKeys: a series of `SortKey`s
- returns: a `FetchChainBuilder` with a series of `SortKey`s
*/
public func orderBy(_ sortKeys: [OrderBy<D>.SortKey]) -> FetchChainBuilder<D> {
return self.fetchChain(appending: OrderBy<D>(sortKeys))
}
/**
Creates a `FetchChainBuilder` with a closure where the `NSFetchRequest` may be configured
@@ -218,7 +240,7 @@ public extension From {
// MARK: - From where D: NSManagedObject
public extension From where D: NSManagedObject {
extension From where D: NSManagedObject {
/**
Creates a `QueryChainBuilder` that starts with a `Select` clause created from the specified key path
@@ -261,7 +283,7 @@ public extension From where D: NSManagedObject {
// MARK: - From where D: CoreStoreObject
public extension From where D: CoreStoreObject {
extension From where D: CoreStoreObject {
/**
Creates a `FetchChainBuilder` that starts with the specified `Where` clause
@@ -431,7 +453,7 @@ public extension From where D: CoreStoreObject {
// MARK: - FetchChainBuilder
public extension FetchChainBuilder {
extension FetchChainBuilder {
/**
Adds a `Where` clause to the `FetchChainBuilder`
@@ -467,6 +489,17 @@ public extension FetchChainBuilder {
return self.fetchChain(appending: Where<D>(format, argumentArray: argumentArray))
}
/**
Adds an `OrderBy` clause to the `FetchChainBuilder`
- parameter clause: the `OrderBy` clause to add
- returns: a new `FetchChainBuilder` containing the `OrderBy` clause
*/
public func orderBy(_ clause: OrderBy<D>) -> FetchChainBuilder<D> {
return self.fetchChain(appending: clause)
}
/**
Adds an `OrderBy` clause to the `FetchChainBuilder`
@@ -479,6 +512,17 @@ public extension FetchChainBuilder {
return self.fetchChain(appending: OrderBy<D>([sortKey] + sortKeys))
}
/**
Adds an `OrderBy` clause to the `FetchChainBuilder`
- parameter sortKeys: a series of `SortKey`s
- returns: a new `FetchChainBuilder` containing the `OrderBy` clause
*/
public func orderBy(_ sortKeys: [OrderBy<D>.SortKey]) -> FetchChainBuilder<D> {
return self.fetchChain(appending: OrderBy<D>(sortKeys))
}
/**
Adds a `Tweak` clause to the `FetchChainBuilder` with a closure where the `NSFetchRequest` may be configured
@@ -536,7 +580,7 @@ public extension FetchChainBuilder {
// MARK: - FetchChainBuilder where D: CoreStoreObject
public extension FetchChainBuilder where D: CoreStoreObject {
extension FetchChainBuilder where D: CoreStoreObject {
public func `where`<T: AnyWhereClause>(_ clause: (D) -> T) -> FetchChainBuilder<D> {
@@ -547,7 +591,7 @@ public extension FetchChainBuilder where D: CoreStoreObject {
// MARK: - QueryChainBuilder
public extension QueryChainBuilder {
extension QueryChainBuilder {
/**
Adds a `Where` clause to the `QueryChainBuilder`
@@ -583,6 +627,17 @@ public extension QueryChainBuilder {
return self.queryChain(appending: Where<D>(format, argumentArray: argumentArray))
}
/**
Adds an `OrderBy` clause to the `QueryChainBuilder`
- parameter clause: the `OrderBy` clause to add
- returns: a new `QueryChainBuilder` containing the `OrderBy` clause
*/
public func orderBy(_ clause: OrderBy<D>) -> QueryChainBuilder<D, R> {
return self.queryChain(appending: clause)
}
/**
Adds an `OrderBy` clause to the `QueryChainBuilder`
@@ -595,6 +650,17 @@ public extension QueryChainBuilder {
return self.queryChain(appending: OrderBy<D>([sortKey] + sortKeys))
}
/**
Adds an `OrderBy` clause to the `QueryChainBuild`
- parameter sortKeys: a series of `SortKey`s
- returns: a new `QueryChainBuilder` containing the `OrderBy` clause
*/
public func orderBy(_ sortKeys: [OrderBy<D>.SortKey]) -> QueryChainBuilder<D, R> {
return self.queryChain(appending: OrderBy<D>(sortKeys))
}
/**
Adds a `Tweak` clause to the `QueryChainBuilder` with a closure where the `NSFetchRequest` may be configured
@@ -688,7 +754,7 @@ public extension QueryChainBuilder {
// MARK: - QueryChainBuilder where D: NSManagedObject
public extension QueryChainBuilder where D: NSManagedObject {
extension QueryChainBuilder where D: NSManagedObject {
/**
Adds a `GroupBy` clause to the `QueryChainBuilder`
@@ -705,7 +771,7 @@ public extension QueryChainBuilder where D: NSManagedObject {
// MARK: - QueryChainBuilder where D: CoreStoreObject
public extension QueryChainBuilder where D: CoreStoreObject {
extension QueryChainBuilder where D: CoreStoreObject {
/**
Adds a `Where` clause to the `QueryChainBuilder`
@@ -767,7 +833,7 @@ public extension QueryChainBuilder where D: CoreStoreObject {
// MARK: - SectionMonitorChainBuilder
@available(macOS 10.12, *)
public extension SectionMonitorChainBuilder {
extension SectionMonitorChainBuilder {
/**
Adds a `Where` clause to the `SectionMonitorChainBuilder`
@@ -803,6 +869,17 @@ public extension SectionMonitorChainBuilder {
return self.sectionMonitorChain(appending: Where<D>(format, argumentArray: argumentArray))
}
/**
Adds an `OrderBy` clause to the `SectionMonitorChainBuilder`
- parameter clause: the `OrderBy` clause to add
- returns: a new `SectionMonitorChainBuilder` containing the `OrderBy` clause
*/
public func orderBy(_ clause: OrderBy<D>) -> SectionMonitorChainBuilder<D> {
return self.sectionMonitorChain(appending: clause)
}
/**
Adds an `OrderBy` clause to the `SectionMonitorChainBuilder`
@@ -815,6 +892,17 @@ public extension SectionMonitorChainBuilder {
return self.sectionMonitorChain(appending: OrderBy<D>([sortKey] + sortKeys))
}
/**
Adds an `OrderBy` clause to the `SectionMonitorChainBuilder`
- parameter sortKeys: a series of `SortKey`s
- returns: a new `SectionMonitorChainBuilder` containing the `OrderBy` clause
*/
public func orderBy(_ sortKeys: [OrderBy<D>.SortKey]) -> SectionMonitorChainBuilder<D> {
return self.sectionMonitorChain(appending: OrderBy<D>(sortKeys))
}
/**
Adds a `Tweak` clause to the `SectionMonitorChainBuilder` with a closure where the `NSFetchRequest` may be configured
@@ -875,7 +963,7 @@ public extension SectionMonitorChainBuilder {
// MARK: - SectionMonitorChainBuilder where D: CoreStoreObject
@available(macOS 10.12, *)
public extension SectionMonitorChainBuilder where D: CoreStoreObject {
extension SectionMonitorChainBuilder where D: CoreStoreObject {
/**
Adds a `Where` clause to the `SectionMonitorChainBuilder`

View File

@@ -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

View File

@@ -103,7 +103,7 @@ public struct GroupBy<D: DynamicObject>: GroupByClause, QueryClause, Hashable {
}
}
public extension GroupBy where D: NSManagedObject {
extension GroupBy where D: NSManagedObject {
/**
Initializes a `GroupBy` clause with a key path
@@ -116,7 +116,7 @@ public extension GroupBy where D: NSManagedObject {
}
}
public extension GroupBy where D: CoreStoreObject {
extension GroupBy where D: CoreStoreObject {
/**
Initializes a `GroupBy` clause with a key path

View File

@@ -554,7 +554,7 @@ public final class ICloudStore: CloudStorage, CustomDebugStringConvertible, Core
// MARK: - Notification Keys
fileprivate extension Notification.Name {
extension Notification.Name {
fileprivate static let iCloudUbiquitousStoreWillFinishInitialImport = Notification.Name(rawValue: "iCloudUbiquitousStoreWillFinishInitialImport")
fileprivate static let iCloudUbiquitousStoreDidFinishInitialImport = Notification.Name(rawValue: "iCloudUbiquitousStoreDidFinishInitialImport")

View File

@@ -80,9 +80,9 @@ public protocol ImportableObject: DynamicObject {
// MARK: - ImportableObject (Default Implementations)
public extension ImportableObject {
extension ImportableObject {
static func shouldInsert(from source: ImportSource, in transaction: BaseDataTransaction) -> Bool {
public static func shouldInsert(from source: ImportSource, in transaction: BaseDataTransaction) -> Bool {
return true
}
@@ -90,14 +90,14 @@ public extension ImportableObject {
// MARK: Obsolete
@available(*, obsoleted: 3.0.0, renamed: "shouldInsert(from:in:)")
static func shouldInsertFromImportSource(_ source: ImportSource, inTransaction transaction: BaseDataTransaction) -> Bool {
@available(swift, obsoleted: 3.0.0, renamed: "shouldInsert(from:in:)")
public static func shouldInsertFromImportSource(_ source: ImportSource, inTransaction transaction: BaseDataTransaction) -> Bool {
return Self.shouldInsert(from: source, in: transaction)
}
@available(*, obsoleted: 3.0.0, renamed: "didInsert(from:in:)")
func didInsertFromImportSource(_ source: ImportSource, inTransaction transaction: BaseDataTransaction) throws {
@available(swift, obsoleted: 3.0.0, renamed: "didInsert(from:in:)")
public func didInsertFromImportSource(_ source: ImportSource, inTransaction transaction: BaseDataTransaction) throws {
try self.didInsert(from: source, in: transaction)
}

View File

@@ -116,11 +116,11 @@ public protocol ImportableUniqueObject: ImportableObject {
}
// MARK: - ImportableUniqueObject (Default Implementations)
// MARK: - ImportableUniqueObject where UniqueIDType.QueryableNativeType: CoreDataNativeType
public extension ImportableUniqueObject where UniqueIDType.QueryableNativeType: CoreDataNativeType {
extension ImportableUniqueObject where UniqueIDType.QueryableNativeType: CoreDataNativeType {
var uniqueIDValue: UniqueIDType {
public var uniqueIDValue: UniqueIDType {
get {
@@ -141,19 +141,22 @@ public extension ImportableUniqueObject where UniqueIDType.QueryableNativeType:
}
}
public extension ImportableUniqueObject {
// MARK: - ImportableUniqueObject
extension ImportableUniqueObject {
static func shouldInsert(from source: ImportSource, in transaction: BaseDataTransaction) -> Bool {
public static func shouldInsert(from source: ImportSource, in transaction: BaseDataTransaction) -> Bool {
return Self.shouldUpdate(from: source, in: transaction)
}
static func shouldUpdate(from source: ImportSource, in transaction: BaseDataTransaction) -> Bool{
public static func shouldUpdate(from source: ImportSource, in transaction: BaseDataTransaction) -> Bool{
return true
}
func didInsert(from source: Self.ImportSource, in transaction: BaseDataTransaction) throws {
public func didInsert(from source: Self.ImportSource, in transaction: BaseDataTransaction) throws {
try self.update(from: source, in: transaction)
}
@@ -161,32 +164,32 @@ public extension ImportableUniqueObject {
// MARK: Obsolete
@available(*, obsoleted: 3.1, renamed: "shouldInsert(from:in:)")
static func shouldInsertFromImportSource(_ source: ImportSource, inTransaction transaction: BaseDataTransaction) -> Bool {
@available(swift, obsoleted: 3.1, renamed: "shouldInsert(from:in:)")
public static func shouldInsertFromImportSource(_ source: ImportSource, inTransaction transaction: BaseDataTransaction) -> Bool {
return Self.shouldInsert(from: source, in: transaction)
}
@available(*, obsoleted: 3.1, renamed: "shouldUpdate(from:in:)")
static func shouldUpdateFromImportSource(_ source: ImportSource, inTransaction transaction: BaseDataTransaction) -> Bool {
@available(swift, obsoleted: 3.1, renamed: "shouldUpdate(from:in:)")
public static func shouldUpdateFromImportSource(_ source: ImportSource, inTransaction transaction: BaseDataTransaction) -> Bool {
return Self.shouldUpdate(from: source, in: transaction)
}
@available(*, obsoleted: 3.1, renamed: "uniqueID(from:in:)")
static func uniqueIDFromImportSource(_ source: ImportSource, inTransaction transaction: BaseDataTransaction) throws -> UniqueIDType? {
@available(swift, obsoleted: 3.1, renamed: "uniqueID(from:in:)")
public static func uniqueIDFromImportSource(_ source: ImportSource, inTransaction transaction: BaseDataTransaction) throws -> UniqueIDType? {
return try Self.uniqueID(from: source, in: transaction)
}
@available(*, obsoleted: 3.1, renamed: "didInsert(from:in:)")
func didInsertFromImportSource(_ source: ImportSource, inTransaction transaction: BaseDataTransaction) throws {
@available(swift, obsoleted: 3.1, renamed: "didInsert(from:in:)")
public func didInsertFromImportSource(_ source: ImportSource, inTransaction transaction: BaseDataTransaction) throws {
try self.didInsert(from: source, in: transaction)
}
@available(*, obsoleted: 3.1, renamed: "update(from:in:)")
func updateFromImportSource(_ source: ImportSource, inTransaction transaction: BaseDataTransaction) throws {
@available(swift, obsoleted: 3.1, renamed: "update(from:in:)")
public func updateFromImportSource(_ source: ImportSource, inTransaction transaction: BaseDataTransaction) throws {
try self.update(from: source, in: transaction)
}

View File

@@ -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>

View File

@@ -0,0 +1,140 @@
//
// KeyPathGenericBindings.swift
// CoreStore
//
// Copyright © 2018 John Rommel Estropia
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
import Foundation
import CoreGraphics
import CoreData
// MARK: - AllowedObjectiveCKeyPathValue
/**
Used only for utility methods. Types allowed as `Value` generic type to `KeyPath` utilities.
*/
public protocol AllowedObjectiveCKeyPathValue {}
// MARK: - AllowedOptionalObjectiveCKeyPathValue
/**
Used only for utility methods. Types allowed as `Value` generic type to `KeyPath` utilities.
*/
public protocol AllowedOptionalObjectiveCKeyPathValue: AllowedObjectiveCKeyPathValue {}
extension Bool: AllowedObjectiveCKeyPathValue {}
extension CGFloat: AllowedObjectiveCKeyPathValue {}
extension Data: AllowedOptionalObjectiveCKeyPathValue {}
extension Date: AllowedOptionalObjectiveCKeyPathValue {}
extension Double: AllowedObjectiveCKeyPathValue {}
extension Float: AllowedObjectiveCKeyPathValue {}
extension Int: AllowedObjectiveCKeyPathValue {}
extension Int8: AllowedObjectiveCKeyPathValue {}
extension Int16: AllowedObjectiveCKeyPathValue {}
extension Int32: AllowedObjectiveCKeyPathValue {}
extension Int64: AllowedObjectiveCKeyPathValue {}
extension NSData: AllowedOptionalObjectiveCKeyPathValue {}
extension NSDate: AllowedOptionalObjectiveCKeyPathValue {}
extension NSManagedObject: AllowedOptionalObjectiveCKeyPathValue {}
extension NSNumber: AllowedOptionalObjectiveCKeyPathValue {}
extension NSString: AllowedOptionalObjectiveCKeyPathValue {}
extension NSSet: AllowedOptionalObjectiveCKeyPathValue {}
extension NSOrderedSet: AllowedOptionalObjectiveCKeyPathValue {}
extension NSURL: AllowedOptionalObjectiveCKeyPathValue {}
extension NSUUID: AllowedOptionalObjectiveCKeyPathValue {}
extension String: AllowedOptionalObjectiveCKeyPathValue {}
extension URL: AllowedOptionalObjectiveCKeyPathValue {}
extension UUID: AllowedOptionalObjectiveCKeyPathValue {}
extension Optional: AllowedObjectiveCKeyPathValue where Wrapped: AllowedOptionalObjectiveCKeyPathValue {}
// MARK: - AllowedObjectiveCCollectionKeyPathValue
/**
Used only for utility methods. Types allowed as `Value` generic type to `KeyPath` utilities.
*/
public protocol AllowedObjectiveCCollectionKeyPathValue: AllowedOptionalObjectiveCKeyPathValue {}
extension NSSet: AllowedObjectiveCCollectionKeyPathValue {}
extension NSOrderedSet: AllowedObjectiveCCollectionKeyPathValue {}
extension Optional: AllowedObjectiveCCollectionKeyPathValue, AllowedOptionalObjectiveCKeyPathValue where Wrapped: AllowedObjectiveCCollectionKeyPathValue {}
// MARK: - AllowedCoreStoreObjectKeyPathValue
/**
Used only for utility methods. Types allowed as `Value` generic type to `KeyPath` utilities.
*/
public protocol AllowedCoreStoreObjectKeyPathValue: DynamicKeyPath {}
extension ValueContainer.Required: AllowedCoreStoreObjectKeyPathValue {}
extension ValueContainer.Optional: AllowedCoreStoreObjectKeyPathValue {}
extension TransformableContainer.Required: AllowedCoreStoreObjectKeyPathValue {}
extension TransformableContainer.Optional: AllowedCoreStoreObjectKeyPathValue {}
extension RelationshipContainer.ToOne: AllowedCoreStoreObjectKeyPathValue {}
extension RelationshipContainer.ToManyOrdered: AllowedCoreStoreObjectKeyPathValue {}
extension RelationshipContainer.ToManyUnordered: AllowedCoreStoreObjectKeyPathValue {}
// MARK: - AllowedCoreStoreObjectCollectionKeyPathValue
/**
Used only for utility methods. Types allowed as `Value` generic type to `KeyPath` utilities.
*/
public protocol AllowedCoreStoreObjectCollectionKeyPathValue: AllowedCoreStoreObjectKeyPathValue {}
extension RelationshipContainer.ToManyOrdered: AllowedCoreStoreObjectCollectionKeyPathValue {}
extension RelationshipContainer.ToManyUnordered: AllowedCoreStoreObjectCollectionKeyPathValue {}

View File

@@ -32,22 +32,22 @@ import CoreData
/**
A storage interface backed by an SQLite database that was created before CoreStore 2.0.0.
*/
@available(*, obsoleted: 3.1, message: "`LegacySQLiteStore` previous users should now use `SQLiteStore`'s new SQLiteStore.legacy(fileName:configuration:migrationMappingProviders:localStorageOptions:) or SQLiteStore.legacy() methods to create an `SQLiteStore` with legacy paths.")
@available(swift, obsoleted: 3.1, message: "`LegacySQLiteStore` previous users should now use `SQLiteStore`'s new SQLiteStore.legacy(fileName:configuration:migrationMappingProviders:localStorageOptions:) or SQLiteStore.legacy() methods to create an `SQLiteStore` with legacy paths.")
public final class LegacySQLiteStore: LocalStorage {
@available(*, obsoleted: 3.1, message: "Use `SQLiteStore`'s new SQLiteStore.init(fileURL:configuration:migrationMappingProviders:localStorageOptions:) initializer.")
@available(swift, obsoleted: 3.1, message: "Use `SQLiteStore`'s new SQLiteStore.init(fileURL:configuration:migrationMappingProviders:localStorageOptions:) initializer.")
public init(fileURL: URL, configuration: ModelConfiguration = nil, mappingModelBundles: [Bundle] = Bundle.allBundles, localStorageOptions: LocalStorageOptions = nil) {
fatalError()
}
@available(*, obsoleted: 3.1, message: "Use `SQLiteStore`'s new SQLiteStore.legacy(fileName:configuration:migrationMappingProviders:localStorageOptions:) factory method.")
@available(swift, obsoleted: 3.1, message: "Use `SQLiteStore`'s new SQLiteStore.legacy(fileName:configuration:migrationMappingProviders:localStorageOptions:) factory method.")
public init(fileName: String, configuration: ModelConfiguration = nil, mappingModelBundles: [Bundle] = Bundle.allBundles, localStorageOptions: LocalStorageOptions = nil) {
fatalError()
}
@available(*, obsoleted: 3.1, message: "Use `SQLiteStore`'s new SQLiteStore.legacy(...) factory method.")
@available(swift, obsoleted: 3.1, message: "Use `SQLiteStore`'s new SQLiteStore.legacy(...) factory method.")
public init() {
fatalError()

View File

@@ -90,7 +90,7 @@ public final class ListMonitor<D: DynamicObject>: Hashable {
)
if self.isSectioned {
return ObjectType.cs_fromRaw(object: self.fetchedResultsController.fetchedObjects![index])
return ObjectType.cs_fromRaw(object: (self.fetchedResultsController.fetchedObjects as NSArray?)![index] as! NSManagedObject)
}
return self[0, index]
}
@@ -105,10 +105,10 @@ public final class ListMonitor<D: DynamicObject>: Hashable {
if self.isSectioned {
let fetchedObjects = self.fetchedResultsController.fetchedObjects!
let fetchedObjects = (self.fetchedResultsController.fetchedObjects as NSArray?)!
if index < fetchedObjects.count && index >= 0 {
return ObjectType.cs_fromRaw(object: fetchedObjects[index])
return ObjectType.cs_fromRaw(object: fetchedObjects[index] as! NSManagedObject)
}
return nil
}
@@ -353,7 +353,7 @@ public final class ListMonitor<D: DynamicObject>: Hashable {
)
if self.isSectioned {
return self.fetchedResultsController.fetchedObjects?.index(of: object.cs_toRaw())
return (self.fetchedResultsController.fetchedObjects as NSArray?)?.index(of: object.cs_toRaw())
}
return self.fetchedResultsController.indexPath(forObject: object.cs_toRaw())?[1]
}
@@ -555,7 +555,8 @@ public final class ListMonitor<D: DynamicObject>: Hashable {
`refetch(...)` broadcasts `listMonitorWillRefetch(...)` to its observers immediately, and then `listMonitorDidRefetch(...)` after the new fetch request completes.
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses. Important: Starting CoreStore 4.0, all `FetchClause`s required by the `ListMonitor` should be provided in the arguments list of `refetch(...)`.
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
- Important: Starting CoreStore 4.0, all `FetchClause`s required by the `ListMonitor` should be provided in the arguments list of `refetch(...)`.
*/
public func refetch(_ fetchClauses: FetchClause...) {
@@ -567,7 +568,8 @@ public final class ListMonitor<D: DynamicObject>: Hashable {
`refetch(...)` broadcasts `listMonitorWillRefetch(...)` to its observers immediately, and then `listMonitorDidRefetch(...)` after the new fetch request completes.
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses. Important: Starting CoreStore 4.0, all `FetchClause`s required by the `ListMonitor` should be provided in the arguments list of `refetch(...)`.
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
- Important: Starting CoreStore 4.0, all `FetchClause`s required by the `ListMonitor` should be provided in the arguments list of `refetch(...)`.
*/
public func refetch(_ fetchClauses: [FetchClause]) {
@@ -626,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,
@@ -638,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,
@@ -650,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,
@@ -662,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,
@@ -921,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,
@@ -1020,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 {
@@ -1043,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 = CoreStoreFetchRequest()
let fetchRequest = CoreStoreFetchRequest<NSManagedObject>()
fetchRequest.fetchLimit = 0
fetchRequest.resultType = .managedObjectResultType
fetchRequest.fetchBatchSize = 20
@@ -1054,7 +1056,7 @@ public final class ListMonitor<D: DynamicObject>: Hashable {
let fetchedResultsController = CoreStoreFetchedResultsController(
context: context,
fetchRequest: fetchRequest.dynamicCast(),
fetchRequest: fetchRequest,
from: from,
sectionBy: sectionBy,
applyFetchClauses: applyFetchClauses
@@ -1069,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
@@ -1112,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 as Any as! CoreStoreFetchRequest).safeAffectedStores ?? []).intersection(removedStores).isEmpty else {
!Set(self.fetchedResultsController.typedFetchRequest.safeAffectedStores() ?? []).intersection(removedStores).isEmpty else {
return
}
@@ -1133,7 +1135,7 @@ public final class ListMonitor<D: DynamicObject>: Hashable {
if !self.isPendingRefetch {
let previousStores = Set((self.fetchedResultsController.fetchRequest as Any as! CoreStoreFetchRequest).safeAffectedStores ?? [])
let previousStores = Set(self.fetchedResultsController.typedFetchRequest.safeAffectedStores() ?? [])
let currentStores = previousStores
.subtracting(note.userInfo?[NSRemovedPersistentStoresKey] as? [NSPersistentStore] ?? [])
.union(note.userInfo?[NSAddedPersistentStoresKey] as? [NSPersistentStore] ?? [])
@@ -1388,6 +1390,9 @@ extension ListMonitor: FetchedResultsControllerHandler {
"\(String(describing: IndexPath.self)).New": newIndexPath!
]
)
@unknown default:
fatalError()
}
}
@@ -1451,7 +1456,7 @@ extension ListMonitor: FetchedResultsControllerHandler {
// MARK: - Notification Keys
@available(macOS 10.12, *)
fileprivate extension Notification.Name {
extension Notification.Name {
fileprivate static let listMonitorWillChangeList = Notification.Name(rawValue: "listMonitorWillChangeList")
fileprivate static let listMonitorDidChangeList = Notification.Name(rawValue: "listMonitorDidChangeList")

View File

@@ -83,7 +83,7 @@ public protocol ListObserver: class {
// MARK: - ListObserver (Default Implementations)
@available(macOS 10.12, *)
public extension ListObserver {
extension ListObserver {
public func listMonitorWillChange(_ monitor: ListMonitor<ListEntityType>) { }
@@ -152,7 +152,7 @@ public protocol ListObjectObserver: ListObserver {
// MARK: - ListObjectObserver (Default Implementations)
@available(macOS 10.12, *)
public extension ListObjectObserver {
extension ListObjectObserver {
public func listMonitor(_ monitor: ListMonitor<ListEntityType>, didInsertObject object: ListEntityType, toIndexPath indexPath: IndexPath) { }
@@ -205,7 +205,7 @@ public protocol ListSectionObserver: ListObjectObserver {
// MARK: - ListSectionObserver (Default Implementations)
@available(macOS 10.12, *)
public extension ListSectionObserver {
extension ListSectionObserver {
public func listMonitor(_ monitor: ListMonitor<ListEntityType>, didInsertSection sectionInfo: NSFetchedResultsSectionInfo, toSectionIndex sectionIndex: Int) { }

View File

@@ -29,7 +29,7 @@ import Foundation
// MARK: - NSEntityDescription
internal extension NSEntityDescription {
extension NSEntityDescription {
@nonobjc
internal var dynamicObjectType: DynamicObject.Type? {

View File

@@ -29,7 +29,7 @@ import Foundation
// MARK: - NSEntityDescription
internal extension NSEntityDescription {
extension NSEntityDescription {
@nonobjc
internal func cs_resolveAttributeNames() -> [String: (attribute: NSAttributeDescription, versionHash: Data)] {

View File

@@ -30,7 +30,7 @@ import CoreData
// MARK: - DataStack
@available(macOS 10.12, *)
public extension DataStack {
extension DataStack {
/**
Utility for creating an `NSFetchedResultsController` from the `DataStack`. This is useful when an `NSFetchedResultsController` is preferred over the overhead of `ListMonitor`s abstraction.
@@ -115,7 +115,7 @@ public extension DataStack {
// MARK: - UnsafeDataTransaction
@available(macOS 10.12, *)
public extension UnsafeDataTransaction {
extension UnsafeDataTransaction {
/**
Utility for creating an `NSFetchedResultsController` from the `UnsafeDataTransaction`. This is useful when an `NSFetchedResultsController` is preferred over the overhead of `ListMonitor`s abstraction.
@@ -205,12 +205,12 @@ fileprivate func createFRC<D: NSManagedObject>(fromContext context: NSManagedObj
let controller = CoreStoreFetchedResultsController(
context: context,
fetchRequest: CoreStoreFetchRequest().dynamicCast(),
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,

View File

@@ -30,7 +30,7 @@ import CoreData
// MARK: - CSDataStack
@available(macOS 10.12, *)
public extension CSDataStack {
extension CSDataStack {
@available(*, deprecated, message: "CoreStore will obsolete NSFetchedResultsController support in the future in favor of CSListMonitor")
@objc
@@ -49,7 +49,7 @@ public extension CSDataStack {
// MARK: - CSUnsafeDataTransaction
@available(macOS 10.12, *)
public extension CSUnsafeDataTransaction {
extension CSUnsafeDataTransaction {
@available(*, deprecated, message: "CoreStore will obsolete NSFetchedResultsController support in the future in favor of CSListMonitor")
@objc
@@ -72,12 +72,12 @@ fileprivate func createFRC(fromContext context: NSManagedObjectContext, from: CS
let controller = CoreStoreFetchedResultsController(
context: context,
fetchRequest: CoreStoreFetchRequest().dynamicCast(),
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,

View File

@@ -29,7 +29,7 @@ import CoreData
// MARK: - NSManagedObject
public extension NSManagedObject {
extension NSManagedObject {
/**
Exposes a `FetchableSource` that can fetch sibling objects of this `NSManagedObject` instance. This may be the `DataStack`, a `BaseDataTransaction`, the `NSManagedObjectContext` itself, or `nil` if the obejct's parent is already deallocated.

View File

@@ -29,7 +29,7 @@ import CoreData
// MARK: - NSManagedObject
internal extension NSManagedObject {
extension NSManagedObject {
@nonobjc
internal weak var coreStoreObject: CoreStoreObject? {

View File

@@ -29,7 +29,7 @@ import CoreData
// MARK: - NSManagedObject
internal extension NSManagedObject {
extension NSManagedObject {
@nonobjc
internal func isRunningInAllowedQueue() -> Bool? {

View File

@@ -29,7 +29,7 @@ import CoreData
// MARK: - NSManagedObject
public extension NSManagedObject {
extension NSManagedObject {
/**
Provides a convenience wrapper for accessing `-primitiveValueForKey:` with proper calls to `-willAccessValueForKey:` and `-didAccessValueForKey:`. This is useful when implementing accessor methods for transient attributes.

View File

@@ -29,7 +29,7 @@ import CoreData
// MARK: - NSManagedObject
public extension NSManagedObject {
extension NSManagedObject {
/**
Returns this object's parent `UnsafeDataTransaction` instance if it was created from one. Returns `nil` if the parent transaction is either an `AsynchronousDataTransaction` or a `SynchronousDataTransaction`, or if the object is not managed by CoreStore.

View File

@@ -29,7 +29,7 @@ import CoreData
// MARK: - NSManagedObjectContext
internal extension NSManagedObjectContext {
extension NSManagedObjectContext {
// MARK: Internal

View File

@@ -29,76 +29,78 @@ import CoreData
// MARK: - NSManagedObjectContext
internal extension NSManagedObjectContext {
extension NSManagedObjectContext {
// MARK: Internal
@nonobjc
internal func fetchOne(_ from: CSFrom, _ fetchClauses: [CSFetchClause]) throws -> NSManagedObject? {
let fetchRequest = CoreStoreFetchRequest()
let fetchRequest = CoreStoreFetchRequest<NSManagedObject>()
try from.bridgeToSwift.applyToFetchRequest(fetchRequest, context: self)
fetchRequest.fetchLimit = 1
fetchRequest.resultType = .managedObjectResultType
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
return try self.fetchOne(fetchRequest.dynamicCast())
return try self.fetchOne(fetchRequest)
}
@nonobjc
internal func fetchAll<T: NSManagedObject>(_ from: CSFrom, _ fetchClauses: [CSFetchClause]) throws -> [T] {
let fetchRequest = CoreStoreFetchRequest()
let fetchRequest = CoreStoreFetchRequest<T>()
try from.bridgeToSwift.applyToFetchRequest(fetchRequest, context: self)
fetchRequest.fetchLimit = 0
fetchRequest.resultType = .managedObjectResultType
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
return try self.fetchAll(fetchRequest.dynamicCast())
return try self.fetchAll(fetchRequest)
}
@nonobjc
internal func fetchCount(_ from: CSFrom, _ fetchClauses: [CSFetchClause]) throws -> Int {
let fetchRequest = CoreStoreFetchRequest()
let fetchRequest = CoreStoreFetchRequest<NSNumber>()
try from.bridgeToSwift.applyToFetchRequest(fetchRequest, context: self)
fetchRequest.resultType = .countResultType
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
return try self.fetchCount(fetchRequest.dynamicCast())
return try self.fetchCount(fetchRequest)
}
@nonobjc
internal func fetchObjectID(_ from: CSFrom, _ fetchClauses: [CSFetchClause]) throws -> NSManagedObjectID? {
let fetchRequest = CoreStoreFetchRequest()
let fetchRequest = CoreStoreFetchRequest<NSManagedObjectID>()
try from.bridgeToSwift.applyToFetchRequest(fetchRequest, context: self)
fetchRequest.fetchLimit = 1
fetchRequest.resultType = .managedObjectIDResultType
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
return try self.fetchObjectID(fetchRequest.dynamicCast())
return try self.fetchObjectID(fetchRequest)
}
@nonobjc
internal func fetchObjectIDs(_ from: CSFrom, _ fetchClauses: [CSFetchClause]) throws -> [NSManagedObjectID] {
let fetchRequest = CoreStoreFetchRequest()
let fetchRequest = CoreStoreFetchRequest<NSManagedObjectID>()
try from.bridgeToSwift.applyToFetchRequest(fetchRequest, context: self)
fetchRequest.fetchLimit = 0
fetchRequest.resultType = .managedObjectIDResultType
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
return try self.fetchObjectIDs(fetchRequest.dynamicCast())
return try self.fetchObjectIDs(fetchRequest)
}
@nonobjc
internal func deleteAll(_ from: CSFrom, _ deleteClauses: [CSDeleteClause]) throws -> Int {
let fetchRequest = CoreStoreFetchRequest()
let fetchRequest = CoreStoreFetchRequest<NSManagedObject>()
try from.bridgeToSwift.applyToFetchRequest(fetchRequest, context: self)
fetchRequest.fetchLimit = 0
@@ -107,13 +109,13 @@ internal extension NSManagedObjectContext {
fetchRequest.includesPropertyValues = false
deleteClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
return try self.deleteAll(fetchRequest.dynamicCast())
return try self.deleteAll(fetchRequest)
}
@nonobjc
internal func queryValue(_ from: CSFrom, _ selectClause: CSSelect, _ queryClauses: [CSQueryClause]) throws -> Any? {
let fetchRequest = CoreStoreFetchRequest()
let fetchRequest = CoreStoreFetchRequest<NSDictionary>()
try from.bridgeToSwift.applyToFetchRequest(fetchRequest, context: self)
fetchRequest.fetchLimit = 0
@@ -121,13 +123,13 @@ internal extension NSManagedObjectContext {
selectClause.applyToFetchRequest(fetchRequest)
queryClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
return try self.queryValue(selectClause.selectTerms, fetchRequest: fetchRequest.dynamicCast())
return try self.queryValue(selectClause.selectTerms, fetchRequest: fetchRequest)
}
@nonobjc
internal func queryAttributes(_ from: CSFrom, _ selectClause: CSSelect, _ queryClauses: [CSQueryClause]) throws -> [[String: Any]] {
let fetchRequest = CoreStoreFetchRequest()
let fetchRequest = CoreStoreFetchRequest<NSDictionary>()
try from.bridgeToSwift.applyToFetchRequest(fetchRequest, context: self)
fetchRequest.fetchLimit = 0
@@ -135,6 +137,6 @@ internal extension NSManagedObjectContext {
selectClause.applyToFetchRequest(fetchRequest)
queryClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
return try self.queryAttributes(fetchRequest.dynamicCast())
return try self.queryAttributes(fetchRequest)
}
}

View File

@@ -109,14 +109,14 @@ extension NSManagedObjectContext: FetchableSource, QueryableSource {
@nonobjc
public func fetchOne<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) throws -> D? {
let fetchRequest = CoreStoreFetchRequest()
let fetchRequest = CoreStoreFetchRequest<NSManagedObject>()
try from.applyToFetchRequest(fetchRequest, context: self)
fetchRequest.fetchLimit = 1
fetchRequest.resultType = .managedObjectResultType
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
return try self.fetchOne(fetchRequest.dynamicCast()).flatMap(from.entityClass.cs_fromRaw)
return try self.fetchOne(fetchRequest).flatMap(from.entityClass.cs_fromRaw)
}
@nonobjc
@@ -134,7 +134,7 @@ extension NSManagedObjectContext: FetchableSource, QueryableSource {
@nonobjc
public func fetchAll<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) throws -> [D] {
let fetchRequest = CoreStoreFetchRequest()
let fetchRequest = CoreStoreFetchRequest<NSManagedObject>()
try from.applyToFetchRequest(fetchRequest, context: self)
fetchRequest.fetchLimit = 0
@@ -142,7 +142,7 @@ extension NSManagedObjectContext: FetchableSource, QueryableSource {
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
let entityClass = from.entityClass
return try self.fetchAll(fetchRequest.dynamicCast()).map(entityClass.cs_fromRaw)
return try self.fetchAll(fetchRequest).map(entityClass.cs_fromRaw)
}
@nonobjc
@@ -160,11 +160,13 @@ extension NSManagedObjectContext: FetchableSource, QueryableSource {
@nonobjc
public func fetchCount<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) throws -> Int {
let fetchRequest = CoreStoreFetchRequest()
let fetchRequest = CoreStoreFetchRequest<NSNumber>()
try from.applyToFetchRequest(fetchRequest, context: self)
fetchRequest.resultType = .countResultType
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
return try self.fetchCount(fetchRequest.dynamicCast())
return try self.fetchCount(fetchRequest)
}
@nonobjc
@@ -182,14 +184,14 @@ extension NSManagedObjectContext: FetchableSource, QueryableSource {
@nonobjc
public func fetchObjectID<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) throws -> NSManagedObjectID? {
let fetchRequest = CoreStoreFetchRequest()
let fetchRequest = CoreStoreFetchRequest<NSManagedObjectID>()
try from.applyToFetchRequest(fetchRequest, context: self)
fetchRequest.fetchLimit = 1
fetchRequest.resultType = .managedObjectIDResultType
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
return try self.fetchObjectID(fetchRequest.dynamicCast())
return try self.fetchObjectID(fetchRequest)
}
@nonobjc
@@ -206,15 +208,15 @@ extension NSManagedObjectContext: FetchableSource, QueryableSource {
@nonobjc
public func fetchObjectIDs<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) throws -> [NSManagedObjectID] {
let fetchRequest = CoreStoreFetchRequest()
let fetchRequest = CoreStoreFetchRequest<NSManagedObjectID>()
try from.applyToFetchRequest(fetchRequest, context: self)
fetchRequest.fetchLimit = 0
fetchRequest.resultType = .managedObjectIDResultType
fetchClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
return try self.fetchObjectIDs(fetchRequest.dynamicCast())
return try self.fetchObjectIDs(fetchRequest)
}
@nonobjc
@@ -224,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?
@@ -232,7 +234,7 @@ extension NSManagedObjectContext: FetchableSource, QueryableSource {
do {
fetchResults = try self.fetch(fetchRequest)
fetchResults = try self.fetch(fetchRequest.dynamicCast())
}
catch {
@@ -263,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 = CoreStoreFetchRequest()
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)
@@ -289,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 = CoreStoreFetchRequest()
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)
@@ -320,7 +322,7 @@ extension NSManagedObjectContext: FetchableSource, QueryableSource {
@nonobjc
internal func deleteAll<D>(_ from: From<D>, _ deleteClauses: [FetchClause]) throws -> Int {
let fetchRequest = CoreStoreFetchRequest()
let fetchRequest = CoreStoreFetchRequest<NSManagedObject>()
try from.applyToFetchRequest(fetchRequest, context: self)
fetchRequest.fetchLimit = 0
@@ -329,7 +331,7 @@ extension NSManagedObjectContext: FetchableSource, QueryableSource {
fetchRequest.includesPropertyValues = false
deleteClauses.forEach { $0.applyToFetchRequest(fetchRequest) }
return try self.deleteAll(fetchRequest.dynamicCast())
return try self.deleteAll(fetchRequest)
}
@@ -345,12 +347,12 @@ extension NSManagedObjectContext: FetchableSource, QueryableSource {
// MARK: - NSManagedObjectContext (Internal)
internal extension NSManagedObjectContext {
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?
@@ -358,7 +360,7 @@ internal extension NSManagedObjectContext {
do {
fetchResults = try self.fetch(fetchRequest)
fetchResults = try self.fetch(fetchRequest.staticCast())
}
catch {
@@ -378,7 +380,7 @@ internal 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?
@@ -386,7 +388,7 @@ internal extension NSManagedObjectContext {
do {
fetchResults = try self.fetch(fetchRequest)
fetchResults = try self.fetch(fetchRequest.staticCast())
}
catch {
@@ -406,7 +408,7 @@ internal extension NSManagedObjectContext {
}
@nonobjc
internal func fetchCount(_ fetchRequest: NSFetchRequest<NSFetchRequestResult>) throws -> Int {
internal func fetchCount(_ fetchRequest: CoreStoreFetchRequest<NSNumber>) throws -> Int {
var count = 0
var countError: Error?
@@ -414,7 +416,7 @@ internal extension NSManagedObjectContext {
do {
count = try self.count(for: fetchRequest)
count = try self.count(for: fetchRequest.staticCast())
}
catch {
@@ -434,7 +436,7 @@ internal 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?
@@ -442,7 +444,7 @@ internal extension NSManagedObjectContext {
do {
fetchResults = try self.fetch(fetchRequest)
fetchResults = try self.fetch(fetchRequest.staticCast())
}
catch {
@@ -465,7 +467,7 @@ internal extension NSManagedObjectContext {
// MARK: Querying
@nonobjc
internal func queryValue<D, U: QueryableAttributeType>(_ selectTerms: [SelectTerm<D>], fetchRequest: NSFetchRequest<NSFetchRequestResult>) throws -> U? {
internal func queryValue<D, U: QueryableAttributeType>(_ selectTerms: [SelectTerm<D>], fetchRequest: CoreStoreFetchRequest<NSDictionary>) throws -> U? {
var fetchResults: [Any]?
var fetchError: Error?
@@ -473,7 +475,7 @@ internal extension NSManagedObjectContext {
do {
fetchResults = try self.fetch(fetchRequest)
fetchResults = try self.fetch(fetchRequest.staticCast())
}
catch {
@@ -498,7 +500,7 @@ internal extension NSManagedObjectContext {
}
@nonobjc
internal func queryValue<D>(_ selectTerms: [SelectTerm<D>], fetchRequest: NSFetchRequest<NSFetchRequestResult>) throws -> Any? {
internal func queryValue<D>(_ selectTerms: [SelectTerm<D>], fetchRequest: CoreStoreFetchRequest<NSDictionary>) throws -> Any? {
var fetchResults: [Any]?
var fetchError: Error?
@@ -506,7 +508,7 @@ internal extension NSManagedObjectContext {
do {
fetchResults = try self.fetch(fetchRequest)
fetchResults = try self.fetch(fetchRequest.staticCast())
}
catch {
@@ -531,7 +533,7 @@ internal extension NSManagedObjectContext {
}
@nonobjc
internal func queryAttributes(_ fetchRequest: NSFetchRequest<NSFetchRequestResult>) throws -> [[String: Any]] {
internal func queryAttributes(_ fetchRequest: CoreStoreFetchRequest<NSDictionary>) throws -> [[String: Any]] {
var fetchResults: [Any]?
var fetchError: Error?
@@ -539,7 +541,7 @@ internal extension NSManagedObjectContext {
do {
fetchResults = try self.fetch(fetchRequest)
fetchResults = try self.fetch(fetchRequest.staticCast())
}
catch {
@@ -562,7 +564,7 @@ internal 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?
@@ -572,7 +574,7 @@ internal extension NSManagedObjectContext {
do {
let fetchResults = try self.fetch(fetchRequest)
let fetchResults = try self.fetch(fetchRequest.staticCast())
for object in fetchResults {
self.delete(object)

View File

@@ -29,7 +29,7 @@ import CoreData
// MARK: - NSManagedObjectContext
internal extension NSManagedObjectContext {
extension NSManagedObjectContext {
// MARK: Internal

View File

@@ -29,7 +29,7 @@ import CoreData
// MARK: - NSManagedObjectContext
internal extension NSManagedObjectContext {
extension NSManagedObjectContext {
// MARK: Internal

View File

@@ -29,7 +29,7 @@ import Foundation
// MARK: - FilePrivate
internal extension NSManagedObjectModel {
extension NSManagedObjectModel {
@nonobjc
internal func cs_resolveNames() -> [String: (entity: NSEntityDescription, versionHash: Data)] {

View File

@@ -29,7 +29,7 @@ import CoreData
// MARK: - NSPersistentStore
internal extension NSPersistentStore {
extension NSPersistentStore {
// MARK: Internal

View File

@@ -29,7 +29,7 @@ import CoreData
// MARK: - NSPersistentStoreCoordinator
internal extension NSPersistentStoreCoordinator {
extension NSPersistentStoreCoordinator {
@nonobjc
internal func performAsynchronously(_ closure: @escaping () -> Void) {

View File

@@ -261,7 +261,7 @@ public final class ObjectMonitor<D: DynamicObject>: Equatable {
private init(context: NSManagedObjectContext, object: ObjectType) {
let objectID = object.cs_id()
let fetchRequest = CoreStoreFetchRequest()
let fetchRequest = CoreStoreFetchRequest<NSManagedObject>()
fetchRequest.entity = objectID.entity
fetchRequest.fetchLimit = 0
fetchRequest.resultType = .managedObjectResultType
@@ -271,7 +271,7 @@ public final class ObjectMonitor<D: DynamicObject>: Equatable {
let fetchedResultsController = CoreStoreFetchedResultsController(
context: context,
fetchRequest: fetchRequest.dynamicCast(),
fetchRequest: fetchRequest,
from: From<ObjectType>([objectID.persistentStore?.configurationName]),
applyFetchClauses: Where<ObjectType>("SELF", isEqualTo: objectID).applyToFetchRequest
)
@@ -385,7 +385,7 @@ extension ObjectMonitor: FetchedResultsControllerHandler {
// MARK: - Notification.Name
@available(macOS 10.12, *)
fileprivate extension Notification.Name {
extension Notification.Name {
fileprivate static let objectMonitorWillChangeObject = Notification.Name(rawValue: "objectMonitorWillChangeObject")
fileprivate static let objectMonitorDidDeleteObject = Notification.Name(rawValue: "objectMonitorDidDeleteObject")

View File

@@ -77,7 +77,7 @@ public protocol ObjectObserver: class {
// MARK: - ObjectObserver (Default Implementations)
@available(macOS 10.12, *)
public extension ObjectObserver {
extension ObjectObserver {
public func objectMonitor(_ monitor: ObjectMonitor<ObjectEntityType>, willUpdateObject object: ObjectEntityType) { }

View File

@@ -257,7 +257,10 @@ public struct OrderBy<D: DynamicObject>: OrderByClause, FetchClause, QueryClause
}
}
public extension OrderBy.SortKey where D: CoreStoreObject {
// MARK: - OrderBy.SortKey where D: CoreStoreObject
extension OrderBy.SortKey where D: CoreStoreObject {
/**
Indicates that the `KeyPathString` should be sorted in ascending order
@@ -298,7 +301,7 @@ public protocol OrderByClause {
// MARK: - Sequence where Iterator.Element: OrderByClause
public extension Sequence where Iterator.Element: OrderByClause {
extension Sequence where Iterator.Element: OrderByClause {
/**
Combines multiple `OrderBy` predicates together

Some files were not shown because too many files have changed in this diff Show More