]> granicus.if.org Git - postgresql/blob - contrib/uuid-ossp/uuid-ossp.c
Contrib module uuid-ossp for generating UUID values using the OSSP UUID
[postgresql] / contrib / uuid-ossp / uuid-ossp.c
1 /*-------------------------------------------------------------------------
2  *
3  * UUID generation functions using the OSSP UUID library
4  *
5  * Copyright (c) 2007 PostgreSQL Global Development Group
6  *
7  * $PostgreSQL: pgsql/contrib/uuid-ossp/uuid-ossp.c,v 1.1 2007/04/21 17:26:17 petere Exp $
8  *
9  *-------------------------------------------------------------------------
10  */
11
12 #include "postgres.h"
13 #include "fmgr.h"
14 #include "utils/builtins.h"
15 #include "utils/uuid.h"
16
17 #include <ossp/uuid.h>
18
19
20 /* better both be 16 */
21 #if (UUID_LEN != UUID_LEN_BIN)
22 #error UUID length mismatch
23 #endif
24
25
26 PG_MODULE_MAGIC;
27
28
29 Datum uuid_nil(PG_FUNCTION_ARGS);
30 Datum uuid_ns_dns(PG_FUNCTION_ARGS);
31 Datum uuid_ns_url(PG_FUNCTION_ARGS);
32 Datum uuid_ns_oid(PG_FUNCTION_ARGS);
33 Datum uuid_ns_x500(PG_FUNCTION_ARGS);
34
35 Datum uuid_generate_v1(PG_FUNCTION_ARGS);
36 Datum uuid_generate_v1mc(PG_FUNCTION_ARGS);
37 Datum uuid_generate_v3(PG_FUNCTION_ARGS);
38 Datum uuid_generate_v4(PG_FUNCTION_ARGS);
39 Datum uuid_generate_v5(PG_FUNCTION_ARGS);
40
41
42 PG_FUNCTION_INFO_V1(uuid_nil);
43 PG_FUNCTION_INFO_V1(uuid_ns_dns);
44 PG_FUNCTION_INFO_V1(uuid_ns_url);
45 PG_FUNCTION_INFO_V1(uuid_ns_oid);
46 PG_FUNCTION_INFO_V1(uuid_ns_x500);
47
48 PG_FUNCTION_INFO_V1(uuid_generate_v1);
49 PG_FUNCTION_INFO_V1(uuid_generate_v1mc);
50 PG_FUNCTION_INFO_V1(uuid_generate_v3);
51 PG_FUNCTION_INFO_V1(uuid_generate_v4);
52 PG_FUNCTION_INFO_V1(uuid_generate_v5);
53
54
55 static char *
56 uuid_to_string(const uuid_t *uuid)
57 {
58         char   *buf = palloc(UUID_LEN_STR + 1);
59         void   *ptr = buf;
60         size_t  len = UUID_LEN_STR + 1;
61
62         uuid_export(uuid, UUID_FMT_STR, &ptr, &len);
63
64         return buf;
65 }
66
67
68 static void
69 string_to_uuid(const char *str, uuid_t *uuid)
70 {
71         uuid_import(uuid, UUID_FMT_STR, str, UUID_LEN_STR + 1);
72 }
73
74
75 static Datum
76 special_uuid_value(const char *name)
77 {
78         uuid_t *uuid;
79         char   *str;
80
81         uuid_create(&uuid);
82         uuid_load(uuid, name);
83         str = uuid_to_string(uuid);
84         uuid_destroy(uuid);
85
86         return DirectFunctionCall1(uuid_in, CStringGetDatum(str));
87 }
88
89
90 Datum
91 uuid_nil(PG_FUNCTION_ARGS)
92 {
93         return special_uuid_value("nil");
94 }
95
96
97 Datum
98 uuid_ns_dns(PG_FUNCTION_ARGS)
99 {
100         return special_uuid_value("ns:DNS");
101 }
102
103
104 Datum
105 uuid_ns_url(PG_FUNCTION_ARGS)
106 {
107         return special_uuid_value("ns:URL");
108 }
109
110
111 Datum
112 uuid_ns_oid(PG_FUNCTION_ARGS)
113 {
114         return special_uuid_value("ns:OID");
115 }
116
117
118 Datum
119 uuid_ns_x500(PG_FUNCTION_ARGS)
120 {
121         return special_uuid_value("ns:X500");
122 }
123
124
125 static Datum
126 uuid_generate_internal(int mode, const uuid_t *ns, const char *name)
127 {
128         uuid_t *uuid;
129         char   *str;
130
131         uuid_create(&uuid);
132         uuid_make(uuid, mode, ns, name);
133         str = uuid_to_string(uuid);
134         uuid_destroy(uuid);
135
136         return DirectFunctionCall1(uuid_in, CStringGetDatum(str));
137 }
138
139
140 Datum
141 uuid_generate_v1(PG_FUNCTION_ARGS)
142 {
143         return uuid_generate_internal(UUID_MAKE_V1, NULL, NULL);
144 }
145
146
147 Datum
148 uuid_generate_v1mc(PG_FUNCTION_ARGS)
149 {
150         return uuid_generate_internal(UUID_MAKE_V1 | UUID_MAKE_MC, NULL, NULL);
151 }
152
153
154 static Datum
155 uuid_generate_v35_internal(int mode, pg_uuid_t *ns, text *name)
156 {
157         uuid_t     *ns_uuid;
158         Datum           result;
159
160         uuid_create(&ns_uuid);
161         string_to_uuid(DatumGetCString(DirectFunctionCall1(uuid_out, UUIDPGetDatum(ns))),
162                                    ns_uuid);
163
164         result = uuid_generate_internal(mode,
165                                                                         ns_uuid,
166                                                                         DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(name))));
167
168         uuid_destroy(ns_uuid);
169
170         return result;
171 }
172
173
174 Datum
175 uuid_generate_v3(PG_FUNCTION_ARGS)
176 {
177         pg_uuid_t  *ns = PG_GETARG_UUID_P(0);
178         text       *name = PG_GETARG_TEXT_P(1);
179
180         return uuid_generate_v35_internal(UUID_MAKE_V3, ns, name);
181 }
182
183
184 Datum
185 uuid_generate_v4(PG_FUNCTION_ARGS)
186 {
187         return uuid_generate_internal(UUID_MAKE_V4, NULL, NULL);
188 }
189
190
191 Datum
192 uuid_generate_v5(PG_FUNCTION_ARGS)
193 {
194         pg_uuid_t  *ns = PG_GETARG_UUID_P(0);
195         text       *name = PG_GETARG_TEXT_P(1);
196
197         return uuid_generate_v35_internal(UUID_MAKE_V5, ns, name);
198 }