mirror of
https://github.com/JohnEstropia/CoreStore.git
synced 2026-11-13 12:23:32 +01:00
Migrations demo done
This commit is contained in:
1 parent
11f5cb9a05
commit
2f93ee7591
29 files changed
+1399
-61
No files matched your search
@@ -11,10 +11,20 @@
|
||||
B531EFE924EB5A53005F247D /* ⭐️Modern.PokedexDemo.PokedexEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = B531EFE824EB5A52005F247D /* ⭐️Modern.PokedexDemo.PokedexEntry.swift */; };
|
||||
B531EFEB24EB5ECD005F247D /* ⭐️Modern.PokedexDemo.Service.swift in Sources */ = {isa = PBXBuildFile; fileRef = B531EFEA24EB5ECD005F247D /* ⭐️Modern.PokedexDemo.Service.swift */; };
|
||||
B531EFED24EB7453005F247D /* Modern.PokedexDemo.MainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B531EFEC24EB7453005F247D /* Modern.PokedexDemo.MainView.swift */; };
|
||||
B54D2F7A25119540004BEC7D /* Advanced.EvolutionDemo.V2.FromV1.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = B54D2F7925119540004BEC7D /* Advanced.EvolutionDemo.V2.FromV1.xcmappingmodel */; };
|
||||
B54D2F7C251196B6004BEC7D /* Advanced.EvolutionDemo.V2.FromV1MigrationPolicy.swift in Sources */ = {isa = PBXBuildFile; fileRef = B54D2F7B251196B6004BEC7D /* Advanced.EvolutionDemo.V2.FromV1MigrationPolicy.swift */; };
|
||||
B54D2F7E25119DCE004BEC7D /* Advanced.EvolutionDemo.V1.FromV2.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = B54D2F7D25119DCE004BEC7D /* Advanced.EvolutionDemo.V1.FromV2.xcmappingmodel */; };
|
||||
B54D2F852511B70B004BEC7D /* Advanced.EvolutionDemo.CreaturesDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = B54D2F842511B70B004BEC7D /* Advanced.EvolutionDemo.CreaturesDataSource.swift */; };
|
||||
B566C8E824F9D406001134A1 /* Modern.PokedexDemo.ListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B566C8E724F9D406001134A1 /* Modern.PokedexDemo.ListView.swift */; };
|
||||
B566C8EA24F9D412001134A1 /* Modern.PokedexDemo.ListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B566C8E924F9D412001134A1 /* Modern.PokedexDemo.ListViewController.swift */; };
|
||||
B566C8EC24F9D694001134A1 /* Modern.PokedexDemo.ItemCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = B566C8EB24F9D694001134A1 /* Modern.PokedexDemo.ItemCell.swift */; };
|
||||
B566C8EE24FA1EA3001134A1 /* Modern.PokedexDemo.Details.swift in Sources */ = {isa = PBXBuildFile; fileRef = B566C8ED24FA1EA3001134A1 /* Modern.PokedexDemo.Details.swift */; };
|
||||
B5931B4225124756007DA58E /* Advanced.EvolutionDemo.V1.FromV2.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5931B4125124756007DA58E /* Advanced.EvolutionDemo.V1.FromV2.swift */; };
|
||||
B5931B442512480A007DA58E /* Advanced.EvolutionDemo.V2.FromV1.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5931B432512480A007DA58E /* Advanced.EvolutionDemo.V2.FromV1.swift */; };
|
||||
B5931B46251248B0007DA58E /* Advanced.EvolutionDemo.V3.FromV2.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5931B45251248B0007DA58E /* Advanced.EvolutionDemo.V3.FromV2.swift */; };
|
||||
B5931B4825124940007DA58E /* Advanced.EvolutionDemo.V4.FromV3.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5931B4725124940007DA58E /* Advanced.EvolutionDemo.V4.FromV3.swift */; };
|
||||
B5931B4A25124993007DA58E /* Advanced.EvolutionDemo.V3.FromV4.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5931B4925124993007DA58E /* Advanced.EvolutionDemo.V3.FromV4.swift */; };
|
||||
B5931B4C251249EE007DA58E /* Advanced.EvolutionDemo.V2.FromV3.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5931B4B251249EE007DA58E /* Advanced.EvolutionDemo.V2.FromV3.swift */; };
|
||||
B5A3911D24E5429200E7E8BD /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A3911C24E5429200E7E8BD /* AppDelegate.swift */; };
|
||||
B5A3911F24E5429200E7E8BD /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A3911E24E5429200E7E8BD /* SceneDelegate.swift */; };
|
||||
B5A3912124E5429200E7E8BD /* Menu.MainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A3912024E5429200E7E8BD /* Menu.MainView.swift */; };
|
||||
@@ -86,6 +96,7 @@
|
||||
B5A5440925049489000DC5E3 /* Advanced.EvolutionDemo.V2.Creature.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A5440825049489000DC5E3 /* Advanced.EvolutionDemo.V2.Creature.swift */; };
|
||||
B5A5440B25049492000DC5E3 /* Advanced.EvolutionDemo.V3.Creature.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A5440A25049492000DC5E3 /* Advanced.EvolutionDemo.V3.Creature.swift */; };
|
||||
B5A5440D2504949C000DC5E3 /* Advanced.EvolutionDemo.V4.Creature.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5A5440C2504949C000DC5E3 /* Advanced.EvolutionDemo.V4.Creature.swift */; };
|
||||
B5C18F3325138700001BEFB3 /* Advanced.EvolutionDemo.ProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5C18F3225138700001BEFB3 /* Advanced.EvolutionDemo.ProgressView.swift */; };
|
||||
B5D6F1F8250E07FD00DF5D2F /* Advanced.EvolutionDemo.V1.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D6F1F7250E07FD00DF5D2F /* Advanced.EvolutionDemo.V1.swift */; };
|
||||
B5D6F1FC250E0B1700DF5D2F /* Advanced.EvolutionDemo.V2.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D6F1FB250E0B1700DF5D2F /* Advanced.EvolutionDemo.V2.swift */; };
|
||||
B5D6F1FE250E0B3F00DF5D2F /* Advanced.EvolutionDemo.GeologicalPeriod.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5D6F1FD250E0B3F00DF5D2F /* Advanced.EvolutionDemo.GeologicalPeriod.swift */; };
|
||||
@@ -118,10 +129,20 @@
|
||||
B531EFE824EB5A52005F247D /* ⭐️Modern.PokedexDemo.PokedexEntry.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "⭐️Modern.PokedexDemo.PokedexEntry.swift"; sourceTree = "<group>"; };
|
||||
B531EFEA24EB5ECD005F247D /* ⭐️Modern.PokedexDemo.Service.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "⭐️Modern.PokedexDemo.Service.swift"; sourceTree = "<group>"; };
|
||||
B531EFEC24EB7453005F247D /* Modern.PokedexDemo.MainView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Modern.PokedexDemo.MainView.swift; sourceTree = "<group>"; };
|
||||
B54D2F7925119540004BEC7D /* Advanced.EvolutionDemo.V2.FromV1.xcmappingmodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcmappingmodel; path = Advanced.EvolutionDemo.V2.FromV1.xcmappingmodel; sourceTree = "<group>"; };
|
||||
B54D2F7B251196B6004BEC7D /* Advanced.EvolutionDemo.V2.FromV1MigrationPolicy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Advanced.EvolutionDemo.V2.FromV1MigrationPolicy.swift; sourceTree = "<group>"; };
|
||||
B54D2F7D25119DCE004BEC7D /* Advanced.EvolutionDemo.V1.FromV2.xcmappingmodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcmappingmodel; path = Advanced.EvolutionDemo.V1.FromV2.xcmappingmodel; sourceTree = "<group>"; };
|
||||
B54D2F842511B70B004BEC7D /* Advanced.EvolutionDemo.CreaturesDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Advanced.EvolutionDemo.CreaturesDataSource.swift; sourceTree = "<group>"; };
|
||||
B566C8E724F9D406001134A1 /* Modern.PokedexDemo.ListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Modern.PokedexDemo.ListView.swift; sourceTree = "<group>"; };
|
||||
B566C8E924F9D412001134A1 /* Modern.PokedexDemo.ListViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Modern.PokedexDemo.ListViewController.swift; sourceTree = "<group>"; };
|
||||
B566C8EB24F9D694001134A1 /* Modern.PokedexDemo.ItemCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Modern.PokedexDemo.ItemCell.swift; sourceTree = "<group>"; };
|
||||
B566C8ED24FA1EA3001134A1 /* Modern.PokedexDemo.Details.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Modern.PokedexDemo.Details.swift; sourceTree = "<group>"; };
|
||||
B5931B4125124756007DA58E /* Advanced.EvolutionDemo.V1.FromV2.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Advanced.EvolutionDemo.V1.FromV2.swift; sourceTree = "<group>"; };
|
||||
B5931B432512480A007DA58E /* Advanced.EvolutionDemo.V2.FromV1.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Advanced.EvolutionDemo.V2.FromV1.swift; sourceTree = "<group>"; };
|
||||
B5931B45251248B0007DA58E /* Advanced.EvolutionDemo.V3.FromV2.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Advanced.EvolutionDemo.V3.FromV2.swift; sourceTree = "<group>"; };
|
||||
B5931B4725124940007DA58E /* Advanced.EvolutionDemo.V4.FromV3.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Advanced.EvolutionDemo.V4.FromV3.swift; sourceTree = "<group>"; };
|
||||
B5931B4925124993007DA58E /* Advanced.EvolutionDemo.V3.FromV4.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Advanced.EvolutionDemo.V3.FromV4.swift; sourceTree = "<group>"; };
|
||||
B5931B4B251249EE007DA58E /* Advanced.EvolutionDemo.V2.FromV3.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Advanced.EvolutionDemo.V2.FromV3.swift; sourceTree = "<group>"; };
|
||||
B5A3911924E5429200E7E8BD /* Demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Demo.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
B5A3911C24E5429200E7E8BD /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||
B5A3911E24E5429200E7E8BD /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
|
||||
@@ -192,6 +213,7 @@
|
||||
B5A5440825049489000DC5E3 /* Advanced.EvolutionDemo.V2.Creature.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Advanced.EvolutionDemo.V2.Creature.swift; sourceTree = "<group>"; };
|
||||
B5A5440A25049492000DC5E3 /* Advanced.EvolutionDemo.V3.Creature.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Advanced.EvolutionDemo.V3.Creature.swift; sourceTree = "<group>"; };
|
||||
B5A5440C2504949C000DC5E3 /* Advanced.EvolutionDemo.V4.Creature.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Advanced.EvolutionDemo.V4.Creature.swift; sourceTree = "<group>"; };
|
||||
B5C18F3225138700001BEFB3 /* Advanced.EvolutionDemo.ProgressView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Advanced.EvolutionDemo.ProgressView.swift; sourceTree = "<group>"; };
|
||||
B5D6F1F7250E07FD00DF5D2F /* Advanced.EvolutionDemo.V1.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Advanced.EvolutionDemo.V1.swift; sourceTree = "<group>"; };
|
||||
B5D6F1FB250E0B1700DF5D2F /* Advanced.EvolutionDemo.V2.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Advanced.EvolutionDemo.V2.swift; sourceTree = "<group>"; };
|
||||
B5D6F1FD250E0B3F00DF5D2F /* Advanced.EvolutionDemo.GeologicalPeriod.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Advanced.EvolutionDemo.GeologicalPeriod.swift; sourceTree = "<group>"; };
|
||||
@@ -516,6 +538,8 @@
|
||||
B5A54400250487C7000DC5E3 /* Advanced.EvolutionDemo.ListView.swift */,
|
||||
B5A54402250487D4000DC5E3 /* Advanced.EvolutionDemo.ItemView.swift */,
|
||||
B5D6F208250E14AA00DF5D2F /* Advanced.EvolutionDemo.Migrator.swift */,
|
||||
B5C18F3225138700001BEFB3 /* Advanced.EvolutionDemo.ProgressView.swift */,
|
||||
B54D2F842511B70B004BEC7D /* Advanced.EvolutionDemo.CreaturesDataSource.swift */,
|
||||
B5A543FD25048794000DC5E3 /* Models */,
|
||||
);
|
||||
path = EvolutionDemo;
|
||||
@@ -554,6 +578,8 @@
|
||||
children = (
|
||||
B5D6F1F7250E07FD00DF5D2F /* Advanced.EvolutionDemo.V1.swift */,
|
||||
B5A5440625049480000DC5E3 /* Advanced.EvolutionDemo.V1.Creature.swift */,
|
||||
B5931B4125124756007DA58E /* Advanced.EvolutionDemo.V1.FromV2.swift */,
|
||||
B54D2F7D25119DCE004BEC7D /* Advanced.EvolutionDemo.V1.FromV2.xcmappingmodel */,
|
||||
);
|
||||
name = V1;
|
||||
sourceTree = "<group>";
|
||||
@@ -563,6 +589,10 @@
|
||||
children = (
|
||||
B5D6F1FB250E0B1700DF5D2F /* Advanced.EvolutionDemo.V2.swift */,
|
||||
B5A5440825049489000DC5E3 /* Advanced.EvolutionDemo.V2.Creature.swift */,
|
||||
B5931B432512480A007DA58E /* Advanced.EvolutionDemo.V2.FromV1.swift */,
|
||||
B54D2F7925119540004BEC7D /* Advanced.EvolutionDemo.V2.FromV1.xcmappingmodel */,
|
||||
B54D2F7B251196B6004BEC7D /* Advanced.EvolutionDemo.V2.FromV1MigrationPolicy.swift */,
|
||||
B5931B4B251249EE007DA58E /* Advanced.EvolutionDemo.V2.FromV3.swift */,
|
||||
);
|
||||
name = V2;
|
||||
sourceTree = "<group>";
|
||||
@@ -572,6 +602,8 @@
|
||||
children = (
|
||||
B5D6F204250E0DD600DF5D2F /* Advanced.EvolutionDemo.V3.swift */,
|
||||
B5A5440A25049492000DC5E3 /* Advanced.EvolutionDemo.V3.Creature.swift */,
|
||||
B5931B45251248B0007DA58E /* Advanced.EvolutionDemo.V3.FromV2.swift */,
|
||||
B5931B4925124993007DA58E /* Advanced.EvolutionDemo.V3.FromV4.swift */,
|
||||
);
|
||||
name = V3;
|
||||
sourceTree = "<group>";
|
||||
@@ -581,6 +613,7 @@
|
||||
children = (
|
||||
B5D6F206250E0E3B00DF5D2F /* Advanced.EvolutionDemo.V4.swift */,
|
||||
B5A5440C2504949C000DC5E3 /* Advanced.EvolutionDemo.V4.Creature.swift */,
|
||||
B5931B4725124940007DA58E /* Advanced.EvolutionDemo.V4.FromV3.swift */,
|
||||
);
|
||||
name = V4;
|
||||
sourceTree = "<group>";
|
||||
@@ -675,26 +708,26 @@
|
||||
B5A391B124E96AF600E7E8BD /* Modern.PokedexDemo.swift in Sources */,
|
||||
B5A3918324E7A21800E7E8BD /* Modern.TimeZonesDemo.swift in Sources */,
|
||||
B5A3915E24E6922E00E7E8BD /* ⭐️Modern.PlacemarksDemo.swift in Sources */,
|
||||
B5D6F207250E0E3B00DF5D2F /* Advanced.EvolutionDemo.V4.swift in Sources */,
|
||||
B5A54405250487F5000DC5E3 /* Advanced.EvolutionDemo.CreatureType.swift in Sources */,
|
||||
B5A5440725049480000DC5E3 /* Advanced.EvolutionDemo.V1.Creature.swift in Sources */,
|
||||
B54D2F852511B70B004BEC7D /* Advanced.EvolutionDemo.CreaturesDataSource.swift in Sources */,
|
||||
B5D6F1FE250E0B3F00DF5D2F /* Advanced.EvolutionDemo.GeologicalPeriod.swift in Sources */,
|
||||
B5A5440925049489000DC5E3 /* Advanced.EvolutionDemo.V2.Creature.swift in Sources */,
|
||||
B5A5440B25049492000DC5E3 /* Advanced.EvolutionDemo.V3.Creature.swift in Sources */,
|
||||
B5A5440D2504949C000DC5E3 /* Advanced.EvolutionDemo.V4.Creature.swift in Sources */,
|
||||
B5A54403250487D5000DC5E3 /* Advanced.EvolutionDemo.ItemView.swift in Sources */,
|
||||
B5D6F1F8250E07FD00DF5D2F /* Advanced.EvolutionDemo.V1.swift in Sources */,
|
||||
B5A54401250487C7000DC5E3 /* Advanced.EvolutionDemo.ListView.swift in Sources */,
|
||||
B5A543FF250487B1000DC5E3 /* Advanced.EvolutionDemo.MainView.swift in Sources */,
|
||||
B5D6F209250E14AA00DF5D2F /* Advanced.EvolutionDemo.Migrator.swift in Sources */,
|
||||
B5C18F3325138700001BEFB3 /* Advanced.EvolutionDemo.ProgressView.swift in Sources */,
|
||||
B5D6F1F8250E07FD00DF5D2F /* Advanced.EvolutionDemo.V1.swift in Sources */,
|
||||
B5D6F210250E1E3200DF5D2F /* Advanced.EvolutionDemo.V1.xcdatamodeld in Sources */,
|
||||
B5D6F1FC250E0B1700DF5D2F /* Advanced.EvolutionDemo.V2.swift in Sources */,
|
||||
B5D6F205250E0DD600DF5D2F /* Advanced.EvolutionDemo.V3.swift in Sources */,
|
||||
B5D6F207250E0E3B00DF5D2F /* Advanced.EvolutionDemo.V4.swift in Sources */,
|
||||
B5A543E924FB84A1000DC5E3 /* Classic.ColorsDemo.DetailView.swift in Sources */,
|
||||
B5A543E724FB82BB000DC5E3 /* Classic.ColorsDemo.Filter.swift in Sources */,
|
||||
B5A543F324FB84EC000DC5E3 /* Classic.ColorsDemo.ItemCell.swift in Sources */,
|
||||
B5D6F209250E14AA00DF5D2F /* Advanced.EvolutionDemo.Migrator.swift in Sources */,
|
||||
B5A543EF24FB84D1000DC5E3 /* Classic.ColorsDemo.LIstView.swift in Sources */,
|
||||
B5A543ED24FB84BE000DC5E3 /* Classic.ColorsDemo.MainView.swift in Sources */,
|
||||
B5A543DD24FB78F9000DC5E3 /* Classic.ColorsDemo.Palette.swift in Sources */,
|
||||
B5A3919824E7E67000E7E8BD /* Modern.ColorsDemo.Filter.swift in Sources */,
|
||||
B5D6F1FC250E0B1700DF5D2F /* Advanced.EvolutionDemo.V2.swift in Sources */,
|
||||
B5A3919224E7E0C600E7E8BD /* Modern.ColorsDemo.Palette.swift in Sources */,
|
||||
B5A3919E24E8EEB600E7E8BD /* Modern.ColorsDemo.SwiftUI.swift in Sources */,
|
||||
B5A391A024E8F00A00E7E8BD /* Modern.ColorsDemo.UIKit.swift in Sources */,
|
||||
@@ -703,7 +736,6 @@
|
||||
B5A3916524E698C700E7E8BD /* Modern.PlacemarksDemo.Place.swift in Sources */,
|
||||
B566C8EE24FA1EA3001134A1 /* Modern.PokedexDemo.Details.swift in Sources */,
|
||||
B566C8EC24F9D694001134A1 /* Modern.PokedexDemo.ItemCell.swift in Sources */,
|
||||
B5D6F210250E1E3200DF5D2F /* Advanced.EvolutionDemo.V1.xcdatamodeld in Sources */,
|
||||
B566C8E824F9D406001134A1 /* Modern.PokedexDemo.ListView.swift in Sources */,
|
||||
B566C8EA24F9D412001134A1 /* Modern.PokedexDemo.ListViewController.swift in Sources */,
|
||||
B531EFED24EB7453005F247D /* Modern.PokedexDemo.MainView.swift in Sources */,
|
||||
@@ -712,7 +744,6 @@
|
||||
B5A3918624E7A54A00E7E8BD /* Modern.TimeZonesDemo.TimeZone.swift in Sources */,
|
||||
B5A543EB24FB84AF000DC5E3 /* ⭐️Classic.ColorsDemo.DetailViewController.swift in Sources */,
|
||||
B5A543F124FB84DD000DC5E3 /* ⭐️Classic.ColorsDemo.ListViewController.swift in Sources */,
|
||||
B5D6F205250E0DD600DF5D2F /* Advanced.EvolutionDemo.V3.swift in Sources */,
|
||||
B5A391A624E8F4EA00E7E8BD /* ⭐️Modern.ColorsDemo.MainView.swift in Sources */,
|
||||
B5A3916224E697BA00E7E8BD /* ⭐️Modern.PlacemarksDemo.MainView.swift in Sources */,
|
||||
B5A391B424E96C0A00E7E8BD /* ⭐️Modern.PokedexDemo.Form.swift in Sources */,
|
||||
@@ -721,6 +752,19 @@
|
||||
B531EFEB24EB5ECD005F247D /* ⭐️Modern.PokedexDemo.Service.swift in Sources */,
|
||||
B5A391B924E96F8500E7E8BD /* ⭐️Modern.PokedexDemo.Species.swift in Sources */,
|
||||
B5A3918824E7A8F900E7E8BD /* ⭐️Modern.TimeZonesDemo.MainView.swift in Sources */,
|
||||
B5A5440725049480000DC5E3 /* Advanced.EvolutionDemo.V1.Creature.swift in Sources */,
|
||||
B5931B4225124756007DA58E /* Advanced.EvolutionDemo.V1.FromV2.swift in Sources */,
|
||||
B54D2F7E25119DCE004BEC7D /* Advanced.EvolutionDemo.V1.FromV2.xcmappingmodel in Sources */,
|
||||
B5A5440925049489000DC5E3 /* Advanced.EvolutionDemo.V2.Creature.swift in Sources */,
|
||||
B5931B442512480A007DA58E /* Advanced.EvolutionDemo.V2.FromV1.swift in Sources */,
|
||||
B54D2F7A25119540004BEC7D /* Advanced.EvolutionDemo.V2.FromV1.xcmappingmodel in Sources */,
|
||||
B54D2F7C251196B6004BEC7D /* Advanced.EvolutionDemo.V2.FromV1MigrationPolicy.swift in Sources */,
|
||||
B5931B4C251249EE007DA58E /* Advanced.EvolutionDemo.V2.FromV3.swift in Sources */,
|
||||
B5A5440B25049492000DC5E3 /* Advanced.EvolutionDemo.V3.Creature.swift in Sources */,
|
||||
B5931B46251248B0007DA58E /* Advanced.EvolutionDemo.V3.FromV2.swift in Sources */,
|
||||
B5931B4A25124993007DA58E /* Advanced.EvolutionDemo.V3.FromV4.swift in Sources */,
|
||||
B5A5440D2504949C000DC5E3 /* Advanced.EvolutionDemo.V4.Creature.swift in Sources */,
|
||||
B5931B4825124940007DA58E /* Advanced.EvolutionDemo.V4.FromV3.swift in Sources */,
|
||||
B5A391AC24E9143B00E7E8BD /* Modern.ColorsDemo.UIKit.DetailView.swift in Sources */,
|
||||
B5A391AA24E9104300E7E8BD /* Modern.ColorsDemo.UIKit.ItemCell.swift in Sources */,
|
||||
B5A391A424E8F04300E7E8BD /* Modern.ColorsDemo.UIKit.ListView.swift in Sources */,
|
||||
@@ -749,12 +793,14 @@
|
||||
B5A3911324E5424E00E7E8BD /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
B5A3911424E5424E00E7E8BD /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 10.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
|
||||
@@ -96,9 +96,10 @@ extension Menu {
|
||||
Menu.ItemView(
|
||||
title: "Evolution",
|
||||
subtitle: "Migrating and reverse-migrating stores",
|
||||
destination: { EmptyView() }
|
||||
destination: {
|
||||
Advanced.EvolutionDemo.MainView()
|
||||
}
|
||||
)
|
||||
.disabled(true)
|
||||
Menu.ItemView(
|
||||
title: "Logger",
|
||||
subtitle: "Implementing a custom logger",
|
||||
|
||||
+7
-1
@@ -18,7 +18,13 @@ extension Advanced.EvolutionDemo {
|
||||
|
||||
protocol Advanced_EvolutionDemo_CreatureType: DynamicObject, CustomStringConvertible {
|
||||
|
||||
var dnaCode: Int64 { get }
|
||||
var dnaCode: Int64 { get set }
|
||||
|
||||
static func dataSource(in dataStack: DataStack) -> Advanced.EvolutionDemo.CreaturesDataSource
|
||||
|
||||
static func count(in transaction: BaseDataTransaction) throws -> Int
|
||||
|
||||
static func create(in transaction: BaseDataTransaction) -> Self
|
||||
|
||||
func mutate(in transaction: BaseDataTransaction)
|
||||
}
|
||||
+165
@@ -0,0 +1,165 @@
|
||||
//
|
||||
// Demo
|
||||
// Copyright © 2020 John Rommel Estropia, Inc. All rights reserved.
|
||||
|
||||
import CoreStore
|
||||
import Combine
|
||||
|
||||
|
||||
// MARK: - Advanced.EvolutionDemo
|
||||
|
||||
extension Advanced.EvolutionDemo {
|
||||
|
||||
// MARK: - Advanced.EvolutionDemo.CreaturesDataSource
|
||||
|
||||
final class CreaturesDataSource: ObservableObject {
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
init<T: NSManagedObject & Advanced.EvolutionDemo.CreatureType>(
|
||||
listPublisher: ListPublisher<T>,
|
||||
dataStack: DataStack
|
||||
) {
|
||||
|
||||
self.numberOfItems = {
|
||||
listPublisher.snapshot.numberOfItems
|
||||
}
|
||||
self.itemDescriptionAtIndex = { index in
|
||||
listPublisher.snapshot[index].object?.description
|
||||
}
|
||||
self.addItems = { count in
|
||||
|
||||
dataStack.perform(
|
||||
asynchronous: { transaction in
|
||||
|
||||
let nextDNACode = try transaction.fetchCount(From<T>())
|
||||
for offset in 0 ..< count {
|
||||
|
||||
let object = transaction.create(Into<T>())
|
||||
object.dnaCode = .init(nextDNACode + offset)
|
||||
object.mutate(in: transaction)
|
||||
}
|
||||
},
|
||||
completion: { _ in }
|
||||
)
|
||||
}
|
||||
self.mutateItemAtIndex = { index in
|
||||
|
||||
let object = listPublisher.snapshot[index]
|
||||
dataStack.perform(
|
||||
asynchronous: { transaction in
|
||||
|
||||
object
|
||||
.asEditable(in: transaction)?
|
||||
.mutate(in: transaction)
|
||||
},
|
||||
completion: { _ in }
|
||||
)
|
||||
}
|
||||
self.deleteAllItems = {
|
||||
|
||||
dataStack.perform(
|
||||
asynchronous: { transaction in
|
||||
|
||||
try transaction.deleteAll(From<T>())
|
||||
},
|
||||
completion: { _ in }
|
||||
)
|
||||
}
|
||||
listPublisher.addObserver(self) { [weak self] (listPublisher) in
|
||||
|
||||
self?.objectWillChange.send()
|
||||
}
|
||||
}
|
||||
|
||||
init<T: CoreStoreObject & Advanced.EvolutionDemo.CreatureType>(
|
||||
listPublisher: ListPublisher<T>,
|
||||
dataStack: DataStack
|
||||
) {
|
||||
|
||||
self.numberOfItems = {
|
||||
listPublisher.snapshot.numberOfItems
|
||||
}
|
||||
self.itemDescriptionAtIndex = { index in
|
||||
listPublisher.snapshot[index].object?.description
|
||||
}
|
||||
self.addItems = { count in
|
||||
|
||||
dataStack.perform(
|
||||
asynchronous: { transaction in
|
||||
|
||||
let nextDNACode = try transaction.fetchCount(From<T>())
|
||||
for offset in 0 ..< count {
|
||||
|
||||
let object = transaction.create(Into<T>())
|
||||
object.dnaCode = .init(nextDNACode + offset)
|
||||
object.mutate(in: transaction)
|
||||
}
|
||||
},
|
||||
completion: { _ in }
|
||||
)
|
||||
}
|
||||
self.mutateItemAtIndex = { index in
|
||||
|
||||
let object = listPublisher.snapshot[index]
|
||||
dataStack.perform(
|
||||
asynchronous: { transaction in
|
||||
|
||||
object
|
||||
.asEditable(in: transaction)?
|
||||
.mutate(in: transaction)
|
||||
},
|
||||
completion: { _ in }
|
||||
)
|
||||
}
|
||||
self.deleteAllItems = {
|
||||
|
||||
dataStack.perform(
|
||||
asynchronous: { transaction in
|
||||
|
||||
try transaction.deleteAll(From<T>())
|
||||
},
|
||||
completion: { _ in }
|
||||
)
|
||||
}
|
||||
listPublisher.addObserver(self) { [weak self] (listPublisher) in
|
||||
|
||||
self?.objectWillChange.send()
|
||||
}
|
||||
}
|
||||
|
||||
func numberOfCreatures() -> Int {
|
||||
|
||||
return self.numberOfItems()
|
||||
}
|
||||
|
||||
func creatureDescription(at index: Int) -> String? {
|
||||
|
||||
return self.itemDescriptionAtIndex(index)
|
||||
}
|
||||
|
||||
func mutate(at index: Int) {
|
||||
|
||||
self.mutateItemAtIndex(index)
|
||||
}
|
||||
|
||||
func add(count: Int) {
|
||||
|
||||
self.addItems(count)
|
||||
}
|
||||
|
||||
func clear() {
|
||||
|
||||
self.deleteAllItems()
|
||||
}
|
||||
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private let numberOfItems: () -> Int
|
||||
private let itemDescriptionAtIndex: (Int) -> String?
|
||||
private let mutateItemAtIndex: (Int) -> Void
|
||||
private let addItems: (Int) -> Void
|
||||
private let deleteAllItems: () -> Void
|
||||
}
|
||||
}
|
||||
+65
-1
@@ -2,13 +2,17 @@
|
||||
// Demo
|
||||
// Copyright © 2020 John Rommel Estropia, Inc. All rights reserved.
|
||||
|
||||
import CoreStore
|
||||
|
||||
|
||||
// MARK: - AdvancedEvolutionDemo
|
||||
|
||||
extension Advanced.EvolutionDemo {
|
||||
|
||||
// MARK: - GeologicalPeriod
|
||||
|
||||
enum GeologicalPeriod: CaseIterable {
|
||||
enum GeologicalPeriod: RawRepresentable, CaseIterable, Hashable, CustomStringConvertible {
|
||||
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
@@ -17,6 +21,11 @@ extension Advanced.EvolutionDemo {
|
||||
case ageOfReptiles
|
||||
case ageOfMammals
|
||||
|
||||
var version: ModelVersion {
|
||||
|
||||
return self.rawValue
|
||||
}
|
||||
|
||||
var creatureType: Advanced.EvolutionDemo.CreatureType.Type {
|
||||
|
||||
switch self {
|
||||
@@ -31,5 +40,60 @@ extension Advanced.EvolutionDemo {
|
||||
return Advanced.EvolutionDemo.V4.Creature.self
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: CustomStringConvertible
|
||||
|
||||
var description: String {
|
||||
|
||||
switch self {
|
||||
|
||||
case .ageOfInvertebrates:
|
||||
return "Invertebrates"
|
||||
case .ageOfFishes:
|
||||
return "Fishes"
|
||||
case .ageOfReptiles:
|
||||
return "Reptiles"
|
||||
case .ageOfMammals:
|
||||
return "Mammals"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MARK: RawRepresentable
|
||||
|
||||
typealias RawValue = ModelVersion
|
||||
|
||||
var rawValue: ModelVersion {
|
||||
|
||||
switch self {
|
||||
|
||||
case .ageOfInvertebrates:
|
||||
return Advanced.EvolutionDemo.V1.name
|
||||
case .ageOfFishes:
|
||||
return Advanced.EvolutionDemo.V2.name
|
||||
case .ageOfReptiles:
|
||||
return Advanced.EvolutionDemo.V3.name
|
||||
case .ageOfMammals:
|
||||
return Advanced.EvolutionDemo.V4.name
|
||||
}
|
||||
}
|
||||
|
||||
init?(rawValue: ModelVersion) {
|
||||
|
||||
switch rawValue {
|
||||
|
||||
case Advanced.EvolutionDemo.V1.name:
|
||||
self = .ageOfInvertebrates
|
||||
case Advanced.EvolutionDemo.V2.name:
|
||||
self = .ageOfFishes
|
||||
case Advanced.EvolutionDemo.V3.name:
|
||||
self = .ageOfReptiles
|
||||
case Advanced.EvolutionDemo.V4.name:
|
||||
self = .ageOfMammals
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+71
-1
@@ -2,4 +2,74 @@
|
||||
// Demo
|
||||
// Copyright © 2020 John Rommel Estropia, Inc. All rights reserved.
|
||||
|
||||
import Foundation
|
||||
import SwiftUI
|
||||
|
||||
// MARK: - Advanced.EvolutionDemo
|
||||
|
||||
extension Advanced.EvolutionDemo {
|
||||
|
||||
// MARK: - Advanced.EvolutionDemo.ItemView
|
||||
|
||||
struct ItemView: View {
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
init(description: String?, mutate: @escaping () -> Void) {
|
||||
|
||||
self.description = description
|
||||
self.mutate = mutate
|
||||
}
|
||||
|
||||
|
||||
// MARK: View
|
||||
|
||||
var body: some View {
|
||||
HStack {
|
||||
Text(self.description ?? "")
|
||||
.font(.footnote)
|
||||
.foregroundColor(.primary)
|
||||
Spacer()
|
||||
Button(
|
||||
action: self.mutate,
|
||||
label: {
|
||||
Text("Mutate")
|
||||
.foregroundColor(.accentColor)
|
||||
.fontWeight(.bold)
|
||||
}
|
||||
)
|
||||
.buttonStyle(PlainButtonStyle())
|
||||
}
|
||||
.disabled(self.description == nil)
|
||||
}
|
||||
|
||||
|
||||
// MARK: FilePrivate
|
||||
|
||||
fileprivate let description: String?
|
||||
fileprivate let mutate: () -> Void
|
||||
}
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
|
||||
struct _Demo_Advanced_EvolutionDemo_ItemView_Preview: PreviewProvider {
|
||||
|
||||
// MARK: PreviewProvider
|
||||
|
||||
static var previews: some View {
|
||||
Advanced.EvolutionDemo.ItemView(
|
||||
description: """
|
||||
dnaCode: 123
|
||||
numberOfLimbs: 4
|
||||
hasVertebrae: true
|
||||
hasHead: true
|
||||
hasTail: true
|
||||
habitat: land
|
||||
hasWings: false
|
||||
""",
|
||||
mutate: {}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
+95
-1
@@ -2,4 +2,98 @@
|
||||
// Demo
|
||||
// Copyright © 2020 John Rommel Estropia, Inc. All rights reserved.
|
||||
|
||||
import Foundation
|
||||
import CoreStore
|
||||
import SwiftUI
|
||||
|
||||
// MARK: - Advanced.EvolutionDemo
|
||||
|
||||
extension Advanced.EvolutionDemo {
|
||||
|
||||
// MARK: - Advanced.EvolutionDemo.ListView
|
||||
|
||||
struct ListView: View {
|
||||
|
||||
// MARK: View
|
||||
|
||||
var body: some View {
|
||||
let dataSource = self.dataSource
|
||||
return List {
|
||||
ForEach(0 ..< dataSource.numberOfCreatures(), id: \.self) { (index) in
|
||||
Advanced.EvolutionDemo.ItemView(
|
||||
description: dataSource.creatureDescription(at: index),
|
||||
mutate: {
|
||||
|
||||
dataSource.mutate(at: index)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
.listStyle(PlainListStyle())
|
||||
}
|
||||
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
init(
|
||||
period: Advanced.EvolutionDemo.GeologicalPeriod,
|
||||
dataStack: DataStack,
|
||||
dataSource: Advanced.EvolutionDemo.CreaturesDataSource
|
||||
) {
|
||||
|
||||
self.period = period
|
||||
self.dataStack = dataStack
|
||||
self.dataSource = dataSource
|
||||
}
|
||||
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private let period: Advanced.EvolutionDemo.GeologicalPeriod
|
||||
|
||||
private let dataStack: DataStack
|
||||
|
||||
@ObservedObject
|
||||
private var dataSource: Advanced.EvolutionDemo.CreaturesDataSource
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if DEBUG
|
||||
|
||||
struct _Demo_Advanced_EvolutionDemo_ListView_Preview: PreviewProvider {
|
||||
|
||||
// MARK: PreviewProvider
|
||||
|
||||
static var previews: some View {
|
||||
|
||||
let dataStack = DataStack(
|
||||
CoreStoreSchema(
|
||||
modelVersion: Advanced.EvolutionDemo.V4.name,
|
||||
entities: [
|
||||
Entity<Advanced.EvolutionDemo.V4.Creature>("Creature")
|
||||
]
|
||||
)
|
||||
)
|
||||
try! dataStack.addStorageAndWait(
|
||||
SQLiteStore(fileName: "Advanced.EvolutionDemo.ListView.Preview.sqlite")
|
||||
)
|
||||
try! dataStack.perform(
|
||||
synchronous: { transaction in
|
||||
|
||||
for dnaCode in 0 ..< 10 as Range<Int64> {
|
||||
|
||||
let object = transaction.create(Into<Advanced.EvolutionDemo.V4.Creature>())
|
||||
object.dnaCode = dnaCode
|
||||
object.mutate(in: transaction)
|
||||
}
|
||||
}
|
||||
)
|
||||
return Advanced.EvolutionDemo.ListView(
|
||||
period: .ageOfMammals,
|
||||
dataStack: dataStack,
|
||||
dataSource: Advanced.EvolutionDemo.V4.Creature.dataSource(in: dataStack)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
+74
-1
@@ -2,4 +2,77 @@
|
||||
// Demo
|
||||
// Copyright © 2020 John Rommel Estropia, Inc. All rights reserved.
|
||||
|
||||
import Foundation
|
||||
import CoreStore
|
||||
import SwiftUI
|
||||
|
||||
// MARK: - Advanced.EvolutionDemo
|
||||
|
||||
extension Advanced.EvolutionDemo {
|
||||
|
||||
// MARK: - Advanced.EvolutionDemo.MainView
|
||||
|
||||
struct MainView: View {
|
||||
|
||||
// MARK: View
|
||||
|
||||
var body: some View {
|
||||
let migrator = self.migrator
|
||||
let listView: AnyView
|
||||
if let current = migrator.current {
|
||||
|
||||
listView = AnyView(
|
||||
Advanced.EvolutionDemo.ListView(
|
||||
period: current.period,
|
||||
dataStack: current.dataStack,
|
||||
dataSource: current.dataSource
|
||||
)
|
||||
)
|
||||
}
|
||||
else {
|
||||
|
||||
listView = AnyView(
|
||||
Advanced.EvolutionDemo.ProgressView(progress: migrator.progress)
|
||||
)
|
||||
}
|
||||
|
||||
return VStack(spacing: 0) {
|
||||
HStack(alignment: .center, spacing: 0) {
|
||||
Text("Age of")
|
||||
.padding(.trailing)
|
||||
Picker(selection: self.$migrator.currentPeriod, label: EmptyView()) {
|
||||
ForEach(Advanced.EvolutionDemo.GeologicalPeriod.allCases, id: \.self) { period in
|
||||
Text(period.description).tag(period)
|
||||
}
|
||||
}
|
||||
.pickerStyle(SegmentedPickerStyle())
|
||||
}
|
||||
.padding()
|
||||
listView
|
||||
.edgesIgnoringSafeArea(.vertical)
|
||||
}
|
||||
.navigationBarTitle("Evolution")
|
||||
.disabled(migrator.isBusy || migrator.current == nil)
|
||||
}
|
||||
|
||||
|
||||
// MARK: Private
|
||||
|
||||
@ObservedObject
|
||||
private var migrator: Advanced.EvolutionDemo.Migrator = .init()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if DEBUG
|
||||
|
||||
struct _Demo_Advanced_EvolutionDemo_MainView_Preview: PreviewProvider {
|
||||
|
||||
// MARK: PreviewProvider
|
||||
|
||||
static var previews: some View {
|
||||
|
||||
Advanced.EvolutionDemo.MainView()
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
+191
-35
@@ -14,34 +14,20 @@ extension Advanced.EvolutionDemo {
|
||||
// MARK: - Advanced.EvolutionDemo.Migrator
|
||||
|
||||
final class Migrator: ObservableObject {
|
||||
|
||||
var currentPeriod: Advanced.EvolutionDemo.GeologicalPeriod? {
|
||||
|
||||
return self.current?.period
|
||||
}
|
||||
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private var current: (period: Advanced.EvolutionDemo.GeologicalPeriod, dataStack: DataStack)? {
|
||||
|
||||
willSet {
|
||||
|
||||
self.objectWillChange.send()
|
||||
}
|
||||
}
|
||||
|
||||
private func findAndSetCurrentVersion() {
|
||||
|
||||
|
||||
/**
|
||||
⭐️ Sample 1: Creating a complex `DataStack` that contains all schema histories. The `exactCurrentModelVersion` will specify the target version (if required), and `migrationChain` will provide the upgrade/downgrade progressive migration path.
|
||||
*/
|
||||
private func createDataStack(
|
||||
exactCurrentModelVersion: ModelVersion?,
|
||||
migrationChain: MigrationChain
|
||||
) -> DataStack {
|
||||
|
||||
let xcodeV1ToV2ModelSchema = XcodeDataModelSchema.from(
|
||||
modelName: "Advanced.EvolutionDemo.V1",
|
||||
bundle: Bundle(for: Advanced.EvolutionDemo.V1.Creature.self),
|
||||
migrationChain: [
|
||||
Advanced.EvolutionDemo.V1.name,
|
||||
Advanced.EvolutionDemo.V2.name
|
||||
]
|
||||
bundle: Bundle(for: Advanced.EvolutionDemo.V1.Creature.self)
|
||||
)
|
||||
let dataStack = DataStack(
|
||||
return DataStack(
|
||||
schemaHistory: SchemaHistory(
|
||||
allSchema: xcodeV1ToV2ModelSchema.allSchema
|
||||
+ [
|
||||
@@ -58,26 +44,196 @@ extension Advanced.EvolutionDemo {
|
||||
]
|
||||
)
|
||||
],
|
||||
migrationChain: [
|
||||
Advanced.EvolutionDemo.V1.name,
|
||||
Advanced.EvolutionDemo.V2.name,
|
||||
Advanced.EvolutionDemo.V3.name,
|
||||
Advanced.EvolutionDemo.V4.name
|
||||
]
|
||||
migrationChain: migrationChain,
|
||||
exactCurrentModelVersion: exactCurrentModelVersion
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
⭐️ Sample 2: Creating a complex `SQLiteStore` that contains all schema mappings for both upgrade and downgrade cases.
|
||||
*/
|
||||
private func accessSQLiteStore() -> SQLiteStore {
|
||||
|
||||
let upgradeMappings: [SchemaMappingProvider] = [
|
||||
Advanced.EvolutionDemo.V2.FromV1.mapping,
|
||||
Advanced.EvolutionDemo.V3.FromV2.mapping,
|
||||
Advanced.EvolutionDemo.V4.FromV3.mapping
|
||||
]
|
||||
let downgradeMappings: [SchemaMappingProvider] = [
|
||||
Advanced.EvolutionDemo.V3.FromV4.mapping,
|
||||
Advanced.EvolutionDemo.V2.FromV3.mapping,
|
||||
Advanced.EvolutionDemo.V1.FromV2.mapping,
|
||||
]
|
||||
return SQLiteStore(
|
||||
fileName: "Advanced.EvolutionDemo.sqlite",
|
||||
configuration: nil,
|
||||
migrationMappingProviders: upgradeMappings + downgradeMappings,
|
||||
localStorageOptions: []
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
var currentPeriod: Advanced.EvolutionDemo.GeologicalPeriod = Advanced.EvolutionDemo.GeologicalPeriod.allCases.last! {
|
||||
|
||||
didSet {
|
||||
|
||||
self.selectModelVersion(self.currentPeriod)
|
||||
}
|
||||
}
|
||||
|
||||
private(set) var current: (
|
||||
period: Advanced.EvolutionDemo.GeologicalPeriod,
|
||||
dataStack: DataStack,
|
||||
dataSource: Advanced.EvolutionDemo.CreaturesDataSource
|
||||
)? {
|
||||
|
||||
willSet {
|
||||
|
||||
self.objectWillChange.send()
|
||||
}
|
||||
}
|
||||
|
||||
private(set) var isBusy: Bool = false
|
||||
|
||||
private(set) var progress: Progress?
|
||||
|
||||
|
||||
init() {
|
||||
|
||||
self.synchronizeCurrentVersion()
|
||||
}
|
||||
|
||||
private func selectModelVersion(_ period: GeologicalPeriod) {
|
||||
|
||||
guard period != self.current?.period else {
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private func synchronizeCurrentVersion() {
|
||||
|
||||
// Since we are only interested in finding current version, we'll assume an upgrading `MigrationChain`
|
||||
let dataStack = self.createDataStack(
|
||||
exactCurrentModelVersion: nil,
|
||||
migrationChain: MigrationChain(
|
||||
Advanced.EvolutionDemo.GeologicalPeriod.allCases.map({ $0.version })
|
||||
)
|
||||
)
|
||||
let migrations = try! dataStack.requiredMigrationsForStorage(
|
||||
self.accessSQLiteStore()
|
||||
)
|
||||
if let period = migrations.first
|
||||
.flatMap({ Advanced.EvolutionDemo.GeologicalPeriod(rawValue: $0.sourceVersion) }) {
|
||||
|
||||
self.selectModelVersion(period)
|
||||
}
|
||||
else {
|
||||
|
||||
self.selectModelVersion(self.currentPeriod)
|
||||
}
|
||||
}
|
||||
|
||||
private func selectModelVersion(_ period: Advanced.EvolutionDemo.GeologicalPeriod) {
|
||||
|
||||
let currentPeriod = self.current?.period
|
||||
guard period != currentPeriod else {
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
self.objectWillChange.send()
|
||||
|
||||
self.isBusy = true
|
||||
|
||||
// explicitly trigger `NSPersistentStore` cleanup by deallocating the `DataStack`
|
||||
self.current = nil
|
||||
|
||||
|
||||
let migrationChain: MigrationChain
|
||||
switch (currentPeriod?.version, period.version) {
|
||||
|
||||
case (nil, let newVersion):
|
||||
migrationChain = [newVersion]
|
||||
|
||||
case (let currentVersion?, let newVersion):
|
||||
let upgradeMigrationChain = Advanced.EvolutionDemo.GeologicalPeriod.allCases
|
||||
.map({ $0.version })
|
||||
let currentVersionIndex = upgradeMigrationChain.firstIndex(of: currentVersion)!
|
||||
let newVersionIndex = upgradeMigrationChain.firstIndex(of: newVersion)!
|
||||
|
||||
migrationChain = MigrationChain(
|
||||
currentVersionIndex > newVersionIndex
|
||||
? upgradeMigrationChain.reversed()
|
||||
: upgradeMigrationChain
|
||||
)
|
||||
}
|
||||
let dataStack = self.createDataStack(
|
||||
exactCurrentModelVersion: period.version,
|
||||
migrationChain: migrationChain
|
||||
)
|
||||
|
||||
let completion = { [weak self] () -> Void in
|
||||
|
||||
guard let self = self else {
|
||||
|
||||
return
|
||||
}
|
||||
self.objectWillChange.send()
|
||||
defer {
|
||||
|
||||
self.isBusy = false
|
||||
}
|
||||
self.current = (
|
||||
period: period,
|
||||
dataStack: dataStack,
|
||||
dataSource: period.creatureType.dataSource(in: dataStack)
|
||||
)
|
||||
self.currentPeriod = period
|
||||
}
|
||||
|
||||
self.progress = dataStack.addStorage(
|
||||
self.accessSQLiteStore(),
|
||||
completion: { [weak self] result in
|
||||
|
||||
guard let self = self else {
|
||||
|
||||
return
|
||||
}
|
||||
guard case .success = result else {
|
||||
|
||||
self.objectWillChange.send()
|
||||
self.isBusy = false
|
||||
return
|
||||
}
|
||||
if self.progress == nil {
|
||||
|
||||
self.spawnCreatures(in: dataStack, period: period, completion: completion)
|
||||
}
|
||||
else {
|
||||
|
||||
completion()
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private func spawnCreatures(
|
||||
in dataStack: DataStack,
|
||||
period: Advanced.EvolutionDemo.GeologicalPeriod,
|
||||
completion: @escaping () -> Void
|
||||
) {
|
||||
|
||||
dataStack.perform(
|
||||
asynchronous: { (transaction) in
|
||||
|
||||
let creatureType = period.creatureType
|
||||
for dnaCode in try creatureType.count(in: transaction) ..< 10000 {
|
||||
|
||||
let object = creatureType.create(in: transaction)
|
||||
object.dnaCode = Int64(dnaCode)
|
||||
object.mutate(in: transaction)
|
||||
}
|
||||
},
|
||||
completion: { _ in completion() }
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
|
||||
+127
@@ -0,0 +1,127 @@
|
||||
//
|
||||
// Demo
|
||||
// Copyright © 2020 John Rommel Estropia, Inc. All rights reserved.
|
||||
|
||||
import SwiftUI
|
||||
|
||||
// MARK: - Advanced.EvolutionDemo
|
||||
|
||||
extension Advanced.EvolutionDemo {
|
||||
|
||||
// MARK: - Advanced.EvolutionDemo.ProgressView
|
||||
|
||||
struct ProgressView: View {
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
init(progress: Progress?) {
|
||||
|
||||
self.progressObserver = .init(progress)
|
||||
}
|
||||
|
||||
|
||||
// MARK: View
|
||||
|
||||
var body: some View {
|
||||
|
||||
guard self.progressObserver.isMigrating else {
|
||||
|
||||
return AnyView(
|
||||
VStack(alignment: .center) {
|
||||
Text("Preparing creatures...")
|
||||
.padding()
|
||||
Spacer()
|
||||
}
|
||||
.padding()
|
||||
)
|
||||
}
|
||||
return AnyView(
|
||||
VStack(alignment: .leading) {
|
||||
Text("Migrating: \(self.progressObserver.localizedDescription)")
|
||||
.font(.headline)
|
||||
.padding([.top, .horizontal])
|
||||
Text("Progressive step: \(self.progressObserver.localizedAdditionalDescription)")
|
||||
.font(.subheadline)
|
||||
.padding(.horizontal)
|
||||
GeometryReader { geometry in
|
||||
ZStack(alignment: .leading) {
|
||||
Color.gray
|
||||
.opacity(0.2)
|
||||
.frame(width: geometry.size.width, height: 8)
|
||||
.cornerRadius(4.0)
|
||||
Color.blue
|
||||
.frame(
|
||||
width: geometry.size.width
|
||||
* self.progressObserver.fractionCompleted,
|
||||
height: 8
|
||||
)
|
||||
.cornerRadius(4.0)
|
||||
}
|
||||
}
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
.padding()
|
||||
Spacer()
|
||||
}
|
||||
.padding()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
// MARK: FilePrivate
|
||||
|
||||
@ObservedObject
|
||||
private var progressObserver: ProgressObserver
|
||||
|
||||
|
||||
// MARK: - ProgressObserver
|
||||
|
||||
fileprivate final class ProgressObserver: ObservableObject {
|
||||
|
||||
private(set) var fractionCompleted: CGFloat = 0
|
||||
private(set) var localizedDescription: String = ""
|
||||
private(set) var localizedAdditionalDescription: String = ""
|
||||
|
||||
var isMigrating: Bool {
|
||||
|
||||
return self.progress != nil
|
||||
}
|
||||
|
||||
init(_ progress: Progress?) {
|
||||
|
||||
self.progress = progress
|
||||
|
||||
progress?.setProgressHandler { [weak self] (progess) in
|
||||
|
||||
guard let self = self else {
|
||||
return
|
||||
}
|
||||
self.objectWillChange.send()
|
||||
self.fractionCompleted = CGFloat(progress?.fractionCompleted ?? 0)
|
||||
self.localizedDescription = progress?.localizedDescription ?? ""
|
||||
self.localizedAdditionalDescription = progress?.localizedAdditionalDescription ?? ""
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private let progress: Progress?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
|
||||
struct _Demo_Advanced_EvolutionDemo_ProgressView_Preview: PreviewProvider {
|
||||
|
||||
// MARK: PreviewProvider
|
||||
|
||||
static var previews: some View {
|
||||
let progress = Progress(totalUnitCount: 10)
|
||||
progress.completedUnitCount = 3
|
||||
return Advanced.EvolutionDemo.ProgressView(
|
||||
progress: progress
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
+25
@@ -30,6 +30,31 @@ final class Advanced_EvolutionDemo_V1_Creature: NSManagedObject, Advanced.Evolut
|
||||
|
||||
|
||||
// MARK: Advanced.EvolutionDemo.CreatureType
|
||||
|
||||
static func dataSource(in dataStack: DataStack) -> Advanced.EvolutionDemo.CreaturesDataSource {
|
||||
|
||||
return .init(
|
||||
listPublisher: dataStack.publishList(
|
||||
From<Advanced.EvolutionDemo.V1.Creature>()
|
||||
.orderBy(.descending(\.dnaCode))
|
||||
),
|
||||
dataStack: dataStack
|
||||
)
|
||||
}
|
||||
|
||||
static func count(in transaction: BaseDataTransaction) throws -> Int {
|
||||
|
||||
return try transaction.fetchCount(
|
||||
From<Advanced.EvolutionDemo.V1.Creature>()
|
||||
)
|
||||
}
|
||||
|
||||
static func create(in transaction: BaseDataTransaction) -> Advanced.EvolutionDemo.V1.Creature {
|
||||
|
||||
return transaction.create(
|
||||
Into<Advanced.EvolutionDemo.V1.Creature>()
|
||||
)
|
||||
}
|
||||
|
||||
func mutate(in transaction: BaseDataTransaction) {
|
||||
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
//
|
||||
// Demo
|
||||
// Copyright © 2020 John Rommel Estropia, Inc. All rights reserved.
|
||||
|
||||
import CoreStore
|
||||
|
||||
|
||||
// MARK: - Advanced.EvolutionDemo.V1
|
||||
|
||||
extension Advanced.EvolutionDemo.V1 {
|
||||
|
||||
// MARK: - Advanced.EvolutionDemo.V1.FromV2
|
||||
|
||||
enum FromV2 {
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
static var mapping: XcodeSchemaMappingProvider {
|
||||
|
||||
return XcodeSchemaMappingProvider(
|
||||
from: Advanced.EvolutionDemo.V2.name,
|
||||
to: Advanced.EvolutionDemo.V1.name,
|
||||
mappingModelBundle: Bundle(for: Advanced.EvolutionDemo.V1.Creature.self)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
<?xml version="1.0" standalone="yes"?>
|
||||
<!DOCTYPE database SYSTEM "file:///System/Library/DTDs/CoreData.dtd">
|
||||
|
||||
<database>
|
||||
<databaseInfo>
|
||||
<version>134481920</version>
|
||||
<UUID>F17B8B92-EEB0-4A30-98EC-425208280CBC</UUID>
|
||||
<nextObjectID>105</nextObjectID>
|
||||
<metadata>
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>NSPersistenceFrameworkVersion</key>
|
||||
<integer>977</integer>
|
||||
<key>NSStoreModelVersionHashes</key>
|
||||
<dict>
|
||||
<key>XDDevAttributeMapping</key>
|
||||
<data>
|
||||
0plcXXRN7XHKl5CcF+fwriFmUpON3ZtcI/AfK748aWc=
|
||||
</data>
|
||||
<key>XDDevEntityMapping</key>
|
||||
<data>
|
||||
qeN1Ym3TkWN1G6dU9RfX6Kd2ccEvcDVWHpd3LpLgboI=
|
||||
</data>
|
||||
<key>XDDevMappingModel</key>
|
||||
<data>
|
||||
EqtMzvRnVZWkXwBHu4VeVGy8UyoOe+bi67KC79kphlQ=
|
||||
</data>
|
||||
<key>XDDevPropertyMapping</key>
|
||||
<data>
|
||||
XN33V44TTGY4JETlMoOB5yyTKxB+u4slvDIinv0rtGA=
|
||||
</data>
|
||||
<key>XDDevRelationshipMapping</key>
|
||||
<data>
|
||||
akYY9LhehVA/mCb4ATLWuI9XGLcjpm14wWL1oEBtIcs=
|
||||
</data>
|
||||
</dict>
|
||||
<key>NSStoreModelVersionHashesDigest</key>
|
||||
<string>+Hmc2uYZK6og+Pvx5GUJ7oW75UG4V/ksQanTjfTKUnxyGWJRMtB5tIRgVwGsrd7lz/QR57++wbvWsr6nxwyS0A==</string>
|
||||
<key>NSStoreModelVersionHashesVersion</key>
|
||||
<integer>3</integer>
|
||||
<key>NSStoreModelVersionIdentifiers</key>
|
||||
<array>
|
||||
<string></string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
</metadata>
|
||||
</databaseInfo>
|
||||
<object type="XDDEVATTRIBUTEMAPPING" id="z102">
|
||||
<attribute name="name" type="string">dnaCode</attribute>
|
||||
<relationship name="entitymapping" type="1/1" destination="XDDEVENTITYMAPPING" idrefs="z104"></relationship>
|
||||
</object>
|
||||
<object type="XDDEVATTRIBUTEMAPPING" id="z103">
|
||||
<attribute name="valueexpressiondata" type="binary">YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9iamVjdHMSAAGGoF8Q
|
||||
D05TS2V5ZWRBcmNoaXZlctEICVRyb290gAGsCwwXGB0eJiswMTQ4VSRudWxs1Q0ODxAREhMUFRZZTlNPcGVyYW5kXk5TU2VsZWN0b3JOYW1lXxAQTlNFeHByZXNzaW9uVHlwZVtOU0FyZ3VtZW50c1YkY2xhc3OAA4ACEASABoALXxAQdmFsdWVGb3JLZXlQYXRoOtMZDxEaGxxaTlNWYXJpYWJsZYAEEAKABVZzb3VyY2XSHyAhIlokY2xhc3NuYW1lWCRjbGFzc2VzXxAUTlNWYXJpYWJsZUV4cHJlc3Npb26jIyQlXxAUTlNWYXJpYWJsZUV4cHJlc3Npb25cTlNFeHByZXNzaW9uWE5TT2JqZWN00icRKCpaTlMub2JqZWN0c6EpgAeACtMRDywtLi9ZTlNLZXlQYXRogAkQCoAIXxAQbnVtYmVyT2ZGbGlwcGVyc9IfIDIzXxAcTlNLZXlQYXRoU3BlY2lmaWVyRXhwcmVzc2lvbqMyJCXSHyA1Nl5OU011dGFibGVBcnJheaM1NyVXTlNBcnJhedIfIDk6XxATTlNLZXlQYXRoRXhwcmVzc2lvbqQ5OyQlXxAUTlNGdW5jdGlvbkV4cHJlc3Npb24ACAARABoAJAApADIANwBJAEwAUQBTAGAAZgBxAHsAigCdAKkAsACyALQAtgC4ALoAzQDUAN8A4QDjAOUA7ADxAPwBBQEcASABNwFEAU0BUgFdAV8BYQFjAWoBdAF2AXgBegGNAZIBsQG1AboByQHNAdUB2gHwAfUAAAAAAAACAQAAAAAAAAA8AAAAAAAAAAAAAAAAAAACDA==
|
||||
</attribute>
|
||||
<attribute name="name" type="string">numberOfFlagella</attribute>
|
||||
<relationship name="entitymapping" type="1/1" destination="XDDEVENTITYMAPPING" idrefs="z104"></relationship>
|
||||
</object>
|
||||
<object type="XDDEVENTITYMAPPING" id="z104">
|
||||
<attribute name="sourcename" type="string">Creature</attribute>
|
||||
<attribute name="mappingtypename" type="string">Undefined</attribute>
|
||||
<attribute name="mappingnumber" type="int16">1</attribute>
|
||||
<attribute name="destinationname" type="string">Creature</attribute>
|
||||
<attribute name="autogenerateexpression" type="bool">1</attribute>
|
||||
<relationship name="mappingmodel" type="1/1" destination="XDDEVMAPPINGMODEL" idrefs="z105"></relationship>
|
||||
<relationship name="attributemappings" type="0/0" destination="XDDEVATTRIBUTEMAPPING" idrefs="z102 z103"></relationship>
|
||||
<relationship name="relationshipmappings" type="0/0" destination="XDDEVRELATIONSHIPMAPPING"></relationship>
|
||||
</object>
|
||||
<object type="XDDEVMAPPINGMODEL" id="z105">
|
||||
<attribute name="sourcemodelpath" type="string">⭐️Sources/⭐️Demos/⭐️Advanced/EvolutionDemo/Advanced.EvolutionDemo.V1.xcdatamodeld/Advanced.EvolutionDemo.V2.xcdatamodel</attribute>
|
||||
<attribute name="sourcemodeldata" type="binary">YnBsaXN0MDDUAAEAAgADAAQABQAGAAcAClgkdmVyc2lvblkkYXJjaGl2ZXJUJHRvcFgkb2JqZWN0
|
||||
cxIAAYagXxAPTlNLZXllZEFyY2hpdmVy0QAIAAlUcm9vdIABrxDJAAsADAAbADcAOAA5AEEAQgBdAF4AXwBlAGYAcgCIAIkAigCLAIwAjQCOAI8AkACRAKoArQC0ALoAyQDYANsA6gD5APwAXAEMARsBHwEjATIBOAE5AUEBUAFRAVoBaAFpAWoBawFsAW0BggGDAYsBjAGNAZkBrQGuAa8BsAGxAbIBswG0AbUBxAHTAeIB5gH1AgQCEwIiAjECPQJPAlACUQJSAlMCVAJVAlYCZQJmAnUChAKTApQCowKyAsECyQLeAt8C5wLzAwcDFgMlAzQDOANHA1YDZQN0A4MDjwOhA7ADvwPOA90D7AP7BAoEHwQgBCgENARIBFcEZgR1BHkEiASXBKYEtQTEBNAE4gTxBPIFAQUQBR8FIAUvBT4FTQViBWMFawV3BYsFmgWpBbgFvAXLBdoF6QX4BgcGEwYlBjQGNQZEBlMGYgZjBnIGgQaQBqUGpgauBroGzgbdBuwG+wb/Bw4HHQcsBzsHSgdWB2gHdweGB5UHpAezB8IH0QfSB9UH3gfiB+YH6gfyB/UH+Qf6VSRudWxs1wANAA4ADwAQABEAEgATABQAFQAWABcAGAAXABpfEA9feGRfcm9vdFBhY2thZ2VWJGNsYXNzXF94ZF9jb21tZW50c18QEF94ZF9tb2RlbE1hbmFnZXJfEBVfY29uZmlndXJhdGlvbnNCeU5hbWVdX3hkX21vZGVsTmFtZV8QF19tb2RlbFZlcnNpb25JZGVudGlmaWVygAKAyIDFgACAxoAAgMfeABwAHQAeAB8AIAAhACIADgAjACQAJQAmACcAKAApACoAKwAJACkAFwAvADAAMQAyADMAKQApABdfEBxYREJ1Y2tldEZvckNsYXNzZXN3YXNFbmNvZGVkXxAaWERCdWNrZXRGb3JQYWNrYWdlc3N0b3JhZ2VfEBxYREJ1Y2tldEZvckludGVyZmFjZXNzdG9yYWdlXxAPX3hkX293bmluZ01vZGVsXxAdWERCdWNrZXRGb3JQYWNrYWdlc3dhc0VuY29kZWRWX293bmVyXxAbWERCdWNrZXRGb3JEYXRhVHlwZXNzdG9yYWdlW192aXNpYmlsaXR5XxAZWERCdWNrZXRGb3JDbGFzc2Vzc3RvcmFnZVVfbmFtZV8QH1hEQnVja2V0Rm9ySW50ZXJmYWNlc3dhc0VuY29kZWRfEB5YREJ1Y2tldEZvckRhdGFUeXBlc3dhc0VuY29kZWRfEBBfdW5pcXVlRWxlbWVudElEgASAw4DBgAGABIAAgMKAxBAAgAWAA4AEgASAAFBTWUVT0wA6ADsADgA8AD4AQFdOUy5rZXlzWk5TLm9iamVjdHOhAD2ABqEAP4AHgCVYQ3JlYXR1cmXfEBAAQwBEAEUARgAhAEcASAAjAEkASgAOACUASwBMACgATQBOAE8AKQApABQAUwBUADEAKQBOAFcAPQBOAFoAWwBcXxAhWERCdWNrZXRGb3JPd25lZEF0dHJpYnV0ZXNvcmRlcmVkXxAhWERCdWNrZXRGb3JPd25lZEF0dHJpYnV0ZXNzdG9yYWdlXxAgWERCdWNrZXRGb3JTdGVyZW90eXBlc3dhc0VuY29kZWRfECRYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc3dhc0VuY29kZWRfEB1YREJ1Y2tldEZvclN0ZXJlb3R5cGVzc3RvcmFnZV8QJFhEQnVja2V0Rm9yR2VuZXJhbGl6YXRpb25zZHVwbGljYXRlc18QJFhEQnVja2V0Rm9yR2VuZXJhbGl6YXRpb25zd2FzRW5jb2RlZF8QHVhEQnVja2V0Rm9yU3RlcmVvdHlwZXNvcmRlcmVkXxAhWERCdWNrZXRGb3JHZW5lcmFsaXphdGlvbnNvcmRlcmVkXxAhWERCdWNrZXRGb3JHZW5lcmFsaXphdGlvbnNzdG9yYWdlW19pc0Fic3RyYWN0gAmALYAEgASAAoAKgL6ABIAJgMCABoAJgL+ACAgSr8lB/VdvcmRlcmVk0wA6ADsADgBgAGIAQKEAYYALoQBjgAyAJV5YRF9QU3RlcmVvdHlwZdkAIQAlAGcADgAoAGgAIwBNAGkAPwBhAE4AbQAXACkAMQBcAHFfECFYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc29yZGVyZWRfECRYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc3dhc0VuY29kZWRfECFYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc3N0b3JhZ2WAB4ALgAmALIAAgAQIgA3TADoAOwAOAHMAfQBAqQB0AHUAdgB3AHgAeQB6AHsAfIAOgA+AEIARgBKAE4AUgBWAFqkA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 truncated
|
||||
</attribute>
|
||||
<attribute name="destinationmodelpath" type="string">⭐️Sources/⭐️Demos/⭐️Advanced/EvolutionDemo/Advanced.EvolutionDemo.V1.xcdatamodeld/Advanced.EvolutionDemo.V1.xcdatamodel</attribute>
|
||||
<attribute name="destinationmodeldata" type="binary">YnBsaXN0MDDUAAEAAgADAAQABQAGAAcAClgkdmVyc2lvblkkYXJjaGl2ZXJUJHRvcFgkb2JqZWN0
|
||||
cxIAAYagXxAPTlNLZXllZEFyY2hpdmVy0QAIAAlUcm9vdIABrxB/AAsADAAbADcAOAA5AEEAQgBdAF4AXwBlAGYAcgCIAIkAigCLAIwAjQCOAI8AkACRAKoArQC0ALoAyQDYANsA6gD5APwAXAEMARsBHwEjATIBOAE5AUEBUAFRAVoBYgFjAWQBeQF6AYIBgwGEAZABpAGlAaYBpwGoAakBqgGrAawBuwHKAdkB3QHsAfsCCgIZAigCNAJGAkcCSAJJAkoCSwJMAk0CXAJdAmwCewKKAosCmgKpArgCwALVAtYC3gLqAv4DDQMcAysDLwM+A00DXANrA3oDhgOYA6cDqAO3A8YD1QPWA+UD9AQDBAQEBwQQBBQEGAQcBCQEJwQrBCxVJG51bGzXAA0ADgAPABAAEQASABMAFAAVABYAFwAYABcAGl8QD194ZF9yb290UGFja2FnZVYkY2xhc3NcX3hkX2NvbW1lbnRzXxAQX3hkX21vZGVsTWFuYWdlcl8QFV9jb25maWd1cmF0aW9uc0J5TmFtZV1feGRfbW9kZWxOYW1lXxAXX21vZGVsVmVyc2lvbklkZW50aWZpZXKAAoB+gHuAAIB8gACAfd4AHAAdAB4AHwAgACEAIgAOACMAJAAlACYAJwAoACkAKgArAAkAKQAXAC8AMAAxADIAMwApACkAF18QHFhEQnVja2V0Rm9yQ2xhc3Nlc3dhc0VuY29kZWRfEBpYREJ1Y2tldEZvclBhY2thZ2Vzc3RvcmFnZV8QHFhEQnVja2V0Rm9ySW50ZXJmYWNlc3N0b3JhZ2VfEA9feGRfb3duaW5nTW9kZWxfEB1YREJ1Y2tldEZvclBhY2thZ2Vzd2FzRW5jb2RlZFZfb3duZXJfEBtYREJ1Y2tldEZvckRhdGFUeXBlc3N0b3JhZ2VbX3Zpc2liaWxpdHlfEBlYREJ1Y2tldEZvckNsYXNzZXNzdG9yYWdlVV9uYW1lXxAfWERCdWNrZXRGb3JJbnRlcmZhY2Vzd2FzRW5jb2RlZF8QHlhEQnVja2V0Rm9yRGF0YVR5cGVzd2FzRW5jb2RlZF8QEF91bmlxdWVFbGVtZW50SUSABIB5gHeAAYAEgACAeIB6EACABYADgASABIAAUFNZRVPTADoAOwAOADwAPgBAV05TLmtleXNaTlMub2JqZWN0c6EAPYAGoQA/gAeAJVhDcmVhdHVyZd8QEABDAEQARQBGACEARwBIACMASQBKAA4AJQBLAEwAKABNAE4ATwApACkAFABTAFQAMQApAE4AVwA9AE4AWgBbAFxfECFYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc29yZGVyZWRfECFYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc3N0b3JhZ2VfECBYREJ1Y2tldEZvclN0ZXJlb3R5cGVzd2FzRW5jb2RlZF8QJFhEQnVja2V0Rm9yT3duZWRBdHRyaWJ1dGVzd2FzRW5jb2RlZF8QHVhEQnVja2V0Rm9yU3RlcmVvdHlwZXNzdG9yYWdlXxAkWERCdWNrZXRGb3JHZW5lcmFsaXphdGlvbnNkdXBsaWNhdGVzXxAkWERCdWNrZXRGb3JHZW5lcmFsaXphdGlvbnN3YXNFbmNvZGVkXxAdWERCdWNrZXRGb3JTdGVyZW90eXBlc29yZGVyZWRfECFYREJ1Y2tldEZvckdlbmVyYWxpemF0aW9uc29yZGVyZWRfECFYREJ1Y2tldEZvckdlbmVyYWxpemF0aW9uc3N0b3JhZ2VbX2lzQWJzdHJhY3SACYAtgASABIACgAqAdIAEgAmAdoAGgAmAdYAICBK59ulAV29yZGVyZWTTADoAOwAOAGAAYgBAoQBhgAuhAGOADIAlXlhEX1BTdGVyZW90eXBl2QAhACUAZwAOACgAaAAjAE0AaQA/AGEATgBtABcAKQAxAFwAcV8QIVhEQnVja2V0Rm9yT3duZWRBdHRyaWJ1dGVzb3JkZXJlZF8QJFhEQnVja2V0Rm9yT3duZWRBdHRyaWJ1dGVzd2FzRW5jb2RlZF8QIVhEQnVja2V0Rm9yT3duZWRBdHRyaWJ1dGVzc3RvcmFnZYAHgAuACYAsgACABAiADdMAOgA7AA4AcwB9AECpAHQAdQB2AHcAeAB5AHoAewB8gA6AD4AQgBGAEoATgBSAFYAWqQB+AH8AgACBAIIAgwCEAIUAhoAXgBuAHIAegB+AIYAjgCaAKoAlXxATWERQTUNvbXBvdW5kSW5kZXhlc18QEFhEX1BTS19lbGVtZW50SURfEBlYRFBNVW5pcXVlbmVzc0NvbnN0cmFpbnRzXxAaWERfUFNLX3ZlcnNpb25IYXNoTW9kaWZpZXJfEBlYRF9QU0tfZmV0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 truncated
|
||||
</attribute>
|
||||
<relationship name="entitymappings" type="0/0" destination="XDDEVENTITYMAPPING" idrefs="z104"></relationship>
|
||||
</object>
|
||||
</database>
|
||||
@@ -18,7 +18,7 @@ extension Advanced.EvolutionDemo {
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
static let name: ModelVersion = "Advanced.Evolution.V1"
|
||||
static let name: ModelVersion = "Advanced.EvolutionDemo.V1"
|
||||
|
||||
typealias Creature = Advanced_EvolutionDemo_V1_Creature
|
||||
}
|
||||
|
||||
+25
@@ -42,6 +42,31 @@ final class Advanced_EvolutionDemo_V2_Creature: NSManagedObject, Advanced.Evolut
|
||||
|
||||
|
||||
// MARK: Advanced.EvolutionDemo.CreatureType
|
||||
|
||||
static func dataSource(in dataStack: DataStack) -> Advanced.EvolutionDemo.CreaturesDataSource {
|
||||
|
||||
return .init(
|
||||
listPublisher: dataStack.publishList(
|
||||
From<Advanced.EvolutionDemo.V2.Creature>()
|
||||
.orderBy(.descending(\.dnaCode))
|
||||
),
|
||||
dataStack: dataStack
|
||||
)
|
||||
}
|
||||
|
||||
static func count(in transaction: BaseDataTransaction) throws -> Int {
|
||||
|
||||
return try transaction.fetchCount(
|
||||
From<Advanced.EvolutionDemo.V2.Creature>()
|
||||
)
|
||||
}
|
||||
|
||||
static func create(in transaction: BaseDataTransaction) -> Advanced.EvolutionDemo.V2.Creature {
|
||||
|
||||
return transaction.create(
|
||||
Into<Advanced.EvolutionDemo.V2.Creature>()
|
||||
)
|
||||
}
|
||||
|
||||
func mutate(in transaction: BaseDataTransaction) {
|
||||
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
//
|
||||
// Demo
|
||||
// Copyright © 2020 John Rommel Estropia, Inc. All rights reserved.
|
||||
|
||||
import CoreStore
|
||||
|
||||
|
||||
// MARK: - Advanced.EvolutionDemo.V2
|
||||
|
||||
extension Advanced.EvolutionDemo.V2 {
|
||||
|
||||
// MARK: - Advanced.EvolutionDemo.V2.FromV1
|
||||
|
||||
enum FromV1 {
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
static var mapping: XcodeSchemaMappingProvider {
|
||||
|
||||
return XcodeSchemaMappingProvider(
|
||||
from: Advanced.EvolutionDemo.V1.name,
|
||||
to: Advanced.EvolutionDemo.V2.name,
|
||||
mappingModelBundle: Bundle(for: Advanced.EvolutionDemo.V1.Creature.self)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
<?xml version="1.0" standalone="yes"?>
|
||||
<!DOCTYPE database SYSTEM "file:///System/Library/DTDs/CoreData.dtd">
|
||||
|
||||
<database>
|
||||
<databaseInfo>
|
||||
<version>134481920</version>
|
||||
<UUID>3F477D57-4044-4E9E-9845-6B9B63B11BB7</UUID>
|
||||
<nextObjectID>108</nextObjectID>
|
||||
<metadata>
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>NSPersistenceFrameworkVersion</key>
|
||||
<integer>977</integer>
|
||||
<key>NSStoreModelVersionHashes</key>
|
||||
<dict>
|
||||
<key>XDDevAttributeMapping</key>
|
||||
<data>
|
||||
0plcXXRN7XHKl5CcF+fwriFmUpON3ZtcI/AfK748aWc=
|
||||
</data>
|
||||
<key>XDDevEntityMapping</key>
|
||||
<data>
|
||||
qeN1Ym3TkWN1G6dU9RfX6Kd2ccEvcDVWHpd3LpLgboI=
|
||||
</data>
|
||||
<key>XDDevMappingModel</key>
|
||||
<data>
|
||||
EqtMzvRnVZWkXwBHu4VeVGy8UyoOe+bi67KC79kphlQ=
|
||||
</data>
|
||||
<key>XDDevPropertyMapping</key>
|
||||
<data>
|
||||
XN33V44TTGY4JETlMoOB5yyTKxB+u4slvDIinv0rtGA=
|
||||
</data>
|
||||
<key>XDDevRelationshipMapping</key>
|
||||
<data>
|
||||
akYY9LhehVA/mCb4ATLWuI9XGLcjpm14wWL1oEBtIcs=
|
||||
</data>
|
||||
</dict>
|
||||
<key>NSStoreModelVersionHashesDigest</key>
|
||||
<string>+Hmc2uYZK6og+Pvx5GUJ7oW75UG4V/ksQanTjfTKUnxyGWJRMtB5tIRgVwGsrd7lz/QR57++wbvWsr6nxwyS0A==</string>
|
||||
<key>NSStoreModelVersionHashesVersion</key>
|
||||
<integer>3</integer>
|
||||
<key>NSStoreModelVersionIdentifiers</key>
|
||||
<array>
|
||||
<string></string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
</metadata>
|
||||
</databaseInfo>
|
||||
<object type="XDDEVENTITYMAPPING" id="z102">
|
||||
<attribute name="migrationpolicyclassname" type="string">Advanced_EvolutionDemo_V2_FromV1MigrationPolicy</attribute>
|
||||
<attribute name="sourcename" type="string">Creature</attribute>
|
||||
<attribute name="mappingtypename" type="string">Undefined</attribute>
|
||||
<attribute name="mappingnumber" type="int16">1</attribute>
|
||||
<attribute name="destinationname" type="string">Creature</attribute>
|
||||
<attribute name="autogenerateexpression" type="bool">1</attribute>
|
||||
<relationship name="mappingmodel" type="1/1" destination="XDDEVMAPPINGMODEL" idrefs="z105"></relationship>
|
||||
<relationship name="attributemappings" type="0/0" destination="XDDEVATTRIBUTEMAPPING" idrefs="z103 z108 z104 z107 z106"></relationship>
|
||||
<relationship name="relationshipmappings" type="0/0" destination="XDDEVRELATIONSHIPMAPPING"></relationship>
|
||||
</object>
|
||||
<object type="XDDEVATTRIBUTEMAPPING" id="z103">
|
||||
<attribute name="name" type="string">dnaCode</attribute>
|
||||
<relationship name="entitymapping" type="1/1" destination="XDDEVENTITYMAPPING" idrefs="z102"></relationship>
|
||||
</object>
|
||||
<object type="XDDEVATTRIBUTEMAPPING" id="z104">
|
||||
<attribute name="valueexpressiondata" type="binary">YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9iamVjdHMSAAGGoF8Q
|
||||
D05TS2V5ZWRBcmNoaXZlctEICVRyb290gAGsCwwXGB0eJiswMTQ4VSRudWxs1Q0ODxAREhMUFRZZTlNPcGVyYW5kXk5TU2VsZWN0b3JOYW1lXxAQTlNFeHByZXNzaW9uVHlwZVtOU0FyZ3VtZW50c1YkY2xhc3OAA4ACEASABoALXxAQdmFsdWVGb3JLZXlQYXRoOtMZDxEaGxxaTlNWYXJpYWJsZYAEEAKABVZzb3VyY2XSHyAhIlokY2xhc3NuYW1lWCRjbGFzc2VzXxAUTlNWYXJpYWJsZUV4cHJlc3Npb26jIyQlXxAUTlNWYXJpYWJsZUV4cHJlc3Npb25cTlNFeHByZXNzaW9uWE5TT2JqZWN00icRKCpaTlMub2JqZWN0c6EpgAeACtMRDywtLi9ZTlNLZXlQYXRogAkQCoAIXxAQbnVtYmVyT2ZGbGFnZWxsYdIfIDIzXxAcTlNLZXlQYXRoU3BlY2lmaWVyRXhwcmVzc2lvbqMyJCXSHyA1Nl5OU011dGFibGVBcnJheaM1NyVXTlNBcnJhedIfIDk6XxATTlNLZXlQYXRoRXhwcmVzc2lvbqQ5OyQlXxAUTlNGdW5jdGlvbkV4cHJlc3Npb24ACAARABoAJAApADIANwBJAEwAUQBTAGAAZgBxAHsAigCdAKkAsACyALQAtgC4ALoAzQDUAN8A4QDjAOUA7ADxAPwBBQEcASABNwFEAU0BUgFdAV8BYQFjAWoBdAF2AXgBegGNAZIBsQG1AboByQHNAdUB2gHwAfUAAAAAAAACAQAAAAAAAAA8AAAAAAAAAAAAAAAAAAACDA==
|
||||
</attribute>
|
||||
<attribute name="name" type="string">numberOfFlippers</attribute>
|
||||
<relationship name="entitymapping" type="1/1" destination="XDDEVENTITYMAPPING" idrefs="z102"></relationship>
|
||||
</object>
|
||||
<object type="XDDEVMAPPINGMODEL" id="z105">
|
||||
<attribute name="sourcemodelpath" type="string">⭐️Sources/⭐️Demos/⭐️Advanced/EvolutionDemo/Advanced.EvolutionDemo.V1.xcdatamodeld/Advanced.EvolutionDemo.V1.xcdatamodel</attribute>
|
||||
<attribute name="sourcemodeldata" type="binary">YnBsaXN0MDDUAAEAAgADAAQABQAGAAcAClgkdmVyc2lvblkkYXJjaGl2ZXJUJHRvcFgkb2JqZWN0
|
||||
cxIAAYagXxAPTlNLZXllZEFyY2hpdmVy0QAIAAlUcm9vdIABrxB/AAsADAAbADcAOAA5AEEAQgBdAF4AXwBlAGYAcgCIAIkAigCLAIwAjQCOAI8AkACRAKoArQC0ALoAyQDYANsA6gD5APwAXAEMARsBHwEjATIBOAE5AUEBUAFRAVoBYgFjAWQBeQF6AYIBgwGEAZABpAGlAaYBpwGoAakBqgGrAawBuwHKAdkB3QHsAfsCCgIZAigCNAJGAkcCSAJJAkoCSwJMAk0CXAJdAmwCewKKAosCmgKpArgCwALVAtYC3gLqAv4DDQMcAysDLwM+A00DXANrA3oDhgOYA6cDqAO3A8YD1QPWA+UD9AQDBAQEBwQQBBQEGAQcBCQEJwQrBCxVJG51bGzXAA0ADgAPABAAEQASABMAFAAVABYAFwAYABcAGl8QD194ZF9yb290UGFja2FnZVYkY2xhc3NcX3hkX2NvbW1lbnRzXxAQX3hkX21vZGVsTWFuYWdlcl8QFV9jb25maWd1cmF0aW9uc0J5TmFtZV1feGRfbW9kZWxOYW1lXxAXX21vZGVsVmVyc2lvbklkZW50aWZpZXKAAoB+gHuAAIB8gACAfd4AHAAdAB4AHwAgACEAIgAOACMAJAAlACYAJwAoACkAKgArAAkAKQAXAC8AMAAxADIAMwApACkAF18QHFhEQnVja2V0Rm9yQ2xhc3Nlc3dhc0VuY29kZWRfEBpYREJ1Y2tldEZvclBhY2thZ2Vzc3RvcmFnZV8QHFhEQnVja2V0Rm9ySW50ZXJmYWNlc3N0b3JhZ2VfEA9feGRfb3duaW5nTW9kZWxfEB1YREJ1Y2tldEZvclBhY2thZ2Vzd2FzRW5jb2RlZFZfb3duZXJfEBtYREJ1Y2tldEZvckRhdGFUeXBlc3N0b3JhZ2VbX3Zpc2liaWxpdHlfEBlYREJ1Y2tldEZvckNsYXNzZXNzdG9yYWdlVV9uYW1lXxAfWERCdWNrZXRGb3JJbnRlcmZhY2Vzd2FzRW5jb2RlZF8QHlhEQnVja2V0Rm9yRGF0YVR5cGVzd2FzRW5jb2RlZF8QEF91bmlxdWVFbGVtZW50SUSABIB5gHeAAYAEgACAeIB6EACABYADgASABIAAUFNZRVPTADoAOwAOADwAPgBAV05TLmtleXNaTlMub2JqZWN0c6EAPYAGoQA/gAeAJVhDcmVhdHVyZd8QEABDAEQARQBGACEARwBIACMASQBKAA4AJQBLAEwAKABNAE4ATwApACkAFABTAFQAMQApAE4AVwA9AE4AWgBbAFxfECFYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc29yZGVyZWRfECFYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc3N0b3JhZ2VfECBYREJ1Y2tldEZvclN0ZXJlb3R5cGVzd2FzRW5jb2RlZF8QJFhEQnVja2V0Rm9yT3duZWRBdHRyaWJ1dGVzd2FzRW5jb2RlZF8QHVhEQnVja2V0Rm9yU3RlcmVvdHlwZXNzdG9yYWdlXxAkWERCdWNrZXRGb3JHZW5lcmFsaXphdGlvbnNkdXBsaWNhdGVzXxAkWERCdWNrZXRGb3JHZW5lcmFsaXphdGlvbnN3YXNFbmNvZGVkXxAdWERCdWNrZXRGb3JTdGVyZW90eXBlc29yZGVyZWRfECFYREJ1Y2tldEZvckdlbmVyYWxpemF0aW9uc29yZGVyZWRfECFYREJ1Y2tldEZvckdlbmVyYWxpemF0aW9uc3N0b3JhZ2VbX2lzQWJzdHJhY3SACYAtgASABIACgAqAdIAEgAmAdoAGgAmAdYAICBMAAAABAdFnUVdvcmRlcmVk0wA6ADsADgBgAGIAQKEAYYALoQBjgAyAJV5YRF9QU3RlcmVvdHlwZdkAIQAlAGcADgAoAGgAIwBNAGkAPwBhAE4AbQAXACkAMQBcAHFfECFYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc29yZGVyZWRfECRYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc3dhc0VuY29kZWRfECFYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc3N0b3JhZ2WAB4ALgAmALIAAgAQIgA3TADoAOwAOAHMAfQBAqQB0AHUAdgB3AHgAeQB6AHsAfIAOgA+AEIARgBKAE4AUgBWAFqkAfgB/AIAAgQCCAIMAhACFAIaAF4AbgByAHoAfgCGAI4AmgCqAJV8QE1hEUE1Db21wb3VuZEluZGV4ZXNfEBBYRF9QU0tfZWxlbWVudElEXxAZWERQTVVuaXF1ZW5lc3NDb25zdHJhaW50c18QGlhEX1BTS192ZXJzaW9uSGFzaE1vZGlmaWVyXxAZWERfUFNL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 truncated
|
||||
</attribute>
|
||||
<attribute name="destinationmodelpath" type="string">⭐️Sources/⭐️Demos/⭐️Advanced/EvolutionDemo/Advanced.EvolutionDemo.V1.xcdatamodeld/Advanced.EvolutionDemo.V2.xcdatamodel</attribute>
|
||||
<attribute name="destinationmodeldata" type="binary">YnBsaXN0MDDUAAEAAgADAAQABQAGAAcAClgkdmVyc2lvblkkYXJjaGl2ZXJUJHRvcFgkb2JqZWN0
|
||||
cxIAAYagXxAPTlNLZXllZEFyY2hpdmVy0QAIAAlUcm9vdIABrxDJAAsADAAbADcAOAA5AEEAQgBdAF4AXwBlAGYAcgCIAIkAigCLAIwAjQCOAI8AkACRAKoArQC0ALoAyQDYANsA6gD5APwAXAEMARsBHwEjATIBOAE5AUEBUAFRAVoBaAFpAWoBawFsAW0BggGDAYsBjAGNAZkBrQGuAa8BsAGxAbIBswG0AbUBxAHTAeIB5gH1AgQCEwIiAjECPQJPAlACUQJSAlMCVAJVAlYCZQJmAnUChAKTApQCowKyAsECyQLeAt8C5wLzAwcDFgMlAzQDOANHA1YDZQN0A4MDjwOhA7ADvwPOA90D7AP7BAoEHwQgBCgENARIBFcEZgR1BHkEiASXBKYEtQTEBNAE4gTxBPIFAQUQBR8FIAUvBT4FTQViBWMFawV3BYsFmgWpBbgFvAXLBdoF6QX4BgcGEwYlBjQGNQZEBlMGYgZjBnIGgQaQBqUGpgauBroGzgbdBuwG+wb/Bw4HHQcsBzsHSgdWB2gHdweGB5UHpAezB8IH0QfSB9UH3gfiB+YH6gfyB/UH+Qf6VSRudWxs1wANAA4ADwAQABEAEgATABQAFQAWABcAGAAXABpfEA9feGRfcm9vdFBhY2thZ2VWJGNsYXNzXF94ZF9jb21tZW50c18QEF94ZF9tb2RlbE1hbmFnZXJfEBVfY29uZmlndXJhdGlvbnNCeU5hbWVdX3hkX21vZGVsTmFtZV8QF19tb2RlbFZlcnNpb25JZGVudGlmaWVygAKAyIDFgACAxoAAgMfeABwAHQAeAB8AIAAhACIADgAjACQAJQAmACcAKAApACoAKwAJACkAFwAvADAAMQAyADMAKQApABdfEBxYREJ1Y2tldEZvckNsYXNzZXN3YXNFbmNvZGVkXxAaWERCdWNrZXRGb3JQYWNrYWdlc3N0b3JhZ2VfEBxYREJ1Y2tldEZvckludGVyZmFjZXNzdG9yYWdlXxAPX3hkX293bmluZ01vZGVsXxAdWERCdWNrZXRGb3JQYWNrYWdlc3dhc0VuY29kZWRWX293bmVyXxAbWERCdWNrZXRGb3JEYXRhVHlwZXNzdG9yYWdlW192aXNpYmlsaXR5XxAZWERCdWNrZXRGb3JDbGFzc2Vzc3RvcmFnZVVfbmFtZV8QH1hEQnVja2V0Rm9ySW50ZXJmYWNlc3dhc0VuY29kZWRfEB5YREJ1Y2tldEZvckRhdGFUeXBlc3dhc0VuY29kZWRfEBBfdW5pcXVlRWxlbWVudElEgASAw4DBgAGABIAAgMKAxBAAgAWAA4AEgASAAFBTWUVT0wA6ADsADgA8AD4AQFdOUy5rZXlzWk5TLm9iamVjdHOhAD2ABqEAP4AHgCVYQ3JlYXR1cmXfEBAAQwBEAEUARgAhAEcASAAjAEkASgAOACUASwBMACgATQBOAE8AKQApABQAUwBUADEAKQBOAFcAPQBOAFoAWwBcXxAhWERCdWNrZXRGb3JPd25lZEF0dHJpYnV0ZXNvcmRlcmVkXxAhWERCdWNrZXRGb3JPd25lZEF0dHJpYnV0ZXNzdG9yYWdlXxAgWERCdWNrZXRGb3JTdGVyZW90eXBlc3dhc0VuY29kZWRfECRYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc3dhc0VuY29kZWRfEB1YREJ1Y2tldEZvclN0ZXJlb3R5cGVzc3RvcmFnZV8QJFhEQnVja2V0Rm9yR2VuZXJhbGl6YXRpb25zZHVwbGljYXRlc18QJFhEQnVja2V0Rm9yR2VuZXJhbGl6YXRpb25zd2FzRW5jb2RlZF8QHVhEQnVja2V0Rm9yU3RlcmVvdHlwZXNvcmRlcmVkXxAhWERCdWNrZXRGb3JHZW5lcmFsaXphdGlvbnNvcmRlcmVkXxAhWERCdWNrZXRGb3JHZW5lcmFsaXphdGlvbnNzdG9yYWdlW19pc0Fic3RyYWN0gAmALYAEgASAAoAKgL6ABIAJgMCABoAJgL+ACAgScIBBUFdvcmRlcmVk0wA6ADsADgBgAGIAQKEAYYALoQBjgAyAJV5YRF9QU3RlcmVvdHlwZdkAIQAlAGcADgAoAGgAIwBNAGkAPwBhAE4AbQAXACkAMQBcAHFfECFYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc29yZGVyZWRfECRYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc3dhc0VuY29kZWRfECFYREJ1Y2tldEZvck93bmVkQXR0cmlidXRlc3N0b3JhZ2WAB4ALgAmALIAAgAQIgA3TADoAOwAOAHMAfQBAqQB0AHUAdgB3AHgAeQB6AHsAfIAOgA+AEIARgBKAE4AUgBWAFqkA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 truncated
|
||||
</attribute>
|
||||
<relationship name="entitymappings" type="0/0" destination="XDDEVENTITYMAPPING" idrefs="z102"></relationship>
|
||||
</object>
|
||||
<object type="XDDEVATTRIBUTEMAPPING" id="z106">
|
||||
<attribute name="name" type="string">hasVertebrae</attribute>
|
||||
<relationship name="entitymapping" type="1/1" destination="XDDEVENTITYMAPPING" idrefs="z102"></relationship>
|
||||
</object>
|
||||
<object type="XDDEVATTRIBUTEMAPPING" id="z107">
|
||||
<attribute name="valueexpressiondata" type="binary">YnBsaXN0MDDUAQIDBAUGBwpYJHZlcnNpb25ZJGFyY2hpdmVyVCR0b3BYJG9iamVjdHMSAAGGoF8Q
|
||||
D05TS2V5ZWRBcmNoaXZlctEICVRyb290gAGkCwwTFFUkbnVsbNMNDg8QERJfEA9OU0NvbnN0YW50VmFsdWVfEBBOU0V4cHJlc3Npb25UeXBlViRjbGFzc4ACEACAAwnSFRYXGFokY2xhc3NuYW1lWCRjbGFzc2VzXxAZTlNDb25zdGFudFZhbHVlRXhwcmVzc2lvbqMXGRpcTlNFeHByZXNzaW9uWE5TT2JqZWN0CBEaJCkyN0lMUVNYXmV3ipGTlZeYnaixzdHeAAAAAAAAAQEAAAAAAAAAGwAAAAAAAAAAAAAAAAAAAOc=
|
||||
</attribute>
|
||||
<attribute name="name" type="string">hasHead</attribute>
|
||||
<relationship name="entitymapping" type="1/1" destination="XDDEVENTITYMAPPING" idrefs="z102"></relationship>
|
||||
</object>
|
||||
<object type="XDDEVATTRIBUTEMAPPING" id="z108">
|
||||
<attribute name="name" type="string">hasTail</attribute>
|
||||
<relationship name="entitymapping" type="1/1" destination="XDDEVENTITYMAPPING" idrefs="z102"></relationship>
|
||||
</object>
|
||||
</database>
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
//
|
||||
// Demo
|
||||
// Copyright © 2020 John Rommel Estropia, Inc. All rights reserved.
|
||||
|
||||
import CoreData
|
||||
import CoreStore
|
||||
|
||||
|
||||
// MARK: - Advanced.EvolutionDemo.V2.FromV1MigrationPolicy
|
||||
|
||||
@objc(Advanced_EvolutionDemo_V2_FromV1MigrationPolicy)
|
||||
final class Advanced_EvolutionDemo_V2_FromV1MigrationPolicy: NSEntityMigrationPolicy {
|
||||
|
||||
// MARK: NSEntityMigrationPolicy
|
||||
|
||||
override func createDestinationInstances(
|
||||
forSource sInstance: NSManagedObject,
|
||||
in mapping: NSEntityMapping,
|
||||
manager: NSMigrationManager
|
||||
) throws {
|
||||
|
||||
try super.createDestinationInstances(
|
||||
forSource: sInstance,
|
||||
in: mapping,
|
||||
manager: manager
|
||||
)
|
||||
|
||||
for dInstance in manager.destinationInstances(forEntityMappingName: mapping.name, sourceInstances: [sInstance]) {
|
||||
|
||||
dInstance.setValue(
|
||||
Bool.random(),
|
||||
forKey: #keyPath(Advanced.EvolutionDemo.V2.Creature.hasVertebrae)
|
||||
)
|
||||
dInstance.setValue(
|
||||
Bool.random(),
|
||||
forKey: #keyPath(Advanced.EvolutionDemo.V2.Creature.hasTail)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
//
|
||||
// Demo
|
||||
// Copyright © 2020 John Rommel Estropia, Inc. All rights reserved.
|
||||
|
||||
import CoreStore
|
||||
|
||||
|
||||
// MARK: - Advanced.EvolutionDemo.V2
|
||||
|
||||
extension Advanced.EvolutionDemo.V2 {
|
||||
|
||||
// MARK: - Advanced.EvolutionDemo.V2.FromV3
|
||||
|
||||
enum FromV3 {
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
static var mapping: CustomSchemaMappingProvider {
|
||||
|
||||
return CustomSchemaMappingProvider(
|
||||
from: Advanced.EvolutionDemo.V3.name,
|
||||
to: Advanced.EvolutionDemo.V2.name,
|
||||
entityMappings: [
|
||||
.transformEntity(
|
||||
sourceEntity: "Creature",
|
||||
destinationEntity: "Creature",
|
||||
transformer: { (source, createDestination) in
|
||||
|
||||
let destination = createDestination()
|
||||
destination["dnaCode"] = source["dnaCode"]
|
||||
destination["numberOfFlippers"] = source["numberOfLimbs"]
|
||||
destination["hasVertebrae"] = source["hasVertebrae"]
|
||||
destination["hasHead"] = source["hasHead"]
|
||||
destination["hasTail"] = source["hasTail"]
|
||||
}
|
||||
)
|
||||
]
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,8 +18,10 @@ extension Advanced.EvolutionDemo {
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
static let name: ModelVersion = "Advanced.Evolution.V2"
|
||||
static let name: ModelVersion = "Advanced.EvolutionDemo.V2"
|
||||
|
||||
typealias Creature = Advanced_EvolutionDemo_V2_Creature
|
||||
|
||||
typealias FromV1MigrationPolicy = Advanced_EvolutionDemo_V2_FromV1MigrationPolicy
|
||||
}
|
||||
}
|
||||
+25
@@ -64,6 +64,31 @@ extension Advanced.EvolutionDemo.V3 {
|
||||
|
||||
|
||||
// MARK: Advanced.EvolutionDemo.CreatureType
|
||||
|
||||
static func dataSource(in dataStack: DataStack) -> Advanced.EvolutionDemo.CreaturesDataSource {
|
||||
|
||||
return .init(
|
||||
listPublisher: dataStack.publishList(
|
||||
From<Advanced.EvolutionDemo.V3.Creature>()
|
||||
.orderBy(.descending(\.$dnaCode))
|
||||
),
|
||||
dataStack: dataStack
|
||||
)
|
||||
}
|
||||
|
||||
static func count(in transaction: BaseDataTransaction) throws -> Int {
|
||||
|
||||
return try transaction.fetchCount(
|
||||
From<Advanced.EvolutionDemo.V3.Creature>()
|
||||
)
|
||||
}
|
||||
|
||||
static func create(in transaction: BaseDataTransaction) -> Advanced.EvolutionDemo.V3.Creature {
|
||||
|
||||
return transaction.create(
|
||||
Into<Advanced.EvolutionDemo.V3.Creature>()
|
||||
)
|
||||
}
|
||||
|
||||
func mutate(in transaction: BaseDataTransaction) {
|
||||
|
||||
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
//
|
||||
// Demo
|
||||
// Copyright © 2020 John Rommel Estropia, Inc. All rights reserved.
|
||||
|
||||
import CoreStore
|
||||
|
||||
|
||||
// MARK: - Advanced.EvolutionDemo.V3
|
||||
|
||||
extension Advanced.EvolutionDemo.V3 {
|
||||
|
||||
// MARK: - Advanced.EvolutionDemo.V3.FromV2
|
||||
|
||||
enum FromV2 {
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
static var mapping: CustomSchemaMappingProvider {
|
||||
|
||||
return CustomSchemaMappingProvider(
|
||||
from: Advanced.EvolutionDemo.V2.name,
|
||||
to: Advanced.EvolutionDemo.V3.name,
|
||||
entityMappings: [
|
||||
.transformEntity(
|
||||
sourceEntity: "Creature",
|
||||
destinationEntity: "Creature",
|
||||
transformer: { (source, createDestination) in
|
||||
|
||||
let destination = createDestination()
|
||||
destination["dnaCode"] = source["dnaCode"]
|
||||
destination["numberOfLimbs"] = source["numberOfFlippers"]
|
||||
destination["hasVertebrae"] = source["hasVertebrae"]
|
||||
destination["hasHead"] = source["hasHead"]
|
||||
destination["hasTail"] = source["hasTail"]
|
||||
destination["hasWings"] = Bool.random()
|
||||
destination["habitat"] = Advanced.EvolutionDemo.V3.Creature.Habitat.allCases.randomElement()!.rawValue
|
||||
}
|
||||
)
|
||||
]
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
//
|
||||
// Demo
|
||||
// Copyright © 2020 John Rommel Estropia, Inc. All rights reserved.
|
||||
|
||||
import CoreStore
|
||||
|
||||
|
||||
// MARK: - Advanced.EvolutionDemo.V3
|
||||
|
||||
extension Advanced.EvolutionDemo.V3 {
|
||||
|
||||
// MARK: - Advanced.EvolutionDemo.V3.FromV4
|
||||
|
||||
enum FromV4 {
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
static var mapping: CustomSchemaMappingProvider {
|
||||
|
||||
return CustomSchemaMappingProvider(
|
||||
from: Advanced.EvolutionDemo.V4.name,
|
||||
to: Advanced.EvolutionDemo.V3.name,
|
||||
entityMappings: [
|
||||
.transformEntity(
|
||||
sourceEntity: "Creature",
|
||||
destinationEntity: "Creature",
|
||||
transformer: CustomSchemaMappingProvider.CustomMapping.inferredTransformation(_:_:)
|
||||
)
|
||||
]
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,6 @@ extension Advanced.EvolutionDemo {
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
static let name: ModelVersion = "Advanced.Evolution.V3"
|
||||
static let name: ModelVersion = "Advanced.EvolutionDemo.V3"
|
||||
}
|
||||
}
|
||||
+25
@@ -60,6 +60,31 @@ extension Advanced.EvolutionDemo.V4 {
|
||||
|
||||
|
||||
// MARK: Advanced.EvolutionDemo.CreatureType
|
||||
|
||||
static func dataSource(in dataStack: DataStack) -> Advanced.EvolutionDemo.CreaturesDataSource {
|
||||
|
||||
return .init(
|
||||
listPublisher: dataStack.publishList(
|
||||
From<Advanced.EvolutionDemo.V4.Creature>()
|
||||
.orderBy(.descending(\.$dnaCode))
|
||||
),
|
||||
dataStack: dataStack
|
||||
)
|
||||
}
|
||||
|
||||
static func count(in transaction: BaseDataTransaction) throws -> Int {
|
||||
|
||||
return try transaction.fetchCount(
|
||||
From<Advanced.EvolutionDemo.V4.Creature>()
|
||||
)
|
||||
}
|
||||
|
||||
static func create(in transaction: BaseDataTransaction) -> Advanced.EvolutionDemo.V4.Creature {
|
||||
|
||||
return transaction.create(
|
||||
Into<Advanced.EvolutionDemo.V4.Creature>()
|
||||
)
|
||||
}
|
||||
|
||||
func mutate(in transaction: BaseDataTransaction) {
|
||||
|
||||
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
//
|
||||
// Demo
|
||||
// Copyright © 2020 John Rommel Estropia, Inc. All rights reserved.
|
||||
|
||||
import CoreStore
|
||||
|
||||
|
||||
// MARK: - Advanced.EvolutionDemo.V4
|
||||
|
||||
extension Advanced.EvolutionDemo.V4 {
|
||||
|
||||
// MARK: - Advanced.EvolutionDemo.V4.FromV3
|
||||
|
||||
enum FromV3 {
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
static var mapping: CustomSchemaMappingProvider {
|
||||
|
||||
return CustomSchemaMappingProvider(
|
||||
from: Advanced.EvolutionDemo.V3.name,
|
||||
to: Advanced.EvolutionDemo.V4.name,
|
||||
entityMappings: [
|
||||
.transformEntity(
|
||||
sourceEntity: "Creature",
|
||||
destinationEntity: "Creature",
|
||||
transformer: { (source, createDestination) in
|
||||
|
||||
let destination = createDestination()
|
||||
destination.enumerateAttributes { (destinationAttribute, sourceAttribute) in
|
||||
|
||||
if let sourceAttribute = sourceAttribute {
|
||||
|
||||
destination[destinationAttribute] = source[sourceAttribute]
|
||||
}
|
||||
}
|
||||
destination["isWarmBlooded"] = Bool.random()
|
||||
}
|
||||
)
|
||||
]
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,6 @@ extension Advanced.EvolutionDemo {
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
static let name: ModelVersion = "Advanced.Evolution.V4"
|
||||
static let name: ModelVersion = "Advanced.EvolutionDemo.V4"
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ extension Advanced {
|
||||
// MARK: - Advanced.EvolutionDemo
|
||||
|
||||
/**
|
||||
Sample execution of progressive migrations. This demo also supports backwards migration.
|
||||
Sample execution of progressive migrations. This demo also shows how to do two-way migration chains (upgrades+downgrades), while allowing the app to use any version of the model.
|
||||
*/
|
||||
enum EvolutionDemo {}
|
||||
}
|
||||
@@ -33,10 +33,6 @@ import CoreData
|
||||
All CoreStore's utilities are designed around `DynamicObject` instances. `NSManagedObject` and `CoreStoreObject` instances all conform to `DynamicObject`.
|
||||
*/
|
||||
public protocol DynamicObject: AnyObject {
|
||||
/**
|
||||
The object ID for this instance
|
||||
*/
|
||||
typealias ObjectID = NSManagedObjectID
|
||||
|
||||
/**
|
||||
Used internally by CoreStore. Do not call directly.
|
||||
@@ -72,6 +68,11 @@ public protocol DynamicObject: AnyObject {
|
||||
extension DynamicObject {
|
||||
|
||||
// MARK: Internal
|
||||
|
||||
/**
|
||||
The object ID for this instance
|
||||
*/
|
||||
public typealias ObjectID = NSManagedObjectID
|
||||
|
||||
internal func runtimeType() -> Self.Type {
|
||||
|
||||
|
||||
Reference in new issue
Block a user