Quantcast
Channel: EchoDitto Labs - Today I Learned...
Viewing all articles
Browse latest Browse all 20

drupal_write_record() Can Return a False Positive on Updates

$
0
0

Today I discovered that the 6.x version of drupal_write_record() returns '2' (or SAVED_UPDATED) even if no record was updated.

In order to update a record via drupal_write_record(), you have to provide both:

a) the primary key value for the record you're updating
b) the field name of the primary key or keys (e.g., 'nid')

I'm not really sure why b) is necessary, since Drupal should be able to get that information from Schema, and a prerequisite for using drupal_write_record() in the first place is that the table you're writing to was defined with Schema.

Anyway, an example:

$row=new stdClass();$row->title='whatever';$result= drupal_write_record('node',$row,'nid');print$result;

The above code returns '2' (SAVED_UPDATED), not FALSE as expected, even though we didn't provide the primary key for the row we wanted to update and, therefore, no row was updated. We get this result because the 6.x version of drupal_write_record() doesn't check to see if any rows were affected after the query was executed:

$query="UPDATE {".$table."} SET $query WHERE ".implode(' AND ',$conditions);$return= SAVED_UPDATED;} 
// Execute the SQL.if(db_query($query,$values)){...}else{$return=FALSE;}

Bad Drupal! Bad! All it does is check that db_query() didn't return FALSE, which only happens when a query is executed incorrectly — say, because of syntactical error. (I would also argue that you shouldn't name a variable $return, but that's a separate issue.)

Happily, the 7.x version of drupal_write_record() corrects this oversight:

// 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;}

Yay! But until you upgrade to D7, if you want to be sure that your update queries really were successful, just add a call to db_affected_rows():

$row=new stdClass();$row->title='whatever';$result= drupal_write_record('node',$row,'nid');if($result== SAVED_UPDATED && db_affected_rows()>0){// stuff to do if the record was really updated}else{// stuff to do if it wasn't}

Viewing all articles
Browse latest Browse all 20

Trending Articles