Skip to content

Commit

Permalink
add NullType
Browse files Browse the repository at this point in the history
  • Loading branch information
xormplus committed Jun 23, 2018
1 parent 00e9bc4 commit 230c242
Show file tree
Hide file tree
Showing 17 changed files with 1,293 additions and 344 deletions.
5 changes: 5 additions & 0 deletions null.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package xorm

type NullType interface {
IsNil() bool
}
90 changes: 90 additions & 0 deletions null_bool.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package xorm

import (
"encoding/json"
"errors"
"fmt"
"reflect"
)

type NullBool struct {
Bool bool
Valid bool
}

func (nb NullBool) Ptr() *bool {
if !nb.Valid {
return nil
}
return &nb.Bool
}

func (nb NullBool) ValueOrZero() bool {
if !nb.Valid {
return false
}
return nb.Bool
}

func (nb NullBool) IsNil() bool {
return !nb.Valid
}

func (nb *NullBool) UnmarshalJSON(data []byte) error {
var err error
var v interface{}
if err = json.Unmarshal(data, &v); err != nil {
return err
}
switch x := v.(type) {
case bool:
nb.Bool = x
case map[string]interface{}:
err = json.Unmarshal(data, &nb)
case nil:
nb.Valid = false
return nil
default:
err = fmt.Errorf("json: cannot unmarshal %v into Go value of type xorm.NullBool", reflect.TypeOf(v).Name())
}
nb.Valid = err == nil
return err
}

func (nb *NullBool) UnmarshalText(text []byte) error {
str := string(text)
switch str {
case "", "null":
nb.Valid = false
return nil
case "true":
nb.Bool = true
case "false":
nb.Bool = false
default:
nb.Valid = false
return errors.New("invalid input:" + str)
}
nb.Valid = true
return nil
}

func (nb NullBool) MarshalJSON() ([]byte, error) {
if !nb.Valid {
return []byte("null"), nil
}
if !nb.Bool {
return []byte("false"), nil
}
return []byte("true"), nil
}

func (nb NullBool) MarshalText() ([]byte, error) {
if !nb.Valid {
return []byte{}, nil
}
if !nb.Bool {
return []byte("false"), nil
}
return []byte("true"), nil
}
100 changes: 100 additions & 0 deletions null_float32.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package xorm

import (
"encoding/json"
"fmt"
"math"
"reflect"
"strconv"
)

type NullFloat32 struct {
Float32 float32
Valid bool
}

func (nf NullFloat32) Ptr() *float32 {
if !nf.Valid {
return nil
}
return &nf.Float32
}

func (nf NullFloat32) ValueOrZero() float32 {
if !nf.Valid {
return 0
}
return nf.Float32
}

func (nf NullFloat32) IsNil() bool {
return !nf.Valid
}

func (nf *NullFloat32) UnmarshalJSON(data []byte) error {
var err error
var v interface{}
if err = json.Unmarshal(data, &v); err != nil {
return err
}
switch x := v.(type) {
case float64:
nf.Float32 = float32(x)
case string:
str := string(x)
if len(str) == 0 {
nf.Valid = false
return nil
}
var f float64
f, err = strconv.ParseFloat(str, 32)
if err == nil {
nf.Float32 = float32(f)
}
case map[string]interface{}:
err = json.Unmarshal(data, &nf)
case nil:
nf.Valid = false
return nil
default:
err = fmt.Errorf("json: cannot unmarshal %v into Go value of type xorm.NullFloat32", reflect.TypeOf(v).Name())
}
nf.Valid = err == nil
return err
}

func (nf *NullFloat32) UnmarshalText(text []byte) error {
str := string(text)
if str == "" || str == "null" {
nf.Valid = false
return nil
}
var err error
var f float64
f, err = strconv.ParseFloat(string(text), 32)
if err == nil {
nf.Float32 = float32(f)
}
nf.Valid = err == nil
return err
}

func (nf NullFloat32) MarshalJSON() ([]byte, error) {
if !nf.Valid {
return []byte("null"), nil
}
if math.IsInf(float64(nf.Float32), 0) || math.IsNaN(float64(nf.Float32)) {
return nil, &json.UnsupportedValueError{
Value: reflect.ValueOf(nf.Float32),
Str: strconv.FormatFloat(float64(nf.Float32), 'g', -1, 32),
}
}
return []byte(strconv.FormatFloat(float64(nf.Float32), 'f', -1, 32)), nil
}

func (nf NullFloat32) MarshalText() ([]byte, error) {
if !nf.Valid {
return []byte{}, nil
}
return []byte(strconv.FormatFloat(float64(nf.Float32), 'f', -1, 32)), nil
}
92 changes: 92 additions & 0 deletions null_float64.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package xorm

import (
"encoding/json"
"fmt"
"math"
"reflect"
"strconv"
)

type NullFloat64 struct {
Float64 float64
Valid bool
}

func (nf NullFloat64) Ptr() *float64 {
if !nf.Valid {
return nil
}
return &nf.Float64
}

func (nf NullFloat64) ValueOrZero() float64 {
if !nf.Valid {
return 0
}
return nf.Float64
}

func (nf NullFloat64) IsNil() bool {
return !nf.Valid
}

func (nf *NullFloat64) UnmarshalJSON(data []byte) error {
var err error
var v interface{}
if err = json.Unmarshal(data, &v); err != nil {
return err
}
switch x := v.(type) {
case float64:
nf.Float64 = float64(x)
case string:
str := string(x)
if len(str) == 0 {
nf.Valid = false
return nil
}
nf.Float64, err = strconv.ParseFloat(str, 64)
case map[string]interface{}:
err = json.Unmarshal(data, &nf)
case nil:
nf.Valid = false
return nil
default:
err = fmt.Errorf("json: cannot unmarshal %v into Go value of type xorm.NullFloat64", reflect.TypeOf(v).Name())
}
nf.Valid = err == nil
return err
}

func (nf *NullFloat64) UnmarshalText(text []byte) error {
str := string(text)
if str == "" || str == "null" {
nf.Valid = false
return nil
}
var err error
nf.Float64, err = strconv.ParseFloat(string(text), 64)
nf.Valid = err == nil
return err
}

func (nf NullFloat64) MarshalJSON() ([]byte, error) {
if !nf.Valid {
return []byte("null"), nil
}
if math.IsInf(nf.Float64, 0) || math.IsNaN(nf.Float64) {
return nil, &json.UnsupportedValueError{
Value: reflect.ValueOf(nf.Float64),
Str: strconv.FormatFloat(nf.Float64, 'g', -1, 64),
}
}
return []byte(strconv.FormatFloat(nf.Float64, 'f', -1, 64)), nil
}

func (nf NullFloat64) MarshalText() ([]byte, error) {
if !nf.Valid {
return []byte{}, nil
}
return []byte(strconv.FormatFloat(nf.Float64, 'f', -1, 64)), nil
}
85 changes: 85 additions & 0 deletions null_int.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package xorm

import (
"encoding/json"
"fmt"
"reflect"
"strconv"
)

type NullInt struct {
Int int
Valid bool
}

func (ni NullInt) Ptr() *int {
if !ni.Valid {
return nil
}
return &ni.Int
}

func (ni NullInt) ValueOrZero() int {
if !ni.Valid {
return 0
}
return ni.Int
}

func (ni NullInt) IsNil() bool {
return !ni.Valid
}

func (ni *NullInt) UnmarshalJSON(data []byte) error {
var err error
var v interface{}
if err = json.Unmarshal(data, &v); err != nil {
return err
}
switch x := v.(type) {
case float64:
err = json.Unmarshal(data, &ni.Int)
case string:
str := string(x)
if len(str) == 0 {
ni.Valid = false
return nil
}
ni.Int, err = strconv.Atoi(string(str))
case map[string]interface{}:
err = json.Unmarshal(data, &ni)
case nil:
ni.Valid = false
return nil
default:
err = fmt.Errorf("json: cannot unmarshal %v into Go value of type xorm.NullInt", reflect.TypeOf(v).Name())
}
ni.Valid = err == nil
return err
}

func (ni *NullInt) UnmarshalText(text []byte) error {
str := string(text)
if str == "" || str == "null" {
ni.Valid = false
return nil
}
var err error
ni.Int, err = strconv.Atoi(string(text))
ni.Valid = err == nil
return err
}

func (ni NullInt) MarshalJSON() ([]byte, error) {
if !ni.Valid {
return []byte("null"), nil
}
return []byte(strconv.Itoa(ni.Int)), nil
}

func (ni NullInt) MarshalText() ([]byte, error) {
if !ni.Valid {
return []byte{}, nil
}
return []byte(strconv.Itoa(ni.Int)), nil
}
Loading

0 comments on commit 230c242

Please sign in to comment.