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  }