-
Notifications
You must be signed in to change notification settings - Fork 855
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Q: How to implement pgtype.FlatArray[uuid.UUID] for gorm? #1781
Comments
thanks @jackc for the response! i now just implemented the gorm interface only but still using the pgx lib through the gorm postgres driver for ref: package uuid_v1
import (
"database/sql/driver"
"fmt"
"github.com/google/uuid"
"strings"
)
type UUIDSlice []uuid.UUID
// Scan implements the sql.Scanner interface for postgres uuid[] deserialization.
// e.g. single: {23e4aa0c-8591-4544-8cc1-8348d9d7f901}
// e.g. multiple: {23e4aa0c-8591-4544-8cc1-8348d9d7f901,aee911e4-3fa8-4866-95ac-e4878d3e06e5}
func (uuidSlice *UUIDSlice) Scan(value interface{}) error {
var ok bool
var err error
var strValue string
if strValue, ok = value.(string); !ok {
return fmt.Errorf("failed to scan UUIDSlice: %v", value)
}
if strValue == "" {
return nil
}
var strValueSplit = strings.Split(strValue[1:len(strValue)-1], ",")
for _, uuidStr := range strValueSplit {
if uuidStr == "" {
continue
}
var tmpUuid uuid.UUID
if tmpUuid, err = uuid.Parse(uuidStr); err != nil {
return err
}
*uuidSlice = append(*uuidSlice, tmpUuid)
}
return nil
}
// Value implements the driver.Valuer interface for postgres uuid[] serialization.
func (uuidSlice *UUIDSlice) Value() (driver.Value, error) {
var uuidStrs []string
for _, u := range *uuidSlice {
uuidStrs = append(uuidStrs, u.String())
}
if len(uuidStrs) == 0 {
return nil, nil
}
return fmt.Sprintf("{%s}", strings.Join(uuidStrs, ",")), nil
} package uuid_v1
import (
"database/sql/driver"
"fmt"
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
"strings"
"testing"
)
func TestUUIDSlice_Scan(t *testing.T) {
var tests = []struct {
name string
uuidSlice UUIDSlice
value interface{}
expectedUuidSlice UUIDSlice
expectedErr error
}{
{
name: "none",
uuidSlice: nil,
value: "{}",
expectedUuidSlice: nil,
expectedErr: nil,
},
{
name: "one",
uuidSlice: nil,
value: "{23e4aa0c-8591-4544-8cc1-8348d9d7f901}",
expectedUuidSlice: UUIDSlice{
uuid.MustParse("23e4aa0c-8591-4544-8cc1-8348d9d7f901"),
},
expectedErr: nil,
},
{
name: "two",
uuidSlice: nil,
value: "{23e4aa0c-8591-4544-8cc1-8348d9d7f901,aee911e4-3fa8-4866-95ac-e4878d3e06e5}",
expectedUuidSlice: UUIDSlice{
uuid.MustParse("23e4aa0c-8591-4544-8cc1-8348d9d7f901"),
uuid.MustParse("aee911e4-3fa8-4866-95ac-e4878d3e06e5"),
},
expectedErr: nil,
},
{
name: "three",
uuidSlice: nil,
value: "{23e4aa0c-8591-4544-8cc1-8348d9d7f901,aee911e4-3fa8-4866-95ac-e4878d3e06e5,6d285174-30f6-462c-8853-de3bd88d36fb}",
expectedUuidSlice: UUIDSlice{
uuid.MustParse("23e4aa0c-8591-4544-8cc1-8348d9d7f901"),
uuid.MustParse("aee911e4-3fa8-4866-95ac-e4878d3e06e5"),
uuid.MustParse("6d285174-30f6-462c-8853-de3bd88d36fb"),
},
expectedErr: nil,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
var err = test.uuidSlice.Scan(test.value)
assert.Equal(t, test.expectedErr, err)
assert.Equal(t, test.expectedUuidSlice, test.uuidSlice)
})
}
}
func TestUUIDSlice_Value(t *testing.T) {
var tests = []struct {
name string
uuidSlice UUIDSlice
expectedValue driver.Value
expectedErr error
}{
{
name: "nil",
uuidSlice: nil,
expectedValue: nil,
expectedErr: nil,
},
{
name: "one",
uuidSlice: UUIDSlice{
uuid.MustParse("23e4aa0c-8591-4544-8cc1-8348d9d7f901"),
},
expectedValue: fmt.Sprintf("{%s}", strings.Join([]string{
"23e4aa0c-8591-4544-8cc1-8348d9d7f901",
}, ",")),
expectedErr: nil,
},
{
name: "multiple",
uuidSlice: UUIDSlice{
uuid.MustParse("23e4aa0c-8591-4544-8cc1-8348d9d7f901"),
uuid.MustParse("aee911e4-3fa8-4866-95ac-e4878d3e06e5"),
},
expectedValue: fmt.Sprintf("{%s}", strings.Join([]string{
"23e4aa0c-8591-4544-8cc1-8348d9d7f901",
"aee911e4-3fa8-4866-95ac-e4878d3e06e5",
}, ",")),
expectedErr: nil,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
var value, err = test.uuidSlice.Value()
assert.Equal(t, test.expectedErr, err)
assert.Equal(t, test.expectedValue, value)
})
}
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
It's unclear for me how to implement this in the most simple way, thank you!
unsupported Scan, storing driver.Value type string into type *pgtype.FlatArray[github.com/google/uuid.UUID]
The text was updated successfully, but these errors were encountered: