Index: modules/comment/comment.module =================================================================== RCS file: /cvs/drupal/drupal/modules/comment/comment.module,v retrieving revision 1.870 diff -u -r1.870 comment.module --- modules/comment/comment.module 24 Apr 2010 14:49:13 -0000 1.870 +++ modules/comment/comment.module 24 Apr 2010 16:53:06 -0000 @@ -1522,39 +1522,86 @@ } /** - * Delete a comment and all its replies. + * Deletes a comment and all its replies. * * @param $cid - * The comment to delete. + * The id of the comment to delete. + * + * @see comment_delete_multiple() */ function comment_delete($cid) { - comment_delete_multiple(array($cid)); + if ($comment = comment_load($cid)) { + // Delete the comment. + db_delete('comment') + ->condition('cid', $comment->cid) + ->execute(); + + field_attach_delete('comment', $comment); + module_invoke_all('comment_delete', $comment); + + // Delete the comment's replies. + $child_cids = db_query('SELECT cid FROM {comment} WHERE pid = :cid', array(':cid' => $comment->cid))->fetchCol(); + comment_delete_multiple($child_cids); + _comment_update_node_statistics($comment->nid); + } } /** - * Delete comments and all their replies. + * Deletes comments and all their replies. + * + * Comments to be deleted are queued, and queue processing starts immediately. + * If this process is aborted before completion, the remaining commentswill be + * deleted during subsequent cron runs. * * @param $cids * The comment to delete. + * + * @see comment_delete() */ function comment_delete_multiple($cids) { - $comments = comment_load_multiple($cids); - if ($comments) { + variable_set('queue_class_comment_deletes', 'BatchQueue'); + $queue = DrupalQueue::get('comment_deletes'); + $queue->createQueue(); - // Delete the comments. - db_delete('comment') - ->condition('cid', array_keys($comments), 'IN') - ->execute(); - foreach ($comments as $comment) { - field_attach_delete('comment', $comment); - module_invoke_all('comment_delete', $comment); - - // Delete the comment's replies. - $child_cids = db_query('SELECT cid FROM {comment} WHERE pid = :cid', array(':cid' => $comment->cid))->fetchCol(); - comment_delete_multiple($child_cids); - _comment_update_node_statistics($comment->nid); - } + foreach ($cids as $cid) { + $queue->createItem($cid); + } + + // Start processing the comments to be deleted. If interupted before + // completion, the remaining comments will be deleted during the next cron + // runs. + while ($item = $queue->claimItem()) { + comment_delete($item->data); + $queue->deleteItem($item); } + +} + +/** + * Worker callback for comment deletions. + * + * @param $item + * A queue item representing the comment to be deleted. + */ +function _comment_delete($item) { + static $queue; + + if (!isset($queue)) { + $queue = DrupalQueue::get('comment_deletes'); + } + + comment_delete($item->data); + $queue->deleteItem($item); +} + +/** + * Implementation of hook_cron_queue_info(). + */ +function comment_cron_queue_info() { + $queues['comment_deletes'] = array( + 'worker_callback' => '_comment_delete', + 'time' => 1, + ); } /** Index: modules/node/node.module =================================================================== RCS file: /cvs/drupal/drupal/modules/node/node.module,v retrieving revision 1.1264 diff -u -r1.1264 node.module --- modules/node/node.module 22 Apr 2010 09:12:35 -0000 1.1264 +++ modules/node/node.module 24 Apr 2010 16:53:07 -0000 @@ -445,7 +445,7 @@ * * All new module-defined node types are saved to the database via a call to * node_type_save(), and obsolete ones are deleted via a call to - * node_type_delete(). See _node_types_build() for an explanation of the new + * node_type_delete(). See _node_types_build() for an explanation of the new * and obsolete types. */ function node_types_rebuild() { @@ -1117,54 +1117,103 @@ } /** - * Delete a node. + * Deletes a single node. * * @param $nid * A node ID. + * + * @see node_delete_multiple() */ function node_delete($nid) { - node_delete_multiple(array($nid)); + if ($node = node_load($nid)) { + db_delete('node') + ->condition('nid', $nid) + ->execute(); + db_delete('node_revision') + ->condition('nid', $nid) + ->execute(); + db_delete('history') + ->condition('nid', $nid) + ->execute(); + + // Call the node-specific callback (if any): + node_invoke($node, 'delete'); + module_invoke_all('node_delete', $node); + field_attach_delete('node', $node); + + // Remove this node from the search index if needed. + // This code is implemented in node module rather than in search module, + // because node module is implementing search module's API, not the other + // way around. + if (module_exists('search')) { + search_reindex($nid, 'node'); + } + + // Clear the page and block and node_load_multiple caches. + cache_clear_all(); + entity_get_controller('node')->resetCache(); + } } /** - * Delete multiple nodes. + * Deletes multiple nodes. + * + * Nodes to be deleted are queued, and queue processing starts immediately. + * If this process is aborted before completion, the remaining nodes will be + * deleted during subsequent cron runs. * * @param $nids * An array of node IDs. + * + * @see node_delete() */ function node_delete_multiple($nids) { if (!empty($nids)) { $nodes = node_load_multiple($nids, array()); - db_delete('node') - ->condition('nid', $nids, 'IN') - ->execute(); - db_delete('node_revision') - ->condition('nid', $nids, 'IN') - ->execute(); - db_delete('history') - ->condition('nid', $nids, 'IN') - ->execute(); + variable_set('queue_class_node_deletes', 'BatchQueue'); + $queue = DrupalQueue::get('node_deletes'); + $queue->createQueue(); - foreach ($nodes as $nid => $node) { - // Call the node-specific callback (if any): - node_invoke($node, 'delete'); - module_invoke_all('node_delete', $node); - field_attach_delete('node', $node); - - // Remove this node from the search index if needed. - // This code is implemented in node module rather than in search module, - // because node module is implementing search module's API, not the other - // way around. - if (module_exists('search')) { - search_reindex($nid, 'node'); - } + foreach ($nids as $nid) { + $queue->createItem($nid); } - // Clear the page and block and node_load_multiple caches. - cache_clear_all(); - entity_get_controller('node')->resetCache(); + // Start processing the nodes to be deleted. If interupted before + // completion, the remaining nodes will be deleted during the next cron + // runs. + while ($item = $queue->claimItem()) { + node_delete($item->data); + $queue->deleteItem($item); + } + } +} + +/** + * Worker callback for node deletions. + * + * @param $item + * A queue item representing the node to be deleted. + */ +function _node_delete($item) { + static $queue; + + if (!isset($queue)) { + $queue = DrupalQueue::get('node_deletes'); } + + node_delete($item->data); + $queue->deleteItem($item); +} + +/** + * Implementation of hook_cron_queue_info(). + */ +function node_cron_queue_info() { + $queues['node_deletes'] = array( + 'worker_callback' => '_node_delete', + 'time' => 1, + ); } /**