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 { - (void)test_ThatFromClauses_BridgeCorrectly {
{ {
CSFrom *from = From([TestEntity1 class]); CSFrom *from = CSFromCreate([TestEntity1 class]);
XCTAssertEqualObjects(from.entityClass, [TestEntity1 class]); XCTAssertEqualObjects(from.entityClass, [TestEntity1 class]);
XCTAssertNil(from.configurations); 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]); XCTAssertEqualObjects(from.entityClass, [TestEntity1 class]);
NSArray *configurations = @[[NSNull null], @"Config2"]; NSArray *configurations = @[[NSNull null], @"Config2"];
@@ -61,26 +75,63 @@
- (void)test_ThatWhereClauses_BridgeCorrectly { - (void)test_ThatWhereClauses_BridgeCorrectly {
{ {
CSWhere *where = Where(@"%K == %@", @"key", @"value"); CSWhere *where = CSWhereFormat(@"%K == %@", @"key", @"value");
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K == %@", @"key", @"value"]; NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K == %@", @"key", @"value"];
XCTAssertEqualObjects(where.predicate, predicate); XCTAssertEqualObjects(where.predicate, predicate);
} }
{ {
CSWhere *where = Where(YES); CSWhere *where = CSWhereValue(YES);
NSPredicate *predicate = [NSPredicate predicateWithValue:YES]; NSPredicate *predicate = [NSPredicate predicateWithValue:YES];
XCTAssertEqualObjects(where.predicate, predicate); 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"]; NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K == %@", @"key", @"value"];
XCTAssertEqualObjects(where.predicate, predicate); 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 { - (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 { - (void)test_ThatDataStacks_BridgeCorrectly {
@@ -93,6 +144,9 @@
[CSCoreStore setDefaultStack:dataStack]; [CSCoreStore setDefaultStack:dataStack];
XCTAssertTrue([dataStack isEqual:[CSCoreStore defaultStack]]); XCTAssertTrue([dataStack isEqual:[CSCoreStore defaultStack]]);
}
- (void)test_ThatStorages_BridgeCorrectly {
NSError *memoryError; NSError *memoryError;
CSInMemoryStore *memoryStorage = [CSCoreStore CSInMemoryStore *memoryStorage = [CSCoreStore

View File

@@ -47,16 +47,6 @@ public struct GroupBy: QueryClause, Hashable {
self.init([]) 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 Initializes a `GroupBy` clause with a list of key path strings
@@ -68,6 +58,16 @@ public struct GroupBy: QueryClause, Hashable {
self.init([keyPath] + keyPaths) 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 // MARK: QueryClause

View File

@@ -70,14 +70,9 @@ public enum SortKey {
public struct OrderBy: FetchClause, QueryClause, DeleteClause, Hashable { public struct OrderBy: FetchClause, QueryClause, DeleteClause, Hashable {
/** /**
Initializes a `OrderBy` clause with a list of sort descriptors The list of sort descriptors
- parameter sortDescriptors: a series of `NSSortDescriptor`s
*/ */
public init(_ sortDescriptors: [NSSortDescriptor]) { public let sortDescriptors: [NSSortDescriptor]
self.sortDescriptors = sortDescriptors
}
/** /**
Initializes a `OrderBy` clause with an empty list of sort descriptors 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]) 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 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) self.init([sortKey] + sortKeys)
} }
public let sortDescriptors: [NSSortDescriptor]
// MARK: FetchClause, QueryClause, DeleteClause // MARK: FetchClause, QueryClause, DeleteClause

View File

@@ -44,15 +44,20 @@ import CoreData
*/ */
public struct Tweak: FetchClause, QueryClause, DeleteClause { 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. 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. - 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) { 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. 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 - parameter entityClass: the `NSManagedObject` class type to be created
- returns: a `CSFrom` clause with the specified entity class
*/ */
@objc @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. 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 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 @objc
public static func entityClass(entityClass: AnyClass, configuration: AnyObject) -> CSFrom { public convenience init(entityClass: AnyClass, configuration: AnyObject) {
switch configuration { switch configuration {
case let string as String: case let string as String:
return self.init(From(entityClass, string)) self.init(From(entityClass, string))
case is NSNull: case is NSNull:
return self.init(From(entityClass, nil)) self.init(From(entityClass, nil))
default: default:
CoreStore.abort("The configuration argument only accepts NSString and NSNull values") 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. 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 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. - 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.
- returns: a `CSFrom` clause with the specified configurations
*/ */
@objc @objc
public static func entityClass(entityClass: AnyClass, configurations: [AnyObject]) -> CSFrom { public convenience init(entityClass: AnyClass, configurations: [AnyObject]) {
var arguments = [String?]() var arguments = [String?]()
for configuration in configurations { 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") 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 The list of key path strings to group results with
*/ */
@objc
public var keyPaths: [KeyPath] { public var keyPaths: [KeyPath] {
return self.bridgeToSwift.keyPaths 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 Initializes a `CSGroupBy` clause with a list of key path strings
- parameter keyPaths: a list of key path strings to group results with - parameter keyPaths: a list of key path strings to group results with
- returns: a `CSGroupBy` clause with a list of key path strings
*/ */
@objc @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 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 // MARK: - CSOrderBy
/** /**
@@ -64,27 +38,44 @@ public final class CSSortKey: NSSortDescriptor {
public final class CSOrderBy: NSObject, CSFetchClause, CSQueryClause, CSDeleteClause, CoreStoreObjectiveCType { public final class CSOrderBy: NSObject, CSFetchClause, CSQueryClause, CSDeleteClause, CoreStoreObjectiveCType {
/** /**
Initializes a `CSOrderBy` clause with a list of sort descriptors The list of sort descriptors
- parameter sortDescriptors: a series of `NSSortDescriptor`s
- returns: a `CSOrderBy` clause with a list of sort descriptors
*/ */
@objc @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 Initializes a `CSOrderBy` clause with a single sort descriptor
```
MyPersonEntity *people = [transaction
fetchAllFrom:CSFromCreate([MyPersonEntity class])
fetchClauses:@[CSOrderBySortKey(CSSortAscending(@"fullname"))]]];
```
- parameter sortDescriptor: a `NSSortDescriptor` - parameter sortDescriptor: a `NSSortDescriptor`
- returns: a `CSOrderBy` clause with a single sort descriptor
*/ */
@objc @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 NSString *fullName = [CSCoreStore
queryValueFrom:[CSFrom entityClass:[MyPersonEntity class]] queryValueFrom:[CSFrom entityClass:[MyPersonEntity class]]
select:[CSSelect stringForTerm:[CSSelectTerm attribute:@"fullName"]] select:CSSelectString(CSAttribute(@"fullname"))
fetchClauses:@[[CSWhere keyPath:@"employeeID" isEqualTo: @1111]]]; fetchClauses:@[[CSWhere keyPath:@"employeeID" isEqualTo: @1111]]];
``` ```
- parameter keyPath: the attribute name - 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 - 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 - 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 { public static func average(keyPath: KeyPath, `as` alias: KeyPath?) -> CSSelectTerm {
return self.init(.Average(keyPath, As: alias)) 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 - 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 - returns: a `SelectTerm` to a `Select` clause for a count query
*/ */
@objc
public static func count(keyPath: KeyPath, `as` alias: KeyPath?) -> CSSelectTerm { public static func count(keyPath: KeyPath, `as` alias: KeyPath?) -> CSSelectTerm {
return self.init(.Count(keyPath, As: alias)) 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 - 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 - 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 { public static func maximum(keyPath: KeyPath, `as` alias: KeyPath?) -> CSSelectTerm {
return self.init(.Maximum(keyPath, As: alias)) 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 - 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 - 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 { public static func minimum(keyPath: KeyPath, `as` alias: KeyPath?) -> CSSelectTerm {
return self.init(.Minimum(keyPath, As: alias)) 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 - 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 - 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 { public static func sum(keyPath: KeyPath, `as` alias: KeyPath?) -> CSSelectTerm {
return self.init(.Sum(keyPath, As: alias)) 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 - 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 - 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( return self.init(.ObjectID(As: alias))
alias: alias ?? "objectID",
nativeType: .ObjectIDAttributeType
)
} }
// MARK: NSObject // MARK: NSObject
public override var hash: Int { public override var hash: Int {
@@ -214,100 +216,97 @@ public final class CSSelect: NSObject {
/** /**
Creates a `CSSelect` clause for querying `NSNumber` values. Creates a `CSSelect` clause for querying `NSNumber` values.
``` ```
NSNumber *maximumAge = [CSCoreStore NSNumber *maxAge = [CSCoreStore
queryValueFrom:[CSFrom entityClass:[MyPersonEntity class]] queryValueFrom:CSFromCreate([MyPersonEntity class])
select:[CSSelect numberForTerm:[CSSelectTerm maximum:@"age" as:nil]]]; select:CSSelectNumber(CSAggregateMax(@"age"))
// ...
``` ```
- parameter term: the `CSSelectTerm` specifying the attribute/aggregate value to query - 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. Creates a `CSSelect` clause for querying `NSDecimalNumber` values.
``` ```
NSNumber *averageAge = [CSCoreStore NSDecimalNumber *averagePrice = [CSCoreStore
queryValueFrom:[CSFrom entityClass:[MyPersonEntity class]] queryValueFrom:CSFromCreate([MyPersonEntity class])
select:[CSSelect decimalNumberForTerm:[CSSelectTerm average:@"age" as:nil]]]; select:CSSelectDecimal(CSAggregateAverage(@"price"))
// ...
``` ```
- parameter term: the `CSSelectTerm` specifying the attribute/aggregate value to query - 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. Creates a `CSSelect` clause for querying `NSString` values.
``` ```
NSString *fullName = [CSCoreStore NSString *fullname = [CSCoreStore
queryValueFrom:[CSFrom entityClass:[MyPersonEntity class]] queryValueFrom:CSFromCreate([MyPersonEntity class])
select:[CSSelect stringForTerm:[CSSelectTerm attribute:@"fullName"]] select:CSSelectString(CSAttribute(@"fullname"))
fetchClauses:@[[CSWhere keyPath:@"employeeID" isEqualTo: @1111]]]; // ...
``` ```
- parameter term: the `CSSelectTerm` specifying the attribute/aggregate value to query - 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. Creates a `CSSelect` clause for querying `NSDate` values.
``` ```
NSDate *lastUpdatedDate = [CSCoreStore NSDate *lastUpdate = [CSCoreStore
queryValueFrom:[CSFrom entityClass:[MyPersonEntity class]] queryValueFrom:CSFromCreate([MyPersonEntity class])
select:[CSSelect dateForTerm:[CSSelectTerm maximum:@"updatedDate" as:nil]]]; select:CSSelectDate(CSAggregateMax(@"updatedDate"))
// ...
``` ```
- parameter term: the `CSSelectTerm` specifying the attribute/aggregate value to query - 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. Creates a `CSSelect` clause for querying `NSData` values.
``` ```
NSData *imageData = [CSCoreStore NSData *imageData = [CSCoreStore
queryValueFrom:[CSFrom entityClass:[MyPersonEntity class]] queryValueFrom:CSFromCreate([MyPersonEntity class])
select:[CSSelect dataForTerm:[CSSelectTerm attribute:@"imageData" as:nil]] select:CSSelectData(CSAttribute(@"imageData"))
fetchClauses:@[[CSWhere keyPath:@"employeeID" isEqualTo: @1111]]]; // ...
``` ```
- parameter term: the `CSSelectTerm` specifying the attribute/aggregate value to query - 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. Creates a `CSSelect` clause for querying `NSManagedObjectID` values.
``` ```
NSManagedObjectID *objectIDForOldest = [CSCoreStore NSManagedObjectID *objectID = [CSCoreStore
queryValueFrom:[CSFrom entityClass:[MyPersonEntity class]] queryValueFrom:CSFromCreate([MyPersonEntity class])
select:[CSSelect objectID] select:CSSelectObjectID()
fetchClauses:@[[CSWhere keyPath:@"employeeID" isEqualTo: @1111]]]; // ...
``` ```
- parameter term: the `CSSelectTerm` specifying the attribute/aggregate value to query - 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 { public final class CSTweak: NSObject, CSFetchClause, CSQueryClause, CSDeleteClause, CoreStoreObjectiveCType {
/** /**
Initializes a `CSTweak` clause with a closure where the `NSFetchRequest` may be configured. The block to customize the `NSFetchRequest`
- 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
*/ */
@objc @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 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 - parameter value: the boolean value for the predicate
- returns: a `CSWhere` clause with a predicate that always evaluates to the specified boolean value
*/ */
@objc @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 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 format: the format string for the predicate
- parameter argumentArray: the arguments for `format` - parameter argumentArray: the arguments for `format`
- returns: a `CSWhere` clause with a predicate using the specified string format and arguments
*/ */
@objc @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 keyPath: the keyPath to compare with
- parameter value: the arguments for the `==` operator - parameter value: the arguments for the `==` operator
- returns: a `CSWhere` clause that compares equality
*/ */
@objc @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 keyPath: the keyPath to compare with
- parameter list: the array to check membership of - parameter list: the array to check membership of
- returns: a `CSWhere` clause that compares membership
*/ */
@objc @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` Initializes a `CSWhere` clause with an `NSPredicate`
- parameter predicate: the `NSPredicate` for the fetch or query - parameter predicate: the `NSPredicate` for the fetch or query
- returns: a `CSWhere` clause with an `NSPredicate`
*/ */
@objc @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. // SOFTWARE.
// //
#import <Foundation/Foundation.h>
#ifndef CoreStoreBridge_h #ifndef CoreStoreBridge_h
#define CoreStoreBridge_h #define CoreStoreBridge_h
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#if !__has_feature(objc_arc) #if !__has_feature(objc_arc)
#error CoreStore Objective-C utilities require ARC be enabled #error CoreStore Objective-C utilities require ARC be enabled
#endif #endif
@@ -36,9 +37,10 @@
#error CoreStore Objective-C utilities can only be used on platforms that support C function overloading #error CoreStore Objective-C utilities can only be used on platforms that support C function overloading
#endif #endif
#define CS_OBJC_EXTERN extern #define CS_OBJC_EXTERN extern
#define CS_OBJC_OVERLOADABLE __attribute__((__overloadable__)) #define CS_OBJC_OVERLOADABLE __attribute__((__overloadable__))
#define CS_OBJC_REQUIRES_NIL_TERMINATION(A, B) __attribute__((sentinel(A, B))) #define CS_OBJC_REQUIRES_NIL_TERMINATION __attribute__((sentinel(0, 1)))
#define CS_OBJC_RETURNS_RETAINED __attribute__((ns_returns_retained))
// MARK: - From // MARK: - From
@@ -50,7 +52,8 @@
Initializes a <tt>CSFrom</tt> clause with the specified entity class. Initializes a <tt>CSFrom</tt> clause with the specified entity class.
@code @code
MyPersonEntity *people = [transaction fetchAllFrom:From([MyPersonEntity class])]; MyPersonEntity *people = [transaction fetchAllFrom:
CSFromCreate([MyPersonEntity class])];
@endcode @endcode
@param entityClass @param entityClass
@@ -60,14 +63,58 @@
a <tt>CSFrom</tt> clause with the specified entity class a <tt>CSFrom</tt> clause with the specified entity class
*/ */
CS_OBJC_EXTERN CS_OBJC_OVERLOADABLE 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 @abstract
Initializes a <tt>CSFrom</tt> clause with the specified configurations. Initializes a <tt>CSFrom</tt> clause with the specified configurations.
@code @code
MyPersonEntity *people = [transaction fetchAllFrom:From([MyPersonEntity class], @[@"Configuration1"])]; MyPersonEntity *people = [transaction fetchAllFrom:
CSFromCreate([MyPersonEntity class],
@[[NSNull null], @"Configuration1"])];
@endcode @endcode
@param entityClass @param entityClass
@@ -80,9 +127,134 @@ CSFrom *_Nonnull From(Class _Nonnull entityClass);
a <tt>CSFrom</tt> clause with the specified configurations a <tt>CSFrom</tt> clause with the specified configurations
*/ */
CS_OBJC_EXTERN CS_OBJC_OVERLOADABLE 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 // MARK: - Where
@@ -92,19 +264,31 @@ CSFrom *_Nonnull From(Class _Nonnull entityClass, NSArray<id> *_Nonnull configur
@abstract @abstract
Initializes a <tt>CSWhere</tt> clause with a predicate that always evaluates to the specified boolean value 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 @param value
the boolean value for the predicate the boolean value for the predicate
@result @result
a <tt>CSWhere</tt> clause with a predicate that always evaluates to the specified boolean value a <tt>CSWhere</tt> clause with a predicate that always evaluates to the specified boolean value
*/ */
CS_OBJC_EXTERN CS_OBJC_OVERLOADABLE CS_OBJC_EXTERN
CSWhere *_Nonnull Where(BOOL value); CSWhere *_Nonnull CSWhereValue(BOOL value) CS_OBJC_RETURNS_RETAINED;
/** /**
@abstract @abstract
Initializes a <tt>CSWhere</tt> clause with a predicate using the specified string format and arguments 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 @param format
the format string for the predicate the format string for the predicate
@@ -114,27 +298,160 @@ CSWhere *_Nonnull Where(BOOL value);
@result @result
a <tt>CSWhere</tt> clause with a predicate using the specified string format and arguments a <tt>CSWhere</tt> clause with a predicate using the specified string format and arguments
*/ */
CS_OBJC_EXTERN CS_OBJC_OVERLOADABLE CS_OBJC_EXTERN
CSWhere *_Nonnull Where(NSString *_Nonnull format, ...); CSWhere *_Nonnull CSWhereFormat(NSString *_Nonnull format, ...) CS_OBJC_RETURNS_RETAINED;
/** /**
@abstract @abstract
Initializes a <tt>CSWhere</tt> clause with an <tt>NSPredicate</tt> 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 @param predicate
the <tt>NSPredicate</tt> for the fetch or query the <tt>NSPredicate</tt> for the fetch or query
@result @result
a <tt>CSWhere</tt> clause with an <tt>NSPredicate</tt> 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 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 // MARK: - GroupBy
@class CSGroupBy; @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 @abstract
Initializes a <tt>CSGroupBy</tt> clause with a list of key path strings Initializes a <tt>CSGroupBy</tt> clause with a list of key path strings
@@ -145,8 +462,29 @@ CSWhere *_Nonnull Where(NSPredicate *_Nonnull predicate);
@result @result
a <tt>CSGroupBy</tt> clause with a list of key path strings a <tt>CSGroupBy</tt> clause with a list of key path strings
*/ */
CS_OBJC_OVERLOADABLE CS_OBJC_EXTERN CS_OBJC_OVERLOADABLE
CSGroupBy *_Nonnull GroupBy(NSArray<NSString *> *_Nonnull keyPaths); 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 */ #endif /* CoreStoreBridge_h */

View File

@@ -28,49 +28,171 @@
CS_OBJC_OVERLOADABLE 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 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 // MARK: - Where
CS_OBJC_OVERLOADABLE CSWhere *_Nonnull CSWhereValue(BOOL value) CS_OBJC_RETURNS_RETAINED {
CSWhere *_Nonnull Where(BOOL value) {
return [CSWhere value:value]; return [[CSWhere alloc] initWithValue:value];
} }
CS_OBJC_OVERLOADABLE CSWhere *_Nonnull CSWhereFormat(NSString *_Nonnull format, ...) CS_OBJC_RETURNS_RETAINED {
CSWhere *_Nonnull Where(NSString *_Nonnull format, ...) {
CSWhere *where; CSWhere *where;
va_list args; va_list args;
va_start(args, format); va_start(args, format);
where = [CSWhere predicate:[NSPredicate predicateWithFormat:format arguments:args]]; where = [[CSWhere alloc] initWithPredicate:[NSPredicate predicateWithFormat:format arguments:args]];
va_end(args); va_end(args);
return where; return where;
} }
CS_OBJC_OVERLOADABLE CSWhere *_Nonnull CSWherePredicate(NSPredicate *_Nonnull predicate) CS_OBJC_RETURNS_RETAINED {
CSWhere *_Nonnull Where(NSPredicate *_Nonnull predicate) {
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 // MARK: - GroupBy
CS_OBJC_OVERLOADABLE CSGroupBy *_Nonnull CSGroupByKeyPath(NSString *_Nonnull keyPath) CS_OBJC_RETURNS_RETAINED {
CSGroupBy *_Nonnull GroupBy(NSArray<NSString *> *_Nonnull keyPaths) {
return [[CSGroupBy alloc] initWithKeyPath:keyPath];
return [CSGroupBy keyPaths:keyPaths]; }
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];
} }