Closed japettyjohn closed 5 years ago
I have an actual issue with the fact String()
is used: I support multiple databases and one of them only takes []byte
for UUID.
In the interest of maintaining backwards compatibility, would a patch introducing a global option (yeah, I know...) be accept to return either String()
or byte[]
?
Something along the lines of uuid.ForceBinaryOutputForSQL(true)
A global option would be bad. It would affect every package's use. You never know who might be depending on this. I will admit I am not a database person and this function was implemented by someone who knew more about databases than me. It seems like maybe a new type is needed that embeds a UUID, though it would break the ability to directly access values:
// A UUID Bytes is a UUID whose sql Value function returns a byte slice rather than a string.
type UUIDBytes struct {
UUID
}
func (uuid UUIDBytes) Value() (driver.Value, error) {
return uuid[:], nil
}
@pborman thanks for the reply. Would you propose this new wrapper type to be part of uuid
?
It actually does not need to be part of the UUID package at all. Before adding it to the package it would be good to get some feedback on how easy/hard such a thing would be to use. I think if you never sliced the uuid then you would have no problem. You might also want:
func (uuid UUIDBytes) Bytes() []byte {
return uuid.UUID[:]
}
I am doing some experimentation currently. I'll report my findings here. Not sure in which context slicing an UUID prior to storing it to the database would make any sense.
It would be more for passing the UUID to something other than a database function, though I guess the code could simply say id.UUID[:] rather than id.Bytes() to get the byte slice.
Bytes() seems to be pretty common in the Go ecosystem - i'll cast a gentle vote in favor of the above as well
I held a similar discussion over https://github.com/gofrs/uuid/issues/48 and a lot has been taken into account. The resulting decision was to not take any action since no solution seems adequate to be adopted long term by a UUID package. If you all agree with considerations taken over there, feel free to close this issue.
Thanks Ricardo, I think I will close this.
The SQL Value() gives a string representation of UUID, if this is unindexed data this may make little difference in the performance of the data but where this is either an index or even the PK this not efficient storage. Here's one of many articles on it.
This could either have a breaking change and make this provide a []byte type. If there is some more dominant SQL DB being targeted which does not benefit from this, then we could minimally have a BytesValuer() function to return a Valuer which does do this.