mirror of
https://github.com/JohnEstropia/CoreStore.git
synced 2026-03-10 07:06:00 +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|
|
Pod::Spec.new do |s|
|
||||||
s.name = "CoreStore"
|
s.name = "CoreStore"
|
||||||
s.version = "7.3.0"
|
s.version = "7.3.1"
|
||||||
s.swift_version = "5.3"
|
s.swift_version = "5.3"
|
||||||
s.license = "MIT"
|
s.license = "MIT"
|
||||||
s.homepage = "https://github.com/JohnEstropia/CoreStore"
|
s.homepage = "https://github.com/JohnEstropia/CoreStore"
|
||||||
|
|||||||
@@ -362,6 +362,10 @@
|
|||||||
B52FD3AB1E3B3EF10001D919 /* NSManagedObject+Logging.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52FD3A91E3B3EF10001D919 /* NSManagedObject+Logging.swift */; };
|
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 */; };
|
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 */; };
|
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 */; };
|
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 */; };
|
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 */; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
B53B275E1EE3B92E00E9B352 /* CoreStoreManagedObject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreStoreManagedObject.swift; sourceTree = "<group>"; };
|
||||||
@@ -1535,6 +1540,14 @@
|
|||||||
name = "Dynamic Schema";
|
name = "Dynamic Schema";
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
B52FEC722596DB6400368BFB /* SwiftUI */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
B52FEC732596DBE000368BFB /* ObjectReader.swift */,
|
||||||
|
);
|
||||||
|
name = SwiftUI;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
B53FBA101CAB607000F0D40A /* Convenience */ = {
|
B53FBA101CAB607000F0D40A /* Convenience */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -1697,6 +1710,7 @@
|
|||||||
B5D1E22B19FA9FBC003B2874 /* CoreStoreError.swift */,
|
B5D1E22B19FA9FBC003B2874 /* CoreStoreError.swift */,
|
||||||
B549F6721E56A92800FBAB2D /* CoreDataNativeType.swift */,
|
B549F6721E56A92800FBAB2D /* CoreDataNativeType.swift */,
|
||||||
B5D339F01E94AF5800C880DE /* CoreStoreStrings.swift */,
|
B5D339F01E94AF5800C880DE /* CoreStoreStrings.swift */,
|
||||||
|
B52FEC722596DB6400368BFB /* SwiftUI */,
|
||||||
B5E84EDA1AFF84500064E85B /* Setup */,
|
B5E84EDA1AFF84500064E85B /* Setup */,
|
||||||
B51B5C2922D43854009FA3BA /* KeyPaths */,
|
B51B5C2922D43854009FA3BA /* KeyPaths */,
|
||||||
B5E84EE21AFF84610064E85B /* Logging */,
|
B5E84EE21AFF84610064E85B /* Logging */,
|
||||||
@@ -2165,7 +2179,7 @@
|
|||||||
isa = PBXProject;
|
isa = PBXProject;
|
||||||
attributes = {
|
attributes = {
|
||||||
LastSwiftUpdateCheck = 0730;
|
LastSwiftUpdateCheck = 0730;
|
||||||
LastUpgradeCheck = 1020;
|
LastUpgradeCheck = 1200;
|
||||||
ORGANIZATIONNAME = "John Rommel Estropia";
|
ORGANIZATIONNAME = "John Rommel Estropia";
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
2F03A52F19C5C6DA005002A5 = {
|
2F03A52F19C5C6DA005002A5 = {
|
||||||
@@ -2441,6 +2455,7 @@
|
|||||||
B559CD491CAA8C6D00E4D58B /* CSStorageInterface.swift in Sources */,
|
B559CD491CAA8C6D00E4D58B /* CSStorageInterface.swift in Sources */,
|
||||||
B5ECDC2F1CA81CDC00C7F112 /* CSCoreStore+Transaction.swift in Sources */,
|
B5ECDC2F1CA81CDC00C7F112 /* CSCoreStore+Transaction.swift in Sources */,
|
||||||
B5E84F311AFF849C0064E85B /* Internals.WeakObject.swift in Sources */,
|
B5E84F311AFF849C0064E85B /* Internals.WeakObject.swift in Sources */,
|
||||||
|
B52FEC742596DBE100368BFB /* ObjectReader.swift in Sources */,
|
||||||
B5E84F101AFF847B0064E85B /* GroupBy.swift in Sources */,
|
B5E84F101AFF847B0064E85B /* GroupBy.swift in Sources */,
|
||||||
B5E84F201AFF84860064E85B /* DataStack+Observing.swift in Sources */,
|
B5E84F201AFF84860064E85B /* DataStack+Observing.swift in Sources */,
|
||||||
B501FDDD1CA8D05000BE22EF /* CSSectionBy.swift in Sources */,
|
B501FDDD1CA8D05000BE22EF /* CSSectionBy.swift in Sources */,
|
||||||
@@ -2693,6 +2708,7 @@
|
|||||||
B501FDDF1CA8D05000BE22EF /* CSSectionBy.swift in Sources */,
|
B501FDDF1CA8D05000BE22EF /* CSSectionBy.swift in Sources */,
|
||||||
B5BF7FAE234C41E90070E741 /* Internals.DiffableDataSourceSnapshot.swift in Sources */,
|
B5BF7FAE234C41E90070E741 /* Internals.DiffableDataSourceSnapshot.swift in Sources */,
|
||||||
B538BA781D15B3E30003A766 /* CoreStoreBridge.m in Sources */,
|
B538BA781D15B3E30003A766 /* CoreStoreBridge.m in Sources */,
|
||||||
|
B52FEC752596DBE100368BFB /* ObjectReader.swift in Sources */,
|
||||||
B51260801E97A18000402229 /* CoreStoreObject+Convenience.swift in Sources */,
|
B51260801E97A18000402229 /* CoreStoreObject+Convenience.swift in Sources */,
|
||||||
82BA18D31C4BBD7100A0916E /* NSManagedObjectContext+CoreStore.swift in Sources */,
|
82BA18D31C4BBD7100A0916E /* NSManagedObjectContext+CoreStore.swift in Sources */,
|
||||||
82BA18AD1C4BBD3100A0916E /* UnsafeDataTransaction.swift in Sources */,
|
82BA18AD1C4BBD3100A0916E /* UnsafeDataTransaction.swift in Sources */,
|
||||||
@@ -2945,6 +2961,7 @@
|
|||||||
B5220E181D130711009BC71E /* ObjectObserver.swift in Sources */,
|
B5220E181D130711009BC71E /* ObjectObserver.swift in Sources */,
|
||||||
B5220E251D13088E009BC71E /* ListObserver.swift in Sources */,
|
B5220E251D13088E009BC71E /* ListObserver.swift in Sources */,
|
||||||
B538BA7A1D15B3E30003A766 /* CoreStoreBridge.m in Sources */,
|
B538BA7A1D15B3E30003A766 /* CoreStoreBridge.m in Sources */,
|
||||||
|
B52FEC772596DBE100368BFB /* ObjectReader.swift in Sources */,
|
||||||
B5BF7FB0234C41E90070E741 /* Internals.DiffableDataSourceSnapshot.swift in Sources */,
|
B5BF7FB0234C41E90070E741 /* Internals.DiffableDataSourceSnapshot.swift in Sources */,
|
||||||
B51260821E97A18000402229 /* CoreStoreObject+Convenience.swift in Sources */,
|
B51260821E97A18000402229 /* CoreStoreObject+Convenience.swift in Sources */,
|
||||||
B52DD1A01BE1F92C00949AFE /* UnsafeDataTransaction.swift in Sources */,
|
B52DD1A01BE1F92C00949AFE /* UnsafeDataTransaction.swift in Sources */,
|
||||||
@@ -3197,6 +3214,7 @@
|
|||||||
B501FDE01CA8D05000BE22EF /* CSSectionBy.swift in Sources */,
|
B501FDE01CA8D05000BE22EF /* CSSectionBy.swift in Sources */,
|
||||||
B5BF7FAF234C41E90070E741 /* Internals.DiffableDataSourceSnapshot.swift in Sources */,
|
B5BF7FAF234C41E90070E741 /* Internals.DiffableDataSourceSnapshot.swift in Sources */,
|
||||||
B538BA791D15B3E30003A766 /* CoreStoreBridge.m in Sources */,
|
B538BA791D15B3E30003A766 /* CoreStoreBridge.m in Sources */,
|
||||||
|
B52FEC762596DBE100368BFB /* ObjectReader.swift in Sources */,
|
||||||
B51260811E97A18000402229 /* CoreStoreObject+Convenience.swift in Sources */,
|
B51260811E97A18000402229 /* CoreStoreObject+Convenience.swift in Sources */,
|
||||||
B56321B11BD6521C006C9394 /* NSManagedObjectContext+CoreStore.swift in Sources */,
|
B56321B11BD6521C006C9394 /* NSManagedObjectContext+CoreStore.swift in Sources */,
|
||||||
B563218D1BD65216006C9394 /* CoreStore+Transaction.swift in Sources */,
|
B563218D1BD65216006C9394 /* CoreStore+Transaction.swift in Sources */,
|
||||||
@@ -3292,6 +3310,7 @@
|
|||||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
@@ -3363,6 +3382,7 @@
|
|||||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
@@ -3413,7 +3433,7 @@
|
|||||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||||
MARKETING_VERSION = 7.3.0;
|
MARKETING_VERSION = 7.3.1;
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"-weak_framework",
|
"-weak_framework",
|
||||||
Combine,
|
Combine,
|
||||||
@@ -3436,7 +3456,7 @@
|
|||||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||||
MARKETING_VERSION = 7.3.0;
|
MARKETING_VERSION = 7.3.1;
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"-weak_framework",
|
"-weak_framework",
|
||||||
Combine,
|
Combine,
|
||||||
@@ -3496,7 +3516,7 @@
|
|||||||
GCC_NO_COMMON_BLOCKS = YES;
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||||
MARKETING_VERSION = 7.3.0;
|
MARKETING_VERSION = 7.3.1;
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"-weak_framework",
|
"-weak_framework",
|
||||||
Combine,
|
Combine,
|
||||||
@@ -3522,7 +3542,7 @@
|
|||||||
GCC_NO_COMMON_BLOCKS = YES;
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||||
MARKETING_VERSION = 7.3.0;
|
MARKETING_VERSION = 7.3.1;
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"-weak_framework",
|
"-weak_framework",
|
||||||
Combine,
|
Combine,
|
||||||
@@ -3587,7 +3607,7 @@
|
|||||||
GCC_NO_COMMON_BLOCKS = YES;
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
|
||||||
MARKETING_VERSION = 7.3.0;
|
MARKETING_VERSION = 7.3.1;
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"-weak_framework",
|
"-weak_framework",
|
||||||
Combine,
|
Combine,
|
||||||
@@ -3616,7 +3636,7 @@
|
|||||||
GCC_NO_COMMON_BLOCKS = YES;
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
|
||||||
MARKETING_VERSION = 7.3.0;
|
MARKETING_VERSION = 7.3.1;
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"-weak_framework",
|
"-weak_framework",
|
||||||
Combine,
|
Combine,
|
||||||
@@ -3682,7 +3702,7 @@
|
|||||||
GCC_NO_COMMON_BLOCKS = YES;
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||||
MARKETING_VERSION = 7.3.0;
|
MARKETING_VERSION = 7.3.1;
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"-weak_framework",
|
"-weak_framework",
|
||||||
Combine,
|
Combine,
|
||||||
@@ -3710,7 +3730,7 @@
|
|||||||
GCC_NO_COMMON_BLOCKS = YES;
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||||
MARKETING_VERSION = 7.3.0;
|
MARKETING_VERSION = 7.3.1;
|
||||||
OTHER_LDFLAGS = (
|
OTHER_LDFLAGS = (
|
||||||
"-weak_framework",
|
"-weak_framework",
|
||||||
Combine,
|
Combine,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Scheme
|
<Scheme
|
||||||
LastUpgradeVersion = "1020"
|
LastUpgradeVersion = "1200"
|
||||||
version = "1.3">
|
version = "1.3">
|
||||||
<BuildAction
|
<BuildAction
|
||||||
parallelizeBuildables = "YES"
|
parallelizeBuildables = "YES"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Scheme
|
<Scheme
|
||||||
LastUpgradeVersion = "1020"
|
LastUpgradeVersion = "1200"
|
||||||
version = "1.3">
|
version = "1.3">
|
||||||
<BuildAction
|
<BuildAction
|
||||||
parallelizeBuildables = "YES"
|
parallelizeBuildables = "YES"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Scheme
|
<Scheme
|
||||||
LastUpgradeVersion = "1020"
|
LastUpgradeVersion = "1200"
|
||||||
version = "1.3">
|
version = "1.3">
|
||||||
<BuildAction
|
<BuildAction
|
||||||
parallelizeBuildables = "YES"
|
parallelizeBuildables = "YES"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Scheme
|
<Scheme
|
||||||
LastUpgradeVersion = "1020"
|
LastUpgradeVersion = "1200"
|
||||||
version = "1.3">
|
version = "1.3">
|
||||||
<BuildAction
|
<BuildAction
|
||||||
parallelizeBuildables = "YES"
|
parallelizeBuildables = "YES"
|
||||||
|
|||||||
2
CoreStore.xcworkspace/contents.xcworkspacedata
generated
2
CoreStore.xcworkspace/contents.xcworkspacedata
generated
@@ -8,6 +8,6 @@
|
|||||||
location = "group:CoreStore.xcodeproj">
|
location = "group:CoreStore.xcodeproj">
|
||||||
</FileRef>
|
</FileRef>
|
||||||
<FileRef
|
<FileRef
|
||||||
location = "group:/Users/JohnEstropia/Documents/XCodeProjects/CoreStore/LegacyDemo/LegacyDemo.xcodeproj">
|
location = "group:LegacyDemo/LegacyDemo.xcodeproj">
|
||||||
</FileRef>
|
</FileRef>
|
||||||
</Workspace>
|
</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
|
let didSetObserver = dog.observe(\.$species, options: [.new, .old]) { (object, change) in
|
||||||
|
|
||||||
XCTAssertEqual(object, dog)
|
XCTAssertEqual(object, dog)
|
||||||
|
|||||||
@@ -77,17 +77,10 @@ final class WhereTests: XCTestCase {
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
// let keyPathBuilder = TestEntity1.keyPathBuilder()
|
|
||||||
|
|
||||||
// let kp = \TestEntity1.testToOne
|
|
||||||
// print(keyPathBuilder.testString)
|
|
||||||
// print(keyPathBuilder.testToOne)
|
|
||||||
// print(keyPathBuilder.testToOne.testEntityID)
|
|
||||||
XCTAssertAllEqual(
|
XCTAssertAllEqual(
|
||||||
#keyPath(TestEntity1.testToOne.testEntityID),
|
#keyPath(TestEntity1.testToOne.testEntityID),
|
||||||
(\TestEntity1.testToOne ~ \.testEntityID).description,
|
(\TestEntity1.testToOne ~ \.testEntityID).description,
|
||||||
String(keyPath: \TestEntity1.testToOne ~ \.testEntityID)
|
String(keyPath: \TestEntity1.testToOne ~ \.testEntityID)
|
||||||
// keyPathBuilder.testToOne.testEntityID.keyPathString
|
|
||||||
)
|
)
|
||||||
XCTAssertAllEqual(
|
XCTAssertAllEqual(
|
||||||
#keyPath(TestEntity1.testToOne.testToOne.testToManyUnordered),
|
#keyPath(TestEntity1.testToOne.testToOne.testToManyUnordered),
|
||||||
|
|||||||
@@ -622,7 +622,7 @@
|
|||||||
isa = PBXProject;
|
isa = PBXProject;
|
||||||
attributes = {
|
attributes = {
|
||||||
LastSwiftUpdateCheck = 1160;
|
LastSwiftUpdateCheck = 1160;
|
||||||
LastUpgradeCheck = 1160;
|
LastUpgradeCheck = 1200;
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
B5A3911824E5429200E7E8BD = {
|
B5A3911824E5429200E7E8BD = {
|
||||||
CreatedOnToolsVersion = 11.6;
|
CreatedOnToolsVersion = 11.6;
|
||||||
@@ -769,6 +769,33 @@
|
|||||||
B5A3911324E5424E00E7E8BD /* Debug */ = {
|
B5A3911324E5424E00E7E8BD /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
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;
|
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||||
};
|
};
|
||||||
name = Debug;
|
name = Debug;
|
||||||
@@ -776,6 +803,32 @@
|
|||||||
B5A3911424E5424E00E7E8BD /* Release */ = {
|
B5A3911424E5424E00E7E8BD /* Release */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
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;
|
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Scheme
|
<Scheme
|
||||||
LastUpgradeVersion = "1160"
|
LastUpgradeVersion = "1200"
|
||||||
version = "1.3">
|
version = "1.3">
|
||||||
<BuildAction
|
<BuildAction
|
||||||
parallelizeBuildables = "YES"
|
parallelizeBuildables = "YES"
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
import CoreStore
|
import CoreStore
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
|
|
||||||
// MARK: - Modern.ColorsDemo.SwiftUI
|
// MARK: - Modern.ColorsDemo.SwiftUI
|
||||||
|
|
||||||
extension Modern.ColorsDemo.SwiftUI {
|
extension Modern.ColorsDemo.SwiftUI {
|
||||||
@@ -39,7 +40,7 @@ extension Modern.ColorsDemo.SwiftUI {
|
|||||||
.listRowInsets(.init())
|
.listRowInsets(.init())
|
||||||
}
|
}
|
||||||
.onDelete { itemIndices in
|
.onDelete { itemIndices in
|
||||||
|
|
||||||
self.deleteColors(at: itemIndices, in: sectionID)
|
self.deleteColors(at: itemIndices, in: sectionID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -295,7 +295,7 @@
|
|||||||
isa = PBXProject;
|
isa = PBXProject;
|
||||||
attributes = {
|
attributes = {
|
||||||
LastSwiftUpdateCheck = 0700;
|
LastSwiftUpdateCheck = 0700;
|
||||||
LastUpgradeCheck = 0930;
|
LastUpgradeCheck = 1200;
|
||||||
ORGANIZATIONNAME = "John Rommel Estropia";
|
ORGANIZATIONNAME = "John Rommel Estropia";
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
B54AAD481AF4D26E00848AE0 = {
|
B54AAD481AF4D26E00848AE0 = {
|
||||||
@@ -422,6 +422,7 @@
|
|||||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
@@ -479,6 +480,7 @@
|
|||||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
|
|||||||
@@ -6,14 +6,24 @@ PlaygroundPage.current.needsIndefiniteExecution = true
|
|||||||
|
|
||||||
/// Model Declaration =====
|
/// Model Declaration =====
|
||||||
class Animal: CoreStoreObject {
|
class Animal: CoreStoreObject {
|
||||||
let species = Value.Required<String>("species", initial: "Swift")
|
|
||||||
let master = Relationship.ToOne<Person>("master")
|
@Field.Stored("species")
|
||||||
let color = Transformable.Optional<UIColor>("color", initial: .orange)
|
var species: String = "Swift"
|
||||||
|
|
||||||
|
@Field.Coded("color", coder: FieldCoders.NSCoding.self)
|
||||||
|
var color: UIColor = .orange
|
||||||
|
|
||||||
|
@Field.Relationship("master")
|
||||||
|
var master: Person?
|
||||||
}
|
}
|
||||||
|
|
||||||
class Person: CoreStoreObject {
|
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: [
|
entities: [
|
||||||
Entity<Animal>("Animal"),
|
Entity<Animal>("Animal"),
|
||||||
Entity<Person>("Person")
|
Entity<Person>("Person")
|
||||||
|
],
|
||||||
|
versionLock: [
|
||||||
|
"Animal": [0x4a201cc685d53c0a, 0x16e6c3b561577875, 0xb032e2da61c792a0, 0xa133b801051acee4],
|
||||||
|
"Person": [0xca938eea1af4bd56, 0xbca30994506356ad, 0x7a7cc655898816ef, 0x1a4551ffedc9b214]
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -42,12 +56,12 @@ dataStack.addStorage(
|
|||||||
asynchronous: { transaction in
|
asynchronous: { transaction in
|
||||||
|
|
||||||
let animal = transaction.create(Into<Animal>())
|
let animal = transaction.create(Into<Animal>())
|
||||||
animal.species .= "Sparrow"
|
animal.species = "Sparrow"
|
||||||
animal.color .= .yellow
|
animal.color = .yellow
|
||||||
|
|
||||||
let person = transaction.create(Into<Person>())
|
let person = transaction.create(Into<Person>())
|
||||||
person.name .= "John"
|
person.name = "John"
|
||||||
person.pets.value.insert(animal)
|
person.pets.insert(animal)
|
||||||
},
|
},
|
||||||
completion: { result in
|
completion: { result in
|
||||||
|
|
||||||
@@ -58,13 +72,16 @@ dataStack.addStorage(
|
|||||||
|
|
||||||
case .success:
|
case .success:
|
||||||
/// Accessing Objects =====
|
/// Accessing Objects =====
|
||||||
let bird = try! dataStack.fetchOne(From<Animal>().where(\.species == "Sparrow"))!
|
let bird = try! dataStack.fetchOne(
|
||||||
print(bird.species.value)
|
From<Animal>()
|
||||||
print(bird.color.value as Any)
|
.where(\.$species == "Sparrow")
|
||||||
|
)!
|
||||||
|
print(bird.species)
|
||||||
|
print(bird.color as Any)
|
||||||
print(bird)
|
print(bird)
|
||||||
|
|
||||||
let owner = bird.master.value!
|
let owner = bird.master!
|
||||||
print(owner.name.value as Any)
|
print(owner.name as Any)
|
||||||
print(owner.pets.count)
|
print(owner.pets.count)
|
||||||
print(owner)
|
print(owner)
|
||||||
/// =======================
|
/// =======================
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
<?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'/>
|
<timeline fileName='timeline.xctimeline'/>
|
||||||
</playground>
|
</playground>
|
||||||
@@ -6,14 +6,24 @@ PlaygroundPage.current.needsIndefiniteExecution = true
|
|||||||
|
|
||||||
/// Model Declaration =====
|
/// Model Declaration =====
|
||||||
class Animal: CoreStoreObject {
|
class Animal: CoreStoreObject {
|
||||||
let species = Value.Required<String>("species", initial: "Swift")
|
|
||||||
let master = Relationship.ToOne<Person>("master")
|
@Field.Stored("species")
|
||||||
let color = Transformable.Optional<NSColor>("color", initial: .orange)
|
var species: String = "Swift"
|
||||||
|
|
||||||
|
@Field.Coded("color", coder: FieldCoders.NSCoding.self)
|
||||||
|
var color: NSColor = .orange
|
||||||
|
|
||||||
|
@Field.Relationship("master")
|
||||||
|
var master: Person?
|
||||||
}
|
}
|
||||||
|
|
||||||
class Person: CoreStoreObject {
|
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: [
|
entities: [
|
||||||
Entity<Animal>("Animal"),
|
Entity<Animal>("Animal"),
|
||||||
Entity<Person>("Person")
|
Entity<Person>("Person")
|
||||||
|
],
|
||||||
|
versionLock: [
|
||||||
|
"Animal": [0x4a201cc685d53c0a, 0x16e6c3b561577875, 0xb032e2da61c792a0, 0xa133b801051acee4],
|
||||||
|
"Person": [0xca938eea1af4bd56, 0xbca30994506356ad, 0x7a7cc655898816ef, 0x1a4551ffedc9b214]
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -42,12 +56,12 @@ dataStack.addStorage(
|
|||||||
asynchronous: { transaction in
|
asynchronous: { transaction in
|
||||||
|
|
||||||
let animal = transaction.create(Into<Animal>())
|
let animal = transaction.create(Into<Animal>())
|
||||||
animal.species .= "Sparrow"
|
animal.species = "Sparrow"
|
||||||
animal.color .= .yellow
|
animal.color = .yellow
|
||||||
|
|
||||||
let person = transaction.create(Into<Person>())
|
let person = transaction.create(Into<Person>())
|
||||||
person.name .= "John"
|
person.name = "John"
|
||||||
person.pets.value.insert(animal)
|
person.pets.insert(animal)
|
||||||
},
|
},
|
||||||
completion: { result in
|
completion: { result in
|
||||||
|
|
||||||
@@ -58,13 +72,16 @@ dataStack.addStorage(
|
|||||||
|
|
||||||
case .success:
|
case .success:
|
||||||
/// Accessing Objects =====
|
/// Accessing Objects =====
|
||||||
let bird = try! dataStack.fetchOne(From<Animal>().where(\.species == "Sparrow"))!
|
let bird = try! dataStack.fetchOne(
|
||||||
print(bird.species.value)
|
From<Animal>()
|
||||||
print(bird.color.value as Any)
|
.where(\.$species == "Sparrow")
|
||||||
|
)!
|
||||||
|
print(bird.species)
|
||||||
|
print(bird.color as Any)
|
||||||
print(bird)
|
print(bird)
|
||||||
|
|
||||||
let owner = bird.master.value!
|
let owner = bird.master!
|
||||||
print(owner.name.value as Any)
|
print(owner.name as Any)
|
||||||
print(owner.pets.count)
|
print(owner.pets.count)
|
||||||
print(owner)
|
print(owner)
|
||||||
/// =======================
|
/// =======================
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
<?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'/>
|
<timeline fileName='timeline.xctimeline'/>
|
||||||
</playground>
|
</playground>
|
||||||
@@ -2095,7 +2095,7 @@ This installs CoreStore as a framework. Declare `import CoreStore` in your swift
|
|||||||
#### Install with Swift Package Manager:
|
#### Install with Swift Package Manager:
|
||||||
```swift
|
```swift
|
||||||
dependencies: [
|
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.
|
Declare `import CoreStore` in your swift file to use the library.
|
||||||
|
|||||||
@@ -230,7 +230,10 @@ extension BaseDataTransaction {
|
|||||||
}
|
}
|
||||||
try autoreleasepool {
|
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 {
|
guard entityType.shouldUpdate(from: source, in: self) else {
|
||||||
|
|
||||||
|
|||||||
@@ -429,7 +429,7 @@ public /*abstract*/ class BaseDataTransaction {
|
|||||||
|
|
||||||
internal let context: NSManagedObjectContext
|
internal let context: NSManagedObjectContext
|
||||||
internal let transactionQueue: DispatchQueue
|
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 supportsUndo: Bool
|
||||||
internal let bypassesQueueing: Bool
|
internal let bypassesQueueing: Bool
|
||||||
internal var isCommitted = false
|
internal var isCommitted = false
|
||||||
|
|||||||
@@ -1189,7 +1189,6 @@ extension NSAttributeDescription: CoreStoreDebugStringConvertible {
|
|||||||
("versionHash", self.versionHash),
|
("versionHash", self.versionHash),
|
||||||
("versionHashModifier", self.versionHashModifier as Any),
|
("versionHashModifier", self.versionHashModifier as Any),
|
||||||
("isIndexedBySpotlight", self.isIndexedBySpotlight),
|
("isIndexedBySpotlight", self.isIndexedBySpotlight),
|
||||||
("isStoredInExternalRecord", self.isStoredInExternalRecord),
|
|
||||||
("renamingIdentifier", self.renamingIdentifier as Any)
|
("renamingIdentifier", self.renamingIdentifier as Any)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -1363,11 +1362,9 @@ extension NSRelationshipDescription: CoreStoreDebugStringConvertible {
|
|||||||
("isOptional", self.isOptional),
|
("isOptional", self.isOptional),
|
||||||
("isTransient", self.isTransient),
|
("isTransient", self.isTransient),
|
||||||
("userInfo", self.userInfo as Any),
|
("userInfo", self.userInfo as Any),
|
||||||
("isIndexed", self.isIndexed),
|
|
||||||
("versionHash", self.versionHash),
|
("versionHash", self.versionHash),
|
||||||
("versionHashModifier", self.versionHashModifier as Any),
|
("versionHashModifier", self.versionHashModifier as Any),
|
||||||
("isIndexedBySpotlight", self.isIndexedBySpotlight),
|
("isIndexedBySpotlight", self.isIndexedBySpotlight),
|
||||||
("isStoredInExternalRecord", self.isStoredInExternalRecord),
|
|
||||||
("renamingIdentifier", self.renamingIdentifier as Any)
|
("renamingIdentifier", self.renamingIdentifier as Any)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,4 +29,4 @@
|
|||||||
FOUNDATION_EXPORT double CoreStoreVersionNumber;
|
FOUNDATION_EXPORT double CoreStoreVersionNumber;
|
||||||
FOUNDATION_EXPORT const unsigned char CoreStoreVersionString[];
|
FOUNDATION_EXPORT const unsigned char CoreStoreVersionString[];
|
||||||
|
|
||||||
#import "CoreStoreBridge.h"
|
#import <CoreStore/CoreStoreBridge.h>
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ public enum CoreStoreDefaults {
|
|||||||
|
|
||||||
// MARK: Private
|
// 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?
|
private static var defaultStackInstance: DataStack?
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,6 +48,6 @@ import Foundation
|
|||||||
|
|
||||||
private enum Static {
|
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>]] = [:]
|
static var cache: [ObjectIdentifier: [KeyPathString: Set<KeyPathString>]] = [:]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -254,7 +254,7 @@ public final class CoreStoreSchema: DynamicSchema {
|
|||||||
|
|
||||||
// MARK: Private
|
// 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>
|
private let allEntities: Set<DynamicEntity>
|
||||||
|
|
||||||
|
|||||||
@@ -440,8 +440,8 @@ public final class DataStack: Equatable {
|
|||||||
internal let rootSavingContext: NSManagedObjectContext
|
internal let rootSavingContext: NSManagedObjectContext
|
||||||
internal let mainContext: NSManagedObjectContext
|
internal let mainContext: NSManagedObjectContext
|
||||||
internal let schemaHistory: SchemaHistory
|
internal let schemaHistory: SchemaHistory
|
||||||
internal let childTransactionQueue = DispatchQueue.serial("com.coreStore.dataStack.childTransactionQueue")
|
internal let childTransactionQueue = DispatchQueue.serial("com.coreStore.dataStack.childTransactionQueue", qos: .utility)
|
||||||
internal let storeMetadataUpdateQueue = DispatchQueue.concurrent("com.coreStore.persistentStoreBarrierQueue")
|
internal let storeMetadataUpdateQueue = DispatchQueue.concurrent("com.coreStore.persistentStoreBarrierQueue", qos: .userInteractive)
|
||||||
internal let migrationQueue: OperationQueue = Internals.with {
|
internal let migrationQueue: OperationQueue = Internals.with {
|
||||||
|
|
||||||
let migrationQueue = OperationQueue()
|
let migrationQueue = OperationQueue()
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ extension DiffableDataSource {
|
|||||||
*/
|
*/
|
||||||
open class TableViewAdapter<O: DynamicObject>: BaseAdapter<O, DefaultTableViewTarget<UITableView>>, UITableViewDataSource {
|
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.
|
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 {
|
extension DispatchQueue {
|
||||||
|
|
||||||
@nonobjc @inline(__always)
|
@nonobjc @inline(__always)
|
||||||
internal static func serial(_ label: String, qos: DispatchQoS = .default) -> DispatchQueue {
|
internal static func serial(_ label: String, qos: DispatchQoS) -> DispatchQueue {
|
||||||
|
|
||||||
return DispatchQueue(
|
return DispatchQueue(
|
||||||
label: label,
|
label: label,
|
||||||
@@ -43,7 +43,7 @@ extension DispatchQueue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@nonobjc @inline(__always)
|
@nonobjc @inline(__always)
|
||||||
internal static func concurrent(_ label: String, qos: DispatchQoS = .default) -> DispatchQueue {
|
internal static func concurrent(_ label: String, qos: DispatchQoS) -> DispatchQueue {
|
||||||
|
|
||||||
return DispatchQueue(
|
return DispatchQueue(
|
||||||
label: label,
|
label: label,
|
||||||
|
|||||||
@@ -217,7 +217,8 @@ extension CoreStoreObject {
|
|||||||
|
|
||||||
guard
|
guard
|
||||||
let object = context.fetchExisting(id) as CoreStoreObject?,
|
let object = context.fetchExisting(id) as CoreStoreObject?,
|
||||||
let rawObject = object.rawObject
|
let rawObject = object.rawObject,
|
||||||
|
!rawObject.isDeleted
|
||||||
else {
|
else {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -42,6 +42,28 @@ extension From {
|
|||||||
return self.fetchChain(appending: clause)
|
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
|
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))
|
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
|
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)
|
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`
|
Adds a `Where` clause to the `FetchChainBuilder`
|
||||||
|
|
||||||
@@ -682,6 +721,28 @@ extension QueryChainBuilder {
|
|||||||
return self.queryChain(appending: clause)
|
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`
|
Adds a `Where` clause to the `QueryChainBuilder`
|
||||||
|
|
||||||
@@ -957,6 +1018,28 @@ extension SectionMonitorChainBuilder {
|
|||||||
return self.sectionMonitorChain(appending: clause)
|
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`
|
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
|
The data type for the entity's unique ID attribute
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ extension Internals {
|
|||||||
|
|
||||||
var numberOfItems: Int {
|
var numberOfItems: Int {
|
||||||
|
|
||||||
return self.structure.allItemIDs.count
|
return self.structure.allItemsCount
|
||||||
}
|
}
|
||||||
|
|
||||||
var numberOfSections: Int {
|
var numberOfSections: Int {
|
||||||
@@ -106,6 +106,59 @@ extension Internals {
|
|||||||
return self.itemIdentifiers(inSection: identifier).count
|
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] {
|
func itemIdentifiers(inSection identifier: String) -> [NSManagedObjectID] {
|
||||||
|
|
||||||
return self.structure.items(in: identifier)
|
return self.structure.items(in: identifier)
|
||||||
@@ -332,6 +385,14 @@ extension Internals {
|
|||||||
return self.sections.map({ $0.differenceIdentifier })
|
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] {
|
var allItemIDs: [NSManagedObjectID] {
|
||||||
|
|
||||||
return self.sections.lazy.flatMap({ $0.elements }).map({ $0.differenceIdentifier })
|
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)
|
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
|
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)
|
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
|
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)
|
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
|
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)
|
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
|
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>
|
// 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>
|
// 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
|
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())
|
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
|
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())
|
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
|
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())
|
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
|
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>
|
// 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
|
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
|
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
|
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
|
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>
|
// 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
|
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)
|
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
|
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)
|
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
|
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> {
|
public subscript(index: Index) -> ObjectPublisher<O> {
|
||||||
|
|
||||||
let context = self.context!
|
let context = self.context!
|
||||||
let itemID = self.diffableSnapshot.itemIdentifiers[index]
|
let itemID = self.diffableSnapshot.itemIdentifier(atAllItemsIndex: index)!
|
||||||
return context.objectPublisher(objectID: itemID)
|
return context.objectPublisher(objectID: itemID)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,16 +83,13 @@ public struct ListSnapshot<O: DynamicObject>: RandomAccessCollection, Hashable {
|
|||||||
*/
|
*/
|
||||||
public subscript(safeIndex index: Index) -> ObjectPublisher<O>? {
|
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
|
return nil
|
||||||
}
|
}
|
||||||
let itemIDs = self.diffableSnapshot.itemIdentifiers
|
|
||||||
guard itemIDs.indices.contains(index) else {
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
let itemID = itemIDs[index]
|
|
||||||
return context.objectPublisher(objectID: itemID)
|
return context.objectPublisher(objectID: itemID)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -597,20 +594,74 @@ public struct ListSnapshot<O: DynamicObject>: RandomAccessCollection, Hashable {
|
|||||||
self.diffableSnapshot.reloadSections(sectionIDs)
|
self.diffableSnapshot.reloadSections(sectionIDs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: RandomAccessCollection
|
// MARK: RandomAccessCollection
|
||||||
|
|
||||||
public var startIndex: Index {
|
public var startIndex: Index {
|
||||||
|
|
||||||
return self.diffableSnapshot.itemIdentifiers.startIndex
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
public var endIndex: Index {
|
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
|
// 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.
|
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, *)
|
@available(macOS 10.12, *)
|
||||||
public final class ObjectMonitor<O: DynamicObject>: Equatable {
|
public final class ObjectMonitor<O: DynamicObject>: Hashable, ObjectRepresentation {
|
||||||
|
|
||||||
/**
|
|
||||||
The object type represented by this `ObjectMonitor`
|
|
||||||
*/
|
|
||||||
public typealias ObjectType = O
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Returns the `DynamicObject` instance being observed, or `nil` if the object was already deleted.
|
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
|
// MARK: Internal
|
||||||
|
|
||||||
internal init(objectID: O.ObjectID, context: NSManagedObjectContext) {
|
internal init(objectID: O.ObjectID, context: NSManagedObjectContext) {
|
||||||
|
|||||||
@@ -125,15 +125,23 @@ public final class ObjectPublisher<O: DynamicObject>: ObjectRepresentation, Hash
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// MARK: ObjectRepresentation
|
// MARK: AnyObjectRepresentation
|
||||||
|
|
||||||
public typealias ObjectType = O
|
|
||||||
|
|
||||||
public func objectID() -> O.ObjectID {
|
public func objectID() -> O.ObjectID {
|
||||||
|
|
||||||
return self.id
|
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> {
|
public func asPublisher(in dataStack: DataStack) -> ObjectPublisher<O> {
|
||||||
|
|
||||||
let context = dataStack.unsafeContext()
|
let context = dataStack.unsafeContext()
|
||||||
@@ -449,20 +457,18 @@ extension ObjectPublisher where O: NSManagedObject {
|
|||||||
/**
|
/**
|
||||||
Returns the value for the property identified by a given key.
|
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! {
|
public func value<V: AllowedObjectiveCKeyPathValue>(forKeyPath keyPath: KeyPath<O, V>) -> V! {
|
||||||
|
|
||||||
let key = String(keyPath: keyPath)
|
return self[dynamicMember: keyPath]
|
||||||
return self.snapshot?.dictionaryForValues()[key] as! V?
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
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
|
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
|
// MARK - ObjectRepresentation
|
||||||
|
|
||||||
/**
|
/**
|
||||||
An object that acts as interfaces for `CoreStoreObject`s or `NSManagedObject`s
|
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
|
The object type represented by this protocol
|
||||||
*/
|
*/
|
||||||
associatedtype ObjectType: DynamicObject
|
associatedtype ObjectType: DynamicObject
|
||||||
|
|
||||||
/**
|
|
||||||
The internal ID for the object.
|
|
||||||
*/
|
|
||||||
func objectID() -> ObjectType.ObjectID
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
An instance that may be observed for object changes.
|
An instance that may be observed for object changes.
|
||||||
*/
|
*/
|
||||||
@@ -96,14 +110,22 @@ extension DynamicObject where Self: ObjectRepresentation {
|
|||||||
.managedObjectContext
|
.managedObjectContext
|
||||||
.flatMap({ ObjectSnapshot<Self>(objectID: self.cs_id(), context: $0) })
|
.flatMap({ ObjectSnapshot<Self>(objectID: self.cs_id(), context: $0) })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// MARK: ObjectRepresentation
|
// MARK: AnyObjectRepresentation
|
||||||
|
|
||||||
public func objectID() -> Self.ObjectID {
|
public func objectID() -> Self.ObjectID {
|
||||||
|
|
||||||
return self.cs_id()
|
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> {
|
public func asPublisher(in dataStack: DataStack) -> ObjectPublisher<Self> {
|
||||||
|
|
||||||
|
|||||||
@@ -48,17 +48,25 @@ public struct ObjectSnapshot<O: DynamicObject>: ObjectRepresentation, Hashable {
|
|||||||
|
|
||||||
return self.values
|
return self.values
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// MARK: ObjectRepresentation
|
|
||||||
|
// MARK: AnyObjectRepresentation
|
||||||
public typealias ObjectType = O
|
|
||||||
|
|
||||||
public func objectID() -> O.ObjectID {
|
public func objectID() -> O.ObjectID {
|
||||||
|
|
||||||
return self.id
|
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> {
|
public func asPublisher(in dataStack: DataStack) -> ObjectPublisher<O> {
|
||||||
|
|
||||||
let context = dataStack.unsafeContext()
|
let context = dataStack.unsafeContext()
|
||||||
@@ -93,7 +101,7 @@ public struct ObjectSnapshot<O: DynamicObject>: ObjectRepresentation, Hashable {
|
|||||||
public static func == (_ lhs: Self, _ rhs: Self) -> Bool {
|
public static func == (_ lhs: Self, _ rhs: Self) -> Bool {
|
||||||
|
|
||||||
return lhs.id == rhs.id
|
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.id = objectID
|
||||||
self.context = context
|
self.context = context
|
||||||
self.values = values
|
self.values = values
|
||||||
|
self.generation = .init()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// MARK: FilePrivate
|
// MARK: FilePrivate
|
||||||
|
|
||||||
fileprivate var values: [String: Any]
|
fileprivate var values: [String: Any] {
|
||||||
|
|
||||||
|
didSet {
|
||||||
|
|
||||||
|
self.generation = .init()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// MARK: Private
|
// MARK: Private
|
||||||
|
|
||||||
private let id: O.ObjectID
|
private let id: O.ObjectID
|
||||||
private let context: NSManagedObjectContext
|
private let context: NSManagedObjectContext
|
||||||
|
|
||||||
|
private var generation: UUID
|
||||||
|
|
||||||
private var valuesRef: NSDictionary {
|
private var valuesRef: NSDictionary {
|
||||||
|
|
||||||
@@ -144,29 +161,33 @@ extension ObjectSnapshot where O: NSManagedObject {
|
|||||||
/**
|
/**
|
||||||
Returns the value for the property identified by a given key.
|
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)
|
get {
|
||||||
return self.values[key] as! V
|
|
||||||
|
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! {
|
public func value<V: AllowedObjectiveCKeyPathValue>(forKeyPath keyPath: KeyPath<O, V>) -> V! {
|
||||||
|
|
||||||
let key = String(keyPath: keyPath)
|
return self[dynamicMember: keyPath]
|
||||||
return self.values[key] as! V?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@available(*, deprecated, message: "Mutating the property directly now works")
|
||||||
Mutates the value for the property identified by a given key.
|
|
||||||
*/
|
|
||||||
public mutating func setValue<V: AllowedObjectiveCKeyPathValue>(_ value: V!, forKeyPath keyPath: KeyPath<O, V>) {
|
public mutating func setValue<V: AllowedObjectiveCKeyPathValue>(_ value: V!, forKeyPath keyPath: KeyPath<O, V>) {
|
||||||
|
|
||||||
let key = String(keyPath: keyPath)
|
self[dynamicMember: keyPath] = value
|
||||||
self.values[key] = value
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -469,7 +469,7 @@ extension Where where O: CoreStoreObject {
|
|||||||
- parameter keyPath: the keyPath to compare with
|
- parameter keyPath: the keyPath to compare with
|
||||||
- parameter null: the arguments for the `==` operator
|
- 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)
|
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 keyPath: the keyPath to compare with
|
||||||
- parameter null: the arguments for the `==` operator
|
- 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)
|
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
|
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)
|
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
|
Initializes a `Where` clause that compares equality
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user