We get these errors in the watchdog:
Duplicate entry '3415499-60' for key 1 query: INSERT INTO role_expire (uid, rid, expiry_timestamp) VALUES (3415499, 60, 1257844486)
The issue is that db_affected_rows() doesn't quite behave as one would expect - if the row already exists, and the value is not actually changed, it returns 0; thus, the attempted insert. No harm is actually done, but the error should be avoided. Cheap solution would be @ on the INSERT statement cleaner would be to use drupal_write_record(): try an update, check for a return of SAVED_UPDATED, and if not then do the insert.
Comments
Comment #1
Mark Theunissen commentedThe problem with using drupal_write_record is that it's also the caller's responsibility to know whether the record exists. If you attempt an update by passing the primary key as the last parameter, it will always return SAVED_UPDATED, even if it actually inserts a record.
Comment #2
stewsnoozeThis looks good. I'll apply it later today. I think you have one more patch coming?
Comment #3
Mark Theunissen commentedThere are a number of ways of fixing this:
I guess it's a tradeoff... do we care more about extra queries that will happen every time a user is loaded, or is it better to have them occur when a user is being updated/saved? I'm leaning towards updated/saved.
Comment #4
stewsnoozeThe cost should be on save, not on load. Save is a much more infrequent event.
Comment #5
stewsnoozeComment #6
stewsnoozeMark, Mike,
I've committed a change to CVS for this that checks for existence of a row to be updated. It then only updates the row if the expiry_timestamp is different, otherwise it inserts a row.
Opinions?
http://drupalcode.org/viewvc/drupal/contributions/modules/role_expire/ro...
Comment #7
sharplesa commentedI think this is fixed as of 1.10. Wake it up if it's not.