github.com/searKing/golang/go@v1.2.117/database/sql/null_json.go (about) 1 // Copyright 2020 The searKing Author. 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 5 package sql 6 7 import ( 8 "database/sql/driver" 9 "encoding/json" 10 "fmt" 11 "time" 12 ) 13 14 // NullJson represents an interface that may be null. 15 // NullJson implements the Scanner interface so it can be used as a scan destination, similar to sql.NullString. 16 // Deprecate, use go-nulljson instead. 17 // For more information, see: 18 // https://godoc.org/github.com/searKing/golang/tools/go-nulljson 19 type NullJson struct { 20 Data any // must be set with a pointer to zero value of expect type 21 22 Valid bool // Valid is true if Data is not NULL 23 } 24 25 // Scan implements the sql.Scanner interface. 26 func (nj *NullJson) Scan(src any) error { 27 if src == nil { 28 nj.Data, nj.Valid = nil, false 29 return nil 30 } 31 nj.Valid = true 32 33 var err error 34 switch src := src.(type) { 35 case string: 36 if len(src) > 0 { 37 err = json.Unmarshal([]byte(src), &nj.Data) 38 } 39 case []byte: 40 if len(src) > 0 { 41 err = json.Unmarshal(src, &nj.Data) 42 } 43 case time.Time: 44 srcBytes, _ := json.Marshal(src) 45 err = json.Unmarshal(srcBytes, &nj.Data) 46 case nil: 47 nj.Data = nil 48 err = nil 49 default: 50 srcBytes, _ := json.Marshal(src) 51 err = json.Unmarshal(srcBytes, &nj.Data) 52 } 53 if err == nil { 54 return nil 55 } 56 57 return fmt.Errorf("unsupported Scan, storing driver.Value type %T into type %T : %w", src, nj.Data, err) 58 } 59 60 // Value implements the driver.Valuer interface. 61 func (nj NullJson) Value() (driver.Value, error) { 62 if !nj.Valid { 63 return nil, nil 64 } 65 return json.Marshal(nj.Data) 66 }