Snowflake IDs
Added in version 33.
Nextcloud integrates a customized version of Snowflake IDs (https://en.wikipedia.org/wiki/Snowflake_ID).
- It allows to generates unique IDs in advance and also contains information about creation:
creation time at millisecond precision
identifier of server which created the ID. It’s usually a hash of server hostname or random if not hostname found.
whether the ID was created from CLI or not
Store a Snowflake ID in database
Snowflake IDs are designed to be used as primary key in database.
They should be stored as UNSIGNED BIGINT (64 bits integer, always positive)
In Nextcloud migrations it looks like:
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
if (!$schema->hasTable('my_table')) {
$table = $schema->createTable('my_table');
$table->addColumn(
'id',
Types::BIGINT,
['notnull' => true, 'unsigned' => true]
);
$table->setPrimaryKey(['id']);
// TODO Add other fields
}
Generate a Snowflake ID
To generate a new ID, call nextId function on the generator:
<?php
declare(strict_types=1);
namespace OCA\MyApp;
use OCP\Snowflake\IGenerator;
class MyObjectFactory {
public function __construct(
private readonly IGenerator $generator,
) {
// TODO Add your implementation
}
public function create(): MyObject {
/** @var string $id */
$id = $this->generator->nextId();
// TODO Create other properties and insert into database
}
}
Decode a Snowflake ID
IDs can be decoded with occ snowflake:decode <id> command.
It’s also possible to decode IDs in your code, for example to get creation time of your object:
<?php
declare(strict_types=1);
namespace OCA\MyApp;
use DateTimeImmutable
use OCP\Snowflake\IDecoder;
class MyObject {
private string $id;
public function __construct(
private readonly IDecoder $decoder,
) {
// TODO Add your implementation
}
public function createdAt(): DateTimeImmutable {
return $this->decoder->decode($this->id)['createdAt'];
}
}