<commit_before>//
//  CoreDataDAO.swift
//  ADGCoreDataKit
//
//  Created by <NAME>

// The MIT License (MIT)
//
// Copyright (c) 2015 <NAME> @alejandrogarin
//
// 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

public class CoreDataDAO<T: NSManagedObject> {
    
    private let coreDataContext: CoreDataContext
    
    /*!
    * @brief if this flag is true every core data operation will be saved to the store. If you are not autocommitting you should
    * call commit() after adding/updating/removing data
    */
    public var autocommit = true
    
    public var entityName:String {
        return self.guessEntityName()
    }
    
    public init(usingContext context: CoreDataContext) {
        self.coreDataContext = context
    }
    
    public func insert(map map: [String : AnyObject]) throws -> T {
        return try self.insert(entityName: entityName, map: map)
    }
    
    public func insert(entityName entityName: String, map: [String: AnyObject?]) throws -> T {
        let managedObject = self.coreDataContext.insertObjectForEntity(entityName)
        for key in map.keys {
            if let value = map[key] {
                managedObject.setValue(value, forKey: key)
            } else {
                managedObject.setValue(nil, forKey: key)
            }
        }
        try self.saveIfAutocommit()
        guard let managedEntity = managedObject as? T else {
            throw CoreDataKitError.CannotCastManagedObject
        }
        return managedEntity
    }
    
    public func update(objectId objectId: String, map: [String:AnyObject?]) throws -> T {
        let managedObject: T = try self.findObjectById(objectId: objectId)
        for key in map.keys {
            let maybeValue: AnyObject? = map[key]!
            (managedObject as NSManagedObject).setValue(maybeValue, forKey: key)
        }
        try self.saveIfAutocommit()
        return managedObject
    }
    
    public func update(managedObject mo: NSManagedObject, map: [String:AnyObject?]) throws {
        for key in map.keys {
            let maybeValue: AnyObject? = map[key]!
            mo.setValue(maybeValue, forKey: key)
        }
        try self.saveIfAutocommit()
    }

    private func findObjectsByEntity(entityName : String, sortKey: String?, ascending: Bool?, predicate: NSPredicate?, page: Int?, pageSize: Int?) throws -> [T] {
        let list: [AnyObject] = try self.coreDataContext.findObjectsByEntity(entityName, sortKey: sortKey, ascending: ascending, predicate: predicate, page: page, pageSize: pageSize)
        var newArray : [T] = []
        for anyObject in list {
            if let anyObject = anyObject as? T {
                newArray.append(anyObject)
            }
        }
        return newArray
    }
    
    public func countObjectsByEntity(entityName: String, predicate: NSPredicate?) throws -> Int {
        return try self.coreDataContext.countObjectsByEntity(entityName, predicate: predicate)
    }
    
    public func findObjectsByEntity(entityName: String) throws -> [T] {
        return try self.findObjectsByEntity(entityName, sortKey: nil, ascending: nil, predicate: nil, page: nil, pageSize: nil)
    }
    
    public func findObjectsByEntity(entityName: String, predicate: NSPredicate) throws -> [T] {
        return try self.findObjectsByEntity(entityName, sortKey: nil, ascending: nil, predicate: predicate, page: nil, pageSize: nil)
    }
    
    public func findObjectsByEntity(entityName: String, withSortKey sortKey: String) throws -> [T] {
        return try self.findObjectsByEntity(entityName, sortKey: sortKey, ascending: true, predicate: nil, page: nil, pageSize: nil)
    }
    
    public func findObjectsByEntity(entityName: String, withSortKey sortKey: String, predicate: NSPredicate) throws -> [T] {
        return try self.findObjectsByEntity(entityName, sortKey: sortKey, ascending: true, predicate: predicate, page: nil, pageSize: nil)
    }
    
    public func findObjectsByEntity(entityName: String, withSortKey sortKey: String, ascending: Bool, predicate: NSPredicate) throws -> [T] {
        return try self.findObjectsByEntity(entityName, sortKey: sortKey, ascending: ascending, predicate: predicate, page: nil, pageSize: nil)
    }
    
    public func findObjectsByEntity(entityName: String, withSortKey sortKey: String, page: Int, pageSize: Int) throws -> [T] {
        return try self.findObjectsByEntity(entityName, sortKey: sortKey, ascending: true, predicate: nil, page: page, pageSize: pageSize)
    }
    
    public func findObjectsByEntity() throws -> [T] {
        return try self.findObjectsByEntity(self.entityName)
    }
    
    public func findObjectsByEntity(sortKey sortKey: String) throws -> [T] {
        return try self.findObjectsByEntity(self.entityName, withSortKey: sortKey)
    }
    
    public func findObjectsByEntity(predicate predicate: NSPredicate) throws -> [T] {
        return try self.findObjectsByEntity(self.entityName, predicate: predicate)
    }
    <commit_msg>added a new method to pass the ascending for the how the ordering is made<commit_after>//
//  CoreDataDAO.swift
//  ADGCoreDataKit
//
//  Created by <NAME>

// The MIT License (MIT)
//
// Copyright (c) 2015 <NAME> @alejandrogarin
//
// 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

public class CoreDataDAO<T: NSManagedObject> {
    
    private let coreDataContext: CoreDataContext
    
    /*!
    * @brief if this flag is true every core data operation will be saved to the store. If you are not autocommitting you should
    * call commit() after adding/updating/removing data
    */
    public var autocommit = true
    
    public var entityName:String {
        return self.guessEntityName()
    }
    
    public init(usingContext context: CoreDataContext) {
        self.coreDataContext = context
    }
    
    public func insert(map map: [String : AnyObject]) throws -> T {
        return try self.insert(entityName: entityName, map: map)
    }
    
    public func insert(entityName entityName: String, map: [String: AnyObject?]) throws -> T {
        let managedObject = self.coreDataContext.insertObjectForEntity(entityName)
        for key in map.keys {
            if let value = map[key] {
                managedObject.setValue(value, forKey: key)
            } else {
                managedObject.setValue(nil, forKey: key)
            }
        }
        try self.saveIfAutocommit()
        guard let managedEntity = managedObject as? T else {
            throw CoreDataKitError.CannotCastManagedObject
        }
        return managedEntity
    }
    
    public func update(objectId objectId: String, map: [String:AnyObject?]) throws -> T {
        let managedObject: T = try self.findObjectById(objectId: objectId)
        for key in map.keys {
            let maybeValue: AnyObject? = map[key]!
            (managedObject as NSManagedObject).setValue(maybeValue, forKey: key)
        }
        try self.saveIfAutocommit()
        return managedObject
    }
    
    public func update(managedObject mo: NSManagedObject, map: [String:AnyObject?]) throws {
        for key in map.keys {
            let maybeValue: AnyObject? = map[key]!
            mo.setValue(maybeValue, forKey: key)
        }
        try self.saveIfAutocommit()
    }

    private func findObjectsByEntity(entityName : String, sortKey: String?, ascending: Bool?, predicate: NSPredicate?, page: Int?, pageSize: Int?) throws -> [T] {
        let list: [AnyObject] = try self.coreDataContext.findObjectsByEntity(entityName, sortKey: sortKey, ascending: ascending, predicate: predicate, page: page, pageSize: pageSize)
        var newArray : [T] = []
        for anyObject in list {
            if let anyObject = anyObject as? T {
                newArray.append(anyObject)
            }
        }
        return newArray
    }
    
    public func countObjectsByEntity(entityName: String, predicate: NSPredicate?) throws -> Int {
        return try self.coreDataContext.countObjectsByEntity(entityName, predicate: predicate)
    }
    
    public func findObjectsByEntity(entityName: String) throws -> [T] {
        return try self.findObjectsByEntity(entityName, sortKey: nil, ascending: nil, predicate: nil, page: nil, pageSize: nil)
    }
    
    public func findObjectsByEntity(entityName: String, predicate: NSPredicate) throws -> [T] {
        return try self.findObjectsByEntity(entityName, sortKey: nil, ascending: nil, predicate: predicate, page: nil, pageSize: nil)
    }
    
    public func findObjectsByEntity(entityName: String, withSortKey sortKey: String) throws -> [T] {
        return try self.findObjectsByEntity(entityName, sortKey: sortKey, ascending: true, predicate: nil, page: nil, pageSize: nil)
    }
    
    public func findObjectsByEntity(entityName: String, withSortKey sortKey: String, predicate: NSPredicate) throws -> [T] {
        return try self.findObjectsByEntity(entityName, sortKey: sortKey, ascending: true, predicate: predicate, page: nil, pageSize: nil)
    }
    
    public func findObjectsByEntity(entityName: String, withSortKey sortKey: String, ascending: Bool, predicate: NSPredicate) throws -> [T] {
        return try self.findObjectsByEntity(entityName, sortKey: sortKey, ascending: ascending, predicate: predicate, page: nil, pageSize: nil)
    }
    
    public func findObjectsByEntity(entityName: String, withSortKey sortKey: String, ascending: Bool, predicate: NSPredicate, page: Int, pageSize: Int) throws -> [T] {
        return try self.findObjectsByEntity(entityName, sortKey: sortKey, ascending: ascending, predicate: predicate, page: page, pageSize: pageSize)
    }
    
    public func findObjectsByEntity(entityName: String, withSortKey sortKey: String, page: Int, pageSize: Int) throws -> [T] {
        return try self.findObjectsByEntity(entityName, sortKey: sortKey, ascending: true, predicate: nil, page: page, pageSize: pageSize)
    }
    
    public func findObjectsByEntity() throws -> [T] {
        return try self.findObjectsByEntity(self.entityName)
    }
    
    public func findObjectsByEntity(sortKey sortKey: String) throws -> [T] {
        return try self.findObjectsByEntity(self.entityName, withSortKey: sortKey)
    }
    
    public func findObjectsByEntity(predicate predicate: NSPredicate) throws -> [T] {
        return try self.findObjectsByEntity(self.entityName, predicate: predicate)
    }
    
{'fraction_non_alphanumeric': 0.08665011612076559, 'fraction_numerical': 0.0006406662929446625, 'mean_word_length': 3.114662273476112, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 38, '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': '2241322', 'n_tokens_mistral': 3476, 'n_tokens_neox': 3355, 'n_words': 1184}