3

I need to know the 'to be inserted ID'

I wrote the following function, it works, however, I'm sure this is not the way to do it.

 function insert_node_style($style) {
  // get latest id
  $id = db_query("SELECT MAX(nid) FROM {node}")->fetchCol('nid');
  $id = array_shift(array_values($id));
  $new_nid = $id + '1';
  // insert nid, vid and style
  db_insert('nodestyle_node') ->fields(array(
    'nid' => $new_nid,
    'vid' => '1',
    'style' => $style,
  ))
  ->execute();
}

Is there are cleaner/drupal way to achieve the same result?

3 Answers 3

2

I don't think there's a 100% reliable way to get the ID that will be used next. Even the method you've got won't work completely. Take this example:

  • Insert a node into the database (it has the new nid of 1 for arguments sake)
  • Insert another node into the database (it has the new nid of 2)
  • Then delete that second node
  • Add a new node to the database again. This time it will have a nid of 3, not 2 (as would be expected from your code).

The problem is that the MySQL AUTO_INCREMENT value exists completely independently of the primary key ids that are currently in the database; so unless you reset the auto increment counter each time there's no way to reliably determine the next id.

Also in a system with multiple simultaneous accessess to the database using code like that introduces potential race conditions.

It would be far simpler to perform this task when the node has been saved, perhaps in hook_node_save().

Oh and one other little thing, the vid you're inserting should not be 1, it'll be determined for you by the system. Using 1 for every node will link every single node to one revision in the node_revision table...probably not what you're looking for.

1
  • oh thanks clive, tested the delete scenario and you're right, of course.. thanks for the hook_node_save(), I will post the solution when fixed :) Oct 9, 2012 at 13:07
2

The next nid for a node is not determined based on the maximum value of the nid column in the node table. In MySQL, it can be set explicitly using

ALTER TABLE node AUTO_INCREMENT = 42;

and is also subject to the auto_increment_increment variable.

You will also run into TOCTOU-problems when making assumptions about what the next nid will be.

Look for some other way to solve the underlying problem without making assumptions about what the next nid will be.

1
  • thanks to you too oswald, gonna check on hook_node_save() and I'll report back when I fixed this Oct 9, 2012 at 13:10
1

How about replacing your current query with:

SELECT Auto_increment 
FROM information_schema.tables 
WHERE table_name='the_table_you_want'
AND table_schema = DATABASE();

See https://stackoverflow.com/questions/933565/get-auto-increment-value-with-mysql-query

But I would have to agree with Oswald; is there another way to solve this problem?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.