Files
sqlite3/value.go

156 lines
3.5 KiB
Go
Raw Normal View History

2023-06-30 10:45:16 +01:00
package sqlite3
import (
2023-10-13 17:06:05 +01:00
"encoding/json"
2023-06-30 10:45:16 +01:00
"math"
2023-10-13 17:06:05 +01:00
"strconv"
2023-06-30 10:45:16 +01:00
"time"
"github.com/ncruces/go-sqlite3/internal/util"
)
// Value is any value that can be stored in a database table.
//
2023-11-09 16:35:45 +00:00
// https://sqlite.org/c3ref/value.html
2023-06-30 10:45:16 +01:00
type Value struct {
2023-07-03 17:21:35 +01:00
*sqlite
2023-06-30 10:45:16 +01:00
handle uint32
}
// Type returns the initial [Datatype] of the value.
//
2023-11-09 16:35:45 +00:00
// https://sqlite.org/c3ref/value_blob.html
2023-07-03 17:08:16 +01:00
func (v Value) Type() Datatype {
2023-07-01 00:15:28 +01:00
r := v.call(v.api.valueType, uint64(v.handle))
2023-06-30 10:45:16 +01:00
return Datatype(r)
}
// Bool returns the value as a bool.
// SQLite does not have a separate boolean storage class.
// Instead, boolean values are retrieved as integers,
// with 0 converted to false and any other value to true.
//
2023-11-09 16:35:45 +00:00
// https://sqlite.org/c3ref/value_blob.html
2023-07-03 17:08:16 +01:00
func (v Value) Bool() bool {
2023-06-30 10:45:16 +01:00
if i := v.Int64(); i != 0 {
return true
}
return false
}
// Int returns the value as an int.
//
2023-11-09 16:35:45 +00:00
// https://sqlite.org/c3ref/value_blob.html
2023-07-03 17:08:16 +01:00
func (v Value) Int() int {
2023-06-30 10:45:16 +01:00
return int(v.Int64())
}
// Int64 returns the value as an int64.
//
2023-11-09 16:35:45 +00:00
// https://sqlite.org/c3ref/value_blob.html
2023-07-03 17:08:16 +01:00
func (v Value) Int64() int64 {
2023-07-01 00:15:28 +01:00
r := v.call(v.api.valueInteger, uint64(v.handle))
2023-06-30 10:45:16 +01:00
return int64(r)
}
// Float returns the value as a float64.
//
2023-11-09 16:35:45 +00:00
// https://sqlite.org/c3ref/value_blob.html
2023-07-03 17:08:16 +01:00
func (v Value) Float() float64 {
2023-07-01 00:15:28 +01:00
r := v.call(v.api.valueFloat, uint64(v.handle))
2023-06-30 10:45:16 +01:00
return math.Float64frombits(r)
}
// Time returns the value as a [time.Time].
//
2023-11-09 16:35:45 +00:00
// https://sqlite.org/c3ref/value_blob.html
2023-07-03 17:08:16 +01:00
func (v Value) Time(format TimeFormat) time.Time {
2023-07-01 00:15:28 +01:00
var a any
2023-06-30 10:45:16 +01:00
switch v.Type() {
case INTEGER:
2023-07-01 00:15:28 +01:00
a = v.Int64()
2023-06-30 10:45:16 +01:00
case FLOAT:
2023-07-01 00:15:28 +01:00
a = v.Float()
2023-06-30 10:45:16 +01:00
case TEXT, BLOB:
2023-07-01 00:15:28 +01:00
a = v.Text()
2023-06-30 10:45:16 +01:00
case NULL:
2023-07-01 00:15:28 +01:00
return time.Time{}
2023-06-30 10:45:16 +01:00
default:
panic(util.AssertErr())
}
2023-07-01 00:15:28 +01:00
t, _ := format.Decode(a)
return t
2023-06-30 10:45:16 +01:00
}
// Text returns the value as a string.
//
2023-11-09 16:35:45 +00:00
// https://sqlite.org/c3ref/value_blob.html
2023-07-03 17:08:16 +01:00
func (v Value) Text() string {
2023-07-01 00:15:28 +01:00
return string(v.RawText())
2023-06-30 10:45:16 +01:00
}
// Blob appends to buf and returns
// the value as a []byte.
//
2023-11-09 16:35:45 +00:00
// https://sqlite.org/c3ref/value_blob.html
2023-07-03 17:08:16 +01:00
func (v Value) Blob(buf []byte) []byte {
2023-07-01 00:15:28 +01:00
return append(buf, v.RawBlob()...)
2023-06-30 10:45:16 +01:00
}
// RawText returns the value as a []byte.
// The []byte is owned by SQLite and may be invalidated by
// subsequent calls to [Value] methods.
//
2023-11-09 16:35:45 +00:00
// https://sqlite.org/c3ref/value_blob.html
2023-07-03 17:08:16 +01:00
func (v Value) RawText() []byte {
2023-07-01 00:15:28 +01:00
r := v.call(v.api.valueText, uint64(v.handle))
2023-06-30 10:45:16 +01:00
return v.rawBytes(uint32(r))
}
// RawBlob returns the value as a []byte.
// The []byte is owned by SQLite and may be invalidated by
// subsequent calls to [Value] methods.
//
2023-11-09 16:35:45 +00:00
// https://sqlite.org/c3ref/value_blob.html
2023-07-03 17:08:16 +01:00
func (v Value) RawBlob() []byte {
2023-07-01 00:15:28 +01:00
r := v.call(v.api.valueBlob, uint64(v.handle))
2023-06-30 10:45:16 +01:00
return v.rawBytes(uint32(r))
}
2023-07-03 17:08:16 +01:00
func (v Value) rawBytes(ptr uint32) []byte {
2023-06-30 10:45:16 +01:00
if ptr == 0 {
2023-07-01 00:15:28 +01:00
return nil
2023-06-30 10:45:16 +01:00
}
2023-07-01 00:15:28 +01:00
r := v.call(v.api.valueBytes, uint64(v.handle))
return util.View(v.mod, ptr, r)
2023-06-30 10:45:16 +01:00
}
2023-10-13 17:06:05 +01:00
2023-11-07 00:50:43 +00:00
// Pointer gets the pointer associated with this value,
// or nil if it has no associated pointer.
func (v Value) Pointer() any {
r := v.call(v.api.valuePointer, uint64(v.handle))
return util.GetHandle(v.ctx, uint32(r))
}
2023-10-13 17:06:05 +01:00
// JSON parses a JSON-encoded value
// and stores the result in the value pointed to by ptr.
func (v Value) JSON(ptr any) error {
var data []byte
switch v.Type() {
case NULL:
2023-10-19 16:46:58 +01:00
data = append(data, "null"...)
case TEXT:
data = v.RawText()
case BLOB:
2023-10-13 17:06:05 +01:00
data = v.RawBlob()
case INTEGER:
data = strconv.AppendInt(nil, v.Int64(), 10)
case FLOAT:
data = strconv.AppendFloat(nil, v.Float(), 'g', -1, 64)
default:
panic(util.AssertErr())
}
return json.Unmarshal(data, ptr)
}