mirror of
https://github.com/chaisql/chai.git
synced 2025-09-27 03:55:59 +08:00
203 lines
3.9 KiB
Go
203 lines
3.9 KiB
Go
package types
|
|
|
|
import (
|
|
"strconv"
|
|
|
|
"github.com/chaisql/chai/internal/encoding"
|
|
"github.com/cockroachdb/errors"
|
|
)
|
|
|
|
var _ TypeDefinition = BooleanTypeDef{}
|
|
|
|
type BooleanTypeDef struct{}
|
|
|
|
func (t BooleanTypeDef) Decode(src []byte) (Value, int) {
|
|
b := encoding.DecodeBoolean(src)
|
|
return NewBooleanValue(b), 1
|
|
}
|
|
|
|
func (BooleanTypeDef) IsComparableWith(other Type) bool {
|
|
return other == TypeBoolean
|
|
}
|
|
|
|
func (BooleanTypeDef) IsIndexComparableWith(other Type) bool {
|
|
return other == TypeBoolean
|
|
}
|
|
|
|
var _ Value = NewBooleanValue(false)
|
|
|
|
type BooleanValue bool
|
|
|
|
// NewBooleanValue returns a SQL BOOLEAN value.
|
|
func NewBooleanValue(x bool) BooleanValue {
|
|
return BooleanValue(x)
|
|
}
|
|
|
|
func (v BooleanValue) V() any {
|
|
return bool(v)
|
|
}
|
|
|
|
func (v BooleanValue) Type() Type {
|
|
return TypeBoolean
|
|
}
|
|
|
|
func (v BooleanValue) TypeDef() TypeDefinition {
|
|
return BooleanTypeDef{}
|
|
}
|
|
|
|
func (v BooleanValue) IsZero() (bool, error) {
|
|
return !bool(v), nil
|
|
}
|
|
|
|
func (v BooleanValue) String() string {
|
|
return strconv.FormatBool(bool(v))
|
|
}
|
|
|
|
func (v BooleanValue) MarshalText() ([]byte, error) {
|
|
return []byte(strconv.FormatBool(bool(v))), nil
|
|
}
|
|
|
|
func (v BooleanValue) MarshalJSON() ([]byte, error) {
|
|
return v.MarshalText()
|
|
}
|
|
|
|
func (v BooleanValue) Encode(dst []byte) ([]byte, error) {
|
|
return encoding.EncodeBoolean(dst, bool(v)), nil
|
|
}
|
|
|
|
func (v BooleanValue) EncodeAsKey(dst []byte) ([]byte, error) {
|
|
return v.Encode(dst)
|
|
}
|
|
|
|
func (v BooleanValue) CastAs(target Type) (Value, error) {
|
|
switch target {
|
|
case TypeBoolean:
|
|
return v, nil
|
|
case TypeInteger:
|
|
if bool(v) {
|
|
return NewIntegerValue(1), nil
|
|
}
|
|
|
|
return NewIntegerValue(0), nil
|
|
case TypeText:
|
|
return NewTextValue(v.String()), nil
|
|
}
|
|
|
|
return nil, errors.Errorf("cannot cast %q as %q", v.Type(), target)
|
|
}
|
|
|
|
func (v BooleanValue) ConvertToIndexedType(t Type) (Value, error) {
|
|
return v, nil
|
|
}
|
|
|
|
func (v BooleanValue) EQ(other Value) (bool, error) {
|
|
if other.Type() == TypeNull {
|
|
return false, nil
|
|
}
|
|
|
|
if other.Type() == TypeText {
|
|
tv, err := other.CastAs(TypeBoolean)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
other = tv
|
|
}
|
|
|
|
if other.Type() != TypeBoolean {
|
|
return false, errors.Errorf("cannot compare boolean with %s", other.Type())
|
|
}
|
|
|
|
return bool(v) == AsBool(other), nil
|
|
}
|
|
|
|
func (v BooleanValue) GT(other Value) (bool, error) {
|
|
if other.Type() == TypeNull {
|
|
return false, nil
|
|
}
|
|
|
|
if other.Type() == TypeText {
|
|
tv, err := other.CastAs(TypeBoolean)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
other = tv
|
|
}
|
|
|
|
if other.Type() != TypeBoolean {
|
|
return false, errors.Errorf("cannot compare boolean with %s", other.Type())
|
|
}
|
|
|
|
return bool(v) && !AsBool(other), nil
|
|
}
|
|
|
|
func (v BooleanValue) GTE(other Value) (bool, error) {
|
|
if other.Type() == TypeNull {
|
|
return false, nil
|
|
}
|
|
|
|
if other.Type() == TypeText {
|
|
tv, err := other.CastAs(TypeBoolean)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
other = tv
|
|
}
|
|
|
|
if other.Type() != TypeBoolean {
|
|
return false, errors.Errorf("cannot compare boolean with %s", other.Type())
|
|
}
|
|
|
|
bv := bool(v)
|
|
return bv == AsBool(other) || bv, nil
|
|
}
|
|
|
|
func (v BooleanValue) LT(other Value) (bool, error) {
|
|
if other.Type() == TypeNull {
|
|
return false, nil
|
|
}
|
|
|
|
if other.Type() == TypeText {
|
|
tv, err := other.CastAs(TypeBoolean)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
other = tv
|
|
}
|
|
|
|
if other.Type() != TypeBoolean {
|
|
return false, errors.Errorf("cannot compare boolean with %s", other.Type())
|
|
}
|
|
|
|
return !bool(v) && AsBool(other), nil
|
|
}
|
|
|
|
func (v BooleanValue) LTE(other Value) (bool, error) {
|
|
if other.Type() == TypeNull {
|
|
return false, nil
|
|
}
|
|
|
|
if other.Type() == TypeText {
|
|
tv, err := other.CastAs(TypeBoolean)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
other = tv
|
|
}
|
|
|
|
if other.Type() != TypeBoolean {
|
|
return false, errors.Errorf("cannot compare boolean with %s", other.Type())
|
|
}
|
|
|
|
bv := bool(v)
|
|
return bv == AsBool(other) || !bv, nil
|
|
}
|
|
|
|
func (v BooleanValue) Between(a, b Value) (bool, error) {
|
|
ok, err := v.GTE(a)
|
|
if err != nil || !ok {
|
|
return false, err
|
|
}
|
|
|
|
return v.LTE(b)
|
|
}
|