drupal_write_record

Definition

drupal_write_record($table, &$object, $primary_keys = array())
drupal/includes/common.inc, line 3705

Description

Save a record to the database based upon the schema.

Default values are filled in for missing items, and 'serial' (auto increment) types are filled in with IDs.

Parameters

$table The name of the table; this must exist in schema API.

$object The object to write. This is a reference, as defaults according to the schema may be filled in on the object, as well as ID on the serial type(s). Both array an object types may be passed.

$primary_keys If this is an update, specify the primary keys' field names. It is the caller's responsibility to know if a record for this object already exists in the database. If there is only 1 key, you may pass a simple string.

Return value

Failure to write a record will return FALSE. Otherwise SAVED_NEW or SAVED_UPDATED is returned depending on the operation performed. The $object parameter contains values for any serial fields defined by the $table. For example, $object->nid will be populated after inserting a new node.

Related topics

Namesort iconDescription
Input validationFunctions to validate user input.
Schema APIA Drupal schema definition is an array structure representing one or more tables and their related keys and indexes. A schema is defined by hook_schema(), which usually lives in a modulename.install file.

Code

function drupal_write_record($table, &$object, $primary_keys = array()) {
  // Standardize $primary_keys to an array.
  if (is_string($primary_keys)) {
    $primary_keys = array($primary_keys);
  }

  $schema = drupal_get_schema($table);
  if (empty($schema)) {
    return FALSE;
  }

  // Convert to an object if needed.
  if (is_array($object)) {
    $object = (object) $object;
    $array = TRUE;
  }
  else {
    $array = FALSE;
  }

  $fields = array();

  // Go through our schema, build SQL, and when inserting, fill in defaults for
  // fields that are not set.
  foreach ($schema['fields'] as $field => $info) {
    // Special case -- skip serial types if we are updating.
    if ($info['type'] == 'serial' && !empty($primary_keys)) {
      continue;
    }

    // For inserts, populate defaults from schema if not already provided.
    if (!isset($object->$field) && empty($primary_keys) && isset($info['default'])) {
      $object->$field = $info['default'];
    }

    // Track serial field so we can helpfully populate them after the query.
    // NOTE: Each table should come with one serial field only.
    if ($info['type'] == 'serial') {
      $serial = $field;
      // Ignore values for serial when inserting data. Unsupported.
      unset($object->$field);
    }

    // Build arrays for the fields and values in our query.
    if (isset($object->$field)) {
      if (empty($info['serialize'])) {
        $fields[$field] = $object->$field;
      }
      elseif (!empty($object->$field)) {
        $fields[$field] = serialize($object->$field);
      }
      else {
        $fields[$field] = '';
      }
    }

    // We don't need to care about type casting if value does not exist.
    if (!isset($fields[$field])) {
      continue;
    }

    // Special case -- skip null value if field allows null.
    if ($fields[$field] == NULL && $info['not null'] == FALSE) {
      continue;
    }

    // Type cast if field does not allow null. Required by DB API.
    if ($info['type'] == 'int' || $info['type'] == 'serial') {
      $fields[$field] = (int) $fields[$field];
    }
    elseif ($info['type'] == 'float') {
      $fields[$field] = (float) $fields[$field];
    }
    else {
      $fields[$field] = (string) $fields[$field];
    }
  }

  if (empty($fields)) {
    // No changes requested.
    // If we began with an array, convert back so we don't surprise the caller.
    if ($array) {
      $object = (array) $object;
    }
    return;
  }

  // Build the SQL.
  if (empty($primary_keys)) {
    $query = db_insert($table)->fields($fields);
    $return = SAVED_NEW;
  }
  else {
    $query = db_update($table)->fields($fields);
    foreach ($primary_keys as $key){
      $query->condition($key, $object->$key);
    }
    $return = SAVED_UPDATED;
  }

  // Execute the SQL.
  if ($last_insert_id = $query->execute()) {
    if (isset($serial)) {
      // Populate the serial field.
      $object->$serial = $last_insert_id;
    }
  }
  else {
    $return = FALSE;
  }

  // If we began with an array, convert back so we don't surprise the caller.
  if ($array) {
    $object = (array) $object;
  }

  return $return;
}