mirror of
https://github.com/JohnEstropia/CoreStore.git
synced 2026-02-19 06:07:47 +01:00
add comparison operators for Where.Expression
This commit is contained in:
@@ -66,14 +66,17 @@ final class WhereTests: XCTestCase {
|
||||
|
||||
XCTAssertEqual(
|
||||
#keyPath(TestEntity1.testToOne.testEntityID),
|
||||
(\TestEntity1.testToOne ~ \.testEntityID).description,
|
||||
String(keyPath: \TestEntity1.testToOne ~ \.testEntityID)
|
||||
)
|
||||
XCTAssertEqual(
|
||||
#keyPath(TestEntity1.testToOne.testToOne.testToManyUnordered),
|
||||
(\TestEntity1.testToOne ~ \.testToOne ~ \.testToManyUnordered).description,
|
||||
String(keyPath: \TestEntity1.testToOne ~ \.testToOne ~ \.testToManyUnordered)
|
||||
)
|
||||
XCTAssertEqual(
|
||||
#keyPath(TestEntity2.testToOne.testToOne.testToManyOrdered),
|
||||
(\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).description,
|
||||
String(keyPath: \TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered)
|
||||
)
|
||||
}
|
||||
@@ -81,14 +84,17 @@ final class WhereTests: XCTestCase {
|
||||
|
||||
XCTAssertEqual(
|
||||
"master.pets",
|
||||
(\Animal.master ~ \.pets).description,
|
||||
String(keyPath: \Animal.master ~ \.pets)
|
||||
)
|
||||
XCTAssertEqual(
|
||||
"master.pets.species",
|
||||
(\Animal.master ~ \.pets ~ \.species).description,
|
||||
String(keyPath: \Animal.master ~ \.pets ~ \.species)
|
||||
)
|
||||
XCTAssertEqual(
|
||||
"master.pets.master",
|
||||
(\Animal.master ~ \.pets ~ \.master).description,
|
||||
String(keyPath: \Animal.master ~ \.pets ~ \.master)
|
||||
)
|
||||
}
|
||||
@@ -96,84 +102,99 @@ final class WhereTests: XCTestCase {
|
||||
|
||||
XCTAssertEqual(
|
||||
#keyPath(TestEntity1.testToOne.testToManyUnordered) + ".@count",
|
||||
(\TestEntity1.testToOne ~ \.testToManyUnordered).count().description
|
||||
(\TestEntity1.testToOne ~ \.testToManyUnordered).count().description,
|
||||
String(keyPath: (\TestEntity1.testToOne ~ \.testToManyUnordered).count())
|
||||
)
|
||||
XCTAssertEqual(
|
||||
#keyPath(TestEntity2.testToOne.testToOne.testToManyOrdered) + ".@count",
|
||||
(\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).count().description
|
||||
(\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).count().description,
|
||||
String(keyPath: (\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).count())
|
||||
)
|
||||
}
|
||||
do {
|
||||
|
||||
XCTAssertEqual(
|
||||
"master.pets.@count",
|
||||
(\Animal.master ~ \.pets).count().description
|
||||
(\Animal.master ~ \.pets).count().description,
|
||||
String(keyPath: (\Animal.master ~ \.pets).count())
|
||||
)
|
||||
}
|
||||
do {
|
||||
|
||||
XCTAssertEqual(
|
||||
"ANY " + #keyPath(TestEntity1.testToOne.testToManyUnordered),
|
||||
(\TestEntity1.testToOne ~ \.testToManyUnordered).any().description
|
||||
(\TestEntity1.testToOne ~ \.testToManyUnordered).any().description,
|
||||
String(keyPath: (\TestEntity1.testToOne ~ \.testToManyUnordered).any())
|
||||
)
|
||||
XCTAssertEqual(
|
||||
"ANY " + #keyPath(TestEntity2.testToOne.testToOne.testToManyOrdered),
|
||||
(\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).any().description
|
||||
(\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).any().description,
|
||||
String(keyPath: (\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).any())
|
||||
)
|
||||
}
|
||||
do {
|
||||
|
||||
XCTAssertEqual(
|
||||
"ANY master.pets",
|
||||
(\Animal.master ~ \.pets).any().description
|
||||
(\Animal.master ~ \.pets).any().description,
|
||||
String(keyPath: (\Animal.master ~ \.pets).any())
|
||||
)
|
||||
XCTAssertEqual(
|
||||
"ANY master.pets.species",
|
||||
(\Animal.master ~ \.pets ~ \.species).any().description
|
||||
(\Animal.master ~ \.pets ~ \.species).any().description,
|
||||
String(keyPath: (\Animal.master ~ \.pets ~ \.species).any())
|
||||
)
|
||||
}
|
||||
do {
|
||||
|
||||
XCTAssertEqual(
|
||||
"ALL " + #keyPath(TestEntity1.testToOne.testToManyUnordered),
|
||||
(\TestEntity1.testToOne ~ \.testToManyUnordered).all().description
|
||||
(\TestEntity1.testToOne ~ \.testToManyUnordered).all().description,
|
||||
String(keyPath: (\TestEntity1.testToOne ~ \.testToManyUnordered).all())
|
||||
)
|
||||
XCTAssertEqual(
|
||||
"ALL " + #keyPath(TestEntity2.testToOne.testToOne.testToManyOrdered),
|
||||
(\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).all().description
|
||||
(\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).all().description,
|
||||
String(keyPath: (\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).all())
|
||||
)
|
||||
}
|
||||
do {
|
||||
|
||||
XCTAssertEqual(
|
||||
"ALL master.pets",
|
||||
(\Animal.master ~ \.pets).all().description
|
||||
(\Animal.master ~ \.pets).all().description,
|
||||
String(keyPath: (\Animal.master ~ \.pets).all())
|
||||
)
|
||||
XCTAssertEqual(
|
||||
"ALL master.pets.species",
|
||||
(\Animal.master ~ \.pets ~ \.species).all().description
|
||||
(\Animal.master ~ \.pets ~ \.species).all().description,
|
||||
String(keyPath: (\Animal.master ~ \.pets ~ \.species).all())
|
||||
)
|
||||
}
|
||||
do {
|
||||
|
||||
XCTAssertEqual(
|
||||
"NONE " + #keyPath(TestEntity1.testToOne.testToManyUnordered),
|
||||
(\TestEntity1.testToOne ~ \.testToManyUnordered).none().description
|
||||
(\TestEntity1.testToOne ~ \.testToManyUnordered).none().description,
|
||||
String(keyPath: (\TestEntity1.testToOne ~ \.testToManyUnordered).none())
|
||||
)
|
||||
XCTAssertEqual(
|
||||
"NONE " + #keyPath(TestEntity2.testToOne.testToOne.testToManyOrdered),
|
||||
(\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).none().description
|
||||
(\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).none().description,
|
||||
String(keyPath: (\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).none())
|
||||
)
|
||||
}
|
||||
do {
|
||||
|
||||
XCTAssertEqual(
|
||||
"NONE master.pets",
|
||||
(\Animal.master ~ \.pets).none().description
|
||||
(\Animal.master ~ \.pets).none().description,
|
||||
String(keyPath: (\Animal.master ~ \.pets).none())
|
||||
)
|
||||
XCTAssertEqual(
|
||||
"NONE master.pets.species",
|
||||
(\Animal.master ~ \.pets ~ \.species).none().description
|
||||
(\Animal.master ~ \.pets ~ \.species).none().description,
|
||||
String(keyPath: (\Animal.master ~ \.pets ~ \.species).none())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ extension Where {
|
||||
}
|
||||
|
||||
|
||||
// MARK: - ~ Operator (Where.Expression Creation Operators)
|
||||
// MARK: - ~ (Where.Expression Creation Operators)
|
||||
|
||||
// MARK: ~ where D: NSManagedObject
|
||||
|
||||
@@ -218,6 +218,29 @@ public func ~= <D, T, V: QueryableAttributeType, S: Sequence>(_ sequence: S, _ e
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Where.Expression where V: QueryableAttributeType & Comparable
|
||||
|
||||
public func < <D, T, V: QueryableAttributeType & Comparable>(_ lhs: Where<D>.Expression<T, V>, _ rhs: V) -> Where<D> {
|
||||
|
||||
return Where<D>(expression: lhs, function: "<", operand: rhs)
|
||||
}
|
||||
|
||||
public func <= <D, T, V: QueryableAttributeType & Comparable>(_ lhs: Where<D>.Expression<T, V>, _ rhs: V) -> Where<D> {
|
||||
|
||||
return Where<D>(expression: lhs, function: "<=", operand: rhs)
|
||||
}
|
||||
|
||||
public func > <D, T, V: QueryableAttributeType & Comparable>(_ lhs: Where<D>.Expression<T, V>, _ rhs: V) -> Where<D> {
|
||||
|
||||
return Where<D>(expression: lhs, function: ">", operand: rhs)
|
||||
}
|
||||
|
||||
public func >= <D, T, V: QueryableAttributeType & Comparable>(_ lhs: Where<D>.Expression<T, V>, _ rhs: V) -> Where<D> {
|
||||
|
||||
return Where<D>(expression: lhs, function: ">=", operand: rhs)
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Where.Expression where V: Optional<QueryableAttributeType>
|
||||
|
||||
public func == <D, T, V: QueryableAttributeType>(_ lhs: Where<D>.Expression<T, V?>, _ rhs: V) -> Where<D> {
|
||||
@@ -246,11 +269,44 @@ public func ~= <D, T, V: QueryableAttributeType, S: Sequence>(_ sequence: S, _ e
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Where.Expression where V: Optional<QueryableAttributeType & Comparable>
|
||||
|
||||
public func < <D, T, V: QueryableAttributeType & Comparable>(_ lhs: Where<D>.Expression<T, V?>, _ rhs: V) -> Where<D> {
|
||||
|
||||
return Where<D>(expression: lhs, function: "<", operand: rhs)
|
||||
}
|
||||
|
||||
public func <= <D, T, V: QueryableAttributeType & Comparable>(_ lhs: Where<D>.Expression<T, V?>, _ rhs: V?) -> Where<D> {
|
||||
|
||||
return Where<D>(expression: lhs, function: "<=", operand: rhs)
|
||||
}
|
||||
|
||||
public func > <D, T, V: QueryableAttributeType & Comparable>(_ lhs: Where<D>.Expression<T, V?>, _ rhs: V) -> Where<D> {
|
||||
|
||||
return Where<D>(expression: lhs, function: ">", operand: rhs)
|
||||
}
|
||||
|
||||
public func >= <D, T, V: QueryableAttributeType & Comparable>(_ lhs: Where<D>.Expression<T, V?>, _ rhs: V?) -> Where<D> {
|
||||
|
||||
return Where<D>(expression: lhs, function: ">=", operand: rhs)
|
||||
}
|
||||
|
||||
|
||||
// MARK: - KeyPath where Root: NSManagedObject, Value: AllowedObjectiveCCollectionKeyPathValue
|
||||
|
||||
extension KeyPath where Root: NSManagedObject, Value: AllowedObjectiveCCollectionKeyPathValue {
|
||||
|
||||
public func count() -> Where<Root>.Expression<Where<Root>.CollectionTarget, Int> {
|
||||
|
||||
return .init(self.cs_keyPathString, "@count")
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Where.Expression where D: NSManagedObject, T == Where<D>.CollectionTarget, V: AllowedObjectiveCCollectionKeyPathValue
|
||||
|
||||
extension Where.Expression where D: NSManagedObject, T == Where<D>.CollectionTarget, V: AllowedObjectiveCCollectionKeyPathValue {
|
||||
|
||||
public func count() -> Where<D>.Expression<Where<D>.CollectionTarget, Int> {
|
||||
public func count() -> Where<D>.Expression<T, Int> {
|
||||
|
||||
return .init(self.cs_keyPathString, "@count")
|
||||
}
|
||||
@@ -261,44 +317,97 @@ extension Where.Expression where D: NSManagedObject, T == Where<D>.CollectionTar
|
||||
|
||||
extension Where.Expression where D: NSManagedObject, T == Where<D>.CollectionTarget, V: AllowedObjectiveCKeyPathValue {
|
||||
|
||||
public func any() -> Where<D>.Expression<Where<D>.CollectionTarget, V> {
|
||||
public func any() -> Where<D>.Expression<T, V> {
|
||||
|
||||
return .init("ANY " + self.cs_keyPathString)
|
||||
}
|
||||
|
||||
public func all() -> Where<D>.Expression<Where<D>.CollectionTarget, V> {
|
||||
public func all() -> Where<D>.Expression<T, V> {
|
||||
|
||||
return .init("ALL " + self.cs_keyPathString)
|
||||
}
|
||||
|
||||
public func none() -> Where<D>.Expression<Where<D>.CollectionTarget, V> {
|
||||
public func none() -> Where<D>.Expression<T, V> {
|
||||
|
||||
return .init("NONE " + self.cs_keyPathString)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - KeyPath where Root: CoreStoreObject, Value: AllowedObjectiveCCollectionKeyPathValue
|
||||
|
||||
extension KeyPath where Root: CoreStoreObject, Value: AllowedCoreStoreObjectCollectionKeyPathValue {
|
||||
|
||||
public func count() -> Where<Root>.Expression<Where<Root>.CollectionTarget, Int> {
|
||||
|
||||
return .init(Root.meta[keyPath: self].cs_keyPathString, "@count")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Where.Expression where D: CoreStoreObject, T == Where<D>.CollectionTarget
|
||||
|
||||
extension Where.Expression where D: CoreStoreObject, T == Where<D>.CollectionTarget {
|
||||
|
||||
public func count() -> Where<D>.Expression<Where<D>.CollectionTarget, Int> {
|
||||
public func count() -> Where<D>.Expression<T, Int> {
|
||||
|
||||
return .init(self.cs_keyPathString, "@count")
|
||||
}
|
||||
|
||||
public func any() -> Where<D>.Expression<Where<D>.CollectionTarget, V> {
|
||||
public func any() -> Where<D>.Expression<T, V> {
|
||||
|
||||
return .init("ANY " + self.cs_keyPathString)
|
||||
}
|
||||
|
||||
public func all() -> Where<D>.Expression<Where<D>.CollectionTarget, V> {
|
||||
public func all() -> Where<D>.Expression<T, V> {
|
||||
|
||||
return .init("ALL " + self.cs_keyPathString)
|
||||
}
|
||||
|
||||
public func none() -> Where<D>.Expression<Where<D>.CollectionTarget, V> {
|
||||
public func none() -> Where<D>.Expression<T, V> {
|
||||
|
||||
return .init("NONE " + self.cs_keyPathString)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Where
|
||||
|
||||
extension Where {
|
||||
|
||||
// MARK: FilePrivate
|
||||
|
||||
fileprivate init<T, V: QueryableAttributeType & Comparable>(expression: Where<D>.Expression<T, V>, function: String, operand: V) {
|
||||
|
||||
self.init("\(expression.cs_keyPathString) \(function) %@", operand.cs_toQueryableNativeType())
|
||||
}
|
||||
|
||||
fileprivate init<T, V: QueryableAttributeType & Comparable>(expression: Where<D>.Expression<T, V?>, function: String, operand: V) {
|
||||
|
||||
self.init("\(expression.cs_keyPathString) \(function) %@", operand.cs_toQueryableNativeType())
|
||||
}
|
||||
|
||||
fileprivate init<T, V: QueryableAttributeType & Comparable>(expression: Where<D>.Expression<T, V>, function: String, operand: V?) {
|
||||
|
||||
if let operand = operand {
|
||||
|
||||
self.init("\(expression.cs_keyPathString) \(function) %@", operand.cs_toQueryableNativeType())
|
||||
}
|
||||
else {
|
||||
|
||||
self.init("\(expression.cs_keyPathString) \(function) nil")
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate init<T, V: QueryableAttributeType & Comparable>(expression: Where<D>.Expression<T, V?>, function: String, operand: V?) {
|
||||
|
||||
if let operand = operand {
|
||||
|
||||
self.init("\(expression.cs_keyPathString) \(function) %@", operand.cs_toQueryableNativeType())
|
||||
}
|
||||
else {
|
||||
|
||||
self.init("\(expression.cs_keyPathString) \(function) nil")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user