Skip to content

Commit

Permalink
UUID version and timestamp.
Browse files Browse the repository at this point in the history
  • Loading branch information
ncruces committed Jan 28, 2025
1 parent 0d9ed94 commit c9135b9
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 6 deletions.
32 changes: 31 additions & 1 deletion ext/uuid/uuid.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"bytes"
"errors"
"fmt"
"time"

"github.com/google/uuid"

Expand Down Expand Up @@ -35,7 +36,9 @@ func Register(db *sqlite3.Conn) error {
db.CreateFunction("uuid", 2, sqlite3.INNOCUOUS, generate),
db.CreateFunction("uuid", 3, sqlite3.INNOCUOUS, generate),
db.CreateFunction("uuid_str", 1, flags, toString),
db.CreateFunction("uuid_blob", 1, flags, toBlob))
db.CreateFunction("uuid_blob", 1, flags, toBlob),
db.CreateFunction("uuid_extract_version", 1, flags, version),
db.CreateFunction("uuid_extract_timestamp", 1, flags, timestamp))
}

func generate(ctx sqlite3.Context, arg ...sqlite3.Value) {
Expand Down Expand Up @@ -167,3 +170,30 @@ func toString(ctx sqlite3.Context, arg ...sqlite3.Value) {
ctx.ResultText(u.String())
}
}

func version(ctx sqlite3.Context, arg ...sqlite3.Value) {
u, err := fromValue(arg[0])
if err != nil {
ctx.ResultError(err)
return // notest
}
if u.Variant() == uuid.RFC4122 {
ctx.ResultInt64(int64(u.Version()))
}
}

func timestamp(ctx sqlite3.Context, arg ...sqlite3.Value) {
u, err := fromValue(arg[0])
if err != nil {
ctx.ResultError(err)
return // notest
}
if u.Variant() == uuid.RFC4122 {
switch u.Version() {
case 1, 2, 6, 7:
ctx.ResultTime(
time.Unix(u.Time().UnixTime()),
sqlite3.TimeFormatDefault)
}
}
}
40 changes: 35 additions & 5 deletions ext/uuid/uuid_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package uuid

import (
"testing"
"time"

"github.com/google/uuid"

Expand Down Expand Up @@ -106,7 +107,26 @@ func Test_generate(t *testing.T) {
t.Error("want error")
}

hash := []struct {
var tstamp time.Time
var version uuid.Version
err = db.QueryRow(`
SELECT
column1,
uuid_extract_version(column1),
uuid_extract_timestamp(column1)
FROM (VALUES (uuid(7)))
`).Scan(&u, &version, &tstamp)
if err != nil {
t.Fatal(err)
}
if got := u.Version(); got != version {
t.Errorf("got %d, want %d", got, version)
}
if got := time.Unix(u.Time().UnixTime()); !got.Equal(tstamp) {
t.Errorf("got %v, want %v", got, tstamp)
}

tests := []struct {
ver uuid.Version
ns any
data string
Expand All @@ -120,7 +140,7 @@ func Test_generate(t *testing.T) {
{3, "url", "https://www.php.net", uuid.MustParse("3f703955-aaba-3e70-a3cb-baff6aa3b28f")},
{5, "url", "https://www.php.net", uuid.MustParse("a8f6ae40-d8a7-58f0-be05-a22f94eca9ec")},
}
for _, tt := range hash {
for _, tt := range tests {
err = db.QueryRow(`SELECT uuid(?, ?, ?)`, tt.ver, tt.ns, tt.data).Scan(&u)
if err != nil {
t.Fatal(err)
Expand All @@ -142,14 +162,14 @@ func Test_convert(t *testing.T) {
defer db.Close()

var u uuid.UUID
lits := []string{
tests := []string{
"'6ba7b8119dad11d180b400c04fd430c8'",
"'6ba7b811-9dad-11d1-80b4-00c04fd430c8'",
"'{6ba7b811-9dad-11d1-80b4-00c04fd430c8}'",
"X'6ba7b8119dad11d180b400c04fd430c8'",
}

for _, tt := range lits {
for _, tt := range tests {
err = db.QueryRow(`SELECT uuid_str(` + tt + `)`).Scan(&u)
if err != nil {
t.Fatal(err)
Expand All @@ -159,7 +179,7 @@ func Test_convert(t *testing.T) {
}
}

for _, tt := range lits {
for _, tt := range tests {
err = db.QueryRow(`SELECT uuid_blob(` + tt + `)`).Scan(&u)
if err != nil {
t.Fatal(err)
Expand All @@ -178,4 +198,14 @@ func Test_convert(t *testing.T) {
if err == nil {
t.Fatal("want error")
}

err = db.QueryRow(`SELECT uuid_extract_version(X'cafe')`).Scan(&u)
if err == nil {
t.Fatal("want error")
}

err = db.QueryRow(`SELECT uuid_extract_timestamp(X'cafe')`).Scan(&u)
if err == nil {
t.Fatal("want error")
}
}

0 comments on commit c9135b9

Please sign in to comment.