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
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;
}
?>Login or register to post comments 
---
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
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
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).
---
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()
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?
Is that really true? I tried this under D6 and got an error in the logs:
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 thatforeach.Ahh, the instructions are
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.)