2023-02-02 10:55:24 +01:00
|
|
|
package sqlite
|
|
|
|
|
|
|
|
import (
|
|
|
|
"database/sql/driver"
|
|
|
|
"encoding/json"
|
|
|
|
|
|
|
|
"github.com/pkg/errors"
|
|
|
|
)
|
|
|
|
|
2024-03-12 16:22:35 +01:00
|
|
|
type JSON struct {
|
|
|
|
value any
|
|
|
|
}
|
|
|
|
|
|
|
|
func (j JSON) Scan(value interface{}) error {
|
|
|
|
if value == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
var data []byte
|
|
|
|
|
|
|
|
switch typ := value.(type) {
|
|
|
|
case []byte:
|
|
|
|
data = typ
|
|
|
|
case string:
|
|
|
|
data = []byte(typ)
|
|
|
|
default:
|
|
|
|
return errors.Errorf("unexpected type '%T'", value)
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := json.Unmarshal(data, &j.value); err != nil {
|
|
|
|
return errors.WithStack(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (j JSON) Value() (driver.Value, error) {
|
|
|
|
data, err := json.Marshal(j.value)
|
|
|
|
if err != nil {
|
|
|
|
return nil, errors.WithStack(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return data, nil
|
|
|
|
}
|
|
|
|
|
2023-02-02 10:55:24 +01:00
|
|
|
type JSONMap map[string]any
|
|
|
|
|
|
|
|
func (j *JSONMap) Scan(value interface{}) error {
|
|
|
|
if value == nil {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
var data []byte
|
|
|
|
|
|
|
|
switch typ := value.(type) {
|
|
|
|
case []byte:
|
|
|
|
data = typ
|
|
|
|
case string:
|
|
|
|
data = []byte(typ)
|
|
|
|
default:
|
|
|
|
return errors.Errorf("unexpected type '%T'", value)
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := json.Unmarshal(data, &j); err != nil {
|
|
|
|
return errors.WithStack(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (j JSONMap) Value() (driver.Value, error) {
|
|
|
|
data, err := json.Marshal(j)
|
|
|
|
if err != nil {
|
|
|
|
return nil, errors.WithStack(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return data, nil
|
|
|
|
}
|