function DatabaseBackend::doSetMultiple

Same name in other branches
  1. 9 core/lib/Drupal/Core/Cache/DatabaseBackend.php \Drupal\Core\Cache\DatabaseBackend::doSetMultiple()
  2. 8.9.x core/lib/Drupal/Core/Cache/DatabaseBackend.php \Drupal\Core\Cache\DatabaseBackend::doSetMultiple()
  3. 11.x 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 251

Class

DatabaseBackend
Defines a default cache implementation.

Namespace

Drupal\Core\Cache

Code

protected function doSetMultiple(array $items) {
    // Chunk the items as the database might not be able to receive thousands
    // of items in a single query.
    $chunks = array_chunk($items, self::MAX_ITEMS_PER_CACHE_SET, TRUE);
    foreach ($chunks as $chunk_items) {
        $values = [];
        foreach ($chunk_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'] = $this->serializer
                    ->encode($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 (count($values) === 0) {
            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();
    }
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.