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.
$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.
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.
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;
}
?>