You are here

function transaction_update in Transaction 6

Same name and namespace in other branches
  1. 5 transaction.module \transaction_update()

Utility function that abstracts transactionalized updates or inserts on a single row.

Parameters

string $table (required) The un-prefixed table name without curly : braces.

mixed $key_field (required) The name(s) of the column(s) to use when: identifying the row to update. If only a single column is being used to select the row, this may be a string. If more than one column is being used, this must be an array of strings. If this operation is an update, these columns must be present as keys in $fields with their desired WHERE = values.

array $fields An associative array mapping column names (keys) to: the values to be inserted/updated. For updates, only the columns with updated values need to be in this array.

Return value

mixed

File

./transaction.module, line 100
Provides a database transaction system for use with InnoDB tables in MySQL.

Code

function transaction_update($table, $key_field, $fields) {
  $txn = new Transaction();

  // Accept a string if the key field is one column
  $return_simple_key_field = FALSE;
  if (!is_array($key_field)) {
    $return_simple_key_field = TRUE;
    $key_field = array(
      $key_field,
    );
  }

  // Convert a passed object to an array
  $fields = (array) $fields;

  // Check if key columns are specified
  $key_field_set = TRUE;
  foreach ($key_field as $column) {
    if (!array_key_exists($column, $fields)) {
      $key_field_set = FALSE;
    }
  }

  // Update
  if ($key_field_set) {
    $sql = 'UPDATE {' . db_escape_table($table) . '} t SET ';
    $where = '';
    $updates = array();
    foreach ($fields as $key => $value) {
      if (!in_array($key, $key_field)) {
        if ($value !== NULL) {
          $updates[] = 't.' . $key . ' = "' . db_escape_string($value) . '"';
        }
        else {
          $updates[] = 't.' . $key . ' = NULL';
        }
      }
    }
    $sql .= implode(',', $updates) . ' ';
    $where .= ' WHERE 1 ';
    foreach ($key_field as $column) {
      if ($fields[$column] !== NULL) {
        $where .= 'AND ' . $column . ' = "' . $fields[$column] . '" ';
      }
      else {
        $where .= 'AND ' . $column . ' IS NULL ';
      }
    }
    $sql .= $where;
    db_query($sql);

    // Return if we've actually updated something
    if (db_affected_rows()) {

      // If we were passed a simple key, return the same
      if ($return_simple_key_field) {
        return $fields[$key_field[0]];
      }
      $return_fields = array();
      foreach ($key_field as $column) {
        $return_fields[$column] = $fields[$column];
      }
      return $return_fields;
    }

    // Return if there was nothing to change, but the row actually exists
    $sql = 'SELECT COUNT(*) FROM {' . db_escape_table($table) . '} ' . $where;
    $exists = db_result(db_query($sql, 0, 1));
    if ($exists) {
      $return_fields = array();
      foreach ($key_field as $column) {
        $return_fields[$column] = $fields[$column];
      }
      return $return_fields;
    }
  }
  else {

    // We can't autogenerate if the key is more than one column
    if (count($key_field) > 1) {
      return FALSE;
    }
  }

  // Insert
  $sql = 'INSERT INTO {' . db_escape_table($table) . '} ';
  $keys = array_keys($fields);
  $values = array();
  foreach ($fields as $key => $value) {
    if ($value !== NULL) {
      $values[] = '"' . db_escape_string($value) . '"';
    }
    else {
      $values[] = 'NULL';
    }
  }
  $sql .= '({' . db_escape_table($table) . '}.' . implode(',{' . db_escape_table($table) . '}.', $keys) . ') ';
  $sql .= 'VALUES (' . implode(',', $values) . ')';
  db_query($sql);
  if (!$key_field_set) {
    $fields[$key_field[0]] = db_last_insert_id($table, $key_field[0]);
  }

  // If we were passed a scalar key, return the key of the new row as a scalar
  if ($return_simple_key_field) {
    return $fields[$key_field[0]];
  }
  $return_fields = array();
  foreach ($key_field as $column) {
    $return_fields[$column] = $fields[$column];
  }
  return $return_fields;
}