WIP: utilities for clauses

This commit is contained in:
John Rommel Estropia
2016-06-20 08:09:11 +09:00
parent e5a199489c
commit 3ccbce5c29
12 changed files with 722 additions and 190 deletions

View File

@@ -45,12 +45,26 @@
- (void)test_ThatFromClauses_BridgeCorrectly {
{
CSFrom *from = From([TestEntity1 class]);
CSFrom *from = CSFromCreate([TestEntity1 class]);
XCTAssertEqualObjects(from.entityClass, [TestEntity1 class]);
XCTAssertNil(from.configurations);
}
{
CSFrom *from = From([TestEntity1 class], @[[NSNull null], @"Config2"]);
CSFrom *from = CSFromCreate([TestEntity1 class], [NSNull null]);
XCTAssertEqualObjects(from.entityClass, [TestEntity1 class]);
NSArray *configurations = @[[NSNull null]];
XCTAssertEqualObjects(from.configurations, configurations);
}
{
CSFrom *from = CSFromCreate([TestEntity1 class], @"Config1");
XCTAssertEqualObjects(from.entityClass, [TestEntity1 class]);
NSArray *configurations = @[@"Config1"];
XCTAssertEqualObjects(from.configurations, configurations);
}
{
CSFrom *from = CSFromCreate([TestEntity1 class], @[[NSNull null], @"Config2"]);
XCTAssertEqualObjects(from.entityClass, [TestEntity1 class]);
NSArray *configurations = @[[NSNull null], @"Config2"];
@@ -61,26 +75,63 @@
- (void)test_ThatWhereClauses_BridgeCorrectly {
{
CSWhere *where = Where(@"%K == %@", @"key", @"value");
CSWhere *where = CSWhereFormat(@"%K == %@", @"key", @"value");
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K == %@", @"key", @"value"];
XCTAssertEqualObjects(where.predicate, predicate);
}
{
CSWhere *where = Where(YES);
CSWhere *where = CSWhereValue(YES);
NSPredicate *predicate = [NSPredicate predicateWithValue:YES];
XCTAssertEqualObjects(where.predicate, predicate);
}
{
CSWhere *where = Where([NSPredicate predicateWithFormat:@"%K == %@", @"key", @"value"]);
CSWhere *where = CSWherePredicate([NSPredicate predicateWithFormat:@"%K == %@", @"key", @"value"]);
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K == %@", @"key", @"value"];
XCTAssertEqualObjects(where.predicate, predicate);
}
}
- (void)test_ThatOrderByClauses_BridgeCorrectly {
{
CSOrderBy *orderBy = CSOrderBySortKey(CSSortAscending(@"key"));
XCTAssertEqualObjects(orderBy.sortDescriptors, @[[NSSortDescriptor sortDescriptorWithKey:@"key" ascending:YES]]);
}
{
CSOrderBy *orderBy = CSOrderBySortKey(CSSortDescending(@"key"));
XCTAssertEqualObjects(orderBy.sortDescriptors, @[[NSSortDescriptor sortDescriptorWithKey:@"key" ascending:NO]]);
}
{
CSOrderBy *orderBy = CSOrderBySortKeys(CSSortAscending(@"key1"), CSSortDescending(@"key2"), nil);
NSArray *sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"key1" ascending:YES],
[NSSortDescriptor sortDescriptorWithKey:@"key2" ascending:NO]];
XCTAssertEqualObjects(orderBy.sortDescriptors, sortDescriptors);
}
}
- (void)test_ThatGroupByClauses_BridgeCorrectly {
CSGroupBy *groupBy = GroupBy(@[@"key"]);
XCTAssertEqualObjects(groupBy.keyPaths, @[@"key"]);
{
CSGroupBy *groupBy = CSGroupByKeyPath(@"key");
XCTAssertEqualObjects(groupBy.keyPaths, @[@"key"]);
}
{
CSGroupBy *groupBy = CSGroupByKeyPaths(@[@"key1", @"key2"]);
NSArray *keyPaths = @[@"key1", @"key2"];
XCTAssertEqualObjects(groupBy.keyPaths, keyPaths);
}
}
- (void)test_ThatTweakClauses_BridgeCorrectly {
CSTweak *tweak = CSTweakCreate(^(NSFetchRequest * _Nonnull fetchRequest) {
fetchRequest.fetchLimit = 100;
});
NSFetchRequest *request = [NSFetchRequest new];
tweak.block(request);
XCTAssertEqual(request.fetchLimit, 100);
}
- (void)test_ThatDataStacks_BridgeCorrectly {
@@ -93,6 +144,9 @@
[CSCoreStore setDefaultStack:dataStack];
XCTAssertTrue([dataStack isEqual:[CSCoreStore defaultStack]]);
}
- (void)test_ThatStorages_BridgeCorrectly {
NSError *memoryError;
CSInMemoryStore *memoryStorage = [CSCoreStore

View File

@@ -47,16 +47,6 @@ public struct GroupBy: QueryClause, Hashable {
self.init([])
}
/**
Initializes a `GroupBy` clause with a list of key path strings
- parameter keyPaths: a list of key path strings to group results with
*/
public init(_ keyPaths: [KeyPath]) {
self.keyPaths = keyPaths
}
/**
Initializes a `GroupBy` clause with a list of key path strings
@@ -68,6 +58,16 @@ public struct GroupBy: QueryClause, Hashable {
self.init([keyPath] + keyPaths)
}
/**
Initializes a `GroupBy` clause with a list of key path strings
- parameter keyPaths: a list of key path strings to group results with
*/
public init(_ keyPaths: [KeyPath]) {
self.keyPaths = keyPaths
}
// MARK: QueryClause

View File

@@ -70,14 +70,9 @@ public enum SortKey {
public struct OrderBy: FetchClause, QueryClause, DeleteClause, Hashable {
/**
Initializes a `OrderBy` clause with a list of sort descriptors
- parameter sortDescriptors: a series of `NSSortDescriptor`s
The list of sort descriptors
*/
public init(_ sortDescriptors: [NSSortDescriptor]) {
self.sortDescriptors = sortDescriptors
}
public let sortDescriptors: [NSSortDescriptor]
/**
Initializes a `OrderBy` clause with an empty list of sort descriptors
@@ -97,6 +92,16 @@ public struct OrderBy: FetchClause, QueryClause, DeleteClause, Hashable {
self.init([sortDescriptor])
}
/**
Initializes a `OrderBy` clause with a list of sort descriptors
- parameter sortDescriptors: a series of `NSSortDescriptor`s
*/
public init(_ sortDescriptors: [NSSortDescriptor]) {
self.sortDescriptors = sortDescriptors
}
/**
Initializes a `OrderBy` clause with a series of `SortKey`s
@@ -130,8 +135,6 @@ public struct OrderBy: FetchClause, QueryClause, DeleteClause, Hashable {
self.init([sortKey] + sortKeys)
}
public let sortDescriptors: [NSSortDescriptor]
// MARK: FetchClause, QueryClause, DeleteClause

View File

@@ -44,15 +44,20 @@ import CoreData
*/
public struct Tweak: FetchClause, QueryClause, DeleteClause {
/**
The block to customize the `NSFetchRequest`
*/
public let closure: (fetchRequest: NSFetchRequest) -> Void
/**
Initializes a `Tweak` clause with a closure where the `NSFetchRequest` may be configured.
- Important: `Tweak`'s closure is executed only just before the fetch occurs, so make sure that any values captured by the closure is not prone to race conditions. Also, some utilities (such as `ListMonitor`s) may keep `FetchClause`s in memory and may thus introduce retain cycles if reference captures are not handled properly.
- parameter customization: a list of key path strings to group results with
- parameter closure: the block to customize the `NSFetchRequest`
*/
public init(_ customization: (fetchRequest: NSFetchRequest) -> Void) {
public init(_ closure: (fetchRequest: NSFetchRequest) -> Void) {
self.customization = customization
self.closure = closure
}
@@ -60,11 +65,6 @@ public struct Tweak: FetchClause, QueryClause, DeleteClause {
public func applyToFetchRequest(fetchRequest: NSFetchRequest) {
self.customization(fetchRequest: fetchRequest)
self.closure(fetchRequest: fetchRequest)
}
// MARK: Private
private let customization: (fetchRequest: NSFetchRequest) -> Void
}

View File

@@ -66,38 +66,36 @@ public final class CSFrom: NSObject, CoreStoreObjectiveCType {
/**
Initializes a `CSFrom` clause with the specified entity class.
```
MyPersonEntity *people = [transaction fetchAllFrom:[CSFrom entityClass:[MyPersonEntity class]]];
MyPersonEntity *people = [transaction fetchAllFrom:CSFromCreate([MyPersonEntity class])];
```
- parameter entityClass: the `NSManagedObject` class type to be created
- returns: a `CSFrom` clause with the specified entity class
*/
@objc
public static func entityClass(entityClass: AnyClass) -> CSFrom {
public convenience init(entityClass: AnyClass) {
return self.init(From(entityClass))
self.init(From(entityClass))
}
/**
Initializes a `CSFrom` clause with the specified configurations.
```
MyPersonEntity *people = [transaction fetchAllFrom:[CSFrom entityClass:[MyPersonEntity class] configuration:@"Configuration1"]];
MyPersonEntity *people = [transaction fetchAllFrom:
CSFromCreate([MyPersonEntity class], @"Config1")];
```
- parameter configuration: the `NSPersistentStore` configuration name to associate objects from. This parameter is required if multiple configurations contain the created `NSManagedObject`'s entity type. Set to `[NSNull null]` to use the default configuration.
- parameter otherConfigurations: an optional list of other configuration names to associate objects from (see `configuration` parameter)
- returns: a `CSFrom` clause with the specified configurations
*/
@objc
public static func entityClass(entityClass: AnyClass, configuration: AnyObject) -> CSFrom {
public convenience init(entityClass: AnyClass, configuration: AnyObject) {
switch configuration {
case let string as String:
return self.init(From(entityClass, string))
self.init(From(entityClass, string))
case is NSNull:
return self.init(From(entityClass, nil))
self.init(From(entityClass, nil))
default:
CoreStore.abort("The configuration argument only accepts NSString and NSNull values")
@@ -107,15 +105,16 @@ public final class CSFrom: NSObject, CoreStoreObjectiveCType {
/**
Initializes a `CSFrom` clause with the specified configurations.
```
MyPersonEntity *people = [transaction fetchAllFrom:[CSFrom entityClass:[MyPersonEntity class] configurations:@[[NSNull null], @"Configuration1"]]];
MyPersonEntity *people = [transaction fetchAllFrom:
CSFromCreate([MyPersonEntity class],
@[[NSNull null], @"Config1"])];
```
- parameter entity: the associated `NSManagedObject` entity class
- parameter configurations: a list of `NSPersistentStore` configuration names to associate objects from. This parameter is required if multiple configurations contain the created `NSManagedObject`'s entity type. Set to `[NSNull null]` to use the default configuration.
- returns: a `CSFrom` clause with the specified configurations
- parameter configurations: an array of the `NSPersistentStore` configuration names to associate objects from. This parameter is required if multiple configurations contain the created `NSManagedObject`'s entity type. Set to `[NSNull null]` to use the default configuration.
*/
@objc
public static func entityClass(entityClass: AnyClass, configurations: [AnyObject]) -> CSFrom {
public convenience init(entityClass: AnyClass, configurations: [AnyObject]) {
var arguments = [String?]()
for configuration in configurations {
@@ -132,7 +131,7 @@ public final class CSFrom: NSObject, CoreStoreObjectiveCType {
CoreStore.abort("The configurations argument only accepts NSString and NSNull values")
}
}
return self.init(From(entityClass, arguments))
self.init(From(entityClass, arguments))
}

View File

@@ -40,21 +40,32 @@ public final class CSGroupBy: NSObject, CSQueryClause, CoreStoreObjectiveCType {
/**
The list of key path strings to group results with
*/
@objc
public var keyPaths: [KeyPath] {
return self.bridgeToSwift.keyPaths
}
/**
Initializes a `CSGroupBy` clause with a key path string
- parameter keyPath: a key path string to group results with
*/
@objc
public convenience init(keyPath: KeyPath) {
self.init(GroupBy(keyPath))
}
/**
Initializes a `CSGroupBy` clause with a list of key path strings
- parameter keyPaths: a list of key path strings to group results with
- returns: a `CSGroupBy` clause with a list of key path strings
*/
@objc
public static func keyPaths(keyPaths: [KeyPath]) -> CSGroupBy {
public convenience init(keyPaths: [KeyPath]) {
return self.init(GroupBy(keyPaths))
self.init(GroupBy(keyPaths))
}

View File

@@ -27,32 +27,6 @@ import Foundation
import CoreData
// MARK: - CSSortKey
/**
The `CSSortKey` is a syntax-sugar class for `NSSortDescriptor` meant to be used with `CSOrderBy`.
- SeeAlso: `CSOrderBy`
- SeeAlso: `SortKey`
*/
@objc
public final class CSSortKey: NSSortDescriptor {
/**
Initializes a `CSSortKey` with a the specified key path and sort order
- parameter keyPath: the property key to use when performing a comparison
- parameter ascending: `YES` if the receiver specifies sorting in ascending order, otherwise `NO`
- returns: a `CSSortKey` with a the specified key path and sort order
*/
@objc
public static func withKeyPath(keyPath: KeyPath, ascending: Bool) -> CSSortKey {
return self.init(key: keyPath, ascending: ascending)
}
}
// MARK: - CSOrderBy
/**
@@ -64,27 +38,44 @@ public final class CSSortKey: NSSortDescriptor {
public final class CSOrderBy: NSObject, CSFetchClause, CSQueryClause, CSDeleteClause, CoreStoreObjectiveCType {
/**
Initializes a `CSOrderBy` clause with a list of sort descriptors
- parameter sortDescriptors: a series of `NSSortDescriptor`s
- returns: a `CSOrderBy` clause with a list of sort descriptors
The list of sort descriptors
*/
@objc
public static func sortDescriptors(sortDescriptors: [NSSortDescriptor]) -> CSOrderBy {
public var sortDescriptors: [NSSortDescriptor] {
return self.init(OrderBy(sortDescriptors))
return self.bridgeToSwift.sortDescriptors
}
/**
Initializes a `CSOrderBy` clause with a single sort descriptor
```
MyPersonEntity *people = [transaction
fetchAllFrom:CSFromCreate([MyPersonEntity class])
fetchClauses:@[CSOrderBySortKey(CSSortAscending(@"fullname"))]]];
```
- parameter sortDescriptor: a `NSSortDescriptor`
- returns: a `CSOrderBy` clause with a single sort descriptor
*/
@objc
public static func sortDescriptor(sortDescriptor: NSSortDescriptor) -> CSOrderBy {
public convenience init(sortDescriptor: NSSortDescriptor) {
return self.init(OrderBy(sortDescriptor))
self.init(OrderBy(sortDescriptor))
}
/**
Initializes a `CSOrderBy` clause with a list of sort descriptors
```
MyPersonEntity *people = [transaction
fetchAllFrom:CSFromCreate([MyPersonEntity class])
fetchClauses:@[CSOrderBySortKeys(CSSortAscending(@"fullname"), CSSortDescending(@"age"), nil))]]];
```
- parameter sortDescriptors: an array of `NSSortDescriptor`s
*/
@objc
public convenience init(sortDescriptors: [NSSortDescriptor]) {
self.init(OrderBy(sortDescriptors))
}

View File

@@ -42,16 +42,16 @@ public final class CSSelectTerm: NSObject, CoreStoreObjectiveCType {
```
NSString *fullName = [CSCoreStore
queryValueFrom:[CSFrom entityClass:[MyPersonEntity class]]
select:[CSSelect stringForTerm:[CSSelectTerm attribute:@"fullName"]]
select:CSSelectString(CSAttribute(@"fullname"))
fetchClauses:@[[CSWhere keyPath:@"employeeID" isEqualTo: @1111]]];
```
- parameter keyPath: the attribute name
- returns: a `CSSelectTerm` to a `CSSelect` clause for querying an entity attribute
*/
public static func attribute(keyPath: KeyPath) -> CSSelectTerm {
@objc
public convenience init(keyPath: KeyPath) {
return self.init(.Attribute(keyPath))
self.init(.Attribute(keyPath))
}
/**
@@ -66,6 +66,7 @@ public final class CSSelectTerm: NSObject, CoreStoreObjectiveCType {
- parameter `as`: the dictionary key to use to access the result. Ignored when the query return value is not an `NSDictionary`. If `nil`, the default key "average(<attributeName>)" is used
- returns: a `CSSelectTerm` to a `CSSelect` clause for querying the average value of an attribute
*/
@objc
public static func average(keyPath: KeyPath, `as` alias: KeyPath?) -> CSSelectTerm {
return self.init(.Average(keyPath, As: alias))
@@ -83,6 +84,7 @@ public final class CSSelectTerm: NSObject, CoreStoreObjectiveCType {
- parameter alias: the dictionary key to use to access the result. Ignored when the query return value is not an `NSDictionary`. If `nil`, the default key "count(<attributeName>)" is used
- returns: a `SelectTerm` to a `Select` clause for a count query
*/
@objc
public static func count(keyPath: KeyPath, `as` alias: KeyPath?) -> CSSelectTerm {
return self.init(.Count(keyPath, As: alias))
@@ -100,6 +102,7 @@ public final class CSSelectTerm: NSObject, CoreStoreObjectiveCType {
- parameter alias: the dictionary key to use to access the result. Ignored when the query return value is not an `NSDictionary`. If `nil`, the default key "max(<attributeName>)" is used
- returns: a `CSSelectTerm` to a `CSSelect` clause for querying the maximum value for an attribute
*/
@objc
public static func maximum(keyPath: KeyPath, `as` alias: KeyPath?) -> CSSelectTerm {
return self.init(.Maximum(keyPath, As: alias))
@@ -117,6 +120,7 @@ public final class CSSelectTerm: NSObject, CoreStoreObjectiveCType {
- parameter alias: the dictionary key to use to access the result. Ignored when the query return value is not an `NSDictionary`. If `nil`, the default key "min(<attributeName>)" is used
- returns: a `CSSelectTerm` to a `CSSelect` clause for querying the minimum value for an attribute
*/
@objc
public static func minimum(keyPath: KeyPath, `as` alias: KeyPath?) -> CSSelectTerm {
return self.init(.Minimum(keyPath, As: alias))
@@ -134,6 +138,7 @@ public final class CSSelectTerm: NSObject, CoreStoreObjectiveCType {
- parameter alias: the dictionary key to use to access the result. Ignored when the query return value is not an `NSDictionary`. If `nil`, the default key "sum(<attributeName>)" is used
- returns: a `CSSelectTerm` to a `CSSelect` clause for querying the sum value for an attribute
*/
@objc
public static func sum(keyPath: KeyPath, `as` alias: KeyPath?) -> CSSelectTerm {
return self.init(.Sum(keyPath, As: alias))
@@ -152,16 +157,13 @@ public final class CSSelectTerm: NSObject, CoreStoreObjectiveCType {
- parameter alias: the dictionary key to use to access the result. Ignored when the query return value is not an `NSDictionary`. If `nil`, the default key "objecID" is used
- returns: a `SelectTerm` to a `Select` clause for querying the sum value for an attribute
*/
public static func objectIDAs(alias: KeyPath? = nil) -> SelectTerm {
@objc
public static func objectIDAs(alias: KeyPath? = nil) -> CSSelectTerm {
return ._Identity(
alias: alias ?? "objectID",
nativeType: .ObjectIDAttributeType
)
return self.init(.ObjectID(As: alias))
}
// MARK: NSObject
public override var hash: Int {
@@ -214,100 +216,97 @@ public final class CSSelect: NSObject {
/**
Creates a `CSSelect` clause for querying `NSNumber` values.
```
NSNumber *maximumAge = [CSCoreStore
queryValueFrom:[CSFrom entityClass:[MyPersonEntity class]]
select:[CSSelect numberForTerm:[CSSelectTerm maximum:@"age" as:nil]]];
NSNumber *maxAge = [CSCoreStore
queryValueFrom:CSFromCreate([MyPersonEntity class])
select:CSSelectNumber(CSAggregateMax(@"age"))
// ...
```
- parameter term: the `CSSelectTerm` specifying the attribute/aggregate value to query
- returns: a `CSSelect` clause for querying an entity attribute
*/
public static func numberForTerm(term: CSSelectTerm) -> CSSelect {
public convenience init(numberTerm: CSSelectTerm) {
return self.init(Select<NSNumber>(term.bridgeToSwift))
self.init(Select<NSNumber>(numberTerm.bridgeToSwift))
}
/**
Creates a `CSSelect` clause for querying `NSDecimalNumber` values.
```
NSNumber *averageAge = [CSCoreStore
queryValueFrom:[CSFrom entityClass:[MyPersonEntity class]]
select:[CSSelect decimalNumberForTerm:[CSSelectTerm average:@"age" as:nil]]];
NSDecimalNumber *averagePrice = [CSCoreStore
queryValueFrom:CSFromCreate([MyPersonEntity class])
select:CSSelectDecimal(CSAggregateAverage(@"price"))
// ...
```
- parameter term: the `CSSelectTerm` specifying the attribute/aggregate value to query
- returns: a `CSSelect` clause for querying an entity attribute
*/
public static func decimalNumberForTerm(term: CSSelectTerm) -> CSSelect {
public convenience init(decimalTerm: CSSelectTerm) {
return self.init(Select<NSDecimalNumber>(term.bridgeToSwift))
self.init(Select<NSDecimalNumber>(decimalTerm.bridgeToSwift))
}
/**
Creates a `CSSelect` clause for querying `NSString` values.
```
NSString *fullName = [CSCoreStore
queryValueFrom:[CSFrom entityClass:[MyPersonEntity class]]
select:[CSSelect stringForTerm:[CSSelectTerm attribute:@"fullName"]]
fetchClauses:@[[CSWhere keyPath:@"employeeID" isEqualTo: @1111]]];
NSString *fullname = [CSCoreStore
queryValueFrom:CSFromCreate([MyPersonEntity class])
select:CSSelectString(CSAttribute(@"fullname"))
// ...
```
- parameter term: the `CSSelectTerm` specifying the attribute/aggregate value to query
- returns: a `CSSelect` clause for querying an entity attribute
*/
public static func stringForTerm(term: CSSelectTerm) -> CSSelect {
public convenience init(stringTerm: CSSelectTerm) {
return self.init(Select<NSString>(term.bridgeToSwift))
self.init(Select<NSString>(stringTerm.bridgeToSwift))
}
/**
Creates a `CSSelect` clause for querying `NSDate` values.
```
NSDate *lastUpdatedDate = [CSCoreStore
queryValueFrom:[CSFrom entityClass:[MyPersonEntity class]]
select:[CSSelect dateForTerm:[CSSelectTerm maximum:@"updatedDate" as:nil]]];
NSDate *lastUpdate = [CSCoreStore
queryValueFrom:CSFromCreate([MyPersonEntity class])
select:CSSelectDate(CSAggregateMax(@"updatedDate"))
// ...
```
- parameter term: the `CSSelectTerm` specifying the attribute/aggregate value to query
- returns: a `CSSelect` clause for querying an entity attribute
*/
public static func dateForTerm(term: CSSelectTerm) -> CSSelect {
public convenience init(dateTerm: CSSelectTerm) {
return self.init(Select<NSDate>(term.bridgeToSwift))
self.init(Select<NSDate>(dateTerm.bridgeToSwift))
}
/**
Creates a `CSSelect` clause for querying `NSData` values.
```
NSData *imageData = [CSCoreStore
queryValueFrom:[CSFrom entityClass:[MyPersonEntity class]]
select:[CSSelect dataForTerm:[CSSelectTerm attribute:@"imageData" as:nil]]
fetchClauses:@[[CSWhere keyPath:@"employeeID" isEqualTo: @1111]]];
queryValueFrom:CSFromCreate([MyPersonEntity class])
select:CSSelectData(CSAttribute(@"imageData"))
// ...
```
- parameter term: the `CSSelectTerm` specifying the attribute/aggregate value to query
- returns: a `CSSelect` clause for querying an entity attribute
*/
public static func dataForTerm(term: CSSelectTerm) -> CSSelect {
public convenience init(dataTerm: CSSelectTerm) {
return self.init(Select<NSData>(term.bridgeToSwift))
self.init(Select<NSData>(dataTerm.bridgeToSwift))
}
/**
Creates a `CSSelect` clause for querying `NSManagedObjectID` values.
```
NSManagedObjectID *objectIDForOldest = [CSCoreStore
queryValueFrom:[CSFrom entityClass:[MyPersonEntity class]]
select:[CSSelect objectID]
fetchClauses:@[[CSWhere keyPath:@"employeeID" isEqualTo: @1111]]];
NSManagedObjectID *objectID = [CSCoreStore
queryValueFrom:CSFromCreate([MyPersonEntity class])
select:CSSelectObjectID()
// ...
```
- parameter term: the `CSSelectTerm` specifying the attribute/aggregate value to query
- returns: a `CSSelect` clause for querying an entity attribute
*/
public static func objectID() -> CSSelect {
public convenience init(objectIDTerm: ()) {
return self.init(Select<NSManagedObjectID>(.ObjectID()))
self.init(Select<NSManagedObjectID>(.ObjectID()))
}
/**

View File

@@ -38,15 +38,24 @@ import CoreData
public final class CSTweak: NSObject, CSFetchClause, CSQueryClause, CSDeleteClause, CoreStoreObjectiveCType {
/**
Initializes a `CSTweak` clause with a closure where the `NSFetchRequest` may be configured.
- parameter customization: a list of key path strings to group results with
- returns: a `CSTweak` clause with a closure where the `NSFetchRequest` may be configured
The block to customize the `NSFetchRequest`
*/
@objc
public static func customization(customization: (fetchRequest: NSFetchRequest) -> Void) -> CSTweak {
public var block: (fetchRequest: NSFetchRequest) -> Void {
return self.init(Tweak(customization))
return self.bridgeToSwift.closure
}
/**
Initializes a `CSTweak` clause with a closure where the `NSFetchRequest` may be configured.
- Important: `CSTweak`'s closure is executed only just before the fetch occurs, so make sure that any values captured by the closure is not prone to race conditions. Also, some utilities (such as `CSListMonitor`s) may keep `CSFetchClause`s in memory and may thus introduce retain cycles if reference captures are not handled properly.
- parameter block: the block to customize the `NSFetchRequest`
*/
@objc
public convenience init(block: (fetchRequest: NSFetchRequest) -> Void) {
self.init(Tweak(block))
}

View File

@@ -48,27 +48,36 @@ public final class CSWhere: NSObject, CSFetchClause, CSQueryClause, CSDeleteClau
/**
Initializes a `CSWhere` clause with a predicate that always evaluates to the specified boolean value
```
MyPersonEntity *people = [transaction
fetchAllFrom:CSFromCreate([MyPersonEntity class])
fetchClauses:@[CSWhereValue(YES)]]];
```
- parameter value: the boolean value for the predicate
- returns: a `CSWhere` clause with a predicate that always evaluates to the specified boolean value
*/
@objc
public static func value(value: Bool) -> CSWhere {
public convenience init(value: Bool) {
return self.init(Where(value))
self.init(Where(value))
}
/**
Initializes a `CSWhere` clause with a predicate using the specified string format and arguments
```
NSPredicate *predicate = // ...
MyPersonEntity *people = [transaction
fetchAllFrom:CSFromCreate([MyPersonEntity class])
fetchClauses:@[CSWherePredicate(predicate)]];
```
- parameter format: the format string for the predicate
- parameter argumentArray: the arguments for `format`
- returns: a `CSWhere` clause with a predicate using the specified string format and arguments
*/
@objc
public static func format(format: String, argumentArray: [NSObject]?) -> CSWhere {
public convenience init(format: String, argumentArray: [NSObject]?) {
return self.init(Where(format, argumentArray: argumentArray))
self.init(Where(format, argumentArray: argumentArray))
}
/**
@@ -76,12 +85,11 @@ public final class CSWhere: NSObject, CSFetchClause, CSQueryClause, CSDeleteClau
- parameter keyPath: the keyPath to compare with
- parameter value: the arguments for the `==` operator
- returns: a `CSWhere` clause that compares equality
*/
@objc
public static func keyPath(keyPath: KeyPath, isEqualTo value: NSObject?) -> CSWhere {
public convenience init(keyPath: KeyPath, isEqualTo value: NSObject?) {
return self.init(Where(keyPath, isEqualTo: value))
self.init(Where(keyPath, isEqualTo: value))
}
/**
@@ -89,24 +97,22 @@ public final class CSWhere: NSObject, CSFetchClause, CSQueryClause, CSDeleteClau
- parameter keyPath: the keyPath to compare with
- parameter list: the array to check membership of
- returns: a `CSWhere` clause that compares membership
*/
@objc
public static func keyPath(keyPath: KeyPath, isMemberOf list: [NSObject]) -> CSWhere {
public convenience init(keyPath: KeyPath, isMemberOf list: [NSObject]) {
return self.init(Where(keyPath, isMemberOf: list))
self.init(Where(keyPath, isMemberOf: list))
}
/**
Initializes a `CSWhere` clause with an `NSPredicate`
- parameter predicate: the `NSPredicate` for the fetch or query
- returns: a `CSWhere` clause with an `NSPredicate`
*/
@objc
public static func predicate(predicate: NSPredicate) -> CSWhere {
public convenience init(predicate: NSPredicate) {
return self.init(Where(predicate))
self.init(Where(predicate))
}

View File

@@ -23,11 +23,12 @@
// SOFTWARE.
//
#import <Foundation/Foundation.h>
#ifndef CoreStoreBridge_h
#define CoreStoreBridge_h
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#if !__has_feature(objc_arc)
#error CoreStore Objective-C utilities require ARC be enabled
#endif
@@ -36,9 +37,10 @@
#error CoreStore Objective-C utilities can only be used on platforms that support C function overloading
#endif
#define CS_OBJC_EXTERN extern
#define CS_OBJC_OVERLOADABLE __attribute__((__overloadable__))
#define CS_OBJC_REQUIRES_NIL_TERMINATION(A, B) __attribute__((sentinel(A, B)))
#define CS_OBJC_EXTERN extern
#define CS_OBJC_OVERLOADABLE __attribute__((__overloadable__))
#define CS_OBJC_REQUIRES_NIL_TERMINATION __attribute__((sentinel(0, 1)))
#define CS_OBJC_RETURNS_RETAINED __attribute__((ns_returns_retained))
// MARK: - From
@@ -50,7 +52,8 @@
Initializes a <tt>CSFrom</tt> clause with the specified entity class.
@code
MyPersonEntity *people = [transaction fetchAllFrom:From([MyPersonEntity class])];
MyPersonEntity *people = [transaction fetchAllFrom:
CSFromCreate([MyPersonEntity class])];
@endcode
@param entityClass
@@ -60,14 +63,58 @@
a <tt>CSFrom</tt> clause with the specified entity class
*/
CS_OBJC_EXTERN CS_OBJC_OVERLOADABLE
CSFrom *_Nonnull From(Class _Nonnull entityClass);
CSFrom *_Nonnull CSFromCreate(Class _Nonnull entityClass) CS_OBJC_RETURNS_RETAINED;
/**
@abstract
Initializes a <tt>CSFrom</tt> clause with the specified configuration.
@code
MyPersonEntity *people = [transaction fetchAllFrom:
CSFromCreate([MyPersonEntity class], @"Configuration1")];
@endcode
@param entityClass
the <tt>NSManagedObject</tt> class type to be created
@param configuration
an <tt>NSPersistentStore</tt> configuration name to associate objects from. This parameter is required if multiple configurations contain the created <tt>NSManagedObject</tt>'s entity type. Set to <tt>[NSNull null]</tt> to use the default configuration.
@result
a <tt>CSFrom</tt> clause with the specified configuration
*/
CS_OBJC_EXTERN CS_OBJC_OVERLOADABLE
CSFrom *_Nonnull CSFromCreate(Class _Nonnull entityClass, NSNull *_Nonnull configuration) CS_OBJC_RETURNS_RETAINED;
/**
@abstract
Initializes a <tt>CSFrom</tt> clause with the specified configuration.
@code
MyPersonEntity *people = [transaction fetchAllFrom:
CSFromCreate([MyPersonEntity class], @"Configuration1")];
@endcode
@param entityClass
the <tt>NSManagedObject</tt> class type to be created
@param configuration
an <tt>NSPersistentStore</tt> configuration name to associate objects from. This parameter is required if multiple configurations contain the created <tt>NSManagedObject</tt>'s entity type. Set to <tt>[NSNull null]</tt> to use the default configuration.
@result
a <tt>CSFrom</tt> clause with the specified configuration
*/
CS_OBJC_EXTERN CS_OBJC_OVERLOADABLE
CSFrom *_Nonnull CSFromCreate(Class _Nonnull entityClass, NSString *_Nonnull configuration) CS_OBJC_RETURNS_RETAINED;
/**
@abstract
Initializes a <tt>CSFrom</tt> clause with the specified configurations.
@code
MyPersonEntity *people = [transaction fetchAllFrom:From([MyPersonEntity class], @[@"Configuration1"])];
MyPersonEntity *people = [transaction fetchAllFrom:
CSFromCreate([MyPersonEntity class],
@[[NSNull null], @"Configuration1"])];
@endcode
@param entityClass
@@ -80,9 +127,134 @@ CSFrom *_Nonnull From(Class _Nonnull entityClass);
a <tt>CSFrom</tt> clause with the specified configurations
*/
CS_OBJC_EXTERN CS_OBJC_OVERLOADABLE
CSFrom *_Nonnull From(Class _Nonnull entityClass, NSArray<id> *_Nonnull configurations);
CSFrom *_Nonnull CSFromCreate(Class _Nonnull entityClass, NSArray<id> *_Nonnull configurations) CS_OBJC_RETURNS_RETAINED;
// MARK: - Select
@class CSSelect;
@class CSSelectTerm;
/**
@abstract
Creates a <tt>CSSelect</tt> clause for querying an <tt>NSNumber</tt> value
@code
NSNumber *maxAge = [CSCoreStore
queryValueFrom:CSFromCreate([MyPersonEntity class])
select:CSSelectNumber(CSAggregateMax(@"age"))
// ...
@endcode
@param selectTerm
the <tt>CSSelectTerm</tt> specifying the attribute/aggregate value to query
@result
a <tt>CSSelect</tt> clause for querying an <tt>NSNumber</tt> value
*/
CS_OBJC_EXTERN
CSSelect *_Nonnull CSSelectNumber(CSSelectTerm *_Nonnull selectTerm) CS_OBJC_RETURNS_RETAINED;
/**
@abstract
Creates a <tt>CSSelect</tt> clause for querying an <tt>NSDecimalNumber</tt> value
@code
NSDecimalNumber *averagePrice = [CSCoreStore
queryValueFrom:CSFromCreate([MyPersonEntity class])
select:CSSelectDecimal(CSAggregateAverage(@"price"))
// ...
@endcode
@param selectTerm
the <tt>CSSelectTerm</tt> specifying the attribute/aggregate value to query
@result
a <tt>CSSelect</tt> clause for querying an <tt>NSDecimalNumber</tt> value
*/
CS_OBJC_EXTERN
CSSelect *_Nonnull CSSelectDecimal(CSSelectTerm *_Nonnull selectTerm) CS_OBJC_RETURNS_RETAINED;
/**
@abstract
Creates a <tt>CSSelect</tt> clause for querying an <tt>NSString</tt> value
@code
NSString *fullname = [CSCoreStore
queryValueFrom:CSFromCreate([MyPersonEntity class])
select:CSSelectString(CSAttribute(@"fullname"))
// ...
@endcode
@param selectTerm
the <tt>CSSelectTerm</tt> specifying the attribute/aggregate value to query
@result
a <tt>CSSelect</tt> clause for querying an <tt>NSString</tt> value
*/
CS_OBJC_EXTERN
CSSelect *_Nonnull CSSelectString(CSSelectTerm *_Nonnull selectTerm) CS_OBJC_RETURNS_RETAINED;
/**
@abstract
Creates a <tt>CSSelect</tt> clause for querying an <tt>NSDate</tt> value
@code
NSDate *lastUpdate = [CSCoreStore
queryValueFrom:CSFromCreate([MyPersonEntity class])
select:CSSelectDate(CSAggregateMax(@"updatedDate"))
// ...
@endcode
@param selectTerm
the <tt>CSSelectTerm</tt> specifying the attribute/aggregate value to query
@result
a <tt>CSSelect</tt> clause for querying an <tt>NSDate</tt> value
*/
CS_OBJC_EXTERN
CSSelect *_Nonnull CSSelectDate(CSSelectTerm *_Nonnull selectTerm) CS_OBJC_RETURNS_RETAINED;
/**
@abstract
Creates a <tt>CSSelect</tt> clause for querying an <tt>NSData</tt> value
@code
NSData *imageData = [CSCoreStore
queryValueFrom:CSFromCreate([MyPersonEntity class])
select:CSSelectData(CSAttribute(@"imageData"))
// ...
@endcode
@param selectTerm
the <tt>CSSelectTerm</tt> specifying the attribute/aggregate value to query
@result
a <tt>CSSelect</tt> clause for querying an <tt>NSData</tt> value
*/
CS_OBJC_EXTERN
CSSelect *_Nonnull CSSelectData(CSSelectTerm *_Nonnull selectTerm) CS_OBJC_RETURNS_RETAINED;
/**
@abstract
Creates a <tt>CSSelect</tt> clause for querying an <tt>NSManagedObjectID</tt> value
@code
NSManagedObjectID *objectID = [CSCoreStore
queryValueFrom:CSFromCreate([MyPersonEntity class])
select:CSSelectObjectID()
// ...
@endcode
@param selectTerm
the <tt>CSSelectTerm</tt> specifying the attribute/aggregate value to query
@result
a <tt>CSSelect</tt> clause for querying an <tt>NSManagedObjectID</tt> value
*/
CS_OBJC_EXTERN
CSSelect *_Nonnull CSSelectObjectID() CS_OBJC_RETURNS_RETAINED;
// MARK: - Where
@@ -92,19 +264,31 @@ CSFrom *_Nonnull From(Class _Nonnull entityClass, NSArray<id> *_Nonnull configur
@abstract
Initializes a <tt>CSWhere</tt> clause with a predicate that always evaluates to the specified boolean value
@code
MyPersonEntity *people = [transaction
fetchAllFrom:CSFromCreate([MyPersonEntity class])
fetchClauses:@[CSWhereValue(YES)]];
@endcode
@param value
the boolean value for the predicate
@result
a <tt>CSWhere</tt> clause with a predicate that always evaluates to the specified boolean value
*/
CS_OBJC_EXTERN CS_OBJC_OVERLOADABLE
CSWhere *_Nonnull Where(BOOL value);
CS_OBJC_EXTERN
CSWhere *_Nonnull CSWhereValue(BOOL value) CS_OBJC_RETURNS_RETAINED;
/**
@abstract
Initializes a <tt>CSWhere</tt> clause with a predicate using the specified string format and arguments
@code
MyPersonEntity *people = [transaction
fetchAllFrom:CSFromCreate([MyPersonEntity class])
fetchClauses:@[CSWhereFormat(@"%K == %@", @"key", @"value")]];
@endcode
@param format
the format string for the predicate
@@ -114,27 +298,160 @@ CSWhere *_Nonnull Where(BOOL value);
@result
a <tt>CSWhere</tt> clause with a predicate using the specified string format and arguments
*/
CS_OBJC_EXTERN CS_OBJC_OVERLOADABLE
CSWhere *_Nonnull Where(NSString *_Nonnull format, ...);
CS_OBJC_EXTERN
CSWhere *_Nonnull CSWhereFormat(NSString *_Nonnull format, ...) CS_OBJC_RETURNS_RETAINED;
/**
@abstract
Initializes a <tt>CSWhere</tt> clause with an <tt>NSPredicate</tt>
@code
NSPredicate *predicate = // ...
MyPersonEntity *people = [transaction
fetchAllFrom:CSFromCreate([MyPersonEntity class])
fetchClauses:@[CSWherePredicate(predicate)]];
@endcode
@param predicate
the <tt>NSPredicate</tt> for the fetch or query
@result
a <tt>CSWhere</tt> clause with an <tt>NSPredicate</tt>
*/
CS_OBJC_EXTERN
CSWhere *_Nonnull CSWherePredicate(NSPredicate *_Nonnull predicate) CS_OBJC_RETURNS_RETAINED;
// MARK: - OrderBy
@class CSOrderBy;
/**
@abstract
Syntax sugar for initializing an ascending <tt>NSSortDescriptor</tt> for use with <tt>CSOrderBy</tt>
@code
MyPersonEntity *people = [CSCoreStore
fetchAllFrom:CSFromCreate([MyPersonEntity class])
fetchClauses:@[CSOrderBySortKey(CSSortAscending(@"fullname"))]]];
@endcode
@param key
the attribute key to sort with
@result
an <tt>NSSortDescriptor</tt> for use with <tt>CSOrderBy</tt>
*/
CS_OBJC_EXTERN
NSSortDescriptor *_Nonnull CSSortAscending(NSString *_Nonnull key) CS_OBJC_RETURNS_RETAINED;
/**
@abstract
Syntax sugar for initializing a descending <tt>NSSortDescriptor</tt> for use with <tt>CSOrderBy</tt>
@code
MyPersonEntity *people = [CSCoreStore
fetchAllFrom:CSFromCreate([MyPersonEntity class])
fetchClauses:@[CSOrderBySortKey(CSSortDescending(@"fullname"))]]];
@endcode
@param key
the attribute key to sort with
@result
an <tt>NSSortDescriptor</tt> for use with <tt>CSOrderBy</tt>
*/
CS_OBJC_EXTERN
NSSortDescriptor *_Nonnull CSSortDescending(NSString *_Nonnull key) CS_OBJC_RETURNS_RETAINED;
/**
@abstract
Initializes a <tt>CSOrderBy</tt> clause with a single sort descriptor
@code
MyPersonEntity *people = [transaction
fetchAllFrom:CSFromCreate([MyPersonEntity class])
fetchClauses:@[CSOrderBySortKey(CSSortAscending(@"fullname"))]]];
@endcode
@param sortDescriptor
an <tt>NSSortDescriptor</tt>
@result
a <tt>CSOrderBy</tt> clause with a single sort descriptor
*/
CS_OBJC_EXTERN
CSOrderBy *_Nonnull CSOrderBySortKey(NSSortDescriptor *_Nonnull sortDescriptor) CS_OBJC_RETURNS_RETAINED;
/**
@abstract
Initializes a <tt>CSOrderBy</tt> clause with a list of sort descriptors
@code
MyPersonEntity *people = [transaction
fetchAllFrom:CSFromCreate([MyPersonEntity class])
fetchClauses:@[CSOrderBySortKeys(CSSortAscending(@"fullname"), CSSortDescending(@"age"), nil))]]];
@endcode
@param sortDescriptors
a nil-terminated array of <tt>NSSortDescriptor</tt>s
@result
a <tt>CSOrderBy</tt> clause with a list of sort descriptors
*/
CS_OBJC_EXTERN CS_OBJC_OVERLOADABLE
CSWhere *_Nonnull Where(NSPredicate *_Nonnull predicate);
CSOrderBy *_Nonnull CSOrderBySortKeys(NSSortDescriptor *_Nonnull sortDescriptor, ...) CS_OBJC_RETURNS_RETAINED CS_OBJC_REQUIRES_NIL_TERMINATION;
/**
@abstract
Initializes a <tt>CSOrderBy</tt> clause with a list of sort descriptors
@code
MyPersonEntity *people = [transaction
fetchAllFrom:CSFromCreate([MyPersonEntity class])
fetchClauses:@[CSOrderBySortKeys(@[CSSortAscending(@"fullname"), CSSortDescending(@"age")]))]]];
@endcode
@param sortDescriptors
an array of <tt>NSSortDescriptor</tt>s
@result
a <tt>CSOrderBy</tt> clause with a list of sort descriptors
*/
CS_OBJC_EXTERN CS_OBJC_OVERLOADABLE
CSOrderBy *_Nonnull CSOrderBySortKeys(NSArray<NSSortDescriptor *> *_Nonnull sortDescriptors) CS_OBJC_RETURNS_RETAINED;
// MARK: - GroupBy
@class CSGroupBy;
/**
@abstract
Initializes a <tt>CSGroupBy</tt> clause with a key path string
@param keyPaths
a key path string to group results with
@result
a <tt>CSGroupBy</tt> clause with a key path string
*/
CS_OBJC_EXTERN
CSGroupBy *_Nonnull CSGroupByKeyPath(NSString *_Nonnull keyPath) CS_OBJC_RETURNS_RETAINED;
/**
@abstract
Initializes a <tt>CSGroupBy</tt> clause with a list of key path strings
@param keyPaths
a nil-terminated list of key path strings to group results with
@result
a <tt>CSGroupBy</tt> clause with a list of key path strings
*/
CS_OBJC_EXTERN CS_OBJC_OVERLOADABLE
CSGroupBy *_Nonnull CSGroupByKeyPaths(NSString *_Nonnull keyPath, ...) CS_OBJC_RETURNS_RETAINED;
/**
@abstract
Initializes a <tt>CSGroupBy</tt> clause with a list of key path strings
@@ -145,8 +462,29 @@ CSWhere *_Nonnull Where(NSPredicate *_Nonnull predicate);
@result
a <tt>CSGroupBy</tt> clause with a list of key path strings
*/
CS_OBJC_OVERLOADABLE
CSGroupBy *_Nonnull GroupBy(NSArray<NSString *> *_Nonnull keyPaths);
CS_OBJC_EXTERN CS_OBJC_OVERLOADABLE
CSGroupBy *_Nonnull CSGroupByKeyPaths(NSArray<NSString *> *_Nonnull keyPaths) CS_OBJC_RETURNS_RETAINED;
// MARK: - Tweak
@class CSTweak;
/**
@abstract
Initializes a <tt>CSTweak</tt> clause with a block where the <tt>NSFetchRequest</tt> may be configured.
@important
<tt>CSTweak</tt>'s closure is executed only just before the fetch occurs, so make sure that any values captured by the closure is not prone to race conditions. Also, some utilities (such as <tt>CSListMonitor</tt>s) may keep <tt>CSFetchClause</tt>s in memory and may thus introduce retain cycles if reference captures are not handled properly.
@param block
the block to customize the <tt>NSFetchRequest</tt>
@result
a <tt>CSTweak</tt> clause with the <tt>NSFetchRequest</tt> configuration block
*/
CS_OBJC_EXTERN CS_OBJC_OVERLOADABLE
CSTweak *_Nonnull CSTweakCreate(void (^_Nonnull block)(NSFetchRequest *_Nonnull fetchRequest)) CS_OBJC_RETURNS_RETAINED;
#endif /* CoreStoreBridge_h */

View File

@@ -28,49 +28,171 @@
CS_OBJC_OVERLOADABLE
CSFrom *_Nonnull From(Class _Nonnull entityClass) {
CSFrom *_Nonnull CSFromCreate(Class _Nonnull entityClass) CS_OBJC_RETURNS_RETAINED {
return [CSFrom entityClass:entityClass];
return [[CSFrom alloc] initWithEntityClass:entityClass];
}
CS_OBJC_OVERLOADABLE
CSFrom *_Nonnull From(Class _Nonnull entityClass, NSArray<id> *_Nonnull configurations) {
CSFrom *_Nonnull CSFromCreate(Class _Nonnull entityClass, NSNull *_Nonnull configuration) CS_OBJC_RETURNS_RETAINED {
return [CSFrom entityClass:entityClass configurations:configurations];
return [[CSFrom alloc] initWithEntityClass:entityClass configuration:configuration];
}
CS_OBJC_OVERLOADABLE
CSFrom *_Nonnull CSFromCreate(Class _Nonnull entityClass, NSString *_Nonnull configuration) CS_OBJC_RETURNS_RETAINED {
return [[CSFrom alloc] initWithEntityClass:entityClass configuration:configuration];
}
CS_OBJC_OVERLOADABLE
CSFrom *_Nonnull CSFromCreate(Class _Nonnull entityClass, NSArray<id> *_Nonnull configurations) CS_OBJC_RETURNS_RETAINED {
return [[CSFrom alloc] initWithEntityClass:entityClass configurations:configurations];
}
// MARK: - Select
//CSSelectTerm *_Nonnull CSAttribute(NSString *_Nonnull keyPath) CS_OBJC_RETURNS_RETAINED {
//
// return [[CSSelectTerm alloc] initWithKeyPath:keyPath];
//}
CSSelect *_Nonnull CSSelectNumber(CSSelectTerm *_Nonnull selectTerm) CS_OBJC_RETURNS_RETAINED {
return [[CSSelect alloc] initWithNumberTerm:selectTerm];
}
CSSelect *_Nonnull CSSelectDecimal(CSSelectTerm *_Nonnull selectTerm) CS_OBJC_RETURNS_RETAINED {
return [[CSSelect alloc] initWithDecimalTerm:selectTerm];
}
CSSelect *_Nonnull CSSelectString(CSSelectTerm *_Nonnull selectTerm) CS_OBJC_RETURNS_RETAINED {
return [[CSSelect alloc] initWithStringTerm:selectTerm];
}
CSSelect *_Nonnull CSSelectDate(CSSelectTerm *_Nonnull selectTerm) CS_OBJC_RETURNS_RETAINED {
return [[CSSelect alloc] initWithDateTerm:selectTerm];
}
CSSelect *_Nonnull CSSelectData(CSSelectTerm *_Nonnull selectTerm) CS_OBJC_RETURNS_RETAINED {
return [[CSSelect alloc] initWithDataTerm:selectTerm];
}
CSSelect *_Nonnull CSSelectObjectID() CS_OBJC_RETURNS_RETAINED {
return [[CSSelect alloc] initWithObjectIDTerm];
}
// MARK: - Where
CS_OBJC_OVERLOADABLE
CSWhere *_Nonnull Where(BOOL value) {
CSWhere *_Nonnull CSWhereValue(BOOL value) CS_OBJC_RETURNS_RETAINED {
return [CSWhere value:value];
return [[CSWhere alloc] initWithValue:value];
}
CS_OBJC_OVERLOADABLE
CSWhere *_Nonnull Where(NSString *_Nonnull format, ...) {
CSWhere *_Nonnull CSWhereFormat(NSString *_Nonnull format, ...) CS_OBJC_RETURNS_RETAINED {
CSWhere *where;
va_list args;
va_start(args, format);
where = [CSWhere predicate:[NSPredicate predicateWithFormat:format arguments:args]];
where = [[CSWhere alloc] initWithPredicate:[NSPredicate predicateWithFormat:format arguments:args]];
va_end(args);
return where;
}
CS_OBJC_OVERLOADABLE
CSWhere *_Nonnull Where(NSPredicate *_Nonnull predicate) {
CSWhere *_Nonnull CSWherePredicate(NSPredicate *_Nonnull predicate) CS_OBJC_RETURNS_RETAINED {
return [CSWhere predicate:predicate];
return [[CSWhere alloc] initWithPredicate:predicate];
}
// MARK: - OrderBy
@class CSOrderBy;
NSSortDescriptor *_Nonnull CSSortAscending(NSString *_Nonnull key) {
return [[NSSortDescriptor alloc] initWithKey:key ascending:YES];
}
NSSortDescriptor *_Nonnull CSSortDescending(NSString *_Nonnull key) {
return [[NSSortDescriptor alloc] initWithKey:key ascending:NO];
}
CSOrderBy *_Nonnull CSOrderBySortKey(NSSortDescriptor *_Nonnull sortDescriptor) CS_OBJC_RETURNS_RETAINED {
return [[CSOrderBy alloc] initWithSortDescriptor:sortDescriptor];
}
CS_OBJC_OVERLOADABLE
CSOrderBy *_Nonnull CSOrderBySortKeys(NSSortDescriptor *_Nonnull sortDescriptor, ...) CS_OBJC_RETURNS_RETAINED {
va_list args;
va_start(args, sortDescriptor);
NSMutableArray *sortDescriptors = [NSMutableArray new];
[sortDescriptors addObject:sortDescriptor];
NSSortDescriptor *next;
while ((next = va_arg(args, NSSortDescriptor *)) != nil) {
[sortDescriptors addObject:next];
}
va_end(args);
return [[CSOrderBy alloc] initWithSortDescriptors:sortDescriptors];
}
CS_OBJC_OVERLOADABLE
CSOrderBy *_Nonnull CSOrderBySortKeys(NSArray<NSSortDescriptor *> *_Nonnull sortDescriptors) CS_OBJC_RETURNS_RETAINED {
return [[CSOrderBy alloc] initWithSortDescriptors:sortDescriptors];
}
// MARK: - GroupBy
CS_OBJC_OVERLOADABLE
CSGroupBy *_Nonnull GroupBy(NSArray<NSString *> *_Nonnull keyPaths) {
return [CSGroupBy keyPaths:keyPaths];
CSGroupBy *_Nonnull CSGroupByKeyPath(NSString *_Nonnull keyPath) CS_OBJC_RETURNS_RETAINED {
return [[CSGroupBy alloc] initWithKeyPath:keyPath];
}
CS_OBJC_OVERLOADABLE
CSGroupBy *_Nonnull CSGroupByKeyPaths(NSString *_Nonnull keyPath, ...) CS_OBJC_RETURNS_RETAINED {
va_list args;
va_start(args, keyPath);
NSMutableArray *keyPaths = [NSMutableArray new];
[keyPaths addObject:keyPath];
NSString *next;
while ((next = va_arg(args, NSString *)) != nil) {
[keyPaths addObject:next];
}
va_end(args);
return [[CSGroupBy alloc] initWithKeyPaths:keyPaths];
}
CS_OBJC_OVERLOADABLE
CSGroupBy *_Nonnull CSGroupByKeyPaths(NSArray<NSString *> *_Nonnull keyPaths) CS_OBJC_RETURNS_RETAINED {
return [[CSGroupBy alloc] initWithKeyPaths:keyPaths];
}
// MARK: - Tweak
CS_OBJC_OVERLOADABLE
CSTweak *_Nonnull CSTweakCreate(void (^_Nonnull block)(NSFetchRequest *_Nonnull fetchRequest)) CS_OBJC_RETURNS_RETAINED {
return [[CSTweak alloc] initWithBlock:block];
}