You are here

protected function DatabaseBackend::doSetMultiple in Drupal 9

Same name and namespace in other branches
  1. 8 core/lib/Drupal/Core/Cache/DatabaseBackend.php \Drupal\Core\Cache\DatabaseBackend::doSetMultiple()

Stores multiple items in the persistent cache.

Parameters

array $items: An array of cache items, keyed by cid.

See also

\Drupal\Core\Cache\CacheBackendInterface::setMultiple()

1 call to DatabaseBackend::doSetMultiple()
DatabaseBackend::setMultiple in core/lib/Drupal/Core/Cache/DatabaseBackend.php
Store multiple items in the persistent cache.

File

core/lib/Drupal/Core/Cache/DatabaseBackend.php, line 217

Class

DatabaseBackend
Defines a default cache implementation.

Namespace

Drupal\Core\Cache

Code

protected function doSetMultiple(array $items) {
  $values = [];
  foreach ($items as $cid => $item) {
    $item += [
      'expire' => CacheBackendInterface::CACHE_PERMANENT,
      'tags' => [],
    ];
    assert(Inspector::assertAllStrings($item['tags']), 'Cache Tags must be strings.');
    $item['tags'] = array_unique($item['tags']);

    // Sort the cache tags so that they are stored consistently in the DB.
    sort($item['tags']);
    $fields = [
      'cid' => $this
        ->normalizeCid($cid),
      'expire' => $item['expire'],
      'created' => round(microtime(TRUE), 3),
      'tags' => implode(' ', $item['tags']),
      'checksum' => $this->checksumProvider
        ->getCurrentChecksum($item['tags']),
    ];

    // Avoid useless writes.
    if ($fields['checksum'] === CacheTagsChecksumInterface::INVALID_CHECKSUM_WHILE_IN_TRANSACTION) {
      continue;
    }
    if (!is_string($item['data'])) {
      $fields['data'] = serialize($item['data']);
      $fields['serialized'] = 1;
    }
    else {
      $fields['data'] = $item['data'];
      $fields['serialized'] = 0;
    }
    $values[] = $fields;
  }

  // If all $items were useless writes, we may end up with zero writes.
  if (empty($values)) {
    return;
  }

  // Use an upsert query which is atomic and optimized for multiple-row
  // merges.
  $query = $this->connection
    ->upsert($this->bin)
    ->key('cid')
    ->fields([
    'cid',
    'expire',
    'created',
    'tags',
    'checksum',
    'data',
    'serialized',
  ]);
  foreach ($values as $fields) {

    // Only pass the values since the order of $fields matches the order of
    // the insert fields. This is a performance optimization to avoid
    // unnecessary loops within the method.
    $query
      ->values(array_values($fields));
  }
  $query
    ->execute();
}