You are here

public function Connection::nextId in Drupal 9

Same name in this branch
  1. 9 core/lib/Drupal/Core/Database/Connection.php \Drupal\Core\Database\Connection::nextId()
  2. 9 core/tests/fixtures/database_drivers/custom/fake/Connection.php \Drupal\Driver\Database\fake\Connection::nextId()
  3. 9 core/lib/Drupal/Core/Database/Driver/sqlite/Connection.php \Drupal\Core\Database\Driver\sqlite\Connection::nextId()
  4. 9 core/lib/Drupal/Core/Database/Driver/pgsql/Connection.php \Drupal\Core\Database\Driver\pgsql\Connection::nextId()
  5. 9 core/lib/Drupal/Core/Database/Driver/mysql/Connection.php \Drupal\Core\Database\Driver\mysql\Connection::nextId()
Same name and namespace in other branches
  1. 8 core/lib/Drupal/Core/Database/Driver/sqlite/Connection.php \Drupal\Core\Database\Driver\sqlite\Connection::nextId()

Retrieves a unique ID from a given sequence.

Use this function if for some reason you can't use a serial field. For example, MySQL has no ways of reading of the current value of a sequence and PostgreSQL can not advance the sequence to be larger than a given value. Or sometimes you just need a unique integer.

Parameters

$existing_id: (optional) After a database import, it might be that the sequences table is behind, so by passing in the maximum existing ID, it can be assured that we never issue the same ID.

Return value

An integer number larger than any number returned by earlier calls and also larger than the $existing_id if one was passed in.

Overrides Connection::nextId

File

core/lib/Drupal/Core/Database/Driver/sqlite/Connection.php, line 444

Class

Connection
SQLite implementation of \Drupal\Core\Database\Connection.

Namespace

Drupal\Core\Database\Driver\sqlite

Code

public function nextId($existing_id = 0) {
  $this
    ->startTransaction();

  // We can safely use literal queries here instead of the slower query
  // builder because if a given database breaks here then it can simply
  // override nextId. However, this is unlikely as we deal with short strings
  // and integers and no known databases require special handling for those
  // simple cases. If another transaction wants to write the same row, it will
  // wait until this transaction commits.
  $stmt = $this
    ->prepareStatement('UPDATE {sequences} SET [value] = GREATEST([value], :existing_id) + 1', [], TRUE);
  $args = [
    ':existing_id' => $existing_id,
  ];
  try {
    $stmt
      ->execute($args);
  } catch (\Exception $e) {
    $this
      ->exceptionHandler()
      ->handleExecutionException($e, $stmt, $args, []);
  }
  if ($stmt
    ->rowCount() === 0) {
    $this
      ->query('INSERT INTO {sequences} ([value]) VALUES (:existing_id + 1)', $args);
  }

  // The transaction gets committed when the transaction object gets destroyed
  // because it gets out of scope.
  return $this
    ->query('SELECT [value] FROM {sequences}')
    ->fetchField();
}