Swift Package Manager support

This commit is contained in:
John Estropia
2016-03-09 17:47:46 +09:00
parent 40c27b9fcb
commit c86ca06bd4
74 changed files with 42 additions and 25 deletions

View File

@@ -0,0 +1,60 @@
//
// 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: StorageInterface, DefaultInitializableStore {
public required init(configuration: String?) {
self.configuration = configuration
}
// MARK: DefaultInitializableStore
public required init() {
self.configuration = nil
}
// MARK: StorageInterface
public static let storeType = NSInMemoryStoreType
public static func validateStoreURL(storeURL: NSURL?) -> Bool {
return storeURL == nil
}
public let configuration: String?
public let storeOptions: [String: AnyObject]? = nil
public var internalStore: NSPersistentStore?
}

View File

@@ -0,0 +1,88 @@
//
// LegacySQLiteStore.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 Foundation
// MARK: - LegacySQLiteStore
public final class LegacySQLiteStore: SQLiteStore {
public required init(fileURL: NSURL, configuration: String? = nil, mappingModelBundles: [NSBundle] = NSBundle.allBundles(), resetStoreOnModelMismatch: Bool = false) {
super.init(
fileURL: fileURL,
configuration: configuration,
mappingModelBundles: mappingModelBundles,
resetStoreOnModelMismatch: resetStoreOnModelMismatch
)
}
/**
Initializes an SQLite store interface from the given SQLite file name. When this instance is passed to the `DataStack`'s `addStorage()` methods, a new SQLite file will be created if it does not exist.
- parameter fileName: the local filename for the SQLite persistent store in the "Application Support/<bundle id>" directory (or the "Caches/<bundle id>" directory on tvOS). Note that if you have multiple configurations, you will need to specify a different `fileName` explicitly for each of them.
- parameter configuration: an optional configuration name from the model file. If not specified, defaults to `nil`, the "Default" configuration. Note that if you have multiple configurations, you will need to specify a different `fileName` explicitly for each of them.
- parameter resetStoreOnModelMismatch: When the `SQLiteStore` is passed to the `DataStack`'s `addStorage()` methods, a true value tells the `DataStack` to delete the store on model mismatch; a false value lets exceptions be thrown on failure instead. Typically should only be set to true when debugging, or if the persistent store can be recreated easily. If not specified, defaults to false.
*/
public required init(fileName: String, configuration: String? = nil, mappingModelBundles: [NSBundle] = NSBundle.allBundles(), resetStoreOnModelMismatch: Bool = false) {
super.init(
fileURL: LegacySQLiteStore.legacyDefaultRootDirectory.URLByAppendingPathComponent(
fileName,
isDirectory: false
),
configuration: configuration,
mappingModelBundles: mappingModelBundles,
resetStoreOnModelMismatch: resetStoreOnModelMismatch
)
}
// MARK: DefaultInitializableStore
public required init() {
super.init(fileURL: LegacySQLiteStore.legacyDefaultFileURL)
}
// MARK: Internal
#if os(tvOS)
internal static let systemDirectorySearchPath = NSSearchPathDirectory.CachesDirectory
#else
internal static let systemDirectorySearchPath = NSSearchPathDirectory.ApplicationSupportDirectory
#endif
internal static let legacyDefaultRootDirectory = NSFileManager.defaultManager().URLsForDirectory(
LegacySQLiteStore.systemDirectorySearchPath,
inDomains: .UserDomainMask
).first!
internal static let legacyDefaultFileURL = LegacySQLiteStore.legacyDefaultRootDirectory
.URLByAppendingPathComponent(DataStack.applicationName, isDirectory: false)
.URLByAppendingPathExtension("sqlite")
}

View File

@@ -0,0 +1,146 @@
//
// SQLiteStore.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: - SQLiteStore
public class SQLiteStore: LocalStorage, DefaultInitializableStore {
/**
Initializes an SQLite store interface from the given SQLite file URL. When this instance is passed to the `DataStack`'s `addStorage()` methods, a new SQLite file will be created if it does not exist.
- parameter fileURL: the local file URL for the target SQLite persistent store. If not specified, defaults to a file URL pointing to a "<Application name>.sqlite" file in the "Application Support/<bundle id>" directory (or the "Caches/<bundle id>" directory on tvOS). Note that if you have multiple configurations, you will need to specify a different `fileURL` explicitly for each of them.
- parameter configuration: an optional configuration name from the model file. If not specified, defaults to `nil`, the "Default" configuration. Note that if you have multiple configurations, you will need to specify a different `fileURL` explicitly for each of them.
- parameter resetStoreOnModelMismatch: When the `SQLiteStore` is passed to the `DataStack`'s `addStorage()` methods, a true value tells the `DataStack` to delete the store on model mismatch; a false value lets exceptions be thrown on failure instead. Typically should only be set to true when debugging, or if the persistent store can be recreated easily. If not specified, defaults to false.
*/
public required init(fileURL: NSURL, configuration: String? = nil, mappingModelBundles: [NSBundle] = NSBundle.allBundles(), resetStoreOnModelMismatch: Bool = false) {
self.fileURL = fileURL
self.configuration = configuration
self.mappingModelBundles = mappingModelBundles
self.resetStoreOnModelMismatch = resetStoreOnModelMismatch
}
/**
Initializes an SQLite store interface from the given SQLite file name. When this instance is passed to the `DataStack`'s `addStorage()` methods, a new SQLite file will be created if it does not exist.
- parameter fileName: the local filename for the SQLite persistent store in the "Application Support/<bundle id>" directory (or the "Caches/<bundle id>" directory on tvOS). Note that if you have multiple configurations, you will need to specify a different `fileName` explicitly for each of them.
- parameter configuration: an optional configuration name from the model file. If not specified, defaults to `nil`, the "Default" configuration. Note that if you have multiple configurations, you will need to specify a different `fileName` explicitly for each of them.
- parameter resetStoreOnModelMismatch: When the `SQLiteStore` is passed to the `DataStack`'s `addStorage()` methods, a true value tells the `DataStack` to delete the store on model mismatch; a false value lets exceptions be thrown on failure instead. Typically should only be set to true when debugging, or if the persistent store can be recreated easily. If not specified, defaults to false.
*/
public required init(fileName: String, configuration: String? = nil, mappingModelBundles: [NSBundle] = NSBundle.allBundles(), resetStoreOnModelMismatch: Bool = false) {
self.fileURL = SQLiteStore.defaultRootDirectory
.URLByAppendingPathComponent(fileName, isDirectory: false)
self.configuration = configuration
self.mappingModelBundles = mappingModelBundles
self.resetStoreOnModelMismatch = resetStoreOnModelMismatch
}
// MARK: DefaultInitializableStore
public required init() {
self.fileURL = SQLiteStore.defaultFileURL
self.configuration = nil
self.mappingModelBundles = NSBundle.allBundles()
self.resetStoreOnModelMismatch = false
}
// MAKR: LocalStorage
public let fileURL: NSURL
public let resetStoreOnModelMismatch: Bool
// MARK: StorageInterface
public static let storeType = NSSQLiteStoreType
public static func validateStoreURL(storeURL: NSURL?) -> Bool {
return storeURL?.fileURL == true
}
public let configuration: String?
public let storeOptions: [String: AnyObject]? = [NSSQLitePragmasOption: ["journal_mode": "WAL"]]
public let mappingModelBundles: [NSBundle]
public var internalStore: NSPersistentStore?
public func eraseStorageAndWait(soureModel soureModel: NSManagedObjectModel) throws {
// TODO: check if attached to persistent store
let fileURL = self.fileURL
try autoreleasepool {
let journalUpdatingCoordinator = NSPersistentStoreCoordinator(managedObjectModel: soureModel)
let store = try journalUpdatingCoordinator.addPersistentStoreWithType(
self.dynamicType.storeType,
configuration: self.configuration,
URL: fileURL,
options: [NSSQLitePragmasOption: ["journal_mode": "DELETE"]]
)
try journalUpdatingCoordinator.removePersistentStore(store)
try NSFileManager.defaultManager().removeItemAtURL(fileURL)
}
}
// MARK: Internal
internal static let defaultRootDirectory: NSURL = {
#if os(tvOS)
let systemDirectorySearchPath = NSSearchPathDirectory.CachesDirectory
#else
let systemDirectorySearchPath = NSSearchPathDirectory.ApplicationSupportDirectory
#endif
let defaultSystemDirectory = NSFileManager
.defaultManager()
.URLsForDirectory(systemDirectorySearchPath, inDomains: .UserDomainMask).first!
return defaultSystemDirectory.URLByAppendingPathComponent(
NSBundle.mainBundle().bundleIdentifier ?? "com.CoreStore.DataStack",
isDirectory: true
)
}()
internal static let defaultFileURL: NSURL = {
let applicationName = (NSBundle.mainBundle().objectForInfoDictionaryKey("CFBundleName") as? String) ?? "CoreData"
return SQLiteStore.defaultRootDirectory
.URLByAppendingPathComponent(applicationName, isDirectory: false)
.URLByAppendingPathExtension("sqlite")
}()
}

View File

@@ -0,0 +1,59 @@
//
// StorageInterface.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: - StorageInterface
public protocol StorageInterface: class {
static var storeType: String { get }
var configuration: String? { get }
var storeOptions: [String: AnyObject]? { get }
var internalStore: NSPersistentStore? { get set }
}
// MARK: - DefaultInitializableStore
public protocol DefaultInitializableStore: StorageInterface {
init()
}
// MARK: - LocalStorage
public protocol LocalStorage: StorageInterface {
var fileURL: NSURL { get }
var mappingModelBundles: [NSBundle] { get }
var resetStoreOnModelMismatch: Bool { get }
func eraseStorageAndWait(soureModel soureModel: NSManagedObjectModel) throws
}