/**
  * Execute a complex manipulation on the database.
  * A manipulation is an array of insert / or update sequences.  The keys of the array are table names,
  * and the values are map containing 'command' and 'fields'.  Command should be 'insert' or 'update',
  * and fields should be a map of field names to field values, NOT including quotes.
  *
  * The field values could also be in paramaterised format, such as
  * array('MAX(?,?)' => array(42, 69)), allowing the use of raw SQL values such as
  * array('NOW()' => array()).
  *
  * @see SQLWriteExpression::addAssignments for syntax examples
  *
  * @param array $manipulation
  */
 public function manipulate($manipulation)
 {
     if (empty($manipulation)) {
         return;
     }
     foreach ($manipulation as $table => $writeInfo) {
         if (empty($writeInfo['fields'])) {
             continue;
         }
         // Note: keys of $fieldValues are not escaped
         $fieldValues = $writeInfo['fields'];
         // Switch command type
         switch ($writeInfo['command']) {
             case "update":
                 // Build update
                 $query = new SQLUpdate("\"{$table}\"", $this->escapeColumnKeys($fieldValues));
                 // Set best condition to use
                 if (!empty($writeInfo['where'])) {
                     $query->addWhere($writeInfo['where']);
                 } elseif (!empty($writeInfo['id'])) {
                     $query->addWhere(array('"ID"' => $writeInfo['id']));
                 }
                 // Test to see if this update query shouldn't, in fact, be an insert
                 if ($query->toSelect()->count()) {
                     $query->execute();
                     break;
                 }
                 // ...if not, we'll skip on to the insert code
             // ...if not, we'll skip on to the insert code
             case "insert":
                 // Ensure that the ID clause is given if possible
                 if (!isset($fieldValues['ID']) && isset($writeInfo['id'])) {
                     $fieldValues['ID'] = $writeInfo['id'];
                 }
                 // Build insert
                 $query = new SQLInsert("\"{$table}\"", $this->escapeColumnKeys($fieldValues));
                 $query->execute();
                 break;
             default:
                 user_error("SS_Database::manipulate() Can't recognise command '{$writeInfo['command']}'", E_USER_ERROR);
         }
     }
 }