public function Connection::nextId

Same name in this branch
  1. 8.x drupal/core/lib/Drupal/Core/Database/Connection.php \Drupal\Core\Database\Connection::nextId()
  2. 8.x drupal/core/lib/Drupal/Core/Database/Driver/mysql/Connection.php \Drupal\Core\Database\Driver\mysql\Connection::nextId()
  3. 8.x drupal/core/lib/Drupal/Core/Database/Driver/sqlite/Connection.php \Drupal\Core\Database\Driver\sqlite\Connection::nextId()
  4. 8.x drupal/core/lib/Drupal/Core/Database/Driver/pgsql/Connection.php \Drupal\Core\Database\Driver\pgsql\Connection::nextId()

Retrive a the next id in a sequence.

PostgreSQL has built in sequences. We'll use these instead of inserting and updating a sequences table.

Overrides Connection::nextId

File

drupal/core/lib/Drupal/Core/Database/Driver/pgsql/Connection.php, line 243
Definition of Drupal\Core\Database\Driver\pgsql\Connection

Class

Connection

Namespace

Drupal\Core\Database\Driver\pgsql

Code

public function nextId($existing = 0) {

  // Retrive the name of the sequence. This information cannot be cached
  // because the prefix may change, for example, like it does in simpletests.
  $sequence_name = $this
    ->makeSequenceName('sequences', 'value');

  // When PostgreSQL gets a value too small then it will lock the table,
  // retry the INSERT and if it's still too small then alter the sequence.
  $id = $this
    ->query("SELECT nextval('" . $sequence_name . "')")
    ->fetchField();
  if ($id > $existing) {
    return $id;
  }

  // PostgreSQL advisory locks are simply locks to be used by an
  // application such as Drupal. This will prevent other Drupal proccesses
  // from altering the sequence while we are.
  $this
    ->query("SELECT pg_advisory_lock(" . self::POSTGRESQL_NEXTID_LOCK . ")");

  // While waiting to obtain the lock, the sequence may have been altered
  // so lets try again to obtain an adequate value.
  $id = $this
    ->query("SELECT nextval('" . $sequence_name . "')")
    ->fetchField();
  if ($id > $existing) {
    $this
      ->query("SELECT pg_advisory_unlock(" . self::POSTGRESQL_NEXTID_LOCK . ")");
    return $id;
  }

  // Reset the sequence to a higher value than the existing id.
  $this
    ->query("ALTER SEQUENCE " . $sequence_name . " RESTART WITH " . ($existing + 1));

  // Retrive the next id. We know this will be as high as we want it.
  $id = $this
    ->query("SELECT nextval('" . $sequence_name . "')")
    ->fetchField();
  $this
    ->query("SELECT pg_advisory_unlock(" . self::POSTGRESQL_NEXTID_LOCK . ")");
  return $id;
}