54 lines
1.1 KiB
Go
54 lines
1.1 KiB
Go
package store
|
|
|
|
import (
|
|
"database/sql/driver"
|
|
"fmt"
|
|
)
|
|
|
|
// JSONB is a nullable JSON value backed by raw bytes.
|
|
// Scans from jsonb (Postgres) or TEXT (SQLite). Empty means SQL NULL.
|
|
type JSONB []byte
|
|
|
|
// Scan implements sql.Scanner.
|
|
func (j *JSONB) Scan(src any) error {
|
|
if src == nil {
|
|
*j = nil
|
|
return nil
|
|
}
|
|
switch v := src.(type) {
|
|
case []byte:
|
|
// Copy: drivers may reuse the buffer between rows.
|
|
*j = append((*j)[:0], v...)
|
|
case string:
|
|
*j = []byte(v)
|
|
default:
|
|
return fmt.Errorf("pase: cannot scan %T into JSONB", src)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Value implements driver.Valuer.
|
|
func (j JSONB) Value() (driver.Value, error) {
|
|
if len(j) == 0 {
|
|
return nil, nil
|
|
}
|
|
return []byte(j), nil
|
|
}
|
|
|
|
// MarshalJSON makes JSONB transparent in API responses.
|
|
func (j JSONB) MarshalJSON() ([]byte, error) {
|
|
if len(j) == 0 {
|
|
return []byte("null"), nil
|
|
}
|
|
return []byte(j), nil
|
|
}
|
|
|
|
// UnmarshalJSON lets you decode directly into JSONB.
|
|
func (j *JSONB) UnmarshalJSON(data []byte) error {
|
|
if string(data) == "null" {
|
|
*j = nil
|
|
return nil
|
|
}
|
|
*j = append((*j)[:0], data...)
|
|
return nil
|
|
}
|