From ab3095f07827b0bf75511f828af6b39734e4a93c Mon Sep 17 00:00:00 2001 From: John Rommel Estropia Date: Sun, 3 Apr 2016 13:37:00 +0900 Subject: [PATCH] WIP: documentation --- CoreStoreTests/CoreStoreTests.swift | 5 -- Sources/CoreStore.swift | 4 +- Sources/CoreStoreError.swift | 3 + .../Concrete Clauses/Select.swift | 76 ++++++++++++++++--- Sources/ObjectiveC/CSSelect.swift | 32 +++++++- 5 files changed, 99 insertions(+), 21 deletions(-) diff --git a/CoreStoreTests/CoreStoreTests.swift b/CoreStoreTests/CoreStoreTests.swift index 1a83ee3..f96d947 100644 --- a/CoreStoreTests/CoreStoreTests.swift +++ b/CoreStoreTests/CoreStoreTests.swift @@ -88,11 +88,6 @@ class CoreStoreTests: XCTestCase { obj1.testString = "lololol" obj1.testNumber = 42 obj1.testDate = NSDate() - let objID = transaction.queryValue( - From(TestEntity1), - Select(.Attribute("testEntityID")) - ) - print(objID) let count = transaction.queryValue( From(), diff --git a/Sources/CoreStore.swift b/Sources/CoreStore.swift index 7281956..e26c83f 100644 --- a/Sources/CoreStore.swift +++ b/Sources/CoreStore.swift @@ -38,8 +38,8 @@ public enum CoreStore { /** The default `DataStack` instance to be used. If `defaultStack` is not set before the first time accessed, a default-configured `DataStack` will be created. - - Changing the `defaultStack` is thread safe, but it is recommended to setup `DataStacks` on a common queue (e.g. the main queue). + - SeeAlso: `DataStack` + - Note: Changing the `defaultStack` is thread safe, but it is recommended to setup `DataStacks` on a common queue (e.g. the main queue). */ public static var defaultStack: DataStack { diff --git a/Sources/CoreStoreError.swift b/Sources/CoreStoreError.swift index a128d9f..3e66664 100644 --- a/Sources/CoreStoreError.swift +++ b/Sources/CoreStoreError.swift @@ -29,6 +29,9 @@ import CoreData // MARK: - CoreStoreError +/** + All errors thrown from CoreStore is expressed in `CoreStoreError` enum values. + */ public enum CoreStoreError: ErrorType, CustomStringConvertible, CustomDebugStringConvertible, Hashable { /** diff --git a/Sources/Fetching and Querying/Concrete Clauses/Select.swift b/Sources/Fetching and Querying/Concrete Clauses/Select.swift index 21b7d18..a7d124b 100644 --- a/Sources/Fetching and Querying/Concrete Clauses/Select.swift +++ b/Sources/Fetching and Querying/Concrete Clauses/Select.swift @@ -107,8 +107,8 @@ public enum SelectTerm: StringLiteralConvertible, Hashable { return ._Aggregate( function: "average:", - keyPath, - As: alias ?? "average(\(keyPath))", + keyPath: keyPath, + alias: alias ?? "average(\(keyPath))", nativeType: .DecimalAttributeType ) } @@ -129,8 +129,8 @@ public enum SelectTerm: StringLiteralConvertible, Hashable { return ._Aggregate( function: "count:", - keyPath, - As: alias ?? "count(\(keyPath))", + keyPath: keyPath, + alias: alias ?? "count(\(keyPath))", nativeType: .Integer64AttributeType ) } @@ -151,8 +151,8 @@ public enum SelectTerm: StringLiteralConvertible, Hashable { return ._Aggregate( function: "max:", - keyPath, - As: alias ?? "max(\(keyPath))", + keyPath: keyPath, + alias: alias ?? "max(\(keyPath))", nativeType: .UndefinedAttributeType ) } @@ -173,8 +173,8 @@ public enum SelectTerm: StringLiteralConvertible, Hashable { return ._Aggregate( function: "min:", - keyPath, - As: alias ?? "min(\(keyPath))", + keyPath: keyPath, + alias: alias ?? "min(\(keyPath))", nativeType: .UndefinedAttributeType ) } @@ -195,12 +195,33 @@ public enum SelectTerm: StringLiteralConvertible, Hashable { return ._Aggregate( function: "sum:", - keyPath, - As: alias ?? "sum(\(keyPath))", + keyPath: keyPath, + alias: alias ?? "sum(\(keyPath))", nativeType: .DecimalAttributeType ) } + /** + Provides a `SelectTerm` to a `Select` clause for querying the `NSManagedObjectID`. + ``` + let objectID = CoreStore.queryValue( + From(MyPersonEntity), + Select(), + Where("employeeID", isEqualTo: 1111) + ) + ``` + - parameter keyPath: the attribute name + - parameter alias: the dictionary key to use to access the result. Ignored when the query return value is not an `NSDictionary`. If `nil`, the default key "objecID" is used + - returns: a `SelectTerm` to a `Select` clause for querying the sum value for an attribute + */ + public static func ObjectID(As alias: KeyPath? = nil) -> SelectTerm { + + return ._Identity( + alias: alias ?? "objectID", + nativeType: .ObjectIDAttributeType + ) + } + // MARK: StringLiteralConvertible @@ -231,6 +252,9 @@ public enum SelectTerm: StringLiteralConvertible, Hashable { case ._Aggregate(let function, let keyPath, let alias, let nativeType): return 1 ^ function.hashValue ^ keyPath.hashValue ^ alias.hashValue ^ nativeType.hashValue + + case ._Identity(let alias, let nativeType): + return 3 ^ alias.hashValue ^ nativeType.hashValue } } @@ -238,7 +262,8 @@ public enum SelectTerm: StringLiteralConvertible, Hashable { // MARK: Internal case _Attribute(KeyPath) - case _Aggregate(function: String, KeyPath, As: String, nativeType: NSAttributeType) + case _Aggregate(function: String, keyPath: KeyPath, alias: String, nativeType: NSAttributeType) + case _Identity(alias: String, nativeType: NSAttributeType) } @@ -259,6 +284,9 @@ public func == (lhs: SelectTerm, rhs: SelectTerm) -> Bool { && alias1 == alias2 && nativeType1 == nativeType2 + case (._Identity(let alias1, let nativeType1), ._Identity(let alias2, let nativeType2)): + return alias1 == alias2 && nativeType1 == nativeType2 + default: return false } @@ -349,6 +377,14 @@ public struct Select: Hashable { internal let selectTerms: [SelectTerm] } +public extension Select where T: NSManagedObjectID { + + public init() { + + self.init(.ObjectID()) + } +} + // MARK: - Select: Equatable @@ -710,6 +746,21 @@ internal extension CollectionType where Generator.Element == SelectTerm { message: "The attribute \"\(keyPath)\" does not exist in entity \(typeName(entityDescription.managedObjectClassName)) and will be ignored by \(typeName(owner)) query clause." ) } + + case ._Identity(let alias, let nativeType): + let expressionDescription = NSExpressionDescription() + expressionDescription.name = alias + if nativeType == .UndefinedAttributeType { + + expressionDescription.expressionResultType = .ObjectIDAttributeType + } + else { + + expressionDescription.expressionResultType = nativeType + } + expressionDescription.expression = NSExpression.expressionForEvaluatedObject() + + propertiesToFetch.append(expressionDescription) } } @@ -725,6 +776,9 @@ internal extension CollectionType where Generator.Element == SelectTerm { case ._Aggregate(_, _, let alias, _): return alias + + case ._Identity(let alias, _): + return alias } } } diff --git a/Sources/ObjectiveC/CSSelect.swift b/Sources/ObjectiveC/CSSelect.swift index ad4522b..4f8b0d4 100644 --- a/Sources/ObjectiveC/CSSelect.swift +++ b/Sources/ObjectiveC/CSSelect.swift @@ -130,6 +130,32 @@ public final class CSSelectTerm: NSObject, CoreStoreObjectiveCType { return self.init(.Sum(keyPath, As: alias)) } + + /** + Provides a `CSSelectTerm` to a `CSSelect` clause for querying the `NSManagedObjectID`. + ``` + NSManagedObjectID *objectID = [CSCoreStore + queryValueFrom:[CSFrom entityClass:[MyPersonEntity class]] + select:[CSSelect objectIDForTerm:[CSSelectTerm objectIDAs:nil]] + fetchClauses:@[[CSWhere keyPath:@"employeeID" isEqualTo: @1111]]]; + + let objectID = CoreStore.queryValue( + From(MyPersonEntity), + Select(.ObjectID()), + Where("employeeID", isEqualTo: 1111) + ) + ``` + - parameter keyPath: the attribute name + - parameter alias: the dictionary key to use to access the result. Ignored when the query return value is not an `NSDictionary`. If `nil`, the default key "objecID" is used + - returns: a `SelectTerm` to a `Select` clause for querying the sum value for an attribute + */ + public static func objectIDAs(alias: KeyPath? = nil) -> SelectTerm { + + return ._Identity( + alias: alias ?? "objectID", + nativeType: .ObjectIDAttributeType + ) + } @@ -262,15 +288,15 @@ public final class CSSelect: NSObject { ``` NSManagedObjectID *objectIDForOldest = [CSCoreStore queryValueFrom:[CSFrom entityClass:[MyPersonEntity class]] - select:[CSSelect managedObjectIDForTerm:[CSSelectTerm attribute:@"age" as:nil]] + select:[CSSelect objectID] fetchClauses:@[[CSWhere keyPath:@"employeeID" isEqualTo: @1111]]]; ``` - parameter term: the `CSSelectTerm` specifying the attribute/aggregate value to query - returns: a `CSSelect` clause for querying an entity attribute */ - public static func managedObjectIDForTerm(term: CSSelectTerm) -> CSSelect { + public static func objectID() -> CSSelect { - return self.init(Select(term.bridgeToSwift)) + return self.init(Select(.ObjectID())) } /**