drupal_write_record

Versions
mediamosa-21
drupal_write_record($table, &$object, $primary_keys = array())

Saves 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 be defined by a hook_schema() implementation.

$object An object or array representing the record to write, passed in by reference. The function will fill in defaults from the schema and add an ID value to serial fields.

$primary_keys If this is an update, specify the primary keys' field names. If this is a new record, you must not provide this value. If there is only 1 field in the key, you may pass in a string; if there are multiple fields in the key, pass in an array.

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 will contain values for any serial fields defined by the $table. For example, $object->nid or $object['nid'] will be populated after inserting a new a new node.

Related topics

▾ 25 functions call drupal_write_record()

block_theme_initialize in modules/block/block.module
Assign an initial, default set of blocks for a theme.
contact_category_edit_form_submit in modules/contact/contact.admin.inc
Process the contact category edit page form submission.
field_create_field in modules/field/field.crud.inc
Creates a field.
field_test_entity_save in modules/field/tests/field_test.entity.inc
Saves a test_entity.
field_update_field in modules/field/field.crud.inc
Updates a field.
file_save in includes/file.inc
Save a file object to the database.
filter_format_save in modules/filter/filter.module
Save a text format object to the database.
hook_menu_link_insert in modules/menu/menu.api.php
Inform modules that a menu link has been created.
image_effect_save in modules/image/image.module
Save an image effect.
image_style_save in modules/image/image.module
Save an image style.
locale_date_format_save in includes/locale.inc
Save locale specific date formats to the database.
module_test_enable in modules/simpletest/tests/module_test.install
Implements hook_enable().
module_test_install in modules/simpletest/tests/module_test.install
Implements hook_install().
node_save in modules/node/node.module
Save changes to a node or add a new node.
path_save in includes/path.inc
Save a path alias to the database.
shortcut_set_save in modules/shortcut/shortcut.module
Saves a shortcut set.
system_date_format_save in modules/system/system.module
Save a date format to the database.
system_date_format_type_save in modules/system/system.module
Save a date type to the database.
taxonomy_term_save in modules/taxonomy/taxonomy.module
Save a term object to the database.
taxonomy_vocabulary_save in modules/taxonomy/taxonomy.module
Save a vocabulary given a vocabulary object.
user_role_save in modules/user/user.module
Save a user role to the database.
user_save in modules/user/user.module
Save changes to a user account or add a new user.
_block_rehash in modules/block/block.module
Update the 'block' DB table with the blocks currently exported by modules.
_field_write_instance in modules/field/field.crud.inc
Stores an instance record in the field configuration database.
_node_save_revision in modules/node/node.module
Helper function to save a revision with the uid of the current user.

Code

includes/common.inc, line 5722

<?php
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) {
    if ($info['type'] == 'serial') {
      // Skip serial types if we are updating.
      if (!empty($primary_keys)) {
        continue;
      }
      // Track serial field so we can helpfully populate them after the query.
      // NOTE: Each table should come with one serial field only.
      $serial = $field;
    }

    if (!property_exists($object, $field)) {
      // Skip fields that are not provided, unless we are inserting and a
      // default value is provided by the schema.
      if (!empty($primary_keys) || !isset($info['default'])) {
        continue;
      }
      $object->$field = $info['default'];
    }

    // Build array of fields to update or insert.
    if (empty($info['serialize'])) {
      $fields[$field] = $object->$field;
    }
    elseif (isset($object->$field)) {
      $fields[$field] = serialize($object->$field);
    }
    else {
      $fields[$field] = '';
    }

    // Type cast to proper datatype, except when the value is NULL and the
    // column allows this.
    //
    // MySQL PDO silently casts e.g. FALSE and '' to 0 when inserting the value
    // into an integer column, but PostgreSQL PDO does not. Also type cast NULL
    // when the column does not allow this.
    if (!is_null($object->$field) || !empty($info['not null'])) {
      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)) {
    // We are doing an insert.
    $options = array('return' => Database::RETURN_INSERT_ID);
    if (isset($serial) && isset($fields[$serial])) {
      // If the serial column has been explicitly set with an ID, then we don't
      // require the database to return the last insert id.
      if ($fields[$serial]) {
        $options['return'] = Database::RETURN_AFFECTED;
      }
      // If a serial column does exist with no value (i.e. 0) then remove it as
      // the database will insert the correct value for us.
      else {
        unset($fields[$serial]);
      }
    }
    $query = db_insert($table, $options)->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 ($query_return = $query->execute()) {
    if (isset($serial)) {
      // If the database was not told to return the last insert id, it will be
      // because we already know it.
      if (isset($options) && $options['return'] != Database::RETURN_INSERT_ID) {
        $object->$serial = $fields[$serial];
      }
      else {
        $object->$serial = $query_return;
      }
    }
  }
  // If we have a single-field primary key but got no insert ID, the
  // query failed. Note that we explicitly check for FALSE, because
  // a valid update query which doesn't change any values will return
  // zero (0) affected rows.
  elseif ($query_return === FALSE && count($primary_keys) == 1) {
    $return = FALSE;
  }

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

  return $return;
}
?>