diff --git a/CoreStore.xcodeproj/project.pbxproj b/CoreStore.xcodeproj/project.pbxproj index 3d8e387..7987477 100644 --- a/CoreStore.xcodeproj/project.pbxproj +++ b/CoreStore.xcodeproj/project.pbxproj @@ -398,6 +398,10 @@ B59FA0B11CCBACA7007C9BCA /* ICloudStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B59FA0AD1CCBAC95007C9BCA /* ICloudStore.swift */; }; B59FA0B21CCBACA8007C9BCA /* ICloudStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B59FA0AD1CCBAC95007C9BCA /* ICloudStore.swift */; }; B5A261211B64BFDB006EB6D3 /* MigrationType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A261201B64BFDB006EB6D3 /* MigrationType.swift */; }; + B5A27F861E857C5300203C3E /* TransactionResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A27F851E857C5300203C3E /* TransactionResult.swift */; }; + B5A27F871E857C5300203C3E /* TransactionResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A27F851E857C5300203C3E /* TransactionResult.swift */; }; + B5A27F881E857C5300203C3E /* TransactionResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A27F851E857C5300203C3E /* TransactionResult.swift */; }; + B5A27F891E857C5300203C3E /* TransactionResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A27F851E857C5300203C3E /* TransactionResult.swift */; }; B5A5F2661CAEC50F004AB9AF /* CSSelect.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A5F2651CAEC50F004AB9AF /* CSSelect.swift */; }; B5A5F2681CAEC50F004AB9AF /* CSSelect.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A5F2651CAEC50F004AB9AF /* CSSelect.swift */; }; B5A5F2691CAEC50F004AB9AF /* CSSelect.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A5F2651CAEC50F004AB9AF /* CSSelect.swift */; }; @@ -685,6 +689,7 @@ B59AFF401C6593E400C0ABE2 /* NSPersistentStoreCoordinator+Setup.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSPersistentStoreCoordinator+Setup.swift"; sourceTree = ""; }; B59FA0AD1CCBAC95007C9BCA /* ICloudStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ICloudStore.swift; sourceTree = ""; }; B5A261201B64BFDB006EB6D3 /* MigrationType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MigrationType.swift; sourceTree = ""; }; + B5A27F851E857C5300203C3E /* TransactionResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionResult.swift; sourceTree = ""; }; B5A5F2651CAEC50F004AB9AF /* CSSelect.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSSelect.swift; sourceTree = ""; }; B5AD60CD1C90141E00F2B2E8 /* Package.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Package.swift; sourceTree = SOURCE_ROOT; }; B5AEFAB41C9962AE00AD137F /* CoreStoreBridge.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreStoreBridge.swift; sourceTree = ""; }; @@ -1160,6 +1165,7 @@ B5E84EEE1AFF846E0064E85B /* CoreStore+Transaction.swift */, B50392F81C478FF3009900CA /* NSManagedObject+Transaction.swift */, B5E84EF21AFF846E0064E85B /* SaveResult.swift */, + B5A27F851E857C5300203C3E /* TransactionResult.swift */, ); path = Transactions; sourceTree = ""; @@ -1603,6 +1609,7 @@ B549F6731E56A92800FBAB2D /* CoreDataNativeType.swift in Sources */, B509C7F41E54511B0061C547 /* ImportableAttributeType.swift in Sources */, B5E84F0E1AFF847B0064E85B /* Tweak.swift in Sources */, + B5A27F861E857C5300203C3E /* TransactionResult.swift in Sources */, B5E1B5931CAA0C15007FD580 /* CSObjectMonitor.swift in Sources */, B5ECDC291CA81CC700C7F112 /* CSDataStack+Transaction.swift in Sources */, B5E84F121AFF847B0064E85B /* OrderBy.swift in Sources */, @@ -1759,6 +1766,7 @@ B549F6741E56A92800FBAB2D /* CoreDataNativeType.swift in Sources */, B509C7F51E54511B0061C547 /* ImportableAttributeType.swift in Sources */, 82BA18B31C4BBD3900A0916E /* ImportableUniqueObject.swift in Sources */, + B5A27F871E857C5300203C3E /* TransactionResult.swift in Sources */, B5E1B5951CAA0C15007FD580 /* CSObjectMonitor.swift in Sources */, B5ECDC2B1CA81CC700C7F112 /* CSDataStack+Transaction.swift in Sources */, 82BA18A11C4BBD1D00A0916E /* CoreStore.swift in Sources */, @@ -1915,6 +1923,7 @@ B549F6761E56A92800FBAB2D /* CoreDataNativeType.swift in Sources */, B509C7F71E54511B0061C547 /* ImportableAttributeType.swift in Sources */, B5220E1F1D130810009BC71E /* CSListObserver.swift in Sources */, + B5A27F891E857C5300203C3E /* TransactionResult.swift in Sources */, B52DD1941BE1F92500949AFE /* CoreStore.swift in Sources */, B52DD1A61BE1F92F00949AFE /* BaseDataTransaction+Importing.swift in Sources */, B5220E1D1D13080A009BC71E /* CSDataStack+Observing.swift in Sources */, @@ -2071,6 +2080,7 @@ B549F6751E56A92800FBAB2D /* CoreDataNativeType.swift in Sources */, B509C7F61E54511B0061C547 /* ImportableAttributeType.swift in Sources */, B5E1B5961CAA0C15007FD580 /* CSObjectMonitor.swift in Sources */, + B5A27F881E857C5300203C3E /* TransactionResult.swift in Sources */, B5ECDC2C1CA81CC700C7F112 /* CSDataStack+Transaction.swift in Sources */, B56321911BD65216006C9394 /* BaseDataTransaction+Importing.swift in Sources */, B546F95A1C99B17400D5AC55 /* CSCoreStore+Setup.swift in Sources */, diff --git a/CoreStoreTests/TransactionTests.swift b/CoreStoreTests/TransactionTests.swift index e4a6504..f842f66 100644 --- a/CoreStoreTests/TransactionTests.swift +++ b/CoreStoreTests/TransactionTests.swift @@ -42,7 +42,7 @@ final class TransactionTests: BaseTestCase { do { let createExpectation = self.expectation(description: "create") - let hasChanges: Bool = stack.perform( + let hasChanges: Bool = try! stack.perform( synchronous: { (transaction) in defer { @@ -84,7 +84,7 @@ final class TransactionTests: BaseTestCase { do { let updateExpectation = self.expectation(description: "update") - let hasChanges: Bool = stack.perform( + let hasChanges: Bool = try! stack.perform( synchronous: { (transaction) in defer { @@ -92,9 +92,9 @@ final class TransactionTests: BaseTestCase { updateExpectation.fulfill() } guard let object = transaction.fetchOne(From()) else { - - XCTFail() - return // TODO: convert fetch methods to throwing methods + // TODO: convert fetch methods to throwing methods + XCTFail() + try transaction.cancel() } object.testString = "string1_edit" object.testNumber = 200 diff --git a/Sources/Fetching and Querying/QueryableAttributeType.swift b/Sources/Fetching and Querying/QueryableAttributeType.swift index 28db6ec..12a19f0 100644 --- a/Sources/Fetching and Querying/QueryableAttributeType.swift +++ b/Sources/Fetching and Querying/QueryableAttributeType.swift @@ -55,6 +55,7 @@ extension NSManagedObjectID: QueryableAttributeType { @nonobjc @inline(__always) public class func cs_fromQueryableNativeType(_ value: QueryableNativeType) -> Self? { + @inline(__always) func forceCast(_ value: Any) -> T? { return value as? T @@ -84,6 +85,7 @@ extension NSNumber: QueryableAttributeType { @nonobjc @inline(__always) public class func cs_fromQueryableNativeType(_ value: QueryableNativeType) -> Self? { + @inline(__always) func forceCast(_ value: Any) -> T? { return value as? T @@ -121,6 +123,7 @@ extension NSString: QueryableAttributeType { @nonobjc @inline(__always) public class func cs_fromQueryableNativeType(_ value: QueryableNativeType) -> Self? { + @inline(__always) func forceCast(_ value: Any) -> T? { return value as? T @@ -147,6 +150,7 @@ extension NSDate: QueryableAttributeType { @nonobjc @inline(__always) public class func cs_fromQueryableNativeType(_ value: QueryableNativeType) -> Self? { + @inline(__always) func forceCast(_ value: Any) -> T? { return value as? T @@ -173,6 +177,7 @@ extension NSData: QueryableAttributeType { @nonobjc @inline(__always) public class func cs_fromQueryableNativeType(_ value: QueryableNativeType) -> Self? { + @inline(__always) func forceCast(_ value: Any) -> T? { return value as? T @@ -204,7 +209,7 @@ extension Bool: QueryableAttributeType { case let decimal as NSDecimalNumber: // iOS: NSDecimalNumber(string: "0.5").boolValue // true // OSX: NSDecimalNumber(string: "0.5").boolValue // false - return NSNumber(value: decimal.doubleValue).boolValue + return decimal != NSDecimalNumber.zero default: return value.boolValue diff --git a/Sources/Importing/ImportableAttributeType.swift b/Sources/Importing/ImportableAttributeType.swift index c77d159..70b4f63 100644 --- a/Sources/Importing/ImportableAttributeType.swift +++ b/Sources/Importing/ImportableAttributeType.swift @@ -59,17 +59,13 @@ extension NSNumber: ImportableAttributeType { @nonobjc @inline(__always) public class func cs_fromImportableNativeType(_ value: ImportableNativeType) -> Self? { - func forceCast(_ value: Any) -> T? { - - return value as? T - } - return forceCast(value) + return self.cs_fromQueryableNativeType(value) } @nonobjc @inline(__always) public func cs_toImportableNativeType() -> ImportableNativeType { - return self + return self.cs_toQueryableNativeType() } } @@ -89,17 +85,13 @@ extension NSString: ImportableAttributeType { @nonobjc @inline(__always) public class func cs_fromImportableNativeType(_ value: ImportableNativeType) -> Self? { - func forceCast(_ value: Any) -> T? { - - return value as? T - } - return forceCast(value) + return self.cs_fromQueryableNativeType(value) } @nonobjc @inline(__always) public func cs_toImportableNativeType() -> ImportableNativeType { - return self + return self.cs_toQueryableNativeType() } } @@ -119,17 +111,13 @@ extension NSDate: ImportableAttributeType { @nonobjc @inline(__always) public class func cs_fromImportableNativeType(_ value: ImportableNativeType) -> Self? { - func forceCast(_ value: Any) -> T? { - - return value as? T - } - return forceCast(value) + return self.cs_fromQueryableNativeType(value) } @nonobjc @inline(__always) public func cs_toImportableNativeType() -> ImportableNativeType { - return self + return self.cs_toQueryableNativeType() } } @@ -149,17 +137,13 @@ extension NSData: ImportableAttributeType { @nonobjc @inline(__always) public class func cs_fromImportableNativeType(_ value: ImportableNativeType) -> Self? { - func forceCast(_ value: Any) -> T? { - - return value as? T - } - return forceCast(value) + return self.cs_fromQueryableNativeType(value) } @nonobjc @inline(__always) public func cs_toImportableNativeType() -> ImportableNativeType { - return self + return self.cs_toQueryableNativeType() } } @@ -179,22 +163,13 @@ extension Bool: ImportableAttributeType { @inline(__always) public static func cs_fromImportableNativeType(_ value: ImportableNativeType) -> Bool? { - switch value { - - case let decimal as NSDecimalNumber: - // iOS: NSDecimalNumber(string: "0.5").boolValue // true - // OSX: NSDecimalNumber(string: "0.5").boolValue // false - return decimal != NSDecimalNumber.zero - - default: - return value.boolValue - } + return self.cs_fromQueryableNativeType(value) } @inline(__always) public func cs_toImportableNativeType() -> ImportableNativeType { - return self as NSNumber + return self.cs_toQueryableNativeType() } } @@ -214,13 +189,13 @@ extension Int16: ImportableAttributeType { @inline(__always) public static func cs_fromImportableNativeType(_ value: ImportableNativeType) -> Int16? { - return value.int16Value + return self.cs_fromQueryableNativeType(value) } @inline(__always) public func cs_toImportableNativeType() -> ImportableNativeType { - return self as NSNumber + return self.cs_toQueryableNativeType() } } @@ -240,13 +215,13 @@ extension Int32: ImportableAttributeType { @inline(__always) public static func cs_fromImportableNativeType(_ value: ImportableNativeType) -> Int32? { - return value.int32Value + return self.cs_fromQueryableNativeType(value) } @inline(__always) public func cs_toImportableNativeType() -> ImportableNativeType { - return self as NSNumber + return self.cs_toQueryableNativeType() } } @@ -266,13 +241,13 @@ extension Int64: ImportableAttributeType { @inline(__always) public static func cs_fromImportableNativeType(_ value: ImportableNativeType) -> Int64? { - return value.int64Value + return self.cs_fromQueryableNativeType(value) } @inline(__always) public func cs_toImportableNativeType() -> ImportableNativeType { - return self as NSNumber + return self.cs_toQueryableNativeType() } } @@ -292,13 +267,13 @@ extension Double: ImportableAttributeType { @inline(__always) public static func cs_fromImportableNativeType(_ value: ImportableNativeType) -> Double? { - return value.doubleValue + return self.cs_fromQueryableNativeType(value) } @inline(__always) public func cs_toImportableNativeType() -> ImportableNativeType { - return self as NSNumber + return self.cs_toQueryableNativeType() } } @@ -318,13 +293,13 @@ extension Float: ImportableAttributeType { @inline(__always) public static func cs_fromImportableNativeType(_ value: ImportableNativeType) -> Float? { - return value.floatValue + return self.cs_fromQueryableNativeType(value) } @inline(__always) public func cs_toImportableNativeType() -> ImportableNativeType { - return self as NSNumber + return self.cs_toQueryableNativeType() } } @@ -344,13 +319,13 @@ extension Date: ImportableAttributeType { @inline(__always) public static func cs_fromImportableNativeType(_ value: ImportableNativeType) -> Date? { - return value as Date + return self.cs_fromQueryableNativeType(value) } @inline(__always) public func cs_toImportableNativeType() -> ImportableNativeType { - return self as NSDate + return self.cs_toQueryableNativeType() } } @@ -370,13 +345,13 @@ extension String: ImportableAttributeType { @inline(__always) public static func cs_fromImportableNativeType(_ value: ImportableNativeType) -> String? { - return value as String + return self.cs_fromQueryableNativeType(value) } @inline(__always) public func cs_toImportableNativeType() -> ImportableNativeType { - return self as NSString + return self.cs_toQueryableNativeType() } } @@ -396,12 +371,12 @@ extension Data: ImportableAttributeType { @inline(__always) public static func cs_fromImportableNativeType(_ value: ImportableNativeType) -> Data? { - return value as Data + return self.cs_fromQueryableNativeType(value) } @inline(__always) public func cs_toImportableNativeType() -> ImportableNativeType { - return self as NSData + return self.cs_toQueryableNativeType() } } diff --git a/Sources/Internal/CoreStoreFetchRequest+CoreStore.swift b/Sources/Internal/CoreStoreFetchRequest+CoreStore.swift index b5f26fa..cd2c3fb 100644 --- a/Sources/Internal/CoreStoreFetchRequest+CoreStore.swift +++ b/Sources/Internal/CoreStoreFetchRequest+CoreStore.swift @@ -33,7 +33,7 @@ internal extension CoreStoreFetchRequest { // MARK: Internal - @nonobjc + @nonobjc @inline(__always) internal func dynamicCast() -> NSFetchRequest { return unsafeBitCast(self, to: NSFetchRequest.self) diff --git a/Sources/Internal/DispatchQueue+CoreStore.swift b/Sources/Internal/DispatchQueue+CoreStore.swift index ac3c654..23c9009 100644 --- a/Sources/Internal/DispatchQueue+CoreStore.swift +++ b/Sources/Internal/DispatchQueue+CoreStore.swift @@ -30,7 +30,7 @@ import Foundation internal extension DispatchQueue { - @nonobjc + @nonobjc @inline(__always) internal static func serial(_ label: String, qos: DispatchQoS = .default) -> DispatchQueue { return DispatchQueue( @@ -42,7 +42,7 @@ internal extension DispatchQueue { ) } - @nonobjc + @nonobjc @inline(__always) internal static func concurrent(_ label: String, qos: DispatchQoS = .default) -> DispatchQueue { return DispatchQueue( @@ -54,7 +54,7 @@ internal extension DispatchQueue { ) } - @nonobjc + @nonobjc @inline(__always) internal func cs_isCurrentExecutionContext() -> Bool { let specific = ObjectIdentifier(self) @@ -63,25 +63,25 @@ internal extension DispatchQueue { return DispatchQueue.getSpecific(key: Static.specificKey) == specific } - @nonobjc + @nonobjc @inline(__always) internal func cs_sync(_ closure: () throws -> T) rethrows -> T { return try self.sync { try autoreleasepool(invoking: closure) } } - @nonobjc + @nonobjc @inline(__always) internal func cs_async(_ closure: @escaping () -> Void) { self.async { autoreleasepool(invoking: closure) } } - @nonobjc + @nonobjc @inline(__always) internal func cs_barrierSync(_ closure: () throws -> T) rethrows -> T { return try self.sync(flags: .barrier) { try autoreleasepool(invoking: closure) } } - @nonobjc + @nonobjc @inline(__always) internal func cs_barrierAsync(_ closure: @escaping () -> Void) { self.async(flags: .barrier) { autoreleasepool(invoking: closure) } diff --git a/Sources/Internal/Functions.swift b/Sources/Internal/Functions.swift index aa75930..e7191bc 100644 --- a/Sources/Internal/Functions.swift +++ b/Sources/Internal/Functions.swift @@ -27,6 +27,7 @@ import Foundation // MARK: Associated Objects +@inline(__always) internal func cs_getAssociatedObjectForKey(_ key: UnsafeRawPointer, inObject object: Any) -> T? { switch objc_getAssociatedObject(object, key) { @@ -42,16 +43,19 @@ internal func cs_getAssociatedObjectForKey(_ key: UnsafeRawPointer } } +@inline(__always) internal func cs_setAssociatedRetainedObject(_ associatedObject: T?, forKey key: UnsafeRawPointer, inObject object: Any) { objc_setAssociatedObject(object, key, associatedObject, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) } +@inline(__always) internal func cs_setAssociatedCopiedObject(_ associatedObject: T?, forKey key: UnsafeRawPointer, inObject object: Any) { objc_setAssociatedObject(object, key, associatedObject, .OBJC_ASSOCIATION_COPY_NONATOMIC) } +@inline(__always) internal func cs_setAssociatedWeakObject(_ associatedObject: T?, forKey key: UnsafeRawPointer, inObject object: Any) { if let associatedObject = associatedObject { @@ -67,26 +71,31 @@ internal func cs_setAssociatedWeakObject(_ associatedObject: T?, f // MARK: Printing Utilities +@inline(__always) internal func cs_typeName(_ value: T) -> String { return "'\(String(reflecting: type(of: value)))'" } +@inline(__always) internal func cs_typeName(_ value: T.Type) -> String { return "'\(value)'" } +@inline(__always) internal func cs_typeName(_ value: AnyClass) -> String { return "'\(value)'" } +@inline(__always) internal func cs_typeName(_ name: String) -> String { return "<\(name)>" } +@inline(__always) internal func cs_typeName(_ name: String?) -> String { return "<\(name ?? "unknown")>" diff --git a/Sources/Transactions/AsynchronousDataTransaction.swift b/Sources/Transactions/AsynchronousDataTransaction.swift index 6a0dcb4..f9228e7 100644 --- a/Sources/Transactions/AsynchronousDataTransaction.swift +++ b/Sources/Transactions/AsynchronousDataTransaction.swift @@ -34,6 +34,11 @@ import CoreData */ public final class AsynchronousDataTransaction: BaseDataTransaction { + public func cancel() throws -> Never { + + throw CoreStoreError.userCancelled + } + /** Saves the transaction changes. This method should not be used after the `commit()` method was already called once. diff --git a/Sources/Transactions/BaseDataTransaction.swift b/Sources/Transactions/BaseDataTransaction.swift index d0b25e6..6b6c0ec 100644 --- a/Sources/Transactions/BaseDataTransaction.swift +++ b/Sources/Transactions/BaseDataTransaction.swift @@ -36,12 +36,6 @@ public /*abstract*/ class BaseDataTransaction { // MARK: Object management - - public func cancel() throws -> Never { - - throw CoreStoreError.userCancelled - } - /** Indicates if the transaction has pending changes */ diff --git a/Sources/Transactions/DataStack+Transaction.swift b/Sources/Transactions/DataStack+Transaction.swift index 68e8d41..9b4076b 100644 --- a/Sources/Transactions/DataStack+Transaction.swift +++ b/Sources/Transactions/DataStack+Transaction.swift @@ -31,6 +31,16 @@ import CoreData public extension DataStack { + + public func perform(asynchronous task: @escaping (_ transaction: AsynchronousDataTransaction) throws -> T, completion: @escaping (TransactionResult) -> Void) { + + self.perform( + asynchronous: task, + success: { completion(TransactionResult(userInfo: $0)) }, + failure: { completion(TransactionResult(error: $0)) } + ) + } + public func perform(asynchronous task: @escaping (_ transaction: AsynchronousDataTransaction) throws -> T, success: @escaping (T) -> Void, failure: @escaping (CoreStoreError) -> Void) { let transaction = AsynchronousDataTransaction( @@ -40,28 +50,28 @@ public extension DataStack { ) transaction.transactionQueue.cs_async { + let userInfo: T do { - let extraInfo = try task(transaction) - transaction.commit { (result) in - - switch result { - - case .success: - success(extraInfo) - - case .failure(let error): - failure(error) - } - } + userInfo = try task(transaction) } catch let error as CoreStoreError { DispatchQueue.main.async { failure(error) } + return } catch let error { DispatchQueue.main.async { failure(.userError(error: error)) } + return + } + transaction.commit { (result) in + + switch result { + + case .success: success(userInfo) + case .failure(let error): failure(error) + } } } } @@ -75,10 +85,10 @@ public extension DataStack { ) return try transaction.transactionQueue.cs_sync { - let extraInfo: T + let userInfo: T do { - extraInfo = try task(transaction) + userInfo = try task(transaction) } catch let error as CoreStoreError { @@ -88,17 +98,13 @@ public extension DataStack { throw CoreStoreError.userError(error: error) } - let result = waitForObserverNotifications ? transaction.commitAndWait() : transaction.commit() switch result { - case .success: - return extraInfo - - case .failure(let error): - throw error + case .success: return userInfo + case .failure(let error): throw error } } } diff --git a/Sources/Transactions/SynchronousDataTransaction.swift b/Sources/Transactions/SynchronousDataTransaction.swift index a3785c3..5b63066 100644 --- a/Sources/Transactions/SynchronousDataTransaction.swift +++ b/Sources/Transactions/SynchronousDataTransaction.swift @@ -34,6 +34,11 @@ import CoreData */ public final class SynchronousDataTransaction: BaseDataTransaction { + public func cancel() throws -> Never { + + throw CoreStoreError.userCancelled + } + /** Saves the transaction changes and waits for completion synchronously. This method should not be used after the `commit()` or `commitAndWait()` method was already called once. - Important: Unlike `SynchronousDataTransaction.commit()`, this method waits for all observers to be notified of the changes before returning. This results in more predictable data update order, but may risk triggering deadlocks. diff --git a/Sources/Transactions/TransactionResult.swift b/Sources/Transactions/TransactionResult.swift new file mode 100644 index 0000000..16f29cf --- /dev/null +++ b/Sources/Transactions/TransactionResult.swift @@ -0,0 +1,58 @@ +// +// TransactionResult.swift +// CoreStore +// +// Copyright © 2017 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: - TransactionResult + +public enum TransactionResult { + + case success(T) + + case failure(CoreStoreError) + + public var boolValue: Bool { + + switch self { + + case .success: return true + case .failure: return false + } + } + + + // MARK: Internal + + internal init(userInfo: T) { + + self = .success(userInfo) + } + + internal init(error: CoreStoreError) { + + self = .failure(error) + } +}