Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

more composite work and testing

  • Loading branch information...
commit 506e19c158728cb690ccdb69de12e67648c183df 1 parent b46e8fa
@carloscm authored
View
4 README.md
@@ -1,6 +1,6 @@
# About
-Gossie is (for now) a Go library with a low level wrapper for the Cassandra 1.0 thrift bidings with with utilities for connection pooling, primitive type marshalling and easy query building (much easier to use than the generated thrift bindings). A higher level layer will be implemented on top of the current code to allow for struct marshalling into rows and composites, among other things.
+Gossie is (for now) a Go library with a low level wrapper for the Cassandra 1.0 thrift bidings with with utilities for connection pooling, primitive type marshaling and easy query building (much easier to use than the generated thrift bindings). A higher level layer will be implemented on top of the current code to allow for struct marshalling into rows and composites, among other things.
# Requeriments
@@ -29,7 +29,7 @@ Launch a Cassandra instance in localhost:9160, create a keyspace named TestGossi
# Example
-I will provide a full example once the higher level marshalling is implemented. For examples of the low level layer check src/gossie/query_test.go
+I will provide a full example once the higher level marshaling is implemented. For examples of the low level layer check src/gossie/query_test.go
# License
View
35 src/gossie/connection_test.go
@@ -9,12 +9,14 @@ import (
func TestConnection(t *testing.T) {
- c, err := newConnection("127.0.0.1:9999", "NotExists", 3000)
- if err == nil {
- t.Fatal("Invalid connection parameters did not return error")
- }
-
- c, err = newConnection("127.0.0.1:9160", "NotExists", 1000)
+ /* kind of pointless
+ c, err := newConnection("127.0.0.1:9999", "NotExists", 3000)
+ if err == nil {
+ t.Fatal("Invalid connection parameters did not return error")
+ }
+ */
+
+ c, err := newConnection("127.0.0.1:9160", "NotExists", 1000)
if err == nil {
t.Fatal("Invalid keyspace did not return error")
}
@@ -33,17 +35,26 @@ func TestConnection(t *testing.T) {
func TestNewConnectionPool(t *testing.T) {
- cp, err := NewConnectionPool([]string{"127.0.0.1:9999"}, "NotExists", PoolOptions{Size: 50, Timeout: 3000})
- if err == nil {
- t.Fatal("Invalid connection parameters did not return error")
- }
+ /* kind of pointless
+ cp, err := NewConnectionPool([]string{"127.0.0.1:9999"}, "NotExists", PoolOptions{Size: 50, Timeout: 3000})
+ if err == nil {
+ t.Fatal("Invalid connection parameters did not return error")
+ }
+ */
- cp, err = NewConnectionPool([]string{"127.0.0.1:9160"}, "NotExists", PoolOptions{Size: 50, Timeout: 3000})
+ cp, err := NewConnectionPool([]string{"127.0.0.1:9160"}, "NotExists", PoolOptions{Size: 50, Timeout: 3000})
if err == nil {
t.Fatal("Invalid keyspace did not return error")
}
- cp, err = NewConnectionPool([]string{"127.0.0.1:9160", "127.0.0.1:9170", "127.0.0.1:9180"}, "TestGossie", PoolOptions{Size: 50, Timeout: 3000})
+ /* kind of pointless
+ cp, err = NewConnectionPool([]string{"127.0.0.1:9160", "127.0.0.1:9170", "127.0.0.1:9180"}, "TestGossie", PoolOptions{Size: 50, Timeout: 3000})
+ if err != nil {
+ t.Fatal("Error connecting to Cassandra:", err)
+ }
+ */
+
+ cp, err = NewConnectionPool([]string{"127.0.0.1:9160"}, "TestGossie", PoolOptions{Size: 50, Timeout: 3000})
if err != nil {
t.Fatal("Error connecting to Cassandra:", err)
}
View
14 src/gossie/struct.go
@@ -17,6 +17,18 @@ todo:
support composite key, not just composite column (is this actually in use by anybody???)
name: and type: tag field modifiers to override default naming and marshaling
+ go maps support for things like
+ type s struct {
+ a int `cf:"cfname" key:"a" col:"atts" val:"atts"`
+ atts map[string]string
+ }
+ type s2 struct {
+ a int `cf:"cfname" key:"a" col:"b,atts" val:"atts"`
+ b UUID
+ atts map[string]string
+ }
+ --> then think about slicing/pagging this, oops
+
unmap
---
@@ -90,7 +102,6 @@ type fieldMapping struct {
fieldKind int
position int
name string
- goType reflect.Type
cassandraType TypeDesc
}
type structMapping struct {
@@ -152,7 +163,6 @@ func newFieldMapping(pos int, sf reflect.StructField) *fieldMapping {
fm.cassandraType, fm.fieldKind = defaultCassandraType(sf.Type)
fm.position = pos
fm.name = sf.Name
- fm.goType = sf.Type
return fm
}
View
167 src/gossie/struct_test.go
@@ -57,6 +57,32 @@ type noErrC struct {
b int
c int
}
+type noErrD struct {
+ a int `cf:"cfname" key:"a" col:"b" val:"c"`
+ b []int
+ c []int
+}
+type noErrE struct {
+ a int `cf:"cfname" key:"a" col:"b,c" val:"d"`
+ b int
+ c []int
+ d []int
+}
+type everythingComp struct {
+ Key string `cf:"cfname" key:"Key" col:"FBytes,FBool,FInt8,FInt16,FInt32,FInt,FInt64,FFloat32,FFloat64,FString,FUUID,*name" val:"*value"`
+ FBytes []byte
+ FBool bool
+ FInt8 int8
+ FInt16 int16
+ FInt32 int32
+ FInt int
+ FInt64 int64
+ FFloat32 float32
+ FFloat64 float64
+ FString string
+ FUUID UUID
+ Val string
+}
func buildMappingFromPtr(instance interface{}) (*structMapping, os.Error) {
valuePtr := reflect.ValueOf(instance)
@@ -72,10 +98,13 @@ func structMapMustError(t *testing.T, instance interface{}) {
}
}
-func TestStructMapping(t *testing.T) {
- var sampleInt int
- sampleIntT := reflect.TypeOf(sampleInt)
+func checkMapping(t *testing.T, expected, actual interface{}, name string) {
+ if !reflect.DeepEqual(expected, actual) {
+ t.Error("Mapping for struct sample", name, "does not match expected output")
+ }
+}
+func TestStructMapping(t *testing.T) {
structMapMustError(t, &errNoMeta{})
structMapMustError(t, &errNoMetaKeyColVal{})
structMapMustError(t, &errNoMetaColVal{})
@@ -87,77 +116,125 @@ func TestStructMapping(t *testing.T) {
mapA, _ := buildMappingFromPtr(&noErrA{1, 2, 3})
goodA := &structMapping{
cf: "cfname",
- key: &fieldMapping{fieldKind: baseTypeField, position: 0, name: "a", goType: sampleIntT, cassandraType: LongType},
+ key: &fieldMapping{fieldKind: baseTypeField, position: 0, name: "a", cassandraType: LongType},
columns: []*fieldMapping{
- &fieldMapping{fieldKind: baseTypeField, position: 1, name: "b", goType: sampleIntT, cassandraType: LongType},
+ &fieldMapping{fieldKind: baseTypeField, position: 1, name: "b", cassandraType: LongType},
},
- value: &fieldMapping{fieldKind: baseTypeField, position: 2, name: "c", goType: sampleIntT, cassandraType: LongType},
+ value: &fieldMapping{fieldKind: baseTypeField, position: 2, name: "c", cassandraType: LongType},
others: nil,
isCompositeColumn: false,
}
- if !reflect.DeepEqual(mapA, goodA) {
- t.Error("Mapping for struct sample A does not match expected output, ", mapA, " vs ", goodA)
- }
+ checkMapping(t, goodA, mapA, "mapA")
mapB, _ := buildMappingFromPtr(&noErrB{1, 2, 3})
goodB := &structMapping{
cf: "cfname",
- key: &fieldMapping{fieldKind: baseTypeField, position: 0, name: "a", goType: sampleIntT, cassandraType: LongType},
+ key: &fieldMapping{fieldKind: baseTypeField, position: 0, name: "a", cassandraType: LongType},
columns: []*fieldMapping{
- &fieldMapping{fieldKind: starNameField, position: 0, name: "", goType: nil, cassandraType: 0},
+ &fieldMapping{fieldKind: starNameField, position: 0, name: "", cassandraType: 0},
},
- value: &fieldMapping{fieldKind: starValueField, position: 0, name: "", goType: nil, cassandraType: 0},
+ value: &fieldMapping{fieldKind: starValueField, position: 0, name: "", cassandraType: 0},
others: map[string]*fieldMapping{
- "b": &fieldMapping{fieldKind: baseTypeField, position: 1, name: "b", goType: sampleIntT, cassandraType: LongType},
- "c": &fieldMapping{fieldKind: baseTypeField, position: 2, name: "c", goType: sampleIntT, cassandraType: LongType},
+ "b": &fieldMapping{fieldKind: baseTypeField, position: 1, name: "b", cassandraType: LongType},
+ "c": &fieldMapping{fieldKind: baseTypeField, position: 2, name: "c", cassandraType: LongType},
},
isCompositeColumn: false,
}
- if !reflect.DeepEqual(mapB, goodB) {
- t.Error("Mapping for struct sample B does not match expected output, ", mapB, " vs ", goodB)
- }
+ checkMapping(t, goodB, mapB, "mapB")
mapC, _ := buildMappingFromPtr(&noErrC{1, 2, 3})
goodC := &structMapping{
cf: "cfname",
- key: &fieldMapping{fieldKind: baseTypeField, position: 0, name: "a", goType: sampleIntT, cassandraType: LongType},
+ key: &fieldMapping{fieldKind: baseTypeField, position: 0, name: "a", cassandraType: LongType},
columns: []*fieldMapping{
- &fieldMapping{fieldKind: baseTypeField, position: 1, name: "b", goType: sampleIntT, cassandraType: LongType},
- &fieldMapping{fieldKind: starNameField, position: 0, name: "", goType: nil, cassandraType: 0},
+ &fieldMapping{fieldKind: baseTypeField, position: 1, name: "b", cassandraType: LongType},
+ &fieldMapping{fieldKind: starNameField, position: 0, name: "", cassandraType: 0},
},
- value: &fieldMapping{fieldKind: starValueField, position: 0, name: "", goType: nil, cassandraType: 0},
+ value: &fieldMapping{fieldKind: starValueField, position: 0, name: "", cassandraType: 0},
others: map[string]*fieldMapping{
- "c": &fieldMapping{fieldKind: baseTypeField, position: 2, name: "c", goType: sampleIntT, cassandraType: LongType},
+ "c": &fieldMapping{fieldKind: baseTypeField, position: 2, name: "c", cassandraType: LongType},
},
isCompositeColumn: true,
}
- if !reflect.DeepEqual(mapC, goodC) {
- t.Error("Mapping for struct sample C does not match expected output, ", mapC, " vs ", goodC)
- }
-}
-
-type timeline struct {
- UserId string `cf:"Timelines" key:"UserId" col:"TweetId,*name" val:"*value"`
- TweetId int
- Author string
- Body string
-}
-
-func TestMap(t *testing.T) {
-
- tweet := &timeline{UserId: "abc", TweetId: 3, Author: "xyz", Body: "hello world"}
+ checkMapping(t, goodC, mapC, "mapC")
- row, _ := Map(tweet)
+ mapD, _ := buildMappingFromPtr(&noErrD{1, []int{2, 3}, []int{4, 5}})
+ goodD := &structMapping{
+ cf: "cfname",
+ key: &fieldMapping{fieldKind: baseTypeField, position: 0, name: "a", cassandraType: LongType},
+ columns: []*fieldMapping{
+ &fieldMapping{fieldKind: baseTypeSliceField, position: 1, name: "b", cassandraType: LongType},
+ },
+ value: &fieldMapping{fieldKind: baseTypeSliceField, position: 2, name: "c", cassandraType: LongType},
+ others: nil,
+ isCompositeColumn: false,
+ }
+ checkMapping(t, goodD, mapD, "mapD")
- if len(row.Columns) != 2 {
- t.Error("Expected number of columns is 2, got ", len(row.Columns))
+ mapE, _ := buildMappingFromPtr(&noErrE{1, 2, []int{3, 4}, []int{5, 6}})
+ goodE := &structMapping{
+ cf: "cfname",
+ key: &fieldMapping{fieldKind: baseTypeField, position: 0, name: "a", cassandraType: LongType},
+ columns: []*fieldMapping{
+ &fieldMapping{fieldKind: baseTypeField, position: 1, name: "b", cassandraType: LongType},
+ &fieldMapping{fieldKind: baseTypeSliceField, position: 2, name: "c", cassandraType: LongType},
+ },
+ value: &fieldMapping{fieldKind: baseTypeSliceField, position: 3, name: "d", cassandraType: LongType},
+ others: nil,
+ isCompositeColumn: true,
}
+ checkMapping(t, goodE, mapE, "mapE")
- t.Log(row.Columns[0].Name)
- t.Log(row.Columns[0].Value)
- t.Log(row.Columns[1].Name)
- t.Log(row.Columns[1].Value)
+ eComp, _ := buildMappingFromPtr(&everythingComp{"a", []byte{1, 2}, true, 3, 4, 5, 6, 7, 8.0, 9.0, "b",
+ [16]byte{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}, "c"})
+ goodEComp := &structMapping{
+ cf: "cfname",
+ key: &fieldMapping{fieldKind: baseTypeField, position: 0, name: "Key", cassandraType: UTF8Type},
+ columns: []*fieldMapping{
+ &fieldMapping{fieldKind: baseTypeField, position: 1, name: "FBytes", cassandraType: BytesType},
+ &fieldMapping{fieldKind: baseTypeField, position: 2, name: "FBool", cassandraType: BooleanType},
+ &fieldMapping{fieldKind: baseTypeField, position: 3, name: "FInt8", cassandraType: LongType},
+ &fieldMapping{fieldKind: baseTypeField, position: 4, name: "FInt16", cassandraType: LongType},
+ &fieldMapping{fieldKind: baseTypeField, position: 5, name: "FInt32", cassandraType: LongType},
+ &fieldMapping{fieldKind: baseTypeField, position: 6, name: "FInt", cassandraType: LongType},
+ &fieldMapping{fieldKind: baseTypeField, position: 7, name: "FInt64", cassandraType: LongType},
+ &fieldMapping{fieldKind: baseTypeField, position: 8, name: "FFloat32", cassandraType: FloatType},
+ &fieldMapping{fieldKind: baseTypeField, position: 9, name: "FFloat64", cassandraType: DoubleType},
+ &fieldMapping{fieldKind: baseTypeField, position: 10, name: "FString", cassandraType: UTF8Type},
+ &fieldMapping{fieldKind: baseTypeField, position: 11, name: "FUUID", cassandraType: UUIDType},
+ &fieldMapping{fieldKind: starNameField, position: 0, name: "", cassandraType: 0},
+ },
+ value: &fieldMapping{fieldKind: starValueField, position: 0, name: "", cassandraType: 0},
+ others: map[string]*fieldMapping{
+ "Val": &fieldMapping{fieldKind: baseTypeField, position: 12, name: "Val", cassandraType: UTF8Type},
+ },
+ isCompositeColumn: true,
+ }
+ t.Log(goodEComp.key)
+ t.Log(eComp.key)
+ checkMapping(t, goodEComp, eComp, "eComp")
- //t.Fatal("heh")
+}
+func TestMap(t *testing.T) {
+ ec := &everythingComp{"a", []byte{1, 2}, true, 3, 4, 5, 6, 7, 8.0, 9.0, "b",
+ [16]byte{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}, "c"}
+ row, err := Map(ec)
+ if err != nil {
+ t.Fatal("Unexpected error in test map:", err)
+ }
+ if len(row.Columns) != 1 {
+ t.Error("Expected number of columns is 1, got ", len(row.Columns))
+ }
+ name := []byte{0, 2, 1, 2, 0, 0, 1, 1, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 8, 0, 0, 0,
+ 0, 0, 0, 0, 5, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 4, 65, 0, 0, 0, 0, 0,
+ 8, 64, 34, 0, 0, 0, 0, 0, 0, 0, 0, 1, 98, 0, 0, 16, 0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204,
+ 221, 238, 255, 0, 0, 3, 86, 97, 108, 0}
+ value := []byte{99}
+ if !reflect.DeepEqual(name, row.Columns[0].Name) {
+ t.Error("Invalid composite column name in for test row")
+ }
+ if !reflect.DeepEqual(value, row.Columns[0].Value) {
+ t.Error("Invalid value in test row")
+ }
}
View
10 src/gossie/types.go
@@ -641,3 +641,13 @@ func packComposite(current, component []byte, comparator, sliceStart, inclusive
r = append(r, component...)
return append(r, eoc)
}
+
+func unpackComposite(composite []byte) [][]byte {
+ components := make([][]byte, 0)
+ for len(composite) > 0 {
+ l := enc.BigEndian.Uint16(composite[:2])
+ components = append(components, composite[2:2+l])
+ composite = composite[3+l:]
+ }
+ return components
+}
Please sign in to comment.
Something went wrong with that request. Please try again.