Skip to content

Commit c9135b9

Browse files
committed
UUID version and timestamp.
1 parent 0d9ed94 commit c9135b9

File tree

2 files changed

+66
-6
lines changed

2 files changed

+66
-6
lines changed

ext/uuid/uuid.go

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"bytes"
88
"errors"
99
"fmt"
10+
"time"
1011

1112
"github.com/google/uuid"
1213

@@ -35,7 +36,9 @@ func Register(db *sqlite3.Conn) error {
3536
db.CreateFunction("uuid", 2, sqlite3.INNOCUOUS, generate),
3637
db.CreateFunction("uuid", 3, sqlite3.INNOCUOUS, generate),
3738
db.CreateFunction("uuid_str", 1, flags, toString),
38-
db.CreateFunction("uuid_blob", 1, flags, toBlob))
39+
db.CreateFunction("uuid_blob", 1, flags, toBlob),
40+
db.CreateFunction("uuid_extract_version", 1, flags, version),
41+
db.CreateFunction("uuid_extract_timestamp", 1, flags, timestamp))
3942
}
4043

4144
func generate(ctx sqlite3.Context, arg ...sqlite3.Value) {
@@ -167,3 +170,30 @@ func toString(ctx sqlite3.Context, arg ...sqlite3.Value) {
167170
ctx.ResultText(u.String())
168171
}
169172
}
173+
174+
func version(ctx sqlite3.Context, arg ...sqlite3.Value) {
175+
u, err := fromValue(arg[0])
176+
if err != nil {
177+
ctx.ResultError(err)
178+
return // notest
179+
}
180+
if u.Variant() == uuid.RFC4122 {
181+
ctx.ResultInt64(int64(u.Version()))
182+
}
183+
}
184+
185+
func timestamp(ctx sqlite3.Context, arg ...sqlite3.Value) {
186+
u, err := fromValue(arg[0])
187+
if err != nil {
188+
ctx.ResultError(err)
189+
return // notest
190+
}
191+
if u.Variant() == uuid.RFC4122 {
192+
switch u.Version() {
193+
case 1, 2, 6, 7:
194+
ctx.ResultTime(
195+
time.Unix(u.Time().UnixTime()),
196+
sqlite3.TimeFormatDefault)
197+
}
198+
}
199+
}

ext/uuid/uuid_test.go

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package uuid
22

33
import (
44
"testing"
5+
"time"
56

67
"github.com/google/uuid"
78

@@ -106,7 +107,26 @@ func Test_generate(t *testing.T) {
106107
t.Error("want error")
107108
}
108109

109-
hash := []struct {
110+
var tstamp time.Time
111+
var version uuid.Version
112+
err = db.QueryRow(`
113+
SELECT
114+
column1,
115+
uuid_extract_version(column1),
116+
uuid_extract_timestamp(column1)
117+
FROM (VALUES (uuid(7)))
118+
`).Scan(&u, &version, &tstamp)
119+
if err != nil {
120+
t.Fatal(err)
121+
}
122+
if got := u.Version(); got != version {
123+
t.Errorf("got %d, want %d", got, version)
124+
}
125+
if got := time.Unix(u.Time().UnixTime()); !got.Equal(tstamp) {
126+
t.Errorf("got %v, want %v", got, tstamp)
127+
}
128+
129+
tests := []struct {
110130
ver uuid.Version
111131
ns any
112132
data string
@@ -120,7 +140,7 @@ func Test_generate(t *testing.T) {
120140
{3, "url", "https://www.php.net", uuid.MustParse("3f703955-aaba-3e70-a3cb-baff6aa3b28f")},
121141
{5, "url", "https://www.php.net", uuid.MustParse("a8f6ae40-d8a7-58f0-be05-a22f94eca9ec")},
122142
}
123-
for _, tt := range hash {
143+
for _, tt := range tests {
124144
err = db.QueryRow(`SELECT uuid(?, ?, ?)`, tt.ver, tt.ns, tt.data).Scan(&u)
125145
if err != nil {
126146
t.Fatal(err)
@@ -142,14 +162,14 @@ func Test_convert(t *testing.T) {
142162
defer db.Close()
143163

144164
var u uuid.UUID
145-
lits := []string{
165+
tests := []string{
146166
"'6ba7b8119dad11d180b400c04fd430c8'",
147167
"'6ba7b811-9dad-11d1-80b4-00c04fd430c8'",
148168
"'{6ba7b811-9dad-11d1-80b4-00c04fd430c8}'",
149169
"X'6ba7b8119dad11d180b400c04fd430c8'",
150170
}
151171

152-
for _, tt := range lits {
172+
for _, tt := range tests {
153173
err = db.QueryRow(`SELECT uuid_str(` + tt + `)`).Scan(&u)
154174
if err != nil {
155175
t.Fatal(err)
@@ -159,7 +179,7 @@ func Test_convert(t *testing.T) {
159179
}
160180
}
161181

162-
for _, tt := range lits {
182+
for _, tt := range tests {
163183
err = db.QueryRow(`SELECT uuid_blob(` + tt + `)`).Scan(&u)
164184
if err != nil {
165185
t.Fatal(err)
@@ -178,4 +198,14 @@ func Test_convert(t *testing.T) {
178198
if err == nil {
179199
t.Fatal("want error")
180200
}
201+
202+
err = db.QueryRow(`SELECT uuid_extract_version(X'cafe')`).Scan(&u)
203+
if err == nil {
204+
t.Fatal("want error")
205+
}
206+
207+
err = db.QueryRow(`SELECT uuid_extract_timestamp(X'cafe')`).Scan(&u)
208+
if err == nil {
209+
t.Fatal("want error")
210+
}
181211
}

0 commit comments

Comments
 (0)