github.com/cockroachdb/cockroachdb-parser@v0.23.3-0.20240213214944-911057d40c9a/pkg/util/uuid/sql.go (about) 1 // Copyright 2019 The Cockroach Authors. 2 // 3 // Use of this software is governed by the Business Source License 4 // included in the file licenses/BSL.txt. 5 // 6 // As of the Change Date specified in that file, in accordance with 7 // the Business Source License, use of this software will be governed 8 // by the Apache License, Version 2.0, included in the file 9 // licenses/APL.txt. 10 11 // Copyright (C) 2013-2018 by Maxim Bublis <b@codemonkey.ru> 12 // Use of this source code is governed by a MIT-style 13 // license that can be found in licenses/MIT-gofrs.txt. 14 15 // This code originated in github.com/gofrs/uuid. 16 17 package uuid 18 19 import ( 20 "bytes" 21 "database/sql/driver" 22 "encoding/json" 23 "fmt" 24 ) 25 26 // Value implements the driver.Valuer interface. 27 func (u UUID) Value() (driver.Value, error) { 28 return u.String(), nil 29 } 30 31 // Scan implements the sql.Scanner interface. 32 // A 16-byte slice will be handled by UnmarshalBinary, while 33 // a longer byte slice or a string will be handled by UnmarshalText. 34 func (u *UUID) Scan(src interface{}) error { 35 switch src := src.(type) { 36 case UUID: // support gorm convert from UUID to NullUUID 37 *u = src 38 return nil 39 40 case []byte: 41 if len(src) == Size { 42 return u.UnmarshalBinary(src) 43 } 44 return u.UnmarshalText(src) 45 46 case string: 47 return u.UnmarshalText([]byte(src)) 48 } 49 50 return fmt.Errorf("uuid: cannot convert %T to UUID", src) 51 } 52 53 // NullUUID can be used with the standard sql package to represent a 54 // UUID value that can be NULL in the database. 55 type NullUUID struct { 56 UUID UUID 57 Valid bool 58 } 59 60 // Value implements the driver.Valuer interface. 61 func (u NullUUID) Value() (driver.Value, error) { 62 if !u.Valid { 63 return nil, nil 64 } 65 // Delegate to UUID Value function 66 return u.UUID.Value() 67 } 68 69 // Scan implements the sql.Scanner interface. 70 func (u *NullUUID) Scan(src interface{}) error { 71 if src == nil { 72 u.UUID, u.Valid = Nil, false 73 return nil 74 } 75 76 // Delegate to UUID Scan function 77 u.Valid = true 78 return u.UUID.Scan(src) 79 } 80 81 // MarshalJSON marshals the NullUUID as null or the nested UUID 82 func (u NullUUID) MarshalJSON() ([]byte, error) { 83 if !u.Valid { 84 return json.Marshal(nil) 85 } 86 87 return json.Marshal(u.UUID) 88 } 89 90 // UnmarshalJSON unmarshals a NullUUID 91 func (u *NullUUID) UnmarshalJSON(b []byte) error { 92 if bytes.Equal(b, []byte("null")) { 93 u.UUID, u.Valid = Nil, false 94 return nil 95 } 96 97 if err := json.Unmarshal(b, &u.UUID); err != nil { 98 return err 99 } 100 101 u.Valid = true 102 103 return nil 104 }