Sfoglia il codice sorgente

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 anni fa
parent
commit
a2336d7724
2 ha cambiato i file con 57 aggiunte e 0 eliminazioni
  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])