? .776222.patch.swp
? 776222.patch
? 880132.patch
Index: includes/file.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/file.inc,v
retrieving revision 1.226
diff -u -p -r1.226 file.inc
--- includes/file.inc	22 Aug 2010 13:52:58 -0000	1.226
+++ includes/file.inc	23 Aug 2010 09:44:59 -0000
@@ -523,20 +523,29 @@ function file_load($fid) {
  * @see hook_file_update()
  */
 function file_save(stdClass $file) {
-  $file->timestamp = REQUEST_TIME;
-  $file->filesize = filesize($file->uri);
+  $transaction = db_transaction();
 
-  if (empty($file->fid)) {
-    drupal_write_record('file_managed', $file);
-    // Inform modules about the newly added file.
-    module_invoke_all('file_insert', $file);
-    module_invoke_all('entity_insert', $file, 'file');
+  try {
+    $file->timestamp = REQUEST_TIME;
+    $file->filesize = filesize($file->uri);
+  
+    if (empty($file->fid)) {
+      drupal_write_record('file_managed', $file);
+      // Inform modules about the newly added file.
+      module_invoke_all('file_insert', $file);
+      module_invoke_all('entity_insert', $file, 'file');
+    }
+    else {
+      drupal_write_record('file_managed', $file, 'fid');
+      // Inform modules that the file has been updated.
+      module_invoke_all('file_update', $file);
+      module_invoke_all('entity_update', $file, 'file');
+    }
   }
-  else {
-    drupal_write_record('file_managed', $file, 'fid');
-    // Inform modules that the file has been updated.
-    module_invoke_all('file_update', $file);
-    module_invoke_all('entity_update', $file, 'file');
+  catch (Exception $e) {
+    $transaction->rollback('file');
+    watchdog_exception('file', $e);
+    throw $e;
   }
 
   return $file;
Index: includes/menu.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/menu.inc,v
retrieving revision 1.406
diff -u -p -r1.406 menu.inc
--- includes/menu.inc	22 Aug 2010 14:57:44 -0000	1.406
+++ includes/menu.inc	23 Aug 2010 09:45:00 -0000
@@ -2685,185 +2685,195 @@ function _menu_delete_item($item, $force
  *   saved.
  */
 function menu_link_save(&$item) {
-  drupal_alter('menu_link', $item);
-
-  // This is the easiest way to handle the unique internal path '<front>',
-  // since a path marked as external does not need to match a router path.
-  $item['external'] = (url_is_external($item['link_path'])  || $item['link_path'] == '<front>') ? 1 : 0;
-  // Load defaults.
-  $item += array(
-    'menu_name' => 'navigation',
-    'weight' => 0,
-    'link_title' => '',
-    'hidden' => 0,
-    'has_children' => 0,
-    'expanded' => 0,
-    'options' => array(),
-    'module' => 'menu',
-    'customized' => 0,
-    'updated' => 0,
-  );
-  $existing_item = FALSE;
-  if (isset($item['mlid'])) {
-    if ($existing_item = db_query("SELECT * FROM {menu_links} WHERE mlid = :mlid", array(':mlid' => $item['mlid']))->fetchAssoc()) {
-      $existing_item['options'] = unserialize($existing_item['options']);
+  $transaction = db_transaction();
+  
+  try {
+    drupal_alter('menu_link', $item);
+  
+    // This is the easiest way to handle the unique internal path '<front>',
+    // since a path marked as external does not need to match a router path.
+    $item['external'] = (url_is_external($item['link_path'])  || $item['link_path'] == '<front>') ? 1 : 0;
+    // Load defaults.
+    $item += array(
+      'menu_name' => 'navigation',
+      'weight' => 0,
+      'link_title' => '',
+      'hidden' => 0,
+      'has_children' => 0,
+      'expanded' => 0,
+      'options' => array(),
+      'module' => 'menu',
+      'customized' => 0,
+      'updated' => 0,
+    );
+    $existing_item = FALSE;
+    if (isset($item['mlid'])) {
+      if ($existing_item = db_query("SELECT * FROM {menu_links} WHERE mlid = :mlid", array(':mlid' => $item['mlid']))->fetchAssoc()) {
+        $existing_item['options'] = unserialize($existing_item['options']);
+      }
     }
-  }
-
-  // If we have a parent link ID, we use it to inherit 'menu_name' and 'depth'.
-  if (isset($item['plid'])) {
-    if ($item['plid']) {
-      $parent = db_query("SELECT * FROM {menu_links} WHERE mlid = :mlid", array(':mlid' => $item['plid']))->fetchAssoc();
+  
+    // If we have a parent link ID, we use it to inherit 'menu_name' and 'depth'.
+    if (isset($item['plid'])) {
+      if ($item['plid']) {
+        $parent = db_query("SELECT * FROM {menu_links} WHERE mlid = :mlid", array(':mlid' => $item['plid']))->fetchAssoc();
+      }
+      // If the parent link ID is zero, then this link lives at the top-level.
+      else {
+        $parent = FALSE;
+      }
     }
-    // If the parent link ID is zero, then this link lives at the top-level.
+    // Otherwise, try to find a valid parent link for this link.
     else {
-      $parent = FALSE;
+      $query = db_select('menu_links');
+      // Only links derived from router items should have module == 'system', and
+      // we want to find the parent even if it's in a different menu.
+      if ($item['module'] == 'system') {
+        $query->condition('module', 'system');
+      }
+      // We always respect the link's 'menu_name'; inheritance for router items is
+      // ensured in _menu_router_build().
+      $query->condition('menu_name', $item['menu_name']);
+  
+      // Find the parent - it must be unique.
+      $parent_path = $item['link_path'];
+      do {
+        $parent = FALSE;
+        $parent_path = substr($parent_path, 0, strrpos($parent_path, '/'));
+        $new_query = clone $query;
+        $new_query->condition('link_path', $parent_path);
+        // Only valid if we get a unique result.
+        if ($new_query->countQuery()->execute()->fetchField() == 1) {
+          $parent = $new_query->fields('menu_links')->execute()->fetchAssoc();
+        }
+      } while ($parent === FALSE && $parent_path);
+    }
+    // If a parent link was found, assign it and derive its menu.
+    if (!empty($parent['mlid'])) {
+      $item['plid'] = $parent['mlid'];
+      $item['menu_name'] = $parent['menu_name'];
     }
-  }
-  // Otherwise, try to find a valid parent link for this link.
-  else {
-    $query = db_select('menu_links');
-    // Only links derived from router items should have module == 'system', and
-    // we want to find the parent even if it's in a different menu.
-    if ($item['module'] == 'system') {
-      $query->condition('module', 'system');
+    // If no corresponding parent link was found, move the link to the top-level.
+    else {
+      $item['plid'] = 0;
     }
-    // We always respect the link's 'menu_name'; inheritance for router items is
-    // ensured in _menu_router_build().
-    $query->condition('menu_name', $item['menu_name']);
-
-    // Find the parent - it must be unique.
-    $parent_path = $item['link_path'];
-    do {
-      $parent = FALSE;
-      $parent_path = substr($parent_path, 0, strrpos($parent_path, '/'));
-      $new_query = clone $query;
-      $new_query->condition('link_path', $parent_path);
-      // Only valid if we get a unique result.
-      if ($new_query->countQuery()->execute()->fetchField() == 1) {
-        $parent = $new_query->fields('menu_links')->execute()->fetchAssoc();
-      }
-    } while ($parent === FALSE && $parent_path);
-  }
-  // If a parent link was found, assign it and derive its menu.
-  if (!empty($parent['mlid'])) {
-    $item['plid'] = $parent['mlid'];
-    $item['menu_name'] = $parent['menu_name'];
-  }
-  // If no corresponding parent link was found, move the link to the top-level.
-  else {
-    $item['plid'] = 0;
-  }
-  $menu_name = $item['menu_name'];
-
-  if (!$existing_item) {
-    $item['mlid'] = db_insert('menu_links')
-      ->fields(array(
-        'menu_name' => $item['menu_name'],
-        'plid' => $item['plid'],
-        'link_path' => $item['link_path'],
-        'hidden' => $item['hidden'],
-        'external' => $item['external'],
-        'has_children' => $item['has_children'],
-        'expanded' => $item['expanded'],
-        'weight' => $item['weight'],
-        'module' => $item['module'],
-        'link_title' => $item['link_title'],
-        'options' => serialize($item['options']),
-        'customized' => $item['customized'],
-        'updated' => $item['updated'],
-      ))
-      ->execute();
-  }
-
-  // Directly fill parents for top-level links.
-  if ($item['plid'] == 0) {
-    $item['p1'] = $item['mlid'];
-    for ($i = 2; $i <= MENU_MAX_DEPTH; $i++) {
-      $item["p$i"] = 0;
-    }
-    $item['depth'] = 1;
-  }
-  // Otherwise, ensure that this link's depth is not beyond the maximum depth
-  // and fill parents based on the parent link.
-  else {
-    if ($item['has_children'] && $existing_item) {
-      $limit = MENU_MAX_DEPTH - menu_link_children_relative_depth($existing_item) - 1;
+    $menu_name = $item['menu_name'];
+  
+    if (!$existing_item) {
+      $item['mlid'] = db_insert('menu_links')
+        ->fields(array(
+          'menu_name' => $item['menu_name'],
+          'plid' => $item['plid'],
+          'link_path' => $item['link_path'],
+          'hidden' => $item['hidden'],
+          'external' => $item['external'],
+          'has_children' => $item['has_children'],
+          'expanded' => $item['expanded'],
+          'weight' => $item['weight'],
+          'module' => $item['module'],
+          'link_title' => $item['link_title'],
+          'options' => serialize($item['options']),
+          'customized' => $item['customized'],
+          'updated' => $item['updated'],
+        ))
+        ->execute();
+    }
+  
+    // Directly fill parents for top-level links.
+    if ($item['plid'] == 0) {
+      $item['p1'] = $item['mlid'];
+      for ($i = 2; $i <= MENU_MAX_DEPTH; $i++) {
+        $item["p$i"] = 0;
+      }
+      $item['depth'] = 1;
     }
+    // Otherwise, ensure that this link's depth is not beyond the maximum depth
+    // and fill parents based on the parent link.
     else {
-      $limit = MENU_MAX_DEPTH - 1;
-    }
-    if ($parent['depth'] > $limit) {
-      return FALSE;
+      if ($item['has_children'] && $existing_item) {
+        $limit = MENU_MAX_DEPTH - menu_link_children_relative_depth($existing_item) - 1;
+      }
+      else {
+        $limit = MENU_MAX_DEPTH - 1;
+      }
+      if ($parent['depth'] > $limit) {
+        return FALSE;
+      }
+      $item['depth'] = $parent['depth'] + 1;
+      _menu_link_parents_set($item, $parent);
     }
-    $item['depth'] = $parent['depth'] + 1;
-    _menu_link_parents_set($item, $parent);
-  }
-  // Need to check both plid and menu_name, since plid can be 0 in any menu.
-  if ($existing_item && ($item['plid'] != $existing_item['plid'] || $menu_name != $existing_item['menu_name'])) {
-    _menu_link_move_children($item, $existing_item);
-  }
-  // Find the router_path.
-  if (empty($item['router_path'])  || !$existing_item || ($existing_item['link_path'] != $item['link_path'])) {
-    if ($item['external']) {
-      $item['router_path'] = '';
+    // Need to check both plid and menu_name, since plid can be 0 in any menu.
+    if ($existing_item && ($item['plid'] != $existing_item['plid'] || $menu_name != $existing_item['menu_name'])) {
+      _menu_link_move_children($item, $existing_item);
+    }
+    // Find the router_path.
+    if (empty($item['router_path'])  || !$existing_item || ($existing_item['link_path'] != $item['link_path'])) {
+      if ($item['external']) {
+        $item['router_path'] = '';
+      }
+      else {
+        // Find the router path which will serve this path.
+        $item['parts'] = explode('/', $item['link_path'], MENU_MAX_PARTS);
+        $item['router_path'] = _menu_find_router_path($item['link_path']);
+      }
     }
-    else {
-      // Find the router path which will serve this path.
-      $item['parts'] = explode('/', $item['link_path'], MENU_MAX_PARTS);
-      $item['router_path'] = _menu_find_router_path($item['link_path']);
+    // If every value in $existing_item is the same in the $item, there is no
+    // reason to run the update queries or clear the caches. We use
+    // array_intersect_assoc() with the $item as the first parameter because
+    // $item may have additional keys left over from building a router entry.
+    // The intersect removes the extra keys, allowing a meaningful comparison.
+    if (!$existing_item || (array_intersect_assoc($item, $existing_item)) != $existing_item) {
+      db_update('menu_links')
+        ->fields(array(
+          'menu_name' => $item['menu_name'],
+          'plid' => $item['plid'],
+          'link_path' => $item['link_path'],
+          'router_path' => $item['router_path'],
+          'hidden' => $item['hidden'],
+          'external' => $item['external'],
+          'has_children' => $item['has_children'],
+          'expanded' => $item['expanded'],
+          'weight' => $item['weight'],
+          'depth' => $item['depth'],
+          'p1' => $item['p1'],
+          'p2' => $item['p2'],
+          'p3' => $item['p3'],
+          'p4' => $item['p4'],
+          'p5' => $item['p5'],
+          'p6' => $item['p6'],
+          'p7' => $item['p7'],
+          'p8' => $item['p8'],
+          'p9' => $item['p9'],
+          'module' => $item['module'],
+          'link_title' => $item['link_title'],
+          'options' => serialize($item['options']),
+          'customized' => $item['customized'],
+        ))
+        ->condition('mlid', $item['mlid'])
+        ->execute();
+      // Check the has_children status of the parent.
+      _menu_update_parental_status($item);
+      menu_cache_clear($menu_name);
+      if ($existing_item && $menu_name != $existing_item['menu_name']) {
+        menu_cache_clear($existing_item['menu_name']);
+      }
+      // Notify modules we have acted on a menu item.
+      $hook = 'menu_link_insert';
+      if ($existing_item) {
+        $hook = 'menu_link_update';
+      }
+      module_invoke_all($hook, $item);
+      // Now clear the cache.
+      _menu_clear_page_cache();
     }
   }
-  // If every value in $existing_item is the same in the $item, there is no
-  // reason to run the update queries or clear the caches. We use
-  // array_intersect_assoc() with the $item as the first parameter because
-  // $item may have additional keys left over from building a router entry.
-  // The intersect removes the extra keys, allowing a meaningful comparison.
-  if (!$existing_item || (array_intersect_assoc($item, $existing_item)) != $existing_item) {
-    db_update('menu_links')
-      ->fields(array(
-        'menu_name' => $item['menu_name'],
-        'plid' => $item['plid'],
-        'link_path' => $item['link_path'],
-        'router_path' => $item['router_path'],
-        'hidden' => $item['hidden'],
-        'external' => $item['external'],
-        'has_children' => $item['has_children'],
-        'expanded' => $item['expanded'],
-        'weight' => $item['weight'],
-        'depth' => $item['depth'],
-        'p1' => $item['p1'],
-        'p2' => $item['p2'],
-        'p3' => $item['p3'],
-        'p4' => $item['p4'],
-        'p5' => $item['p5'],
-        'p6' => $item['p6'],
-        'p7' => $item['p7'],
-        'p8' => $item['p8'],
-        'p9' => $item['p9'],
-        'module' => $item['module'],
-        'link_title' => $item['link_title'],
-        'options' => serialize($item['options']),
-        'customized' => $item['customized'],
-      ))
-      ->condition('mlid', $item['mlid'])
-      ->execute();
-    // Check the has_children status of the parent.
-    _menu_update_parental_status($item);
-    menu_cache_clear($menu_name);
-    if ($existing_item && $menu_name != $existing_item['menu_name']) {
-      menu_cache_clear($existing_item['menu_name']);
-    }
-    // Notify modules we have acted on a menu item.
-    $hook = 'menu_link_insert';
-    if ($existing_item) {
-      $hook = 'menu_link_update';
-    }
-    module_invoke_all($hook, $item);
-    // Now clear the cache.
-    _menu_clear_page_cache();
+  catch (Exception $e) {
+    $transaction->rollback('menu link');
+    watchdog_exception('menu link', $e);
+    throw $e;
   }
-  return $item['mlid'];
+  
+  return !empty($item['mlid']) ? $item['mlid'] : FALSE;
 }
 
 /**
@@ -3318,80 +3328,89 @@ function _menu_router_build($callbacks) 
  * Helper function to save data from menu_router_build() to the router table.
  */
 function _menu_router_save($menu, $masks) {
-  // Delete the existing router since we have some data to replace it.
-  db_truncate('menu_router')->execute();
-
-  // Prepare insert object.
-  $insert = db_insert('menu_router')
-    ->fields(array(
-      'path',
-      'load_functions',
-      'to_arg_functions',
-      'access_callback',
-      'access_arguments',
-      'page_callback',
-      'page_arguments',
-      'delivery_callback',
-      'fit',
-      'number_parts',
-      'context',
-      'tab_parent',
-      'tab_root',
-      'title',
-      'title_callback',
-      'title_arguments',
-      'theme_callback',
-      'theme_arguments',
-      'type',
-      'block_callback',
-      'description',
-      'position',
-      'weight',
-      'include_file',
-    ));
-
-  $num_records = 0;
-
-  foreach ($menu as $path => $item) {
-    // Fill in insert object values.
-    $insert->values(array(
-      'path' => $item['path'],
-      'load_functions' => $item['load_functions'],
-      'to_arg_functions' => $item['to_arg_functions'],
-      'access_callback' => $item['access callback'],
-      'access_arguments' => serialize($item['access arguments']),
-      'page_callback' => $item['page callback'],
-      'page_arguments' => serialize($item['page arguments']),
-      'delivery_callback' => $item['delivery callback'],
-      'fit' => $item['_fit'],
-      'number_parts' => $item['_number_parts'],
-      'context' => $item['context'],
-      'tab_parent' => $item['tab_parent'],
-      'tab_root' => $item['tab_root'],
-      'title' => $item['title'],
-      'title_callback' => $item['title callback'],
-      'title_arguments' => ($item['title arguments'] ? serialize($item['title arguments']) : ''),
-      'theme_callback' => $item['theme callback'],
-      'theme_arguments' => serialize($item['theme arguments']),
-      'type' => $item['type'],
-      'block_callback' => $item['block callback'],
-      'description' => $item['description'],
-      'position' => $item['position'],
-      'weight' => $item['weight'],
-      'include_file' => $item['include file'],
-    ));
-
-    // Execute in batches to avoid the memory overhead of all of those records
-    // in the query object.
-    if (++$num_records == 20) {
-      $insert->execute();
-      $num_records = 0;
-    }
-  }
-  // Insert any remaining records.
-  $insert->execute();
-  // Store the masks.
-  variable_set('menu_masks', $masks);
+  $transaction = db_transaction();
+  
+  try {
+    // Delete the existing router since we have some data to replace it.
+    db_truncate('menu_router')->execute();
+  
+    // Prepare insert object.
+    $insert = db_insert('menu_router')
+      ->fields(array(
+        'path',
+        'load_functions',
+        'to_arg_functions',
+        'access_callback',
+        'access_arguments',
+        'page_callback',
+        'page_arguments',
+        'delivery_callback',
+        'fit',
+        'number_parts',
+        'context',
+        'tab_parent',
+        'tab_root',
+        'title',
+        'title_callback',
+        'title_arguments',
+        'theme_callback',
+        'theme_arguments',
+        'type',
+        'block_callback',
+        'description',
+        'position',
+        'weight',
+        'include_file',
+      ));
+  
+    $num_records = 0;
+  
+    foreach ($menu as $path => $item) {
+      // Fill in insert object values.
+      $insert->values(array(
+        'path' => $item['path'],
+        'load_functions' => $item['load_functions'],
+        'to_arg_functions' => $item['to_arg_functions'],
+        'access_callback' => $item['access callback'],
+        'access_arguments' => serialize($item['access arguments']),
+        'page_callback' => $item['page callback'],
+        'page_arguments' => serialize($item['page arguments']),
+        'delivery_callback' => $item['delivery callback'],
+        'fit' => $item['_fit'],
+        'number_parts' => $item['_number_parts'],
+        'context' => $item['context'],
+        'tab_parent' => $item['tab_parent'],
+        'tab_root' => $item['tab_root'],
+        'title' => $item['title'],
+        'title_callback' => $item['title callback'],
+        'title_arguments' => ($item['title arguments'] ? serialize($item['title arguments']) : ''),
+        'theme_callback' => $item['theme callback'],
+        'theme_arguments' => serialize($item['theme arguments']),
+        'type' => $item['type'],
+        'block_callback' => $item['block callback'],
+        'description' => $item['description'],
+        'position' => $item['position'],
+        'weight' => $item['weight'],
+        'include_file' => $item['include file'],
+      ));
+  
+      // Execute in batches to avoid the memory overhead of all of those records
+      // in the query object.
+      if (++$num_records == 20) {
+        $insert->execute();
+        $num_records = 0;
+      }
+    }
+    // Insert any remaining records.
+    $insert->execute();
+    // Store the masks.
+    variable_set('menu_masks', $masks);
+  }
+  catch (Exception $e) {
+    $transaction->rollback('menu router');
+    watchdog_exception('menu router', $e);
+    throw $e;
+  }
 
   return $menu;
 }
Index: includes/path.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/path.inc,v
retrieving revision 1.71
diff -u -p -r1.71 path.inc
--- includes/path.inc	9 Aug 2010 00:13:06 -0000	1.71
+++ includes/path.inc	23 Aug 2010 09:45:00 -0000
@@ -394,20 +394,30 @@ function path_load($conditions) {
  *   - language: (optional) The language of the alias.
  */
 function path_save(&$path) {
-  $path += array('pid' => NULL, 'language' => LANGUAGE_NONE);
-
-  // Insert or update the alias.
-  $status = drupal_write_record('url_alias', $path, (!empty($path['pid']) ? 'pid' : array()));
-
-  // Verify that a record was written.
-  if ($status) {
-    if ($status === SAVED_NEW) {
-      module_invoke_all('path_insert', $path);
-    }
-    else {
-      module_invoke_all('path_update', $path);
+  $transaction = db_transaction();
+  $status = FALSE;
+  
+  try {
+    $path += array('pid' => NULL, 'language' => LANGUAGE_NONE);
+  
+    // Insert or update the alias.
+    $status = drupal_write_record('url_alias', $path, (!empty($path['pid']) ? 'pid' : array()));
+  
+    // Verify that a record was written.
+    if ($status) {
+      if ($status === SAVED_NEW) {
+        module_invoke_all('path_insert', $path);
+      }
+      else {
+        module_invoke_all('path_update', $path);
+      }
+      drupal_clear_path_cache($path['source']);
     }
-    drupal_clear_path_cache($path['source']);
+  }
+  catch (Exception $e) {
+    $transaction->rollback('path');
+    watchdog_exception('path', $e);
+    throw $e;
   }
 }
 
Index: modules/filter/filter.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/filter/filter.module,v
retrieving revision 1.340
diff -u -p -r1.340 filter.module
--- modules/filter/filter.module	22 Aug 2010 12:55:04 -0000	1.340
+++ modules/filter/filter.module	23 Aug 2010 09:45:00 -0000
@@ -185,73 +185,83 @@ function filter_format_load($format_id) 
  *       See hook_filter_info() for details.
  */
 function filter_format_save(&$format) {
-  $format->name = trim($format->name);
-  $format->cache = _filter_format_is_cacheable($format);
-  // Programmatic saves may not contain any filters.
-  if (!isset($format->filters)) {
-    $format->filters = array();
-  }
-
-  // Add a new text format.
-  if (empty($format->format)) {
-    $return = drupal_write_record('filter_format', $format);
-  }
-  else {
-    $return = drupal_write_record('filter_format', $format, 'format');
-  }
-
-  $filter_info = filter_get_filters();
-  foreach ($filter_info as $name => $filter) {
-    // Add new filters without weight to the bottom.
-    if (!isset($format->filters[$name]['weight'])) {
-      $format->filters[$name]['weight'] = 10;
-    }
-    $format->filters[$name]['status'] = isset($format->filters[$name]['status']) ? $format->filters[$name]['status'] : 0;
-    $format->filters[$name]['module'] = $filter['module'];
-
-    // If settings were passed, only ensure default settings.
-    if (isset($format->filters[$name]['settings'])) {
-      if (isset($filter['default settings'])) {
-        $format->filters[$name]['settings'] = array_merge($filter['default settings'], $format->filters[$name]['settings']);
-      }
+  $transaction = db_transaction();
+  $return = FALSE;
+  
+  try {
+    $format->name = trim($format->name);
+    $format->cache = _filter_format_is_cacheable($format);
+    // Programmatic saves may not contain any filters.
+    if (!isset($format->filters)) {
+      $format->filters = array();
+    }
+  
+    // Add a new text format.
+    if (empty($format->format)) {
+      $return = drupal_write_record('filter_format', $format);
     }
-    // Otherwise, use default settings or fall back to an empty array.
     else {
-      $format->filters[$name]['settings'] = isset($filter['default settings']) ? $filter['default settings'] : array();
+      $return = drupal_write_record('filter_format', $format, 'format');
     }
-
-    $fields = array();
-    $fields['weight'] = $format->filters[$name]['weight'];
-    $fields['status'] = $format->filters[$name]['status'];
-    $fields['module'] = $format->filters[$name]['module'];
-    $fields['settings'] = serialize($format->filters[$name]['settings']);
-
-    db_merge('filter')
-      ->key(array(
-        'format' => $format->format,
-        'name' => $name,
-      ))
-      ->fields($fields)
-      ->execute();
-  }
-
-  if ($return == SAVED_NEW) {
-    module_invoke_all('filter_format_insert', $format);
-  }
-  else {
-    module_invoke_all('filter_format_update', $format);
-    // Explicitly indicate that the format was updated. We need to do this
-    // since if the filters were updated but the format object itself was not,
-    // the call to drupal_write_record() above would not return an indication
-    // that anything had changed.
-    $return = SAVED_UPDATED;
-
-    // Clear the filter cache whenever a text format is updated.
-    cache_clear_all($format->format . ':', 'cache_filter', TRUE);
+  
+    $filter_info = filter_get_filters();
+    foreach ($filter_info as $name => $filter) {
+      // Add new filters without weight to the bottom.
+      if (!isset($format->filters[$name]['weight'])) {
+        $format->filters[$name]['weight'] = 10;
+      }
+      $format->filters[$name]['status'] = isset($format->filters[$name]['status']) ? $format->filters[$name]['status'] : 0;
+      $format->filters[$name]['module'] = $filter['module'];
+  
+      // If settings were passed, only ensure default settings.
+      if (isset($format->filters[$name]['settings'])) {
+        if (isset($filter['default settings'])) {
+          $format->filters[$name]['settings'] = array_merge($filter['default settings'], $format->filters[$name]['settings']);
+        }
+      }
+      // Otherwise, use default settings or fall back to an empty array.
+      else {
+        $format->filters[$name]['settings'] = isset($filter['default settings']) ? $filter['default settings'] : array();
+      }
+  
+      $fields = array();
+      $fields['weight'] = $format->filters[$name]['weight'];
+      $fields['status'] = $format->filters[$name]['status'];
+      $fields['module'] = $format->filters[$name]['module'];
+      $fields['settings'] = serialize($format->filters[$name]['settings']);
+  
+      db_merge('filter')
+        ->key(array(
+          'format' => $format->format,
+          'name' => $name,
+        ))
+        ->fields($fields)
+        ->execute();
+    }
+  
+    if ($return == SAVED_NEW) {
+      module_invoke_all('filter_format_insert', $format);
+    }
+    else {
+      module_invoke_all('filter_format_update', $format);
+      // Explicitly indicate that the format was updated. We need to do this
+      // since if the filters were updated but the format object itself was not,
+      // the call to drupal_write_record() above would not return an indication
+      // that anything had changed.
+      $return = SAVED_UPDATED;
+  
+      // Clear the filter cache whenever a text format is updated.
+      cache_clear_all($format->format . ':', 'cache_filter', TRUE);
+    }
+  
+    filter_formats_reset();
+  }
+  catch (Exception $e) {
+    $transaction->rollback('filter format');
+    watchdog_exception('filter format', $e);
+    throw $e;
   }
 
-  filter_formats_reset();
-
   return $return;
 }
 
Index: modules/image/image.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/image/image.module,v
retrieving revision 1.46
diff -u -p -r1.46 image.module
--- modules/image/image.module	22 Aug 2010 13:52:58 -0000	1.46
+++ modules/image/image.module	23 Aug 2010 09:45:00 -0000
@@ -515,26 +515,35 @@ function image_style_load($name = NULL, 
  *   An image style array. In the case of a new style, 'isid' will be populated.
  */
 function image_style_save($style) {
-  if (isset($style['isid']) && is_numeric($style['isid'])) {
-    // Load the existing style to make sure we account for renamed styles.
-    $old_style = image_style_load(NULL, $style['isid']);
-    image_style_flush($old_style);
-    drupal_write_record('image_styles', $style, 'isid');
-    if ($old_style['name'] != $style['name']) {
-      $style['old_name'] = $old_style['name'];
+  $transaction = db_transaction();
+  
+  try {
+    if (isset($style['isid']) && is_numeric($style['isid'])) {
+      // Load the existing style to make sure we account for renamed styles.
+      $old_style = image_style_load(NULL, $style['isid']);
+      image_style_flush($old_style);
+      drupal_write_record('image_styles', $style, 'isid');
+      if ($old_style['name'] != $style['name']) {
+        $style['old_name'] = $old_style['name'];
+      }
     }
+    else {
+      drupal_write_record('image_styles', $style);
+      $style['is_new'] = TRUE;
+    }
+  
+    // Let other modules update as necessary on save.
+    module_invoke_all('image_style_save', $style);
+  
+    // Clear all caches and flush.
+    image_style_flush($style);
+  }
+  catch (Exception $e) {
+    $transaction->rollback('image style');
+    watchdog_exception('image style', $e);
+    throw $e;
   }
-  else {
-    drupal_write_record('image_styles', $style);
-    $style['is_new'] = TRUE;
-  }
-
-  // Let other modules update as necessary on save.
-  module_invoke_all('image_style_save', $style);
-
-  // Clear all caches and flush.
-  image_style_flush($style);
-
+  
   return $style;
 }
 
Index: modules/menu/menu.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/menu/menu.module,v
retrieving revision 1.231
diff -u -p -r1.231 menu.module
--- modules/menu/menu.module	1 Aug 2010 23:33:18 -0000	1.231
+++ modules/menu/menu.module	23 Aug 2010 09:45:00 -0000
@@ -256,23 +256,32 @@ function menu_load_all() {
  * @see menu_load()
  */
 function menu_save($menu) {
-  $status = db_merge('menu_custom')
-    ->key(array('menu_name' => $menu['menu_name']))
-    ->fields(array(
-      'title' => $menu['title'],
-      'description' => $menu['description'],
-    ))
-    ->execute();
-  menu_cache_clear_all();
-
-  switch ($status) {
-    case SAVED_NEW:
-      module_invoke_all('menu_insert', $menu);
-      break;
-
-    case SAVED_UPDATED:
-      module_invoke_all('menu_update', $menu);
-      break;
+  $transaction = db_transaction();
+  
+  try {
+    $status = db_merge('menu_custom')
+      ->key(array('menu_name' => $menu['menu_name']))
+      ->fields(array(
+        'title' => $menu['title'],
+        'description' => $menu['description'],
+      ))
+      ->execute();
+    menu_cache_clear_all();
+  
+    switch ($status) {
+      case SAVED_NEW:
+        module_invoke_all('menu_insert', $menu);
+        break;
+  
+      case SAVED_UPDATED:
+        module_invoke_all('menu_update', $menu);
+        break;
+    }
+  }
+  catch (Exception $e) {
+    $transaction->rollback('menu');
+    watchdog_exception('menu', $e);
+    throw $e;
   }
 }
 
Index: modules/node/node.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/node/node.module,v
retrieving revision 1.1291
diff -u -p -r1.1291 node.module
--- modules/node/node.module	22 Aug 2010 16:11:12 -0000	1.1291
+++ modules/node/node.module	23 Aug 2010 09:45:01 -0000
@@ -500,51 +500,61 @@ function node_type_load($name) {
  *   Status flag indicating outcome of the operation.
  */
 function node_type_save($info) {
-  $is_existing = FALSE;
-  $existing_type = !empty($info->old_type) ? $info->old_type : $info->type;
-  $is_existing = (bool) db_query_range('SELECT 1 FROM {node_type} WHERE type = :type', 0, 1, array(':type' => $existing_type))->fetchField();
-  $type = node_type_set_defaults($info);
-
-  $fields = array(
-    'type' => (string) $type->type,
-    'name' => (string) $type->name,
-    'base' => (string) $type->base,
-    'has_title' => (int) $type->has_title,
-    'title_label' => (string) $type->title_label,
-    'description' => (string) $type->description,
-    'help' => (string) $type->help,
-    'custom' => (int) $type->custom,
-    'modified' => (int) $type->modified,
-    'locked' => (int) $type->locked,
-  );
-
-  if ($is_existing) {
-    db_update('node_type')
-      ->fields($fields)
-      ->condition('type', $existing_type)
-      ->execute();
-
-    if (!empty($type->old_type) && $type->old_type != $type->type) {
-      field_attach_rename_bundle('node', $type->old_type, $type->type);
+  $transaction = db_transaction();
+  $status = FALSE;
+  
+  try {
+    $is_existing = FALSE;
+    $existing_type = !empty($info->old_type) ? $info->old_type : $info->type;
+    $is_existing = (bool) db_query_range('SELECT 1 FROM {node_type} WHERE type = :type', 0, 1, array(':type' => $existing_type))->fetchField();
+    $type = node_type_set_defaults($info);
+  
+    $fields = array(
+      'type' => (string) $type->type,
+      'name' => (string) $type->name,
+      'base' => (string) $type->base,
+      'has_title' => (int) $type->has_title,
+      'title_label' => (string) $type->title_label,
+      'description' => (string) $type->description,
+      'help' => (string) $type->help,
+      'custom' => (int) $type->custom,
+      'modified' => (int) $type->modified,
+      'locked' => (int) $type->locked,
+    );
+  
+    if ($is_existing) {
+      db_update('node_type')
+        ->fields($fields)
+        ->condition('type', $existing_type)
+        ->execute();
+  
+      if (!empty($type->old_type) && $type->old_type != $type->type) {
+        field_attach_rename_bundle('node', $type->old_type, $type->type);
+      }
+      module_invoke_all('node_type_update', $type);
+      $status = SAVED_UPDATED;
     }
-    module_invoke_all('node_type_update', $type);
-    $status = SAVED_UPDATED;
+    else {
+      $fields['orig_type'] = (string) $type->orig_type;
+      db_insert('node_type')
+        ->fields($fields)
+        ->execute();
+  
+      field_attach_create_bundle('node', $type->type);
+  
+      module_invoke_all('node_type_insert', $type);
+      $status = SAVED_NEW;
+    }
+  
+    // Clear the node type cache.
+    drupal_static_reset('_node_types_build');
   }
-  else {
-    $fields['orig_type'] = (string) $type->orig_type;
-    db_insert('node_type')
-      ->fields($fields)
-      ->execute();
-
-    field_attach_create_bundle('node', $type->type);
-
-    module_invoke_all('node_type_insert', $type);
-    $status = SAVED_NEW;
+  catch (Exception $e) {
+    $transaction->rollback('node type');
+    watchdog_exception('node type', $e);
+    throw $e;
   }
 
-  // Clear the node type cache.
-  drupal_static_reset('_node_types_build');
-
   return $status;
 }
 
Index: modules/system/system.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.module,v
retrieving revision 1.957
diff -u -p -r1.957 system.module
--- modules/system/system.module	22 Aug 2010 13:52:58 -0000	1.957
+++ modules/system/system.module	23 Aug 2010 09:45:01 -0000
@@ -3601,41 +3601,50 @@ function system_date_format_type_delete(
  *   identifier.
  */
 function system_date_format_save($date_format, $dfid = 0) {
-  $format = array();
-  $format['dfid'] = $dfid;
-  $format['type'] = $date_format['type'];
-  $format['format'] = $date_format['format'];
-  $format['locked'] = $date_format['locked'];
-
-  // Update date_format table.
-  if (!empty($date_format['is_new'])) {
-    drupal_write_record('date_formats', $format);
-  }
-  else {
-    $keys = ($dfid ? array('dfid') : array('format', 'type'));
-    drupal_write_record('date_formats', $format, $keys);
-  }
-
-  $languages = language_list('enabled');
-  $languages = $languages[1];
-
-  $locale_format = array();
-  $locale_format['type'] = $date_format['type'];
-  $locale_format['format'] = $date_format['format'];
-
-  // Check if the suggested language codes are configured and enabled.
-  if (!empty($date_format['locales'])) {
-    foreach ($date_format['locales'] as $langcode) {
-      // Only proceed if language is enabled.
-      if (in_array($langcode, $languages)) {
-        $is_existing = (bool) db_query_range('SELECT 1 FROM {date_format_locale} WHERE type = :type AND language = :language', 0, 1, array(':type' => $date_format['type'], ':language' => $langcode))->fetchField();
-        if (!$is_existing) {
-          $locale_format['language'] = $langcode;
-          drupal_write_record('date_format_locale', $locale_format);
+  $transaction = db_transaction();
+  
+  try {
+    $format = array();
+    $format['dfid'] = $dfid;
+    $format['type'] = $date_format['type'];
+    $format['format'] = $date_format['format'];
+    $format['locked'] = $date_format['locked'];
+  
+    // Update date_format table.
+    if (!empty($date_format['is_new'])) {
+      drupal_write_record('date_formats', $format);
+    }
+    else {
+      $keys = ($dfid ? array('dfid') : array('format', 'type'));
+      drupal_write_record('date_formats', $format, $keys);
+    }
+  
+    $languages = language_list('enabled');
+    $languages = $languages[1];
+  
+    $locale_format = array();
+    $locale_format['type'] = $date_format['type'];
+    $locale_format['format'] = $date_format['format'];
+  
+    // Check if the suggested language codes are configured and enabled.
+    if (!empty($date_format['locales'])) {
+      foreach ($date_format['locales'] as $langcode) {
+        // Only proceed if language is enabled.
+        if (in_array($langcode, $languages)) {
+          $is_existing = (bool) db_query_range('SELECT 1 FROM {date_format_locale} WHERE type = :type AND language = :language', 0, 1, array(':type' => $date_format['type'], ':language' => $langcode))->fetchField();
+          if (!$is_existing) {
+            $locale_format['language'] = $langcode;
+            drupal_write_record('date_format_locale', $locale_format);
+          }
         }
       }
     }
   }
+  catch (Exception $e) {
+    $transaction->rollback('system date format');
+    watchdog_exception('system date format', $e);
+    throw $e;
+  }
 }
 
 /**
Index: modules/taxonomy/taxonomy.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/taxonomy/taxonomy.module,v
retrieving revision 1.603
diff -u -p -r1.603 taxonomy.module
--- modules/taxonomy/taxonomy.module	22 Aug 2010 15:45:03 -0000	1.603
+++ modules/taxonomy/taxonomy.module	23 Aug 2010 09:45:02 -0000
@@ -373,32 +373,41 @@ function taxonomy_admin_vocabulary_title
  * Save a vocabulary given a vocabulary object.
  */
 function taxonomy_vocabulary_save($vocabulary) {
-
-  if (!empty($vocabulary->name)) {
-    // Prevent leading and trailing spaces in vocabulary names.
-    $vocabulary->name = trim($vocabulary->name);
-  }
-
-  if (!isset($vocabulary->module)) {
-    $vocabulary->module = 'taxonomy';
-  }
-
-  module_invoke_all('taxonomy_vocabulary_presave', $vocabulary);
-
-  if (!empty($vocabulary->vid) && !empty($vocabulary->name)) {
-    $status = drupal_write_record('taxonomy_vocabulary', $vocabulary, 'vid');
-    module_invoke_all('taxonomy_vocabulary_update', $vocabulary);
-    module_invoke_all('entity_update', $vocabulary, 'taxonomy_vocabulary');
+  $transaction = db_transaction();
+  $status = FALSE;
+  
+  try {
+    if (!empty($vocabulary->name)) {
+      // Prevent leading and trailing spaces in vocabulary names.
+      $vocabulary->name = trim($vocabulary->name);
+    }
+  
+    if (!isset($vocabulary->module)) {
+      $vocabulary->module = 'taxonomy';
+    }
+  
+    module_invoke_all('taxonomy_vocabulary_presave', $vocabulary);
+  
+    if (!empty($vocabulary->vid) && !empty($vocabulary->name)) {
+      $status = drupal_write_record('taxonomy_vocabulary', $vocabulary, 'vid');
+      module_invoke_all('taxonomy_vocabulary_update', $vocabulary);
+      module_invoke_all('entity_update', $vocabulary, 'taxonomy_vocabulary');
+    }
+    elseif (empty($vocabulary->vid)) {
+      $status = drupal_write_record('taxonomy_vocabulary', $vocabulary);
+      field_attach_create_bundle('taxonomy_term', $vocabulary->machine_name);
+      module_invoke_all('taxonomy_vocabulary_insert', $vocabulary);
+      module_invoke_all('entity_insert', $vocabulary, 'taxonomy_vocabulary');
+    }
+  
+    cache_clear_all();
+    entity_get_controller('taxonomy_vocabulary')->resetCache();
+  }
+  catch (Exception $e) {
+    $transaction->rollback('taxonomy vocabulary');
+    watchdog_exception('taxonomy vocabulary', $e);
+    throw $e;
   }
-  elseif (empty($vocabulary->vid)) {
-    $status = drupal_write_record('taxonomy_vocabulary', $vocabulary);
-    field_attach_create_bundle('taxonomy_term', $vocabulary->machine_name);
-    module_invoke_all('taxonomy_vocabulary_insert', $vocabulary);
-    module_invoke_all('entity_insert', $vocabulary, 'taxonomy_vocabulary');
-  }
-
-  cache_clear_all();
-  entity_get_controller('taxonomy_vocabulary')->resetCache();
 
   return $status;
 }
@@ -482,67 +491,77 @@ function taxonomy_check_vocabulary_hiera
  *   Status constant indicating if term was inserted or updated.
  */
 function taxonomy_term_save($term) {
-  // Prevent leading and trailing spaces in term names.
-  $term->name = trim($term->name);
-  if (!isset($term->vocabulary_machine_name)) {
-    $vocabulary = taxonomy_vocabulary_load($term->vid);
-    $term->vocabulary_machine_name = $vocabulary->machine_name;
-  }
-
-  field_attach_presave('taxonomy_term', $term);
-  module_invoke_all('taxonomy_term_presave', $term);
-
-  if (empty($term->tid)) {
-    $op = 'insert';
-    $status = drupal_write_record('taxonomy_term_data', $term);
-    field_attach_insert('taxonomy_term', $term);
-    if (!isset($term->parent)) {
-      $term->parent = array(0);
-    }
-  }
-  else {
-    $op = 'update';
-    $status = drupal_write_record('taxonomy_term_data', $term, 'tid');
-    field_attach_update('taxonomy_term', $term);
-    if (isset($term->parent)) {
-      db_delete('taxonomy_term_hierarchy')
-        ->condition('tid', $term->tid)
-        ->execute();
+  $transaction = db_transaction();
+  $status = FALSE;
+  
+  try {
+    // Prevent leading and trailing spaces in term names.
+    $term->name = trim($term->name);
+    if (!isset($term->vocabulary_machine_name)) {
+      $vocabulary = taxonomy_vocabulary_load($term->vid);
+      $term->vocabulary_machine_name = $vocabulary->machine_name;
+    }
+  
+    field_attach_presave('taxonomy_term', $term);
+    module_invoke_all('taxonomy_term_presave', $term);
+  
+    if (empty($term->tid)) {
+      $op = 'insert';
+      $status = drupal_write_record('taxonomy_term_data', $term);
+      field_attach_insert('taxonomy_term', $term);
+      if (!isset($term->parent)) {
+        $term->parent = array(0);
+      }
     }
-  }
-
-  if (isset($term->parent)) {
-    if (!is_array($term->parent)) {
-      $term->parent = array($term->parent);
+    else {
+      $op = 'update';
+      $status = drupal_write_record('taxonomy_term_data', $term, 'tid');
+      field_attach_update('taxonomy_term', $term);
+      if (isset($term->parent)) {
+        db_delete('taxonomy_term_hierarchy')
+          ->condition('tid', $term->tid)
+          ->execute();
+      }
     }
-    $query = db_insert('taxonomy_term_hierarchy')
-      ->fields(array('tid', 'parent'));
-    foreach ($term->parent as $parent) {
-      if (is_array($parent)) {
-        foreach ($parent as $tid) {
+  
+    if (isset($term->parent)) {
+      if (!is_array($term->parent)) {
+        $term->parent = array($term->parent);
+      }
+      $query = db_insert('taxonomy_term_hierarchy')
+        ->fields(array('tid', 'parent'));
+      foreach ($term->parent as $parent) {
+        if (is_array($parent)) {
+          foreach ($parent as $tid) {
+            $query->values(array(
+              'tid' => $term->tid,
+              'parent' => $tid
+            ));
+          }
+        }
+        else {
           $query->values(array(
             'tid' => $term->tid,
-            'parent' => $tid
+            'parent' => $parent
           ));
         }
       }
-      else {
-        $query->values(array(
-          'tid' => $term->tid,
-          'parent' => $parent
-        ));
-      }
+      $query->execute();
     }
-    $query->execute();
+  
+    // Reset the taxonomy term static variables.
+    taxonomy_terms_static_reset();
+  
+    // Invoke the taxonomy hooks.
+    module_invoke_all("taxonomy_term_$op", $term);
+    module_invoke_all("entity_$op", $term, 'taxonomy_term');
+  }
+  catch (Exception $e) {
+    $transaction->rollback('taxonomy term');
+    watchdog_exception('taxonomy term', $e);
+    throw $e;
   }
-
-  // Reset the taxonomy term static variables.
-  taxonomy_terms_static_reset();
-
-  // Invoke the taxonomy hooks.
-  module_invoke_all("taxonomy_term_$op", $term);
-  module_invoke_all("entity_$op", $term, 'taxonomy_term');
-
+  
   return $status;
 }
 
Index: modules/user/user.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/user/user.module,v
retrieving revision 1.1194
diff -u -p -r1.1194 user.module
--- modules/user/user.module	22 Aug 2010 13:52:59 -0000	1.1194
+++ modules/user/user.module	23 Aug 2010 09:45:02 -0000
@@ -2732,29 +2732,39 @@ function user_role_load_by_name($role_na
  *   performed.
  */
 function user_role_save($role) {
-  if ($role->name) {
-    // Prevent leading and trailing spaces in role names.
-    $role->name = trim($role->name);
-  }
-  if (!isset($role->weight)) {
-    // Set a role weight to make this new role last.
-    $query = db_select('role');
-    $query->addExpression('MAX(weight)');
-    $role->weight = $query->execute()->fetchField() + 1;
-  }
-  if (!empty($role->rid) && $role->name) {
-    $status = drupal_write_record('role', $role, 'rid');
-    module_invoke_all('user_role_update', $role);
-  }
-  else {
-    $status = drupal_write_record('role', $role);
-    module_invoke_all('user_role_insert', $role);
+  $transaction = db_transaction();
+  $status = FALSE;
+  
+  try {
+    if ($role->name) {
+      // Prevent leading and trailing spaces in role names.
+      $role->name = trim($role->name);
+    }
+    if (!isset($role->weight)) {
+      // Set a role weight to make this new role last.
+      $query = db_select('role');
+      $query->addExpression('MAX(weight)');
+      $role->weight = $query->execute()->fetchField() + 1;
+    }
+    if (!empty($role->rid) && $role->name) {
+      $status = drupal_write_record('role', $role, 'rid');
+      module_invoke_all('user_role_update', $role);
+    }
+    else {
+      $status = drupal_write_record('role', $role);
+      module_invoke_all('user_role_insert', $role);
+    }
+  
+    // Clear the user access cache.
+    drupal_static_reset('user_access');
+    drupal_static_reset('user_role_permissions');
+  }
+  catch (Exception $e) {
+    $transaction->rollback('user role');
+    watchdog_exception('user role', $e);
+    throw $e;
   }
-
-  // Clear the user access cache.
-  drupal_static_reset('user_access');
-  drupal_static_reset('user_role_permissions');
-
+  
   return $status;
 }
 
