Tighter generics implementations. You can now pass any SequenceType's for methods that previously only accepts Array's.

This commit is contained in:
John Rommel Estropia
2015-09-19 19:45:01 +09:00
parent 114b7ce605
commit 622c5aa652

View File

@@ -67,70 +67,33 @@ public extension BaseDataTransaction {
- parameter into: an `Into` clause specifying the entity type
- parameter sourceArray: the array of objects to import values from
*/
public func importObjects<T where T: NSManagedObject, T: ImportableObject>(
into: Into<T>,
sourceArray: [T.ImportSource]) throws {
CoreStore.assert(
self.bypassesQueueing || self.transactionQueue.isCurrentExecutionContext(),
"Attempted to import an object of type \(typeName(into.entityClass)) outside the transaction's designated queue."
)
try autoreleasepool {
for source in sourceArray {
guard T.shouldInsertFromImportSource(source, inTransaction: self) else {
continue
}
try autoreleasepool {
let object = self.create(into)
try object.didInsertFromImportSource(source, inTransaction: self)
}
}
}
}
/**
Creates multiple `ImportableObject`s by importing from the specified array of import sources.
- parameter into: an `Into` clause specifying the entity type
- parameter sourceArray: the array of objects to import values from
- parameter postProcess: a closure that exposes the array of created objects
- returns: the array of created `ImportableObject` instances
*/
public func importObjects<T, S: SequenceType where T: NSManagedObject, T: ImportableObject, S.Generator.Element == T.ImportSource>(
into: Into<T>,
sourceArray: S,
@noescape postProcess: (sorted: [T]) -> Void) throws {
sourceArray: S) throws -> [T] {
CoreStore.assert(
self.bypassesQueueing || self.transactionQueue.isCurrentExecutionContext(),
"Attempted to import an object of type \(typeName(into.entityClass)) outside the transaction's designated queue."
)
try autoreleasepool {
return try autoreleasepool {
var objects = [T]()
for source in sourceArray {
return try sourceArray.flatMap { (source) -> T? in
guard T.shouldInsertFromImportSource(source, inTransaction: self) else {
continue
return nil
}
try autoreleasepool {
return try autoreleasepool {
let object = self.create(into)
try object.didInsertFromImportSource(source, inTransaction: self)
objects.append(object)
return object
}
}
postProcess(sorted: objects)
}
}
@@ -184,102 +147,32 @@ public extension BaseDataTransaction {
- parameter into: an `Into` clause specifying the entity type
- parameter sourceArray: the array of objects to import values from
- parameter preProcess: a closure that lets the caller tweak the internal `UniqueIDType`-to-`ImportSource` mapping to be used for importing. Callers can remove from/add to/update `mapping` and return the updated array from the closure.
- returns: the array of created/updated `ImportableUniqueObject` instances
*/
public func importUniqueObjects<T, S: SequenceType where T: NSManagedObject, T: ImportableUniqueObject, S.Generator.Element == T.ImportSource>(
into: Into<T>,
sourceArray: S,
@noescape preProcess: (mapping: [T.UniqueIDType: T.ImportSource]) throws -> [T.UniqueIDType: T.ImportSource] = { $0 }) throws {
@noescape preProcess: (mapping: [T.UniqueIDType: T.ImportSource]) throws -> [T.UniqueIDType: T.ImportSource] = { $0 }) throws -> [T] {
CoreStore.assert(
self.bypassesQueueing || self.transactionQueue.isCurrentExecutionContext(),
"Attempted to import an object of type \(typeName(into.entityClass)) outside the transaction's designated queue."
)
try autoreleasepool {
return try autoreleasepool {
var mapping = Dictionary<T.UniqueIDType, T.ImportSource>()
for source in sourceArray {
let sortedIDs = try autoreleasepool {
try autoreleasepool {
return try sourceArray.flatMap { (source) -> T.UniqueIDType? in
guard let uniqueIDValue = try T.uniqueIDFromImportSource(source, inTransaction: self) else {
return
return nil
}
mapping[uniqueIDValue] = source
}
}
mapping = try autoreleasepool { try preProcess(mapping: mapping) }
for object in self.fetchAll(From(T), Where(T.uniqueIDKeyPath, isMemberOf: mapping.keys)) ?? [] {
try autoreleasepool {
let uniqueIDValue = object.uniqueIDValue
guard let source = mapping.removeValueForKey(uniqueIDValue)
where T.shouldUpdateFromImportSource(source, inTransaction: self) else {
return
}
try object.updateFromImportSource(source, inTransaction: self)
}
}
for (uniqueIDValue, source) in mapping {
try autoreleasepool {
guard T.shouldInsertFromImportSource(source, inTransaction: self) else {
return
}
let object = self.create(into)
object.uniqueIDValue = uniqueIDValue
try object.didInsertFromImportSource(source, inTransaction: self)
}
}
}
}
/**
Updates existing `ImportableUniqueObject`s or creates them by importing from the specified array of import sources.
- parameter into: an `Into` clause specifying the entity type
- parameter sourceArray: the array of objects to import values from
- parameter preProcess: a closure that lets the caller tweak the internal `UniqueIDType`-to-`ImportSource` mapping to be used for importing. Callers can remove from/add to/update `mapping` and return the updated array from the closure.
- parameter postProcess: a closure that exposes the array of created/updated objects
*/
public func importUniqueObjects<T, S: SequenceType where T: NSManagedObject, T: ImportableUniqueObject, S.Generator.Element == T.ImportSource>(
into: Into<T>,
sourceArray: S,
@noescape preProcess: (mapping: [T.UniqueIDType: T.ImportSource]) throws -> [T.UniqueIDType: T.ImportSource] = { $0 },
@noescape postProcess: (sorted: [T]) -> Void) throws {
CoreStore.assert(
self.bypassesQueueing || self.transactionQueue.isCurrentExecutionContext(),
"Attempted to import an object of type \(typeName(into.entityClass)) outside the transaction's designated queue."
)
try autoreleasepool {
var sortedIDs = Array<T.UniqueIDType>()
var mapping = Dictionary<T.UniqueIDType, T.ImportSource>()
for source in sourceArray {
try autoreleasepool {
guard let uniqueIDValue = try T.uniqueIDFromImportSource(source, inTransaction: self) else {
return
}
mapping[uniqueIDValue] = source
sortedIDs.append(uniqueIDValue)
return uniqueIDValue
}
}
@@ -320,7 +213,7 @@ public extension BaseDataTransaction {
}
}
postProcess(sorted: sortedIDs.flatMap { objects[$0] })
return sortedIDs.flatMap { objects[$0] }
}
}
}