feat: document Snowflake IDs

Signed-off-by: Benjamin Gaussorgues <benjamin.gaussorgues@nextcloud.com>
This commit is contained in:
Benjamin Gaussorgues
2025-10-23 14:49:12 +02:00
parent 96a9c541be
commit dd9e066e76
3 changed files with 127 additions and 0 deletions

View File

@@ -46,6 +46,7 @@ occ command Directory
* :ref:`system_tags_commands_label`
* :ref:`antivirus_commands_label`
* :ref:`setupchecks_commands_label`
* :ref:`snowflakes_commands_label`
* :ref:`share_operations_label`
* `Debugging`_
@@ -2273,6 +2274,28 @@ Example output::
✓ Internet connectivity
...
.. _snowflakes_commands_label:
Snowflake IDs
-------------
You can decode Snowflake IDs with occ::
sudo -E -u www-data php occ decode-snowflake <snowflake_id>
Example output::
+--------------------+-------------------------+
| Snowflake ID | 6768789079123765868 |
| Seconds | 1575981518 |
| Milliseconds | 50 |
| Created from CLI | no |
| Server ID | 441 |
| Sequence ID | 2668 |
| Creation timestamp | 3335258318.050 |
| Creation date | 2075-09-09 12:38:38.050 |
+--------------------+-------------------------+
.. _share_operations_label:
Share operations

View File

@@ -38,6 +38,7 @@ Digging deeper
security
settings
setup_checks
snowflake_ids
speech-to-text
talk
task_processing

View File

@@ -0,0 +1,103 @@
.. _snowflake_ids:
=============
Snowflake IDs
=============
.. versionadded:: 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:
.. code-block:: php
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:
.. code-block:: php
<?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 decode-snowflake <id>`` command.
Its also possible to decode IDs in your code, for example to get creation time of your object:
.. code-block:: php
<?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'];
}
}