Skip to content

Commit

Permalink
Add support for the third type of the ID. Closes #55
Browse files Browse the repository at this point in the history
  • Loading branch information
radekg committed Dec 3, 2021
1 parent 29825e7 commit 1a9f4f7
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 12 deletions.
43 changes: 35 additions & 8 deletions utils/ybdbid/ybdbid.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,38 @@ package ybdbid
import (
"encoding/base64"
"fmt"
"regexp"

"github.com/google/uuid"
)

// This ID type appears in the databasse when a snapshot with incorrect
// configuration is created via RPC. To trigger creating a snapshot
// with such ID, create a YSQL database where:
// - table namespace is not set
// - transaction aware is false
var nonUUIDIDTypeR *regexp.Regexp

func init() {
r, _ := regexp.Compile("^[a-fA-F0-9]{32}$")
nonUUIDIDTypeR = r
}

// YBDBID represents a parsed YugabyteDB.
type YBDBID interface {
Bytes() []byte
UUID() uuid.UUID
String() string
}

type defaultYBDBID struct {
bytes []byte
uuid uuid.UUID
str string
}

func (id *defaultYBDBID) Bytes() []byte {
return id.bytes
}

func (id *defaultYBDBID) UUID() uuid.UUID {
return id.uuid
}

func (id *defaultYBDBID) String() string {
return id.str
}
Expand All @@ -36,11 +44,21 @@ func (id *defaultYBDBID) String() string {
func TryParseFromBytes(input []byte) (YBDBID, error) {
aUUID := uuid.New()
if err := aUUID.UnmarshalBinary(input); err != nil {

// if it failed, it could be a third ID type:
if nonUUIDIDTypeR.Match(input) {
output := &defaultYBDBID{
bytes: make([]byte, len(input)),
str: string(input),
}
copy(output.bytes, input)
return output, nil
}

return nil, err
}
output := &defaultYBDBID{
bytes: make([]byte, len(input)),
uuid: aUUID,
str: aUUID.String(),
}
copy(output.bytes, input)
Expand All @@ -52,6 +70,16 @@ func TryParseFromBytes(input []byte) (YBDBID, error) {
// as originally returned by the protobuf API.
func TryParseFromString(input string) (YBDBID, error) {

// support third type of ID:
if nonUUIDIDTypeR.Match([]byte(input)) {
output := &defaultYBDBID{
bytes: make([]byte, len(input)),
str: string(input),
}
copy(output.bytes, input)
return output, nil
}

// try decoding as base64:
maybeDecoded, err := base64.StdEncoding.DecodeString(input)
if err == nil {
Expand All @@ -74,7 +102,6 @@ func TryParseFromString(input string) (YBDBID, error) {

output := &defaultYBDBID{
bytes: make([]byte, len(bys)),
uuid: aUUID,
str: aUUID.String(),
}
copy(output.bytes, bys)
Expand Down
16 changes: 12 additions & 4 deletions utils/ybdbid/ybdbid_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,10 @@ func TestYBDBIDParsing(t *testing.T) {

parsedBackViaBytes, err := TryParseFromBytes(parsed.Bytes())
assert.Nil(tt, err)
assert.Equal(tt, parsed.UUID(), parsedBackViaBytes.UUID())
assert.Equal(tt, parsed.String(), parsedBackViaBytes.String())

parsedBackViaString, err := TryParseFromString(parsed.String())
assert.Nil(tt, err)
assert.Equal(tt, parsed.UUID(), parsedBackViaString.UUID())
assert.Equal(tt, parsed.String(), parsedBackViaString.String())

assert.Equal(tt, validBase64YBDBID, base64.StdEncoding.EncodeToString(parsedBackViaBytes.Bytes()))
Expand All @@ -40,12 +38,10 @@ func TestYBDBIDParsing(t *testing.T) {

parsedBackViaBytes, err := TryParseFromBytes(parsed.Bytes())
assert.Nil(tt, err)
assert.Equal(tt, parsed.UUID(), parsedBackViaBytes.UUID())
assert.Equal(tt, parsed.String(), parsedBackViaBytes.String())

parsedBackViaString, err := TryParseFromString(parsed.String())
assert.Nil(tt, err)
assert.Equal(tt, parsed.UUID(), parsedBackViaString.UUID())
assert.Equal(tt, parsed.String(), parsedBackViaString.String())

})
Expand All @@ -70,4 +66,16 @@ func TestYBDBIDParsing(t *testing.T) {
assert.Nil(tt, parsed)
})

t.Run("it-supports non-UUID ID types", func(tt *testing.T) {
encodedRepresentation := "ODU4OWYyMzJjYWQxNGJiZWFmNGU4ZTA0NzEwMmYwNmI="
bys, err := base64.StdEncoding.DecodeString(encodedRepresentation)
assert.Nil(tt, err)
parsed, err := TryParseFromBytes(bys)
assert.Nil(tt, err)
reparsed, err := TryParseFromString(parsed.String())
assert.Nil(tt, err)
reencoded := base64.StdEncoding.EncodeToString([]byte(reparsed.String()))
assert.Equal(tt, encodedRepresentation, reencoded)
})

}

0 comments on commit 1a9f4f7

Please sign in to comment.