| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 |
- // Package null contains SQL types that consider zero input and null input as separate values,
- // with convenient support for JSON and text marshaling.
- // Types in this package will always encode to their null value if null.
- // Use the zero subpackage if you want zero values and null to be treated the same.
- package null
- import (
- "database/sql"
- "encoding/json"
- "fmt"
- "math/rand"
- "reflect"
- "github.com/2637309949/dolphin/packages/uuid"
- )
- // String is a nullable string. It supports SQL and JSON serialization.
- // It will marshal to null if null. Blank string input will be considered null.
- type String struct {
- sql.NullString
- }
- // StringFrom creates a new String that will never be blank.
- func StringFrom(s string) String {
- return NewString(s, true)
- }
- // StringFromRandom creates a new random String that will never be blank.
- func StringFromRandom(n int) String {
- var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
- b := make([]rune, n)
- for i := range b {
- b[i] = letters[rand.Intn(len(letters))]
- }
- return NewString(string(b), true)
- }
- // StringFromUUID creates a new String that will never be blank.
- func StringFromUUID() String {
- return NewString(uuid.MustString(), true)
- }
- // StringFromPtr creates a new String that be null if s is nil.
- func StringFromPtr(s *string) String {
- if s == nil {
- return NewString("", false)
- }
- return NewString(*s, true)
- }
- // ValueOrZero returns the inner value if valid, otherwise zero.
- func (s String) ValueOrZero() string {
- if !s.Valid {
- return ""
- }
- return s.String
- }
- // NewString creates a new String
- func NewString(s string, valid bool) String {
- return String{
- NullString: sql.NullString{
- String: s,
- Valid: valid,
- },
- }
- }
- // UnmarshalJSON implements json.Unmarshaler.
- // It supports string and null input. Blank string input does not produce a null String.
- // It also supports unmarshalling a sql.NullString.
- func (s *String) UnmarshalJSON(data []byte) error {
- var err error
- var v interface{}
- if err = json.Unmarshal(data, &v); err != nil {
- return err
- }
- switch x := v.(type) {
- case string:
- s.String = x
- case map[string]interface{}:
- err = json.Unmarshal(data, &s.NullString)
- case nil:
- s.Valid = false
- return nil
- default:
- err = fmt.Errorf("json: cannot unmarshal %v into Go value of type null.String", reflect.TypeOf(v).Name())
- }
- s.Valid = err == nil
- return err
- }
- // MarshalJSON implements json.Marshaler.
- // It will encode null if this String is null.
- func (s String) MarshalJSON() ([]byte, error) {
- if !s.Valid {
- return []byte("null"), nil
- }
- return json.Marshal(s.String)
- }
- // MarshalText implements encoding.TextMarshaler.
- // It will encode a blank string when this String is null.
- func (s String) MarshalText() ([]byte, error) {
- if !s.Valid {
- return []byte{}, nil
- }
- return []byte(s.String), nil
- }
- // UnmarshalText implements encoding.TextUnmarshaler.
- // It will unmarshal to a null String if the input is a blank string.
- func (s *String) UnmarshalText(text []byte) error {
- s.String = string(text)
- s.Valid = s.String != ""
- return nil
- }
- // SetValid changes this String's value and also sets it to be non-null.
- func (s *String) SetValid(v string) {
- s.String = v
- s.Valid = true
- }
- // Ptr returns a pointer to this String's value, or a nil pointer if this String is null.
- func (s String) Ptr() *string {
- if !s.Valid {
- return nil
- }
- return &s.String
- }
- // IsZero returns true for null strings, for potential future omitempty support.
- func (s String) IsZero() bool {
- return !s.Valid
- }
|