I'm having a database table which contains a assigned_id field which has the type uuid.
The database is postgres and my ORM is gorm. I was wondering how its possible to set that assigned_id to NULL?
I've tried setting the field to nil in the model, as well as using gorm.Expr("NULL"), nil or sql.NullString.
None of those methods work.
Maybe someone will be able to answer that question for me.
So you can declare a custom type to handle uuid (or any other non-default type). I've provided the implementation and it works for me with examples. NOTE: I've already declared a custom type to handle null string but I've left it out for brevity.
Also I did not do a complete test coverage of this code, so please take it as a starting point.
type NullUUID struct {
UUID uuid.UUID
Valid bool
}
func (nd *NullUUID) Scan(value interface{}) (err error) {
var s uuid.UUID
if err := s.Scan(value); err != nil {
return err
}
// if nil then make Valid false
if reflect.TypeOf(value) == nil {
*nd = NullUUID{Valid: false}
} else {
if err != nil {
return err
}
*nd = NullUUID{s, true}
}
return nil
}
func (nd NullUUID) Value() (driver.Value, error) {
if !nd.Valid {
return nil, nil
}
return nd.Value, nil
}
func (nd NullUUID) MarshalJSON() ([]byte, error) {
if !nd.Valid {
return []byte("null"), nil
}
return json.Marshal(nd.UUID.String())
}
func (nd *NullUUID) UnmarshalJSON(b []byte) error {
var str string
err := json.Unmarshal(b, &str)
if err != nil {
nd.Valid = false
return err
}
id, err := uuid.Parse(str)
if err != nil {
nd.Valid = false
return err
}
nd.UUID = id
nd.Valid = true
return err
}
This also handles marshalling and unmarshalling so it either prints the value or "null", but you can edit this is required.
Here is my tested example:
id | text
----+------
| sda
// Row result:
main.Row{Id:main.NullUUID{UUID:uuid.UUID{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, Valid:false}, Text:main.NullString{String:"sda", Valid:true}}
// Row marshalled:
{"id":null,"text":"sda"}
// Row unmarshalled:
main.Row{Id:main.NullUUID{UUID:uuid.UUID{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, Valid:false}, Text:main.NullString{String:"", Valid:false}} // seems to be a bug in my null string unmarshalling but I don't think it's relevant here
Just in case, I also tested non null uuid and here is the result:
// Row marshalled
{"id":"889f2163-ee59-4632-b238-3ac9574f111e","text":null}
// Row unmarshalled
main.Row{Id:main.NullUUID{UUID:uuid.UUID{0x88, 0x9f, 0x21, 0x63, 0xee, 0x59, 0x46, 0x32, 0xb2, 0x38, 0x3a, 0xc9, 0x57, 0x4f, 0x11, 0x1e}, Valid:true}, Text:main.NullString{String:"", Valid:true}} // again seems to be a bug in my null string unmarshalling but I don't think it's relevant here
// Printed UUID string
889f2163-ee59-4632-b238-3ac9574f111e
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With