15
15
#include <sqlite3ext.h>
16
16
SQLITE_EXTENSION_INIT1
17
17
#include <assert.h>
18
- #include <fcntl.h>
19
- #include <unistd.h>
20
- #include <stdio.h>
21
- #include <stdlib.h>
18
+ #include <uuid/uuid.h>
22
19
23
20
/*
24
- ** A UUID represents an RFC 4122 UUID .
21
+ ** Implementation of uuid1() function .
25
22
*/
26
- typedef struct UUID {
27
- unsigned char bytes [16 ];
28
- } UUID ;
29
-
30
- /*
31
- ** Set the UUID version.
32
- */
33
- void set_uuid_version (UUID * u , char version ) {
34
- u -> bytes [6 ] = (u -> bytes [6 ] & 0x0f ) | (version << 4 );
23
+ static void uuid1func (
24
+ sqlite3_context * context ,
25
+ int argc ,
26
+ sqlite3_value * * argv
27
+ ){
28
+ assert (argc == 0 );
29
+ uuid_t uuid ;
30
+ uuid_generate_time (uuid );
31
+ char uuid_str [37 ];
32
+ uuid_unparse_lower (uuid , uuid_str );
33
+ sqlite3_result_text (context , uuid_str , 37 , SQLITE_TRANSIENT );
35
34
}
36
35
37
36
/*
38
- ** Set the UUID variant to match the RFC4122 specification.
39
- **
40
- ** Example:
41
- **
42
- ** e462c464-d4d9-433b-b372-cc90939dbe6d
43
- ** ^
44
- ** one of {8, 9, a, b}
37
+ ** Implementation of the uuid4() function.
45
38
*/
46
- void set_uuid_variant (UUID * u ) {
47
- u -> bytes [8 ] = (u -> bytes [8 ] & 0x3f ) | 0x80 ;
39
+ static void uuid4func (
40
+ sqlite3_context * context ,
41
+ int argc ,
42
+ sqlite3_value * * argv
43
+ ){
44
+ assert (argc == 0 );
45
+ uuid_t uuid ;
46
+ uuid_generate_random (uuid );
47
+ char uuid_str [37 ];
48
+ uuid_unparse_lower (uuid , uuid_str );
49
+ sqlite3_result_text (context , uuid_str , 37 , SQLITE_TRANSIENT );
48
50
}
49
51
50
52
/*
51
- ** Represent a UUID in its canonical string form .
53
+ ** Register UUID functions to database `db` .
52
54
*/
53
- char * uuid_to_string (UUID * u ) {
54
-
55
- int i ;
56
- char * buf = sqlite3_malloc (sizeof (char )* 36 + 1 );
57
-
58
- for (i = 0 ; i < 4 ; i ++ ) {
59
- sprintf (& buf [2 * i ], "%02x" , u -> bytes [i ]);
60
- }
61
- sprintf (& buf [8 ], "-" );
62
- for (i = 4 ; i < 6 ; i ++ ) {
63
- sprintf (& buf [2 * i + 1 ], "%02x" , u -> bytes [i ]);
64
- }
65
- sprintf (& buf [13 ], "-" );
66
- for (i = 6 ; i < 8 ; i ++ ) {
67
- sprintf (& buf [2 * i + 2 ], "%02x" , u -> bytes [i ]);
68
- }
69
- sprintf (& buf [18 ], "-" );
70
- for (i = 8 ; i < 10 ; i ++ ) {
71
- sprintf (& buf [2 * i + 3 ], "%02x" , u -> bytes [i ]);
72
- }
73
- sprintf (& buf [23 ], "-" );
74
- for (i = 10 ; i < 16 ; i ++ ) {
75
- sprintf (& buf [2 * i + 4 ], "%02x" , u -> bytes [i ]);
76
- }
55
+ int register_uuid_functions (sqlite3 * db ) {
56
+ typedef struct UUIDScalar {
57
+ const char * name ;
58
+ int argc ;
59
+ int enc ;
60
+ void (* func )(sqlite3_context * , int , sqlite3_value * * );
61
+ } UUIDScalar ;
77
62
78
- return buf ;
79
- }
63
+ UUIDScalar scalars [] = {
64
+ {"uuid1" , 0 , SQLITE_UTF8 , uuid1func },
65
+ {"uuid4" , 0 , SQLITE_UTF8 , uuid4func },
66
+ };
80
67
81
- UUID random_uuid () {
82
- UUID u ;
68
+ int rc = SQLITE_OK ;
69
+ int i , n ;
83
70
84
- int fd = open ("/dev/urandom" , O_RDONLY );
85
- read (fd , u .bytes , sizeof (u .bytes ));
86
- close (fd );
71
+ n = (int )(sizeof (scalars )/sizeof (scalars [0 ]));
87
72
88
- set_uuid_version ( & u , 4 );
89
- set_uuid_variant ( & u ) ;
90
- return u ;
91
- }
73
+ for ( i = 0 ; rc == SQLITE_OK && i < n ; i ++ ) {
74
+ UUIDScalar * s = & scalars [ i ] ;
75
+ rc = sqlite3_create_function ( db , s -> name , s -> argc , s -> enc , 0 , s -> func , 0 , 0 ) ;
76
+ }
92
77
93
- /*
94
- ** Implementation of the uuid4() function.
95
- */
96
- static void uuid4func (
97
- sqlite3_context * context ,
98
- int argc ,
99
- sqlite3_value * * argv
100
- ){
101
- assert (argc == 0 );
102
- UUID uuid = random_uuid ();
103
- char * buf = uuid_to_string (& uuid );
104
- sqlite3_result_text (context , (char * )buf , 36 , SQLITE_TRANSIENT );
105
- sqlite3_free (buf );
78
+ return rc ;
106
79
}
107
80
108
81
#ifdef _WIN32
@@ -113,8 +86,6 @@ int sqlite3_uuid_init(
113
86
char * * pzErrMsg ,
114
87
const sqlite3_api_routines * pApi
115
88
){
116
- int rc = SQLITE_OK ;
117
89
SQLITE_EXTENSION_INIT2 (pApi );
118
- rc = sqlite3_create_function (db , "uuid4" , 0 , SQLITE_UTF8 , 0 , uuid4func , 0 , 0 );
119
- return rc ;
90
+ return register_uuid_functions (db );
120
91
}
0 commit comments