From ac10ca65204488a12ec4592fd4395da124b5ee2f Mon Sep 17 00:00:00 2001 From: chris s <18578417+umeldt@users.noreply.github.com> Date: Sun, 8 Dec 2024 23:29:02 +0900 Subject: [PATCH] allow setting an explicit timestamp when generating a uuidv7 --- docs/uuid.md | 12 ++++++++++++ src/uuid/extension.c | 10 ++++++++-- test/uuid.sql | 1 + 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/docs/uuid.md b/docs/uuid.md index 5153ee52..39af5038 100644 --- a/docs/uuid.md +++ b/docs/uuid.md @@ -52,6 +52,18 @@ select uuid7(); -- 018ff383-94fd-70fa-8da6-339180b8e15d ``` +The timestamp used for creating the UUID can be specified explicitly by passing the number of seconds since 1 January 1970. + +```sql +select uuid7(0); +-- 00000000-0000-7558-a13b-e7014913d8ad +``` + +```sql +select uuid7(1700000000); +-- 018bcfe5-6800-7b8a-8a96-e315717d31bb +``` + ### uuid7_timestamp_ms ```text diff --git a/src/uuid/extension.c b/src/uuid/extension.c index a809cdd7..45b1e0a6 100644 --- a/src/uuid/extension.c +++ b/src/uuid/extension.c @@ -14,6 +14,7 @@ * * uuid4() - generate a version 4 UUID as a string * uuid7() - generate a version 7 UUID as a string + * uuid7(X) - generate a version 7 UUID as a string using X seconds since the unix epoch as the timestamp * uuid_str(X) - convert a UUID X into a well-formed UUID string * uuid_blob(X) - convert a UUID X into a 16-byte blob * uuid7_timestamp_ms(X) - extract unix timestamp in miliseconds @@ -190,7 +191,12 @@ static void uuid_v7_generate(sqlite3_context* context, int argc, sqlite3_value** (void)argv; struct timespec ts; - timespec_get(&ts, TIME_UTC); + if (argc == 1 && sqlite3_value_type(argv[0])==SQLITE_INTEGER) { + sqlite3_int64 seconds = sqlite3_value_int64(argv[0]); + ts.tv_sec = seconds; + } else { + timespec_get(&ts, TIME_UTC); + } unsigned long long timestampMs = ts.tv_sec * 1000ULL + ts.tv_nsec / 1000000; sqlite3_randomness(16, aBlob); @@ -266,7 +272,7 @@ int uuid_init(sqlite3* db) { sqlite3_create_function(db, "uuid4", 0, flags, 0, uuid_v4_generate, 0, 0); sqlite3_create_function(db, "gen_random_uuid", 0, flags, 0, uuid_v4_generate, 0, 0); #ifndef SQLEAN_OMIT_UUID7 - sqlite3_create_function(db, "uuid7", 0, flags, 0, uuid_v7_generate, 0, 0); + sqlite3_create_function(db, "uuid7", -1, flags, 0, uuid_v7_generate, 0, 0); sqlite3_create_function(db, "uuid7_timestamp_ms", 1, det_flags, 0, uuid_v7_extract_timestamp_ms, 0, 0); #endif diff --git a/test/uuid.sql b/test/uuid.sql index c9c49971..19679e24 100644 --- a/test/uuid.sql +++ b/test/uuid.sql @@ -30,6 +30,7 @@ select '3_07', uuid_blob(null) is null; -- uuid7 select '4_01', uuid7() like '________-____-7___-____-____________'; +select '4_02', uuid7(0) like '00000000-0000-7___-____-____________'; -- uuid7_timestamp_ms select '5_01', uuid7_timestamp_ms('018ff38a-a5c9-712d-bc80-0550b3ad41a2') = 1717777901001;