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  }