mirror of https://github.com/VinGarcia/ksql.git
50 lines
1.2 KiB
Go
50 lines
1.2 KiB
Go
package ksql
|
|
|
|
import (
|
|
"database/sql/driver"
|
|
"encoding/json"
|
|
"fmt"
|
|
"reflect"
|
|
)
|
|
|
|
// This type was created to make it easier to adapt
|
|
// input attributes to be convertible to and from JSON
|
|
// before sending or receiving it from the database.
|
|
type jsonSerializable struct {
|
|
DriverName string
|
|
Attr interface{}
|
|
}
|
|
|
|
// Scan Implements the Scanner interface in order to load
|
|
// this field from the JSON stored in the database
|
|
func (j *jsonSerializable) Scan(value interface{}) error {
|
|
if value == nil {
|
|
v := reflect.ValueOf(j.Attr)
|
|
// Set the struct to its 0 value just like json.Unmarshal
|
|
// does for nil attributes:
|
|
v.Elem().Set(reflect.Zero(reflect.TypeOf(j.Attr).Elem()))
|
|
return nil
|
|
}
|
|
|
|
// Required since sqlite3 returns strings not bytes
|
|
if v, ok := value.(string); ok {
|
|
value = []byte(v)
|
|
}
|
|
|
|
rawJSON, ok := value.([]byte)
|
|
if !ok {
|
|
return fmt.Errorf("unexpected type received to Scan: %T", value)
|
|
}
|
|
return json.Unmarshal(rawJSON, j.Attr)
|
|
}
|
|
|
|
// Value Implements the Valuer interface in order to save
|
|
// this field as JSON on the database.
|
|
func (j jsonSerializable) Value() (driver.Value, error) {
|
|
b, err := json.Marshal(j.Attr)
|
|
if j.DriverName == "sqlserver" {
|
|
return string(b), err
|
|
}
|
|
return b, err
|
|
}
|