Pārlūkot izejas kodu

added batch example

Christoph Hack 12 gadi atpakaļ
vecāks
revīzija
c0835a0a1e
9 mainītis faili ar 106 papildinājumiem un 49 dzēšanām
  1. 4 3
      cluster.go
  2. 5 15
      conn.go
  3. 2 2
      frame.go
  4. 0 24
      gocql.go
  5. 46 3
      gocql_test/main.go
  6. 17 2
      marshal.go
  7. 13 0
      marshal_test.go
  8. 15 0
      session.go
  9. 4 0
      topology.go

+ 4 - 3
cluster.go

@@ -24,7 +24,7 @@ type ClusterConfig struct {
 	Timeout      time.Duration
 	DefaultPort  int
 	Keyspace     string
-	NumConn      int
+	NumConns     int
 	NumStreams   int
 	DelayMin     time.Duration
 	DelayMax     time.Duration
@@ -38,7 +38,8 @@ func NewCluster(hosts ...string) *ClusterConfig {
 		ProtoVersion: 2,
 		Timeout:      200 * time.Millisecond,
 		DefaultPort:  9042,
-		NumConn:      2,
+		NumConns:     2,
+		NumStreams:   128,
 		DelayMin:     1 * time.Second,
 		DelayMax:     10 * time.Minute,
 		StartupMin:   len(hosts)/2 + 1,
@@ -82,7 +83,7 @@ func (c *clusterImpl) startup() {
 		if strings.IndexByte(addr, ':') < 0 {
 			addr = fmt.Sprintf("%s:%d", addr, c.cfg.DefaultPort)
 		}
-		for j := 0; j < c.cfg.NumConn; j++ {
+		for j := 0; j < c.cfg.NumConns; j++ {
 			go c.connect(addr)
 		}
 	}

+ 5 - 15
conn.go

@@ -45,9 +45,8 @@ type Conn struct {
 	prepMu sync.Mutex
 	prep   map[string]*queryInfo
 
-	cluster  Cluster
-	addr     string
-	keyspace string
+	cluster Cluster
+	addr    string
 }
 
 // Connect establishes a connection to a Cassandra node.
@@ -246,16 +245,6 @@ func (c *Conn) prepareStatement(stmt string) (*queryInfo, error) {
 	return info, nil
 }
 
-func (c *Conn) switchKeyspace(keyspace string) error {
-	if keyspace == "" || c.keyspace == keyspace {
-		return nil
-	}
-	if _, err := c.ExecuteQuery(&Query{Stmt: "USE " + keyspace}); err != nil {
-		return err
-	}
-	return nil
-}
-
 func (c *Conn) ExecuteQuery(qry *Query) (*Iter, error) {
 	frame, err := c.executeQuery(qry)
 	if err != nil {
@@ -280,7 +269,8 @@ func (c *Conn) ExecuteBatch(batch *Batch) error {
 		entry := &batch.Entries[i]
 		var info *queryInfo
 		if len(entry.Args) > 0 {
-			info, err := c.prepareStatement(entry.Stmt)
+			var err error
+			info, err = c.prepareStatement(entry.Stmt)
 			if err != nil {
 				return err
 			}
@@ -292,7 +282,7 @@ func (c *Conn) ExecuteBatch(batch *Batch) error {
 		}
 		frame.writeShort(uint16(len(entry.Args)))
 		for j := 0; j < len(entry.Args); j++ {
-			val, err := Marshal(info.args[j].TypeInfo, entry.Args[i])
+			val, err := Marshal(info.args[j].TypeInfo, entry.Args[j])
 			if err != nil {
 				return err
 			}

+ 2 - 2
frame.go

@@ -159,9 +159,9 @@ func (f *frame) readInt() int {
 	if len(*f) < 4 {
 		panic(ErrProtocol)
 	}
-	v := int((*f)[0])<<24 | int((*f)[1])<<16 | int((*f)[2])<<8 | int((*f)[3])
+	v := uint32((*f)[0])<<24 | uint32((*f)[1])<<16 | uint32((*f)[2])<<8 | uint32((*f)[3])
 	*f = (*f)[4:]
-	return v
+	return int(int32(v))
 }
 
 func (f *frame) readShort() uint16 {

+ 0 - 24
gocql.go

@@ -1,24 +0,0 @@
-// Copyright (c) 2012 The gocql Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package gocql
-
-import (
-	"errors"
-)
-
-type Error struct {
-	Code    int
-	Message string
-}
-
-func (e Error) Error() string {
-	return e.Message
-}
-
-var (
-	ErrNotFound        = errors.New("not found")
-	ErrNoHostAvailable = errors.New("no host available")
-	ErrProtocol        = errors.New("protocol error")
-)

+ 46 - 3
gocql_test/main.go

@@ -1,3 +1,7 @@
+// Copyright (c) 2012 The gocql Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
 package main
 
 import (
@@ -82,6 +86,12 @@ var pageTestData = []*Page{
 			"favicon": Attachment("favicon.ico"),
 		},
 	},
+	&Page{
+		Title:    "Foobar",
+		RevId:    uuid.TimeUUID(),
+		Body:     "foo::Foo f = new foo::Foo(foo::Foo::INIT);",
+		Modified: time.Date(2013, time.August, 13, 9, 52, 3, 0, time.UTC),
+	},
 }
 
 func insertTestData() error {
@@ -97,11 +107,26 @@ func insertTestData() error {
 	return nil
 }
 
+func insertBatch() error {
+	batch := gocql.NewBatch(gocql.LoggedBatch)
+	for _, page := range pageTestData {
+		batch.Query(`INSERT INTO page
+			(title, revid, body, views, protected, modified, tags, attachments)
+			VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
+			page.Title, page.RevId, page.Body, page.Views, page.Protected,
+			page.Modified, page.Tags, page.Attachments)
+	}
+	if err := session.ExecuteBatch(batch); err != nil {
+		return err
+	}
+	return nil
+}
+
 func getPage(title string, revid uuid.UUID) (*Page, error) {
 	p := new(Page)
 	err := session.Query(`SELECT title, revid, body, views, protected, modified,
-		tags, attachments
-		FROM page WHERE title = ? AND revid = ?`, title, revid).Scan(
+			tags, attachments
+			FROM page WHERE title = ? AND revid = ?`, title, revid).Scan(
 		&p.Title, &p.RevId, &p.Body, &p.Views, &p.Protected, &p.Modified,
 		&p.Tags, &p.Attachments)
 	return p, err
@@ -121,7 +146,7 @@ func main() {
 		log.Fatal("getCount: ", err)
 	}
 	if count != len(pageTestData) {
-		log.Println("count: expected %d, got %d", len(pageTestData), count)
+		log.Printf("count: expected %d, got %d", len(pageTestData), count)
 	}
 
 	for _, original := range pageTestData {
@@ -136,4 +161,22 @@ func main() {
 			log.Printf("page: expected %#v, got %#v\n", original, page)
 		}
 	}
+
+	for _, original := range pageTestData {
+		if err := session.Query("DELETE FROM page WHERE title = ? AND revid = ?",
+			original.Title, original.RevId).Exec(); err != nil {
+			log.Println("delete:", err)
+		}
+	}
+	if err := session.Query("SELECT COUNT(*) FROM page").Scan(&count); err != nil {
+		log.Fatal("getCount: ", err)
+	}
+	if count != 0 {
+		log.Printf("count: expected %d, got %d", len(pageTestData), count)
+	}
+
+	if err := insertBatch(); err != nil {
+		log.Fatal("insertBatch: ", err)
+	}
+
 }

+ 17 - 2
marshal.go

@@ -720,6 +720,9 @@ func marshalList(info *TypeInfo, value interface{}) ([]byte, error) {
 	k := t.Kind()
 	switch k {
 	case reflect.Slice, reflect.Array:
+		if k == reflect.Slice && rv.IsNil() {
+			return nil, nil
+		}
 		buf := &bytes.Buffer{}
 		n := rv.Len()
 		if n > math.MaxUint16 {
@@ -766,6 +769,13 @@ func unmarshalList(info *TypeInfo, data []byte, value interface{}) error {
 
 	switch k {
 	case reflect.Slice, reflect.Array:
+		if data == nil {
+			if k == reflect.Array {
+				return unmarshalErrorf("unmarshal list: can not store nil in array value")
+			}
+			rv.Set(reflect.Zero(t))
+			return nil
+		}
 		if len(data) < 2 {
 			return unmarshalErrorf("unmarshal list: unexpected eof")
 		}
@@ -803,6 +813,9 @@ func marshalMap(info *TypeInfo, value interface{}) ([]byte, error) {
 	if t.Kind() != reflect.Map {
 		return nil, marshalErrorf("can not marshal %T into %s", value, info)
 	}
+	if rv.IsNil() {
+		return nil, nil
+	}
 	buf := &bytes.Buffer{}
 	n := rv.Len()
 	if n > math.MaxUint16 {
@@ -841,14 +854,16 @@ func unmarshalMap(info *TypeInfo, data []byte, value interface{}) error {
 	rv := reflect.ValueOf(value)
 	if rv.Kind() != reflect.Ptr {
 		return unmarshalErrorf("can not unmarshal into non-pointer %T", value)
-
 	}
 	rv = rv.Elem()
 	t := rv.Type()
 	if t.Kind() != reflect.Map {
 		return unmarshalErrorf("can not unmarshal %s into %T", info, value)
 	}
-
+	if data == nil {
+		rv.Set(reflect.Zero(t))
+		return nil
+	}
 	rv.Set(reflect.MakeMap(t))
 	if len(data) < 2 {
 		return unmarshalErrorf("unmarshal map: unexpected eof")

+ 13 - 0
marshal_test.go

@@ -134,6 +134,11 @@ var marshalTests = []struct {
 		[]byte("\x00\x02\x00\x04\x00\x00\x00\x01\x00\x04\x00\x00\x00\x02"),
 		[]int{1, 2},
 	},
+	{
+		&TypeInfo{Type: TypeSet, Elem: &TypeInfo{Type: TypeInt}},
+		[]byte(nil),
+		[]int(nil),
+	},
 	{
 		&TypeInfo{Type: TypeMap,
 			Key:  &TypeInfo{Type: TypeVarchar},
@@ -142,6 +147,14 @@ var marshalTests = []struct {
 		[]byte("\x00\x01\x00\x03foo\x00\x04\x00\x00\x00\x01"),
 		map[string]int{"foo": 1},
 	},
+	{
+		&TypeInfo{Type: TypeMap,
+			Key:  &TypeInfo{Type: TypeVarchar},
+			Elem: &TypeInfo{Type: TypeInt},
+		},
+		[]byte(nil),
+		map[string]int(nil),
+	},
 }
 
 func TestMarshal(t *testing.T) {

+ 15 - 0
session.go

@@ -247,3 +247,18 @@ type ColumnInfo struct {
 	Name     string
 	TypeInfo *TypeInfo
 }
+
+type Error struct {
+	Code    int
+	Message string
+}
+
+func (e Error) Error() string {
+	return e.Message
+}
+
+var (
+	ErrNotFound        = errors.New("not found")
+	ErrNoHostAvailable = errors.New("no host available")
+	ErrProtocol        = errors.New("protocol error")
+)

+ 4 - 0
topology.go

@@ -1,3 +1,7 @@
+// Copyright (c) 2012 The gocql Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
 package gocql
 
 import (