github.com/gocaveman/caveman@v0.0.0-20191211162744-0ddf99dbdf6e/dbutil/string-obj-map.go (about) 1 package dbutil 2 3 import ( 4 "database/sql/driver" 5 "encoding/json" 6 "fmt" 7 ) 8 9 // StringObjMap is map[string]interface{} that encodes to JSON in the database. 10 type StringObjMap map[string]interface{} 11 12 // MarshalJSON customizes the marshal so that a nil map encodes to "{}" not "null". 13 // This makes things more consistent for JS clients and easier to work with. 14 func (m StringObjMap) MarshalJSON() ([]byte, error) { 15 if m == nil { 16 return []byte(`{}`), nil 17 } 18 return json.Marshal(map[string]interface{}(m)) 19 } 20 21 func (m StringObjMap) Value() (driver.Value, error) { 22 if m == nil { 23 m = StringObjMap{} 24 } 25 b, err := json.Marshal(m) 26 return driver.Value(b), err 27 } 28 29 func (m *StringObjMap) Scan(value interface{}) error { 30 31 var ret StringObjMap 32 var b []byte 33 34 if value != nil { 35 36 switch v := value.(type) { 37 case []byte: 38 b = v 39 case string: 40 b = []byte(v) 41 default: 42 return fmt.Errorf("cannot convert from StringObjMap to sql driver type %T", value) 43 } 44 45 err := json.Unmarshal(b, &ret) 46 if err != nil { 47 return err 48 } 49 50 } else { 51 ret = StringObjMap{} 52 } 53 54 // ensure we always have a valid map 55 if ret == nil { 56 ret = StringObjMap{} 57 } 58 59 *m = ret 60 61 return nil 62 }