mirror of
https://github.com/JohnEstropia/CoreStore.git
synced 2026-03-02 14:20:08 +01:00
Compare commits
226 Commits
4.0.0-beta
...
5.1.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e3f9139304 | ||
|
|
4aa461872f | ||
|
|
3d43314076 | ||
|
|
7b1075b759 | ||
|
|
0c29e07ddb | ||
|
|
ce91cf22f9 | ||
|
|
2dd033c002 | ||
|
|
c7fcba112e | ||
|
|
c8b1c4358f | ||
|
|
5431e2e974 | ||
|
|
83e6082c56 | ||
|
|
c7bdbbde57 | ||
|
|
abf15c8aa8 | ||
|
|
d9db7e4a82 | ||
|
|
65dbc22ddd | ||
|
|
51961dd737 | ||
|
|
18a7055cdf | ||
|
|
4b9fddad6a | ||
|
|
fbe7bd7bf8 | ||
|
|
15edabdbb5 | ||
|
|
f447bcfb95 | ||
|
|
15e5e4fdf6 | ||
|
|
583c6b7249 | ||
|
|
18b933957e | ||
|
|
2c7039232e | ||
|
|
d3b3b5ff4a | ||
|
|
d90e8d1303 | ||
|
|
b55dd13dff | ||
|
|
66dd5b6f27 | ||
|
|
49c4b770eb | ||
|
|
662aaa1e75 | ||
|
|
dd4e47d7f9 | ||
|
|
9ea5073bc8 | ||
|
|
e314db8f56 | ||
|
|
48d936d068 | ||
|
|
b2ff8a15ef | ||
|
|
8a4d1cd7c6 | ||
|
|
8ce26c213d | ||
|
|
f3816b9abf | ||
|
|
21961780d4 | ||
|
|
305e2b61a0 | ||
|
|
0430f66240 | ||
|
|
65772edd00 | ||
|
|
02d7870d75 | ||
|
|
aca1709e13 | ||
|
|
b6ee0b014f | ||
|
|
e37186da73 | ||
|
|
588fa35c84 | ||
|
|
f6614cda66 | ||
|
|
639574d8c2 | ||
|
|
094703155c | ||
|
|
6dd254e713 | ||
|
|
204025721c | ||
|
|
27ffc1d225 | ||
|
|
ba6f0c39d5 | ||
|
|
ab2eac8f6c | ||
|
|
f460a0b30f | ||
|
|
50bc3ace06 | ||
|
|
d2ddf2002f | ||
|
|
b4117eeb02 | ||
|
|
106275b2dd | ||
|
|
08d9298be0 | ||
|
|
ff0c4d94fc | ||
|
|
50e50c0613 | ||
|
|
5c8a0e425b | ||
|
|
03b71caf7e | ||
|
|
7ff29d6086 | ||
|
|
8d86425875 | ||
|
|
97242d9726 | ||
|
|
780ff4e60b | ||
|
|
11743dfb5f | ||
|
|
9eaf85388c | ||
|
|
06635c9d2f | ||
|
|
1d2eef7894 | ||
|
|
85ed815ec2 | ||
|
|
096e5493a6 | ||
|
|
0aa8c03424 | ||
|
|
4ead3c34dd | ||
|
|
645034dde5 | ||
|
|
85706a3c57 | ||
|
|
c5ae4606b9 | ||
|
|
fa682215c5 | ||
|
|
e814733ae9 | ||
|
|
e2236698fa | ||
|
|
be5da632b3 | ||
|
|
dc73cd6dd9 | ||
|
|
7beb3bec75 | ||
|
|
53100b202d | ||
|
|
cc84b1f8bd | ||
|
|
474f52ed2b | ||
|
|
16225fc4c6 | ||
|
|
03bb7619da | ||
|
|
1bfb7451c3 | ||
|
|
3e082d5ed4 | ||
|
|
e45d67252c | ||
|
|
3d427c29c4 | ||
|
|
1068517b94 | ||
|
|
0d23ce1598 | ||
|
|
fd1ce20863 | ||
|
|
2c5fa63f40 | ||
|
|
78e43a37a5 | ||
|
|
fde85a9743 | ||
|
|
dbbc0adae5 | ||
|
|
2a62770552 | ||
|
|
f436b26e8e | ||
|
|
c566226747 | ||
|
|
cd405e038e | ||
|
|
92a37053b0 | ||
|
|
0b57cff27d | ||
|
|
3ebc44b546 | ||
|
|
68f1027ba7 | ||
|
|
005729be85 | ||
|
|
8bac4aa901 | ||
|
|
da170c7e51 | ||
|
|
211e69023e | ||
|
|
2912dcf010 | ||
|
|
3e00a3da06 | ||
|
|
a33e248828 | ||
|
|
75e14fbbed | ||
|
|
9922deac4d | ||
|
|
86be046c9f | ||
|
|
0f10bc3349 | ||
|
|
9685f0aef2 | ||
|
|
1e51000155 | ||
|
|
3bd459bb1a | ||
|
|
c89bc3c227 | ||
|
|
0f405a50aa | ||
|
|
f5e1643ef7 | ||
|
|
f62137fb58 | ||
|
|
37fbedd799 | ||
|
|
28b43f33fa | ||
|
|
81a72f29ea | ||
|
|
f7aaf4fb2a | ||
|
|
a52acf2ebd | ||
|
|
74c64619c3 | ||
|
|
4a5bc6450b | ||
|
|
fe69e7c6c4 | ||
|
|
ccf7c62aad | ||
|
|
f36cb8af63 | ||
|
|
10ccadd96c | ||
|
|
5c0e78bd53 | ||
|
|
8a09688117 | ||
|
|
a366bcf1a3 | ||
|
|
fcd4be9011 | ||
|
|
535eb76adc | ||
|
|
c6e68ac24f | ||
|
|
aff966aac9 | ||
|
|
32743b3aee | ||
|
|
a20ad87583 | ||
|
|
a11915db12 | ||
|
|
961f39a806 | ||
|
|
3096cb784c | ||
|
|
809aa4ff96 | ||
|
|
8d926d25ec | ||
|
|
790454f514 | ||
|
|
9a38707c58 | ||
|
|
fb7e2f7f7f | ||
|
|
f72efc80b2 | ||
|
|
fcda5399da | ||
|
|
fd3a9b00ec | ||
|
|
f56c37f9ee | ||
|
|
5f5000218a | ||
|
|
e8eb309d82 | ||
|
|
d0c3203e63 | ||
|
|
f5b3901caa | ||
|
|
1a99fea820 | ||
|
|
195b60615b | ||
|
|
2c394965b8 | ||
|
|
746d697691 | ||
|
|
5689158b43 | ||
|
|
6fcdf3d011 | ||
|
|
e26573c18e | ||
|
|
801cf8d9f0 | ||
|
|
eced8f2e93 | ||
|
|
3b735d07ec | ||
|
|
5eb5476e3a | ||
|
|
6a42a0054e | ||
|
|
8c437e19b8 | ||
|
|
9cd3b6c879 | ||
|
|
fe135acbec | ||
|
|
997c5bdcfa | ||
|
|
23e12c4539 | ||
|
|
ca9798be14 | ||
|
|
6e01a58c85 | ||
|
|
f618617053 | ||
|
|
49b8b9c372 | ||
|
|
129f975d96 | ||
|
|
a2e463e58c | ||
|
|
5fd50f0e15 | ||
|
|
7f9a915d71 | ||
|
|
0a81736b7a | ||
|
|
f9b6dd0c6a | ||
|
|
0354401b56 | ||
|
|
0304067beb | ||
|
|
ddd83da434 | ||
|
|
fc7df671de | ||
|
|
5fde9030c7 | ||
|
|
d7b07b3f00 | ||
|
|
ddd1ffb29f | ||
|
|
98094000bb | ||
|
|
d5026ef996 | ||
|
|
2cd913b9dd | ||
|
|
ad9520abbc | ||
|
|
c0fc57d10c | ||
|
|
0cf4d303e4 | ||
|
|
6de397958a | ||
|
|
55292a84dc | ||
|
|
981b560d53 | ||
|
|
c4c4dd55cd | ||
|
|
1ddbe20c86 | ||
|
|
da9e8c1550 | ||
|
|
ef0937fec4 | ||
|
|
35885b40de | ||
|
|
d669569196 | ||
|
|
ae919ff3c8 | ||
|
|
1a7a4690d1 | ||
|
|
b9b96d1a35 | ||
|
|
da3a9590ac | ||
|
|
6b3d75bea1 | ||
|
|
d44721fef0 | ||
|
|
3f268e8376 | ||
|
|
303fea4ebe | ||
|
|
77173cdad0 | ||
|
|
1e24a7d739 | ||
|
|
a3b33bedb8 | ||
|
|
eaf7544c50 |
2
.cocoapods.yml
Normal file
2
.cocoapods.yml
Normal file
@@ -0,0 +1,2 @@
|
||||
try:
|
||||
project: 'CoreStore.xcworkspace'
|
||||
@@ -1 +0,0 @@
|
||||
3.1
|
||||
35
.travis.yml
35
.travis.yml
@@ -1,5 +1,5 @@
|
||||
language: objective-c
|
||||
osx_image: xcode8.3
|
||||
osx_image: xcode9
|
||||
sudo: false
|
||||
git:
|
||||
submodules: false
|
||||
@@ -9,25 +9,26 @@ env:
|
||||
global:
|
||||
- LC_CTYPE=en_US.UTF-8
|
||||
- LANG=en_US.UTF-8
|
||||
matrix:
|
||||
- DESTINATION="OS=10.3,name=iPhone 7" SCHEME="CoreStore iOS" SDK=iphonesimulator10.3 RUN_TESTS="YES" POD_LINT="NO"
|
||||
- DESTINATION="OS=10.1,name=iPhone 7" SCHEME="CoreStore iOS" SDK=iphonesimulator10.3 RUN_TESTS="YES" POD_LINT="NO"
|
||||
- DESTINATION="OS=9.0,name=iPhone 6 Plus" SCHEME="CoreStore iOS" SDK=iphonesimulator10.3 RUN_TESTS="YES" POD_LINT="NO"
|
||||
- DESTINATION="OS=8.4,name=iPhone 6" SCHEME="CoreStore iOS" SDK=iphonesimulator10.3 RUN_TESTS="YES" POD_LINT="NO"
|
||||
- DESTINATION="OS=8.3,name=iPhone 5S" SCHEME="CoreStore iOS" SDK=iphonesimulator10.3 RUN_TESTS="YES" POD_LINT="NO"
|
||||
- DESTINATION="OS=8.3,name=iPhone 5" SCHEME="CoreStore iOS" SDK=iphonesimulator10.3 RUN_TESTS="YES" POD_LINT="NO"
|
||||
- DESTINATION="OS=8.3,name=iPhone 4S" SCHEME="CoreStore iOS" SDK=iphonesimulator10.3 RUN_TESTS="YES" POD_LINT="NO"
|
||||
- DESTINATION="arch=x86_64" SCHEME="CoreStore OSX" SDK=macosx10.12 RUN_TESTS="YES" POD_LINT="NO"
|
||||
- DESTINATION="OS=3.2,name=Apple Watch - 42mm" SCHEME="CoreStore watchOS" SDK=watchsimulator3.2 RUN_TESTS="NO" POD_LINT="NO"
|
||||
- DESTINATION="OS=2.2,name=Apple Watch - 42mm" SCHEME="CoreStore watchOS" SDK=watchsimulator3.2 RUN_TESTS="NO" POD_LINT="NO"
|
||||
- DESTINATION="OS=10.2,name=Apple TV 1080p" SCHEME="CoreStore tvOS" SDK=appletvsimulator10.2 RUN_TESTS="YES" POD_LINT="NO"
|
||||
- DESTINATION="OS=9.2,name=Apple TV 1080p" SCHEME="CoreStore tvOS" SDK=appletvsimulator10.2 RUN_TESTS="YES" POD_LINT="NO"
|
||||
matrix:
|
||||
- DESTINATION="OS=11.0,name=iPhone 8" SCHEME="CoreStore iOS" SDK=iphonesimulator11.0 RUN_TESTS="YES" POD_LINT="NO"
|
||||
- DESTINATION="OS=10.3,name=iPhone 7" SCHEME="CoreStore iOS" SDK=iphonesimulator11.0 RUN_TESTS="YES" POD_LINT="NO"
|
||||
- DESTINATION="OS=10.1,name=iPhone 7" SCHEME="CoreStore iOS" SDK=iphonesimulator11.0 RUN_TESTS="YES" POD_LINT="NO"
|
||||
- DESTINATION="OS=9.0,name=iPhone 6 Plus" SCHEME="CoreStore iOS" SDK=iphonesimulator11.0 RUN_TESTS="YES" POD_LINT="NO"
|
||||
- DESTINATION="arch=x86_64" SCHEME="CoreStore OSX" SDK=macosx10.13 RUN_TESTS="YES" POD_LINT="NO"
|
||||
- DESTINATION="OS=4.0,name=Apple Watch - 42mm" SCHEME="CoreStore watchOS" SDK=watchsimulator4.0 RUN_TESTS="NO" POD_LINT="NO"
|
||||
- DESTINATION="OS=3.2,name=Apple Watch - 42mm" SCHEME="CoreStore watchOS" SDK=watchsimulator4.0 RUN_TESTS="NO" POD_LINT="NO"
|
||||
- DESTINATION="OS=2.2,name=Apple Watch - 42mm" SCHEME="CoreStore watchOS" SDK=watchsimulator4.0 RUN_TESTS="NO" POD_LINT="NO"
|
||||
- DESTINATION="OS=11.0,name=Apple TV 1080p" SCHEME="CoreStore tvOS" SDK=appletvsimulator11.0 RUN_TESTS="YES" POD_LINT="NO"
|
||||
- DESTINATION="OS=10.2,name=Apple TV 1080p" SCHEME="CoreStore tvOS" SDK=appletvsimulator11.0 RUN_TESTS="YES" POD_LINT="NO"
|
||||
- DESTINATION="OS=9.2,name=Apple TV 1080p" SCHEME="CoreStore tvOS" SDK=appletvsimulator11.0 RUN_TESTS="YES" POD_LINT="NO"
|
||||
before_install:
|
||||
- gem install cocoapods --no-rdoc --no-ri --no-document --quiet
|
||||
- gem install xcpretty --no-rdoc --no-ri --no-document --quiet
|
||||
- curl -OlL "https://github.com/Carthage/Carthage/releases/download/0.20.1/Carthage.pkg"
|
||||
- curl -OlL "https://github.com/Carthage/Carthage/releases/download/0.26.0/Carthage.pkg"
|
||||
- sudo installer -pkg "Carthage.pkg" -target /
|
||||
- rm "Carthage.pkg"
|
||||
- npm install ios-sim -g
|
||||
- ios-sim start --devicetypeid "com.apple.CoreSimulator.SimDeviceType.iPhone-8, 11.0"
|
||||
before_script:
|
||||
- carthage update --use-submodules
|
||||
script:
|
||||
@@ -38,8 +39,8 @@ script:
|
||||
xcodebuild -workspace CoreStore.xcworkspace -scheme "$SCHEME" -sdk "$SDK" -destination "$DESTINATION" -configuration Debug ONLY_ACTIVE_ARCH=NO clean test | xcpretty -c;
|
||||
xcodebuild -workspace CoreStore.xcworkspace -scheme "$SCHEME" -sdk "$SDK" -destination "$DESTINATION" -configuration Release ONLY_ACTIVE_ARCH=NO clean test | xcpretty -c;
|
||||
fi
|
||||
- xcodebuild -workspace "CoreStore.xcworkspace" -scheme "CoreStore iOS" -sdk "iphonesimulator10.3" -destination "OS=10.3,name=iPhone 7" -configuration Debug ONLY_ACTIVE_ARCH=NO clean test | xcpretty -c;
|
||||
- xcodebuild -workspace "CoreStore.xcworkspace" -scheme "CoreStore iOS" -sdk "iphonesimulator10.3" -destination "OS=10.3,name=iPhone 7" -configuration Release ONLY_ACTIVE_ARCH=NO clean test | xcpretty -c;
|
||||
- xcodebuild -workspace "CoreStore.xcworkspace" -scheme "CoreStoreDemo" -sdk "iphonesimulator11.0" -destination "OS=11.0,name=iPhone 8" -configuration Debug ONLY_ACTIVE_ARCH=NO build | xcpretty -c;
|
||||
- xcodebuild -workspace "CoreStore.xcworkspace" -scheme "CoreStoreDemo" -sdk "iphonesimulator11.0" -destination "OS=11.0,name=iPhone 8" -configuration Release ONLY_ACTIVE_ARCH=NO build | xcpretty -c;
|
||||
- if [ $POD_LINT == "YES" ]; then
|
||||
pod lib lint --quick;
|
||||
fi
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
Pod::Spec.new do |s|
|
||||
s.name = "CoreStore"
|
||||
s.version = "4.0.0-beta2"
|
||||
s.version = "5.1.1"
|
||||
s.swift_version = "4.1"
|
||||
s.license = "MIT"
|
||||
s.summary = "Unleashing the real power of Core Data with the elegance and safety of Swift"
|
||||
s.homepage = "https://github.com/JohnEstropia/CoreStore"
|
||||
s.author = { "John Rommel Estropia" => "rommel.estropia@gmail.com" }
|
||||
s.source = { :git => "https://github.com/JohnEstropia/CoreStore.git", :tag => s.version.to_s }
|
||||
|
||||
s.ios.deployment_target = "8.0"
|
||||
s.osx.deployment_target = "10.10"
|
||||
s.ios.deployment_target = "9.0"
|
||||
s.osx.deployment_target = "10.11"
|
||||
s.watchos.deployment_target = "2.0"
|
||||
s.tvos.deployment_target = "9.0"
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
82BA18B51C4BBD3F00A0916E /* BaseDataTransaction+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84EFE1AFF847B0064E85B /* BaseDataTransaction+Querying.swift */; };
|
||||
82BA18B61C4BBD3F00A0916E /* DataStack+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F061AFF847B0064E85B /* DataStack+Querying.swift */; };
|
||||
82BA18B71C4BBD3F00A0916E /* CoreStore+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F071AFF847B0064E85B /* CoreStore+Querying.swift */; };
|
||||
82BA18B81C4BBD4200A0916E /* ClauseTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F401AFF8CCD0064E85B /* ClauseTypes.swift */; };
|
||||
82BA18B81C4BBD4200A0916E /* TypeErasedClauses.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F401AFF8CCD0064E85B /* TypeErasedClauses.swift */; };
|
||||
82BA18B91C4BBD4A00A0916E /* From.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F011AFF847B0064E85B /* From.swift */; };
|
||||
82BA18BA1C4BBD4A00A0916E /* Select.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F031AFF847B0064E85B /* Select.swift */; };
|
||||
82BA18BB1C4BBD4A00A0916E /* Where.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F051AFF847B0064E85B /* Where.swift */; };
|
||||
@@ -101,6 +101,18 @@
|
||||
B51FE5AF1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift in Sources */ = {isa = PBXBuildFile; fileRef = B51FE5AA1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift */; };
|
||||
B5202CFA1C04688100DED140 /* NSFetchedResultsController+Convenience.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5202CF91C04688100DED140 /* NSFetchedResultsController+Convenience.swift */; };
|
||||
B5202CFD1C046E8400DED140 /* NSFetchedResultsController+Convenience.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5202CF91C04688100DED140 /* NSFetchedResultsController+Convenience.swift */; };
|
||||
B5215CA41FA47DFD00139E3A /* FetchChainBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5215CA31FA47DFD00139E3A /* FetchChainBuilder.swift */; };
|
||||
B5215CA51FA47DFD00139E3A /* FetchChainBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5215CA31FA47DFD00139E3A /* FetchChainBuilder.swift */; };
|
||||
B5215CA61FA47DFD00139E3A /* FetchChainBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5215CA31FA47DFD00139E3A /* FetchChainBuilder.swift */; };
|
||||
B5215CA71FA47DFD00139E3A /* FetchChainBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5215CA31FA47DFD00139E3A /* FetchChainBuilder.swift */; };
|
||||
B5215CA91FA4810300139E3A /* QueryChainBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5215CA81FA4810300139E3A /* QueryChainBuilder.swift */; };
|
||||
B5215CAA1FA4810300139E3A /* QueryChainBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5215CA81FA4810300139E3A /* QueryChainBuilder.swift */; };
|
||||
B5215CAB1FA4810300139E3A /* QueryChainBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5215CA81FA4810300139E3A /* QueryChainBuilder.swift */; };
|
||||
B5215CAC1FA4810300139E3A /* QueryChainBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5215CA81FA4810300139E3A /* QueryChainBuilder.swift */; };
|
||||
B5215CAE1FA4812500139E3A /* SectionMonitorBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5215CAD1FA4812500139E3A /* SectionMonitorBuilder.swift */; };
|
||||
B5215CAF1FA4812500139E3A /* SectionMonitorBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5215CAD1FA4812500139E3A /* SectionMonitorBuilder.swift */; };
|
||||
B5215CB01FA4812500139E3A /* SectionMonitorBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5215CAD1FA4812500139E3A /* SectionMonitorBuilder.swift */; };
|
||||
B5215CB11FA4812500139E3A /* SectionMonitorBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5215CAD1FA4812500139E3A /* SectionMonitorBuilder.swift */; };
|
||||
B5220E081D0C5F8D009BC71E /* ObjectObserverTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5220E071D0C5F8D009BC71E /* ObjectObserverTests.swift */; };
|
||||
B5220E091D0C5F8D009BC71E /* ObjectObserverTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5220E071D0C5F8D009BC71E /* ObjectObserverTests.swift */; };
|
||||
B5220E0C1D0D0D19009BC71E /* ImportTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5220E0B1D0D0D19009BC71E /* ImportTests.swift */; };
|
||||
@@ -184,7 +196,7 @@
|
||||
B52DD1A71BE1F93200949AFE /* BaseDataTransaction+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84EFE1AFF847B0064E85B /* BaseDataTransaction+Querying.swift */; };
|
||||
B52DD1A81BE1F93200949AFE /* DataStack+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F061AFF847B0064E85B /* DataStack+Querying.swift */; };
|
||||
B52DD1A91BE1F93200949AFE /* CoreStore+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F071AFF847B0064E85B /* CoreStore+Querying.swift */; };
|
||||
B52DD1AA1BE1F93500949AFE /* ClauseTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F401AFF8CCD0064E85B /* ClauseTypes.swift */; };
|
||||
B52DD1AA1BE1F93500949AFE /* TypeErasedClauses.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F401AFF8CCD0064E85B /* TypeErasedClauses.swift */; };
|
||||
B52DD1AB1BE1F93900949AFE /* From.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F011AFF847B0064E85B /* From.swift */; };
|
||||
B52DD1AC1BE1F93900949AFE /* Select.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F031AFF847B0064E85B /* Select.swift */; };
|
||||
B52DD1AD1BE1F93900949AFE /* Where.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F051AFF847B0064E85B /* Where.swift */; };
|
||||
@@ -214,10 +226,10 @@
|
||||
B52F743E1E9B8724005F3DAC /* DynamicSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F743A1E9B8724005F3DAC /* DynamicSchema.swift */; };
|
||||
B52F743F1E9B8724005F3DAC /* DynamicSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F743A1E9B8724005F3DAC /* DynamicSchema.swift */; };
|
||||
B52F74401E9B8724005F3DAC /* DynamicSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F743A1E9B8724005F3DAC /* DynamicSchema.swift */; };
|
||||
B52F74411E9B8724005F3DAC /* LegacyXcodeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F743B1E9B8724005F3DAC /* LegacyXcodeDataModelSchema.swift */; };
|
||||
B52F74421E9B8724005F3DAC /* LegacyXcodeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F743B1E9B8724005F3DAC /* LegacyXcodeDataModelSchema.swift */; };
|
||||
B52F74431E9B8724005F3DAC /* LegacyXcodeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F743B1E9B8724005F3DAC /* LegacyXcodeDataModelSchema.swift */; };
|
||||
B52F74441E9B8724005F3DAC /* LegacyXcodeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F743B1E9B8724005F3DAC /* LegacyXcodeDataModelSchema.swift */; };
|
||||
B52F74411E9B8724005F3DAC /* UnsafeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F743B1E9B8724005F3DAC /* UnsafeDataModelSchema.swift */; };
|
||||
B52F74421E9B8724005F3DAC /* UnsafeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F743B1E9B8724005F3DAC /* UnsafeDataModelSchema.swift */; };
|
||||
B52F74431E9B8724005F3DAC /* UnsafeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F743B1E9B8724005F3DAC /* UnsafeDataModelSchema.swift */; };
|
||||
B52F74441E9B8724005F3DAC /* UnsafeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F743B1E9B8724005F3DAC /* UnsafeDataModelSchema.swift */; };
|
||||
B52F74451E9B8724005F3DAC /* XcodeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F743C1E9B8724005F3DAC /* XcodeDataModelSchema.swift */; };
|
||||
B52F74461E9B8724005F3DAC /* XcodeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F743C1E9B8724005F3DAC /* XcodeDataModelSchema.swift */; };
|
||||
B52F74471E9B8724005F3DAC /* XcodeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B52F743C1E9B8724005F3DAC /* XcodeDataModelSchema.swift */; };
|
||||
@@ -238,6 +250,14 @@
|
||||
B538BA781D15B3E30003A766 /* CoreStoreBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = B538BA701D15B3E30003A766 /* CoreStoreBridge.m */; };
|
||||
B538BA791D15B3E30003A766 /* CoreStoreBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = B538BA701D15B3E30003A766 /* CoreStoreBridge.m */; };
|
||||
B538BA7A1D15B3E30003A766 /* CoreStoreBridge.m in Sources */ = {isa = PBXBuildFile; fileRef = B538BA701D15B3E30003A766 /* CoreStoreBridge.m */; };
|
||||
B53B275F1EE3B92E00E9B352 /* CoreStoreManagedObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53B275E1EE3B92E00E9B352 /* CoreStoreManagedObject.swift */; };
|
||||
B53B27601EE3B92E00E9B352 /* CoreStoreManagedObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53B275E1EE3B92E00E9B352 /* CoreStoreManagedObject.swift */; };
|
||||
B53B27611EE3B92E00E9B352 /* CoreStoreManagedObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53B275E1EE3B92E00E9B352 /* CoreStoreManagedObject.swift */; };
|
||||
B53B27621EE3B92E00E9B352 /* CoreStoreManagedObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53B275E1EE3B92E00E9B352 /* CoreStoreManagedObject.swift */; };
|
||||
B53CA9A21EF1EF1600E0F440 /* PartialObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53CA9A11EF1EF1600E0F440 /* PartialObject.swift */; };
|
||||
B53CA9A31EF1EF1600E0F440 /* PartialObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53CA9A11EF1EF1600E0F440 /* PartialObject.swift */; };
|
||||
B53CA9A41EF1EF1600E0F440 /* PartialObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53CA9A11EF1EF1600E0F440 /* PartialObject.swift */; };
|
||||
B53CA9A51EF1EF1600E0F440 /* PartialObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53CA9A11EF1EF1600E0F440 /* PartialObject.swift */; };
|
||||
B53FB9FE1CAB2D2F00F0D40A /* CSMigrationResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53FB9FD1CAB2D2F00F0D40A /* CSMigrationResult.swift */; };
|
||||
B53FBA001CAB2D2F00F0D40A /* CSMigrationResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53FB9FD1CAB2D2F00F0D40A /* CSMigrationResult.swift */; };
|
||||
B53FBA011CAB2D2F00F0D40A /* CSMigrationResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B53FB9FD1CAB2D2F00F0D40A /* CSMigrationResult.swift */; };
|
||||
@@ -316,6 +336,10 @@
|
||||
B5519A601CA21954002BEF78 /* CSAsynchronousDataTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5519A5E1CA21954002BEF78 /* CSAsynchronousDataTransaction.swift */; };
|
||||
B5519A611CA21954002BEF78 /* CSAsynchronousDataTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5519A5E1CA21954002BEF78 /* CSAsynchronousDataTransaction.swift */; };
|
||||
B5519A621CA21954002BEF78 /* CSAsynchronousDataTransaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5519A5E1CA21954002BEF78 /* CSAsynchronousDataTransaction.swift */; };
|
||||
B55514EA1EED8BF900BAB888 /* From+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B55514E91EED8BF900BAB888 /* From+Querying.swift */; };
|
||||
B55514EB1EED8BF900BAB888 /* From+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B55514E91EED8BF900BAB888 /* From+Querying.swift */; };
|
||||
B55514EC1EED8BF900BAB888 /* From+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B55514E91EED8BF900BAB888 /* From+Querying.swift */; };
|
||||
B55514ED1EED8BF900BAB888 /* From+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B55514E91EED8BF900BAB888 /* From+Querying.swift */; };
|
||||
B55717441D15B09E009BDBCA /* CoreStoreBridge.h in Headers */ = {isa = PBXBuildFile; fileRef = B55717421D15AF9C009BDBCA /* CoreStoreBridge.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
B55717451D15B09F009BDBCA /* CoreStoreBridge.h in Headers */ = {isa = PBXBuildFile; fileRef = B55717421D15AF9C009BDBCA /* CoreStoreBridge.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
B55717461D15B0A1009BDBCA /* CoreStoreBridge.h in Headers */ = {isa = PBXBuildFile; fileRef = B55717421D15AF9C009BDBCA /* CoreStoreBridge.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
@@ -354,7 +378,7 @@
|
||||
B56321921BD65216006C9394 /* BaseDataTransaction+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84EFE1AFF847B0064E85B /* BaseDataTransaction+Querying.swift */; };
|
||||
B56321931BD65216006C9394 /* DataStack+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F061AFF847B0064E85B /* DataStack+Querying.swift */; };
|
||||
B56321941BD65216006C9394 /* CoreStore+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F071AFF847B0064E85B /* CoreStore+Querying.swift */; };
|
||||
B56321951BD65216006C9394 /* ClauseTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F401AFF8CCD0064E85B /* ClauseTypes.swift */; };
|
||||
B56321951BD65216006C9394 /* TypeErasedClauses.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F401AFF8CCD0064E85B /* TypeErasedClauses.swift */; };
|
||||
B56321961BD65216006C9394 /* From.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F011AFF847B0064E85B /* From.swift */; };
|
||||
B56321971BD65216006C9394 /* Select.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F031AFF847B0064E85B /* Select.swift */; };
|
||||
B56321981BD65216006C9394 /* Where.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F051AFF847B0064E85B /* Where.swift */; };
|
||||
@@ -426,10 +450,10 @@
|
||||
B56923FB1EB82956007C4DC9 /* CSXcodeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923F91EB82956007C4DC9 /* CSXcodeDataModelSchema.swift */; };
|
||||
B56923FC1EB82956007C4DC9 /* CSXcodeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923F91EB82956007C4DC9 /* CSXcodeDataModelSchema.swift */; };
|
||||
B56923FD1EB82956007C4DC9 /* CSXcodeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923F91EB82956007C4DC9 /* CSXcodeDataModelSchema.swift */; };
|
||||
B56923FF1EB82976007C4DC9 /* CSLegacyXcodeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923FE1EB82976007C4DC9 /* CSLegacyXcodeDataModelSchema.swift */; };
|
||||
B56924001EB82976007C4DC9 /* CSLegacyXcodeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923FE1EB82976007C4DC9 /* CSLegacyXcodeDataModelSchema.swift */; };
|
||||
B56924011EB82976007C4DC9 /* CSLegacyXcodeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923FE1EB82976007C4DC9 /* CSLegacyXcodeDataModelSchema.swift */; };
|
||||
B56924021EB82976007C4DC9 /* CSLegacyXcodeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923FE1EB82976007C4DC9 /* CSLegacyXcodeDataModelSchema.swift */; };
|
||||
B56923FF1EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923FE1EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift */; };
|
||||
B56924001EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923FE1EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift */; };
|
||||
B56924011EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923FE1EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift */; };
|
||||
B56924021EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56923FE1EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift */; };
|
||||
B56964D41B22FFAD0075EE4A /* DataStack+Migration.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56964D31B22FFAD0075EE4A /* DataStack+Migration.swift */; };
|
||||
B56965241B356B820075EE4A /* MigrationResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = B56965231B356B820075EE4A /* MigrationResult.swift */; };
|
||||
B57D27BE1D0BBE8200539C58 /* BaseTestDataTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = B57D27BD1D0BBE8200539C58 /* BaseTestDataTestCase.swift */; };
|
||||
@@ -441,6 +465,18 @@
|
||||
B580857A1CDF808C004C2EEB /* SetupTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B58085741CDF7F00004C2EEB /* SetupTests.swift */; };
|
||||
B580857B1CDF808D004C2EEB /* SetupTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B58085741CDF7F00004C2EEB /* SetupTests.swift */; };
|
||||
B580857C1CDF808F004C2EEB /* SetupTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B58085741CDF7F00004C2EEB /* SetupTests.swift */; };
|
||||
B5831B701F34AC3400A9F647 /* AttributeProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5831B6F1F34AC3400A9F647 /* AttributeProtocol.swift */; };
|
||||
B5831B711F34AC3400A9F647 /* AttributeProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5831B6F1F34AC3400A9F647 /* AttributeProtocol.swift */; };
|
||||
B5831B721F34AC3400A9F647 /* AttributeProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5831B6F1F34AC3400A9F647 /* AttributeProtocol.swift */; };
|
||||
B5831B731F34AC3400A9F647 /* AttributeProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5831B6F1F34AC3400A9F647 /* AttributeProtocol.swift */; };
|
||||
B5831B751F34AC7A00A9F647 /* RelationshipProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5831B741F34AC7A00A9F647 /* RelationshipProtocol.swift */; };
|
||||
B5831B761F34AC7A00A9F647 /* RelationshipProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5831B741F34AC7A00A9F647 /* RelationshipProtocol.swift */; };
|
||||
B5831B771F34AC7A00A9F647 /* RelationshipProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5831B741F34AC7A00A9F647 /* RelationshipProtocol.swift */; };
|
||||
B5831B781F34AC7A00A9F647 /* RelationshipProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5831B741F34AC7A00A9F647 /* RelationshipProtocol.swift */; };
|
||||
B5831B7A1F34ACBA00A9F647 /* Transformable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5831B791F34ACBA00A9F647 /* Transformable.swift */; };
|
||||
B5831B7B1F34ACBA00A9F647 /* Transformable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5831B791F34ACBA00A9F647 /* Transformable.swift */; };
|
||||
B5831B7C1F34ACBA00A9F647 /* Transformable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5831B791F34ACBA00A9F647 /* Transformable.swift */; };
|
||||
B5831B7D1F34ACBA00A9F647 /* Transformable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5831B791F34ACBA00A9F647 /* Transformable.swift */; };
|
||||
B58B22F51C93C1BA00521925 /* CoreStore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2F03A53019C5C6DA005002A5 /* CoreStore.framework */; };
|
||||
B58D0C631EAA0C7E003EDD87 /* NSManagedObject+DynamicModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B58D0C621EAA0C7E003EDD87 /* NSManagedObject+DynamicModel.swift */; };
|
||||
B58D0C641EAA0C7E003EDD87 /* NSManagedObject+DynamicModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B58D0C621EAA0C7E003EDD87 /* NSManagedObject+DynamicModel.swift */; };
|
||||
@@ -465,6 +501,10 @@
|
||||
B59FA0B01CCBACA7007C9BCA /* ICloudStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B59FA0AD1CCBAC95007C9BCA /* ICloudStore.swift */; };
|
||||
B59FA0B11CCBACA7007C9BCA /* ICloudStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B59FA0AD1CCBAC95007C9BCA /* ICloudStore.swift */; };
|
||||
B59FA0B21CCBACA8007C9BCA /* ICloudStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B59FA0AD1CCBAC95007C9BCA /* ICloudStore.swift */; };
|
||||
B5A1DAC81F111BFA003CF369 /* KeyPath+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A1DAC71F111BFA003CF369 /* KeyPath+Querying.swift */; };
|
||||
B5A1DAC91F111BFA003CF369 /* KeyPath+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A1DAC71F111BFA003CF369 /* KeyPath+Querying.swift */; };
|
||||
B5A1DACA1F111BFA003CF369 /* KeyPath+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A1DAC71F111BFA003CF369 /* KeyPath+Querying.swift */; };
|
||||
B5A1DACB1F111BFA003CF369 /* KeyPath+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A1DAC71F111BFA003CF369 /* KeyPath+Querying.swift */; };
|
||||
B5A261211B64BFDB006EB6D3 /* MigrationType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A261201B64BFDB006EB6D3 /* MigrationType.swift */; };
|
||||
B5A5F2661CAEC50F004AB9AF /* CSSelect.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A5F2651CAEC50F004AB9AF /* CSSelect.swift */; };
|
||||
B5A5F2681CAEC50F004AB9AF /* CSSelect.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A5F2651CAEC50F004AB9AF /* CSSelect.swift */; };
|
||||
@@ -488,6 +528,14 @@
|
||||
B5C976E71C6E3A5A00B1AF90 /* CoreStoreFetchedResultsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5C976E61C6E3A5900B1AF90 /* CoreStoreFetchedResultsController.swift */; };
|
||||
B5C976E81C6E3A5D00B1AF90 /* CoreStoreFetchedResultsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5C976E61C6E3A5900B1AF90 /* CoreStoreFetchedResultsController.swift */; };
|
||||
B5C976E91C6E3A5E00B1AF90 /* CoreStoreFetchedResultsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5C976E61C6E3A5900B1AF90 /* CoreStoreFetchedResultsController.swift */; };
|
||||
B5CA2B081F7E5ACA004B1936 /* WhereClauseType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5CA2B071F7E5ACA004B1936 /* WhereClauseType.swift */; };
|
||||
B5CA2B091F7E5ACA004B1936 /* WhereClauseType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5CA2B071F7E5ACA004B1936 /* WhereClauseType.swift */; };
|
||||
B5CA2B0A1F7E5ACA004B1936 /* WhereClauseType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5CA2B071F7E5ACA004B1936 /* WhereClauseType.swift */; };
|
||||
B5CA2B0B1F7E5ACA004B1936 /* WhereClauseType.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5CA2B071F7E5ACA004B1936 /* WhereClauseType.swift */; };
|
||||
B5CA2B121F81DBFE004B1936 /* DynamicKeyPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5CA2B111F81DBFE004B1936 /* DynamicKeyPath.swift */; };
|
||||
B5CA2B131F81DBFE004B1936 /* DynamicKeyPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5CA2B111F81DBFE004B1936 /* DynamicKeyPath.swift */; };
|
||||
B5CA2B141F81DBFE004B1936 /* DynamicKeyPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5CA2B111F81DBFE004B1936 /* DynamicKeyPath.swift */; };
|
||||
B5CA2B151F81DBFF004B1936 /* DynamicKeyPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5CA2B111F81DBFE004B1936 /* DynamicKeyPath.swift */; };
|
||||
B5D1E22C19FA9FBC003B2874 /* CoreStoreError.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D1E22B19FA9FBC003B2874 /* CoreStoreError.swift */; };
|
||||
B5D339B41E925C2B00C880DE /* DynamicModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339B31E925C2B00C880DE /* DynamicModelTests.swift */; };
|
||||
B5D339B51E925C2B00C880DE /* DynamicModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D339B31E925C2B00C880DE /* DynamicModelTests.swift */; };
|
||||
@@ -610,7 +658,7 @@
|
||||
B5E84F361AFF85470064E85B /* NSManagedObjectContext+Setup.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F321AFF85470064E85B /* NSManagedObjectContext+Setup.swift */; };
|
||||
B5E84F371AFF85470064E85B /* NSManagedObjectContext+Transaction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F331AFF85470064E85B /* NSManagedObjectContext+Transaction.swift */; };
|
||||
B5E84F391AFF85470064E85B /* NSManagedObjectContext+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F351AFF85470064E85B /* NSManagedObjectContext+Querying.swift */; };
|
||||
B5E84F411AFF8CCD0064E85B /* ClauseTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F401AFF8CCD0064E85B /* ClauseTypes.swift */; };
|
||||
B5E84F411AFF8CCD0064E85B /* TypeErasedClauses.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5E84F401AFF8CCD0064E85B /* TypeErasedClauses.swift */; };
|
||||
B5ECDBDF1CA6BB2B00C7F112 /* CSBaseDataTransaction+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5ECDBDE1CA6BB2B00C7F112 /* CSBaseDataTransaction+Querying.swift */; };
|
||||
B5ECDBE11CA6BB2B00C7F112 /* CSBaseDataTransaction+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5ECDBDE1CA6BB2B00C7F112 /* CSBaseDataTransaction+Querying.swift */; };
|
||||
B5ECDBE21CA6BB2B00C7F112 /* CSBaseDataTransaction+Querying.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5ECDBDE1CA6BB2B00C7F112 /* CSBaseDataTransaction+Querying.swift */; };
|
||||
@@ -729,6 +777,9 @@
|
||||
B51260921E9B28F100402229 /* EntityIdentifier.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EntityIdentifier.swift; sourceTree = "<group>"; };
|
||||
B51FE5AA1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CoreStore+CustomDebugStringConvertible.swift"; sourceTree = "<group>"; };
|
||||
B5202CF91C04688100DED140 /* NSFetchedResultsController+Convenience.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSFetchedResultsController+Convenience.swift"; sourceTree = "<group>"; };
|
||||
B5215CA31FA47DFD00139E3A /* FetchChainBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FetchChainBuilder.swift; sourceTree = "<group>"; };
|
||||
B5215CA81FA4810300139E3A /* QueryChainBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QueryChainBuilder.swift; sourceTree = "<group>"; };
|
||||
B5215CAD1FA4812500139E3A /* SectionMonitorBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SectionMonitorBuilder.swift; sourceTree = "<group>"; };
|
||||
B5220E071D0C5F8D009BC71E /* ObjectObserverTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObjectObserverTests.swift; sourceTree = "<group>"; };
|
||||
B5220E0B1D0D0D19009BC71E /* ImportTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImportTests.swift; sourceTree = "<group>"; };
|
||||
B5220E0F1D0DA6AB009BC71E /* ListObserverTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListObserverTests.swift; sourceTree = "<group>"; };
|
||||
@@ -746,12 +797,14 @@
|
||||
B52DD17D1BE1F8CC00949AFE /* CoreStoreTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CoreStoreTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
B52F742E1E9B50D0005F3DAC /* SchemaHistory.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SchemaHistory.swift; sourceTree = "<group>"; };
|
||||
B52F743A1E9B8724005F3DAC /* DynamicSchema.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DynamicSchema.swift; sourceTree = "<group>"; };
|
||||
B52F743B1E9B8724005F3DAC /* LegacyXcodeDataModelSchema.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LegacyXcodeDataModelSchema.swift; sourceTree = "<group>"; };
|
||||
B52F743B1E9B8724005F3DAC /* UnsafeDataModelSchema.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UnsafeDataModelSchema.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>"; };
|
||||
B52FD3A91E3B3EF10001D919 /* NSManagedObject+Logging.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSManagedObject+Logging.swift"; sourceTree = "<group>"; };
|
||||
B533C4DA1D7D4BFA001383CB /* DispatchQueue+CoreStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "DispatchQueue+CoreStore.swift"; sourceTree = "<group>"; };
|
||||
B538BA701D15B3E30003A766 /* CoreStoreBridge.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CoreStoreBridge.m; sourceTree = "<group>"; };
|
||||
B53B275E1EE3B92E00E9B352 /* CoreStoreManagedObject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreStoreManagedObject.swift; sourceTree = "<group>"; };
|
||||
B53CA9A11EF1EF1600E0F440 /* PartialObject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PartialObject.swift; sourceTree = "<group>"; };
|
||||
B53FB9FD1CAB2D2F00F0D40A /* CSMigrationResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSMigrationResult.swift; sourceTree = "<group>"; };
|
||||
B53FBA031CAB300C00F0D40A /* CSMigrationType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSMigrationType.swift; sourceTree = "<group>"; };
|
||||
B53FBA0A1CAB5E6500F0D40A /* CSCoreStore+Migrating.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CSCoreStore+Migrating.swift"; sourceTree = "<group>"; };
|
||||
@@ -776,6 +829,7 @@
|
||||
B5519A5E1CA21954002BEF78 /* CSAsynchronousDataTransaction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSAsynchronousDataTransaction.swift; sourceTree = "<group>"; };
|
||||
B5548CD51BD65AE00077652A /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };
|
||||
B5548CD71BD65AE50077652A /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/System/Library/Frameworks/CoreData.framework; sourceTree = DEVELOPER_DIR; };
|
||||
B55514E91EED8BF900BAB888 /* From+Querying.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "From+Querying.swift"; sourceTree = "<group>"; };
|
||||
B55717421D15AF9C009BDBCA /* CoreStoreBridge.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CoreStoreBridge.h; sourceTree = "<group>"; };
|
||||
B559CD421CAA8B6300E4D58B /* CSSetupResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSSetupResult.swift; sourceTree = "<group>"; };
|
||||
B559CD481CAA8C6D00E4D58B /* CSStorageInterface.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSStorageInterface.swift; sourceTree = "<group>"; };
|
||||
@@ -800,18 +854,22 @@
|
||||
B56923DF1EB827F5007C4DC9 /* XcodeSchemaMappingProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = XcodeSchemaMappingProvider.swift; sourceTree = "<group>"; };
|
||||
B56923F41EB828BF007C4DC9 /* CSDynamicSchema.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSDynamicSchema.swift; sourceTree = "<group>"; };
|
||||
B56923F91EB82956007C4DC9 /* CSXcodeDataModelSchema.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSXcodeDataModelSchema.swift; sourceTree = "<group>"; };
|
||||
B56923FE1EB82976007C4DC9 /* CSLegacyXcodeDataModelSchema.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSLegacyXcodeDataModelSchema.swift; sourceTree = "<group>"; };
|
||||
B56923FE1EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSUnsafeDataModelSchema.swift; sourceTree = "<group>"; };
|
||||
B56964D31B22FFAD0075EE4A /* DataStack+Migration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "DataStack+Migration.swift"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
|
||||
B56965231B356B820075EE4A /* MigrationResult.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MigrationResult.swift; sourceTree = "<group>"; };
|
||||
B57D27BD1D0BBE8200539C58 /* BaseTestDataTestCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseTestDataTestCase.swift; sourceTree = "<group>"; };
|
||||
B57D27C11D0BC20100539C58 /* QueryTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QueryTests.swift; sourceTree = "<group>"; };
|
||||
B58085741CDF7F00004C2EEB /* SetupTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SetupTests.swift; sourceTree = "<group>"; };
|
||||
B5831B6F1F34AC3400A9F647 /* AttributeProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttributeProtocol.swift; sourceTree = "<group>"; };
|
||||
B5831B741F34AC7A00A9F647 /* RelationshipProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelationshipProtocol.swift; sourceTree = "<group>"; };
|
||||
B5831B791F34ACBA00A9F647 /* Transformable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Transformable.swift; sourceTree = "<group>"; };
|
||||
B58D0C621EAA0C7E003EDD87 /* NSManagedObject+DynamicModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSManagedObject+DynamicModel.swift"; sourceTree = "<group>"; };
|
||||
B596BBAD1DD59FDB001DCDD9 /* ConvenienceTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConvenienceTests.swift; sourceTree = "<group>"; };
|
||||
B596BBB51DD5BC67001DCDD9 /* FetchableSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FetchableSource.swift; sourceTree = "<group>"; };
|
||||
B596BBBA1DD5C39F001DCDD9 /* QueryableSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QueryableSource.swift; sourceTree = "<group>"; };
|
||||
B59AFF401C6593E400C0ABE2 /* NSPersistentStoreCoordinator+Setup.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSPersistentStoreCoordinator+Setup.swift"; sourceTree = "<group>"; };
|
||||
B59FA0AD1CCBAC95007C9BCA /* ICloudStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ICloudStore.swift; sourceTree = "<group>"; };
|
||||
B5A1DAC71F111BFA003CF369 /* KeyPath+Querying.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "KeyPath+Querying.swift"; sourceTree = "<group>"; };
|
||||
B5A261201B64BFDB006EB6D3 /* MigrationType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MigrationType.swift; sourceTree = "<group>"; };
|
||||
B5A5F2651CAEC50F004AB9AF /* CSSelect.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSSelect.swift; sourceTree = "<group>"; };
|
||||
B5A991EB1E9DC2CE0091A2E3 /* VersionLock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VersionLock.swift; sourceTree = "<group>"; };
|
||||
@@ -822,7 +880,10 @@
|
||||
B5BDC9271C2024F2008147CD /* .travis.yml */ = {isa = PBXFileReference; lastKnownFileType = text; path = .travis.yml; sourceTree = SOURCE_ROOT; };
|
||||
B5C976E21C6C9F6A00B1AF90 /* UnsafeDataTransaction+Observing.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UnsafeDataTransaction+Observing.swift"; sourceTree = "<group>"; };
|
||||
B5C976E61C6E3A5900B1AF90 /* CoreStoreFetchedResultsController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreStoreFetchedResultsController.swift; sourceTree = "<group>"; };
|
||||
B5CA2B071F7E5ACA004B1936 /* WhereClauseType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WhereClauseType.swift; sourceTree = "<group>"; };
|
||||
B5CA2B111F81DBFE004B1936 /* DynamicKeyPath.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DynamicKeyPath.swift; sourceTree = "<group>"; };
|
||||
B5D1E22B19FA9FBC003B2874 /* CoreStoreError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreStoreError.swift; sourceTree = "<group>"; };
|
||||
B5D2D5A91F7558CB00A4DE67 /* .cocoapods.yml */ = {isa = PBXFileReference; lastKnownFileType = text; path = .cocoapods.yml; sourceTree = SOURCE_ROOT; };
|
||||
B5D339B31E925C2B00C880DE /* DynamicModelTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DynamicModelTests.swift; sourceTree = "<group>"; };
|
||||
B5D339D71E9489AB00C880DE /* CoreStoreObject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreStoreObject.swift; sourceTree = "<group>"; };
|
||||
B5D339DC1E9489C700C880DE /* DynamicObject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DynamicObject.swift; sourceTree = "<group>"; };
|
||||
@@ -888,7 +949,7 @@
|
||||
B5E84F321AFF85470064E85B /* NSManagedObjectContext+Setup.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSManagedObjectContext+Setup.swift"; sourceTree = "<group>"; };
|
||||
B5E84F331AFF85470064E85B /* NSManagedObjectContext+Transaction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSManagedObjectContext+Transaction.swift"; sourceTree = "<group>"; };
|
||||
B5E84F351AFF85470064E85B /* NSManagedObjectContext+Querying.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSManagedObjectContext+Querying.swift"; sourceTree = "<group>"; };
|
||||
B5E84F401AFF8CCD0064E85B /* ClauseTypes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ClauseTypes.swift; sourceTree = "<group>"; };
|
||||
B5E84F401AFF8CCD0064E85B /* TypeErasedClauses.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TypeErasedClauses.swift; sourceTree = "<group>"; };
|
||||
B5ECDBDE1CA6BB2B00C7F112 /* CSBaseDataTransaction+Querying.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CSBaseDataTransaction+Querying.swift"; sourceTree = "<group>"; };
|
||||
B5ECDBE41CA6BEA300C7F112 /* CSClauseTypes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSClauseTypes.swift; sourceTree = "<group>"; };
|
||||
B5ECDBEB1CA6BF2000C7F112 /* CSFrom.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSFrom.swift; sourceTree = "<group>"; };
|
||||
@@ -1019,6 +1080,7 @@
|
||||
B5E84ED91AFF82360064E85B /* LICENSE */,
|
||||
B5D9C8F61B160ED200E64F0E /* CoreStore.podspec */,
|
||||
B5BDC91A1C202269008147CD /* Cartfile */,
|
||||
B5D2D5A91F7558CB00A4DE67 /* .cocoapods.yml */,
|
||||
B5BDC9271C2024F2008147CD /* .travis.yml */,
|
||||
B5AD60CD1C90141E00F2B2E8 /* Package.swift */,
|
||||
);
|
||||
@@ -1102,13 +1164,24 @@
|
||||
name = Observing;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
B5215CA21FA47BF300139E3A /* Chained Clauses */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B55514E91EED8BF900BAB888 /* From+Querying.swift */,
|
||||
B5215CA31FA47DFD00139E3A /* FetchChainBuilder.swift */,
|
||||
B5215CA81FA4810300139E3A /* QueryChainBuilder.swift */,
|
||||
B5215CAD1FA4812500139E3A /* SectionMonitorBuilder.swift */,
|
||||
);
|
||||
name = "Chained Clauses";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
B52F74391E9B8724005F3DAC /* Dynamic Schema */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B52F743A1E9B8724005F3DAC /* DynamicSchema.swift */,
|
||||
B52F74491E9B8740005F3DAC /* CoreStoreSchema.swift */,
|
||||
B52F743C1E9B8724005F3DAC /* XcodeDataModelSchema.swift */,
|
||||
B52F743B1E9B8724005F3DAC /* LegacyXcodeDataModelSchema.swift */,
|
||||
B52F743B1E9B8724005F3DAC /* UnsafeDataModelSchema.swift */,
|
||||
);
|
||||
name = "Dynamic Schema";
|
||||
sourceTree = "<group>";
|
||||
@@ -1190,7 +1263,7 @@
|
||||
children = (
|
||||
B56923F41EB828BF007C4DC9 /* CSDynamicSchema.swift */,
|
||||
B56923F91EB82956007C4DC9 /* CSXcodeDataModelSchema.swift */,
|
||||
B56923FE1EB82976007C4DC9 /* CSLegacyXcodeDataModelSchema.swift */,
|
||||
B56923FE1EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift */,
|
||||
);
|
||||
name = "Dynamic Schema";
|
||||
sourceTree = "<group>";
|
||||
@@ -1224,17 +1297,37 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B5D339D71E9489AB00C880DE /* CoreStoreObject.swift */,
|
||||
B53CA9A11EF1EF1600E0F440 /* PartialObject.swift */,
|
||||
B5831B6E1F3355C300A9F647 /* Properties */,
|
||||
B52F74391E9B8724005F3DAC /* Dynamic Schema */,
|
||||
B5D339DC1E9489C700C880DE /* DynamicObject.swift */,
|
||||
B52F742E1E9B50D0005F3DAC /* SchemaHistory.swift */,
|
||||
B5D339E61E9493A500C880DE /* Entity.swift */,
|
||||
B5D33A001E96012400C880DE /* Relationship.swift */,
|
||||
B5D339E11E948C3600C880DE /* Value.swift */,
|
||||
B5A991EB1E9DC2CE0091A2E3 /* VersionLock.swift */,
|
||||
);
|
||||
name = "Dynamic Models";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
B5831B6E1F3355C300A9F647 /* Properties */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B5D33A001E96012400C880DE /* Relationship.swift */,
|
||||
B5D339E11E948C3600C880DE /* Value.swift */,
|
||||
B5831B791F34ACBA00A9F647 /* Transformable.swift */,
|
||||
);
|
||||
name = Properties;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
B5A1DAC61F111BBE003CF369 /* KeyPath Utilities */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B5A1DAC71F111BFA003CF369 /* KeyPath+Querying.swift */,
|
||||
B5D339EB1E9495E500C880DE /* CoreStoreObject+Querying.swift */,
|
||||
B5CA2B111F81DBFE004B1936 /* DynamicKeyPath.swift */,
|
||||
);
|
||||
name = "KeyPath Utilities";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
B5A5F26B1CAFF8D0004AB9AF /* Swift */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -1358,13 +1451,14 @@
|
||||
B5E84EFD1AFF847B0064E85B /* Fetching and Querying */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B5D339EB1E9495E500C880DE /* CoreStoreObject+Querying.swift */,
|
||||
B5E84EFE1AFF847B0064E85B /* BaseDataTransaction+Querying.swift */,
|
||||
B5E84F061AFF847B0064E85B /* DataStack+Querying.swift */,
|
||||
B5E84F071AFF847B0064E85B /* CoreStore+Querying.swift */,
|
||||
B596BBB51DD5BC67001DCDD9 /* FetchableSource.swift */,
|
||||
B596BBBA1DD5C39F001DCDD9 /* QueryableSource.swift */,
|
||||
B549F65D1E569C7400FBAB2D /* QueryableAttributeType.swift */,
|
||||
B5215CA21FA47BF300139E3A /* Chained Clauses */,
|
||||
B5A1DAC61F111BBE003CF369 /* KeyPath Utilities */,
|
||||
B5E84F0A1AFF847B0064E85B /* Protocol Clauses */,
|
||||
B5E84EFF1AFF847B0064E85B /* Concrete Clauses */,
|
||||
);
|
||||
@@ -1387,7 +1481,8 @@
|
||||
B5E84F0A1AFF847B0064E85B /* Protocol Clauses */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B5E84F401AFF8CCD0064E85B /* ClauseTypes.swift */,
|
||||
B5E84F401AFF8CCD0064E85B /* TypeErasedClauses.swift */,
|
||||
B5CA2B071F7E5ACA004B1936 /* WhereClauseType.swift */,
|
||||
);
|
||||
name = "Protocol Clauses";
|
||||
sourceTree = "<group>";
|
||||
@@ -1423,18 +1518,21 @@
|
||||
B5E84F291AFF849C0064E85B /* Internal */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B5831B6F1F34AC3400A9F647 /* AttributeProtocol.swift */,
|
||||
B5831B741F34AC7A00A9F647 /* RelationshipProtocol.swift */,
|
||||
B5C976E61C6E3A5900B1AF90 /* CoreStoreFetchedResultsController.swift */,
|
||||
B526613F1CADD585007B85D9 /* CoreStoreFetchRequest+CoreStore.swift */,
|
||||
B51260881E9B252B00402229 /* NSEntityDescription+DynamicModel.swift */,
|
||||
B56923C31EB823B4007C4DC9 /* NSEntityDescription+Migration.swift */,
|
||||
B53B275E1EE3B92E00E9B352 /* CoreStoreManagedObject.swift */,
|
||||
B533C4DA1D7D4BFA001383CB /* DispatchQueue+CoreStore.swift */,
|
||||
B51260921E9B28F100402229 /* EntityIdentifier.swift */,
|
||||
B54A6A541BA15F2A007870FD /* FetchedResultsControllerDelegate.swift */,
|
||||
B5E834BA1B7691F3001D3D50 /* Functions.swift */,
|
||||
B5FAD6AB1B51285300714891 /* MigrationManager.swift */,
|
||||
B5E84F2B1AFF849C0064E85B /* NotificationObserver.swift */,
|
||||
B533C4DA1D7D4BFA001383CB /* DispatchQueue+CoreStore.swift */,
|
||||
B52FD3A91E3B3EF10001D919 /* NSManagedObject+Logging.swift */,
|
||||
B51260881E9B252B00402229 /* NSEntityDescription+DynamicModel.swift */,
|
||||
B56923C31EB823B4007C4DC9 /* NSEntityDescription+Migration.swift */,
|
||||
B58D0C621EAA0C7E003EDD87 /* NSManagedObject+DynamicModel.swift */,
|
||||
B52FD3A91E3B3EF10001D919 /* NSManagedObject+Logging.swift */,
|
||||
B5E84F2C1AFF849C0064E85B /* NSManagedObjectContext+CoreStore.swift */,
|
||||
B5E84F351AFF85470064E85B /* NSManagedObjectContext+Querying.swift */,
|
||||
B5E84F321AFF85470064E85B /* NSManagedObjectContext+Setup.swift */,
|
||||
@@ -1656,32 +1754,32 @@
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 0730;
|
||||
LastUpgradeCheck = 0800;
|
||||
LastUpgradeCheck = 0930;
|
||||
ORGANIZATIONNAME = "John Rommel Estropia";
|
||||
TargetAttributes = {
|
||||
2F03A52F19C5C6DA005002A5 = {
|
||||
CreatedOnToolsVersion = 6.0;
|
||||
LastSwiftMigration = 0800;
|
||||
LastSwiftMigration = 0900;
|
||||
};
|
||||
2F03A53A19C5C6DA005002A5 = {
|
||||
CreatedOnToolsVersion = 6.0;
|
||||
LastSwiftMigration = 0800;
|
||||
LastSwiftMigration = 0900;
|
||||
};
|
||||
82BA18881C4BBCBA00A0916E = {
|
||||
CreatedOnToolsVersion = 7.2;
|
||||
LastSwiftMigration = 0800;
|
||||
LastSwiftMigration = 0900;
|
||||
};
|
||||
82BA18911C4BBCBA00A0916E = {
|
||||
CreatedOnToolsVersion = 7.2;
|
||||
LastSwiftMigration = 0800;
|
||||
LastSwiftMigration = 0900;
|
||||
};
|
||||
B52DD1731BE1F8CC00949AFE = {
|
||||
CreatedOnToolsVersion = 7.1;
|
||||
LastSwiftMigration = 0800;
|
||||
LastSwiftMigration = 0900;
|
||||
};
|
||||
B52DD17C1BE1F8CC00949AFE = {
|
||||
CreatedOnToolsVersion = 7.1;
|
||||
LastSwiftMigration = 0800;
|
||||
LastSwiftMigration = 0900;
|
||||
};
|
||||
B563216E1BD65082006C9394 = {
|
||||
CreatedOnToolsVersion = 7.0.1;
|
||||
@@ -1771,6 +1869,7 @@
|
||||
files = (
|
||||
B5E84F221AFF84860064E85B /* ObjectMonitor.swift in Sources */,
|
||||
B5ECDBF91CA804FD00C7F112 /* NSManagedObjectContext+ObjectiveC.swift in Sources */,
|
||||
B5CA2B081F7E5ACA004B1936 /* WhereClauseType.swift in Sources */,
|
||||
B5C976E71C6E3A5A00B1AF90 /* CoreStoreFetchedResultsController.swift in Sources */,
|
||||
B56923F51EB828BF007C4DC9 /* CSDynamicSchema.swift in Sources */,
|
||||
B5F1DA901B9AA991007C5CBB /* ImportableUniqueObject.swift in Sources */,
|
||||
@@ -1782,13 +1881,14 @@
|
||||
B5D339D81E9489AB00C880DE /* CoreStoreObject.swift in Sources */,
|
||||
B5D3F6451C887C0A00C7492A /* LegacySQLiteStore.swift in Sources */,
|
||||
B56923FA1EB82956007C4DC9 /* CSXcodeDataModelSchema.swift in Sources */,
|
||||
B55514EA1EED8BF900BAB888 /* From+Querying.swift in Sources */,
|
||||
B596BBBB1DD5C39F001DCDD9 /* QueryableSource.swift in Sources */,
|
||||
B5ECDBFF1CA80CBA00C7F112 /* CSWhere.swift in Sources */,
|
||||
B5ECDC051CA8138100C7F112 /* CSOrderBy.swift in Sources */,
|
||||
B5E1B5981CAA0C23007FD580 /* CSObjectObserver.swift in Sources */,
|
||||
B5519A5F1CA21954002BEF78 /* CSAsynchronousDataTransaction.swift in Sources */,
|
||||
B52FD3AA1E3B3EF10001D919 /* NSManagedObject+Logging.swift in Sources */,
|
||||
B52F74411E9B8724005F3DAC /* LegacyXcodeDataModelSchema.swift in Sources */,
|
||||
B52F74411E9B8724005F3DAC /* UnsafeDataModelSchema.swift in Sources */,
|
||||
B51FE5AB1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift in Sources */,
|
||||
B5A9921F1EA898710091A2E3 /* UserInfo.swift in Sources */,
|
||||
B54A6A551BA15F2A007870FD /* FetchedResultsControllerDelegate.swift in Sources */,
|
||||
@@ -1802,6 +1902,7 @@
|
||||
B5ECDC1D1CA81A2100C7F112 /* CSDataStack+Querying.swift in Sources */,
|
||||
B5C976E31C6C9F6A00B1AF90 /* UnsafeDataTransaction+Observing.swift in Sources */,
|
||||
B53FBA121CAB63CB00F0D40A /* Progress+ObjectiveC.swift in Sources */,
|
||||
B5831B751F34AC7A00A9F647 /* RelationshipProtocol.swift in Sources */,
|
||||
B5E1B5A81CAA49E2007FD580 /* CSDataStack+Migrating.swift in Sources */,
|
||||
B5D339F11E94AF5800C880DE /* CoreStoreStrings.swift in Sources */,
|
||||
B56007161B4018AB00A9A8F9 /* MigrationChain.swift in Sources */,
|
||||
@@ -1820,6 +1921,7 @@
|
||||
B5FAD6AE1B518DCB00714891 /* CoreStore+Migration.swift in Sources */,
|
||||
B5E84EE71AFF84610064E85B /* CoreStore+Logging.swift in Sources */,
|
||||
B546F9731C9C553300D5AC55 /* SetupResult.swift in Sources */,
|
||||
B53CA9A21EF1EF1600E0F440 /* PartialObject.swift in Sources */,
|
||||
B56007111B3F6BD500A9A8F9 /* Into.swift in Sources */,
|
||||
B5E84F111AFF847B0064E85B /* Select.swift in Sources */,
|
||||
B51260931E9B28F100402229 /* EntityIdentifier.swift in Sources */,
|
||||
@@ -1840,10 +1942,11 @@
|
||||
B501FDE71CA8D20500BE22EF /* CSListObserver.swift in Sources */,
|
||||
B5E41EC01EA9BB37006240F0 /* DynamicSchema+Convenience.swift in Sources */,
|
||||
B501FDE21CA8D1F500BE22EF /* CSListMonitor.swift in Sources */,
|
||||
B5A1DAC81F111BFA003CF369 /* KeyPath+Querying.swift in Sources */,
|
||||
2F291E2719C6D3CF007AF63F /* CoreStore.swift in Sources */,
|
||||
B5ECDC111CA816E500C7F112 /* CSTweak.swift in Sources */,
|
||||
B56923C41EB823B4007C4DC9 /* NSEntityDescription+Migration.swift in Sources */,
|
||||
B5E84F411AFF8CCD0064E85B /* ClauseTypes.swift in Sources */,
|
||||
B5E84F411AFF8CCD0064E85B /* TypeErasedClauses.swift in Sources */,
|
||||
B5E84F0D1AFF847B0064E85B /* BaseDataTransaction+Querying.swift in Sources */,
|
||||
B52F74451E9B8724005F3DAC /* XcodeDataModelSchema.swift in Sources */,
|
||||
B5FAD6AC1B51285300714891 /* MigrationManager.swift in Sources */,
|
||||
@@ -1868,6 +1971,7 @@
|
||||
B5E84F0F1AFF847B0064E85B /* From.swift in Sources */,
|
||||
B5FAD6A91B50A4B400714891 /* Progress+Convenience.swift in Sources */,
|
||||
B5E84EFC1AFF846E0064E85B /* SynchronousDataTransaction.swift in Sources */,
|
||||
B5215CA91FA4810300139E3A /* QueryChainBuilder.swift in Sources */,
|
||||
B5E222231CA4E12600BA2E95 /* CSSynchronousDataTransaction.swift in Sources */,
|
||||
B5E84F281AFF84920064E85B /* NSManagedObject+Convenience.swift in Sources */,
|
||||
B52F744A1E9B8740005F3DAC /* CoreStoreSchema.swift in Sources */,
|
||||
@@ -1875,6 +1979,8 @@
|
||||
B5E2222A1CA51B6E00BA2E95 /* CSUnsafeDataTransaction.swift in Sources */,
|
||||
B5E84F391AFF85470064E85B /* NSManagedObjectContext+Querying.swift in Sources */,
|
||||
B56923E81EB827F5007C4DC9 /* InferredSchemaMappingProvider.swift in Sources */,
|
||||
B53B275F1EE3B92E00E9B352 /* CoreStoreManagedObject.swift in Sources */,
|
||||
B5215CA41FA47DFD00139E3A /* FetchChainBuilder.swift in Sources */,
|
||||
B5D33A011E96012400C880DE /* Relationship.swift in Sources */,
|
||||
B5E84EE81AFF84610064E85B /* CoreStoreLogger.swift in Sources */,
|
||||
B56923C91EB82410007C4DC9 /* NSManagedObjectModel+Migration.swift in Sources */,
|
||||
@@ -1892,21 +1998,25 @@
|
||||
B59FA0AE1CCBAC95007C9BCA /* ICloudStore.swift in Sources */,
|
||||
B5E84EF81AFF846E0064E85B /* CoreStore+Transaction.swift in Sources */,
|
||||
B5E84F301AFF849C0064E85B /* NSManagedObjectContext+CoreStore.swift in Sources */,
|
||||
B5831B7A1F34ACBA00A9F647 /* Transformable.swift in Sources */,
|
||||
B546F9691C9AF26D00D5AC55 /* CSInMemoryStore.swift in Sources */,
|
||||
B53FBA1E1CAB63FA00F0D40A /* NSFetchedResultsController+ObjectiveC.swift in Sources */,
|
||||
B549F65E1E569C7400FBAB2D /* QueryableAttributeType.swift in Sources */,
|
||||
B5E84F211AFF84860064E85B /* CoreStore+Observing.swift in Sources */,
|
||||
B559CD431CAA8B6300E4D58B /* CSSetupResult.swift in Sources */,
|
||||
B5CA2B121F81DBFE004B1936 /* DynamicKeyPath.swift in Sources */,
|
||||
B5A991EC1E9DC2CE0091A2E3 /* VersionLock.swift in Sources */,
|
||||
B5FE4DA71C84FB4400FA6A91 /* InMemoryStore.swift in Sources */,
|
||||
B52F743D1E9B8724005F3DAC /* DynamicSchema.swift in Sources */,
|
||||
B56923FF1EB82976007C4DC9 /* CSLegacyXcodeDataModelSchema.swift in Sources */,
|
||||
B56923FF1EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift in Sources */,
|
||||
B5215CAE1FA4812500139E3A /* SectionMonitorBuilder.swift in Sources */,
|
||||
B5ECDBEC1CA6BF2000C7F112 /* CSFrom.swift in Sources */,
|
||||
B56923EC1EB827F6007C4DC9 /* SchemaMappingProvider.swift in Sources */,
|
||||
B5E834B91B76311F001D3D50 /* BaseDataTransaction+Importing.swift in Sources */,
|
||||
B5E84EE61AFF84610064E85B /* DefaultLogger.swift in Sources */,
|
||||
B53FBA041CAB300C00F0D40A /* CSMigrationType.swift in Sources */,
|
||||
B5E84EF41AFF846E0064E85B /* AsynchronousDataTransaction.swift in Sources */,
|
||||
B5831B701F34AC3400A9F647 /* AttributeProtocol.swift in Sources */,
|
||||
B5DBE2CD1C9914A900B5CEFA /* CSCoreStore.swift in Sources */,
|
||||
B546F95D1C9A12B800D5AC55 /* CSSQliteStore.swift in Sources */,
|
||||
B5D339E71E9493A500C880DE /* Entity.swift in Sources */,
|
||||
@@ -1955,6 +2065,7 @@
|
||||
files = (
|
||||
82BA18B61C4BBD3F00A0916E /* DataStack+Querying.swift in Sources */,
|
||||
B5ECDBFB1CA804FD00C7F112 /* NSManagedObjectContext+ObjectiveC.swift in Sources */,
|
||||
B5CA2B091F7E5ACA004B1936 /* WhereClauseType.swift in Sources */,
|
||||
B5C976E81C6E3A5D00B1AF90 /* CoreStoreFetchedResultsController.swift in Sources */,
|
||||
B56923F61EB828BF007C4DC9 /* CSDynamicSchema.swift in Sources */,
|
||||
82BA18A21C4BBD1D00A0916E /* CoreStoreError.swift in Sources */,
|
||||
@@ -1966,13 +2077,14 @@
|
||||
B5D339D91E9489AB00C880DE /* CoreStoreObject.swift in Sources */,
|
||||
82BA18CE1C4BBD7100A0916E /* FetchedResultsControllerDelegate.swift in Sources */,
|
||||
B56923FB1EB82956007C4DC9 /* CSXcodeDataModelSchema.swift in Sources */,
|
||||
B55514EB1EED8BF900BAB888 /* From+Querying.swift in Sources */,
|
||||
B596BBBC1DD5C39F001DCDD9 /* QueryableSource.swift in Sources */,
|
||||
B5ECDC011CA80CBA00C7F112 /* CSWhere.swift in Sources */,
|
||||
B5ECDC071CA8138100C7F112 /* CSOrderBy.swift in Sources */,
|
||||
B5E1B59A1CAA0C23007FD580 /* CSObjectObserver.swift in Sources */,
|
||||
B5519A601CA21954002BEF78 /* CSAsynchronousDataTransaction.swift in Sources */,
|
||||
B52FD3AB1E3B3EF10001D919 /* NSManagedObject+Logging.swift in Sources */,
|
||||
B52F74421E9B8724005F3DAC /* LegacyXcodeDataModelSchema.swift in Sources */,
|
||||
B52F74421E9B8724005F3DAC /* UnsafeDataModelSchema.swift in Sources */,
|
||||
B51FE5AD1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift in Sources */,
|
||||
B5A992201EA898720091A2E3 /* UserInfo.swift in Sources */,
|
||||
B5FE4DAD1C85D44E00FA6A91 /* SQLiteStore.swift in Sources */,
|
||||
@@ -1986,6 +2098,7 @@
|
||||
B5ECDC1F1CA81A2100C7F112 /* CSDataStack+Querying.swift in Sources */,
|
||||
B5C976E41C6C9F9A00B1AF90 /* UnsafeDataTransaction+Observing.swift in Sources */,
|
||||
B53FBA141CAB63CB00F0D40A /* Progress+ObjectiveC.swift in Sources */,
|
||||
B5831B761F34AC7A00A9F647 /* RelationshipProtocol.swift in Sources */,
|
||||
B5E1B5AA1CAA49E2007FD580 /* CSDataStack+Migrating.swift in Sources */,
|
||||
B5D339F21E94AF5800C880DE /* CoreStoreStrings.swift in Sources */,
|
||||
B5D3F6461C887C0A00C7492A /* LegacySQLiteStore.swift in Sources */,
|
||||
@@ -2004,6 +2117,7 @@
|
||||
82BA18A31C4BBD2200A0916E /* DataStack.swift in Sources */,
|
||||
82BA18C81C4BBD5900A0916E /* MigrationChain.swift in Sources */,
|
||||
B546F9741C9C553300D5AC55 /* SetupResult.swift in Sources */,
|
||||
B53CA9A31EF1EF1600E0F440 /* PartialObject.swift in Sources */,
|
||||
82BA18B11C4BBD3100A0916E /* SaveResult.swift in Sources */,
|
||||
82BA18DD1C4BBE1400A0916E /* NSFetchedResultsController+Convenience.swift in Sources */,
|
||||
B51260941E9B28F100402229 /* EntityIdentifier.swift in Sources */,
|
||||
@@ -2024,6 +2138,7 @@
|
||||
B501FDE91CA8D20500BE22EF /* CSListObserver.swift in Sources */,
|
||||
B5E41EC11EA9BB37006240F0 /* DynamicSchema+Convenience.swift in Sources */,
|
||||
B501FDE41CA8D1F500BE22EF /* CSListMonitor.swift in Sources */,
|
||||
B5A1DAC91F111BFA003CF369 /* KeyPath+Querying.swift in Sources */,
|
||||
B5FE4DA31C8481E100FA6A91 /* StorageInterface.swift in Sources */,
|
||||
B5ECDC131CA816E500C7F112 /* CSTweak.swift in Sources */,
|
||||
B56923C51EB823B4007C4DC9 /* NSEntityDescription+Migration.swift in Sources */,
|
||||
@@ -2052,6 +2167,7 @@
|
||||
82BA18C71C4BBD5900A0916E /* CoreStore+Migration.swift in Sources */,
|
||||
B5E222251CA4E12600BA2E95 /* CSSynchronousDataTransaction.swift in Sources */,
|
||||
82BA18C41C4BBD5300A0916E /* ListMonitor.swift in Sources */,
|
||||
B5215CAA1FA4810300139E3A /* QueryChainBuilder.swift in Sources */,
|
||||
82BA18BA1C4BBD4A00A0916E /* Select.swift in Sources */,
|
||||
B52F744B1E9B8740005F3DAC /* CoreStoreSchema.swift in Sources */,
|
||||
B5AEFAB61C9962AE00AD137F /* CoreStoreBridge.swift in Sources */,
|
||||
@@ -2059,6 +2175,8 @@
|
||||
82BA18A71C4BBD2900A0916E /* CoreStore+Logging.swift in Sources */,
|
||||
82BA18D81C4BBD7100A0916E /* WeakObject.swift in Sources */,
|
||||
B56923E91EB827F5007C4DC9 /* InferredSchemaMappingProvider.swift in Sources */,
|
||||
B53B27601EE3B92E00E9B352 /* CoreStoreManagedObject.swift in Sources */,
|
||||
B5215CA51FA47DFD00139E3A /* FetchChainBuilder.swift in Sources */,
|
||||
B5D33A021E96012400C880DE /* Relationship.swift in Sources */,
|
||||
B559CD4B1CAA8C6D00E4D58B /* CSStorageInterface.swift in Sources */,
|
||||
B56923CA1EB82410007C4DC9 /* NSManagedObjectModel+Migration.swift in Sources */,
|
||||
@@ -2076,21 +2194,25 @@
|
||||
82BA18D31C4BBD7100A0916E /* NSManagedObjectContext+CoreStore.swift in Sources */,
|
||||
82BA18AD1C4BBD3100A0916E /* UnsafeDataTransaction.swift in Sources */,
|
||||
B546F96A1C9AF26D00D5AC55 /* CSInMemoryStore.swift in Sources */,
|
||||
B5831B7B1F34ACBA00A9F647 /* Transformable.swift in Sources */,
|
||||
B53FBA201CAB63FA00F0D40A /* NSFetchedResultsController+ObjectiveC.swift in Sources */,
|
||||
82BA18A81C4BBD2900A0916E /* CoreStoreLogger.swift in Sources */,
|
||||
B549F65F1E569C7400FBAB2D /* QueryableAttributeType.swift in Sources */,
|
||||
B559CD451CAA8B6300E4D58B /* CSSetupResult.swift in Sources */,
|
||||
82BA18B81C4BBD4200A0916E /* ClauseTypes.swift in Sources */,
|
||||
82BA18B81C4BBD4200A0916E /* TypeErasedClauses.swift in Sources */,
|
||||
B5CA2B131F81DBFE004B1936 /* DynamicKeyPath.swift in Sources */,
|
||||
B5A991ED1E9DC2CE0091A2E3 /* VersionLock.swift in Sources */,
|
||||
B5ECDBEE1CA6BF2000C7F112 /* CSFrom.swift in Sources */,
|
||||
B52F743E1E9B8724005F3DAC /* DynamicSchema.swift in Sources */,
|
||||
B56924001EB82976007C4DC9 /* CSLegacyXcodeDataModelSchema.swift in Sources */,
|
||||
B56924001EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift in Sources */,
|
||||
B5215CAF1FA4812500139E3A /* SectionMonitorBuilder.swift in Sources */,
|
||||
82BA18D61C4BBD7100A0916E /* NSManagedObjectContext+Transaction.swift in Sources */,
|
||||
B56923ED1EB827F6007C4DC9 /* SchemaMappingProvider.swift in Sources */,
|
||||
82BA18B91C4BBD4A00A0916E /* From.swift in Sources */,
|
||||
B53FBA061CAB300C00F0D40A /* CSMigrationType.swift in Sources */,
|
||||
82BA18BE1C4BBD4A00A0916E /* Tweak.swift in Sources */,
|
||||
B5DBE2CE1C9914A900B5CEFA /* CSCoreStore.swift in Sources */,
|
||||
B5831B711F34AC3400A9F647 /* AttributeProtocol.swift in Sources */,
|
||||
B546F95E1C9A12B800D5AC55 /* CSSQliteStore.swift in Sources */,
|
||||
B5ECDC0D1CA8161B00C7F112 /* CSGroupBy.swift in Sources */,
|
||||
B5D339E81E9493A500C880DE /* Entity.swift in Sources */,
|
||||
@@ -2139,6 +2261,7 @@
|
||||
files = (
|
||||
B5220E1E1D13080D009BC71E /* CSListMonitor.swift in Sources */,
|
||||
B5DBE2D01C9914A900B5CEFA /* CSCoreStore.swift in Sources */,
|
||||
B5CA2B0B1F7E5ACA004B1936 /* WhereClauseType.swift in Sources */,
|
||||
B5677D411CD3B1E400322BFC /* ICloudStoreObserver.swift in Sources */,
|
||||
B56923F81EB828BF007C4DC9 /* CSDynamicSchema.swift in Sources */,
|
||||
B52DD1BE1BE1F94300949AFE /* Progress+Convenience.swift in Sources */,
|
||||
@@ -2150,13 +2273,14 @@
|
||||
B5D339DB1E9489AB00C880DE /* CoreStoreObject.swift in Sources */,
|
||||
B52DD1951BE1F92500949AFE /* CoreStoreError.swift in Sources */,
|
||||
B56923FD1EB82956007C4DC9 /* CSXcodeDataModelSchema.swift in Sources */,
|
||||
B55514ED1EED8BF900BAB888 /* From+Querying.swift in Sources */,
|
||||
B596BBBE1DD5C39F001DCDD9 /* QueryableSource.swift in Sources */,
|
||||
B546F9601C9A12B800D5AC55 /* CSSQliteStore.swift in Sources */,
|
||||
B5ECDC0F1CA8161B00C7F112 /* CSGroupBy.swift in Sources */,
|
||||
B5ECDC211CA81A2100C7F112 /* CSDataStack+Querying.swift in Sources */,
|
||||
B52DD1C21BE1F94600949AFE /* MigrationManager.swift in Sources */,
|
||||
B52FD3AD1E3B3EF10001D919 /* NSManagedObject+Logging.swift in Sources */,
|
||||
B52F74441E9B8724005F3DAC /* LegacyXcodeDataModelSchema.swift in Sources */,
|
||||
B52F74441E9B8724005F3DAC /* UnsafeDataModelSchema.swift in Sources */,
|
||||
B5ECDC2D1CA81CC700C7F112 /* CSDataStack+Transaction.swift in Sources */,
|
||||
B5A992221EA898720091A2E3 /* UserInfo.swift in Sources */,
|
||||
B5D7A5BA1CA3BF8F005C752B /* CSInto.swift in Sources */,
|
||||
@@ -2170,6 +2294,7 @@
|
||||
B5D3F6481C887C0A00C7492A /* LegacySQLiteStore.swift in Sources */,
|
||||
B5220E1C1D130801009BC71E /* FetchedResultsControllerDelegate.swift in Sources */,
|
||||
B52DD19E1BE1F92C00949AFE /* AsynchronousDataTransaction.swift in Sources */,
|
||||
B5831B781F34AC7A00A9F647 /* RelationshipProtocol.swift in Sources */,
|
||||
B52DD1981BE1F92500949AFE /* CoreStore+Setup.swift in Sources */,
|
||||
B5D339F41E94AF5800C880DE /* CoreStoreStrings.swift in Sources */,
|
||||
B5220E241D13085E009BC71E /* NSFetchedResultsController+Convenience.swift in Sources */,
|
||||
@@ -2188,6 +2313,7 @@
|
||||
B52DD1961BE1F92500949AFE /* DataStack.swift in Sources */,
|
||||
B5ECDBFD1CA804FD00C7F112 /* NSManagedObjectContext+ObjectiveC.swift in Sources */,
|
||||
B52DD1BD1BE1F94300949AFE /* NSManagedObject+Convenience.swift in Sources */,
|
||||
B53CA9A51EF1EF1600E0F440 /* PartialObject.swift in Sources */,
|
||||
B52DD1AD1BE1F93900949AFE /* Where.swift in Sources */,
|
||||
B53FBA1C1CAB63E200F0D40A /* NSManagedObject+ObjectiveC.swift in Sources */,
|
||||
B51260961E9B28F100402229 /* EntityIdentifier.swift in Sources */,
|
||||
@@ -2208,6 +2334,7 @@
|
||||
B559CD4D1CAA8C6D00E4D58B /* CSStorageInterface.swift in Sources */,
|
||||
B5E41EC31EA9BB37006240F0 /* DynamicSchema+Convenience.swift in Sources */,
|
||||
B5ECDBE91CA6BEA300C7F112 /* CSClauseTypes.swift in Sources */,
|
||||
B5A1DACB1F111BFA003CF369 /* KeyPath+Querying.swift in Sources */,
|
||||
B52DD1B81BE1F94000949AFE /* DataStack+Migration.swift in Sources */,
|
||||
B5ECDC091CA8138100C7F112 /* CSOrderBy.swift in Sources */,
|
||||
B56923C71EB823B4007C4DC9 /* NSEntityDescription+Migration.swift in Sources */,
|
||||
@@ -2236,6 +2363,7 @@
|
||||
B52DD1CB1BE1F94600949AFE /* WeakObject.swift in Sources */,
|
||||
B52DD1C11BE1F94600949AFE /* Functions.swift in Sources */,
|
||||
B5220E1A1D130791009BC71E /* CoreStoreFetchedResultsController.swift in Sources */,
|
||||
B5215CAC1FA4810300139E3A /* QueryChainBuilder.swift in Sources */,
|
||||
B53FBA0F1CAB5E6500F0D40A /* CSCoreStore+Migrating.swift in Sources */,
|
||||
B52F744D1E9B8740005F3DAC /* CoreStoreSchema.swift in Sources */,
|
||||
B59FA0B21CCBACA8007C9BCA /* ICloudStore.swift in Sources */,
|
||||
@@ -2243,6 +2371,8 @@
|
||||
B52DD1A71BE1F93200949AFE /* BaseDataTransaction+Querying.swift in Sources */,
|
||||
B546F96C1C9AF26D00D5AC55 /* CSInMemoryStore.swift in Sources */,
|
||||
B56923EB1EB827F5007C4DC9 /* InferredSchemaMappingProvider.swift in Sources */,
|
||||
B53B27621EE3B92E00E9B352 /* CoreStoreManagedObject.swift in Sources */,
|
||||
B5215CA71FA47DFD00139E3A /* FetchChainBuilder.swift in Sources */,
|
||||
B5D33A041E96012400C880DE /* Relationship.swift in Sources */,
|
||||
B52DD1C61BE1F94600949AFE /* NSManagedObjectContext+CoreStore.swift in Sources */,
|
||||
B56923CC1EB82410007C4DC9 /* NSManagedObjectModel+Migration.swift in Sources */,
|
||||
@@ -2260,25 +2390,29 @@
|
||||
B52DD1A01BE1F92C00949AFE /* UnsafeDataTransaction.swift in Sources */,
|
||||
B5ECDC331CA81CDC00C7F112 /* CSCoreStore+Transaction.swift in Sources */,
|
||||
B52DD1BB1BE1F94000949AFE /* MigrationType.swift in Sources */,
|
||||
B5831B7D1F34ACBA00A9F647 /* Transformable.swift in Sources */,
|
||||
B52DD1C91BE1F94600949AFE /* NSManagedObjectContext+Transaction.swift in Sources */,
|
||||
B5220E151D130663009BC71E /* CoreStore+Observing.swift in Sources */,
|
||||
B549F6611E569C7400FBAB2D /* QueryableAttributeType.swift in Sources */,
|
||||
B52DD19B1BE1F92800949AFE /* CoreStoreLogger.swift in Sources */,
|
||||
B52DD1991BE1F92800949AFE /* DefaultLogger.swift in Sources */,
|
||||
B5CA2B151F81DBFF004B1936 /* DynamicKeyPath.swift in Sources */,
|
||||
B5A991EF1E9DC2CE0091A2E3 /* VersionLock.swift in Sources */,
|
||||
B5220E201D130813009BC71E /* CSObjectMonitor.swift in Sources */,
|
||||
B52F74401E9B8724005F3DAC /* DynamicSchema.swift in Sources */,
|
||||
B56924021EB82976007C4DC9 /* CSLegacyXcodeDataModelSchema.swift in Sources */,
|
||||
B56924021EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift in Sources */,
|
||||
B5215CB11FA4812500139E3A /* SectionMonitorBuilder.swift in Sources */,
|
||||
B5220E171D1306DF009BC71E /* UnsafeDataTransaction+Observing.swift in Sources */,
|
||||
B56923EF1EB827F6007C4DC9 /* SchemaMappingProvider.swift in Sources */,
|
||||
B53FBA081CAB300C00F0D40A /* CSMigrationType.swift in Sources */,
|
||||
B52DD1B91BE1F94000949AFE /* CoreStore+Migration.swift in Sources */,
|
||||
B5519A5C1CA2008C002BEF78 /* CSBaseDataTransaction.swift in Sources */,
|
||||
B5DBE2D51C991B3E00B5CEFA /* CSDataStack.swift in Sources */,
|
||||
B5831B731F34AC3400A9F647 /* AttributeProtocol.swift in Sources */,
|
||||
B5AEFAB81C9962AE00AD137F /* CoreStoreBridge.swift in Sources */,
|
||||
B598514B1C90289F00C99590 /* NSPersistentStoreCoordinator+Setup.swift in Sources */,
|
||||
B5D339EA1E9493A500C880DE /* Entity.swift in Sources */,
|
||||
B52DD1AA1BE1F93500949AFE /* ClauseTypes.swift in Sources */,
|
||||
B52DD1AA1BE1F93500949AFE /* TypeErasedClauses.swift in Sources */,
|
||||
B53FBA021CAB2D2F00F0D40A /* CSMigrationResult.swift in Sources */,
|
||||
B51FE5AF1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift in Sources */,
|
||||
);
|
||||
@@ -2323,6 +2457,7 @@
|
||||
files = (
|
||||
B56321A91BD65219006C9394 /* Progress+Convenience.swift in Sources */,
|
||||
B5ECDBFC1CA804FD00C7F112 /* NSManagedObjectContext+ObjectiveC.swift in Sources */,
|
||||
B5CA2B0A1F7E5ACA004B1936 /* WhereClauseType.swift in Sources */,
|
||||
B5C976E91C6E3A5E00B1AF90 /* CoreStoreFetchedResultsController.swift in Sources */,
|
||||
B56923F71EB828BF007C4DC9 /* CSDynamicSchema.swift in Sources */,
|
||||
B56321801BD65216006C9394 /* CoreStoreError.swift in Sources */,
|
||||
@@ -2334,13 +2469,14 @@
|
||||
B5D339DA1E9489AB00C880DE /* CoreStoreObject.swift in Sources */,
|
||||
B5ECDC021CA80CBA00C7F112 /* CSWhere.swift in Sources */,
|
||||
B56923FC1EB82956007C4DC9 /* CSXcodeDataModelSchema.swift in Sources */,
|
||||
B55514EC1EED8BF900BAB888 /* From+Querying.swift in Sources */,
|
||||
B596BBBD1DD5C39F001DCDD9 /* QueryableSource.swift in Sources */,
|
||||
B5ECDC081CA8138100C7F112 /* CSOrderBy.swift in Sources */,
|
||||
B5E1B59B1CAA0C23007FD580 /* CSObjectObserver.swift in Sources */,
|
||||
B5519A611CA21954002BEF78 /* CSAsynchronousDataTransaction.swift in Sources */,
|
||||
B5FE4DAE1C85D44E00FA6A91 /* SQLiteStore.swift in Sources */,
|
||||
B52FD3AC1E3B3EF10001D919 /* NSManagedObject+Logging.swift in Sources */,
|
||||
B52F74431E9B8724005F3DAC /* LegacyXcodeDataModelSchema.swift in Sources */,
|
||||
B52F74431E9B8724005F3DAC /* UnsafeDataModelSchema.swift in Sources */,
|
||||
B51FE5AE1CD4D00300E54258 /* CoreStore+CustomDebugStringConvertible.swift in Sources */,
|
||||
B5A992211EA898720091A2E3 /* UserInfo.swift in Sources */,
|
||||
B563218C1BD65216006C9394 /* DataStack+Transaction.swift in Sources */,
|
||||
@@ -2354,6 +2490,7 @@
|
||||
B5C976E51C6C9F9B00B1AF90 /* UnsafeDataTransaction+Observing.swift in Sources */,
|
||||
B53FBA151CAB63CB00F0D40A /* Progress+ObjectiveC.swift in Sources */,
|
||||
B5E1B5AB1CAA49E2007FD580 /* CSDataStack+Migrating.swift in Sources */,
|
||||
B5831B771F34AC7A00A9F647 /* RelationshipProtocol.swift in Sources */,
|
||||
B5D3F6471C887C0A00C7492A /* LegacySQLiteStore.swift in Sources */,
|
||||
B5D339F31E94AF5800C880DE /* CoreStoreStrings.swift in Sources */,
|
||||
B5E1B5A01CAA2568007FD580 /* CSDataStack+Observing.swift in Sources */,
|
||||
@@ -2372,6 +2509,7 @@
|
||||
B56321A81BD65219006C9394 /* NSManagedObject+Convenience.swift in Sources */,
|
||||
B546F9751C9C553300D5AC55 /* SetupResult.swift in Sources */,
|
||||
B56321981BD65216006C9394 /* Where.swift in Sources */,
|
||||
B53CA9A41EF1EF1600E0F440 /* PartialObject.swift in Sources */,
|
||||
B5202CFD1C046E8400DED140 /* NSFetchedResultsController+Convenience.swift in Sources */,
|
||||
B5FE4DA91C84FB4400FA6A91 /* InMemoryStore.swift in Sources */,
|
||||
B51260951E9B28F100402229 /* EntityIdentifier.swift in Sources */,
|
||||
@@ -2392,6 +2530,7 @@
|
||||
B501FDE51CA8D1F500BE22EF /* CSListMonitor.swift in Sources */,
|
||||
B5E41EC21EA9BB37006240F0 /* DynamicSchema+Convenience.swift in Sources */,
|
||||
B5ECDC141CA816E500C7F112 /* CSTweak.swift in Sources */,
|
||||
B5A1DACA1F111BFA003CF369 /* KeyPath+Querying.swift in Sources */,
|
||||
B56321AE1BD6521C006C9394 /* NotificationObserver.swift in Sources */,
|
||||
B56321931BD65216006C9394 /* DataStack+Querying.swift in Sources */,
|
||||
B56923C61EB823B4007C4DC9 /* NSEntityDescription+Migration.swift in Sources */,
|
||||
@@ -2420,6 +2559,7 @@
|
||||
B563218E1BD65216006C9394 /* SaveResult.swift in Sources */,
|
||||
B5E222261CA4E12600BA2E95 /* CSSynchronousDataTransaction.swift in Sources */,
|
||||
B56321A21BD65216006C9394 /* ListObserver.swift in Sources */,
|
||||
B5215CAB1FA4810300139E3A /* QueryChainBuilder.swift in Sources */,
|
||||
B563218A1BD65216006C9394 /* SynchronousDataTransaction.swift in Sources */,
|
||||
B52F744C1E9B8740005F3DAC /* CoreStoreSchema.swift in Sources */,
|
||||
B5AEFAB71C9962AE00AD137F /* CoreStoreBridge.swift in Sources */,
|
||||
@@ -2427,6 +2567,8 @@
|
||||
B563219F1BD65216006C9394 /* ObjectMonitor.swift in Sources */,
|
||||
B56321B61BD6521C006C9394 /* WeakObject.swift in Sources */,
|
||||
B56923EA1EB827F5007C4DC9 /* InferredSchemaMappingProvider.swift in Sources */,
|
||||
B53B27611EE3B92E00E9B352 /* CoreStoreManagedObject.swift in Sources */,
|
||||
B5215CA61FA47DFD00139E3A /* FetchChainBuilder.swift in Sources */,
|
||||
B5D33A031E96012400C880DE /* Relationship.swift in Sources */,
|
||||
B559CD4C1CAA8C6D00E4D58B /* CSStorageInterface.swift in Sources */,
|
||||
B56923CB1EB82410007C4DC9 /* NSManagedObjectModel+Migration.swift in Sources */,
|
||||
@@ -2444,27 +2586,31 @@
|
||||
B56321B11BD6521C006C9394 /* NSManagedObjectContext+CoreStore.swift in Sources */,
|
||||
B563218D1BD65216006C9394 /* CoreStore+Transaction.swift in Sources */,
|
||||
B546F96B1C9AF26D00D5AC55 /* CSInMemoryStore.swift in Sources */,
|
||||
B5831B7C1F34ACBA00A9F647 /* Transformable.swift in Sources */,
|
||||
B53FBA211CAB63FA00F0D40A /* NSFetchedResultsController+ObjectiveC.swift in Sources */,
|
||||
B563218B1BD65216006C9394 /* UnsafeDataTransaction.swift in Sources */,
|
||||
B549F6601E569C7400FBAB2D /* QueryableAttributeType.swift in Sources */,
|
||||
B559CD461CAA8B6300E4D58B /* CSSetupResult.swift in Sources */,
|
||||
B56321A61BD65216006C9394 /* MigrationType.swift in Sources */,
|
||||
B5CA2B141F81DBFE004B1936 /* DynamicKeyPath.swift in Sources */,
|
||||
B5A991EE1E9DC2CE0091A2E3 /* VersionLock.swift in Sources */,
|
||||
B5ECDBEF1CA6BF2000C7F112 /* CSFrom.swift in Sources */,
|
||||
B52F743F1E9B8724005F3DAC /* DynamicSchema.swift in Sources */,
|
||||
B56924011EB82976007C4DC9 /* CSLegacyXcodeDataModelSchema.swift in Sources */,
|
||||
B56924011EB82976007C4DC9 /* CSUnsafeDataModelSchema.swift in Sources */,
|
||||
B5215CB01FA4812500139E3A /* SectionMonitorBuilder.swift in Sources */,
|
||||
B56321B41BD6521C006C9394 /* NSManagedObjectContext+Transaction.swift in Sources */,
|
||||
B56923EE1EB827F6007C4DC9 /* SchemaMappingProvider.swift in Sources */,
|
||||
B56321861BD65216006C9394 /* CoreStoreLogger.swift in Sources */,
|
||||
B53FBA071CAB300C00F0D40A /* CSMigrationType.swift in Sources */,
|
||||
B56321841BD65216006C9394 /* DefaultLogger.swift in Sources */,
|
||||
B5DBE2CF1C9914A900B5CEFA /* CSCoreStore.swift in Sources */,
|
||||
B5831B721F34AC3400A9F647 /* AttributeProtocol.swift in Sources */,
|
||||
B546F95F1C9A12B800D5AC55 /* CSSQliteStore.swift in Sources */,
|
||||
B5ECDC0E1CA8161B00C7F112 /* CSGroupBy.swift in Sources */,
|
||||
B5D339E91E9493A500C880DE /* Entity.swift in Sources */,
|
||||
B56321A41BD65216006C9394 /* CoreStore+Migration.swift in Sources */,
|
||||
B56321A01BD65216006C9394 /* ObjectObserver.swift in Sources */,
|
||||
B56321951BD65216006C9394 /* ClauseTypes.swift in Sources */,
|
||||
B56321951BD65216006C9394 /* TypeErasedClauses.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -2498,15 +2644,23 @@
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
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_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = 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_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
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;
|
||||
@@ -2531,8 +2685,8 @@
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
INFOPLIST_FILE = Sources/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.10;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.11;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
OTHER_SWIFT_FLAGS = "-D DEBUG";
|
||||
@@ -2540,6 +2694,8 @@
|
||||
PRODUCT_NAME = CoreStore;
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
TVOS_DEPLOYMENT_TARGET = 9.0;
|
||||
VERSIONING_SYSTEM = "apple-generic";
|
||||
@@ -2557,15 +2713,23 @@
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
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_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = 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_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
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;
|
||||
@@ -2585,13 +2749,15 @@
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
INFOPLIST_FILE = Sources/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.10;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.11;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.johnestropia.CoreStore;
|
||||
PRODUCT_NAME = CoreStore;
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
TVOS_DEPLOYMENT_TARGET = 9.0;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
@@ -2611,11 +2777,13 @@
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 3.0;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@@ -2629,11 +2797,13 @@
|
||||
DYLIB_CURRENT_VERSION = 1;
|
||||
DYLIB_INSTALL_NAME_BASE = "@rpath";
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
||||
SWIFT_VERSION = 3.0;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
@@ -2653,7 +2823,8 @@
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "CoreStoreTests/CoreStoreTests-Bridging-Header.h";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 3.0;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@@ -2668,7 +2839,8 @@
|
||||
PRODUCT_NAME = CoreStoreTests;
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "CoreStoreTests/CoreStoreTests-Bridging-Header.h";
|
||||
SWIFT_VERSION = 3.0;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
@@ -2688,7 +2860,8 @@
|
||||
SDKROOT = appletvos;
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 3.0;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.0;
|
||||
TARGETED_DEVICE_FAMILY = 3;
|
||||
};
|
||||
name = Debug;
|
||||
@@ -2709,7 +2882,8 @@
|
||||
SDKROOT = appletvos;
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
||||
SWIFT_VERSION = 3.0;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.0;
|
||||
TARGETED_DEVICE_FAMILY = 3;
|
||||
};
|
||||
name = Release;
|
||||
@@ -2727,7 +2901,8 @@
|
||||
SDKROOT = appletvos;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "CoreStoreTests/CoreStoreTests-Bridging-Header.h";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 3.0;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.0;
|
||||
TARGETED_DEVICE_FAMILY = 3;
|
||||
};
|
||||
name = Debug;
|
||||
@@ -2745,7 +2920,8 @@
|
||||
PRODUCT_NAME = CoreStoreTests;
|
||||
SDKROOT = appletvos;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "CoreStoreTests/CoreStoreTests-Bridging-Header.h";
|
||||
SWIFT_VERSION = 3.0;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.0;
|
||||
TARGETED_DEVICE_FAMILY = 3;
|
||||
};
|
||||
name = Release;
|
||||
@@ -2766,10 +2942,12 @@
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.11;
|
||||
SDKROOT = macosx;
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 3.0;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@@ -2790,10 +2968,12 @@
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks";
|
||||
MACOSX_DEPLOYMENT_TARGET = 10.11;
|
||||
SDKROOT = macosx;
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
||||
SWIFT_VERSION = 3.0;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
@@ -2813,7 +2993,8 @@
|
||||
SDKROOT = macosx;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "CoreStoreTests/CoreStoreTests-Bridging-Header.h";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 3.0;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@@ -2833,7 +3014,8 @@
|
||||
PRODUCT_NAME = CoreStoreTests;
|
||||
SDKROOT = macosx;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "CoreStoreTests/CoreStoreTests-Bridging-Header.h";
|
||||
SWIFT_VERSION = 3.0;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
@@ -2854,7 +3036,8 @@
|
||||
SDKROOT = watchos;
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_VERSION = 3.0;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.0;
|
||||
TARGETED_DEVICE_FAMILY = 4;
|
||||
};
|
||||
name = Debug;
|
||||
@@ -2877,7 +3060,8 @@
|
||||
SDKROOT = watchos;
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
||||
SWIFT_VERSION = 3.0;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.0;
|
||||
TARGETED_DEVICE_FAMILY = 4;
|
||||
};
|
||||
name = Release;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0800"
|
||||
LastUpgradeVersion = "0930"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0800"
|
||||
LastUpgradeVersion = "0930"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
@@ -89,6 +89,12 @@
|
||||
ReferencedContainer = "container:CoreStore.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<CommandLineArguments>
|
||||
<CommandLineArgument
|
||||
argument = "-com.apple.CoreData.SQLDebug 2"
|
||||
isEnabled = "NO">
|
||||
</CommandLineArgument>
|
||||
</CommandLineArguments>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0800"
|
||||
LastUpgradeVersion = "0930"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0800"
|
||||
LastUpgradeVersion = "0930"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEDidComputeMac32BitWarning</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -265,12 +265,12 @@
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 0700;
|
||||
LastUpgradeCheck = 0800;
|
||||
LastUpgradeCheck = 0930;
|
||||
ORGANIZATIONNAME = "John Rommel Estropia";
|
||||
TargetAttributes = {
|
||||
B54AAD481AF4D26E00848AE0 = {
|
||||
CreatedOnToolsVersion = 6.3;
|
||||
LastSwiftMigration = 0800;
|
||||
LastSwiftMigration = 0900;
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -371,14 +371,22 @@
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
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_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
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_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
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;
|
||||
@@ -402,11 +410,13 @@
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@@ -418,14 +428,22 @@
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
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_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
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_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
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;
|
||||
@@ -442,9 +460,11 @@
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.0;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
@@ -454,11 +474,12 @@
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
INFOPLIST_FILE = CoreStoreDemo/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.johnestropia.corestore.demo;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_VERSION = 3.0;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@@ -467,12 +488,13 @@
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
INFOPLIST_FILE = CoreStoreDemo/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.johnestropia.corestore.demo;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
|
||||
SWIFT_VERSION = 3.0;
|
||||
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
|
||||
SWIFT_VERSION = 4.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0800"
|
||||
LastUpgradeVersion = "0930"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
|
||||
import UIKit
|
||||
|
||||
import CoreStore
|
||||
|
||||
// MARK: - AppDelegate
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12113" systemVersion="16C67" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="Ni8-QF-XHB">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="Ni8-QF-XHB">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12078"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
|
||||
<capability name="Aspect ratio constraints" minToolsVersion="5.1"/>
|
||||
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
|
||||
<capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
|
||||
@@ -459,8 +459,8 @@
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="301.5"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" verticalCompressionResistancePriority="250" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="NhC-oM-bkd">
|
||||
<rect key="frame" x="20" y="69.5" width="552" height="36.5"/>
|
||||
<view contentMode="scaleToFill" verticalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="NhC-oM-bkd">
|
||||
<rect key="frame" x="16" y="89.5" width="343" height="50"/>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" relation="greaterThanOrEqual" id="TIX-qi-B34"/>
|
||||
@@ -511,8 +511,8 @@
|
||||
<action selector="brightnessSliderValueDidChange:" destination="dX3-kR-CYC" eventType="valueChanged" id="F09-EP-2iD"/>
|
||||
</connections>
|
||||
</slider>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="Label" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="p4O-tf-dgt">
|
||||
<rect key="frame" x="20" y="49" width="552" height="20.5"/>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="p4O-tf-dgt">
|
||||
<rect key="frame" x="16" y="69" width="343" height="20.5"/>
|
||||
<fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
@@ -797,8 +797,8 @@
|
||||
<rect key="frame" x="0.0" y="64" width="375" height="603"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<mapView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" ambiguous="YES" mapType="standard" translatesAutoresizingMaskIntoConstraints="NO" id="V2U-0R-Ts0">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="536"/>
|
||||
<mapView verifyAmbiguity="ignoreSizes" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" ambiguous="YES" mapType="standard" translatesAutoresizingMaskIntoConstraints="NO" id="V2U-0R-Ts0">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="558"/>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="jPl-fH-NlD" id="Sjn-YC-haS"/>
|
||||
</connections>
|
||||
@@ -806,7 +806,7 @@
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstItem="RZg-hi-T8O" firstAttribute="top" secondItem="V2U-0R-Ts0" secondAttribute="bottom" id="GcS-Jz-Wcm"/>
|
||||
<constraint firstItem="RZg-hi-T8O" firstAttribute="top" secondItem="V2U-0R-Ts0" secondAttribute="bottom" id="N9r-9J-68d"/>
|
||||
<constraint firstItem="V2U-0R-Ts0" firstAttribute="top" secondItem="k4s-iL-Krh" secondAttribute="top" id="S5Z-Da-V6J"/>
|
||||
<constraint firstAttribute="trailing" secondItem="V2U-0R-Ts0" secondAttribute="trailing" id="YPc-RK-5ib"/>
|
||||
<constraint firstItem="V2U-0R-Ts0" firstAttribute="leading" secondItem="k4s-iL-Krh" secondAttribute="leading" id="hk5-Rz-FyU"/>
|
||||
@@ -820,7 +820,7 @@
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="YnG-TD-zxQ" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="3694" y="2020"/>
|
||||
<point key="canvasLocation" x="3693.5" y="2019.5"/>
|
||||
</scene>
|
||||
<!--Logger-->
|
||||
<scene sceneID="n7W-0g-bbY">
|
||||
@@ -927,7 +927,7 @@
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="bordered" selectedSegmentIndex="0" translatesAutoresizingMaskIntoConstraints="NO" id="YVj-dA-fyV">
|
||||
<rect key="frame" x="20" y="26" width="560" height="29"/>
|
||||
<rect key="frame" x="20" y="26" width="335" height="29"/>
|
||||
<segments>
|
||||
<segment title="Fetch"/>
|
||||
<segment title="Query"/>
|
||||
|
||||
@@ -1,36 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<model userDefinedModelVersionIdentifier="" type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="10169.1" systemVersion="15D21" minimumToolsVersion="Automatic">
|
||||
<entity name="Palette" representedClassName="CoreStoreDemo.Palette">
|
||||
<attribute name="brightness" optional="YES" attributeType="Float" defaultValueString="0.0" syncable="YES"/>
|
||||
<attribute name="colorName" optional="YES" transient="YES" attributeType="String" syncable="YES"/>
|
||||
<attribute name="hue" optional="YES" attributeType="Integer 32" defaultValueString="0.0" syncable="YES"/>
|
||||
<attribute name="saturation" optional="YES" attributeType="Float" defaultValueString="0.0" syncable="YES"/>
|
||||
<userInfo/>
|
||||
</entity>
|
||||
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="12141" systemVersion="16F73" minimumToolsVersion="Xcode 7.3" sourceLanguage="Objective-C" userDefinedModelVersionIdentifier="">
|
||||
<entity name="Place" representedClassName="CoreStoreDemo.Place" syncable="YES">
|
||||
<attribute name="latitude" optional="YES" attributeType="Double" defaultValueString="0.0" syncable="YES"/>
|
||||
<attribute name="longitude" optional="YES" attributeType="Double" defaultValueString="0.0" syncable="YES"/>
|
||||
<attribute name="latitude" optional="YES" attributeType="Double" defaultValueString="0.0" usesScalarValueType="NO" syncable="YES"/>
|
||||
<attribute name="longitude" optional="YES" attributeType="Double" defaultValueString="0.0" usesScalarValueType="NO" syncable="YES"/>
|
||||
<attribute name="subtitle" optional="YES" attributeType="String" syncable="YES"/>
|
||||
<attribute name="title" optional="YES" attributeType="String" syncable="YES"/>
|
||||
</entity>
|
||||
<entity name="TimeZone" representedClassName="CoreStoreDemo.TimeZone" syncable="YES">
|
||||
<attribute name="abbreviation" optional="YES" attributeType="String" syncable="YES"/>
|
||||
<attribute name="daylightSavingTimeOffset" optional="YES" attributeType="Double" defaultValueString="0.0" syncable="YES"/>
|
||||
<attribute name="hasDaylightSavingTime" optional="YES" attributeType="Boolean" syncable="YES"/>
|
||||
<attribute name="daylightSavingTimeOffset" optional="YES" attributeType="Double" defaultValueString="0.0" usesScalarValueType="NO" syncable="YES"/>
|
||||
<attribute name="hasDaylightSavingTime" optional="YES" attributeType="Boolean" usesScalarValueType="NO" syncable="YES"/>
|
||||
<attribute name="name" optional="YES" attributeType="String" syncable="YES"/>
|
||||
<attribute name="secondsFromGMT" optional="YES" attributeType="Integer 32" defaultValueString="0.0" syncable="YES"/>
|
||||
<attribute name="secondsFromGMT" optional="YES" attributeType="Integer 32" defaultValueString="0.0" usesScalarValueType="NO" syncable="YES"/>
|
||||
</entity>
|
||||
<configuration name="FetchingAndQueryingDemo">
|
||||
<memberEntity name="TimeZone"/>
|
||||
</configuration>
|
||||
<configuration name="ObservingDemo">
|
||||
<memberEntity name="Palette"/>
|
||||
</configuration>
|
||||
<configuration name="TransactionsDemo">
|
||||
<memberEntity name="Place"/>
|
||||
</configuration>
|
||||
<elements>
|
||||
<element name="Palette" positionX="261" positionY="189" width="128" height="105"/>
|
||||
<element name="Place" positionX="261" positionY="225" width="128" height="105"/>
|
||||
<element name="TimeZone" positionX="297" positionY="270" width="128" height="120"/>
|
||||
</elements>
|
||||
|
||||
@@ -165,8 +165,8 @@ class FetchingAndQueryingDemoViewController: UIViewController, UITableViewDataSo
|
||||
fetch: { () -> [TimeZone] in
|
||||
|
||||
return Static.timeZonesStack.fetchAll(
|
||||
From<TimeZone>(),
|
||||
OrderBy(.ascending(#keyPath(TimeZone.name)))
|
||||
From<TimeZone>()
|
||||
.orderBy(.ascending(\.name))
|
||||
)!
|
||||
}
|
||||
),
|
||||
@@ -175,9 +175,13 @@ class FetchingAndQueryingDemoViewController: UIViewController, UITableViewDataSo
|
||||
fetch: { () -> [TimeZone] in
|
||||
|
||||
return Static.timeZonesStack.fetchAll(
|
||||
From<TimeZone>(),
|
||||
Where("%K BEGINSWITH[c] %@", #keyPath(TimeZone.name), "Asia"),
|
||||
OrderBy(.ascending(#keyPath(TimeZone.secondsFromGMT)))
|
||||
From<TimeZone>()
|
||||
.where(
|
||||
format: "%K BEGINSWITH[c] %@",
|
||||
#keyPath(TimeZone.name),
|
||||
"Asia"
|
||||
)
|
||||
.orderBy(.ascending(\.secondsFromGMT))
|
||||
)!
|
||||
}
|
||||
),
|
||||
@@ -186,10 +190,15 @@ class FetchingAndQueryingDemoViewController: UIViewController, UITableViewDataSo
|
||||
fetch: { () -> [TimeZone] in
|
||||
|
||||
return Static.timeZonesStack.fetchAll(
|
||||
From<TimeZone>(),
|
||||
Where("%K BEGINSWITH[c] %@", #keyPath(TimeZone.name), "America")
|
||||
|| Where("%K BEGINSWITH[c] %@", #keyPath(TimeZone.name), "Europe"),
|
||||
OrderBy(.ascending(#keyPath(TimeZone.secondsFromGMT)))
|
||||
From<TimeZone>()
|
||||
.where(
|
||||
format: "%K BEGINSWITH[c] %@ OR %K BEGINSWITH[c] %@",
|
||||
#keyPath(TimeZone.name),
|
||||
"America",
|
||||
#keyPath(TimeZone.name),
|
||||
"Europe"
|
||||
)
|
||||
.orderBy(.ascending(\.secondsFromGMT))
|
||||
)!
|
||||
}
|
||||
),
|
||||
@@ -198,9 +207,13 @@ class FetchingAndQueryingDemoViewController: UIViewController, UITableViewDataSo
|
||||
fetch: { () -> [TimeZone] in
|
||||
|
||||
return Static.timeZonesStack.fetchAll(
|
||||
From<TimeZone>(),
|
||||
!Where("%K BEGINSWITH[c] %@", #keyPath(TimeZone.name), "America"),
|
||||
OrderBy(.ascending(#keyPath(TimeZone.secondsFromGMT)))
|
||||
From<TimeZone>()
|
||||
.where(
|
||||
format: "%K BEGINSWITH[c] %@",
|
||||
#keyPath(TimeZone.name),
|
||||
"America"
|
||||
)
|
||||
.orderBy(.ascending(\.secondsFromGMT))
|
||||
)!
|
||||
}
|
||||
),
|
||||
@@ -209,23 +222,23 @@ class FetchingAndQueryingDemoViewController: UIViewController, UITableViewDataSo
|
||||
fetch: { () -> [TimeZone] in
|
||||
|
||||
return Static.timeZonesStack.fetchAll(
|
||||
From<TimeZone>(),
|
||||
Where("hasDaylightSavingTime", isEqualTo: true),
|
||||
OrderBy(.ascending(#keyPath(TimeZone.name)))
|
||||
From<TimeZone>()
|
||||
.where(\.hasDaylightSavingTime == true)
|
||||
.orderBy(.ascending(\.name))
|
||||
)!
|
||||
}
|
||||
)
|
||||
]
|
||||
|
||||
private let queryingItems = [
|
||||
private let queryingItems: [(title: String, query: () -> Any)] = [
|
||||
(
|
||||
title: "Number of Time Zones",
|
||||
query: { () -> Any in
|
||||
|
||||
return Static.timeZonesStack.queryValue(
|
||||
From<TimeZone>(),
|
||||
Select<NSNumber>(.count(#keyPath(TimeZone.name)))
|
||||
)!
|
||||
From<TimeZone>()
|
||||
.select(NSNumber.self, .count(\.name))
|
||||
)! as Any
|
||||
}
|
||||
),
|
||||
(
|
||||
@@ -233,10 +246,10 @@ class FetchingAndQueryingDemoViewController: UIViewController, UITableViewDataSo
|
||||
query: { () -> Any in
|
||||
|
||||
return Static.timeZonesStack.queryValue(
|
||||
From<TimeZone>(),
|
||||
Select<String>(#keyPath(TimeZone.abbreviation)),
|
||||
Where("%K ENDSWITH[c] %@", #keyPath(TimeZone.name), "Tokyo")
|
||||
)!
|
||||
From<TimeZone>()
|
||||
.select(String.self, .attribute(\.abbreviation))
|
||||
.where(format: "%K ENDSWITH[c] %@", #keyPath(TimeZone.name), "Tokyo")
|
||||
)! as Any
|
||||
}
|
||||
),
|
||||
(
|
||||
@@ -244,9 +257,13 @@ class FetchingAndQueryingDemoViewController: UIViewController, UITableViewDataSo
|
||||
query: { () -> Any in
|
||||
|
||||
return Static.timeZonesStack.queryAttributes(
|
||||
From<TimeZone>(),
|
||||
Select<NSDictionary>(#keyPath(TimeZone.name), #keyPath(TimeZone.abbreviation)),
|
||||
OrderBy(.ascending(#keyPath(TimeZone.name)))
|
||||
From<TimeZone>()
|
||||
.select(
|
||||
NSDictionary.self,
|
||||
.attribute(\.name),
|
||||
.attribute(\.abbreviation)
|
||||
)
|
||||
.orderBy(.ascending(\.name))
|
||||
)!
|
||||
}
|
||||
),
|
||||
@@ -255,10 +272,17 @@ class FetchingAndQueryingDemoViewController: UIViewController, UITableViewDataSo
|
||||
query: { () -> Any in
|
||||
|
||||
return Static.timeZonesStack.queryAttributes(
|
||||
From<TimeZone>(),
|
||||
Select<NSDictionary>(.count(#keyPath(TimeZone.abbreviation)), #keyPath(TimeZone.abbreviation)),
|
||||
GroupBy(#keyPath(TimeZone.abbreviation)),
|
||||
OrderBy(.ascending(#keyPath(TimeZone.secondsFromGMT)), .ascending(#keyPath(TimeZone.name)))
|
||||
From<TimeZone>()
|
||||
.select(
|
||||
NSDictionary.self,
|
||||
.count(\.abbreviation),
|
||||
.attribute(\.abbreviation)
|
||||
)
|
||||
.groupBy(\.abbreviation)
|
||||
.orderBy(
|
||||
.ascending(\.secondsFromGMT),
|
||||
.ascending(\.name)
|
||||
)
|
||||
)!
|
||||
}
|
||||
),
|
||||
@@ -267,13 +291,17 @@ class FetchingAndQueryingDemoViewController: UIViewController, UITableViewDataSo
|
||||
query: { () -> Any in
|
||||
|
||||
return Static.timeZonesStack.queryAttributes(
|
||||
From<TimeZone>(),
|
||||
Select<NSDictionary>(
|
||||
.count(#keyPath(TimeZone.hasDaylightSavingTime), as: "numberOfCountries"),
|
||||
#keyPath(TimeZone.hasDaylightSavingTime)
|
||||
),
|
||||
GroupBy(#keyPath(TimeZone.hasDaylightSavingTime)),
|
||||
OrderBy(.descending(#keyPath(TimeZone.hasDaylightSavingTime)))
|
||||
From<TimeZone>()
|
||||
.select(
|
||||
NSDictionary.self,
|
||||
.count(\.hasDaylightSavingTime, as: "numberOfCountries"),
|
||||
.attribute(\.hasDaylightSavingTime)
|
||||
)
|
||||
.groupBy(\.hasDaylightSavingTime)
|
||||
.orderBy(
|
||||
.descending(\.hasDaylightSavingTime),
|
||||
.ascending(\.name)
|
||||
)
|
||||
)!
|
||||
}
|
||||
)
|
||||
|
||||
@@ -17,11 +17,11 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0.1</string>
|
||||
<string>5.1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<string>4</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
|
||||
@@ -10,7 +10,7 @@ import UIKit
|
||||
import CoreStore
|
||||
|
||||
|
||||
private struct Static {
|
||||
struct ColorsDemo {
|
||||
|
||||
enum Filter: String {
|
||||
|
||||
@@ -28,13 +28,13 @@ private struct Static {
|
||||
}
|
||||
}
|
||||
|
||||
func whereClause() -> Where {
|
||||
func whereClause() -> Where<Palette> {
|
||||
|
||||
switch self {
|
||||
|
||||
case .all: return Where(true)
|
||||
case .light: return Where("%K >= %@", #keyPath(Palette.brightness), 0.9)
|
||||
case .dark: return Where("%K <= %@", #keyPath(Palette.brightness), 0.4)
|
||||
case .all: return .init()
|
||||
case .light: return (\Palette.brightness >= 0.9)
|
||||
case .dark: return (\Palette.brightness <= 0.4)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -45,25 +45,38 @@ private struct Static {
|
||||
|
||||
self.palettes.refetch(
|
||||
self.filter.whereClause(),
|
||||
OrderBy(.ascending(#keyPath(Palette.hue)))
|
||||
OrderBy<Palette>(.ascending(\.hue))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
static let stack: DataStack = {
|
||||
|
||||
return DataStack(
|
||||
CoreStoreSchema(
|
||||
modelVersion: "ColorsDemo",
|
||||
entities: [
|
||||
Entity<Palette>("Palette"),
|
||||
],
|
||||
versionLock: [
|
||||
"Palette": [0x8c25aa53c7c90a28, 0xa243a34d25f1a3a7, 0x56565b6935b6055a, 0x4f988bb257bf274f]
|
||||
]
|
||||
)
|
||||
)
|
||||
}()
|
||||
|
||||
static let palettes: ListMonitor<Palette> = {
|
||||
|
||||
try! CoreStore.addStorageAndWait(
|
||||
try! ColorsDemo.stack.addStorageAndWait(
|
||||
SQLiteStore(
|
||||
fileName: "ColorsDemo.sqlite",
|
||||
configuration: "ObservingDemo",
|
||||
localStorageOptions: .recreateStoreOnModelMismatch
|
||||
)
|
||||
)
|
||||
|
||||
return CoreStore.monitorSectionedList(
|
||||
From<Palette>(),
|
||||
SectionBy(#keyPath(Palette.colorName)),
|
||||
OrderBy(.ascending(#keyPath(Palette.hue)))
|
||||
return ColorsDemo.stack.monitorSectionedList(
|
||||
From<Palette>()
|
||||
.sectionBy(\.colorName)
|
||||
.orderBy(.ascending(\.hue))
|
||||
)
|
||||
}()
|
||||
}
|
||||
@@ -77,7 +90,7 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
|
||||
|
||||
deinit {
|
||||
|
||||
Static.palettes.removeObserver(self)
|
||||
ColorsDemo.palettes.removeObserver(self)
|
||||
}
|
||||
|
||||
|
||||
@@ -98,7 +111,7 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
|
||||
]
|
||||
|
||||
let filterBarButton = UIBarButtonItem(
|
||||
title: Static.filter.rawValue,
|
||||
title: ColorsDemo.filter.rawValue,
|
||||
style: .plain,
|
||||
target: self,
|
||||
action: #selector(self.filterBarButtonItemTouched(_:))
|
||||
@@ -113,9 +126,9 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
|
||||
]
|
||||
self.filterBarButton = filterBarButton
|
||||
|
||||
Static.palettes.addObserver(self)
|
||||
ColorsDemo.palettes.addObserver(self)
|
||||
|
||||
self.setTable(enabled: !Static.palettes.isPendingRefetch)
|
||||
self.setTable(enabled: !ColorsDemo.palettes.isPendingRefetch)
|
||||
}
|
||||
|
||||
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
|
||||
@@ -137,19 +150,19 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
|
||||
|
||||
override func numberOfSections(in tableView: UITableView) -> Int {
|
||||
|
||||
return Static.palettes.numberOfSections()
|
||||
return ColorsDemo.palettes.numberOfSections()
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
|
||||
return Static.palettes.numberOfObjectsInSection(section)
|
||||
return ColorsDemo.palettes.numberOfObjectsInSection(section)
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: "PaletteTableViewCell") as! PaletteTableViewCell
|
||||
|
||||
let palette = Static.palettes[indexPath]
|
||||
let palette = ColorsDemo.palettes[indexPath]
|
||||
cell.colorView?.backgroundColor = palette.color
|
||||
cell.label?.text = palette.colorText
|
||||
|
||||
@@ -165,7 +178,7 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
|
||||
|
||||
self.performSegue(
|
||||
withIdentifier: "ObjectObserverDemoViewController",
|
||||
sender: Static.palettes[indexPath]
|
||||
sender: ColorsDemo.palettes[indexPath]
|
||||
)
|
||||
}
|
||||
|
||||
@@ -174,8 +187,8 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
|
||||
switch editingStyle {
|
||||
|
||||
case .delete:
|
||||
let palette = Static.palettes[indexPath]
|
||||
CoreStore.perform(
|
||||
let palette = ColorsDemo.palettes[indexPath]
|
||||
ColorsDemo.stack.perform(
|
||||
asynchronous: { (transaction) in
|
||||
|
||||
transaction.delete(palette)
|
||||
@@ -190,7 +203,7 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
|
||||
|
||||
override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
|
||||
|
||||
return Static.palettes.sectionInfoAtIndex(section).name
|
||||
return ColorsDemo.palettes.sectionInfoAtIndex(section).name
|
||||
}
|
||||
|
||||
|
||||
@@ -213,7 +226,7 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
|
||||
|
||||
func listMonitorDidRefetch(_ monitor: ListMonitor<Palette>) {
|
||||
|
||||
self.filterBarButton?.title = Static.filter.rawValue
|
||||
self.filterBarButton?.title = ColorsDemo.filter.rawValue
|
||||
self.tableView.reloadData()
|
||||
self.setTable(enabled: true)
|
||||
}
|
||||
@@ -235,7 +248,7 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
|
||||
|
||||
if let cell = self.tableView.cellForRow(at: indexPath) as? PaletteTableViewCell {
|
||||
|
||||
let palette = Static.palettes[indexPath]
|
||||
let palette = ColorsDemo.palettes[indexPath]
|
||||
cell.colorView?.backgroundColor = palette.color
|
||||
cell.label?.text = palette.colorText
|
||||
}
|
||||
@@ -255,7 +268,6 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
|
||||
self.tableView.insertSections(IndexSet(integer: sectionIndex), with: .automatic)
|
||||
}
|
||||
|
||||
|
||||
func listMonitor(_ monitor: ListMonitor<Palette>, didDeleteSection sectionInfo: NSFetchedResultsSectionInfo, fromSectionIndex sectionIndex: Int) {
|
||||
|
||||
self.tableView.deleteSections(IndexSet(integer: sectionIndex), with: .automatic)
|
||||
@@ -268,7 +280,7 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
|
||||
|
||||
@IBAction private dynamic func resetBarButtonItemTouched(_ sender: AnyObject?) {
|
||||
|
||||
CoreStore.perform(
|
||||
ColorsDemo.stack.perform(
|
||||
asynchronous: { (transaction) in
|
||||
|
||||
transaction.deleteAll(From<Palette>())
|
||||
@@ -279,16 +291,16 @@ class ListObserverDemoViewController: UITableViewController, ListSectionObserver
|
||||
|
||||
@IBAction private dynamic func filterBarButtonItemTouched(_ sender: AnyObject?) {
|
||||
|
||||
Static.filter = Static.filter.next()
|
||||
ColorsDemo.filter = ColorsDemo.filter.next()
|
||||
}
|
||||
|
||||
@IBAction private dynamic func addBarButtonItemTouched(_ sender: AnyObject?) {
|
||||
|
||||
CoreStore.perform(
|
||||
ColorsDemo.stack.perform(
|
||||
asynchronous: { (transaction) in
|
||||
|
||||
let palette = transaction.create(Into<Palette>())
|
||||
palette.setInitialValues()
|
||||
palette.setInitialValues(in: transaction)
|
||||
},
|
||||
completion: { _ in }
|
||||
)
|
||||
|
||||
@@ -29,7 +29,7 @@ class ObjectObserverDemoViewController: UIViewController, ObjectObserver {
|
||||
|
||||
if let palette = newValue {
|
||||
|
||||
self.monitor = CoreStore.monitorObject(palette)
|
||||
self.monitor = ColorsDemo.stack.monitorObject(palette)
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -50,22 +50,22 @@ class ObjectObserverDemoViewController: UIViewController, ObjectObserver {
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
|
||||
if let palette = CoreStore.fetchOne(From<Palette>(), OrderBy(.ascending(#keyPath(Palette.hue)))) {
|
||||
if let palette = ColorsDemo.stack.fetchOne(From<Palette>().orderBy(.ascending(\.hue))) {
|
||||
|
||||
self.monitor = CoreStore.monitorObject(palette)
|
||||
self.monitor = ColorsDemo.stack.monitorObject(palette)
|
||||
}
|
||||
else {
|
||||
|
||||
_ = try? CoreStore.perform(
|
||||
_ = try? ColorsDemo.stack.perform(
|
||||
synchronous: { (transaction) in
|
||||
|
||||
let palette = transaction.create(Into(Palette.self))
|
||||
palette.setInitialValues()
|
||||
let palette = transaction.create(Into<Palette>())
|
||||
palette.setInitialValues(in: transaction)
|
||||
}
|
||||
)
|
||||
|
||||
let palette = CoreStore.fetchOne(From<Palette>(), OrderBy(.ascending(#keyPath(Palette.hue))))!
|
||||
self.monitor = CoreStore.monitorObject(palette)
|
||||
let palette = ColorsDemo.stack.fetchOne(From<Palette>().orderBy(.ascending(\.hue)))!
|
||||
self.monitor = ColorsDemo.stack.monitorObject(palette)
|
||||
}
|
||||
|
||||
super.init(coder: aDecoder)
|
||||
@@ -85,7 +85,7 @@ class ObjectObserverDemoViewController: UIViewController, ObjectObserver {
|
||||
|
||||
// MARK: ObjectObserver
|
||||
|
||||
func objectMonitor(_ monitor: ObjectMonitor<Palette>, didUpdateObject object: Palette, changedPersistentKeys: Set<KeyPath>) {
|
||||
func objectMonitor(_ monitor: ObjectMonitor<Palette>, didUpdateObject object: Palette, changedPersistentKeys: Set<KeyPathString>) {
|
||||
|
||||
self.reloadPaletteInfo(object, changedKeys: changedPersistentKeys)
|
||||
}
|
||||
@@ -121,12 +121,12 @@ class ObjectObserverDemoViewController: UIViewController, ObjectObserver {
|
||||
@IBAction dynamic func hueSliderValueDidChange(_ sender: AnyObject?) {
|
||||
|
||||
let hue = self.hueSlider?.value ?? 0
|
||||
CoreStore.perform(
|
||||
ColorsDemo.stack.perform(
|
||||
asynchronous: { [weak self] (transaction) in
|
||||
|
||||
if let palette = transaction.edit(self?.monitor?.object) {
|
||||
|
||||
palette.hue = Int32(hue)
|
||||
palette.hue .= Int(hue)
|
||||
}
|
||||
},
|
||||
completion: { _ in }
|
||||
@@ -136,12 +136,12 @@ class ObjectObserverDemoViewController: UIViewController, ObjectObserver {
|
||||
@IBAction dynamic func saturationSliderValueDidChange(_ sender: AnyObject?) {
|
||||
|
||||
let saturation = self.saturationSlider?.value ?? 0
|
||||
CoreStore.perform(
|
||||
ColorsDemo.stack.perform(
|
||||
asynchronous: { [weak self] (transaction) in
|
||||
|
||||
if let palette = transaction.edit(self?.monitor?.object) {
|
||||
|
||||
palette.saturation = saturation
|
||||
palette.saturation .= saturation
|
||||
}
|
||||
},
|
||||
completion: { _ in }
|
||||
@@ -151,12 +151,12 @@ class ObjectObserverDemoViewController: UIViewController, ObjectObserver {
|
||||
@IBAction dynamic func brightnessSliderValueDidChange(_ sender: AnyObject?) {
|
||||
|
||||
let brightness = self.brightnessSlider?.value ?? 0
|
||||
CoreStore.perform(
|
||||
ColorsDemo.stack.perform(
|
||||
asynchronous: { [weak self] (transaction) in
|
||||
|
||||
if let palette = transaction.edit(self?.monitor?.object) {
|
||||
|
||||
palette.brightness = brightness
|
||||
palette.brightness .= brightness
|
||||
}
|
||||
},
|
||||
completion: { _ in }
|
||||
@@ -165,7 +165,7 @@ class ObjectObserverDemoViewController: UIViewController, ObjectObserver {
|
||||
|
||||
@IBAction dynamic func deleteBarButtonTapped(_ sender: AnyObject?) {
|
||||
|
||||
CoreStore.perform(
|
||||
ColorsDemo.stack.perform(
|
||||
asynchronous: { [weak self] (transaction) in
|
||||
|
||||
transaction.delete(self?.monitor?.object)
|
||||
@@ -176,7 +176,7 @@ class ObjectObserverDemoViewController: UIViewController, ObjectObserver {
|
||||
|
||||
func reloadPaletteInfo(_ palette: Palette, changedKeys: Set<String>?) {
|
||||
|
||||
self.colorNameLabel?.text = palette.colorName
|
||||
self.colorNameLabel?.text = palette.colorName.value
|
||||
|
||||
let color = palette.color
|
||||
self.colorNameLabel?.textColor = color
|
||||
@@ -184,17 +184,17 @@ class ObjectObserverDemoViewController: UIViewController, ObjectObserver {
|
||||
|
||||
self.hsbLabel?.text = palette.colorText
|
||||
|
||||
if changedKeys == nil || changedKeys?.contains(#keyPath(Palette.hue)) == true {
|
||||
if changedKeys == nil || changedKeys?.contains(String(keyPath: \Palette.hue)) == true {
|
||||
|
||||
self.hueSlider?.value = Float(palette.hue)
|
||||
self.hueSlider?.value = Float(palette.hue.value)
|
||||
}
|
||||
if changedKeys == nil || changedKeys?.contains(#keyPath(Palette.saturation)) == true {
|
||||
if changedKeys == nil || changedKeys?.contains(String(keyPath: \Palette.saturation)) == true {
|
||||
|
||||
self.saturationSlider?.value = palette.saturation
|
||||
self.saturationSlider?.value = palette.saturation.value
|
||||
}
|
||||
if changedKeys == nil || changedKeys?.contains(#keyPath(Palette.brightness)) == true {
|
||||
if changedKeys == nil || changedKeys?.contains(String(keyPath: \Palette.hue)) == true {
|
||||
|
||||
self.brightnessSlider?.value = palette.brightness
|
||||
self.brightnessSlider?.value = palette.brightness.value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,64 +14,65 @@ import CoreStore
|
||||
|
||||
// MARK: - Palette
|
||||
|
||||
class Palette: NSManagedObject {
|
||||
|
||||
@NSManaged var hue: Int32
|
||||
@NSManaged var saturation: Float
|
||||
@NSManaged var brightness: Float
|
||||
final class Palette: CoreStoreObject {
|
||||
|
||||
@objc dynamic var colorName: String {
|
||||
let hue = Value.Required<Int>("hue", initial: 0)
|
||||
let saturation = Value.Required<Float>("saturation", initial: 0)
|
||||
let brightness = Value.Required<Float>("brightness", initial: 0)
|
||||
|
||||
let colorName = Value.Optional<String>(
|
||||
"colorName",
|
||||
isTransient: true,
|
||||
customGetter: Palette.getColorName
|
||||
)
|
||||
|
||||
private static func getColorName(_ partialObject: PartialObject<Palette>) -> String? {
|
||||
|
||||
get {
|
||||
if let colorName = partialObject.primitiveValue(for: { $0.colorName }) {
|
||||
|
||||
let KVCKey = #keyPath(Palette.colorName)
|
||||
if let colorName = self.getValue(forKvcKey: KVCKey) as? String {
|
||||
|
||||
return colorName
|
||||
}
|
||||
|
||||
let colorName: String
|
||||
switch self.hue % 360 {
|
||||
|
||||
case 0 ..< 20: colorName = "Lower Reds"
|
||||
case 20 ..< 57: colorName = "Oranges and Browns"
|
||||
case 57 ..< 90: colorName = "Yellow-Greens"
|
||||
case 90 ..< 159: colorName = "Greens"
|
||||
case 159 ..< 197: colorName = "Blue-Greens"
|
||||
case 197 ..< 241: colorName = "Blues"
|
||||
case 241 ..< 297: colorName = "Violets"
|
||||
case 297 ..< 331: colorName = "Magentas"
|
||||
default: colorName = "Upper Reds"
|
||||
}
|
||||
|
||||
self.setPrimitiveValue(colorName, forKey: KVCKey)
|
||||
return colorName
|
||||
}
|
||||
set {
|
||||
|
||||
let colorName: String
|
||||
switch partialObject.value(for: { $0.hue }) % 360 {
|
||||
|
||||
self.setValue(newValue.cs_toImportableNativeType(), forKvcKey: #keyPath(Palette.colorName))
|
||||
case 0 ..< 20: colorName = "Lower Reds"
|
||||
case 20 ..< 57: colorName = "Oranges and Browns"
|
||||
case 57 ..< 90: colorName = "Yellow-Greens"
|
||||
case 90 ..< 159: colorName = "Greens"
|
||||
case 159 ..< 197: colorName = "Blue-Greens"
|
||||
case 197 ..< 241: colorName = "Blues"
|
||||
case 241 ..< 297: colorName = "Violets"
|
||||
case 297 ..< 331: colorName = "Magentas"
|
||||
default: colorName = "Upper Reds"
|
||||
}
|
||||
|
||||
partialObject.setPrimitiveValue(colorName, for: { $0.colorName })
|
||||
return colorName
|
||||
}
|
||||
}
|
||||
|
||||
extension Palette {
|
||||
|
||||
var color: UIColor {
|
||||
|
||||
return UIColor(
|
||||
hue: CGFloat(self.hue) / 360.0,
|
||||
saturation: CGFloat(self.saturation),
|
||||
brightness: CGFloat(self.brightness),
|
||||
hue: CGFloat(self.hue.value) / 360.0,
|
||||
saturation: CGFloat(self.saturation.value),
|
||||
brightness: CGFloat(self.brightness.value),
|
||||
alpha: 1.0
|
||||
)
|
||||
}
|
||||
|
||||
var colorText: String {
|
||||
|
||||
return "H: \(self.hue)˚, S: \(round(self.saturation * 100.0))%, B: \(round(self.brightness * 100.0))%"
|
||||
return "H: \(self.hue.value)˚, S: \(round(self.saturation.value * 100.0))%, B: \(round(self.brightness.value * 100.0))%"
|
||||
}
|
||||
|
||||
func setInitialValues() {
|
||||
func setInitialValues(in transaction: BaseDataTransaction) {
|
||||
|
||||
self.hue = Int32(arc4random_uniform(360))
|
||||
self.saturation = 1.0
|
||||
self.brightness = Float(arc4random_uniform(70) + 30) / 100.0
|
||||
self.hue .= Int(arc4random_uniform(360))
|
||||
self.saturation .= Float(1.0)
|
||||
self.brightness .= Float(arc4random_uniform(70) + 30) / 100.0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,8 +99,8 @@ class CustomLoggerViewController: UIViewController, CoreStoreLogger {
|
||||
|
||||
case 0?:
|
||||
let request = NSFetchRequest<NSFetchRequestResult>()
|
||||
Where(true).applyToFetchRequest(request)
|
||||
Where(false).applyToFetchRequest(request)
|
||||
Where<NSManagedObject>(true).applyToFetchRequest(request)
|
||||
Where<NSManagedObject>(false).applyToFetchRequest(request)
|
||||
|
||||
case 1?:
|
||||
_ = try? dataStack.addStorageAndWait(
|
||||
@@ -113,7 +113,7 @@ class CustomLoggerViewController: UIViewController, CoreStoreLogger {
|
||||
case 2?:
|
||||
DispatchQueue.global(qos: .background).async {
|
||||
|
||||
_ = self.dataStack.fetchOne(From<Palette>())
|
||||
_ = self.dataStack.fetchOne(From<Place>())
|
||||
}
|
||||
|
||||
default:
|
||||
|
||||
@@ -46,7 +46,7 @@ class MigrationsDemoViewController: UIViewController, ListObserver, UITableViewD
|
||||
self.present(alert, animated: true, completion: nil)
|
||||
|
||||
|
||||
let modelMetadata = withExtendedLifetime(DataStack(modelName: "MigrationDemo")) {
|
||||
let modelMetadata = withExtendedLifetime(DataStack(xcodeModelName: "MigrationDemo")) {
|
||||
(dataStack: DataStack) -> ModelMetadata in
|
||||
|
||||
let models = self.models
|
||||
@@ -91,6 +91,11 @@ class MigrationsDemoViewController: UIViewController, ListObserver, UITableViewD
|
||||
}
|
||||
}
|
||||
|
||||
func listMonitorDidRefetch(_ monitor: ListMonitor<NSManagedObject>) {
|
||||
|
||||
self.listMonitorDidChange(monitor)
|
||||
}
|
||||
|
||||
// MARK: UITableViewDataSource
|
||||
|
||||
@objc dynamic func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
@@ -104,7 +109,7 @@ class MigrationsDemoViewController: UIViewController, ListObserver, UITableViewD
|
||||
|
||||
let dna = (self.listMonitor?[indexPath] as? OrganismProtocol)?.dna.description ?? ""
|
||||
cell.dnaLabel?.text = "DNA: \(dna)"
|
||||
cell.mutateButtonHandler = { [weak self] _ -> Void in
|
||||
cell.mutateButtonHandler = { [weak self] () -> Void in
|
||||
|
||||
guard let `self` = self,
|
||||
let dataStack = self.dataStack,
|
||||
@@ -148,7 +153,10 @@ class MigrationsDemoViewController: UIViewController, ListObserver, UITableViewD
|
||||
label: "Model V1",
|
||||
entityType: OrganismV1.self,
|
||||
schemaHistory: SchemaHistory(
|
||||
modelName: "MigrationDemo",
|
||||
XcodeDataModelSchema.from(
|
||||
modelName: "MigrationDemo",
|
||||
migrationChain: ["MigrationDemoV3", "MigrationDemoV2", "MigrationDemo"]
|
||||
),
|
||||
migrationChain: ["MigrationDemoV3", "MigrationDemoV2", "MigrationDemo"]
|
||||
)
|
||||
),
|
||||
@@ -156,7 +164,13 @@ class MigrationsDemoViewController: UIViewController, ListObserver, UITableViewD
|
||||
label: "Model V2",
|
||||
entityType: OrganismV2.self,
|
||||
schemaHistory: SchemaHistory(
|
||||
modelName: "MigrationDemo",
|
||||
XcodeDataModelSchema.from(
|
||||
modelName: "MigrationDemo",
|
||||
migrationChain: [
|
||||
"MigrationDemo": "MigrationDemoV2",
|
||||
"MigrationDemoV3": "MigrationDemoV2"
|
||||
]
|
||||
),
|
||||
migrationChain: [
|
||||
"MigrationDemo": "MigrationDemoV2",
|
||||
"MigrationDemoV3": "MigrationDemoV2"
|
||||
@@ -167,7 +181,10 @@ class MigrationsDemoViewController: UIViewController, ListObserver, UITableViewD
|
||||
label: "Model V3",
|
||||
entityType: OrganismV3.self,
|
||||
schemaHistory: SchemaHistory(
|
||||
modelName: "MigrationDemo",
|
||||
XcodeDataModelSchema.from(
|
||||
modelName: "MigrationDemo",
|
||||
migrationChain: ["MigrationDemo", "MigrationDemoV2", "MigrationDemoV3"]
|
||||
),
|
||||
migrationChain: ["MigrationDemo", "MigrationDemoV2", "MigrationDemoV3"]
|
||||
)
|
||||
)
|
||||
@@ -270,8 +287,8 @@ class MigrationsDemoViewController: UIViewController, ListObserver, UITableViewD
|
||||
self.set(dataStack: dataStack, model: model, scrollToSelection: true)
|
||||
|
||||
let count = dataStack.queryValue(
|
||||
From(model.entityType),
|
||||
Select<Int>(.count(#keyPath(OrganismV1.dna))))!
|
||||
From<NSManagedObject>(model.entityType)
|
||||
.select(Int.self, .count(#keyPath(OrganismV1.dna))))!
|
||||
if count > 0 {
|
||||
|
||||
self.setEnabled(true)
|
||||
@@ -344,14 +361,18 @@ class MigrationsDemoViewController: UIViewController, ListObserver, UITableViewD
|
||||
|
||||
self.segmentedControl?.selectedSegmentIndex = self.models
|
||||
.index(
|
||||
where: { (_, _, schemaHistory) -> Bool in
|
||||
where: { (arg) -> Bool in
|
||||
|
||||
schemaHistory.currentModelVersion == model.schemaHistory.currentModelVersion
|
||||
let (_, _, schemaHistory) = arg
|
||||
return schemaHistory.currentModelVersion == model.schemaHistory.currentModelVersion
|
||||
}
|
||||
)!
|
||||
|
||||
self._dataStack = dataStack
|
||||
let listMonitor = dataStack.monitorList(From(model.entityType), OrderBy(.descending("dna")))
|
||||
let listMonitor = dataStack.monitorList(
|
||||
From(model.entityType),
|
||||
OrderBy<NSManagedObject>(.descending(#keyPath(OrganismV1.dna)))
|
||||
)
|
||||
listMonitor.addObserver(self)
|
||||
self._listMonitor = listMonitor
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ private struct Static {
|
||||
|
||||
static let facebookStack: DataStack = {
|
||||
|
||||
let dataStack = DataStack(modelName: "StackSetupDemo")
|
||||
let dataStack = DataStack(xcodeModelName: "StackSetupDemo")
|
||||
try! dataStack.addStorageAndWait(
|
||||
SQLiteStore(
|
||||
fileName: "AccountsDemo_FB_Male.sqlite",
|
||||
@@ -55,7 +55,7 @@ private struct Static {
|
||||
|
||||
static let twitterStack: DataStack = {
|
||||
|
||||
let dataStack = DataStack(modelName: "StackSetupDemo")
|
||||
let dataStack = DataStack(xcodeModelName: "StackSetupDemo")
|
||||
try! dataStack.addStorageAndWait(
|
||||
SQLiteStore(
|
||||
fileName: "AccountsDemo_TW_Male.sqlite",
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import Contacts
|
||||
import CoreLocation
|
||||
import MapKit
|
||||
import AddressBookUI
|
||||
@@ -131,7 +132,7 @@ class TransactionsDemoViewController: UIViewController, MKMapViewDelegate, Objec
|
||||
// none
|
||||
}
|
||||
|
||||
func objectMonitor(_ monitor: ObjectMonitor<Place>, didUpdateObject object: Place, changedPersistentKeys: Set<KeyPath>) {
|
||||
func objectMonitor(_ monitor: ObjectMonitor<Place>, didUpdateObject object: Place, changedPersistentKeys: Set<KeyPathString>) {
|
||||
|
||||
if let mapView = self.mapView {
|
||||
|
||||
@@ -203,11 +204,23 @@ class TransactionsDemoViewController: UIViewController, MKMapViewDelegate, Objec
|
||||
CLLocation(latitude: place.latitude, longitude: place.longitude),
|
||||
completionHandler: { [weak self] (placemarks, error) -> Void in
|
||||
|
||||
if let placemark = placemarks?.first, let addressDictionary = placemark.addressDictionary {
|
||||
if let placemark = placemarks?.first, let dictionary = placemark.addressDictionary {
|
||||
|
||||
let place = transaction.edit(Static.placeController.object)
|
||||
place?.title = placemark.name
|
||||
place?.subtitle = ABCreateStringWithAddressDictionary(addressDictionary, true)
|
||||
place?.subtitle = CNPostalAddressFormatter.string(
|
||||
from: autoreleasepool {
|
||||
|
||||
let address = CNMutablePostalAddress()
|
||||
(dictionary["Street"] as? String).flatMap({ address.street = $0 })
|
||||
(dictionary["State"] as? String).flatMap({ address.state = $0 })
|
||||
(dictionary["City"] as? String).flatMap({ address.city = $0 })
|
||||
(dictionary["Country"] as? String).flatMap({ address.country = $0 })
|
||||
(dictionary["ZIP"] as? String).flatMap({ address.postalCode = $0 })
|
||||
return address
|
||||
},
|
||||
style: .mailingAddress
|
||||
)
|
||||
transaction.commit { (_) -> Void in }
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ class BaseTestCase: XCTestCase {
|
||||
func prepareStack<T>(configurations: [ModelConfiguration] = [nil], _ closure: (_ dataStack: DataStack) -> T) -> T {
|
||||
|
||||
let stack = DataStack(
|
||||
modelName: "Model",
|
||||
xcodeModelName: "Model",
|
||||
bundle: Bundle(for: type(of: self))
|
||||
)
|
||||
do {
|
||||
|
||||
@@ -2,8 +2,25 @@
|
||||
// BaseTestDataTestCase.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Created by John Rommel Estropia on 2016/06/11.
|
||||
// Copyright © 2016 John Rommel Estropia. All rights reserved.
|
||||
// Copyright © 2017 John Rommel Estropia
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
@@ -163,7 +163,7 @@
|
||||
- (void)test_ThatDataStacks_BridgeCorrectly {
|
||||
|
||||
CSDataStack *dataStack = [[CSDataStack alloc]
|
||||
initWithModelName:@"Model"
|
||||
initWithXcodeModelName:@"Model"
|
||||
bundle:[NSBundle bundleForClass:[self class]]
|
||||
versionChain:nil];
|
||||
XCTAssertNotNil(dataStack);
|
||||
@@ -201,7 +201,7 @@
|
||||
|
||||
[CSCoreStore
|
||||
setDefaultStack:[[CSDataStack alloc]
|
||||
initWithModelName:@"Model"
|
||||
initWithXcodeModelName:@"Model"
|
||||
bundle:[NSBundle bundleForClass:[self class]]
|
||||
versionChain:nil]];
|
||||
[CSCoreStore
|
||||
@@ -253,37 +253,5 @@
|
||||
}
|
||||
[self waitForExpectationsWithTimeout:10 handler:nil];
|
||||
}
|
||||
|
||||
#if TARGET_OS_IOS || TARGET_OS_WATCHOS || TARGET_OS_TV
|
||||
|
||||
- (void)test_ThatDataStacks_CanCreateCustomFetchedResultsControllers {
|
||||
|
||||
[CSCoreStore
|
||||
setDefaultStack:[[CSDataStack alloc]
|
||||
initWithModelName:@"Model"
|
||||
bundle:[NSBundle bundleForClass:[self class]]
|
||||
versionChain:nil]];
|
||||
[CSCoreStore
|
||||
addInMemoryStorageAndWait:[CSInMemoryStore new]
|
||||
error:nil];
|
||||
NSFetchedResultsController *controller =
|
||||
[[CSCoreStore defaultStack]
|
||||
createFetchedResultsControllerFrom:CSFromClass([TestEntity1 class])
|
||||
sectionBy:[CSSectionBy keyPath:CSKeyPath(TestEntity1, testString)]
|
||||
fetchClauses:@[CSWhereFormat(@"%K > %d", CSKeyPath(TestEntity1, testEntityID), 100),
|
||||
CSOrderByKeys(CSSortAscending(CSKeyPath(TestEntity1, testString)), nil),
|
||||
CSTweakRequest(^(NSFetchRequest *fetchRequest) { fetchRequest.fetchLimit = 10; })]];
|
||||
|
||||
XCTAssertNotNil(controller);
|
||||
XCTAssertEqualObjects(controller.fetchRequest.entity.managedObjectClassName, [[TestEntity1 class] description]);
|
||||
XCTAssertEqualObjects(controller.sectionNameKeyPath, CSKeyPath(TestEntity1, testString));
|
||||
XCTAssertEqualObjects(controller.fetchRequest.predicate,
|
||||
CSWhereFormat(@"%K > %d", CSKeyPath(TestEntity1, testEntityID), 100).predicate);
|
||||
XCTAssertEqualObjects(controller.fetchRequest.sortDescriptors,
|
||||
CSOrderByKeys(CSSortAscending(CSKeyPath(TestEntity1, testString)), nil).sortDescriptors);
|
||||
XCTAssertEqual(controller.fetchRequest.fetchLimit, 10);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@end
|
||||
|
||||
@@ -40,8 +40,8 @@ class ConvenienceTests: BaseTestCase {
|
||||
let controller = stack.createFetchedResultsController(
|
||||
From<TestEntity1>(),
|
||||
SectionBy(#keyPath(TestEntity1.testString)),
|
||||
Where("%@ > %d", #keyPath(TestEntity1.testEntityID), 100),
|
||||
OrderBy(.ascending(#keyPath(TestEntity1.testString))),
|
||||
Where<TestEntity1>("%@ > %d", #keyPath(TestEntity1.testEntityID), 100),
|
||||
OrderBy<TestEntity1>(.ascending(#keyPath(TestEntity1.testString))),
|
||||
Tweak { $0.fetchLimit = 10 }
|
||||
)
|
||||
XCTAssertEqual(controller.managedObjectContext, stack.mainContext)
|
||||
@@ -49,11 +49,11 @@ class ConvenienceTests: BaseTestCase {
|
||||
XCTAssertEqual(controller.sectionNameKeyPath, #keyPath(TestEntity1.testString))
|
||||
XCTAssertEqual(
|
||||
controller.fetchRequest.sortDescriptors!,
|
||||
OrderBy(.ascending(#keyPath(TestEntity1.testString))).sortDescriptors
|
||||
OrderBy<TestEntity1>(.ascending(#keyPath(TestEntity1.testString))).sortDescriptors
|
||||
)
|
||||
XCTAssertEqual(
|
||||
controller.fetchRequest.predicate,
|
||||
Where("%@ > %d", #keyPath(TestEntity1.testEntityID), 100).predicate
|
||||
Where<TestEntity1>("%@ > %d", #keyPath(TestEntity1.testEntityID), 100).predicate
|
||||
)
|
||||
XCTAssertEqual(controller.fetchRequest.fetchLimit, 10)
|
||||
}
|
||||
@@ -69,8 +69,8 @@ class ConvenienceTests: BaseTestCase {
|
||||
let controller = transaction.createFetchedResultsController(
|
||||
From<TestEntity1>(),
|
||||
SectionBy(#keyPath(TestEntity1.testString)),
|
||||
Where("%@ > %d", #keyPath(TestEntity1.testEntityID), 100),
|
||||
OrderBy(.ascending(#keyPath(TestEntity1.testString))),
|
||||
Where<TestEntity1>("%@ > %d", #keyPath(TestEntity1.testEntityID), 100),
|
||||
OrderBy<TestEntity1>(.ascending(#keyPath(TestEntity1.testString))),
|
||||
Tweak { $0.fetchLimit = 10 }
|
||||
)
|
||||
XCTAssertEqual(controller.managedObjectContext, transaction.context)
|
||||
@@ -78,11 +78,11 @@ class ConvenienceTests: BaseTestCase {
|
||||
XCTAssertEqual(controller.sectionNameKeyPath, #keyPath(TestEntity1.testString))
|
||||
XCTAssertEqual(
|
||||
controller.fetchRequest.sortDescriptors!,
|
||||
OrderBy(.ascending(#keyPath(TestEntity1.testString))).sortDescriptors
|
||||
OrderBy<TestEntity1>(.ascending(#keyPath(TestEntity1.testString))).sortDescriptors
|
||||
)
|
||||
XCTAssertEqual(
|
||||
controller.fetchRequest.predicate,
|
||||
Where("%@ > %d", #keyPath(TestEntity1.testEntityID), 100).predicate
|
||||
Where<TestEntity1>("%@ > %d", #keyPath(TestEntity1.testEntityID), 100).predicate
|
||||
)
|
||||
XCTAssertEqual(controller.fetchRequest.fetchLimit, 10)
|
||||
}
|
||||
|
||||
@@ -28,32 +28,83 @@ import XCTest
|
||||
@testable
|
||||
import CoreStore
|
||||
|
||||
#if os(OSX)
|
||||
typealias Color = NSColor
|
||||
#else
|
||||
|
||||
typealias Color = UIColor
|
||||
#endif
|
||||
|
||||
class Animal: CoreStoreObject {
|
||||
|
||||
let species = Value.Required<String>("species", default: "Swift")
|
||||
let species = Value.Required<String>("species", initial: "Swift")
|
||||
let master = Relationship.ToOne<Person>("master")
|
||||
let color = Transformable.Optional<UIColor>("color")
|
||||
let color = Transformable.Optional<Color>("color")
|
||||
}
|
||||
|
||||
class Dog: Animal {
|
||||
|
||||
let nickname = Value.Optional<String>("nickname")
|
||||
let age = Value.Required<Int>("age", default: 1)
|
||||
let age = Value.Required<Int>("age", initial: 1)
|
||||
let friends = Relationship.ToManyOrdered<Dog>("friends")
|
||||
let friendedBy = Relationship.ToManyUnordered<Dog>("friendedBy", inverse: { $0.friends })
|
||||
}
|
||||
|
||||
class Person: CoreStoreObject {
|
||||
let title = Value.Required<String>("title", default: "Mr.")
|
||||
|
||||
let title = Value.Required<String>(
|
||||
"title",
|
||||
initial: "Mr.",
|
||||
customSetter: Person.setTitle
|
||||
)
|
||||
|
||||
let name = Value.Required<String>(
|
||||
"name",
|
||||
customGetter: { (`self`, getValue) in
|
||||
|
||||
return "\(self.title.value) \(getValue())"
|
||||
}
|
||||
initial: "",
|
||||
customSetter: Person.setName
|
||||
)
|
||||
|
||||
let displayName = Value.Optional<String>(
|
||||
"displayName",
|
||||
isTransient: true,
|
||||
customGetter: Person.getDisplayName(_:),
|
||||
affectedByKeyPaths: Person.keyPathsAffectingDisplayName()
|
||||
)
|
||||
|
||||
let pets = Relationship.ToManyUnordered<Animal>("pets", inverse: { $0.master })
|
||||
|
||||
private static func setTitle(_ partialObject: PartialObject<Person>, _ newValue: String) {
|
||||
|
||||
partialObject.setPrimitiveValue(newValue, for: { $0.title })
|
||||
partialObject.setPrimitiveValue(nil, for: { $0.displayName })
|
||||
}
|
||||
|
||||
private static func setName(_ partialObject: PartialObject<Person>, _ newValue: String) {
|
||||
|
||||
partialObject.setPrimitiveValue(newValue, for: { $0.name })
|
||||
partialObject.setPrimitiveValue(nil, for: { $0.displayName })
|
||||
}
|
||||
|
||||
static func getDisplayName(_ partialObject: PartialObject<Person>) -> String? {
|
||||
|
||||
if let displayName = partialObject.primitiveValue(for: { $0.displayName }) {
|
||||
|
||||
return displayName
|
||||
}
|
||||
let title = partialObject.value(for: { $0.title })
|
||||
let name = partialObject.value(for: { $0.name })
|
||||
let displayName = "\(title) \(name)"
|
||||
partialObject.setPrimitiveValue(displayName, for: { $0.displayName })
|
||||
return displayName
|
||||
}
|
||||
|
||||
static func keyPathsAffectingDisplayName() -> Set<String> {
|
||||
|
||||
return [
|
||||
String(keyPath: \Person.title),
|
||||
String(keyPath: \Person.name)
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -61,7 +112,8 @@ class Person: CoreStoreObject {
|
||||
|
||||
class DynamicModelTests: BaseTestDataTestCase {
|
||||
|
||||
func testDynamicModels_CanBeDeclaredCorrectly() {
|
||||
@objc
|
||||
dynamic func test_ThatDynamicModels_CanBeDeclaredCorrectly() {
|
||||
|
||||
let dataStack = DataStack(
|
||||
CoreStoreSchema(
|
||||
@@ -80,13 +132,13 @@ class DynamicModelTests: BaseTestDataTestCase {
|
||||
)
|
||||
self.prepareStack(dataStack, configurations: [nil]) { (stack) in
|
||||
|
||||
let k1 = Animal.keyPath({ $0.species })
|
||||
let k1 = String(keyPath: \Animal.species)
|
||||
XCTAssertEqual(k1, "species")
|
||||
|
||||
let k2 = Dog.keyPath({ $0.species })
|
||||
let k2 = String(keyPath: \Dog.species)
|
||||
XCTAssertEqual(k2, "species")
|
||||
|
||||
let k3 = Dog.keyPath({ $0.nickname })
|
||||
let k3 = String(keyPath: \Dog.nickname)
|
||||
XCTAssertEqual(k3, "nickname")
|
||||
|
||||
let updateDone = self.expectation(description: "update-done")
|
||||
@@ -102,7 +154,7 @@ class DynamicModelTests: BaseTestDataTestCase {
|
||||
XCTAssertEqual(animal.species.value, "Sparrow")
|
||||
|
||||
animal.color .= .yellow
|
||||
XCTAssertEqual(animal.color.value, UIColor.yellow)
|
||||
XCTAssertEqual(animal.color.value, Color.yellow)
|
||||
|
||||
let dog = transaction.create(Into<Dog>())
|
||||
XCTAssertEqual(dog.species.value, "Swift")
|
||||
@@ -118,11 +170,25 @@ class DynamicModelTests: BaseTestDataTestCase {
|
||||
let person = transaction.create(Into<Person>())
|
||||
XCTAssertTrue(person.pets.value.isEmpty)
|
||||
|
||||
XCTAssertEqual(
|
||||
type(of: person.rawObject!).keyPathsForValuesAffectingValue(forKey: "displayName"),
|
||||
["title", "name"]
|
||||
)
|
||||
|
||||
person.name .= "Joe"
|
||||
|
||||
XCTAssertEqual(person.rawObject!.value(forKey: "name") as! String?, "Joe")
|
||||
XCTAssertEqual(person.rawObject!.value(forKey: "displayName") as! String?, "Mr. Joe")
|
||||
|
||||
person.rawObject!.setValue("AAAA", forKey: "displayName")
|
||||
XCTAssertEqual(person.rawObject!.value(forKey: "displayName") as! String?, "AAAA")
|
||||
|
||||
person.name .= "John"
|
||||
XCTAssertEqual(person.name.value, "Mr. John") // Custom getter
|
||||
XCTAssertEqual(person.name.value, "John")
|
||||
XCTAssertEqual(person.displayName.value, "Mr. John") // Custom getter
|
||||
|
||||
person.title .= "Sir"
|
||||
XCTAssertEqual(person.name.value, "Sir John")
|
||||
XCTAssertEqual(person.displayName.value, "Sir John")
|
||||
|
||||
person.pets.value.insert(dog)
|
||||
XCTAssertEqual(person.pets.count, 1)
|
||||
@@ -131,7 +197,7 @@ class DynamicModelTests: BaseTestDataTestCase {
|
||||
XCTAssertEqual(dog.master.value, person)
|
||||
XCTAssertEqual(dog.master.value?.pets.value.first, dog)
|
||||
},
|
||||
success: {
|
||||
success: { _ in
|
||||
|
||||
updateDone.fulfill()
|
||||
},
|
||||
@@ -143,17 +209,17 @@ class DynamicModelTests: BaseTestDataTestCase {
|
||||
stack.perform(
|
||||
asynchronous: { (transaction) in
|
||||
|
||||
let p1 = Animal.where({ $0.species == "Sparrow" })
|
||||
let p1 = Where<Animal>({ $0.species == "Sparrow" })
|
||||
XCTAssertEqual(p1.predicate, NSPredicate(format: "%K == %@", "species", "Sparrow"))
|
||||
|
||||
let bird = transaction.fetchOne(From<Animal>(), p1)
|
||||
XCTAssertNotNil(bird)
|
||||
XCTAssertEqual(bird!.species.value, "Sparrow")
|
||||
|
||||
let p2 = Dog.where({ $0.nickname == "Spot" })
|
||||
let p2 = Where<Dog>({ $0.nickname == "Spot" })
|
||||
XCTAssertEqual(p2.predicate, NSPredicate(format: "%K == %@", "nickname", "Spot"))
|
||||
|
||||
let dog = transaction.fetchOne(From<Dog>(), p2)
|
||||
let dog = transaction.fetchOne(From<Dog>().where(\.nickname == "Spot"))
|
||||
XCTAssertNotNil(dog)
|
||||
XCTAssertEqual(dog!.nickname.value, "Spot")
|
||||
XCTAssertEqual(dog!.species.value, "Dog")
|
||||
@@ -162,13 +228,42 @@ class DynamicModelTests: BaseTestDataTestCase {
|
||||
XCTAssertNotNil(person)
|
||||
XCTAssertEqual(person!.pets.value.first, dog)
|
||||
|
||||
let p3 = Dog.where({ $0.age == 10 })
|
||||
let p3 = Where<Dog>({ $0.age == 10 })
|
||||
XCTAssertEqual(p3.predicate, NSPredicate(format: "%K == %d", "age", 10))
|
||||
|
||||
_ = transaction.fetchAll(
|
||||
From<Dog>()
|
||||
.where(\Animal.species == "Dog" && \.age == 10)
|
||||
)
|
||||
_ = transaction.fetchAll(
|
||||
From<Dog>()
|
||||
.where(\.age == 10 && \Animal.species == "Dog")
|
||||
.orderBy(.ascending({ $0.species }))
|
||||
)
|
||||
_ = transaction.fetchAll(
|
||||
From<Dog>(),
|
||||
Where<Dog>({ $0.age > 10 && $0.age <= 15 })
|
||||
)
|
||||
_ = transaction.fetchAll(
|
||||
From<Dog>(),
|
||||
Where<Dog>({ $0.species == "Dog" && $0.age == 10 })
|
||||
)
|
||||
_ = transaction.fetchAll(
|
||||
From<Dog>(),
|
||||
Where<Dog>({ $0.age == 10 && $0.species == "Dog" })
|
||||
)
|
||||
_ = transaction.fetchAll(
|
||||
From<Dog>(),
|
||||
Where<Dog>({ $0.age > 10 && $0.age <= 15 })
|
||||
)
|
||||
_ = transaction.fetchAll(
|
||||
From<Dog>(),
|
||||
(\Dog.age > 10 && \Dog.age <= 15)
|
||||
)
|
||||
},
|
||||
success: {
|
||||
success: { _ in
|
||||
|
||||
fetchDone.fulfill()
|
||||
withExtendedLifetime(stack, {})
|
||||
},
|
||||
failure: { _ in
|
||||
|
||||
@@ -179,6 +274,13 @@ class DynamicModelTests: BaseTestDataTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
dynamic func test_ThatDynamicModelKeyPaths_CanBeCreated() {
|
||||
|
||||
XCTAssertEqual(String(keyPath: \Animal.species), "species")
|
||||
XCTAssertEqual(String(keyPath: \Dog.species), "species")
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
func prepareStack(_ dataStack: DataStack, configurations: [ModelConfiguration] = [nil], _ closure: (_ dataStack: DataStack) -> Void) {
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -38,14 +38,14 @@ final class GroupByTests: BaseTestCase {
|
||||
|
||||
do {
|
||||
|
||||
let groupBy = GroupBy()
|
||||
let groupBy = GroupBy<NSManagedObject>()
|
||||
XCTAssertEqual(groupBy, GroupBy([] as [String]))
|
||||
XCTAssertNotEqual(groupBy, GroupBy("key"))
|
||||
XCTAssertTrue(groupBy.keyPaths.isEmpty)
|
||||
}
|
||||
do {
|
||||
|
||||
let groupBy = GroupBy("key1")
|
||||
let groupBy = GroupBy<NSManagedObject>("key1")
|
||||
XCTAssertEqual(groupBy, GroupBy("key1"))
|
||||
XCTAssertEqual(groupBy, GroupBy(["key1"]))
|
||||
XCTAssertNotEqual(groupBy, GroupBy("key2"))
|
||||
@@ -53,7 +53,7 @@ final class GroupByTests: BaseTestCase {
|
||||
}
|
||||
do {
|
||||
|
||||
let groupBy = GroupBy("key1", "key2")
|
||||
let groupBy = GroupBy<NSManagedObject>("key1", "key2")
|
||||
XCTAssertEqual(groupBy, GroupBy("key1", "key2"))
|
||||
XCTAssertEqual(groupBy, GroupBy(["key1", "key2"]))
|
||||
XCTAssertNotEqual(groupBy, GroupBy("key2", "key1"))
|
||||
@@ -66,7 +66,7 @@ final class GroupByTests: BaseTestCase {
|
||||
|
||||
self.prepareStack { (dataStack) in
|
||||
|
||||
let groupBy = GroupBy(#keyPath(TestEntity1.testString))
|
||||
let groupBy = GroupBy<NSManagedObject>(#keyPath(TestEntity1.testString))
|
||||
|
||||
let request = CoreStoreFetchRequest()
|
||||
_ = From<TestEntity1>().applyToFetchRequest(request, context: dataStack.mainContext)
|
||||
|
||||
@@ -36,33 +36,33 @@ class ImportTests: BaseTestDataTestCase {
|
||||
@objc
|
||||
dynamic func test_ThatAttributeProtocols_BehaveCorrectly() {
|
||||
|
||||
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSNumber(value: true))?.boolValue, true)
|
||||
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSNumber(value: Int16.max))?.int16Value, Int16.max)
|
||||
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSNumber(value: Int32.max))?.int32Value, Int32.max)
|
||||
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSNumber(value: Int64.max))?.int64Value, Int64.max)
|
||||
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSNumber(value: MAXFLOAT))?.floatValue, MAXFLOAT)
|
||||
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSNumber(value: Double(MAXFLOAT)))?.doubleValue, Double(MAXFLOAT))
|
||||
XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSNumber(value: true))?.boolValue, true)
|
||||
XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSNumber(value: Int16.max))?.int16Value, Int16.max)
|
||||
XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSNumber(value: Int32.max))?.int32Value, Int32.max)
|
||||
XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSNumber(value: Int64.max))?.int64Value, Int64.max)
|
||||
XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSNumber(value: MAXFLOAT))?.floatValue, MAXFLOAT)
|
||||
XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSNumber(value: Double(MAXFLOAT)))?.doubleValue, Double(MAXFLOAT))
|
||||
|
||||
XCTAssertEqual(NSDecimalNumber.cs_fromImportableNativeType(NSDecimalNumber(string: "1"))?.boolValue, true)
|
||||
XCTAssertEqual(NSDecimalNumber.cs_fromImportableNativeType(NSDecimalNumber(string: Int16.max.description))?.int16Value, Int16.max)
|
||||
XCTAssertEqual(NSDecimalNumber.cs_fromImportableNativeType(NSDecimalNumber(string: Int32.max.description))?.int32Value, Int32.max)
|
||||
XCTAssertEqual(NSDecimalNumber.cs_fromImportableNativeType(NSDecimalNumber(string: Int64.max.description))?.int64Value, Int64.max)
|
||||
XCTAssertEqual(NSDecimalNumber.cs_fromImportableNativeType(NSDecimalNumber(string: MAXFLOAT.description))?.doubleValue, NSDecimalNumber(string: MAXFLOAT.description).doubleValue)
|
||||
XCTAssertEqual(NSDecimalNumber.cs_fromImportableNativeType(NSDecimalNumber(string: MAXFLOAT.description))?.floatValue, NSDecimalNumber(string: MAXFLOAT.description).floatValue)
|
||||
XCTAssertEqual(NSDecimalNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: "1"))?.boolValue, true)
|
||||
XCTAssertEqual(NSDecimalNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: Int16.max.description))?.int16Value, Int16.max)
|
||||
XCTAssertEqual(NSDecimalNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: Int32.max.description))?.int32Value, Int32.max)
|
||||
XCTAssertEqual(NSDecimalNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: Int64.max.description))?.int64Value, Int64.max)
|
||||
XCTAssertEqual(NSDecimalNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: MAXFLOAT.description))?.doubleValue, NSDecimalNumber(string: MAXFLOAT.description).doubleValue)
|
||||
XCTAssertEqual(NSDecimalNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: MAXFLOAT.description))?.floatValue, NSDecimalNumber(string: MAXFLOAT.description).floatValue)
|
||||
|
||||
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSDecimalNumber(string: "1"))?.boolValue, true)
|
||||
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSDecimalNumber(string: Int16.max.description))?.int16Value, Int16.max)
|
||||
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSDecimalNumber(string: Int32.max.description))?.int32Value, Int32.max)
|
||||
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSDecimalNumber(string: Int64.max.description))?.int64Value, Int64.max)
|
||||
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSDecimalNumber(string: MAXFLOAT.description))?.doubleValue, NSDecimalNumber(string: MAXFLOAT.description).doubleValue)
|
||||
XCTAssertEqual(NSNumber.cs_fromImportableNativeType(NSDecimalNumber(string: MAXFLOAT.description))?.floatValue, NSDecimalNumber(string: MAXFLOAT.description).floatValue)
|
||||
XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: "1"))?.boolValue, true)
|
||||
XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: Int16.max.description))?.int16Value, Int16.max)
|
||||
XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: Int32.max.description))?.int32Value, Int32.max)
|
||||
XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: Int64.max.description))?.int64Value, Int64.max)
|
||||
XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: MAXFLOAT.description))?.doubleValue, NSDecimalNumber(string: MAXFLOAT.description).doubleValue)
|
||||
XCTAssertEqual(NSNumber.cs_fromQueryableNativeType(NSDecimalNumber(string: MAXFLOAT.description))?.floatValue, NSDecimalNumber(string: MAXFLOAT.description).floatValue)
|
||||
|
||||
XCTAssertNil(NSDecimalNumber.cs_fromImportableNativeType(NSNumber(value: true)))
|
||||
XCTAssertNil(NSDecimalNumber.cs_fromImportableNativeType(NSNumber(value: Int16.max)))
|
||||
XCTAssertNil(NSDecimalNumber.cs_fromImportableNativeType(NSNumber(value: Int32.max)))
|
||||
XCTAssertNil(NSDecimalNumber.cs_fromImportableNativeType(NSNumber(value: Int64.max)))
|
||||
XCTAssertNil(NSDecimalNumber.cs_fromImportableNativeType(NSNumber(value: MAXFLOAT)))
|
||||
XCTAssertNil(NSDecimalNumber.cs_fromImportableNativeType(NSNumber(value: Double(MAXFLOAT))))
|
||||
XCTAssertNil(NSDecimalNumber.cs_fromQueryableNativeType(NSNumber(value: true)))
|
||||
XCTAssertNil(NSDecimalNumber.cs_fromQueryableNativeType(NSNumber(value: Int16.max)))
|
||||
XCTAssertNil(NSDecimalNumber.cs_fromQueryableNativeType(NSNumber(value: Int32.max)))
|
||||
XCTAssertNil(NSDecimalNumber.cs_fromQueryableNativeType(NSNumber(value: Int64.max)))
|
||||
XCTAssertNil(NSDecimalNumber.cs_fromQueryableNativeType(NSNumber(value: MAXFLOAT)))
|
||||
XCTAssertNil(NSDecimalNumber.cs_fromQueryableNativeType(NSNumber(value: Double(MAXFLOAT))))
|
||||
|
||||
XCTAssertEqual(true.cs_toQueryableNativeType(), NSNumber(value: true))
|
||||
XCTAssertEqual(Int16.max.cs_toQueryableNativeType(), NSNumber(value: Int16.max))
|
||||
@@ -444,7 +444,7 @@ class ImportTests: BaseTestDataTestCase {
|
||||
XCTAssertNil(object)
|
||||
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 5)
|
||||
|
||||
let existingObjects = transaction.fetchAll(From<TestEntity1>(), Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 105))
|
||||
let existingObjects = transaction.fetchAll(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 105))
|
||||
XCTAssertNotNil(existingObjects)
|
||||
XCTAssertEqual(existingObjects?.count, 1)
|
||||
|
||||
@@ -565,7 +565,9 @@ class ImportTests: BaseTestDataTestCase {
|
||||
XCTAssertEqual(objects.count, 2)
|
||||
|
||||
zip(objects, sourceArray)
|
||||
.forEach { object, dictionary in
|
||||
.forEach {
|
||||
|
||||
let (object, dictionary) = $0
|
||||
XCTAssertEqual(object.testEntityID, dictionary[(#keyPath(TestEntity1.testEntityID))] as? NSNumber)
|
||||
XCTAssertEqual(object.testBoolean, dictionary[(#keyPath(TestEntity1.testBoolean))] as? NSNumber)
|
||||
XCTAssertEqual(object.testNumber, dictionary[(#keyPath(TestEntity1.testNumber))] as? NSNumber)
|
||||
@@ -618,7 +620,7 @@ class ImportTests: BaseTestDataTestCase {
|
||||
errorExpectation.fulfill()
|
||||
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 6)
|
||||
|
||||
let object = transaction.fetchOne(From<TestEntity1>(), Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 106))
|
||||
let object = transaction.fetchOne(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 106))
|
||||
XCTAssertNotNil(object)
|
||||
XCTAssertEqual(object?.testEntityID, NSNumber(value: 106))
|
||||
XCTAssertNil(object?.testBoolean)
|
||||
@@ -657,7 +659,7 @@ class ImportTests: BaseTestDataTestCase {
|
||||
errorExpectation.fulfill()
|
||||
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 6)
|
||||
|
||||
let existingObjects = transaction.fetchAll(From<TestEntity1>(), Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 105))
|
||||
let existingObjects = transaction.fetchAll(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 105))
|
||||
XCTAssertNotNil(existingObjects)
|
||||
XCTAssertEqual(existingObjects?.count, 1)
|
||||
|
||||
@@ -743,7 +745,7 @@ class ImportTests: BaseTestDataTestCase {
|
||||
XCTAssertEqual(object?.testData, ("nil:TestEntity1:7" as NSString).data(using: String.Encoding.utf8.rawValue)!)
|
||||
XCTAssertEqual(object?.testDate, self.dateFormatter.date(from: "2000-01-07T00:00:00Z")!)
|
||||
|
||||
let existingObjects = transaction.fetchAll(From<TestEntity1>(), Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 106))
|
||||
let existingObjects = transaction.fetchAll(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 106))
|
||||
XCTAssertNotNil(existingObjects)
|
||||
XCTAssertEqual(existingObjects?.count, 1)
|
||||
|
||||
@@ -864,8 +866,8 @@ class ImportTests: BaseTestDataTestCase {
|
||||
errorExpectation.fulfill()
|
||||
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 5)
|
||||
|
||||
XCTAssertNil(transaction.fetchOne(From<TestEntity1>(), Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 106)))
|
||||
XCTAssertNil(transaction.fetchOne(From<TestEntity1>(), Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 107)))
|
||||
XCTAssertNil(transaction.fetchOne(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 106)))
|
||||
XCTAssertNil(transaction.fetchOne(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 107)))
|
||||
}
|
||||
transaction.unsafeContext().reset()
|
||||
self.checkExpectationsImmediately()
|
||||
@@ -908,7 +910,7 @@ class ImportTests: BaseTestDataTestCase {
|
||||
|
||||
errorExpectation.fulfill()
|
||||
|
||||
let object = transaction.fetchOne(From<TestEntity1>(), Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 106))
|
||||
let object = transaction.fetchOne(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 106))
|
||||
XCTAssertNotNil(object)
|
||||
XCTAssertEqual(object?.testEntityID, NSNumber(value: 106))
|
||||
XCTAssertNil(object?.testBoolean)
|
||||
@@ -951,7 +953,7 @@ class ImportTests: BaseTestDataTestCase {
|
||||
errorExpectation.fulfill()
|
||||
XCTAssertEqual(transaction.fetchCount(From<TestEntity1>()), 5)
|
||||
|
||||
let object = transaction.fetchOne(From<TestEntity1>(), Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 105))
|
||||
let object = transaction.fetchOne(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 105))
|
||||
XCTAssertNotNil(object)
|
||||
XCTAssertEqual(object?.testEntityID, NSNumber(value: 105))
|
||||
XCTAssertEqual(object?.testBoolean, NSNumber(value: true))
|
||||
@@ -961,7 +963,7 @@ class ImportTests: BaseTestDataTestCase {
|
||||
XCTAssertEqual(object?.testData, ("nil:TestEntity1:5" as NSString).data(using: String.Encoding.utf8.rawValue)!)
|
||||
XCTAssertEqual(object?.testDate, self.dateFormatter.date(from: "2000-01-05T00:00:00Z")!)
|
||||
|
||||
let existingObjects = transaction.fetchAll(From<TestEntity1>(), Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 105))
|
||||
let existingObjects = transaction.fetchAll(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 105))
|
||||
XCTAssertNotNil(existingObjects)
|
||||
XCTAssertEqual(existingObjects?.count, 1)
|
||||
|
||||
@@ -1030,7 +1032,7 @@ class ImportTests: BaseTestDataTestCase {
|
||||
XCTAssertEqual(object.testData, dictionary[(#keyPath(TestEntity1.testData))] as? Data)
|
||||
XCTAssertEqual(object.testDate, dictionary[(#keyPath(TestEntity1.testDate))] as? Date)
|
||||
}
|
||||
let existingObjects = transaction.fetchAll(From<TestEntity1>(), Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 105))
|
||||
let existingObjects = transaction.fetchAll(From<TestEntity1>(), Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 105))
|
||||
XCTAssertNotNil(existingObjects)
|
||||
XCTAssertEqual(existingObjects?.count, 1)
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>BNDL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<string>5.1.1</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
|
||||
@@ -43,7 +43,7 @@ class ListObserverTests: BaseTestDataTestCase {
|
||||
let monitor = stack.monitorSectionedList(
|
||||
From<TestEntity1>(),
|
||||
SectionBy(#keyPath(TestEntity1.testBoolean)),
|
||||
OrderBy(.ascending(#keyPath(TestEntity1.testBoolean)), .ascending(#keyPath(TestEntity1.testEntityID)))
|
||||
OrderBy<TestEntity1>(.ascending(#keyPath(TestEntity1.testBoolean)), .ascending(#keyPath(TestEntity1.testEntityID)))
|
||||
)
|
||||
monitor.addObserver(observer)
|
||||
|
||||
@@ -54,7 +54,7 @@ class ListObserverTests: BaseTestDataTestCase {
|
||||
var events = 0
|
||||
|
||||
let willChangeExpectation = self.expectation(
|
||||
forNotification: "listMonitorWillChange:",
|
||||
forNotification: NSNotification.Name(rawValue: "listMonitorWillChange:"),
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
@@ -68,7 +68,7 @@ class ListObserverTests: BaseTestDataTestCase {
|
||||
}
|
||||
)
|
||||
let didInsertSectionExpectation = self.expectation(
|
||||
forNotification: "listMonitor:didInsertSection:toSectionIndex:",
|
||||
forNotification: NSNotification.Name(rawValue: "listMonitor:didInsertSection:toSectionIndex:"),
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
@@ -88,7 +88,7 @@ class ListObserverTests: BaseTestDataTestCase {
|
||||
}
|
||||
)
|
||||
let didInsertObjectExpectation = self.expectation(
|
||||
forNotification: "listMonitor:didInsertObject:toIndexPath:",
|
||||
forNotification: NSNotification.Name(rawValue: "listMonitor:didInsertObject:toIndexPath:"),
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
@@ -120,7 +120,7 @@ class ListObserverTests: BaseTestDataTestCase {
|
||||
}
|
||||
)
|
||||
let didChangeExpectation = self.expectation(
|
||||
forNotification: "listMonitorDidChange:",
|
||||
forNotification: NSNotification.Name(rawValue: "listMonitorDidChange:"),
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
@@ -171,7 +171,7 @@ class ListObserverTests: BaseTestDataTestCase {
|
||||
let monitor = stack.monitorSectionedList(
|
||||
From<TestEntity1>(),
|
||||
SectionBy(#keyPath(TestEntity1.testBoolean)),
|
||||
OrderBy(.ascending(#keyPath(TestEntity1.testBoolean)), .ascending(#keyPath(TestEntity1.testEntityID)))
|
||||
OrderBy<TestEntity1>(.ascending(#keyPath(TestEntity1.testBoolean)), .ascending(#keyPath(TestEntity1.testEntityID)))
|
||||
)
|
||||
monitor.addObserver(observer)
|
||||
|
||||
@@ -185,7 +185,7 @@ class ListObserverTests: BaseTestDataTestCase {
|
||||
var events = 0
|
||||
|
||||
let willChangeExpectation = self.expectation(
|
||||
forNotification: "listMonitorWillChange:",
|
||||
forNotification: NSNotification.Name(rawValue: "listMonitorWillChange:"),
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
@@ -198,62 +198,60 @@ class ListObserverTests: BaseTestDataTestCase {
|
||||
return events == 0
|
||||
}
|
||||
)
|
||||
for _ in 1 ... 2 {
|
||||
|
||||
let didUpdateObjectExpectation = self.expectation(
|
||||
forNotification: "listMonitor:didUpdateObject:atIndexPath:",
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
let didUpdateObjectExpectation = self.expectation(
|
||||
forNotification: NSNotification.Name(rawValue: "listMonitor:didUpdateObject:atIndexPath:"),
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
XCTAssert(events == 1 || events == 2)
|
||||
|
||||
let userInfo = note.userInfo
|
||||
XCTAssertNotNil(userInfo)
|
||||
XCTAssertEqual(
|
||||
Set(userInfo?.keys.map({ $0 as! String }) ?? []),
|
||||
["indexPath", "object"]
|
||||
)
|
||||
|
||||
let indexPath = userInfo?["indexPath"] as? NSIndexPath
|
||||
let object = userInfo?["object"] as? TestEntity1
|
||||
|
||||
switch object?.testEntityID {
|
||||
|
||||
XCTAssert(events == 1 || events == 2)
|
||||
case NSNumber(value: 101)?:
|
||||
XCTAssertEqual(indexPath?.index(atPosition: 0), 1)
|
||||
XCTAssertEqual(indexPath?.index(atPosition: 1), 0)
|
||||
|
||||
let userInfo = note.userInfo
|
||||
XCTAssertNotNil(userInfo)
|
||||
XCTAssertEqual(
|
||||
Set(userInfo?.keys.map({ $0 as! String }) ?? []),
|
||||
["indexPath", "object"]
|
||||
)
|
||||
XCTAssertEqual(object?.testBoolean, NSNumber(value: true))
|
||||
XCTAssertEqual(object?.testNumber, NSNumber(value: 11))
|
||||
XCTAssertEqual(object?.testDecimal, NSDecimalNumber(string: "11"))
|
||||
XCTAssertEqual(object?.testString, "nil:TestEntity1:11")
|
||||
XCTAssertEqual(object?.testData, ("nil:TestEntity1:11" as NSString).data(using: String.Encoding.utf8.rawValue)!)
|
||||
XCTAssertEqual(object?.testDate, self.dateFormatter.date(from: "2000-01-11T00:00:00Z")!)
|
||||
|
||||
let indexPath = userInfo?["indexPath"] as? NSIndexPath
|
||||
let object = userInfo?["object"] as? TestEntity1
|
||||
case NSNumber(value: 102)?:
|
||||
XCTAssertEqual(indexPath?.index(atPosition: 0), 0)
|
||||
XCTAssertEqual(indexPath?.index(atPosition: 1), 0)
|
||||
|
||||
switch object?.testEntityID {
|
||||
|
||||
case NSNumber(value: 101)?:
|
||||
XCTAssertEqual(indexPath?.index(atPosition: 0), 1)
|
||||
XCTAssertEqual(indexPath?.index(atPosition: 1), 0)
|
||||
|
||||
XCTAssertEqual(object?.testBoolean, NSNumber(value: true))
|
||||
XCTAssertEqual(object?.testNumber, NSNumber(value: 11))
|
||||
XCTAssertEqual(object?.testDecimal, NSDecimalNumber(string: "11"))
|
||||
XCTAssertEqual(object?.testString, "nil:TestEntity1:11")
|
||||
XCTAssertEqual(object?.testData, ("nil:TestEntity1:11" as NSString).data(using: String.Encoding.utf8.rawValue)!)
|
||||
XCTAssertEqual(object?.testDate, self.dateFormatter.date(from: "2000-01-11T00:00:00Z")!)
|
||||
|
||||
case NSNumber(value: 102)?:
|
||||
XCTAssertEqual(indexPath?.index(atPosition: 0), 0)
|
||||
XCTAssertEqual(indexPath?.index(atPosition: 1), 0)
|
||||
|
||||
XCTAssertEqual(object?.testBoolean, NSNumber(value: false))
|
||||
XCTAssertEqual(object?.testNumber, NSNumber(value: 22))
|
||||
XCTAssertEqual(object?.testDecimal, NSDecimalNumber(string: "22"))
|
||||
XCTAssertEqual(object?.testString, "nil:TestEntity1:22")
|
||||
XCTAssertEqual(object?.testData, ("nil:TestEntity1:22" as NSString).data(using: String.Encoding.utf8.rawValue)!)
|
||||
XCTAssertEqual(object?.testDate, self.dateFormatter.date(from: "2000-01-22T00:00:00Z")!)
|
||||
|
||||
default:
|
||||
XCTFail()
|
||||
}
|
||||
defer {
|
||||
|
||||
events += 1
|
||||
}
|
||||
return events == 1 || events == 2
|
||||
XCTAssertEqual(object?.testBoolean, NSNumber(value: false))
|
||||
XCTAssertEqual(object?.testNumber, NSNumber(value: 22))
|
||||
XCTAssertEqual(object?.testDecimal, NSDecimalNumber(string: "22"))
|
||||
XCTAssertEqual(object?.testString, "nil:TestEntity1:22")
|
||||
XCTAssertEqual(object?.testData, ("nil:TestEntity1:22" as NSString).data(using: String.Encoding.utf8.rawValue)!)
|
||||
XCTAssertEqual(object?.testDate, self.dateFormatter.date(from: "2000-01-22T00:00:00Z")!)
|
||||
|
||||
default:
|
||||
XCTFail()
|
||||
}
|
||||
)
|
||||
}
|
||||
defer {
|
||||
|
||||
events += 1
|
||||
}
|
||||
return events == 1 || events == 2
|
||||
}
|
||||
)
|
||||
let didChangeExpectation = self.expectation(
|
||||
forNotification: "listMonitorDidChange:",
|
||||
forNotification: NSNotification.Name(rawValue: "listMonitorDidChange:"),
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
@@ -272,7 +270,7 @@ class ListObserverTests: BaseTestDataTestCase {
|
||||
|
||||
if let object = transaction.fetchOne(
|
||||
From<TestEntity1>(),
|
||||
Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 101)) {
|
||||
Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 101)) {
|
||||
|
||||
object.testNumber = NSNumber(value: 11)
|
||||
object.testDecimal = NSDecimalNumber(string: "11")
|
||||
@@ -286,7 +284,7 @@ class ListObserverTests: BaseTestDataTestCase {
|
||||
}
|
||||
if let object = transaction.fetchOne(
|
||||
From<TestEntity1>(),
|
||||
Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 102)) {
|
||||
Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 102)) {
|
||||
|
||||
object.testNumber = NSNumber(value: 22)
|
||||
object.testDecimal = NSDecimalNumber(string: "22")
|
||||
@@ -325,14 +323,14 @@ class ListObserverTests: BaseTestDataTestCase {
|
||||
let monitor = stack.monitorSectionedList(
|
||||
From<TestEntity1>(),
|
||||
SectionBy(#keyPath(TestEntity1.testBoolean)),
|
||||
OrderBy(.ascending(#keyPath(TestEntity1.testBoolean)), .ascending(#keyPath(TestEntity1.testEntityID)))
|
||||
OrderBy<TestEntity1>(.ascending(#keyPath(TestEntity1.testBoolean)), .ascending(#keyPath(TestEntity1.testEntityID)))
|
||||
)
|
||||
monitor.addObserver(observer)
|
||||
|
||||
var events = 0
|
||||
|
||||
let willChangeExpectation = self.expectation(
|
||||
forNotification: "listMonitorWillChange:",
|
||||
forNotification: NSNotification.Name(rawValue: "listMonitorWillChange:"),
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
@@ -346,7 +344,7 @@ class ListObserverTests: BaseTestDataTestCase {
|
||||
}
|
||||
)
|
||||
let didMoveObjectExpectation = self.expectation(
|
||||
forNotification: "listMonitor:didMoveObject:fromIndexPath:toIndexPath:",
|
||||
forNotification: NSNotification.Name(rawValue: "listMonitor:didMoveObject:fromIndexPath:toIndexPath:"),
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
@@ -379,7 +377,7 @@ class ListObserverTests: BaseTestDataTestCase {
|
||||
}
|
||||
)
|
||||
let didChangeExpectation = self.expectation(
|
||||
forNotification: "listMonitorDidChange:",
|
||||
forNotification: NSNotification.Name(rawValue: "listMonitorDidChange:"),
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
@@ -398,7 +396,7 @@ class ListObserverTests: BaseTestDataTestCase {
|
||||
|
||||
if let object = transaction.fetchOne(
|
||||
From<TestEntity1>(),
|
||||
Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 102)) {
|
||||
Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 102)) {
|
||||
|
||||
object.testBoolean = NSNumber(value: true)
|
||||
}
|
||||
@@ -433,14 +431,14 @@ class ListObserverTests: BaseTestDataTestCase {
|
||||
let monitor = stack.monitorSectionedList(
|
||||
From<TestEntity1>(),
|
||||
SectionBy(#keyPath(TestEntity1.testBoolean)),
|
||||
OrderBy(.ascending(#keyPath(TestEntity1.testBoolean)), .ascending(#keyPath(TestEntity1.testEntityID)))
|
||||
OrderBy<TestEntity1>(.ascending(#keyPath(TestEntity1.testBoolean)), .ascending(#keyPath(TestEntity1.testEntityID)))
|
||||
)
|
||||
monitor.addObserver(observer)
|
||||
|
||||
var events = 0
|
||||
|
||||
let willChangeExpectation = self.expectation(
|
||||
forNotification: "listMonitorWillChange:",
|
||||
forNotification: NSNotification.Name(rawValue: "listMonitorWillChange:"),
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
@@ -453,40 +451,37 @@ class ListObserverTests: BaseTestDataTestCase {
|
||||
return events == 0
|
||||
}
|
||||
)
|
||||
for _ in 1 ... 2 {
|
||||
|
||||
let didUpdateObjectExpectation = self.expectation(
|
||||
forNotification: "listMonitor:didDeleteObject:fromIndexPath:",
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
let didUpdateObjectExpectation = self.expectation(
|
||||
forNotification: NSNotification.Name(rawValue: "listMonitor:didDeleteObject:fromIndexPath:"),
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
XCTAssert(events == 1 || events == 2)
|
||||
|
||||
let userInfo = note.userInfo
|
||||
XCTAssertNotNil(userInfo)
|
||||
XCTAssertEqual(
|
||||
Set(userInfo?.keys.map({ $0 as! String }) ?? []),
|
||||
["indexPath", "object"]
|
||||
)
|
||||
|
||||
let indexPath = userInfo?["indexPath"] as? NSIndexPath
|
||||
|
||||
XCTAssertEqual(indexPath?.section, 0)
|
||||
XCTAssert(indexPath?.index(atPosition: 1) == 0 || indexPath?.index(atPosition: 1) == 1)
|
||||
|
||||
let object = userInfo?["object"] as? TestEntity1
|
||||
XCTAssertEqual(object?.isDeleted, true)
|
||||
|
||||
defer {
|
||||
|
||||
XCTAssert(events == 1 || events == 2)
|
||||
|
||||
let userInfo = note.userInfo
|
||||
XCTAssertNotNil(userInfo)
|
||||
XCTAssertEqual(
|
||||
Set(userInfo?.keys.map({ $0 as! String }) ?? []),
|
||||
["indexPath", "object"]
|
||||
)
|
||||
|
||||
let indexPath = userInfo?["indexPath"] as? NSIndexPath
|
||||
|
||||
XCTAssertEqual(indexPath?.section, 0)
|
||||
XCTAssert(indexPath?.index(atPosition: 1) == 0 || indexPath?.index(atPosition: 1) == 1)
|
||||
|
||||
let object = userInfo?["object"] as? TestEntity1
|
||||
XCTAssertEqual(object?.isDeleted, true)
|
||||
|
||||
defer {
|
||||
|
||||
events += 1
|
||||
}
|
||||
return events == 1 || events == 2
|
||||
events += 1
|
||||
}
|
||||
)
|
||||
}
|
||||
return events == 1 || events == 2
|
||||
}
|
||||
)
|
||||
let didDeleteSectionExpectation = self.expectation(
|
||||
forNotification: "listMonitor:didDeleteSection:fromSectionIndex:",
|
||||
forNotification: NSNotification.Name(rawValue: "listMonitor:didDeleteSection:fromSectionIndex:"),
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
@@ -514,7 +509,7 @@ class ListObserverTests: BaseTestDataTestCase {
|
||||
}
|
||||
)
|
||||
let didChangeExpectation = self.expectation(
|
||||
forNotification: "listMonitorDidChange:",
|
||||
forNotification: NSNotification.Name(rawValue: "listMonitorDidChange:"),
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
@@ -531,10 +526,11 @@ class ListObserverTests: BaseTestDataTestCase {
|
||||
stack.perform(
|
||||
asynchronous: { (transaction) -> Bool in
|
||||
|
||||
transaction.deleteAll(
|
||||
let count = transaction.deleteAll(
|
||||
From<TestEntity1>(),
|
||||
Where(#keyPath(TestEntity1.testBoolean), isEqualTo: false)
|
||||
Where<TestEntity1>(#keyPath(TestEntity1.testBoolean), isEqualTo: false)
|
||||
)
|
||||
XCTAssertEqual(count, 2)
|
||||
return transaction.hasChanges
|
||||
},
|
||||
success: { (hasChanges) in
|
||||
|
||||
@@ -43,7 +43,7 @@ class ObjectObserverTests: BaseTestDataTestCase {
|
||||
|
||||
guard let object = stack.fetchOne(
|
||||
From<TestEntity1>(),
|
||||
Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 101)) else {
|
||||
Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 101)) else {
|
||||
|
||||
XCTFail()
|
||||
return
|
||||
@@ -58,7 +58,7 @@ class ObjectObserverTests: BaseTestDataTestCase {
|
||||
var events = 0
|
||||
|
||||
let willUpdateExpectation = self.expectation(
|
||||
forNotification: "objectMonitor:willUpdateObject:",
|
||||
forNotification: NSNotification.Name(rawValue: "objectMonitor:willUpdateObject:"),
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
@@ -75,7 +75,7 @@ class ObjectObserverTests: BaseTestDataTestCase {
|
||||
}
|
||||
)
|
||||
let didUpdateExpectation = self.expectation(
|
||||
forNotification: "objectMonitor:didUpdateObject:changedPersistentKeys:",
|
||||
forNotification: NSNotification.Name(rawValue: "objectMonitor:didUpdateObject:changedPersistentKeys:"),
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
@@ -140,7 +140,7 @@ class ObjectObserverTests: BaseTestDataTestCase {
|
||||
|
||||
guard let object = stack.fetchOne(
|
||||
From<TestEntity1>(),
|
||||
Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 101)) else {
|
||||
Where<TestEntity1>(#keyPath(TestEntity1.testEntityID), isEqualTo: 101)) else {
|
||||
|
||||
XCTFail()
|
||||
return
|
||||
@@ -155,7 +155,7 @@ class ObjectObserverTests: BaseTestDataTestCase {
|
||||
var events = 0
|
||||
|
||||
let didDeleteExpectation = self.expectation(
|
||||
forNotification: "objectMonitor:didDeleteObject:",
|
||||
forNotification: NSNotification.Name(rawValue: "objectMonitor:didDeleteObject:"),
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
@@ -219,7 +219,7 @@ class TestObjectObserver: ObjectObserver {
|
||||
)
|
||||
}
|
||||
|
||||
func objectMonitor(_ monitor: ObjectMonitor<TestEntity1>, didUpdateObject object: TestEntity1, changedPersistentKeys: Set<KeyPath>) {
|
||||
func objectMonitor(_ monitor: ObjectMonitor<TestEntity1>, didUpdateObject object: TestEntity1, changedPersistentKeys: Set<String>) {
|
||||
|
||||
NotificationCenter.default.post(
|
||||
name: NSNotification.Name(rawValue: "objectMonitor:didUpdateObject:changedPersistentKeys:"),
|
||||
|
||||
@@ -38,21 +38,21 @@ final class OrderByTests: XCTestCase {
|
||||
|
||||
do {
|
||||
|
||||
let orderBy = OrderBy()
|
||||
XCTAssertEqual(orderBy, OrderBy([NSSortDescriptor]()))
|
||||
XCTAssertNotEqual(orderBy, OrderBy(NSSortDescriptor(key: "key", ascending: false)))
|
||||
let orderBy = OrderBy<NSManagedObject>()
|
||||
XCTAssertEqual(orderBy, OrderBy<NSManagedObject>([NSSortDescriptor]()))
|
||||
XCTAssertNotEqual(orderBy, OrderBy<NSManagedObject>(NSSortDescriptor(key: "key", ascending: false)))
|
||||
XCTAssertTrue(orderBy.sortDescriptors.isEmpty)
|
||||
}
|
||||
do {
|
||||
|
||||
let sortDescriptor = NSSortDescriptor(key: "key1", ascending: true)
|
||||
let orderBy = OrderBy(sortDescriptor)
|
||||
let orderBy = OrderBy<NSManagedObject>(sortDescriptor)
|
||||
XCTAssertEqual(orderBy, OrderBy(sortDescriptor))
|
||||
XCTAssertEqual(orderBy, OrderBy(.ascending("key1")))
|
||||
XCTAssertNotEqual(orderBy, OrderBy(.ascending("key2")))
|
||||
XCTAssertNotEqual(orderBy, OrderBy(.descending("key1")))
|
||||
XCTAssertNotEqual(orderBy, OrderBy(NSSortDescriptor(key: "key1", ascending: false)))
|
||||
XCTAssertEqual(orderBy, OrderBy([sortDescriptor]))
|
||||
XCTAssertEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key1")))
|
||||
XCTAssertNotEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key2")))
|
||||
XCTAssertNotEqual(orderBy, OrderBy<NSManagedObject>(.descending("key1")))
|
||||
XCTAssertNotEqual(orderBy, OrderBy<NSManagedObject>(NSSortDescriptor(key: "key1", ascending: false)))
|
||||
XCTAssertEqual(orderBy, OrderBy<NSManagedObject>([sortDescriptor]))
|
||||
XCTAssertEqual(orderBy.sortDescriptors, [sortDescriptor])
|
||||
}
|
||||
do {
|
||||
@@ -61,76 +61,76 @@ final class OrderByTests: XCTestCase {
|
||||
NSSortDescriptor(key: "key1", ascending: true),
|
||||
NSSortDescriptor(key: "key2", ascending: false)
|
||||
]
|
||||
let orderBy = OrderBy(sortDescriptors)
|
||||
XCTAssertEqual(orderBy, OrderBy(sortDescriptors))
|
||||
XCTAssertEqual(orderBy, OrderBy(.ascending("key1"), .descending("key2")))
|
||||
let orderBy = OrderBy<NSManagedObject>(sortDescriptors)
|
||||
XCTAssertEqual(orderBy, OrderBy<NSManagedObject>(sortDescriptors))
|
||||
XCTAssertEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key1"), .descending("key2")))
|
||||
XCTAssertNotEqual(
|
||||
orderBy,
|
||||
OrderBy(
|
||||
OrderBy<NSManagedObject>(
|
||||
[
|
||||
NSSortDescriptor(key: "key1", ascending: false),
|
||||
NSSortDescriptor(key: "key2", ascending: false)
|
||||
]
|
||||
)
|
||||
)
|
||||
XCTAssertNotEqual(orderBy, OrderBy(.ascending("key1"), .ascending("key2")))
|
||||
XCTAssertNotEqual(orderBy, OrderBy(.ascending("key1"), .descending("key3")))
|
||||
XCTAssertNotEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key1"), .ascending("key2")))
|
||||
XCTAssertNotEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key1"), .descending("key3")))
|
||||
XCTAssertEqual(orderBy.sortDescriptors, sortDescriptors)
|
||||
}
|
||||
do {
|
||||
|
||||
let orderBy = OrderBy(.ascending("key1"))
|
||||
let orderBy = OrderBy<NSManagedObject>(.ascending("key1"))
|
||||
let sortDescriptor = NSSortDescriptor(key: "key1", ascending: true)
|
||||
XCTAssertEqual(orderBy, OrderBy(sortDescriptor))
|
||||
XCTAssertEqual(orderBy, OrderBy(.ascending("key1")))
|
||||
XCTAssertNotEqual(orderBy, OrderBy(.descending("key1")))
|
||||
XCTAssertNotEqual(orderBy, OrderBy(.ascending("key2")))
|
||||
XCTAssertEqual(orderBy, OrderBy([sortDescriptor]))
|
||||
XCTAssertEqual(orderBy, OrderBy<NSManagedObject>(sortDescriptor))
|
||||
XCTAssertEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key1")))
|
||||
XCTAssertNotEqual(orderBy, OrderBy<NSManagedObject>(.descending("key1")))
|
||||
XCTAssertNotEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key2")))
|
||||
XCTAssertEqual(orderBy, OrderBy<NSManagedObject>([sortDescriptor]))
|
||||
XCTAssertEqual(orderBy.sortDescriptors, [sortDescriptor])
|
||||
}
|
||||
do {
|
||||
|
||||
let orderBy = OrderBy(.ascending("key1"), .descending("key2"))
|
||||
let orderBy = OrderBy<NSManagedObject>(.ascending("key1"), .descending("key2"))
|
||||
let sortDescriptors = [
|
||||
NSSortDescriptor(key: "key1", ascending: true),
|
||||
NSSortDescriptor(key: "key2", ascending: false)
|
||||
]
|
||||
XCTAssertEqual(orderBy, OrderBy(sortDescriptors))
|
||||
XCTAssertEqual(orderBy, OrderBy(.ascending("key1"), .descending("key2")))
|
||||
XCTAssertEqual(orderBy, OrderBy<NSManagedObject>(sortDescriptors))
|
||||
XCTAssertEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key1"), .descending("key2")))
|
||||
XCTAssertNotEqual(
|
||||
orderBy,
|
||||
OrderBy(
|
||||
OrderBy<NSManagedObject>(
|
||||
[
|
||||
NSSortDescriptor(key: "key1", ascending: false),
|
||||
NSSortDescriptor(key: "key2", ascending: false)
|
||||
]
|
||||
)
|
||||
)
|
||||
XCTAssertNotEqual(orderBy, OrderBy(.ascending("key1"), .ascending("key2")))
|
||||
XCTAssertNotEqual(orderBy, OrderBy(.ascending("key1"), .descending("key3")))
|
||||
XCTAssertNotEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key1"), .ascending("key2")))
|
||||
XCTAssertNotEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key1"), .descending("key3")))
|
||||
XCTAssertEqual(orderBy.sortDescriptors, sortDescriptors)
|
||||
}
|
||||
do {
|
||||
|
||||
let sortKeys: [SortKey] = [.ascending("key1"), .descending("key2")]
|
||||
let orderBy = OrderBy(sortKeys)
|
||||
let sortKeys: [OrderBy<NSManagedObject>.SortKey] = [.ascending("key1"), .descending("key2")]
|
||||
let orderBy = OrderBy<NSManagedObject>(sortKeys)
|
||||
let sortDescriptors = [
|
||||
NSSortDescriptor(key: "key1", ascending: true),
|
||||
NSSortDescriptor(key: "key2", ascending: false)
|
||||
]
|
||||
XCTAssertEqual(orderBy, OrderBy(sortDescriptors))
|
||||
XCTAssertEqual(orderBy, OrderBy(.ascending("key1"), .descending("key2")))
|
||||
XCTAssertEqual(orderBy, OrderBy<NSManagedObject>(sortDescriptors))
|
||||
XCTAssertEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key1"), .descending("key2")))
|
||||
XCTAssertNotEqual(
|
||||
orderBy,
|
||||
OrderBy(
|
||||
OrderBy<NSManagedObject>(
|
||||
[
|
||||
NSSortDescriptor(key: "key1", ascending: false),
|
||||
NSSortDescriptor(key: "key2", ascending: false)
|
||||
]
|
||||
)
|
||||
)
|
||||
XCTAssertNotEqual(orderBy, OrderBy(.ascending("key1"), .ascending("key2")))
|
||||
XCTAssertNotEqual(orderBy, OrderBy(.ascending("key1"), .descending("key3")))
|
||||
XCTAssertNotEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key1"), .ascending("key2")))
|
||||
XCTAssertNotEqual(orderBy, OrderBy<NSManagedObject>(.ascending("key1"), .descending("key3")))
|
||||
XCTAssertEqual(orderBy.sortDescriptors, sortDescriptors)
|
||||
}
|
||||
}
|
||||
@@ -138,15 +138,15 @@ final class OrderByTests: XCTestCase {
|
||||
@objc
|
||||
dynamic func test_ThatOrderByClauseOperations_ComputeCorrectly() {
|
||||
|
||||
let orderBy1 = OrderBy(.ascending("key1"))
|
||||
let orderBy2 = OrderBy(.descending("key2"))
|
||||
let orderBy3 = OrderBy(.ascending("key3"))
|
||||
let orderBy1 = OrderBy<NSManagedObject>(.ascending("key1"))
|
||||
let orderBy2 = OrderBy<NSManagedObject>(.descending("key2"))
|
||||
let orderBy3 = OrderBy<NSManagedObject>(.ascending("key3"))
|
||||
|
||||
do {
|
||||
|
||||
let plusOrderBy = orderBy1 + orderBy2 + orderBy3
|
||||
XCTAssertEqual(plusOrderBy, OrderBy(.ascending("key1"), .descending("key2"), .ascending("key3")))
|
||||
XCTAssertEqual(plusOrderBy, OrderBy(.ascending("key1")) + OrderBy(.descending("key2"), .ascending("key3")))
|
||||
XCTAssertEqual(plusOrderBy, OrderBy<NSManagedObject>(.ascending("key1"), .descending("key2"), .ascending("key3")))
|
||||
XCTAssertEqual(plusOrderBy, OrderBy<NSManagedObject>(.ascending("key1")) + OrderBy<NSManagedObject>(.descending("key2"), .ascending("key3")))
|
||||
XCTAssertNotEqual(plusOrderBy, orderBy1 + orderBy3 + orderBy2)
|
||||
XCTAssertNotEqual(plusOrderBy, orderBy2 + orderBy1 + orderBy3)
|
||||
XCTAssertNotEqual(plusOrderBy, orderBy2 + orderBy3 + orderBy1)
|
||||
@@ -158,14 +158,14 @@ final class OrderByTests: XCTestCase {
|
||||
|
||||
var plusOrderBy = orderBy1
|
||||
plusOrderBy += orderBy2
|
||||
XCTAssertEqual(plusOrderBy, OrderBy(.ascending("key1"), .descending("key2")))
|
||||
XCTAssertEqual(plusOrderBy, OrderBy(.ascending("key1")) + OrderBy(.descending("key2")))
|
||||
XCTAssertEqual(plusOrderBy, OrderBy<NSManagedObject>(.ascending("key1"), .descending("key2")))
|
||||
XCTAssertEqual(plusOrderBy, OrderBy<NSManagedObject>(.ascending("key1")) + OrderBy<NSManagedObject>(.descending("key2")))
|
||||
XCTAssertNotEqual(plusOrderBy, orderBy2 + orderBy1)
|
||||
XCTAssertEqual(plusOrderBy.sortDescriptors, orderBy1.sortDescriptors + orderBy2.sortDescriptors)
|
||||
|
||||
plusOrderBy += orderBy3
|
||||
XCTAssertEqual(plusOrderBy, OrderBy(.ascending("key1"), .descending("key2"), .ascending("key3")))
|
||||
XCTAssertEqual(plusOrderBy, OrderBy(.ascending("key1"), .descending("key2")) + OrderBy(.ascending("key3")))
|
||||
XCTAssertEqual(plusOrderBy, OrderBy<NSManagedObject>(.ascending("key1"), .descending("key2"), .ascending("key3")))
|
||||
XCTAssertEqual(plusOrderBy, OrderBy<NSManagedObject>(.ascending("key1"), .descending("key2")) + OrderBy<NSManagedObject>(.ascending("key3")))
|
||||
XCTAssertNotEqual(plusOrderBy, orderBy1 + orderBy3 + orderBy2)
|
||||
XCTAssertNotEqual(plusOrderBy, orderBy2 + orderBy1 + orderBy3)
|
||||
XCTAssertNotEqual(plusOrderBy, orderBy2 + orderBy3 + orderBy1)
|
||||
@@ -178,7 +178,7 @@ final class OrderByTests: XCTestCase {
|
||||
@objc
|
||||
dynamic func test_ThatOrderByClauses_ApplyToFetchRequestsCorrectly() {
|
||||
|
||||
let orderBy = OrderBy(.ascending("key"))
|
||||
let orderBy = OrderBy<NSManagedObject>(.ascending("key"))
|
||||
let request = CoreStoreFetchRequest()
|
||||
orderBy.applyToFetchRequest(request)
|
||||
XCTAssertNotNil(request.sortDescriptors)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -39,13 +39,13 @@ final class SectionByTests: XCTestCase {
|
||||
|
||||
do {
|
||||
|
||||
let sectionBy = SectionBy("key")
|
||||
let sectionBy = SectionBy<NSManagedObject>("key")
|
||||
XCTAssertEqual(sectionBy.sectionKeyPath, "key")
|
||||
XCTAssertEqual(sectionBy.sectionIndexTransformer("key"), "key")
|
||||
}
|
||||
do {
|
||||
|
||||
let sectionBy = SectionBy("key") { $0.flatMap { "\($0):suffix" } }
|
||||
let sectionBy = SectionBy<NSManagedObject>("key") { $0.flatMap { "\($0):suffix" } }
|
||||
XCTAssertEqual(sectionBy.sectionKeyPath, "key")
|
||||
XCTAssertEqual(sectionBy.sectionIndexTransformer("key"), "key:suffix")
|
||||
XCTAssertNil(sectionBy.sectionIndexTransformer(nil))
|
||||
|
||||
@@ -38,7 +38,7 @@ final class SelectTests: XCTestCase {
|
||||
|
||||
do {
|
||||
|
||||
let term: SelectTerm = "attribute"
|
||||
let term: SelectTerm<NSManagedObject> = "attribute"
|
||||
XCTAssertEqual(term, SelectTerm.attribute("attribute"))
|
||||
XCTAssertNotEqual(term, SelectTerm.attribute("attribute2"))
|
||||
XCTAssertNotEqual(term, SelectTerm.average("attribute"))
|
||||
@@ -58,7 +58,7 @@ final class SelectTests: XCTestCase {
|
||||
}
|
||||
do {
|
||||
|
||||
let term = SelectTerm.attribute("attribute")
|
||||
let term = SelectTerm<NSManagedObject>.attribute("attribute")
|
||||
XCTAssertNotEqual(term, SelectTerm.attribute("attribute2"))
|
||||
XCTAssertNotEqual(term, SelectTerm.average("attribute"))
|
||||
XCTAssertNotEqual(term, SelectTerm.count("attribute"))
|
||||
@@ -82,7 +82,7 @@ final class SelectTests: XCTestCase {
|
||||
|
||||
do {
|
||||
|
||||
let term = SelectTerm.average("attribute")
|
||||
let term = SelectTerm<NSManagedObject>.average("attribute")
|
||||
XCTAssertEqual(term, SelectTerm.average("attribute"))
|
||||
XCTAssertNotEqual(term, SelectTerm.average("attribute", as: "alias"))
|
||||
XCTAssertNotEqual(term, SelectTerm.average("attribute2"))
|
||||
@@ -106,7 +106,7 @@ final class SelectTests: XCTestCase {
|
||||
}
|
||||
do {
|
||||
|
||||
let term = SelectTerm.average("attribute", as: "alias")
|
||||
let term = SelectTerm<NSManagedObject>.average("attribute", as: "alias")
|
||||
XCTAssertEqual(term, SelectTerm.average("attribute", as: "alias"))
|
||||
XCTAssertNotEqual(term, SelectTerm.average("attribute", as: "alias2"))
|
||||
XCTAssertNotEqual(term, SelectTerm.average("attribute2"))
|
||||
@@ -135,7 +135,7 @@ final class SelectTests: XCTestCase {
|
||||
|
||||
do {
|
||||
|
||||
let term = SelectTerm.count("attribute")
|
||||
let term = SelectTerm<NSManagedObject>.count("attribute")
|
||||
XCTAssertEqual(term, SelectTerm.count("attribute"))
|
||||
XCTAssertNotEqual(term, SelectTerm.count("attribute", as: "alias"))
|
||||
XCTAssertNotEqual(term, SelectTerm.count("attribute2"))
|
||||
@@ -159,7 +159,7 @@ final class SelectTests: XCTestCase {
|
||||
}
|
||||
do {
|
||||
|
||||
let term = SelectTerm.count("attribute", as: "alias")
|
||||
let term = SelectTerm<NSManagedObject>.count("attribute", as: "alias")
|
||||
XCTAssertEqual(term, SelectTerm.count("attribute", as: "alias"))
|
||||
XCTAssertNotEqual(term, SelectTerm.count("attribute", as: "alias2"))
|
||||
XCTAssertNotEqual(term, SelectTerm.count("attribute2"))
|
||||
@@ -188,7 +188,7 @@ final class SelectTests: XCTestCase {
|
||||
|
||||
do {
|
||||
|
||||
let term = SelectTerm.maximum("attribute")
|
||||
let term = SelectTerm<NSManagedObject>.maximum("attribute")
|
||||
XCTAssertEqual(term, SelectTerm.maximum("attribute"))
|
||||
XCTAssertNotEqual(term, SelectTerm.maximum("attribute", as: "alias"))
|
||||
XCTAssertNotEqual(term, SelectTerm.maximum("attribute2"))
|
||||
@@ -212,7 +212,7 @@ final class SelectTests: XCTestCase {
|
||||
}
|
||||
do {
|
||||
|
||||
let term = SelectTerm.maximum("attribute", as: "alias")
|
||||
let term = SelectTerm<NSManagedObject>.maximum("attribute", as: "alias")
|
||||
XCTAssertEqual(term, SelectTerm.maximum("attribute", as: "alias"))
|
||||
XCTAssertNotEqual(term, SelectTerm.maximum("attribute", as: "alias2"))
|
||||
XCTAssertNotEqual(term, SelectTerm.maximum("attribute2"))
|
||||
@@ -241,7 +241,7 @@ final class SelectTests: XCTestCase {
|
||||
|
||||
do {
|
||||
|
||||
let term = SelectTerm.minimum("attribute")
|
||||
let term = SelectTerm<NSManagedObject>.minimum("attribute")
|
||||
XCTAssertEqual(term, SelectTerm.minimum("attribute"))
|
||||
XCTAssertNotEqual(term, SelectTerm.minimum("attribute", as: "alias"))
|
||||
XCTAssertNotEqual(term, SelectTerm.minimum("attribute2"))
|
||||
@@ -265,7 +265,7 @@ final class SelectTests: XCTestCase {
|
||||
}
|
||||
do {
|
||||
|
||||
let term = SelectTerm.minimum("attribute", as: "alias")
|
||||
let term = SelectTerm<NSManagedObject>.minimum("attribute", as: "alias")
|
||||
XCTAssertEqual(term, SelectTerm.minimum("attribute", as: "alias"))
|
||||
XCTAssertNotEqual(term, SelectTerm.minimum("attribute", as: "alias2"))
|
||||
XCTAssertNotEqual(term, SelectTerm.minimum("attribute2"))
|
||||
@@ -294,7 +294,7 @@ final class SelectTests: XCTestCase {
|
||||
|
||||
do {
|
||||
|
||||
let term = SelectTerm.sum("attribute")
|
||||
let term = SelectTerm<NSManagedObject>.sum("attribute")
|
||||
XCTAssertEqual(term, SelectTerm.sum("attribute"))
|
||||
XCTAssertNotEqual(term, SelectTerm.sum("attribute", as: "alias"))
|
||||
XCTAssertNotEqual(term, SelectTerm.sum("attribute2"))
|
||||
@@ -318,7 +318,7 @@ final class SelectTests: XCTestCase {
|
||||
}
|
||||
do {
|
||||
|
||||
let term = SelectTerm.sum("attribute", as: "alias")
|
||||
let term = SelectTerm<NSManagedObject>.sum("attribute", as: "alias")
|
||||
XCTAssertEqual(term, SelectTerm.sum("attribute", as: "alias"))
|
||||
XCTAssertNotEqual(term, SelectTerm.sum("attribute", as: "alias2"))
|
||||
XCTAssertNotEqual(term, SelectTerm.sum("attribute2"))
|
||||
@@ -347,7 +347,7 @@ final class SelectTests: XCTestCase {
|
||||
|
||||
do {
|
||||
|
||||
let term = SelectTerm.objectID()
|
||||
let term = SelectTerm<NSManagedObject>.objectID()
|
||||
XCTAssertEqual(term, SelectTerm.objectID())
|
||||
XCTAssertNotEqual(term, SelectTerm.objectID(as: "alias"))
|
||||
XCTAssertNotEqual(term, SelectTerm.attribute("attribute"))
|
||||
@@ -368,7 +368,7 @@ final class SelectTests: XCTestCase {
|
||||
}
|
||||
do {
|
||||
|
||||
let term = SelectTerm.objectID(as: "alias")
|
||||
let term = SelectTerm<NSManagedObject>.objectID(as: "alias")
|
||||
XCTAssertEqual(term, SelectTerm.objectID(as: "alias"))
|
||||
XCTAssertNotEqual(term, SelectTerm.objectID(as: "alias2"))
|
||||
XCTAssertNotEqual(term, SelectTerm.objectID())
|
||||
@@ -393,12 +393,12 @@ final class SelectTests: XCTestCase {
|
||||
@objc
|
||||
dynamic func test_ThatSelectClauses_ConfigureCorrectly() {
|
||||
|
||||
let term1 = SelectTerm.attribute("attribute1")
|
||||
let term2 = SelectTerm.attribute("attribute2")
|
||||
let term3 = SelectTerm.attribute("attribute3")
|
||||
let term1 = SelectTerm<NSManagedObject>.attribute("attribute1")
|
||||
let term2 = SelectTerm<NSManagedObject>.attribute("attribute2")
|
||||
let term3 = SelectTerm<NSManagedObject>.attribute("attribute3")
|
||||
do {
|
||||
|
||||
let select = Select<Int>(term1, term2, term3)
|
||||
let select = Select<NSManagedObject, Int>(term1, term2, term3)
|
||||
XCTAssertEqual(select.selectTerms, [term1, term2, term3])
|
||||
XCTAssertNotEqual(select.selectTerms, [term1, term3, term2])
|
||||
XCTAssertNotEqual(select.selectTerms, [term2, term1, term3])
|
||||
@@ -408,7 +408,7 @@ final class SelectTests: XCTestCase {
|
||||
}
|
||||
do {
|
||||
|
||||
let select = Select<Int>([term1, term2, term3])
|
||||
let select = Select<NSManagedObject, Int>([term1, term2, term3])
|
||||
XCTAssertEqual(select.selectTerms, [term1, term2, term3])
|
||||
XCTAssertNotEqual(select.selectTerms, [term1, term3, term2])
|
||||
XCTAssertNotEqual(select.selectTerms, [term2, term1, term3])
|
||||
|
||||
@@ -67,7 +67,7 @@ class SetupTests: BaseTestDataTestCase {
|
||||
let stack = self.expectLogger([.logWarning]) {
|
||||
|
||||
DataStack(
|
||||
modelName: "Model",
|
||||
xcodeModelName: "Model",
|
||||
bundle: Bundle(for: type(of: self)),
|
||||
migrationChain: migrationChain
|
||||
)
|
||||
@@ -84,7 +84,7 @@ class SetupTests: BaseTestDataTestCase {
|
||||
dynamic func test_ThatInMemoryStores_SetupCorrectly() {
|
||||
|
||||
let stack = DataStack(
|
||||
modelName: "Model",
|
||||
xcodeModelName: "Model",
|
||||
bundle: Bundle(for: type(of: self))
|
||||
)
|
||||
do {
|
||||
@@ -139,7 +139,7 @@ class SetupTests: BaseTestDataTestCase {
|
||||
dynamic func test_ThatSQLiteStores_SetupCorrectly() {
|
||||
|
||||
let stack = DataStack(
|
||||
modelName: "Model",
|
||||
xcodeModelName: "Model",
|
||||
bundle: Bundle(for: type(of: self))
|
||||
)
|
||||
do {
|
||||
@@ -207,7 +207,7 @@ class SetupTests: BaseTestDataTestCase {
|
||||
do {
|
||||
|
||||
let stack = DataStack(
|
||||
modelName: "Model",
|
||||
xcodeModelName: "Model",
|
||||
bundle: Bundle(for: type(of: self))
|
||||
)
|
||||
try! stack.addStorageAndWait(sqliteStore)
|
||||
@@ -226,7 +226,7 @@ class SetupTests: BaseTestDataTestCase {
|
||||
|
||||
let metadata = try createStore()
|
||||
let stack = DataStack(
|
||||
modelName: "Model",
|
||||
xcodeModelName: "Model",
|
||||
bundle: Bundle(for: type(of: self))
|
||||
)
|
||||
try sqliteStore.cs_eraseStorageAndWait(
|
||||
@@ -259,7 +259,7 @@ class SetupTests: BaseTestDataTestCase {
|
||||
dynamic func test_ThatLegacySQLiteStores_SetupCorrectly() {
|
||||
|
||||
let stack = DataStack(
|
||||
modelName: "Model",
|
||||
xcodeModelName: "Model",
|
||||
bundle: Bundle(for: type(of: self))
|
||||
)
|
||||
do {
|
||||
@@ -327,7 +327,7 @@ class SetupTests: BaseTestDataTestCase {
|
||||
do {
|
||||
|
||||
let stack = DataStack(
|
||||
modelName: "Model",
|
||||
xcodeModelName: "Model",
|
||||
bundle: Bundle(for: type(of: self))
|
||||
)
|
||||
try! stack.addStorageAndWait(sqliteStore)
|
||||
@@ -346,7 +346,7 @@ class SetupTests: BaseTestDataTestCase {
|
||||
|
||||
let metadata = try createStore()
|
||||
let stack = DataStack(
|
||||
modelName: "Model",
|
||||
xcodeModelName: "Model",
|
||||
bundle: Bundle(for: type(of: self))
|
||||
)
|
||||
try sqliteStore.cs_eraseStorageAndWait(
|
||||
|
||||
@@ -396,7 +396,7 @@ final class TransactionTests: BaseTestCase {
|
||||
let observer = TestListObserver()
|
||||
let monitor = stack.monitorList(
|
||||
From<TestEntity1>(),
|
||||
OrderBy(.ascending("testEntityID"))
|
||||
OrderBy<TestEntity1>(.ascending("testEntityID"))
|
||||
)
|
||||
monitor.addObserver(observer)
|
||||
|
||||
@@ -404,7 +404,7 @@ final class TransactionTests: BaseTestCase {
|
||||
|
||||
var events = 0
|
||||
let willChangeExpectation = self.expectation(
|
||||
forNotification: "listMonitorWillChange:",
|
||||
forNotification: NSNotification.Name(rawValue: "listMonitorWillChange:"),
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
@@ -418,7 +418,7 @@ final class TransactionTests: BaseTestCase {
|
||||
}
|
||||
)
|
||||
let didInsertObjectExpectation = self.expectation(
|
||||
forNotification: "listMonitor:didInsertObject:toIndexPath:",
|
||||
forNotification: NSNotification.Name(rawValue: "listMonitor:didInsertObject:toIndexPath:"),
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
@@ -448,7 +448,7 @@ final class TransactionTests: BaseTestCase {
|
||||
}
|
||||
)
|
||||
let didChangeExpectation = self.expectation(
|
||||
forNotification: "listMonitorDidChange:",
|
||||
forNotification: NSNotification.Name(rawValue: "listMonitorDidChange:"),
|
||||
object: observer,
|
||||
handler: { (note) -> Bool in
|
||||
|
||||
@@ -737,7 +737,7 @@ final class TransactionTests: BaseTestCase {
|
||||
createDiscardExpectation.fulfill()
|
||||
try transaction.cancel()
|
||||
},
|
||||
success: {
|
||||
success: { _ in
|
||||
|
||||
XCTFail()
|
||||
},
|
||||
@@ -795,7 +795,7 @@ final class TransactionTests: BaseTestCase {
|
||||
|
||||
try transaction.cancel()
|
||||
},
|
||||
success: {
|
||||
success: { _ in
|
||||
|
||||
XCTFail()
|
||||
},
|
||||
@@ -828,7 +828,7 @@ final class TransactionTests: BaseTestCase {
|
||||
|
||||
try transaction.cancel()
|
||||
},
|
||||
success: {
|
||||
success: { _ in
|
||||
|
||||
XCTFail()
|
||||
},
|
||||
|
||||
@@ -31,12 +31,12 @@ import CoreStore
|
||||
|
||||
// MARK: - XCTAssertAllEqual
|
||||
|
||||
private func XCTAssertAllEqual(_ whereClauses: Where...) {
|
||||
private func XCTAssertAllEqual<D>(_ whereClauses: Where<D>...) {
|
||||
|
||||
XCTAssertAllEqual(whereClauses)
|
||||
}
|
||||
|
||||
private func XCTAssertAllEqual(_ whereClauses: [Where]) {
|
||||
private func XCTAssertAllEqual<D>(_ whereClauses: [Where<D>]) {
|
||||
|
||||
for i in whereClauses.indices {
|
||||
|
||||
@@ -52,56 +52,62 @@ private func XCTAssertAllEqual(_ whereClauses: [Where]) {
|
||||
|
||||
final class WhereTests: XCTestCase {
|
||||
|
||||
@objc
|
||||
dynamic func test_ThatDynamicModelKeyPaths_CanBeCreated() {
|
||||
|
||||
XCTAssertEqual(String(keyPath: \TestEntity1.testEntityID), "testEntityID")
|
||||
}
|
||||
|
||||
@objc
|
||||
dynamic func test_ThatWhereClauses_ConfigureCorrectly() {
|
||||
|
||||
do {
|
||||
|
||||
let whereClause = Where()
|
||||
XCTAssertEqual(whereClause, Where(true))
|
||||
XCTAssertNotEqual(whereClause, Where(false))
|
||||
let whereClause = Where<NSManagedObject>()
|
||||
XCTAssertEqual(whereClause, Where<NSManagedObject>(true))
|
||||
XCTAssertNotEqual(whereClause, Where<NSManagedObject>(false))
|
||||
XCTAssertEqual(whereClause.predicate, NSPredicate(value: true))
|
||||
}
|
||||
do {
|
||||
|
||||
let whereClause = Where(true)
|
||||
XCTAssertEqual(whereClause, Where())
|
||||
XCTAssertNotEqual(whereClause, Where(false))
|
||||
let whereClause = Where<NSManagedObject>(true)
|
||||
XCTAssertEqual(whereClause, Where<NSManagedObject>())
|
||||
XCTAssertNotEqual(whereClause, Where<NSManagedObject>(false))
|
||||
XCTAssertEqual(whereClause.predicate, NSPredicate(value: true))
|
||||
}
|
||||
do {
|
||||
|
||||
let predicate = NSPredicate(format: "%K == %@", "key", "value")
|
||||
let whereClause = Where(predicate)
|
||||
XCTAssertEqual(whereClause, Where(predicate))
|
||||
let whereClause = Where<NSManagedObject>(predicate)
|
||||
XCTAssertEqual(whereClause, Where<NSManagedObject>(predicate))
|
||||
XCTAssertEqual(whereClause.predicate, predicate)
|
||||
}
|
||||
do {
|
||||
|
||||
let whereClause = Where("%K == %@", "key", "value")
|
||||
let whereClause = Where<NSManagedObject>("%K == %@", "key", "value")
|
||||
let predicate = NSPredicate(format: "%K == %@", "key", "value")
|
||||
XCTAssertEqual(whereClause, Where(predicate))
|
||||
XCTAssertEqual(whereClause, Where<NSManagedObject>(predicate))
|
||||
XCTAssertEqual(whereClause.predicate, predicate)
|
||||
}
|
||||
do {
|
||||
|
||||
let whereClause = Where("%K == %@", argumentArray: ["key", "value"])
|
||||
let whereClause = Where<NSManagedObject>("%K == %@", argumentArray: ["key", "value"])
|
||||
let predicate = NSPredicate(format: "%K == %@", "key", "value")
|
||||
XCTAssertEqual(whereClause, Where(predicate))
|
||||
XCTAssertEqual(whereClause, Where<NSManagedObject>(predicate))
|
||||
XCTAssertEqual(whereClause.predicate, predicate)
|
||||
}
|
||||
do {
|
||||
|
||||
let whereClause = Where("key", isEqualTo: "value")
|
||||
let whereClause = Where<NSManagedObject>("key", isEqualTo: "value")
|
||||
let predicate = NSPredicate(format: "%K == %@", "key", "value")
|
||||
XCTAssertEqual(whereClause, Where(predicate))
|
||||
XCTAssertEqual(whereClause, Where<NSManagedObject>(predicate))
|
||||
XCTAssertEqual(whereClause.predicate, predicate)
|
||||
}
|
||||
do {
|
||||
|
||||
let whereClause = Where("key", isMemberOf: ["value1", "value2", "value3"])
|
||||
let whereClause = Where<NSManagedObject>("key", isMemberOf: ["value1", "value2", "value3"])
|
||||
let predicate = NSPredicate(format: "%K IN %@", "key", ["value1", "value2", "value3"])
|
||||
XCTAssertEqual(whereClause, Where(predicate))
|
||||
XCTAssertEqual(whereClause, Where<NSManagedObject>(predicate))
|
||||
XCTAssertEqual(whereClause.predicate, predicate)
|
||||
}
|
||||
}
|
||||
@@ -113,112 +119,112 @@ final class WhereTests: XCTestCase {
|
||||
|
||||
let value: Int = 100
|
||||
XCTAssertAllEqual(
|
||||
Where("%K == %d", "key", value),
|
||||
Where("%K == %d", "key", value as AnyObject),
|
||||
Where("%K == %d", "key", NSNumber(value: value)),
|
||||
Where("%K == %@", "key", value),
|
||||
Where("%K == %@", "key", value as AnyObject),
|
||||
Where("%K == %@", "key", NSNumber(value: value)),
|
||||
Where("key", isEqualTo: value),
|
||||
Where("key", isEqualTo: NSNumber(value: value))
|
||||
Where<NSManagedObject>("%K == %d", "key", value),
|
||||
Where<NSManagedObject>("%K == %d", "key", value as AnyObject),
|
||||
Where<NSManagedObject>("%K == %d", "key", NSNumber(value: value)),
|
||||
Where<NSManagedObject>("%K == %@", "key", value),
|
||||
Where<NSManagedObject>("%K == %@", "key", value as AnyObject),
|
||||
Where<NSManagedObject>("%K == %@", "key", NSNumber(value: value)),
|
||||
Where<NSManagedObject>("key", isEqualTo: value),
|
||||
Where<NSManagedObject>("key", isEqualTo: NSNumber(value: value))
|
||||
)
|
||||
}
|
||||
do {
|
||||
|
||||
let value = NSNumber(value: 100)
|
||||
XCTAssertAllEqual(
|
||||
Where("%K == %d", "key", value),
|
||||
Where("%K == %d", "key", value as AnyObject),
|
||||
Where("%K == %d", "key", value.intValue),
|
||||
Where("%K == %@", "key", value),
|
||||
Where("%K == %@", "key", value as AnyObject),
|
||||
Where("%K == %@", "key", value.intValue),
|
||||
Where("key", isEqualTo: value),
|
||||
Where("key", isEqualTo: value.intValue)
|
||||
Where<NSManagedObject>("%K == %d", "key", value),
|
||||
Where<NSManagedObject>("%K == %d", "key", value as AnyObject),
|
||||
Where<NSManagedObject>("%K == %d", "key", value.intValue),
|
||||
Where<NSManagedObject>("%K == %@", "key", value),
|
||||
Where<NSManagedObject>("%K == %@", "key", value as AnyObject),
|
||||
Where<NSManagedObject>("%K == %@", "key", value.intValue),
|
||||
Where<NSManagedObject>("key", isEqualTo: value),
|
||||
Where<NSManagedObject>("key", isEqualTo: value.intValue)
|
||||
)
|
||||
}
|
||||
do {
|
||||
|
||||
let value: Int64 = Int64.max
|
||||
XCTAssertAllEqual(
|
||||
Where("%K == %d", "key", value),
|
||||
Where("%K == %d", "key", value as AnyObject),
|
||||
Where("%K == %d", "key", NSNumber(value: value)),
|
||||
Where("%K == %@", "key", value),
|
||||
Where("%K == %@", "key", value as AnyObject),
|
||||
Where("%K == %@", "key", NSNumber(value: value)),
|
||||
Where("key", isEqualTo: value),
|
||||
Where("key", isEqualTo: NSNumber(value: value))
|
||||
Where<NSManagedObject>("%K == %d", "key", value),
|
||||
Where<NSManagedObject>("%K == %d", "key", value as AnyObject),
|
||||
Where<NSManagedObject>("%K == %d", "key", NSNumber(value: value)),
|
||||
Where<NSManagedObject>("%K == %@", "key", value),
|
||||
Where<NSManagedObject>("%K == %@", "key", value as AnyObject),
|
||||
Where<NSManagedObject>("%K == %@", "key", NSNumber(value: value)),
|
||||
Where<NSManagedObject>("key", isEqualTo: value),
|
||||
Where<NSManagedObject>("key", isEqualTo: NSNumber(value: value))
|
||||
)
|
||||
}
|
||||
do {
|
||||
|
||||
let value = NSNumber(value: Int64.max)
|
||||
XCTAssertAllEqual(
|
||||
Where("%K == %d", "key", value),
|
||||
Where("%K == %d", "key", value as AnyObject),
|
||||
Where("%K == %d", "key", value.int64Value),
|
||||
Where("%K == %@", "key", value),
|
||||
Where("%K == %@", "key", value as AnyObject),
|
||||
Where("%K == %@", "key", value.int64Value),
|
||||
Where("key", isEqualTo: value),
|
||||
Where("key", isEqualTo: value.int64Value)
|
||||
Where<NSManagedObject>("%K == %d", "key", value),
|
||||
Where<NSManagedObject>("%K == %d", "key", value as AnyObject),
|
||||
Where<NSManagedObject>("%K == %d", "key", value.int64Value),
|
||||
Where<NSManagedObject>("%K == %@", "key", value),
|
||||
Where<NSManagedObject>("%K == %@", "key", value as AnyObject),
|
||||
Where<NSManagedObject>("%K == %@", "key", value.int64Value),
|
||||
Where<NSManagedObject>("key", isEqualTo: value),
|
||||
Where<NSManagedObject>("key", isEqualTo: value.int64Value)
|
||||
)
|
||||
}
|
||||
do {
|
||||
|
||||
let value: String = "value"
|
||||
XCTAssertAllEqual(
|
||||
Where("%K == %s", "key", value),
|
||||
Where("%K == %s", "key", value as AnyObject),
|
||||
Where("%K == %s", "key", NSString(string: value)),
|
||||
Where("%K == %@", "key", value),
|
||||
Where("%K == %@", "key", value as AnyObject),
|
||||
Where("%K == %@", "key", NSString(string: value)),
|
||||
Where("key", isEqualTo: value),
|
||||
Where("key", isEqualTo: value as NSString),
|
||||
Where("key", isEqualTo: NSString(string: value))
|
||||
Where<NSManagedObject>("%K == %s", "key", value),
|
||||
Where<NSManagedObject>("%K == %s", "key", value as AnyObject),
|
||||
Where<NSManagedObject>("%K == %s", "key", NSString(string: value)),
|
||||
Where<NSManagedObject>("%K == %@", "key", value),
|
||||
Where<NSManagedObject>("%K == %@", "key", value as AnyObject),
|
||||
Where<NSManagedObject>("%K == %@", "key", NSString(string: value)),
|
||||
Where<NSManagedObject>("key", isEqualTo: value),
|
||||
Where<NSManagedObject>("key", isEqualTo: value as NSString),
|
||||
Where<NSManagedObject>("key", isEqualTo: NSString(string: value))
|
||||
)
|
||||
}
|
||||
do {
|
||||
|
||||
let value = NSString(string: "value")
|
||||
XCTAssertAllEqual(
|
||||
Where("%K == %s", "key", value),
|
||||
Where("%K == %s", "key", value as String),
|
||||
Where("%K == %s", "key", value as String as AnyObject),
|
||||
Where("%K == %@", "key", value),
|
||||
Where("%K == %@", "key", value as String),
|
||||
Where("%K == %@", "key", value as String as AnyObject),
|
||||
Where("key", isEqualTo: value),
|
||||
Where("key", isEqualTo: value as String),
|
||||
Where("key", isEqualTo: value as String as NSString)
|
||||
Where<NSManagedObject>("%K == %s", "key", value),
|
||||
Where<NSManagedObject>("%K == %s", "key", value as String),
|
||||
Where<NSManagedObject>("%K == %s", "key", value as String as AnyObject),
|
||||
Where<NSManagedObject>("%K == %@", "key", value),
|
||||
Where<NSManagedObject>("%K == %@", "key", value as String),
|
||||
Where<NSManagedObject>("%K == %@", "key", value as String as AnyObject),
|
||||
Where<NSManagedObject>("key", isEqualTo: value),
|
||||
Where<NSManagedObject>("key", isEqualTo: value as String),
|
||||
Where<NSManagedObject>("key", isEqualTo: value as String as NSString)
|
||||
)
|
||||
}
|
||||
do {
|
||||
|
||||
let value: [Int] = [100, 200]
|
||||
XCTAssertAllEqual(
|
||||
Where("%K IN %@", "key", value),
|
||||
Where("%K IN %@", "key", value as AnyObject),
|
||||
Where("%K IN %@", "key", value as [AnyObject]),
|
||||
Where("%K IN %@", "key", value as NSArray),
|
||||
Where("%K IN %@", "key", NSArray(array: value)),
|
||||
Where("%K IN %@", "key", value as AnyObject as! NSArray),
|
||||
Where("key", isMemberOf: value)
|
||||
Where<NSManagedObject>("%K IN %@", "key", value),
|
||||
Where<NSManagedObject>("%K IN %@", "key", value as AnyObject),
|
||||
Where<NSManagedObject>("%K IN %@", "key", value as [AnyObject]),
|
||||
Where<NSManagedObject>("%K IN %@", "key", value as NSArray),
|
||||
Where<NSManagedObject>("%K IN %@", "key", NSArray(array: value)),
|
||||
Where<NSManagedObject>("%K IN %@", "key", value as AnyObject as! NSArray),
|
||||
Where<NSManagedObject>("key", isMemberOf: value)
|
||||
)
|
||||
}
|
||||
do {
|
||||
|
||||
let value: [Int64] = [Int64.min, 100, Int64.max]
|
||||
XCTAssertAllEqual(
|
||||
Where("%K IN %@", "key", value),
|
||||
Where("%K IN %@", "key", value as AnyObject),
|
||||
Where("%K IN %@", "key", value as [AnyObject]),
|
||||
Where("%K IN %@", "key", value as NSArray),
|
||||
Where("%K IN %@", "key", NSArray(array: value)),
|
||||
Where("%K IN %@", "key", value as AnyObject as! NSArray),
|
||||
Where("key", isMemberOf: value)
|
||||
Where<NSManagedObject>("%K IN %@", "key", value),
|
||||
Where<NSManagedObject>("%K IN %@", "key", value as AnyObject),
|
||||
Where<NSManagedObject>("%K IN %@", "key", value as [AnyObject]),
|
||||
Where<NSManagedObject>("%K IN %@", "key", value as NSArray),
|
||||
Where<NSManagedObject>("%K IN %@", "key", NSArray(array: value)),
|
||||
Where<NSManagedObject>("%K IN %@", "key", value as AnyObject as! NSArray),
|
||||
Where<NSManagedObject>("key", isMemberOf: value)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -226,9 +232,9 @@ final class WhereTests: XCTestCase {
|
||||
@objc
|
||||
dynamic func test_ThatWhereClauseOperations_ComputeCorrectly() {
|
||||
|
||||
let whereClause1 = Where("key1", isEqualTo: "value1")
|
||||
let whereClause2 = Where("key2", isEqualTo: "value2")
|
||||
let whereClause3 = Where("key3", isEqualTo: "value3")
|
||||
let whereClause1 = Where<NSManagedObject>("key1", isEqualTo: "value1")
|
||||
let whereClause2 = Where<NSManagedObject>("key2", isEqualTo: "value2")
|
||||
let whereClause3 = Where<NSManagedObject>("key3", isEqualTo: "value3")
|
||||
|
||||
do {
|
||||
|
||||
@@ -256,6 +262,21 @@ final class WhereTests: XCTestCase {
|
||||
XCTAssertEqual(andWhere.predicate, andPredicate)
|
||||
XCTAssertEqual(andWhere, whereClause1 && whereClause2 && whereClause3)
|
||||
}
|
||||
do {
|
||||
|
||||
let andWhere = whereClause1 && whereClause2 && whereClause3
|
||||
let noneWhere: Where<NSManagedObject>? = nil
|
||||
let someWhere: Where<NSManagedObject>? = Where<NSManagedObject>("key4", isEqualTo: "value4")
|
||||
|
||||
|
||||
let finalNoneWhere = andWhere &&? noneWhere
|
||||
let finalSomeWhere = andWhere &&? someWhere
|
||||
let unwrappedFinalSomeWhere = andWhere && someWhere!
|
||||
|
||||
|
||||
XCTAssertEqual(andWhere.predicate, finalNoneWhere.predicate)
|
||||
XCTAssertEqual(finalSomeWhere.predicate, unwrappedFinalSomeWhere.predicate)
|
||||
}
|
||||
do {
|
||||
|
||||
let orWhere = whereClause1 || whereClause2 || whereClause3
|
||||
@@ -272,12 +293,27 @@ final class WhereTests: XCTestCase {
|
||||
XCTAssertEqual(orWhere.predicate, orPredicate)
|
||||
XCTAssertEqual(orWhere, whereClause1 || whereClause2 || whereClause3)
|
||||
}
|
||||
do {
|
||||
|
||||
let orWhere = whereClause1 || whereClause2 || whereClause3
|
||||
let noneWhere: Where<NSManagedObject>? = nil
|
||||
let someWhere: Where<NSManagedObject>? = Where<NSManagedObject>("key4", isEqualTo: "value4")
|
||||
|
||||
|
||||
let finalNoneWhere = orWhere &&? noneWhere
|
||||
let finalSomeWhere = orWhere &&? someWhere
|
||||
let unwrappedFinalSomeWhere = orWhere && someWhere!
|
||||
|
||||
XCTAssertEqual(orWhere.predicate, finalNoneWhere.predicate)
|
||||
XCTAssertEqual(finalSomeWhere.predicate, unwrappedFinalSomeWhere.predicate)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@objc
|
||||
dynamic func test_ThatWhereClauses_ApplyToFetchRequestsCorrectly() {
|
||||
|
||||
let whereClause = Where("key", isEqualTo: "value")
|
||||
let whereClause = Where<NSManagedObject>("key", isEqualTo: "value")
|
||||
let request = CoreStoreFetchRequest()
|
||||
whereClause.applyToFetchRequest(request)
|
||||
XCTAssertNotNil(request.predicate)
|
||||
|
||||
@@ -100,7 +100,7 @@ public final class AsynchronousDataTransaction: BaseDataTransaction {
|
||||
- parameter into: the `Into` clause indicating the destination `NSManagedObject` or `CoreStoreObject` entity type and the destination configuration
|
||||
- returns: a new `NSManagedObject` or `CoreStoreObject` instance of the specified entity type.
|
||||
*/
|
||||
public override func create<T: DynamicObject>(_ into: Into<T>) -> T {
|
||||
public override func create<D>(_ into: Into<D>) -> D {
|
||||
|
||||
CoreStore.assert(
|
||||
!self.isCommitted,
|
||||
@@ -116,7 +116,7 @@ public final class AsynchronousDataTransaction: BaseDataTransaction {
|
||||
- parameter object: the `NSManagedObject` or `CoreStoreObject` to be edited
|
||||
- returns: an editable proxy for the specified `NSManagedObject` or `CoreStoreObject`.
|
||||
*/
|
||||
public override func edit<T: DynamicObject>(_ object: T?) -> T? {
|
||||
public override func edit<D: DynamicObject>(_ object: D?) -> D? {
|
||||
|
||||
CoreStore.assert(
|
||||
!self.isCommitted,
|
||||
@@ -133,7 +133,7 @@ public final class AsynchronousDataTransaction: BaseDataTransaction {
|
||||
- parameter objectID: the `NSManagedObjectID` for the object to be edited
|
||||
- returns: an editable proxy for the specified `NSManagedObject` or `CoreStoreObject`.
|
||||
*/
|
||||
public override func edit<T: DynamicObject>(_ into: Into<T>, _ objectID: NSManagedObjectID) -> T? {
|
||||
public override func edit<D>(_ into: Into<D>, _ objectID: NSManagedObjectID) -> D? {
|
||||
|
||||
CoreStore.assert(
|
||||
!self.isCommitted,
|
||||
@@ -148,7 +148,7 @@ public final class AsynchronousDataTransaction: BaseDataTransaction {
|
||||
|
||||
- parameter object: the `NSManagedObject` or `CoreStoreObject` to be deleted
|
||||
*/
|
||||
public override func delete<T: DynamicObject>(_ object: T?) {
|
||||
public override func delete<D: DynamicObject>(_ object: D?) {
|
||||
|
||||
CoreStore.assert(
|
||||
!self.isCommitted,
|
||||
@@ -165,14 +165,14 @@ public final class AsynchronousDataTransaction: BaseDataTransaction {
|
||||
- parameter object2: another `DynamicObject` to be deleted
|
||||
- parameter objects: other `DynamicObject`s to be deleted
|
||||
*/
|
||||
public override func delete<T: DynamicObject>(_ object1: T?, _ object2: T?, _ objects: T?...) {
|
||||
public override func delete<D: DynamicObject>(_ object1: D?, _ object2: D?, _ objects: D?...) {
|
||||
|
||||
CoreStore.assert(
|
||||
!self.isCommitted,
|
||||
"Attempted to delete an entities from an already committed \(cs_typeName(self))."
|
||||
)
|
||||
|
||||
super.delete(([object1, object2] + objects).flatMap { $0 })
|
||||
super.delete(([object1, object2] + objects).compactMap { $0 })
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -203,13 +203,14 @@ public final class AsynchronousDataTransaction: BaseDataTransaction {
|
||||
self.isCommitted = true
|
||||
let group = DispatchGroup()
|
||||
group.enter()
|
||||
self.context.saveAsynchronouslyWithCompletion { (result) -> Void in
|
||||
self.context.saveAsynchronouslyWithCompletion { (hasChanges, error) -> Void in
|
||||
|
||||
completion(result.0, result.1)
|
||||
self.result = result
|
||||
completion(hasChanges, error)
|
||||
self.result = (hasChanges, error)
|
||||
group.leave()
|
||||
}
|
||||
group.wait()
|
||||
self.context.reset()
|
||||
}
|
||||
|
||||
|
||||
@@ -226,12 +227,15 @@ public final class AsynchronousDataTransaction: BaseDataTransaction {
|
||||
!self.isCommitted,
|
||||
"Attempted to commit a \(cs_typeName(self)) more than once."
|
||||
)
|
||||
self.autoCommit { (result) in
|
||||
self.autoCommit { (hasChanges, error) in
|
||||
|
||||
switch result {
|
||||
if let error = error {
|
||||
|
||||
case (let hasChanges, nil): completion(SaveResult(hasChanges: hasChanges))
|
||||
case (_, let error?): completion(SaveResult(error))
|
||||
completion(SaveResult(error))
|
||||
}
|
||||
else {
|
||||
|
||||
completion(SaveResult(hasChanges: hasChanges))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -266,9 +270,9 @@ public final class AsynchronousDataTransaction: BaseDataTransaction {
|
||||
}
|
||||
switch childTransaction.result {
|
||||
|
||||
case nil: return nil
|
||||
case (let hasChanges, nil)?: return SaveResult(hasChanges: hasChanges)
|
||||
case (_, let error?)?: return SaveResult(error)
|
||||
case .none: return nil
|
||||
case .some(let hasChanges, nil): return SaveResult(hasChanges: hasChanges)
|
||||
case .some(_, let error?): return SaveResult(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
47
Sources/AttributeProtocol.swift
Normal file
47
Sources/AttributeProtocol.swift
Normal file
@@ -0,0 +1,47 @@
|
||||
//
|
||||
// AttributeProtocol.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright © 2017 John Rommel Estropia
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import CoreData
|
||||
|
||||
|
||||
// MARK: - AttributeProtocol
|
||||
|
||||
internal protocol AttributeProtocol: class {
|
||||
|
||||
static var attributeType: NSAttributeType { get }
|
||||
|
||||
var keyPath: KeyPathString { get }
|
||||
var isOptional: Bool { get }
|
||||
var isTransient: Bool { get }
|
||||
var allowsExternalBinaryDataStorage: Bool { get }
|
||||
var versionHashModifier: () -> String? { get }
|
||||
var renamingIdentifier: () -> String? { get }
|
||||
var defaultValue: () -> Any? { get }
|
||||
var affectedByKeyPaths: () -> Set<String> { get }
|
||||
var parentObject: CoreStoreObject? { get set }
|
||||
var getter: CoreStoreManagedObject.CustomGetter? { get }
|
||||
var setter: CoreStoreManagedObject.CustomSetter? { get }
|
||||
}
|
||||
@@ -39,9 +39,9 @@ public extension BaseDataTransaction {
|
||||
- throws: an `Error` thrown from any of the `ImportableObject` methods
|
||||
- returns: the created `ImportableObject` instance, or `nil` if the import was ignored
|
||||
*/
|
||||
public func importObject<T: DynamicObject & ImportableObject>(
|
||||
_ into: Into<T>,
|
||||
source: T.ImportSource) throws -> T? {
|
||||
public func importObject<D: ImportableObject>(
|
||||
_ into: Into<D>,
|
||||
source: D.ImportSource) throws -> D? {
|
||||
|
||||
CoreStore.assert(
|
||||
self.isRunningInAllowedQueue(),
|
||||
@@ -69,9 +69,9 @@ public extension BaseDataTransaction {
|
||||
- parameter source: the object to import values from
|
||||
- throws: an `Error` thrown from any of the `ImportableObject` methods
|
||||
*/
|
||||
public func importObject<T: DynamicObject & ImportableObject>(
|
||||
_ object: T,
|
||||
source: T.ImportSource) throws {
|
||||
public func importObject<D: ImportableObject>(
|
||||
_ object: D,
|
||||
source: D.ImportSource) throws {
|
||||
|
||||
CoreStore.assert(
|
||||
self.isRunningInAllowedQueue(),
|
||||
@@ -97,9 +97,9 @@ public extension BaseDataTransaction {
|
||||
- throws: an `Error` thrown from any of the `ImportableObject` methods
|
||||
- returns: the array of created `ImportableObject` instances
|
||||
*/
|
||||
public func importObjects<T: DynamicObject & ImportableObject, S: Sequence>(
|
||||
_ into: Into<T>,
|
||||
sourceArray: S) throws -> [T] where S.Iterator.Element == T.ImportSource {
|
||||
public func importObjects<D: ImportableObject, S: Sequence>(
|
||||
_ into: Into<D>,
|
||||
sourceArray: S) throws -> [D] where S.Iterator.Element == D.ImportSource {
|
||||
|
||||
CoreStore.assert(
|
||||
self.isRunningInAllowedQueue(),
|
||||
@@ -108,7 +108,7 @@ public extension BaseDataTransaction {
|
||||
|
||||
return try autoreleasepool {
|
||||
|
||||
return try sourceArray.flatMap { (source) -> T? in
|
||||
return try sourceArray.compactMap { (source) -> D? in
|
||||
|
||||
let entityType = into.entityClass
|
||||
guard entityType.shouldInsert(from: source, in: self) else {
|
||||
@@ -133,9 +133,9 @@ public extension BaseDataTransaction {
|
||||
- throws: an `Error` thrown from any of the `ImportableUniqueObject` methods
|
||||
- returns: the created/updated `ImportableUniqueObject` instance, or `nil` if the import was ignored
|
||||
*/
|
||||
public func importUniqueObject<T: DynamicObject & ImportableUniqueObject>(
|
||||
_ into: Into<T>,
|
||||
source: T.ImportSource) throws -> T? {
|
||||
public func importUniqueObject<D: ImportableUniqueObject>(
|
||||
_ into: Into<D>,
|
||||
source: D.ImportSource) throws -> D? {
|
||||
|
||||
CoreStore.assert(
|
||||
self.isRunningInAllowedQueue(),
|
||||
@@ -151,7 +151,7 @@ public extension BaseDataTransaction {
|
||||
return nil
|
||||
}
|
||||
|
||||
if let object = self.fetchOne(From(entityType), Where(uniqueIDKeyPath, isEqualTo: uniqueIDValue)) {
|
||||
if let object = self.fetchOne(From(entityType), Where<D>(uniqueIDKeyPath, isEqualTo: uniqueIDValue)) {
|
||||
|
||||
guard entityType.shouldUpdate(from: source, in: self) else {
|
||||
|
||||
@@ -185,10 +185,10 @@ public extension BaseDataTransaction {
|
||||
- throws: an `Error` thrown from any of the `ImportableUniqueObject` methods
|
||||
- returns: the array of created/updated `ImportableUniqueObject` instances
|
||||
*/
|
||||
public func importUniqueObjects<T: DynamicObject & ImportableUniqueObject, S: Sequence>(
|
||||
_ into: Into<T>,
|
||||
public func importUniqueObjects<D: ImportableUniqueObject, S: Sequence>(
|
||||
_ into: Into<D>,
|
||||
sourceArray: S,
|
||||
preProcess: @escaping (_ mapping: [T.UniqueIDType: T.ImportSource]) throws -> [T.UniqueIDType: T.ImportSource] = { $0 }) throws -> [T] where S.Iterator.Element == T.ImportSource {
|
||||
preProcess: @escaping (_ mapping: [D.UniqueIDType: D.ImportSource]) throws -> [D.UniqueIDType: D.ImportSource] = { $0 }) throws -> [D] where S.Iterator.Element == D.ImportSource {
|
||||
|
||||
CoreStore.assert(
|
||||
self.isRunningInAllowedQueue(),
|
||||
@@ -198,10 +198,10 @@ public extension BaseDataTransaction {
|
||||
return try autoreleasepool {
|
||||
|
||||
let entityType = into.entityClass
|
||||
var importSourceByID = Dictionary<T.UniqueIDType, T.ImportSource>()
|
||||
var importSourceByID = Dictionary<D.UniqueIDType, D.ImportSource>()
|
||||
let sortedIDs = try autoreleasepool {
|
||||
|
||||
return try sourceArray.flatMap { (source) -> T.UniqueIDType? in
|
||||
return try sourceArray.compactMap { (source) -> D.UniqueIDType? in
|
||||
|
||||
guard let uniqueIDValue = try entityType.uniqueID(from: source, in: self) else {
|
||||
|
||||
@@ -214,12 +214,12 @@ public extension BaseDataTransaction {
|
||||
|
||||
importSourceByID = try autoreleasepool { try preProcess(importSourceByID) }
|
||||
|
||||
var existingObjectsByID = Dictionary<T.UniqueIDType, T>()
|
||||
self.fetchAll(From(entityType), Where(entityType.uniqueIDKeyPath, isMemberOf: sortedIDs))?
|
||||
var existingObjectsByID = Dictionary<D.UniqueIDType, D>()
|
||||
self.fetchAll(From(entityType), Where<D>(entityType.uniqueIDKeyPath, isMemberOf: sortedIDs))?
|
||||
.forEach { existingObjectsByID[$0.uniqueIDValue] = $0 }
|
||||
|
||||
var processedObjectIDs = Set<T.UniqueIDType>()
|
||||
var result = [T]()
|
||||
var processedObjectIDs = Set<D.UniqueIDType>()
|
||||
var result = [D]()
|
||||
|
||||
for objectID in sortedIDs where !processedObjectIDs.contains(objectID) {
|
||||
|
||||
|
||||
@@ -39,13 +39,12 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
||||
- returns: the number of `DynamicObject`s deleted
|
||||
*/
|
||||
@discardableResult
|
||||
public func deleteAll<T: DynamicObject>(_ from: From<T>, _ deleteClauses: DeleteClause...) -> Int? {
|
||||
public func deleteAll<D>(_ from: From<D>, _ deleteClauses: DeleteClause...) -> Int? {
|
||||
|
||||
CoreStore.assert(
|
||||
self.isRunningInAllowedQueue(),
|
||||
"Attempted to delete from a \(cs_typeName(self)) outside its designated queue."
|
||||
)
|
||||
|
||||
return self.context.deleteAll(from, deleteClauses)
|
||||
}
|
||||
|
||||
@@ -57,14 +56,32 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
||||
- returns: the number of `DynamicObject`s deleted
|
||||
*/
|
||||
@discardableResult
|
||||
public func deleteAll<T: DynamicObject>(_ from: From<T>, _ deleteClauses: [DeleteClause]) -> Int? {
|
||||
public func deleteAll<D>(_ from: From<D>, _ deleteClauses: [DeleteClause]) -> Int? {
|
||||
|
||||
CoreStore.assert(
|
||||
self.isRunningInAllowedQueue(),
|
||||
"Attempted to delete from a \(cs_typeName(self)) outside its designated queue."
|
||||
)
|
||||
return self.context.deleteAll(from, deleteClauses)
|
||||
}
|
||||
|
||||
/**
|
||||
Deletes all `DynamicObject`s that satisfy the specified conditions.
|
||||
```
|
||||
transaction.deleteAll(From<Person>().where(\.age > 50))
|
||||
```
|
||||
- parameter clauseChain: a `FetchChainableBuilderType` clause chain created from a `From` clause
|
||||
- returns: the number of `DynamicObject`s deleted
|
||||
*/
|
||||
@discardableResult
|
||||
public func deleteAll<B: FetchChainableBuilderType>(_ clauseChain: B) -> Int? {
|
||||
|
||||
CoreStore.assert(
|
||||
self.isRunningInAllowedQueue(),
|
||||
"Attempted to delete from a \(cs_typeName(self)) outside its designated queue."
|
||||
)
|
||||
|
||||
return self.context.deleteAll(from, deleteClauses)
|
||||
return self.context.deleteAll(clauseChain.from, clauseChain.fetchClauses)
|
||||
}
|
||||
|
||||
|
||||
@@ -76,7 +93,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
||||
- parameter object: a reference to the object created/fetched outside the transaction
|
||||
- returns: the `DynamicObject` instance if the object exists in the transaction, or `nil` if not found.
|
||||
*/
|
||||
public func fetchExisting<T: DynamicObject>(_ object: T) -> T? {
|
||||
public func fetchExisting<D: DynamicObject>(_ object: D) -> D? {
|
||||
|
||||
return self.context.fetchExisting(object)
|
||||
}
|
||||
@@ -87,7 +104,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
||||
- parameter objectID: the `NSManagedObjectID` for the object
|
||||
- returns: the `DynamicObject` instance if the object exists in the transaction, or `nil` if not found.
|
||||
*/
|
||||
public func fetchExisting<T: DynamicObject>(_ objectID: NSManagedObjectID) -> T? {
|
||||
public func fetchExisting<D: DynamicObject>(_ objectID: NSManagedObjectID) -> D? {
|
||||
|
||||
return self.context.fetchExisting(objectID)
|
||||
}
|
||||
@@ -98,7 +115,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
||||
- parameter objects: an array of `DynamicObject`s created/fetched outside the transaction
|
||||
- returns: the `DynamicObject` array for objects that exists in the transaction
|
||||
*/
|
||||
public func fetchExisting<T: DynamicObject, S: Sequence>(_ objects: S) -> [T] where S.Iterator.Element == T {
|
||||
public func fetchExisting<D: DynamicObject, S: Sequence>(_ objects: S) -> [D] where S.Iterator.Element == D {
|
||||
|
||||
return self.context.fetchExisting(objects)
|
||||
}
|
||||
@@ -109,7 +126,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
||||
- parameter objectIDs: the `NSManagedObjectID` array for the objects
|
||||
- returns: the `DynamicObject` array for objects that exists in the transaction
|
||||
*/
|
||||
public func fetchExisting<T: DynamicObject, S: Sequence>(_ objectIDs: S) -> [T] where S.Iterator.Element == NSManagedObjectID {
|
||||
public func fetchExisting<D: DynamicObject, S: Sequence>(_ objectIDs: S) -> [D] where S.Iterator.Element == NSManagedObjectID {
|
||||
|
||||
return self.context.fetchExisting(objectIDs)
|
||||
}
|
||||
@@ -121,7 +138,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
- returns: the first `DynamicObject` instance that satisfies the specified `FetchClause`s
|
||||
*/
|
||||
public func fetchOne<T: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> T? {
|
||||
public func fetchOne<D>(_ from: From<D>, _ fetchClauses: FetchClause...) -> D? {
|
||||
|
||||
CoreStore.assert(
|
||||
self.isRunningInAllowedQueue(),
|
||||
@@ -137,7 +154,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
- returns: the first `DynamicObject` instance that satisfies the specified `FetchClause`s
|
||||
*/
|
||||
public func fetchOne<T: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> T? {
|
||||
public func fetchOne<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) -> D? {
|
||||
|
||||
CoreStore.assert(
|
||||
self.isRunningInAllowedQueue(),
|
||||
@@ -146,6 +163,27 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
||||
return self.context.fetchOne(from, fetchClauses)
|
||||
}
|
||||
|
||||
/**
|
||||
Fetches the first `DynamicObject` instance that satisfies the specified `FetchChainableBuilderType` built from a chain of clauses.
|
||||
```
|
||||
let youngestTeen = transaction.fetchOne(
|
||||
From<MyPersonEntity>()
|
||||
.where(\.age > 18)
|
||||
.orderBy(.ascending(\.age))
|
||||
)
|
||||
```
|
||||
- parameter clauseChain: a `FetchChainableBuilderType` built from a chain of clauses
|
||||
- returns: the first `DynamicObject` instance that satisfies the specified `FetchChainableBuilderType`
|
||||
*/
|
||||
public func fetchOne<B: FetchChainableBuilderType>(_ clauseChain: B) -> B.ObjectType? {
|
||||
|
||||
CoreStore.assert(
|
||||
self.isRunningInAllowedQueue(),
|
||||
"Attempted to fetch from a \(cs_typeName(self)) outside its designated queue."
|
||||
)
|
||||
return self.context.fetchOne(clauseChain)
|
||||
}
|
||||
|
||||
/**
|
||||
Fetches all `DynamicObject` instances that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
|
||||
@@ -153,7 +191,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
- returns: all `DynamicObject` instances that satisfy the specified `FetchClause`s
|
||||
*/
|
||||
public func fetchAll<T: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> [T]? {
|
||||
public func fetchAll<D>(_ from: From<D>, _ fetchClauses: FetchClause...) -> [D]? {
|
||||
|
||||
CoreStore.assert(
|
||||
self.isRunningInAllowedQueue(),
|
||||
@@ -169,7 +207,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
- returns: all `DynamicObject` instances that satisfy the specified `FetchClause`s
|
||||
*/
|
||||
public func fetchAll<T: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> [T]? {
|
||||
public func fetchAll<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) -> [D]? {
|
||||
|
||||
CoreStore.assert(
|
||||
self.isRunningInAllowedQueue(),
|
||||
@@ -178,6 +216,27 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
||||
return self.context.fetchAll(from, fetchClauses)
|
||||
}
|
||||
|
||||
/**
|
||||
Fetches all `DynamicObject` instances that satisfy the specified `FetchChainableBuilderType` built from a chain of clauses.
|
||||
```
|
||||
let people = transaction.fetchAll(
|
||||
From<MyPersonEntity>()
|
||||
.where(\.age > 18)
|
||||
.orderBy(.ascending(\.age))
|
||||
)
|
||||
```
|
||||
- parameter clauseChain: a `FetchChainableBuilderType` built from a chain of clauses
|
||||
- returns: all `DynamicObject` instances that satisfy the specified `FetchChainableBuilderType`
|
||||
*/
|
||||
public func fetchAll<B: FetchChainableBuilderType>(_ clauseChain: B) -> [B.ObjectType]? {
|
||||
|
||||
CoreStore.assert(
|
||||
self.isRunningInAllowedQueue(),
|
||||
"Attempted to fetch from a \(cs_typeName(self)) outside its designated queue."
|
||||
)
|
||||
return self.context.fetchAll(clauseChain)
|
||||
}
|
||||
|
||||
/**
|
||||
Fetches the number of `DynamicObject`s that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
|
||||
@@ -185,7 +244,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
- returns: the number `DynamicObject`s that satisfy the specified `FetchClause`s
|
||||
*/
|
||||
public func fetchCount<T: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> Int? {
|
||||
public func fetchCount<D>(_ from: From<D>, _ fetchClauses: FetchClause...) -> Int? {
|
||||
|
||||
CoreStore.assert(
|
||||
self.isRunningInAllowedQueue(),
|
||||
@@ -201,7 +260,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
- returns: the number `DynamicObject`s that satisfy the specified `FetchClause`s
|
||||
*/
|
||||
public func fetchCount<T: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> Int? {
|
||||
public func fetchCount<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) -> Int? {
|
||||
|
||||
CoreStore.assert(
|
||||
self.isRunningInAllowedQueue(),
|
||||
@@ -210,6 +269,27 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
||||
return self.context.fetchCount(from, fetchClauses)
|
||||
}
|
||||
|
||||
/**
|
||||
Fetches the number of `DynamicObject`s that satisfy the specified `FetchChainableBuilderType` built from a chain of clauses.
|
||||
```
|
||||
let numberOfAdults = transaction.fetchCount(
|
||||
From<MyPersonEntity>()
|
||||
.where(\.age > 18)
|
||||
.orderBy(.ascending(\.age))
|
||||
)
|
||||
```
|
||||
- parameter clauseChain: a `FetchChainableBuilderType` built from a chain of clauses
|
||||
- returns: the number `DynamicObject`s that satisfy the specified `FetchChainableBuilderType`
|
||||
*/
|
||||
public func fetchCount<B: FetchChainableBuilderType>(_ clauseChain: B) -> Int? {
|
||||
|
||||
CoreStore.assert(
|
||||
self.isRunningInAllowedQueue(),
|
||||
"Attempted to fetch from a \(cs_typeName(self)) outside its designated queue."
|
||||
)
|
||||
return self.context.fetchCount(clauseChain)
|
||||
}
|
||||
|
||||
/**
|
||||
Fetches the `NSManagedObjectID` for the first `DynamicObject` that satisfies the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
|
||||
@@ -217,7 +297,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
- returns: the `NSManagedObjectID` for the first `DynamicObject` that satisfies the specified `FetchClause`s
|
||||
*/
|
||||
public func fetchObjectID<T: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> NSManagedObjectID? {
|
||||
public func fetchObjectID<D>(_ from: From<D>, _ fetchClauses: FetchClause...) -> NSManagedObjectID? {
|
||||
|
||||
CoreStore.assert(
|
||||
self.isRunningInAllowedQueue(),
|
||||
@@ -233,7 +313,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
- returns: the `NSManagedObjectID` for the first `DynamicObject` that satisfies the specified `FetchClause`s
|
||||
*/
|
||||
public func fetchObjectID<T: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> NSManagedObjectID? {
|
||||
public func fetchObjectID<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) -> NSManagedObjectID? {
|
||||
|
||||
CoreStore.assert(
|
||||
self.isRunningInAllowedQueue(),
|
||||
@@ -242,6 +322,27 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
||||
return self.context.fetchObjectID(from, fetchClauses)
|
||||
}
|
||||
|
||||
/**
|
||||
Fetches the `NSManagedObjectID` for the first `DynamicObject` that satisfies the specified `FetchChainableBuilderType` built from a chain of clauses.
|
||||
```
|
||||
let youngestTeenID = transaction.fetchObjectID(
|
||||
From<MyPersonEntity>()
|
||||
.where(\.age > 18)
|
||||
.orderBy(.ascending(\.age))
|
||||
)
|
||||
```
|
||||
- parameter clauseChain: a `FetchChainableBuilderType` built from a chain of clauses
|
||||
- returns: the `NSManagedObjectID` for the first `DynamicObject` that satisfies the specified `FetchChainableBuilderType`
|
||||
*/
|
||||
public func fetchObjectID<B: FetchChainableBuilderType>(_ clauseChain: B) -> NSManagedObjectID? {
|
||||
|
||||
CoreStore.assert(
|
||||
self.isRunningInAllowedQueue(),
|
||||
"Attempted to fetch from a \(cs_typeName(self)) outside its designated queue."
|
||||
)
|
||||
return self.context.fetchObjectID(clauseChain)
|
||||
}
|
||||
|
||||
/**
|
||||
Fetches the `NSManagedObjectID` for all `DynamicObject`s that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
|
||||
@@ -249,7 +350,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
- returns: the `NSManagedObjectID` for all `DynamicObject`s that satisfy the specified `FetchClause`s
|
||||
*/
|
||||
public func fetchObjectIDs<T: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> [NSManagedObjectID]? {
|
||||
public func fetchObjectIDs<D>(_ from: From<D>, _ fetchClauses: FetchClause...) -> [NSManagedObjectID]? {
|
||||
|
||||
CoreStore.assert(
|
||||
self.isRunningInAllowedQueue(),
|
||||
@@ -265,7 +366,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
- returns: the `NSManagedObjectID` for all `DynamicObject`s that satisfy the specified `FetchClause`s
|
||||
*/
|
||||
public func fetchObjectIDs<T: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> [NSManagedObjectID]? {
|
||||
public func fetchObjectIDs<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) -> [NSManagedObjectID]? {
|
||||
|
||||
CoreStore.assert(
|
||||
self.isRunningInAllowedQueue(),
|
||||
@@ -274,6 +375,27 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
||||
return self.context.fetchObjectIDs(from, fetchClauses)
|
||||
}
|
||||
|
||||
/**
|
||||
Fetches the `NSManagedObjectID` for all `DynamicObject`s that satisfy the specified `FetchChainableBuilderType` built from a chain of clauses.
|
||||
```
|
||||
let idsOfAdults = transaction.fetchObjectIDs(
|
||||
From<MyPersonEntity>()
|
||||
.where(\.age > 18)
|
||||
.orderBy(.ascending(\.age))
|
||||
)
|
||||
```
|
||||
- parameter clauseChain: a `FetchChainableBuilderType` built from a chain of clauses
|
||||
- returns: the `NSManagedObjectID` for all `DynamicObject`s that satisfy the specified `FetchChainableBuilderType`
|
||||
*/
|
||||
public func fetchObjectIDs<B: FetchChainableBuilderType>(_ clauseChain: B) -> [NSManagedObjectID]? {
|
||||
|
||||
CoreStore.assert(
|
||||
self.isRunningInAllowedQueue(),
|
||||
"Attempted to fetch from a \(cs_typeName(self)) outside its designated queue."
|
||||
)
|
||||
return self.context.fetchObjectIDs(clauseChain)
|
||||
}
|
||||
|
||||
|
||||
// MARK: QueryableSource
|
||||
|
||||
@@ -287,7 +409,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
||||
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
||||
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
|
||||
*/
|
||||
public func queryValue<T: DynamicObject, U: QueryableAttributeType>(_ from: From<T>, _ selectClause: Select<U>, _ queryClauses: QueryClause...) -> U? {
|
||||
public func queryValue<D, U: QueryableAttributeType>(_ from: From<D>, _ selectClause: Select<D, U>, _ queryClauses: QueryClause...) -> U? {
|
||||
|
||||
CoreStore.assert(
|
||||
self.isRunningInAllowedQueue(),
|
||||
@@ -306,7 +428,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
||||
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
||||
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
|
||||
*/
|
||||
public func queryValue<T: DynamicObject, U: QueryableAttributeType>(_ from: From<T>, _ selectClause: Select<U>, _ queryClauses: [QueryClause]) -> U? {
|
||||
public func queryValue<D, U: QueryableAttributeType>(_ from: From<D>, _ selectClause: Select<D, U>, _ queryClauses: [QueryClause]) -> U? {
|
||||
|
||||
CoreStore.assert(
|
||||
self.isRunningInAllowedQueue(),
|
||||
@@ -315,6 +437,29 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
||||
return self.context.queryValue(from, selectClause, queryClauses)
|
||||
}
|
||||
|
||||
/**
|
||||
Queries a property value or aggregate as specified by the `QueryChainableBuilderType` built from a chain of clauses.
|
||||
|
||||
A "query" differs from a "fetch" in that it only retrieves values already stored in the persistent store. As such, values from unsaved transactions or contexts will not be incorporated in the query result.
|
||||
```
|
||||
let averageAdultAge = transaction.queryValue(
|
||||
From<MyPersonEntity>()
|
||||
.select(Int.self, .average(\.age))
|
||||
.where(\.age > 18)
|
||||
)
|
||||
```
|
||||
- parameter clauseChain: a `QueryChainableBuilderType` indicating the property/aggregate to fetch and the series of queries for the request.
|
||||
- returns: the result of the the query as specified by the `QueryChainableBuilderType`
|
||||
*/
|
||||
public func queryValue<B: QueryChainableBuilderType>(_ clauseChain: B) -> B.ResultType? where B.ResultType: QueryableAttributeType {
|
||||
|
||||
CoreStore.assert(
|
||||
self.isRunningInAllowedQueue(),
|
||||
"Attempted to query from a \(cs_typeName(self)) outside its designated queue."
|
||||
)
|
||||
return self.context.queryValue(clauseChain.from, clauseChain.select, clauseChain.queryClauses)
|
||||
}
|
||||
|
||||
/**
|
||||
Queries a dictionary of attribute values as specified by the `QueryClause`s. Requires at least a `Select` clause, and optional `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
||||
|
||||
@@ -325,7 +470,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
||||
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
||||
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
|
||||
*/
|
||||
public func queryAttributes<T: DynamicObject>(_ from: From<T>, _ selectClause: Select<NSDictionary>, _ queryClauses: QueryClause...) -> [[String: Any]]? {
|
||||
public func queryAttributes<D>(_ from: From<D>, _ selectClause: Select<D, NSDictionary>, _ queryClauses: QueryClause...) -> [[String: Any]]? {
|
||||
|
||||
CoreStore.assert(
|
||||
self.isRunningInAllowedQueue(),
|
||||
@@ -344,7 +489,7 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
||||
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
||||
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
|
||||
*/
|
||||
public func queryAttributes<T: DynamicObject>(_ from: From<T>, _ selectClause: Select<NSDictionary>, _ queryClauses: [QueryClause]) -> [[String: Any]]? {
|
||||
public func queryAttributes<D>(_ from: From<D>, _ selectClause: Select<D, NSDictionary>, _ queryClauses: [QueryClause]) -> [[String: Any]]? {
|
||||
|
||||
CoreStore.assert(
|
||||
self.isRunningInAllowedQueue(),
|
||||
@@ -353,6 +498,38 @@ extension BaseDataTransaction: FetchableSource, QueryableSource {
|
||||
return self.context.queryAttributes(from, selectClause, queryClauses)
|
||||
}
|
||||
|
||||
/**
|
||||
Queries a dictionary of attribute values or as specified by the `QueryChainableBuilderType` built from a chain of clauses.
|
||||
|
||||
A "query" differs from a "fetch" in that it only retrieves values already stored in the persistent store. As such, values from unsaved transactions or contexts will not be incorporated in the query result.
|
||||
```
|
||||
let results = dataStack.queryAttributes(
|
||||
From<MyPersonEntity>()
|
||||
.select(
|
||||
NSDictionary.self,
|
||||
.attribute(\.age, as: "age"),
|
||||
.count(\.age, as: "numberOfPeople")
|
||||
)
|
||||
.groupBy(\.age)
|
||||
)
|
||||
for dictionary in results! {
|
||||
let age = dictionary["age"] as! Int
|
||||
let count = dictionary["numberOfPeople"] as! Int
|
||||
print("There are \(count) people who are \(age) years old."
|
||||
}
|
||||
```
|
||||
- parameter clauseChain: a `QueryChainableBuilderType` indicating the properties to fetch and the series of queries for the request.
|
||||
- returns: the result of the the query as specified by the `QueryChainableBuilderType`
|
||||
*/
|
||||
public func queryAttributes<B: QueryChainableBuilderType>(_ clauseChain: B) -> [[String: Any]]? where B.ResultType == NSDictionary {
|
||||
|
||||
CoreStore.assert(
|
||||
self.isRunningInAllowedQueue(),
|
||||
"Attempted to query from a \(cs_typeName(self)) outside its designated queue."
|
||||
)
|
||||
return self.context.queryAttributes(clauseChain.from, clauseChain.select, clauseChain.queryClauses)
|
||||
}
|
||||
|
||||
|
||||
// MARK: FetchableSource, QueryableSource
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ public /*abstract*/ class BaseDataTransaction {
|
||||
- parameter into: the `Into` clause indicating the destination `NSManagedObject` or `CoreStoreObject` entity type and the destination configuration
|
||||
- returns: a new `NSManagedObject` or `CoreStoreObject` instance of the specified entity type.
|
||||
*/
|
||||
public func create<T: DynamicObject>(_ into: Into<T>) -> T {
|
||||
public func create<D>(_ into: Into<D>) -> D {
|
||||
|
||||
let entityClass = into.entityClass
|
||||
CoreStore.assert(
|
||||
@@ -116,12 +116,12 @@ public /*abstract*/ class BaseDataTransaction {
|
||||
}
|
||||
|
||||
/**
|
||||
Returns an editable proxy of a specified `NSManagedObject`.
|
||||
Returns an editable proxy of a specified `NSManagedObject` or `CoreStoreObject`.
|
||||
|
||||
- parameter object: the `NSManagedObject` type to be edited
|
||||
- returns: an editable proxy for the specified `NSManagedObject`.
|
||||
- parameter object: the `NSManagedObject` or `CoreStoreObject` type to be edited
|
||||
- returns: an editable proxy for the specified `NSManagedObject` or `CoreStoreObject`.
|
||||
*/
|
||||
public func edit<T: DynamicObject>(_ object: T?) -> T? {
|
||||
public func edit<D: DynamicObject>(_ object: D?) -> D? {
|
||||
|
||||
CoreStore.assert(
|
||||
self.isRunningInAllowedQueue(),
|
||||
@@ -139,9 +139,9 @@ public /*abstract*/ class BaseDataTransaction {
|
||||
|
||||
- parameter into: an `Into` clause specifying the entity type
|
||||
- parameter objectID: the `NSManagedObjectID` for the object to be edited
|
||||
- returns: an editable proxy for the specified `NSManagedObject`.
|
||||
- returns: an editable proxy for the specified `NSManagedObject` or `CoreStoreObject`.
|
||||
*/
|
||||
public func edit<T: DynamicObject>(_ into: Into<T>, _ objectID: NSManagedObjectID) -> T? {
|
||||
public func edit<D>(_ into: Into<D>, _ objectID: NSManagedObjectID) -> D? {
|
||||
|
||||
CoreStore.assert(
|
||||
self.isRunningInAllowedQueue(),
|
||||
@@ -156,11 +156,11 @@ public /*abstract*/ class BaseDataTransaction {
|
||||
}
|
||||
|
||||
/**
|
||||
Deletes a specified `NSManagedObject`.
|
||||
Deletes a specified `NSManagedObject` or `CoreStoreObject`.
|
||||
|
||||
- parameter object: the `NSManagedObject` to be deleted
|
||||
- parameter object: the `NSManagedObject` or `CoreStoreObject` to be deleted
|
||||
*/
|
||||
public func delete<T: DynamicObject>(_ object: T?) {
|
||||
public func delete<D: DynamicObject>(_ object: D?) {
|
||||
|
||||
CoreStore.assert(
|
||||
self.isRunningInAllowedQueue(),
|
||||
@@ -173,21 +173,21 @@ public /*abstract*/ class BaseDataTransaction {
|
||||
}
|
||||
|
||||
/**
|
||||
Deletes the specified `NSManagedObject`s.
|
||||
Deletes the specified `NSManagedObject`s or `CoreStoreObject`s.
|
||||
|
||||
- parameter object1: the `NSManagedObject` to be deleted
|
||||
- parameter object2: another `NSManagedObject` to be deleted
|
||||
- parameter objects: other `NSManagedObject`s to be deleted
|
||||
- parameter object1: the `NSManagedObject` or `CoreStoreObject` to be deleted
|
||||
- parameter object2: another `NSManagedObject` or `CoreStoreObject` to be deleted
|
||||
- parameter objects: other `NSManagedObject`s or `CoreStoreObject`s to be deleted
|
||||
*/
|
||||
public func delete<T: DynamicObject>(_ object1: T?, _ object2: T?, _ objects: T?...) {
|
||||
public func delete<D: DynamicObject>(_ object1: D?, _ object2: D?, _ objects: D?...) {
|
||||
|
||||
self.delete(([object1, object2] + objects).flatMap { $0 })
|
||||
self.delete(([object1, object2] + objects).compactMap { $0 })
|
||||
}
|
||||
|
||||
/**
|
||||
Deletes the specified `NSManagedObject`s.
|
||||
Deletes the specified `NSManagedObject`s or `CoreStoreObject`s.
|
||||
|
||||
- parameter objects: the `NSManagedObject`s to be deleted
|
||||
- parameter objects: the `NSManagedObject`s or `CoreStoreObject`s to be deleted
|
||||
*/
|
||||
public func delete<S: Sequence>(_ objects: S) where S.Iterator.Element: DynamicObject {
|
||||
|
||||
@@ -220,7 +220,7 @@ public /*abstract*/ class BaseDataTransaction {
|
||||
- parameter entity: the `DynamicObject` subclass to filter
|
||||
- returns: a `Set` of pending `DynamicObject`s of the specified type that were inserted to the transaction.
|
||||
*/
|
||||
public func insertedObjects<T: DynamicObject>(_ entity: T.Type) -> Set<T> {
|
||||
public func insertedObjects<D: DynamicObject>(_ entity: D.Type) -> Set<D> {
|
||||
|
||||
CoreStore.assert(
|
||||
self.transactionQueue.cs_isCurrentExecutionContext(),
|
||||
@@ -230,7 +230,7 @@ public /*abstract*/ class BaseDataTransaction {
|
||||
!self.isCommitted,
|
||||
"Attempted to access inserted objects from an already committed \(cs_typeName(self))."
|
||||
)
|
||||
return Set(self.context.insertedObjects.flatMap({ entity.cs_matches(object: $0) ? entity.cs_fromRaw(object: $0) : nil }))
|
||||
return Set(self.context.insertedObjects.compactMap({ entity.cs_matches(object: $0) ? entity.cs_fromRaw(object: $0) : nil }))
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -257,7 +257,7 @@ public /*abstract*/ class BaseDataTransaction {
|
||||
- parameter entity: the `DynamicObject` subclass to filter
|
||||
- returns: a `Set` of pending `NSManagedObjectID`s of the specified type that were inserted to the transaction.
|
||||
*/
|
||||
public func insertedObjectIDs<T: DynamicObject>(_ entity: T.Type) -> Set<NSManagedObjectID> {
|
||||
public func insertedObjectIDs<D: DynamicObject>(_ entity: D.Type) -> Set<NSManagedObjectID> {
|
||||
|
||||
CoreStore.assert(
|
||||
self.transactionQueue.cs_isCurrentExecutionContext(),
|
||||
@@ -267,7 +267,7 @@ public /*abstract*/ class BaseDataTransaction {
|
||||
!self.isCommitted,
|
||||
"Attempted to access inserted objects IDs from an already committed \(cs_typeName(self))."
|
||||
)
|
||||
return Set(self.context.insertedObjects.flatMap({ entity.cs_matches(object: $0) ? $0.objectID : nil }))
|
||||
return Set(self.context.insertedObjects.compactMap({ entity.cs_matches(object: $0) ? $0.objectID : nil }))
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -276,7 +276,7 @@ public /*abstract*/ class BaseDataTransaction {
|
||||
- parameter entity: the `DynamicObject` subclass to filter
|
||||
- returns: a `Set` of pending `DynamicObject`s of the specified type that were updated in the transaction.
|
||||
*/
|
||||
public func updatedObjects<T: DynamicObject>(_ entity: T.Type) -> Set<T> {
|
||||
public func updatedObjects<D: DynamicObject>(_ entity: D.Type) -> Set<D> {
|
||||
|
||||
CoreStore.assert(
|
||||
self.transactionQueue.cs_isCurrentExecutionContext(),
|
||||
@@ -286,7 +286,7 @@ public /*abstract*/ class BaseDataTransaction {
|
||||
!self.isCommitted,
|
||||
"Attempted to access updated objects from an already committed \(cs_typeName(self))."
|
||||
)
|
||||
return Set(self.context.updatedObjects.flatMap({ entity.cs_matches(object: $0) ? entity.cs_fromRaw(object: $0) : nil }))
|
||||
return Set(self.context.updatedObjects.compactMap({ entity.cs_matches(object: $0) ? entity.cs_fromRaw(object: $0) : nil }))
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -313,7 +313,7 @@ public /*abstract*/ class BaseDataTransaction {
|
||||
- parameter entity: the `DynamicObject` subclass to filter
|
||||
- returns: a `Set` of pending `NSManagedObjectID`s of the specified type that were updated in the transaction.
|
||||
*/
|
||||
public func updatedObjectIDs<T: DynamicObject>(_ entity: T.Type) -> Set<NSManagedObjectID> {
|
||||
public func updatedObjectIDs<D: DynamicObject>(_ entity: D.Type) -> Set<NSManagedObjectID> {
|
||||
|
||||
CoreStore.assert(
|
||||
self.transactionQueue.cs_isCurrentExecutionContext(),
|
||||
@@ -323,7 +323,7 @@ public /*abstract*/ class BaseDataTransaction {
|
||||
!self.isCommitted,
|
||||
"Attempted to access updated object IDs from an already committed \(cs_typeName(self))."
|
||||
)
|
||||
return Set(self.context.updatedObjects.flatMap({ entity.cs_matches(object: $0) ? $0.objectID : nil }))
|
||||
return Set(self.context.updatedObjects.compactMap({ entity.cs_matches(object: $0) ? $0.objectID : nil }))
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -332,7 +332,7 @@ public /*abstract*/ class BaseDataTransaction {
|
||||
- parameter entity: the `DynamicObject` subclass to filter
|
||||
- returns: a `Set` of pending `DynamicObject`s of the specified type that were deleted from the transaction.
|
||||
*/
|
||||
public func deletedObjects<T: DynamicObject>(_ entity: T.Type) -> Set<T> {
|
||||
public func deletedObjects<D: DynamicObject>(_ entity: D.Type) -> Set<D> {
|
||||
|
||||
CoreStore.assert(
|
||||
self.transactionQueue.cs_isCurrentExecutionContext(),
|
||||
@@ -342,7 +342,7 @@ public /*abstract*/ class BaseDataTransaction {
|
||||
!self.isCommitted,
|
||||
"Attempted to access deleted objects from an already committed \(cs_typeName(self))."
|
||||
)
|
||||
return Set(self.context.deletedObjects.flatMap({ entity.cs_matches(object: $0) ? entity.cs_fromRaw(object: $0) : nil }))
|
||||
return Set(self.context.deletedObjects.compactMap({ entity.cs_matches(object: $0) ? entity.cs_fromRaw(object: $0) : nil }))
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -370,7 +370,7 @@ public /*abstract*/ class BaseDataTransaction {
|
||||
- parameter entity: the `DynamicObject` subclass to filter
|
||||
- returns: a `Set` of pending `NSManagedObjectID`s of the specified type that were deleted from the transaction.
|
||||
*/
|
||||
public func deletedObjectIDs<T: DynamicObject>(_ entity: T.Type) -> Set<NSManagedObjectID> {
|
||||
public func deletedObjectIDs<D: DynamicObject>(_ entity: D.Type) -> Set<NSManagedObjectID> {
|
||||
|
||||
CoreStore.assert(
|
||||
self.transactionQueue.cs_isCurrentExecutionContext(),
|
||||
@@ -380,7 +380,7 @@ public /*abstract*/ class BaseDataTransaction {
|
||||
!self.isCommitted,
|
||||
"Attempted to access deleted object IDs from an already committed \(cs_typeName(self))."
|
||||
)
|
||||
return Set(self.context.deletedObjects.flatMap({ entity.cs_matches(object: $0) ? $0.objectID : nil }))
|
||||
return Set(self.context.deletedObjects.compactMap({ entity.cs_matches(object: $0) ? $0.objectID : nil }))
|
||||
}
|
||||
|
||||
|
||||
@@ -438,6 +438,11 @@ public /*abstract*/ class BaseDataTransaction {
|
||||
return self.bypassesQueueing || self.transactionQueue.cs_isCurrentExecutionContext()
|
||||
}
|
||||
|
||||
deinit {
|
||||
|
||||
self.context.reset()
|
||||
}
|
||||
|
||||
|
||||
// MARK: Deprecated
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ import CoreData
|
||||
- SeeAlso: `AsynchronousDataTransaction`
|
||||
*/
|
||||
@objc
|
||||
public final class CSAsynchronousDataTransaction: CSBaseDataTransaction {
|
||||
public final class CSAsynchronousDataTransaction: CSBaseDataTransaction, CoreStoreObjectiveCType {
|
||||
|
||||
/**
|
||||
Saves the transaction changes. This method should not be used after the `-commitWithCompletion:` method was already called once.
|
||||
@@ -54,12 +54,15 @@ public final class CSAsynchronousDataTransaction: CSBaseDataTransaction {
|
||||
!self.bridgeToSwift.isCommitted,
|
||||
"Attempted to commit a \(cs_typeName(self)) more than once."
|
||||
)
|
||||
self.bridgeToSwift.autoCommit { (result) in
|
||||
self.bridgeToSwift.autoCommit { (_, error) in
|
||||
|
||||
switch result {
|
||||
if let error = error {
|
||||
|
||||
case (_, nil): success?()
|
||||
case (_, let error?): failure?(error.bridgeToObjectiveC)
|
||||
failure?(error.bridgeToObjectiveC)
|
||||
}
|
||||
else {
|
||||
|
||||
success?()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -139,9 +142,9 @@ public final class CSAsynchronousDataTransaction: CSBaseDataTransaction {
|
||||
|
||||
public typealias SwiftType = AsynchronousDataTransaction
|
||||
|
||||
public override var bridgeToSwift: AsynchronousDataTransaction {
|
||||
public var bridgeToSwift: AsynchronousDataTransaction {
|
||||
|
||||
return super.bridgeToSwift as! AsynchronousDataTransaction
|
||||
return super.swiftTransaction as! AsynchronousDataTransaction
|
||||
}
|
||||
|
||||
public required init(_ swiftValue: AsynchronousDataTransaction) {
|
||||
@@ -149,9 +152,9 @@ public final class CSAsynchronousDataTransaction: CSBaseDataTransaction {
|
||||
super.init(swiftValue as BaseDataTransaction)
|
||||
}
|
||||
|
||||
public required init(_ swiftValue: BaseDataTransaction) {
|
||||
public required override init(_ swiftValue: BaseDataTransaction) {
|
||||
|
||||
super.init(swiftValue as! AsynchronousDataTransaction)
|
||||
super.init(swiftValue)
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ public extension CSBaseDataTransaction {
|
||||
@objc
|
||||
public func fetchExistingObject(_ object: NSManagedObject) -> Any? {
|
||||
|
||||
return self.bridgeToSwift.context.fetchExisting(object) as NSManagedObject?
|
||||
return self.swiftTransaction.context.fetchExisting(object) as NSManagedObject?
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -52,7 +52,7 @@ public extension CSBaseDataTransaction {
|
||||
@objc
|
||||
public func fetchExistingObjectWithID(_ objectID: NSManagedObjectID) -> Any? {
|
||||
|
||||
return self.bridgeToSwift.context.fetchExisting(objectID) as NSManagedObject?
|
||||
return self.swiftTransaction.context.fetchExisting(objectID) as NSManagedObject?
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -64,7 +64,7 @@ public extension CSBaseDataTransaction {
|
||||
@objc
|
||||
public func fetchExistingObjects(_ objects: [NSManagedObject]) -> [Any] {
|
||||
|
||||
return self.bridgeToSwift.context.fetchExisting(objects) as [NSManagedObject]
|
||||
return self.swiftTransaction.context.fetchExisting(objects) as [NSManagedObject]
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -76,7 +76,7 @@ public extension CSBaseDataTransaction {
|
||||
@objc
|
||||
public func fetchExistingObjectsWithIDs(_ objectIDs: [NSManagedObjectID]) -> [Any] {
|
||||
|
||||
return self.bridgeToSwift.context.fetchExisting(objectIDs) as [NSManagedObject]
|
||||
return self.swiftTransaction.context.fetchExisting(objectIDs) as [NSManagedObject]
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -90,10 +90,10 @@ public extension CSBaseDataTransaction {
|
||||
public func fetchOneFrom(_ from: CSFrom, fetchClauses: [CSFetchClause]) -> Any? {
|
||||
|
||||
CoreStore.assert(
|
||||
self.bridgeToSwift.isRunningInAllowedQueue(),
|
||||
self.swiftTransaction.isRunningInAllowedQueue(),
|
||||
"Attempted to fetch from a \(cs_typeName(self)) outside its designated queue."
|
||||
)
|
||||
return self.bridgeToSwift.context.fetchOne(from, fetchClauses)
|
||||
return self.swiftTransaction.context.fetchOne(from, fetchClauses)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -107,10 +107,10 @@ public extension CSBaseDataTransaction {
|
||||
public func fetchAllFrom(_ from: CSFrom, fetchClauses: [CSFetchClause]) -> [Any]? {
|
||||
|
||||
CoreStore.assert(
|
||||
self.bridgeToSwift.isRunningInAllowedQueue(),
|
||||
self.swiftTransaction.isRunningInAllowedQueue(),
|
||||
"Attempted to fetch from a \(cs_typeName(self)) outside its designated queue."
|
||||
)
|
||||
return self.bridgeToSwift.context.fetchAll(from, fetchClauses)
|
||||
return self.swiftTransaction.context.fetchAll(from, fetchClauses)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -124,10 +124,10 @@ public extension CSBaseDataTransaction {
|
||||
public func fetchCountFrom(_ from: CSFrom, fetchClauses: [CSFetchClause]) -> NSNumber? {
|
||||
|
||||
CoreStore.assert(
|
||||
self.bridgeToSwift.isRunningInAllowedQueue(),
|
||||
self.swiftTransaction.isRunningInAllowedQueue(),
|
||||
"Attempted to fetch from a \(cs_typeName(self)) outside its designated queue."
|
||||
)
|
||||
return self.bridgeToSwift.context
|
||||
return self.swiftTransaction.context
|
||||
.fetchCount(from, fetchClauses)
|
||||
.flatMap { NSNumber(value: $0) }
|
||||
}
|
||||
@@ -143,10 +143,10 @@ public extension CSBaseDataTransaction {
|
||||
public func fetchObjectIDFrom(_ from: CSFrom, fetchClauses: [CSFetchClause]) -> NSManagedObjectID? {
|
||||
|
||||
CoreStore.assert(
|
||||
self.bridgeToSwift.isRunningInAllowedQueue(),
|
||||
self.swiftTransaction.isRunningInAllowedQueue(),
|
||||
"Attempted to fetch from a \(cs_typeName(self)) outside its designated queue."
|
||||
)
|
||||
return self.bridgeToSwift.context.fetchObjectID(from, fetchClauses)
|
||||
return self.swiftTransaction.context.fetchObjectID(from, fetchClauses)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -163,10 +163,10 @@ public extension CSBaseDataTransaction {
|
||||
public func queryValueFrom(_ from: CSFrom, selectClause: CSSelect, queryClauses: [CSQueryClause]) -> Any? {
|
||||
|
||||
CoreStore.assert(
|
||||
self.bridgeToSwift.isRunningInAllowedQueue(),
|
||||
self.swiftTransaction.isRunningInAllowedQueue(),
|
||||
"Attempted to query from a \(cs_typeName(self)) outside its designated queue."
|
||||
)
|
||||
return self.bridgeToSwift.context.queryValue(from, selectClause, queryClauses)
|
||||
return self.swiftTransaction.context.queryValue(from, selectClause, queryClauses)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -183,9 +183,9 @@ public extension CSBaseDataTransaction {
|
||||
public func queryAttributesFrom(_ from: CSFrom, selectClause: CSSelect, queryClauses: [CSQueryClause]) -> [[String: Any]]? {
|
||||
|
||||
CoreStore.assert(
|
||||
self.bridgeToSwift.isRunningInAllowedQueue(),
|
||||
self.swiftTransaction.isRunningInAllowedQueue(),
|
||||
"Attempted to query from a \(cs_typeName(self)) outside its designated queue."
|
||||
)
|
||||
return self.bridgeToSwift.context.queryAttributes(from, selectClause, queryClauses)
|
||||
return self.swiftTransaction.context.queryAttributes(from, selectClause, queryClauses)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ import CoreData
|
||||
- SeeAlso: `BaseDataTransaction`
|
||||
*/
|
||||
@objc
|
||||
public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
|
||||
public class CSBaseDataTransaction: NSObject {
|
||||
|
||||
// MARK: Object management
|
||||
|
||||
@@ -45,7 +45,7 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
|
||||
@objc
|
||||
public var hasChanges: Bool {
|
||||
|
||||
return self.bridgeToSwift.hasChanges
|
||||
return self.swiftTransaction.hasChanges
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -57,7 +57,7 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
|
||||
@objc
|
||||
public func createInto(_ into: CSInto) -> Any {
|
||||
|
||||
return self.bridgeToSwift.create(into.bridgeToSwift)
|
||||
return self.swiftTransaction.create(into.bridgeToSwift)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -69,7 +69,7 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
|
||||
@objc
|
||||
public func editObject(_ object: NSManagedObject?) -> Any? {
|
||||
|
||||
return self.bridgeToSwift.edit(object)
|
||||
return self.swiftTransaction.edit(object)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -82,7 +82,7 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
|
||||
@objc
|
||||
public func editInto(_ into: CSInto, objectID: NSManagedObjectID) -> Any? {
|
||||
|
||||
return self.bridgeToSwift.edit(into.bridgeToSwift, objectID)
|
||||
return self.swiftTransaction.edit(into.bridgeToSwift, objectID)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -93,7 +93,7 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
|
||||
@objc
|
||||
public func deleteObject(_ object: NSManagedObject?) {
|
||||
|
||||
self.bridgeToSwift.delete(object)
|
||||
self.swiftTransaction.delete(object)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -104,7 +104,7 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
|
||||
@objc
|
||||
public func deleteObjects(_ objects: [NSManagedObject]) {
|
||||
|
||||
self.bridgeToSwift.delete(objects)
|
||||
self.swiftTransaction.delete(objects)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -113,7 +113,7 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
|
||||
@objc
|
||||
public func refreshAndMergeAllObjects() {
|
||||
|
||||
self.bridgeToSwift.refreshAndMergeAllObjects()
|
||||
self.swiftTransaction.refreshAndMergeAllObjects()
|
||||
}
|
||||
|
||||
|
||||
@@ -128,7 +128,7 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
|
||||
@objc
|
||||
public func insertedObjectsOfType(_ entity: NSManagedObject.Type) -> Set<NSManagedObject> {
|
||||
|
||||
return self.bridgeToSwift.insertedObjects(entity)
|
||||
return self.swiftTransaction.insertedObjects(entity)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -139,7 +139,7 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
|
||||
@objc
|
||||
public func insertedObjectIDs() -> Set<NSManagedObjectID> {
|
||||
|
||||
return self.bridgeToSwift.insertedObjectIDs()
|
||||
return self.swiftTransaction.insertedObjectIDs()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -151,7 +151,7 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
|
||||
@objc
|
||||
public func insertedObjectIDsOfType(_ entity: NSManagedObject.Type) -> Set<NSManagedObjectID> {
|
||||
|
||||
return self.bridgeToSwift.insertedObjectIDs(entity)
|
||||
return self.swiftTransaction.insertedObjectIDs(entity)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -163,7 +163,7 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
|
||||
@objc
|
||||
public func updatedObjectsOfType(_ entity: NSManagedObject.Type) -> Set<NSManagedObject> {
|
||||
|
||||
return self.bridgeToSwift.updatedObjects(entity)
|
||||
return self.swiftTransaction.updatedObjects(entity)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -174,7 +174,7 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
|
||||
@objc
|
||||
public func updatedObjectIDs() -> Set<NSManagedObjectID> {
|
||||
|
||||
return self.bridgeToSwift.updatedObjectIDs()
|
||||
return self.swiftTransaction.updatedObjectIDs()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -186,7 +186,7 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
|
||||
@objc
|
||||
public func updatedObjectIDsOfType(_ entity: NSManagedObject.Type) -> Set<NSManagedObjectID> {
|
||||
|
||||
return self.bridgeToSwift.updatedObjectIDs(entity)
|
||||
return self.swiftTransaction.updatedObjectIDs(entity)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -198,7 +198,7 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
|
||||
@objc
|
||||
public func deletedObjectsOfType(_ entity: NSManagedObject.Type) -> Set<NSManagedObject> {
|
||||
|
||||
return self.bridgeToSwift.deletedObjects(entity)
|
||||
return self.swiftTransaction.deletedObjects(entity)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -209,7 +209,7 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
|
||||
@objc
|
||||
public func deletedObjectIDs() -> Set<NSManagedObjectID> {
|
||||
|
||||
return self.bridgeToSwift.deletedObjectIDs()
|
||||
return self.swiftTransaction.deletedObjectIDs()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -221,7 +221,7 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
|
||||
@objc
|
||||
public func deletedObjectIDsOfType(_ entity: NSManagedObject.Type) -> Set<NSManagedObjectID> {
|
||||
|
||||
return self.bridgeToSwift.deletedObjectIDs(entity)
|
||||
return self.swiftTransaction.deletedObjectIDs(entity)
|
||||
}
|
||||
|
||||
|
||||
@@ -229,7 +229,7 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
|
||||
|
||||
public override var hash: Int {
|
||||
|
||||
return ObjectIdentifier(self.bridgeToSwift).hashValue
|
||||
return ObjectIdentifier(self.swiftTransaction).hashValue
|
||||
}
|
||||
|
||||
public override func isEqual(_ object: Any?) -> Bool {
|
||||
@@ -238,28 +238,20 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
|
||||
|
||||
return false
|
||||
}
|
||||
return self.bridgeToSwift === object.bridgeToSwift
|
||||
return self.swiftTransaction === object.swiftTransaction
|
||||
}
|
||||
|
||||
|
||||
// MARK: CoreStoreObjectiveCType
|
||||
// MARK: Internal
|
||||
|
||||
public required init(_ swiftValue: BaseDataTransaction) {
|
||||
internal let swiftTransaction: BaseDataTransaction
|
||||
|
||||
internal init(_ swiftValue: BaseDataTransaction) {
|
||||
|
||||
self.swiftTransaction = swiftValue
|
||||
super.init()
|
||||
}
|
||||
|
||||
public var bridgeToSwift: BaseDataTransaction {
|
||||
|
||||
return self.swiftTransaction
|
||||
}
|
||||
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private let swiftTransaction: BaseDataTransaction
|
||||
|
||||
|
||||
// MARK: Deprecated
|
||||
|
||||
@@ -267,20 +259,20 @@ public class CSBaseDataTransaction: NSObject, CoreStoreObjectiveCType {
|
||||
@objc
|
||||
public func insertedObjects() -> Set<NSManagedObject> {
|
||||
|
||||
return self.bridgeToSwift.insertedObjects()
|
||||
return self.swiftTransaction.insertedObjects()
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "Use -[updatedObjectsOfType:] and pass the specific entity class")
|
||||
@objc
|
||||
public func updatedObjects() -> Set<NSManagedObject> {
|
||||
|
||||
return self.bridgeToSwift.updatedObjects()
|
||||
return self.swiftTransaction.updatedObjects()
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "Use -[deletedObjectsOfType:] and pass the specific entity class")
|
||||
@objc
|
||||
public func deletedObjects() -> Set<NSManagedObject> {
|
||||
|
||||
return self.bridgeToSwift.deletedObjects()
|
||||
return self.swiftTransaction.deletedObjects()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,41 +49,22 @@ public final class CSDataStack: NSObject, CoreStoreObjectiveCType {
|
||||
/**
|
||||
Initializes a `CSDataStack` from the model with the specified `modelName` in the specified `bundle`.
|
||||
|
||||
- parameter modelName: the name of the (.xcdatamodeld) model file. If not specified, the application name (CFBundleName) will be used if it exists, or "CoreData" if it the bundle name was not set.
|
||||
- parameter xcodeModelName: the name of the (.xcdatamodeld) model file. If not specified, the application name (CFBundleName) will be used if it exists, or "CoreData" if it the bundle name was not set.
|
||||
- parameter bundle: an optional bundle to load models from. If not specified, the main bundle will be used.
|
||||
- parameter versionChain: the version strings that indicate the sequence of model versions to be used as the order for progressive migrations. If not specified, will default to a non-migrating data stack.
|
||||
*/
|
||||
@objc
|
||||
public convenience init(modelName: XcodeDataModelFileName?, bundle: Bundle?, versionChain: [String]?) {
|
||||
public convenience init(xcodeModelName: XcodeDataModelFileName?, bundle: Bundle?, versionChain: [String]?) {
|
||||
|
||||
self.init(
|
||||
DataStack(
|
||||
modelName: modelName ?? DataStack.applicationName,
|
||||
xcodeModelName: xcodeModelName ?? DataStack.applicationName,
|
||||
bundle: bundle ?? Bundle.main,
|
||||
migrationChain: versionChain.flatMap { MigrationChain($0) } ?? nil
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
Initializes a `CSDataStack` from the model with the specified `modelName` in the specified `bundle`.
|
||||
|
||||
- parameter modelName: the name of the (.xcdatamodeld) model file. If not specified, the application name (CFBundleName) will be used if it exists, or "CoreData" if it the bundle name was not set.
|
||||
- parameter bundle: an optional bundle to load models from. If not specified, the main bundle will be used.
|
||||
- parameter versionTree: the version strings that indicate the sequence of model versions to be used as the order for progressive migrations. If not specified, will default to a non-migrating data stack.
|
||||
*/
|
||||
@objc
|
||||
public convenience init(modelName: XcodeDataModelFileName?, bundle: Bundle?, versionTree: [String: String]?) {
|
||||
|
||||
self.init(
|
||||
DataStack(
|
||||
modelName: modelName ?? DataStack.applicationName,
|
||||
bundle: bundle ?? Bundle.main,
|
||||
migrationChain: versionTree.flatMap { MigrationChain($0) } ?? nil
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the stack's model version. The version string is the same as the name of the version-specific .xcdatamodeld file.
|
||||
*/
|
||||
@@ -227,6 +208,19 @@ public final class CSDataStack: NSObject, CoreStoreObjectiveCType {
|
||||
|
||||
// MARK: Deprecated
|
||||
|
||||
@available(*, deprecated, message: "Use the -[initWithXcodeModelName:bundle:versionChain:] initializer.")
|
||||
@objc
|
||||
public convenience init(modelName: XcodeDataModelFileName?, bundle: Bundle?, versionChain: [String]?) {
|
||||
|
||||
self.init(
|
||||
DataStack(
|
||||
xcodeModelName: modelName ?? DataStack.applicationName,
|
||||
bundle: bundle ?? Bundle.main,
|
||||
migrationChain: versionChain.flatMap { MigrationChain($0) } ?? nil
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "Use the -[initWithModelName:bundle:versionChain:] initializer.")
|
||||
@objc
|
||||
public convenience init(model: NSManagedObjectModel, versionChain: [String]?) {
|
||||
|
||||
@@ -145,7 +145,7 @@ public final class CSFrom: NSObject {
|
||||
|
||||
public let bridgeToSwift: From<NSManagedObject>
|
||||
|
||||
public init<T: NSManagedObject>(_ swiftValue: From<T>) {
|
||||
public init<D: NSManagedObject>(_ swiftValue: From<D>) {
|
||||
|
||||
self.bridgeToSwift = swiftValue.downcast()
|
||||
super.init()
|
||||
@@ -155,7 +155,7 @@ public final class CSFrom: NSObject {
|
||||
|
||||
// MARK: - From
|
||||
|
||||
extension From where T: NSManagedObject {
|
||||
extension From where D: NSManagedObject {
|
||||
|
||||
// MARK: CoreStoreSwiftType
|
||||
|
||||
|
||||
@@ -35,13 +35,13 @@ import CoreData
|
||||
- SeeAlso: `GroupBy`
|
||||
*/
|
||||
@objc
|
||||
public final class CSGroupBy: NSObject, CSQueryClause, CoreStoreObjectiveCType {
|
||||
public final class CSGroupBy: NSObject, CSQueryClause {
|
||||
|
||||
/**
|
||||
The list of key path strings to group results with
|
||||
*/
|
||||
@objc
|
||||
public var keyPaths: [KeyPath] {
|
||||
public var keyPaths: [KeyPathString] {
|
||||
|
||||
return self.bridgeToSwift.keyPaths
|
||||
}
|
||||
@@ -52,7 +52,7 @@ public final class CSGroupBy: NSObject, CSQueryClause, CoreStoreObjectiveCType {
|
||||
- parameter keyPath: a key path string to group results with
|
||||
*/
|
||||
@objc
|
||||
public convenience init(keyPath: KeyPath) {
|
||||
public convenience init(keyPath: KeyPathString) {
|
||||
|
||||
self.init(GroupBy(keyPath))
|
||||
}
|
||||
@@ -63,7 +63,7 @@ public final class CSGroupBy: NSObject, CSQueryClause, CoreStoreObjectiveCType {
|
||||
- parameter keyPaths: a list of key path strings to group results with
|
||||
*/
|
||||
@objc
|
||||
public convenience init(keyPaths: [KeyPath]) {
|
||||
public convenience init(keyPaths: [KeyPathString]) {
|
||||
|
||||
self.init(GroupBy(keyPaths))
|
||||
}
|
||||
@@ -102,11 +102,11 @@ public final class CSGroupBy: NSObject, CSQueryClause, CoreStoreObjectiveCType {
|
||||
|
||||
// MARK: CoreStoreObjectiveCType
|
||||
|
||||
public let bridgeToSwift: GroupBy
|
||||
public let bridgeToSwift: GroupBy<NSManagedObject>
|
||||
|
||||
public init(_ swiftValue: GroupBy) {
|
||||
public init<D: NSManagedObject>(_ swiftValue: GroupBy<D>) {
|
||||
|
||||
self.bridgeToSwift = swiftValue
|
||||
self.bridgeToSwift = swiftValue.downcast()
|
||||
super.init()
|
||||
}
|
||||
}
|
||||
@@ -114,7 +114,7 @@ public final class CSGroupBy: NSObject, CSQueryClause, CoreStoreObjectiveCType {
|
||||
|
||||
// MARK: - GroupBy
|
||||
|
||||
extension GroupBy: CoreStoreSwiftType {
|
||||
extension GroupBy where D: NSManagedObject {
|
||||
|
||||
// MARK: CoreStoreSwiftType
|
||||
|
||||
@@ -122,4 +122,12 @@ extension GroupBy: CoreStoreSwiftType {
|
||||
|
||||
return CSGroupBy(self)
|
||||
}
|
||||
|
||||
|
||||
// MARK: FilePrivate
|
||||
|
||||
fileprivate func downcast() -> GroupBy<NSManagedObject> {
|
||||
|
||||
return GroupBy<NSManagedObject>(self.keyPaths)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,7 +112,7 @@ public final class CSInto: NSObject {
|
||||
|
||||
public let bridgeToSwift: Into<NSManagedObject>
|
||||
|
||||
public required init<T: NSManagedObject>(_ swiftValue: Into<T>) {
|
||||
public required init<D: NSManagedObject>(_ swiftValue: Into<D>) {
|
||||
|
||||
self.bridgeToSwift = swiftValue.downcast()
|
||||
super.init()
|
||||
@@ -122,7 +122,7 @@ public final class CSInto: NSObject {
|
||||
|
||||
// MARK: - Into
|
||||
|
||||
extension Into where T: NSManagedObject {
|
||||
extension Into where D: NSManagedObject {
|
||||
|
||||
// MARK: CoreStoreSwiftType
|
||||
|
||||
|
||||
@@ -560,7 +560,6 @@ extension ListMonitor where ListMonitor.ObjectType: NSManagedObject {
|
||||
|
||||
fileprivate func downcast() -> ListMonitor<NSManagedObject> {
|
||||
|
||||
@inline(__always)
|
||||
func noWarnUnsafeBitCast<T, U>(_ x: T, to type: U.Type) -> U {
|
||||
|
||||
return unsafeBitCast(x, to: type)
|
||||
|
||||
@@ -42,7 +42,7 @@ import CoreData
|
||||
*/
|
||||
@available(OSX 10.12, *)
|
||||
@objc
|
||||
public protocol CSListObserver: class, AnyObject {
|
||||
public protocol CSListObserver: class {
|
||||
|
||||
/**
|
||||
Handles processing just before a change to the observed list occurs
|
||||
|
||||
@@ -152,7 +152,6 @@ extension ObjectMonitor where ObjectMonitor.ObjectType: NSManagedObject {
|
||||
|
||||
fileprivate func downcast() -> ObjectMonitor<NSManagedObject> {
|
||||
|
||||
@inline(__always)
|
||||
func noWarnUnsafeBitCast<T, U>(_ x: T, to type: U.Type) -> U {
|
||||
|
||||
return unsafeBitCast(x, to: type)
|
||||
|
||||
@@ -40,7 +40,7 @@ import CoreData
|
||||
*/
|
||||
@available(OSX 10.12, *)
|
||||
@objc
|
||||
public protocol CSObjectObserver: class, AnyObject {
|
||||
public protocol CSObjectObserver: class {
|
||||
|
||||
/**
|
||||
Handles processing just before a change to the observed `object` occurs
|
||||
|
||||
@@ -35,7 +35,7 @@ import CoreData
|
||||
- SeeAlso: `OrderBy`
|
||||
*/
|
||||
@objc
|
||||
public final class CSOrderBy: NSObject, CSFetchClause, CSQueryClause, CSDeleteClause, CoreStoreObjectiveCType {
|
||||
public final class CSOrderBy: NSObject, CSFetchClause, CSQueryClause, CSDeleteClause {
|
||||
|
||||
/**
|
||||
The list of sort descriptors
|
||||
@@ -110,11 +110,11 @@ public final class CSOrderBy: NSObject, CSFetchClause, CSQueryClause, CSDeleteCl
|
||||
|
||||
// MARK: CoreStoreObjectiveCType
|
||||
|
||||
public let bridgeToSwift: OrderBy
|
||||
public let bridgeToSwift: OrderBy<NSManagedObject>
|
||||
|
||||
public init(_ swiftValue: OrderBy) {
|
||||
public init<D: NSManagedObject>(_ swiftValue: OrderBy<D>) {
|
||||
|
||||
self.bridgeToSwift = swiftValue
|
||||
self.bridgeToSwift = swiftValue.downcast()
|
||||
super.init()
|
||||
}
|
||||
}
|
||||
@@ -122,7 +122,7 @@ public final class CSOrderBy: NSObject, CSFetchClause, CSQueryClause, CSDeleteCl
|
||||
|
||||
// MARK: - OrderBy
|
||||
|
||||
extension OrderBy: CoreStoreSwiftType {
|
||||
extension OrderBy where D: NSManagedObject {
|
||||
|
||||
// MARK: CoreStoreSwiftType
|
||||
|
||||
@@ -130,4 +130,12 @@ extension OrderBy: CoreStoreSwiftType {
|
||||
|
||||
return CSOrderBy(self)
|
||||
}
|
||||
|
||||
|
||||
// MARK: FilePrivate
|
||||
|
||||
fileprivate func downcast() -> OrderBy<NSManagedObject> {
|
||||
|
||||
return OrderBy<NSManagedObject>(self.sortDescriptors)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ public final class CSSQLiteStore: NSObject, CSLocalStorage, CoreStoreObjectiveCT
|
||||
}
|
||||
|
||||
/**
|
||||
Initializes an `CSSQLiteStore` with an all-default settings: a `fileURL` pointing to a "<Application name>.sqlite" file in the "Application Support/<bundle id>" directory (or the "Caches/<bundle id>" directory on tvOS), a `nil` `configuration` pertaining to the "Default" configuration, a `mappingModelBundles` set to search all `NSBundle`s, and `localStorageOptions` set to `[CSLocalStorageOptions none]`.
|
||||
Initializes an `CSSQLiteStore` with an all-default settings: a `fileURL` pointing to a "<Application name>.sqlite" file in the "Application Support/<bundle id>" directory (or the "Caches/<bundle id>" directory on tvOS), a `nil` `configuration` pertaining to the "Default" configuration, and `localStorageOptions` set to `[CSLocalStorageOptions none]`.
|
||||
|
||||
- Important: Initializing `CSSQLiteStore`s with custom migration mapping models is currently not supported. Create an `SQLiteStore` instance from Swift code and bridge the instance to Objective-C using its `SQLiteStore.bridgeToObjectiveC` property.
|
||||
*/
|
||||
|
||||
@@ -36,7 +36,7 @@ import CoreData
|
||||
*/
|
||||
@available(OSX 10.12, *)
|
||||
@objc
|
||||
public final class CSSectionBy: NSObject, CoreStoreObjectiveCType {
|
||||
public final class CSSectionBy: NSObject {
|
||||
|
||||
/**
|
||||
Initializes a `CSSectionBy` clause with the key path to use to group `CSListMonitor` objects into sections
|
||||
@@ -45,9 +45,9 @@ public final class CSSectionBy: NSObject, CoreStoreObjectiveCType {
|
||||
- returns: a `CSSectionBy` clause with the key path to use to group `CSListMonitor` objects into sections
|
||||
*/
|
||||
@objc
|
||||
public static func keyPath(_ sectionKeyPath: KeyPath) -> CSSectionBy {
|
||||
public static func keyPath(_ sectionKeyPath: KeyPathString) -> CSSectionBy {
|
||||
|
||||
return self.init(SectionBy(sectionKeyPath))
|
||||
return self.init(SectionBy<NSManagedObject>(sectionKeyPath))
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -58,9 +58,9 @@ public final class CSSectionBy: NSObject, CoreStoreObjectiveCType {
|
||||
- returns: a `CSSectionBy` clause with the key path to use to group `CSListMonitor` objects into sections
|
||||
*/
|
||||
@objc
|
||||
public static func keyPath(_ sectionKeyPath: KeyPath, sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?) -> CSSectionBy {
|
||||
public static func keyPath(_ sectionKeyPath: KeyPathString, sectionIndexTransformer: @escaping (_ sectionName: String?) -> String?) -> CSSectionBy {
|
||||
|
||||
return self.init(SectionBy(sectionKeyPath, sectionIndexTransformer))
|
||||
return self.init(SectionBy<NSManagedObject>(sectionKeyPath, sectionIndexTransformer))
|
||||
}
|
||||
|
||||
|
||||
@@ -74,11 +74,11 @@ public final class CSSectionBy: NSObject, CoreStoreObjectiveCType {
|
||||
|
||||
// MARK: CoreStoreObjectiveCType
|
||||
|
||||
public let bridgeToSwift: SectionBy
|
||||
public let bridgeToSwift: SectionBy<NSManagedObject>
|
||||
|
||||
public init(_ swiftValue: SectionBy) {
|
||||
public init<D>(_ swiftValue: SectionBy<D>) {
|
||||
|
||||
self.bridgeToSwift = swiftValue
|
||||
self.bridgeToSwift = swiftValue.downcast()
|
||||
super.init()
|
||||
}
|
||||
}
|
||||
@@ -87,7 +87,7 @@ public final class CSSectionBy: NSObject, CoreStoreObjectiveCType {
|
||||
// MARK: - SectionBy
|
||||
|
||||
@available(OSX 10.12, *)
|
||||
extension SectionBy: CoreStoreSwiftType {
|
||||
extension SectionBy {
|
||||
|
||||
// MARK: CoreStoreSwiftType
|
||||
|
||||
@@ -95,4 +95,12 @@ extension SectionBy: CoreStoreSwiftType {
|
||||
|
||||
return CSSectionBy(self)
|
||||
}
|
||||
|
||||
|
||||
// MARK: FilePrivate
|
||||
|
||||
fileprivate func downcast() -> SectionBy<NSManagedObject> {
|
||||
|
||||
return SectionBy<NSManagedObject>(self.sectionKeyPath, self.sectionIndexTransformer)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ import CoreData
|
||||
- SeeAlso: `SelectTerm`
|
||||
*/
|
||||
@objc
|
||||
public final class CSSelectTerm: NSObject, CoreStoreObjectiveCType {
|
||||
public final class CSSelectTerm: NSObject {
|
||||
|
||||
/**
|
||||
Provides a `CSSelectTerm` to a `CSSelect` clause for querying an entity attribute.
|
||||
@@ -48,7 +48,7 @@ public final class CSSelectTerm: NSObject, CoreStoreObjectiveCType {
|
||||
- parameter keyPath: the attribute name
|
||||
*/
|
||||
@objc
|
||||
public convenience init(keyPath: KeyPath) {
|
||||
public convenience init(keyPath: KeyPathString) {
|
||||
|
||||
self.init(.attribute(keyPath))
|
||||
}
|
||||
@@ -65,7 +65,7 @@ public final class CSSelectTerm: NSObject, CoreStoreObjectiveCType {
|
||||
- returns: a `CSSelectTerm` to a `CSSelect` clause for querying the average value of an attribute
|
||||
*/
|
||||
@objc
|
||||
public static func average(_ keyPath: KeyPath, as alias: KeyPath?) -> CSSelectTerm {
|
||||
public static func average(_ keyPath: KeyPathString, as alias: KeyPathString?) -> CSSelectTerm {
|
||||
|
||||
return self.init(.average(keyPath, as: alias))
|
||||
}
|
||||
@@ -82,7 +82,7 @@ public final class CSSelectTerm: NSObject, CoreStoreObjectiveCType {
|
||||
- returns: a `SelectTerm` to a `Select` clause for a count query
|
||||
*/
|
||||
@objc
|
||||
public static func count(_ keyPath: KeyPath, as alias: KeyPath?) -> CSSelectTerm {
|
||||
public static func count(_ keyPath: KeyPathString, as alias: KeyPathString?) -> CSSelectTerm {
|
||||
|
||||
return self.init(.count(keyPath, as: alias))
|
||||
}
|
||||
@@ -99,7 +99,7 @@ public final class CSSelectTerm: NSObject, CoreStoreObjectiveCType {
|
||||
- returns: a `CSSelectTerm` to a `CSSelect` clause for querying the maximum value for an attribute
|
||||
*/
|
||||
@objc
|
||||
public static func maximum(_ keyPath: KeyPath, as alias: KeyPath?) -> CSSelectTerm {
|
||||
public static func maximum(_ keyPath: KeyPathString, as alias: KeyPathString?) -> CSSelectTerm {
|
||||
|
||||
return self.init(.maximum(keyPath, as: alias))
|
||||
}
|
||||
@@ -116,7 +116,7 @@ public final class CSSelectTerm: NSObject, CoreStoreObjectiveCType {
|
||||
- returns: a `CSSelectTerm` to a `CSSelect` clause for querying the minimum value for an attribute
|
||||
*/
|
||||
@objc
|
||||
public static func minimum(_ keyPath: KeyPath, as alias: KeyPath?) -> CSSelectTerm {
|
||||
public static func minimum(_ keyPath: KeyPathString, as alias: KeyPathString?) -> CSSelectTerm {
|
||||
|
||||
return self.init(.minimum(keyPath, as: alias))
|
||||
}
|
||||
@@ -133,7 +133,7 @@ public final class CSSelectTerm: NSObject, CoreStoreObjectiveCType {
|
||||
- returns: a `CSSelectTerm` to a `CSSelect` clause for querying the sum value for an attribute
|
||||
*/
|
||||
@objc
|
||||
public static func sum(_ keyPath: KeyPath, as alias: KeyPath?) -> CSSelectTerm {
|
||||
public static func sum(_ keyPath: KeyPathString, as alias: KeyPathString?) -> CSSelectTerm {
|
||||
|
||||
return self.init(.sum(keyPath, as: alias))
|
||||
}
|
||||
@@ -150,7 +150,7 @@ public final class CSSelectTerm: NSObject, CoreStoreObjectiveCType {
|
||||
- returns: a `SelectTerm` to a `Select` clause for querying the sum value for an attribute
|
||||
*/
|
||||
@objc
|
||||
public static func objectIDAs(_ alias: KeyPath? = nil) -> CSSelectTerm {
|
||||
public static func objectIDAs(_ alias: KeyPathString? = nil) -> CSSelectTerm {
|
||||
|
||||
return self.init(.objectID(as: alias))
|
||||
}
|
||||
@@ -175,11 +175,11 @@ public final class CSSelectTerm: NSObject, CoreStoreObjectiveCType {
|
||||
|
||||
// MARK: CoreStoreObjectiveCType
|
||||
|
||||
public let bridgeToSwift: SelectTerm
|
||||
public let bridgeToSwift: SelectTerm<NSManagedObject>
|
||||
|
||||
public init(_ swiftValue: SelectTerm) {
|
||||
public init<D: NSManagedObject>(_ swiftValue: SelectTerm<D>) {
|
||||
|
||||
self.bridgeToSwift = swiftValue
|
||||
self.bridgeToSwift = swiftValue.downcast()
|
||||
super.init()
|
||||
}
|
||||
}
|
||||
@@ -187,7 +187,7 @@ public final class CSSelectTerm: NSObject, CoreStoreObjectiveCType {
|
||||
|
||||
// MARK: - SelectTerm
|
||||
|
||||
extension SelectTerm: CoreStoreSwiftType {
|
||||
extension SelectTerm where D: NSManagedObject {
|
||||
|
||||
// MARK: CoreStoreSwiftType
|
||||
|
||||
@@ -195,6 +195,24 @@ extension SelectTerm: CoreStoreSwiftType {
|
||||
|
||||
return CSSelectTerm(self)
|
||||
}
|
||||
|
||||
|
||||
// MARK: FilePrivate
|
||||
|
||||
fileprivate func downcast() -> SelectTerm<NSManagedObject> {
|
||||
|
||||
switch self {
|
||||
|
||||
case ._attribute(let keyPath):
|
||||
return SelectTerm<NSManagedObject>._attribute(keyPath)
|
||||
|
||||
case ._aggregate(let function, let keyPath, let alias, let nativeType):
|
||||
return SelectTerm<NSManagedObject>._aggregate(function: function, keyPath: keyPath, alias: alias, nativeType: nativeType)
|
||||
|
||||
case ._identity(let alias, let nativeType):
|
||||
return SelectTerm<NSManagedObject>._identity(alias: alias, nativeType: nativeType)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -218,9 +236,10 @@ public final class CSSelect: NSObject {
|
||||
```
|
||||
- parameter numberTerm: the `CSSelectTerm` specifying the attribute/aggregate value to query
|
||||
*/
|
||||
@objc
|
||||
public convenience init(numberTerm: CSSelectTerm) {
|
||||
|
||||
self.init(Select<NSNumber>(numberTerm.bridgeToSwift))
|
||||
self.init(Select<NSManagedObject, NSNumber>(numberTerm.bridgeToSwift))
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -233,9 +252,10 @@ public final class CSSelect: NSObject {
|
||||
```
|
||||
- parameter decimalTerm: the `CSSelectTerm` specifying the attribute/aggregate value to query
|
||||
*/
|
||||
@objc
|
||||
public convenience init(decimalTerm: CSSelectTerm) {
|
||||
|
||||
self.init(Select<NSDecimalNumber>(decimalTerm.bridgeToSwift))
|
||||
self.init(Select<NSManagedObject, NSDecimalNumber>(decimalTerm.bridgeToSwift))
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -248,9 +268,10 @@ public final class CSSelect: NSObject {
|
||||
```
|
||||
- parameter stringTerm: the `CSSelectTerm` specifying the attribute/aggregate value to query
|
||||
*/
|
||||
@objc
|
||||
public convenience init(stringTerm: CSSelectTerm) {
|
||||
|
||||
self.init(Select<NSString>(stringTerm.bridgeToSwift))
|
||||
self.init(Select<NSManagedObject, NSString>(stringTerm.bridgeToSwift))
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -263,9 +284,10 @@ public final class CSSelect: NSObject {
|
||||
```
|
||||
- parameter dateTerm: the `CSSelectTerm` specifying the attribute/aggregate value to query
|
||||
*/
|
||||
@objc
|
||||
public convenience init(dateTerm: CSSelectTerm) {
|
||||
|
||||
self.init(Select<Date>(dateTerm.bridgeToSwift))
|
||||
self.init(Select<NSManagedObject, Date>(dateTerm.bridgeToSwift))
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -278,9 +300,10 @@ public final class CSSelect: NSObject {
|
||||
```
|
||||
- parameter dataTerm: the `CSSelectTerm` specifying the attribute/aggregate value to query
|
||||
*/
|
||||
@objc
|
||||
public convenience init(dataTerm: CSSelectTerm) {
|
||||
|
||||
self.init(Select<Data>(dataTerm.bridgeToSwift))
|
||||
self.init(Select<NSManagedObject, Data>(dataTerm.bridgeToSwift))
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -292,9 +315,10 @@ public final class CSSelect: NSObject {
|
||||
// ...
|
||||
```
|
||||
*/
|
||||
@objc
|
||||
public convenience init(objectIDTerm: ()) {
|
||||
|
||||
self.init(Select<NSManagedObjectID>(.objectID()))
|
||||
self.init(Select<NSManagedObject, NSManagedObjectID>(.objectID()))
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -307,9 +331,10 @@ public final class CSSelect: NSObject {
|
||||
- parameter term: the `CSSelectTerm` specifying the attribute/aggregate value to query
|
||||
- returns: a `CSSelect` clause for querying an entity attribute
|
||||
*/
|
||||
@objc
|
||||
public static func dictionaryForTerm(_ term: CSSelectTerm) -> CSSelect {
|
||||
|
||||
return self.init(Select<NSDictionary>(term.bridgeToSwift))
|
||||
return self.init(Select<NSManagedObject, NSDictionary>(term.bridgeToSwift))
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -325,9 +350,10 @@ public final class CSSelect: NSObject {
|
||||
- parameter terms: the `CSSelectTerm`s specifying the attribute/aggregate values to query
|
||||
- returns: a `CSSelect` clause for querying an entity attribute
|
||||
*/
|
||||
@objc
|
||||
public static func dictionaryForTerms(_ terms: [CSSelectTerm]) -> CSSelect {
|
||||
|
||||
return self.init(Select<NSDictionary>(terms.map { $0.bridgeToSwift }))
|
||||
return self.init(Select<NSManagedObject, NSDictionary>(terms.map { $0.bridgeToSwift }))
|
||||
}
|
||||
|
||||
|
||||
@@ -357,18 +383,18 @@ public final class CSSelect: NSObject {
|
||||
|
||||
// MARK: CoreStoreObjectiveCType
|
||||
|
||||
public init<T: QueryableAttributeType>(_ swiftValue: Select<T>) {
|
||||
public init<D: NSManagedObject, T: QueryableAttributeType>(_ swiftValue: Select<D, T>) {
|
||||
|
||||
self.attributeType = T.cs_rawAttributeType
|
||||
self.selectTerms = swiftValue.selectTerms
|
||||
self.selectTerms = swiftValue.selectTerms.map({ $0.downcast() })
|
||||
self.bridgeToSwift = swiftValue
|
||||
super.init()
|
||||
}
|
||||
|
||||
public init<T: SelectResultType>(_ swiftValue: Select<T>) {
|
||||
public init<D: NSManagedObject, T>(_ swiftValue: Select<D, T>) {
|
||||
|
||||
self.attributeType = .undefinedAttributeType
|
||||
self.selectTerms = swiftValue.selectTerms
|
||||
self.selectTerms = swiftValue.selectTerms.map({ $0.downcast() })
|
||||
self.bridgeToSwift = swiftValue
|
||||
super.init()
|
||||
}
|
||||
@@ -377,7 +403,95 @@ public final class CSSelect: NSObject {
|
||||
// MARK: Internal
|
||||
|
||||
internal let attributeType: NSAttributeType
|
||||
internal let selectTerms: [SelectTerm]
|
||||
internal let selectTerms: [SelectTerm<NSManagedObject>]
|
||||
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
internal func applyToFetchRequest(_ fetchRequest: NSFetchRequest<NSFetchRequestResult>) {
|
||||
|
||||
fetchRequest.includesPendingChanges = false
|
||||
fetchRequest.resultType = .dictionaryResultType
|
||||
|
||||
func attributeDescription(for keyPath: String, in entity: NSEntityDescription) -> NSAttributeDescription? {
|
||||
|
||||
let components = keyPath.components(separatedBy: ".")
|
||||
switch components.count {
|
||||
|
||||
case 0:
|
||||
return nil
|
||||
|
||||
case 1:
|
||||
return entity.attributesByName[components[0]]
|
||||
|
||||
default:
|
||||
guard let relationship = entity.relationshipsByName[components[0]],
|
||||
let destinationEntity = relationship.destinationEntity else {
|
||||
|
||||
return nil
|
||||
}
|
||||
return attributeDescription(
|
||||
for: components.dropFirst().joined(separator: "."),
|
||||
in: destinationEntity
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
var propertiesToFetch = [Any]()
|
||||
for term in self.selectTerms {
|
||||
|
||||
switch term {
|
||||
|
||||
case ._attribute(let keyPath):
|
||||
propertiesToFetch.append(keyPath)
|
||||
|
||||
case ._aggregate(let function, let keyPath, let alias, let nativeType):
|
||||
let entityDescription = fetchRequest.entity!
|
||||
if let attributeDescription = attributeDescription(for: keyPath, in: entityDescription) {
|
||||
|
||||
let expressionDescription = NSExpressionDescription()
|
||||
expressionDescription.name = alias
|
||||
if nativeType == .undefinedAttributeType {
|
||||
|
||||
expressionDescription.expressionResultType = attributeDescription.attributeType
|
||||
}
|
||||
else {
|
||||
|
||||
expressionDescription.expressionResultType = nativeType
|
||||
}
|
||||
expressionDescription.expression = NSExpression(
|
||||
forFunction: function,
|
||||
arguments: [NSExpression(forKeyPath: keyPath)]
|
||||
)
|
||||
propertiesToFetch.append(expressionDescription)
|
||||
}
|
||||
else {
|
||||
|
||||
CoreStore.log(
|
||||
.warning,
|
||||
message: "The key path \"\(keyPath)\" could not be resolved in entity \(cs_typeName(entityDescription.managedObjectClassName)) as an attribute and will be ignored by \(cs_typeName(self)) query clause."
|
||||
)
|
||||
}
|
||||
|
||||
case ._identity(let alias, let nativeType):
|
||||
let expressionDescription = NSExpressionDescription()
|
||||
expressionDescription.name = alias
|
||||
if nativeType == .undefinedAttributeType {
|
||||
|
||||
expressionDescription.expressionResultType = .objectIDAttributeType
|
||||
}
|
||||
else {
|
||||
|
||||
expressionDescription.expressionResultType = nativeType
|
||||
}
|
||||
expressionDescription.expression = NSExpression.expressionForEvaluatedObject()
|
||||
|
||||
propertiesToFetch.append(expressionDescription)
|
||||
}
|
||||
}
|
||||
|
||||
fetchRequest.propertiesToFetch = propertiesToFetch
|
||||
}
|
||||
|
||||
|
||||
// MARK: Private
|
||||
@@ -388,7 +502,7 @@ public final class CSSelect: NSObject {
|
||||
|
||||
// MARK: - Select
|
||||
|
||||
extension Select: CoreStoreSwiftType {
|
||||
extension Select where D: NSManagedObject {
|
||||
|
||||
// MARK: CoreStoreSwiftType
|
||||
|
||||
@@ -396,4 +510,12 @@ extension Select: CoreStoreSwiftType {
|
||||
|
||||
return CSSelect(self)
|
||||
}
|
||||
|
||||
|
||||
// MARK: FilePrivate
|
||||
|
||||
fileprivate func downcast() -> Select<NSManagedObject, T> {
|
||||
|
||||
return Select<NSManagedObject, T>(self.selectTerms.map({ $0.downcast() }))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,7 +152,7 @@ public final class CSSetupResult: NSObject {
|
||||
|
||||
// MARK: CoreStoreObjectiveCType
|
||||
|
||||
public required init<T: StorageInterface>(_ swiftValue: SetupResult<T>) where T: CoreStoreSwiftType, T.ObjectiveCType: CSStorageInterface {
|
||||
public required init<T>(_ swiftValue: SetupResult<T>) where T: CoreStoreSwiftType, T.ObjectiveCType: CSStorageInterface {
|
||||
|
||||
switch swiftValue {
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ import CoreData
|
||||
- SeeAlso: `SynchronousDataTransaction`
|
||||
*/
|
||||
@objc
|
||||
public final class CSSynchronousDataTransaction: CSBaseDataTransaction {
|
||||
public final class CSSynchronousDataTransaction: CSBaseDataTransaction, CoreStoreObjectiveCType {
|
||||
|
||||
/**
|
||||
Saves the transaction changes and waits for completion synchronously. This method should not be used after the `-commitAndWaitWithError:` method was already called once.
|
||||
@@ -129,9 +129,9 @@ public final class CSSynchronousDataTransaction: CSBaseDataTransaction {
|
||||
|
||||
public typealias SwiftType = SynchronousDataTransaction
|
||||
|
||||
public override var bridgeToSwift: SynchronousDataTransaction {
|
||||
public var bridgeToSwift: SynchronousDataTransaction {
|
||||
|
||||
return super.bridgeToSwift as! SynchronousDataTransaction
|
||||
return super.swiftTransaction as! SynchronousDataTransaction
|
||||
}
|
||||
|
||||
public required init(_ swiftValue: SynchronousDataTransaction) {
|
||||
@@ -139,9 +139,9 @@ public final class CSSynchronousDataTransaction: CSBaseDataTransaction {
|
||||
super.init(swiftValue as BaseDataTransaction)
|
||||
}
|
||||
|
||||
public required init(_ swiftValue: BaseDataTransaction) {
|
||||
public required override init(_ swiftValue: BaseDataTransaction) {
|
||||
|
||||
super.init(swiftValue as! SynchronousDataTransaction)
|
||||
super.init(swiftValue)
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// CSLegacyXcodeDataModelSchema.swift
|
||||
// CSUnsafeDataModelSchema.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright © 2017 John Rommel Estropia
|
||||
@@ -27,18 +27,18 @@ import CoreData
|
||||
import Foundation
|
||||
|
||||
|
||||
// MARK: - CSLegacyXcodeDataModelSchema
|
||||
// MARK: - CSUnsafeDataModelSchema
|
||||
|
||||
/**
|
||||
The `CSLegacyXcodeDataModelSchema` serves as the Objective-C bridging type for `LegacyXcodeDataModelSchema`.
|
||||
The `CSUnsafeDataModelSchema` serves as the Objective-C bridging type for `UnsafeDataModelSchema`.
|
||||
|
||||
- SeeAlso: `LegacyXcodeDataModelSchema`
|
||||
- SeeAlso: `UnsafeDataModelSchema`
|
||||
*/
|
||||
@objc
|
||||
public final class CSLegacyXcodeDataModelSchema: NSObject, CSDynamicSchema, CoreStoreObjectiveCType {
|
||||
public final class CSUnsafeDataModelSchema: NSObject, CSDynamicSchema, CoreStoreObjectiveCType {
|
||||
|
||||
/**
|
||||
Initializes a `CSLegacyXcodeDataModelSchema` from an `NSManagedObjectModel`.
|
||||
Initializes a `CSUnsafeDataModelSchema` from an `NSManagedObjectModel`.
|
||||
|
||||
- parameter modelName: the model version, typically the file name of an *.xcdatamodeld file (without the file extension)
|
||||
- parameter model: the `NSManagedObjectModel`
|
||||
@@ -46,7 +46,7 @@ public final class CSLegacyXcodeDataModelSchema: NSObject, CSDynamicSchema, Core
|
||||
@objc
|
||||
public required init(modelName: ModelVersion, model: NSManagedObjectModel) {
|
||||
|
||||
self.bridgeToSwift = LegacyXcodeDataModelSchema(
|
||||
self.bridgeToSwift = UnsafeDataModelSchema(
|
||||
modelName: modelName,
|
||||
model: model
|
||||
)
|
||||
@@ -62,7 +62,7 @@ public final class CSLegacyXcodeDataModelSchema: NSObject, CSDynamicSchema, Core
|
||||
|
||||
public override func isEqual(_ object: Any?) -> Bool {
|
||||
|
||||
guard let object = object as? CSLegacyXcodeDataModelSchema else {
|
||||
guard let object = object as? CSUnsafeDataModelSchema else {
|
||||
|
||||
return false
|
||||
}
|
||||
@@ -92,9 +92,9 @@ public final class CSLegacyXcodeDataModelSchema: NSObject, CSDynamicSchema, Core
|
||||
|
||||
// MARK: CoreStoreObjectiveCType
|
||||
|
||||
public let bridgeToSwift: LegacyXcodeDataModelSchema
|
||||
public let bridgeToSwift: UnsafeDataModelSchema
|
||||
|
||||
public required init(_ swiftValue: LegacyXcodeDataModelSchema) {
|
||||
public required init(_ swiftValue: UnsafeDataModelSchema) {
|
||||
|
||||
self.bridgeToSwift = swiftValue
|
||||
super.init()
|
||||
@@ -102,14 +102,14 @@ public final class CSLegacyXcodeDataModelSchema: NSObject, CSDynamicSchema, Core
|
||||
}
|
||||
|
||||
|
||||
// MARK: - LegacyXcodeDataModelSchema
|
||||
// MARK: - UnsafeDataModelSchema
|
||||
|
||||
extension LegacyXcodeDataModelSchema: CoreStoreSwiftType {
|
||||
extension UnsafeDataModelSchema: CoreStoreSwiftType {
|
||||
|
||||
// MARK: CoreStoreSwiftType
|
||||
|
||||
public var bridgeToObjectiveC: CSLegacyXcodeDataModelSchema {
|
||||
public var bridgeToObjectiveC: CSUnsafeDataModelSchema {
|
||||
|
||||
return CSLegacyXcodeDataModelSchema(self)
|
||||
return CSUnsafeDataModelSchema(self)
|
||||
}
|
||||
}
|
||||
@@ -35,7 +35,7 @@ import CoreData
|
||||
- SeeAlso: `UnsafeDataTransaction`
|
||||
*/
|
||||
@objc
|
||||
public final class CSUnsafeDataTransaction: CSBaseDataTransaction {
|
||||
public final class CSUnsafeDataTransaction: CSBaseDataTransaction, CoreStoreObjectiveCType {
|
||||
/**
|
||||
Saves the transaction changes asynchronously. For a `CSUnsafeDataTransaction`, multiple commits are allowed, although it is the developer's responsibility to ensure a reasonable leeway to prevent blocking the main thread.
|
||||
|
||||
@@ -47,6 +47,10 @@ public final class CSUnsafeDataTransaction: CSBaseDataTransaction {
|
||||
|
||||
self.bridgeToSwift.context.saveAsynchronouslyWithCompletion { (_, error) in
|
||||
|
||||
defer {
|
||||
|
||||
withExtendedLifetime(self, {})
|
||||
}
|
||||
if let error = error {
|
||||
|
||||
failure?(error.bridgeToObjectiveC)
|
||||
@@ -55,7 +59,6 @@ public final class CSUnsafeDataTransaction: CSBaseDataTransaction {
|
||||
|
||||
success?()
|
||||
}
|
||||
withExtendedLifetime(self, {})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,9 +189,9 @@ public final class CSUnsafeDataTransaction: CSBaseDataTransaction {
|
||||
|
||||
public typealias SwiftType = UnsafeDataTransaction
|
||||
|
||||
public override var bridgeToSwift: UnsafeDataTransaction {
|
||||
public var bridgeToSwift: UnsafeDataTransaction {
|
||||
|
||||
return super.bridgeToSwift as! UnsafeDataTransaction
|
||||
return super.swiftTransaction as! UnsafeDataTransaction
|
||||
}
|
||||
|
||||
public required init(_ swiftValue: UnsafeDataTransaction) {
|
||||
@@ -196,9 +199,9 @@ public final class CSUnsafeDataTransaction: CSBaseDataTransaction {
|
||||
super.init(swiftValue as BaseDataTransaction)
|
||||
}
|
||||
|
||||
public required init(_ swiftValue: BaseDataTransaction) {
|
||||
public required override init(_ swiftValue: BaseDataTransaction) {
|
||||
|
||||
super.init(swiftValue as! UnsafeDataTransaction)
|
||||
super.init(swiftValue)
|
||||
}
|
||||
|
||||
|
||||
@@ -217,6 +220,10 @@ public final class CSUnsafeDataTransaction: CSBaseDataTransaction {
|
||||
|
||||
self.bridgeToSwift.context.saveAsynchronouslyWithCompletion { (hasChanges, error) in
|
||||
|
||||
defer {
|
||||
|
||||
withExtendedLifetime(self, {})
|
||||
}
|
||||
if let error = error {
|
||||
|
||||
completion?(SaveResult(error).bridgeToObjectiveC)
|
||||
@@ -225,7 +232,6 @@ public final class CSUnsafeDataTransaction: CSBaseDataTransaction {
|
||||
|
||||
completion?(SaveResult(hasChanges: hasChanges).bridgeToObjectiveC)
|
||||
}
|
||||
withExtendedLifetime(self, {})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ import CoreData
|
||||
- SeeAlso: `Where`
|
||||
*/
|
||||
@objc
|
||||
public final class CSWhere: NSObject, CSFetchClause, CSQueryClause, CSDeleteClause, CoreStoreObjectiveCType {
|
||||
public final class CSWhere: NSObject, CSFetchClause, CSQueryClause, CSDeleteClause {
|
||||
|
||||
/**
|
||||
The internal `NSPredicate` instance for the `Where` clause
|
||||
@@ -85,7 +85,7 @@ public final class CSWhere: NSObject, CSFetchClause, CSQueryClause, CSDeleteClau
|
||||
- parameter value: the arguments for the `==` operator
|
||||
*/
|
||||
@objc
|
||||
public convenience init(keyPath: KeyPath, isEqualTo value: CoreDataNativeType?) {
|
||||
public convenience init(keyPath: KeyPathString, isEqualTo value: CoreDataNativeType?) {
|
||||
|
||||
self.init(value == nil || value is NSNull
|
||||
? Where("\(keyPath) == nil")
|
||||
@@ -99,7 +99,7 @@ public final class CSWhere: NSObject, CSFetchClause, CSQueryClause, CSDeleteClau
|
||||
- parameter list: the array to check membership of
|
||||
*/
|
||||
@objc
|
||||
public convenience init(keyPath: KeyPath, isMemberOf list: [CoreDataNativeType]) {
|
||||
public convenience init(keyPath: KeyPathString, isMemberOf list: [CoreDataNativeType]) {
|
||||
|
||||
self.init(Where("\(keyPath) IN %@", list as NSArray))
|
||||
}
|
||||
@@ -149,11 +149,11 @@ public final class CSWhere: NSObject, CSFetchClause, CSQueryClause, CSDeleteClau
|
||||
|
||||
// MARK: CoreStoreObjectiveCType
|
||||
|
||||
public let bridgeToSwift: Where
|
||||
public let bridgeToSwift: Where<NSManagedObject>
|
||||
|
||||
public init(_ swiftValue: Where) {
|
||||
public init<D: NSManagedObject>(_ swiftValue: Where<D>) {
|
||||
|
||||
self.bridgeToSwift = swiftValue
|
||||
self.bridgeToSwift = swiftValue.downcast()
|
||||
super.init()
|
||||
}
|
||||
}
|
||||
@@ -161,7 +161,7 @@ public final class CSWhere: NSObject, CSFetchClause, CSQueryClause, CSDeleteClau
|
||||
|
||||
// MARK: - Where
|
||||
|
||||
extension Where: CoreStoreSwiftType {
|
||||
extension Where where D: NSManagedObject {
|
||||
|
||||
// MARK: CoreStoreSwiftType
|
||||
|
||||
@@ -169,4 +169,12 @@ extension Where: CoreStoreSwiftType {
|
||||
|
||||
return CSWhere(self)
|
||||
}
|
||||
|
||||
|
||||
// MARK: FilePrivate
|
||||
|
||||
fileprivate func downcast() -> Where<NSManagedObject> {
|
||||
|
||||
return Where<NSManagedObject>(self.predicate)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ import CoreData
|
||||
Objective-C Foundation types that are natively supported by Core Data managed attributes all conform to `CoreDataNativeType`.
|
||||
*/
|
||||
@objc
|
||||
public protocol CoreDataNativeType: class, NSObjectProtocol, AnyObject {}
|
||||
public protocol CoreDataNativeType: class, NSObjectProtocol {}
|
||||
|
||||
|
||||
// MARK: - NSNumber
|
||||
|
||||
@@ -231,7 +231,9 @@ extension Entity: CustomDebugStringConvertible, CoreStoreDebugStringConvertible
|
||||
return createFormattedString(
|
||||
"(", ")",
|
||||
("type", self.type),
|
||||
("entityName", self.entityName)
|
||||
("entityName", self.entityName),
|
||||
("isAbstract", self.isAbstract),
|
||||
("versionHashModifier", self.versionHashModifier as Any)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -372,9 +374,9 @@ extension Into: CustomDebugStringConvertible, CoreStoreDebugStringConvertible {
|
||||
}
|
||||
|
||||
|
||||
// MARK: - LegacyXcodeDataModelSchema
|
||||
// MARK: - UnsafeDataModelSchema
|
||||
|
||||
extension LegacyXcodeDataModelSchema: CustomDebugStringConvertible, CoreStoreDebugStringConvertible {
|
||||
extension UnsafeDataModelSchema: CustomDebugStringConvertible, CoreStoreDebugStringConvertible {
|
||||
|
||||
// MARK: CustomDebugStringConvertible
|
||||
|
||||
@@ -866,7 +868,8 @@ extension SQLiteStore: CustomDebugStringConvertible, CoreStoreDebugStringConvert
|
||||
("storeOptions", self.storeOptions as Any),
|
||||
("fileURL", self.fileURL),
|
||||
("migrationMappingProviders", self.migrationMappingProviders),
|
||||
("localStorageOptions", self.localStorageOptions)
|
||||
("localStorageOptions", self.localStorageOptions),
|
||||
("fileSize", self.fileSize() as Any)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -983,7 +986,7 @@ extension VersionLock: CustomStringConvertible, CustomDebugStringConvertible, Co
|
||||
string.append(":]")
|
||||
return string
|
||||
}
|
||||
for (index, keyValue) in self.hashesByEntityName.enumerated() {
|
||||
for (index, keyValue) in self.hashesByEntityName.sorted(by: { $0.key < $1.key }).enumerated() {
|
||||
|
||||
let data = keyValue.value
|
||||
let count = data.count
|
||||
@@ -1090,15 +1093,6 @@ fileprivate extension String {
|
||||
return String(repeating: " ", count: level * 4)
|
||||
}
|
||||
|
||||
fileprivate func trimSwiftModuleName() -> String {
|
||||
|
||||
if self.hasPrefix("Swift.") {
|
||||
|
||||
return self.substring(from: "Swift.".endIndex)
|
||||
}
|
||||
return self
|
||||
}
|
||||
|
||||
fileprivate mutating func indent(_ level: Int) {
|
||||
|
||||
self = self.replacingOccurrences(of: "\n", with: "\n\(String.indention(level))")
|
||||
@@ -1183,7 +1177,6 @@ extension NSAttributeDescription: CoreStoreDebugStringConvertible {
|
||||
("isOptional", self.isOptional),
|
||||
("isTransient", self.isTransient),
|
||||
("userInfo", self.userInfo as Any),
|
||||
("isIndexed", self.isIndexed),
|
||||
("versionHash", self.versionHash),
|
||||
("versionHashModifier", self.versionHashModifier as Any),
|
||||
("isIndexedBySpotlight", self.isIndexedBySpotlight),
|
||||
@@ -1212,6 +1205,8 @@ extension NSAttributeType: CoreStoreDebugStringConvertible {
|
||||
case .binaryDataAttributeType: return ".binaryDataAttributeType"
|
||||
case .transformableAttributeType: return ".transformableAttributeType"
|
||||
case .objectIDAttributeType: return ".objectIDAttributeType"
|
||||
case .UUIDAttributeType: return ".UUIDAttributeType"
|
||||
case .URIAttributeType: return ".URIAttributeType"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1252,13 +1247,17 @@ extension NSEntityDescription: CoreStoreDebugStringConvertible {
|
||||
("userInfo", self.userInfo as Any),
|
||||
("versionHash", self.versionHash),
|
||||
("versionHashModifier", self.versionHashModifier as Any),
|
||||
("renamingIdentifier", self.renamingIdentifier as Any),
|
||||
("compoundIndexes", self.compoundIndexes)
|
||||
("renamingIdentifier", self.renamingIdentifier as Any)
|
||||
]
|
||||
if #available(iOS 9.0, OSXApplicationExtension 10.11, OSX 10.11, *) {
|
||||
if #available(iOS 11.0, OSX 10.13, watchOS 4.0, tvOS 11.0, *) {
|
||||
|
||||
info.append(("uniquenessConstraints", self.uniquenessConstraints))
|
||||
info.append(("indexes", self.indexes))
|
||||
}
|
||||
else {
|
||||
|
||||
info.append(("compoundIndexes", self.compoundIndexes))
|
||||
}
|
||||
info.append(("uniquenessConstraints", self.uniquenessConstraints))
|
||||
return createFormattedString(
|
||||
"(", ")",
|
||||
info
|
||||
|
||||
@@ -47,7 +47,7 @@ public extension CoreStore {
|
||||
- parameter storage: the storage
|
||||
- parameter completion: the closure to be executed on the main queue when the process completes, either due to success or failure. The closure's `SetupResult` argument indicates the result. Note that the `StorageInterface` associated to the `SetupResult.success` may not always be the same instance as the parameter argument if a previous `StorageInterface` was already added at the same URL and with the same configuration.
|
||||
*/
|
||||
public static func addStorage<T: StorageInterface>(_ storage: T, completion: @escaping (SetupResult<T>) -> Void) {
|
||||
public static func addStorage<T>(_ storage: T, completion: @escaping (SetupResult<T>) -> Void) {
|
||||
|
||||
self.defaultStack.addStorage(storage, completion: completion)
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ public extension CoreStore {
|
||||
- parameter object: the `DynamicObject` to observe changes from
|
||||
- returns: a `ObjectMonitor` that monitors changes to `object`
|
||||
*/
|
||||
public static func monitorObject<T: DynamicObject>(_ object: T) -> ObjectMonitor<T> {
|
||||
public static func monitorObject<D>(_ object: D) -> ObjectMonitor<D> {
|
||||
|
||||
return self.defaultStack.monitorObject(object)
|
||||
}
|
||||
@@ -50,7 +50,7 @@ public extension CoreStore {
|
||||
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
- returns: a `ListMonitor` instance that monitors changes to the list
|
||||
*/
|
||||
public static func monitorList<T: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> ListMonitor<T> {
|
||||
public static func monitorList<D>(_ from: From<D>, _ fetchClauses: FetchClause...) -> ListMonitor<D> {
|
||||
|
||||
return self.defaultStack.monitorList(from, fetchClauses)
|
||||
}
|
||||
@@ -62,11 +62,28 @@ public extension CoreStore {
|
||||
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
- returns: a `ListMonitor` instance that monitors changes to the list
|
||||
*/
|
||||
public static func monitorList<T: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> ListMonitor<T> {
|
||||
public static func monitorList<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) -> ListMonitor<D> {
|
||||
|
||||
return self.defaultStack.monitorList(from, fetchClauses)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `ListMonitor` for a list of `DynamicObject`s that satisfy the specified `FetchChainableBuilderType` built from a chain of clauses.
|
||||
```
|
||||
let monitor = CoreStore.monitorList(
|
||||
From<MyPersonEntity>()
|
||||
.where(\.age > 18)
|
||||
.orderBy(.ascending(\.age))
|
||||
)
|
||||
```
|
||||
- parameter clauseChain: a `FetchChainableBuilderType` built from a chain of clauses
|
||||
- returns: a `ListMonitor` for a list of `DynamicObject`s that satisfy the specified `FetchChainableBuilderType`
|
||||
*/
|
||||
public static func monitorList<B: FetchChainableBuilderType>(_ clauseChain: B) -> ListMonitor<B.ObjectType> {
|
||||
|
||||
return self.defaultStack.monitorList(clauseChain.from, clauseChain.fetchClauses)
|
||||
}
|
||||
|
||||
/**
|
||||
Using the `defaultStack`, asynchronously creates a `ListMonitor` for a list of `DynamicObject`s that satisfy the specified fetch clauses. Multiple `ListObserver`s may then register themselves to be notified when changes are made to the list. Since `NSFetchedResultsController` greedily locks the persistent store on initial fetch, you may prefer this method instead of the synchronous counterpart to avoid deadlocks while background updates/saves are being executed.
|
||||
|
||||
@@ -74,7 +91,7 @@ public extension CoreStore {
|
||||
- parameter from: a `From` clause indicating the entity type
|
||||
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
*/
|
||||
public static func monitorList<T: DynamicObject>(createAsynchronously: @escaping (ListMonitor<T>) -> Void, _ from: From<T>, _ fetchClauses: FetchClause...) {
|
||||
public static func monitorList<D>(createAsynchronously: @escaping (ListMonitor<D>) -> Void, _ from: From<D>, _ fetchClauses: FetchClause...) {
|
||||
|
||||
self.defaultStack.monitorList(createAsynchronously: createAsynchronously, from, fetchClauses)
|
||||
}
|
||||
@@ -86,11 +103,37 @@ public extension CoreStore {
|
||||
- parameter from: a `From` clause indicating the entity type
|
||||
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
*/
|
||||
public static func monitorList<T: DynamicObject>(createAsynchronously: @escaping (ListMonitor<T>) -> Void, _ from: From<T>, _ fetchClauses: [FetchClause]) {
|
||||
public static func monitorList<D>(createAsynchronously: @escaping (ListMonitor<D>) -> Void, _ from: From<D>, _ fetchClauses: [FetchClause]) {
|
||||
|
||||
self.defaultStack.monitorList(createAsynchronously: createAsynchronously, from, fetchClauses)
|
||||
}
|
||||
|
||||
/**
|
||||
Asynchronously creates a `ListMonitor` for a list of `DynamicObject`s that satisfy the specified `FetchChainableBuilderType` built from a chain of clauses. Since `NSFetchedResultsController` greedily locks the persistent store on initial fetch, you may prefer this method instead of the synchronous counterpart to avoid deadlocks while background updates/saves are being executed.
|
||||
|
||||
```
|
||||
CoreStore.monitorList(
|
||||
{ (monitor) in
|
||||
self.monitor = monitor
|
||||
},
|
||||
From<MyPersonEntity>()
|
||||
.where(\.age > 18)
|
||||
.orderBy(.ascending(\.age))
|
||||
)
|
||||
```
|
||||
- parameter createAsynchronously: the closure that receives the created `ListMonitor` instance
|
||||
- parameter clauseChain: a `FetchChainableBuilderType` built from a chain of clauses
|
||||
- returns: a `ListMonitor` for a list of `DynamicObject`s that satisfy the specified `FetchChainableBuilderType`
|
||||
*/
|
||||
public static func monitorList<B: FetchChainableBuilderType>(createAsynchronously: @escaping (ListMonitor<B.ObjectType>) -> Void, _ clauseChain: B) {
|
||||
|
||||
self.defaultStack.monitorList(
|
||||
createAsynchronously: createAsynchronously,
|
||||
clauseChain.from,
|
||||
clauseChain.fetchClauses
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
Using the `defaultStack`, creates a `ListMonitor` for a sectioned list of `DynamicObject`s that satisfy the specified fetch clauses. Multiple `ListObserver`s may then register themselves to be notified when changes are made to the list.
|
||||
|
||||
@@ -99,7 +142,7 @@ public extension CoreStore {
|
||||
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
- returns: a `ListMonitor` instance that monitors changes to the list
|
||||
*/
|
||||
public static func monitorSectionedList<T: DynamicObject>(_ from: From<T>, _ sectionBy: SectionBy, _ fetchClauses: FetchClause...) -> ListMonitor<T> {
|
||||
public static func monitorSectionedList<D>(_ from: From<D>, _ sectionBy: SectionBy<D>, _ fetchClauses: FetchClause...) -> ListMonitor<D> {
|
||||
|
||||
return self.defaultStack.monitorSectionedList(from, sectionBy, fetchClauses)
|
||||
}
|
||||
@@ -112,11 +155,33 @@ public extension CoreStore {
|
||||
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
- returns: a `ListMonitor` instance that monitors changes to the list
|
||||
*/
|
||||
public static func monitorSectionedList<T: DynamicObject>(_ from: From<T>, _ sectionBy: SectionBy, _ fetchClauses: [FetchClause]) -> ListMonitor<T> {
|
||||
public static func monitorSectionedList<D>(_ from: From<D>, _ sectionBy: SectionBy<D>, _ fetchClauses: [FetchClause]) -> ListMonitor<D> {
|
||||
|
||||
return self.defaultStack.monitorSectionedList(from, sectionBy, fetchClauses)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `ListMonitor` for a sectioned list of `DynamicObject`s that satisfy the specified `SectionMonitorBuilderType` built from a chain of clauses.
|
||||
```
|
||||
let monitor = CoreStore.monitorSectionedList(
|
||||
From<MyPersonEntity>()
|
||||
.sectionBy(\.age, { "\($0!) years old" })
|
||||
.where(\.age > 18)
|
||||
.orderBy(.ascending(\.age))
|
||||
)
|
||||
```
|
||||
- parameter clauseChain: a `SectionMonitorBuilderType` built from a chain of clauses
|
||||
- returns: a `ListMonitor` for a list of `DynamicObject`s that satisfy the specified `SectionMonitorBuilderType`
|
||||
*/
|
||||
public static func monitorSectionedList<B: SectionMonitorBuilderType>(_ clauseChain: B) -> ListMonitor<B.ObjectType> {
|
||||
|
||||
return self.defaultStack.monitorSectionedList(
|
||||
clauseChain.from,
|
||||
clauseChain.sectionBy,
|
||||
clauseChain.fetchClauses
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
Using the `defaultStack`, asynchronously creates a `ListMonitor` for a sectioned list of `DynamicObject`s that satisfy the specified fetch clauses. Multiple `ListObserver`s may then register themselves to be notified when changes are made to the list. Since `NSFetchedResultsController` greedily locks the persistent store on initial fetch, you may prefer this method instead of the synchronous counterpart to avoid deadlocks while background updates/saves are being executed.
|
||||
|
||||
@@ -125,7 +190,7 @@ public extension CoreStore {
|
||||
- parameter sectionBy: a `SectionBy` clause indicating the keyPath for the attribute to use when sorting the list into sections.
|
||||
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
*/
|
||||
public static func monitorSectionedList<T: DynamicObject>(createAsynchronously: @escaping (ListMonitor<T>) -> Void, _ from: From<T>, _ sectionBy: SectionBy, _ fetchClauses: FetchClause...) {
|
||||
public static func monitorSectionedList<D>(createAsynchronously: @escaping (ListMonitor<D>) -> Void, _ from: From<D>, _ sectionBy: SectionBy<D>, _ fetchClauses: FetchClause...) {
|
||||
|
||||
self.defaultStack.monitorSectionedList(createAsynchronously: createAsynchronously, from, sectionBy, fetchClauses)
|
||||
}
|
||||
@@ -138,8 +203,34 @@ public extension CoreStore {
|
||||
- parameter sectionBy: a `SectionBy` clause indicating the keyPath for the attribute to use when sorting the list into sections.
|
||||
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
*/
|
||||
public static func monitorSectionedList<T: DynamicObject>(createAsynchronously: @escaping (ListMonitor<T>) -> Void, _ from: From<T>, _ sectionBy: SectionBy, _ fetchClauses: [FetchClause]) {
|
||||
public static func monitorSectionedList<D>(createAsynchronously: @escaping (ListMonitor<D>) -> Void, _ from: From<D>, _ sectionBy: SectionBy<D>, _ fetchClauses: [FetchClause]) {
|
||||
|
||||
self.defaultStack.monitorSectionedList(createAsynchronously: createAsynchronously, from, sectionBy, fetchClauses)
|
||||
}
|
||||
|
||||
/**
|
||||
Asynchronously creates a `ListMonitor` for a sectioned list of `DynamicObject`s that satisfy the specified `SectionMonitorBuilderType` built from a chain of clauses.
|
||||
```
|
||||
CoreStore.monitorSectionedList(
|
||||
{ (monitor) in
|
||||
self.monitor = monitor
|
||||
},
|
||||
From<MyPersonEntity>()
|
||||
.sectionBy(\.age, { "\($0!) years old" })
|
||||
.where(\.age > 18)
|
||||
.orderBy(.ascending(\.age))
|
||||
)
|
||||
```
|
||||
- parameter clauseChain: a `SectionMonitorBuilderType` built from a chain of clauses
|
||||
- returns: a `ListMonitor` for a list of `DynamicObject`s that satisfy the specified `SectionMonitorBuilderType`
|
||||
*/
|
||||
public static func monitorSectionedList<B: SectionMonitorBuilderType>(createAsynchronously: @escaping (ListMonitor<B.ObjectType>) -> Void, _ clauseChain: B) {
|
||||
|
||||
self.defaultStack.monitorSectionedList(
|
||||
createAsynchronously: createAsynchronously,
|
||||
clauseChain.from,
|
||||
clauseChain.sectionBy,
|
||||
clauseChain.fetchClauses
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ public extension CoreStore {
|
||||
- parameter object: a reference to the object created/fetched outside the `DataStack`
|
||||
- returns: the `DynamicObject` instance if the object exists in the `DataStack`, or `nil` if not found.
|
||||
*/
|
||||
public static func fetchExisting<T: DynamicObject>(_ object: T) -> T? {
|
||||
public static func fetchExisting<D: DynamicObject>(_ object: D) -> D? {
|
||||
|
||||
return self.defaultStack.fetchExisting(object)
|
||||
}
|
||||
@@ -48,7 +48,7 @@ public extension CoreStore {
|
||||
- parameter objectID: the `NSManagedObjectID` for the object
|
||||
- returns: the `DynamicObject` instance if the object exists in the `DataStack`, or `nil` if not found.
|
||||
*/
|
||||
public static func fetchExisting<T: DynamicObject>(_ objectID: NSManagedObjectID) -> T? {
|
||||
public static func fetchExisting<D: DynamicObject>(_ objectID: NSManagedObjectID) -> D? {
|
||||
|
||||
return self.defaultStack.fetchExisting(objectID)
|
||||
}
|
||||
@@ -59,7 +59,7 @@ public extension CoreStore {
|
||||
- parameter objects: an array of `DynamicObject`s created/fetched outside the `DataStack`
|
||||
- returns: the `DynamicObject` array for objects that exists in the `DataStack`
|
||||
*/
|
||||
public static func fetchExisting<T: DynamicObject, S: Sequence>(_ objects: S) -> [T] where S.Iterator.Element == T {
|
||||
public static func fetchExisting<D: DynamicObject, S: Sequence>(_ objects: S) -> [D] where S.Iterator.Element == D {
|
||||
|
||||
return self.defaultStack.fetchExisting(objects)
|
||||
}
|
||||
@@ -70,7 +70,7 @@ public extension CoreStore {
|
||||
- parameter objectIDs: the `NSManagedObjectID` array for the objects
|
||||
- returns: the `DynamicObject` array for objects that exists in the `DataStack`
|
||||
*/
|
||||
public static func fetchExisting<T: DynamicObject, S: Sequence>(_ objectIDs: S) -> [T] where S.Iterator.Element == NSManagedObjectID {
|
||||
public static func fetchExisting<D: DynamicObject, S: Sequence>(_ objectIDs: S) -> [D] where S.Iterator.Element == NSManagedObjectID {
|
||||
|
||||
return self.defaultStack.fetchExisting(objectIDs)
|
||||
}
|
||||
@@ -82,7 +82,7 @@ public extension CoreStore {
|
||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
- returns: the first `DynamicObject` instance that satisfies the specified `FetchClause`s
|
||||
*/
|
||||
public static func fetchOne<T: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> T? {
|
||||
public static func fetchOne<D>(_ from: From<D>, _ fetchClauses: FetchClause...) -> D? {
|
||||
|
||||
return self.defaultStack.fetchOne(from, fetchClauses)
|
||||
}
|
||||
@@ -94,11 +94,28 @@ public extension CoreStore {
|
||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
- returns: the first `DynamicObject` instance that satisfies the specified `FetchClause`s
|
||||
*/
|
||||
public static func fetchOne<T: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> T? {
|
||||
public static func fetchOne<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) -> D? {
|
||||
|
||||
return self.defaultStack.fetchOne(from, fetchClauses)
|
||||
}
|
||||
|
||||
/**
|
||||
Fetches the first `DynamicObject` instance that satisfies the specified `FetchChainableBuilderType` built from a chain of clauses.
|
||||
```
|
||||
let youngestTeen = CoreStore.fetchOne(
|
||||
From<MyPersonEntity>()
|
||||
.where(\.age > 18)
|
||||
.orderBy(.ascending(\.age))
|
||||
)
|
||||
```
|
||||
- parameter clauseChain: a `FetchChainableBuilderType` built from a chain of clauses
|
||||
- returns: the first `DynamicObject` instance that satisfies the specified `FetchChainableBuilderType`
|
||||
*/
|
||||
public static func fetchOne<B: FetchChainableBuilderType>(_ clauseChain: B) -> B.ObjectType? {
|
||||
|
||||
return self.defaultStack.fetchOne(clauseChain)
|
||||
}
|
||||
|
||||
/**
|
||||
Using the `defaultStack`, fetches all `DynamicObject` instances that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
|
||||
@@ -106,7 +123,7 @@ public extension CoreStore {
|
||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
- returns: all `DynamicObject` instances that satisfy the specified `FetchClause`s
|
||||
*/
|
||||
public static func fetchAll<T: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> [T]? {
|
||||
public static func fetchAll<D>(_ from: From<D>, _ fetchClauses: FetchClause...) -> [D]? {
|
||||
|
||||
return self.defaultStack.fetchAll(from, fetchClauses)
|
||||
}
|
||||
@@ -118,11 +135,28 @@ public extension CoreStore {
|
||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
- returns: all `DynamicObject` instances that satisfy the specified `FetchClause`s
|
||||
*/
|
||||
public static func fetchAll<T: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> [T]? {
|
||||
public static func fetchAll<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) -> [D]? {
|
||||
|
||||
return self.defaultStack.fetchAll(from, fetchClauses)
|
||||
}
|
||||
|
||||
/**
|
||||
Fetches all `DynamicObject` instances that satisfy the specified `FetchChainableBuilderType` built from a chain of clauses.
|
||||
```
|
||||
let people = CoreStore.fetchAll(
|
||||
From<MyPersonEntity>()
|
||||
.where(\.age > 18)
|
||||
.orderBy(.ascending(\.age))
|
||||
)
|
||||
```
|
||||
- parameter clauseChain: a `FetchChainableBuilderType` built from a chain of clauses
|
||||
- returns: all `DynamicObject` instances that satisfy the specified `FetchChainableBuilderType`
|
||||
*/
|
||||
public static func fetchAll<B: FetchChainableBuilderType>(_ clauseChain: B) -> [B.ObjectType]? {
|
||||
|
||||
return self.defaultStack.fetchAll(clauseChain)
|
||||
}
|
||||
|
||||
/**
|
||||
Using the `defaultStack`, fetches the number of `DynamicObject`s that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
|
||||
@@ -130,7 +164,7 @@ public extension CoreStore {
|
||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
- returns: the number `DynamicObject`s that satisfy the specified `FetchClause`s
|
||||
*/
|
||||
public static func fetchCount<T: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> Int? {
|
||||
public static func fetchCount<D>(_ from: From<D>, _ fetchClauses: FetchClause...) -> Int? {
|
||||
|
||||
return self.defaultStack.fetchCount(from, fetchClauses)
|
||||
}
|
||||
@@ -142,11 +176,28 @@ public extension CoreStore {
|
||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
- returns: the number `DynamicObject`s that satisfy the specified `FetchClause`s
|
||||
*/
|
||||
public static func fetchCount<T: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> Int? {
|
||||
public static func fetchCount<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) -> Int? {
|
||||
|
||||
return self.defaultStack.fetchCount(from, fetchClauses)
|
||||
}
|
||||
|
||||
/**
|
||||
Fetches the number of `DynamicObject`s that satisfy the specified `FetchChainableBuilderType` built from a chain of clauses.
|
||||
```
|
||||
let numberOfAdults = CoreStore.fetchCount(
|
||||
From<MyPersonEntity>()
|
||||
.where(\.age > 18)
|
||||
.orderBy(.ascending(\.age))
|
||||
)
|
||||
```
|
||||
- parameter clauseChain: a `FetchChainableBuilderType` built from a chain of clauses
|
||||
- returns: the number `DynamicObject`s that satisfy the specified `FetchChainableBuilderType`
|
||||
*/
|
||||
public static func fetchCount<B: FetchChainableBuilderType>(_ clauseChain: B) -> Int? {
|
||||
|
||||
return self.defaultStack.fetchCount(clauseChain)
|
||||
}
|
||||
|
||||
/**
|
||||
Using the `defaultStack`, fetches the `NSManagedObjectID` for the first `DynamicObject` that satisfies the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
|
||||
@@ -154,7 +205,7 @@ public extension CoreStore {
|
||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
- returns: the `NSManagedObjectID` for the first `DynamicObject` that satisfies the specified `FetchClause`s
|
||||
*/
|
||||
public static func fetchObjectID<T: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> NSManagedObjectID? {
|
||||
public static func fetchObjectID<D>(_ from: From<D>, _ fetchClauses: FetchClause...) -> NSManagedObjectID? {
|
||||
|
||||
return self.defaultStack.fetchObjectID(from, fetchClauses)
|
||||
}
|
||||
@@ -166,11 +217,28 @@ public extension CoreStore {
|
||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
- returns: the `NSManagedObjectID` for the first `DynamicObject` that satisfies the specified `FetchClause`s
|
||||
*/
|
||||
public static func fetchObjectID<T: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> NSManagedObjectID? {
|
||||
public static func fetchObjectID<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) -> NSManagedObjectID? {
|
||||
|
||||
return self.defaultStack.fetchObjectID(from, fetchClauses)
|
||||
}
|
||||
|
||||
/**
|
||||
Fetches the `NSManagedObjectID` for the first `DynamicObject` that satisfies the specified `FetchChainableBuilderType` built from a chain of clauses.
|
||||
```
|
||||
let youngestTeenID = CoreStore.fetchObjectID(
|
||||
From<MyPersonEntity>()
|
||||
.where(\.age > 18)
|
||||
.orderBy(.ascending(\.age))
|
||||
)
|
||||
```
|
||||
- parameter clauseChain: a `FetchChainableBuilderType` built from a chain of clauses
|
||||
- returns: the `NSManagedObjectID` for the first `DynamicObject` that satisfies the specified `FetchChainableBuilderType`
|
||||
*/
|
||||
public static func fetchObjectID<B: FetchChainableBuilderType>(_ clauseChain: B) -> NSManagedObjectID? {
|
||||
|
||||
return self.defaultStack.fetchObjectID(clauseChain)
|
||||
}
|
||||
|
||||
/**
|
||||
Using the `defaultStack`, fetches the `NSManagedObjectID` for all `DynamicObject`s that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
|
||||
@@ -178,7 +246,7 @@ public extension CoreStore {
|
||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
- returns: the `NSManagedObjectID` for all `DynamicObject`s that satisfy the specified `FetchClause`s
|
||||
*/
|
||||
public static func fetchObjectIDs<T: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> [NSManagedObjectID]? {
|
||||
public static func fetchObjectIDs<D>(_ from: From<D>, _ fetchClauses: FetchClause...) -> [NSManagedObjectID]? {
|
||||
|
||||
return self.defaultStack.fetchObjectIDs(from, fetchClauses)
|
||||
}
|
||||
@@ -190,11 +258,28 @@ public extension CoreStore {
|
||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
- returns: the `NSManagedObjectID` for all `DynamicObject`s that satisfy the specified `FetchClause`s
|
||||
*/
|
||||
public static func fetchObjectIDs<T: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> [NSManagedObjectID]? {
|
||||
public static func fetchObjectIDs<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) -> [NSManagedObjectID]? {
|
||||
|
||||
return self.defaultStack.fetchObjectIDs(from, fetchClauses)
|
||||
}
|
||||
|
||||
/**
|
||||
Fetches the `NSManagedObjectID` for all `DynamicObject`s that satisfy the specified `FetchChainableBuilderType` built from a chain of clauses.
|
||||
```
|
||||
let idsOfAdults = transaction.fetchObjectIDs(
|
||||
From<MyPersonEntity>()
|
||||
.where(\.age > 18)
|
||||
.orderBy(.ascending(\.age))
|
||||
)
|
||||
```
|
||||
- parameter clauseChain: a `FetchChainableBuilderType` built from a chain of clauses
|
||||
- returns: the `NSManagedObjectID` for all `DynamicObject`s that satisfy the specified `FetchChainableBuilderType`
|
||||
*/
|
||||
public static func fetchObjectIDs<B: FetchChainableBuilderType>(_ clauseChain: B) -> [NSManagedObjectID]? {
|
||||
|
||||
return self.defaultStack.fetchObjectIDs(clauseChain)
|
||||
}
|
||||
|
||||
/**
|
||||
Using the `defaultStack`, queries aggregate values as specified by the `QueryClause`s. Requires at least a `Select` clause, and optional `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
||||
|
||||
@@ -205,7 +290,7 @@ public extension CoreStore {
|
||||
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
||||
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
|
||||
*/
|
||||
public static func queryValue<T: DynamicObject, U: QueryableAttributeType>(_ from: From<T>, _ selectClause: Select<U>, _ queryClauses: QueryClause...) -> U? {
|
||||
public static func queryValue<D, U: QueryableAttributeType>(_ from: From<D>, _ selectClause: Select<D, U>, _ queryClauses: QueryClause...) -> U? {
|
||||
|
||||
return self.defaultStack.queryValue(from, selectClause, queryClauses)
|
||||
}
|
||||
@@ -220,11 +305,30 @@ public extension CoreStore {
|
||||
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
||||
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
|
||||
*/
|
||||
public static func queryValue<T: DynamicObject, U: QueryableAttributeType>(_ from: From<T>, _ selectClause: Select<U>, _ queryClauses: [QueryClause]) -> U? {
|
||||
public static func queryValue<D, U: QueryableAttributeType>(_ from: From<D>, _ selectClause: Select<D, U>, _ queryClauses: [QueryClause]) -> U? {
|
||||
|
||||
return self.defaultStack.queryValue(from, selectClause, queryClauses)
|
||||
}
|
||||
|
||||
/**
|
||||
Queries a property value or aggregate as specified by the `QueryChainableBuilderType` built from a chain of clauses.
|
||||
|
||||
A "query" differs from a "fetch" in that it only retrieves values already stored in the persistent store. As such, values from unsaved transactions or contexts will not be incorporated in the query result.
|
||||
```
|
||||
let averageAdultAge = CoreStore.queryValue(
|
||||
From<MyPersonEntity>()
|
||||
.select(Int.self, .average(\.age))
|
||||
.where(\.age > 18)
|
||||
)
|
||||
```
|
||||
- parameter clauseChain: a `QueryChainableBuilderType` indicating the property/aggregate to fetch and the series of queries for the request.
|
||||
- returns: the result of the the query as specified by the `QueryChainableBuilderType`
|
||||
*/
|
||||
public static func queryValue<B: QueryChainableBuilderType>(_ clauseChain: B) -> B.ResultType? where B.ResultType: QueryableAttributeType {
|
||||
|
||||
return self.defaultStack.queryValue(clauseChain)
|
||||
}
|
||||
|
||||
/**
|
||||
Using the `defaultStack`, queries a dictionary of attribtue values as specified by the `QueryClause`s. Requires at least a `Select` clause, and optional `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
||||
|
||||
@@ -235,7 +339,7 @@ public extension CoreStore {
|
||||
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
||||
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
|
||||
*/
|
||||
public static func queryAttributes<T: DynamicObject>(_ from: From<T>, _ selectClause: Select<NSDictionary>, _ queryClauses: QueryClause...) -> [[String: Any]]? {
|
||||
public static func queryAttributes<D>(_ from: From<D>, _ selectClause: Select<D, NSDictionary>, _ queryClauses: QueryClause...) -> [[String: Any]]? {
|
||||
|
||||
return self.defaultStack.queryAttributes(from, selectClause, queryClauses)
|
||||
}
|
||||
@@ -250,8 +354,36 @@ public extension CoreStore {
|
||||
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
||||
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
|
||||
*/
|
||||
public static func queryAttributes<T: DynamicObject>(_ from: From<T>, _ selectClause: Select<NSDictionary>, _ queryClauses: [QueryClause]) -> [[String: Any]]? {
|
||||
public static func queryAttributes<D>(_ from: From<D>, _ selectClause: Select<D, NSDictionary>, _ queryClauses: [QueryClause]) -> [[String: Any]]? {
|
||||
|
||||
return self.defaultStack.queryAttributes(from, selectClause, queryClauses)
|
||||
}
|
||||
|
||||
/**
|
||||
Queries a dictionary of attribute values or as specified by the `QueryChainableBuilderType` built from a chain of clauses.
|
||||
|
||||
A "query" differs from a "fetch" in that it only retrieves values already stored in the persistent store. As such, values from unsaved transactions or contexts will not be incorporated in the query result.
|
||||
```
|
||||
let results = CoreStore.queryAttributes(
|
||||
From<MyPersonEntity>()
|
||||
.select(
|
||||
NSDictionary.self,
|
||||
.attribute(\.age, as: "age"),
|
||||
.count(\.age, as: "numberOfPeople")
|
||||
)
|
||||
.groupBy(\.age)
|
||||
)
|
||||
for dictionary in results! {
|
||||
let age = dictionary["age"] as! Int
|
||||
let count = dictionary["numberOfPeople"] as! Int
|
||||
print("There are \(count) people who are \(age) years old."
|
||||
}
|
||||
```
|
||||
- parameter clauseChain: a `QueryChainableBuilderType` indicating the properties to fetch and the series of queries for the request.
|
||||
- returns: the result of the the query as specified by the `QueryChainableBuilderType`
|
||||
*/
|
||||
public static func queryAttributes<B: QueryChainableBuilderType>(_ clauseChain: B) -> [[String: Any]]? where B.ResultType == NSDictionary {
|
||||
|
||||
return self.defaultStack.queryAttributes(clauseChain)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ public extension CoreStore {
|
||||
}
|
||||
|
||||
/**
|
||||
Using the `defaultStack`, performs a transaction synchronously where `NSManagedObject` or `CoreStoreObject` creates, updates, and deletes can be made. The changes are commited automatically after the `task` closure returns. On success, the value returned from closure will be the return value of `perform(synchronous:)`. Any errors thrown from inside the `task` will be rethrown from `perform(synchronous:)`. To cancel/rollback changes, call `try transaction.cancel()`, which throws a `CoreStoreError.userCancelled`.
|
||||
Using the `defaultStack`, performs a transaction synchronously where `NSManagedObject` or `CoreStoreObject` creates, updates, and deletes can be made. The changes are commited automatically after the `task` closure returns. On success, the value returned from closure will be the return value of `perform(synchronous:)`. Any errors thrown from inside the `task` will be thrown from `perform(synchronous:)`. To cancel/rollback changes, call `try transaction.cancel()`, which throws a `CoreStoreError.userCancelled`.
|
||||
|
||||
- parameter task: the synchronous non-escaping closure where creates, updates, and deletes can be made to the transaction. Transaction blocks are executed serially in a background queue, and all changes are made from a concurrent `NSManagedObjectContext`.
|
||||
- parameter waitForAllObservers: When `true`, this method waits for all observers to be notified of the changes before returning. This results in more predictable data update order, but may risk triggering deadlocks. When `false`, this method does not wait for observers to be notified of the changes before returning. This results in lower risk for deadlocks, but the updated data may not have been propagated to the `DataStack` after returning. Defaults to `true`.
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
#define CORESTORE_RETURNS_RETAINED __attribute__((ns_returns_retained))
|
||||
|
||||
|
||||
#pragma mark - KeyPath Utilities
|
||||
#pragma mark - KeyPathString Utilities
|
||||
|
||||
#define CSKeyPath(type, property) ({ \
|
||||
type *_je_keypath_dummy __attribute__((unused)); \
|
||||
@@ -477,7 +477,7 @@ CSSelect *_Nonnull CSSelectData(CSSelectTerm *_Nonnull selectTerm) CORESTORE_RET
|
||||
a <tt>CSSelect</tt> clause for querying an <tt>NSManagedObjectID</tt> value
|
||||
*/
|
||||
CORESTORE_EXTERN
|
||||
CSSelect *_Nonnull CSSelectObjectID() CORESTORE_RETURNS_RETAINED;
|
||||
CSSelect *_Nonnull CSSelectObjectID(void) CORESTORE_RETURNS_RETAINED;
|
||||
|
||||
|
||||
#pragma mark CSTweak
|
||||
|
||||
@@ -235,15 +235,15 @@ CSWhere *_Nonnull CSWherePredicate(NSPredicate *_Nonnull predicate) CORESTORE_RE
|
||||
|
||||
- (void)setAffectedStores:(NSArray<NSPersistentStore *> *_Nullable)affectedStores {
|
||||
|
||||
// Bugfix for NSFetchRequest messing up memory management for `affectedStores`
|
||||
// http://stackoverflow.com/questions/14396375/nsfetchedresultscontroller-crashes-in-ios-6-if-affectedstores-is-specified
|
||||
|
||||
if (NSFoundationVersionNumber < NSFoundationVersionNumber10_0) {
|
||||
if (NSFoundationVersionNumber < NSFoundationVersionNumber10_0
|
||||
|| [[NSProcessInfo processInfo] isOperatingSystemAtLeastVersion:(NSOperatingSystemVersion){ 11, 0, 0 }]) {
|
||||
|
||||
self.safeAffectedStores = affectedStores;
|
||||
[super setAffectedStores:affectedStores];
|
||||
return;
|
||||
}
|
||||
// Bugfix for NSFetchRequest messing up memory management for `affectedStores`
|
||||
// http://stackoverflow.com/questions/14396375/nsfetchedresultscontroller-crashes-in-ios-6-if-affectedstores-is-specified
|
||||
if (self.releaseArray != NULL) {
|
||||
|
||||
CFRelease(self.releaseArray);
|
||||
|
||||
@@ -31,7 +31,7 @@ import Foundation
|
||||
/**
|
||||
`CoreStoreObjectiveCType`s are Objective-C accessible classes that represent CoreStore's Swift types.
|
||||
*/
|
||||
public protocol CoreStoreObjectiveCType: class, AnyObject {
|
||||
public protocol CoreStoreObjectiveCType: class {
|
||||
|
||||
/**
|
||||
The corresponding Swift type
|
||||
|
||||
@@ -282,7 +282,7 @@ public enum CoreStoreErrorCode: Int {
|
||||
|
||||
// MARK: - NSError
|
||||
|
||||
public extension NSError {
|
||||
internal extension NSError {
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
@@ -294,7 +294,8 @@ public extension NSError {
|
||||
}
|
||||
switch CocoaError.Code(rawValue: self.code) {
|
||||
|
||||
case CocoaError.Code.persistentStoreIncompatibleVersionHash,
|
||||
case CocoaError.Code.persistentStoreIncompatibleSchema,
|
||||
CocoaError.Code.persistentStoreIncompatibleVersionHash,
|
||||
CocoaError.Code.migrationMissingSourceModel,
|
||||
CocoaError.Code.migration:
|
||||
return true
|
||||
|
||||
@@ -34,7 +34,7 @@ internal extension CoreStoreFetchRequest {
|
||||
// MARK: Internal
|
||||
|
||||
@nonobjc @inline(__always)
|
||||
internal func dynamicCast<U: NSFetchRequestResult>() -> NSFetchRequest<U> {
|
||||
internal func dynamicCast<U>() -> NSFetchRequest<U> {
|
||||
|
||||
return unsafeBitCast(self, to: NSFetchRequest<U>.self)
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ internal final class CoreStoreFetchedResultsController: NSFetchedResultsControll
|
||||
// MARK: Internal
|
||||
|
||||
@nonobjc
|
||||
internal convenience init<T: DynamicObject>(dataStack: DataStack, fetchRequest: NSFetchRequest<NSManagedObject>, from: From<T>?, sectionBy: SectionBy? = nil, applyFetchClauses: @escaping (_ fetchRequest: NSFetchRequest<NSManagedObject>) -> Void) {
|
||||
internal convenience init<D>(dataStack: DataStack, fetchRequest: NSFetchRequest<NSManagedObject>, from: From<D>, sectionBy: SectionBy<D>? = nil, applyFetchClauses: @escaping (_ fetchRequest: NSFetchRequest<NSManagedObject>) -> Void) {
|
||||
|
||||
self.init(
|
||||
context: dataStack.mainContext,
|
||||
@@ -47,33 +47,18 @@ internal final class CoreStoreFetchedResultsController: NSFetchedResultsControll
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
internal init<T: DynamicObject>(context: NSManagedObjectContext, fetchRequest: NSFetchRequest<NSManagedObject>, from: From<T>?, sectionBy: SectionBy? = nil, applyFetchClauses: @escaping (_ fetchRequest: NSFetchRequest<NSManagedObject>) -> Void) {
|
||||
internal init<D>(context: NSManagedObjectContext, fetchRequest: NSFetchRequest<NSManagedObject>, from: From<D>, sectionBy: SectionBy<D>? = nil, applyFetchClauses: @escaping (_ fetchRequest: NSFetchRequest<NSManagedObject>) -> Void) {
|
||||
|
||||
_ = from?.applyToFetchRequest(
|
||||
_ = from.applyToFetchRequest(
|
||||
fetchRequest,
|
||||
context: context,
|
||||
applyAffectedStores: false
|
||||
)
|
||||
applyFetchClauses(fetchRequest)
|
||||
|
||||
if let from = from {
|
||||
self.reapplyAffectedStores = { fetchRequest, context in
|
||||
|
||||
self.reapplyAffectedStores = { fetchRequest, context in
|
||||
|
||||
return from.applyAffectedStoresForFetchedRequest(fetchRequest, context: context)
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
guard let from = (fetchRequest.entity.flatMap { $0.managedObjectClassName }).flatMap(NSClassFromString).flatMap({ From<T>($0 as! T.Type) }) else {
|
||||
|
||||
CoreStore.abort("Attempted to create a \(CoreStoreFetchedResultsController.self) without a \(cs_typeName(From<T>.self)) clause or an \(cs_typeName(NSEntityDescription.self)).")
|
||||
}
|
||||
|
||||
self.reapplyAffectedStores = { fetchRequest, context in
|
||||
|
||||
return from.applyAffectedStoresForFetchedRequest(fetchRequest, context: context)
|
||||
}
|
||||
return from.applyAffectedStoresForFetchedRequest(fetchRequest, context: context)
|
||||
}
|
||||
|
||||
super.init(
|
||||
@@ -98,7 +83,7 @@ internal final class CoreStoreFetchedResultsController: NSFetchedResultsControll
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
internal func dynamicCast<U: NSFetchRequestResult>() -> NSFetchedResultsController<U> {
|
||||
internal func dynamicCast<U>() -> NSFetchedResultsController<U> {
|
||||
|
||||
return unsafeBitCast(self, to: NSFetchedResultsController<U>.self)
|
||||
}
|
||||
|
||||
@@ -47,12 +47,6 @@ public enum LogLevel {
|
||||
*/
|
||||
public protocol CoreStoreLogger {
|
||||
|
||||
/**
|
||||
When `true`, all `NSManagedObject` attribute and relationship access will raise an assertion when executed on the wrong transaction/datastack queue. Defaults to `false` if not implemented.
|
||||
*/
|
||||
// TODO: test before release (rolled back)
|
||||
// var enableObjectConcurrencyDebugging: Bool { get set }
|
||||
|
||||
/**
|
||||
Handles log messages sent by the `CoreStore` framework.
|
||||
|
||||
@@ -100,13 +94,6 @@ public protocol CoreStoreLogger {
|
||||
|
||||
extension CoreStoreLogger {
|
||||
|
||||
// TODO: test before release (rolled back)
|
||||
// public var enableObjectConcurrencyDebugging: Bool {
|
||||
//
|
||||
// get { return false }
|
||||
// set {}
|
||||
// }
|
||||
|
||||
public func abort(_ message: String, fileName: StaticString, lineNumber: Int, functionName: StaticString) {
|
||||
|
||||
Swift.fatalError(message, file: fileName, line: UInt(lineNumber))
|
||||
|
||||
51
Sources/CoreStoreManagedObject.swift
Normal file
51
Sources/CoreStoreManagedObject.swift
Normal file
@@ -0,0 +1,51 @@
|
||||
//
|
||||
// CoreStoreManagedObject.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright © 2017 John Rommel Estropia
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
|
||||
import CoreData
|
||||
|
||||
|
||||
// MARK: - CoreStoreManagedObject
|
||||
|
||||
@objc internal class CoreStoreManagedObject: NSManagedObject {
|
||||
|
||||
internal typealias CustomGetter = @convention(block) (_ rawObject: Any) -> Any?
|
||||
internal typealias CustomSetter = @convention(block) (_ rawObject: Any, _ newValue: Any?) -> Void
|
||||
internal typealias CustomGetterSetter = (getter: CustomGetter?, setter: CustomSetter?)
|
||||
|
||||
@nonobjc @inline(__always)
|
||||
internal static func cs_subclassName(for entity: DynamicEntity, in modelVersion: ModelVersion) -> String {
|
||||
|
||||
return "_\(NSStringFromClass(CoreStoreManagedObject.self))__\(modelVersion)__\(NSStringFromClass(entity.type))__\(entity.entityName)"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private enum Static {
|
||||
|
||||
static let queue = DispatchQueue.concurrent("com.coreStore.coreStoreManagerObjectBarrierQueue")
|
||||
static var cache: [ObjectIdentifier: [KeyPathString: Set<KeyPathString>]] = [:]
|
||||
}
|
||||
@@ -27,141 +27,85 @@ import CoreData
|
||||
import Foundation
|
||||
|
||||
|
||||
// MARK: - DynamicObject
|
||||
|
||||
public extension DynamicObject where Self: CoreStoreObject {
|
||||
|
||||
/**
|
||||
Extracts the keyPath string from a `CoreStoreObject.Value` property.
|
||||
```
|
||||
let keyPath: String = Person.keyPath { $0.nickname }
|
||||
```
|
||||
*/
|
||||
public static func keyPath<O: CoreStoreObject, V: ImportableAttributeType>(_ attribute: (Self) -> ValueContainer<O>.Required<V>) -> String {
|
||||
|
||||
return attribute(self.meta).keyPath
|
||||
}
|
||||
|
||||
/**
|
||||
Extracts the keyPath string from a `CoreStoreObject.Value` property.
|
||||
```
|
||||
let keyPath: String = Person.keyPath { $0.nickname }
|
||||
```
|
||||
*/
|
||||
public static func keyPath<O: CoreStoreObject, V: ImportableAttributeType>(_ attribute: (Self) -> ValueContainer<O>.Optional<V>) -> String {
|
||||
|
||||
return attribute(self.meta).keyPath
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause from a `CoreStoreObject.Value` property.
|
||||
```
|
||||
let person = CoreStore.fetchOne(From<Person>(), Person.where { $0.nickname == "John" })
|
||||
```
|
||||
*/
|
||||
public static func `where`(_ condition: (Self) -> Where) -> Where {
|
||||
|
||||
return condition(self.meta)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates an `OrderBy` clause from a `CoreStoreObject.Value` property.
|
||||
```
|
||||
let person = CoreStore.fetchAll(From<Person>(), Person.ascending { $0.age })
|
||||
```
|
||||
*/
|
||||
public static func ascending<O: CoreStoreObject, V: ImportableAttributeType>(_ attribute: (Self) -> ValueContainer<O>.Optional<V>) -> OrderBy {
|
||||
|
||||
return OrderBy(.ascending(attribute(self.meta).keyPath))
|
||||
}
|
||||
|
||||
/**
|
||||
Creates an `OrderBy` clause from a `CoreStoreObject.Value` property.
|
||||
```
|
||||
let person = CoreStore.fetchAll(From<Person>(), Person.descending { $0.age })
|
||||
```
|
||||
*/
|
||||
public static func descending<O: CoreStoreObject, V: ImportableAttributeType>(_ attribute: (Self) -> ValueContainer<O>.Optional<V>) -> OrderBy {
|
||||
|
||||
return OrderBy(.descending(attribute(self.meta).keyPath))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - ValueContainer.Required
|
||||
|
||||
public extension ValueContainer.Required {
|
||||
|
||||
/**
|
||||
Creates a `Where` clause from a `CoreStoreObject.Value` property.
|
||||
Creates a `Where` clause by comparing if a property is equal to a value
|
||||
```
|
||||
let person = CoreStore.fetchOne(From<Person>(), Person.where { $0.nickname == "John" })
|
||||
let person = CoreStore.fetchOne(From<Person>().where({ $0.nickname == "John" }))
|
||||
```
|
||||
*/
|
||||
@inline(__always)
|
||||
public static func == (_ attribute: ValueContainer<O>.Required<V>, _ value: V) -> Where {
|
||||
public static func == (_ attribute: ValueContainer<O>.Required<V>, _ value: V) -> Where<O> {
|
||||
|
||||
return Where(attribute.keyPath, isEqualTo: value)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause from a `CoreStoreObject.Value` property.
|
||||
Creates a `Where` clause by comparing if a property is not equal to a value
|
||||
```
|
||||
let person = CoreStore.fetchOne(From<Person>(), Person.where { $0.nickname != "John" })
|
||||
let person = CoreStore.fetchOne(From<Person>().where({ $0.nickname != "John" }))
|
||||
```
|
||||
*/
|
||||
@inline(__always)
|
||||
public static func != (_ attribute: ValueContainer<O>.Required<V>, _ value: V) -> Where {
|
||||
public static func != (_ attribute: ValueContainer<O>.Required<V>, _ value: V) -> Where<O> {
|
||||
|
||||
return !Where(attribute.keyPath, isEqualTo: value)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause from a `CoreStoreObject.Value` property.
|
||||
Creates a `Where` clause by comparing if a property is less than a value
|
||||
```
|
||||
let person = CoreStore.fetchOne(From<Person>(), Person.where { $0.age < 20 })
|
||||
let person = CoreStore.fetchOne(From<Person>().where({ $0.age < 20 }))
|
||||
```
|
||||
*/
|
||||
@inline(__always)
|
||||
public static func < (_ attribute: ValueContainer<O>.Required<V>, _ value: V) -> Where {
|
||||
public static func < (_ attribute: ValueContainer<O>.Required<V>, _ value: V) -> Where<O> {
|
||||
|
||||
return Where("%K < %@", attribute.keyPath, value)
|
||||
return Where("%K < %@", attribute.keyPath, value.cs_toQueryableNativeType())
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause from a `CoreStoreObject.Value` property.
|
||||
Creates a `Where` clause by comparing if a property is greater than a value
|
||||
```
|
||||
let person = CoreStore.fetchOne(From<Person>(), Person.where { $0.age > 20 })
|
||||
let person = CoreStore.fetchOne(From<Person>().where({ $0.age > 20 }))
|
||||
```
|
||||
*/
|
||||
@inline(__always)
|
||||
public static func > (_ attribute: ValueContainer<O>.Required<V>, _ value: V) -> Where {
|
||||
public static func > (_ attribute: ValueContainer<O>.Required<V>, _ value: V) -> Where<O> {
|
||||
|
||||
return Where("%K > %@", attribute.keyPath, value)
|
||||
return Where("%K > %@", attribute.keyPath, value.cs_toQueryableNativeType())
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause from a `CoreStoreObject.Value` property.
|
||||
Creates a `Where` clause by comparing if a property is less than or equal to a value
|
||||
```
|
||||
let person = CoreStore.fetchOne(From<Person>(), Person.where { $0.age <= 20 })
|
||||
let person = CoreStore.fetchOne(From<Person>().where({ $0.age <= 20 }))
|
||||
```
|
||||
*/
|
||||
@inline(__always)
|
||||
public static func <= (_ attribute: ValueContainer<O>.Required<V>, _ value: V) -> Where {
|
||||
public static func <= (_ attribute: ValueContainer<O>.Required<V>, _ value: V) -> Where<O> {
|
||||
|
||||
return Where("%K <= %@", attribute.keyPath, value)
|
||||
return Where("%K <= %@", attribute.keyPath, value.cs_toQueryableNativeType())
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause from a `CoreStoreObject.Value` property.
|
||||
Creates a `Where` clause by comparing if a property is greater than or equal to a value
|
||||
```
|
||||
let person = CoreStore.fetchOne(From<Person>(), Person.where { $0.age >= 20 })
|
||||
let person = CoreStore.fetchOne(From<Person>().where({ $0.age >= 20 }))
|
||||
```
|
||||
*/
|
||||
@inline(__always)
|
||||
public static func >= (_ attribute: ValueContainer<O>.Required<V>, _ value: V) -> Where {
|
||||
public static func >= (_ attribute: ValueContainer<O>.Required<V>, _ value: V) -> Where<O> {
|
||||
|
||||
return Where("%K >= %@", attribute.keyPath, value)
|
||||
return Where("%K >= %@", attribute.keyPath, value.cs_toQueryableNativeType())
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by checking if a sequence contains the value of a property
|
||||
```
|
||||
let dog = CoreStore.fetchOne(From<Dog>().where({ ["Pluto", "Snoopy", "Scooby"] ~= $0.nickname }))
|
||||
```
|
||||
*/
|
||||
public static func ~= <S: Sequence>(_ sequence: S, _ attribute: ValueContainer<O>.Required<V>) -> Where<O> where S.Iterator.Element == V {
|
||||
|
||||
return Where(attribute.keyPath, isMemberOf: sequence)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,26 +115,212 @@ public extension ValueContainer.Required {
|
||||
public extension ValueContainer.Optional {
|
||||
|
||||
/**
|
||||
Creates a `Where` clause from a `CoreStoreObject.Value` property.
|
||||
Creates a `Where` clause by comparing if a property is equal to a value
|
||||
```
|
||||
let person = CoreStore.fetchOne(From<Person>(), Person.where { $0.nickname == "John" })
|
||||
let person = CoreStore.fetchOne(From<Person>().where({ $0.nickname == "John" }))
|
||||
```
|
||||
*/
|
||||
@inline(__always)
|
||||
public static func == (_ attribute: ValueContainer<O>.Optional<V>, _ value: V?) -> Where {
|
||||
public static func == (_ attribute: ValueContainer<O>.Optional<V>, _ value: V?) -> Where<O> {
|
||||
|
||||
return Where(attribute.keyPath, isEqualTo: value)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause from a `CoreStoreObject.Value` property.
|
||||
Creates a `Where` clause by comparing if a property is not equal to a value
|
||||
```
|
||||
let person = CoreStore.fetchOne(From<Person>(), Person.where { $0.nickname != "John" })
|
||||
let person = CoreStore.fetchOne(From<Person>().where({ $0.nickname != "John" }))
|
||||
```
|
||||
*/
|
||||
@inline(__always)
|
||||
public static func != (_ attribute: ValueContainer<O>.Optional<V>, _ value: V?) -> Where {
|
||||
public static func != (_ attribute: ValueContainer<O>.Optional<V>, _ value: V?) -> Where<O> {
|
||||
|
||||
return !Where(attribute.keyPath, isEqualTo: value)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if a property is less than a value
|
||||
```
|
||||
let person = CoreStore.fetchOne(From<Person>().where({ $0.age < 20 }))
|
||||
```
|
||||
*/
|
||||
public static func < (_ attribute: ValueContainer<O>.Optional<V>, _ value: V?) -> Where<O> {
|
||||
|
||||
if let value = value {
|
||||
|
||||
return Where("%K < %@", attribute.keyPath, value.cs_toQueryableNativeType())
|
||||
}
|
||||
else {
|
||||
|
||||
return Where("%K < nil", attribute.keyPath)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if a property is greater than a value
|
||||
```
|
||||
let person = CoreStore.fetchOne(From<Person>().where({ $0.age > 20 }))
|
||||
```
|
||||
*/
|
||||
public static func > (_ attribute: ValueContainer<O>.Optional<V>, _ value: V?) -> Where<O> {
|
||||
|
||||
if let value = value {
|
||||
|
||||
return Where("%K > %@", attribute.keyPath, value.cs_toQueryableNativeType())
|
||||
}
|
||||
else {
|
||||
|
||||
return Where("%K > nil", attribute.keyPath)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if a property is less than or equal to a value
|
||||
```
|
||||
let person = CoreStore.fetchOne(From<Person>().where({ $0.age <= 20 }))
|
||||
```
|
||||
*/
|
||||
public static func <= (_ attribute: ValueContainer<O>.Optional<V>, _ value: V?) -> Where<O> {
|
||||
|
||||
if let value = value {
|
||||
|
||||
return Where("%K <= %@", attribute.keyPath, value.cs_toQueryableNativeType())
|
||||
}
|
||||
else {
|
||||
|
||||
return Where("%K <= nil", attribute.keyPath)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if a property is greater than or equal to a value
|
||||
```
|
||||
let person = CoreStore.fetchOne(From<Person>().where({ $0.age >= 20 }))
|
||||
```
|
||||
*/
|
||||
public static func >= (_ attribute: ValueContainer<O>.Optional<V>, _ value: V?) -> Where<O> {
|
||||
|
||||
if let value = value {
|
||||
|
||||
return Where("%K >= %@", attribute.keyPath, value.cs_toQueryableNativeType())
|
||||
}
|
||||
else {
|
||||
|
||||
return Where("%K >= nil", attribute.keyPath)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by checking if a sequence contains the value of a property
|
||||
```
|
||||
let dog = CoreStore.fetchOne(From<Dog>().where({ ["Pluto", "Snoopy", "Scooby"] ~= $0.nickname }))
|
||||
```
|
||||
*/
|
||||
public static func ~= <S: Sequence>(_ sequence: S, _ attribute: ValueContainer<O>.Optional<V>) -> Where<O> where S.Iterator.Element == V {
|
||||
|
||||
return Where(attribute.keyPath, isMemberOf: sequence)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - RelationshipContainer.ToOne
|
||||
|
||||
public extension RelationshipContainer.ToOne {
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if a property is equal to a value
|
||||
```
|
||||
let dog = CoreStore.fetchOne(From<Dog>().where({ $0.master == me }))
|
||||
```
|
||||
*/
|
||||
public static func == (_ relationship: RelationshipContainer<O>.ToOne<D>, _ object: D?) -> Where<O> {
|
||||
|
||||
return Where(relationship.keyPath, isEqualTo: object)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by comparing if a property is not equal to a value
|
||||
```
|
||||
let dog = CoreStore.fetchOne(From<Dog>().where({ $0.master != me }))
|
||||
```
|
||||
*/
|
||||
public static func != (_ relationship: RelationshipContainer<O>.ToOne<D>, _ object: D?) -> Where<O> {
|
||||
|
||||
return !Where(relationship.keyPath, isEqualTo: object)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `Where` clause by checking if a sequence contains the value of a property
|
||||
```
|
||||
let dog = CoreStore.fetchOne(From<Dog>().where({ [john, joe, bob] ~= $0.master }))
|
||||
```
|
||||
*/
|
||||
public static func ~= <S: Sequence>(_ sequence: S, _ relationship: RelationshipContainer<O>.ToOne<D>) -> Where<O> where S.Iterator.Element == D {
|
||||
|
||||
return Where(relationship.keyPath, isMemberOf: sequence)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: Deprecated
|
||||
|
||||
extension DynamicObject where Self: CoreStoreObject {
|
||||
|
||||
@available(*, deprecated, message: "Use the String(keyPath:) initializer and pass the KeyPath: String(keyPath: \\Person.name)")
|
||||
public static func keyPath<O, V>(_ attribute: (Self) -> ValueContainer<O>.Required<V>) -> String {
|
||||
|
||||
return attribute(self.meta).keyPath
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "Use the String(keyPath:) initializer and pass the KeyPath: String(keyPath: \\Person.name)")
|
||||
public static func keyPath<O, V>(_ attribute: (Self) -> ValueContainer<O>.Optional<V>) -> String {
|
||||
|
||||
return attribute(self.meta).keyPath
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "Use the String(keyPath:) initializer and pass the KeyPath: String(keyPath: \\Person.friend)")
|
||||
public static func keyPath<O, D>(_ relationship: (Self) -> RelationshipContainer<O>.ToOne<D>) -> String {
|
||||
|
||||
return relationship(self.meta).keyPath
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "Use the String(keyPath:) initializer and pass the KeyPath: String(keyPath: \\Person.friends)")
|
||||
public static func keyPath<O, D>(_ relationship: (Self) -> RelationshipContainer<O>.ToManyOrdered<D>) -> String {
|
||||
|
||||
return relationship(self.meta).keyPath
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "Use the String(keyPath:) initializer and pass the KeyPath: String(keyPath: \\Person.friends)")
|
||||
public static func keyPath<O, D>(_ relationship: (Self) -> RelationshipContainer<O>.ToManyUnordered<D>) -> String {
|
||||
|
||||
return relationship(self.meta).keyPath
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "Use the Where<DynamicObject>(_:) initializer that accepts the same closure argument")
|
||||
public static func `where`(_ condition: (Self) -> Where<Self>) -> Where<Self> {
|
||||
|
||||
return condition(self.meta)
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "Use the new OrderBy<DynamicObject>(ascending:) overload that accepts the same closure argument")
|
||||
public static func orderBy<O, V>(ascending attribute: (Self) -> ValueContainer<O>.Required<V>) -> OrderBy<Self> {
|
||||
|
||||
return OrderBy(.ascending(attribute(self.meta).keyPath))
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "Use the new OrderBy<DynamicObject>(ascending:) overload that accepts the same closure argument")
|
||||
public static func orderBy<O, V>(ascending attribute: (Self) -> ValueContainer<O>.Optional<V>) -> OrderBy<Self> {
|
||||
|
||||
return OrderBy(.ascending(attribute(self.meta).keyPath))
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "Use the new OrderBy<DynamicObject>(descending:) overload that accepts the same closure argument")
|
||||
public static func orderBy<O, V>(descending attribute: (Self) -> ValueContainer<O>.Required<V>) -> OrderBy<Self> {
|
||||
|
||||
return OrderBy(.descending(attribute(self.meta).keyPath))
|
||||
}
|
||||
|
||||
@available(*, deprecated, message: "Use the new OrderBy<DynamicObject>(descending:) overload that accepts the same closure argument")
|
||||
public static func orderBy<O, V>(descending attribute: (Self) -> ValueContainer<O>.Optional<V>) -> OrderBy<Self> {
|
||||
|
||||
return OrderBy(.descending(attribute(self.meta).keyPath))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,13 +33,13 @@ import Foundation
|
||||
The `CoreStoreObject` is an abstract class for creating CoreStore-managed objects that are more type-safe and more convenient than `NSManagedObject` subclasses. The model entities for `CoreStoreObject` subclasses are inferred from the Swift declaration themselves; no .xcdatamodeld files are needed. To declare persisted attributes and relationships for the `CoreStoreObject` subclass, declare properties of type `Value.Required<T>`, `Value.Optional<T>` for values, or `Relationship.ToOne<T>`, `Relationship.ToManyOrdered<T>`, `Relationship.ToManyUnordered<T>` for relationships.
|
||||
```
|
||||
class Animal: CoreStoreObject {
|
||||
let species = Value.Required<String>("species")
|
||||
let species = Value.Required<String>("species", initial: "")
|
||||
let nickname = Value.Optional<String>("nickname")
|
||||
let master = Relationship.ToOne<Person>("master")
|
||||
}
|
||||
|
||||
class Person: CoreStoreObject {
|
||||
let name = Value.Required<String>("name")
|
||||
let name = Value.Required<String>("name", initial: "")
|
||||
let pet = Relationship.ToOne<Animal>("pet", inverse: { $0.master })
|
||||
}
|
||||
```
|
||||
@@ -68,8 +68,8 @@ open /*abstract*/ class CoreStoreObject: DynamicObject, Hashable {
|
||||
public required init(rawObject: NSManagedObject) {
|
||||
|
||||
self.isMeta = false
|
||||
self.rawObject = rawObject
|
||||
self.initializeAttributes(Mirror(reflecting: self), { [unowned self] in self })
|
||||
self.rawObject = (rawObject as! CoreStoreManagedObject)
|
||||
self.initializeAttributes(Mirror(reflecting: self), self)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -110,13 +110,13 @@ open /*abstract*/ class CoreStoreObject: DynamicObject, Hashable {
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
internal let rawObject: NSManagedObject?
|
||||
internal let rawObject: CoreStoreManagedObject?
|
||||
internal let isMeta: Bool
|
||||
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private func initializeAttributes(_ mirror: Mirror, _ parentObject: @escaping () -> CoreStoreObject) {
|
||||
private func initializeAttributes(_ mirror: Mirror, _ parentObject: CoreStoreObject) {
|
||||
|
||||
_ = mirror.superclassMirror.flatMap({ self.initializeAttributes($0, parentObject) })
|
||||
for child in mirror.children {
|
||||
@@ -135,3 +135,26 @@ open /*abstract*/ class CoreStoreObject: DynamicObject, Hashable {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - DynamicObject where Self: CoreStoreObject
|
||||
|
||||
public extension DynamicObject where Self: CoreStoreObject {
|
||||
|
||||
/**
|
||||
Returns the `PartialObject` instance for the object, which acts as a fast, type-safe KVC interface for `CoreStoreObject`.
|
||||
*/
|
||||
public func partialObject() -> PartialObject<Self> {
|
||||
|
||||
CoreStore.assert(
|
||||
!self.isMeta,
|
||||
"Attempted to create a \(cs_typeName(PartialObject<Self>.self)) from a meta object. Meta objects are only used for querying keyPaths and infering types."
|
||||
)
|
||||
return PartialObject<Self>(self.rawObject!)
|
||||
}
|
||||
|
||||
internal static var meta: Self {
|
||||
|
||||
return self.init(asMeta: ())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,13 +33,13 @@ import Foundation
|
||||
The `CoreStoreSchema` describes models written for `CoreStoreObject` Swift class declarations for a particular model version. `CoreStoreObject` entities for a model version should be added to `CoreStoreSchema` instance.
|
||||
```
|
||||
class Animal: CoreStoreObject {
|
||||
let species = Value.Required<String>("species")
|
||||
let species = Value.Required<String>("species", initial: "")
|
||||
let nickname = Value.Optional<String>("nickname")
|
||||
let master = Relationship.ToOne<Person>("master")
|
||||
}
|
||||
|
||||
class Person: CoreStoreObject {
|
||||
let name = Value.Required<String>("name")
|
||||
let name = Value.Required<String>("name", initial: "")
|
||||
let pet = Relationship.ToOne<Animal>("pet", inverse: { $0.master })
|
||||
}
|
||||
|
||||
@@ -66,13 +66,13 @@ public final class CoreStoreSchema: DynamicSchema {
|
||||
Initializes a `CoreStoreSchema`. Using this initializer only if the entities don't need to be assigned to particular "Configurations". To use multiple configurations (for example, to separate entities in different `StorageInterface`s), use the `init(modelVersion:entitiesByConfiguration:versionLock:)` initializer.
|
||||
```
|
||||
class Animal: CoreStoreObject {
|
||||
let species = Value.Required<String>("species")
|
||||
let species = Value.Required<String>("species", initial: "")
|
||||
let nickname = Value.Optional<String>("nickname")
|
||||
let master = Relationship.ToOne<Person>("master")
|
||||
}
|
||||
|
||||
class Person: CoreStoreObject {
|
||||
let name = Value.Required<String>("name")
|
||||
let name = Value.Required<String>("name", initial: "")
|
||||
let pet = Relationship.ToOne<Animal>("pet", inverse: { $0.master })
|
||||
}
|
||||
|
||||
@@ -112,12 +112,12 @@ public final class CoreStoreSchema: DynamicSchema {
|
||||
Initializes a `CoreStoreSchema`. Using this initializer if multiple "Configurations" (for example, to separate entities in different `StorageInterface`s) are needed. To add an entity only to the default configuration, assign an empty set to its configurations list. Note that regardless of the set configurations, all entities will be added to the default configuration.
|
||||
```
|
||||
class Animal: CoreStoreObject {
|
||||
let species = Value.Required<String>("species")
|
||||
let species = Value.Required<String>("species", initial: "")
|
||||
let nickname = Value.Optional<String>("nickname")
|
||||
}
|
||||
|
||||
class Person: CoreStoreObject {
|
||||
let name = Value.Required<String>("name")
|
||||
let name = Value.Required<String>("name", initial: "")
|
||||
}
|
||||
|
||||
CoreStore.defaultStack = DataStack(
|
||||
@@ -187,7 +187,7 @@ public final class CoreStoreSchema: DynamicSchema {
|
||||
#if DEBUG
|
||||
CoreStore.log(
|
||||
.notice,
|
||||
message: "These are hashes for the \(cs_typeName(CoreStoreSchema.self)) with version name \"\(modelVersion)\". Copy the dictionary below and pass it to the \(cs_typeName(CoreStoreSchema.self)) initializer's \"versionLock\" argument:\n\(VersionLock(entityVersionHashesByName: self.rawModel().entityVersionHashesByName))"
|
||||
message: "These are hashes for the \(cs_typeName(CoreStoreSchema.self)) with version name \"\(modelVersion)\". Copy the dictionary below and pass it to the \(cs_typeName(CoreStoreSchema.self)) initializer's \"versionLock\" argument:\nversionLock: \(VersionLock(entityVersionHashesByName: self.rawModel().entityVersionHashesByName))"
|
||||
)
|
||||
#endif
|
||||
}
|
||||
@@ -200,35 +200,44 @@ public final class CoreStoreSchema: DynamicSchema {
|
||||
|
||||
public func rawModel() -> NSManagedObjectModel {
|
||||
|
||||
if let cachedRawModel = self.cachedRawModel {
|
||||
return CoreStoreSchema.barrierQueue.sync(flags: .barrier) {
|
||||
|
||||
return cachedRawModel
|
||||
}
|
||||
let rawModel = NSManagedObjectModel()
|
||||
var entityDescriptionsByEntity: [DynamicEntity: NSEntityDescription] = [:]
|
||||
for entity in self.allEntities {
|
||||
|
||||
let entityDescription = self.entityDescription(
|
||||
for: entity,
|
||||
initializer: CoreStoreSchema.firstPassCreateEntityDescription
|
||||
if let cachedRawModel = self.cachedRawModel {
|
||||
|
||||
return cachedRawModel
|
||||
}
|
||||
let rawModel = NSManagedObjectModel()
|
||||
var entityDescriptionsByEntity: [DynamicEntity: NSEntityDescription] = [:]
|
||||
var allCustomGettersSetters: [DynamicEntity: [KeyPathString: CoreStoreManagedObject.CustomGetterSetter]] = [:]
|
||||
for entity in self.allEntities {
|
||||
|
||||
let (entityDescription, customGetterSetterByKeyPaths) = self.entityDescription(
|
||||
for: entity,
|
||||
initializer: CoreStoreSchema.firstPassCreateEntityDescription(from:in:)
|
||||
)
|
||||
entityDescriptionsByEntity[entity] = (entityDescription.copy() as! NSEntityDescription)
|
||||
allCustomGettersSetters[entity] = customGetterSetterByKeyPaths
|
||||
}
|
||||
CoreStoreSchema.secondPassConnectRelationshipAttributes(for: entityDescriptionsByEntity)
|
||||
CoreStoreSchema.thirdPassConnectInheritanceTreeAndIndexes(for: entityDescriptionsByEntity)
|
||||
CoreStoreSchema.fourthPassSynthesizeManagedObjectClasses(
|
||||
for: entityDescriptionsByEntity,
|
||||
allCustomGettersSetters: allCustomGettersSetters
|
||||
)
|
||||
entityDescriptionsByEntity[entity] = (entityDescription.copy() as! NSEntityDescription)
|
||||
}
|
||||
CoreStoreSchema.secondPassConnectRelationshipAttributes(for: entityDescriptionsByEntity)
|
||||
CoreStoreSchema.thirdPassConnectInheritanceTree(for: entityDescriptionsByEntity)
|
||||
|
||||
rawModel.entities = entityDescriptionsByEntity.values.sorted(by: { $0.name! < $1.name! })
|
||||
for (configuration, entities) in self.entitiesByConfiguration {
|
||||
|
||||
rawModel.setEntities(
|
||||
entities
|
||||
.map({ entityDescriptionsByEntity[$0]! })
|
||||
.sorted(by: { $0.name! < $1.name! }),
|
||||
forConfigurationName: configuration
|
||||
)
|
||||
rawModel.entities = entityDescriptionsByEntity.values.sorted(by: { $0.name! < $1.name! })
|
||||
for (configuration, entities) in self.entitiesByConfiguration {
|
||||
|
||||
rawModel.setEntities(
|
||||
entities
|
||||
.map({ entityDescriptionsByEntity[$0]! })
|
||||
.sorted(by: { $0.name! < $1.name! }),
|
||||
forConfigurationName: configuration
|
||||
)
|
||||
}
|
||||
self.cachedRawModel = rawModel
|
||||
return rawModel
|
||||
}
|
||||
self.cachedRawModel = rawModel
|
||||
return rawModel
|
||||
}
|
||||
|
||||
|
||||
@@ -244,28 +253,33 @@ public final class CoreStoreSchema: DynamicSchema {
|
||||
private let allEntities: Set<DynamicEntity>
|
||||
|
||||
private var entityDescriptionsByEntity: [DynamicEntity: NSEntityDescription] = [:]
|
||||
private var customGettersSettersByEntity: [DynamicEntity: [KeyPathString: CoreStoreManagedObject.CustomGetterSetter]] = [:]
|
||||
private weak var cachedRawModel: NSManagedObjectModel?
|
||||
|
||||
private func entityDescription(for entity: DynamicEntity, initializer: (DynamicEntity) -> NSEntityDescription) -> NSEntityDescription {
|
||||
private func entityDescription(for entity: DynamicEntity, initializer: (DynamicEntity, ModelVersion) -> (entity: NSEntityDescription, customGetterSetterByKeyPaths: [KeyPathString: CoreStoreManagedObject.CustomGetterSetter])) -> (entity: NSEntityDescription, customGetterSetterByKeyPaths: [KeyPathString: CoreStoreManagedObject.CustomGetterSetter]) {
|
||||
|
||||
if let cachedEntityDescription = self.entityDescriptionsByEntity[entity] {
|
||||
|
||||
return cachedEntityDescription
|
||||
return (cachedEntityDescription, self.customGettersSettersByEntity[entity] ?? [:])
|
||||
}
|
||||
let entityDescription = withoutActuallyEscaping(initializer, do: { $0(entity) })
|
||||
let modelVersion = self.modelVersion
|
||||
let (entityDescription, customGetterSetterByKeyPaths) = withoutActuallyEscaping(initializer, do: { $0(entity, modelVersion) })
|
||||
self.entityDescriptionsByEntity[entity] = entityDescription
|
||||
return entityDescription
|
||||
self.customGettersSettersByEntity[entity] = customGetterSetterByKeyPaths
|
||||
return (entityDescription, customGetterSetterByKeyPaths)
|
||||
}
|
||||
|
||||
private static func firstPassCreateEntityDescription(from entity: DynamicEntity) -> NSEntityDescription {
|
||||
private static func firstPassCreateEntityDescription(from entity: DynamicEntity, in modelVersion: ModelVersion) -> (entity: NSEntityDescription, customGetterSetterByKeyPaths: [KeyPathString: CoreStoreManagedObject.CustomGetterSetter]) {
|
||||
|
||||
let entityDescription = NSEntityDescription()
|
||||
entityDescription.coreStoreEntity = entity
|
||||
entityDescription.name = entity.entityName
|
||||
entityDescription.isAbstract = entity.isAbstract
|
||||
entityDescription.versionHashModifier = entity.versionHashModifier
|
||||
entityDescription.managedObjectClassName = NSStringFromClass(NSManagedObject.self)
|
||||
entityDescription.managedObjectClassName = CoreStoreManagedObject.cs_subclassName(for: entity, in: modelVersion)
|
||||
|
||||
var keyPathsByAffectedKeyPaths: [KeyPathString: Set<KeyPathString>] = [:]
|
||||
var customGetterSetterByKeyPaths: [KeyPathString: CoreStoreManagedObject.CustomGetterSetter] = [:]
|
||||
func createProperties(for type: CoreStoreObject.Type) -> [NSPropertyDescription] {
|
||||
|
||||
var propertyDescriptions: [NSPropertyDescription] = []
|
||||
@@ -276,14 +290,16 @@ public final class CoreStoreSchema: DynamicSchema {
|
||||
case let attribute as AttributeProtocol:
|
||||
let description = NSAttributeDescription()
|
||||
description.name = attribute.keyPath
|
||||
description.attributeType = type(of: attribute).attributeType
|
||||
description.attributeType = Swift.type(of: attribute).attributeType
|
||||
description.isOptional = attribute.isOptional
|
||||
description.isIndexed = attribute.isIndexed
|
||||
description.defaultValue = attribute.defaultValue
|
||||
description.defaultValue = attribute.defaultValue()
|
||||
description.isTransient = attribute.isTransient
|
||||
description.versionHashModifier = attribute.versionHashModifier
|
||||
description.renamingIdentifier = attribute.renamingIdentifier
|
||||
description.allowsExternalBinaryDataStorage = attribute.allowsExternalBinaryDataStorage
|
||||
description.versionHashModifier = attribute.versionHashModifier()
|
||||
description.renamingIdentifier = attribute.renamingIdentifier()
|
||||
propertyDescriptions.append(description)
|
||||
keyPathsByAffectedKeyPaths[attribute.keyPath] = attribute.affectedByKeyPaths()
|
||||
customGetterSetterByKeyPaths[attribute.keyPath] = (attribute.getter, attribute.setter)
|
||||
|
||||
case let relationship as RelationshipProtocol:
|
||||
let description = NSRelationshipDescription()
|
||||
@@ -292,9 +308,10 @@ public final class CoreStoreSchema: DynamicSchema {
|
||||
description.maxCount = relationship.maxCount
|
||||
description.isOrdered = relationship.isOrdered
|
||||
description.deleteRule = relationship.deleteRule
|
||||
description.versionHashModifier = relationship.versionHashModifier
|
||||
description.renamingIdentifier = relationship.renamingIdentifier
|
||||
description.versionHashModifier = relationship.versionHashModifier()
|
||||
description.renamingIdentifier = relationship.renamingIdentifier()
|
||||
propertyDescriptions.append(description)
|
||||
keyPathsByAffectedKeyPaths[relationship.keyPath] = relationship.affectedByKeyPaths()
|
||||
|
||||
default:
|
||||
continue
|
||||
@@ -302,9 +319,9 @@ public final class CoreStoreSchema: DynamicSchema {
|
||||
}
|
||||
return propertyDescriptions
|
||||
}
|
||||
|
||||
entityDescription.properties = createProperties(for: entity.type as! CoreStoreObject.Type)
|
||||
return entityDescription
|
||||
entityDescription.keyPathsByAffectedKeyPaths = keyPathsByAffectedKeyPaths
|
||||
return (entityDescription, customGetterSetterByKeyPaths)
|
||||
}
|
||||
|
||||
private static func secondPassConnectRelationshipAttributes(for entityDescriptionsByEntity: [DynamicEntity: NSEntityDescription]) {
|
||||
@@ -398,7 +415,7 @@ public final class CoreStoreSchema: DynamicSchema {
|
||||
}
|
||||
}
|
||||
|
||||
private static func thirdPassConnectInheritanceTree(for entityDescriptionsByEntity: [DynamicEntity: NSEntityDescription]) {
|
||||
private static func thirdPassConnectInheritanceTreeAndIndexes(for entityDescriptionsByEntity: [DynamicEntity: NSEntityDescription]) {
|
||||
|
||||
func connectBaseEntity(mirror: Mirror, entityDescription: NSEntityDescription) {
|
||||
|
||||
@@ -424,5 +441,160 @@ public final class CoreStoreSchema: DynamicSchema {
|
||||
entityDescription: entityDescription
|
||||
)
|
||||
}
|
||||
for (entity, entityDescription) in entityDescriptionsByEntity {
|
||||
|
||||
let uniqueConstraints = entity.uniqueConstraints.filter({ !$0.isEmpty })
|
||||
if !uniqueConstraints.isEmpty {
|
||||
|
||||
CoreStore.assert(
|
||||
entityDescription.superentity == nil,
|
||||
"Uniqueness constraints must be defined at the highest level possible."
|
||||
)
|
||||
entityDescription.uniquenessConstraints = entity.uniqueConstraints.map { $0.map { $0 as NSString } }
|
||||
}
|
||||
guard !entity.indexes.isEmpty else {
|
||||
|
||||
continue
|
||||
}
|
||||
defer {
|
||||
|
||||
entityDescription.coreStoreEntity = entity // reserialize
|
||||
}
|
||||
let attributesByName = entityDescription.attributesByName
|
||||
if #available(iOS 11.0, OSX 10.13, watchOS 4.0, tvOS 11.0, *) {
|
||||
|
||||
entityDescription.indexes = entity.indexes.map { (compoundIndexes) in
|
||||
|
||||
return NSFetchIndexDescription.init(
|
||||
name: "_CoreStoreSchema_indexes_\(entityDescription.name!)_\(compoundIndexes.joined(separator: "-"))",
|
||||
elements: compoundIndexes.map { (keyPath) in
|
||||
|
||||
return NSFetchIndexElementDescription(
|
||||
property: attributesByName[keyPath]!,
|
||||
collationType: .binary
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
entityDescription.compoundIndexes = entity.indexes.map { (compoundIndexes) in
|
||||
|
||||
return compoundIndexes.map { (keyPath) in
|
||||
|
||||
return attributesByName[keyPath]!
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static func fourthPassSynthesizeManagedObjectClasses(for entityDescriptionsByEntity: [DynamicEntity: NSEntityDescription], allCustomGettersSetters: [DynamicEntity: [KeyPathString: CoreStoreManagedObject.CustomGetterSetter]]) {
|
||||
|
||||
func createManagedObjectSubclass(for entityDescription: NSEntityDescription, customGetterSetterByKeyPaths: [KeyPathString: CoreStoreManagedObject.CustomGetterSetter]?) {
|
||||
|
||||
let superEntity = entityDescription.superentity
|
||||
let className = entityDescription.managedObjectClassName!
|
||||
guard case nil = NSClassFromString(className) as! CoreStoreManagedObject.Type? else {
|
||||
|
||||
return
|
||||
}
|
||||
if let superEntity = superEntity {
|
||||
|
||||
createManagedObjectSubclass(
|
||||
for: superEntity,
|
||||
customGetterSetterByKeyPaths: superEntity.coreStoreEntity.flatMap({ allCustomGettersSetters[$0] })
|
||||
)
|
||||
}
|
||||
let superClass = cs_lazy { () -> CoreStoreManagedObject.Type in
|
||||
|
||||
if let superClassName = superEntity?.managedObjectClassName,
|
||||
let superClass = NSClassFromString(superClassName) {
|
||||
|
||||
return superClass as! CoreStoreManagedObject.Type
|
||||
}
|
||||
return CoreStoreManagedObject.self
|
||||
}
|
||||
let managedObjectClass: AnyClass = className.withCString {
|
||||
|
||||
return objc_allocateClassPair(superClass, $0, 0)!
|
||||
}
|
||||
defer {
|
||||
|
||||
objc_registerClassPair(managedObjectClass)
|
||||
}
|
||||
|
||||
func capitalize(_ string: String) -> String {
|
||||
|
||||
return string.replacingCharacters(
|
||||
in: Range(uncheckedBounds: (string.startIndex, string.index(after: string.startIndex))),
|
||||
with: String(string[string.startIndex]).uppercased()
|
||||
)
|
||||
}
|
||||
for (attributeName, customGetterSetters) in (customGetterSetterByKeyPaths ?? [:])
|
||||
where customGetterSetters.getter != nil || customGetterSetters.setter != nil {
|
||||
|
||||
if let getter = customGetterSetters.getter {
|
||||
|
||||
let getterName = "\(attributeName)"
|
||||
guard class_addMethod(
|
||||
managedObjectClass,
|
||||
NSSelectorFromString(getterName),
|
||||
imp_implementationWithBlock(getter),
|
||||
"@@:") else {
|
||||
|
||||
CoreStore.abort("Could not dynamically add getter method \"\(getterName)\" to class \(cs_typeName(managedObjectClass))")
|
||||
}
|
||||
}
|
||||
if let setter = customGetterSetters.setter {
|
||||
|
||||
let setterName = "set\(capitalize(attributeName)):"
|
||||
guard class_addMethod(
|
||||
managedObjectClass,
|
||||
NSSelectorFromString(setterName),
|
||||
imp_implementationWithBlock(setter),
|
||||
"v@:@") else {
|
||||
|
||||
CoreStore.abort("Could not dynamically add setter method \"\(setterName)\" to class \(cs_typeName(managedObjectClass))")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let newSelector = NSSelectorFromString("cs_keyPathsForValuesAffectingValueForKey:")
|
||||
let keyPathsByAffectedKeyPaths = entityDescription.keyPathsByAffectedKeyPaths
|
||||
let keyPathsForValuesAffectingValue: @convention(block) (Any, String) -> Set<String> = { (instance, keyPath) in
|
||||
|
||||
if let keyPaths = keyPathsByAffectedKeyPaths[keyPath] {
|
||||
|
||||
return keyPaths
|
||||
}
|
||||
return []
|
||||
}
|
||||
let origSelector = #selector(NSManagedObject.keyPathsForValuesAffectingValue(forKey:))
|
||||
|
||||
let metaClass: AnyClass = object_getClass(managedObjectClass)!
|
||||
let origMethod = class_getClassMethod(managedObjectClass, origSelector)!
|
||||
|
||||
let origImp = method_getImplementation(origMethod)
|
||||
let newImp = imp_implementationWithBlock(keyPathsForValuesAffectingValue)
|
||||
|
||||
if class_addMethod(metaClass, origSelector, newImp, method_getTypeEncoding(origMethod)) {
|
||||
|
||||
class_replaceMethod(metaClass, newSelector, origImp, method_getTypeEncoding(origMethod))
|
||||
}
|
||||
else {
|
||||
|
||||
let newMethod = class_getClassMethod(managedObjectClass, newSelector)!
|
||||
method_exchangeImplementations(origMethod, newMethod)
|
||||
}
|
||||
}
|
||||
for (dynamicEntity, entityDescription) in entityDescriptionsByEntity {
|
||||
|
||||
createManagedObjectSubclass(
|
||||
for: entityDescription,
|
||||
customGetterSetterByKeyPaths: allCustomGettersSetters[dynamicEntity]
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,3 +64,11 @@ public typealias EntityName = String
|
||||
An `String` that pertains to a dynamically-accessable class name (usable with NSClassFromString(...)).
|
||||
*/
|
||||
public typealias ClassName = String
|
||||
|
||||
|
||||
// MARK: - KeyPathString
|
||||
|
||||
/**
|
||||
An `String` that pertains to a attribute keyPaths.
|
||||
*/
|
||||
public typealias KeyPathString = String
|
||||
|
||||
@@ -32,7 +32,7 @@ import Foundation
|
||||
/**
|
||||
A `SchemaMappingProvider` that accepts custom mappings for some entities. Mappings of entities with no `CustomMapping` provided will be automatically calculated if possible.
|
||||
*/
|
||||
open class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
|
||||
public class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
|
||||
|
||||
/**
|
||||
The source model version for the mapping.
|
||||
@@ -56,8 +56,8 @@ open class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
|
||||
CoreStore.assert(
|
||||
cs_lazy {
|
||||
|
||||
let sources = entityMappings.flatMap({ $0.entityMappingSourceEntity })
|
||||
let destinations = entityMappings.flatMap({ $0.entityMappingDestinationEntity })
|
||||
let sources = entityMappings.compactMap({ $0.entityMappingSourceEntity })
|
||||
let destinations = entityMappings.compactMap({ $0.entityMappingDestinationEntity })
|
||||
return sources.count == Set(sources).count
|
||||
&& destinations.count == Set(destinations).count
|
||||
},
|
||||
@@ -210,7 +210,7 @@ open class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
|
||||
/**
|
||||
Accesses the property value via its keyPath.
|
||||
*/
|
||||
public subscript(attribute: KeyPath) -> Any? {
|
||||
public subscript(attribute: KeyPathString) -> Any? {
|
||||
|
||||
return self.rawObject.cs_accessValueForKVCKey(attribute)
|
||||
}
|
||||
@@ -267,7 +267,7 @@ open class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
|
||||
/**
|
||||
Accesses or mutates the property value via its keyPath.
|
||||
*/
|
||||
public subscript(attribute: KeyPath) -> Any? {
|
||||
public subscript(attribute: KeyPathString) -> Any? {
|
||||
|
||||
get { return self.rawObject.cs_accessValueForKVCKey(attribute) }
|
||||
set { self.rawObject.cs_setValue(newValue, forKVCKey: attribute) }
|
||||
@@ -304,7 +304,7 @@ open class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
internal init(_ rawObject: NSManagedObject, _ sourceAttributesByDestinationKey: [KeyPath: NSAttributeDescription]) {
|
||||
internal init(_ rawObject: NSManagedObject, _ sourceAttributesByDestinationKey: [KeyPathString: NSAttributeDescription]) {
|
||||
|
||||
self.rawObject = rawObject
|
||||
self.sourceAttributesByDestinationKey = sourceAttributesByDestinationKey
|
||||
@@ -314,7 +314,7 @@ open class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
|
||||
// MARK: FilePrivate
|
||||
|
||||
fileprivate let rawObject: NSManagedObject
|
||||
fileprivate let sourceAttributesByDestinationKey: [KeyPath: NSAttributeDescription]
|
||||
fileprivate let sourceAttributesByDestinationKey: [KeyPathString: NSAttributeDescription]
|
||||
}
|
||||
|
||||
|
||||
@@ -352,7 +352,7 @@ open class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
|
||||
)
|
||||
func expression(forSource sourceEntity: NSEntityDescription) -> NSExpression {
|
||||
|
||||
return NSExpression(format: "FETCH(FUNCTION($\(NSMigrationManagerKey), \"fetchRequestForSourceEntityNamed:predicateString:\" , \"\(sourceEntity.name!)\", \"\(NSPredicate(value: true))\"), $\(NSMigrationManagerKey).\(#keyPath(NSMigrationManager.sourceContext)), \(false))")
|
||||
return NSExpression(format: "FETCH(FUNCTION($\(NSMigrationManagerKey), \"fetchRequestForSourceEntityNamed:predicateString:\" , \"\(sourceEntity.name!)\", \"\(NSPredicate(value: true))\"), FUNCTION($\(NSMigrationManagerKey), \"\(#selector(getter: NSMigrationManager.sourceContext))\"), \(false))")
|
||||
}
|
||||
|
||||
let sourceEntitiesByName = sourceModel.entitiesByName
|
||||
@@ -427,22 +427,25 @@ open class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
|
||||
let destinationAttribute = destination.attribute
|
||||
let propertyMapping = NSPropertyMapping()
|
||||
propertyMapping.name = destinationAttribute.name
|
||||
propertyMapping.valueExpression = NSExpression(format: "$\(NSMigrationSourceObjectKey).\(sourceAttribute.name)")
|
||||
propertyMapping.valueExpression = NSExpression(format: "FUNCTION($\(NSMigrationSourceObjectKey), \"\(#selector(NSManagedObject.value(forKey:)))\", \"\(sourceAttribute.name)\")")
|
||||
attributeMappings.append(propertyMapping)
|
||||
}
|
||||
return attributeMappings
|
||||
}
|
||||
let entityMappingName = entityMapping.name!
|
||||
entityMapping.relationshipMappings = autoreleasepool { () -> [NSPropertyMapping] in
|
||||
|
||||
let sourceRelationships = sourceEntity.cs_resolvedRelationshipRenamingIdentities()
|
||||
let destinationRelationships = destinationEntity.cs_resolvedRelationshipRenamingIdentities()
|
||||
var relationshipMappings: [NSPropertyMapping] = []
|
||||
for (_, destination) in destinationRelationships {
|
||||
for (renamingIdentifier, destination) in destinationRelationships {
|
||||
|
||||
let sourceRelationship = sourceRelationships[renamingIdentifier]!.relationship
|
||||
let destinationRelationship = destination.relationship
|
||||
let sourceRelationshipName = sourceRelationship.name
|
||||
|
||||
let propertyMapping = NSPropertyMapping()
|
||||
propertyMapping.name = destinationRelationship.name
|
||||
propertyMapping.valueExpression = NSExpression(format: "FUNCTION($\(NSMigrationManagerKey), \"\(#selector(NSMigrationManager.destinationInstances(forEntityMappingName:sourceInstances:)))\" , \"\(entityMappingName)\", $\(NSMigrationSourceObjectKey))[0]")
|
||||
propertyMapping.valueExpression = NSExpression(format: "FUNCTION($\(NSMigrationManagerKey), \"destinationInstancesForSourceRelationshipNamed:sourceInstances:\", \"\(sourceRelationshipName)\", FUNCTION($\(NSMigrationSourceObjectKey), \"\(#selector(NSManagedObject.value(forKey:)))\", \"\(sourceRelationshipName)\"))")
|
||||
relationshipMappings.append(propertyMapping)
|
||||
}
|
||||
return relationshipMappings
|
||||
@@ -474,7 +477,7 @@ open class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
|
||||
let transformedRenamingIdentifiers = Set(destinationAttributes.keys)
|
||||
.intersection(sourceAttributes.keys)
|
||||
|
||||
var sourceAttributesByDestinationKey: [KeyPath: NSAttributeDescription] = [:]
|
||||
var sourceAttributesByDestinationKey: [KeyPathString: NSAttributeDescription] = [:]
|
||||
for renamingIdentifier in transformedRenamingIdentifiers {
|
||||
|
||||
let sourceAttribute = sourceAttributes[renamingIdentifier]!.attribute
|
||||
@@ -483,17 +486,24 @@ open class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
|
||||
}
|
||||
userInfo[CustomEntityMigrationPolicy.UserInfoKey.sourceAttributesByDestinationKey] = sourceAttributesByDestinationKey
|
||||
}
|
||||
let entityMappingName = entityMapping.name!
|
||||
entityMapping.relationshipMappings = autoreleasepool { () -> [NSPropertyMapping] in
|
||||
|
||||
let sourceRelationships = sourceEntity.cs_resolvedRelationshipRenamingIdentities()
|
||||
let destinationRelationships = destinationEntity.cs_resolvedRelationshipRenamingIdentities()
|
||||
let transformedRenamingIdentifiers = Set(destinationRelationships.keys)
|
||||
.intersection(sourceRelationships.keys)
|
||||
|
||||
var relationshipMappings: [NSPropertyMapping] = []
|
||||
for (_, destination) in destinationRelationships {
|
||||
|
||||
let destinationRelationship = destination.relationship
|
||||
for renamingIdentifier in transformedRenamingIdentifiers {
|
||||
|
||||
let sourceRelationship = sourceRelationships[renamingIdentifier]!.relationship
|
||||
let destinationRelationship = destinationRelationships[renamingIdentifier]!.relationship
|
||||
let sourceRelationshipName = sourceRelationship.name
|
||||
let destinationRelationshipName = destinationRelationship.name
|
||||
|
||||
let propertyMapping = NSPropertyMapping()
|
||||
propertyMapping.name = destinationRelationship.name
|
||||
propertyMapping.valueExpression = NSExpression(format: "FUNCTION($\(NSMigrationManagerKey), \"\(#selector(NSMigrationManager.destinationInstances(forEntityMappingName:sourceInstances:)))\" , \"\(entityMappingName)\", $\(NSMigrationSourceObjectKey))[0]")
|
||||
propertyMapping.name = destinationRelationshipName
|
||||
propertyMapping.valueExpression = NSExpression(format: "FUNCTION($\(NSMigrationManagerKey), \"destinationInstancesForSourceRelationshipNamed:sourceInstances:\", \"\(sourceRelationshipName)\", FUNCTION($\(NSMigrationSourceObjectKey), \"\(#selector(NSManagedObject.value(forKey:)))\", \"\(sourceRelationshipName)\"))")
|
||||
relationshipMappings.append(propertyMapping)
|
||||
}
|
||||
return relationshipMappings
|
||||
@@ -525,7 +535,7 @@ open class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
|
||||
|
||||
let userInfo = mapping.userInfo!
|
||||
let transformer = userInfo[CustomEntityMigrationPolicy.UserInfoKey.transformer]! as! CustomMapping.Transformer
|
||||
let sourceAttributesByDestinationKey = userInfo[CustomEntityMigrationPolicy.UserInfoKey.sourceAttributesByDestinationKey] as! [KeyPath: NSAttributeDescription]
|
||||
let sourceAttributesByDestinationKey = userInfo[CustomEntityMigrationPolicy.UserInfoKey.sourceAttributesByDestinationKey] as! [KeyPathString: NSAttributeDescription]
|
||||
|
||||
var destinationObject: UnsafeDestinationObject?
|
||||
try transformer(
|
||||
@@ -545,11 +555,7 @@ open class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
|
||||
)
|
||||
if let dInstance = destinationObject?.rawObject {
|
||||
|
||||
manager.associate(
|
||||
sourceInstance: sInstance,
|
||||
withDestinationInstance: dInstance,
|
||||
for: mapping
|
||||
)
|
||||
manager.associate(sourceInstance: sInstance, withDestinationInstance: dInstance, for: mapping)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -579,8 +585,8 @@ open class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
|
||||
var insertMappings: Set<CustomMapping> = []
|
||||
var copyMappings: Set<CustomMapping> = []
|
||||
var transformMappings: Set<CustomMapping> = []
|
||||
var allMappedSourceKeys: [KeyPath: KeyPath] = [:]
|
||||
var allMappedDestinationKeys: [KeyPath: KeyPath] = [:]
|
||||
var allMappedSourceKeys: [KeyPathString: KeyPathString] = [:]
|
||||
var allMappedDestinationKeys: [KeyPathString: KeyPathString] = [:]
|
||||
|
||||
let sourceRenamingIdentifiers = sourceModel.cs_resolvedRenamingIdentities()
|
||||
let sourceEntityNames = sourceModel.entitiesByName
|
||||
@@ -670,77 +676,76 @@ open class CustomSchemaMappingProvider: Hashable, SchemaMappingProvider {
|
||||
allMappedSourceKeys[sourceEntity] = destinationEntity
|
||||
allMappedDestinationKeys[destinationEntity] = sourceEntity
|
||||
}
|
||||
}
|
||||
for renamingIdentifier in transformedRenamingIdentifiers {
|
||||
|
||||
for renamingIdentifier in transformedRenamingIdentifiers {
|
||||
let sourceEntity = sourceRenamingIdentifiers[renamingIdentifier]!.entity
|
||||
let destinationEntity = destinationRenamingIdentifiers[renamingIdentifier]!.entity
|
||||
let sourceEntityName = sourceEntity.name!
|
||||
let destinationEntityName = destinationEntity.name!
|
||||
switch (allMappedSourceKeys[sourceEntityName], allMappedDestinationKeys[destinationEntityName]) {
|
||||
|
||||
let sourceEntity = sourceRenamingIdentifiers[renamingIdentifier]!.entity
|
||||
let destinationEntity = destinationRenamingIdentifiers[renamingIdentifier]!.entity
|
||||
let sourceEntityName = sourceEntity.name!
|
||||
let destinationEntityName = destinationEntity.name!
|
||||
switch (allMappedSourceKeys[sourceEntityName], allMappedDestinationKeys[destinationEntityName]) {
|
||||
case (nil, nil):
|
||||
if sourceEntity.versionHash == destinationEntity.versionHash {
|
||||
|
||||
case (nil, nil):
|
||||
if sourceEntity.versionHash == destinationEntity.versionHash {
|
||||
|
||||
copyMappings.insert(
|
||||
.copyEntity(
|
||||
sourceEntity: sourceEntityName,
|
||||
destinationEntity: destinationEntityName
|
||||
)
|
||||
copyMappings.insert(
|
||||
.copyEntity(
|
||||
sourceEntity: sourceEntityName,
|
||||
destinationEntity: destinationEntityName
|
||||
)
|
||||
}
|
||||
else {
|
||||
|
||||
transformMappings.insert(
|
||||
.transformEntity(
|
||||
sourceEntity: sourceEntityName,
|
||||
destinationEntity: destinationEntityName,
|
||||
transformer: CustomMapping.inferredTransformation
|
||||
)
|
||||
)
|
||||
}
|
||||
else {
|
||||
|
||||
transformMappings.insert(
|
||||
.transformEntity(
|
||||
sourceEntity: sourceEntityName,
|
||||
destinationEntity: destinationEntityName,
|
||||
transformer: CustomMapping.inferredTransformation
|
||||
)
|
||||
}
|
||||
allMappedSourceKeys[sourceEntityName] = destinationEntityName
|
||||
allMappedDestinationKeys[destinationEntityName] = sourceEntityName
|
||||
|
||||
case (""?, nil):
|
||||
insertMappings.insert(.insertEntity(destinationEntity: destinationEntityName))
|
||||
allMappedDestinationKeys[destinationEntityName] = ""
|
||||
|
||||
case (nil, ""?):
|
||||
deleteMappings.insert(.deleteEntity(sourceEntity: sourceEntityName))
|
||||
allMappedSourceKeys[sourceEntityName] = ""
|
||||
|
||||
default:
|
||||
continue
|
||||
)
|
||||
}
|
||||
}
|
||||
for renamingIdentifier in removedRenamingIdentifiers {
|
||||
allMappedSourceKeys[sourceEntityName] = destinationEntityName
|
||||
allMappedDestinationKeys[destinationEntityName] = sourceEntityName
|
||||
|
||||
let sourceEntity = sourceRenamingIdentifiers[renamingIdentifier]!.entity
|
||||
let sourceEntityName = sourceEntity.name!
|
||||
switch allMappedSourceKeys[sourceEntityName] {
|
||||
|
||||
case nil:
|
||||
deleteMappings.insert(.deleteEntity(sourceEntity: sourceEntityName))
|
||||
allMappedSourceKeys[sourceEntityName] = ""
|
||||
|
||||
default:
|
||||
continue
|
||||
}
|
||||
}
|
||||
for renamingIdentifier in addedRenamingIdentifiers {
|
||||
case (""?, nil):
|
||||
insertMappings.insert(.insertEntity(destinationEntity: destinationEntityName))
|
||||
allMappedDestinationKeys[destinationEntityName] = ""
|
||||
|
||||
let destinationEntity = destinationRenamingIdentifiers[renamingIdentifier]!.entity
|
||||
let destinationEntityName = destinationEntity.name!
|
||||
switch allMappedDestinationKeys[destinationEntityName] {
|
||||
|
||||
case nil:
|
||||
insertMappings.insert(.insertEntity(destinationEntity: destinationEntityName))
|
||||
allMappedDestinationKeys[destinationEntityName] = ""
|
||||
|
||||
default:
|
||||
continue
|
||||
}
|
||||
case (nil, ""?):
|
||||
deleteMappings.insert(.deleteEntity(sourceEntity: sourceEntityName))
|
||||
allMappedSourceKeys[sourceEntityName] = ""
|
||||
|
||||
default:
|
||||
continue
|
||||
}
|
||||
}
|
||||
for renamingIdentifier in removedRenamingIdentifiers {
|
||||
|
||||
let sourceEntity = sourceRenamingIdentifiers[renamingIdentifier]!.entity
|
||||
let sourceEntityName = sourceEntity.name!
|
||||
switch allMappedSourceKeys[sourceEntityName] {
|
||||
|
||||
case nil:
|
||||
deleteMappings.insert(.deleteEntity(sourceEntity: sourceEntityName))
|
||||
allMappedSourceKeys[sourceEntityName] = ""
|
||||
|
||||
default:
|
||||
continue
|
||||
}
|
||||
}
|
||||
for renamingIdentifier in addedRenamingIdentifiers {
|
||||
|
||||
let destinationEntity = destinationRenamingIdentifiers[renamingIdentifier]!.entity
|
||||
let destinationEntityName = destinationEntity.name!
|
||||
switch allMappedDestinationKeys[destinationEntityName] {
|
||||
|
||||
case nil:
|
||||
insertMappings.insert(.insertEntity(destinationEntity: destinationEntityName))
|
||||
allMappedDestinationKeys[destinationEntityName] = ""
|
||||
|
||||
default:
|
||||
continue
|
||||
}
|
||||
}
|
||||
return (deleteMappings, insertMappings, copyMappings, transformMappings)
|
||||
|
||||
@@ -47,7 +47,7 @@ public extension DataStack {
|
||||
- parameter storage: the storage
|
||||
- parameter completion: the closure to be executed on the main queue when the process completes, either due to success or failure. The closure's `SetupResult` argument indicates the result. Note that the `StorageInterface` associated to the `SetupResult.success` may not always be the same instance as the parameter argument if a previous `StorageInterface` was already added at the same URL and with the same configuration.
|
||||
*/
|
||||
public func addStorage<T: StorageInterface>(_ storage: T, completion: @escaping (SetupResult<T>) -> Void) {
|
||||
public func addStorage<T>(_ storage: T, completion: @escaping (SetupResult<T>) -> Void) {
|
||||
|
||||
self.coordinator.performAsynchronously {
|
||||
|
||||
@@ -575,6 +575,7 @@ public extension DataStack {
|
||||
sourceModel: sourceModel,
|
||||
destinationModel: destinationModel,
|
||||
mappingModel: mappingModel,
|
||||
migrationType: migrationType,
|
||||
progress: childProgress
|
||||
)
|
||||
}
|
||||
@@ -647,8 +648,9 @@ public extension DataStack {
|
||||
let mappingProviders = storage.migrationMappingProviders
|
||||
do {
|
||||
|
||||
try withExtendedLifetime((sourceSchema.rawModel(), destinationSchema.rawModel())) { (sourceModel, destinationModel) in
|
||||
try withExtendedLifetime((sourceSchema.rawModel(), destinationSchema.rawModel())) {
|
||||
|
||||
let (sourceModel, destinationModel) = $0
|
||||
let mapping = try mappingProviders.findMapping(
|
||||
sourceSchema: sourceSchema,
|
||||
destinationSchema: destinationSchema,
|
||||
@@ -679,10 +681,74 @@ public extension DataStack {
|
||||
return nil
|
||||
}
|
||||
|
||||
private func startMigrationForStorage<T: LocalStorage>(_ storage: T, sourceModel: NSManagedObjectModel, destinationModel: NSManagedObjectModel, mappingModel: NSMappingModel, progress: Progress) throws {
|
||||
private func startMigrationForStorage<T: LocalStorage>(_ storage: T, sourceModel: NSManagedObjectModel, destinationModel: NSManagedObjectModel, mappingModel: NSMappingModel, migrationType: MigrationType, progress: Progress) throws {
|
||||
|
||||
do {
|
||||
|
||||
try storage.cs_finalizeStorageAndWait(soureModelHint: sourceModel)
|
||||
}
|
||||
catch {
|
||||
|
||||
throw CoreStoreError(error)
|
||||
}
|
||||
|
||||
let fileURL = storage.fileURL
|
||||
|
||||
if case .lightweight = migrationType {
|
||||
|
||||
do {
|
||||
|
||||
let timerQueue = DispatchQueue(
|
||||
label: "DataStack.lightweightMigration.timerQueue",
|
||||
qos: .utility,
|
||||
attributes: []
|
||||
)
|
||||
let estimatedTime: TimeInterval = 60 * 3 // 3 mins
|
||||
let interval: TimeInterval = 1
|
||||
let fakeTotalUnitCount: Float = 0.9 * Float(progress.totalUnitCount)
|
||||
var fakeProgress: Float = 0
|
||||
|
||||
var recursiveCheck: () -> Void = {}
|
||||
recursiveCheck = {
|
||||
|
||||
guard fakeProgress < 1 else {
|
||||
|
||||
return
|
||||
}
|
||||
progress.completedUnitCount = Int64(fakeTotalUnitCount * fakeProgress)
|
||||
fakeProgress += Float(interval / estimatedTime)
|
||||
|
||||
timerQueue.asyncAfter(
|
||||
deadline: .now() + interval,
|
||||
execute: recursiveCheck
|
||||
)
|
||||
}
|
||||
timerQueue.async(execute: recursiveCheck)
|
||||
|
||||
_ = try withExtendedLifetime(NSPersistentStoreCoordinator(managedObjectModel: destinationModel)) { (coordinator: NSPersistentStoreCoordinator) in
|
||||
|
||||
try coordinator.addPersistentStoreSynchronously(
|
||||
type(of: storage).storeType,
|
||||
configuration: storage.configuration,
|
||||
URL: fileURL,
|
||||
options: storage.dictionary(
|
||||
forOptions: storage.localStorageOptions.union(.allowSynchronousLightweightMigration)
|
||||
)
|
||||
)
|
||||
}
|
||||
timerQueue.sync {
|
||||
|
||||
fakeProgress = 1
|
||||
}
|
||||
try storage.cs_finalizeStorageAndWait(soureModelHint: destinationModel)
|
||||
progress.completedUnitCount = progress.totalUnitCount
|
||||
return
|
||||
}
|
||||
catch {
|
||||
|
||||
throw CoreStoreError(error)
|
||||
}
|
||||
}
|
||||
|
||||
let temporaryDirectoryURL = URL(fileURLWithPath: NSTemporaryDirectory(), isDirectory: true)
|
||||
.appendingPathComponent(Bundle.main.bundleIdentifier ?? "com.CoreStore.DataStack")
|
||||
.appendingPathComponent(ProcessInfo().globallyUniqueString)
|
||||
@@ -716,6 +782,13 @@ public extension DataStack {
|
||||
destinationType: type(of: storage).storeType,
|
||||
destinationOptions: nil
|
||||
)
|
||||
let temporaryStorage = SQLiteStore(
|
||||
fileURL: temporaryFileURL,
|
||||
configuration: storage.configuration,
|
||||
migrationMappingProviders: storage.migrationMappingProviders,
|
||||
localStorageOptions: storage.localStorageOptions
|
||||
)
|
||||
try temporaryStorage.cs_finalizeStorageAndWait(soureModelHint: destinationModel)
|
||||
}
|
||||
catch {
|
||||
|
||||
@@ -723,6 +796,11 @@ public extension DataStack {
|
||||
throw CoreStoreError(error)
|
||||
}
|
||||
|
||||
let externalStorageDirName = "." + fileURL.deletingPathExtension().lastPathComponent + "_SUPPORT"
|
||||
let temporaryExternalStorageURL = temporaryDirectoryURL.appendingPathComponent(
|
||||
externalStorageDirName,
|
||||
isDirectory: true
|
||||
)
|
||||
do {
|
||||
|
||||
try fileManager.replaceItem(
|
||||
@@ -733,11 +811,23 @@ public extension DataStack {
|
||||
resultingItemURL: nil
|
||||
)
|
||||
|
||||
if fileManager.fileExists(atPath: temporaryExternalStorageURL.path) {
|
||||
let extenralStorageURL = fileURL.deletingLastPathComponent().appendingPathComponent(externalStorageDirName, isDirectory: true)
|
||||
try fileManager.replaceItem(
|
||||
at: extenralStorageURL as URL,
|
||||
withItemAt: temporaryExternalStorageURL,
|
||||
backupItemName: nil,
|
||||
options: [],
|
||||
resultingItemURL: nil
|
||||
)
|
||||
}
|
||||
|
||||
progress.completedUnitCount = progress.totalUnitCount
|
||||
}
|
||||
catch {
|
||||
|
||||
_ = try? fileManager.removeItem(at: temporaryFileURL)
|
||||
_ = try? fileManager.removeItem(at: temporaryExternalStorageURL)
|
||||
throw CoreStoreError(error)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ public extension DataStack {
|
||||
- parameter object: the `DynamicObject` to observe changes from
|
||||
- returns: a `ObjectMonitor` that monitors changes to `object`
|
||||
*/
|
||||
public func monitorObject<T: DynamicObject>(_ object: T) -> ObjectMonitor<T> {
|
||||
public func monitorObject<D>(_ object: D) -> ObjectMonitor<D> {
|
||||
|
||||
CoreStore.assert(
|
||||
Thread.isMainThread,
|
||||
@@ -54,7 +54,7 @@ public extension DataStack {
|
||||
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
- returns: a `ListMonitor` instance that monitors changes to the list
|
||||
*/
|
||||
public func monitorList<T: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> ListMonitor<T> {
|
||||
public func monitorList<D>(_ from: From<D>, _ fetchClauses: FetchClause...) -> ListMonitor<D> {
|
||||
|
||||
return self.monitorList(from, fetchClauses)
|
||||
}
|
||||
@@ -66,7 +66,7 @@ public extension DataStack {
|
||||
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
- returns: a `ListMonitor` instance that monitors changes to the list
|
||||
*/
|
||||
public func monitorList<T: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> ListMonitor<T> {
|
||||
public func monitorList<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) -> ListMonitor<D> {
|
||||
|
||||
CoreStore.assert(
|
||||
Thread.isMainThread,
|
||||
@@ -82,12 +82,29 @@ public extension DataStack {
|
||||
|
||||
CoreStore.assert(
|
||||
fetchRequest.sortDescriptors?.isEmpty == false,
|
||||
"An \(cs_typeName(ListMonitor<T>.self)) requires a sort information. Specify from a \(cs_typeName(OrderBy.self)) clause or any custom \(cs_typeName(FetchClause.self)) that provides a sort descriptor."
|
||||
"An \(cs_typeName(ListMonitor<D>.self)) requires a sort information. Specify from a \(cs_typeName(OrderBy<D>.self)) clause or any custom \(cs_typeName(FetchClause.self)) that provides a sort descriptor."
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `ListMonitor` for a list of `DynamicObject`s that satisfy the specified `FetchChainableBuilderType` built from a chain of clauses.
|
||||
```
|
||||
let monitor = dataStack.monitorList(
|
||||
From<MyPersonEntity>()
|
||||
.where(\.age > 18)
|
||||
.orderBy(.ascending(\.age))
|
||||
)
|
||||
```
|
||||
- parameter clauseChain: a `FetchChainableBuilderType` built from a chain of clauses
|
||||
- returns: a `ListMonitor` for a list of `DynamicObject`s that satisfy the specified `FetchChainableBuilderType`
|
||||
*/
|
||||
public func monitorList<B: FetchChainableBuilderType>(_ clauseChain: B) -> ListMonitor<B.ObjectType> {
|
||||
|
||||
return self.monitorList(clauseChain.from, clauseChain.fetchClauses)
|
||||
}
|
||||
|
||||
/**
|
||||
Asynchronously creates a `ListMonitor` for a list of `DynamicObject`s that satisfy the specified fetch clauses. Multiple `ListObserver`s may then register themselves to be notified when changes are made to the list. Since `NSFetchedResultsController` greedily locks the persistent store on initial fetch, you may prefer this method instead of the synchronous counterpart to avoid deadlocks while background updates/saves are being executed.
|
||||
|
||||
@@ -95,7 +112,7 @@ public extension DataStack {
|
||||
- parameter from: a `From` clause indicating the entity type
|
||||
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
*/
|
||||
public func monitorList<T: DynamicObject>(createAsynchronously: @escaping (ListMonitor<T>) -> Void, _ from: From<T>, _ fetchClauses: FetchClause...) {
|
||||
public func monitorList<D>(createAsynchronously: @escaping (ListMonitor<D>) -> Void, _ from: From<D>, _ fetchClauses: FetchClause...) {
|
||||
|
||||
self.monitorList(createAsynchronously: createAsynchronously, from, fetchClauses)
|
||||
}
|
||||
@@ -107,7 +124,7 @@ public extension DataStack {
|
||||
- parameter from: a `From` clause indicating the entity type
|
||||
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
*/
|
||||
public func monitorList<T: DynamicObject>(createAsynchronously: @escaping (ListMonitor<T>) -> Void, _ from: From<T>, _ fetchClauses: [FetchClause]) {
|
||||
public func monitorList<D>(createAsynchronously: @escaping (ListMonitor<D>) -> Void, _ from: From<D>, _ fetchClauses: [FetchClause]) {
|
||||
|
||||
CoreStore.assert(
|
||||
Thread.isMainThread,
|
||||
@@ -123,13 +140,39 @@ public extension DataStack {
|
||||
|
||||
CoreStore.assert(
|
||||
fetchRequest.sortDescriptors?.isEmpty == false,
|
||||
"An \(cs_typeName(ListMonitor<T>.self)) requires a sort information. Specify from a \(cs_typeName(OrderBy.self)) clause or any custom \(cs_typeName(FetchClause.self)) that provides a sort descriptor."
|
||||
"An \(cs_typeName(ListMonitor<D>.self)) requires a sort information. Specify from a \(cs_typeName(OrderBy<D>.self)) clause or any custom \(cs_typeName(FetchClause.self)) that provides a sort descriptor."
|
||||
)
|
||||
},
|
||||
createAsynchronously: createAsynchronously
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
Asynchronously creates a `ListMonitor` for a list of `DynamicObject`s that satisfy the specified `FetchChainableBuilderType` built from a chain of clauses. Since `NSFetchedResultsController` greedily locks the persistent store on initial fetch, you may prefer this method instead of the synchronous counterpart to avoid deadlocks while background updates/saves are being executed.
|
||||
|
||||
```
|
||||
dataStack.monitorList(
|
||||
{ (monitor) in
|
||||
self.monitor = monitor
|
||||
},
|
||||
From<MyPersonEntity>()
|
||||
.where(\.age > 18)
|
||||
.orderBy(.ascending(\.age))
|
||||
)
|
||||
```
|
||||
- parameter createAsynchronously: the closure that receives the created `ListMonitor` instance
|
||||
- parameter clauseChain: a `FetchChainableBuilderType` built from a chain of clauses
|
||||
- returns: a `ListMonitor` for a list of `DynamicObject`s that satisfy the specified `FetchChainableBuilderType`
|
||||
*/
|
||||
public func monitorList<B: FetchChainableBuilderType>(createAsynchronously: @escaping (ListMonitor<B.ObjectType>) -> Void, _ clauseChain: B) {
|
||||
|
||||
self.monitorList(
|
||||
createAsynchronously: createAsynchronously,
|
||||
clauseChain.from,
|
||||
clauseChain.fetchClauses
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `ListMonitor` for a sectioned list of `DynamicObject`s that satisfy the specified fetch clauses. Multiple `ListObserver`s may then register themselves to be notified when changes are made to the list.
|
||||
|
||||
@@ -138,7 +181,7 @@ public extension DataStack {
|
||||
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
- returns: a `ListMonitor` instance that monitors changes to the list
|
||||
*/
|
||||
public func monitorSectionedList<T: DynamicObject>(_ from: From<T>, _ sectionBy: SectionBy, _ fetchClauses: FetchClause...) -> ListMonitor<T> {
|
||||
public func monitorSectionedList<D>(_ from: From<D>, _ sectionBy: SectionBy<D>, _ fetchClauses: FetchClause...) -> ListMonitor<D> {
|
||||
|
||||
return self.monitorSectionedList(from, sectionBy, fetchClauses)
|
||||
}
|
||||
@@ -151,7 +194,7 @@ public extension DataStack {
|
||||
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
- returns: a `ListMonitor` instance that monitors changes to the list
|
||||
*/
|
||||
public func monitorSectionedList<T: DynamicObject>(_ from: From<T>, _ sectionBy: SectionBy, _ fetchClauses: [FetchClause]) -> ListMonitor<T> {
|
||||
public func monitorSectionedList<D>(_ from: From<D>, _ sectionBy: SectionBy<D>, _ fetchClauses: [FetchClause]) -> ListMonitor<D> {
|
||||
|
||||
CoreStore.assert(
|
||||
Thread.isMainThread,
|
||||
@@ -168,12 +211,34 @@ public extension DataStack {
|
||||
|
||||
CoreStore.assert(
|
||||
fetchRequest.sortDescriptors?.isEmpty == false,
|
||||
"An \(cs_typeName(ListMonitor<T>.self)) requires a sort information. Specify from a \(cs_typeName(OrderBy.self)) clause or any custom \(cs_typeName(FetchClause.self)) that provides a sort descriptor."
|
||||
"An \(cs_typeName(ListMonitor<D>.self)) requires a sort information. Specify from a \(cs_typeName(OrderBy<D>.self)) clause or any custom \(cs_typeName(FetchClause.self)) that provides a sort descriptor."
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
Creates a `ListMonitor` for a sectioned list of `DynamicObject`s that satisfy the specified `SectionMonitorBuilderType` built from a chain of clauses.
|
||||
```
|
||||
let monitor = dataStack.monitorSectionedList(
|
||||
From<MyPersonEntity>()
|
||||
.sectionBy(\.age, { "\($0!) years old" })
|
||||
.where(\.age > 18)
|
||||
.orderBy(.ascending(\.age))
|
||||
)
|
||||
```
|
||||
- parameter clauseChain: a `SectionMonitorBuilderType` built from a chain of clauses
|
||||
- returns: a `ListMonitor` for a list of `DynamicObject`s that satisfy the specified `SectionMonitorBuilderType`
|
||||
*/
|
||||
public func monitorSectionedList<B: SectionMonitorBuilderType>(_ clauseChain: B) -> ListMonitor<B.ObjectType> {
|
||||
|
||||
return self.monitorSectionedList(
|
||||
clauseChain.from,
|
||||
clauseChain.sectionBy,
|
||||
clauseChain.fetchClauses
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
Asynchronously creates a `ListMonitor` for a sectioned list of `DynamicObject`s that satisfy the specified fetch clauses. Multiple `ListObserver`s may then register themselves to be notified when changes are made to the list. Since `NSFetchedResultsController` greedily locks the persistent store on initial fetch, you may prefer this method instead of the synchronous counterpart to avoid deadlocks while background updates/saves are being executed.
|
||||
|
||||
@@ -182,7 +247,7 @@ public extension DataStack {
|
||||
- parameter sectionBy: a `SectionBy` clause indicating the keyPath for the attribute to use when sorting the list into sections.
|
||||
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
*/
|
||||
public func monitorSectionedList<T: DynamicObject>(createAsynchronously: @escaping (ListMonitor<T>) -> Void, _ from: From<T>, _ sectionBy: SectionBy, _ fetchClauses: FetchClause...) {
|
||||
public func monitorSectionedList<D>(createAsynchronously: @escaping (ListMonitor<D>) -> Void, _ from: From<D>, _ sectionBy: SectionBy<D>, _ fetchClauses: FetchClause...) {
|
||||
|
||||
self.monitorSectionedList(createAsynchronously: createAsynchronously, from, sectionBy, fetchClauses)
|
||||
}
|
||||
@@ -195,7 +260,7 @@ public extension DataStack {
|
||||
- parameter sectionBy: a `SectionBy` clause indicating the keyPath for the attribute to use when sorting the list into sections.
|
||||
- parameter fetchClauses: a series of `FetchClause` instances for fetching the object list. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
*/
|
||||
public func monitorSectionedList<T: DynamicObject>(createAsynchronously: @escaping (ListMonitor<T>) -> Void, _ from: From<T>, _ sectionBy: SectionBy, _ fetchClauses: [FetchClause]) {
|
||||
public func monitorSectionedList<D>(createAsynchronously: @escaping (ListMonitor<D>) -> Void, _ from: From<D>, _ sectionBy: SectionBy<D>, _ fetchClauses: [FetchClause]) {
|
||||
|
||||
CoreStore.assert(
|
||||
Thread.isMainThread,
|
||||
@@ -212,10 +277,36 @@ public extension DataStack {
|
||||
|
||||
CoreStore.assert(
|
||||
fetchRequest.sortDescriptors?.isEmpty == false,
|
||||
"An \(cs_typeName(ListMonitor<T>.self)) requires a sort information. Specify from a \(cs_typeName(OrderBy.self)) clause or any custom \(cs_typeName(FetchClause.self)) that provides a sort descriptor."
|
||||
"An \(cs_typeName(ListMonitor<D>.self)) requires a sort information. Specify from a \(cs_typeName(OrderBy<D>.self)) clause or any custom \(cs_typeName(FetchClause.self)) that provides a sort descriptor."
|
||||
)
|
||||
},
|
||||
createAsynchronously: createAsynchronously
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
Asynchronously creates a `ListMonitor` for a sectioned list of `DynamicObject`s that satisfy the specified `SectionMonitorBuilderType` built from a chain of clauses.
|
||||
```
|
||||
dataStack.monitorSectionedList(
|
||||
{ (monitor) in
|
||||
self.monitor = monitor
|
||||
},
|
||||
From<MyPersonEntity>()
|
||||
.sectionBy(\.age, { "\($0!) years old" })
|
||||
.where(\.age > 18)
|
||||
.orderBy(.ascending(\.age))
|
||||
)
|
||||
```
|
||||
- parameter clauseChain: a `SectionMonitorBuilderType` built from a chain of clauses
|
||||
- returns: a `ListMonitor` for a list of `DynamicObject`s that satisfy the specified `SectionMonitorBuilderType`
|
||||
*/
|
||||
public func monitorSectionedList<B: SectionMonitorBuilderType>(createAsynchronously: @escaping (ListMonitor<B.ObjectType>) -> Void, _ clauseChain: B) {
|
||||
|
||||
self.monitorSectionedList(
|
||||
createAsynchronously: createAsynchronously,
|
||||
clauseChain.from,
|
||||
clauseChain.sectionBy,
|
||||
clauseChain.fetchClauses
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ extension DataStack: FetchableSource, QueryableSource {
|
||||
- parameter object: a reference to the object created/fetched outside the `DataStack`
|
||||
- returns: the `DynamicObject` instance if the object exists in the `DataStack`, or `nil` if not found.
|
||||
*/
|
||||
public func fetchExisting<T: DynamicObject>(_ object: T) -> T? {
|
||||
public func fetchExisting<D: DynamicObject>(_ object: D) -> D? {
|
||||
|
||||
return self.mainContext.fetchExisting(object)
|
||||
}
|
||||
@@ -50,7 +50,7 @@ extension DataStack: FetchableSource, QueryableSource {
|
||||
- parameter objectID: the `NSManagedObjectID` for the object
|
||||
- returns: the `DynamicObject` instance if the object exists in the `DataStack`, or `nil` if not found.
|
||||
*/
|
||||
public func fetchExisting<T: DynamicObject>(_ objectID: NSManagedObjectID) -> T? {
|
||||
public func fetchExisting<D: DynamicObject>(_ objectID: NSManagedObjectID) -> D? {
|
||||
|
||||
return self.mainContext.fetchExisting(objectID)
|
||||
}
|
||||
@@ -61,7 +61,7 @@ extension DataStack: FetchableSource, QueryableSource {
|
||||
- parameter objects: an array of `DynamicObject`s created/fetched outside the `DataStack`
|
||||
- returns: the `DynamicObject` array for objects that exists in the `DataStack`
|
||||
*/
|
||||
public func fetchExisting<T: DynamicObject, S: Sequence>(_ objects: S) -> [T] where S.Iterator.Element == T {
|
||||
public func fetchExisting<D: DynamicObject, S: Sequence>(_ objects: S) -> [D] where S.Iterator.Element == D {
|
||||
|
||||
return self.mainContext.fetchExisting(objects)
|
||||
}
|
||||
@@ -72,7 +72,7 @@ extension DataStack: FetchableSource, QueryableSource {
|
||||
- parameter objectIDs: the `NSManagedObjectID` array for the objects
|
||||
- returns: the `DynamicObject` array for objects that exists in the `DataStack`
|
||||
*/
|
||||
public func fetchExisting<T: DynamicObject, S: Sequence>(_ objectIDs: S) -> [T] where S.Iterator.Element == NSManagedObjectID {
|
||||
public func fetchExisting<D: DynamicObject, S: Sequence>(_ objectIDs: S) -> [D] where S.Iterator.Element == NSManagedObjectID {
|
||||
|
||||
return self.mainContext.fetchExisting(objectIDs)
|
||||
}
|
||||
@@ -84,7 +84,7 @@ extension DataStack: FetchableSource, QueryableSource {
|
||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
- returns: the first `DynamicObject` instance that satisfies the specified `FetchClause`s
|
||||
*/
|
||||
public func fetchOne<T: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> T? {
|
||||
public func fetchOne<D>(_ from: From<D>, _ fetchClauses: FetchClause...) -> D? {
|
||||
|
||||
CoreStore.assert(
|
||||
Thread.isMainThread,
|
||||
@@ -100,7 +100,7 @@ extension DataStack: FetchableSource, QueryableSource {
|
||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
- returns: the first `DynamicObject` instance that satisfies the specified `FetchClause`s
|
||||
*/
|
||||
public func fetchOne<T: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> T? {
|
||||
public func fetchOne<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) -> D? {
|
||||
|
||||
CoreStore.assert(
|
||||
Thread.isMainThread,
|
||||
@@ -109,6 +109,27 @@ extension DataStack: FetchableSource, QueryableSource {
|
||||
return self.mainContext.fetchOne(from, fetchClauses)
|
||||
}
|
||||
|
||||
/**
|
||||
Fetches the first `DynamicObject` instance that satisfies the specified `FetchChainableBuilderType` built from a chain of clauses.
|
||||
```
|
||||
let youngestTeen = dataStack.fetchOne(
|
||||
From<MyPersonEntity>()
|
||||
.where(\.age > 18)
|
||||
.orderBy(.ascending(\.age))
|
||||
)
|
||||
```
|
||||
- parameter clauseChain: a `FetchChainableBuilderType` built from a chain of clauses
|
||||
- returns: the first `DynamicObject` instance that satisfies the specified `FetchChainableBuilderType`
|
||||
*/
|
||||
public func fetchOne<B: FetchChainableBuilderType>(_ clauseChain: B) -> B.ObjectType? {
|
||||
|
||||
CoreStore.assert(
|
||||
Thread.isMainThread,
|
||||
"Attempted to fetch from a \(cs_typeName(self)) outside the main thread."
|
||||
)
|
||||
return self.mainContext.fetchOne(clauseChain)
|
||||
}
|
||||
|
||||
/**
|
||||
Fetches all `DynamicObject` instances that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
|
||||
@@ -116,7 +137,7 @@ extension DataStack: FetchableSource, QueryableSource {
|
||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
- returns: all `DynamicObject` instances that satisfy the specified `FetchClause`s
|
||||
*/
|
||||
public func fetchAll<T: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> [T]? {
|
||||
public func fetchAll<D>(_ from: From<D>, _ fetchClauses: FetchClause...) -> [D]? {
|
||||
|
||||
CoreStore.assert(
|
||||
Thread.isMainThread,
|
||||
@@ -132,7 +153,7 @@ extension DataStack: FetchableSource, QueryableSource {
|
||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
- returns: all `DynamicObject` instances that satisfy the specified `FetchClause`s
|
||||
*/
|
||||
public func fetchAll<T: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> [T]? {
|
||||
public func fetchAll<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) -> [D]? {
|
||||
|
||||
CoreStore.assert(
|
||||
Thread.isMainThread,
|
||||
@@ -141,6 +162,27 @@ extension DataStack: FetchableSource, QueryableSource {
|
||||
return self.mainContext.fetchAll(from, fetchClauses)
|
||||
}
|
||||
|
||||
/**
|
||||
Fetches all `DynamicObject` instances that satisfy the specified `FetchChainableBuilderType` built from a chain of clauses.
|
||||
```
|
||||
let people = dataStack.fetchAll(
|
||||
From<MyPersonEntity>()
|
||||
.where(\.age > 18)
|
||||
.orderBy(.ascending(\.age))
|
||||
)
|
||||
```
|
||||
- parameter clauseChain: a `FetchChainableBuilderType` built from a chain of clauses
|
||||
- returns: all `DynamicObject` instances that satisfy the specified `FetchChainableBuilderType`
|
||||
*/
|
||||
public func fetchAll<B: FetchChainableBuilderType>(_ clauseChain: B) -> [B.ObjectType]? {
|
||||
|
||||
CoreStore.assert(
|
||||
Thread.isMainThread,
|
||||
"Attempted to fetch from a \(cs_typeName(self)) outside the main thread."
|
||||
)
|
||||
return self.mainContext.fetchAll(clauseChain)
|
||||
}
|
||||
|
||||
/**
|
||||
Fetches the number of `DynamicObject`s that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
|
||||
@@ -148,7 +190,7 @@ extension DataStack: FetchableSource, QueryableSource {
|
||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
- returns: the number `DynamicObject`s that satisfy the specified `FetchClause`s
|
||||
*/
|
||||
public func fetchCount<T: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> Int? {
|
||||
public func fetchCount<D>(_ from: From<D>, _ fetchClauses: FetchClause...) -> Int? {
|
||||
|
||||
CoreStore.assert(
|
||||
Thread.isMainThread,
|
||||
@@ -164,7 +206,7 @@ extension DataStack: FetchableSource, QueryableSource {
|
||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
- returns: the number `DynamicObject`s that satisfy the specified `FetchClause`s
|
||||
*/
|
||||
public func fetchCount<T: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> Int? {
|
||||
public func fetchCount<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) -> Int? {
|
||||
|
||||
CoreStore.assert(
|
||||
Thread.isMainThread,
|
||||
@@ -173,6 +215,27 @@ extension DataStack: FetchableSource, QueryableSource {
|
||||
return self.mainContext.fetchCount(from, fetchClauses)
|
||||
}
|
||||
|
||||
/**
|
||||
Fetches the number of `DynamicObject`s that satisfy the specified `FetchChainableBuilderType` built from a chain of clauses.
|
||||
```
|
||||
let numberOfAdults = dataStack.fetchCount(
|
||||
From<MyPersonEntity>()
|
||||
.where(\.age > 18)
|
||||
.orderBy(.ascending(\.age))
|
||||
)
|
||||
```
|
||||
- parameter clauseChain: a `FetchChainableBuilderType` built from a chain of clauses
|
||||
- returns: the number `DynamicObject`s that satisfy the specified `FetchChainableBuilderType`
|
||||
*/
|
||||
public func fetchCount<B: FetchChainableBuilderType>(_ clauseChain: B) -> Int? {
|
||||
|
||||
CoreStore.assert(
|
||||
Thread.isMainThread,
|
||||
"Attempted to fetch from a \(cs_typeName(self)) outside the main thread."
|
||||
)
|
||||
return self.mainContext.fetchCount(clauseChain)
|
||||
}
|
||||
|
||||
/**
|
||||
Fetches the `NSManagedObjectID` for the first `DynamicObject` that satisfies the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
|
||||
@@ -180,7 +243,7 @@ extension DataStack: FetchableSource, QueryableSource {
|
||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
- returns: the `NSManagedObjectID` for the first `DynamicObject` that satisfies the specified `FetchClause`s
|
||||
*/
|
||||
public func fetchObjectID<T: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> NSManagedObjectID? {
|
||||
public func fetchObjectID<D>(_ from: From<D>, _ fetchClauses: FetchClause...) -> NSManagedObjectID? {
|
||||
|
||||
CoreStore.assert(
|
||||
Thread.isMainThread,
|
||||
@@ -196,7 +259,7 @@ extension DataStack: FetchableSource, QueryableSource {
|
||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
- returns: the `NSManagedObjectID` for the first `DynamicObject` that satisfies the specified `FetchClause`s
|
||||
*/
|
||||
public func fetchObjectID<T: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> NSManagedObjectID? {
|
||||
public func fetchObjectID<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) -> NSManagedObjectID? {
|
||||
|
||||
CoreStore.assert(
|
||||
Thread.isMainThread,
|
||||
@@ -205,6 +268,27 @@ extension DataStack: FetchableSource, QueryableSource {
|
||||
return self.mainContext.fetchObjectID(from, fetchClauses)
|
||||
}
|
||||
|
||||
/**
|
||||
Fetches the `NSManagedObjectID` for the first `DynamicObject` that satisfies the specified `FetchChainableBuilderType` built from a chain of clauses.
|
||||
```
|
||||
let youngestTeenID = dataStack.fetchObjectID(
|
||||
From<MyPersonEntity>()
|
||||
.where(\.age > 18)
|
||||
.orderBy(.ascending(\.age))
|
||||
)
|
||||
```
|
||||
- parameter clauseChain: a `FetchChainableBuilderType` built from a chain of clauses
|
||||
- returns: the `NSManagedObjectID` for the first `DynamicObject` that satisfies the specified `FetchChainableBuilderType`
|
||||
*/
|
||||
public func fetchObjectID<B: FetchChainableBuilderType>(_ clauseChain: B) -> NSManagedObjectID? {
|
||||
|
||||
CoreStore.assert(
|
||||
Thread.isMainThread,
|
||||
"Attempted to fetch from a \(cs_typeName(self)) outside the main thread."
|
||||
)
|
||||
return self.mainContext.fetchObjectID(clauseChain)
|
||||
}
|
||||
|
||||
/**
|
||||
Fetches the `NSManagedObjectID` for all `DynamicObject`s that satisfy the specified `FetchClause`s. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
|
||||
@@ -212,7 +296,7 @@ extension DataStack: FetchableSource, QueryableSource {
|
||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
- returns: the `NSManagedObjectID` for all `DynamicObject`s that satisfy the specified `FetchClause`s
|
||||
*/
|
||||
public func fetchObjectIDs<T: DynamicObject>(_ from: From<T>, _ fetchClauses: FetchClause...) -> [NSManagedObjectID]? {
|
||||
public func fetchObjectIDs<D>(_ from: From<D>, _ fetchClauses: FetchClause...) -> [NSManagedObjectID]? {
|
||||
|
||||
CoreStore.assert(
|
||||
Thread.isMainThread,
|
||||
@@ -228,7 +312,7 @@ extension DataStack: FetchableSource, QueryableSource {
|
||||
- parameter fetchClauses: a series of `FetchClause` instances for the fetch request. Accepts `Where`, `OrderBy`, and `Tweak` clauses.
|
||||
- returns: the `NSManagedObjectID` for all `DynamicObject`s that satisfy the specified `FetchClause`s
|
||||
*/
|
||||
public func fetchObjectIDs<T: DynamicObject>(_ from: From<T>, _ fetchClauses: [FetchClause]) -> [NSManagedObjectID]? {
|
||||
public func fetchObjectIDs<D>(_ from: From<D>, _ fetchClauses: [FetchClause]) -> [NSManagedObjectID]? {
|
||||
|
||||
CoreStore.assert(
|
||||
Thread.isMainThread,
|
||||
@@ -237,6 +321,27 @@ extension DataStack: FetchableSource, QueryableSource {
|
||||
return self.mainContext.fetchObjectIDs(from, fetchClauses)
|
||||
}
|
||||
|
||||
/**
|
||||
Fetches the `NSManagedObjectID` for all `DynamicObject`s that satisfy the specified `FetchChainableBuilderType` built from a chain of clauses.
|
||||
```
|
||||
let idsOfAdults = dataStack.fetchObjectIDs(
|
||||
From<MyPersonEntity>()
|
||||
.where(\.age > 18)
|
||||
.orderBy(.ascending(\.age))
|
||||
)
|
||||
```
|
||||
- parameter clauseChain: a `FetchChainableBuilderType` built from a chain of clauses
|
||||
- returns: the `NSManagedObjectID` for all `DynamicObject`s that satisfy the specified `FetchChainableBuilderType`
|
||||
*/
|
||||
public func fetchObjectIDs<B: FetchChainableBuilderType>(_ clauseChain: B) -> [NSManagedObjectID]? {
|
||||
|
||||
CoreStore.assert(
|
||||
Thread.isMainThread,
|
||||
"Attempted to fetch from a \(cs_typeName(self)) outside the main thread."
|
||||
)
|
||||
return self.mainContext.fetchObjectIDs(clauseChain)
|
||||
}
|
||||
|
||||
|
||||
// MARK: QueryableSource
|
||||
|
||||
@@ -250,7 +355,7 @@ extension DataStack: FetchableSource, QueryableSource {
|
||||
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
||||
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
|
||||
*/
|
||||
public func queryValue<T: DynamicObject, U: QueryableAttributeType>(_ from: From<T>, _ selectClause: Select<U>, _ queryClauses: QueryClause...) -> U? {
|
||||
public func queryValue<D, U: QueryableAttributeType>(_ from: From<D>, _ selectClause: Select<D, U>, _ queryClauses: QueryClause...) -> U? {
|
||||
|
||||
CoreStore.assert(
|
||||
Thread.isMainThread,
|
||||
@@ -269,7 +374,7 @@ extension DataStack: FetchableSource, QueryableSource {
|
||||
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
||||
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
|
||||
*/
|
||||
public func queryValue<T: DynamicObject, U: QueryableAttributeType>(_ from: From<T>, _ selectClause: Select<U>, _ queryClauses: [QueryClause]) -> U? {
|
||||
public func queryValue<D, U: QueryableAttributeType>(_ from: From<D>, _ selectClause: Select<D, U>, _ queryClauses: [QueryClause]) -> U? {
|
||||
|
||||
CoreStore.assert(
|
||||
Thread.isMainThread,
|
||||
@@ -278,6 +383,29 @@ extension DataStack: FetchableSource, QueryableSource {
|
||||
return self.mainContext.queryValue(from, selectClause, queryClauses)
|
||||
}
|
||||
|
||||
/**
|
||||
Queries a property value or aggregate as specified by the `QueryChainableBuilderType` built from a chain of clauses.
|
||||
|
||||
A "query" differs from a "fetch" in that it only retrieves values already stored in the persistent store. As such, values from unsaved transactions or contexts will not be incorporated in the query result.
|
||||
```
|
||||
let averageAdultAge = dataStack.queryValue(
|
||||
From<MyPersonEntity>()
|
||||
.select(Int.self, .average(\.age))
|
||||
.where(\.age > 18)
|
||||
)
|
||||
```
|
||||
- parameter clauseChain: a `QueryChainableBuilderType` indicating the property/aggregate to fetch and the series of queries for the request.
|
||||
- returns: the result of the the query as specified by the `QueryChainableBuilderType`
|
||||
*/
|
||||
public func queryValue<B: QueryChainableBuilderType>(_ clauseChain: B) -> B.ResultType? where B.ResultType: QueryableAttributeType {
|
||||
|
||||
CoreStore.assert(
|
||||
Thread.isMainThread,
|
||||
"Attempted to query from a \(cs_typeName(self)) outside the main thread."
|
||||
)
|
||||
return self.mainContext.queryValue(clauseChain.from, clauseChain.select, clauseChain.queryClauses)
|
||||
}
|
||||
|
||||
/**
|
||||
Queries a dictionary of attribute values as specified by the `QueryClause`s. Requires at least a `Select` clause, and optional `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
||||
|
||||
@@ -288,7 +416,7 @@ extension DataStack: FetchableSource, QueryableSource {
|
||||
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
||||
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
|
||||
*/
|
||||
public func queryAttributes<T: DynamicObject>(_ from: From<T>, _ selectClause: Select<NSDictionary>, _ queryClauses: QueryClause...) -> [[String: Any]]? {
|
||||
public func queryAttributes<D>(_ from: From<D>, _ selectClause: Select<D, NSDictionary>, _ queryClauses: QueryClause...) -> [[String: Any]]? {
|
||||
|
||||
CoreStore.assert(
|
||||
Thread.isMainThread,
|
||||
@@ -307,7 +435,7 @@ extension DataStack: FetchableSource, QueryableSource {
|
||||
- parameter queryClauses: a series of `QueryClause` instances for the query request. Accepts `Where`, `OrderBy`, `GroupBy`, and `Tweak` clauses.
|
||||
- returns: the result of the the query. The type of the return value is specified by the generic type of the `Select<U>` parameter.
|
||||
*/
|
||||
public func queryAttributes<T: DynamicObject>(_ from: From<T>, _ selectClause: Select<NSDictionary>, _ queryClauses: [QueryClause]) -> [[String: Any]]? {
|
||||
public func queryAttributes<D>(_ from: From<D>, _ selectClause: Select<D, NSDictionary>, _ queryClauses: [QueryClause]) -> [[String: Any]]? {
|
||||
|
||||
CoreStore.assert(
|
||||
Thread.isMainThread,
|
||||
@@ -316,6 +444,38 @@ extension DataStack: FetchableSource, QueryableSource {
|
||||
return self.mainContext.queryAttributes(from, selectClause, queryClauses)
|
||||
}
|
||||
|
||||
/**
|
||||
Queries a dictionary of attribute values or as specified by the `QueryChainableBuilderType` built from a chain of clauses.
|
||||
|
||||
A "query" differs from a "fetch" in that it only retrieves values already stored in the persistent store. As such, values from unsaved transactions or contexts will not be incorporated in the query result.
|
||||
```
|
||||
let results = dataStack.queryAttributes(
|
||||
From<MyPersonEntity>()
|
||||
.select(
|
||||
NSDictionary.self,
|
||||
.attribute(\.age, as: "age"),
|
||||
.count(\.age, as: "numberOfPeople")
|
||||
)
|
||||
.groupBy(\.age)
|
||||
)
|
||||
for dictionary in results! {
|
||||
let age = dictionary["age"] as! Int
|
||||
let count = dictionary["numberOfPeople"] as! Int
|
||||
print("There are \(count) people who are \(age) years old."
|
||||
}
|
||||
```
|
||||
- parameter clauseChain: a `QueryChainableBuilderType` indicating the properties to fetch and the series of queries for the request.
|
||||
- returns: the result of the the query as specified by the `QueryChainableBuilderType`
|
||||
*/
|
||||
public func queryAttributes<B: QueryChainableBuilderType>(_ clauseChain: B) -> [[String: Any]]? where B.ResultType == NSDictionary {
|
||||
|
||||
CoreStore.assert(
|
||||
Thread.isMainThread,
|
||||
"Attempted to query from a \(cs_typeName(self)) outside the main thread."
|
||||
)
|
||||
return self.mainContext.queryAttributes(clauseChain.from, clauseChain.select, clauseChain.queryClauses)
|
||||
}
|
||||
|
||||
|
||||
// MARK: FetchableSource, QueryableSource
|
||||
|
||||
|
||||
@@ -61,10 +61,6 @@ public extension DataStack {
|
||||
)
|
||||
transaction.transactionQueue.cs_async {
|
||||
|
||||
defer {
|
||||
|
||||
withExtendedLifetime(transaction, {})
|
||||
}
|
||||
let userInfo: T
|
||||
do {
|
||||
|
||||
@@ -82,6 +78,10 @@ public extension DataStack {
|
||||
}
|
||||
transaction.autoCommit { (_, error) in
|
||||
|
||||
defer {
|
||||
|
||||
withExtendedLifetime((self, transaction), {})
|
||||
}
|
||||
if let error = error {
|
||||
|
||||
failure(error)
|
||||
@@ -95,7 +95,7 @@ public extension DataStack {
|
||||
}
|
||||
|
||||
/**
|
||||
Performs a transaction synchronously where `NSManagedObject` or `CoreStoreObject` creates, updates, and deletes can be made. The changes are commited automatically after the `task` closure returns. On success, the value returned from closure will be the return value of `perform(synchronous:)`. Any errors thrown from inside the `task` will be rethrown from `perform(synchronous:)`. To cancel/rollback changes, call `try transaction.cancel()`, which throws a `CoreStoreError.userCancelled`.
|
||||
Performs a transaction synchronously where `NSManagedObject` or `CoreStoreObject` creates, updates, and deletes can be made. The changes are commited automatically after the `task` closure returns. On success, the value returned from closure will be the return value of `perform(synchronous:)`. Any errors thrown from inside the `task` will be thrown from `perform(synchronous:)`. To cancel/rollback changes, call `try transaction.cancel()`, which throws a `CoreStoreError.userCancelled`.
|
||||
|
||||
- parameter task: the synchronous non-escaping closure where creates, updates, and deletes can be made to the transaction. Transaction blocks are executed serially in a background queue, and all changes are made from a concurrent `NSManagedObjectContext`.
|
||||
- parameter waitForAllObservers: When `true`, this method waits for all observers to be notified of the changes before returning. This results in more predictable data update order, but may risk triggering deadlocks. When `false`, this method does not wait for observers to be notified of the changes before returning. This results in lower risk for deadlocks, but the updated data may not have been propagated to the `DataStack` after returning. Defaults to `true`.
|
||||
@@ -112,7 +112,7 @@ public extension DataStack {
|
||||
|
||||
defer {
|
||||
|
||||
withExtendedLifetime(transaction, {})
|
||||
withExtendedLifetime((self, transaction), {})
|
||||
}
|
||||
let userInfo: T
|
||||
do {
|
||||
@@ -211,9 +211,9 @@ public extension DataStack {
|
||||
}
|
||||
switch transaction.result {
|
||||
|
||||
case nil: return nil
|
||||
case (let hasChanges, nil)?: return SaveResult(hasChanges: hasChanges)
|
||||
case (_, let error?)?: return SaveResult(error)
|
||||
case .none: return nil
|
||||
case .some(let hasChanges, nil): return SaveResult(hasChanges: hasChanges)
|
||||
case .some(_, let error?): return SaveResult(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,19 +34,24 @@ import CoreData
|
||||
*/
|
||||
public final class DataStack: Equatable {
|
||||
|
||||
/**
|
||||
The resolved application name, used by the `DataStack` as the default Xcode model name (.xcdatamodel filename) if not explicitly provided.
|
||||
*/
|
||||
public static let applicationName = (Bundle.main.object(forInfoDictionaryKey: "CFBundleName") as? String) ?? "CoreData"
|
||||
|
||||
/**
|
||||
Convenience initializer for `DataStack` that creates a `SchemaHistory` from the model with the specified `modelName` in the specified `bundle`.
|
||||
|
||||
- parameter modelName: the name of the (.xcdatamodeld) model file. If not specified, the application name (CFBundleName) will be used if it exists, or "CoreData" if it the bundle name was not set (e.g. in Unit Tests).
|
||||
- parameter xcodeModelName: the name of the (.xcdatamodeld) model file. If not specified, the application name (CFBundleName) will be used if it exists, or "CoreData" if it the bundle name was not set (e.g. in Unit Tests).
|
||||
- parameter bundle: an optional bundle to load models from. If not specified, the main bundle will be used.
|
||||
- parameter migrationChain: the `MigrationChain` that indicates the sequence of model versions to be used as the order for progressive migrations. If not specified, will default to a non-migrating data stack.
|
||||
*/
|
||||
public convenience init(modelName: XcodeDataModelFileName = DataStack.applicationName, bundle: Bundle = Bundle.main, migrationChain: MigrationChain = nil) {
|
||||
public convenience init(xcodeModelName: XcodeDataModelFileName = DataStack.applicationName, bundle: Bundle = Bundle.main, migrationChain: MigrationChain = nil) {
|
||||
|
||||
self.init(
|
||||
schemaHistory: SchemaHistory(
|
||||
XcodeDataModelSchema.from(
|
||||
modelName: modelName,
|
||||
modelName: xcodeModelName,
|
||||
bundle: bundle,
|
||||
migrationChain: migrationChain
|
||||
),
|
||||
@@ -105,9 +110,6 @@ public final class DataStack: Equatable {
|
||||
*/
|
||||
public required init(schemaHistory: SchemaHistory) {
|
||||
|
||||
// TODO: test before release (rolled back)
|
||||
// _ = DataStack.isGloballyInitialized
|
||||
|
||||
self.coordinator = NSPersistentStoreCoordinator(managedObjectModel: schemaHistory.rawModel)
|
||||
self.rootSavingContext = NSManagedObjectContext.rootSavingContextForCoordinator(self.coordinator)
|
||||
self.mainContext = NSManagedObjectContext.mainContextForRootContext(self.rootSavingContext)
|
||||
@@ -477,8 +479,6 @@ public final class DataStack: Equatable {
|
||||
|
||||
internal static var defaultConfigurationName = "PF_DEFAULT_CONFIGURATION_NAME"
|
||||
|
||||
internal static let applicationName = (Bundle.main.object(forInfoDictionaryKey: "CFBundleName") as? String) ?? "CoreData"
|
||||
|
||||
internal let coordinator: NSPersistentStoreCoordinator
|
||||
internal let rootSavingContext: NSManagedObjectContext
|
||||
internal let mainContext: NSManagedObjectContext
|
||||
@@ -585,13 +585,6 @@ public final class DataStack: Equatable {
|
||||
|
||||
// MARK: Private
|
||||
|
||||
// TODO: test before release (rolled back)
|
||||
// private static let isGloballyInitialized: Bool = {
|
||||
//
|
||||
// NSManagedObject.cs_swizzleMethodsForLogging()
|
||||
// return true
|
||||
// }()
|
||||
|
||||
private var persistentStoresByFinalConfiguration = [String: NSPersistentStore]()
|
||||
private var finalConfigurationsByEntityIdentifier = [EntityIdentifier: Set<String>]()
|
||||
|
||||
@@ -613,14 +606,25 @@ public final class DataStack: Equatable {
|
||||
|
||||
// MARK: Deprecated
|
||||
|
||||
@available(*, deprecated, message: "Use the new DataStack.init(schemaHistory:) initializer passing a LegacyXcodeDataModelSchema instance as argument")
|
||||
@available(*, deprecated, renamed: "init(xcodeModelName:bundle:migrationChain:)")
|
||||
public convenience init(modelName: XcodeDataModelFileName, bundle: Bundle = Bundle.main, migrationChain: MigrationChain = nil) {
|
||||
|
||||
self.init(
|
||||
xcodeModelName: modelName,
|
||||
bundle: bundle,
|
||||
migrationChain: migrationChain
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@available(*, deprecated, message: "Use the new DataStack.init(schemaHistory:) initializer passing an UnsafeDataModelSchema instance as argument")
|
||||
public convenience init(model: NSManagedObjectModel, migrationChain: MigrationChain = nil) {
|
||||
|
||||
let modelVersion = migrationChain.leafVersions.first!
|
||||
self.init(
|
||||
schemaHistory: SchemaHistory(
|
||||
allSchema: [
|
||||
LegacyXcodeDataModelSchema(
|
||||
UnsafeDataModelSchema(
|
||||
modelName: modelVersion,
|
||||
model: model
|
||||
)
|
||||
|
||||
@@ -33,12 +33,6 @@ import Foundation
|
||||
*/
|
||||
public final class DefaultLogger: CoreStoreLogger {
|
||||
|
||||
/**
|
||||
When `true`, all `NSManagedObject` attribute and relationship access will raise an assertion when executed on the wrong transaction/datastack queue. Defaults to `false`.
|
||||
*/
|
||||
// TODO: test before release (rolled back)
|
||||
// public var enableObjectConcurrencyDebugging: Bool = false
|
||||
|
||||
/**
|
||||
Creates a `DefaultLogger`.
|
||||
*/
|
||||
|
||||
199
Sources/DynamicKeyPath.swift
Normal file
199
Sources/DynamicKeyPath.swift
Normal file
@@ -0,0 +1,199 @@
|
||||
//
|
||||
// DynamicKeyPath.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright © 2017 John Rommel Estropia
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
|
||||
// MARK: - AnyDynamicKeyPath
|
||||
|
||||
public protocol AnyDynamicKeyPath {
|
||||
|
||||
/**
|
||||
The keyPath string
|
||||
*/
|
||||
var cs_keyPathString: String { get }
|
||||
}
|
||||
|
||||
|
||||
// MARK: - DynamicKeyPath
|
||||
|
||||
/**
|
||||
Used only for utility methods.
|
||||
*/
|
||||
public protocol DynamicKeyPath: AnyDynamicKeyPath {
|
||||
|
||||
/**
|
||||
The DynamicObject type
|
||||
*/
|
||||
associatedtype ObjectType
|
||||
|
||||
/**
|
||||
The Value type
|
||||
*/
|
||||
associatedtype ValueType
|
||||
}
|
||||
|
||||
|
||||
// MARK: - KeyPathString
|
||||
|
||||
public extension KeyPathString {
|
||||
|
||||
/**
|
||||
Extracts the keyPath string from the property.
|
||||
```
|
||||
let keyPath = String(keyPath: \Person.nickname)
|
||||
```
|
||||
*/
|
||||
public init<O: NSManagedObject, V>(keyPath: KeyPath<O, V>) {
|
||||
|
||||
self = keyPath.cs_keyPathString
|
||||
}
|
||||
|
||||
/**
|
||||
Extracts the keyPath string from the property.
|
||||
```
|
||||
let keyPath = String(keyPath: \Person.nickname)
|
||||
```
|
||||
*/
|
||||
public init<O: CoreStoreObject, K: DynamicKeyPath>(keyPath: KeyPath<O, K>) {
|
||||
|
||||
self = O.meta[keyPath: keyPath].cs_keyPathString
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - KeyPath: DynamicKeyPath
|
||||
|
||||
// TODO: SE-0143 is not implemented: https://github.com/apple/swift-evolution/blob/master/proposals/0143-conditional-conformances.md
|
||||
//extension KeyPath: DynamicKeyPath where Root: NSManagedObject, Value: ImportableAttributeType {
|
||||
extension KeyPath: DynamicKeyPath {
|
||||
|
||||
public typealias ObjectType = Root
|
||||
public typealias ValueType = Value
|
||||
|
||||
public var cs_keyPathString: String {
|
||||
|
||||
return self._kvcKeyPathString!
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - ValueContainer.Required: DynamicKeyPath
|
||||
|
||||
extension ValueContainer.Required: DynamicKeyPath {
|
||||
|
||||
public typealias ObjectType = O
|
||||
public typealias ValueType = V
|
||||
|
||||
public var cs_keyPathString: String {
|
||||
|
||||
return self.keyPath
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - ValueContainer.Optional: DynamicKeyPath
|
||||
|
||||
extension ValueContainer.Optional: DynamicKeyPath {
|
||||
|
||||
public typealias ObjectType = O
|
||||
public typealias ValueType = V
|
||||
|
||||
public var cs_keyPathString: String {
|
||||
|
||||
return self.keyPath
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - TransformableContainer.Required: DynamicKeyPath
|
||||
|
||||
extension TransformableContainer.Required: DynamicKeyPath {
|
||||
|
||||
public typealias ObjectType = O
|
||||
public typealias ValueType = V
|
||||
|
||||
public var cs_keyPathString: String {
|
||||
|
||||
return self.keyPath
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - TransformableContainer.Optional: DynamicKeyPath
|
||||
|
||||
extension TransformableContainer.Optional: DynamicKeyPath {
|
||||
|
||||
public typealias ObjectType = O
|
||||
public typealias ValueType = V
|
||||
|
||||
public var cs_keyPathString: String {
|
||||
|
||||
return self.keyPath
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - RelationshipContainer.ToOne: DynamicKeyPath
|
||||
|
||||
extension RelationshipContainer.ToOne: DynamicKeyPath {
|
||||
|
||||
public typealias ObjectType = O
|
||||
public typealias ValueType = D
|
||||
|
||||
public var cs_keyPathString: String {
|
||||
|
||||
return self.keyPath
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - RelationshipContainer.ToManyOrdered: DynamicKeyPath
|
||||
|
||||
extension RelationshipContainer.ToManyOrdered: DynamicKeyPath {
|
||||
|
||||
public typealias ObjectType = O
|
||||
public typealias ValueType = D
|
||||
|
||||
public var cs_keyPathString: String {
|
||||
|
||||
return self.keyPath
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - RelationshipContainer.ToManyUnordered: DynamicKeyPath
|
||||
|
||||
extension RelationshipContainer.ToManyUnordered: DynamicKeyPath {
|
||||
|
||||
public typealias ObjectType = O
|
||||
public typealias ValueType = D
|
||||
|
||||
public var cs_keyPathString: String {
|
||||
|
||||
return self.keyPath
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,6 +48,11 @@ public protocol DynamicObject: class {
|
||||
*/
|
||||
static func cs_matches(object: NSManagedObject) -> Bool
|
||||
|
||||
/**
|
||||
Used internally by CoreStore. Do not call directly.
|
||||
*/
|
||||
func cs_id() -> NSManagedObjectID
|
||||
|
||||
/**
|
||||
Used internally by CoreStore. Do not call directly.
|
||||
*/
|
||||
@@ -73,12 +78,7 @@ extension NSManagedObject: DynamicObject {
|
||||
|
||||
public class func cs_fromRaw(object: NSManagedObject) -> Self {
|
||||
|
||||
@inline(__always)
|
||||
func forceCast<T: NSManagedObject>(_ value: Any) -> T {
|
||||
|
||||
return value as! T
|
||||
}
|
||||
return forceCast(object)
|
||||
return unsafeDowncast(object, to: self)
|
||||
}
|
||||
|
||||
public static func cs_matches(object: NSManagedObject) -> Bool {
|
||||
@@ -86,6 +86,11 @@ extension NSManagedObject: DynamicObject {
|
||||
return object.isKind(of: self)
|
||||
}
|
||||
|
||||
public func cs_id() -> NSManagedObjectID {
|
||||
|
||||
return self.objectID
|
||||
}
|
||||
|
||||
public func cs_toRaw() -> NSManagedObject {
|
||||
|
||||
return self
|
||||
@@ -114,14 +119,13 @@ extension CoreStoreObject {
|
||||
|
||||
if let coreStoreObject = object.coreStoreObject {
|
||||
|
||||
@inline(__always)
|
||||
func forceCast<T: CoreStoreObject>(_ value: CoreStoreObject) -> T {
|
||||
|
||||
return value as! T
|
||||
}
|
||||
return forceCast(coreStoreObject)
|
||||
return unsafeDowncast(coreStoreObject, to: self)
|
||||
}
|
||||
let coreStoreObject = self.init(rawObject: object)
|
||||
func forceTypeCast<T: CoreStoreObject>(_ type: AnyClass, to: T.Type) -> T.Type {
|
||||
|
||||
return type as! T.Type
|
||||
}
|
||||
let coreStoreObject = forceTypeCast(object.entity.dynamicObjectType!, to: self).init(rawObject: object)
|
||||
object.coreStoreObject = coreStoreObject
|
||||
return coreStoreObject
|
||||
}
|
||||
@@ -135,19 +139,13 @@ extension CoreStoreObject {
|
||||
return (self as AnyClass).isSubclass(of: type as AnyClass)
|
||||
}
|
||||
|
||||
public func cs_id() -> NSManagedObjectID {
|
||||
|
||||
return self.rawObject!.objectID
|
||||
}
|
||||
|
||||
public func cs_toRaw() -> NSManagedObject {
|
||||
|
||||
return self.rawObject!
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: - Internal
|
||||
|
||||
internal extension DynamicObject where Self: CoreStoreObject {
|
||||
|
||||
internal static var meta: Self {
|
||||
|
||||
return self.init(asMeta: ())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,12 @@ import Foundation
|
||||
|
||||
public extension DynamicSchema {
|
||||
|
||||
/**
|
||||
Prints the `DynamicSchema` as their corresponding `CoreStoreObject` Swift declarations. This is useful for converting current `XcodeDataModelSchema`-based models into the new `CoreStoreSchema` framework. Additional adjustments may need to be done to the generated source code; for example: `Transformable` concrete types need to be provided, as well as `default` values.
|
||||
|
||||
- Important: After transitioning to the new `CoreStoreSchema` framework, it is recommended to add the new schema as a new version that the existing versions' `XcodeDataModelSchema` can migrate to. It is discouraged to load existing SQLite files created with `XcodeDataModelSchema` directly into a `CoreStoreSchema`.
|
||||
- returns: a string that represents the source code for the `DynamicSchema` as their corresponding `CoreStoreObject` Swift declarations.
|
||||
*/
|
||||
public func printCoreStoreSchema() -> String {
|
||||
|
||||
let model = self.rawModel()
|
||||
@@ -90,72 +96,62 @@ public extension DynamicSchema {
|
||||
|
||||
case .integer16AttributeType:
|
||||
valueType = Int16.self
|
||||
if let defaultValue = (attribute.defaultValue as! Int16.ImportableNativeType?).flatMap(Int16.cs_fromImportableNativeType),
|
||||
defaultValue != Int16.cs_emptyValue() {
|
||||
if let defaultValue = (attribute.defaultValue as! Int16.QueryableNativeType?).flatMap(Int16.cs_fromQueryableNativeType) {
|
||||
|
||||
defaultString = ", default: \(defaultValue)"
|
||||
defaultString = ", initial: \(defaultValue)"
|
||||
}
|
||||
case .integer32AttributeType:
|
||||
valueType = Int32.self
|
||||
if let defaultValue = (attribute.defaultValue as! Int32.ImportableNativeType?).flatMap(Int32.cs_fromImportableNativeType),
|
||||
defaultValue != Int32.cs_emptyValue() {
|
||||
if let defaultValue = (attribute.defaultValue as! Int32.QueryableNativeType?).flatMap(Int32.cs_fromQueryableNativeType) {
|
||||
|
||||
defaultString = ", default: \(defaultValue)"
|
||||
defaultString = ", initial: \(defaultValue)"
|
||||
}
|
||||
case .integer64AttributeType:
|
||||
valueType = Int64.self
|
||||
if let defaultValue = (attribute.defaultValue as! Int64.ImportableNativeType?).flatMap(Int64.cs_fromImportableNativeType),
|
||||
defaultValue != Int64.cs_emptyValue() {
|
||||
if let defaultValue = (attribute.defaultValue as! Int64.QueryableNativeType?).flatMap(Int64.cs_fromQueryableNativeType) {
|
||||
|
||||
defaultString = ", default: \(defaultValue)"
|
||||
defaultString = ", initial: \(defaultValue)"
|
||||
}
|
||||
case .decimalAttributeType:
|
||||
valueType = NSDecimalNumber.self
|
||||
if let defaultValue = (attribute.defaultValue as! NSDecimalNumber.ImportableNativeType?).flatMap(NSDecimalNumber.cs_fromImportableNativeType),
|
||||
defaultValue != NSDecimalNumber.cs_emptyValue() {
|
||||
if let defaultValue = (attribute.defaultValue as! NSDecimalNumber?) {
|
||||
|
||||
defaultString = ", default: NSDecimalNumber(string: \"\(defaultValue.description(withLocale: nil))\")"
|
||||
defaultString = ", initial: NSDecimalNumber(string: \"\(defaultValue.description(withLocale: nil))\")"
|
||||
}
|
||||
case .doubleAttributeType:
|
||||
valueType = Double.self
|
||||
if let defaultValue = (attribute.defaultValue as! Double.ImportableNativeType?).flatMap(Double.cs_fromImportableNativeType),
|
||||
defaultValue != Double.cs_emptyValue() {
|
||||
if let defaultValue = (attribute.defaultValue as! Double.QueryableNativeType?).flatMap(Double.cs_fromQueryableNativeType) {
|
||||
|
||||
defaultString = ", default: \(defaultValue)"
|
||||
defaultString = ", initial: \(defaultValue)"
|
||||
}
|
||||
case .floatAttributeType:
|
||||
valueType = Float.self
|
||||
if let defaultValue = (attribute.defaultValue as! Float.ImportableNativeType?).flatMap(Float.cs_fromImportableNativeType),
|
||||
defaultValue != Float.cs_emptyValue() {
|
||||
if let defaultValue = (attribute.defaultValue as! Float.QueryableNativeType?).flatMap(Float.cs_fromQueryableNativeType) {
|
||||
|
||||
defaultString = ", default: \(defaultValue)"
|
||||
defaultString = ", initial: \(defaultValue)"
|
||||
}
|
||||
case .stringAttributeType:
|
||||
valueType = String.self
|
||||
if let defaultValue = (attribute.defaultValue as! String.ImportableNativeType?).flatMap(String.cs_fromImportableNativeType),
|
||||
defaultValue != String.cs_emptyValue() {
|
||||
if let defaultValue = (attribute.defaultValue as! String.QueryableNativeType?).flatMap(String.cs_fromQueryableNativeType) {
|
||||
|
||||
// TODO: escape strings
|
||||
defaultString = ", default: \"\(defaultValue)\""
|
||||
defaultString = ", initial: \"\(defaultValue)\""
|
||||
}
|
||||
case .booleanAttributeType:
|
||||
valueType = Bool.self
|
||||
if let defaultValue = (attribute.defaultValue as! Bool.ImportableNativeType?).flatMap(Bool.cs_fromImportableNativeType),
|
||||
defaultValue != Bool.cs_emptyValue() {
|
||||
if let defaultValue = (attribute.defaultValue as! Bool.QueryableNativeType?).flatMap(Bool.cs_fromQueryableNativeType) {
|
||||
|
||||
defaultString = ", default: \(defaultValue ? "true" : "false")"
|
||||
defaultString = ", initial: \(defaultValue ? "true" : "false")"
|
||||
}
|
||||
case .dateAttributeType:
|
||||
valueType = Date.self
|
||||
if let defaultValue = (attribute.defaultValue as! Date.ImportableNativeType?).flatMap(Date.cs_fromImportableNativeType),
|
||||
defaultValue != Date.cs_emptyValue() {
|
||||
if let defaultValue = (attribute.defaultValue as! Date.QueryableNativeType?).flatMap(Date.cs_fromQueryableNativeType) {
|
||||
|
||||
defaultString = ", default: Date(timeIntervalSinceReferenceDate: \(defaultValue.timeIntervalSinceReferenceDate))"
|
||||
defaultString = ", initial: Date(timeIntervalSinceReferenceDate: \(defaultValue.timeIntervalSinceReferenceDate))"
|
||||
}
|
||||
case .binaryDataAttributeType:
|
||||
valueType = Data.self
|
||||
if let defaultValue = (attribute.defaultValue as! Data.ImportableNativeType?).flatMap(Data.cs_fromImportableNativeType),
|
||||
defaultValue != Data.cs_emptyValue() {
|
||||
if let defaultValue = (attribute.defaultValue as! Data.QueryableNativeType?).flatMap(Data.cs_fromQueryableNativeType) {
|
||||
|
||||
let count = defaultValue.count
|
||||
let bytes = defaultValue.withUnsafeBytes { (pointer: UnsafePointer<UInt8>) in
|
||||
@@ -163,7 +159,7 @@ public extension DynamicSchema {
|
||||
return (0 ..< (count / MemoryLayout<UInt8>.size))
|
||||
.map({ "\("0x\(String(pointer[$0], radix: 16, uppercase: false))")" })
|
||||
}
|
||||
defaultString = ", default: Data(bytes: [\(bytes.joined(separator: ", "))])"
|
||||
defaultString = ", initial: Data(bytes: [\(bytes.joined(separator: ", "))])"
|
||||
}
|
||||
case .transformableAttributeType:
|
||||
if let attributeValueClassName = attribute.attributeValueClassName {
|
||||
@@ -176,22 +172,23 @@ public extension DynamicSchema {
|
||||
}
|
||||
if let defaultValue = attribute.defaultValue {
|
||||
|
||||
defaultString = ", default: /* \"\(defaultValue)\" */"
|
||||
defaultString = ", initial: /* \"\(defaultValue)\" */"
|
||||
}
|
||||
else if !attribute.isOptional {
|
||||
|
||||
defaultString = ", default: /* required */"
|
||||
defaultString = ", initial: /* required */"
|
||||
}
|
||||
default:
|
||||
fatalError("Unsupported attribute type: \(attribute.attributeType.rawValue)")
|
||||
}
|
||||
let indexedString = attribute.isIndexed ? ", isIndexed: true" : ""
|
||||
let transientString = attribute.isTransient ? ", isTransient: true" : ""
|
||||
// TODO: escape strings
|
||||
let versionHashModifierString = attribute.versionHashModifier.flatMap({ ", versionHashModifier: \"\($0)\"" }) ?? ""
|
||||
let versionHashModifierString = attribute.versionHashModifier
|
||||
.flatMap({ ", versionHashModifier: \"\($0)\"" }) ?? ""
|
||||
// TODO: escape strings
|
||||
let renamingIdentifierString = attribute.renamingIdentifier.flatMap({ ", renamingIdentifier: \"\($0)\"" }) ?? ""
|
||||
output.append(" let \(attributeName) = \(containerType)<\(String(describing: valueType))>(\"\(attributeName)\"\(indexedString)\(defaultString)\(transientString)\(versionHashModifierString)\(renamingIdentifierString))\n")
|
||||
let renamingIdentifierString = attribute.renamingIdentifier
|
||||
.flatMap({ ($0 == attributeName ? "" : ", renamingIdentifier: \"\($0)\"") as String }) ?? ""
|
||||
output.append(" let \(attributeName) = \(containerType)<\(String(describing: valueType))>(\"\(attributeName)\"\(defaultString)\(transientString)\(versionHashModifierString)\(renamingIdentifierString))\n")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -255,8 +252,10 @@ public extension DynamicSchema {
|
||||
fatalError("Unsupported delete rule \((relationship.deleteRule)) for relationship \"\(relationshipQualifier)\"")
|
||||
}
|
||||
}
|
||||
let versionHashModifierString = relationship.versionHashModifier.flatMap({ ", versionHashModifier: \"\($0)\"" }) ?? ""
|
||||
let renamingIdentifierString = relationship.renamingIdentifier.flatMap({ ", renamingIdentifier: \"\($0)\"" }) ?? ""
|
||||
let versionHashModifierString = relationship.versionHashModifier
|
||||
.flatMap({ ", versionHashModifier: \"\($0)\"" }) ?? ""
|
||||
let renamingIdentifierString = relationship.renamingIdentifier
|
||||
.flatMap({ ($0 == relationshipName ? "" : ", renamingIdentifier: \"\($0)\"") as String }) ?? ""
|
||||
output.append(" let \(relationshipName) = \(containerType)<\(relationship.destinationEntity!.name!)>(\"\(relationshipName)\"\(inverseString)\(deleteRuleString)\(minCountString)\(maxCountString)\(versionHashModifierString)\(renamingIdentifierString))\n")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ import Foundation
|
||||
/**
|
||||
`DynamicSchema` are types that provide `NSManagedObjectModel` instances for a single model version. CoreStore currently supports the following concrete types:
|
||||
- `XcodeDataModelSchema`: describes models loaded from a .xcdatamodeld file.
|
||||
- `LegacyXcodeDataModelSchema`: describes models loaded directly from an existing `NSManagedObjectModel`. It is not advisable to continue using this model as its metadata are not available to CoreStore.
|
||||
- `UnsafeDataModelSchema`: describes models loaded directly from an existing `NSManagedObjectModel`. It is not advisable to continue using this model as its metadata are not available to CoreStore.
|
||||
- `CoreStoreSchema`: describes models written for `CoreStoreObject` Swift class declarations.
|
||||
*/
|
||||
public protocol DynamicSchema {
|
||||
|
||||
@@ -34,13 +34,13 @@ import ObjectiveC
|
||||
The `Entity<O>` contains `NSEntityDescription` metadata for `CoreStoreObject` subclasses. Pass the `Entity` instances to `CoreStoreSchema` initializer.
|
||||
```
|
||||
class Animal: CoreStoreObject {
|
||||
let species = Value.Required<String>("species")
|
||||
let species = Value.Required<String>("species", initial: "")
|
||||
let nickname = Value.Optional<String>("nickname")
|
||||
let master = Relationship.ToOne<Person>("master")
|
||||
}
|
||||
|
||||
class Person: CoreStoreObject {
|
||||
let name = Value.Required<String>("name")
|
||||
let name = Value.Required<String>("name", initial: "")
|
||||
let pet = Relationship.ToOne<Animal>("pet", inverse: { $0.master })
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ import ObjectiveC
|
||||
- SeeAlso: CoreStoreSchema
|
||||
- SeeAlso: CoreStoreObject
|
||||
*/
|
||||
public final class Entity<O: DynamicObject>: DynamicEntity {
|
||||
public final class Entity<O: CoreStoreObject>: DynamicEntity {
|
||||
|
||||
/**
|
||||
Initializes an `Entity`. Always provide a concrete generic type to `Entity`.
|
||||
@@ -66,11 +66,20 @@ public final class Entity<O: DynamicObject>: DynamicEntity {
|
||||
```
|
||||
- parameter entityName: the `NSEntityDescription` name to use for the entity
|
||||
- parameter isAbstract: set to `true` if the entity is meant to be an abstract class and can only be initialized with subclass types.
|
||||
- parameter versionHashModifier: The version hash modifier for the entity. Used to mark or denote an entity as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where, for example, the structure of an entity is unchanged but the format or content of data has changed.)
|
||||
- parameter versionHashModifier: the version hash modifier for the entity. Used to mark or denote an entity as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where, for example, the structure of an entity is unchanged but the format or content of data has changed.)
|
||||
- parameter indexes: the compound indexes for the entity as an array of arrays. The arrays contained in the returned array contain `KeyPath`s to properties of the entity.
|
||||
- parameter uniqueConstraints: sets uniqueness constraints for the entity. A uniqueness constraint is a set of one or more `KeyPath`s whose value must be unique over the set of instances of that entity. This value forms part of the entity's version hash. Uniqueness constraint violations can be computationally expensive to handle. It is highly suggested that there be only one uniqueness constraint per entity hierarchy. Uniqueness constraints must be defined at the highest level possible, and CoreStore will raise an assertion failure if unique constraints are added to a sub entity.
|
||||
*/
|
||||
public convenience init(_ entityName: String, isAbstract: Bool = false, versionHashModifier: String? = nil) {
|
||||
public convenience init(_ entityName: String, isAbstract: Bool = false, versionHashModifier: String? = nil, indexes: [[PartialKeyPath<O>]] = [], uniqueConstraints: [[PartialKeyPath<O>]] = []) {
|
||||
|
||||
self.init(O.self, entityName, isAbstract: isAbstract, versionHashModifier: versionHashModifier)
|
||||
self.init(
|
||||
O.self,
|
||||
entityName,
|
||||
isAbstract: isAbstract,
|
||||
versionHashModifier: versionHashModifier,
|
||||
indexes: indexes,
|
||||
uniqueConstraints: uniqueConstraints
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -81,11 +90,28 @@ public final class Entity<O: DynamicObject>: DynamicEntity {
|
||||
- parameter type: the `DynamicObject` type associated with the entity
|
||||
- parameter entityName: the `NSEntityDescription` name to use for the entity
|
||||
- parameter isAbstract: set to `true` if the entity is meant to be an abstract class and can only be initialized with subclass types.
|
||||
- parameter versionHashModifier: The version hash modifier for the entity. Used to mark or denote an entity as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where, for example, the structure of an entity is unchanged but the format or content of data has changed.)
|
||||
- parameter versionHashModifier: the version hash modifier for the entity. Used to mark or denote an entity as being a different "version" than another even if all of the values which affect persistence are equal. (Such a difference is important in cases where, for example, the structure of an entity is unchanged but the format or content of data has changed.)
|
||||
- parameter indexes: the compound indexes for the entity as an array of arrays. The arrays contained in the returned array contain KeyPath's to properties of the entity.
|
||||
- parameter uniqueConstraints: sets uniqueness constraints for the entity. A uniqueness constraint is a set of one or more `KeyPath`s whose value must be unique over the set of instances of that entity. This value forms part of the entity's version hash. Uniqueness constraint violations can be computationally expensive to handle. It is highly suggested that there be only one uniqueness constraint per entity hierarchy. Uniqueness constraints must be defined at the highest level possible, and CoreStore will raise an assertion failure if unique constraints are added to a sub entity.
|
||||
*/
|
||||
public init(_ type: O.Type, _ entityName: String, isAbstract: Bool = false, versionHashModifier: String? = nil) {
|
||||
public init(_ type: O.Type, _ entityName: String, isAbstract: Bool = false, versionHashModifier: String? = nil, indexes: [[PartialKeyPath<O>]] = [], uniqueConstraints: [[PartialKeyPath<O>]] = []) {
|
||||
|
||||
super.init(type: type, entityName: entityName, isAbstract: isAbstract, versionHashModifier: versionHashModifier)
|
||||
let meta = O.meta
|
||||
let toStringArray: ([PartialKeyPath<O>]) -> [KeyPathString] = {
|
||||
|
||||
return $0.map {
|
||||
|
||||
return (meta[keyPath: $0] as! AnyDynamicKeyPath).cs_keyPathString
|
||||
}
|
||||
}
|
||||
super.init(
|
||||
type: type,
|
||||
entityName: entityName,
|
||||
isAbstract: isAbstract,
|
||||
versionHashModifier: versionHashModifier,
|
||||
indexes: indexes.map(toStringArray),
|
||||
uniqueConstraints: uniqueConstraints.map(toStringArray)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,6 +143,16 @@ public /*abstract*/ class DynamicEntity: Hashable {
|
||||
*/
|
||||
public let versionHashModifier: String?
|
||||
|
||||
/**
|
||||
Do not use directly.
|
||||
*/
|
||||
public let indexes: [[KeyPathString]]
|
||||
|
||||
/**
|
||||
Do not use directly.
|
||||
*/
|
||||
public let uniqueConstraints: [[KeyPathString]]
|
||||
|
||||
|
||||
// MARK: Equatable
|
||||
|
||||
@@ -126,6 +162,8 @@ public /*abstract*/ class DynamicEntity: Hashable {
|
||||
&& lhs.entityName == rhs.entityName
|
||||
&& lhs.isAbstract == rhs.isAbstract
|
||||
&& lhs.versionHashModifier == rhs.versionHashModifier
|
||||
&& lhs.indexes == rhs.indexes
|
||||
&& lhs.uniqueConstraints == rhs.uniqueConstraints
|
||||
}
|
||||
|
||||
// MARK: Hashable
|
||||
@@ -136,16 +174,20 @@ public /*abstract*/ class DynamicEntity: Hashable {
|
||||
^ self.entityName.hashValue
|
||||
^ self.isAbstract.hashValue
|
||||
^ (self.versionHashModifier ?? "").hashValue
|
||||
// ^ self.indexes.hashValue
|
||||
// ^ self.uniqueConstraints.hashValue
|
||||
}
|
||||
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
internal init(type: DynamicObject.Type, entityName: String, isAbstract: Bool = false, versionHashModifier: String?) {
|
||||
internal init(type: DynamicObject.Type, entityName: String, isAbstract: Bool, versionHashModifier: String?, indexes: [[KeyPathString]], uniqueConstraints: [[KeyPathString]]) {
|
||||
|
||||
self.type = type
|
||||
self.entityName = entityName
|
||||
self.isAbstract = isAbstract
|
||||
self.versionHashModifier = versionHashModifier
|
||||
self.indexes = indexes
|
||||
self.uniqueConstraints = uniqueConstraints
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ internal struct EntityIdentifier: Hashable {
|
||||
internal init(_ type: CoreStoreObject.Type) {
|
||||
|
||||
self.category = .coreStore
|
||||
self.interfacedClassName = String(reflecting: type)
|
||||
self.interfacedClassName = NSStringFromClass(type)
|
||||
}
|
||||
|
||||
internal init(_ type: DynamicObject.Type) {
|
||||
|
||||
74
Sources/FetchChainBuilder.swift
Normal file
74
Sources/FetchChainBuilder.swift
Normal file
@@ -0,0 +1,74 @@
|
||||
//
|
||||
// FetchChainBuilder.swift
|
||||
// CoreStore
|
||||
//
|
||||
// Copyright © 2017 John Rommel Estropia
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import CoreData
|
||||
|
||||
|
||||
// MARK: - FetchChainBuilder
|
||||
|
||||
/**
|
||||
The fetch builder type used for fetches. A `FetchChainBuilder` is created from a `From` clause.
|
||||
```
|
||||
let people = source.fetchAll(
|
||||
From<MyPersonEntity>()
|
||||
.where(\.age > 18)
|
||||
.orderBy(.ascending(\.age))
|
||||
)
|
||||
```
|
||||
*/
|
||||
public struct FetchChainBuilder<D: DynamicObject>: FetchChainableBuilderType {
|
||||
|
||||
// MARK: FetchChainableBuilderType
|
||||
|
||||
public typealias ObjectType = D
|
||||
|
||||
public var from: From<D>
|
||||
public var fetchClauses: [FetchClause] = []
|
||||
}
|
||||
|
||||
|
||||
// MARK: - FetchChainableBuilderType
|
||||
|
||||
/**
|
||||
Utility protocol for `FetchChainBuilder`. Used in fetch methods that support chained fetch builders.
|
||||
*/
|
||||
public protocol FetchChainableBuilderType {
|
||||
|
||||
/**
|
||||
The `DynamicObject` type for the fetch
|
||||
*/
|
||||
associatedtype ObjectType: DynamicObject
|
||||
|
||||
/**
|
||||
The `From` clause specifies the source entity and source persistent store for the fetch
|
||||
*/
|
||||
var from: From<ObjectType> { get set }
|
||||
|
||||
/**
|
||||
The `FetchClause`s to be used for the fetch
|
||||
*/
|
||||
var fetchClauses: [FetchClause] { get set }
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user