60 lines
1.4 KiB
Go
60 lines
1.4 KiB
Go
package dbx
|
|
|
|
import (
|
|
"database/sql/driver"
|
|
"encoding/json"
|
|
"fmt"
|
|
)
|
|
|
|
// JSONB is a type that represents a JSON object stored in the database. It is
|
|
// a map[string]any and implements sql.Scanner, driver.Valuer, and Stringer.
|
|
type JSONB map[string]any
|
|
|
|
// NewJSONB creates a new JSONB value from a map[string]any.
|
|
func NewJSONB(data map[string]any) JSONB {
|
|
return JSONB(data)
|
|
}
|
|
|
|
// ToMap converts the JSONB value to a map[string]any.
|
|
func (j JSONB) ToMap() map[string]any {
|
|
return map[string]any(j)
|
|
}
|
|
|
|
// Scan implements the sql.Scanner interface. It supports converting from
|
|
// string, []byte, or nil into a JSONB value. Attempting to convert from
|
|
// any other type will return an error.
|
|
func (j *JSONB) Scan(src any) error {
|
|
switch v := src.(type) {
|
|
case nil:
|
|
*j = nil
|
|
return nil
|
|
case []byte:
|
|
return json.Unmarshal(v, j)
|
|
case string:
|
|
return json.Unmarshal([]byte(v), j)
|
|
default:
|
|
return fmt.Errorf("Scan: unable to scan type %T into JSONB", v)
|
|
}
|
|
}
|
|
|
|
// Value implements the driver.Valuer interface. It converts the JSONB
|
|
// value into a SQL driver value which can be used to directly use the
|
|
// JSONB as a parameter to a SQL query.
|
|
func (j JSONB) Value() (driver.Value, error) {
|
|
if j == nil {
|
|
return nil, nil
|
|
}
|
|
|
|
// Marshal the JSONB to a byte slice
|
|
return json.Marshal(j)
|
|
}
|
|
|
|
func (j JSONB) String() string {
|
|
// Marshal the JSONB to a byte slice
|
|
bytes, err := json.Marshal(j)
|
|
if err != nil {
|
|
return ""
|
|
}
|
|
return string(bytes)
|
|
}
|