complete query utilities

This commit is contained in:
John Rommel Estropia
2017-08-08 07:36:52 +09:00
parent fe69e7c6c4
commit 4a5bc6450b
13 changed files with 325 additions and 230 deletions

View File

@@ -38,14 +38,14 @@ final class GroupByTests: BaseTestCase {
do {
let groupBy = GroupBy()
let groupBy = GroupBy<NSManagedObject>()
XCTAssertEqual(groupBy, GroupBy([] as [String]))
XCTAssertNotEqual(groupBy, GroupBy("key"))
XCTAssertTrue(groupBy.keyPaths.isEmpty)
}
do {
let groupBy = GroupBy("key1")
let groupBy = GroupBy<NSManagedObject>("key1")
XCTAssertEqual(groupBy, GroupBy("key1"))
XCTAssertEqual(groupBy, GroupBy(["key1"]))
XCTAssertNotEqual(groupBy, GroupBy("key2"))
@@ -53,7 +53,7 @@ final class GroupByTests: BaseTestCase {
}
do {
let groupBy = GroupBy("key1", "key2")
let groupBy = GroupBy<NSManagedObject>("key1", "key2")
XCTAssertEqual(groupBy, GroupBy("key1", "key2"))
XCTAssertEqual(groupBy, GroupBy(["key1", "key2"]))
XCTAssertNotEqual(groupBy, GroupBy("key2", "key1"))
@@ -66,7 +66,7 @@ final class GroupByTests: BaseTestCase {
self.prepareStack { (dataStack) in
let groupBy = GroupBy(#keyPath(TestEntity1.testString))
let groupBy = GroupBy<NSManagedObject>(#keyPath(TestEntity1.testString))
let request = CoreStoreFetchRequest()
_ = From<TestEntity1>().applyToFetchRequest(request, context: dataStack.mainContext)

View File

@@ -31,12 +31,12 @@ import CoreStore
// MARK: - XCTAssertAllEqual
private func XCTAssertAllEqual<D: DynamicObject>(_ whereClauses: Where<D>...) {
private func XCTAssertAllEqual<D>(_ whereClauses: Where<D>...) {
XCTAssertAllEqual(whereClauses)
}
private func XCTAssertAllEqual<D: DynamicObject>(_ whereClauses: [Where<D>]) {
private func XCTAssertAllEqual<D>(_ whereClauses: [Where<D>]) {
for i in whereClauses.indices {

View File

@@ -33,7 +33,7 @@ internal protocol AttributeProtocol: class {
static var attributeType: NSAttributeType { get }
var keyPath: RawKeyPath { get }
var keyPath: KeyPathString { get }
var isOptional: Bool { get }
var isIndexed: Bool { get }
var isTransient: Bool { get }

View File

@@ -35,7 +35,7 @@ import CoreData
- SeeAlso: `GroupBy`
*/
@objc
public final class CSGroupBy: NSObject, CSQueryClause, CoreStoreObjectiveCType {
public final class CSGroupBy: NSObject, CSQueryClause {
/**
The list of key path strings to group results with
@@ -102,11 +102,11 @@ public final class CSGroupBy: NSObject, CSQueryClause, CoreStoreObjectiveCType {
// MARK: CoreStoreObjectiveCType
public let bridgeToSwift: GroupBy
public let bridgeToSwift: GroupBy<NSManagedObject>
public init(_ swiftValue: GroupBy) {
public init<D: NSManagedObject>(_ swiftValue: GroupBy<D>) {
self.bridgeToSwift = swiftValue
self.bridgeToSwift = swiftValue.downcast()
super.init()
}
}
@@ -114,7 +114,7 @@ public final class CSGroupBy: NSObject, CSQueryClause, CoreStoreObjectiveCType {
// MARK: - GroupBy
extension GroupBy: CoreStoreSwiftType {
extension GroupBy where D: NSManagedObject {
// MARK: CoreStoreSwiftType
@@ -122,4 +122,12 @@ extension GroupBy: CoreStoreSwiftType {
return CSGroupBy(self)
}
// MARK: FilePrivate
fileprivate func downcast() -> GroupBy<NSManagedObject> {
return GroupBy<NSManagedObject>(self.keyPaths)
}
}

View File

@@ -42,7 +42,6 @@ public protocol QueryChainableBuilderType {
var from: From<ObjectType> { get set }
var select: Select<ResultType> { get set }
var groupBy: GroupBy { get set }
var queryClauses: [QueryClause] { get set }
}
@@ -80,7 +79,6 @@ public struct QueryChainBuilder<D: DynamicObject, R: SelectResultType>: QueryCha
public var from: From<D>
public var select: Select<R>
public var groupBy: GroupBy
public var queryClauses: [QueryClause] = []
}
@@ -111,7 +109,6 @@ public extension From {
return .init(
from: self,
select: .init(selectTerms),
groupBy: .init(),
queryClauses: []
)
}
@@ -215,19 +212,19 @@ public extension FetchChainBuilder {
public extension QueryChainBuilder {
public func groupBy(_ clause: GroupBy<D>) -> QueryChainBuilder<D, R> {
return self.queryChain(appending: clause)
}
public func groupBy(_ keyPath: KeyPathString, _ keyPaths: KeyPathString...) -> QueryChainBuilder<D, R> {
return self.groupBy([keyPath] + keyPaths)
return self.groupBy(GroupBy<D>([keyPath] + keyPaths))
}
public func groupBy(_ keyPaths: [KeyPathString]) -> QueryChainBuilder<D, R> {
return .init(
from: self.from,
select: self.select,
groupBy: .init(keyPaths),
queryClauses: self.queryClauses
)
return self.queryChain(appending: GroupBy<D>(keyPaths))
}
public func `where`(_ clause: Where<D>) -> QueryChainBuilder<D, R> {
@@ -268,7 +265,6 @@ public extension QueryChainBuilder {
return .init(
from: self.from,
select: self.select,
groupBy: self.groupBy,
queryClauses: self.queryClauses + [clause]
)
}

View File

@@ -26,58 +26,6 @@
import CoreData
import Foundation
//public extension From where D: NSManagedObject {
//
//// public func select<R>(_ resultType: R.Type, _ selectTerm: SelectTerm, _ selectTerms: SelectTerm...) -> QueryChainBuilder<D, R> {
////
//// return self.select(resultType, [selectTerm] + selectTerms)
//// }
////
//// public func select<R>(_ resultType: R.Type, _ selectTerms: [SelectTerm]) -> QueryChainBuilder<D, R> {
////
//// return .init(
//// from: self,
//// select: .init(selectTerms),
//// groupBy: .init(),
//// fetchClauses: []
//// )
//// }
//
// public func sectionBy<T>(_ sectionKeyPath: KeyPath<D, T>) -> SectionMonitorChainBuilder<D> {
//
// return self.sectionBy(sectionKeyPath._kvcKeyPathString!, { $0 })
// }
//
// public func sectionBy<T>(_ sectionKeyPath: KeyPath<D, T>, _ sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?) -> SectionMonitorChainBuilder<D> {
//
// return self.sectionBy(sectionKeyPath._kvcKeyPathString!, sectionIndexTransformer)
// }
//
// public func `where`<T>(_ keyPath: KeyPath<D, T>, isEqualTo value: Void?) -> FetchChainBuilder<D> {
//
// return self.where(keyPath._kvcKeyPathString!, isEqualTo: value)
// }
//
// public func `where`<U: QueryableAttributeType>(_ keyPath: KeyPath<D, U>, isEqualTo value: U?) -> FetchChainBuilder<D> {
//
// return self.where(keyPath._kvcKeyPathString!, isEqualTo: value)
// }
//
// public func `where`(_ keyPath: KeyPath<D, D>, isEqualTo object: D?) -> FetchChainBuilder<D> {
//
// return self.where(keyPath._kvcKeyPathString!, isEqualTo: object)
// }
//
// public func `where`<S: Sequence>(_ keyPath: KeyPath<D, S.Iterator.Element>, isMemberOf list: S) -> FetchChainBuilder<D> where S.Iterator.Element: QueryableAttributeType {
//
// return self.where(keyPath._kvcKeyPathString!, isMemberOf: list)
// }
//
// public func `where`<S: Sequence>(_ keyPath: KeyPath<D, S.Iterator.Element>, isMemberOf list: S) -> FetchChainBuilder<D> where S.Iterator.Element == D {
//
// return self.where(keyPath._kvcKeyPathString!, isMemberOf: list)
// }
//}
// MARK: - DynamicObject

View File

@@ -153,7 +153,7 @@ extension DataStack: FetchableSource, QueryableSource {
// TODO: docs
public func fetchAll<B: FetchChainableBuilderType>(_ clauseChain: B) -> [B.ObjectType]? {
CoreStore.assert(
Thread.isMainThread,
"Attempted to fetch from a \(cs_typeName(self)) outside the main thread."

View File

@@ -32,12 +32,7 @@ import CoreData
/**
The `GroupBy` clause specifies that the result of a query be grouped accoording to the specified key path.
*/
public struct GroupBy: QueryClause, Hashable {
/**
The list of key path strings to group results with
*/
public let keyPaths: [KeyPathString]
public struct GroupBy<D: DynamicObject>: GroupByClause, QueryClause, Hashable {
/**
Initializes a `GroupBy` clause with an empty list of key path strings
@@ -69,6 +64,13 @@ public struct GroupBy: QueryClause, Hashable {
}
// MARK: WhereClause
public typealias ObjectType = D
public let keyPaths: [KeyPathString]
// MARK: QueryClause
public func applyToFetchRequest<ResultType>(_ fetchRequest: NSFetchRequest<ResultType>) {
@@ -100,3 +102,22 @@ public struct GroupBy: QueryClause, Hashable {
return (self.keyPaths as NSArray).hashValue
}
}
// MARK: - GroupByClause
/**
Abstracts the `GroupBy` clause for protocol utilities.
*/
public protocol GroupByClause {
/**
The `DynamicObject` type associated with the clause
*/
associatedtype ObjectType: DynamicObject
/**
The list of key path strings to group results with
*/
var keyPaths: [KeyPathString] { get }
}

View File

@@ -303,6 +303,12 @@ extension NSManagedObjectContext: FetchableSource, QueryableSource {
return self.queryValue(selectTerms, fetchRequest: fetchRequest)
}
@nonobjc
public func queryValue<B>(_ clauseChain: B) -> B.ResultType? where B : QueryChainableBuilderType, B.ResultType : QueryableAttributeType {
return self.queryValue(clauseChain.from, clauseChain.select, clauseChain.queryClauses)
}
@nonobjc
public func queryAttributes<D>(_ from: From<D>, _ selectClause: Select<NSDictionary>, _ queryClauses: QueryClause...) -> [[String: Any]]? {
@@ -327,6 +333,11 @@ extension NSManagedObjectContext: FetchableSource, QueryableSource {
return self.queryAttributes(fetchRequest)
}
public func queryAttributes<B>(_ clauseChain: B) -> [[String : Any]]? where B : QueryChainableBuilderType, B.ResultType == NSDictionary {
return self.queryAttributes(clauseChain.from, clauseChain.select, clauseChain.queryClauses)
}
// MARK: FetchableSource, QueryableSource

View File

@@ -31,11 +31,11 @@ import CoreData
internal protocol RelationshipProtocol: class {
var keyPath: RawKeyPath { get }
var keyPath: KeyPathString { get }
var isToMany: Bool { get }
var isOrdered: Bool { get }
var deleteRule: NSDeleteRule { get }
var inverse: (type: CoreStoreObject.Type, keyPath: () -> RawKeyPath?) { get }
var inverse: (type: CoreStoreObject.Type, keyPath: () -> KeyPathString?) { get }
var affectedByKeyPaths: () -> Set<String> { get }
weak var parentObject: CoreStoreObject? { get set }
var versionHashModifier: () -> String? { get }

View File

@@ -116,7 +116,7 @@ public enum TransformableContainer<O: CoreStoreObject> {
- parameter affectedByKeyPaths: a set of key paths for properties whose values affect the value of the receiver. This is similar to `NSManagedObject.keyPathsForValuesAffectingValue(forKey:)`.
*/
public init(
_ keyPath: RawKeyPath,
_ keyPath: KeyPathString,
initial: @autoclosure @escaping () -> V,
isIndexed: Bool = false,
isTransient: Bool = false,
@@ -197,7 +197,7 @@ public enum TransformableContainer<O: CoreStoreObject> {
return .transformableAttributeType
}
public let keyPath: RawKeyPath
public let keyPath: KeyPathString
internal let isOptional = false
internal let isIndexed: Bool
@@ -261,7 +261,7 @@ public enum TransformableContainer<O: CoreStoreObject> {
@available(*, deprecated: 3.2, renamed: "init(_:initial:isIndexed:isTransient:versionHashModifier:renamingIdentifier:customGetter:customSetter:affectedByKeyPaths:)")
public convenience init(
_ keyPath: RawKeyPath,
_ keyPath: KeyPathString,
`default`: @autoclosure @escaping () -> V,
isIndexed: Bool = false,
isTransient: Bool = false,
@@ -339,7 +339,7 @@ public enum TransformableContainer<O: CoreStoreObject> {
- parameter affectedByKeyPaths: a set of key paths for properties whose values affect the value of the receiver. This is similar to `NSManagedObject.keyPathsForValuesAffectingValue(forKey:)`.
*/
public init(
_ keyPath: RawKeyPath,
_ keyPath: KeyPathString,
initial: @autoclosure @escaping () -> V? = nil,
isIndexed: Bool = false,
isTransient: Bool = false,
@@ -420,7 +420,7 @@ public enum TransformableContainer<O: CoreStoreObject> {
return .transformableAttributeType
}
public let keyPath: RawKeyPath
public let keyPath: KeyPathString
internal let isOptional = true
internal let isIndexed: Bool
@@ -484,7 +484,7 @@ public enum TransformableContainer<O: CoreStoreObject> {
@available(*, deprecated: 3.2, renamed: "init(_:initial:isIndexed:isTransient:versionHashModifier:renamingIdentifier:customGetter:customSetter:affectedByKeyPaths:)")
public convenience init(
_ keyPath: RawKeyPath,
_ keyPath: KeyPathString,
`default`: @autoclosure @escaping () -> V? = nil,
isIndexed: Bool = false,
isTransient: Bool = false,

View File

@@ -258,7 +258,7 @@ public enum ValueContainer<O: CoreStoreObject> {
@available(*, deprecated: 3.2, renamed: "init(_:initial:isIndexed:isTransient:versionHashModifier:renamingIdentifier:customGetter:customSetter:affectedByKeyPaths:)")
public convenience init(
_ keyPath: RawKeyPath,
_ keyPath: KeyPathString,
`default`: @autoclosure @escaping () -> V,
isIndexed: Bool = false,
isTransient: Bool = false,

View File

@@ -29,192 +29,303 @@ import Foundation
// MARK: - KeyPath where Root: NSManagedObject, Value: QueryableAttributeType & Equatable
public extension KeyPath where Root: NSManagedObject, Value: QueryableAttributeType & Equatable {
public func == <O: NSManagedObject, V: QueryableAttributeType & Equatable>(_ keyPath: KeyPath<O, V>, _ value: V) -> Where<O> {
public static func == (_ keyPath: KeyPath<Root, Value>, _ value: Value) -> Where<Root> {
return Where(keyPath._kvcKeyPathString!, isEqualTo: value)
}
public static func != (_ keyPath: KeyPath<Root, Value>, _ value: Value) -> Where<Root> {
return !Where(keyPath._kvcKeyPathString!, isEqualTo: value)
}
public static func ~= <S: Sequence>(_ sequence: S, _ keyPath: KeyPath<Root, Value>) -> Where<Root> where S.Iterator.Element == Value {
return Where(keyPath._kvcKeyPathString!, isMemberOf: sequence)
}
return Where<O>(keyPath._kvcKeyPathString!, isEqualTo: value)
}
public func != <O: NSManagedObject, V: QueryableAttributeType & Equatable>(_ keyPath: KeyPath<O, V>, _ value: V) -> Where<O> {
return !Where<O>(keyPath._kvcKeyPathString!, isEqualTo: value)
}
public func ~= <O: NSManagedObject, V: QueryableAttributeType & Equatable, S: Sequence>(_ sequence: S, _ keyPath: KeyPath<O, V>) -> Where<O> where S.Iterator.Element == V {
return Where<O>(keyPath._kvcKeyPathString!, isMemberOf: sequence)
}
// MARK: - KeyPath where Root: NSManagedObject, Value: Optional<QueryableAttributeType & Equatable>
public extension KeyPath where Root: NSManagedObject {
public func == <O: NSManagedObject, V: QueryableAttributeType & Equatable>(_ keyPath: KeyPath<O, Optional<V>>, _ value: V?) -> Where<O> {
public static func == <V: QueryableAttributeType & Equatable> (_ keyPath: KeyPath<Root, Value>, _ value: Value) -> Where<Root> where Value == Optional<V> {
return Where(keyPath._kvcKeyPathString!, isEqualTo: value)
}
return Where<O>(keyPath._kvcKeyPathString!, isEqualTo: value)
}
public func != <O: NSManagedObject, V: QueryableAttributeType & Equatable>(_ keyPath: KeyPath<O, Optional<V>>, _ value: V?) -> Where<O> {
public static func != <V: QueryableAttributeType & Equatable> (_ keyPath: KeyPath<Root, Value>, _ value: Value) -> Where<Root> where Value == Optional<V> {
return !Where(keyPath._kvcKeyPathString!, isEqualTo: value)
}
return !Where<O>(keyPath._kvcKeyPathString!, isEqualTo: value)
}
public func ~= <O: NSManagedObject, V: QueryableAttributeType & Equatable, S: Sequence>(_ sequence: S, _ keyPath: KeyPath<O, Optional<V>>) -> Where<O> where S.Iterator.Element == V {
public static func ~= <S: Sequence, V: QueryableAttributeType & Equatable>(_ sequence: S, _ keyPath: KeyPath<Root, Value>) -> Where<Root> where Value == Optional<V>, S.Iterator.Element == V {
return Where(keyPath._kvcKeyPathString!, isMemberOf: sequence)
}
return Where<O>(keyPath._kvcKeyPathString!, isMemberOf: sequence)
}
// MARK: - KeyPath where Root: NSManagedObject, Value: QueryableAttributeType
// MARK: - KeyPath where Root: NSManagedObject, Value: QueryableAttributeType & Comparable
public extension KeyPath where Root: NSManagedObject, Value: QueryableAttributeType {
public func < <O: NSManagedObject, V: QueryableAttributeType & Comparable>(_ keyPath: KeyPath<O, V>, _ value: V) -> Where<O> {
public static func < (_ keyPath: KeyPath<Root, Value>, _ value: Value) -> Where<Root> {
return Where("%K < %@", keyPath._kvcKeyPathString!, value)
}
return Where<O>("%K < %@", keyPath._kvcKeyPathString!, value)
}
public func > <O: NSManagedObject, V: QueryableAttributeType & Comparable>(_ keyPath: KeyPath<O, V>, _ value: V) -> Where<O> {
public static func > (_ keyPath: KeyPath<Root, Value>, _ value: Value) -> Where<Root> {
return Where("%K > %@", keyPath._kvcKeyPathString!, value)
}
return Where<O>("%K > %@", keyPath._kvcKeyPathString!, value)
}
public func <= <O: NSManagedObject, V: QueryableAttributeType & Comparable>(_ keyPath: KeyPath<O, V>, _ value: V) -> Where<O> {
public static func <= (_ keyPath: KeyPath<Root, Value>, _ value: Value) -> Where<Root> {
return Where("%K <= %@", keyPath._kvcKeyPathString!, value)
}
return Where<O>("%K <= %@", keyPath._kvcKeyPathString!, value)
}
public func >= <O: NSManagedObject, V: QueryableAttributeType & Comparable>(_ keyPath: KeyPath<O, V>, _ value: V) -> Where<O> {
public static func >= (_ keyPath: KeyPath<Root, Value>, _ value: Value) -> Where<Root> {
return Where("%K >= %@", keyPath._kvcKeyPathString!, value)
}
return Where<O>("%K >= %@", keyPath._kvcKeyPathString!, value)
}
// MARK: - KeyPath where Root: NSManagedObject, Value: Optional<QueryableAttributeType>
// MARK: - KeyPath where Root: NSManagedObject, Value: Optional<QueryableAttributeType & Comparable>
public extension KeyPath where Root: NSManagedObject {
public func < <O: NSManagedObject, V: QueryableAttributeType & Comparable>(_ keyPath: KeyPath<O, Optional<V>>, _ value: V?) -> Where<O> {
public static func < <V: QueryableAttributeType> (_ keyPath: KeyPath<Root, Value>, _ value: Value) -> Where<Root> where Value == Optional<V> {
if let value = value {
if let value = value {
return Where("%K < %@", keyPath._kvcKeyPathString!, value)
}
else {
return Where("%K < nil", keyPath._kvcKeyPathString!)
}
return Where<O>("%K < %@", keyPath._kvcKeyPathString!, value)
}
public static func > <V: QueryableAttributeType> (_ keyPath: KeyPath<Root, Value>, _ value: Value) -> Where<Root> where Value == Optional<V> {
else {
if let value = value {
return Where("%K > %@", keyPath._kvcKeyPathString!, value)
}
else {
return Where("%K > nil", keyPath._kvcKeyPathString!)
}
return Where<O>("%K < nil", keyPath._kvcKeyPathString!)
}
}
public func > <O: NSManagedObject, V: QueryableAttributeType & Comparable>(_ keyPath: KeyPath<O, Optional<V>>, _ value: V?) -> Where<O> {
public static func <= <V: QueryableAttributeType> (_ keyPath: KeyPath<Root, Value>, _ value: Value) -> Where<Root> where Value == Optional<V> {
if let value = value {
if let value = value {
return Where("%K <= %@", keyPath._kvcKeyPathString!, value)
}
else {
return Where("%K <= nil", keyPath._kvcKeyPathString!)
}
return Where<O>("%K > %@", keyPath._kvcKeyPathString!, value)
}
public static func >= <V: QueryableAttributeType> (_ keyPath: KeyPath<Root, Value>, _ value: Value) -> Where<Root> where Value == Optional<V> {
else {
if let value = value {
return Where("%K >= %@", keyPath._kvcKeyPathString!, value)
}
else {
return Where("%K >= nil", keyPath._kvcKeyPathString!)
}
return Where<O>("%K > nil", keyPath._kvcKeyPathString!)
}
}
public func <= <O: NSManagedObject, V: QueryableAttributeType & Comparable>(_ keyPath: KeyPath<O, Optional<V>>, _ value: V?) -> Where<O> {
if let value = value {
return Where<O>("%K <= %@", keyPath._kvcKeyPathString!, value)
}
else {
return Where<O>("%K <= nil", keyPath._kvcKeyPathString!)
}
}
public func >= <O: NSManagedObject, V: QueryableAttributeType & Comparable>(_ keyPath: KeyPath<O, Optional<V>>, _ value: V?) -> Where<O> {
if let value = value {
return Where<O>("%K >= %@", keyPath._kvcKeyPathString!, value)
}
else {
return Where<O>("%K >= nil", keyPath._kvcKeyPathString!)
}
}
// MARK: - KeyPath where Root: NSManagedObject, Value: NSManagedObject
public extension KeyPath where Root: NSManagedObject, Value: NSManagedObject {
public func == <O: NSManagedObject, D: NSManagedObject>(_ keyPath: KeyPath<O, D>, _ object: D) -> Where<O> {
public static func == (_ keyPath: KeyPath<Root, Value>, _ object: Value) -> Where<Root> {
return Where(keyPath._kvcKeyPathString!, isEqualTo: object)
}
return Where<O>(keyPath._kvcKeyPathString!, isEqualTo: object)
}
public func != <O: NSManagedObject, D: NSManagedObject>(_ keyPath: KeyPath<O, D>, _ object: D) -> Where<O> {
public static func != (_ keyPath: KeyPath<Root, Value>, _ object: Value) -> Where<Root> {
return !Where(keyPath._kvcKeyPathString!, isEqualTo: object)
}
return !Where<O>(keyPath._kvcKeyPathString!, isEqualTo: object)
}
public func ~= <O: NSManagedObject, D: NSManagedObject, S: Sequence>(_ sequence: S, _ keyPath: KeyPath<O, D>) -> Where<O> where S.Iterator.Element == D {
public static func ~= <S: Sequence>(_ sequence: S, _ keyPath: KeyPath<Root, Value>) -> Where<Root> where S.Iterator.Element == Value {
return Where(keyPath._kvcKeyPathString!, isMemberOf: sequence)
}
return Where<O>(keyPath._kvcKeyPathString!, isMemberOf: sequence)
}
public func == <O: NSManagedObject, D: NSManagedObject>(_ keyPath: KeyPath<O, D>, _ objectID: NSManagedObjectID?) -> Where<O> {
public static func == (_ keyPath: KeyPath<Root, Value>, _ objectID: NSManagedObjectID?) -> Where<Root> {
return Where(keyPath._kvcKeyPathString!, isEqualTo: objectID)
}
return Where<O>(keyPath._kvcKeyPathString!, isEqualTo: objectID)
}
public func != <O: NSManagedObject, D: NSManagedObject>(_ keyPath: KeyPath<O, D>, _ objectID: NSManagedObjectID?) -> Where<O> {
public static func != (_ keyPath: KeyPath<Root, Value>, _ objectID: NSManagedObjectID?) -> Where<Root> {
return !Where(keyPath._kvcKeyPathString!, isEqualTo: objectID)
}
return !Where<O>(keyPath._kvcKeyPathString!, isEqualTo: objectID)
}
public func ~= <O: NSManagedObject, D: NSManagedObject, S: Sequence>(_ sequence: S, _ keyPath: KeyPath<O, D>) -> Where<O> where S.Iterator.Element == NSManagedObjectID {
public static func ~= <S: Sequence>(_ sequence: S, _ keyPath: KeyPath<Root, Value>) -> Where<Root> where S.Iterator.Element == NSManagedObjectID {
return Where(keyPath._kvcKeyPathString!, isMemberOf: sequence)
}
return Where<O>(keyPath._kvcKeyPathString!, isMemberOf: sequence)
}
// MARK: - KeyPath where Root: NSManagedObject, Value: Optional<NSManagedObject>
public extension KeyPath where Root: NSManagedObject {
public func == <O: NSManagedObject, D: NSManagedObject>(_ keyPath: KeyPath<O, Optional<D>>, _ object: D?) -> Where<O> {
public static func == <V: NSManagedObject> (_ keyPath: KeyPath<Root, Value>, _ object: Value) -> Where<Root> where Value == Optional<V> {
return Where(keyPath._kvcKeyPathString!, isEqualTo: object)
return Where<O>(keyPath._kvcKeyPathString!, isEqualTo: object)
}
public func != <O: NSManagedObject, D: NSManagedObject>(_ keyPath: KeyPath<O, Optional<D>>, _ object: D?) -> Where<O> {
return !Where<O>(keyPath._kvcKeyPathString!, isEqualTo: object)
}
public func ~= <O: NSManagedObject, D: NSManagedObject, S: Sequence>(_ sequence: S, _ keyPath: KeyPath<O, Optional<D>>) -> Where<O> where S.Iterator.Element == D {
return Where<O>(keyPath._kvcKeyPathString!, isMemberOf: sequence)
}
public func == <O: NSManagedObject, D: NSManagedObject>(_ keyPath: KeyPath<O, Optional<D>>, _ objectID: NSManagedObjectID?) -> Where<O> {
return Where<O>(keyPath._kvcKeyPathString!, isEqualTo: objectID)
}
public func != <O: NSManagedObject, D: NSManagedObject>(_ keyPath: KeyPath<O, Optional<D>>, _ objectID: NSManagedObjectID?) -> Where<O> {
return !Where<O>(keyPath._kvcKeyPathString!, isEqualTo: objectID)
}
public func ~= <O: NSManagedObject, D: NSManagedObject, S: Sequence>(_ sequence: S, _ keyPath: KeyPath<O, Optional<D>>) -> Where<O> where S.Iterator.Element == NSManagedObjectID {
return Where<O>(keyPath._kvcKeyPathString!, isMemberOf: sequence)
}
// MARK: - KeyPath where Root: CoreStoreObject, Value: ValueContainer<Root>.Required<QueryableAttributeType & Equatable>
public func == <O, V>(_ keyPath: KeyPath<O, ValueContainer<O>.Required<V>>, _ value: V) -> Where<O> {
return Where<O>(O.meta[keyPath: keyPath].keyPath, isEqualTo: value)
}
public func != <O, V>(_ keyPath: KeyPath<O, ValueContainer<O>.Required<V>>, _ value: V) -> Where<O> {
return !Where<O>(O.meta[keyPath: keyPath].keyPath, isEqualTo: value)
}
public func ~= <O, V, S: Sequence>(_ sequence: S, _ keyPath: KeyPath<O, ValueContainer<O>.Required<V>>) -> Where<O> where S.Iterator.Element == V {
return Where<O>(O.meta[keyPath: keyPath].keyPath, isMemberOf: sequence)
}
// MARK: - KeyPath where Root: CoreStoreObject, Value: ValueContainer<Root>.Optional<QueryableAttributeType & Equatable>
public func == <O, V>(_ keyPath: KeyPath<O, ValueContainer<O>.Optional<V>>, _ value: V?) -> Where<O> {
return Where<O>(O.meta[keyPath: keyPath].keyPath, isEqualTo: value)
}
public func != <O, V>(_ keyPath: KeyPath<O, ValueContainer<O>.Optional<V>>, _ value: V?) -> Where<O> {
return !Where<O>(O.meta[keyPath: keyPath].keyPath, isEqualTo: value)
}
public func ~= <O, V, S: Sequence>(_ sequence: S, _ keyPath: KeyPath<O, ValueContainer<O>.Optional<V>>) -> Where<O> where S.Iterator.Element == V {
return Where<O>(O.meta[keyPath: keyPath].keyPath, isMemberOf: sequence)
}
// MARK: - KeyPath where Root: CoreStoreObject, Value: ValueContainer<Root>.Required<QueryableAttributeType & Comparable>
public func < <O, V: Comparable>(_ keyPath: KeyPath<O, ValueContainer<O>.Required<V>>, _ value: V) -> Where<O> {
return Where<O>("%K < %@", O.meta[keyPath: keyPath].keyPath, value)
}
public func > <O, V: Comparable>(_ keyPath: KeyPath<O, ValueContainer<O>.Required<V>>, _ value: V) -> Where<O> {
return Where<O>("%K > %@", O.meta[keyPath: keyPath].keyPath, value)
}
public func <= <O, V: Comparable>(_ keyPath: KeyPath<O, ValueContainer<O>.Required<V>>, _ value: V) -> Where<O> {
return Where<O>("%K <= %@", O.meta[keyPath: keyPath].keyPath, value)
}
public func >= <O, V: Comparable>(_ keyPath: KeyPath<O, ValueContainer<O>.Required<V>>, _ value: V) -> Where<O> {
return Where<O>("%K >= %@", O.meta[keyPath: keyPath].keyPath, value)
}
// MARK: - KeyPath where Root: CoreStoreObject, Value: ValueContainer<Root>.Optional<QueryableAttributeType & Comparable>
public func < <O, V>(_ keyPath: KeyPath<O, ValueContainer<O>.Optional<V>>, _ value: V?) -> Where<O> {
if let value = value {
return Where<O>("%K < %@", O.meta[keyPath: keyPath].keyPath, value)
}
public static func != <V: NSManagedObject> (_ keyPath: KeyPath<Root, Value>, _ object: Value) -> Where<Root> where Value == Optional<V> {
return !Where(keyPath._kvcKeyPathString!, isEqualTo: object)
}
public static func ~= <S: Sequence, V: NSManagedObject>(_ sequence: S, _ keyPath: KeyPath<Root, Value>) -> Where<Root> where Value == Optional<V>, S.Iterator.Element == V {
return Where(keyPath._kvcKeyPathString!, isMemberOf: sequence)
}
public static func == <V: NSManagedObject> (_ keyPath: KeyPath<Root, Value>, _ objectID: NSManagedObjectID?) -> Where<Root> where Value == Optional<V> {
return Where(keyPath._kvcKeyPathString!, isEqualTo: objectID)
}
public static func != <V: NSManagedObject> (_ keyPath: KeyPath<Root, Value>, _ objectID: NSManagedObjectID?) -> Where<Root> where Value == Optional<V> {
return !Where(keyPath._kvcKeyPathString!, isEqualTo: objectID)
}
public static func ~= <S: Sequence, V: NSManagedObject>(_ sequence: S, _ keyPath: KeyPath<Root, Value>) -> Where<Root> where Value == Optional<V>, S.Iterator.Element == NSManagedObjectID {
return Where(keyPath._kvcKeyPathString!, isMemberOf: sequence)
else {
return Where<O>("%K < nil", O.meta[keyPath: keyPath].keyPath)
}
}
public func > <O, V>(_ keyPath: KeyPath<O, ValueContainer<O>.Optional<V>>, _ value: V?) -> Where<O> {
if let value = value {
return Where<O>("%K > %@", O.meta[keyPath: keyPath].keyPath, value)
}
else {
return Where<O>("%K > nil", O.meta[keyPath: keyPath].keyPath)
}
}
public func <= <O, V>(_ keyPath: KeyPath<O, ValueContainer<O>.Optional<V>>, _ value: V?) -> Where<O> {
if let value = value {
return Where<O>("%K <= %@", O.meta[keyPath: keyPath].keyPath, value)
}
else {
return Where<O>("%K <= nil", O.meta[keyPath: keyPath].keyPath)
}
}
public func >= <O, V>(_ keyPath: KeyPath<O, ValueContainer<O>.Optional<V>>, _ value: V?) -> Where<O> {
if let value = value {
return Where<O>("%K >= %@", O.meta[keyPath: keyPath].keyPath, value)
}
else {
return Where<O>("%K >= nil", O.meta[keyPath: keyPath].keyPath)
}
}
// MARK: - KeyPath where Root: CoreStoreObject, Value: RelationshipContainer<Root>.ToOne<CoreStoreObject>
public func == <O, D>(_ keyPath: KeyPath<O, RelationshipContainer<O>.ToOne<D>>, _ object: D) -> Where<O> {
return Where<O>(O.meta[keyPath: keyPath].keyPath, isEqualTo: object)
}
public func != <O, D>(_ keyPath: KeyPath<O, RelationshipContainer<O>.ToOne<D>>, _ object: D) -> Where<O> {
return !Where<O>(O.meta[keyPath: keyPath].keyPath, isEqualTo: object)
}
public func ~= <O, D, S: Sequence>(_ sequence: S, _ keyPath: KeyPath<O, RelationshipContainer<O>.ToOne<D>>) -> Where<O> where S.Iterator.Element == D {
return Where<O>(O.meta[keyPath: keyPath].keyPath, isMemberOf: sequence)
}