<commit_before>//
//  DataManager.swift
//  DataManager
//
//  Copyright (c) 2016 Metova Inc.
//
//  MIT License
//
//  Permission is hereby granted, free of charge, to any person obtaining
//  a copy of this software and associated documentation files (the
//  "Software"), to deal in the Software without restriction, including
//  without limitation the rights to use, copy, modify, merge, publish,
//  distribute, sublicense, and/or sell copies of the Software, and to
//  permit persons to whom the Software is furnished to do so, subject to
//  the following conditions:
//
//  The above copyright notice and this permission notice shall be
//  included in all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
//  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
//  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
//  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
//  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
//  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
//  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//

import Foundation
import CoreData

// MARK: - PersistentStoreType

public enum PersistentStoreType {
    
    case SQLite
    case Binary
    case InMemory
    
    var stringValue: String {
        switch self {
        case .SQLite:
            return NSSQLiteStoreType
        case .Binary:
            return NSBinaryStoreType
        case .InMemory:
            return NSInMemoryStoreType
        }
    }
}



// MARK: - Constants

private struct Constants {
    
    static private let mustCallSetupMethodErrorMessage = "DataManager must be set up using setUpWithDataModelName(_:persistentStoreType:) before it can be used."
}



// MARK: - DataManager

public final class DataManager {
    
    // MARK: Properties
    
    static var dataModelName: String?
    static var dataModelBundle: NSBundle?
    static var persistentStoreName: String?
    static var persistentStoreType = PersistentStoreType.SQLite
    
    public static var defaultFetchBatchSize = 50
    public static var shouldSuppressLogs = false
    
    
    
    // MARK: Setup
    
    /**
     This method must be called before DataManager can be used. It provides DataManager with the required information for setting up the Core Data stack. Call this in application(_:didFinishLaunchingWithOptions:).
     
     - parameter dataModelName:       The name of the data model schema file.
     - parameter dataModelBundle:     The bundle in which the data model schema file resides.
     - parameter persistentStoreName: The name of the persistent store.
     - parameter persistentStoreType: The persistent store type. Defaults to SQLite.
     */
    public static func setUpWithDataModelName(dataModelName: String, dataModelBundle: NSBundle? = nil, persistentStoreName: String, persistentStoreType: PersistentStoreType = .SQLite) {
        
        DataManager.dataModelName = dataModelName
        DataManager.dataModelBundle = dataModelBundle ?? NSBundle.mainBundle()
        DataManager.persistentStoreName = persistentStoreName
        DataManager.persistentStoreType = persistentStoreType
    }
    
    
    
    // MARK: Core Data Stack
    
    private static var applicationDocumentsDirectory: NSURL = {
        
        let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
        return urls[urls.count - 1]
    }()
    
    
    
    private static var managedObjectModel: NSManagedObjectModel = {
        
        guard let dataModelName = DataManager.dataModelName else {
            fatalError("Attempting to use nil data model name. \(Constants.mustCallSetupMethodErrorMessage)")
        }
        
        guard let modelURL = DataManager.dataModelBundle?.URLForResource(DataManager.dataModelName, withExtension: "momd") else {
            fatalError("Failed to locate data model schema file.")
        }
        
        guard let managedObjectModel = NSManagedObjectModel(contentsOfURL: modelURL) else {
            fatalError("Failed to created managed object model")
        }
        
        return managedObjectModel
    }()
    
    
    
    private static var persistentStoreCoordinator: NSPersistentStoreCoordinator = {
        
        guard let persistentStoreName = DataManager.persistentStoreName else {
            fatalError("Attempting to use nil persistent store name. \(Constants.mustCallSetupMethodErrorMessage)")
        }
        
        let coordinator = NSPersistentStoreCoordinator(managedObjectModel: DataManager.managedObjectModel)
        let url = DataManager.applicationDocumentsDirectory.URLByAppendingPathComponent("\(DataManager.persistentStoreName).sqlite")
        
        let options: Dictionary? = [
            NSMigratePersistentStoresAutomaticallyOption: true,
            NSInferMappingModelAutomaticallyOption: true
        ]
        
        do {
            try coordinator.addPersistentStoreWithType(DataManager.persistentStoreType.stringValue, configuration: nil, URL: url, options: options)
        }
        catch let error as NSError {
            fatalError("Failed to initialize the application's persistent data: \(error.localizedDescription)")
        }
        catch {
            fatalError("Failed to initialize the application's persistent data")
        }
        
        return coordinator
    }()
    
    
    
    private static var privateContext: NSManagedObjectContext = {
        
        let context = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType)
        context.persistentStoreCoordinator = DataManager.persistentStoreCoordinator
        return context
    }()
    
    
    
        /// A MainQueueConcurrencyType context whose parent is a PrivateQueueConcurrencyType context. The PrivateQueueConcurrencyType context is the root context.
    public static var mainContext: NSManagedObjectContext = {
        
        let context = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
        context.parentContext = DataManager.privateContext
        return context<commit_msg>Added documentation for all public API.<commit_after>//
//  DataManager.swift
//  DataManager
//
//  Copyright (c) 2016 Metova Inc.
//
//  MIT License
//
//  Permission is hereby granted, free of charge, to any person obtaining
//  a copy of this software and associated documentation files (the
//  "Software"), to deal in the Software without restriction, including
//  without limitation the rights to use, copy, modify, merge, publish,
//  distribute, sublicense, and/or sell copies of the Software, and to
//  permit persons to whom the Software is furnished to do so, subject to
//  the following conditions:
//
//  The above copyright notice and this permission notice shall be
//  included in all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
//  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
//  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
//  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
//  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
//  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
//  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//

import Foundation
import CoreData

// MARK: - PersistentStoreType

/// An enumeration of the three string constants that are used for specifying the persistent store type (NSSQLiteStoreType, NSBinaryStoreType, NSInMemoryStoreType).
public enum PersistentStoreType {
    
    /// Represents the value for NSSQLiteStoreType.
    case SQLite
    
    /// Represents the value for NSBinaryStoreType.
    case Binary
    
    /// Represents the value for NSInMemoryStoreType.
    case InMemory
    
    /// Value of the Core Data string constants corresponding to each case.
    private var stringValue: String {
        switch self {
        case .SQLite:
            return NSSQLiteStoreType
        case .Binary:
            return NSBinaryStoreType
        case .InMemory:
            return NSInMemoryStoreType
        }
    }
}



// MARK: - Constants

private struct Constants {
    
    static private let mustCallSetupMethodErrorMessage = "DataManager must be set up using setUpWithDataModelName(_:persistentStoreType:) before it can be used."
}



// MARK: - DataManager

/**
 Responsible for setting up the Core Data stack. Also provides some convenience methods for fetching, deleting, and saving.
 */
public final class DataManager {
    
    // MARK: Properties
    
    private static var dataModelName: String?
    private static var dataModelBundle: NSBundle?
    private static var persistentStoreName: String?
    private static var persistentStoreType = PersistentStoreType.SQLite
    
    /// The value to use for `fetchBatchSize` when fetching objects.
    public static var defaultFetchBatchSize = 50
    
    /// When set to `true`, DataManager does not emit any logs to the console.
    public static var shouldSuppressLogs = false
    
    
    
    // MARK: Setup
    
    /**
     This method must be called before DataManager can be used. It provides DataManager with the required information for setting up the Core Data stack. Call this in application(_:didFinishLaunchingWithOptions:).
     
     - parameter dataModelName:       The name of the data model schema file.
     - parameter dataModelBundle:     The bundle in which the data model schema file resides.
     - parameter persistentStoreName: The name of the persistent store.
     - parameter persistentStoreType: The persistent store type. Defaults to SQLite.
     */
    public static func setUpWithDataModelName(dataModelName: String, dataModelBundle: NSBundle? = nil, persistentStoreName: String, persistentStoreType: PersistentStoreType = .SQLite) {
        
        DataManager.dataModelName = dataModelName
        DataManager.dataModelBundle = dataModelBundle ?? NSBundle.mainBundle()
        DataManager.persistentStoreName = persistentStoreName
        DataManager.persistentStoreType = persistentStoreType
    }
    
    
    
    // MARK: Core Data Stack
    
    private static var applicationDocumentsDirectory: NSURL = {
        
        let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
        return urls[urls.count - 1]
    }()
    
    
    
    private static var managedObjectModel: NSManagedObjectModel = {
        
        guard let dataModelName = DataManager.dataModelName else {
            fatalError("Attempting to use nil data model name. \(Constants.mustCallSetupMethodErrorMessage)")
        }
        
        guard let modelURL = DataManager.dataModelBundle?.URLForResource(DataManager.dataModelName, withExtension: "momd") else {
            fatalError("Failed to locate data model schema file.")
        }
        
        guard let managedObjectModel = NSManagedObjectModel(contentsOfURL: modelURL) else {
            fatalError("Failed to created managed object model")
        }
        
        return managedObjectModel
    }()
    
    
    
    private static var persistentStoreCoordinator: NSPersistentStoreCoordinator = {
        
        guard let persistentStoreName = DataManager.persistentStoreName else {
            fatalError("Attempting to use nil persistent store name. \(Constants.mustCallSetupMethodErrorMessage)")
        }
        
        let coordinator = NSPersistentStoreCoordinator(managedObjectModel: DataManager.managedObjectModel)
        let url = DataManager.applicationDocumentsDirectory.URLByAppendingPathComponent("\(DataManager.persistentStoreName).sqlite")
        
        let options: Dictionary? = [
            NSMigratePersistentStoresAutomaticallyOption: true,
            NSInferMappingModelAutomaticallyOption: true
        ]
        
        do {
            try coordinator.addPersistentStoreWithType(DataManager.persistentStoreType.stringValue, configuration: nil, URL: url, options: options)
        }
        catch let error as NSError {
            fatalError("Failed to initialize the application's persistent data: \(error.localizedDescription)")
        }
        catch {
            fatalError("Failed to initialize the application's persistent data")
        }
        
        return coordinator
    }()
    
    
    
    private static var privateContext: NSManagedObjectContext = {
        
        let context = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType)
        context.persistentStoreCoordinator = DataManager.persistentStoreCoordinator
        return context
    }()
    
    
    
    /// A MainQueueConcurrencyType context whose parent is a PrivateQueueConcurrencyType context. The PrivateQueueConcurrencyType context is the root context.
    public static var mainContext: NSManagedObjectContext = {
        
        let context = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
        context.parentContext = DataManager.privateContext
        return context
{'fraction_non_alphanumeric': 0.06030188679245283, 'fraction_numerical': 0.0010566037735849057, 'mean_word_length': 2.824242424242424, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1327075', 'n_tokens_mistral': 3284, 'n_tokens_neox': 3191, 'n_words': 1132}