mirror of
https://github.com/JohnEstropia/CoreStore.git
synced 2026-01-13 04:40:32 +01:00
Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
edd8ba55d8 | ||
|
|
18aac84335 | ||
|
|
c6be892cb0 | ||
|
|
2cd8101987 | ||
|
|
e1aed37da0 | ||
|
|
5de5ecee06 | ||
|
|
9406901b28 | ||
|
|
477f478d85 | ||
|
|
668b5ad606 | ||
|
|
f985828f3b | ||
|
|
bb3bc940c2 | ||
|
|
2d5bc77219 | ||
|
|
a40df37192 | ||
|
|
63b3d25d78 | ||
|
|
74721b5c12 | ||
|
|
f136549b46 | ||
|
|
4ec2b2e311 | ||
|
|
3d82ee18c7 |
@@ -1,6 +1,6 @@
|
||||
Pod::Spec.new do |s|
|
||||
s.name = "CoreStore"
|
||||
s.version = "7.3.0"
|
||||
s.version = "7.3.1"
|
||||
s.swift_version = "5.3"
|
||||
s.license = "MIT"
|
||||
s.homepage = "https://github.com/JohnEstropia/CoreStore"
|
||||
|
||||
@@ -362,6 +362,10 @@
|
||||
B52FD3AB1E3B3EF10001D919 /* NSManagedObject+Logging.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52FD3A91E3B3EF10001D919 /* NSManagedObject+Logging.swift */; };
|
||||
B52FD3AC1E3B3EF10001D919 /* NSManagedObject+Logging.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52FD3A91E3B3EF10001D919 /* NSManagedObject+Logging.swift */; };
|
||||
B52FD3AD1E3B3EF10001D919 /* NSManagedObject+Logging.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52FD3A91E3B3EF10001D919 /* NSManagedObject+Logging.swift */; };
|
||||
B52FEC742596DBE100368BFB /* ObjectReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52FEC732596DBE000368BFB /* ObjectReader.swift */; };
|
||||
B52FEC752596DBE100368BFB /* ObjectReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52FEC732596DBE000368BFB /* ObjectReader.swift */; };
|
||||
B52FEC762596DBE100368BFB /* ObjectReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52FEC732596DBE000368BFB /* ObjectReader.swift */; };
|
||||
B52FEC772596DBE100368BFB /* ObjectReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52FEC732596DBE000368BFB /* ObjectReader.swift */; };
|
||||
B533C4DB1D7D4BFA001383CB /* DispatchQueue+CoreStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B533C4DA1D7D4BFA001383CB /* DispatchQueue+CoreStore.swift */; };
|
||||
B533C4DC1D7D4BFA001383CB /* DispatchQueue+CoreStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B533C4DA1D7D4BFA001383CB /* DispatchQueue+CoreStore.swift */; };
|
||||
B533C4DD1D7D4BFA001383CB /* DispatchQueue+CoreStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B533C4DA1D7D4BFA001383CB /* DispatchQueue+CoreStore.swift */; };
|
||||
@@ -1064,6 +1068,7 @@
|
||||
B52F743C1E9B8724005F3DAC /* XcodeDataModelSchema.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = XcodeDataModelSchema.swift; sourceTree = "<group>"; };
|
||||
B52F74491E9B8740005F3DAC /* CoreStoreSchema.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreStoreSchema.swift; sourceTree = "<group>"; };
|
||||
B52FD3A91E3B3EF10001D919 /* NSManagedObject+Logging.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSManagedObject+Logging.swift"; sourceTree = "<group>"; };
|
||||
B52FEC732596DBE000368BFB /* ObjectReader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ObjectReader.swift; sourceTree = "<group>"; };
|
||||
B533C4DA1D7D4BFA001383CB /* DispatchQueue+CoreStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "DispatchQueue+CoreStore.swift"; sourceTree = "<group>"; };
|
||||
B538BA701D15B3E30003A766 /* CoreStoreBridge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CoreStoreBridge.m; sourceTree = "<group>"; };
|
||||
B53B275E1EE3B92E00E9B352 /* CoreStoreManagedObject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreStoreManagedObject.swift; sourceTree = "<group>"; };
|
||||
@@ -1535,6 +1540,14 @@
|
||||
name = "Dynamic Schema";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
B52FEC722596DB6400368BFB /* SwiftUI */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B52FEC732596DBE000368BFB /* ObjectReader.swift */,
|
||||
);
|
||||
name = SwiftUI;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
B53FBA101CAB607000F0D40A /* Convenience */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -1697,6 +1710,7 @@
|
||||
B5D1E22B19FA9FBC003B2874 /* CoreStoreError.swift */,
|
||||
B549F6721E56A92800FBAB2D /* CoreDataNativeType.swift */,
|
||||
B5D339F01E94AF5800C880DE /* CoreStoreStrings.swift */,
|
||||
B52FEC722596DB6400368BFB /* SwiftUI */,
|
||||
B5E84EDA1AFF84500064E85B /* Setup */,
|
||||
B51B5C2922D43854009FA3BA /* KeyPaths */,
|
||||
B5E84EE21AFF84610064E85B /* Logging */,
|
||||
@@ -2165,7 +2179,7 @@
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 0730;
|
||||
LastUpgradeCheck = 1020;
|
||||
LastUpgradeCheck = 1200;
|
||||
ORGANIZATIONNAME = "John Rommel Estropia";
|
||||
TargetAttributes = {
|
||||
2F03A52F19C5C6DA005002A5 = {
|
||||
@@ -2441,6 +2455,7 @@
|
||||
B559CD491CAA8C6D00E4D58B /* CSStorageInterface.swift in Sources */,
|
||||
B5ECDC2F1CA81CDC00C7F112 /* CSCoreStore+Transaction.swift in Sources */,
|
||||
B5E84F311AFF849C0064E85B /* Internals.WeakObject.swift in Sources */,
|
||||
B52FEC742596DBE100368BFB /* ObjectReader.swift in Sources */,
|
||||
B5E84F101AFF847B0064E85B /* GroupBy.swift in Sources */,
|
||||
B5E84F201AFF84860064E85B /* DataStack+Observing.swift in Sources */,
|
||||
B501FDDD1CA8D05000BE22EF /* CSSectionBy.swift in Sources */,
|
||||
@@ -2693,6 +2708,7 @@
|
||||
B501FDDF1CA8D05000BE22EF /* CSSectionBy.swift in Sources */,
|
||||
B5BF7FAE234C41E90070E741 /* Internals.DiffableDataSourceSnapshot.swift in Sources */,
|
||||
B538BA781D15B3E30003A766 /* CoreStoreBridge.m in Sources */,
|
||||
B52FEC752596DBE100368BFB /* ObjectReader.swift in Sources */,
|
||||
B51260801E97A18000402229 /* CoreStoreObject+Convenience.swift in Sources */,
|
||||
82BA18D31C4BBD7100A0916E /* NSManagedObjectContext+CoreStore.swift in Sources */,
|
||||
82BA18AD1C4BBD3100A0916E /* UnsafeDataTransaction.swift in Sources */,
|
||||
@@ -2945,6 +2961,7 @@
|
||||
B5220E181D130711009BC71E /* ObjectObserver.swift in Sources */,
|
||||
B5220E251D13088E009BC71E /* ListObserver.swift in Sources */,
|
||||
B538BA7A1D15B3E30003A766 /* CoreStoreBridge.m in Sources */,
|
||||
B52FEC772596DBE100368BFB /* ObjectReader.swift in Sources */,
|
||||
B5BF7FB0234C41E90070E741 /* Internals.DiffableDataSourceSnapshot.swift in Sources */,
|
||||
B51260821E97A18000402229 /* CoreStoreObject+Convenience.swift in Sources */,
|
||||
B52DD1A01BE1F92C00949AFE /* UnsafeDataTransaction.swift in Sources */,
|
||||
@@ -3197,6 +3214,7 @@
|
||||
B501FDE01CA8D05000BE22EF /* CSSectionBy.swift in Sources */,
|
||||
B5BF7FAF234C41E90070E741 /* Internals.DiffableDataSourceSnapshot.swift in Sources */,
|
||||
B538BA791D15B3E30003A766 /* CoreStoreBridge.m in Sources */,
|
||||
B52FEC762596DBE100368BFB /* ObjectReader.swift in Sources */,
|
||||
B51260811E97A18000402229 /* CoreStoreObject+Convenience.swift in Sources */,
|
||||
B56321B11BD6521C006C9394 /* NSManagedObjectContext+CoreStore.swift in Sources */,
|
||||
B563218D1BD65216006C9394 /* CoreStore+Transaction.swift in Sources */,
|
||||
@@ -3292,6 +3310,7 @@
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
@@ -3363,6 +3382,7 @@
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
@@ -3413,7 +3433,7 @@
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
MARKETING_VERSION = 7.3.0;
|
||||
MARKETING_VERSION = 7.3.1;
|
||||
OTHER_LDFLAGS = (
|
||||
"-weak_framework",
|
||||
Combine,
|
||||
@@ -3436,7 +3456,7 @@
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
MARKETING_VERSION = 7.3.0;
|
||||
MARKETING_VERSION = 7.3.1;
|
||||
OTHER_LDFLAGS = (
|
||||
"-weak_framework",
|
||||
Combine,
|
||||
@@ -3496,7 +3516,7 @@
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
MARKETING_VERSION = 7.3.0;
|
||||
MARKETING_VERSION = 7.3.1;
|
||||
OTHER_LDFLAGS = (
|
||||
"-weak_framework",
|
||||
Combine,
|
||||
@@ -3522,7 +3542,7 @@
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
MARKETING_VERSION = 7.3.0;
|
||||
MARKETING_VERSION = 7.3.1;
|
||||
OTHER_LDFLAGS = (
|
||||
"-weak_framework",
|
||||
Combine,
|
||||
@@ -3587,7 +3607,7 @@
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
|
||||
MARKETING_VERSION = 7.3.0;
|
||||
MARKETING_VERSION = 7.3.1;
|
||||
OTHER_LDFLAGS = (
|
||||
"-weak_framework",
|
||||
Combine,
|
||||
@@ -3616,7 +3636,7 @@
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
|
||||
MARKETING_VERSION = 7.3.0;
|
||||
MARKETING_VERSION = 7.3.1;
|
||||
OTHER_LDFLAGS = (
|
||||
"-weak_framework",
|
||||
Combine,
|
||||
@@ -3682,7 +3702,7 @@
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
MARKETING_VERSION = 7.3.0;
|
||||
MARKETING_VERSION = 7.3.1;
|
||||
OTHER_LDFLAGS = (
|
||||
"-weak_framework",
|
||||
Combine,
|
||||
@@ -3710,7 +3730,7 @@
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
MARKETING_VERSION = 7.3.0;
|
||||
MARKETING_VERSION = 7.3.1;
|
||||
OTHER_LDFLAGS = (
|
||||
"-weak_framework",
|
||||
Combine,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1020"
|
||||
LastUpgradeVersion = "1200"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1020"
|
||||
LastUpgradeVersion = "1200"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1020"
|
||||
LastUpgradeVersion = "1200"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1020"
|
||||
LastUpgradeVersion = "1200"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
||||
2
CoreStore.xcworkspace/contents.xcworkspacedata
generated
2
CoreStore.xcworkspace/contents.xcworkspacedata
generated
@@ -8,6 +8,6 @@
|
||||
location = "group:CoreStore.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:/Users/JohnEstropia/Documents/XCodeProjects/CoreStore/LegacyDemo/LegacyDemo.xcodeproj">
|
||||
location = "group:LegacyDemo/LegacyDemo.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
||||
@@ -290,19 +290,6 @@ class DynamicModelTests: BaseTestDataTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
// #if swift(>=5.1)
|
||||
//
|
||||
// let dogKeyPathBuilder = Dog.keyPathBuilder()
|
||||
// XCTAssertEqual(dogKeyPathBuilder.species.keyPathString, "SELF.species")
|
||||
// XCTAssertEqual(dogKeyPathBuilder.master.title.keyPathString, "SELF.master.title")
|
||||
// let a = dogKeyPathBuilder.master
|
||||
// let b = dogKeyPathBuilder.master.spouse
|
||||
// let c = dogKeyPathBuilder.master.spouse.pets
|
||||
// let d = dogKeyPathBuilder.master.spouse.pets.color
|
||||
// XCTAssertEqual(dogKeyPathBuilder.master.spouse.pets.color.keyPathString, "SELF.master.spouse.pets.color")
|
||||
//
|
||||
// #endif
|
||||
|
||||
let didSetObserver = dog.observe(\.$species, options: [.new, .old]) { (object, change) in
|
||||
|
||||
XCTAssertEqual(object, dog)
|
||||
|
||||
@@ -77,17 +77,10 @@ final class WhereTests: XCTestCase {
|
||||
|
||||
do {
|
||||
|
||||
// let keyPathBuilder = TestEntity1.keyPathBuilder()
|
||||
|
||||
// let kp = \TestEntity1.testToOne
|
||||
// print(keyPathBuilder.testString)
|
||||
// print(keyPathBuilder.testToOne)
|
||||
// print(keyPathBuilder.testToOne.testEntityID)
|
||||
XCTAssertAllEqual(
|
||||
#keyPath(TestEntity1.testToOne.testEntityID),
|
||||
(\TestEntity1.testToOne ~ \.testEntityID).description,
|
||||
String(keyPath: \TestEntity1.testToOne ~ \.testEntityID)
|
||||
// keyPathBuilder.testToOne.testEntityID.keyPathString
|
||||
)
|
||||
XCTAssertAllEqual(
|
||||
#keyPath(TestEntity1.testToOne.testToOne.testToManyUnordered),
|
||||
|
||||
@@ -622,7 +622,7 @@
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 1160;
|
||||
LastUpgradeCheck = 1160;
|
||||
LastUpgradeCheck = 1200;
|
||||
TargetAttributes = {
|
||||
B5A3911824E5429200E7E8BD = {
|
||||
CreatedOnToolsVersion = 11.6;
|
||||
@@ -769,6 +769,33 @@
|
||||
B5A3911324E5424E00E7E8BD /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||
};
|
||||
name = Debug;
|
||||
@@ -776,6 +803,32 @@
|
||||
B5A3911424E5424E00E7E8BD /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||
};
|
||||
name = Release;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1160"
|
||||
LastUpgradeVersion = "1200"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
import CoreStore
|
||||
import SwiftUI
|
||||
|
||||
|
||||
// MARK: - Modern.ColorsDemo.SwiftUI
|
||||
|
||||
extension Modern.ColorsDemo.SwiftUI {
|
||||
@@ -39,7 +40,7 @@ extension Modern.ColorsDemo.SwiftUI {
|
||||
.listRowInsets(.init())
|
||||
}
|
||||
.onDelete { itemIndices in
|
||||
|
||||
|
||||
self.deleteColors(at: itemIndices, in: sectionID)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -295,7 +295,7 @@
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 0700;
|
||||
LastUpgradeCheck = 0930;
|
||||
LastUpgradeCheck = 1200;
|
||||
ORGANIZATIONNAME = "John Rommel Estropia";
|
||||
TargetAttributes = {
|
||||
B54AAD481AF4D26E00848AE0 = {
|
||||
@@ -422,6 +422,7 @@
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
@@ -479,6 +480,7 @@
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
|
||||
@@ -6,14 +6,24 @@ PlaygroundPage.current.needsIndefiniteExecution = true
|
||||
|
||||
/// Model Declaration =====
|
||||
class Animal: CoreStoreObject {
|
||||
let species = Value.Required<String>("species", initial: "Swift")
|
||||
let master = Relationship.ToOne<Person>("master")
|
||||
let color = Transformable.Optional<UIColor>("color", initial: .orange)
|
||||
|
||||
@Field.Stored("species")
|
||||
var species: String = "Swift"
|
||||
|
||||
@Field.Coded("color", coder: FieldCoders.NSCoding.self)
|
||||
var color: UIColor = .orange
|
||||
|
||||
@Field.Relationship("master")
|
||||
var master: Person?
|
||||
}
|
||||
|
||||
class Person: CoreStoreObject {
|
||||
let name = Value.Optional<String>("name")
|
||||
let pets = Relationship.ToManyUnordered<Animal>("pets", inverse: { $0.master })
|
||||
|
||||
@Field.Stored("name")
|
||||
var name: String?
|
||||
|
||||
@Field.Relationship("pets", inverse: \.$master)
|
||||
var pets: Set<Animal>
|
||||
}
|
||||
/// =======================
|
||||
|
||||
@@ -24,6 +34,10 @@ let dataStack = DataStack(
|
||||
entities: [
|
||||
Entity<Animal>("Animal"),
|
||||
Entity<Person>("Person")
|
||||
],
|
||||
versionLock: [
|
||||
"Animal": [0x4a201cc685d53c0a, 0x16e6c3b561577875, 0xb032e2da61c792a0, 0xa133b801051acee4],
|
||||
"Person": [0xca938eea1af4bd56, 0xbca30994506356ad, 0x7a7cc655898816ef, 0x1a4551ffedc9b214]
|
||||
]
|
||||
)
|
||||
)
|
||||
@@ -42,12 +56,12 @@ dataStack.addStorage(
|
||||
asynchronous: { transaction in
|
||||
|
||||
let animal = transaction.create(Into<Animal>())
|
||||
animal.species .= "Sparrow"
|
||||
animal.color .= .yellow
|
||||
animal.species = "Sparrow"
|
||||
animal.color = .yellow
|
||||
|
||||
let person = transaction.create(Into<Person>())
|
||||
person.name .= "John"
|
||||
person.pets.value.insert(animal)
|
||||
person.name = "John"
|
||||
person.pets.insert(animal)
|
||||
},
|
||||
completion: { result in
|
||||
|
||||
@@ -58,13 +72,16 @@ dataStack.addStorage(
|
||||
|
||||
case .success:
|
||||
/// Accessing Objects =====
|
||||
let bird = try! dataStack.fetchOne(From<Animal>().where(\.species == "Sparrow"))!
|
||||
print(bird.species.value)
|
||||
print(bird.color.value as Any)
|
||||
let bird = try! dataStack.fetchOne(
|
||||
From<Animal>()
|
||||
.where(\.$species == "Sparrow")
|
||||
)!
|
||||
print(bird.species)
|
||||
print(bird.color as Any)
|
||||
print(bird)
|
||||
|
||||
let owner = bird.master.value!
|
||||
print(owner.name.value as Any)
|
||||
let owner = bird.master!
|
||||
print(owner.name as Any)
|
||||
print(owner.pets.count)
|
||||
print(owner)
|
||||
/// =======================
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<playground version='5.0' target-platform='ios' executeOnSourceChanges='false'>
|
||||
<playground version='5.0' target-platform='ios' buildActiveScheme='true'>
|
||||
<timeline fileName='timeline.xctimeline'/>
|
||||
</playground>
|
||||
@@ -6,14 +6,24 @@ PlaygroundPage.current.needsIndefiniteExecution = true
|
||||
|
||||
/// Model Declaration =====
|
||||
class Animal: CoreStoreObject {
|
||||
let species = Value.Required<String>("species", initial: "Swift")
|
||||
let master = Relationship.ToOne<Person>("master")
|
||||
let color = Transformable.Optional<NSColor>("color", initial: .orange)
|
||||
|
||||
@Field.Stored("species")
|
||||
var species: String = "Swift"
|
||||
|
||||
@Field.Coded("color", coder: FieldCoders.NSCoding.self)
|
||||
var color: NSColor = .orange
|
||||
|
||||
@Field.Relationship("master")
|
||||
var master: Person?
|
||||
}
|
||||
|
||||
class Person: CoreStoreObject {
|
||||
let name = Value.Optional<String>("name")
|
||||
let pets = Relationship.ToManyUnordered<Animal>("pets", inverse: { $0.master })
|
||||
|
||||
@Field.Stored("name")
|
||||
var name: String?
|
||||
|
||||
@Field.Relationship("pets", inverse: \.$master)
|
||||
var pets: Set<Animal>
|
||||
}
|
||||
/// =======================
|
||||
|
||||
@@ -24,6 +34,10 @@ let dataStack = DataStack(
|
||||
entities: [
|
||||
Entity<Animal>("Animal"),
|
||||
Entity<Person>("Person")
|
||||
],
|
||||
versionLock: [
|
||||
"Animal": [0x4a201cc685d53c0a, 0x16e6c3b561577875, 0xb032e2da61c792a0, 0xa133b801051acee4],
|
||||
"Person": [0xca938eea1af4bd56, 0xbca30994506356ad, 0x7a7cc655898816ef, 0x1a4551ffedc9b214]
|
||||
]
|
||||
)
|
||||
)
|
||||
@@ -42,12 +56,12 @@ dataStack.addStorage(
|
||||
asynchronous: { transaction in
|
||||
|
||||
let animal = transaction.create(Into<Animal>())
|
||||
animal.species .= "Sparrow"
|
||||
animal.color .= .yellow
|
||||
animal.species = "Sparrow"
|
||||
animal.color = .yellow
|
||||
|
||||
let person = transaction.create(Into<Person>())
|
||||
person.name .= "John"
|
||||
person.pets.value.insert(animal)
|
||||
person.name = "John"
|
||||
person.pets.insert(animal)
|
||||
},
|
||||
completion: { result in
|
||||
|
||||
@@ -58,13 +72,16 @@ dataStack.addStorage(
|
||||
|
||||
case .success:
|
||||
/// Accessing Objects =====
|
||||
let bird = try! dataStack.fetchOne(From<Animal>().where(\.species == "Sparrow"))!
|
||||
print(bird.species.value)
|
||||
print(bird.color.value as Any)
|
||||
let bird = try! dataStack.fetchOne(
|
||||
From<Animal>()
|
||||
.where(\.$species == "Sparrow")
|
||||
)!
|
||||
print(bird.species)
|
||||
print(bird.color as Any)
|
||||
print(bird)
|
||||
|
||||
let owner = bird.master.value!
|
||||
print(owner.name.value as Any)
|
||||
let owner = bird.master!
|
||||
print(owner.name as Any)
|
||||
print(owner.pets.count)
|
||||
print(owner)
|
||||
/// =======================
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<playground version='5.0' target-platform='macos' executeOnSourceChanges='false'>
|
||||
<playground version='5.0' target-platform='macos' buildActiveScheme='true'>
|
||||
<timeline fileName='timeline.xctimeline'/>
|
||||
</playground>
|
||||
@@ -2095,7 +2095,7 @@ This installs CoreStore as a framework. Declare `import CoreStore` in your swift
|
||||
#### Install with Swift Package Manager:
|
||||
```swift
|
||||
dependencies: [
|
||||
.package(url: "https://github.com/JohnEstropia/CoreStore.git", from: "7.3.0"))
|
||||
.package(url: "https://github.com/JohnEstropia/CoreStore.git", from: "7.3.1"))
|
||||
]
|
||||
```
|
||||
Declare `import CoreStore` in your swift file to use the library.
|
||||
|
||||
@@ -230,7 +230,10 @@ extension BaseDataTransaction {
|
||||
}
|
||||
try autoreleasepool {
|
||||
|
||||
if let object = existingObjectsByID[objectID] {
|
||||
if let object = existingObjectsByID[objectID]
|
||||
?? self.context.insertedObjects
|
||||
.compactMap({ O.cs_matches(object: $0) ? O.cs_fromRaw(object: $0) : nil })
|
||||
.first(where: { $0.uniqueIDValue == objectID }) {
|
||||
|
||||
guard entityType.shouldUpdate(from: source, in: self) else {
|
||||
|
||||
|
||||
@@ -429,7 +429,7 @@ public /*abstract*/ class BaseDataTransaction {
|
||||
|
||||
internal let context: NSManagedObjectContext
|
||||
internal let transactionQueue: DispatchQueue
|
||||
internal let childTransactionQueue = DispatchQueue.serial("com.corestore.datastack.childTransactionQueue")
|
||||
internal let childTransactionQueue = DispatchQueue.serial("com.corestore.datastack.childTransactionQueue", qos: .utility)
|
||||
internal let supportsUndo: Bool
|
||||
internal let bypassesQueueing: Bool
|
||||
internal var isCommitted = false
|
||||
|
||||
@@ -1189,7 +1189,6 @@ extension NSAttributeDescription: CoreStoreDebugStringConvertible {
|
||||
("versionHash", self.versionHash),
|
||||
("versionHashModifier", self.versionHashModifier as Any),
|
||||
("isIndexedBySpotlight", self.isIndexedBySpotlight),
|
||||
("isStoredInExternalRecord", self.isStoredInExternalRecord),
|
||||
("renamingIdentifier", self.renamingIdentifier as Any)
|
||||
)
|
||||
}
|
||||
@@ -1363,11 +1362,9 @@ extension NSRelationshipDescription: CoreStoreDebugStringConvertible {
|
||||
("isOptional", self.isOptional),
|
||||
("isTransient", self.isTransient),
|
||||
("userInfo", self.userInfo as Any),
|
||||
("isIndexed", self.isIndexed),
|
||||
("versionHash", self.versionHash),
|
||||
("versionHashModifier", self.versionHashModifier as Any),
|
||||
("isIndexedBySpotlight", self.isIndexedBySpotlight),
|
||||
("isStoredInExternalRecord", self.isStoredInExternalRecord),
|
||||
("renamingIdentifier", self.renamingIdentifier as Any)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -29,4 +29,4 @@
|
||||
FOUNDATION_EXPORT double CoreStoreVersionNumber;
|
||||
FOUNDATION_EXPORT const unsigned char CoreStoreVersionString[];
|
||||
|
||||
#import "CoreStoreBridge.h"
|
||||
#import <CoreStore/CoreStoreBridge.h>
|
||||
|
||||
@@ -69,7 +69,7 @@ public enum CoreStoreDefaults {
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private static let defaultStackBarrierQueue = DispatchQueue.concurrent("com.coreStore.defaultStackBarrierQueue")
|
||||
private static let defaultStackBarrierQueue = DispatchQueue.concurrent("com.coreStore.defaultStackBarrierQueue", qos: .userInteractive)
|
||||
|
||||
private static var defaultStackInstance: DataStack?
|
||||
}
|
||||
|
||||
@@ -48,6 +48,6 @@ import Foundation
|
||||
|
||||
private enum Static {
|
||||
|
||||
static let queue = DispatchQueue.concurrent("com.coreStore.coreStoreManagerObjectBarrierQueue")
|
||||
static let queue = DispatchQueue.concurrent("com.coreStore.coreStoreManagerObjectBarrierQueue", qos: .userInteractive)
|
||||
static var cache: [ObjectIdentifier: [KeyPathString: Set<KeyPathString>]] = [:]
|
||||
}
|
||||
|
||||
@@ -254,7 +254,7 @@ public final class CoreStoreSchema: DynamicSchema {
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private static let barrierQueue = DispatchQueue.concurrent("com.coreStore.coreStoreDataModelBarrierQueue")
|
||||
private static let barrierQueue = DispatchQueue.concurrent("com.coreStore.coreStoreDataModelBarrierQueue", qos: .userInteractive)
|
||||
|
||||
private let allEntities: Set<DynamicEntity>
|
||||
|
||||
|
||||
@@ -440,8 +440,8 @@ public final class DataStack: Equatable {
|
||||
internal let rootSavingContext: NSManagedObjectContext
|
||||
internal let mainContext: NSManagedObjectContext
|
||||
internal let schemaHistory: SchemaHistory
|
||||
internal let childTransactionQueue = DispatchQueue.serial("com.coreStore.dataStack.childTransactionQueue")
|
||||
internal let storeMetadataUpdateQueue = DispatchQueue.concurrent("com.coreStore.persistentStoreBarrierQueue")
|
||||
internal let childTransactionQueue = DispatchQueue.serial("com.coreStore.dataStack.childTransactionQueue", qos: .utility)
|
||||
internal let storeMetadataUpdateQueue = DispatchQueue.concurrent("com.coreStore.persistentStoreBarrierQueue", qos: .userInteractive)
|
||||
internal let migrationQueue: OperationQueue = Internals.with {
|
||||
|
||||
let migrationQueue = OperationQueue()
|
||||
|
||||
@@ -63,7 +63,7 @@ extension DiffableDataSource {
|
||||
*/
|
||||
open class TableViewAdapter<O: DynamicObject>: BaseAdapter<O, DefaultTableViewTarget<UITableView>>, UITableViewDataSource {
|
||||
|
||||
// MARK: Publi
|
||||
// MARK: Public
|
||||
|
||||
/**
|
||||
Initializes the `DiffableDataSource.TableViewAdapter`. This instance needs to be held on (retained) for as long as the `UITableView`'s lifecycle.
|
||||
|
||||
@@ -31,7 +31,7 @@ import Foundation
|
||||
extension DispatchQueue {
|
||||
|
||||
@nonobjc @inline(__always)
|
||||
internal static func serial(_ label: String, qos: DispatchQoS = .default) -> DispatchQueue {
|
||||
internal static func serial(_ label: String, qos: DispatchQoS) -> DispatchQueue {
|
||||
|
||||
return DispatchQueue(
|
||||
label: label,
|
||||
@@ -43,7 +43,7 @@ extension DispatchQueue {
|
||||
}
|
||||
|
||||
@nonobjc @inline(__always)
|
||||
internal static func concurrent(_ label: String, qos: DispatchQoS = .default) -> DispatchQueue {
|
||||
internal static func concurrent(_ label: String, qos: DispatchQoS) -> DispatchQueue {
|
||||
|
||||
return DispatchQueue(
|
||||
label: label,
|
||||
|
||||
@@ -217,7 +217,8 @@ extension CoreStoreObject {
|
||||
|
||||
guard
|
||||
let object = context.fetchExisting(id) as CoreStoreObject?,
|
||||
let rawObject = object.rawObject
|
||||
let rawObject = object.rawObject,
|
||||
!rawObject.isDeleted
|
||||
else {
|
||||
|
||||
return nil
|
||||
|
||||
@@ -42,6 +42,28 @@ extension From {
|
||||
return self.fetchChain(appending: clause)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `FetchChainBuilder` that `AND`s the specified `Where` clauses. Use this overload if the compiler cannot infer the types when chaining multiple `&&` operators.
|
||||
|
||||
- parameter clauses: the `Where` clauses to create a `FetchChainBuilder` with
|
||||
- returns: a `FetchChainBuilder` that `AND`s the specified `Where` clauses
|
||||
*/
|
||||
public func `where`(combineByAnd clauses: Where<O>...) -> FetchChainBuilder<O> {
|
||||
|
||||
return self.fetchChain(appending: clauses.combinedByAnd())
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `FetchChainBuilder` that `OR`s the specified `Where` clauses. Use this overload if the compiler cannot infer the types when chaining multiple `||` operators.
|
||||
|
||||
- parameter clauses: the `Where` clauses to create a `FetchChainBuilder` with
|
||||
- returns: a `FetchChainBuilder` that `OR`s the specified `Where` clauses
|
||||
*/
|
||||
public func `where`(combineByOr clauses: Where<O>...) -> FetchChainBuilder<O> {
|
||||
|
||||
return self.fetchChain(appending: clauses.combinedByOr())
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `FetchChainBuilder` with a predicate using the specified string format and arguments
|
||||
|
||||
@@ -295,11 +317,6 @@ extension From where O: CoreStoreObject {
|
||||
|
||||
return self.fetchChain(appending: clause(O.meta))
|
||||
}
|
||||
|
||||
public func `where`(combinedByAnd clause: Where<O>, _ others: Where<O>...) -> FetchChainBuilder<O> {
|
||||
|
||||
return self.fetchChain(appending: ([clause] + others).combinedByAnd())
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `QueryChainBuilder` that starts with a `Select` clause created from the specified key path
|
||||
@@ -544,6 +561,28 @@ extension FetchChainBuilder {
|
||||
return self.fetchChain(appending: clause)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `FetchChainBuilder` that `AND`s the specified `Where` clauses. Use this overload if the compiler cannot infer the types when chaining multiple `&&` operators.
|
||||
|
||||
- parameter clauses: the `Where` clauses to create a `FetchChainBuilder` with
|
||||
- returns: a `FetchChainBuilder` that `AND`s the specified `Where` clauses
|
||||
*/
|
||||
public func `where`(combineByAnd clauses: Where<O>...) -> FetchChainBuilder<O> {
|
||||
|
||||
return self.fetchChain(appending: clauses.combinedByAnd())
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `FetchChainBuilder` that `OR`s the specified `Where` clauses. Use this overload if the compiler cannot infer the types when chaining multiple `||` operators.
|
||||
|
||||
- parameter clauses: the `Where` clauses to create a `FetchChainBuilder` with
|
||||
- returns: a `FetchChainBuilder` that `OR`s the specified `Where` clauses
|
||||
*/
|
||||
public func `where`(combineByOr clauses: Where<O>...) -> FetchChainBuilder<O> {
|
||||
|
||||
return self.fetchChain(appending: clauses.combinedByOr())
|
||||
}
|
||||
|
||||
/**
|
||||
Adds a `Where` clause to the `FetchChainBuilder`
|
||||
|
||||
@@ -682,6 +721,28 @@ extension QueryChainBuilder {
|
||||
return self.queryChain(appending: clause)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `FetchChainBuilder` that `AND`s the specified `Where` clauses. Use this overload if the compiler cannot infer the types when chaining multiple `&&` operators.
|
||||
|
||||
- parameter clauses: the `Where` clauses to create a `FetchChainBuilder` with
|
||||
- returns: a `FetchChainBuilder` that `AND`s the specified `Where` clauses
|
||||
*/
|
||||
public func `where`(combineByAnd clauses: Where<O>...) -> QueryChainBuilder<O, R> {
|
||||
|
||||
return self.queryChain(appending: clauses.combinedByAnd())
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `FetchChainBuilder` that `OR`s the specified `Where` clauses. Use this overload if the compiler cannot infer the types when chaining multiple `||` operators.
|
||||
|
||||
- parameter clauses: the `Where` clauses to create a `FetchChainBuilder` with
|
||||
- returns: a `FetchChainBuilder` that `OR`s the specified `Where` clauses
|
||||
*/
|
||||
public func `where`(combineByOr clauses: Where<O>...) -> QueryChainBuilder<O, R> {
|
||||
|
||||
return self.queryChain(appending: clauses.combinedByOr())
|
||||
}
|
||||
|
||||
/**
|
||||
Adds a `Where` clause to the `QueryChainBuilder`
|
||||
|
||||
@@ -957,6 +1018,28 @@ extension SectionMonitorChainBuilder {
|
||||
return self.sectionMonitorChain(appending: clause)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `FetchChainBuilder` that `AND`s the specified `Where` clauses. Use this overload if the compiler cannot infer the types when chaining multiple `&&` operators.
|
||||
|
||||
- parameter clauses: the `Where` clauses to create a `FetchChainBuilder` with
|
||||
- returns: a `FetchChainBuilder` that `AND`s the specified `Where` clauses
|
||||
*/
|
||||
public func `where`(combineByAnd clauses: Where<O>...) -> SectionMonitorChainBuilder<O> {
|
||||
|
||||
return self.sectionMonitorChain(appending: clauses.combinedByAnd())
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `FetchChainBuilder` that `OR`s the specified `Where` clauses. Use this overload if the compiler cannot infer the types when chaining multiple `||` operators.
|
||||
|
||||
- parameter clauses: the `Where` clauses to create a `FetchChainBuilder` with
|
||||
- returns: a `FetchChainBuilder` that `OR`s the specified `Where` clauses
|
||||
*/
|
||||
public func `where`(combineByOr clauses: Where<O>...) -> SectionMonitorChainBuilder<O> {
|
||||
|
||||
return self.sectionMonitorChain(appending: clauses.combinedByOr())
|
||||
}
|
||||
|
||||
/**
|
||||
Adds a `Where` clause to the `SectionMonitorChainBuilder`
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ import CoreData
|
||||
)
|
||||
```
|
||||
*/
|
||||
public protocol ImportableUniqueObject: ImportableObject {
|
||||
public protocol ImportableUniqueObject: ImportableObject, Hashable {
|
||||
|
||||
/**
|
||||
The data type for the entity's unique ID attribute
|
||||
|
||||
@@ -78,7 +78,7 @@ extension Internals {
|
||||
|
||||
var numberOfItems: Int {
|
||||
|
||||
return self.structure.allItemIDs.count
|
||||
return self.structure.allItemsCount
|
||||
}
|
||||
|
||||
var numberOfSections: Int {
|
||||
@@ -106,6 +106,59 @@ extension Internals {
|
||||
return self.itemIdentifiers(inSection: identifier).count
|
||||
}
|
||||
|
||||
func itemIdentifier(atAllItemsIndex index: Int) -> NSManagedObjectID? {
|
||||
|
||||
guard index >= 0 else {
|
||||
|
||||
return nil
|
||||
}
|
||||
var remainingIndex = index
|
||||
for section in self.structure.sections {
|
||||
|
||||
let elements = section.elements
|
||||
let sectionCount = elements.count
|
||||
if remainingIndex < sectionCount {
|
||||
|
||||
return elements[remainingIndex].differenceIdentifier
|
||||
}
|
||||
|
||||
remainingIndex -= sectionCount
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func itemIdentifiers(atAllItemsBounds bounds: Range<Int>) -> [NSManagedObjectID] {
|
||||
|
||||
var remainingIndex = bounds.lowerBound
|
||||
var itemIdentifiers: [NSManagedObjectID] = []
|
||||
for section in self.structure.sections {
|
||||
|
||||
let elements = section.elements
|
||||
let sectionCount = elements.count
|
||||
if remainingIndex < sectionCount {
|
||||
|
||||
itemIdentifiers.append(
|
||||
contentsOf: elements[remainingIndex..<min(sectionCount, bounds.count)]
|
||||
.map({ $0.differenceIdentifier })
|
||||
)
|
||||
}
|
||||
else if !itemIdentifiers.isEmpty {
|
||||
|
||||
itemIdentifiers.append(
|
||||
contentsOf: elements.prefix(bounds.count - itemIdentifiers.count)
|
||||
.map({ $0.differenceIdentifier })
|
||||
)
|
||||
}
|
||||
if itemIdentifiers.count >= bounds.count {
|
||||
|
||||
return itemIdentifiers
|
||||
}
|
||||
|
||||
remainingIndex -= sectionCount
|
||||
}
|
||||
return itemIdentifiers
|
||||
}
|
||||
|
||||
func itemIdentifiers(inSection identifier: String) -> [NSManagedObjectID] {
|
||||
|
||||
return self.structure.items(in: identifier)
|
||||
@@ -332,6 +385,14 @@ extension Internals {
|
||||
return self.sections.map({ $0.differenceIdentifier })
|
||||
}
|
||||
|
||||
var allItemsCount: Int {
|
||||
|
||||
return self.sections.reduce(into: 0) { (result, section) in
|
||||
|
||||
result += section.elements.count
|
||||
}
|
||||
}
|
||||
|
||||
var allItemIDs: [NSManagedObjectID] {
|
||||
|
||||
return self.sections.lazy.flatMap({ $0.elements }).map({ $0.differenceIdentifier })
|
||||
|
||||
@@ -267,6 +267,17 @@ public func == <O: NSManagedObject, D: NSManagedObject>(_ keyPath: KeyPath<O, D>
|
||||
return Where<O>(keyPath._kvcKeyPathString!, isEqualTo: objectID)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if a property is equal to a value
|
||||
```
|
||||
let dog = dataStack.fetchOne(From<Dog>().where(\.master == john))
|
||||
```
|
||||
*/
|
||||
public func == <O: ObjectRepresentation, D: NSManagedObject>(_ keyPath: KeyPath<O, D>, _ object: O) -> Where<O> where O.ObjectType: NSManagedObject {
|
||||
|
||||
return Where<O>(keyPath._kvcKeyPathString!, isEqualTo: object.cs_id())
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if a property is not equal to a value
|
||||
```
|
||||
@@ -278,6 +289,17 @@ public func != <O: NSManagedObject, D: NSManagedObject>(_ keyPath: KeyPath<O, D>
|
||||
return !Where<O>(keyPath._kvcKeyPathString!, isEqualTo: objectID)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if a property is not equal to a value
|
||||
```
|
||||
let dog = dataStack.fetchOne(From<Dog>().where(\.master != john))
|
||||
```
|
||||
*/
|
||||
public func != <O: ObjectRepresentation, D: NSManagedObject>(_ keyPath: KeyPath<O, D>, _ object: O) -> Where<O> where O.ObjectType: NSManagedObject {
|
||||
|
||||
return !Where<O>(keyPath._kvcKeyPathString!, isEqualTo: object.cs_id())
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by checking if a sequence contains a value of a property
|
||||
```
|
||||
@@ -303,6 +325,17 @@ public func == <O: NSManagedObject, D: NSManagedObject>(_ keyPath: KeyPath<O, Op
|
||||
return Where<O>(keyPath._kvcKeyPathString!, isEqualTo: object)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if a property is equal to a value
|
||||
```
|
||||
let dog = dataStack.fetchOne(From<Dog>().where(\.master == john))
|
||||
```
|
||||
*/
|
||||
public func == <O: ObjectRepresentation, D: NSManagedObject>(_ keyPath: KeyPath<O, Optional<D>>, _ object: O?) -> Where<O> where O.ObjectType: NSManagedObject {
|
||||
|
||||
return Where<O>(keyPath._kvcKeyPathString!, isEqualTo: object?.cs_toRaw())
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if a property is not equal to a value
|
||||
```
|
||||
@@ -314,6 +347,17 @@ public func != <O: NSManagedObject, D: NSManagedObject>(_ keyPath: KeyPath<O, Op
|
||||
return !Where<O>(keyPath._kvcKeyPathString!, isEqualTo: object)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if a property is not equal to a value
|
||||
```
|
||||
let dog = dataStack.fetchOne(From<Dog>().where(\.master != john))
|
||||
```
|
||||
*/
|
||||
public func != <O: ObjectRepresentation, D: NSManagedObject>(_ keyPath: KeyPath<O, Optional<D>>, _ object: O?) -> Where<O> where O.ObjectType: NSManagedObject {
|
||||
|
||||
return !Where<O>(keyPath._kvcKeyPathString!, isEqualTo: object?.cs_toRaw())
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by checking if a sequence contains a value of a property
|
||||
```
|
||||
@@ -395,6 +439,155 @@ public func ~= <O, V, S: Sequence>(_ sequence: S, _ keyPath: KeyPath<O, FieldCon
|
||||
}
|
||||
|
||||
|
||||
// MARK: - KeyPath where Root: CoreStoreObject, Value: FieldContainer<Root>.Stored<QueryableAttributeType & Comparable>
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if a property is less than a value
|
||||
```
|
||||
let person = dataStack.fetchOne(From<Person>().where(\.$age < 20))
|
||||
```
|
||||
*/
|
||||
public func < <O, V: Comparable>(_ keyPath: KeyPath<O, FieldContainer<O>.Stored<V>>, _ value: V) -> Where<O> {
|
||||
|
||||
return Where<O>("%K < %@", O.meta[keyPath: keyPath].keyPath, value.cs_toFieldStoredNativeType() as! V.FieldStoredNativeType)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if a property is less than a value
|
||||
```
|
||||
let person = dataStack.fetchOne(From<Person>().where(\.$age < 20))
|
||||
```
|
||||
*/
|
||||
public func < <O, V: FieldOptionalType>(_ keyPath: KeyPath<O, FieldContainer<O>.Stored<V>>, _ value: V) -> Where<O> where V.Wrapped: Comparable {
|
||||
|
||||
return Where<O>("%K < %@", O.meta[keyPath: keyPath].keyPath, value.cs_toFieldStoredNativeType() as! V.FieldStoredNativeType)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if a property is greater than a value
|
||||
```
|
||||
let person = dataStack.fetchOne(From<Person>().where(\.$age > 20))
|
||||
```
|
||||
*/
|
||||
public func > <O, V: Comparable>(_ keyPath: KeyPath<O, FieldContainer<O>.Stored<V>>, _ value: V) -> Where<O> {
|
||||
|
||||
return Where<O>("%K > %@", O.meta[keyPath: keyPath].keyPath, value.cs_toFieldStoredNativeType() as! V.FieldStoredNativeType)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if a property is greater than a value
|
||||
```
|
||||
let person = dataStack.fetchOne(From<Person>().where(\.$age > 20))
|
||||
```
|
||||
*/
|
||||
public func > <O, V: FieldOptionalType>(_ keyPath: KeyPath<O, FieldContainer<O>.Stored<V>>, _ value: V) -> Where<O> where V.Wrapped: Comparable {
|
||||
|
||||
return Where<O>("%K > %@", O.meta[keyPath: keyPath].keyPath, value.cs_toFieldStoredNativeType() as! V.FieldStoredNativeType)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if a property is less than or equal to a value
|
||||
```
|
||||
let person = dataStack.fetchOne(From<Person>().where(\.$age <= 20))
|
||||
```
|
||||
*/
|
||||
public func <= <O, V: Comparable>(_ keyPath: KeyPath<O, FieldContainer<O>.Stored<V>>, _ value: V) -> Where<O> {
|
||||
|
||||
return Where<O>("%K <= %@", O.meta[keyPath: keyPath].keyPath, value.cs_toFieldStoredNativeType() as! V.FieldStoredNativeType)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if a property is less than or equal to a value
|
||||
```
|
||||
let person = dataStack.fetchOne(From<Person>().where(\.$age <= 20))
|
||||
```
|
||||
*/
|
||||
public func <= <O, V: FieldOptionalType>(_ keyPath: KeyPath<O, FieldContainer<O>.Stored<V>>, _ value: V) -> Where<O> where V.Wrapped: Comparable {
|
||||
|
||||
return Where<O>("%K <= %@", O.meta[keyPath: keyPath].keyPath, value.cs_toFieldStoredNativeType() as! V.FieldStoredNativeType)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if a property is greater than or equal to a value
|
||||
```
|
||||
let person = dataStack.fetchOne(From<Person>().where(\.$age >= 20))
|
||||
```
|
||||
*/
|
||||
public func >= <O, V: Comparable>(_ keyPath: KeyPath<O, FieldContainer<O>.Stored<V>>, _ value: V) -> Where<O> {
|
||||
|
||||
return Where<O>("%K >= %@", O.meta[keyPath: keyPath].keyPath, value.cs_toFieldStoredNativeType() as! V.FieldStoredNativeType)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if a property is greater than or equal to a value
|
||||
```
|
||||
let person = dataStack.fetchOne(From<Person>().where(\.$age >= 20))
|
||||
```
|
||||
*/
|
||||
public func >= <O, V: FieldOptionalType>(_ keyPath: KeyPath<O, FieldContainer<O>.Stored<V>>, _ value: V) -> Where<O> where V.Wrapped: Comparable {
|
||||
|
||||
return Where<O>("%K >= %@", O.meta[keyPath: keyPath].keyPath, value.cs_toFieldStoredNativeType() as! V.FieldStoredNativeType)
|
||||
}
|
||||
|
||||
|
||||
// MARK: - KeyPath where Root: CoreStoreObject, Value: FieldContainer<Root>.Relationship<CoreStoreObject>
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if a property is equal to a value
|
||||
```
|
||||
let dog = dataStack.fetchOne(From<Dog>().where(\.$master == john))
|
||||
```
|
||||
*/
|
||||
public func == <O, D: FieldRelationshipToOneType>(_ keyPath: KeyPath<O, FieldContainer<O>.Relationship<D>>, _ object: D.DestinationObjectType?) -> Where<O> {
|
||||
|
||||
return Where<O>(O.meta[keyPath: keyPath].keyPath, isEqualTo: object)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if a property is equal to a value
|
||||
```
|
||||
let dog = dataStack.fetchOne(From<Dog>().where(\.master == john))
|
||||
```
|
||||
*/
|
||||
public func == <O, D: FieldRelationshipToOneType, R: ObjectRepresentation>(_ keyPath: KeyPath<O, FieldContainer<O>.Relationship<D>>, _ object: R?) -> Where<O> where D.DestinationObjectType == R.ObjectType {
|
||||
|
||||
return Where<O>(O.meta[keyPath: keyPath].keyPath, isEqualTo: object?.objectID())
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if a property is not equal to a value
|
||||
```
|
||||
let dog = dataStack.fetchOne(From<Dog>().where(\.$master != john))
|
||||
```
|
||||
*/
|
||||
public func != <O, D: FieldRelationshipToOneType>(_ keyPath: KeyPath<O, FieldContainer<O>.Relationship<D>>, _ object: D.DestinationObjectType?) -> Where<O> {
|
||||
|
||||
return !Where<O>(O.meta[keyPath: keyPath].keyPath, isEqualTo: object)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if a property is not equal to a value
|
||||
```
|
||||
let dog = dataStack.fetchOne(From<Dog>().where(\.master != john))
|
||||
```
|
||||
*/
|
||||
public func != <O, D: FieldRelationshipToOneType, R: ObjectRepresentation>(_ keyPath: KeyPath<O, FieldContainer<O>.Relationship<D>>, _ object: R?) -> Where<O> where D.DestinationObjectType == R.ObjectType {
|
||||
|
||||
return !Where<O>(O.meta[keyPath: keyPath].keyPath, isEqualTo: object?.objectID())
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by checking if a sequence contains a value of a property
|
||||
```
|
||||
let dog = dataStack.fetchOne(From<Dog>().where([john, bob, joe] ~= \.$master))
|
||||
```
|
||||
*/
|
||||
public func ~= <O, D: FieldRelationshipToOneType, S: Sequence>(_ sequence: S, _ keyPath: KeyPath<O, FieldContainer<O>.Relationship<D>>) -> Where<O> where S.Iterator.Element == D.DestinationObjectType {
|
||||
|
||||
return Where<O>(O.meta[keyPath: keyPath].keyPath, isMemberOf: sequence)
|
||||
}
|
||||
|
||||
|
||||
// MARK: - KeyPath where Root: CoreStoreObject, Value: ValueContainer<Root>.Required<QueryableAttributeType & Equatable>
|
||||
|
||||
/**
|
||||
@@ -469,17 +662,6 @@ public func ~= <O, V, S: Sequence>(_ sequence: S, _ keyPath: KeyPath<O, ValueCon
|
||||
|
||||
// MARK: - KeyPath where Root: CoreStoreObject, Value: ValueContainer<Root>.Required<QueryableAttributeType & Comparable>
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if a property is less than a value
|
||||
```
|
||||
let person = dataStack.fetchOne(From<Person>().where(\.$age < 20))
|
||||
```
|
||||
*/
|
||||
public func < <O, V: Comparable>(_ keyPath: KeyPath<O, FieldContainer<O>.Stored<V>>, _ value: V) -> Where<O> {
|
||||
|
||||
return Where<O>("%K < %@", O.meta[keyPath: keyPath].keyPath, value.cs_toFieldStoredNativeType() as! V.FieldStoredNativeType)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if a property is less than a value
|
||||
```
|
||||
@@ -491,17 +673,6 @@ public func < <O, V: Comparable>(_ keyPath: KeyPath<O, ValueContainer<O>.Require
|
||||
return Where<O>("%K < %@", O.meta[keyPath: keyPath].keyPath, value.cs_toQueryableNativeType())
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if a property is greater than a value
|
||||
```
|
||||
let person = dataStack.fetchOne(From<Person>().where(\.$age > 20))
|
||||
```
|
||||
*/
|
||||
public func > <O, V: Comparable>(_ keyPath: KeyPath<O, FieldContainer<O>.Stored<V>>, _ value: V) -> Where<O> {
|
||||
|
||||
return Where<O>("%K > %@", O.meta[keyPath: keyPath].keyPath, value.cs_toFieldStoredNativeType() as! V.FieldStoredNativeType)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if a property is greater than a value
|
||||
```
|
||||
@@ -513,17 +684,6 @@ public func > <O, V: Comparable>(_ keyPath: KeyPath<O, ValueContainer<O>.Require
|
||||
return Where<O>("%K > %@", O.meta[keyPath: keyPath].keyPath, value.cs_toQueryableNativeType())
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if a property is less than or equal to a value
|
||||
```
|
||||
let person = dataStack.fetchOne(From<Person>().where(\.$age <= 20))
|
||||
```
|
||||
*/
|
||||
public func <= <O, V: Comparable>(_ keyPath: KeyPath<O, FieldContainer<O>.Stored<V>>, _ value: V) -> Where<O> {
|
||||
|
||||
return Where<O>("%K <= %@", O.meta[keyPath: keyPath].keyPath, value.cs_toFieldStoredNativeType() as! V.FieldStoredNativeType)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if a property is less than or equal to a value
|
||||
```
|
||||
@@ -535,17 +695,6 @@ public func <= <O, V: Comparable>(_ keyPath: KeyPath<O, ValueContainer<O>.Requir
|
||||
return Where<O>("%K <= %@", O.meta[keyPath: keyPath].keyPath, value.cs_toQueryableNativeType())
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if a property is greater than or equal to a value
|
||||
```
|
||||
let person = dataStack.fetchOne(From<Person>().where(\.$age >= 20))
|
||||
```
|
||||
*/
|
||||
public func >= <O, V: Comparable>(_ keyPath: KeyPath<O, FieldContainer<O>.Stored<V>>, _ value: V) -> Where<O> {
|
||||
|
||||
return Where<O>("%K >= %@", O.meta[keyPath: keyPath].keyPath, value.cs_toFieldStoredNativeType() as! V.FieldStoredNativeType)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if a property is greater than or equal to a value
|
||||
```
|
||||
@@ -560,17 +709,6 @@ public func >= <O, V: Comparable>(_ keyPath: KeyPath<O, ValueContainer<O>.Requir
|
||||
|
||||
// MARK: - KeyPath where Root: CoreStoreObject, Value: ValueContainer<Root>.Optional<QueryableAttributeType & Comparable>
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if a property is less than a value
|
||||
```
|
||||
let person = dataStack.fetchOne(From<Person>().where(\.$age < 20))
|
||||
```
|
||||
*/
|
||||
public func < <O, V: FieldOptionalType>(_ keyPath: KeyPath<O, FieldContainer<O>.Stored<V>>, _ value: V) -> Where<O> where V.Wrapped: Comparable {
|
||||
|
||||
return Where<O>("%K < %@", O.meta[keyPath: keyPath].keyPath, value.cs_toFieldStoredNativeType() as! V.FieldStoredNativeType)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if a property is less than a value
|
||||
```
|
||||
@@ -589,17 +727,6 @@ public func < <O, V>(_ keyPath: KeyPath<O, ValueContainer<O>.Optional<V>>, _ val
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if a property is greater than a value
|
||||
```
|
||||
let person = dataStack.fetchOne(From<Person>().where(\.$age > 20))
|
||||
```
|
||||
*/
|
||||
public func > <O, V: FieldOptionalType>(_ keyPath: KeyPath<O, FieldContainer<O>.Stored<V>>, _ value: V) -> Where<O> where V.Wrapped: Comparable {
|
||||
|
||||
return Where<O>("%K > %@", O.meta[keyPath: keyPath].keyPath, value.cs_toFieldStoredNativeType() as! V.FieldStoredNativeType)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if a property is greater than a value
|
||||
```
|
||||
@@ -618,17 +745,6 @@ public func > <O, V>(_ keyPath: KeyPath<O, ValueContainer<O>.Optional<V>>, _ val
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if a property is less than or equal to a value
|
||||
```
|
||||
let person = dataStack.fetchOne(From<Person>().where(\.$age <= 20))
|
||||
```
|
||||
*/
|
||||
public func <= <O, V: FieldOptionalType>(_ keyPath: KeyPath<O, FieldContainer<O>.Stored<V>>, _ value: V) -> Where<O> where V.Wrapped: Comparable {
|
||||
|
||||
return Where<O>("%K <= %@", O.meta[keyPath: keyPath].keyPath, value.cs_toFieldStoredNativeType() as! V.FieldStoredNativeType)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if a property is less than or equal to a value
|
||||
```
|
||||
@@ -647,17 +763,6 @@ public func <= <O, V>(_ keyPath: KeyPath<O, ValueContainer<O>.Optional<V>>, _ va
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if a property is greater than or equal to a value
|
||||
```
|
||||
let person = dataStack.fetchOne(From<Person>().where(\.$age >= 20))
|
||||
```
|
||||
*/
|
||||
public func >= <O, V: FieldOptionalType>(_ keyPath: KeyPath<O, FieldContainer<O>.Stored<V>>, _ value: V) -> Where<O> where V.Wrapped: Comparable {
|
||||
|
||||
return Where<O>("%K >= %@", O.meta[keyPath: keyPath].keyPath, value.cs_toFieldStoredNativeType() as! V.FieldStoredNativeType)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if a property is greater than or equal to a value
|
||||
```
|
||||
@@ -679,17 +784,6 @@ public func >= <O, V>(_ keyPath: KeyPath<O, ValueContainer<O>.Optional<V>>, _ va
|
||||
|
||||
// MARK: - KeyPath where Root: CoreStoreObject, Value: RelationshipContainer<Root>.ToOne<CoreStoreObject>
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if a property is equal to a value
|
||||
```
|
||||
let dog = dataStack.fetchOne(From<Dog>().where(\.$master == john))
|
||||
```
|
||||
*/
|
||||
public func == <O, D: FieldRelationshipToOneType>(_ keyPath: KeyPath<O, FieldContainer<O>.Relationship<D>>, _ object: D.DestinationObjectType?) -> Where<O> {
|
||||
|
||||
return Where<O>(O.meta[keyPath: keyPath].keyPath, isEqualTo: object)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if a property is equal to a value
|
||||
```
|
||||
@@ -712,17 +806,6 @@ public func == <O, D>(_ keyPath: KeyPath<O, RelationshipContainer<O>.ToOne<D>>,
|
||||
return Where<O>(O.meta[keyPath: keyPath].keyPath, isEqualTo: object)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if a property is not equal to a value
|
||||
```
|
||||
let dog = dataStack.fetchOne(From<Dog>().where(\.$master != john))
|
||||
```
|
||||
*/
|
||||
public func != <O, D: FieldRelationshipToOneType>(_ keyPath: KeyPath<O, FieldContainer<O>.Relationship<D>>, _ object: D.DestinationObjectType?) -> Where<O> {
|
||||
|
||||
return !Where<O>(O.meta[keyPath: keyPath].keyPath, isEqualTo: object)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if a property is not equal to a value
|
||||
```
|
||||
@@ -745,17 +828,6 @@ public func != <O, D>(_ keyPath: KeyPath<O, RelationshipContainer<O>.ToOne<D>>,
|
||||
return !Where<O>(O.meta[keyPath: keyPath].keyPath, isEqualTo: object)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by checking if a sequence contains a value of a property
|
||||
```
|
||||
let dog = dataStack.fetchOne(From<Dog>().where([john, bob, joe] ~= \.$master))
|
||||
```
|
||||
*/
|
||||
public func ~= <O, D: FieldRelationshipToOneType, S: Sequence>(_ sequence: S, _ keyPath: KeyPath<O, FieldContainer<O>.Relationship<D>>) -> Where<O> where S.Iterator.Element == D.DestinationObjectType {
|
||||
|
||||
return Where<O>(O.meta[keyPath: keyPath].keyPath, isMemberOf: sequence)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by checking if a sequence contains a value of a property
|
||||
```
|
||||
|
||||
@@ -71,7 +71,7 @@ public struct ListSnapshot<O: DynamicObject>: RandomAccessCollection, Hashable {
|
||||
public subscript(index: Index) -> ObjectPublisher<O> {
|
||||
|
||||
let context = self.context!
|
||||
let itemID = self.diffableSnapshot.itemIdentifiers[index]
|
||||
let itemID = self.diffableSnapshot.itemIdentifier(atAllItemsIndex: index)!
|
||||
return context.objectPublisher(objectID: itemID)
|
||||
}
|
||||
|
||||
@@ -83,16 +83,13 @@ public struct ListSnapshot<O: DynamicObject>: RandomAccessCollection, Hashable {
|
||||
*/
|
||||
public subscript(safeIndex index: Index) -> ObjectPublisher<O>? {
|
||||
|
||||
guard let context = self.context else {
|
||||
guard
|
||||
let context = self.context,
|
||||
let itemID = self.diffableSnapshot.itemIdentifier(atAllItemsIndex: index)
|
||||
else {
|
||||
|
||||
return nil
|
||||
}
|
||||
let itemIDs = self.diffableSnapshot.itemIdentifiers
|
||||
guard itemIDs.indices.contains(index) else {
|
||||
|
||||
return nil
|
||||
}
|
||||
let itemID = itemIDs[index]
|
||||
return context.objectPublisher(objectID: itemID)
|
||||
}
|
||||
|
||||
@@ -597,20 +594,74 @@ public struct ListSnapshot<O: DynamicObject>: RandomAccessCollection, Hashable {
|
||||
self.diffableSnapshot.reloadSections(sectionIDs)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// MARK: RandomAccessCollection
|
||||
|
||||
public var startIndex: Index {
|
||||
|
||||
return self.diffableSnapshot.itemIdentifiers.startIndex
|
||||
return 0
|
||||
}
|
||||
|
||||
public var endIndex: Index {
|
||||
|
||||
return self.diffableSnapshot.itemIdentifiers.endIndex
|
||||
return self.diffableSnapshot.numberOfItems
|
||||
}
|
||||
|
||||
|
||||
public func index(after i: Index) -> Index {
|
||||
|
||||
return i + 1
|
||||
}
|
||||
|
||||
public func formIndex(after i: inout Index) {
|
||||
|
||||
return i += 1
|
||||
}
|
||||
|
||||
public func index(before i: Index) -> Index {
|
||||
|
||||
return i - 1
|
||||
}
|
||||
|
||||
public func formIndex(before i: inout Index) {
|
||||
|
||||
return i -= 1
|
||||
}
|
||||
|
||||
|
||||
// MARK: BidirectionalCollection
|
||||
|
||||
public func index(_ i: Index, offsetBy distance: Int) -> Index {
|
||||
|
||||
return i + distance
|
||||
}
|
||||
|
||||
public func index(_ i: Index, offsetBy distance: Int, limitedBy limit: Int) -> Index? {
|
||||
|
||||
let length = limit - i
|
||||
if distance > 0
|
||||
? length >= 0 && length < distance
|
||||
: length <= 0 && length > distance {
|
||||
|
||||
return nil
|
||||
}
|
||||
return i + distance
|
||||
}
|
||||
|
||||
public func distance(from start: Index, to end: Index) -> Int {
|
||||
|
||||
return end - start
|
||||
}
|
||||
|
||||
public subscript(bounds: Range<Index>) -> ArraySlice<Element> {
|
||||
|
||||
guard let context = self.context else {
|
||||
|
||||
return .init()
|
||||
}
|
||||
let itemIDs = self.diffableSnapshot.itemIdentifiers(atAllItemsBounds: bounds)
|
||||
return ArraySlice(itemIDs.map(context.objectPublisher(objectID:)))
|
||||
}
|
||||
|
||||
|
||||
// MARK: Sequence
|
||||
|
||||
|
||||
@@ -40,12 +40,7 @@ import CoreData
|
||||
Observers registered via `addObserver(_:)` are not retained. `ObjectMonitor` only keeps a `weak` reference to all observers, thus keeping itself free from retain-cycles.
|
||||
*/
|
||||
@available(macOS 10.12, *)
|
||||
public final class ObjectMonitor<O: DynamicObject>: Equatable {
|
||||
|
||||
/**
|
||||
The object type represented by this `ObjectMonitor`
|
||||
*/
|
||||
public typealias ObjectType = O
|
||||
public final class ObjectMonitor<O: DynamicObject>: Hashable, ObjectRepresentation {
|
||||
|
||||
/**
|
||||
Returns the `DynamicObject` instance being observed, or `nil` if the object was already deleted.
|
||||
@@ -156,6 +151,51 @@ public final class ObjectMonitor<O: DynamicObject>: Equatable {
|
||||
}
|
||||
|
||||
|
||||
// MARK: AnyObjectRepresentation
|
||||
|
||||
public func objectID() -> O.ObjectID {
|
||||
|
||||
return self.id
|
||||
}
|
||||
|
||||
public func cs_dataStack() -> DataStack? {
|
||||
|
||||
return self.context.parentStack
|
||||
}
|
||||
|
||||
|
||||
// MARK: ObjectRepresentation
|
||||
|
||||
public typealias ObjectType = O
|
||||
|
||||
public func asPublisher(in dataStack: DataStack) -> ObjectPublisher<O> {
|
||||
|
||||
return dataStack.unsafeContext().objectPublisher(objectID: self.id)
|
||||
}
|
||||
|
||||
public func asReadOnly(in dataStack: DataStack) -> O? {
|
||||
|
||||
return dataStack.unsafeContext().fetchExisting(self.id)
|
||||
}
|
||||
|
||||
public func asEditable(in transaction: BaseDataTransaction) -> O? {
|
||||
|
||||
return transaction.unsafeContext().fetchExisting(self.id)
|
||||
}
|
||||
|
||||
public func asSnapshot(in dataStack: DataStack) -> ObjectSnapshot<O>? {
|
||||
|
||||
let context = dataStack.unsafeContext()
|
||||
return ObjectSnapshot<O>(objectID: self.id, context: context)
|
||||
}
|
||||
|
||||
public func asSnapshot(in transaction: BaseDataTransaction) -> ObjectSnapshot<O>? {
|
||||
|
||||
let context = transaction.unsafeContext()
|
||||
return ObjectSnapshot<O>(objectID: self.id, context: context)
|
||||
}
|
||||
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
internal init(objectID: O.ObjectID, context: NSManagedObjectContext) {
|
||||
|
||||
@@ -125,15 +125,23 @@ public final class ObjectPublisher<O: DynamicObject>: ObjectRepresentation, Hash
|
||||
}
|
||||
|
||||
|
||||
// MARK: ObjectRepresentation
|
||||
|
||||
public typealias ObjectType = O
|
||||
// MARK: AnyObjectRepresentation
|
||||
|
||||
public func objectID() -> O.ObjectID {
|
||||
|
||||
return self.id
|
||||
}
|
||||
|
||||
public func cs_dataStack() -> DataStack? {
|
||||
|
||||
return self.context.parentStack
|
||||
}
|
||||
|
||||
|
||||
// MARK: ObjectRepresentation
|
||||
|
||||
public typealias ObjectType = O
|
||||
|
||||
public func asPublisher(in dataStack: DataStack) -> ObjectPublisher<O> {
|
||||
|
||||
let context = dataStack.unsafeContext()
|
||||
@@ -449,20 +457,18 @@ extension ObjectPublisher where O: NSManagedObject {
|
||||
/**
|
||||
Returns the value for the property identified by a given key.
|
||||
*/
|
||||
@available(*, unavailable, message: "KeyPaths accessed from @dynamicMemberLookup types can't generate KVC keys yet (https://bugs.swift.org/browse/SR-11351)")
|
||||
public subscript<V: AllowedObjectiveCKeyPathValue>(dynamicMember member: KeyPath<O, V>) -> V {
|
||||
public subscript<V: AllowedObjectiveCKeyPathValue>(dynamicMember member: KeyPath<O, V>) -> V! {
|
||||
|
||||
fatalError()
|
||||
// return self.snapshot[dynamicMember: member]
|
||||
return self.snapshot?[dynamicMember: member]
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the value for the property identified by a given key.
|
||||
*/
|
||||
|
||||
// MARK: Deprecated
|
||||
|
||||
@available(*, deprecated, message: "Accessing the property directly now works")
|
||||
public func value<V: AllowedObjectiveCKeyPathValue>(forKeyPath keyPath: KeyPath<O, V>) -> V! {
|
||||
|
||||
let key = String(keyPath: keyPath)
|
||||
return self.snapshot?.dictionaryForValues()[key] as! V?
|
||||
return self[dynamicMember: keyPath]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
100
Sources/ObjectReader.swift
Normal file
100
Sources/ObjectReader.swift
Normal file
@@ -0,0 +1,100 @@
|
||||
//
|
||||
// ListState.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Created by John Rommel Estropia on 2020/12/26.
|
||||
// Copyright © 2020 John Rommel Estropia. All rights reserved.
|
||||
//
|
||||
|
||||
#if canImport(Combine) && canImport(SwiftUI)
|
||||
|
||||
import Combine
|
||||
import SwiftUI
|
||||
|
||||
|
||||
// MARK: - ObjectReader
|
||||
|
||||
@available(iOS 13.0, tvOS 13.0, watchOS 6.0, macOS 10.15, *)
|
||||
public struct ObjectReader<Object: DynamicObject, Content: View, Placeholder: View>: View {
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
public init(
|
||||
_ objectPublisher: ObjectPublisher<Object>?,
|
||||
@ViewBuilder content: @escaping (ObjectSnapshot<Object>) -> Content,
|
||||
@ViewBuilder placeholder: @escaping () -> Placeholder
|
||||
) {
|
||||
|
||||
self.objectPublisher = .init(
|
||||
objectPublisher.flatMap {
|
||||
|
||||
guard let dataStack = $0.cs_dataStack() else {
|
||||
|
||||
return nil
|
||||
}
|
||||
return $0.asPublisher(in: dataStack)
|
||||
}
|
||||
)
|
||||
self.content = content
|
||||
self.placeholder = placeholder
|
||||
}
|
||||
|
||||
public init(
|
||||
_ objectPublisher: ObjectPublisher<Object>?,
|
||||
@ViewBuilder content: @escaping (ObjectSnapshot<Object>) -> Content
|
||||
) where Placeholder == EmptyView {
|
||||
|
||||
self.init(
|
||||
objectPublisher,
|
||||
content: content,
|
||||
placeholder: EmptyView.init
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
// MARK: View
|
||||
|
||||
public var body: some View {
|
||||
|
||||
if let snapshot = self.objectPublisher.wrappedValue?.snapshot {
|
||||
|
||||
self.content(snapshot)
|
||||
}
|
||||
else {
|
||||
|
||||
self.placeholder()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: Private
|
||||
|
||||
@ObservedObject
|
||||
private var objectPublisher: OptionalObservedObject<ObjectPublisher<Object>>
|
||||
|
||||
private let content: (ObjectSnapshot<Object>) -> Content
|
||||
private let placeholder: () -> Placeholder
|
||||
|
||||
|
||||
// MARK: - OptionalObservedObject
|
||||
|
||||
fileprivate final class OptionalObservedObject<T: ObservableObject>: ObservableObject where ObservableObjectPublisher == T.ObjectWillChangePublisher {
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
let wrappedValue: T?
|
||||
|
||||
init(_ wrappedValue: T?) {
|
||||
|
||||
self.wrappedValue = wrappedValue
|
||||
self.objectWillChange = wrappedValue.map(\.objectWillChange) ?? .init()
|
||||
}
|
||||
|
||||
// MARK: ObservableObject
|
||||
|
||||
let objectWillChange: ObservableObjectPublisher
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -26,23 +26,37 @@
|
||||
import CoreData
|
||||
|
||||
|
||||
// MARK: - AnyObjectRepresentation
|
||||
|
||||
/**
|
||||
Used internally by CoreStore. Do not conform to directly.
|
||||
*/
|
||||
public protocol AnyObjectRepresentation {
|
||||
|
||||
/**
|
||||
The internal ID for the object.
|
||||
*/
|
||||
func objectID() -> NSManagedObjectID
|
||||
|
||||
/**
|
||||
Used internally by CoreStore. Do not call directly.
|
||||
*/
|
||||
func cs_dataStack() -> DataStack?
|
||||
}
|
||||
|
||||
|
||||
// MARK - ObjectRepresentation
|
||||
|
||||
/**
|
||||
An object that acts as interfaces for `CoreStoreObject`s or `NSManagedObject`s
|
||||
*/
|
||||
public protocol ObjectRepresentation {
|
||||
public protocol ObjectRepresentation: AnyObjectRepresentation {
|
||||
|
||||
/**
|
||||
The object type represented by this protocol
|
||||
*/
|
||||
associatedtype ObjectType: DynamicObject
|
||||
|
||||
/**
|
||||
The internal ID for the object.
|
||||
*/
|
||||
func objectID() -> ObjectType.ObjectID
|
||||
|
||||
/**
|
||||
An instance that may be observed for object changes.
|
||||
*/
|
||||
@@ -96,14 +110,22 @@ extension DynamicObject where Self: ObjectRepresentation {
|
||||
.managedObjectContext
|
||||
.flatMap({ ObjectSnapshot<Self>(objectID: self.cs_id(), context: $0) })
|
||||
}
|
||||
|
||||
|
||||
// MARK: ObjectRepresentation
|
||||
|
||||
|
||||
|
||||
// MARK: AnyObjectRepresentation
|
||||
|
||||
public func objectID() -> Self.ObjectID {
|
||||
|
||||
return self.cs_id()
|
||||
}
|
||||
|
||||
public func cs_dataStack() -> DataStack? {
|
||||
|
||||
return self.cs_toRaw().managedObjectContext?.parentStack
|
||||
}
|
||||
|
||||
|
||||
// MARK: ObjectRepresentation
|
||||
|
||||
public func asPublisher(in dataStack: DataStack) -> ObjectPublisher<Self> {
|
||||
|
||||
|
||||
@@ -48,17 +48,25 @@ public struct ObjectSnapshot<O: DynamicObject>: ObjectRepresentation, Hashable {
|
||||
|
||||
return self.values
|
||||
}
|
||||
|
||||
|
||||
// MARK: ObjectRepresentation
|
||||
|
||||
public typealias ObjectType = O
|
||||
|
||||
// MARK: AnyObjectRepresentation
|
||||
|
||||
public func objectID() -> O.ObjectID {
|
||||
|
||||
return self.id
|
||||
}
|
||||
|
||||
public func cs_dataStack() -> DataStack? {
|
||||
|
||||
return self.context.parentStack
|
||||
}
|
||||
|
||||
|
||||
// MARK: ObjectRepresentation
|
||||
|
||||
public typealias ObjectType = O
|
||||
|
||||
public func asPublisher(in dataStack: DataStack) -> ObjectPublisher<O> {
|
||||
|
||||
let context = dataStack.unsafeContext()
|
||||
@@ -93,7 +101,7 @@ public struct ObjectSnapshot<O: DynamicObject>: ObjectRepresentation, Hashable {
|
||||
public static func == (_ lhs: Self, _ rhs: Self) -> Bool {
|
||||
|
||||
return lhs.id == rhs.id
|
||||
&& lhs.valuesRef == rhs.valuesRef
|
||||
&& (lhs.generation == rhs.generation || lhs.valuesRef == rhs.valuesRef)
|
||||
}
|
||||
|
||||
|
||||
@@ -117,18 +125,27 @@ public struct ObjectSnapshot<O: DynamicObject>: ObjectRepresentation, Hashable {
|
||||
self.id = objectID
|
||||
self.context = context
|
||||
self.values = values
|
||||
self.generation = .init()
|
||||
}
|
||||
|
||||
|
||||
// MARK: FilePrivate
|
||||
|
||||
fileprivate var values: [String: Any]
|
||||
fileprivate var values: [String: Any] {
|
||||
|
||||
didSet {
|
||||
|
||||
self.generation = .init()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private let id: O.ObjectID
|
||||
private let context: NSManagedObjectContext
|
||||
|
||||
private var generation: UUID
|
||||
|
||||
private var valuesRef: NSDictionary {
|
||||
|
||||
@@ -144,29 +161,33 @@ extension ObjectSnapshot where O: NSManagedObject {
|
||||
/**
|
||||
Returns the value for the property identified by a given key.
|
||||
*/
|
||||
@available(*, unavailable, message: "KeyPaths accessed from @dynamicMemberLookup types can't generate KVC keys yet (https://bugs.swift.org/browse/SR-11351)")
|
||||
public subscript<V: AllowedObjectiveCKeyPathValue>(dynamicMember member: KeyPath<O, V>) -> V {
|
||||
public subscript<V: AllowedObjectiveCKeyPathValue>(dynamicMember member: KeyPath<O, V>) -> V! {
|
||||
|
||||
let key = String(keyPath: member)
|
||||
return self.values[key] as! V
|
||||
get {
|
||||
|
||||
let key = String(keyPath: member)
|
||||
return self.values[key] as! V?
|
||||
}
|
||||
set {
|
||||
|
||||
let key = String(keyPath: member)
|
||||
self.values[key] = newValue
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the value for the property identified by a given key.
|
||||
*/
|
||||
|
||||
// MARK: Deprecated
|
||||
|
||||
@available(*, deprecated, message: "Accessing the property directly now works")
|
||||
public func value<V: AllowedObjectiveCKeyPathValue>(forKeyPath keyPath: KeyPath<O, V>) -> V! {
|
||||
|
||||
let key = String(keyPath: keyPath)
|
||||
return self.values[key] as! V?
|
||||
return self[dynamicMember: keyPath]
|
||||
}
|
||||
|
||||
/**
|
||||
Mutates the value for the property identified by a given key.
|
||||
*/
|
||||
@available(*, deprecated, message: "Mutating the property directly now works")
|
||||
public mutating func setValue<V: AllowedObjectiveCKeyPathValue>(_ value: V!, forKeyPath keyPath: KeyPath<O, V>) {
|
||||
|
||||
let key = String(keyPath: keyPath)
|
||||
self.values[key] = value
|
||||
self[dynamicMember: keyPath] = value
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -469,7 +469,7 @@ extension Where where O: CoreStoreObject {
|
||||
- parameter keyPath: the keyPath to compare with
|
||||
- parameter null: the arguments for the `==` operator
|
||||
*/
|
||||
public init<V>(_ keyPath: KeyPath<O, ValueContainer<O>.Optional<V>>, isEqualTo null: Void?) {
|
||||
public init<V>(_ keyPath: KeyPath<O, FieldContainer<O>.Stored<V>>, isEqualTo null: Void?) {
|
||||
|
||||
self.init(O.meta[keyPath: keyPath].keyPath, isEqualTo: null)
|
||||
}
|
||||
@@ -480,11 +480,44 @@ extension Where where O: CoreStoreObject {
|
||||
- parameter keyPath: the keyPath to compare with
|
||||
- parameter null: the arguments for the `==` operator
|
||||
*/
|
||||
public init<D>(_ keyPath: KeyPath<O, RelationshipContainer<O>.ToOne<D>>, isEqualTo null: Void?) {
|
||||
public init<V: FieldRelationshipToOneType>(_ keyPath: KeyPath<O, FieldContainer<O>.Relationship<V>>, isEqualTo null: Void?) {
|
||||
|
||||
self.init(O.meta[keyPath: keyPath].keyPath, isEqualTo: null)
|
||||
}
|
||||
|
||||
/**
|
||||
Initializes a `Where` clause that compares membership
|
||||
|
||||
- parameter keyPath: the keyPath to compare with
|
||||
- parameter list: the sequence to check membership of
|
||||
*/
|
||||
public init<V, S: Sequence>(_ keyPath: KeyPath<O, FieldContainer<O>.Stored<V>>, isMemberOf list: S) where S.Iterator.Element == V {
|
||||
|
||||
self.init(O.meta[keyPath: keyPath].keyPath, isMemberOf: list)
|
||||
}
|
||||
|
||||
/**
|
||||
Initializes a `Where` clause that compares membership
|
||||
|
||||
- parameter keyPath: the keyPath to compare with
|
||||
- parameter list: the sequence to check membership of
|
||||
*/
|
||||
public init<V: FieldRelationshipToOneType, S: Sequence>(_ keyPath: KeyPath<O, FieldContainer<O>.Relationship<V>>, isMemberOf list: S) where S.Iterator.Element == V.DestinationObjectType {
|
||||
|
||||
self.init(O.meta[keyPath: keyPath].keyPath, isMemberOf: list)
|
||||
}
|
||||
|
||||
/**
|
||||
Initializes a `Where` clause that compares membership
|
||||
|
||||
- parameter keyPath: the keyPath to compare with
|
||||
- parameter list: the sequence to check membership of
|
||||
*/
|
||||
public init<V: FieldRelationshipToOneType, S: Sequence>(_ keyPath: KeyPath<O, FieldContainer<O>.Relationship<V>>, isMemberOf list: S) where S.Iterator.Element: NSManagedObjectID {
|
||||
|
||||
self.init(O.meta[keyPath: keyPath].keyPath, isMemberOf: list)
|
||||
}
|
||||
|
||||
/**
|
||||
Initializes a `Where` clause that compares equality
|
||||
|
||||
@@ -507,6 +540,28 @@ extension Where where O: CoreStoreObject {
|
||||
self.init(O.meta[keyPath: keyPath].keyPath, isEqualTo: value)
|
||||
}
|
||||
|
||||
/**
|
||||
Initializes a `Where` clause that compares equality to `nil`
|
||||
|
||||
- parameter keyPath: the keyPath to compare with
|
||||
- parameter null: the arguments for the `==` operator
|
||||
*/
|
||||
public init<V>(_ keyPath: KeyPath<O, ValueContainer<O>.Optional<V>>, isEqualTo null: Void?) {
|
||||
|
||||
self.init(O.meta[keyPath: keyPath].keyPath, isEqualTo: null)
|
||||
}
|
||||
|
||||
/**
|
||||
Initializes a `Where` clause that compares equality to `nil`
|
||||
|
||||
- parameter keyPath: the keyPath to compare with
|
||||
- parameter null: the arguments for the `==` operator
|
||||
*/
|
||||
public init<D>(_ keyPath: KeyPath<O, RelationshipContainer<O>.ToOne<D>>, isEqualTo null: Void?) {
|
||||
|
||||
self.init(O.meta[keyPath: keyPath].keyPath, isEqualTo: null)
|
||||
}
|
||||
|
||||
/**
|
||||
Initializes a `Where` clause that compares equality
|
||||
|
||||
|
||||
Reference in New Issue
Block a user