WIP: protocol cleanup

This commit is contained in:
John Estropia
2017-09-29 20:33:10 +09:00
parent 4ead3c34dd
commit 096e5493a6
9 changed files with 248 additions and 102 deletions

View File

@@ -64,3 +64,11 @@ public typealias EntityName = String
An `String` that pertains to a dynamically-accessable class name (usable with NSClassFromString(...)).
*/
public typealias ClassName = String
// MARK: - KeyPathString
/**
An `String` that pertains to a attribute keyPaths.
*/
public typealias KeyPathString = String

View File

@@ -64,7 +64,7 @@ public struct GroupBy<D: DynamicObject>: GroupByClause, QueryClause, Hashable {
}
// MARK: WhereClause
// MARK: GroupByClause
public typealias ObjectType = D

View File

@@ -27,11 +27,6 @@ import Foundation
import CoreData
// MARK: - KeyPathString
public typealias KeyPathString = String
// MARK: - OrderBy
/**

View File

@@ -1,5 +1,5 @@
//
// ClauseTypes.swift
// TypeErasedClauses.swift
// CoreStore
//
// Copyright © 2014 John Rommel Estropia
@@ -58,3 +58,24 @@ public protocol DeleteClause: FetchClause {
func applyToFetchRequest<T>(_ fetchRequest: NSFetchRequest<T>)
}
// MARK: - AnyWhereClause
/**
Type-erased `Where` clause for protocol utilities.
*/
public protocol AnyWhereClause: QueryClause, DeleteClause {
/**
The `NSPredicate` for the fetch or query
*/
var predicate: NSPredicate { get }
/**
Initializes a `Where` clause with an `NSPredicate`
- parameter predicate: the `NSPredicate` for the fetch or query
*/
init(_ predicate: NSPredicate)
}

View File

@@ -27,66 +27,72 @@ import Foundation
import CoreData
infix operator &&? : LogicalConjunctionPrecedence
infix operator ||? : LogicalConjunctionPrecedence
// MARK: - Where
/**
The `Where` clause specifies the conditions for a fetch or a query.
*/
public struct Where<D: DynamicObject>: WhereClause, FetchClause, QueryClause, DeleteClause, Hashable {
public struct Where<D: DynamicObject>: WhereClauseType, FetchClause, QueryClause, DeleteClause, Hashable {
/**
Combines two `Where` predicates together using `AND` operator
*/
public static func && (left: Where, right: Where) -> Where {
public static func && (left: Where<D>, right: Where<D>) -> Where<D> {
return Where(NSCompoundPredicate(type: .and, subpredicates: [left.predicate, right.predicate]))
}
/**
Combines two `Where` predicates together using `AND` operator.
- parameter left: the left hand side `Where` clause
- parameter right: the right hand side `Where` clause
- returns: Return `left` unchanged if `right` is nil
*/
public static func && (left: Where, right: Where?) -> Where {
if let right = right {
return left && right
}
return left
}
/**
Combines two `Where` predicates together using `AND` operator.
- parameter left: the left hand side `Where` clause
- parameter right: the right hand side `Where` clause
- returns: Returns `right` unchanged if `left` is nil
*/
public static func && (left: Where?, right: Where) -> Where {
if let left = left {
return left && right
}
return right
return Where<D>(NSCompoundPredicate(type: .and, subpredicates: [left.predicate, right.predicate]))
}
/**
Combines two `Where` predicates together using `OR` operator
*/
public static func || (left: Where, right: Where) -> Where {
public static func || (left: Where<D>, right: Where<D>) -> Where<D> {
return Where(NSCompoundPredicate(type: .or, subpredicates: [left.predicate, right.predicate]))
return Where<D>(NSCompoundPredicate(type: .or, subpredicates: [left.predicate, right.predicate]))
}
/**
Inverts the predicate of a `Where` clause using `NOT` operator
*/
public static prefix func ! (clause: Where<D>) -> Where<D> {
return Where<D>(NSCompoundPredicate(type: .not, subpredicates: [clause.predicate]))
}
/**
Combines two `Where` predicates together using `AND` operator.
- returns: `left` if `right` is `nil`, otherwise equivalent to `(left && right)`
*/
public static func &&? (left: Where<D>, right: Where<D>?) -> Where<D> {
if let right = right {
return left && right
}
return left
}
/**
Combines two `Where` predicates together using `AND` operator.
- returns: `right` if `left` is `nil`, otherwise equivalent to `(left && right)`
*/
public static func &&? (left: Where<D>?, right: Where<D>) -> Where<D> {
if let left = left {
return left && right
}
return right
}
/**
Combines two `Where` predicates together using `OR` operator.
- parameter left: the left hand side `Where` clause
- parameter right: the right hand side `Where` clause
- returns: Returns `left` unchanged if `right` is nil
- returns: `left` if `right` is `nil`, otherwise equivalent to `(left || right)`
*/
public static func || (left: Where, right: Where?) -> Where {
public static func ||? (left: Where<D>, right: Where<D>?) -> Where<D> {
if let right = right {
@@ -97,11 +103,9 @@ public struct Where<D: DynamicObject>: WhereClause, FetchClause, QueryClause, De
/**
Combines two `Where` predicates together using `OR` operator.
- parameter left: the left hand side `Where` clause
- parameter right: the right hand side `Where` clause
- returns: Return `right` unchanged if `left` is nil
- returns: `right` if `left` is `nil`, otherwise equivalent to `(left || right)`
*/
public static func || (left: Where?, right: Where) -> Where {
public static func ||? (left: Where<D>?, right: Where<D>) -> Where<D> {
if let left = left {
@@ -110,14 +114,6 @@ public struct Where<D: DynamicObject>: WhereClause, FetchClause, QueryClause, De
return right
}
/**
Inverts the predicate of a `Where` clause using `NOT` operator
*/
public static prefix func ! (clause: Where) -> Where {
return Where(NSCompoundPredicate(type: .not, subpredicates: [clause.predicate]))
}
/**
Initializes a `Where` clause with a predicate that always evaluates to `true`
*/
@@ -250,23 +246,21 @@ public struct Where<D: DynamicObject>: WhereClause, FetchClause, QueryClause, De
self.init(NSPredicate(format: "\(keyPath) IN %@", list.map({ $0 }) as NSArray))
}
/**
Initializes a `Where` clause with an `NSPredicate`
- parameter predicate: the `NSPredicate` for the fetch or query
*/
// MARK: AnyWhereClause
public let predicate: NSPredicate
public init(_ predicate: NSPredicate) {
self.predicate = predicate
}
// MARK: WhereClause
// MARK: WhereClauseType
public typealias ObjectType = D
public let predicate: NSPredicate
// MARK: FetchClause, QueryClause, DeleteClause
@@ -301,25 +295,6 @@ public struct Where<D: DynamicObject>: WhereClause, FetchClause, QueryClause, De
}
// MARK: - WhereClause
/**
Abstracts the `Where` clause for protocol utilities.
*/
public protocol WhereClause {
/**
The `DynamicObject` type associated with the clause
*/
associatedtype ObjectType: DynamicObject
/**
The `NSPredicate` for the fetch or query
*/
var predicate: NSPredicate { get }
}
// MARK: - Where where D: NSManagedObject
public extension Where where D: NSManagedObject {
@@ -530,9 +505,9 @@ public extension Where where D: CoreStoreObject {
}
// MARK: - Sequence where Iterator.Element: WhereClause
// MARK: - Sequence where Iterator.Element: WhereClauseType
public extension Sequence where Iterator.Element: WhereClause {
public extension Sequence where Iterator.Element: WhereClauseType {
/**
Combines multiple `Where` predicates together using `AND` operator
@@ -550,3 +525,49 @@ public extension Sequence where Iterator.Element: WhereClause {
return Where(NSCompoundPredicate(type: .or, subpredicates: self.map({ $0.predicate })))
}
}
// MARK: - Deprecated
public extension Where {
@available(*, deprecated: 4.0, renamed: "&&?")
public static func && (left: Where<D>, right: Where<D>?) -> Where<D> {
if let right = right {
return left && right
}
return left
}
@available(*, deprecated: 4.0, renamed: "&&?")
public static func && (left: Where<D>?, right: Where<D>) -> Where<D> {
if let left = left {
return left && right
}
return right
}
@available(*, deprecated: 4.0, renamed: "||?")
public static func || (left: Where<D>, right: Where<D>?) -> Where<D> {
if let right = right {
return left || right
}
return left
}
@available(*, deprecated: 4.0, renamed: "||?")
public static func || (left: Where<D>?, right: Where<D>) -> Where<D> {
if let left = left {
return left || right
}
return right
}
}

View File

@@ -0,0 +1,62 @@
//
// WhereClauseType.swift
// CoreStore
//
// Created by John Estropia on 2017/09/29.
// Copyright © 2017 John Rommel Estropia. All rights reserved.
//
import Foundation
// MARK: - WhereClauseType
/**
Abstracts the `Where` clause for protocol utilities.
*/
public protocol WhereClauseType: AnyWhereClause {
/**
The `DynamicObject` type associated with the clause
*/
associatedtype ObjectType: DynamicObject
}
public extension WhereClauseType {
/**
Combines two `Where` predicates together using `AND` operator.
- Warning: This operator overload is a workaround for Swift generics' inability to constrain by inheritance (https://bugs.swift.org/browse/SR-5213). In effect, this is less type-safe than other overloads because it allows AND'ing clauses of unrelated `DynamicObject` types.
*/
public static func && <TWhere: WhereClauseType>(left: Self, right: TWhere) -> Self {
return Self.init(NSCompoundPredicate(type: .and, subpredicates: [left.predicate, right.predicate]))
}
/**
Combines two `Where` predicates together using `AND` operator.
- Warning: This operator overload is a workaround for Swift generics' inability to constrain by inheritance (https://bugs.swift.org/browse/SR-5213). In effect, this is less type-safe than other overloads because it allows AND'ing clauses of unrelated `DynamicObject` types.
*/
public static func && <TWhere: WhereClauseType>(left: TWhere, right: Self) -> Self {
return Self.init(NSCompoundPredicate(type: .and, subpredicates: [left.predicate, right.predicate]))
}
/**
Combines two `Where` predicates together using `OR` operator.
- Warning: This operator overload is a workaround for Swift generics' inability to constrain by inheritance (https://bugs.swift.org/browse/SR-5213). In effect, this is less type-safe than other overloads because it allows OR'ing clauses of unrelated `DynamicObject` types.
*/
public static func || <TWhere: WhereClauseType>(left: Self, right: TWhere) -> Self {
return Self.init(NSCompoundPredicate(type: .or, subpredicates: [left.predicate, right.predicate]))
}
/**
Combines two `Where` predicates together using `OR` operator.
- Warning: This operator overload is a workaround for Swift generics' inability to constrain by inheritance (https://bugs.swift.org/browse/SR-5213). In effect, this is less type-safe than other overloads because it allows OR'ing clauses of unrelated `DynamicObject` types.
*/
public static func || <TWhere: WhereClauseType>(left: TWhere, right: Self) -> Self {
return Self.init(NSCompoundPredicate(type: .or, subpredicates: [left.predicate, right.predicate]))
}
}