package datatypes
import (
"bytes"
"context"
"database/sql/driver"
"encoding/json"
"errors"
"fmt"
"strings"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"gorm.io/gorm/clause"
"gorm.io/gorm/schema"
)
type JSONMap map [string ]interface {}
func (m JSONMap ) Value () (driver .Value , error ) {
if m == nil {
return nil , nil
}
ba , err := m .MarshalJSON ()
return string (ba ), err
}
func (m *JSONMap ) Scan (val interface {}) error {
if val == nil {
*m = make (JSONMap )
return nil
}
var ba []byte
switch v := val .(type ) {
case []byte :
ba = v
case string :
ba = []byte (v )
default :
return errors .New (fmt .Sprint ("Failed to unmarshal JSONB value:" , val ))
}
t := map [string ]interface {}{}
rd := bytes .NewReader (ba )
decoder := json .NewDecoder (rd )
decoder .UseNumber ()
err := decoder .Decode (&t )
*m = t
return err
}
func (m JSONMap ) MarshalJSON () ([]byte , error ) {
if m == nil {
return []byte ("null" ), nil
}
t := (map [string ]interface {})(m )
return json .Marshal (t )
}
func (m *JSONMap ) UnmarshalJSON (b []byte ) error {
t := map [string ]interface {}{}
err := json .Unmarshal (b , &t )
*m = JSONMap (t )
return err
}
func (m JSONMap ) GormDataType () string {
return "jsonmap"
}
func (JSONMap ) GormDBDataType (db *gorm .DB , field *schema .Field ) string {
switch db .Dialector .Name () {
case "sqlite" :
return "JSON"
case "mysql" :
return "JSON"
case "postgres" :
return "JSONB"
case "sqlserver" :
return "NVARCHAR(MAX)"
}
return ""
}
func (jm JSONMap ) GormValue (ctx context .Context , db *gorm .DB ) clause .Expr {
data , _ := jm .MarshalJSON ()
switch db .Dialector .Name () {
case "mysql" :
if v , ok := db .Dialector .(*mysql .Dialector ); ok && !strings .Contains (v .ServerVersion , "MariaDB" ) {
return gorm .Expr ("CAST(? AS JSON)" , string (data ))
}
}
return gorm .Expr ("?" , string (data ))
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .