<commit_before>//
//  Created by <NAME>
//  http://www.jessesquires.com
//
//
//  Documentation
//  http://www.jessesquires.com/JSQCoreDataKit
//
//
//  GitHub
//  https://github.com/jessesquires/JSQCoreDataKit
//
//
//  License
//  Copyright (c) 2015 <NAME>
//  Released under an MIT license: http://opensource.org/licenses/MIT
//

import Foundation
import CoreData

/**
Attempts to commit unsaved changes to registered objects to the specified context's parent store. 
This function is performed in a block on the context's queue. If the context has no changes,
then this function returns immediately and the completion block is not called.

- parameter context:    The managed object context to save.
- parameter wait:       If true (the default), perform the save synchronously.
- parameter completion: The closure to be executed when the save operation completes.
*/
public func saveContext(context: NSManagedObjectContext, wait: Bool = true, completion: ((NSError?) -> Void)? = nil) {
    guard context.hasChanges else { return }

    let block = { () -> Void in
        do {
            try context.save()
            completion?(nil)
        }
        catch {
            completion?(error as NSError)
        }
    }

    wait ? context.performBlockAndWait(block) : context.performBlock(block)
}

/**
Returns the entity with the specified name from the managed object model associated with 
the specified managed object context’s persistent store coordinator.

- parameter name:    The name of an entity.
- parameter context: The managed object context to use.

- returns: The entity with the specified name from the managed object 
model associated with context’s persistent store coordinator.
*/
public func entity(name name: String, context: NSManagedObjectContext) -> NSEntityDescription {
    return NSEntityDescription.entityForName(name, inManagedObjectContext: context)!
}

/**
An instance of `FetchRequest <T: NSManagedObject>` describes search criteria used to retrieve data from a persistent store.
This is a subclass of `NSFetchRequest` that adds a type parameter specifying the type of managed objects for the fetch request.
The type parameter acts as a phantom type.
*/
public class FetchRequest <T: NSManagedObject>: NSFetchRequest {

    /**
    Constructs a new `FetchRequest` instance.

    - parameter entity: The entity description for the entities that this request fetches.

    - returns: A new `FetchRequest` instance.
    */
    public init(entity: NSEntityDescription) {
        super.init()
        self.entity = entity
    }
}

/**
Executes the fetch request in the given context and returns the result.
This function is performed synchronously in a block on the context's queue.

- parameter request: A fetch request that specifies the search criteria for the fetch.
- parameter context: The managed object context in which to search.

- throws: If the fetch fails or errors, then this function throws an `NSError`.

- returns: An array of objects that meet the criteria specified by the fetch request. This array may be empty.
*/
public func fetch <T: NSManagedObject>(request request: FetchRequest<T>, inContext context: NSManagedObjectContext) throws -> [T] {
    var results = [AnyObject]()
    var caughtError: NSError?

    context.performBlockAndWait { () -> Void in
        do {
            results = try context.executeFetchRequest(request)
        }
        catch {
            caughtError = error as NSError
        }
    }

    guard caughtError == nil else {
        throw caughtError!
    }

    return results as! [T]
}

/**
Deletes the objects from the specified context.<commit_msg>refinements for the extensions. default saveContext to be async instead of sync<commit_after>//
//  Created by <NAME>
//  http://www.jessesquires.com
//
//
//  Documentation
//  http://www.jessesquires.com/JSQCoreDataKit
//
//
//  GitHub
//  https://github.com/jessesquires/JSQCoreDataKit
//
//
//  License
//  Copyright © 2015 <NAME>
//  Released under an MIT license: http://opensource.org/licenses/MIT
//

import CoreData
import Foundation


/**
Attempts to commit unsaved changes to registered objects to the specified context's parent store. 
This function is performed in a block on the context's queue. If the context has no changes,
then this function returns immediately and the completion block is not called.

- parameter context:    The managed object context to save.
- parameter wait:       If false (the default), saves asynchronously. If true, saves synchronously.
- parameter completion: The closure to be executed when the save operation completes.
*/
public func saveContext(context: NSManagedObjectContext, wait: Bool = false, completion: ((NSError?) -> Void)? = nil) {
    guard context.hasChanges else { return }

    let block = { () -> Void in
        do {
            try context.save()
            completion?(nil)
        }
        catch {
            completion?(error as NSError)
        }
    }

    wait ? context.performBlockAndWait(block) : context.performBlock(block)
}


/**
Returns the entity with the specified name from the managed object model associated with 
the specified managed object context’s persistent store coordinator.

- parameter name:    The name of an entity.
- parameter context: The managed object context to use.

- returns: The entity with the specified name from the managed object 
model associated with context’s persistent store coordinator.
*/
public func entity(name name: String, context: NSManagedObjectContext) -> NSEntityDescription {
    return NSEntityDescription.entityForName(name, inManagedObjectContext: context)!
}


/**
An instance of `FetchRequest` describes search criteria used to retrieve data from a persistent store.
This is a subclass of `NSFetchRequest` that adds a type parameter specifying the type of managed objects for the fetch request.
The type parameter acts as a phantom type.
*/
public class FetchRequest <T: NSManagedObject>: NSFetchRequest {

    /**
    Constructs a new `FetchRequest` instance.

    - parameter entity: The entity description for the entities that this request fetches.

    - returns: A new `FetchRequest` instance.
    */
    public init(entity: NSEntityDescription) {
        super.init()
        self.entity = entity
    }
}


/**
Executes the fetch request in the given context and returns the result.
This function is performed synchronously in a block on the context's queue.

- parameter request: A fetch request that specifies the search criteria for the fetch.
- parameter context: The managed object context in which to search.

- throws: If the fetch fails or errors, then this function throws an `NSError`.

- returns: An array of objects that meet the criteria specified by the fetch request. This array may be empty.
*/
public func fetch <T: NSManagedObject>(request request: FetchRequest<T>, inContext context: NSManagedObjectContext) throws -> [T] {
    var results = [AnyObject]()
    var caughtError: NSError?

    context.performBlockAndWait { () -> Void in
        do {
            results = try context.executeFetchRequest(request)
        }
        catch {
            caughtError = error as NSError
        }
    }

    guard caughtError == nil else {
        throw caughtError!
    }

    return results as! [T]
}


/**
Deletes the objects from the specified context.
{'fraction_non_alphanumeric': 0.07992919389978213, 'fraction_numerical': 0.0010893246187363835, 'mean_word_length': 3.2091690544412605, 'pattern_counts': {'":': 0, '<': 14, '<?xml version=': 0, '>': 24, 'https://': 2, 'lorem ipsum': 0, 'www.': 4, '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': '6642754', 'n_tokens_mistral': 1943, 'n_tokens_neox': 1859, 'n_words': 810}