github.com/jxskiss/gopkg@v0.17.3/sqlutil/types_json.go (about) 1 package sqlutil 2 3 import ( 4 "bytes" 5 "database/sql/driver" 6 "fmt" 7 8 "github.com/jxskiss/gopkg/gemap" 9 "github.com/jxskiss/gopkg/internal/unsafeheader" 10 "github.com/jxskiss/gopkg/json" 11 ) 12 13 var ( 14 null = []byte("null") 15 emptyObject = []byte("{}") 16 ) 17 18 // JSON holds a map[string]interface{} value, it implements 19 // sql/driver.Valuer and sql.Scanner. It uses JSON to do serialization. 20 // 21 // JSON embeds a gemap.Map, thus all methods defined on gemap.Map is also 22 // available from a JSON instance. 23 type JSON struct { 24 gemap.Map 25 } 26 27 // Value implements driver.Valuer interface. 28 func (p JSON) Value() (driver.Value, error) { 29 if p.Map == nil { 30 return emptyObject, nil 31 } 32 33 buf := bytes.NewBuffer(nil) 34 enc := json.NewEncoder(buf) 35 enc.SetEscapeHTML(false) 36 err := enc.Encode(p.Map) 37 if err != nil { 38 return nil, err 39 } 40 return buf.Bytes(), nil 41 } 42 43 // Scan implements sql.Scanner interface. 44 func (p *JSON) Scan(src interface{}) error { 45 var data []byte 46 switch v := src.(type) { 47 case []byte: 48 data = v 49 case string: 50 data = unsafeheader.StringToBytes(v) 51 default: 52 return fmt.Errorf("sqlutil: wants []byte/string but got %T", src) 53 } 54 55 dec := json.NewDecoder(bytes.NewReader(data)) 56 dec.UseNumber() 57 return dec.Decode(&p.Map) 58 } 59 60 func (p JSON) MarshalJSON() ([]byte, error) { 61 return json.Marshal(p.Map) 62 } 63 64 func (p *JSON) UnmarshalJSON(data []byte) error { 65 return json.Unmarshal(data, &p.Map) 66 }