فهرست منبع

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 12 سال پیش
والد
کامیت
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])