Skip to content

Commit

Permalink
CDQI v3.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Revolucent committed Dec 31, 2015
1 parent e947177 commit 5ed9a8e
Show file tree
Hide file tree
Showing 34 changed files with 1,108 additions and 989 deletions.
132 changes: 62 additions & 70 deletions CoreDataQueryInterface.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

20 changes: 20 additions & 0 deletions CoreDataQueryInterface/Aggregable.swift
@@ -0,0 +1,20 @@
//
// Aggregable.swift
// CoreDataQueryInterface
//
// Created by Gregory Higley on 12/28/15.
// Copyright © 2015 Prosumma LLC. All rights reserved.
//

import Foundation

public protocol Aggregable: Countable {
typealias AggregateType: Attribute = Self
func subquery(variable: String, predicate: AggregateType -> NSPredicate) -> NSExpression
func subquery(predicate: AggregateType -> NSPredicate) -> NSExpression
var average: AggregateType { get }
var sum: AggregateType { get }
var max: AggregateType { get }
var min: AggregateType { get }
}

40 changes: 0 additions & 40 deletions CoreDataQueryInterface/Alias.swift

This file was deleted.

80 changes: 66 additions & 14 deletions CoreDataQueryInterface/Attribute.swift
Expand Up @@ -7,30 +7,82 @@
//

import Foundation
import CoreData

/**
The default implementation of `AttributeType`.
The base class for attributes.
- note: Don't use this class directly. Create or use one of its subclasses, such as `KeyAttribute`.
*/
public class Attribute : AttributeType {

public class Attribute: CustomStringConvertible, CustomExpressionConvertible {
private let _name: String?
private let _parent: AttributeType?

public required init(_ name: String? = nil, parent: AttributeType? = nil) {
if let _ = parent { assert(name != nil) }
if let name = name { assert(!name.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet()).isEmpty) }
private let _parent: Attribute?
public required init() {
_name = nil
_parent = nil
}
public required init(_ name: String, parent: Attribute? = nil) {
_name = name
_parent = parent
}

public var description: String {
if let parent = _parent {
public private(set) lazy var description: String = {
if let parent = self._parent {
let parentName = String(parent)
let prefix = parentName.isEmpty ? "" : (parentName + ".")
return prefix + _name!
return prefix + self._name!
} else {
return self._name ?? ""
}
}()
public private(set) lazy var expression: NSExpression = {
let keyPath = String(self)
if keyPath.hasPrefix("$") {
return NSExpression(forVariable: keyPath.substringFromIndex(keyPath.startIndex.successor()))
} else if keyPath == "" {
return NSExpression(format: "SELF")
} else {
return _name ?? ""
return NSExpression(forKeyPath: keyPath)
}
}()
public func named(name: String, type: NSAttributeType = .UndefinedAttributeType) -> NSExpressionDescription {
let e = NSExpressionDescription()
e.expression = expression
e.name = name
e.expressionResultType = type
return e
}
}

extension Aggregable where Self: Attribute {
public func subquery(variable: String, predicate: AggregateType -> NSPredicate) -> NSExpression {
let collection = AggregateType(_name!) // Can't do a subquery unless _name is not nil.
let iteratorVariable = AggregateType(variable)
return NSExpression(forSubquery: collection.expression, usingIteratorVariable: iteratorVariable.expression.variable, predicate: predicate(iteratorVariable))
}
public func subquery(predicate: AggregateType -> NSPredicate) -> NSExpression {
var identifier = NSProcessInfo().globallyUniqueString.stringByReplacingOccurrencesOfString("-", withString: "")
identifier = identifier.substringToIndex(identifier.startIndex.advancedBy(10)).lowercaseString
let variable = "$v\(identifier)"
return subquery(variable, predicate: predicate)
}
public var count: NSExpression {
return NSExpression(format: "%@.@count", expression)
}
public var average: AggregateType {
return AggregateType("@avg", parent: self)
}
public var sum: AggregateType {
return AggregateType("@sum", parent: self)
}
public var max: AggregateType {
return AggregateType("@max", parent: self)
}
public var min: AggregateType {
return AggregateType("@min", parent: self)
}
}

extension Attribute: CustomPropertyConvertible {
public var property: AnyObject {
return String(self)
}

}
27 changes: 0 additions & 27 deletions CoreDataQueryInterface/AttributeType.swift

This file was deleted.

19 changes: 19 additions & 0 deletions CoreDataQueryInterface/Countable.swift
@@ -0,0 +1,19 @@
//
// Countable.swift
// CoreDataQueryInterface
//
// Created by Gregory Higley on 12/30/15.
// Copyright © 2015 Prosumma LLC. All rights reserved.
//

import Foundation

public protocol Countable {
var count: NSExpression { get }
}

extension NSExpression: Countable {
public var count: NSExpression {
return NSExpression(format: "%@.@count", self)
}
}
69 changes: 69 additions & 0 deletions CoreDataQueryInterface/CustomExpressionConvertible.swift
@@ -0,0 +1,69 @@
//
// CustomExpressionConvertible.swift
// CoreDataQueryInterface
//
// Created by Gregory Higley on 12/28/15.
// Copyright © 2015 Prosumma LLC. All rights reserved.
//

import Foundation
import CoreData

public protocol CustomExpressionConvertible {
var expression: NSExpression { get }
}

extension CustomExpressionConvertible {
public func compare(rhs: Any?, type: NSPredicateOperatorType, options: NSComparisonPredicateOptions) -> NSPredicate {
let rightExpression: NSExpression
if let rhs = rhs as? CustomExpressionConvertible {
rightExpression = rhs.expression
} else {
rightExpression = NSExpression(forConstantValue: rhs as! AnyObject?)
}
debugPrint(rightExpression)
return NSComparisonPredicate(leftExpression: expression, rightExpression: rightExpression, modifier: .DirectPredicateModifier, type: type, options: options)
}
public func equalTo(rhs: Any?, options: NSComparisonPredicateOptions = []) -> NSPredicate {
return compare(rhs, type: .EqualToPredicateOperatorType, options: options)
}
public func greaterThan(rhs: Any?, options: NSComparisonPredicateOptions = []) -> NSPredicate {
return compare(rhs, type: .GreaterThanPredicateOperatorType, options: options)
}
public func greaterThanOrEqualTo(rhs: Any?, options: NSComparisonPredicateOptions = []) -> NSPredicate {
return compare(rhs, type: .GreaterThanOrEqualToPredicateOperatorType, options: options)
}
public func lessThan(rhs: Any?, options: NSComparisonPredicateOptions = []) -> NSPredicate {
return compare(rhs, type: .LessThanPredicateOperatorType, options: options)
}
public func lessThanOrEqualTo(rhs: Any?, options: NSComparisonPredicateOptions = []) -> NSPredicate {
return compare(rhs, type: .LessThanOrEqualToPredicateOperatorType, options: options)
}
public func beginsWith(rhs: Any?, options: NSComparisonPredicateOptions = []) -> NSPredicate {
return compare(rhs, type: .BeginsWithPredicateOperatorType, options: options)
}
public func contains(rhs: Any?, options: NSComparisonPredicateOptions = []) -> NSPredicate {
return compare(rhs, type: .ContainsPredicateOperatorType, options: options)
}
public func endsWith(rhs: Any?, options: NSComparisonPredicateOptions = []) -> NSPredicate {
return compare(rhs, type: .EndsWithPredicateOperatorType, options: options)
}
public func among(rhs: [Any], options: NSComparisonPredicateOptions = []) -> NSPredicate {
var expressions = [AnyObject]()
for elem in rhs {
let o = elem as! AnyObject
let e = NSExpression(forConstantValue: o)
expressions.append(e)
}
return compare(NSExpression(forAggregate: expressions), type: .InPredicateOperatorType, options: options)
}
public func like(rhs: Any?, options: NSComparisonPredicateOptions = []) -> NSPredicate {
return compare(rhs, type: .LikePredicateOperatorType, options: options)
}
}

extension NSExpression: CustomExpressionConvertible {
public var expression: NSExpression {
return self
}
}
27 changes: 27 additions & 0 deletions CoreDataQueryInterface/CustomPropertyConvertible.swift
@@ -0,0 +1,27 @@
//
// CustomPropertyConvertible.swift
// CoreDataQueryInterface
//
// Created by Gregory Higley on 12/28/15.
// Copyright © 2015 Prosumma LLC. All rights reserved.
//

import Foundation
import CoreData

public protocol CustomPropertyConvertible {
var property: AnyObject { get }
}

extension String: CustomPropertyConvertible {
public var property: AnyObject {
return self
}
}

extension NSPropertyDescription: CustomPropertyConvertible {
public var property: AnyObject {
return self
}
}

@@ -1,5 +1,5 @@
//
// OrderType.swift
// CustomSortDescriptorConvertible.swift
// CoreDataQueryInterface
//
// Created by Gregory Higley on 6/14/15.
Expand All @@ -9,33 +9,33 @@
import Foundation

/**
`OrderType` represents a type that can be converted to a sort descriptor.
`CustomSortDescriptorConvertible` represents a type that can be converted to a sort descriptor.
- note: `NSSortDescriptor` itself implements this protocol. It ignores the
`ascending` parameter of `toSortDescriptor`. So, `order(descending: NSSortDescriptor(key: "foo", ascending: true))`
sorts ascending, *not* descending. For this reason, it's best to use
`NSSortDescriptor` with the overloads of `order()` that do not contain the
`descending` keyword argument.
*/
public protocol OrderType {
public protocol CustomSortDescriptorConvertible {
/** Convert the underlying type to `NSSortDescriptor` */
func toSortDescriptor(ascending ascending: Bool) -> NSSortDescriptor
}

extension NSSortDescriptor : OrderType {
extension NSSortDescriptor: CustomSortDescriptorConvertible {
public func toSortDescriptor(ascending ascending: Bool) -> NSSortDescriptor {
return self
}
}

extension String : OrderType {
extension String: CustomSortDescriptorConvertible {
public func toSortDescriptor(ascending ascending: Bool) -> NSSortDescriptor {
return NSSortDescriptor(key: self, ascending: ascending)
}
}

extension AttributeType {
extension Attribute: CustomSortDescriptorConvertible {
public func toSortDescriptor(ascending ascending: Bool) -> NSSortDescriptor {
return NSSortDescriptor(key: String(self), ascending: ascending)
return NSSortDescriptor(key: String(self), ascending: ascending)
}
}
}
2 changes: 1 addition & 1 deletion CoreDataQueryInterface/EntityType.swift
Expand Up @@ -11,7 +11,7 @@ import Foundation
import ObjectiveC

public protocol EntityType: class {
typealias EntityAttributeType: AttributeType = Attribute
typealias EntityAttributeType: Attribute = Attribute
static func entityNameInManagedObjectModel(managedObjectModel: NSManagedObjectModel) -> String
}

Expand Down

0 comments on commit 5ed9a8e

Please sign in to comment.