forked from apache/cassandra-gocql-driver
-
Notifications
You must be signed in to change notification settings - Fork 60
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
680 additions
and
297 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package marshal | ||
|
||
// Marshaller is an interface for marshalling objects according to the CQL binary protocol. | ||
// Initially, each value of the 'CQL binary protocol' consist of <value_len> and <value_data>. | ||
// <value_len> can be 'unset'(-2), 'nil'(-1), 'zero'(0) or any value up to 2147483647. | ||
// In 'unset', 'nil' and 'zero' cases <value_data> is not present. | ||
// Basically, 'unset' is applicable only to columns, but there may be exceptions. | ||
// The current version of 'gocql' writes <value_len> through logic after marshaling functions, | ||
// so you need to tell this logic about these cases: | ||
// 1. In 'unset' case - you need to put gocql.UnsetValue instead of value. | ||
// 2. In 'nil' case - your Marshaller implementation should return []byte==nil. | ||
// 3. In 'zero' case - your Marshaller implementation should return initiated []byte with len==0. | ||
// | ||
// All CQL DB`s have proprietary value coding features, which you need to consider. | ||
// CQL binary protocol info:https://github.com/apache/cassandra/tree/trunk/doc | ||
type Marshaller interface { | ||
MarshalCQLv2() ([]byte, error) | ||
} | ||
|
||
// Unmarshaller is an interface for unmarshalling objects according to the CQL binary protocol. | ||
// Initially, each value of the 'CQL binary protocol' consist of <value_len> and <value_data>. | ||
// <value_len> can be 'nil'(-1), 'zero'(0) or any value up to 2147483647. | ||
// In 'nil' and 'zero' cases <value_data> is not present. | ||
// The current version of 'gocql' reads <value_len> through logic before unmarshalling functions, | ||
// so your Unmarshaller implementation will receive: | ||
// in the 'nil' case - []byte==nil, | ||
// in the 'zero' case - initiated []byte with len==0. | ||
// CQL binary protocol info:https://github.com/apache/cassandra/tree/trunk/doc | ||
type Unmarshaller interface { | ||
UnmarshalCQLv2(data []byte) error | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,88 +1,80 @@ | ||
package tinyint | ||
|
||
import ( | ||
"math" | ||
"math/big" | ||
"reflect" | ||
"strconv" | ||
|
||
"github.com/gocql/gocql/marshal/erro" | ||
"github.com/gocql/gocql/marshal" | ||
) | ||
|
||
func Marshal(value interface{}) ([]byte, error) { | ||
switch v := value.(type) { | ||
case nil: | ||
return nil, nil | ||
case marshal.Marshaller: | ||
return v.MarshalCQLv2() | ||
|
||
case int8: | ||
return []byte{byte(v)}, nil | ||
case uint8: | ||
return []byte{byte(v)}, nil | ||
case int16: | ||
if v > math.MaxInt8 || v < math.MinInt8 { | ||
return nil, erro.Newf("marshal tinyint: value %#v out of range", v) | ||
} | ||
return []byte{byte(v)}, nil | ||
case uint16: | ||
if v > math.MaxUint8 { | ||
return nil, erro.Newf("marshal tinyint: value %#v out of range", v) | ||
} | ||
return []byte{byte(v)}, nil | ||
case int: | ||
if v > math.MaxInt8 || v < math.MinInt8 { | ||
return nil, erro.Newf("marshal tinyint: value %#v out of range", v) | ||
} | ||
return []byte{byte(v)}, nil | ||
return EncInt8(v) | ||
case int32: | ||
if v > math.MaxInt8 || v < math.MinInt8 { | ||
return nil, erro.Newf("marshal tinyint: value %#v out of range", v) | ||
} | ||
return []byte{byte(v)}, nil | ||
return EncInt32(v) | ||
case int16: | ||
return EncInt16(v) | ||
case int64: | ||
if v > math.MaxInt8 || v < math.MinInt8 { | ||
return nil, erro.Newf("marshal tinyint: value %#v out of range", v) | ||
} | ||
return []byte{byte(v)}, nil | ||
case uint: | ||
if v > math.MaxUint8 { | ||
return nil, erro.Newf("marshal tinyint: value %#v out of range", v) | ||
} | ||
return []byte{byte(v)}, nil | ||
return EncInt64(v) | ||
case int: | ||
return EncInt(v) | ||
|
||
case uint8: | ||
return EncUint8(v) | ||
case uint16: | ||
return EncUint16(v) | ||
case uint32: | ||
if v > math.MaxUint8 { | ||
return nil, erro.Newf("marshal tinyint: value %#v out of range", v) | ||
} | ||
return []byte{byte(v)}, nil | ||
return EncUint32(v) | ||
case uint64: | ||
if v > math.MaxUint8 { | ||
return nil, erro.Newf("marshal tinyint: value %#v out of range", v) | ||
} | ||
return []byte{byte(v)}, nil | ||
return EncUint64(v) | ||
case uint: | ||
return EncUint(v) | ||
|
||
case big.Int: | ||
return EncBigInt(v) | ||
case string: | ||
n, err := strconv.ParseInt(v, 10, 8) | ||
if err != nil { | ||
return nil, erro.Newf("marshal tinyint: can not marshal %#v %s", value, err) | ||
} | ||
return []byte{byte(n)}, nil | ||
} | ||
return EncString(v) | ||
|
||
if value == nil { | ||
return nil, nil | ||
} | ||
case *int8: | ||
return EncInt8R(v) | ||
case *int16: | ||
return EncInt16R(v) | ||
case *int32: | ||
return EncInt32R(v) | ||
case *int64: | ||
return EncInt64R(v) | ||
case *int: | ||
return EncIntR(v) | ||
|
||
switch rv := reflect.ValueOf(value); rv.Type().Kind() { | ||
case reflect.Int, reflect.Int64, reflect.Int32, reflect.Int16, reflect.Int8: | ||
v := rv.Int() | ||
if v > math.MaxInt8 || v < math.MinInt8 { | ||
return nil, erro.Newf("marshal tinyint: value %#v out of range", v) | ||
} | ||
return []byte{byte(v)}, nil | ||
case reflect.Uint, reflect.Uint64, reflect.Uint32, reflect.Uint16, reflect.Uint8: | ||
v := rv.Uint() | ||
if v > math.MaxUint8 { | ||
return nil, erro.Newf("marshal tinyint: value %#v out of range", v) | ||
} | ||
return []byte{byte(v)}, nil | ||
case reflect.Ptr: | ||
if rv.IsNil() { | ||
return nil, nil | ||
case *uint8: | ||
return EncUint8R(v) | ||
case *uint16: | ||
return EncUint16R(v) | ||
case *uint32: | ||
return EncUint32R(v) | ||
case *uint64: | ||
return EncUint64R(v) | ||
case *uint: | ||
return EncUintR(v) | ||
|
||
case *big.Int: | ||
return EncBigIntR(v) | ||
case *string: | ||
return EncStringR(v) | ||
default: | ||
rv := reflect.TypeOf(value) | ||
if rv.Kind() == reflect.Ptr { | ||
if rv.Elem().Kind() != reflect.Ptr { | ||
return EncReflect(reflect.ValueOf(v)) | ||
} | ||
return EncReflectR(reflect.ValueOf(v)) | ||
} | ||
return nil, errMarshal.Addf("unsupported value type %#v", value) | ||
} | ||
return nil, erro.Newf("marshal tinyint: can not marshal %#v", value) | ||
} |
Oops, something went wrong.