From 7a85f738b715a7cd2a99512b243e68704cde0894 Mon Sep 17 00:00:00 2001 From: Ben Ramsey Date: Sat, 7 Mar 2020 23:29:27 -0600 Subject: [PATCH] [ci skip] Complete documentation for version 6 UUIDs --- docs/customize.rst | 11 + docs/customize/ordered-time-codec.rst | 5 + docs/customize/timestamp-first-comb-codec.rst | 5 + docs/index.rst | 1 + docs/nonstandard.rst | 1 - docs/nonstandard/comb.rst | 5 - docs/nonstandard/version6.rst | 199 +++++++++++++++++- 7 files changed, 220 insertions(+), 7 deletions(-) create mode 100644 docs/customize.rst create mode 100644 docs/customize/ordered-time-codec.rst create mode 100644 docs/customize/timestamp-first-comb-codec.rst delete mode 100644 docs/nonstandard/comb.rst diff --git a/docs/customize.rst b/docs/customize.rst new file mode 100644 index 0000000..cafd884 --- /dev/null +++ b/docs/customize.rst @@ -0,0 +1,11 @@ +.. _customize: + +============= +Customization +============= + +.. toctree:: + :titlesonly: + + customize/ordered-time-codec + customize/timestamp-first-comb-codec diff --git a/docs/customize/ordered-time-codec.rst b/docs/customize/ordered-time-codec.rst new file mode 100644 index 0000000..ce3a75d --- /dev/null +++ b/docs/customize/ordered-time-codec.rst @@ -0,0 +1,5 @@ +.. _customize.ordered-time-codec: + +================== +Ordered-time Codec +================== diff --git a/docs/customize/timestamp-first-comb-codec.rst b/docs/customize/timestamp-first-comb-codec.rst new file mode 100644 index 0000000..909395d --- /dev/null +++ b/docs/customize/timestamp-first-comb-codec.rst @@ -0,0 +1,5 @@ +.. _customize.timestamp-first-comb-codec: + +========================== +Timestamp-first COMB Codec +========================== diff --git a/docs/index.rst b/docs/index.rst index 65a48e8..9e769e5 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -19,6 +19,7 @@ Contents quickstart rfc4122 nonstandard + customize upgrading FAQs reference diff --git a/docs/nonstandard.rst b/docs/nonstandard.rst index 2374a52..725bb81 100644 --- a/docs/nonstandard.rst +++ b/docs/nonstandard.rst @@ -6,5 +6,4 @@ Nonstandard UUIDs :titlesonly: nonstandard/version6 - nonstandard/comb nonstandard/guid diff --git a/docs/nonstandard/comb.rst b/docs/nonstandard/comb.rst deleted file mode 100644 index 06c7c31..0000000 --- a/docs/nonstandard/comb.rst +++ /dev/null @@ -1,5 +0,0 @@ -.. _nonstandard.codec.comb: - -===== -COMBs -===== diff --git a/docs/nonstandard/version6.rst b/docs/nonstandard/version6.rst index f75a7af..0489d5b 100644 --- a/docs/nonstandard/version6.rst +++ b/docs/nonstandard/version6.rst @@ -1,5 +1,202 @@ .. _nonstandard.version6: ======================= -Version 6: Ordered Time +Version 6: Ordered-Time ======================= + +.. admonition:: Experimental + :class: warning + + Version 6, ordered-time UUIDs are an experimental feature based on an + `Internet-Draft under review`_ at the IETF. While the basic layout is not + expected to change, be aware that the draft is a moving target. If there + are significant changes to the layout, ramsey/uuid will attempt to maintain + backward compatibility but cannot guarantee it. + +Version 6 UUIDs solve two problems that have long existed with the use of +:ref:`version 1 ` UUIDs: + +1. Scattered database records +2. Inability to sort by identifier in a meaningful way (i.e., insert order) + +To overcome these issues, we need the ability to generate UUID that is +*monotonically increasing*, while still providing all the benefits of a version +1 UUID. + +Version 6 UUIDs do this by storing the time in standard byte order, instead of +breaking it up and rearranging the time bytes, according to the `RFC 4122`_ +definition. All other fields remain the same, and the version maintains its +position, according to RFC 4122. + +In all other ways, version 6 UUIDs function like version 1 UUIDs. + +.. tip:: + + Prior to version 4.0.0, ramsey/uuid provided a solution for this with the + :ref:`ordered-time codec `. Use of the + ordered-time codec is still valid and acceptable. However, you may replace + UUIDs generated using the ordered-time codec with version 6 UUIDs. Keep + reading to find out how. + +.. code-block:: php + :caption: Generate a version 6, ordered-time UUID + :name: nonstandard.version6.example + + use Ramsey\Uuid\Uuid; + + $uuid = Uuid::uuid6(); + + printf( + "UUID: %s\nVersion: %d\nDate: %s\nNode: %s\n", + $uuid->toString(), + $uuid->getFields()->getVersion(), + $uuid->getDateTime()->format('r'), + $uuid->getFields()->getNode()->toString() + ); + +This will generate a version 6 UUID and print out its string representation, the +time the UUID was created, and the node used to create the UUID. + +It will look something like this: + +.. code-block:: text + + UUID: 1ea60f56-b67b-61fc-829a-0242ac130003 + Version: 6 + Date: Sun, 08 Mar 2020 04:29:37 +0000 + Node: 0242ac130003 + +You may provide custom values for version 6 UUIDs, including node and clock +sequence. + +.. code-block:: php + :caption: Provide custom node and clock sequence to create a version 6, + ordered-time UUID + :name: nonstandard.version6.custom-example + + use Ramsey\Uuid\Provider\Node\StaticNodeProvider; + use Ramsey\Uuid\Type\Hexadecimal; + use Ramsey\Uuid\Uuid; + + $nodeProvider = new StaticNodeProvider(new Hexadecimal('121212121212')); + $clockSequence = 16383; + + $uuid = Uuid::uuid6($nodeProvider->getNode(), $clockSequence); + + +.. _nonstandard.version6.nodes: + +Custom and Random Nodes +####################### + +In the :ref:`example above `, we provided a +custom node when generating a version 6 UUID. You may also generate random +node values. + +To learn more, see the :ref:`rfc4122.version1.custom` and +:ref:`rfc4122.version1.random` sections under :ref:`rfc4122.version1`. + + +.. _nonstandard.version6.clock: + +Clock Sequence +############## + +In a version 6 UUID, the clock sequence serves the same purpose as in a version +1 UUID. See :ref:`rfc4122.version1.clock` to learn more. + + +.. _nonstandard.version6.version1-conversion: + +Version 1-to-6 Conversion +######################### + +It is possible to convert back-and-forth between version 6 and version 1 UUIDs. + +.. code-block:: php + :caption: Convert a version 1 UUID to a version 6 UUID + :name: nonstandard.version6.convert-version1-example + + use Ramsey\Uuid\Nonstandard\UuidV6; + use Ramsey\Uuid\Rfc4122\UuidV1; + use Ramsey\Uuid\Uuid; + + $uuid1 = Uuid::fromString('3960c5d8-60f8-11ea-bc55-0242ac130003'); + + if ($uuid1 instanceof UuidV1) { + $uuid6 = UuidV6::fromUuidV1($uuid1); + } + +.. code-block:: php + :caption: Convert a version 6 UUID to a version 1 UUID + :name: nonstandard.version6.convert-version6-example + + use Ramsey\Uuid\Nonstandard\UuidV6; + use Ramsey\Uuid\Uuid; + + $uuid6 = Uuid::fromString('1ea60f83-960c-65d8-bc55-0242ac130003'); + + if ($uuid6 instanceof UuidV6) { + $uuid1 = $uuid6->toUuidV1(); + } + + +.. _nonstandard.version6.ordered-time-conversion: + +Ordered-time to Version 6 Conversion +#################################### + +You may convert UUIDs previously generated and stored using the +:ref:`ordered-time codec ` into version 6 UUIDs. + +.. caution:: + + If you perform this conversion, the bytes and string representation of your + UUIDs will change. This will break any software that expects your + identifiers to be fixed. + +.. code-block:: php + :caption: Convert an ordered-time codec encoded UUID to a version 6 UUID + :name: nonstandard.version6.convert-ordered-time-example + + use Ramsey\Uuid\Codec\OrderedTimeCodec; + use Ramsey\Uuid\Nonstandard\UuidV6; + use Ramsey\Uuid\Rfc4122\UuidV1; + use Ramsey\Uuid\UuidFactory; + + // The bytes of a version 1 UUID previously stored in some datastore + // after encoding to bytes with the OrderedTimeCodec. + $bytes = hex2bin('11ea60faf17c8af6ad23acde48001122'); + + $factory = new UuidFactory(); + $codec = new OrderedTimeCodec($factory->getUuidBuilder()); + + $factory->setCodec($codec); + + $orderedTimeUuid = $factory->fromBytes($bytes); + + if ($orderedTimeUuid instanceof UuidV1) { + $uuid6 = UuidV6::fromUuidV1($orderedTimeUuid); + } + + +.. _nonstandard.version6.privacy: + +Privacy Concerns +################ + +Like :ref:`version 1 UUIDs `, version 6 UUIDs use a MAC +address from a local hardware network interface. This means it is possible to +uniquely identify the machine on which a version 6 UUID was created. + +If the value provided by the timestamp of a version 6 UUID is important to you, +but you do not wish to expose the interface address of any of your local +machines, see :ref:`nonstandard.version6.nodes`. + +If you do not need an identifier with a node value embedded in it, but you still +need the benefit of a monotonically increasing unique identifier, see +:ref:`customize.timestamp-first-comb-codec`. + + +.. _Internet-Draft under review: https://tools.ietf.org/html/draft-peabody-dispatch-new-uuid-format +.. _RFC 4122: https://tools.ietf.org/html/rfc4122