diff --git a/CoreStore.xcodeproj/project.pbxproj b/CoreStore.xcodeproj/project.pbxproj index 94b9709..7e39346 100644 --- a/CoreStore.xcodeproj/project.pbxproj +++ b/CoreStore.xcodeproj/project.pbxproj @@ -159,11 +159,22 @@ 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 */; }; - B546F9781C9CD1F800D5AC55 /* CSCoreStoreLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = B546F9771C9CD1F800D5AC55 /* CSCoreStoreLogger.swift */; }; - B546F9791C9CD1F800D5AC55 /* CSCoreStoreLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = B546F9771C9CD1F800D5AC55 /* CSCoreStoreLogger.swift */; }; - B546F97A1C9CD1F800D5AC55 /* CSCoreStoreLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = B546F9771C9CD1F800D5AC55 /* CSCoreStoreLogger.swift */; }; - B546F97B1C9CD1F800D5AC55 /* CSCoreStoreLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = B546F9771C9CD1F800D5AC55 /* CSCoreStoreLogger.swift */; }; B54A6A551BA15F2A007870FD /* FetchedResultsControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B54A6A541BA15F2A007870FD /* FetchedResultsControllerDelegate.swift */; }; + B5519A401CA1B17B002BEF78 /* ErrorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5519A3F1CA1B17B002BEF78 /* ErrorTests.swift */; }; + B5519A411CA1B17B002BEF78 /* ErrorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5519A3F1CA1B17B002BEF78 /* ErrorTests.swift */; }; + B5519A421CA1B17B002BEF78 /* ErrorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5519A3F1CA1B17B002BEF78 /* ErrorTests.swift */; }; + B5519A4A1CA1F4FB002BEF78 /* CSError.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5519A491CA1F4FB002BEF78 /* CSError.swift */; }; + B5519A4B1CA1F4FB002BEF78 /* CSError.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5519A491CA1F4FB002BEF78 /* CSError.swift */; }; + B5519A4C1CA1F4FB002BEF78 /* CSError.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5519A491CA1F4FB002BEF78 /* CSError.swift */; }; + B5519A4D1CA1F4FB002BEF78 /* CSError.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5519A491CA1F4FB002BEF78 /* CSError.swift */; }; + B5519A591CA2008C002BEF78 /* CSBaseDataTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5519A581CA2008C002BEF78 /* CSBaseDataTransaction.swift */; }; + B5519A5A1CA2008C002BEF78 /* CSBaseDataTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5519A581CA2008C002BEF78 /* CSBaseDataTransaction.swift */; }; + B5519A5B1CA2008C002BEF78 /* CSBaseDataTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5519A581CA2008C002BEF78 /* CSBaseDataTransaction.swift */; }; + B5519A5C1CA2008C002BEF78 /* CSBaseDataTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5519A581CA2008C002BEF78 /* CSBaseDataTransaction.swift */; }; + B5519A5F1CA21954002BEF78 /* CSAsynchronousDataTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5519A5E1CA21954002BEF78 /* CSAsynchronousDataTransaction.swift */; }; + B5519A601CA21954002BEF78 /* CSAsynchronousDataTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5519A5E1CA21954002BEF78 /* CSAsynchronousDataTransaction.swift */; }; + B5519A611CA21954002BEF78 /* CSAsynchronousDataTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5519A5E1CA21954002BEF78 /* CSAsynchronousDataTransaction.swift */; }; + B5519A621CA21954002BEF78 /* CSAsynchronousDataTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5519A5E1CA21954002BEF78 /* CSAsynchronousDataTransaction.swift */; }; B5598BCC1BE2093D0092EFCE /* Model.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = B5D372821A39CD6900F583D9 /* Model.xcdatamodeld */; }; B56007111B3F6BD500A9A8F9 /* Into.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56007101B3F6BD500A9A8F9 /* Into.swift */; }; B56007141B3F6C2800A9A8F9 /* SectionBy.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56007131B3F6C2800A9A8F9 /* SectionBy.swift */; }; @@ -380,8 +391,11 @@ B546F9681C9AF26D00D5AC55 /* CSInMemoryStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSInMemoryStore.swift; sourceTree = ""; }; B546F96D1C9B14AC00D5AC55 /* CSStorageInterface.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSStorageInterface.swift; sourceTree = ""; }; B546F9721C9C553300D5AC55 /* SetupResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SetupResult.swift; sourceTree = ""; }; - B546F9771C9CD1F800D5AC55 /* CSCoreStoreLogger.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSCoreStoreLogger.swift; sourceTree = ""; }; B54A6A541BA15F2A007870FD /* FetchedResultsControllerDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FetchedResultsControllerDelegate.swift; sourceTree = ""; }; + B5519A3F1CA1B17B002BEF78 /* ErrorTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ErrorTests.swift; sourceTree = ""; }; + B5519A491CA1F4FB002BEF78 /* CSError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSError.swift; sourceTree = ""; }; + B5519A581CA2008C002BEF78 /* CSBaseDataTransaction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSBaseDataTransaction.swift; sourceTree = ""; }; + B5519A5E1CA21954002BEF78 /* CSAsynchronousDataTransaction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSAsynchronousDataTransaction.swift; sourceTree = ""; }; B5548CD51BD65AE00077652A /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; B5548CD71BD65AE50077652A /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/System/Library/Frameworks/CoreData.framework; sourceTree = DEVELOPER_DIR; }; B56007101B3F6BD500A9A8F9 /* Into.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Into.swift; sourceTree = ""; }; @@ -601,6 +615,7 @@ B5DBE2DD1C9939E100B5CEFA /* BridgingTests.h */, B5DBE2DE1C9939E100B5CEFA /* BridgingTests.m */, B5DC47C51C93D22900FA3BF3 /* MigrationChainTests.swift */, + B5519A3F1CA1B17B002BEF78 /* ErrorTests.swift */, B5D372851A39CDDB00F583D9 /* TestEntity1.swift */, B5D5E0CE1A4D6AAB006468AF /* TestEntity2.swift */, 2F03A53D19C5C6DA005002A5 /* Supporting Files */, @@ -662,6 +677,15 @@ name = StorageInterfaces; sourceTree = ""; }; + B5519A5D1CA20093002BEF78 /* Saving and Processing */ = { + isa = PBXGroup; + children = ( + B5519A581CA2008C002BEF78 /* CSBaseDataTransaction.swift */, + B5519A5E1CA21954002BEF78 /* CSAsynchronousDataTransaction.swift */, + ); + name = "Saving and Processing"; + sourceTree = ""; + }; B56964D11B22FF700075EE4A /* Migrating */ = { isa = PBXGroup; children = ( @@ -680,8 +704,9 @@ children = ( B5AEFAB41C9962AE00AD137F /* CoreStoreBridge.swift */, B5DBE2CC1C9914A900B5CEFA /* CSCoreStore.swift */, - B546F9771C9CD1F800D5AC55 /* CSCoreStoreLogger.swift */, + B5519A491CA1F4FB002BEF78 /* CSError.swift */, B546F9611C9A13F400D5AC55 /* Setup */, + B5519A5D1CA20093002BEF78 /* Saving and Processing */, ); path = ObjectiveC; sourceTree = ""; @@ -1108,6 +1133,7 @@ B5D1E22C19FA9FBC003B2874 /* CoreStoreError.swift in Sources */, B5E84F131AFF847B0064E85B /* Where.swift in Sources */, B5D3F6451C887C0A00C7492A /* LegacySQLiteStore.swift in Sources */, + B5519A5F1CA21954002BEF78 /* CSAsynchronousDataTransaction.swift in Sources */, B54A6A551BA15F2A007870FD /* FetchedResultsControllerDelegate.swift in Sources */, B5A261211B64BFDB006EB6D3 /* MigrationType.swift in Sources */, B5E84F141AFF847B0064E85B /* DataStack+Querying.swift in Sources */, @@ -1128,6 +1154,7 @@ B5DBE2D21C991B3E00B5CEFA /* CSDataStack.swift in Sources */, B50392F91C478FF3009900CA /* NSManagedObject+Transaction.swift in Sources */, B5202CFA1C04688100DED140 /* NSFetchedResultsController+Convenience.swift in Sources */, + B5519A591CA2008C002BEF78 /* CSBaseDataTransaction.swift in Sources */, B546F96E1C9B14AC00D5AC55 /* CSStorageInterface.swift in Sources */, B5E84F251AFF84860064E85B /* ObjectObserver.swift in Sources */, B5E84F2F1AFF849C0064E85B /* NotificationObserver.swift in Sources */, @@ -1146,6 +1173,7 @@ B5E84F231AFF84860064E85B /* ListMonitor.swift in Sources */, B5E84EF71AFF846E0064E85B /* UnsafeDataTransaction.swift in Sources */, B56964D41B22FFAD0075EE4A /* DataStack+Migration.swift in Sources */, + B5519A4A1CA1F4FB002BEF78 /* CSError.swift in Sources */, B5E84EF51AFF846E0064E85B /* BaseDataTransaction.swift in Sources */, B5E84EFB1AFF846E0064E85B /* SaveResult.swift in Sources */, B5E84F0F1AFF847B0064E85B /* From.swift in Sources */, @@ -1161,7 +1189,6 @@ B5E84F101AFF847B0064E85B /* GroupBy.swift in Sources */, B5E84F201AFF84860064E85B /* DataStack+Observing.swift in Sources */, B5E84EF81AFF846E0064E85B /* CoreStore+Transaction.swift in Sources */, - B546F9781C9CD1F800D5AC55 /* CSCoreStoreLogger.swift in Sources */, B5E84F301AFF849C0064E85B /* NSManagedObjectContext+CoreStore.swift in Sources */, B546F9691C9AF26D00D5AC55 /* CSInMemoryStore.swift in Sources */, B5E84F211AFF84860064E85B /* CoreStore+Observing.swift in Sources */, @@ -1181,6 +1208,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + B5519A401CA1B17B002BEF78 /* ErrorTests.swift in Sources */, 2F03A54019C5C6DA005002A5 /* CoreStoreTests.swift in Sources */, B5DC47C61C93D22900FA3BF3 /* MigrationChainTests.swift in Sources */, B5D372861A39CDDB00F583D9 /* TestEntity1.swift in Sources */, @@ -1202,6 +1230,7 @@ 82BA18AE1C4BBD3100A0916E /* DataStack+Transaction.swift in Sources */, 82BA18AB1C4BBD3100A0916E /* AsynchronousDataTransaction.swift in Sources */, 82BA18CE1C4BBD7100A0916E /* FetchedResultsControllerDelegate.swift in Sources */, + B5519A601CA21954002BEF78 /* CSAsynchronousDataTransaction.swift in Sources */, B5FE4DAD1C85D44E00FA6A91 /* SQLiteStore.swift in Sources */, 82BA18C51C4BBD5300A0916E /* ListObserver.swift in Sources */, 82BA18C21C4BBD5300A0916E /* ObjectMonitor.swift in Sources */, @@ -1222,6 +1251,7 @@ B5DBE2D31C991B3E00B5CEFA /* CSDataStack.swift in Sources */, 82BA18B41C4BBD3900A0916E /* BaseDataTransaction+Importing.swift in Sources */, 82BA18CA1C4BBD5900A0916E /* MigrationResult.swift in Sources */, + B5519A5A1CA2008C002BEF78 /* CSBaseDataTransaction.swift in Sources */, B546F96F1C9B14AC00D5AC55 /* CSStorageInterface.swift in Sources */, 82BA18C11C4BBD5300A0916E /* CoreStore+Observing.swift in Sources */, 82BA18BC1C4BBD4A00A0916E /* OrderBy.swift in Sources */, @@ -1240,6 +1270,7 @@ 82BA18A91C4BBD3100A0916E /* Into.swift in Sources */, 82BA18D11C4BBD7100A0916E /* NotificationObserver.swift in Sources */, 82BA18BB1C4BBD4A00A0916E /* Where.swift in Sources */, + B5519A4B1CA1F4FB002BEF78 /* CSError.swift in Sources */, 82BA18D71C4BBD7100A0916E /* NSManagedObjectModel+Setup.swift in Sources */, 82BA18C31C4BBD5300A0916E /* ObjectObserver.swift in Sources */, 82BA18D21C4BBD7100A0916E /* NSFileManager+Setup.swift in Sources */, @@ -1255,7 +1286,6 @@ 82BA18CB1C4BBD6400A0916E /* NSManagedObject+Convenience.swift in Sources */, 82BA18B51C4BBD3F00A0916E /* BaseDataTransaction+Querying.swift in Sources */, 82BA18D31C4BBD7100A0916E /* NSManagedObjectContext+CoreStore.swift in Sources */, - B546F9791C9CD1F800D5AC55 /* CSCoreStoreLogger.swift in Sources */, 82BA18AD1C4BBD3100A0916E /* UnsafeDataTransaction.swift in Sources */, B546F96A1C9AF26D00D5AC55 /* CSInMemoryStore.swift in Sources */, 82BA18A81C4BBD2900A0916E /* CoreStoreLogger.swift in Sources */, @@ -1275,6 +1305,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + B5519A411CA1B17B002BEF78 /* ErrorTests.swift in Sources */, 82BA18DA1C4BBD9700A0916E /* TestEntity1.swift in Sources */, B5DC47C71C93D22900FA3BF3 /* MigrationChainTests.swift in Sources */, 82BA18DB1C4BBD9700A0916E /* TestEntity2.swift in Sources */, @@ -1306,6 +1337,7 @@ B52DD1941BE1F92500949AFE /* CoreStore.swift in Sources */, B52DD1A61BE1F92F00949AFE /* BaseDataTransaction+Importing.swift in Sources */, B52DD1A91BE1F93200949AFE /* CoreStore+Querying.swift in Sources */, + B5519A4D1CA1F4FB002BEF78 /* CSError.swift in Sources */, B52DD1961BE1F92500949AFE /* DataStack.swift in Sources */, B52DD1BD1BE1F94300949AFE /* NSManagedObject+Convenience.swift in Sources */, B52DD1AD1BE1F93900949AFE /* Where.swift in Sources */, @@ -1320,6 +1352,7 @@ B52DD19D1BE1F92C00949AFE /* BaseDataTransaction.swift in Sources */, B52DD1B81BE1F94000949AFE /* DataStack+Migration.swift in Sources */, B52DD1A51BE1F92F00949AFE /* ImportableUniqueObject.swift in Sources */, + B5519A621CA21954002BEF78 /* CSAsynchronousDataTransaction.swift in Sources */, B52DD19C1BE1F92C00949AFE /* Into.swift in Sources */, B5FE4DA51C8481E100FA6A91 /* StorageInterface.swift in Sources */, B546F9711C9B14AC00D5AC55 /* CSStorageInterface.swift in Sources */, @@ -1345,8 +1378,8 @@ B52DD1C91BE1F94600949AFE /* NSManagedObjectContext+Transaction.swift in Sources */, B52DD19B1BE1F92800949AFE /* CoreStoreLogger.swift in Sources */, B52DD1991BE1F92800949AFE /* DefaultLogger.swift in Sources */, - B546F97B1C9CD1F800D5AC55 /* CSCoreStoreLogger.swift in Sources */, B52DD1B91BE1F94000949AFE /* CoreStore+Migration.swift in Sources */, + B5519A5C1CA2008C002BEF78 /* CSBaseDataTransaction.swift in Sources */, B5DBE2D51C991B3E00B5CEFA /* CSDataStack.swift in Sources */, B5AEFAB81C9962AE00AD137F /* CoreStoreBridge.swift in Sources */, B598514B1C90289F00C99590 /* NSPersistentStoreCoordinator+Setup.swift in Sources */, @@ -1358,6 +1391,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + B5519A421CA1B17B002BEF78 /* ErrorTests.swift in Sources */, B52DD1CD1BE1F94D00949AFE /* TestEntity1.swift in Sources */, B5DC47C81C93D22900FA3BF3 /* MigrationChainTests.swift in Sources */, B52DD1CE1BE1F94D00949AFE /* TestEntity2.swift in Sources */, @@ -1379,6 +1413,7 @@ B563219D1BD65216006C9394 /* DataStack+Observing.swift in Sources */, B56321961BD65216006C9394 /* From.swift in Sources */, B56321AA1BD6521C006C9394 /* AssociatedObjects.swift in Sources */, + B5519A611CA21954002BEF78 /* CSAsynchronousDataTransaction.swift in Sources */, B5FE4DAE1C85D44E00FA6A91 /* SQLiteStore.swift in Sources */, B563218C1BD65216006C9394 /* DataStack+Transaction.swift in Sources */, B563219E1BD65216006C9394 /* CoreStore+Observing.swift in Sources */, @@ -1399,6 +1434,7 @@ B5DBE2D41C991B3E00B5CEFA /* CSDataStack.swift in Sources */, B56321AF1BD6521C006C9394 /* NSFileManager+Setup.swift in Sources */, B50392FA1C47963F009900CA /* NSManagedObject+Transaction.swift in Sources */, + B5519A5B1CA2008C002BEF78 /* CSBaseDataTransaction.swift in Sources */, B546F9701C9B14AC00D5AC55 /* CSStorageInterface.swift in Sources */, B56321971BD65216006C9394 /* Select.swift in Sources */, B56321AB1BD6521C006C9394 /* FetchedResultsControllerDelegate.swift in Sources */, @@ -1417,6 +1453,7 @@ B56321901BD65216006C9394 /* ImportableUniqueObject.swift in Sources */, B56321871BD65216006C9394 /* Into.swift in Sources */, B563219A1BD65216006C9394 /* GroupBy.swift in Sources */, + B5519A4C1CA1F4FB002BEF78 /* CSError.swift in Sources */, B563219B1BD65216006C9394 /* Tweak.swift in Sources */, B56321B51BD6521C006C9394 /* NSManagedObjectModel+Setup.swift in Sources */, B563218F1BD65216006C9394 /* ImportableObject.swift in Sources */, @@ -1432,7 +1469,6 @@ B56321851BD65216006C9394 /* CoreStore+Logging.swift in Sources */, B56321921BD65216006C9394 /* BaseDataTransaction+Querying.swift in Sources */, B56321B11BD6521C006C9394 /* NSManagedObjectContext+CoreStore.swift in Sources */, - B546F97A1C9CD1F800D5AC55 /* CSCoreStoreLogger.swift in Sources */, B563218D1BD65216006C9394 /* CoreStore+Transaction.swift in Sources */, B546F96B1C9AF26D00D5AC55 /* CSInMemoryStore.swift in Sources */, B563218B1BD65216006C9394 /* UnsafeDataTransaction.swift in Sources */, diff --git a/CoreStoreTests/ErrorTests.swift b/CoreStoreTests/ErrorTests.swift new file mode 100644 index 0000000..18ffcb6 --- /dev/null +++ b/CoreStoreTests/ErrorTests.swift @@ -0,0 +1,159 @@ +// +// ErrorTests.swift +// CoreStore +// +// Copyright © 2016 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 XCTest + +@testable +import CoreStore + +class ErrorTests: XCTestCase { + + func testErrors() { + + do { + + let error = CoreStoreError.Unknown + XCTAssertEqual((error as NSError).domain, CoreStoreErrorDomain) + XCTAssertEqual((error as NSError).code, CoreStoreErrorCode.UnknownError.rawValue) + + let userInfo: NSDictionary = [:] + + let objcError = error.objc + XCTAssertEqual(error, objcError.swift) + XCTAssertEqual(objcError.domain, CoreStoreErrorDomain) + XCTAssertEqual(objcError.code, CoreStoreErrorCode.UnknownError.rawValue) + XCTAssertEqual(objcError.userInfo, userInfo) + + let objcError2 = objcError.swift.objc + XCTAssertEqual(error, objcError2.swift) + XCTAssertEqual(objcError2.domain, CoreStoreErrorDomain) + XCTAssertEqual(objcError2.code, CoreStoreErrorCode.UnknownError.rawValue) + XCTAssertEqual(objcError2.userInfo, userInfo) + } + + let dummyURL = NSURL(string: "file:///test1/test2.sqlite")! + do { + + let error = CoreStoreError.DifferentStorageExistsAtURL(existingPersistentStoreURL: dummyURL) + XCTAssertEqual((error as NSError).domain, CoreStoreErrorDomain) + XCTAssertEqual((error as NSError).code, CoreStoreErrorCode.DifferentPersistentStoreExistsAtURL.rawValue) + + let userInfo: NSDictionary = [ + "existingPersistentStoreURL": dummyURL + ] + let objcError = error.objc + XCTAssertEqual(error, objcError.swift) + XCTAssertEqual(objcError.domain, CoreStoreErrorDomain) + XCTAssertEqual(objcError.code, CoreStoreErrorCode.DifferentPersistentStoreExistsAtURL.rawValue) + XCTAssertEqual(objcError.userInfo, userInfo) + + let objcError2 = objcError.swift.objc + XCTAssertEqual(error, objcError2.swift) + XCTAssertEqual(objcError2.domain, CoreStoreErrorDomain) + XCTAssertEqual(objcError2.code, CoreStoreErrorCode.DifferentPersistentStoreExistsAtURL.rawValue) + XCTAssertEqual(objcError2.userInfo, userInfo) + } + + do { + + let model = NSManagedObjectModel.fromBundle(NSBundle(forClass: self.dynamicType), modelName: "Model") + let version = "1.0.0" + + let error = CoreStoreError.MappingModelNotFound(localStoreURL: dummyURL, targetModel: model, targetModelVersion: version) + XCTAssertEqual((error as NSError).domain, CoreStoreErrorDomain) + XCTAssertEqual((error as NSError).code, CoreStoreErrorCode.MappingModelNotFound.rawValue) + + let userInfo: NSDictionary = [ + "localStoreURL": dummyURL, + "targetModel": model, + "targetModelVersion": version + ] + let objcError = error.objc + XCTAssertEqual(error, objcError.swift) + XCTAssertEqual(objcError.domain, CoreStoreErrorDomain) + XCTAssertEqual(objcError.code, CoreStoreErrorCode.MappingModelNotFound.rawValue) + XCTAssertEqual(objcError.userInfo, userInfo) + + let objcError2 = objcError.swift.objc + XCTAssertEqual(error, objcError2.swift) + XCTAssertEqual(objcError2.domain, CoreStoreErrorDomain) + XCTAssertEqual(objcError2.code, CoreStoreErrorCode.MappingModelNotFound.rawValue) + XCTAssertEqual(objcError2.userInfo, userInfo) + } + + do { + + let error = CoreStoreError.ProgressiveMigrationRequired(localStoreURL: dummyURL) + XCTAssertEqual((error as NSError).domain, CoreStoreErrorDomain) + XCTAssertEqual((error as NSError).code, CoreStoreErrorCode.ProgressiveMigrationRequired.rawValue) + + let userInfo: NSDictionary = [ + "localStoreURL": dummyURL + ] + let objcError = error.objc + XCTAssertEqual(error, objcError.swift) + XCTAssertEqual(objcError.domain, CoreStoreErrorDomain) + XCTAssertEqual(objcError.code, CoreStoreErrorCode.ProgressiveMigrationRequired.rawValue) + XCTAssertEqual(objcError.userInfo, userInfo) + + let objcError2 = objcError.swift.objc + XCTAssertEqual(error, objcError2.swift) + XCTAssertEqual(objcError2.domain, CoreStoreErrorDomain) + XCTAssertEqual(objcError2.code, CoreStoreErrorCode.ProgressiveMigrationRequired.rawValue) + XCTAssertEqual(objcError2.userInfo, userInfo) + } + + do { + + let internalError = NSError( + domain: "com.dummy", + code: 123, + userInfo: [ + "key1": "value1", + "key2": 2, + "key3": NSDate() + ] + ) + let error = CoreStoreError.InternalError(NSError: internalError) + XCTAssertEqual((error as NSError).domain, CoreStoreErrorDomain) + XCTAssertEqual((error as NSError).code, CoreStoreErrorCode.InternalError.rawValue) + + let userInfo: NSDictionary = [ + "NSError": internalError + ] + let objcError = error.objc + XCTAssertEqual(error, objcError.swift) + XCTAssertEqual(objcError.domain, CoreStoreErrorDomain) + XCTAssertEqual(objcError.code, CoreStoreErrorCode.InternalError.rawValue) + XCTAssertEqual(objcError.userInfo, userInfo) + + let objcError2 = objcError.swift.objc + XCTAssertEqual(error, objcError2.swift) + XCTAssertEqual(objcError2.domain, CoreStoreErrorDomain) + XCTAssertEqual(objcError2.code, CoreStoreErrorCode.InternalError.rawValue) + XCTAssertEqual(objcError2.userInfo, userInfo) + } + } +} diff --git a/Sources/CoreStoreError.swift b/Sources/CoreStoreError.swift index 5c02533..9b38b1e 100644 --- a/Sources/CoreStoreError.swift +++ b/Sources/CoreStoreError.swift @@ -29,7 +29,7 @@ import CoreData // MARK: - CoreStoreError -public enum CoreStoreError: ErrorType, CustomStringConvertible, CustomDebugStringConvertible { +public enum CoreStoreError: ErrorType, CustomStringConvertible, CustomDebugStringConvertible, Equatable { /** A failure occured because of an unknown error. @@ -61,26 +61,21 @@ public enum CoreStoreError: ErrorType, CustomStringConvertible, CustomDebugStrin public var _domain: String { - return "com.corestore.error" + return CoreStoreErrorDomain } public var _code: Int { switch self { - case .Unknown: return Code.Unknown.rawValue - case .DifferentStorageExistsAtURL: return Code.DifferentStorageExistsAtURL.rawValue - case .MappingModelNotFound: return Code.MappingModelNotFound.rawValue - case .ProgressiveMigrationRequired: return Code.ProgressiveMigrationRequired.rawValue - case .InternalError: return Code.InternalError.rawValue + case .Unknown: return CoreStoreErrorCode.UnknownError.rawValue + case .DifferentStorageExistsAtURL: return CoreStoreErrorCode.DifferentPersistentStoreExistsAtURL.rawValue + case .MappingModelNotFound: return CoreStoreErrorCode.MappingModelNotFound.rawValue + case .ProgressiveMigrationRequired: return CoreStoreErrorCode.ProgressiveMigrationRequired.rawValue + case .InternalError: return CoreStoreErrorCode.InternalError.rawValue } } - public var _userInfo: [NSObject: AnyObject] { - - return ["test": 1] - } - // MARK: CustomStringConvertible @@ -105,33 +100,51 @@ public enum CoreStoreError: ErrorType, CustomStringConvertible, CustomDebugStrin self = error.flatMap { $0.swift } ?? .Unknown } +} + + +// MARK: - CoreStoreError: Equatable + +@warn_unused_result +public func == (lhs: CoreStoreError, rhs: CoreStoreError) -> Bool { - - // MARK: Private - - private enum Code: Int { + switch (lhs, rhs) { - case Unknown - case DifferentStorageExistsAtURL - case MappingModelNotFound - case ProgressiveMigrationRequired - case InternalError + case (.Unknown, .Unknown): + return true + + case (.DifferentStorageExistsAtURL(let url1), .DifferentStorageExistsAtURL(let url2)): + return url1 == url2 + + case (.MappingModelNotFound(let url1, let model1, let version1), .MappingModelNotFound(let url2, let model2, let version2)): + return url1 == url2 && model1 == model2 && version1 == version2 + + case (.ProgressiveMigrationRequired(let url1), .ProgressiveMigrationRequired(let url2)): + return url1 == url2 + + case (.InternalError(let NSError1), .InternalError(let NSError2)): + return NSError1 == NSError2 + + default: + return false } } +// MARK: - CoreStoreErrorDomain + +/** + The `NSError` error domain for `CoreStore`. + */ +@nonobjc +public let CoreStoreErrorDomain = "com.corestore.error" + + // MARK: - CoreStoreErrorCode -/** - The `NSError` error domain for `CoreStore`. - */ -@available(*, deprecated=2.0.0, message="Use CoreStoreError enum values instead.") -public let CoreStoreErrorDomain = "com.corestore.error" - /** The `NSError` error codes for `CoreStoreErrorDomain`. */ -@available(*, deprecated=2.0.0, message="Use CoreStoreError enum values instead.") public enum CoreStoreErrorCode: Int { /** @@ -153,6 +166,11 @@ public enum CoreStoreErrorCode: Int { Progressive migrations are disabled for a store, but an `NSMappingModel` could not be found for a specific source and destination model versions. */ case ProgressiveMigrationRequired + + /** + An internal SDK call failed with the specified "NSError" userInfo key. + */ + case InternalError } @@ -203,12 +221,12 @@ internal extension ErrorType { return .Unknown } - guard error.domain == "com.corestore.error" else { + guard error.domain == CoreStoreErrorDomain else { return .InternalError(NSError: error) } - guard let code = CoreStoreError.Code(rawValue: error.code) else { + guard let code = CoreStoreErrorCode(rawValue: error.code) else { return .Unknown } @@ -216,10 +234,10 @@ internal extension ErrorType { let info = error.userInfo switch code { - case .Unknown: + case .UnknownError: return .Unknown - case .DifferentStorageExistsAtURL: + case .DifferentPersistentStoreExistsAtURL: guard case let existingPersistentStoreURL as NSURL = info["existingPersistentStoreURL"] else { return .Unknown @@ -253,23 +271,21 @@ internal extension ErrorType { internal var objc: NSError { - let domain = "com.corestore.error" guard let error = self as? CoreStoreError else { - return ((self as Any) as? NSError) - ?? NSError(domain: domain, code: CoreStoreError.Code.Unknown.rawValue, userInfo: [:]) + return ((self as Any) as? NSError) ?? self as NSError } - let code: CoreStoreError.Code + let code: CoreStoreErrorCode let info: [NSObject: AnyObject] switch error { case .Unknown: - code = .Unknown + code = .UnknownError info = [:] case .DifferentStorageExistsAtURL(let existingPersistentStoreURL): - code = .DifferentStorageExistsAtURL + code = .DifferentPersistentStoreExistsAtURL info = [ "existingPersistentStoreURL": existingPersistentStoreURL ] @@ -295,6 +311,6 @@ internal extension ErrorType { ] } - return NSError(domain: domain, code: code.rawValue, userInfo: info) + return NSError(domain: CoreStoreErrorDomain, code: code.rawValue, userInfo: info) } } diff --git a/Sources/Logging/CoreStoreLogger.swift b/Sources/Logging/CoreStoreLogger.swift index 4c86333..184115a 100644 --- a/Sources/Logging/CoreStoreLogger.swift +++ b/Sources/Logging/CoreStoreLogger.swift @@ -98,7 +98,7 @@ extension CoreStoreLogger { @available(*, deprecated=2.0.0, message="Use log(error:message:fileName:lineNumber:functionName:) instead.") public func handleError(error error: NSError, message: String, fileName: StaticString, lineNumber: Int, functionName: StaticString) { - self.log(error: (error as ErrorType) as! CoreStoreError, message: message, fileName: fileName, lineNumber: lineNumber, functionName: functionName) + self.log(error: error.swift, message: message, fileName: fileName, lineNumber: lineNumber, functionName: functionName) } } diff --git a/Sources/Logging/DefaultLogger.swift b/Sources/Logging/DefaultLogger.swift index c4cdbfb..dce6ac0 100644 --- a/Sources/Logging/DefaultLogger.swift +++ b/Sources/Logging/DefaultLogger.swift @@ -37,6 +37,9 @@ import Foundation */ public final class DefaultLogger: CoreStoreLogger { + /** + Creates a `DefaultLogger`. + */ public init() { } public func log(level level: LogLevel, message: String, fileName: StaticString, lineNumber: Int, functionName: StaticString) { diff --git a/Sources/ObjectiveC/CSAsynchronousDataTransaction.swift b/Sources/ObjectiveC/CSAsynchronousDataTransaction.swift new file mode 100644 index 0000000..27501e0 --- /dev/null +++ b/Sources/ObjectiveC/CSAsynchronousDataTransaction.swift @@ -0,0 +1,38 @@ +// +// CSAsynchronousDataTransaction.swift +// CoreStore +// +// Copyright © 2016 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 + + +// MARK: - CSAsynchronousDataTransaction + +@objc +public final class CSAsynchronousDataTransaction: CSBaseDataTransaction { + + internal init(_ swiftObject: AsynchronousDataTransaction) { + + super.init(swiftObject) + } +} diff --git a/Sources/ObjectiveC/CSBaseDataTransaction.swift b/Sources/ObjectiveC/CSBaseDataTransaction.swift new file mode 100644 index 0000000..12c546c --- /dev/null +++ b/Sources/ObjectiveC/CSBaseDataTransaction.swift @@ -0,0 +1,430 @@ +// +// CSBaseDataTransaction.swift +// CoreStore +// +// Copyright © 2016 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 + + +// MARK: - DataStack + +extension BaseDataTransaction { + + var objc: CSBaseDataTransaction { + + return CSBaseDataTransaction(self) + } +} + + +// MARK: - CSBaseDataTransaction + +/** + The `CSBaseDataTransaction` serves as the Objective-C bridging type for `BaseDataTransaction`. + */ +@objc +public class CSBaseDataTransaction: NSObject { + + // MARK: Object management + + /** + Indicates if the transaction has pending changes + */ + @objc + public var hasChanges: Bool { + + return self.swift.hasChanges + } + + /** + Creates a new `NSManagedObject` with the specified entity type. + + - parameter into: the `Into` clause indicating the destination `NSManagedObject` entity type and the destination configuration + - returns: a new `NSManagedObject` instance of the specified entity type. + */ + @objc + public func create(into into: NSManagedObject.Type) -> NSManagedObject { + + return self.swift.create(Into(into)) + } + + /** + Returns an editable proxy of a specified `NSManagedObject`. + + - parameter object: the `NSManagedObject` type to be edited + - returns: an editable proxy for the specified `NSManagedObject`. + */ + @objc + @warn_unused_result + public func edit(object: NSManagedObject?) -> NSManagedObject? { + + return self.swift.edit(object) + } + +// /** +// Returns an editable proxy of the object with the specified `NSManagedObjectID`. +// +// - parameter into: an `Into` clause specifying the entity type +// - parameter objectID: the `NSManagedObjectID` for the object to be edited +// - returns: an editable proxy for the specified `NSManagedObject`. +// */ +// @warn_unused_result +// public func edit(into: Into, _ objectID: NSManagedObjectID) -> T? { +// +// CoreStore.assert( +// self.isRunningInAllowedQueue(), +// "Attempted to update an entity of type \(typeName(T)) outside its designated queue." +// ) +// CoreStore.assert( +// into.inferStoreIfPossible +// || (into.configuration ?? Into.defaultConfigurationName) == objectID.persistentStore?.configurationName, +// "Attempted to update an entity of type \(typeName(T)) but the specified persistent store do not match the `NSManagedObjectID`." +// ) +// return self.fetchExisting(objectID) as? T +// } +// +// /** +// Deletes a specified `NSManagedObject`. +// +// - parameter object: the `NSManagedObject` to be deleted +// */ +// public func delete(object: NSManagedObject?) { +// +// CoreStore.assert( +// self.isRunningInAllowedQueue(), +// "Attempted to delete an entity outside its designated queue." +// ) +// guard let object = object else { +// +// return +// } +// self.context.fetchExisting(object)?.deleteFromContext() +// } +// +// /** +// Deletes the specified `NSManagedObject`s. +// +// - parameter object1: the `NSManagedObject` to be deleted +// - parameter object2: another `NSManagedObject` to be deleted +// - parameter objects: other `NSManagedObject`s to be deleted +// */ +// public func delete(object1: NSManagedObject?, _ object2: NSManagedObject?, _ objects: NSManagedObject?...) { +// +// self.delete(([object1, object2] + objects).flatMap { $0 }) +// } +// +// /** +// Deletes the specified `NSManagedObject`s. +// +// - parameter objects: the `NSManagedObject`s to be deleted +// */ +// public func delete(objects: S) { +// +// CoreStore.assert( +// self.isRunningInAllowedQueue(), +// "Attempted to delete entities outside their designated queue." +// ) +// +// let context = self.context +// objects.forEach { context.fetchExisting($0)?.deleteFromContext() } +// } +// +// /** +// Refreshes all registered objects `NSManagedObject`s in the transaction. +// */ +// public func refreshAllObjectsAsFaults() { +// +// CoreStore.assert( +// self.isRunningInAllowedQueue(), +// "Attempted to refresh entities outside their designated queue." +// ) +// +// self.context.refreshAllObjectsAsFaults() +// } +// +// +// // MARK: Inspecting Pending Objects +// +// /** +// Returns all pending `NSManagedObject`s that were inserted to the transaction. This method should not be called after the `commit()` method was called. +// +// - returns: a `Set` of pending `NSManagedObject`s that were inserted to the transaction. +// */ +// public func insertedObjects() -> Set { +// +// CoreStore.assert( +// self.transactionQueue.isCurrentExecutionContext(), +// "Attempted to access inserted objects from a \(typeName(self)) outside its designated queue." +// ) +// CoreStore.assert( +// !self.isCommitted, +// "Attempted to access inserted objects from an already committed \(typeName(self))." +// ) +// +// return self.context.insertedObjects +// } +// +// /** +// Returns all pending `NSManagedObject`s of the specified type that were inserted to the transaction. This method should not be called after the `commit()` method was called. +// +// - parameter entity: the `NSManagedObject` subclass to filter +// - returns: a `Set` of pending `NSManagedObject`s of the specified type that were inserted to the transaction. +// */ +// public func insertedObjects(entity: T.Type) -> Set { +// +// CoreStore.assert( +// self.transactionQueue.isCurrentExecutionContext(), +// "Attempted to access inserted objects from a \(typeName(self)) outside its designated queue." +// ) +// CoreStore.assert( +// !self.isCommitted, +// "Attempted to access inserted objects from an already committed \(typeName(self))." +// ) +// +// return Set(self.context.insertedObjects.flatMap { $0 as? T }) +// } +// +// /** +// Returns all pending `NSManagedObjectID`s that were inserted to the transaction. This method should not be called after the `commit()` method was called. +// +// - returns: a `Set` of pending `NSManagedObjectID`s that were inserted to the transaction. +// */ +// public func insertedObjectIDs() -> Set { +// +// CoreStore.assert( +// self.transactionQueue.isCurrentExecutionContext(), +// "Attempted to access inserted object IDs from a \(typeName(self)) outside its designated queue." +// ) +// CoreStore.assert( +// !self.isCommitted, +// "Attempted to access inserted objects IDs from an already committed \(typeName(self))." +// ) +// +// return Set(self.context.insertedObjects.map { $0.objectID }) +// } +// +// /** +// Returns all pending `NSManagedObjectID`s of the specified type that were inserted to the transaction. This method should not be called after the `commit()` method was called. +// +// - parameter entity: the `NSManagedObject` subclass to filter +// - returns: a `Set` of pending `NSManagedObjectID`s of the specified type that were inserted to the transaction. +// */ +// public func insertedObjectIDs(entity: T.Type) -> Set { +// +// CoreStore.assert( +// self.transactionQueue.isCurrentExecutionContext(), +// "Attempted to access inserted object IDs from a \(typeName(self)) outside its designated queue." +// ) +// CoreStore.assert( +// !self.isCommitted, +// "Attempted to access inserted objects IDs from an already committed \(typeName(self))." +// ) +// +// return Set(self.context.insertedObjects.flatMap { $0 as? T }.map { $0.objectID }) +// } +// +// /** +// Returns all pending `NSManagedObject`s that were updated in the transaction. This method should not be called after the `commit()` method was called. +// +// - returns: a `Set` of pending `NSManagedObject`s that were updated to the transaction. +// */ +// public func updatedObjects() -> Set { +// +// CoreStore.assert( +// self.transactionQueue.isCurrentExecutionContext(), +// "Attempted to access updated objects from a \(typeName(self)) outside its designated queue." +// ) +// CoreStore.assert( +// !self.isCommitted, +// "Attempted to access updated objects from an already committed \(typeName(self))." +// ) +// +// return self.context.updatedObjects +// } +// +// /** +// Returns all pending `NSManagedObject`s of the specified type that were updated in the transaction. This method should not be called after the `commit()` method was called. +// +// - parameter entity: the `NSManagedObject` subclass to filter +// - returns: a `Set` of pending `NSManagedObject`s of the specified type that were updated in the transaction. +// */ +// public func updatedObjects(entity: T.Type) -> Set { +// +// CoreStore.assert( +// self.transactionQueue.isCurrentExecutionContext(), +// "Attempted to access updated objects from a \(typeName(self)) outside its designated queue." +// ) +// CoreStore.assert( +// !self.isCommitted, +// "Attempted to access updated objects from an already committed \(typeName(self))." +// ) +// +// return Set(self.context.updatedObjects.flatMap { $0 as? T }) +// } +// +// /** +// Returns all pending `NSManagedObjectID`s that were updated in the transaction. This method should not be called after the `commit()` method was called. +// +// - returns: a `Set` of pending `NSManagedObjectID`s that were updated in the transaction. +// */ +// public func updatedObjectIDs() -> Set { +// +// CoreStore.assert( +// self.transactionQueue.isCurrentExecutionContext(), +// "Attempted to access updated object IDs from a \(typeName(self)) outside its designated queue." +// ) +// CoreStore.assert( +// !self.isCommitted, +// "Attempted to access updated object IDs from an already committed \(typeName(self))." +// ) +// +// return Set(self.context.updatedObjects.map { $0.objectID }) +// } +// +// /** +// Returns all pending `NSManagedObjectID`s of the specified type that were updated in the transaction. This method should not be called after the `commit()` method was called. +// +// - parameter entity: the `NSManagedObject` subclass to filter +// - returns: a `Set` of pending `NSManagedObjectID`s of the specified type that were updated in the transaction. +// */ +// public func updatedObjectIDs(entity: T.Type) -> Set { +// +// CoreStore.assert( +// self.transactionQueue.isCurrentExecutionContext(), +// "Attempted to access updated object IDs from a \(typeName(self)) outside its designated queue." +// ) +// CoreStore.assert( +// !self.isCommitted, +// "Attempted to access updated object IDs from an already committed \(typeName(self))." +// ) +// +// return Set(self.context.updatedObjects.flatMap { $0 as? T }.map { $0.objectID }) +// } +// +// /** +// Returns all pending `NSManagedObject`s that were deleted from the transaction. This method should not be called after the `commit()` method was called. +// +// - returns: a `Set` of pending `NSManagedObject`s that were deleted from the transaction. +// */ +// public func deletedObjects() -> Set { +// +// CoreStore.assert( +// self.transactionQueue.isCurrentExecutionContext(), +// "Attempted to access deleted objects from a \(typeName(self)) outside its designated queue." +// ) +// CoreStore.assert( +// !self.isCommitted, +// "Attempted to access deleted objects from an already committed \(typeName(self))." +// ) +// +// return self.context.deletedObjects +// } +// +// /** +// Returns all pending `NSManagedObject`s of the specified type that were deleted from the transaction. This method should not be called after the `commit()` method was called. +// +// - parameter entity: the `NSManagedObject` subclass to filter +// - returns: a `Set` of pending `NSManagedObject`s of the specified type that were deleted from the transaction. +// */ +// public func deletedObjects(entity: T.Type) -> Set { +// +// CoreStore.assert( +// self.transactionQueue.isCurrentExecutionContext(), +// "Attempted to access deleted objects from a \(typeName(self)) outside its designated queue." +// ) +// CoreStore.assert( +// !self.isCommitted, +// "Attempted to access deleted objects from an already committed \(typeName(self))." +// ) +// +// return Set(self.context.deletedObjects.flatMap { $0 as? T }) +// } +// +// /** +// Returns all pending `NSManagedObjectID`s of the specified type that were deleted from the transaction. This method should not be called after the `commit()` method was called. +// +// - parameter entity: the `NSManagedObject` subclass to filter +// - returns: a `Set` of pending `NSManagedObjectID`s of the specified type that were deleted from the transaction. +// */ +// public func deletedObjectIDs() -> Set { +// +// CoreStore.assert( +// self.transactionQueue.isCurrentExecutionContext(), +// "Attempted to access deleted object IDs from a \(typeName(self)) outside its designated queue." +// ) +// CoreStore.assert( +// !self.isCommitted, +// "Attempted to access deleted object IDs from an already committed \(typeName(self))." +// ) +// +// return Set(self.context.deletedObjects.map { $0.objectID }) +// } +// +// /** +// Returns all pending `NSManagedObjectID`s of the specified type that were deleted from the transaction. This method should not be called after the `commit()` method was called. +// +// - parameter entity: the `NSManagedObject` subclass to filter +// - returns: a `Set` of pending `NSManagedObjectID`s of the specified type that were deleted from the transaction. +// */ +// public func deletedObjectIDs(entity: T.Type) -> Set { +// +// CoreStore.assert( +// self.transactionQueue.isCurrentExecutionContext(), +// "Attempted to access deleted object IDs from a \(typeName(self)) outside its designated queue." +// ) +// CoreStore.assert( +// !self.isCommitted, +// "Attempted to access deleted object IDs from an already committed \(typeName(self))." +// ) +// +// return Set(self.context.deletedObjects.flatMap { $0 as? T }.map { $0.objectID }) +// } + + + // MARK: NSObject + + public override var hash: Int { + + return ObjectIdentifier(self.swift).hashValue + } + + public override func isEqual(object: AnyObject?) -> Bool { + + guard let object = object as? CSBaseDataTransaction else { + + return false + } + return self.swift === object.swift + } + + + // MARK: CoreStoreBridge + + internal let swift: BaseDataTransaction + + internal init(_ swiftObject: BaseDataTransaction) { + + self.swift = swiftObject + super.init() + } +} diff --git a/Sources/ObjectiveC/CSCoreStore+Setup.swift b/Sources/ObjectiveC/CSCoreStore+Setup.swift index d7b6151..c59c144 100644 --- a/Sources/ObjectiveC/CSCoreStore+Setup.swift +++ b/Sources/ObjectiveC/CSCoreStore+Setup.swift @@ -48,7 +48,10 @@ public extension CSCoreStore { @objc public static func addInMemoryStorageAndWait() throws -> CSInMemoryStore { - return try CoreStore.defaultStack.addStorageAndWait(InMemoryStore).objc + return try bridge { + + try CoreStore.defaultStack.addStorageAndWait(InMemoryStore) + } } /** @@ -62,7 +65,10 @@ public extension CSCoreStore { @objc public static func addSQLiteStorageAndWait() throws -> CSSQLiteStore { - return try CoreStore.defaultStack.addStorageAndWait(SQLiteStore).objc + return try bridge { + + try CoreStore.defaultStack.addStorageAndWait(SQLiteStore) + } } /** @@ -80,7 +86,10 @@ public extension CSCoreStore { @objc public static func addInMemoryStorageAndWait(storage: CSInMemoryStore) throws -> CSInMemoryStore { - return try CoreStore.defaultStack.addStorageAndWait(storage.swift).objc + return try bridge { + + try CoreStore.defaultStack.addStorageAndWait(storage.swift) + } } /** @@ -98,6 +107,9 @@ public extension CSCoreStore { @objc public static func addSQLiteStorageAndWait(storage: CSSQLiteStore) throws -> CSSQLiteStore { - return try CoreStore.defaultStack.addStorageAndWait(storage.swift).objc + return try bridge { + + try CoreStore.defaultStack.addStorageAndWait(storage.swift) + } } } \ No newline at end of file diff --git a/Sources/ObjectiveC/CSCoreStoreLogger.swift b/Sources/ObjectiveC/CSCoreStoreLogger.swift deleted file mode 100644 index 6fdead9..0000000 --- a/Sources/ObjectiveC/CSCoreStoreLogger.swift +++ /dev/null @@ -1,13 +0,0 @@ -// -// CSCoreStoreLogger.swift -// CoreStore -// -// Created by John Rommel Estropia on 2016/03/19. -// Copyright © 2016 John Rommel Estropia. All rights reserved. -// - -import UIKit - -class CSCoreStoreLogger: NSObject { - -} diff --git a/Sources/ObjectiveC/CSDataStack.swift b/Sources/ObjectiveC/CSDataStack.swift index 534a330..a4e281d 100644 --- a/Sources/ObjectiveC/CSDataStack.swift +++ b/Sources/ObjectiveC/CSDataStack.swift @@ -164,7 +164,10 @@ public final class CSDataStack: NSObject, CoreStoreBridge { @objc public func addInMemoryStorageAndWait() throws -> CSInMemoryStore { - return try self.swift.addStorageAndWait(InMemoryStore).objc + return try bridge { + + try self.swift.addStorageAndWait(InMemoryStore) + } } /** @@ -178,7 +181,10 @@ public final class CSDataStack: NSObject, CoreStoreBridge { @objc public func addSQLiteStorageAndWait() throws -> CSSQLiteStore { - return try self.swift.addStorageAndWait(SQLiteStore).objc + return try bridge { + + return try self.swift.addStorageAndWait(SQLiteStore) + } } /** @@ -196,7 +202,10 @@ public final class CSDataStack: NSObject, CoreStoreBridge { @objc public func addInMemoryStorageAndWait(storage: CSInMemoryStore) throws -> CSInMemoryStore { - return try self.swift.addStorageAndWait(storage.swift).objc + return try bridge { + + return try self.swift.addStorageAndWait(storage.swift) + } } /** @@ -214,7 +223,10 @@ public final class CSDataStack: NSObject, CoreStoreBridge { @objc public func addSQLiteStorageAndWait(storage: CSSQLiteStore) throws -> CSSQLiteStore { - return try self.swift.addStorageAndWait(storage.swift).objc + return try bridge { + + return try self.swift.addStorageAndWait(storage.swift) + } } diff --git a/Sources/ObjectiveC/CSError.swift b/Sources/ObjectiveC/CSError.swift new file mode 100644 index 0000000..758c361 --- /dev/null +++ b/Sources/ObjectiveC/CSError.swift @@ -0,0 +1,82 @@ +// +// CSError.swift +// CoreStore +// +// Copyright © 2016 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. +// + + +// MARK: - CSError + +/** + The `CSError` provides a facade for CoreStore Objective-C constants. + */ +public final class CSError: NSObject { + + /** + The `NSError` error domain for `CSCoreStore`. + */ + @objc + public static let domain = CoreStoreErrorDomain + + + // MARK: Private + + private override init() { + + fatalError() + } +} + + +// MARK: - CSErrorCode + +/** + The `NSError` error codes for `CSError.Domain`. + */ +@objc +public enum CSErrorCode: Int { + + /** + A failure occured because of an unknown error. + */ + case UnknownError + + /** + The `NSPersistentStore` could note be initialized because another store existed at the specified `NSURL`. + */ + case DifferentPersistentStoreExistsAtURL + + /** + An `NSMappingModel` could not be found for a specific source and destination model versions. + */ + case MappingModelNotFound + + /** + Progressive migrations are disabled for a store, but an `NSMappingModel` could not be found for a specific source and destination model versions. + */ + case ProgressiveMigrationRequired + + /** + An internal SDK call failed with the specified "NSError" userInfo key. + */ + case InternalError +} diff --git a/Sources/ObjectiveC/CSInMemoryStore.swift b/Sources/ObjectiveC/CSInMemoryStore.swift index 3334c2f..71dc403 100644 --- a/Sources/ObjectiveC/CSInMemoryStore.swift +++ b/Sources/ObjectiveC/CSInMemoryStore.swift @@ -43,7 +43,7 @@ extension InMemoryStore: CoreStoreBridgeable { The `CSInMemoryStore` serves as the Objective-C bridging type for `InMemoryStore`. */ @objc -public final class CSInMemoryStore: NSObject, CoreStoreBridge { +public final class CSInMemoryStore: NSObject, CSStorageInterface, CoreStoreBridge { /** Initializes a `CSInMemoryStore` for the specified configuration diff --git a/Sources/ObjectiveC/CSSQliteStore.swift b/Sources/ObjectiveC/CSSQliteStore.swift index a4c822a..4584a66 100644 --- a/Sources/ObjectiveC/CSSQliteStore.swift +++ b/Sources/ObjectiveC/CSSQliteStore.swift @@ -40,10 +40,10 @@ extension SQLiteStore: CoreStoreBridgeable { // MARK: - CSSQLiteStore /** - The `CSSQLiteStore` serves as the Objective-C bridging type for `CSSQLiteStore`. + The `CSSQLiteStore` serves as the Objective-C bridging type for `SQLiteStore`. */ @objc -public final class CSSQLiteStore: NSObject, CoreStoreBridge { +public final class CSSQLiteStore: NSObject, CSLocalStorage, CoreStoreBridge { /** Initializes an SQLite store interface from the given SQLite file URL. When this instance is passed to the `CSDataStack`'s `addStorage()` methods, a new SQLite file will be created if it does not exist. @@ -163,7 +163,10 @@ public final class CSSQLiteStore: NSObject, CoreStoreBridge { @objc public func eraseStorageAndWait(soureModel soureModel: NSManagedObjectModel) throws { - try self.swift.eraseStorageAndWait(soureModel: soureModel) + try bridge { + + try self.swift.eraseStorageAndWait(soureModel: soureModel) + } } diff --git a/Sources/ObjectiveC/CoreStoreBridge.swift b/Sources/ObjectiveC/CoreStoreBridge.swift index f6cd6fd..15dfb99 100644 --- a/Sources/ObjectiveC/CoreStoreBridge.swift +++ b/Sources/ObjectiveC/CoreStoreBridge.swift @@ -25,6 +25,9 @@ import Foundation + +// MARK: - CoreStoreBridge + public protocol CoreStoreBridge: class, AnyObject { associatedtype SwiftType @@ -34,6 +37,9 @@ public protocol CoreStoreBridge: class, AnyObject { init(_ swiftObject: SwiftType) } + +// MARK: - CoreStoreBridgeable + public protocol CoreStoreBridgeable: _ObjectiveCBridgeable { associatedtype ObjCType: CoreStoreBridge @@ -72,3 +78,37 @@ public extension CoreStoreBridgeable where Self == ObjCType.SwiftType { return self._bridgeToObjectiveC() } } + + +// MARK: - Internal + +internal func bridge(@noescape closure: () -> T) -> T.ObjCType { + + return closure().objc +} + +internal func bridge(@noescape closure: () throws -> T) throws -> T.ObjCType { + + do { + + return try closure().objc + } + catch { + + throw error.objc + } +} + +internal func bridge(@noescape closure: () throws -> Void) throws { + + do { + + try closure() + } + catch { + + throw error.objc + } +} + +