From 82887b1dd289c590b8221d914e3d27fd1a91aa67 Mon Sep 17 00:00:00 2001 From: John Rommel Estropia Date: Sat, 25 Jun 2016 13:43:43 +0900 Subject: [PATCH] CSInto unit tests --- CoreStore.xcodeproj/project.pbxproj | 9 + CoreStoreTests/BridgingTests.m | 26 +- Sources/ObjectiveC/CSInto.swift | 35 +- Sources/ObjectiveC/CSOrderBy.swift | 4 +- Sources/ObjectiveC/CoreStoreBridge.h | 461 +++++++++++++++------------ Sources/ObjectiveC/CoreStoreBridge.m | 268 +++++++++------- Sources/Transactions/Into.swift | 13 +- 7 files changed, 479 insertions(+), 337 deletions(-) diff --git a/CoreStore.xcodeproj/project.pbxproj b/CoreStore.xcodeproj/project.pbxproj index 1aaccf4..2fc29e6 100644 --- a/CoreStore.xcodeproj/project.pbxproj +++ b/CoreStore.xcodeproj/project.pbxproj @@ -2753,6 +2753,11 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "USE_FRAMEWORKS=0", + "SWIFT_OBJC_INTERFACE_HEADER_NAME=<$(SWIFT_MODULE_NAME)/$(SWIFT_OBJC_INTERFACE_HEADER_NAME)>", + ); INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 7.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; @@ -2772,6 +2777,10 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREPROCESSOR_DEFINITIONS = ( + "USE_FRAMEWORKS=0", + "SWIFT_OBJC_INTERFACE_HEADER_NAME=<$(SWIFT_MODULE_NAME)/$(SWIFT_OBJC_INTERFACE_HEADER_NAME)>", + ); INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 7.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; diff --git a/CoreStoreTests/BridgingTests.m b/CoreStoreTests/BridgingTests.m index 4369050..5d5f99e 100644 --- a/CoreStoreTests/BridgingTests.m +++ b/CoreStoreTests/BridgingTests.m @@ -94,15 +94,15 @@ - (void)test_ThatOrderByClauses_BridgeCorrectly { { - CSOrderBy *orderBy = CSOrderBySortKey(CSSortAscending(@"key")); + CSOrderBy *orderBy = CSOrderByKey(CSSortAscending(@"key")); XCTAssertEqualObjects(orderBy.sortDescriptors, @[[NSSortDescriptor sortDescriptorWithKey:@"key" ascending:YES]]); } { - CSOrderBy *orderBy = CSOrderBySortKey(CSSortDescending(@"key")); + CSOrderBy *orderBy = CSOrderByKey(CSSortDescending(@"key")); XCTAssertEqualObjects(orderBy.sortDescriptors, @[[NSSortDescriptor sortDescriptorWithKey:@"key" ascending:NO]]); } { - CSOrderBy *orderBy = CSOrderBySortKeys(CSSortAscending(@"key1"), CSSortDescending(@"key2"), nil); + CSOrderBy *orderBy = CSOrderByKeys(CSSortAscending(@"key1"), CSSortDescending(@"key2"), nil); NSArray *sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"key1" ascending:YES], [NSSortDescriptor sortDescriptorWithKey:@"key2" ascending:NO]]; XCTAssertEqualObjects(orderBy.sortDescriptors, sortDescriptors); @@ -125,7 +125,7 @@ - (void)test_ThatTweakClauses_BridgeCorrectly { - CSTweak *tweak = CSTweakCreate(^(NSFetchRequest * _Nonnull fetchRequest) { + CSTweak *tweak = CSTweakRequest(^(NSFetchRequest * _Nonnull fetchRequest) { fetchRequest.fetchLimit = 100; }); @@ -134,6 +134,24 @@ XCTAssertEqual(request.fetchLimit, 100); } +- (void)test_ThatIntoClauses_BridgeCorrectly { + + { + CSInto *into = CSIntoClass([TestEntity1 class]); + XCTAssertEqualObjects(into.entityClass, [TestEntity1 class]); + } + { + CSInto *into = CSIntoClass([TestEntity1 class], [NSNull null]); + XCTAssertEqualObjects(into.entityClass, [TestEntity1 class]); + XCTAssertNil(into.configuration); + } + { + CSInto *into = CSIntoClass([TestEntity1 class], @"Config1"); + XCTAssertEqualObjects(into.entityClass, [TestEntity1 class]); + XCTAssertEqualObjects(into.configuration, @"Config1"); + } +} + - (void)test_ThatDataStacks_BridgeCorrectly { CSDataStack *dataStack = [[CSDataStack alloc] diff --git a/Sources/ObjectiveC/CSInto.swift b/Sources/ObjectiveC/CSInto.swift index f2e10c8..1f65bd7 100644 --- a/Sources/ObjectiveC/CSInto.swift +++ b/Sources/ObjectiveC/CSInto.swift @@ -37,35 +37,54 @@ import CoreData @objc public final class CSInto: NSObject, CoreStoreObjectiveCType { + /** + The associated `NSManagedObject` entity class + */ + @objc + public var entityClass: AnyClass { + + return self.bridgeToSwift.entityClass + } + + /** + The `NSPersistentStore` configuration name to associate objects from. + May contain a `String` to pertain to a named configuration, or `nil` to pertain to the default configuration + */ + @objc + public var configuration: String? { + + return self.bridgeToSwift.configuration + } + /** Initializes a `CSInto` clause with the specified entity class. ``` - MyPersonEntity *person = [transaction createInto:[CSInto entityClass:[MyPersonEntity class]]]; + MyPersonEntity *person = [transaction createInto: + CSIntoClass([MyPersonEntity class])]; ``` - parameter entityClass: the `NSManagedObject` class type to be created - - returns: a `CSInto` clause with the specified entity class */ @objc - public static func entityClass(entityClass: AnyClass) -> CSInto { + public convenience init(entityClass: AnyClass) { - return self.init(Into(entityClass)) + self.init(Into(entityClass)) } /** Initializes a `CSInto` clause with the specified configuration. ``` - MyPersonEntity *person = [transaction createInto:[CSInto entityClass:[MyPersonEntity class]]]; + MyPersonEntity *person = [transaction createInto: + CSIntoClass([MyPersonEntity class])]; ``` - parameter entityClass: the `NSManagedObject` class type to be created - parameter configuration: the `NSPersistentStore` configuration name to associate the object to. This parameter is required if multiple configurations contain the created `NSManagedObject`'s entity type. Set to `nil` to use the default configuration. - - returns: a `CSInto` clause with the specified configuration */ @objc - public static func entityClass(entityClass: AnyClass, configuration: String?) -> CSInto { + public convenience init(entityClass: AnyClass, configuration: String?) { - return self.init(Into(entityClass, configuration)) + self.init(Into(entityClass, configuration)) } diff --git a/Sources/ObjectiveC/CSOrderBy.swift b/Sources/ObjectiveC/CSOrderBy.swift index e28c897..9be4fbc 100644 --- a/Sources/ObjectiveC/CSOrderBy.swift +++ b/Sources/ObjectiveC/CSOrderBy.swift @@ -51,7 +51,7 @@ public final class CSOrderBy: NSObject, CSFetchClause, CSQueryClause, CSDeleteCl ``` MyPersonEntity *people = [transaction fetchAllFrom:CSFromClass([MyPersonEntity class]) - fetchClauses:@[CSOrderBySortKey(CSSortAscending(@"fullname"))]]]; + fetchClauses:@[CSOrderByKey(CSSortAscending(@"fullname"))]]]; ``` - parameter sortDescriptor: a `NSSortDescriptor` @@ -67,7 +67,7 @@ public final class CSOrderBy: NSObject, CSFetchClause, CSQueryClause, CSDeleteCl ``` MyPersonEntity *people = [transaction fetchAllFrom:CSFromClass([MyPersonEntity class]) - fetchClauses:@[CSOrderBySortKeys(CSSortAscending(@"fullname"), CSSortDescending(@"age"), nil))]]]; + fetchClauses:@[CSOrderByKeys(CSSortAscending(@"fullname"), CSSortDescending(@"age"), nil))]]]; ``` - parameter sortDescriptors: an array of `NSSortDescriptor`s diff --git a/Sources/ObjectiveC/CoreStoreBridge.h b/Sources/ObjectiveC/CoreStoreBridge.h index 98bfa81..1105a00 100644 --- a/Sources/ObjectiveC/CoreStoreBridge.h +++ b/Sources/ObjectiveC/CoreStoreBridge.h @@ -37,13 +37,13 @@ #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 __attribute__((sentinel(0, 1))) -#define CS_OBJC_RETURNS_RETAINED __attribute__((ns_returns_retained)) +#define CORESTORE_EXTERN extern +#define CORESTORE_OVERLOADABLE __attribute__((__overloadable__)) +#define CORESTORE_REQUIRES_NIL_TERMINATION __attribute__((sentinel(0, 1))) +#define CORESTORE_RETURNS_RETAINED __attribute__((ns_returns_retained)) -// MARK: - From +// MARK: - CSFrom @class CSFrom; @@ -62,8 +62,8 @@ @result a CSFrom clause with the specified entity class */ -CS_OBJC_EXTERN CS_OBJC_OVERLOADABLE -CSFrom *_Nonnull CSFromClass(Class _Nonnull entityClass) CS_OBJC_RETURNS_RETAINED; +CORESTORE_EXTERN CORESTORE_OVERLOADABLE +CSFrom *_Nonnull CSFromClass(Class _Nonnull entityClass) CORESTORE_RETURNS_RETAINED; /** @abstract @@ -83,8 +83,8 @@ CSFrom *_Nonnull CSFromClass(Class _Nonnull entityClass) CS_OBJC_RETURNS_RETAINE @result a CSFrom clause with the specified configuration */ -CS_OBJC_EXTERN CS_OBJC_OVERLOADABLE -CSFrom *_Nonnull CSFromClass(Class _Nonnull entityClass, NSNull *_Nonnull configuration) CS_OBJC_RETURNS_RETAINED; +CORESTORE_EXTERN CORESTORE_OVERLOADABLE +CSFrom *_Nonnull CSFromClass(Class _Nonnull entityClass, NSNull *_Nonnull configuration) CORESTORE_RETURNS_RETAINED; /** @abstract @@ -104,8 +104,8 @@ CSFrom *_Nonnull CSFromClass(Class _Nonnull entityClass, NSNull *_Nonnull config @result a CSFrom clause with the specified configuration */ -CS_OBJC_EXTERN CS_OBJC_OVERLOADABLE -CSFrom *_Nonnull CSFromClass(Class _Nonnull entityClass, NSString *_Nonnull configuration) CS_OBJC_RETURNS_RETAINED; +CORESTORE_EXTERN CORESTORE_OVERLOADABLE +CSFrom *_Nonnull CSFromClass(Class _Nonnull entityClass, NSString *_Nonnull configuration) CORESTORE_RETURNS_RETAINED; /** @abstract @@ -126,11 +126,220 @@ CSFrom *_Nonnull CSFromClass(Class _Nonnull entityClass, NSString *_Nonnull conf @result a CSFrom clause with the specified configurations */ -CS_OBJC_EXTERN CS_OBJC_OVERLOADABLE -CSFrom *_Nonnull CSFromClass(Class _Nonnull entityClass, NSArray *_Nonnull configurations) CS_OBJC_RETURNS_RETAINED; +CORESTORE_EXTERN CORESTORE_OVERLOADABLE +CSFrom *_Nonnull CSFromClass(Class _Nonnull entityClass, NSArray *_Nonnull configurations) CORESTORE_RETURNS_RETAINED; -// MARK: - Select +// MARK: - CSGroupBy + +@class CSGroupBy; + +/** + @abstract + Initializes a CSGroupBy clause with a key path string + + @param keyPaths + a key path string to group results with + + @result + a CSGroupBy clause with a key path string + */ +CORESTORE_EXTERN +CSGroupBy *_Nonnull CSGroupByKeyPath(NSString *_Nonnull keyPath) CORESTORE_RETURNS_RETAINED; + +/** + @abstract + Initializes a CSGroupBy clause with a list of key path strings + + @param keyPaths + a nil-terminated list of key path strings to group results with + + @result + a CSGroupBy clause with a list of key path strings + */ +CORESTORE_EXTERN CORESTORE_OVERLOADABLE +CSGroupBy *_Nonnull CSGroupByKeyPaths(NSString *_Nonnull keyPath, ...) CORESTORE_RETURNS_RETAINED; + +/** + @abstract + Initializes a CSGroupBy clause with a list of key path strings + + @param keyPaths + a list of key path strings to group results with + + @result + a CSGroupBy clause with a list of key path strings + */ +CORESTORE_EXTERN CORESTORE_OVERLOADABLE +CSGroupBy *_Nonnull CSGroupByKeyPaths(NSArray *_Nonnull keyPaths) CORESTORE_RETURNS_RETAINED; + + +// MARK: - CSInto + +@class CSInto; + +/** + @abstract + Initializes a CSInto clause with the specified entity class. + + @code + MyPersonEntity *people = [transaction createInto: + CSIntoClass([MyPersonEntity class])]; + @endcode + + @param entityClass + the NSManagedObject class type to be created + + @result + a CSInto clause with the specified entity class + */ +CORESTORE_EXTERN CORESTORE_OVERLOADABLE +CSInto *_Nonnull CSIntoClass(Class _Nonnull entityClass) CORESTORE_RETURNS_RETAINED; + +/** + @abstract + Initializes a CSInto clause with the specified entity class. + + @code + MyPersonEntity *people = [transaction createInto: + CSIntoClass([MyPersonEntity class], [NSNull null])]; + @endcode + + @param entityClass + the NSManagedObject class type to be created + + @param configuration + an 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. + + @result + a CSInto clause with the specified entity class + */ +CORESTORE_OVERLOADABLE +CSInto *_Nonnull CSIntoClass(Class _Nonnull entityClass, NSNull *_Nonnull configuration) CORESTORE_RETURNS_RETAINED; + +/** + @abstract + Initializes a CSInto clause with the specified entity class. + + @code + MyPersonEntity *people = [transaction createInto: + CSIntoClass([MyPersonEntity class], @"Configuration1")]; + @endcode + + @param entityClass + the NSManagedObject class type to be created + + @param configuration + an 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. + + @result + a CSInto clause with the specified entity class + */ +CORESTORE_OVERLOADABLE +CSInto *_Nonnull CSIntoClass(Class _Nonnull entityClass, NSString *_Nonnull configuration) CORESTORE_RETURNS_RETAINED; + + +// MARK: - CSOrderBy + +@class CSOrderBy; + +/** + @abstract + Syntax sugar for initializing an ascending NSSortDescriptor for use with CSOrderBy + + @code + MyPersonEntity *people = [CSCoreStore + fetchAllFrom:CSFromClass([MyPersonEntity class]) + fetchClauses:@[CSOrderByKey(CSSortAscending(@"fullname"))]]]; + @endcode + + @param key + the attribute key to sort with + + @result + an NSSortDescriptor for use with CSOrderBy + */ +CORESTORE_EXTERN +NSSortDescriptor *_Nonnull CSSortAscending(NSString *_Nonnull key) CORESTORE_RETURNS_RETAINED; + +/** + @abstract + Syntax sugar for initializing a descending NSSortDescriptor for use with CSOrderBy + + @code + MyPersonEntity *people = [CSCoreStore + fetchAllFrom:CSFromClass([MyPersonEntity class]) + fetchClauses:@[CSOrderByKey(CSSortDescending(@"fullname"))]]]; + @endcode + + @param key + the attribute key to sort with + + @result + an NSSortDescriptor for use with CSOrderBy + */ +CORESTORE_EXTERN +NSSortDescriptor *_Nonnull CSSortDescending(NSString *_Nonnull key) CORESTORE_RETURNS_RETAINED; + +/** + @abstract + Initializes a CSOrderBy clause with a single sort descriptor + + @code + MyPersonEntity *people = [transaction + fetchAllFrom:CSFromClass([MyPersonEntity class]) + fetchClauses:@[CSOrderByKey(CSSortAscending(@"fullname"))]]]; + @endcode + + @param sortDescriptor + an NSSortDescriptor + + @result + a CSOrderBy clause with a single sort descriptor + */ +CORESTORE_EXTERN +CSOrderBy *_Nonnull CSOrderByKey(NSSortDescriptor *_Nonnull sortDescriptor) CORESTORE_RETURNS_RETAINED; + +/** + @abstract + Initializes a CSOrderBy clause with a list of sort descriptors + + @code + MyPersonEntity *people = [transaction + fetchAllFrom:CSFromClass([MyPersonEntity class]) + fetchClauses:@[CSOrderByKeys(CSSortAscending(@"fullname"), CSSortDescending(@"age"), nil))]]]; + @endcode + + @param sortDescriptors + a nil-terminated array of NSSortDescriptors + + @result + a CSOrderBy clause with a list of sort descriptors + */ +CORESTORE_EXTERN CORESTORE_OVERLOADABLE +CSOrderBy *_Nonnull CSOrderByKeys(NSSortDescriptor *_Nonnull sortDescriptor, ...) CORESTORE_RETURNS_RETAINED CORESTORE_REQUIRES_NIL_TERMINATION; + +/** + @abstract + Initializes a CSOrderBy clause with a list of sort descriptors + + @code + MyPersonEntity *people = [transaction + fetchAllFrom:CSFromClass([MyPersonEntity class]) + fetchClauses:@[CSOrderByKeys(@[CSSortAscending(@"fullname"), CSSortDescending(@"age")]))]]]; + @endcode + + @param sortDescriptors + an array of NSSortDescriptors + + @result + a CSOrderBy clause with a list of sort descriptors + */ +CORESTORE_EXTERN CORESTORE_OVERLOADABLE +CSOrderBy *_Nonnull CSOrderByKeys(NSArray *_Nonnull sortDescriptors) CORESTORE_RETURNS_RETAINED; + + +// MARK: - CSSelect @class CSSelect; @class CSSelectTerm; @@ -152,8 +361,8 @@ CSFrom *_Nonnull CSFromClass(Class _Nonnull entityClass, NSArray *_Nonnull c @result a CSSelect clause for querying an NSNumber value */ -CS_OBJC_EXTERN -CSSelect *_Nonnull CSSelectNumber(CSSelectTerm *_Nonnull selectTerm) CS_OBJC_RETURNS_RETAINED; +CORESTORE_EXTERN +CSSelect *_Nonnull CSSelectNumber(CSSelectTerm *_Nonnull selectTerm) CORESTORE_RETURNS_RETAINED; /** @abstract @@ -172,8 +381,8 @@ CSSelect *_Nonnull CSSelectNumber(CSSelectTerm *_Nonnull selectTerm) CS_OBJC_RET @result a CSSelect clause for querying an NSDecimalNumber value */ -CS_OBJC_EXTERN -CSSelect *_Nonnull CSSelectDecimal(CSSelectTerm *_Nonnull selectTerm) CS_OBJC_RETURNS_RETAINED; +CORESTORE_EXTERN +CSSelect *_Nonnull CSSelectDecimal(CSSelectTerm *_Nonnull selectTerm) CORESTORE_RETURNS_RETAINED; /** @abstract @@ -192,8 +401,8 @@ CSSelect *_Nonnull CSSelectDecimal(CSSelectTerm *_Nonnull selectTerm) CS_OBJC_RE @result a CSSelect clause for querying an NSString value */ -CS_OBJC_EXTERN -CSSelect *_Nonnull CSSelectString(CSSelectTerm *_Nonnull selectTerm) CS_OBJC_RETURNS_RETAINED; +CORESTORE_EXTERN +CSSelect *_Nonnull CSSelectString(CSSelectTerm *_Nonnull selectTerm) CORESTORE_RETURNS_RETAINED; /** @abstract @@ -212,8 +421,8 @@ CSSelect *_Nonnull CSSelectString(CSSelectTerm *_Nonnull selectTerm) CS_OBJC_RET @result a CSSelect clause for querying an NSDate value */ -CS_OBJC_EXTERN -CSSelect *_Nonnull CSSelectDate(CSSelectTerm *_Nonnull selectTerm) CS_OBJC_RETURNS_RETAINED; +CORESTORE_EXTERN +CSSelect *_Nonnull CSSelectDate(CSSelectTerm *_Nonnull selectTerm) CORESTORE_RETURNS_RETAINED; /** @abstract @@ -232,8 +441,8 @@ CSSelect *_Nonnull CSSelectDate(CSSelectTerm *_Nonnull selectTerm) CS_OBJC_RETUR @result a CSSelect clause for querying an NSData value */ -CS_OBJC_EXTERN -CSSelect *_Nonnull CSSelectData(CSSelectTerm *_Nonnull selectTerm) CS_OBJC_RETURNS_RETAINED; +CORESTORE_EXTERN +CSSelect *_Nonnull CSSelectData(CSSelectTerm *_Nonnull selectTerm) CORESTORE_RETURNS_RETAINED; /** @abstract @@ -252,11 +461,32 @@ CSSelect *_Nonnull CSSelectData(CSSelectTerm *_Nonnull selectTerm) CS_OBJC_RETUR @result a CSSelect clause for querying an NSManagedObjectID value */ -CS_OBJC_EXTERN -CSSelect *_Nonnull CSSelectObjectID() CS_OBJC_RETURNS_RETAINED; +CORESTORE_EXTERN +CSSelect *_Nonnull CSSelectObjectID() CORESTORE_RETURNS_RETAINED; -// MARK: - Where +// MARK: - CSTweak + +@class CSTweak; + +/** + @abstract + Initializes a CSTweak clause with a block 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 CSListMonitors) may keep CSFetchClauses in memory and may thus introduce retain cycles if reference captures are not handled properly. + + @param block + the block to customize the NSFetchRequest + + @result + a CSTweak clause with the NSFetchRequest configuration block + */ +CORESTORE_EXTERN CORESTORE_OVERLOADABLE +CSTweak *_Nonnull CSTweakRequest(void (^_Nonnull block)(NSFetchRequest *_Nonnull fetchRequest)) CORESTORE_RETURNS_RETAINED; + + +// MARK: - CSWhere @class CSWhere; @@ -276,8 +506,8 @@ CSSelect *_Nonnull CSSelectObjectID() CS_OBJC_RETURNS_RETAINED; @result a CSWhere clause with a predicate that always evaluates to the specified boolean value */ -CS_OBJC_EXTERN -CSWhere *_Nonnull CSWhereValue(BOOL value) CS_OBJC_RETURNS_RETAINED; +CORESTORE_EXTERN +CSWhere *_Nonnull CSWhereValue(BOOL value) CORESTORE_RETURNS_RETAINED; /** @abstract @@ -298,8 +528,8 @@ CSWhere *_Nonnull CSWhereValue(BOOL value) CS_OBJC_RETURNS_RETAINED; @result a CSWhere clause with a predicate using the specified string format and arguments */ -CS_OBJC_EXTERN -CSWhere *_Nonnull CSWhereFormat(NSString *_Nonnull format, ...) CS_OBJC_RETURNS_RETAINED; +CORESTORE_EXTERN +CSWhere *_Nonnull CSWhereFormat(NSString *_Nonnull format, ...) CORESTORE_RETURNS_RETAINED; /** @abstract @@ -318,173 +548,8 @@ CSWhere *_Nonnull CSWhereFormat(NSString *_Nonnull format, ...) CS_OBJC_RETURNS_ @result a CSWhere clause with an NSPredicate */ -CS_OBJC_EXTERN -CSWhere *_Nonnull CSWherePredicate(NSPredicate *_Nonnull predicate) CS_OBJC_RETURNS_RETAINED; - - -// MARK: - OrderBy - -@class CSOrderBy; - -/** - @abstract - Syntax sugar for initializing an ascending NSSortDescriptor for use with CSOrderBy - - @code - MyPersonEntity *people = [CSCoreStore - fetchAllFrom:CSFromClass([MyPersonEntity class]) - fetchClauses:@[CSOrderBySortKey(CSSortAscending(@"fullname"))]]]; - @endcode - - @param key - the attribute key to sort with - - @result - an NSSortDescriptor for use with CSOrderBy - */ -CS_OBJC_EXTERN -NSSortDescriptor *_Nonnull CSSortAscending(NSString *_Nonnull key) CS_OBJC_RETURNS_RETAINED; - -/** - @abstract - Syntax sugar for initializing a descending NSSortDescriptor for use with CSOrderBy - - @code - MyPersonEntity *people = [CSCoreStore - fetchAllFrom:CSFromClass([MyPersonEntity class]) - fetchClauses:@[CSOrderBySortKey(CSSortDescending(@"fullname"))]]]; - @endcode - - @param key - the attribute key to sort with - - @result - an NSSortDescriptor for use with CSOrderBy - */ -CS_OBJC_EXTERN -NSSortDescriptor *_Nonnull CSSortDescending(NSString *_Nonnull key) CS_OBJC_RETURNS_RETAINED; - -/** - @abstract - Initializes a CSOrderBy clause with a single sort descriptor - - @code - MyPersonEntity *people = [transaction - fetchAllFrom:CSFromClass([MyPersonEntity class]) - fetchClauses:@[CSOrderBySortKey(CSSortAscending(@"fullname"))]]]; - @endcode - - @param sortDescriptor - an NSSortDescriptor - - @result - a CSOrderBy clause with a single sort descriptor - */ -CS_OBJC_EXTERN -CSOrderBy *_Nonnull CSOrderBySortKey(NSSortDescriptor *_Nonnull sortDescriptor) CS_OBJC_RETURNS_RETAINED; - -/** - @abstract - Initializes a CSOrderBy clause with a list of sort descriptors - - @code - MyPersonEntity *people = [transaction - fetchAllFrom:CSFromClass([MyPersonEntity class]) - fetchClauses:@[CSOrderBySortKeys(CSSortAscending(@"fullname"), CSSortDescending(@"age"), nil))]]]; - @endcode - - @param sortDescriptors - a nil-terminated array of NSSortDescriptors - - @result - a CSOrderBy clause with a list of sort descriptors - */ -CS_OBJC_EXTERN CS_OBJC_OVERLOADABLE -CSOrderBy *_Nonnull CSOrderBySortKeys(NSSortDescriptor *_Nonnull sortDescriptor, ...) CS_OBJC_RETURNS_RETAINED CS_OBJC_REQUIRES_NIL_TERMINATION; - -/** - @abstract - Initializes a CSOrderBy clause with a list of sort descriptors - - @code - MyPersonEntity *people = [transaction - fetchAllFrom:CSFromClass([MyPersonEntity class]) - fetchClauses:@[CSOrderBySortKeys(@[CSSortAscending(@"fullname"), CSSortDescending(@"age")]))]]]; - @endcode - - @param sortDescriptors - an array of NSSortDescriptors - - @result - a CSOrderBy clause with a list of sort descriptors - */ -CS_OBJC_EXTERN CS_OBJC_OVERLOADABLE -CSOrderBy *_Nonnull CSOrderBySortKeys(NSArray *_Nonnull sortDescriptors) CS_OBJC_RETURNS_RETAINED; - - -// MARK: - GroupBy - -@class CSGroupBy; - -/** - @abstract - Initializes a CSGroupBy clause with a key path string - - @param keyPaths - a key path string to group results with - - @result - a CSGroupBy clause with a key path string - */ -CS_OBJC_EXTERN -CSGroupBy *_Nonnull CSGroupByKeyPath(NSString *_Nonnull keyPath) CS_OBJC_RETURNS_RETAINED; - -/** - @abstract - Initializes a CSGroupBy clause with a list of key path strings - - @param keyPaths - a nil-terminated list of key path strings to group results with - - @result - a CSGroupBy 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 CSGroupBy clause with a list of key path strings - - @param keyPaths - a list of key path strings to group results with - - @result - a CSGroupBy clause with a list of key path strings - */ -CS_OBJC_EXTERN CS_OBJC_OVERLOADABLE -CSGroupBy *_Nonnull CSGroupByKeyPaths(NSArray *_Nonnull keyPaths) CS_OBJC_RETURNS_RETAINED; - - -// MARK: - Tweak - -@class CSTweak; - -/** - @abstract - Initializes a CSTweak clause with a block 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 CSListMonitors) may keep CSFetchClauses in memory and may thus introduce retain cycles if reference captures are not handled properly. - - @param block - the block to customize the NSFetchRequest - - @result - a CSTweak clause with the NSFetchRequest configuration block - */ -CS_OBJC_EXTERN CS_OBJC_OVERLOADABLE -CSTweak *_Nonnull CSTweakCreate(void (^_Nonnull block)(NSFetchRequest *_Nonnull fetchRequest)) CS_OBJC_RETURNS_RETAINED; +CORESTORE_EXTERN +CSWhere *_Nonnull CSWherePredicate(NSPredicate *_Nonnull predicate) CORESTORE_RETURNS_RETAINED; #endif /* CoreStoreBridge_h */ diff --git a/Sources/ObjectiveC/CoreStoreBridge.m b/Sources/ObjectiveC/CoreStoreBridge.m index 617397e..93d3f0c 100644 --- a/Sources/ObjectiveC/CoreStoreBridge.m +++ b/Sources/ObjectiveC/CoreStoreBridge.m @@ -23,6 +23,7 @@ // SOFTWARE. // + #import "CoreStoreBridge.h" #if USE_FRAMEWORKS @@ -31,6 +32,9 @@ #elif !defined(SWIFT_OBJC_INTERFACE_HEADER_NAME) #error Add "SWIFT_OBJC_INTERFACE_HEADER_NAME=$(SWIFT_OBJC_INTERFACE_HEADER_NAME)" to the project's GCC_PREPROCESSOR_DEFINITIONS settings +#elif __has_include(SWIFT_OBJC_INTERFACE_HEADER_NAME) +#import SWIFT_OBJC_INTERFACE_HEADER_NAME + #else #define _STRINGIFY(x) #x #define STRINGIFY(x) _STRINGIFY(x) @@ -39,145 +43,42 @@ #endif -CS_OBJC_OVERLOADABLE -CSFrom *_Nonnull CSFromClass(Class _Nonnull entityClass) CS_OBJC_RETURNS_RETAINED { +// MARK: - CSFrom + +CORESTORE_OVERLOADABLE +CSFrom *_Nonnull CSFromClass(Class _Nonnull entityClass) CORESTORE_RETURNS_RETAINED { return [[CSFrom alloc] initWithEntityClass:entityClass]; } -CS_OBJC_OVERLOADABLE -CSFrom *_Nonnull CSFromClass(Class _Nonnull entityClass, NSNull *_Nonnull configuration) CS_OBJC_RETURNS_RETAINED { +CORESTORE_OVERLOADABLE +CSFrom *_Nonnull CSFromClass(Class _Nonnull entityClass, NSNull *_Nonnull configuration) CORESTORE_RETURNS_RETAINED { return [[CSFrom alloc] initWithEntityClass:entityClass configuration:configuration]; } -CS_OBJC_OVERLOADABLE -CSFrom *_Nonnull CSFromClass(Class _Nonnull entityClass, NSString *_Nonnull configuration) CS_OBJC_RETURNS_RETAINED { +CORESTORE_OVERLOADABLE +CSFrom *_Nonnull CSFromClass(Class _Nonnull entityClass, NSString *_Nonnull configuration) CORESTORE_RETURNS_RETAINED { return [[CSFrom alloc] initWithEntityClass:entityClass configuration:configuration]; } -CS_OBJC_OVERLOADABLE -CSFrom *_Nonnull CSFromClass(Class _Nonnull entityClass, NSArray *_Nonnull configurations) CS_OBJC_RETURNS_RETAINED { +CORESTORE_OVERLOADABLE +CSFrom *_Nonnull CSFromClass(Class _Nonnull entityClass, NSArray *_Nonnull configurations) CORESTORE_RETURNS_RETAINED { return [[CSFrom alloc] initWithEntityClass:entityClass configurations:configurations]; } -// MARK: - Select +// MARK: - CSGroupBy -//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 - -CSWhere *_Nonnull CSWhereValue(BOOL value) CS_OBJC_RETURNS_RETAINED { - - return [[CSWhere alloc] initWithValue:value]; -} - -CSWhere *_Nonnull CSWhereFormat(NSString *_Nonnull format, ...) CS_OBJC_RETURNS_RETAINED { - - CSWhere *where; - va_list args; - va_start(args, format); - where = [[CSWhere alloc] initWithPredicate:[NSPredicate predicateWithFormat:format arguments:args]]; - va_end(args); - return where; -} - -CSWhere *_Nonnull CSWherePredicate(NSPredicate *_Nonnull predicate) CS_OBJC_RETURNS_RETAINED { - - 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 *_Nonnull sortDescriptors) CS_OBJC_RETURNS_RETAINED { - - return [[CSOrderBy alloc] initWithSortDescriptors:sortDescriptors]; -} - - -// MARK: - GroupBy - -CSGroupBy *_Nonnull CSGroupByKeyPath(NSString *_Nonnull keyPath) CS_OBJC_RETURNS_RETAINED { +CSGroupBy *_Nonnull CSGroupByKeyPath(NSString *_Nonnull keyPath) CORESTORE_RETURNS_RETAINED { return [[CSGroupBy alloc] initWithKeyPath:keyPath]; } -CS_OBJC_OVERLOADABLE -CSGroupBy *_Nonnull CSGroupByKeyPaths(NSString *_Nonnull keyPath, ...) CS_OBJC_RETURNS_RETAINED { +CORESTORE_OVERLOADABLE +CSGroupBy *_Nonnull CSGroupByKeyPaths(NSString *_Nonnull keyPath, ...) CORESTORE_RETURNS_RETAINED { va_list args; va_start(args, keyPath); @@ -194,17 +95,138 @@ CSGroupBy *_Nonnull CSGroupByKeyPaths(NSString *_Nonnull keyPath, ...) CS_OBJC_R return [[CSGroupBy alloc] initWithKeyPaths:keyPaths]; } -CS_OBJC_OVERLOADABLE -CSGroupBy *_Nonnull CSGroupByKeyPaths(NSArray *_Nonnull keyPaths) CS_OBJC_RETURNS_RETAINED { - +CORESTORE_OVERLOADABLE +CSGroupBy *_Nonnull CSGroupByKeyPaths(NSArray *_Nonnull keyPaths) CORESTORE_RETURNS_RETAINED { + return [[CSGroupBy alloc] initWithKeyPaths:keyPaths]; } -// MARK: - Tweak +// MARK: - CSInto -CS_OBJC_OVERLOADABLE -CSTweak *_Nonnull CSTweakCreate(void (^_Nonnull block)(NSFetchRequest *_Nonnull fetchRequest)) CS_OBJC_RETURNS_RETAINED { +CORESTORE_OVERLOADABLE +CSInto *_Nonnull CSIntoClass(Class _Nonnull entityClass) CORESTORE_RETURNS_RETAINED { + + return [[CSInto alloc] initWithEntityClass:entityClass]; +} + +CORESTORE_OVERLOADABLE +CSInto *_Nonnull CSIntoClass(Class _Nonnull entityClass, NSNull *_Nonnull configuration) CORESTORE_RETURNS_RETAINED { + + return [[CSInto alloc] initWithEntityClass:entityClass configuration:nil]; +} + +CORESTORE_OVERLOADABLE +CSInto *_Nonnull CSIntoClass(Class _Nonnull entityClass, NSString *_Nonnull configuration) CORESTORE_RETURNS_RETAINED { + + return [[CSInto alloc] initWithEntityClass:entityClass configuration:configuration]; +} + + +// MARK: - CSOrderBy + +@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 CSOrderByKey(NSSortDescriptor *_Nonnull sortDescriptor) CORESTORE_RETURNS_RETAINED { + + return [[CSOrderBy alloc] initWithSortDescriptor:sortDescriptor]; +} + +CORESTORE_OVERLOADABLE +CSOrderBy *_Nonnull CSOrderByKeys(NSSortDescriptor *_Nonnull sortDescriptor, ...) CORESTORE_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]; +} + +CORESTORE_OVERLOADABLE +CSOrderBy *_Nonnull CSOrderByKeys(NSArray *_Nonnull sortDescriptors) CORESTORE_RETURNS_RETAINED { + + return [[CSOrderBy alloc] initWithSortDescriptors:sortDescriptors]; +} + + +// MARK: - CSSelect + +CSSelect *_Nonnull CSSelectNumber(CSSelectTerm *_Nonnull selectTerm) CORESTORE_RETURNS_RETAINED { + + return [[CSSelect alloc] initWithNumberTerm:selectTerm]; +} + +CSSelect *_Nonnull CSSelectDecimal(CSSelectTerm *_Nonnull selectTerm) CORESTORE_RETURNS_RETAINED { + + return [[CSSelect alloc] initWithDecimalTerm:selectTerm]; +} + +CSSelect *_Nonnull CSSelectString(CSSelectTerm *_Nonnull selectTerm) CORESTORE_RETURNS_RETAINED { + + return [[CSSelect alloc] initWithStringTerm:selectTerm]; +} + +CSSelect *_Nonnull CSSelectDate(CSSelectTerm *_Nonnull selectTerm) CORESTORE_RETURNS_RETAINED { + + return [[CSSelect alloc] initWithDateTerm:selectTerm]; +} + +CSSelect *_Nonnull CSSelectData(CSSelectTerm *_Nonnull selectTerm) CORESTORE_RETURNS_RETAINED { + + return [[CSSelect alloc] initWithDataTerm:selectTerm]; +} + +CSSelect *_Nonnull CSSelectObjectID() CORESTORE_RETURNS_RETAINED { + + return [[CSSelect alloc] initWithObjectIDTerm]; +} + + +// MARK: - CSTweak + +CORESTORE_OVERLOADABLE +CSTweak *_Nonnull CSTweakRequest(void (^_Nonnull block)(NSFetchRequest *_Nonnull fetchRequest)) CORESTORE_RETURNS_RETAINED { return [[CSTweak alloc] initWithBlock:block]; } + + +// MARK: - CSWhere + +CSWhere *_Nonnull CSWhereValue(BOOL value) CORESTORE_RETURNS_RETAINED { + + return [[CSWhere alloc] initWithValue:value]; +} + +CSWhere *_Nonnull CSWhereFormat(NSString *_Nonnull format, ...) CORESTORE_RETURNS_RETAINED { + + CSWhere *where; + va_list args; + va_start(args, format); + where = [[CSWhere alloc] initWithPredicate:[NSPredicate predicateWithFormat:format arguments:args]]; + va_end(args); + return where; +} + +CSWhere *_Nonnull CSWherePredicate(NSPredicate *_Nonnull predicate) CORESTORE_RETURNS_RETAINED { + + return [[CSWhere alloc] initWithPredicate:predicate]; +} diff --git a/Sources/Transactions/Into.swift b/Sources/Transactions/Into.swift index 18ba958..90eaa2c 100644 --- a/Sources/Transactions/Into.swift +++ b/Sources/Transactions/Into.swift @@ -41,6 +41,17 @@ import CoreData */ public struct Into: Hashable { + /** + The associated `NSManagedObject` entity class + */ + public let entityClass: AnyClass + + /** + The `NSPersistentStore` configuration name to associate objects from. + May contain a `String` to pertain to a named configuration, or `nil` to pertain to the default configuration + */ + public let configuration: String? + /** Initializes an `Into` clause. ``` @@ -145,8 +156,6 @@ public struct Into: Hashable { return "PF_DEFAULT_CONFIGURATION_NAME" } - internal let entityClass: AnyClass - internal let configuration: String? internal let inferStoreIfPossible: Bool internal func upcast() -> Into {