Skip to content

Instantly share code, notes, and snippets.

@yccheok
Created December 10, 2023 18:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yccheok/8c42536adf986222f047ec56b37a7b0a to your computer and use it in GitHub Desktop.
Save yccheok/8c42536adf986222f047ec56b37a7b0a to your computer and use it in GitHub Desktop.
Update "order" column using Batch Update Operation
private func _updateOrdersIfPossible2(context: NSManagedObjectContext, updateOrders: [UpdateOrder]) {
let count = updateOrders.count
if count < 2 {
return
}
var prevOrder = updateOrders[0].order
var updatedObjectIDs = [NSManagedObjectID]()
if !Utils.isValidOrder(prevOrder) {
prevOrder = prevOrder - 1
precondition(Utils.isValidOrder(prevOrder))
// Time-consuming operation.
if let updatedObjectID = _updateWithoutMerge(context: context, objectID: updateOrders[0].objectID, propertiesToUpdate: [
"order": prevOrder
]) {
updatedObjectIDs.append(updatedObjectID)
}
}
for index in 1..<count {
precondition(Utils.isValidOrder(prevOrder))
let updateOrder = updateOrders[index]
if !Utils.isValidOrder(updateOrder.order) || updateOrder.order <= prevOrder {
var newOrder = prevOrder + 1
if !Utils.isValidOrder(newOrder) {
newOrder = newOrder + 1
}
precondition(newOrder > prevOrder)
prevOrder = newOrder
precondition(Utils.isValidOrder(newOrder))
// Time-consuming operation.
if let updatedObjectID = _updateWithoutMerge(context: context, objectID: updateOrder.objectID, propertiesToUpdate: [
"order": newOrder
]) {
updatedObjectIDs.append(updatedObjectID)
}
} else {
// Skip from updating. Fast!
prevOrder = updateOrder.order
}
} // for index in 1..<count
if !updatedObjectIDs.isEmpty {
let changes = [NSUpdatedObjectsKey : updatedObjectIDs]
CoreDataStack.INSTANCE.mergeChanges(changes)
}
}
private func _updateWithoutMerge(context: NSManagedObjectContext, objectID: NSManagedObjectID, propertiesToUpdate: [AnyHashable : Any]) -> NSManagedObjectID? {
return RepositoryUtils._updateWithoutMerge(
context: context,
entityName: "NSPlainNote",
objectID: objectID,
propertiesToUpdate: propertiesToUpdate
)
}
static func _updateWithoutMerge(context: NSManagedObjectContext, entityName: String, objectID: NSManagedObjectID, propertiesToUpdate: [AnyHashable : Any]) -> NSManagedObjectID? {
var result: NSManagedObjectID? = nil
do {
let batchUpdateRequest = NSBatchUpdateRequest(entityName: entityName)
batchUpdateRequest.predicate = NSPredicate(format: "self = %@", objectID)
batchUpdateRequest.propertiesToUpdate = propertiesToUpdate
batchUpdateRequest.resultType = .updatedObjectIDsResultType
let batchUpdateResult = try context.execute(batchUpdateRequest) as? NSBatchUpdateResult
if let managedObjectIDs = batchUpdateResult?.result as? [NSManagedObjectID] {
result = managedObjectIDs.first
}
} catch {
context.rollback()
error_log(error)
}
return result
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment