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  }