null.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. // Copyright 2021 Google Inc. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package uuid
  5. import (
  6. "bytes"
  7. "database/sql/driver"
  8. "encoding/json"
  9. "fmt"
  10. )
  11. var jsonNull = []byte("null")
  12. // NullUUID represents a UUID that may be null.
  13. // NullUUID implements the SQL driver.Scanner interface so
  14. // it can be used as a scan destination:
  15. //
  16. // var u uuid.NullUUID
  17. // err := db.QueryRow("SELECT name FROM foo WHERE id=?", id).Scan(&u)
  18. // ...
  19. // if u.Valid {
  20. // // use u.UUID
  21. // } else {
  22. // // NULL value
  23. // }
  24. //
  25. type NullUUID struct {
  26. UUID UUID
  27. Valid bool // Valid is true if UUID is not NULL
  28. }
  29. // Scan implements the SQL driver.Scanner interface.
  30. func (nu *NullUUID) Scan(value interface{}) error {
  31. if value == nil {
  32. nu.UUID, nu.Valid = Nil, false
  33. return nil
  34. }
  35. err := nu.UUID.Scan(value)
  36. if err != nil {
  37. nu.Valid = false
  38. return err
  39. }
  40. nu.Valid = true
  41. return nil
  42. }
  43. // Value implements the driver Valuer interface.
  44. func (nu NullUUID) Value() (driver.Value, error) {
  45. if !nu.Valid {
  46. return nil, nil
  47. }
  48. // Delegate to UUID Value function
  49. return nu.UUID.Value()
  50. }
  51. // MarshalBinary implements encoding.BinaryMarshaler.
  52. func (nu NullUUID) MarshalBinary() ([]byte, error) {
  53. if nu.Valid {
  54. return nu.UUID[:], nil
  55. }
  56. return []byte(nil), nil
  57. }
  58. // UnmarshalBinary implements encoding.BinaryUnmarshaler.
  59. func (nu *NullUUID) UnmarshalBinary(data []byte) error {
  60. if len(data) != 16 {
  61. return fmt.Errorf("invalid UUID (got %d bytes)", len(data))
  62. }
  63. copy(nu.UUID[:], data)
  64. nu.Valid = true
  65. return nil
  66. }
  67. // MarshalText implements encoding.TextMarshaler.
  68. func (nu NullUUID) MarshalText() ([]byte, error) {
  69. if nu.Valid {
  70. return nu.UUID.MarshalText()
  71. }
  72. return jsonNull, nil
  73. }
  74. // UnmarshalText implements encoding.TextUnmarshaler.
  75. func (nu *NullUUID) UnmarshalText(data []byte) error {
  76. id, err := ParseBytes(data)
  77. if err != nil {
  78. nu.Valid = false
  79. return err
  80. }
  81. nu.UUID = id
  82. nu.Valid = true
  83. return nil
  84. }
  85. // MarshalJSON implements json.Marshaler.
  86. func (nu NullUUID) MarshalJSON() ([]byte, error) {
  87. if nu.Valid {
  88. return json.Marshal(nu.UUID)
  89. }
  90. return jsonNull, nil
  91. }
  92. // UnmarshalJSON implements json.Unmarshaler.
  93. func (nu *NullUUID) UnmarshalJSON(data []byte) error {
  94. if bytes.Equal(data, jsonNull) {
  95. *nu = NullUUID{}
  96. return nil // valid null UUID
  97. }
  98. err := json.Unmarshal(data, &nu.UUID)
  99. nu.Valid = err == nil
  100. return err
  101. }