add missing documentations for Where.Expression, updated playgrounds

This commit is contained in:
John Estropia
2019-02-20 18:47:29 +09:00
parent 1cd3c4fcf4
commit 99b871b97a
4 changed files with 409 additions and 77 deletions

View File

@@ -1,5 +1,8 @@
import UIKit
import CoreStore
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
/// Model Declaration =====
class Animal: CoreStoreObject {
@@ -24,30 +27,53 @@ let dataStack = DataStack(
]
)
)
try dataStack.addStorageAndWait(SQLiteStore(fileName: "data.sqlite"))
/// =======================
dataStack.addStorage(
SQLiteStore(fileName: "data.sqlite"),
completion: { result in
/// Transactions ==========
dataStack.perform(synchronous: { transaction in
switch result {
let animal = transaction.create(Into<Animal>())
animal.species .= "Sparrow"
animal.color .= .yellow
case .failure(let error):
print(error)
let person = transaction.create(Into<Person>())
person.name .= "John"
person.pets.value.insert(animal)
})
/// =======================
case .success:
/// Transactions ==========
dataStack.perform(
asynchronous: { transaction in
let animal = transaction.create(Into<Animal>())
animal.species .= "Sparrow"
animal.color .= .yellow
let person = transaction.create(Into<Person>())
person.name .= "John"
person.pets.value.insert(animal)
},
completion: { result in
switch result {
case .failure(let error):
print(error)
case .success:
/// Accessing Objects =====
let bird = try! dataStack.fetchOne(From<Animal>().where(\.species == "Sparrow"))!
print(bird.species.value)
print(bird.color.value as Any)
print(bird)
let owner = bird.master.value!
print(owner.name.value as Any)
print(owner.pets.count)
print(owner)
/// =======================
}
}
)
/// =======================
}
}
)
/// Accessing Objects =====
let bird = dataStack.fetchOne(From<Animal>().where(\.species == "Sparrow"))!
print(bird.species.value)
print(bird.color.value as Any)
print(bird)
let owner = bird.master.value!
print(owner.name.value)
print(owner.pets.count as Any)
print(owner)
/// =======================

View File

@@ -1,5 +1,8 @@
import AppKit
import CoreStore
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
/// Model Declaration =====
class Animal: CoreStoreObject {
@@ -24,32 +27,51 @@ let dataStack = DataStack(
]
)
)
try dataStack.addStorageAndWait(SQLiteStore(fileName: "data.sqlite"))
/// =======================
dataStack.addStorage(
SQLiteStore(fileName: "data.sqlite"),
completion: { result in
/// Transactions ==========
try dataStack.perform(
synchronous: { transaction in
switch result {
let animal = transaction.create(Into<Animal>())
animal.species .= "Sparrow"
animal.color .= .yellow
case .failure(let error):
print(error)
let person = transaction.create(Into<Person>())
person.name .= "John"
person.pets.value.insert(animal)
}
case .success:
/// Transactions ==========
dataStack.perform(
asynchronous: { transaction in
let animal = transaction.create(Into<Animal>())
animal.species .= "Sparrow"
animal.color .= .yellow
let person = transaction.create(Into<Person>())
person.name .= "John"
person.pets.value.insert(animal)
},
completion: { result in
switch result {
case .failure(let error):
print(error)
case .success:
/// Accessing Objects =====
let bird = try! dataStack.fetchOne(From<Animal>().where(\.species == "Sparrow"))!
print(bird.species.value)
print(bird.color.value as Any)
print(bird)
let owner = bird.master.value!
print(owner.name.value as Any)
print(owner.pets.count)
print(owner)
/// =======================
}
}
)
/// =======================
}
}
)
/// =======================
/// Accessing Objects =====
let bird = try dataStack.fetchOne(From<Animal>().where(\.species == "Sparrow"))!
print(bird.species.value)
print(bird.color.value as Any)
print(bird)
let owner = bird.master.value!
print(owner.name.value as Any)
print(owner.pets.count)
print(owner)
/// =======================

View File

@@ -29,11 +29,24 @@ import CoreData
// MARK: - ~
/**
Connects multiple `DynamicKeyPath`s to create a type-safe chain usable in query/fetch expressions
```
let owner = CoreStore.fetchOne(
From<Pet>().where(
(\.master ~ \.name) == "John"
)
)
```
*/
infix operator ~ : AdditionPrecedence
// MARK: - WhereExpressionTrait
/**
Used only for `Where.Expression` type constraints. Currently supports `SingleTarget` and `CollectionTarget`.
*/
public protocol WhereExpressionTrait {}
@@ -43,8 +56,20 @@ extension Where {
// MARK: - Expression
/**
Type-safe keyPath chain usable in query/fetch expressions.
```
let expression: Where<Pet>.Expression = (\.master ~ \.name)
let owner = CoreStore.fetchOne(
From<Pet>().where(expression == "John")
)
```
*/
public struct Expression<T: WhereExpressionTrait, V>: CustomStringConvertible, DynamicKeyPath {
/**
Currently supports `SingleTarget` and `CollectionTarget`.
*/
public typealias Trait = T
@@ -83,10 +108,17 @@ extension Where {
// MARK: - SingleTarget
/**
Used only for `Where.Expression` type constraints. Specifies that this `Where.Expression` type pertains to an attribute property expression.
*/
public enum SingleTarget: WhereExpressionTrait {}
// MARK: - CollectionTarget
/**
Used only for `Where.Expression` type constraints. Specifies that this `Where.Expression` type pertains to a to-many relationship expression.
*/
public enum CollectionTarget: WhereExpressionTrait {}
}
@@ -95,47 +127,101 @@ extension Where {
// MARK: ~ where D: NSManagedObject
/**
Connects multiple `DynamicKeyPath`s to create a type-safe chain usable in query/fetch expressions
```
let owner = CoreStore.fetchOne(From<Pet>().where((\.master ~ \.name) == "John"))
```
*/
public func ~<D: NSManagedObject, O: NSManagedObject, V: AllowedObjectiveCKeyPathValue>(_ lhs: KeyPath<D, O>, _ rhs: KeyPath<O, V>) -> Where<D>.Expression<Where<D>.SingleTarget, V> {
return .init(lhs.cs_keyPathString, rhs.cs_keyPathString)
}
public func ~<D: NSManagedObject, O: NSManagedObject, V: AllowedObjectiveCKeyPathValue>(_ lhs: KeyPath<D, O?>, _ rhs: KeyPath<O, V>) -> Where<D>.Expression<Where<D>.SingleTarget, V> {
/**
Connects multiple `DynamicKeyPath`s to create a type-safe chain usable in query/fetch expressions
```
let owner = CoreStore.fetchOne(From<Pet>().where((\.master ~ \.name) == "John"))
```
*/
public func ~ <D: NSManagedObject, O: NSManagedObject, V: AllowedObjectiveCKeyPathValue>(_ lhs: KeyPath<D, O?>, _ rhs: KeyPath<O, V>) -> Where<D>.Expression<Where<D>.SingleTarget, V> {
return .init(lhs.cs_keyPathString, rhs.cs_keyPathString)
}
public func ~<D: NSManagedObject, O: NSManagedObject, V: AllowedObjectiveCCollectionKeyPathValue>(_ lhs: KeyPath<D, O>, _ rhs: KeyPath<O, V>) -> Where<D>.Expression<Where<D>.CollectionTarget, V> {
/**
Connects multiple `DynamicKeyPath`s to create a type-safe chain usable in query/fetch expressions
```
let happyPets = CoreStore.fetchAll(From<Pet>().where((\.master ~ \.pets).count() > 1))
```
*/
public func ~ <D: NSManagedObject, O: NSManagedObject, V: AllowedObjectiveCCollectionKeyPathValue>(_ lhs: KeyPath<D, O>, _ rhs: KeyPath<O, V>) -> Where<D>.Expression<Where<D>.CollectionTarget, V> {
return .init(lhs.cs_keyPathString, rhs.cs_keyPathString)
}
public func ~<D: NSManagedObject, O: NSManagedObject, V: AllowedObjectiveCCollectionKeyPathValue>(_ lhs: KeyPath<D, O?>, _ rhs: KeyPath<O, V>) -> Where<D>.Expression<Where<D>.CollectionTarget, V> {
/**
Connects multiple `DynamicKeyPath`s to create a type-safe chain usable in query/fetch expressions
```
let happyPets = CoreStore.fetchAll(From<Pet>().where((\.master ~ \.pets).count() > 1))
```
*/
public func ~ <D: NSManagedObject, O: NSManagedObject, V: AllowedObjectiveCCollectionKeyPathValue>(_ lhs: KeyPath<D, O?>, _ rhs: KeyPath<O, V>) -> Where<D>.Expression<Where<D>.CollectionTarget, V> {
return .init(lhs.cs_keyPathString, rhs.cs_keyPathString)
}
public func ~<D: NSManagedObject, O: NSManagedObject, T, V: AllowedObjectiveCKeyPathValue>(_ lhs: Where<D>.Expression<T, O>, _ rhs: KeyPath<O, V>) -> Where<D>.Expression<T, V> {
/**
Connects multiple `DynamicKeyPath`s to create a type-safe chain usable in query/fetch expressions
```
let johnsSonInLaw = CoreStore.fetchOne(From<Person>().where((\.spouse ~ \.father ~ \.name) == "John"))
```
*/
public func ~ <D: NSManagedObject, O: NSManagedObject, T, V: AllowedObjectiveCKeyPathValue>(_ lhs: Where<D>.Expression<T, O>, _ rhs: KeyPath<O, V>) -> Where<D>.Expression<T, V> {
return .init(lhs.cs_keyPathString, rhs.cs_keyPathString)
}
public func ~<D: NSManagedObject, O: NSManagedObject, T, V: AllowedObjectiveCCollectionKeyPathValue>(_ lhs: Where<D>.Expression<T, O>, _ rhs: KeyPath<O, V>) -> Where<D>.Expression<Where<D>.CollectionTarget, V> {
/**
Connects multiple `DynamicKeyPath`s to create a type-safe chain usable in query/fetch expressions
```
let johnsSonInLaw = CoreStore.fetchOne(From<Person>().where((\.spouse ~ \.father ~ \.name) == "John"))
```
*/
public func ~ <D: NSManagedObject, O: NSManagedObject, T, V: AllowedObjectiveCKeyPathValue>(_ lhs: Where<D>.Expression<T, O?>, _ rhs: KeyPath<O, V>) -> Where<D>.Expression<T, V> {
return .init(lhs.cs_keyPathString, rhs.cs_keyPathString)
}
public func ~<D: NSManagedObject, O: NSManagedObject, T, V: AllowedObjectiveCKeyPathValue>(_ lhs: Where<D>.Expression<T, O?>, _ rhs: KeyPath<O, V>) -> Where<D>.Expression<T, V> {
/**
Connects multiple `DynamicKeyPath`s to create a type-safe chain usable in query/fetch expressions
```
let spouseHasSiblings = CoreStore.fetchOne(From<Person>().where((\.spouse ~ \.father ~ \.children).count() > 0))
```
*/
public func ~ <D: NSManagedObject, O: NSManagedObject, T, V: AllowedObjectiveCCollectionKeyPathValue>(_ lhs: Where<D>.Expression<T, O>, _ rhs: KeyPath<O, V>) -> Where<D>.Expression<Where<D>.CollectionTarget, V> {
return .init(lhs.cs_keyPathString, rhs.cs_keyPathString)
}
public func ~<D: NSManagedObject, O: NSManagedObject, T, V: AllowedObjectiveCCollectionKeyPathValue>(_ lhs: Where<D>.Expression<T, O?>, _ rhs: KeyPath<O, V>) -> Where<D>.Expression<Where<D>.CollectionTarget, V> {
/**
Connects multiple `DynamicKeyPath`s to create a type-safe chain usable in query/fetch expressions
```
let spouseHasSiblings = CoreStore.fetchOne(From<Person>().where((\.spouse ~ \.father ~ \.children).count() > 0))
```
*/
public func ~ <D: NSManagedObject, O: NSManagedObject, T, V: AllowedObjectiveCCollectionKeyPathValue>(_ lhs: Where<D>.Expression<T, O?>, _ rhs: KeyPath<O, V>) -> Where<D>.Expression<Where<D>.CollectionTarget, V> {
return .init(lhs.cs_keyPathString, rhs.cs_keyPathString)
}
public func ~<D: NSManagedObject, O: NSManagedObject, T, C: AllowedObjectiveCCollectionKeyPathValue, V: AllowedObjectiveCKeyPathValue>(_ lhs: Where<D>.Expression<T, C>, _ rhs: KeyPath<O, V>) -> Where<D>.Expression<Where<D>.CollectionTarget, V> {
/**
Connects multiple `DynamicKeyPath`s to create a type-safe chain usable in query/fetch expressions
```
let spousesWithBadNamingSense = CoreStore.fetchAll(From<Person>().where((\.spouse ~ \.pets ~ \.name).any() == "Spot"))
```
*/
public func ~ <D: NSManagedObject, O: NSManagedObject, T, C: AllowedObjectiveCCollectionKeyPathValue, V: AllowedObjectiveCKeyPathValue>(_ lhs: Where<D>.Expression<T, C>, _ rhs: KeyPath<O, V>) -> Where<D>.Expression<Where<D>.CollectionTarget, V> {
return .init(lhs.cs_keyPathString, rhs.cs_keyPathString)
}
@@ -143,7 +229,13 @@ public func ~<D: NSManagedObject, O: NSManagedObject, T, C: AllowedObjectiveCCol
// MARK: - ~ where D: CoreStoreObject
public func ~<D: CoreStoreObject, O: CoreStoreObject, K: AllowedCoreStoreObjectKeyPathValue>(_ lhs: KeyPath<D, RelationshipContainer<D>.ToOne<O>>, _ rhs: KeyPath<O, K>) -> Where<D>.Expression<Where<D>.SingleTarget, K.ValueType> where K.ObjectType == O {
/**
Connects multiple `DynamicKeyPath`s to create a type-safe chain usable in query/fetch expressions
```
let owner = CoreStore.fetchOne(From<Pet>().where((\.master ~ \.name) == "John"))
```
*/
public func ~ <D: CoreStoreObject, O: CoreStoreObject, K: AllowedCoreStoreObjectKeyPathValue>(_ lhs: KeyPath<D, RelationshipContainer<D>.ToOne<O>>, _ rhs: KeyPath<O, K>) -> Where<D>.Expression<Where<D>.SingleTarget, K.ValueType> where K.ObjectType == O {
return .init(
D.meta[keyPath: lhs].cs_keyPathString,
@@ -151,7 +243,41 @@ public func ~<D: CoreStoreObject, O: CoreStoreObject, K: AllowedCoreStoreObjectK
)
}
public func ~<D: CoreStoreObject, O: CoreStoreObject, K: AllowedCoreStoreObjectCollectionKeyPathValue>(_ lhs: KeyPath<D, RelationshipContainer<D>.ToOne<O>>, _ rhs: KeyPath<O, K>) -> Where<D>.Expression<Where<D>.CollectionTarget, K.ValueType> where K.ObjectType == O {
/**
Connects multiple `DynamicKeyPath`s to create a type-safe chain usable in query/fetch expressions
```
let owner = CoreStore.fetchOne(From<Pet>().where((\.master ~ \.name) == "John"))
```
*/
public func ~ <D: CoreStoreObject, O: CoreStoreObject, T, K: AllowedCoreStoreObjectKeyPathValue>(_ lhs: Where<D>.Expression<T, O>, _ rhs: KeyPath<O, K>) -> Where<D>.Expression<T, K.ValueType> where K.ObjectType == O {
return .init(
lhs.cs_keyPathString,
O.meta[keyPath: rhs].cs_keyPathString
)
}
/**
Connects multiple `DynamicKeyPath`s to create a type-safe chain usable in query/fetch expressions
```
let owner = CoreStore.fetchOne(From<Pet>().where((\.master ~ \.name) == "John"))
```
*/
public func ~ <D: CoreStoreObject, O: CoreStoreObject, T, K: AllowedCoreStoreObjectKeyPathValue>(_ lhs: Where<D>.Expression<T, O?>, _ rhs: KeyPath<O, K>) -> Where<D>.Expression<T, K.ValueType> where K.ObjectType == O {
return .init(
lhs.cs_keyPathString,
O.meta[keyPath: rhs].cs_keyPathString
)
}
/**
Connects multiple `DynamicKeyPath`s to create a type-safe chain usable in query/fetch expressions
```
let happyPets = CoreStore.fetchAll(From<Pet>().where((\.master ~ \.pets).count() > 1))
```
*/
public func ~ <D: CoreStoreObject, O: CoreStoreObject, K: AllowedCoreStoreObjectCollectionKeyPathValue>(_ lhs: KeyPath<D, RelationshipContainer<D>.ToOne<O>>, _ rhs: KeyPath<O, K>) -> Where<D>.Expression<Where<D>.CollectionTarget, K.ValueType> where K.ObjectType == O {
return .init(
D.meta[keyPath: lhs].cs_keyPathString,
@@ -159,7 +285,13 @@ public func ~<D: CoreStoreObject, O: CoreStoreObject, K: AllowedCoreStoreObjectC
)
}
public func ~<D: CoreStoreObject, O: CoreStoreObject, T, K: AllowedCoreStoreObjectKeyPathValue>(_ lhs: Where<D>.Expression<T, O>, _ rhs: KeyPath<O, K>) -> Where<D>.Expression<T, K.ValueType> where K.ObjectType == O {
/**
Connects multiple `DynamicKeyPath`s to create a type-safe chain usable in query/fetch expressions
```
let happyPets = CoreStore.fetchAll(From<Pet>().where((\.master ~ \.pets).count() > 1))
```
*/
public func ~ <D: CoreStoreObject, O: CoreStoreObject, T, K: AllowedCoreStoreObjectCollectionKeyPathValue>(_ lhs: Where<D>.Expression<T, O>, _ rhs: KeyPath<O, K>) -> Where<D>.Expression<Where<D>.CollectionTarget, K.ValueType> where K.ObjectType == O {
return .init(
lhs.cs_keyPathString,
@@ -167,7 +299,13 @@ public func ~<D: CoreStoreObject, O: CoreStoreObject, T, K: AllowedCoreStoreObje
)
}
public func ~<D: CoreStoreObject, O: CoreStoreObject, T, K: AllowedCoreStoreObjectCollectionKeyPathValue>(_ lhs: Where<D>.Expression<T, O>, _ rhs: KeyPath<O, K>) -> Where<D>.Expression<Where<D>.CollectionTarget, K.ValueType> where K.ObjectType == O {
/**
Connects multiple `DynamicKeyPath`s to create a type-safe chain usable in query/fetch expressions
```
let happyPets = CoreStore.fetchAll(From<Pet>().where((\.master ~ \.pets).count() > 1))
```
*/
public func ~ <D: CoreStoreObject, O: CoreStoreObject, T, K: AllowedCoreStoreObjectCollectionKeyPathValue>(_ lhs: Where<D>.Expression<T, O?>, _ rhs: KeyPath<O, K>) -> Where<D>.Expression<Where<D>.CollectionTarget, K.ValueType> where K.ObjectType == O {
return .init(
lhs.cs_keyPathString,
@@ -175,23 +313,13 @@ public func ~<D: CoreStoreObject, O: CoreStoreObject, T, K: AllowedCoreStoreObje
)
}
public func ~<D: CoreStoreObject, O: CoreStoreObject, T, K: AllowedCoreStoreObjectKeyPathValue>(_ lhs: Where<D>.Expression<T, O?>, _ rhs: KeyPath<O, K>) -> Where<D>.Expression<T, K.ValueType> where K.ObjectType == O {
return .init(
lhs.cs_keyPathString,
O.meta[keyPath: rhs].cs_keyPathString
)
}
public func ~<D: CoreStoreObject, O: CoreStoreObject, T, K: AllowedCoreStoreObjectCollectionKeyPathValue>(_ lhs: Where<D>.Expression<T, O?>, _ rhs: KeyPath<O, K>) -> Where<D>.Expression<Where<D>.CollectionTarget, K.ValueType> where K.ObjectType == O {
return .init(
lhs.cs_keyPathString,
O.meta[keyPath: rhs].cs_keyPathString
)
}
public func ~<D: CoreStoreObject, O: CoreStoreObject, T, KC: AllowedCoreStoreObjectCollectionKeyPathValue, KV: AllowedCoreStoreObjectKeyPathValue>(_ lhs: Where<D>.Expression<T, KC>, _ rhs: KeyPath<O, KV>) -> Where<D>.Expression<Where<D>.CollectionTarget, KV.ValueType> where KC.ObjectType == D, KV.ObjectType == O {
/**
Connects multiple `DynamicKeyPath`s to create a type-safe chain usable in query/fetch expressions
```
let spousesWithBadNamingSense = CoreStore.fetchAll(From<Pet>().where((\.master ~ \.pets ~ \.name).any() == "Spot"))
```
*/
public func ~ <D: CoreStoreObject, O: CoreStoreObject, T, KC: AllowedCoreStoreObjectCollectionKeyPathValue, KV: AllowedCoreStoreObjectKeyPathValue>(_ lhs: Where<D>.Expression<T, KC>, _ rhs: KeyPath<O, KV>) -> Where<D>.Expression<Where<D>.CollectionTarget, KV.ValueType> where KC.ObjectType == D, KV.ObjectType == O {
return .init(
lhs.cs_keyPathString,
@@ -202,16 +330,34 @@ public func ~<D: CoreStoreObject, O: CoreStoreObject, T, KC: AllowedCoreStoreObj
// MARK: - Where.Expression where V: QueryableAttributeType
/**
Creates a `Where` clause by comparing if an expression is equal to a value
```
let dog = CoreStore.fetchOne(From<Dog>().where((\.master ~ \.name) == "John"))
```
*/
public func == <D, T, V: QueryableAttributeType>(_ lhs: Where<D>.Expression<T, V>, _ rhs: V) -> Where<D> {
return Where<D>(lhs.cs_keyPathString, isEqualTo: rhs)
}
/**
Creates a `Where` clause by comparing if an expression is not equal to a value
```
let dog = CoreStore.fetchOne(From<Dog>().where((\.master ~ \.name) != "John"))
```
*/
public func != <D, T, V: QueryableAttributeType>(_ lhs: Where<D>.Expression<T, V>, _ rhs: V) -> Where<D> {
return !Where<D>(lhs.cs_keyPathString, isEqualTo: rhs)
}
/**
Creates a `Where` clause by checking if a sequence contains a value
```
let dog = CoreStore.fetchOne(From<Dog>().where(["John", "Joe"] ~= (\.master ~ \.name))
```
*/
public func ~= <D, T, V: QueryableAttributeType, S: Sequence>(_ sequence: S, _ expression: Where<D>.Expression<T, V>) -> Where<D> where S.Iterator.Element == V {
return Where<D>(expression.cs_keyPathString, isMemberOf: sequence)
@@ -220,21 +366,45 @@ public func ~= <D, T, V: QueryableAttributeType, S: Sequence>(_ sequence: S, _ e
// MARK: - Where.Expression where V: QueryableAttributeType & Comparable
/**
Creates a `Where` clause by comparing if an expression is less than a value
```
let lonelyDog = CoreStore.fetchOne(From<Dog>().where((\.master ~ \.pets).count() < 2))
```
*/
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)
}
/**
Creates a `Where` clause by comparing if an expression is less than or equal to a value
```
let lonelyDog = CoreStore.fetchOne(From<Dog>().where((\.master ~ \.pets).count() <= 1)
```
*/
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)
}
/**
Creates a `Where` clause by comparing if an expression is greater than a value
```
let happyDog = CoreStore.fetchOne(From<Dog>().where((\.master ~ \.pets).count() > 1)
```
*/
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)
}
/**
Creates a `Where` clause by comparing if an expression is greater than or equal to a value
```
let happyDog = CoreStore.fetchOne(From<Dog>().where((\.master ~ \.pets).count() >= 2)
```
*/
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)
@@ -243,26 +413,56 @@ public func >= <D, T, V: QueryableAttributeType & Comparable>(_ lhs: Where<D>.Ex
// MARK: - Where.Expression where V: Optional<QueryableAttributeType>
/**
Creates a `Where` clause by comparing if an expression is equal to a value
```
let dog = CoreStore.fetchOne(From<Dog>().where((\.master ~ \.name) == "John"))
```
*/
public func == <D, T, V: QueryableAttributeType>(_ lhs: Where<D>.Expression<T, V?>, _ rhs: V) -> Where<D> {
return Where<D>(lhs.cs_keyPathString, isEqualTo: rhs)
}
/**
Creates a `Where` clause by comparing if an expression is equal to a value
```
let dog = CoreStore.fetchOne(From<Dog>().where((\.master ~ \.name) == "John"))
```
*/
public func == <D, T, V: QueryableAttributeType>(_ lhs: Where<D>.Expression<T, V?>, _ rhs: V?) -> Where<D> {
return Where<D>(lhs.cs_keyPathString, isEqualTo: rhs)
}
/**
Creates a `Where` clause by comparing if an expression is equal to a value
```
let dog = CoreStore.fetchOne(From<Dog>().where((\.master ~ \.name) != "John"))
```
*/
public func != <D, T, V: QueryableAttributeType>(_ lhs: Where<D>.Expression<T, V?>, _ rhs: V) -> Where<D> {
return !Where<D>(lhs.cs_keyPathString, isEqualTo: rhs)
}
/**
Creates a `Where` clause by comparing if an expression is equal to a value
```
let dog = CoreStore.fetchOne(From<Dog>().where((\.master ~ \.name) != "John"))
```
*/
public func != <D, T, V: QueryableAttributeType>(_ lhs: Where<D>.Expression<T, V?>, _ rhs: V?) -> Where<D> {
return !Where<D>(lhs.cs_keyPathString, isEqualTo: rhs)
}
/**
Creates a `Where` clause by checking if a sequence contains a value
```
let dog = CoreStore.fetchOne(From<Dog>().where(["John", "Joe"] ~= (\.master ~ \.name))
```
*/
public func ~= <D, T, V: QueryableAttributeType, S: Sequence>(_ sequence: S, _ expression: Where<D>.Expression<T, V?>) -> Where<D> where S.Iterator.Element == V {
return Where<D>(expression.cs_keyPathString, isMemberOf: sequence)
@@ -271,21 +471,45 @@ public func ~= <D, T, V: QueryableAttributeType, S: Sequence>(_ sequence: S, _ e
// MARK: - Where.Expression where V: Optional<QueryableAttributeType & Comparable>
/**
Creates a `Where` clause by comparing if an expression is less than a value
```
let childsPet = CoreStore.fetchOne(From<Dog>().where((\.master ~ \.age) < 10))
```
*/
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)
}
/**
Creates a `Where` clause by comparing if an expression is less than or equal to a value
```
let childsPet = CoreStore.fetchOne(From<Dog>().where((\.master ~ \.age) <= 10))
```
*/
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)
}
/**
Creates a `Where` clause by comparing if an expression is greater than a value
```
let teensPet = CoreStore.fetchOne(From<Dog>().where((\.master ~ \.age) > 10))
```
*/
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)
}
/**
Creates a `Where` clause by comparing if an expression is greater than or equal to a value
```
let teensPet = CoreStore.fetchOne(From<Dog>().where((\.master ~ \.age) >= 10))
```
*/
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)
@@ -296,6 +520,12 @@ public func >= <D, T, V: QueryableAttributeType & Comparable>(_ lhs: Where<D>.Ex
extension KeyPath where Root: NSManagedObject, Value: AllowedObjectiveCCollectionKeyPathValue {
/**
Creates a `Where.Expression` clause for COUNT
```
let dogsWithPlaymates = CoreStore.fetchAll(From<Dog>().where((\.master ~ \.pets).count() > 1))
```
*/
public func count() -> Where<Root>.Expression<Where<Root>.CollectionTarget, Int> {
return .init(self.cs_keyPathString, "@count")
@@ -306,6 +536,12 @@ extension KeyPath where Root: NSManagedObject, Value: AllowedObjectiveCCollectio
extension Where.Expression where D: NSManagedObject, T == Where<D>.CollectionTarget, V: AllowedObjectiveCCollectionKeyPathValue {
/**
Creates a `Where.Expression` clause for COUNT
```
let dogsWithPlaymates = CoreStore.fetchAll(From<Dog>().where((\.master ~ \.pets).count() > 1))
```
*/
public func count() -> Where<D>.Expression<T, Int> {
return .init(self.cs_keyPathString, "@count")
@@ -317,16 +553,34 @@ extension Where.Expression where D: NSManagedObject, T == Where<D>.CollectionTar
extension Where.Expression where D: NSManagedObject, T == Where<D>.CollectionTarget, V: AllowedObjectiveCKeyPathValue {
/**
Creates a `Where.Expression` clause for ANY
```
let dogsWithBadNamingSense = CoreStore.fetchAll(From<Dog>().where((\.master ~ \.pets ~ \.name).any() > "Spot"))
```
*/
public func any() -> Where<D>.Expression<T, V> {
return .init("ANY " + self.cs_keyPathString)
}
/**
Creates a `Where.Expression` clause for ALL
```
let allPlaymatePuppies = CoreStore.fetchAll(From<Dog>().where((\.master ~ \.pets ~ \.age).all() > 5))
```
*/
public func all() -> Where<D>.Expression<T, V> {
return .init("ALL " + self.cs_keyPathString)
}
/**
Creates a `Where.Expression` clause for NONE
```
let dogs = CoreStore.fetchAll(From<Dog>().where((\.master ~ \.pets ~ \.name).any() > "Spot"))
```
*/
public func none() -> Where<D>.Expression<T, V> {
return .init("NONE " + self.cs_keyPathString)
@@ -338,6 +592,12 @@ extension Where.Expression where D: NSManagedObject, T == Where<D>.CollectionTar
extension KeyPath where Root: CoreStoreObject, Value: AllowedCoreStoreObjectCollectionKeyPathValue {
/**
Creates a `Where.Expression` clause for COUNT
```
let dogsWithPlaymates = CoreStore.fetchAll(From<Dog>().where((\.master ~ \.pets).count() > 1))
```
*/
public func count() -> Where<Root>.Expression<Where<Root>.CollectionTarget, Int> {
return .init(Root.meta[keyPath: self].cs_keyPathString, "@count")
@@ -349,21 +609,45 @@ extension KeyPath where Root: CoreStoreObject, Value: AllowedCoreStoreObjectColl
extension Where.Expression where D: CoreStoreObject, T == Where<D>.CollectionTarget {
/**
Creates a `Where.Expression` clause for COUNT
```
let dogsWithPlaymates = CoreStore.fetchAll(From<Dog>().where((\.master ~ \.pets).count() > 1))
```
*/
public func count() -> Where<D>.Expression<T, Int> {
return .init(self.cs_keyPathString, "@count")
}
/**
Creates a `Where.Expression` clause for ANY
```
let dogsWithBadNamingSense = CoreStore.fetchAll(From<Dog>().where((\.master ~ \.pets ~ \.name).any() > "Spot"))
```
*/
public func any() -> Where<D>.Expression<T, V> {
return .init("ANY " + self.cs_keyPathString)
}
/**
Creates a `Where.Expression` clause for ALL
```
let allPlaymatePuppies = CoreStore.fetchAll(From<Dog>().where((\.master ~ \.pets ~ \.age).all() > 5))
```
*/
public func all() -> Where<D>.Expression<T, V> {
return .init("ALL " + self.cs_keyPathString)
}
/**
Creates a `Where.Expression` clause for NONE
```
let dogs = CoreStore.fetchAll(From<Dog>().where((\.master ~ \.pets ~ \.name).any() > "Spot"))
```
*/
public func none() -> Where<D>.Expression<T, V> {
return .init("NONE " + self.cs_keyPathString)

View File

@@ -29,7 +29,7 @@ import Foundation
// MARK: - WhereClauseType
/**
Abstracts the `Where` clause for protocol utilities.
Abstracts the `Where` clause for protocol utilities. Typically used only for utility method generic constraints.
*/
public protocol WhereClauseType: AnyWhereClause {