Files
sqlite3/json.go

48 lines
1.0 KiB
Go
Raw Normal View History

2023-10-18 23:14:46 +01:00
package sqlite3
import (
"encoding/json"
"strconv"
"time"
"unsafe"
2023-10-19 16:46:58 +01:00
"github.com/ncruces/go-sqlite3/internal/util"
2023-10-18 23:14:46 +01:00
)
2023-11-09 16:16:48 +00:00
// JSON returns a value that can be used as an argument to
// [database/sql.DB.Exec], [database/sql.Row.Scan] and similar methods to
// store value as JSON, or decode JSON into value.
2023-12-22 02:45:26 +00:00
// JSON should NOT be used with [BindJSON] or [ResultJSON].
2023-10-18 23:14:46 +01:00
func JSON(value any) any {
return jsonValue{value}
}
type jsonValue struct{ any }
2023-11-09 16:16:48 +00:00
func (j jsonValue) JSON() any { return j.any }
2023-10-18 23:14:46 +01:00
func (j jsonValue) Scan(value any) error {
2023-10-19 16:46:58 +01:00
var buf []byte
2023-10-18 23:14:46 +01:00
switch v := value.(type) {
case []byte:
buf = v
case string:
buf = unsafe.Slice(unsafe.StringData(v), len(v))
case int64:
buf = strconv.AppendInt(nil, v, 10)
case float64:
buf = strconv.AppendFloat(nil, v, 'g', -1, 64)
case time.Time:
buf = append(buf, '"')
buf = v.AppendFormat(buf, time.RFC3339Nano)
buf = append(buf, '"')
case nil:
buf = append(buf, "null"...)
2023-10-19 16:46:58 +01:00
default:
panic(util.AssertErr())
2023-10-18 23:14:46 +01:00
}
2023-11-09 16:16:48 +00:00
return json.Unmarshal(buf, j.any)
2023-10-18 23:14:46 +01:00
}