mirror of
https://github.com/nextcloud/server.git
synced 2026-05-28 04:32:30 -04:00
feat: extend Entity and adjust QBMapper to support Snowflake IDs
Signed-off-by: Anna Larch <anna@nextcloud.com>
This commit is contained in:
parent
f546daada7
commit
a100ede789
6 changed files with 80 additions and 14 deletions
|
|
@ -44,7 +44,7 @@ class VersionEntity extends Entity implements JsonSerializable {
|
|||
|
||||
public function jsonSerialize(): array {
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'id' => $this->getId(),
|
||||
'file_id' => $this->fileId,
|
||||
'timestamp' => $this->timestamp,
|
||||
'size' => $this->size,
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@ return array(
|
|||
'OCP\\AppFramework\\Db\\IMapperException' => $baseDir . '/lib/public/AppFramework/Db/IMapperException.php',
|
||||
'OCP\\AppFramework\\Db\\MultipleObjectsReturnedException' => $baseDir . '/lib/public/AppFramework/Db/MultipleObjectsReturnedException.php',
|
||||
'OCP\\AppFramework\\Db\\QBMapper' => $baseDir . '/lib/public/AppFramework/Db/QBMapper.php',
|
||||
'OCP\\AppFramework\\Db\\SnowflakeAwareEntity' => $baseDir . '/lib/public/AppFramework/Db/SnowflakeAwareEntity.php',
|
||||
'OCP\\AppFramework\\Db\\TTransactional' => $baseDir . '/lib/public/AppFramework/Db/TTransactional.php',
|
||||
'OCP\\AppFramework\\Http' => $baseDir . '/lib/public/AppFramework/Http.php',
|
||||
'OCP\\AppFramework\\Http\\Attribute\\ARateLimit' => $baseDir . '/lib/public/AppFramework/Http/Attribute/ARateLimit.php',
|
||||
|
|
|
|||
|
|
@ -119,6 +119,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
|
|||
'OCP\\AppFramework\\Db\\IMapperException' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Db/IMapperException.php',
|
||||
'OCP\\AppFramework\\Db\\MultipleObjectsReturnedException' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Db/MultipleObjectsReturnedException.php',
|
||||
'OCP\\AppFramework\\Db\\QBMapper' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Db/QBMapper.php',
|
||||
'OCP\\AppFramework\\Db\\SnowflakeAwareEntity' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Db/SnowflakeAwareEntity.php',
|
||||
'OCP\\AppFramework\\Db\\TTransactional' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Db/TTransactional.php',
|
||||
'OCP\\AppFramework\\Http' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Http.php',
|
||||
'OCP\\AppFramework\\Http\\Attribute\\ARateLimit' => __DIR__ . '/../../..' . '/lib/public/AppFramework/Http/Attribute/ARateLimit.php',
|
||||
|
|
|
|||
|
|
@ -13,19 +13,23 @@ use function lcfirst;
|
|||
use function substr;
|
||||
|
||||
/**
|
||||
* @method int getId()
|
||||
* @method void setId(int $id)
|
||||
* @since 7.0.0
|
||||
* @psalm-consistent-constructor
|
||||
*/
|
||||
abstract class Entity {
|
||||
/** @var int $id */
|
||||
public $id = null;
|
||||
|
||||
private ?int $id = null;
|
||||
private array $_updatedFields = [];
|
||||
/** @var array<string, \OCP\DB\Types::*> */
|
||||
/** @psalm-param $_fieldTypes array<string, Types::*> */
|
||||
private array $_fieldTypes = ['id' => 'integer'];
|
||||
|
||||
public function setId($id): void {
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
public function getId(): ?int {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple alternative constructor for building entities from a request
|
||||
* @param array $params the array which was obtained via $this->params('key')
|
||||
|
|
@ -64,7 +68,7 @@ abstract class Entity {
|
|||
|
||||
|
||||
/**
|
||||
* @return array<string, \OCP\DB\Types::*> with attribute and type
|
||||
* @return array<string, Types::*> with attribute and type
|
||||
* @since 7.0.0
|
||||
*/
|
||||
public function getFieldTypes(): array {
|
||||
|
|
@ -266,8 +270,8 @@ abstract class Entity {
|
|||
* that value once its being returned from the database
|
||||
*
|
||||
* @param string $fieldName the name of the attribute
|
||||
* @param \OCP\DB\Types::* $type the type which will be used to match a cast
|
||||
* @since 31.0.0 Parameter $type is now restricted to {@see \OCP\DB\Types} constants. The formerly accidentally supported types 'int'|'bool'|'double' are mapped to Types::INTEGER|Types::BOOLEAN|Types::FLOAT accordingly.
|
||||
* @param Types::* $type the type which will be used to match a cast
|
||||
* @since 31.0.0 Parameter $type is now restricted to {@see Types} constants. The formerly accidentally supported types 'int'|'bool'|'double' are mapped to Types::INTEGER|Types::BOOLEAN|Types::FLOAT accordingly.
|
||||
* @since 7.0.0
|
||||
*/
|
||||
protected function addType(string $fieldName, string $type): void {
|
||||
|
|
|
|||
|
|
@ -112,13 +112,17 @@ abstract class QBMapper {
|
|||
$qb->setValue($column, $qb->createNamedParameter($value, $type));
|
||||
}
|
||||
|
||||
$qb->executeStatement();
|
||||
|
||||
if ($entity->id === null) {
|
||||
if ($entity instanceof SnowflakeAwareEntity) {
|
||||
/** @psalm-suppress DocblockTypeContradiction */
|
||||
$entity->setId();
|
||||
$qb->executeStatement();
|
||||
} elseif ($entity->getId() === null) {
|
||||
$qb->executeStatement();
|
||||
// When autoincrement is used id is always an int
|
||||
$entity->setId($qb->getLastInsertId());
|
||||
} else {
|
||||
$qb->executeStatement();
|
||||
}
|
||||
|
||||
return $entity;
|
||||
}
|
||||
|
||||
|
|
|
|||
56
lib/public/AppFramework/Db/SnowflakeAwareEntity.php
Normal file
56
lib/public/AppFramework/Db/SnowflakeAwareEntity.php
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
namespace OCP\AppFramework\Db;
|
||||
|
||||
use OCP\AppFramework\Attribute\Consumable;
|
||||
use OCP\DB\Types;
|
||||
use OCP\Server;
|
||||
use OCP\Snowflake\ISnowflakeDecoder;
|
||||
use OCP\Snowflake\ISnowflakeGenerator;
|
||||
use OCP\Snowflake\Snowflake;
|
||||
|
||||
/**
|
||||
* Entity with snowflake support
|
||||
*
|
||||
* @since 33.0.0
|
||||
*/
|
||||
#[Consumable(since: '33.0.0')]
|
||||
abstract class SnowflakeAwareEntity extends Entity {
|
||||
private ?string $id = null;
|
||||
protected ?Snowflake $snowflake = null;
|
||||
|
||||
/** @psalm-param $_fieldTypes array<string, Types::*> */
|
||||
private array $_fieldTypes = ['id' => Types::STRING];
|
||||
|
||||
/**
|
||||
* Automatically creates a snowflake ID
|
||||
*/
|
||||
#[\Override]
|
||||
public function setId($id = null): void {
|
||||
if ($this->id === null) {
|
||||
$this->id = Server::get(ISnowflakeGenerator::class)->nextId();
|
||||
$this->markFieldUpdated('id');
|
||||
}
|
||||
}
|
||||
|
||||
public function getCreatedAt(): ?\DateTimeImmutable {
|
||||
return $this->getSnowflake()?->getCreatedAt();
|
||||
}
|
||||
|
||||
public function getSnowflake(): ?Snowflake {
|
||||
if ($this->id === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($this->snowflake === null) {
|
||||
$this->snowflake = Server::get(ISnowflakeDecoder::class)->decode($this->id);
|
||||
}
|
||||
|
||||
return $this->snowflake;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue