From d43747066e65157add02533fb55e815b9fa07859 Mon Sep 17 00:00:00 2001 From: inliquid Date: Wed, 2 Jan 2019 20:27:48 +0300 Subject: [PATCH 1/2] - Implemented bson.Getter/Setter interfaces for correct marshaling/unmarshaling in MongoDB's BSON binary UUID format with Legacy UUID as default kind (0x03). - Introduced SetBSONKind function to make user able to set different BSON kind. --- codec.go | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/codec.go b/codec.go index 656892c..b4fc6a2 100644 --- a/codec.go +++ b/codec.go @@ -24,7 +24,17 @@ package uuid import ( "bytes" "encoding/hex" + "errors" "fmt" + + "gopkg.in/mgo.v2/bson" +) + +var ( + // By default Legacy UUID subtype (0x03) is used, see + // https://studio3t.com/knowledge-base/articles/mongodb-best-practices-uuid-data/#binary-subtypes-0x03-and-0x04 and + // http://bsonspec.org/spec.html for details. Can be changed with SetBSONKind. + bsonKind byte = 0x03 ) // FromBytes returns UUID converted from raw byte slice input. @@ -204,3 +214,41 @@ func (u *UUID) UnmarshalBinary(data []byte) (err error) { return } + +// GetBSON implements bson.Getter for marshaling UUID in BSON binary UUID format. +// By default Kind of 0x03 (Legacy UUID) will be used. Can be changed with SetBSONKind. +func (u UUID) GetBSON() (interface{}, error) { + toMarshal := bson.Binary{ + Kind: bsonKind, + Data: u.Bytes(), + } + + return toMarshal, nil +} + +// SetBSON implements bson.Setter for unmarshaling UUID from BSON binary UUID format. +// By default Kind of 0x03 (Legacy UUID) will be used. Can be changed with SetBSONKind. +func (u *UUID) SetBSON(raw bson.Raw) error { + var toUnmarshal bson.Binary + + err := raw.Unmarshal(&toUnmarshal) + if err != nil { + return err + } + + *u, err = FromBytes(toUnmarshal.Data) + + return err +} + +// SetBSONKind changes BSON UUID Kind that will be used by GetBSON and SetBSON. Only value of +// 0x03 (Legacy UUID) or 0x04 (UUID) can be used, SetBSONKind returns an error when requested value is different. +func SetBSONKind(kind byte) error { + if kind < 0x03 || kind > 0x04 { + return errors.New("requested BSON UUID kind is not allowed") + } + + bsonKind = kind + + return nil +} From 186ab3502a6e4f26a34dbece9e80c1a79ad7ad92 Mon Sep 17 00:00:00 2001 From: inliquid Date: Thu, 3 Jan 2019 16:54:20 +0300 Subject: [PATCH 2/2] - Default BSON kind changed to new UUID instead of Legacy UUID - Comments changed accordingly --- codec.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/codec.go b/codec.go index b4fc6a2..0367fae 100644 --- a/codec.go +++ b/codec.go @@ -31,10 +31,10 @@ import ( ) var ( - // By default Legacy UUID subtype (0x03) is used, see + // By default, new (recommended) UUID subtype/kind (0x04) is used, see // https://studio3t.com/knowledge-base/articles/mongodb-best-practices-uuid-data/#binary-subtypes-0x03-and-0x04 and // http://bsonspec.org/spec.html for details. Can be changed with SetBSONKind. - bsonKind byte = 0x03 + bsonKind byte = 0x04 ) // FromBytes returns UUID converted from raw byte slice input. @@ -216,7 +216,7 @@ func (u *UUID) UnmarshalBinary(data []byte) (err error) { } // GetBSON implements bson.Getter for marshaling UUID in BSON binary UUID format. -// By default Kind of 0x03 (Legacy UUID) will be used. Can be changed with SetBSONKind. +// By default Kind of 0x04 (new UUID) will be used. Can be changed with SetBSONKind. func (u UUID) GetBSON() (interface{}, error) { toMarshal := bson.Binary{ Kind: bsonKind, @@ -227,7 +227,7 @@ func (u UUID) GetBSON() (interface{}, error) { } // SetBSON implements bson.Setter for unmarshaling UUID from BSON binary UUID format. -// By default Kind of 0x03 (Legacy UUID) will be used. Can be changed with SetBSONKind. +// By default Kind of 0x04 (new UUID) will be used. Can be changed with SetBSONKind. func (u *UUID) SetBSON(raw bson.Raw) error { var toUnmarshal bson.Binary @@ -241,8 +241,8 @@ func (u *UUID) SetBSON(raw bson.Raw) error { return err } -// SetBSONKind changes BSON UUID Kind that will be used by GetBSON and SetBSON. Only value of -// 0x03 (Legacy UUID) or 0x04 (UUID) can be used, SetBSONKind returns an error when requested value is different. +// SetBSONKind changes BSON UUID Kind which will be used by GetBSON and SetBSON. Only values of +// 0x03 (Legacy UUID) or 0x04 (new UUID) can be used, SetBSONKind returns error when requested kind is different. func SetBSONKind(kind byte) error { if kind < 0x03 || kind > 0x04 { return errors.New("requested BSON UUID kind is not allowed")