6767#include <string.h>
6868#include <time.h>
6969
70+ // Some older systems do not support timespec_get() from time.h
71+ #if !defined(__STDC_VERSION__ ) || __STDC_VERSION__ < 201112L || \
72+ (!defined(TIME_UTC ) && (!defined(_POSIX_TIMERS ) || _POSIX_TIMERS <= 0 ))
73+ #include <sys/time.h>
74+ #endif
75+
7076#include "sqlite3ext.h"
7177SQLITE_EXTENSION_INIT3
7278
7379#if !defined(SQLITE_ASCII ) && !defined(SQLITE_EBCDIC )
7480#define SQLITE_ASCII 1
7581#endif
7682
83+ // timespec_now returns the current time with nanosecond precision.
84+ static struct timespec timespec_now (void ) {
85+ struct timespec ts ;
86+ #if defined(__STDC_VERSION__ ) && __STDC_VERSION__ >= 201112L && defined(TIME_UTC )
87+ timespec_get (& ts , TIME_UTC );
88+ #elif defined(_POSIX_TIMERS ) && (_POSIX_TIMERS > 0 )
89+ clock_gettime (CLOCK_REALTIME , & ts );
90+ #else
91+ struct timeval tv ;
92+ gettimeofday (& tv , NULL );
93+ ts .tv_sec = tv .tv_sec ;
94+ ts .tv_nsec = tv .tv_usec * 1000 ;
95+ #endif
96+ return ts ;
97+ }
98+
7799/*
78100 * Translate a single byte of Hex into an integer.
79101 * This routine only works if h really is a valid hexadecimal
@@ -191,23 +213,22 @@ static void uuid_v7_generate(sqlite3_context* context, int argc, sqlite3_value**
191213 (void )argc ;
192214 (void )argv ;
193215
194- struct timespec ts ;
216+ unsigned long long timestamp_ms ;
195217 if (argc == 1 && sqlite3_value_type (argv [0 ]) == SQLITE_INTEGER ) {
196218 sqlite3_int64 seconds = sqlite3_value_int64 (argv [0 ]);
197- ts .tv_sec = seconds ;
198- ts .tv_nsec = 0 ;
219+ timestamp_ms = seconds * 1000ULL ;
199220 } else {
200- timespec_get (& ts , TIME_UTC );
221+ struct timespec ts = timespec_now ();
222+ timestamp_ms = ts .tv_sec * 1000ULL + ts .tv_nsec / 1000000 ;
201223 }
202- unsigned long long timestampMs = ts .tv_sec * 1000ULL + ts .tv_nsec / 1000000 ;
203224
204225 sqlite3_randomness (16 , aBlob );
205- aBlob [0 ] = timestampMs >> 40 ;
206- aBlob [1 ] = timestampMs >> 32 ;
207- aBlob [2 ] = timestampMs >> 24 ;
208- aBlob [3 ] = timestampMs >> 16 ;
209- aBlob [4 ] = timestampMs >> 8 ;
210- aBlob [5 ] = timestampMs ;
226+ aBlob [0 ] = timestamp_ms >> 40 ;
227+ aBlob [1 ] = timestamp_ms >> 32 ;
228+ aBlob [2 ] = timestamp_ms >> 24 ;
229+ aBlob [3 ] = timestamp_ms >> 16 ;
230+ aBlob [4 ] = timestamp_ms >> 8 ;
231+ aBlob [5 ] = timestamp_ms ;
211232 aBlob [6 ] = (aBlob [6 ] & 0x0f ) + 0x70 ;
212233 aBlob [8 ] = (aBlob [8 ] & 0x3f ) + 0x80 ;
213234 sqlite3_uuid_blob_to_str (aBlob , zStr );
@@ -228,12 +249,12 @@ static void uuid_v7_extract_timestamp_ms(sqlite3_context* context, int argc, sql
228249 if (pBlob == 0 || (pBlob [6 ] >> 4 ) != 7 )
229250 return ;
230251
231- unsigned long long timestampMs = 0 ;
252+ unsigned long long timestamp_ms = 0 ;
232253 for (size_t i = 0 ; i < 6 ; ++ i ) {
233- timestampMs = (timestampMs << 8 ) + pBlob [i ];
254+ timestamp_ms = (timestamp_ms << 8 ) + pBlob [i ];
234255 }
235256
236- sqlite3_result_int64 (context , timestampMs );
257+ sqlite3_result_int64 (context , timestamp_ms );
237258}
238259
239260#endif
0 commit comments