From f71ad4c577c331f4929faa702c2d159808d13f4d Mon Sep 17 00:00:00 2001 From: John Rommel Estropia Date: Tue, 1 Mar 2016 08:01:40 +0900 Subject: [PATCH] WIP: Storage protocols --- CoreStore.xcodeproj/project.pbxproj | 32 +++++++++++-- CoreStore/Setting Up/DataStack.swift | 30 ++++++++---- .../PersistentStores/InMemoryStore.swift | 48 +++++++++++++++++++ .../Setting Up/PersistentStores/Storage.swift | 48 +++++++++++++++++++ CoreStoreDemo/CoreStoreDemo/Info.plist | 2 + 5 files changed, 147 insertions(+), 13 deletions(-) create mode 100644 CoreStore/Setting Up/PersistentStores/InMemoryStore.swift create mode 100644 CoreStore/Setting Up/PersistentStores/Storage.swift diff --git a/CoreStore.xcodeproj/project.pbxproj b/CoreStore.xcodeproj/project.pbxproj index c7e0cbe..87e2684 100644 --- a/CoreStore.xcodeproj/project.pbxproj +++ b/CoreStore.xcodeproj/project.pbxproj @@ -263,6 +263,14 @@ B5FAD6A91B50A4B400714891 /* NSProgress+Convenience.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5FAD6A81B50A4B300714891 /* NSProgress+Convenience.swift */; }; B5FAD6AC1B51285300714891 /* MigrationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5FAD6AB1B51285300714891 /* MigrationManager.swift */; }; B5FAD6AE1B518DCB00714891 /* CoreStore+Migration.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5FAD6AD1B518DCB00714891 /* CoreStore+Migration.swift */; }; + B5FE4DA21C8481E100FA6A91 /* Storage.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5FE4DA11C8481E100FA6A91 /* Storage.swift */; }; + B5FE4DA31C8481E100FA6A91 /* Storage.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5FE4DA11C8481E100FA6A91 /* Storage.swift */; }; + B5FE4DA41C8481E100FA6A91 /* Storage.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5FE4DA11C8481E100FA6A91 /* Storage.swift */; }; + B5FE4DA51C8481E100FA6A91 /* Storage.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5FE4DA11C8481E100FA6A91 /* Storage.swift */; }; + B5FE4DA71C84FB4400FA6A91 /* InMemoryStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5FE4DA61C84FB4400FA6A91 /* InMemoryStore.swift */; }; + B5FE4DA81C84FB4400FA6A91 /* InMemoryStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5FE4DA61C84FB4400FA6A91 /* InMemoryStore.swift */; }; + B5FE4DA91C84FB4400FA6A91 /* InMemoryStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5FE4DA61C84FB4400FA6A91 /* InMemoryStore.swift */; }; + B5FE4DAA1C84FB4400FA6A91 /* InMemoryStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5FE4DA61C84FB4400FA6A91 /* InMemoryStore.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -379,6 +387,8 @@ B5FAD6A81B50A4B300714891 /* NSProgress+Convenience.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSProgress+Convenience.swift"; sourceTree = ""; }; B5FAD6AB1B51285300714891 /* MigrationManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MigrationManager.swift; sourceTree = ""; }; B5FAD6AD1B518DCB00714891 /* CoreStore+Migration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "CoreStore+Migration.swift"; sourceTree = ""; }; + B5FE4DA11C8481E100FA6A91 /* Storage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Storage.swift; sourceTree = ""; }; + B5FE4DA61C84FB4400FA6A91 /* InMemoryStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InMemoryStore.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -578,6 +588,7 @@ B5E84EDB1AFF84500064E85B /* DataStack.swift */, B5E84EDE1AFF84500064E85B /* PersistentStoreResult.swift */, B504D0D51B02362500B2BBB1 /* CoreStore+Setup.swift */, + B5FE4DA01C84818B00FA6A91 /* PersistentStores */, ); path = "Setting Up"; sourceTree = ""; @@ -687,6 +698,15 @@ path = Internal; sourceTree = ""; }; + B5FE4DA01C84818B00FA6A91 /* PersistentStores */ = { + isa = PBXGroup; + children = ( + B5FE4DA11C8481E100FA6A91 /* Storage.swift */, + B5FE4DA61C84FB4400FA6A91 /* InMemoryStore.swift */, + ); + path = PersistentStores; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -985,6 +1005,7 @@ B5E84EE71AFF84610064E85B /* CoreStore+Logging.swift in Sources */, B56007111B3F6BD500A9A8F9 /* Into.swift in Sources */, B5E84F111AFF847B0064E85B /* Select.swift in Sources */, + B5FE4DA21C8481E100FA6A91 /* Storage.swift in Sources */, B50392F91C478FF3009900CA /* NSManagedObject+Transaction.swift in Sources */, B5202CFA1C04688100DED140 /* NSFetchedResultsController+Convenience.swift in Sources */, B5E84EE11AFF84500064E85B /* PersistentStoreResult.swift in Sources */, @@ -997,7 +1018,6 @@ B5E84F0D1AFF847B0064E85B /* BaseDataTransaction+Querying.swift in Sources */, B5FAD6AC1B51285300714891 /* MigrationManager.swift in Sources */, B5E84EF61AFF846E0064E85B /* DataStack+Transaction.swift in Sources */, - B51F259A1C5747DD0083A5DD /* DataStack+iCloud.swift in Sources */, B5E84EDF1AFF84500064E85B /* DataStack.swift in Sources */, B59AFF411C6593E400C0ABE2 /* NSPersistentStoreCoordinator+Setup.swift in Sources */, B5E834BB1B7691F3001D3D50 /* Functions.swift in Sources */, @@ -1020,6 +1040,7 @@ B5E84EF81AFF846E0064E85B /* CoreStore+Transaction.swift in Sources */, B5E84F301AFF849C0064E85B /* NSManagedObjectContext+CoreStore.swift in Sources */, B5E84F211AFF84860064E85B /* CoreStore+Observing.swift in Sources */, + B5FE4DA71C84FB4400FA6A91 /* InMemoryStore.swift in Sources */, B5E834B91B76311F001D3D50 /* BaseDataTransaction+Importing.swift in Sources */, B5E84EE61AFF84610064E85B /* DefaultLogger.swift in Sources */, B5E84EF41AFF846E0064E85B /* AsynchronousDataTransaction.swift in Sources */, @@ -1063,6 +1084,7 @@ 82BA18C81C4BBD5900A0916E /* MigrationChain.swift in Sources */, 82BA18B11C4BBD3100A0916E /* SaveResult.swift in Sources */, 82BA18DD1C4BBE1400A0916E /* NSFetchedResultsController+Convenience.swift in Sources */, + B5FE4DA81C84FB4400FA6A91 /* InMemoryStore.swift in Sources */, 82BA18B41C4BBD3900A0916E /* BaseDataTransaction+Importing.swift in Sources */, 82BA18CA1C4BBD5900A0916E /* MigrationResult.swift in Sources */, 82BA18C11C4BBD5300A0916E /* CoreStore+Observing.swift in Sources */, @@ -1070,13 +1092,13 @@ 82BA18B01C4BBD3100A0916E /* NSManagedObject+Transaction.swift in Sources */, 82BA18D41C4BBD7100A0916E /* NSManagedObjectContext+Querying.swift in Sources */, 82BA18D51C4BBD7100A0916E /* NSManagedObjectContext+Setup.swift in Sources */, + B5FE4DA31C8481E100FA6A91 /* Storage.swift in Sources */, 82BA18C91C4BBD5900A0916E /* MigrationType.swift in Sources */, 82BA18D01C4BBD7100A0916E /* MigrationManager.swift in Sources */, 82BA18C61C4BBD5900A0916E /* DataStack+Migration.swift in Sources */, 82BA18CD1C4BBD7100A0916E /* AssociatedObjects.swift in Sources */, 82BA18B71C4BBD3F00A0916E /* CoreStore+Querying.swift in Sources */, 82BA18A41C4BBD2200A0916E /* PersistentStoreResult.swift in Sources */, - B51F259B1C57875E0083A5DD /* DataStack+iCloud.swift in Sources */, 82BA18AA1C4BBD3100A0916E /* BaseDataTransaction.swift in Sources */, 82BA18A91C4BBD3100A0916E /* Into.swift in Sources */, 82BA18D11C4BBD7100A0916E /* NotificationObserver.swift in Sources */, @@ -1129,7 +1151,6 @@ B52DD1BF1BE1F94600949AFE /* AssociatedObjects.swift in Sources */, B52DD1A11BE1F92C00949AFE /* DataStack+Transaction.swift in Sources */, B52DD19E1BE1F92C00949AFE /* AsynchronousDataTransaction.swift in Sources */, - B51F259D1C5787600083A5DD /* DataStack+iCloud.swift in Sources */, B52DD1981BE1F92500949AFE /* CoreStore+Setup.swift in Sources */, B52DD1941BE1F92500949AFE /* CoreStore.swift in Sources */, B52DD1A61BE1F92F00949AFE /* BaseDataTransaction+Importing.swift in Sources */, @@ -1149,6 +1170,8 @@ B52DD1B81BE1F94000949AFE /* DataStack+Migration.swift in Sources */, B52DD1A51BE1F92F00949AFE /* ImportableUniqueObject.swift in Sources */, B52DD19C1BE1F92C00949AFE /* Into.swift in Sources */, + B5FE4DA51C8481E100FA6A91 /* Storage.swift in Sources */, + B5FE4DAA1C84FB4400FA6A91 /* InMemoryStore.swift in Sources */, B52DD1AF1BE1F93900949AFE /* GroupBy.swift in Sources */, B52DD1B01BE1F93900949AFE /* Tweak.swift in Sources */, B52DD1CA1BE1F94600949AFE /* NSManagedObjectModel+Setup.swift in Sources */, @@ -1208,6 +1231,7 @@ B56321A81BD65219006C9394 /* NSManagedObject+Convenience.swift in Sources */, B56321981BD65216006C9394 /* Where.swift in Sources */, B5202CFD1C046E8400DED140 /* NSFetchedResultsController+Convenience.swift in Sources */, + B5FE4DA91C84FB4400FA6A91 /* InMemoryStore.swift in Sources */, B56321AF1BD6521C006C9394 /* NSFileManager+Setup.swift in Sources */, B50392FA1C47963F009900CA /* NSManagedObject+Transaction.swift in Sources */, B56321971BD65216006C9394 /* Select.swift in Sources */, @@ -1215,13 +1239,13 @@ B56321821BD65216006C9394 /* PersistentStoreResult.swift in Sources */, B563219C1BD65216006C9394 /* SectionBy.swift in Sources */, B56321B21BD6521C006C9394 /* NSManagedObjectContext+Querying.swift in Sources */, + B5FE4DA41C8481E100FA6A91 /* Storage.swift in Sources */, B56321B31BD6521C006C9394 /* NSManagedObjectContext+Setup.swift in Sources */, B56321AE1BD6521C006C9394 /* NotificationObserver.swift in Sources */, B56321931BD65216006C9394 /* DataStack+Querying.swift in Sources */, B56321A71BD65216006C9394 /* MigrationResult.swift in Sources */, B56321A11BD65216006C9394 /* ListMonitor.swift in Sources */, B56321881BD65216006C9394 /* BaseDataTransaction.swift in Sources */, - B51F259C1C57875F0083A5DD /* DataStack+iCloud.swift in Sources */, B56321A31BD65216006C9394 /* DataStack+Migration.swift in Sources */, B56321901BD65216006C9394 /* ImportableUniqueObject.swift in Sources */, B56321871BD65216006C9394 /* Into.swift in Sources */, diff --git a/CoreStore/Setting Up/DataStack.swift b/CoreStore/Setting Up/DataStack.swift index d67534b..07fe3f9 100644 --- a/CoreStore/Setting Up/DataStack.swift +++ b/CoreStore/Setting Up/DataStack.swift @@ -123,30 +123,42 @@ public final class DataStack { return self.coordinator.managedObjectIDForURIRepresentation(url) } + @available(*, deprecated=2.0.0, message="Use addStoreAndWait(_:configuration:) by passing an InMemoryStore instance") + public func addInMemoryStoreAndWait(configuration configuration: String? = nil) throws -> NSPersistentStore { + + return try self.addStoreAndWait(InMemoryStore()).internalStore! + } + /** Adds an in-memory store to the stack. - - parameter configuration: an optional configuration name from the model file. If not specified, defaults to `nil`. - - returns: the `NSPersistentStore` added to the stack. + - parameter store: the `AtomicStore`. + - returns: the `AtomicStore` added to the stack. */ - public func addInMemoryStoreAndWait(configuration configuration: String? = nil) throws -> NSPersistentStore { + public func addStoreAndWait(store: T) throws -> T { + + CoreStore.assert( + store.internalStore == nil, + "The specified store was already added to the data stack:\n\(store)" + ) do { - let store = try self.coordinator.addPersistentStoreSynchronously( - NSInMemoryStoreType, - configuration: configuration, - URL: nil, + let persistentStore = try self.coordinator.addPersistentStoreSynchronously( + T.storeType, + configuration: store.configuration, + URL: store.storeURL, options: nil ) - self.updateMetadataForPersistentStore(store) + self.updateMetadataForPersistentStore(persistentStore) + store.internalStore = persistentStore return store } catch { CoreStore.handleError( error as NSError, - "Failed to add in-memory \(typeName(NSPersistentStore)) to the stack." + "Failed to add \(typeName(T)) to the stack." ) throw error } diff --git a/CoreStore/Setting Up/PersistentStores/InMemoryStore.swift b/CoreStore/Setting Up/PersistentStores/InMemoryStore.swift new file mode 100644 index 0000000..cc144c8 --- /dev/null +++ b/CoreStore/Setting Up/PersistentStores/InMemoryStore.swift @@ -0,0 +1,48 @@ +// +// InMemoryStore.swift +// CoreStore +// +// Copyright © 2016 John Rommel Estropia +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// + +import CoreData + + +// MARK: - InMemoryStore + +public class InMemoryStore: AtomicStore { + + public required init(configuration: String? = nil) { + + self.configuration = configuration + } + + + // MARK: PersistentStore + + public static let storeType = NSInMemoryStoreType + + public let storeURL: NSURL? = nil + + public let configuration: String? + + public var internalStore: NSPersistentStore? +} diff --git a/CoreStore/Setting Up/PersistentStores/Storage.swift b/CoreStore/Setting Up/PersistentStores/Storage.swift new file mode 100644 index 0000000..f753a50 --- /dev/null +++ b/CoreStore/Setting Up/PersistentStores/Storage.swift @@ -0,0 +1,48 @@ +// +// Storage.swift +// CoreStore +// +// Copyright © 2016 John Rommel Estropia +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// + + +// MARK: - Storage + +public protocol Storage: class { + + static var storeType: String { get } + + var storeURL: NSURL? { get } + + var configuration: String? { get } + + var internalStore: NSPersistentStore? { get set } +} + + +// MARK: - AtomicStore + +public protocol AtomicStore: Storage { } + + +// MARK: - IncrementalStore + +public protocol IncrementalStore: Storage { } diff --git a/CoreStoreDemo/CoreStoreDemo/Info.plist b/CoreStoreDemo/CoreStoreDemo/Info.plist index 614a3ac..90a8eac 100644 --- a/CoreStoreDemo/CoreStoreDemo/Info.plist +++ b/CoreStoreDemo/CoreStoreDemo/Info.plist @@ -20,6 +20,8 @@ ???? CFBundleVersion 1 + CFBundleDisplayName + CoreStore LSRequiresIPhoneOS UILaunchStoryboardName