Преглед изворни кода

Parse custom types in the org.apache.cassandra.db.marshal. namespace. This behaviour is not documented in the wire spec, however it is done by the python datastax driver

Nimi Wariboko пре 11 година
родитељ
комит
a2336d7724
2 измењених фајлова са 57 додато и 0 уклоњено
  1. 12 0
      frame.go
  2. 45 0
      helpers.go

+ 12 - 0
frame.go

@@ -59,6 +59,8 @@ const (
 	errUnprepared    = 0x2500
 
 	headerSize = 8
+
+	apacheCassandraTypePrefix = "org.apache.cassandra.db.marshal."
 )
 
 type frame []byte
@@ -243,6 +245,16 @@ func (f *frame) readTypeInfo() *TypeInfo {
 	switch typ.Type {
 	case TypeCustom:
 		typ.Custom = f.readString()
+		if cassType := getApacheCassandraType(typ.Custom); cassType != TypeCustom {
+			typ = &TypeInfo{Type: cassType}
+			switch typ.Type {
+			case TypeMap:
+				typ.Key = f.readTypeInfo()
+				fallthrough
+			case TypeList, TypeSet:
+				typ.Elem = f.readTypeInfo()
+			}
+		}
 	case TypeMap:
 		typ.Key = f.readTypeInfo()
 		fallthrough

+ 45 - 0
helpers.go

@@ -7,6 +7,7 @@ package gocql
 import (
 	"reflect"
 	"speter.net/go/exp/math/dec/inf"
+	"strings"
 	"time"
 )
 
@@ -56,6 +57,50 @@ func dereference(i interface{}) interface{} {
 	return reflect.Indirect(reflect.ValueOf(i)).Interface()
 }
 
+func getApacheCassandraType(class string) Type {
+	if strings.HasPrefix(class, apacheCassandraTypePrefix) {
+		switch strings.TrimPrefix(class, apacheCassandraTypePrefix) {
+		case "AsciiType":
+			return TypeAscii
+		case "LongType":
+			return TypeBigInt
+		case "BytesType":
+			return TypeBlob
+		case "BooleanType":
+			return TypeBoolean
+		case "CounterColumnType":
+			return TypeCounter
+		case "DecimalType":
+			return TypeDecimal
+		case "DoubleType":
+			return TypeDouble
+		case "FloatType":
+			return TypeFloat
+		case "Int32Type":
+			return TypeInt
+		case "DateType":
+			return TypeTimestamp
+		case "UUIDType":
+			return TypeUUID
+		case "UTF8Type":
+			return TypeVarchar
+		case "IntegerType":
+			return TypeVarint
+		case "TimeUUIDType":
+			return TypeTimeUUID
+		case "InetAddressType":
+			return TypeInet
+		case "MapType":
+			return TypeMap
+		case "ListType":
+			return TypeInet
+		case "SetType":
+			return TypeInet
+		}
+	}
+	return TypeCustom
+}
+
 func (r *RowData) rowMap(m map[string]interface{}) {
 	for i, column := range r.Columns {
 		m[column] = dereference(r.Values[i])