nextcloud/lib/private/BackgroundJob/JobClassesRegistry.php
Côme Chilliet 1ab09ec753
chore: Apply new coding standard to all files
The diff can be checked using: git diff --ignore-all-space --ignore-blank-lines
To see only the changes not related to blank lines.

Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>
2026-06-01 13:46:39 +02:00

100 lines
2.7 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
declare(strict_types=1);
/**
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OC\BackgroundJob;
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
use InvalidArgumentException;
use OCP\BackgroundJob\IJob;
use OCP\IDBConnection;
use OCP\Snowflake\ISnowflakeGenerator;
/**
* Map background job classes and their ID in database
*/
final class JobClassesRegistry {
/**
* @var array<string,string>
*/
private array $registry = [];
private const TABLE = 'job_classes_registry';
public function __construct(
private readonly IDBConnection $connection,
private readonly ISnowflakeGenerator $snowflakeGenerator,
) {
}
private function loadRegistry(): void {
if ($this->registry !== []) {
return;
}
$qb = $this->connection->getQueryBuilder();
$result = $qb->select('class_id', 'class_name')->from(self::TABLE)->executeQuery();
foreach ($result->iterateAssociative() as $row) {
$this->registry[$row['class_name']] = (string)$row['class_id'];
}
}
/**
* Resolve current ID or generates a new one
*/
public function getId(string $className): string {
$this->loadRegistry();
if (isset($this->registry[$className])) {
return $this->registry[$className];
}
if (!class_exists($className)) {
throw new InvalidArgumentException('Class ' . $className . ' doesnt exists');
}
if (!is_a($className, IJob::class, true)) {
throw new InvalidArgumentException('Class ' . $className . ' isnt an instance of ' . IJob::class);
}
$qb = $this->connection->getQueryBuilder();
try {
$classId = $this->snowflakeGenerator->nextId();
$qb
->insert(self::TABLE)
->values([
'class_id' => $qb->createNamedParameter($classId),
'class_name' => $qb->createNamedParameter($className),
])
->executeStatement();
$this->registry[$className] = $classId;
return $classId;
} catch (UniqueConstraintViolationException $e) {
// Class was probably added by a concurrent process
// Try to load it
$result = $qb->select('class_id')->from(self::TABLE)->where($qb->expr()->eq('class_name', $className))->executeQuery();
if ($classId = $result->fetchOne()) {
$classId = (string)$classId;
$this->registry[$className] = $classId;
return $classId;
}
}
throw new \Exception('Fail to retrieve ' . $className . ' ID', previous: $e);
}
public function getName(string|int $classId): string {
$this->loadRegistry();
$classId = (string)$classId;
$className = array_search($classId, $this->registry, true);
if ($className === false) {
throw new InvalidArgumentException('Class ID ' . $classId . ' doesnt match any class name');
}
return $className;
}
}