package datatypes

import (
	
	
	
	
	
	
	

	
	
	
	
)

// JSONMap defined JSON data type, need to implements driver.Valuer, sql.Scanner interface
type JSONMap map[string]interface{}

// Value return json value, implement driver.Valuer interface
func ( JSONMap) () (driver.Value, error) {
	if  == nil {
		return nil, nil
	}
	,  := .MarshalJSON()
	return string(), 
}

// Scan scan value into Jsonb, implements sql.Scanner interface
func ( *JSONMap) ( interface{}) error {
	if  == nil {
		* = make(JSONMap)
		return nil
	}
	var  []byte
	switch v := .(type) {
	case []byte:
		 = 
	case string:
		 = []byte()
	default:
		return errors.New(fmt.Sprint("Failed to unmarshal JSONB value:", ))
	}
	 := map[string]interface{}{}
	 := bytes.NewReader()
	 := json.NewDecoder()
	.UseNumber()
	 := .Decode(&)
	* = 
	return 
}

// MarshalJSON to output non base64 encoded []byte
func ( JSONMap) () ([]byte, error) {
	if  == nil {
		return []byte("null"), nil
	}
	 := (map[string]interface{})()
	return json.Marshal()
}

// UnmarshalJSON to deserialize []byte
func ( *JSONMap) ( []byte) error {
	 := map[string]interface{}{}
	 := json.Unmarshal(, &)
	* = JSONMap()
	return 
}

// GormDataType gorm common data type
func ( JSONMap) () string {
	return "jsonmap"
}

// GormDBDataType gorm db data type
func (JSONMap) ( *gorm.DB,  *schema.Field) string {
	switch .Dialector.Name() {
	case "sqlite":
		return "JSON"
	case "mysql":
		return "JSON"
	case "postgres":
		return "JSONB"
	case "sqlserver":
		return "NVARCHAR(MAX)"
	}
	return ""
}

func ( JSONMap) ( context.Context,  *gorm.DB) clause.Expr {
	,  := .MarshalJSON()
	switch .Dialector.Name() {
	case "mysql":
		if ,  := .Dialector.(*mysql.Dialector);  && !strings.Contains(.ServerVersion, "MariaDB") {
			return gorm.Expr("CAST(? AS JSON)", string())
		}
	}
	return gorm.Expr("?", string())
}