This repository has been archived by the owner on May 11, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
cursor.go
97 lines (81 loc) · 1.96 KB
/
cursor.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
// Copyright 2010, Evan Shaw. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package mongo
import (
"bytes"
"encoding/binary"
"os"
"github.com/edsrzf/go-bson"
)
// A Cursor is the result of a query.
type Cursor struct {
collection *Collection
id int64
pos int
docs []bson.Doc
}
// Peek returns the next document or nil if the Cursor is at the end.
func (c *Cursor) Peek() bson.Doc {
if !c.HasNext() {
return nil
}
return c.docs[c.pos]
}
// Next is like Peek, but also iterates to the next document.
func (c *Cursor) Next() bson.Doc {
if !c.HasNext() {
return nil
}
doc := c.docs[c.pos]
c.pos++
return doc
}
// HasNext indicates whether the Cursor still has more documents to iterate through.
func (c *Cursor) HasNext() bool {
if c.pos < len(c.docs) {
return true
}
if err := c.getMore(0); err != nil {
return false
}
return c.pos < len(c.docs)
}
func (c *Cursor) getMore(limit int32) os.Error {
if c.id == 0 {
return os.NewError("no cursorID")
}
cap := headerSize + 4 + len(c.collection.fullName) + 4 + 8
payload := make([]byte, headerSize+4, cap)
buf := bytes.NewBuffer(payload)
buf.Write(c.collection.fullName)
binary.Write(buf, order, limit)
binary.Write(buf, order, c.id)
payload = payload[:cap]
conn := c.collection.db.conn
if err := conn.sendMessage(2005, 0, payload); err != nil {
return err
}
reply, err := conn.readReply()
if err != nil {
return err
}
c.pos = 0
c.docs = reply.docs
return nil
}
// Close tells the server that c is no longer in use and makes c invalid.
func (c *Cursor) Close() os.Error {
if c.id == 0 {
// not open on server
return nil
}
cap := headerSize + 16
payload := make([]byte, headerSize+4, cap)
buf := bytes.NewBuffer(payload)
binary.Write(buf, order, int32(1))
binary.Write(buf, order, c.id)
payload = payload[:cap]
c.id = 0
return c.collection.db.conn.sendMessage(2007, 0, payload)
}