Skip to content

Commit 916b031

Browse files
committed
Merge branch 'release/v0.3'
2 parents b106bed + 2dd7eae commit 916b031

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+1696
-1732
lines changed

CHANGELOG.md

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,18 @@
11
# Changelog
22

3-
## v0.2 (RethinkDB v1.12) - 13 April
3+
## v0.3 (RethinkDB v1.13) - 26 June 2014
4+
5+
- Replaced `ResultRows`/`ResultRow` with `Cursor`, `Cursor` has the `Next`, `All` and `One` methods which stores the relevant value in the value pointed at by result. For more information check the examples.
6+
- Changed the time constants (Days and Months) to package globals instead of functions
7+
- Added the `Args` term and changed the arguments for many terms to `args ...interface{}` to allow argument splicing
8+
- Added the `Changes` term and support for the feed response type
9+
- Added the `Random` term
10+
- Added the `Http` term
11+
- The second argument for `Slice` is now optional
12+
- `EqJoin` now accepts a function as its first argument
13+
- `Nth` now returns a selection
14+
15+
## v0.2 (RethinkDB v1.12) - 13 April 2014
416

517
* Changed `Connect` to use `ConnectOpts` instead of `map[string]interface{}`
618
* Migrated to new `Group`/`Ungroup` functions, these replace `GroupedMapReduce` and `GroupBy`
@@ -13,8 +25,8 @@
1325

1426
## v0.1 (RethinkDB v1.11) - 27 November 2013
1527

16-
* Added noreply writes
17-
* Added the new terms `index_status`, `index_wait` and `sync`
18-
* Added the profile flag to the run functions
19-
* Optional arguments are now structs instead of key, pair strings. Almost all of the struct fields are of type interface{} as they can have terms inside them. For example: `r.TableCreateOpts{ PrimaryKey: r.Expr("index") }`
20-
* Returned arrays are now properly loaded into ResultRows. In the past when running `r.Expr([]interface{}{1,2,3})` would require you to use `RunRow` followed by `Scan`. You can now use `Run` followed by `ScanAll`
28+
* Added noreply writes
29+
* Added the new terms `index_status`, `index_wait` and `sync`
30+
* Added the profile flag to the run functions
31+
* Optional arguments are now structs instead of key, pair strings. Almost all of the struct fields are of type interface{} as they can have terms inside them. For example: `r.TableCreateOpts{ PrimaryKey: r.Expr("index") }`
32+
* Returned arrays are now properly loaded into ResultRows. In the past when running `r.Expr([]interface{}{1,2,3})` would require you to use `RunRow` followed by `Scan`. You can now use `Run` followed by `ScanAll`

README.md

Lines changed: 44 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ GoRethink - RethinkDB Driver for Go [![wercker status](https://app.wercker.com/s
33

44
[Go](http://golang.org/) driver for [RethinkDB](http://www.rethinkdb.com/) made by [Daniel Cannon](http://github.com/dancannon) and based off of Christopher Hesse's [RethinkGo](https://github.com/christopherhesse/rethinkgo) driver.
55

6-
Current version: v0.2.1 (RethinkDB v1.12)
76

8-
**Version 0.2 introduced some BC breaking changes, for more information check the [change log](CHANGELOG.md)**
7+
Current version: v0.3 (RethinkDB v1.13)
8+
9+
**Version 0.3 introduced some API changes, for more information check the [change log](CHANGELOG.md)**
910

1011
## Installation
1112

@@ -67,36 +68,36 @@ A pre-configured [Pool](http://godoc.org/github.com/dancannon/gorethink#Pool) in
6768

6869
This library is based on the official drivers so the code on the [API](http://www.rethinkdb.com/api/) page should require very few changes to work.
6970

70-
To view full documentation for the query functions check the [GoDoc](http://godoc.org/github.com/dancannon/gorethink#RqlTerm)
71+
To view full documentation for the query functions check the [GoDoc](http://godoc.org/github.com/dancannon/gorethink#Term)
7172

7273
Slice Expr Example
7374
```go
74-
r.Expr([]interface{}{1, 2, 3, 4, 5}).RunRow(conn)
75+
r.Expr([]interface{}{1, 2, 3, 4, 5}).Run(session)
7576
```
7677
Map Expr Example
7778
```go
78-
r.Expr(map[string]interface{}{"a": 1, "b": 2, "c": 3}).RunRow(conn)
79+
r.Expr(map[string]interface{}{"a": 1, "b": 2, "c": 3}).Run(session)
7980
```
8081
Get Example
8182
```go
82-
r.Db("database").Table("table").Get("GUID").RunRow(conn)
83+
r.Db("database").Table("table").Get("GUID").Run(session)
8384
```
8485
Map Example (Func)
8586
```go
86-
r.Expr([]interface{}{1, 2, 3, 4, 5}).Map(func (row RqlTerm) RqlTerm {
87+
r.Expr([]interface{}{1, 2, 3, 4, 5}).Map(func (row Term) interface{} {
8788
return row.Add(1)
88-
}).Run(conn)
89+
}).Run(session)
8990
```
9091
Map Example (Implicit)
9192
```go
92-
r.Expr([]interface{}{1, 2, 3, 4, 5}).Map(r.Row.Add(1)).Run(conn)
93+
r.Expr([]interface{}{1, 2, 3, 4, 5}).Map(r.Row.Add(1)).Run(session)
9394
```
9495
Between (Optional Args) Example
9596
```go
9697
r.Db("database").Table("table").Between(1, 10, r.BetweenOpts{
9798
Index: "num",
9899
RightBound: "closed",
99-
}).Run(conn)
100+
}).Run(session)
100101
```
101102

102103

@@ -108,42 +109,54 @@ As shown above in the Between example optional arguments are passed to the funct
108109

109110
Different result types are returned depending on what function is used to execute the query.
110111

111-
- Run returns a ResultRows type which can be used to view
112+
- `Run` returns a cursor which can be used to view
112113
all rows returned.
113-
- RunRow returns a single row and can be used for queries such as Get where only a single row should be returned(or none).
114-
- RunWrite returns a ResultRow scanned into WriteResponse and should be used for queries such as Insert,Update,etc...
115-
- Exec sends a query to the server with the noreply flag set and returns immediately
116-
117-
Both ResultRows and ResultRow have the function `Scan` which is used to bind a row to a variable.
114+
- `RunWrite` returns a WriteResponse and should be used for queries such as Insert,Update,etc...
115+
- `Exec` sends a query to the server with the noreply flag set and returns immediately
118116

119117
Example:
120118

121119
```go
122-
row, err := Table("tablename").Get(key).RunRow(conn)
120+
res, err := Table("tablename").Get(key).Run(session)
123121
if err != nil {
124-
// error
125-
}
126-
// Check if something was found
127-
if !row.IsNil() {
128-
var response interface{}
129-
err := row.Scan(&response)
122+
// error
130123
}
131124
```
132125

133-
ResultRows also has the function `Next` which is used to iterate through a result set. If a partial sequence is returned by the server Next will automatically fetch the result of the sequence.
126+
Cursors have a number of methods available for accessing the query results
134127

135-
Example:
128+
- `Next` retrieves the next document from the result set, blocking if necessary.
129+
- `All` retrieves all documents from the result set into the provided slice.
130+
- `One` retrieves the first document from the result se.
131+
132+
Examples:
133+
134+
```go
135+
var row interface{}
136+
for res.Next(&result) {
137+
// Do something with row
138+
}
139+
if res.Err() != nil {
140+
// error
141+
}
142+
```
136143

137144
```go
138-
rows, err := Table("tablename").Run(conn)
145+
var rows []interface{}
146+
err := res.All(&rows)
139147
if err != nil {
140-
// error
148+
// error
141149
}
142-
for rows.Next() {
143-
var row interface{}
144-
err := rows.Scan(&row)
150+
```
145151

146-
// Do something with row
152+
```go
153+
var row interface{}
154+
err := res.One(&row)
155+
if err == r.ErrEmptyResult {
156+
// row not found
157+
}
158+
if err != nil {
159+
// error
147160
}
148161
```
149162

connection.go

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import (
1313
)
1414

1515
type Conn interface {
16-
SendQuery(s *Session, q *p.Query, t RqlTerm, opts map[string]interface{}, async bool) (*ResultRows, error)
16+
SendQuery(s *Session, q *p.Query, t Term, opts map[string]interface{}, async bool) (*Cursor, error)
1717
ReadResponse(s *Session, token int64) (*p.Response, error)
1818
Close() error
1919
}
@@ -27,23 +27,33 @@ type Connection struct {
2727
closed bool
2828
}
2929

30-
// Reconnect closes the previous connection and attempts to connect again.
30+
// Dial closes the previous connection and attempts to connect again.
3131
func Dial(s *Session) (*Connection, error) {
3232
conn, err := net.Dial("tcp", s.address)
3333
if err != nil {
3434
return nil, RqlConnectionError{err.Error()}
3535
}
3636

37-
if err := binary.Write(conn, binary.LittleEndian, p.VersionDummy_V0_2); err != nil {
37+
// Send the protocol version to the server as a 4-byte little-endian-encoded integer
38+
if err := binary.Write(conn, binary.LittleEndian, p.VersionDummy_V0_3); err != nil {
3839
return nil, RqlConnectionError{err.Error()}
3940
}
4041

41-
// authorization key
42+
// Send the length of the auth key to the server as a 4-byte little-endian-encoded integer
4243
if err := binary.Write(conn, binary.LittleEndian, uint32(len(s.authkey))); err != nil {
4344
return nil, RqlConnectionError{err.Error()}
4445
}
4546

46-
if err := binary.Write(conn, binary.BigEndian, []byte(s.authkey)); err != nil {
47+
// Send the auth key as an ASCII string
48+
// If there is no auth key, skip this step
49+
if s.authkey != "" {
50+
if _, err := io.WriteString(conn, s.authkey); err != nil {
51+
return nil, RqlConnectionError{err.Error()}
52+
}
53+
}
54+
55+
// Send the protocol type as a 4-byte little-endian-encoded integer
56+
if err := binary.Write(conn, binary.LittleEndian, p.VersionDummy_PROTOBUF); err != nil {
4757
return nil, RqlConnectionError{err.Error()}
4858
}
4959

@@ -111,7 +121,7 @@ func (c *Connection) ReadResponse(s *Session, token int64) (*p.Response, error)
111121
}
112122
}
113123

114-
func (c *Connection) SendQuery(s *Session, q *p.Query, t RqlTerm, opts map[string]interface{}, async bool) (*ResultRows, error) {
124+
func (c *Connection) SendQuery(s *Session, q *p.Query, t Term, opts map[string]interface{}, async bool) (*Cursor, error) {
115125
var data []byte
116126
var err error
117127

@@ -170,24 +180,26 @@ func (c *Connection) SendQuery(s *Session, q *p.Query, t RqlTerm, opts map[strin
170180
}
171181
}
172182

173-
// De-construct datum and return the result
183+
// De-construct datum and return a cursor
174184
switch response.GetType() {
175-
case p.Response_SUCCESS_PARTIAL, p.Response_SUCCESS_SEQUENCE:
176-
result := &ResultRows{
185+
case p.Response_SUCCESS_PARTIAL, p.Response_SUCCESS_SEQUENCE, p.Response_SUCCESS_FEED:
186+
cursor := &Cursor{
177187
session: s,
178188
query: q,
179189
term: t,
180190
opts: opts,
181191
profile: profile,
192+
timeout: -1,
182193
}
194+
cursor.gotReply.L = &cursor.mu
183195

184196
s.Lock()
185-
s.cache[*q.Token] = result
197+
s.cache[*q.Token] = cursor
186198
s.Unlock()
187199

188-
result.extend(response)
200+
cursor.extend(response)
189201

190-
return result, nil
202+
return cursor, nil
191203
case p.Response_SUCCESS_ATOM:
192204
var value []interface{}
193205
var err error
@@ -216,15 +228,19 @@ func (c *Connection) SendQuery(s *Session, q *p.Query, t RqlTerm, opts map[strin
216228
}
217229
}
218230

219-
return &ResultRows{
231+
cursor := &Cursor{
220232
session: s,
221233
query: q,
222234
term: t,
223235
opts: opts,
224236
profile: profile,
225237
buffer: value,
226238
finished: true,
227-
}, nil
239+
timeout: -1,
240+
}
241+
cursor.gotReply.L = &cursor.mu
242+
243+
return cursor, nil
228244
case p.Response_WAIT_COMPLETE:
229245
return nil, nil
230246
default:
@@ -237,7 +253,7 @@ func (c *Connection) Close() error {
237253
return c.Conn.Close()
238254
}
239255

240-
func checkErrorResponse(response *p.Response, t RqlTerm) error {
256+
func checkErrorResponse(response *p.Response, t Term) error {
241257
switch response.GetType() {
242258
case p.Response_CLIENT_ERROR:
243259
return RqlClientError{rqlResponseError{response, t}}

datum.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import (
1111

1212
// Converts a query term to a datum. If the term cannot be converted to a datum
1313
// object then the function panics.
14-
func constructDatum(t RqlTerm) (*p.Term, error) {
14+
func constructDatum(t Term) (*p.Term, error) {
1515
if t.data == nil {
1616
return &p.Term{
1717
Type: p.Term_DATUM.Enum(),

doc.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Go driver for RethinkDB
22
//
3-
// Current version: v0.2.1 (RethinkDB v1.12)
3+
// Current version: v0.3 (RethinkDB v1.13)
44
// For more in depth information on how to use RethinkDB check out the API docs
55
// at http://rethinkdb.com/api
66
package gorethink

errors.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@ package gorethink
22

33
import (
44
"bytes"
5+
"errors"
56
"fmt"
67

78
p "github.com/dancannon/gorethink/ql2"
89
)
910

10-
func printCarrots(t RqlTerm, frames []*p.Frame) string {
11+
func printCarrots(t Term, frames []*p.Frame) string {
1112
var frame *p.Frame
1213
if len(frames) > 1 {
1314
frame, frames = frames[0], frames[1:]
@@ -17,7 +18,7 @@ func printCarrots(t RqlTerm, frames []*p.Frame) string {
1718

1819
for i, arg := range t.args {
1920
if frame.GetPos() == int64(i) {
20-
t.args[i] = RqlTerm{
21+
t.args[i] = Term{
2122
termType: p.Term_DATUM,
2223
data: printCarrots(arg, frames),
2324
}
@@ -26,7 +27,7 @@ func printCarrots(t RqlTerm, frames []*p.Frame) string {
2627

2728
for k, arg := range t.optArgs {
2829
if frame.GetOpt() == k {
29-
t.optArgs[k] = RqlTerm{
30+
t.optArgs[k] = Term{
3031
termType: p.Term_DATUM,
3132
data: printCarrots(arg, frames),
3233
}
@@ -45,11 +46,14 @@ func printCarrots(t RqlTerm, frames []*p.Frame) string {
4546
return b.String()
4647
}
4748

49+
// Error constants
50+
var ErrEmptyResult = errors.New("The result does not contain any more rows")
51+
4852
// Connection/Response errors
49-
// ----------------------------------------------------------------------------
53+
5054
type rqlResponseError struct {
5155
response *p.Response
52-
term RqlTerm
56+
term Term
5357
}
5458

5559
func (e rqlResponseError) Error() string {

0 commit comments

Comments
 (0)