|
@@ -90,6 +90,10 @@ func Unmarshal(info *TypeInfo, data []byte, value interface{}) error {
|
|
|
if v, ok := value.(Unmarshaler); ok {
|
|
if v, ok := value.(Unmarshaler); ok {
|
|
|
return v.UnmarshalCQL(info, data)
|
|
return v.UnmarshalCQL(info, data)
|
|
|
}
|
|
}
|
|
|
|
|
+ if isNullableValue(value) {
|
|
|
|
|
+ return unmarshalNullable(info, data, value)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
switch info.Type {
|
|
switch info.Type {
|
|
|
case TypeVarchar, TypeAscii, TypeBlob:
|
|
case TypeVarchar, TypeAscii, TypeBlob:
|
|
|
return unmarshalVarchar(info, data, value)
|
|
return unmarshalVarchar(info, data, value)
|
|
@@ -124,6 +128,29 @@ func Unmarshal(info *TypeInfo, data []byte, value interface{}) error {
|
|
|
return fmt.Errorf("can not unmarshal %s into %T", info, value)
|
|
return fmt.Errorf("can not unmarshal %s into %T", info, value)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+func isNullableValue(value interface{}) bool {
|
|
|
|
|
+ v := reflect.ValueOf(value)
|
|
|
|
|
+ return v.Kind() == reflect.Ptr && v.Type().Elem().Kind() == reflect.Ptr
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func isNullData(info *TypeInfo, data []byte) bool {
|
|
|
|
|
+ return len(data) == 0
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+func unmarshalNullable(info *TypeInfo, data []byte, value interface{}) error {
|
|
|
|
|
+ valueRef := reflect.ValueOf(value)
|
|
|
|
|
+
|
|
|
|
|
+ if isNullData(info, data) {
|
|
|
|
|
+ nilValue := reflect.Zero(valueRef.Type().Elem())
|
|
|
|
|
+ valueRef.Elem().Set(nilValue)
|
|
|
|
|
+ return nil
|
|
|
|
|
+ } else {
|
|
|
|
|
+ newValue := reflect.New(valueRef.Type().Elem().Elem())
|
|
|
|
|
+ valueRef.Elem().Set(newValue)
|
|
|
|
|
+ return Unmarshal(info, data, newValue.Interface())
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
func marshalVarchar(info *TypeInfo, value interface{}) ([]byte, error) {
|
|
func marshalVarchar(info *TypeInfo, value interface{}) ([]byte, error) {
|
|
|
switch v := value.(type) {
|
|
switch v := value.(type) {
|
|
|
case Marshaler:
|
|
case Marshaler:
|
|
@@ -323,7 +350,7 @@ func unmarshalInt(info *TypeInfo, data []byte, value interface{}) error {
|
|
|
|
|
|
|
|
func unmarshalVarint(info *TypeInfo, data []byte, value interface{}) error {
|
|
func unmarshalVarint(info *TypeInfo, data []byte, value interface{}) error {
|
|
|
switch value.(type) {
|
|
switch value.(type) {
|
|
|
- case *big.Int, **big.Int:
|
|
|
|
|
|
|
+ case *big.Int:
|
|
|
return unmarshalIntlike(info, 0, data, value)
|
|
return unmarshalIntlike(info, 0, data, value)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -449,13 +476,6 @@ func unmarshalIntlike(info *TypeInfo, int64Val int64, data []byte, value interfa
|
|
|
case *big.Int:
|
|
case *big.Int:
|
|
|
decBigInt2C(data, v)
|
|
decBigInt2C(data, v)
|
|
|
return nil
|
|
return nil
|
|
|
- case **big.Int:
|
|
|
|
|
- if len(data) == 0 {
|
|
|
|
|
- *v = nil
|
|
|
|
|
- } else {
|
|
|
|
|
- *v = decBigInt2C(data, nil)
|
|
|
|
|
- }
|
|
|
|
|
- return nil
|
|
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
rv := reflect.ValueOf(value)
|
|
rv := reflect.ValueOf(value)
|
|
@@ -680,18 +700,12 @@ func unmarshalDecimal(info *TypeInfo, data []byte, value interface{}) error {
|
|
|
switch v := value.(type) {
|
|
switch v := value.(type) {
|
|
|
case Unmarshaler:
|
|
case Unmarshaler:
|
|
|
return v.UnmarshalCQL(info, data)
|
|
return v.UnmarshalCQL(info, data)
|
|
|
- case **inf.Dec:
|
|
|
|
|
- if len(data) > 4 {
|
|
|
|
|
- scale := decInt(data[0:4])
|
|
|
|
|
- unscaled := decBigInt2C(data[4:], nil)
|
|
|
|
|
- *v = inf.NewDecBig(unscaled, inf.Scale(scale))
|
|
|
|
|
- return nil
|
|
|
|
|
- } else if len(data) == 0 {
|
|
|
|
|
- *v = nil
|
|
|
|
|
- return nil
|
|
|
|
|
- } else {
|
|
|
|
|
- return unmarshalErrorf("can not unmarshal %s into %T", info, value)
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ case *inf.Dec:
|
|
|
|
|
+ scale := decInt(data[0:4])
|
|
|
|
|
+ unscaled := decBigInt2C(data[4:], nil)
|
|
|
|
|
+ newValue := reflect.ValueOf(inf.NewDecBig(unscaled, inf.Scale(scale)))
|
|
|
|
|
+ reflect.ValueOf(value).Elem().Set(newValue.Elem())
|
|
|
|
|
+ return nil
|
|
|
}
|
|
}
|
|
|
return unmarshalErrorf("can not unmarshal %s into %T", info, value)
|
|
return unmarshalErrorf("can not unmarshal %s into %T", info, value)
|
|
|
}
|
|
}
|