mirror of
https://github.com/JohnEstropia/CoreStore.git
synced 2026-01-16 05:56:50 +01:00
WIP: objc utilities
This commit is contained in:
@@ -207,6 +207,11 @@
|
||||
B52DD1C91BE1F94600949AFE /* NSManagedObjectContext+Transaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F331AFF85470064E85B /* NSManagedObjectContext+Transaction.swift */; };
|
||||
B52DD1CA1BE1F94600949AFE /* NSManagedObjectModel+Setup.swift in Sources */ = {isa = PBXBuildFile; fileRef = B51BE0691B47FC4B0069F532 /* NSManagedObjectModel+Setup.swift */; };
|
||||
B52DD1CB1BE1F94600949AFE /* WeakObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F2D1AFF849C0064E85B /* WeakObject.swift */; };
|
||||
B538BA761D15B3E30003A766 /* CoreStoreBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = B538BA701D15B3E30003A766 /* CoreStoreBridge.m */; };
|
||||
B538BA771D15B3E30003A766 /* CoreStoreBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = B538BA701D15B3E30003A766 /* CoreStoreBridge.m */; };
|
||||
B538BA781D15B3E30003A766 /* CoreStoreBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = B538BA701D15B3E30003A766 /* CoreStoreBridge.m */; };
|
||||
B538BA791D15B3E30003A766 /* CoreStoreBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = B538BA701D15B3E30003A766 /* CoreStoreBridge.m */; };
|
||||
B538BA7A1D15B3E30003A766 /* CoreStoreBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = B538BA701D15B3E30003A766 /* CoreStoreBridge.m */; };
|
||||
B53FB9FE1CAB2D2F00F0D40A /* CSMigrationResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53FB9FD1CAB2D2F00F0D40A /* CSMigrationResult.swift */; };
|
||||
B53FB9FF1CAB2D2F00F0D40A /* CSMigrationResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53FB9FD1CAB2D2F00F0D40A /* CSMigrationResult.swift */; };
|
||||
B53FBA001CAB2D2F00F0D40A /* CSMigrationResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53FB9FD1CAB2D2F00F0D40A /* CSMigrationResult.swift */; };
|
||||
@@ -283,6 +288,11 @@
|
||||
B5519A601CA21954002BEF78 /* CSAsynchronousDataTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5519A5E1CA21954002BEF78 /* CSAsynchronousDataTransaction.swift */; };
|
||||
B5519A611CA21954002BEF78 /* CSAsynchronousDataTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5519A5E1CA21954002BEF78 /* CSAsynchronousDataTransaction.swift */; };
|
||||
B5519A621CA21954002BEF78 /* CSAsynchronousDataTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5519A5E1CA21954002BEF78 /* CSAsynchronousDataTransaction.swift */; };
|
||||
B55717431D15B09D009BDBCA /* CoreStoreBridge.h in Headers */ = {isa = PBXBuildFile; fileRef = B55717421D15AF9C009BDBCA /* CoreStoreBridge.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
B55717441D15B09E009BDBCA /* CoreStoreBridge.h in Headers */ = {isa = PBXBuildFile; fileRef = B55717421D15AF9C009BDBCA /* CoreStoreBridge.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
B55717451D15B09F009BDBCA /* CoreStoreBridge.h in Headers */ = {isa = PBXBuildFile; fileRef = B55717421D15AF9C009BDBCA /* CoreStoreBridge.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
B55717461D15B0A1009BDBCA /* CoreStoreBridge.h in Headers */ = {isa = PBXBuildFile; fileRef = B55717421D15AF9C009BDBCA /* CoreStoreBridge.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
B55717471D15B0A1009BDBCA /* CoreStoreBridge.h in Headers */ = {isa = PBXBuildFile; fileRef = B55717421D15AF9C009BDBCA /* CoreStoreBridge.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
B5598BCC1BE2093D0092EFCE /* Model.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = B5D372821A39CD6900F583D9 /* Model.xcdatamodeld */; };
|
||||
B559CD431CAA8B6300E4D58B /* CSSetupResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B559CD421CAA8B6300E4D58B /* CSSetupResult.swift */; };
|
||||
B559CD441CAA8B6300E4D58B /* CSSetupResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B559CD421CAA8B6300E4D58B /* CSSetupResult.swift */; };
|
||||
@@ -715,6 +725,7 @@
|
||||
B529C2031CA4A2DB007E7EBD /* CSSaveResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSSaveResult.swift; sourceTree = "<group>"; };
|
||||
B52DD1741BE1F8CC00949AFE /* CoreStore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = CoreStore.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
B52DD17D1BE1F8CC00949AFE /* CoreStoreTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CoreStoreTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
B538BA701D15B3E30003A766 /* CoreStoreBridge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CoreStoreBridge.m; sourceTree = "<group>"; };
|
||||
B53FB9FD1CAB2D2F00F0D40A /* CSMigrationResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSMigrationResult.swift; sourceTree = "<group>"; };
|
||||
B53FBA031CAB300C00F0D40A /* CSMigrationType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSMigrationType.swift; sourceTree = "<group>"; };
|
||||
B53FBA0A1CAB5E6500F0D40A /* CSCoreStore+Migrating.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CSCoreStore+Migrating.swift"; sourceTree = "<group>"; };
|
||||
@@ -737,6 +748,7 @@
|
||||
B5519A5E1CA21954002BEF78 /* CSAsynchronousDataTransaction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSAsynchronousDataTransaction.swift; sourceTree = "<group>"; };
|
||||
B5548CD51BD65AE00077652A /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };
|
||||
B5548CD71BD65AE50077652A /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/System/Library/Frameworks/CoreData.framework; sourceTree = DEVELOPER_DIR; };
|
||||
B55717421D15AF9C009BDBCA /* CoreStoreBridge.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CoreStoreBridge.h; sourceTree = "<group>"; };
|
||||
B559CD421CAA8B6300E4D58B /* CSSetupResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSSetupResult.swift; sourceTree = "<group>"; };
|
||||
B559CD481CAA8C6D00E4D58B /* CSStorageInterface.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSStorageInterface.swift; sourceTree = "<group>"; };
|
||||
B56007101B3F6BD500A9A8F9 /* Into.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Into.swift; sourceTree = "<group>"; };
|
||||
@@ -1155,6 +1167,8 @@
|
||||
B5DBE2CB1C99148100B5CEFA /* ObjectiveC */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B55717421D15AF9C009BDBCA /* CoreStoreBridge.h */,
|
||||
B538BA701D15B3E30003A766 /* CoreStoreBridge.m */,
|
||||
B5AEFAB41C9962AE00AD137F /* CoreStoreBridge.swift */,
|
||||
B5DBE2CC1C9914A900B5CEFA /* CSCoreStore.swift */,
|
||||
B5519A491CA1F4FB002BEF78 /* CSError.swift */,
|
||||
@@ -1368,6 +1382,7 @@
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
B55717441D15B09E009BDBCA /* CoreStoreBridge.h in Headers */,
|
||||
2F03A53619C5C6DA005002A5 /* CoreStore.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@@ -1376,6 +1391,7 @@
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
B55717451D15B09F009BDBCA /* CoreStoreBridge.h in Headers */,
|
||||
82BA18A01C4BBD1400A0916E /* CoreStore.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@@ -1384,6 +1400,7 @@
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
B55717461D15B0A1009BDBCA /* CoreStoreBridge.h in Headers */,
|
||||
B52DD1931BE1F8FD00949AFE /* CoreStore.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@@ -1392,6 +1409,7 @@
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
B55717471D15B0A1009BDBCA /* CoreStoreBridge.h in Headers */,
|
||||
B563217E1BD65110006C9394 /* CoreStore.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@@ -1400,6 +1418,7 @@
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
B55717431D15B09D009BDBCA /* CoreStoreBridge.h in Headers */,
|
||||
B5D9E32F1CA2C317007A9D52 /* CoreStore.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@@ -1764,6 +1783,7 @@
|
||||
B5E84F101AFF847B0064E85B /* GroupBy.swift in Sources */,
|
||||
B5E84F201AFF84860064E85B /* DataStack+Observing.swift in Sources */,
|
||||
B501FDDD1CA8D05000BE22EF /* CSSectionBy.swift in Sources */,
|
||||
B538BA771D15B3E30003A766 /* CoreStoreBridge.m in Sources */,
|
||||
B59FA0AE1CCBAC95007C9BCA /* ICloudStore.swift in Sources */,
|
||||
B5E84EF81AFF846E0064E85B /* CoreStore+Transaction.swift in Sources */,
|
||||
B5E84F301AFF849C0064E85B /* NSManagedObjectContext+CoreStore.swift in Sources */,
|
||||
@@ -1911,6 +1931,7 @@
|
||||
82BA18B51C4BBD3F00A0916E /* BaseDataTransaction+Querying.swift in Sources */,
|
||||
B501FDDF1CA8D05000BE22EF /* CSSectionBy.swift in Sources */,
|
||||
B59FA0B01CCBACA7007C9BCA /* ICloudStore.swift in Sources */,
|
||||
B538BA781D15B3E30003A766 /* CoreStoreBridge.m in Sources */,
|
||||
82BA18D31C4BBD7100A0916E /* NSManagedObjectContext+CoreStore.swift in Sources */,
|
||||
82BA18AD1C4BBD3100A0916E /* UnsafeDataTransaction.swift in Sources */,
|
||||
B546F96A1C9AF26D00D5AC55 /* CSInMemoryStore.swift in Sources */,
|
||||
@@ -2058,6 +2079,7 @@
|
||||
B5220E191D130761009BC71E /* ListMonitor.swift in Sources */,
|
||||
B5220E181D130711009BC71E /* ObjectObserver.swift in Sources */,
|
||||
B5220E251D13088E009BC71E /* ListObserver.swift in Sources */,
|
||||
B538BA7A1D15B3E30003A766 /* CoreStoreBridge.m in Sources */,
|
||||
B52DD1A01BE1F92C00949AFE /* UnsafeDataTransaction.swift in Sources */,
|
||||
B5ECDC331CA81CDC00C7F112 /* CSCoreStore+Transaction.swift in Sources */,
|
||||
B52DD1BB1BE1F94000949AFE /* MigrationType.swift in Sources */,
|
||||
@@ -2205,6 +2227,7 @@
|
||||
B56321921BD65216006C9394 /* BaseDataTransaction+Querying.swift in Sources */,
|
||||
B501FDE01CA8D05000BE22EF /* CSSectionBy.swift in Sources */,
|
||||
B59FA0B11CCBACA7007C9BCA /* ICloudStore.swift in Sources */,
|
||||
B538BA791D15B3E30003A766 /* CoreStoreBridge.m in Sources */,
|
||||
B56321B11BD6521C006C9394 /* NSManagedObjectContext+CoreStore.swift in Sources */,
|
||||
B563218D1BD65216006C9394 /* CoreStore+Transaction.swift in Sources */,
|
||||
B546F96B1C9AF26D00D5AC55 /* CSInMemoryStore.swift in Sources */,
|
||||
@@ -2233,6 +2256,7 @@
|
||||
B5ECDC0C1CA8161B00C7F112 /* CSGroupBy.swift in Sources */,
|
||||
B5EA11DD1CA3AFD9002282F8 /* NSPersistentStoreCoordinator+Setup.swift in Sources */,
|
||||
B53FBA191CAB63E200F0D40A /* NSManagedObject+ObjectiveC.swift in Sources */,
|
||||
B538BA761D15B3E30003A766 /* CoreStoreBridge.m in Sources */,
|
||||
B5ECDC3A1CA8369400C7F112 /* CSDataStack.swift in Sources */,
|
||||
B5D9E2EF1CA2C317007A9D52 /* ObjectMonitor.swift in Sources */,
|
||||
B5ECDC3B1CA836AD00C7F112 /* CoreStoreBridge.swift in Sources */,
|
||||
@@ -2734,6 +2758,7 @@
|
||||
PRODUCT_NAME = CoreStore_iOS7;
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
|
||||
@@ -28,7 +28,7 @@ class BaseTestDataTestCase: BaseTestCase {
|
||||
}()
|
||||
|
||||
@nonobjc
|
||||
func prepareTestDataForStack(stack: DataStack, configurations: [String?]) {
|
||||
func prepareTestDataForStack(stack: DataStack, configurations: [String?] = [nil]) {
|
||||
|
||||
stack.beginSynchronous { (transaction) in
|
||||
|
||||
|
||||
@@ -24,14 +24,17 @@
|
||||
//
|
||||
|
||||
#import "BridgingTests.h"
|
||||
#import <CoreStore/CoreStore.h>
|
||||
#import <CoreStore/CoreStore-Swift.h>
|
||||
#import "CoreStoreTests-Swift.h"
|
||||
|
||||
@import CoreData;
|
||||
|
||||
// MARK: - BridgingTests
|
||||
|
||||
@implementation BridgingTests
|
||||
|
||||
- (void)testFlags {
|
||||
- (void)test_ThatFlags_HaveCorrectValues {
|
||||
|
||||
XCTAssertEqual(CSLocalStorageOptionsNone, 0);
|
||||
XCTAssertEqual(CSLocalStorageOptionsRecreateStoreOnModelMismatch, 1);
|
||||
@@ -39,7 +42,48 @@
|
||||
XCTAssertEqual(CSLocalStorageOptionsAllowSynchronousLightweightMigration, 4);
|
||||
}
|
||||
|
||||
- (void)testDataStack {
|
||||
- (void)test_ThatFromClauses_BridgeCorrectly {
|
||||
|
||||
{
|
||||
CSFrom *from = From([TestEntity1 class]);
|
||||
XCTAssertEqualObjects(from.entityClass, [TestEntity1 class]);
|
||||
XCTAssertNil(from.configurations);
|
||||
}
|
||||
{
|
||||
CSFrom *from = From([TestEntity1 class], @[[NSNull null], @"Config2"]);
|
||||
XCTAssertEqualObjects(from.entityClass, [TestEntity1 class]);
|
||||
|
||||
NSArray *configurations = @[[NSNull null], @"Config2"];
|
||||
XCTAssertEqualObjects(from.configurations, configurations);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)test_ThatWhereClauses_BridgeCorrectly {
|
||||
|
||||
{
|
||||
CSWhere *where = Where(@"%K == %@", @"key", @"value");
|
||||
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K == %@", @"key", @"value"];
|
||||
XCTAssertEqualObjects(where.predicate, predicate);
|
||||
}
|
||||
{
|
||||
CSWhere *where = Where(YES);
|
||||
NSPredicate *predicate = [NSPredicate predicateWithValue:YES];
|
||||
XCTAssertEqualObjects(where.predicate, predicate);
|
||||
}
|
||||
{
|
||||
CSWhere *where = Where([NSPredicate predicateWithFormat:@"%K == %@", @"key", @"value"]);
|
||||
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K == %@", @"key", @"value"];
|
||||
XCTAssertEqualObjects(where.predicate, predicate);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)test_ThatGroupByClauses_BridgeCorrectly {
|
||||
|
||||
CSGroupBy *groupBy = GroupBy(@[@"key"]);
|
||||
XCTAssertEqualObjects(groupBy.keyPaths, @[@"key"]);
|
||||
}
|
||||
|
||||
- (void)test_ThatDataStacks_BridgeCorrectly {
|
||||
|
||||
CSDataStack *dataStack = [[CSDataStack alloc]
|
||||
initWithModelName:@"Model"
|
||||
|
||||
@@ -40,45 +40,35 @@ final class FromTests: BaseTestCase {
|
||||
|
||||
let from = From()
|
||||
XCTAssert(from.entityClass === NSManagedObject.self)
|
||||
XCTAssertNil(from.dumpInfo)
|
||||
XCTAssertNil(from.configurations)
|
||||
}
|
||||
do {
|
||||
|
||||
let from = From<TestEntity1>()
|
||||
XCTAssert(from.entityClass === TestEntity1.self)
|
||||
XCTAssertNil(from.dumpInfo)
|
||||
XCTAssertNil(from.configurations)
|
||||
}
|
||||
do {
|
||||
|
||||
let from = From<TestEntity1>("Config1")
|
||||
XCTAssert(from.entityClass === TestEntity1.self)
|
||||
|
||||
let dumpInfo = from.dumpInfo
|
||||
XCTAssertEqual(dumpInfo?.key, "configurations")
|
||||
|
||||
let configurations = dumpInfo?.value as! [String?]
|
||||
XCTAssertEqual(configurations.count, 1)
|
||||
XCTAssertEqual(configurations[0], "Config1")
|
||||
XCTAssertEqual(from.configurations?.count, 1)
|
||||
XCTAssertEqual(from.configurations?[0], "Config1")
|
||||
}
|
||||
do {
|
||||
|
||||
let from = From<TestEntity1>(nil, "Config1")
|
||||
XCTAssert(from.entityClass === TestEntity1.self)
|
||||
|
||||
let dumpInfo = from.dumpInfo
|
||||
XCTAssertEqual(dumpInfo?.key, "configurations")
|
||||
|
||||
let configurations = dumpInfo?.value as! [String?]
|
||||
XCTAssertEqual(configurations.count, 2)
|
||||
XCTAssertEqual(configurations[0], nil)
|
||||
XCTAssertEqual(configurations[1], "Config1")
|
||||
XCTAssertEqual(from.configurations?.count, 2)
|
||||
XCTAssertEqual(from.configurations?[0], nil)
|
||||
XCTAssertEqual(from.configurations?[1], "Config1")
|
||||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
dynamic func test_ThatFromClauses_ApplyToFetchRequestsCorrectlyForDefaultConfigurations() {
|
||||
|
||||
self.prepareStack(configurations: [nil]) { (dataStack) in
|
||||
self.prepareStack { (dataStack) in
|
||||
|
||||
do {
|
||||
|
||||
|
||||
@@ -349,7 +349,7 @@ class ImportTests: BaseTestDataTestCase {
|
||||
|
||||
self.prepareStack { (stack) in
|
||||
|
||||
self.prepareTestDataForStack(stack, configurations: [nil])
|
||||
self.prepareTestDataForStack(stack)
|
||||
|
||||
stack.beginSynchronous { (transaction) in
|
||||
|
||||
@@ -419,7 +419,7 @@ class ImportTests: BaseTestDataTestCase {
|
||||
|
||||
self.prepareStack { (stack) in
|
||||
|
||||
self.prepareTestDataForStack(stack, configurations: [nil])
|
||||
self.prepareTestDataForStack(stack)
|
||||
|
||||
stack.beginSynchronous { (transaction) in
|
||||
|
||||
@@ -519,7 +519,7 @@ class ImportTests: BaseTestDataTestCase {
|
||||
|
||||
self.prepareStack { (stack) in
|
||||
|
||||
self.prepareTestDataForStack(stack, configurations: [nil])
|
||||
self.prepareTestDataForStack(stack)
|
||||
|
||||
stack.beginSynchronous { (transaction) in
|
||||
|
||||
@@ -598,7 +598,7 @@ class ImportTests: BaseTestDataTestCase {
|
||||
|
||||
self.prepareStack { (stack) in
|
||||
|
||||
self.prepareTestDataForStack(stack, configurations: [nil])
|
||||
self.prepareTestDataForStack(stack)
|
||||
|
||||
stack.beginSynchronous { (transaction) in
|
||||
|
||||
@@ -656,7 +656,7 @@ class ImportTests: BaseTestDataTestCase {
|
||||
|
||||
self.prepareStack { (stack) in
|
||||
|
||||
self.prepareTestDataForStack(stack, configurations: [nil])
|
||||
self.prepareTestDataForStack(stack)
|
||||
|
||||
stack.beginSynchronous { (transaction) in
|
||||
|
||||
@@ -818,7 +818,7 @@ class ImportTests: BaseTestDataTestCase {
|
||||
|
||||
self.prepareStack { (stack) in
|
||||
|
||||
self.prepareTestDataForStack(stack, configurations: [nil])
|
||||
self.prepareTestDataForStack(stack)
|
||||
|
||||
stack.beginSynchronous { (transaction) in
|
||||
|
||||
|
||||
@@ -44,12 +44,12 @@ class ListObserverTests: BaseTestDataTestCase {
|
||||
let monitor = stack.monitorSectionedList(
|
||||
From(TestEntity1),
|
||||
SectionBy("testBoolean"),
|
||||
OrderBy(.Ascending("testEntityID"))
|
||||
OrderBy(.Ascending("testBoolean"), .Ascending("testEntityID"))
|
||||
)
|
||||
monitor.addObserver(observer)
|
||||
|
||||
XCTAssertFalse(monitor.hasSections())
|
||||
XCTAssertFalse(monitor.hasObjects())
|
||||
XCTAssertFalse(monitor.hasObjectsInSection(0))
|
||||
XCTAssertTrue(monitor.objectsInAllSections().isEmpty)
|
||||
|
||||
var events = 0
|
||||
@@ -59,6 +59,7 @@ class ListObserverTests: BaseTestDataTestCase {
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
XCTAssertEqual(events, 0)
|
||||
XCTAssertEqual((note.userInfo ?? [:]), NSDictionary())
|
||||
defer {
|
||||
|
||||
@@ -72,6 +73,7 @@ class ListObserverTests: BaseTestDataTestCase {
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
XCTAssertEqual(events, 1)
|
||||
XCTAssertEqual(
|
||||
(note.userInfo ?? [:]),
|
||||
[
|
||||
@@ -91,11 +93,20 @@ class ListObserverTests: BaseTestDataTestCase {
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
let indexPath = note.userInfo?["indexPath"] as? NSIndexPath
|
||||
XCTAssertEqual(events, 2)
|
||||
|
||||
let userInfo = note.userInfo
|
||||
XCTAssertNotNil(userInfo)
|
||||
XCTAssertEqual(
|
||||
Set(((userInfo as? [String: AnyObject]) ?? [:]).keys),
|
||||
["indexPath", "object"]
|
||||
)
|
||||
|
||||
let indexPath = userInfo?["indexPath"] as? NSIndexPath
|
||||
XCTAssertEqual(indexPath?.section, 0)
|
||||
XCTAssertEqual(indexPath?.row, 0)
|
||||
|
||||
let object = note.userInfo?["object"] as? TestEntity1
|
||||
let object = userInfo?["object"] as? TestEntity1
|
||||
XCTAssertEqual(object?.testBoolean, NSNumber(bool: true))
|
||||
XCTAssertEqual(object?.testNumber, NSNumber(integer: 1))
|
||||
XCTAssertEqual(object?.testDecimal, NSDecimalNumber(string: "1"))
|
||||
@@ -149,6 +160,397 @@ class ListObserverTests: BaseTestDataTestCase {
|
||||
self.waitAndCheckExpectations()
|
||||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
dynamic func test_ThatListObservers_CanReceiveUpdateNotifications() {
|
||||
|
||||
self.prepareStack { (stack) in
|
||||
|
||||
self.prepareTestDataForStack(stack)
|
||||
|
||||
let observer = TestListObserver()
|
||||
let monitor = stack.monitorSectionedList(
|
||||
From(TestEntity1),
|
||||
SectionBy("testBoolean"),
|
||||
OrderBy(.Ascending("testBoolean"), .Ascending("testEntityID"))
|
||||
)
|
||||
monitor.addObserver(observer)
|
||||
|
||||
XCTAssertTrue(monitor.hasSections())
|
||||
XCTAssertEqual(monitor.numberOfSections(), 2)
|
||||
XCTAssertTrue(monitor.hasObjects())
|
||||
XCTAssertTrue(monitor.hasObjectsInSection(0))
|
||||
XCTAssertEqual(monitor.numberOfObjectsInSection(0), 2)
|
||||
XCTAssertEqual(monitor.numberOfObjectsInSection(1), 3)
|
||||
|
||||
var events = 0
|
||||
|
||||
let willChangeExpectation = self.expectationForNotification(
|
||||
"listMonitorWillChange:",
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
XCTAssertEqual(events, 0)
|
||||
XCTAssertEqual((note.userInfo ?? [:]), NSDictionary())
|
||||
defer {
|
||||
|
||||
events += 1
|
||||
}
|
||||
return events == 0
|
||||
}
|
||||
)
|
||||
for _ in 1 ... 2 {
|
||||
|
||||
let didUpdateObjectExpectation = self.expectationForNotification(
|
||||
"listMonitor:didUpdateObject:atIndexPath:",
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
XCTAssert(events == 1 || events == 2)
|
||||
|
||||
let userInfo = note.userInfo
|
||||
XCTAssertNotNil(userInfo)
|
||||
XCTAssertEqual(
|
||||
Set(((userInfo as? [String: AnyObject]) ?? [:]).keys),
|
||||
["indexPath", "object"]
|
||||
)
|
||||
|
||||
let indexPath = userInfo?["indexPath"] as? NSIndexPath
|
||||
let object = userInfo?["object"] as? TestEntity1
|
||||
|
||||
switch object?.testEntityID {
|
||||
|
||||
case NSNumber(integer: 101)?:
|
||||
XCTAssertEqual(indexPath?.section, 1)
|
||||
XCTAssertEqual(indexPath?.row, 0)
|
||||
|
||||
XCTAssertEqual(object?.testBoolean, NSNumber(bool: true))
|
||||
XCTAssertEqual(object?.testNumber, NSNumber(integer: 11))
|
||||
XCTAssertEqual(object?.testDecimal, NSDecimalNumber(string: "11"))
|
||||
XCTAssertEqual(object?.testString, "nil:TestEntity1:11")
|
||||
XCTAssertEqual(object?.testData, ("nil:TestEntity1:11" as NSString).dataUsingEncoding(NSUTF8StringEncoding)!)
|
||||
XCTAssertEqual(object?.testDate, self.dateFormatter.dateFromString("2000-01-11T00:00:00Z")!)
|
||||
|
||||
case NSNumber(integer: 102)?:
|
||||
XCTAssertEqual(indexPath?.section, 0)
|
||||
XCTAssertEqual(indexPath?.row, 0)
|
||||
|
||||
XCTAssertEqual(object?.testBoolean, NSNumber(bool: false))
|
||||
XCTAssertEqual(object?.testNumber, NSNumber(integer: 22))
|
||||
XCTAssertEqual(object?.testDecimal, NSDecimalNumber(string: "22"))
|
||||
XCTAssertEqual(object?.testString, "nil:TestEntity1:22")
|
||||
XCTAssertEqual(object?.testData, ("nil:TestEntity1:22" as NSString).dataUsingEncoding(NSUTF8StringEncoding)!)
|
||||
XCTAssertEqual(object?.testDate, self.dateFormatter.dateFromString("2000-01-22T00:00:00Z")!)
|
||||
|
||||
default:
|
||||
XCTFail()
|
||||
}
|
||||
defer {
|
||||
|
||||
events += 1
|
||||
}
|
||||
return events == 1 || events == 2
|
||||
}
|
||||
)
|
||||
}
|
||||
let didChangeExpectation = self.expectationForNotification(
|
||||
"listMonitorDidChange:",
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
XCTAssertEqual(events, 3)
|
||||
XCTAssertEqual((note.userInfo ?? [:]), NSDictionary())
|
||||
defer {
|
||||
|
||||
events += 1
|
||||
}
|
||||
return events == 3
|
||||
}
|
||||
)
|
||||
let saveExpectation = self.expectationWithDescription("save")
|
||||
stack.beginAsynchronous { (transaction) in
|
||||
|
||||
if let object = transaction.fetchOne(
|
||||
From(TestEntity1),
|
||||
Where("testEntityID", isEqualTo: 101)) {
|
||||
|
||||
object.testNumber = NSNumber(integer: 11)
|
||||
object.testDecimal = NSDecimalNumber(string: "11")
|
||||
object.testString = "nil:TestEntity1:11"
|
||||
object.testData = ("nil:TestEntity1:11" as NSString).dataUsingEncoding(NSUTF8StringEncoding)!
|
||||
object.testDate = self.dateFormatter.dateFromString("2000-01-11T00:00:00Z")!
|
||||
}
|
||||
else {
|
||||
|
||||
XCTFail()
|
||||
}
|
||||
if let object = transaction.fetchOne(
|
||||
From(TestEntity1),
|
||||
Where("testEntityID", isEqualTo: 102)) {
|
||||
|
||||
object.testNumber = NSNumber(integer: 22)
|
||||
object.testDecimal = NSDecimalNumber(string: "22")
|
||||
object.testString = "nil:TestEntity1:22"
|
||||
object.testData = ("nil:TestEntity1:22" as NSString).dataUsingEncoding(NSUTF8StringEncoding)!
|
||||
object.testDate = self.dateFormatter.dateFromString("2000-01-22T00:00:00Z")!
|
||||
}
|
||||
else {
|
||||
|
||||
XCTFail()
|
||||
}
|
||||
transaction.commit { (result) in
|
||||
|
||||
switch result {
|
||||
|
||||
case .Success(let hasChanges):
|
||||
XCTAssertTrue(hasChanges)
|
||||
saveExpectation.fulfill()
|
||||
|
||||
case .Failure:
|
||||
XCTFail()
|
||||
}
|
||||
}
|
||||
}
|
||||
self.waitAndCheckExpectations()
|
||||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
dynamic func test_ThatListObservers_CanReceiveMoveNotifications() {
|
||||
|
||||
self.prepareStack { (stack) in
|
||||
|
||||
self.prepareTestDataForStack(stack)
|
||||
|
||||
let observer = TestListObserver()
|
||||
let monitor = stack.monitorSectionedList(
|
||||
From(TestEntity1),
|
||||
SectionBy("testBoolean"),
|
||||
OrderBy(.Ascending("testBoolean"), .Ascending("testEntityID"))
|
||||
)
|
||||
monitor.addObserver(observer)
|
||||
|
||||
var events = 0
|
||||
|
||||
let willChangeExpectation = self.expectationForNotification(
|
||||
"listMonitorWillChange:",
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
XCTAssertEqual(events, 0)
|
||||
XCTAssertEqual((note.userInfo ?? [:]), NSDictionary())
|
||||
defer {
|
||||
|
||||
events += 1
|
||||
}
|
||||
return events == 0
|
||||
}
|
||||
)
|
||||
let didMoveObjectExpectation = self.expectationForNotification(
|
||||
"listMonitor:didMoveObject:fromIndexPath:toIndexPath:",
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
XCTAssertEqual(events, 1)
|
||||
|
||||
let userInfo = note.userInfo
|
||||
XCTAssertNotNil(userInfo)
|
||||
XCTAssertEqual(
|
||||
Set(((userInfo as? [String: AnyObject]) ?? [:]).keys),
|
||||
["fromIndexPath", "toIndexPath", "object"]
|
||||
)
|
||||
|
||||
let fromIndexPath = userInfo?["fromIndexPath"] as? NSIndexPath
|
||||
XCTAssertEqual(fromIndexPath?.section, 0)
|
||||
XCTAssertEqual(fromIndexPath?.row, 0)
|
||||
|
||||
let toIndexPath = userInfo?["toIndexPath"] as? NSIndexPath
|
||||
XCTAssertEqual(toIndexPath?.section, 1)
|
||||
XCTAssertEqual(toIndexPath?.row, 1)
|
||||
|
||||
let object = userInfo?["object"] as? TestEntity1
|
||||
XCTAssertEqual(object?.testEntityID, NSNumber(integer: 102))
|
||||
XCTAssertEqual(object?.testBoolean, NSNumber(bool: true))
|
||||
|
||||
defer {
|
||||
|
||||
events += 1
|
||||
}
|
||||
return events == 1
|
||||
}
|
||||
)
|
||||
let didChangeExpectation = self.expectationForNotification(
|
||||
"listMonitorDidChange:",
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
XCTAssertEqual(events, 2)
|
||||
XCTAssertEqual((note.userInfo ?? [:]), NSDictionary())
|
||||
defer {
|
||||
|
||||
events += 1
|
||||
}
|
||||
return events == 2
|
||||
}
|
||||
)
|
||||
let saveExpectation = self.expectationWithDescription("save")
|
||||
stack.beginAsynchronous { (transaction) in
|
||||
|
||||
if let object = transaction.fetchOne(
|
||||
From(TestEntity1),
|
||||
Where("testEntityID", isEqualTo: 102)) {
|
||||
|
||||
object.testBoolean = NSNumber(bool: true)
|
||||
}
|
||||
else {
|
||||
|
||||
XCTFail()
|
||||
}
|
||||
transaction.commit { (result) in
|
||||
|
||||
switch result {
|
||||
|
||||
case .Success(let hasChanges):
|
||||
XCTAssertTrue(hasChanges)
|
||||
saveExpectation.fulfill()
|
||||
|
||||
case .Failure:
|
||||
XCTFail()
|
||||
}
|
||||
}
|
||||
}
|
||||
self.waitAndCheckExpectations()
|
||||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
dynamic func test_ThatListObservers_CanReceiveDeleteNotifications() {
|
||||
|
||||
self.prepareStack { (stack) in
|
||||
|
||||
self.prepareTestDataForStack(stack)
|
||||
|
||||
let observer = TestListObserver()
|
||||
let monitor = stack.monitorSectionedList(
|
||||
From(TestEntity1),
|
||||
SectionBy("testBoolean"),
|
||||
OrderBy(.Ascending("testBoolean"), .Ascending("testEntityID"))
|
||||
)
|
||||
monitor.addObserver(observer)
|
||||
|
||||
var events = 0
|
||||
|
||||
let willChangeExpectation = self.expectationForNotification(
|
||||
"listMonitorWillChange:",
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
XCTAssertEqual(events, 0)
|
||||
XCTAssertEqual((note.userInfo ?? [:]), NSDictionary())
|
||||
defer {
|
||||
|
||||
events += 1
|
||||
}
|
||||
return events == 0
|
||||
}
|
||||
)
|
||||
for _ in 1 ... 2 {
|
||||
|
||||
let didUpdateObjectExpectation = self.expectationForNotification(
|
||||
"listMonitor:didDeleteObject:fromIndexPath:",
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
XCTAssert(events == 1 || events == 2)
|
||||
|
||||
let userInfo = note.userInfo
|
||||
XCTAssertNotNil(userInfo)
|
||||
XCTAssertEqual(
|
||||
Set(((userInfo as? [String: AnyObject]) ?? [:]).keys),
|
||||
["indexPath", "object"]
|
||||
)
|
||||
|
||||
let indexPath = userInfo?["indexPath"] as? NSIndexPath
|
||||
|
||||
XCTAssertEqual(indexPath?.section, 0)
|
||||
XCTAssert(indexPath?.row == 0 || indexPath?.row == 1)
|
||||
|
||||
let object = userInfo?["object"] as? TestEntity1
|
||||
XCTAssertEqual(object?.deleted, true)
|
||||
|
||||
defer {
|
||||
|
||||
events += 1
|
||||
}
|
||||
return events == 1 || events == 2
|
||||
}
|
||||
)
|
||||
}
|
||||
let didDeleteSectionExpectation = self.expectationForNotification(
|
||||
"listMonitor:didDeleteSection:fromSectionIndex:",
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
XCTAssertEqual(events, 3)
|
||||
|
||||
let userInfo = note.userInfo
|
||||
XCTAssertNotNil(userInfo)
|
||||
XCTAssertEqual(
|
||||
Set(((userInfo as? [String: AnyObject]) ?? [:]).keys),
|
||||
["sectionInfo", "sectionIndex"]
|
||||
)
|
||||
|
||||
let sectionInfo = userInfo?["sectionInfo"]
|
||||
XCTAssertNotNil(sectionInfo)
|
||||
XCTAssertEqual(sectionInfo?.name, "0")
|
||||
|
||||
let sectionIndex = userInfo?["sectionIndex"]
|
||||
XCTAssertEqual(sectionIndex as? NSNumber, NSNumber(integer: 0))
|
||||
|
||||
defer {
|
||||
|
||||
events += 1
|
||||
}
|
||||
return events == 3
|
||||
}
|
||||
)
|
||||
let didChangeExpectation = self.expectationForNotification(
|
||||
"listMonitorDidChange:",
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
XCTAssertEqual(events, 4)
|
||||
XCTAssertEqual((note.userInfo ?? [:]), NSDictionary())
|
||||
defer {
|
||||
|
||||
events += 1
|
||||
}
|
||||
return events == 4
|
||||
}
|
||||
)
|
||||
let saveExpectation = self.expectationWithDescription("save")
|
||||
stack.beginAsynchronous { (transaction) in
|
||||
|
||||
transaction.deleteAll(
|
||||
From(TestEntity1),
|
||||
Where("testBoolean", isEqualTo: false)
|
||||
)
|
||||
transaction.commit { (result) in
|
||||
|
||||
switch result {
|
||||
|
||||
case .Success(let hasChanges):
|
||||
XCTAssertTrue(hasChanges)
|
||||
saveExpectation.fulfill()
|
||||
|
||||
case .Failure:
|
||||
XCTFail()
|
||||
}
|
||||
}
|
||||
}
|
||||
self.waitAndCheckExpectations()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ class ObjectObserverTests: BaseTestDataTestCase {
|
||||
|
||||
self.prepareStack { (stack) in
|
||||
|
||||
self.prepareTestDataForStack(stack, configurations: [nil])
|
||||
self.prepareTestDataForStack(stack)
|
||||
|
||||
guard let object = stack.fetchOne(
|
||||
From(TestEntity1),
|
||||
@@ -63,6 +63,7 @@ class ObjectObserverTests: BaseTestDataTestCase {
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
XCTAssertEqual(events, 0)
|
||||
XCTAssertEqual(
|
||||
(note.userInfo ?? [:]),
|
||||
["object": object] as NSDictionary
|
||||
@@ -79,6 +80,7 @@ class ObjectObserverTests: BaseTestDataTestCase {
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
XCTAssertEqual(events, 1)
|
||||
XCTAssertEqual(
|
||||
(note.userInfo ?? [:]),
|
||||
[
|
||||
@@ -89,7 +91,7 @@ class ObjectObserverTests: BaseTestDataTestCase {
|
||||
"testString"
|
||||
]
|
||||
)
|
||||
] as NSDictionary
|
||||
] as NSDictionary
|
||||
)
|
||||
let object = note.userInfo?["object"] as? TestEntity1
|
||||
XCTAssertEqual(object?.testNumber, NSNumber(integer: 10))
|
||||
@@ -135,7 +137,7 @@ class ObjectObserverTests: BaseTestDataTestCase {
|
||||
|
||||
self.prepareStack { (stack) in
|
||||
|
||||
self.prepareTestDataForStack(stack, configurations: [nil])
|
||||
self.prepareTestDataForStack(stack)
|
||||
|
||||
guard let object = stack.fetchOne(
|
||||
From(TestEntity1),
|
||||
@@ -158,6 +160,7 @@ class ObjectObserverTests: BaseTestDataTestCase {
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
XCTAssertEqual(events, 0)
|
||||
XCTAssertEqual(
|
||||
(note.userInfo ?? [:]),
|
||||
["object": object] as NSDictionary
|
||||
|
||||
@@ -28,3 +28,5 @@
|
||||
|
||||
FOUNDATION_EXPORT double CoreStoreVersionNumber;
|
||||
FOUNDATION_EXPORT const unsigned char CoreStoreVersionString[];
|
||||
|
||||
#import "CoreStoreBridge.h"
|
||||
|
||||
@@ -41,6 +41,17 @@ import CoreData
|
||||
*/
|
||||
public struct From<T: NSManagedObject> {
|
||||
|
||||
/**
|
||||
The associated `NSManagedObject` entity class
|
||||
*/
|
||||
public let entityClass: AnyClass
|
||||
|
||||
/**
|
||||
The `NSPersistentStore` configuration names to associate objects from.
|
||||
May contain `String`s to pertain to named configurations, or `nil` to pertain to the default configuration
|
||||
*/
|
||||
public let configurations: [String?]?
|
||||
|
||||
/**
|
||||
Initializes a `From` clause.
|
||||
```
|
||||
@@ -49,7 +60,7 @@ public struct From<T: NSManagedObject> {
|
||||
*/
|
||||
public init(){
|
||||
|
||||
self.init(entityClass: T.self)
|
||||
self.init(entityClass: T.self, configurations: nil)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -58,11 +69,11 @@ public struct From<T: NSManagedObject> {
|
||||
let people = transaction.fetchAll(From<MyPersonEntity>())
|
||||
```
|
||||
|
||||
- parameter entity: the `NSManagedObject` type to be created
|
||||
- parameter entity: the associated `NSManagedObject` type
|
||||
*/
|
||||
public init(_ entity: T.Type) {
|
||||
|
||||
self.init(entityClass: entity)
|
||||
self.init(entityClass: entity, configurations: nil)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -71,7 +82,7 @@ public struct From<T: NSManagedObject> {
|
||||
let people = transaction.fetchAll(From<MyPersonEntity>())
|
||||
```
|
||||
|
||||
- parameter entityClass: the `NSManagedObject` class type to be created
|
||||
- parameter entityClass: the associated `NSManagedObject` entity class
|
||||
*/
|
||||
public init(_ entityClass: AnyClass) {
|
||||
|
||||
@@ -79,7 +90,7 @@ public struct From<T: NSManagedObject> {
|
||||
entityClass is T.Type,
|
||||
"Attempted to create generic type \(cs_typeName(From<T>)) with entity class \(cs_typeName(entityClass))"
|
||||
)
|
||||
self.init(entityClass: entityClass)
|
||||
self.init(entityClass: entityClass, configurations: nil)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -178,9 +189,6 @@ public struct From<T: NSManagedObject> {
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
internal let entityClass: AnyClass
|
||||
internal let dumpInfo: (key: String, value: Any)?
|
||||
|
||||
@warn_unused_result
|
||||
internal func applyToFetchRequest(fetchRequest: NSFetchRequest, context: NSManagedObjectContext, applyAffectedStores: Bool = true) -> Bool {
|
||||
|
||||
@@ -211,7 +219,7 @@ public struct From<T: NSManagedObject> {
|
||||
|
||||
return From<NSManagedObject>(
|
||||
entityClass: self.entityClass,
|
||||
dumpInfo: self.dumpInfo,
|
||||
configurations: self.configurations,
|
||||
findPersistentStores: self.findPersistentStores
|
||||
)
|
||||
}
|
||||
@@ -221,197 +229,145 @@ public struct From<T: NSManagedObject> {
|
||||
|
||||
private let findPersistentStores: (context: NSManagedObjectContext) -> [NSPersistentStore]?
|
||||
|
||||
private init(entityClass: AnyClass) {
|
||||
private init(entityClass: AnyClass, configurations: [String?]?) {
|
||||
|
||||
self.init(
|
||||
entityClass: entityClass,
|
||||
dumpInfo: nil,
|
||||
findPersistentStores: { (context: NSManagedObjectContext) -> [NSPersistentStore]? in
|
||||
|
||||
return context.parentStack?.persistentStoresForEntityClass(entityClass)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private init(entityClass: AnyClass, configurations: [String?]) {
|
||||
|
||||
let configurationsSet = Set(configurations.map { $0 ?? Into.defaultConfigurationName })
|
||||
self.init(
|
||||
entityClass: entityClass,
|
||||
dumpInfo: ("configurations", configurations),
|
||||
findPersistentStores: { (context: NSManagedObjectContext) -> [NSPersistentStore]? in
|
||||
self.entityClass = entityClass
|
||||
self.configurations = configurations
|
||||
if let configurations = configurations {
|
||||
|
||||
let configurationsSet = Set(configurations.map { $0 ?? Into.defaultConfigurationName })
|
||||
self.findPersistentStores = { (context: NSManagedObjectContext) -> [NSPersistentStore]? in
|
||||
|
||||
return context.parentStack?.persistentStoresForEntityClass(entityClass)?.filter {
|
||||
|
||||
return configurationsSet.contains($0.configurationName)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private init(entityClass: AnyClass, storeURLs: [NSURL]) {
|
||||
|
||||
let storeURLsSet = Set(storeURLs)
|
||||
self.init(
|
||||
entityClass: entityClass,
|
||||
dumpInfo: ("storeURLs", storeURLs),
|
||||
findPersistentStores: { (context: NSManagedObjectContext) -> [NSPersistentStore]? in
|
||||
}
|
||||
else {
|
||||
|
||||
self.findPersistentStores = { (context: NSManagedObjectContext) -> [NSPersistentStore]? in
|
||||
|
||||
return context.parentStack?.persistentStoresForEntityClass(entityClass)?.filter {
|
||||
|
||||
return $0.URL != nil && storeURLsSet.contains($0.URL!)
|
||||
}
|
||||
return context.parentStack?.persistentStoresForEntityClass(entityClass)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private init(entityClass: AnyClass, persistentStores: [NSPersistentStore]) {
|
||||
|
||||
let persistentStores = Set(persistentStores)
|
||||
self.init(
|
||||
entityClass: entityClass,
|
||||
dumpInfo: ("persistentStores", persistentStores),
|
||||
findPersistentStores: { (context: NSManagedObjectContext) -> [NSPersistentStore]? in
|
||||
|
||||
return context.parentStack?.persistentStoresForEntityClass(entityClass)?.filter {
|
||||
|
||||
return persistentStores.contains($0)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private init(entityClass: AnyClass, dumpInfo: (key: String, value: Any)?, findPersistentStores: (context: NSManagedObjectContext) -> [NSPersistentStore]?) {
|
||||
private init(entityClass: AnyClass, configurations: [String?]?, findPersistentStores: (context: NSManagedObjectContext) -> [NSPersistentStore]?) {
|
||||
|
||||
self.entityClass = entityClass
|
||||
self.dumpInfo = dumpInfo
|
||||
self.configurations = configurations
|
||||
self.findPersistentStores = findPersistentStores
|
||||
}
|
||||
|
||||
|
||||
// MARK: Deprecated
|
||||
// MARK: Obsolete
|
||||
|
||||
/**
|
||||
Deprecated. Use initializers that accept configuration names.
|
||||
Obsolete. Use initializers that accept configuration names.
|
||||
*/
|
||||
@available(*, deprecated=2.0.0, message="Use initializers that accept configuration names.")
|
||||
@available(*, obsoleted=2.0.0, message="Use initializers that accept configuration names.")
|
||||
public init(_ storeURL: NSURL, _ otherStoreURLs: NSURL...) {
|
||||
|
||||
self.init(entityClass: T.self, storeURLs: [storeURL] + otherStoreURLs)
|
||||
CoreStore.abort("Use initializers that accept configuration names.")
|
||||
}
|
||||
|
||||
/**
|
||||
Deprecated. Use initializers that accept configuration names.
|
||||
Obsolete. Use initializers that accept configuration names.
|
||||
*/
|
||||
@available(*, deprecated=2.0.0, message="Use initializers that accept configuration names.")
|
||||
@available(*, obsoleted=2.0.0, message="Use initializers that accept configuration names.")
|
||||
public init(_ storeURLs: [NSURL]) {
|
||||
|
||||
self.init(entityClass: T.self, storeURLs: storeURLs)
|
||||
CoreStore.abort("Use initializers that accept configuration names.")
|
||||
}
|
||||
|
||||
/**
|
||||
Deprecated. Use initializers that accept configuration names.
|
||||
Obsolete. Use initializers that accept configuration names.
|
||||
*/
|
||||
@available(*, deprecated=2.0.0, message="Use initializers that accept configuration names.")
|
||||
@available(*, obsoleted=2.0.0, message="Use initializers that accept configuration names.")
|
||||
public init(_ entity: T.Type, _ storeURL: NSURL, _ otherStoreURLs: NSURL...) {
|
||||
|
||||
self.init(entityClass: entity, storeURLs: [storeURL] + otherStoreURLs)
|
||||
CoreStore.abort("Use initializers that accept configuration names.")
|
||||
}
|
||||
|
||||
/**
|
||||
Deprecated. Use initializers that accept configuration names.
|
||||
Obsolete. Use initializers that accept configuration names.
|
||||
*/
|
||||
@available(*, deprecated=2.0.0, message="Use initializers that accept configuration names.")
|
||||
@available(*, obsoleted=2.0.0, message="Use initializers that accept configuration names.")
|
||||
public init(_ entity: T.Type, _ storeURLs: [NSURL]) {
|
||||
|
||||
self.init(entityClass: entity, storeURLs: storeURLs)
|
||||
CoreStore.abort("Use initializers that accept configuration names.")
|
||||
}
|
||||
|
||||
/**
|
||||
Deprecated. Use initializers that accept configuration names.
|
||||
Obsolete. Use initializers that accept configuration names.
|
||||
*/
|
||||
@available(*, deprecated=2.0.0, message="Use initializers that accept configuration names.")
|
||||
@available(*, obsoleted=2.0.0, message="Use initializers that accept configuration names.")
|
||||
public init(_ entityClass: AnyClass, _ storeURL: NSURL, _ otherStoreURLs: NSURL...) {
|
||||
|
||||
CoreStore.assert(
|
||||
entityClass is T.Type,
|
||||
"Attempted to create generic type \(cs_typeName(From<T>)) with entity class \(cs_typeName(entityClass))"
|
||||
)
|
||||
self.init(entityClass: entityClass, storeURLs: [storeURL] + otherStoreURLs)
|
||||
CoreStore.abort("Use initializers that accept configuration names.")
|
||||
}
|
||||
|
||||
/**
|
||||
Deprecated. Use initializers that accept configuration names.
|
||||
Obsolete. Use initializers that accept configuration names.
|
||||
*/
|
||||
@available(*, deprecated=2.0.0, message="Use initializers that accept configuration names.")
|
||||
@available(*, obsoleted=2.0.0, message="Use initializers that accept configuration names.")
|
||||
public init(_ entityClass: AnyClass, _ storeURLs: [NSURL]) {
|
||||
|
||||
CoreStore.assert(
|
||||
entityClass is T.Type,
|
||||
"Attempted to create generic type \(cs_typeName(From<T>)) with entity class \(cs_typeName(entityClass))"
|
||||
)
|
||||
self.init(entityClass: entityClass, storeURLs: storeURLs)
|
||||
CoreStore.abort("Use initializers that accept configuration names.")
|
||||
}
|
||||
|
||||
/**
|
||||
Deprecated. Use initializers that accept configuration names.
|
||||
Obsolete. Use initializers that accept configuration names.
|
||||
*/
|
||||
@available(*, deprecated=2.0.0, message="Use initializers that accept configuration names.")
|
||||
@available(*, obsoleted=2.0.0, message="Use initializers that accept configuration names.")
|
||||
public init(_ persistentStore: NSPersistentStore, _ otherPersistentStores: NSPersistentStore...) {
|
||||
|
||||
self.init(entityClass: T.self, persistentStores: [persistentStore] + otherPersistentStores)
|
||||
CoreStore.abort("Use initializers that accept configuration names.")
|
||||
}
|
||||
|
||||
/**
|
||||
Deprecated. Use initializers that accept configuration names.
|
||||
Obsolete. Use initializers that accept configuration names.
|
||||
*/
|
||||
@available(*, deprecated=2.0.0, message="Use initializers that accept configuration names.")
|
||||
@available(*, obsoleted=2.0.0, message="Use initializers that accept configuration names.")
|
||||
public init(_ persistentStores: [NSPersistentStore]) {
|
||||
|
||||
self.init(entityClass: T.self, persistentStores: persistentStores)
|
||||
CoreStore.abort("Use initializers that accept configuration names.")
|
||||
}
|
||||
|
||||
/**
|
||||
Deprecated. Use initializers that accept configuration names.
|
||||
Obsolete. Use initializers that accept configuration names.
|
||||
*/
|
||||
@available(*, deprecated=2.0.0, message="Use initializers that accept configuration names.")
|
||||
@available(*, obsoleted=2.0.0, message="Use initializers that accept configuration names.")
|
||||
public init(_ entity: T.Type, _ persistentStore: NSPersistentStore, _ otherPersistentStores: NSPersistentStore...) {
|
||||
|
||||
self.init(entityClass: entity, persistentStores: [persistentStore] + otherPersistentStores)
|
||||
CoreStore.abort("Use initializers that accept configuration names.")
|
||||
}
|
||||
|
||||
/**
|
||||
Deprecated. Use initializers that accept configuration names.
|
||||
Obsolete. Use initializers that accept configuration names.
|
||||
*/
|
||||
@available(*, deprecated=2.0.0, message="Use initializers that accept configuration names.")
|
||||
@available(*, obsoleted=2.0.0, message="Use initializers that accept configuration names.")
|
||||
public init(_ entity: T.Type, _ persistentStores: [NSPersistentStore]) {
|
||||
|
||||
self.init(entityClass: entity, persistentStores: persistentStores)
|
||||
CoreStore.abort("Use initializers that accept configuration names.")
|
||||
}
|
||||
|
||||
/**
|
||||
Deprecated. Use initializers that accept configuration names.
|
||||
Obsolete. Use initializers that accept configuration names.
|
||||
*/
|
||||
@available(*, deprecated=2.0.0, message="Use initializers that accept configuration names.")
|
||||
@available(*, obsoleted=2.0.0, message="Use initializers that accept configuration names.")
|
||||
public init(_ entityClass: AnyClass, _ persistentStore: NSPersistentStore, _ otherPersistentStores: NSPersistentStore...) {
|
||||
|
||||
CoreStore.assert(
|
||||
entityClass is T.Type,
|
||||
"Attempted to create generic type \(cs_typeName(From<T>)) with entity class \(cs_typeName(entityClass))"
|
||||
)
|
||||
self.init(entityClass: entityClass, persistentStores: [persistentStore] + otherPersistentStores)
|
||||
CoreStore.abort("Use initializers that accept configuration names.")
|
||||
}
|
||||
|
||||
/**
|
||||
Deprecated. Use initializers that accept configuration names.
|
||||
Obsolete. Use initializers that accept configuration names.
|
||||
*/
|
||||
@available(*, deprecated=2.0.0, message="Use initializers that accept configuration names.")
|
||||
@available(*, obsoleted=2.0.0, message="Use initializers that accept configuration names.")
|
||||
public init(_ entityClass: AnyClass, _ persistentStores: [NSPersistentStore]) {
|
||||
|
||||
CoreStore.assert(
|
||||
entityClass is T.Type,
|
||||
"Attempted to create generic type \(cs_typeName(From<T>)) with entity class \(cs_typeName(entityClass))"
|
||||
)
|
||||
self.init(entityClass: entityClass, persistentStores: persistentStores)
|
||||
CoreStore.abort("Use initializers that accept configuration names.")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,14 +35,9 @@ import CoreData
|
||||
public struct GroupBy: QueryClause, Hashable {
|
||||
|
||||
/**
|
||||
Initializes a `GroupBy` clause with a list of key path strings
|
||||
|
||||
- parameter keyPaths: a list of key path strings to group results with
|
||||
The list of key path strings to group results with
|
||||
*/
|
||||
public init(_ keyPaths: [KeyPath]) {
|
||||
|
||||
self.keyPaths = keyPaths
|
||||
}
|
||||
public let keyPaths: [KeyPath]
|
||||
|
||||
/**
|
||||
Initializes a `GroupBy` clause with an empty list of key path strings
|
||||
@@ -52,6 +47,16 @@ 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
|
||||
|
||||
@@ -63,8 +68,6 @@ public struct GroupBy: QueryClause, Hashable {
|
||||
self.init([keyPath] + keyPaths)
|
||||
}
|
||||
|
||||
public let keyPaths: [KeyPath]
|
||||
|
||||
|
||||
// MARK: QueryClause
|
||||
|
||||
|
||||
@@ -412,10 +412,11 @@ extension Bool: SelectValueResultType {
|
||||
}
|
||||
|
||||
public static func fromResultObject(result: AnyObject) -> Bool? {
|
||||
|
||||
switch result {
|
||||
|
||||
case let decimal as NSDecimalNumber:
|
||||
// iOS: NSDecimalNumber(string: "0.5").boolValue // true
|
||||
// OSX: NSDecimalNumber(string: "0.5").boolValue // false
|
||||
return NSNumber(double: decimal.doubleValue).boolValue
|
||||
|
||||
case let number as NSNumber:
|
||||
|
||||
@@ -51,14 +51,9 @@ public prefix func !(clause: Where) -> Where {
|
||||
public struct Where: FetchClause, QueryClause, DeleteClause, Hashable {
|
||||
|
||||
/**
|
||||
Initializes a `Where` clause with an `NSPredicate`
|
||||
|
||||
- parameter predicate: the `NSPredicate` for the fetch or query
|
||||
The `NSPredicate` for the fetch or query
|
||||
*/
|
||||
public init(_ predicate: NSPredicate) {
|
||||
|
||||
self.predicate = predicate
|
||||
}
|
||||
public let predicate: NSPredicate
|
||||
|
||||
/**
|
||||
Initializes a `Where` clause with a predicate that always evaluates to `true`
|
||||
@@ -135,7 +130,15 @@ public struct Where: FetchClause, QueryClause, DeleteClause, Hashable {
|
||||
self.init(NSPredicate(format: "\(keyPath) IN %@", Array(list) as NSArray))
|
||||
}
|
||||
|
||||
public let predicate: NSPredicate
|
||||
/**
|
||||
Initializes a `Where` clause with an `NSPredicate`
|
||||
|
||||
- parameter predicate: the `NSPredicate` for the fetch or query
|
||||
*/
|
||||
public init(_ predicate: NSPredicate) {
|
||||
|
||||
self.predicate = predicate
|
||||
}
|
||||
|
||||
|
||||
// MARK: FetchClause, QueryClause, DeleteClause
|
||||
|
||||
@@ -198,9 +198,9 @@ extension From: CustomDebugStringConvertible, CoreStoreDebugStringConvertible {
|
||||
public var coreStoreDumpString: String {
|
||||
|
||||
var info: DumpInfo = [("entityClass", self.entityClass)]
|
||||
if let extraInfo = self.dumpInfo {
|
||||
if let configurations = self.configurations {
|
||||
|
||||
info.append(extraInfo)
|
||||
info.append(("configurations", configurations))
|
||||
}
|
||||
return createFormattedString(
|
||||
"(", ")",
|
||||
|
||||
@@ -37,6 +37,32 @@ import CoreData
|
||||
@objc
|
||||
public final class CSFrom: NSObject, CoreStoreObjectiveCType {
|
||||
|
||||
/**
|
||||
The associated `NSManagedObject` entity class
|
||||
*/
|
||||
@objc
|
||||
public var entityClass: AnyClass {
|
||||
|
||||
return self.bridgeToSwift.entityClass
|
||||
}
|
||||
|
||||
/**
|
||||
The `NSPersistentStore` configuration names to associate objects from.
|
||||
May contain `NSString` instances to pertain to named configurations, or `NSNull` to pertain to the default configuration
|
||||
*/
|
||||
@objc
|
||||
public var configurations: [AnyObject]? {
|
||||
|
||||
return self.bridgeToSwift.configurations?.map {
|
||||
|
||||
switch $0 {
|
||||
|
||||
case nil: return NSNull()
|
||||
case let string as NSString: return string
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Initializes a `CSFrom` clause with the specified entity class.
|
||||
```
|
||||
@@ -58,14 +84,24 @@ public final class CSFrom: NSObject, CoreStoreObjectiveCType {
|
||||
MyPersonEntity *people = [transaction fetchAllFrom:[CSFrom entityClass:[MyPersonEntity class] configuration:@"Configuration1"]];
|
||||
```
|
||||
|
||||
- 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 `nil` 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
|
||||
public static func entityClass(entityClass: AnyClass, configuration: String?) -> CSFrom {
|
||||
public static func entityClass(entityClass: AnyClass, configuration: AnyObject) -> CSFrom {
|
||||
|
||||
return self.init(From(entityClass, configuration))
|
||||
switch configuration {
|
||||
|
||||
case let string as String:
|
||||
return self.init(From(entityClass, string))
|
||||
|
||||
case is NSNull:
|
||||
return self.init(From(entityClass, nil))
|
||||
|
||||
default:
|
||||
CoreStore.abort("The configuration argument only accepts NSString and NSNull values")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -81,7 +117,22 @@ public final class CSFrom: NSObject, CoreStoreObjectiveCType {
|
||||
@objc
|
||||
public static func entityClass(entityClass: AnyClass, configurations: [AnyObject]) -> CSFrom {
|
||||
|
||||
return self.init(From(entityClass, configurations.map { $0 is NSNull ? nil : ($0 as! String) }))
|
||||
var arguments = [String?]()
|
||||
for configuration in configurations {
|
||||
|
||||
switch configuration {
|
||||
|
||||
case let string as String:
|
||||
arguments.append(string)
|
||||
|
||||
case is NSNull:
|
||||
arguments.append(nil)
|
||||
|
||||
default:
|
||||
CoreStore.abort("The configurations argument only accepts NSString and NSNull values")
|
||||
}
|
||||
}
|
||||
return self.init(From(entityClass, arguments))
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -37,6 +37,14 @@ import CoreData
|
||||
@objc
|
||||
public final class CSGroupBy: NSObject, CSQueryClause, CoreStoreObjectiveCType {
|
||||
|
||||
/**
|
||||
The list of key path strings to group results with
|
||||
*/
|
||||
public var keyPaths: [KeyPath] {
|
||||
|
||||
return self.bridgeToSwift.keyPaths
|
||||
}
|
||||
|
||||
/**
|
||||
Initializes a `CSGroupBy` clause with a list of key path strings
|
||||
|
||||
|
||||
@@ -38,15 +38,12 @@ import CoreData
|
||||
public final class CSWhere: NSObject, CSFetchClause, CSQueryClause, CSDeleteClause, CoreStoreObjectiveCType {
|
||||
|
||||
/**
|
||||
Initializes a `CSWhere` clause with an `NSPredicate`
|
||||
|
||||
- parameter predicate: the `NSPredicate` for the fetch or query
|
||||
- returns: a `CSWhere` clause with an `NSPredicate`
|
||||
The internal `NSPredicate` instance for the `Where` clause
|
||||
*/
|
||||
@objc
|
||||
public static func predicate(predicate: NSPredicate) -> CSWhere {
|
||||
public var predicate: NSPredicate {
|
||||
|
||||
return self.init(Where(predicate))
|
||||
return self.bridgeToSwift.predicate
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -100,6 +97,18 @@ public final class CSWhere: NSObject, CSFetchClause, CSQueryClause, CSDeleteClau
|
||||
return 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 {
|
||||
|
||||
return self.init(Where(predicate))
|
||||
}
|
||||
|
||||
|
||||
// MARK: NSObject
|
||||
|
||||
|
||||
152
Sources/ObjectiveC/CoreStoreBridge.h
Normal file
152
Sources/ObjectiveC/CoreStoreBridge.h
Normal file
@@ -0,0 +1,152 @@
|
||||
//
|
||||
// CoreStoreBridge.h
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright © 2016 John Rommel Estropia
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#ifndef CoreStoreBridge_h
|
||||
#define CoreStoreBridge_h
|
||||
|
||||
#if !__has_feature(objc_arc)
|
||||
#error CoreStore Objective-C utilities require ARC be enabled
|
||||
#endif
|
||||
|
||||
#if !__has_extension(attribute_overloadable)
|
||||
#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)))
|
||||
|
||||
|
||||
// MARK: - From
|
||||
|
||||
@class CSFrom;
|
||||
|
||||
/**
|
||||
@abstract
|
||||
Initializes a <tt>CSFrom</tt> clause with the specified entity class.
|
||||
|
||||
@code
|
||||
MyPersonEntity *people = [transaction fetchAllFrom:From([MyPersonEntity class])];
|
||||
@endcode
|
||||
|
||||
@param entityClass
|
||||
the <tt>NSManagedObject</tt> class type to be created
|
||||
|
||||
@result
|
||||
a <tt>CSFrom</tt> clause with the specified entity class
|
||||
*/
|
||||
CS_OBJC_EXTERN CS_OBJC_OVERLOADABLE
|
||||
CSFrom *_Nonnull From(Class _Nonnull entityClass);
|
||||
|
||||
/**
|
||||
@abstract
|
||||
Initializes a <tt>CSFrom</tt> clause with the specified configurations.
|
||||
|
||||
@code
|
||||
MyPersonEntity *people = [transaction fetchAllFrom:From([MyPersonEntity class], @[@"Configuration1"])];
|
||||
@endcode
|
||||
|
||||
@param entityClass
|
||||
the <tt>NSManagedObject</tt> class type to be created
|
||||
|
||||
@param configurations
|
||||
an array of the <tt>NSPersistentStore</tt> configuration names 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 configurations
|
||||
*/
|
||||
CS_OBJC_EXTERN CS_OBJC_OVERLOADABLE
|
||||
CSFrom *_Nonnull From(Class _Nonnull entityClass, NSArray<id> *_Nonnull configurations);
|
||||
|
||||
|
||||
|
||||
// MARK: - Where
|
||||
|
||||
@class CSWhere;
|
||||
|
||||
/**
|
||||
@abstract
|
||||
Initializes a <tt>CSWhere</tt> clause with a predicate that always evaluates to the specified boolean value
|
||||
|
||||
@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);
|
||||
|
||||
/**
|
||||
@abstract
|
||||
Initializes a <tt>CSWhere</tt> clause with a predicate using the specified string format and arguments
|
||||
|
||||
@param format
|
||||
the format string for the predicate
|
||||
|
||||
@param argumentArray
|
||||
the arguments for <tt>format</tt>
|
||||
|
||||
@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, ...);
|
||||
|
||||
/**
|
||||
@abstract
|
||||
Initializes a <tt>CSWhere</tt> clause with an <tt>NSPredicate</tt>
|
||||
|
||||
@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 CS_OBJC_OVERLOADABLE
|
||||
CSWhere *_Nonnull Where(NSPredicate *_Nonnull predicate);
|
||||
|
||||
|
||||
// MARK: - GroupBy
|
||||
|
||||
@class CSGroupBy;
|
||||
|
||||
/**
|
||||
@abstract
|
||||
Initializes a <tt>CSGroupBy</tt> clause with a list of key path strings
|
||||
|
||||
@param keyPaths
|
||||
a list of key path strings to group results with
|
||||
|
||||
@result
|
||||
a <tt>CSGroupBy</tt> clause with a list of key path strings
|
||||
*/
|
||||
CS_OBJC_OVERLOADABLE
|
||||
CSGroupBy *_Nonnull GroupBy(NSArray<NSString *> *_Nonnull keyPaths);
|
||||
|
||||
|
||||
#endif /* CoreStoreBridge_h */
|
||||
76
Sources/ObjectiveC/CoreStoreBridge.m
Normal file
76
Sources/ObjectiveC/CoreStoreBridge.m
Normal file
@@ -0,0 +1,76 @@
|
||||
//
|
||||
// CoreStoreBridge.m
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright © 2016 John Rommel Estropia
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
|
||||
#import "CoreStoreBridge.h"
|
||||
#import <CoreStore/CoreStore-Swift.h>
|
||||
|
||||
|
||||
CS_OBJC_OVERLOADABLE
|
||||
CSFrom *_Nonnull From(Class _Nonnull entityClass) {
|
||||
|
||||
return [CSFrom entityClass:entityClass];
|
||||
}
|
||||
|
||||
CS_OBJC_OVERLOADABLE
|
||||
CSFrom *_Nonnull From(Class _Nonnull entityClass, NSArray<id> *_Nonnull configurations) {
|
||||
|
||||
return [CSFrom entityClass:entityClass configurations:configurations];
|
||||
}
|
||||
|
||||
|
||||
|
||||
// MARK: - Where
|
||||
|
||||
CS_OBJC_OVERLOADABLE
|
||||
CSWhere *_Nonnull Where(BOOL value) {
|
||||
|
||||
return [CSWhere value:value];
|
||||
}
|
||||
|
||||
CS_OBJC_OVERLOADABLE
|
||||
CSWhere *_Nonnull Where(NSString *_Nonnull format, ...) {
|
||||
|
||||
CSWhere *where;
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
where = [CSWhere predicate:[NSPredicate predicateWithFormat:format arguments:args]];
|
||||
va_end(args);
|
||||
return where;
|
||||
}
|
||||
|
||||
CS_OBJC_OVERLOADABLE
|
||||
CSWhere *_Nonnull Where(NSPredicate *_Nonnull predicate) {
|
||||
|
||||
return [CSWhere predicate:predicate];
|
||||
}
|
||||
|
||||
|
||||
// MARK: - GroupBy
|
||||
|
||||
CS_OBJC_OVERLOADABLE
|
||||
CSGroupBy *_Nonnull GroupBy(NSArray<NSString *> *_Nonnull keyPaths) {
|
||||
|
||||
return [CSGroupBy keyPaths:keyPaths];
|
||||
}
|
||||
@@ -158,6 +158,17 @@ public final class ListMonitor<T: NSManagedObject>: Hashable {
|
||||
]
|
||||
}
|
||||
|
||||
/**
|
||||
Checks if the `ListMonitor` has at least one section
|
||||
|
||||
- returns: `true` if at least one section exists, `false` otherwise
|
||||
*/
|
||||
@warn_unused_result
|
||||
public func hasSections() -> Bool {
|
||||
|
||||
return self.sections().count > 0
|
||||
}
|
||||
|
||||
/**
|
||||
Checks if the `ListMonitor` has at least one object in any section.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user