Browse Source

Adds parsing / handling for CQLv4 Custom Payload, bytes map, access via Iter

* adding parsing for CQLv4 Custom Payload, bytes map, access via Iter

* dropping needless nil checks

* Update AUTHORS
Rob McColl 9 years ago
parent
commit
7b1caf3559
3 changed files with 35 additions and 5 deletions
  1. 1 0
      AUTHORS
  2. 23 5
      frame.go
  3. 11 0
      session.go

+ 1 - 0
AUTHORS

@@ -66,3 +66,4 @@ LOVOO <opensource@lovoo.com>
 nikandfor <nikandfor@gmail.com>
 nikandfor <nikandfor@gmail.com>
 Anthony Woods <awoods@raintank.io>
 Anthony Woods <awoods@raintank.io>
 Alexander Inozemtsev <alexander.inozemtsev@gmail.com>
 Alexander Inozemtsev <alexander.inozemtsev@gmail.com>
+Rob McColl <rob@robmccoll.com>; <rmccoll@ionicsecurity.com>

+ 23 - 5
frame.go

@@ -252,11 +252,12 @@ func readShort(p []byte) uint16 {
 }
 }
 
 
 type frameHeader struct {
 type frameHeader struct {
-	version protoVersion
-	flags   byte
-	stream  int
-	op      frameOp
-	length  int
+	version       protoVersion
+	flags         byte
+	stream        int
+	op            frameOp
+	length        int
+	customPayload map[string][]byte
 }
 }
 
 
 func (f frameHeader) String() string {
 func (f frameHeader) String() string {
@@ -446,6 +447,10 @@ func (f *framer) parseFrame() (frame frame, err error) {
 		}
 		}
 	}
 	}
 
 
+	if f.header.flags&flagCustomPayload == flagCustomPayload {
+		f.header.customPayload = f.readBytesMap()
+	}
+
 	// assumes that the frame body has been read into rbuf
 	// assumes that the frame body has been read into rbuf
 	switch f.header.op {
 	switch f.header.op {
 	case opError:
 	case opError:
@@ -1629,6 +1634,19 @@ func (f *framer) readStringMap() map[string]string {
 	return m
 	return m
 }
 }
 
 
+func (f *framer) readBytesMap() map[string][]byte {
+	size := f.readShort()
+	m := make(map[string][]byte)
+
+	for i := 0; i < int(size); i++ {
+		k := f.readString()
+		v := f.readBytes()
+		m[k] = v
+	}
+
+	return m
+}
+
 func (f *framer) readStringMultiMap() map[string][]string {
 func (f *framer) readStringMultiMap() map[string][]string {
 	size := f.readShort()
 	size := f.readShort()
 	m := make(map[string][]string)
 	m := make(map[string][]string)

+ 11 - 0
session.go

@@ -996,6 +996,17 @@ func (iter *Iter) Scan(dest ...interface{}) bool {
 	return true
 	return true
 }
 }
 
 
+// GetCustomPayload returns any parsed custom payload results if given in the
+// response from Cassandra. Note that the result is not a copy.
+//
+// This additional feature of CQL Protocol v4
+// allows additional results and query information to be returned by
+// custom QueryHandlers running in your C* cluster.
+// See https://datastax.github.io/java-driver/manual/custom_payloads/
+func (iter *Iter) GetCustomPayload() map[string][]byte {
+	return iter.framer.header.customPayload
+}
+
 // Close closes the iterator and returns any errors that happened during
 // Close closes the iterator and returns any errors that happened during
 // the query or the iteration.
 // the query or the iteration.
 func (iter *Iter) Close() error {
 func (iter *Iter) Close() error {