drupal_write_record

Versions
6
drupal_write_record($table, &$object, $update = array())
7
drupal_write_record($table, &$object, $primary_keys = array())

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.

$update 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

▾ 8 functions call drupal_write_record()

blogapi_metaweblog_new_media_object in modules/blogapi/blogapi.module
Blogging API callback. Inserts a file into Drupal.
contact_admin_edit_submit in modules/contact/contact.admin.inc
Process the contact category edit page form submission.
file_save_upload in includes/file.inc
Saves a file upload to a new location. The source file is validated as a proper upload and handled as such.
node_save in modules/node/node.module
Save a node object into the database.
taxonomy_save_term in modules/taxonomy/taxonomy.module
Helper function for taxonomy_form_term_submit().
taxonomy_save_vocabulary in modules/taxonomy/taxonomy.module
_block_rehash in modules/block/block.module
Update the 'blocks' DB table with the blocks currently exported by modules.
_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 3385

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

  $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 = $defs = $values = $serials = $placeholders = 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' && count($update)) {
      continue;
    }

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

    // Track serial fields so we can helpfully populate them after the query.
    if ($info['type'] == 'serial') {
      $serials[] = $field;
      // Ignore values for serials when inserting data. Unsupported.
      unset($object->$field);
    }

    // Build arrays for the fields, placeholders, and values in our query.
    if (isset($object->$field)) {
      $fields[] = $field;
      $placeholders[] = db_type_placeholder($info['type']);

      if (empty($info['serialize'])) {
        $values[] = $object->$field;
      }
      else {
        $values[] = serialize($object->$field);
      }
    }
  }

  // Build the SQL.
  $query = '';
  if (!count($update)) {
    $query = "INSERT INTO {". $table ."} (". implode(', ', $fields) .') VALUES ('. implode(', ', $placeholders) .')';
    $return = SAVED_NEW;
  }
  else {
    $query = '';
    foreach ($fields as $id => $field) {
      if ($query) {
        $query .= ', ';
      }
      $query .= $field .' = '. $placeholders[$id];
    }

    foreach ($update as $key){
      $conditions[] = "$key = ". db_type_placeholder($schema['fields'][$key]['type']);
      $values[] = $object->$key;
    }

    $query = "UPDATE {". $table ."} SET $query WHERE ". implode(' AND ', $conditions);
    $return = SAVED_UPDATED;
  }

  // Execute the SQL.
  if (db_query($query, $values)) {
    if ($serials) {
      // Get last insert ids and fill them in.
      foreach ($serials as $field) {
        $object->$field = db_last_insert_id($table, $field);
      }
    }
  }
  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;
}
?>

---

kiamlaluno - Tue, 2009-09-08 14:39

The function cannot be called from hook_install() because Drupal would not find the database schema defined from the module, which is still going to be installed, and enabled.

actually i'm pretty sure i

drewish - Mon, 2009-10-26 20:45

actually i'm pretty sure i have used it in hook_install(). i seem to remember that after using drupal_install_schema() you needed to use drupal_get_schema() clear the schema cache.

Also tried, but failed

remi - Fri, 2009-12-18 06:36

I also tried to use drupal_write_record() in hook_install() and it didn't see to work, even after calling drupal_install_schema() and drupal_get_schema(NULL, TRUE).

---

kiamlaluno - Tue, 2010-01-12 22:25

drupal_get_schema() calls module_load_all_includes(), which then calls module_list(). When module_list() is invoked, the module (which has not yet completed the installation) is not reported in the modules list, its implementation of hook_schema() will not be called, and Drupal will not have any information about the tables used by the module. In this case, drupal_write_record() doesn't write any data.

Be careful in combination with db_lock_table()

mkalkbrenner - Wed, 2010-01-06 19:29

Be careful in combination with db_lock_table(). See http://drupal.org/node/372308 for an explanation and a workaround.

$update as a "simple string": really?

jp.stacey - Wed, 2010-02-03 11:48

$update 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.

Is that really true? I tried this under D6 and got an error in the logs:

... WHERE 1 = unsupported type for db_type_placeholder in /var/www/drupal-6/includes/common.inc on line 3468

That code up there does a clear foreach ($update as $key), which suggests that "a simple string" won't cut it. Or does the documentation actually mean "you may pass an array consisting of one simple string"? I'm still not sure if that would work given that foreach.

Ahh, the instructions are

jp.stacey - Wed, 2010-02-03 12:03

Ahh, the instructions are ambiguous: you have to pass in the primary ID itself, as field(s) on $object, and then specify the field names as an array e.g:

<?php
 
/* ... */
 
$object->primary_id = 100;
 
drupal_write_record('mytable', $object, array('primary_id'));
?>

(The "simple string" does work, once you've figured the above trick out, because of the is_string() at the top of the function.)

Login or register to post comments
 
 

All source code and documentation on this site is released under the terms of the GNU General Public License, version 2 and later. Drupal is a registered trademark of Dries Buytaert.