mirror of
https://github.com/docker/docs.git
synced 2026-10-28 07:15:09 +03:00
Update RethinkDB to 2.3.0, gorethink to v2
Signed-off-by: Riyaz Faizullabhoy <riyaz.faizullabhoy@docker.com>
This commit is contained in:
27
Godeps/Godeps.json
generated
27
Godeps/Godeps.json
generated
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"ImportPath": "github.com/docker/notary",
|
||||
"GoVersion": "go1.6.1",
|
||||
"GoVersion": "go1.6",
|
||||
"GodepVersion": "v62",
|
||||
"Packages": [
|
||||
"./..."
|
||||
],
|
||||
@@ -180,24 +181,24 @@
|
||||
"Rev": "71acacd42f85e5e82f70a55327789582a5200a90"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/dancannon/gorethink",
|
||||
"Comment": "v1.4.0",
|
||||
"Rev": "ef48c048b4f1f4d923de4197e78c1b206c14fa4c"
|
||||
"ImportPath": "gopkg.in/dancannon/gorethink.v2",
|
||||
"Comment": "v2.0.0",
|
||||
"Rev": "ad28ba0b1cbf0aa5bbae1ea71941564cc08abfe4"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/dancannon/gorethink/encoding",
|
||||
"Comment": "v1.4.0",
|
||||
"Rev": "ef48c048b4f1f4d923de4197e78c1b206c14fa4c"
|
||||
"ImportPath": "gopkg.in/dancannon/gorethink.v2/encoding",
|
||||
"Comment": "v2.0.0",
|
||||
"Rev": "ad28ba0b1cbf0aa5bbae1ea71941564cc08abfe4"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/dancannon/gorethink/ql2",
|
||||
"Comment": "v1.4.0",
|
||||
"Rev": "ef48c048b4f1f4d923de4197e78c1b206c14fa4c"
|
||||
"ImportPath": "gopkg.in/dancannon/gorethink.v2/ql2",
|
||||
"Comment": "v2.0.0",
|
||||
"Rev": "ad28ba0b1cbf0aa5bbae1ea71941564cc08abfe4"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/dancannon/gorethink/types",
|
||||
"Comment": "v1.4.0",
|
||||
"Rev": "ef48c048b4f1f4d923de4197e78c1b206c14fa4c"
|
||||
"ImportPath": "gopkg.in/dancannon/gorethink.v2/types",
|
||||
"Comment": "v2.0.0",
|
||||
"Rev": "ad28ba0b1cbf0aa5bbae1ea71941564cc08abfe4"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/denisenkom/go-mssqldb",
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/dancannon/gorethink"
|
||||
_ "github.com/docker/distribution/registry/auth/htpasswd"
|
||||
_ "github.com/docker/distribution/registry/auth/token"
|
||||
"github.com/docker/go-connections/tlsconfig"
|
||||
@@ -22,6 +21,7 @@ import (
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/spf13/viper"
|
||||
"golang.org/x/net/context"
|
||||
"gopkg.in/dancannon/gorethink.v2"
|
||||
)
|
||||
|
||||
// get the address for the HTTP server, and parses the optional TLS
|
||||
|
||||
@@ -14,7 +14,6 @@ import (
|
||||
"google.golang.org/grpc/credentials"
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/dancannon/gorethink"
|
||||
"github.com/docker/distribution/health"
|
||||
"github.com/docker/notary"
|
||||
"github.com/docker/notary/cryptoservice"
|
||||
@@ -29,6 +28,7 @@ import (
|
||||
"github.com/docker/notary/tuf/data"
|
||||
"github.com/docker/notary/utils"
|
||||
"github.com/spf13/viper"
|
||||
"gopkg.in/dancannon/gorethink.v2"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -39,7 +39,7 @@ services:
|
||||
depends_on:
|
||||
- rdb-proxy
|
||||
rdb-01:
|
||||
image: jlhawn/rethinkdb-tls
|
||||
image: jlhawn/rethinkdb:2.3.0
|
||||
volumes:
|
||||
- ./fixtures/rethinkdb:/tls
|
||||
- rdb-01-data:/var/data
|
||||
@@ -49,9 +49,9 @@ services:
|
||||
- rdb
|
||||
- rdb.rdb
|
||||
- rdb-01.rdb
|
||||
command: "--bind all --no-http-admin --server-name rdb_01 --canonical-address rdb-01.rdb --directory /var/data/rethinkdb --join rdb.rdb --driver-tls --driver-tls-key /tls/key.pem --driver-tls-cert /tls/cert.pem --cluster-tls --cluster-tls-key /tls/key.pem --cluster-tls-cert /tls/cert.pem --cluster-tls-ca /tls/ca.pem"
|
||||
command: "--bind all --no-http-admin --server-name rdb_01 --canonical-address rdb-01.rdb --directory /var/data/rethinkdb --join rdb.rdb --driver-tls-key /tls/key.pem --driver-tls-cert /tls/cert.pem --cluster-tls-key /tls/key.pem --cluster-tls-cert /tls/cert.pem --cluster-tls-ca /tls/ca.pem"
|
||||
rdb-02:
|
||||
image: jlhawn/rethinkdb-tls
|
||||
image: jlhawn/rethinkdb:2.3.0
|
||||
volumes:
|
||||
- ./fixtures/rethinkdb:/tls
|
||||
- rdb-02-data:/var/data
|
||||
@@ -61,9 +61,9 @@ services:
|
||||
- rdb
|
||||
- rdb.rdb
|
||||
- rdb-02.rdb
|
||||
command: "--bind all --no-http-admin --server-name rdb_02 --canonical-address rdb-02.rdb --directory /var/data/rethinkdb --join rdb.rdb --driver-tls --driver-tls-key /tls/key.pem --driver-tls-cert /tls/cert.pem --cluster-tls --cluster-tls-key /tls/key.pem --cluster-tls-cert /tls/cert.pem --cluster-tls-ca /tls/ca.pem"
|
||||
command: "--bind all --no-http-admin --server-name rdb_02 --canonical-address rdb-02.rdb --directory /var/data/rethinkdb --join rdb.rdb --driver-tls-key /tls/key.pem --driver-tls-cert /tls/cert.pem --cluster-tls-key /tls/key.pem --cluster-tls-cert /tls/cert.pem --cluster-tls-ca /tls/ca.pem"
|
||||
rdb-03:
|
||||
image: jlhawn/rethinkdb-tls
|
||||
image: jlhawn/rethinkdb:2.3.0
|
||||
volumes:
|
||||
- ./fixtures/rethinkdb:/tls
|
||||
- rdb-03-data:/var/data
|
||||
@@ -73,9 +73,9 @@ services:
|
||||
- rdb
|
||||
- rdb.rdb
|
||||
- rdb-03.rdb
|
||||
command: "--bind all --no-http-admin --server-name rdb_03 --canonical-address rdb-03.rdb --directory /var/data/rethinkdb --join rdb.rdb --driver-tls --driver-tls-key /tls/key.pem --driver-tls-cert /tls/cert.pem --cluster-tls --cluster-tls-key /tls/key.pem --cluster-tls-cert /tls/cert.pem --cluster-tls-ca /tls/ca.pem"
|
||||
command: "--bind all --no-http-admin --server-name rdb_03 --canonical-address rdb-03.rdb --directory /var/data/rethinkdb --join rdb.rdb --driver-tls-key /tls/key.pem --driver-tls-cert /tls/cert.pem --cluster-tls-key /tls/key.pem --cluster-tls-cert /tls/cert.pem --cluster-tls-ca /tls/ca.pem"
|
||||
rdb-proxy:
|
||||
image: jlhawn/rethinkdb-tls
|
||||
image: jlhawn/rethinkdb:2.3.0
|
||||
ports:
|
||||
- "8080:8080"
|
||||
volumes:
|
||||
@@ -85,7 +85,7 @@ services:
|
||||
aliases:
|
||||
- rdb-proxy
|
||||
- rdb-proxy.rdp
|
||||
command: "proxy --bind all --join rdb.rdb --web-tls --web-tls-key /tls/key.pem --web-tls-cert /tls/cert.pem --driver-tls --driver-tls-key /tls/key.pem --driver-tls-cert /tls/cert.pem --cluster-tls --cluster-tls-key /tls/key.pem --cluster-tls-cert /tls/cert.pem --cluster-tls-ca /tls/ca.pem"
|
||||
command: "proxy --bind all --join rdb.rdb --driver-tls-key /tls/key.pem --driver-tls-cert /tls/cert.pem --cluster-tls-key /tls/key.pem --cluster-tls-cert /tls/cert.pem --cluster-tls-ca /tls/ca.pem"
|
||||
depends_on:
|
||||
- rdb-01
|
||||
- rdb-02
|
||||
|
||||
@@ -39,7 +39,7 @@ services:
|
||||
depends_on:
|
||||
- rdb-proxy
|
||||
rdb-01:
|
||||
image: jlhawn/rethinkdb-tls
|
||||
image: jlhawn/rethinkdb:2.3.0
|
||||
volumes:
|
||||
- ./fixtures/rethinkdb:/tls
|
||||
- rdb-01-data:/var/data
|
||||
@@ -49,9 +49,9 @@ services:
|
||||
- rdb
|
||||
- rdb.rdb
|
||||
- rdb-01.rdb
|
||||
command: "--bind all --no-http-admin --server-name rdb_01 --canonical-address rdb-01.rdb --directory /var/data/rethinkdb --join rdb.rdb --driver-tls --driver-tls-key /tls/key.pem --driver-tls-cert /tls/cert.pem --cluster-tls --cluster-tls-key /tls/key.pem --cluster-tls-cert /tls/cert.pem --cluster-tls-ca /tls/ca.pem"
|
||||
command: "--bind all --no-http-admin --server-name rdb_01 --canonical-address rdb-01.rdb --directory /var/data/rethinkdb --join rdb.rdb --driver-tls-key /tls/key.pem --driver-tls-cert /tls/cert.pem --cluster-tls-key /tls/key.pem --cluster-tls-cert /tls/cert.pem --cluster-tls-ca /tls/ca.pem"
|
||||
rdb-02:
|
||||
image: jlhawn/rethinkdb-tls
|
||||
image: jlhawn/rethinkdb:2.3.0
|
||||
volumes:
|
||||
- ./fixtures/rethinkdb:/tls
|
||||
- rdb-02-data:/var/data
|
||||
@@ -61,9 +61,9 @@ services:
|
||||
- rdb
|
||||
- rdb.rdb
|
||||
- rdb-02.rdb
|
||||
command: "--bind all --no-http-admin --server-name rdb_02 --canonical-address rdb-02.rdb --directory /var/data/rethinkdb --join rdb.rdb --driver-tls --driver-tls-key /tls/key.pem --driver-tls-cert /tls/cert.pem --cluster-tls --cluster-tls-key /tls/key.pem --cluster-tls-cert /tls/cert.pem --cluster-tls-ca /tls/ca.pem"
|
||||
command: "--bind all --no-http-admin --server-name rdb_02 --canonical-address rdb-02.rdb --directory /var/data/rethinkdb --join rdb.rdb --driver-tls-key /tls/key.pem --driver-tls-cert /tls/cert.pem --cluster-tls-key /tls/key.pem --cluster-tls-cert /tls/cert.pem --cluster-tls-ca /tls/ca.pem"
|
||||
rdb-03:
|
||||
image: jlhawn/rethinkdb-tls
|
||||
image: jlhawn/rethinkdb:2.3.0
|
||||
volumes:
|
||||
- ./fixtures/rethinkdb:/tls
|
||||
- rdb-03-data:/var/data
|
||||
@@ -73,9 +73,9 @@ services:
|
||||
- rdb
|
||||
- rdb.rdb
|
||||
- rdb-03.rdb
|
||||
command: "--bind all --no-http-admin --server-name rdb_03 --canonical-address rdb-03.rdb --directory /var/data/rethinkdb --join rdb.rdb --driver-tls --driver-tls-key /tls/key.pem --driver-tls-cert /tls/cert.pem --cluster-tls --cluster-tls-key /tls/key.pem --cluster-tls-cert /tls/cert.pem --cluster-tls-ca /tls/ca.pem"
|
||||
command: "--bind all --no-http-admin --server-name rdb_03 --canonical-address rdb-03.rdb --directory /var/data/rethinkdb --join rdb.rdb --driver-tls-key /tls/key.pem --driver-tls-cert /tls/cert.pem --cluster-tls-key /tls/key.pem --cluster-tls-cert /tls/cert.pem --cluster-tls-ca /tls/ca.pem"
|
||||
rdb-proxy:
|
||||
image: jlhawn/rethinkdb-tls
|
||||
image: jlhawn/rethinkdb:2.3.0
|
||||
ports:
|
||||
- "8080:8080"
|
||||
volumes:
|
||||
@@ -85,7 +85,7 @@ services:
|
||||
aliases:
|
||||
- rdb-proxy
|
||||
- rdb-proxy.rdp
|
||||
command: "proxy --bind all --join rdb.rdb --web-tls --web-tls-key /tls/key.pem --web-tls-cert /tls/cert.pem --driver-tls --driver-tls-key /tls/key.pem --driver-tls-cert /tls/cert.pem --cluster-tls --cluster-tls-key /tls/key.pem --cluster-tls-cert /tls/cert.pem --cluster-tls-ca /tls/ca.pem"
|
||||
command: "proxy --bind all --join rdb.rdb --driver-tls-key /tls/key.pem --driver-tls-cert /tls/cert.pem --cluster-tls-key /tls/key.pem --cluster-tls-cert /tls/cert.pem --cluster-tls-ca /tls/ca.pem"
|
||||
depends_on:
|
||||
- rdb-01
|
||||
- rdb-02
|
||||
|
||||
@@ -7,9 +7,9 @@ import (
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"github.com/dancannon/gorethink"
|
||||
"github.com/docker/notary/storage/rethinkdb"
|
||||
"github.com/docker/notary/tuf/data"
|
||||
"gopkg.in/dancannon/gorethink.v2"
|
||||
)
|
||||
|
||||
// RDBTUFFile is a tuf file record
|
||||
|
||||
@@ -6,13 +6,13 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/dancannon/gorethink"
|
||||
"github.com/docker/notary/passphrase"
|
||||
"github.com/docker/notary/storage/rethinkdb"
|
||||
"github.com/docker/notary/trustmanager"
|
||||
"github.com/docker/notary/tuf/data"
|
||||
"github.com/docker/notary/tuf/utils"
|
||||
jose "github.com/dvsekhvalnov/jose2go"
|
||||
"gopkg.in/dancannon/gorethink.v2"
|
||||
)
|
||||
|
||||
// RethinkDBKeyStore persists and manages private keys on a RethinkDB database
|
||||
|
||||
@@ -4,7 +4,8 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/dancannon/gorethink"
|
||||
"github.com/Sirupsen/logrus"
|
||||
"gopkg.in/dancannon/gorethink.v2"
|
||||
)
|
||||
|
||||
func makeDB(session *gorethink.Session, name string) error {
|
||||
@@ -16,7 +17,6 @@ func makeDB(session *gorethink.Session, name string) error {
|
||||
|
||||
return err
|
||||
}
|
||||
// Note: Wait() not supported by RethinkDB 2.3+
|
||||
resp, err := gorethink.DB(name).Wait().Run(session)
|
||||
if resp != nil {
|
||||
resp.Close()
|
||||
@@ -41,7 +41,6 @@ func (t Table) term(dbName string) gorethink.Term {
|
||||
}
|
||||
|
||||
func (t Table) wait(session *gorethink.Session, dbName string) error {
|
||||
// Note: Wait() not supported by RethinkDB 2.3+
|
||||
resp, err := t.term(dbName).Wait().Run(session)
|
||||
|
||||
if resp != nil {
|
||||
@@ -58,6 +57,7 @@ func (t Table) create(session *gorethink.Session, dbName string, numReplicas uin
|
||||
}
|
||||
|
||||
if _, err := gorethink.DB(dbName).TableCreate(t.Name, createOpts).RunWrite(session); err != nil {
|
||||
logrus.Debugf("error when creating database: %s", err)
|
||||
if !strings.Contains(err.Error(), "already exists") {
|
||||
return fmt.Errorf("unable to run table creation: %s", err)
|
||||
}
|
||||
@@ -68,6 +68,10 @@ func (t Table) create(session *gorethink.Session, dbName string, numReplicas uin
|
||||
Replicas: numReplicas,
|
||||
}
|
||||
|
||||
if err := t.wait(session, dbName); err != nil {
|
||||
return fmt.Errorf("unable to wait for table to be ready after creation: %s", err)
|
||||
}
|
||||
|
||||
if _, err := t.term(dbName).Reconfigure(reconfigureOpts).RunWrite(session); err != nil {
|
||||
return fmt.Errorf("unable to reconfigure table replication: %s", err)
|
||||
}
|
||||
|
||||
@@ -3,8 +3,8 @@ package rethinkdb
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/dancannon/gorethink"
|
||||
"github.com/docker/go-connections/tlsconfig"
|
||||
"gopkg.in/dancannon/gorethink.v2"
|
||||
)
|
||||
|
||||
var session *gorethink.Session
|
||||
|
||||
100
vendor/github.com/dancannon/gorethink/connection_helper.go
generated
vendored
100
vendor/github.com/dancannon/gorethink/connection_helper.go
generated
vendored
@@ -1,100 +0,0 @@
|
||||
package gorethink
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
p "github.com/dancannon/gorethink/ql2"
|
||||
)
|
||||
|
||||
// Write 'data' to conn
|
||||
func (c *Connection) writeData(data []byte) error {
|
||||
_, err := c.Conn.Write(data[:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Connection) writeHandshakeReq() error {
|
||||
pos := 0
|
||||
dataLen := 4 + 4 + len(c.opts.AuthKey) + 4
|
||||
data := make([]byte, dataLen)
|
||||
|
||||
// Send the protocol version to the server as a 4-byte little-endian-encoded integer
|
||||
binary.LittleEndian.PutUint32(data[pos:], uint32(p.VersionDummy_V0_4))
|
||||
pos += 4
|
||||
|
||||
// Send the length of the auth key to the server as a 4-byte little-endian-encoded integer
|
||||
binary.LittleEndian.PutUint32(data[pos:], uint32(len(c.opts.AuthKey)))
|
||||
pos += 4
|
||||
|
||||
// Send the auth key as an ASCII string
|
||||
if len(c.opts.AuthKey) > 0 {
|
||||
pos += copy(data[pos:], c.opts.AuthKey)
|
||||
}
|
||||
|
||||
// Send the protocol type as a 4-byte little-endian-encoded integer
|
||||
binary.LittleEndian.PutUint32(data[pos:], uint32(p.VersionDummy_JSON))
|
||||
pos += 4
|
||||
|
||||
return c.writeData(data)
|
||||
}
|
||||
|
||||
func (c *Connection) readHandshakeSuccess() error {
|
||||
reader := bufio.NewReader(c.Conn)
|
||||
line, err := reader.ReadBytes('\x00')
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
return fmt.Errorf("Unexpected EOF: %s", string(line))
|
||||
}
|
||||
return err
|
||||
}
|
||||
// convert to string and remove trailing NUL byte
|
||||
response := string(line[:len(line)-1])
|
||||
if response != "SUCCESS" {
|
||||
response = strings.TrimSpace(response)
|
||||
// we failed authorization or something else terrible happened
|
||||
return RQLDriverError{rqlError(fmt.Sprintf("Server dropped connection with message: \"%s\"", response))}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Connection) read(buf []byte, length int) (total int, err error) {
|
||||
var n int
|
||||
for total < length {
|
||||
if n, err = c.Conn.Read(buf[total:length]); err != nil {
|
||||
break
|
||||
}
|
||||
total += n
|
||||
}
|
||||
if err != nil {
|
||||
return total, err
|
||||
}
|
||||
|
||||
return total, nil
|
||||
}
|
||||
|
||||
func (c *Connection) writeQuery(token int64, q []byte) error {
|
||||
pos := 0
|
||||
dataLen := 8 + 4 + len(q)
|
||||
data := make([]byte, dataLen)
|
||||
|
||||
// Send the protocol version to the server as a 4-byte little-endian-encoded integer
|
||||
binary.LittleEndian.PutUint64(data[pos:], uint64(token))
|
||||
pos += 8
|
||||
|
||||
// Send the length of the auth key to the server as a 4-byte little-endian-encoded integer
|
||||
binary.LittleEndian.PutUint32(data[pos:], uint32(len(q)))
|
||||
pos += 4
|
||||
|
||||
// Send the auth key as an ASCII string
|
||||
pos += copy(data[pos:], q)
|
||||
|
||||
return c.writeData(data)
|
||||
}
|
||||
@@ -6,6 +6,8 @@ go:
|
||||
|
||||
cache: apt
|
||||
|
||||
go_import_path: gopkg.in/dancannon/gorethink.v2
|
||||
|
||||
before_script:
|
||||
- source /etc/lsb-release && echo "deb http://download.rethinkdb.com/apt $DISTRIB_CODENAME main" | sudo tee /etc/apt/sources.list.d/rethinkdb.list
|
||||
- wget -qO- http://download.rethinkdb.com/apt/pubkey.gpg | sudo apt-key add -
|
||||
@@ -2,9 +2,49 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
This project adheres to [Semantic Versioning](http://semver.org/).
|
||||
|
||||
## v2.0.0 - 2016-04-13
|
||||
|
||||
### Changed
|
||||
|
||||
- GoRethink now uses the v1.0 RethinkDB protocol which supports RethinkDB v2.3 and above. If you are using RethinkDB 2.2 or older please set `HandshakeVersion` when creating a session. For example:
|
||||
```go
|
||||
r.Connect(
|
||||
...
|
||||
HandshakeVersion: r.HandshakeV0_4,
|
||||
...
|
||||
)
|
||||
```
|
||||
|
||||
### Added
|
||||
- Added support for username/password authentication. To login pass your username and password when creating a session using the `Username` and `Password` fields in the `ConnectOpts`.
|
||||
- Added the `Grant` term
|
||||
- Added the `Ordered` optional argument to `EqJoin`
|
||||
- Added the `Fold` term and examples
|
||||
- Added the `ReadOne` and `ReadAll` helper functions for quickly executing a query and scanning the result into a variable. For examples see the godocs.
|
||||
- Added the `Peek` and `Skip` functions to the `Cursor`.
|
||||
- Added support for referential arrays in structs
|
||||
- Added the `Durability` argument to `RunOpts`/`ExecOpts`
|
||||
|
||||
### Deprecated
|
||||
- Deprecated the root `Wait` term, `r.Table(...).Wait()` should now be used instead.
|
||||
- Deprecated session authentication using `AuthKey`
|
||||
|
||||
### Fixed
|
||||
- Fixed issue with `ReconfigureOpts` field `PrimaryTag`
|
||||
|
||||
## v1.4.1 - 2016-04-02
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed panic when closing a connection at the same time as using a changefeed.
|
||||
- Update imports to correctly use gopkg.in
|
||||
- Fixed race condition when using anonymous functions
|
||||
- Fixed IsConflictErr and IsTypeErr panicking when passed nil errors
|
||||
- RunWrite no longer misformats errors with formatting directives in them
|
||||
|
||||
## v1.4.0 - 2016-03-15
|
||||
|
||||
## Added
|
||||
### Added
|
||||
- Added the ability to reference subdocuments when inserting new documents, for more information see the documentation in the readme.
|
||||
- Added the `SetTags` function which allows GoRethink to override which tags are used when working with structs. For example to support the `json` add the following call `SetTags("gorethink", "json")`.
|
||||
- Added helper functions for checking the error type of a write query, this is useful when calling `RunWrite`.
|
||||
@@ -14,7 +54,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
||||
- Added the `NextResponse` function to `Cursor` which will return the next raw JSON response in the result set.
|
||||
- Added ability to set the keep alive period by setting the `KeepAlivePeriod` field in `ConnectOpts`.
|
||||
|
||||
## Fixed
|
||||
### Fixed
|
||||
- Fixed an issue that could prevent bad connections from being removed from the connection pool.
|
||||
- Fixed certain connection errors not being returned as `RqlConnectionError` when calling `Run`, `Exec` or `RunWrite`.
|
||||
- Fixed potential dead lock in connection code caused when building the query.
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||

|
||||
|
||||
Current version: v1.4.0 (RethinkDB v2.2)
|
||||
Current version: v2.0.0 (RethinkDB v2.3)
|
||||
|
||||
Please note that this version of the driver only supports versions of RethinkDB using the v0.4 protocol (any versions of the driver older than RethinkDB 2.0 will not work).
|
||||
|
||||
@@ -22,7 +22,7 @@ go get -u github.com/dancannon/gorethink
|
||||
|
||||
Or (pinned to the v1.x.x tag)
|
||||
```
|
||||
go get gopkg.in/dancannon/gorethink.v1
|
||||
go get gopkg.in/dancannon/gorethink.v2
|
||||
```
|
||||
|
||||
## Connection
|
||||
284
vendor/gopkg.in/dancannon/gorethink.v2/benchmarks_test.go
generated
vendored
Normal file
284
vendor/gopkg.in/dancannon/gorethink.v2/benchmarks_test.go
generated
vendored
Normal file
@@ -0,0 +1,284 @@
|
||||
package gorethink
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"strconv"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func BenchmarkBatch200RandomWrites(b *testing.B) {
|
||||
|
||||
var term Term
|
||||
var data []map[string]interface{}
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
|
||||
for is := 0; is < 200; is++ {
|
||||
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
cid := map[string]interface{}{
|
||||
"customer_id": strconv.FormatInt(r.Int63(), 10),
|
||||
}
|
||||
data = append(data, cid)
|
||||
}
|
||||
|
||||
// Insert the new item into the database
|
||||
term = DB("benchmarks").Table("benchmarks").Insert(data)
|
||||
|
||||
// Insert the new item into the database
|
||||
_, err := term.RunWrite(session, RunOpts{
|
||||
MinBatchRows: 200,
|
||||
MaxBatchRows: 200,
|
||||
})
|
||||
if err != nil {
|
||||
b.Errorf("insert failed [%s] ", err)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func BenchmarkBatch200RandomWritesParallel10(b *testing.B) {
|
||||
|
||||
var term Term
|
||||
var data []map[string]interface{}
|
||||
|
||||
b.SetParallelism(10)
|
||||
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
|
||||
for pb.Next() {
|
||||
for is := 0; is < 200; is++ {
|
||||
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
cid := map[string]interface{}{
|
||||
"customer_id": strconv.FormatInt(r.Int63(), 10),
|
||||
}
|
||||
data = append(data, cid)
|
||||
}
|
||||
|
||||
// Insert the new item into the database
|
||||
term = DB("benchmarks").Table("benchmarks").Insert(data)
|
||||
|
||||
// Insert the new item into the database
|
||||
_, err := term.RunWrite(session, RunOpts{
|
||||
MinBatchRows: 200,
|
||||
MaxBatchRows: 200,
|
||||
})
|
||||
if err != nil {
|
||||
b.Errorf("insert failed [%s] ", err)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func BenchmarkBatch200SoftRandomWritesParallel10(b *testing.B) {
|
||||
|
||||
var term Term
|
||||
var data []map[string]interface{}
|
||||
|
||||
b.SetParallelism(10)
|
||||
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
|
||||
for pb.Next() {
|
||||
|
||||
opts := InsertOpts{Durability: "soft"}
|
||||
|
||||
for is := 0; is < 200; is++ {
|
||||
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
cid := map[string]interface{}{
|
||||
"customer_id": strconv.FormatInt(r.Int63(), 10),
|
||||
}
|
||||
data = append(data, cid)
|
||||
}
|
||||
|
||||
// Insert the new item into the database
|
||||
term = DB("benchmarks").Table("benchmarks").Insert(data, opts)
|
||||
|
||||
// Insert the new item into the database
|
||||
_, err := term.RunWrite(session, RunOpts{
|
||||
MinBatchRows: 200,
|
||||
MaxBatchRows: 200,
|
||||
})
|
||||
if err != nil {
|
||||
b.Errorf("insert failed [%s] ", err)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func BenchmarkRandomWrites(b *testing.B) {
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
data := map[string]interface{}{
|
||||
"customer_id": strconv.FormatInt(r.Int63(), 10),
|
||||
}
|
||||
// Insert the new item into the database
|
||||
_, err := DB("benchmarks").Table("benchmarks").Insert(data).RunWrite(session)
|
||||
if err != nil {
|
||||
b.Errorf("insert failed [%s] ", err)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func BenchmarkRandomWritesParallel10(b *testing.B) {
|
||||
|
||||
// p*GOMAXPROCS
|
||||
b.SetParallelism(10)
|
||||
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
data := map[string]interface{}{
|
||||
"customer_id": strconv.FormatInt(r.Int63(), 10),
|
||||
}
|
||||
// Insert the new item into the database
|
||||
_, err := DB("benchmarks").Table("benchmarks").Insert(data).RunWrite(session)
|
||||
if err != nil {
|
||||
b.Errorf("insert failed [%s] ", err)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func BenchmarkRandomSoftWrites(b *testing.B) {
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
data := map[string]interface{}{
|
||||
"customer_id": strconv.FormatInt(rand.Int63(), 10),
|
||||
}
|
||||
// Insert the new item into the database
|
||||
opts := InsertOpts{Durability: "soft"}
|
||||
_, err := DB("benchmarks").Table("benchmarks").Insert(data, opts).RunWrite(session)
|
||||
if err != nil {
|
||||
b.Errorf("insert failed [%s] ", err)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func BenchmarkRandomSoftWritesParallel10(b *testing.B) {
|
||||
|
||||
// p*GOMAXPROCS
|
||||
b.SetParallelism(10)
|
||||
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
data := map[string]interface{}{
|
||||
"customer_id": strconv.FormatInt(r.Int63(), 10),
|
||||
}
|
||||
|
||||
// Insert the new item into the database
|
||||
opts := InsertOpts{Durability: "soft"}
|
||||
_, err := DB("benchmarks").Table("benchmarks").Insert(data, opts).RunWrite(session)
|
||||
if err != nil {
|
||||
b.Errorf("insert failed [%s] ", err)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func BenchmarkSequentialWrites(b *testing.B) {
|
||||
|
||||
si := 0
|
||||
for i := 0; i < b.N; i++ {
|
||||
si++
|
||||
data := map[string]interface{}{
|
||||
"customer_id": si,
|
||||
}
|
||||
|
||||
// Insert the new item into the database
|
||||
_, err := DB("benchmarks").Table("benchmarks").Insert(data).RunWrite(session)
|
||||
if err != nil {
|
||||
b.Errorf("insert failed [%s] ", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkSequentialWritesParallel10(b *testing.B) {
|
||||
|
||||
var mu sync.Mutex
|
||||
si := 0
|
||||
|
||||
// p*GOMAXPROCS
|
||||
b.SetParallelism(10)
|
||||
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
mu.Lock()
|
||||
si++
|
||||
mu.Unlock()
|
||||
|
||||
data := map[string]interface{}{
|
||||
"customer_id": si,
|
||||
}
|
||||
|
||||
// Insert the new item into the database
|
||||
_, err := DB("benchmarks").Table("benchmarks").Insert(data).RunWrite(session)
|
||||
if err != nil {
|
||||
b.Errorf("insert failed [%s] ", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func BenchmarkSequentialSoftWrites(b *testing.B) {
|
||||
|
||||
opts := InsertOpts{Durability: "soft"}
|
||||
si := 0
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
si++
|
||||
data := map[string]interface{}{
|
||||
"customer_id": si,
|
||||
}
|
||||
|
||||
// Insert the new item into the database
|
||||
_, err := Table("benchmarks").Insert(data, opts).RunWrite(session)
|
||||
if err != nil {
|
||||
b.Errorf("insert failed [%s] ", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkSequentialSoftWritesParallel10(b *testing.B) {
|
||||
|
||||
var mu sync.Mutex
|
||||
si := 0
|
||||
|
||||
// p*GOMAXPROCS
|
||||
b.SetParallelism(10)
|
||||
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
for pb.Next() {
|
||||
mu.Lock()
|
||||
si++
|
||||
mu.Unlock()
|
||||
|
||||
data := map[string]interface{}{
|
||||
"customer_id": si,
|
||||
}
|
||||
|
||||
opts := InsertOpts{Durability: "soft"}
|
||||
|
||||
// Insert the new item into the database
|
||||
_, err := Table("benchmarks").Insert(data, opts).RunWrite(session)
|
||||
if err != nil {
|
||||
b.Errorf("insert failed [%s] ", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
168
vendor/gopkg.in/dancannon/gorethink.v2/checkers_test.go
generated
vendored
Normal file
168
vendor/gopkg.in/dancannon/gorethink.v2/checkers_test.go
generated
vendored
Normal file
@@ -0,0 +1,168 @@
|
||||
package gorethink
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
test "gopkg.in/check.v1"
|
||||
|
||||
"gopkg.in/dancannon/gorethink.v2/types"
|
||||
)
|
||||
|
||||
type jsonChecker struct {
|
||||
*test.CheckerInfo
|
||||
}
|
||||
|
||||
func (j jsonChecker) Check(params []interface{}, names []string) (result bool, error string) {
|
||||
var jsonParams []interface{}
|
||||
for _, param := range params {
|
||||
jsonParam, err := json.Marshal(param)
|
||||
if err != nil {
|
||||
return false, err.Error()
|
||||
}
|
||||
jsonParams = append(jsonParams, jsonParam)
|
||||
}
|
||||
return test.DeepEquals.Check(jsonParams, names)
|
||||
}
|
||||
|
||||
// jsonEquals compares two interface{} objects by converting them to JSON and
|
||||
// seeing if the strings match
|
||||
var jsonEquals = &jsonChecker{
|
||||
&test.CheckerInfo{Name: "jsonEquals", Params: []string{"obtained", "expected"}},
|
||||
}
|
||||
|
||||
type geometryChecker struct {
|
||||
*test.CheckerInfo
|
||||
}
|
||||
|
||||
func (j geometryChecker) Check(params []interface{}, names []string) (result bool, error string) {
|
||||
obtained, ok := params[0].(types.Geometry)
|
||||
if !ok {
|
||||
return false, "obtained must be a Geometry"
|
||||
}
|
||||
expectedType, ok := params[1].(string)
|
||||
if !ok {
|
||||
return false, "expectedType must be a string"
|
||||
}
|
||||
|
||||
switch expectedType {
|
||||
case "Polygon":
|
||||
expectedCoords, ok := params[2].([][][]float64)
|
||||
if !ok {
|
||||
return false, "expectedCoords must be a [][][]float64"
|
||||
}
|
||||
|
||||
return comparePolygon(expectedCoords, obtained)
|
||||
case "LineString":
|
||||
expectedCoords, ok := params[2].([][]float64)
|
||||
if !ok {
|
||||
return false, "expectedCoords must be a [][]float64"
|
||||
}
|
||||
|
||||
return compareLineString(expectedCoords, obtained)
|
||||
case "Point":
|
||||
expectedCoords, ok := params[2].([]float64)
|
||||
if !ok {
|
||||
return false, "expectedCoords must be a []float64"
|
||||
}
|
||||
|
||||
return comparePoint(expectedCoords, obtained)
|
||||
default:
|
||||
return false, "unknown expectedType"
|
||||
}
|
||||
}
|
||||
|
||||
// geometryEquals compares two geometry values, all coordinates are compared with a small amount of tolerance
|
||||
var geometryEquals = &geometryChecker{
|
||||
&test.CheckerInfo{Name: "geometryEquals", Params: []string{"obtained", "expectedType", "expectedCoords"}},
|
||||
}
|
||||
|
||||
/* BEGIN FLOAT HELPERS */
|
||||
|
||||
// totally ripped off from math/all_test.go
|
||||
// https://github.com/golang/go/blob/master/src/math/all_test.go#L1723-L1749
|
||||
func tolerance(a, b, e float64) bool {
|
||||
d := a - b
|
||||
if d < 0 {
|
||||
d = -d
|
||||
|
||||
}
|
||||
|
||||
if a != 0 {
|
||||
e = e * a
|
||||
if e < 0 {
|
||||
e = -e
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
return d < e
|
||||
}
|
||||
|
||||
func mehclose(a, b float64) bool { return tolerance(a, b, 1e-2) }
|
||||
func kindaclose(a, b float64) bool { return tolerance(a, b, 1e-8) }
|
||||
func prettyclose(a, b float64) bool { return tolerance(a, b, 1e-14) }
|
||||
func veryclose(a, b float64) bool { return tolerance(a, b, 4e-16) }
|
||||
func soclose(a, b, e float64) bool { return tolerance(a, b, e) }
|
||||
|
||||
func comparePolygon(expected [][][]float64, obtained types.Geometry) (result bool, error string) {
|
||||
if obtained.Type != "Polygon" {
|
||||
return false, fmt.Sprintf("obtained geometry has incorrect type, has %s but expected Polygon", obtained.Type)
|
||||
}
|
||||
|
||||
for i, line := range obtained.Lines {
|
||||
for j, point := range line {
|
||||
ok, err := assertPointsEqual(
|
||||
expected[i][j][0], point.Lon, // Lon
|
||||
expected[i][j][1], point.Lat, // Lat
|
||||
)
|
||||
if !ok {
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true, ""
|
||||
}
|
||||
|
||||
func compareLineString(expected [][]float64, obtained types.Geometry) (result bool, error string) {
|
||||
if obtained.Type != "LineString" {
|
||||
return false, fmt.Sprintf("obtained geometry has incorrect type, has %s but expected LineString", obtained.Type)
|
||||
}
|
||||
|
||||
for j, point := range obtained.Line {
|
||||
ok, err := assertPointsEqual(
|
||||
expected[j][0], point.Lon, // Lon
|
||||
expected[j][1], point.Lat, // Lat
|
||||
)
|
||||
if !ok {
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
|
||||
return true, ""
|
||||
}
|
||||
|
||||
func comparePoint(expected []float64, obtained types.Geometry) (result bool, error string) {
|
||||
if obtained.Type != "Point" {
|
||||
return false, fmt.Sprintf("obtained geometry has incorrect type, has %s but expected Point", obtained.Type)
|
||||
}
|
||||
|
||||
return assertPointsEqual(
|
||||
expected[0], obtained.Point.Lon, // Lon
|
||||
expected[1], obtained.Point.Lat, // Lat
|
||||
)
|
||||
}
|
||||
|
||||
func assertPointsEqual(expectedLon, obtainedLon, expectedLat, obtainedLat float64) (result bool, error string) {
|
||||
if !kindaclose(expectedLon, obtainedLon) {
|
||||
return false, fmt.Sprintf("the deviation between the compared floats is too great [%v:%v]", expectedLon, obtainedLon)
|
||||
}
|
||||
if !kindaclose(expectedLat, obtainedLat) {
|
||||
return false, fmt.Sprintf("the deviation between the compared floats is too great [%v:%v]", expectedLat, obtainedLat)
|
||||
}
|
||||
|
||||
return true, ""
|
||||
}
|
||||
|
||||
/* END FLOAT HELPERS */
|
||||
99
vendor/gopkg.in/dancannon/gorethink.v2/cluster_integration_test.go
generated
vendored
Normal file
99
vendor/gopkg.in/dancannon/gorethink.v2/cluster_integration_test.go
generated
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
// +build cluster
|
||||
// +build integration
|
||||
|
||||
package gorethink
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
test "gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
func (s *RethinkSuite) TestClusterDetectNewNode(c *test.C) {
|
||||
session, err := Connect(ConnectOpts{
|
||||
Addresses: []string{url, url2},
|
||||
DiscoverHosts: true,
|
||||
NodeRefreshInterval: time.Second,
|
||||
})
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
t := time.NewTimer(time.Second * 30)
|
||||
for {
|
||||
select {
|
||||
// Fail if deadline has passed
|
||||
case <-t.C:
|
||||
c.Fatal("No node was added to the cluster")
|
||||
default:
|
||||
// Pass if another node was added
|
||||
if len(session.cluster.GetNodes()) >= 3 {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestClusterRecoverAfterNoNodes(c *test.C) {
|
||||
session, err := Connect(ConnectOpts{
|
||||
Addresses: []string{url, url2},
|
||||
DiscoverHosts: true,
|
||||
NodeRefreshInterval: time.Second,
|
||||
})
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
t := time.NewTimer(time.Second * 30)
|
||||
hasHadZeroNodes := false
|
||||
for {
|
||||
select {
|
||||
// Fail if deadline has passed
|
||||
case <-t.C:
|
||||
c.Fatal("No node was added to the cluster")
|
||||
default:
|
||||
// Check if there are no nodes
|
||||
if len(session.cluster.GetNodes()) == 0 {
|
||||
hasHadZeroNodes = true
|
||||
}
|
||||
|
||||
// Pass if another node was added
|
||||
if len(session.cluster.GetNodes()) >= 1 && hasHadZeroNodes {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestClusterNodeHealth(c *test.C) {
|
||||
session, err := Connect(ConnectOpts{
|
||||
Addresses: []string{url1, url2, url3},
|
||||
DiscoverHosts: true,
|
||||
NodeRefreshInterval: time.Second,
|
||||
MaxIdle: 50,
|
||||
MaxOpen: 200,
|
||||
})
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
attempts := 0
|
||||
failed := 0
|
||||
seconds := 0
|
||||
|
||||
t := time.NewTimer(time.Second * 30)
|
||||
tick := time.NewTicker(time.Second)
|
||||
for {
|
||||
select {
|
||||
// Fail if deadline has passed
|
||||
case <-tick.C:
|
||||
seconds++
|
||||
c.Logf("%ds elapsed", seconds)
|
||||
case <-t.C:
|
||||
// Execute queries for 10s and check that at most 5% of the queries fail
|
||||
c.Logf("%d of the %d(%d%%) queries failed", failed, attempts, (failed / attempts))
|
||||
c.Assert(failed <= 100, test.Equals, true)
|
||||
return
|
||||
default:
|
||||
attempts++
|
||||
if err := Expr(1).Exec(session); err != nil {
|
||||
c.Logf("Query failed, %s", err)
|
||||
failed++
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
63
vendor/gopkg.in/dancannon/gorethink.v2/cluster_test.go
generated
vendored
Normal file
63
vendor/gopkg.in/dancannon/gorethink.v2/cluster_test.go
generated
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
// +build cluster
|
||||
|
||||
package gorethink
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
test "gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
func (s *RethinkSuite) TestClusterConnect(c *test.C) {
|
||||
session, err := Connect(ConnectOpts{
|
||||
Addresses: []string{url1, url2, url3},
|
||||
})
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
row, err := Expr("Hello World").Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
var response string
|
||||
err = row.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, "Hello World")
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestClusterMultipleQueries(c *test.C) {
|
||||
session, err := Connect(ConnectOpts{
|
||||
Addresses: []string{url1, url2, url3},
|
||||
})
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
for i := 0; i < 1000; i++ {
|
||||
row, err := Expr(fmt.Sprintf("Hello World", i)).Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
var response string
|
||||
err = row.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, fmt.Sprintf("Hello World", i))
|
||||
}
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestClusterConnectError(c *test.C) {
|
||||
var err error
|
||||
_, err = Connect(ConnectOpts{
|
||||
Addresses: []string{"nonexistanturl"},
|
||||
Timeout: time.Second,
|
||||
})
|
||||
c.Assert(err, test.NotNil)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestClusterConnectDatabase(c *test.C) {
|
||||
session, err := Connect(ConnectOpts{
|
||||
Addresses: []string{url1, url2, url3},
|
||||
Database: "test2",
|
||||
})
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
_, err = Table("test2").Run(session)
|
||||
c.Assert(err, test.NotNil)
|
||||
c.Assert(err.Error(), test.Equals, "gorethink: Database `test2` does not exist. in: \nr.Table(\"test2\")")
|
||||
}
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
p "github.com/dancannon/gorethink/ql2"
|
||||
p "gopkg.in/dancannon/gorethink.v2/ql2"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -41,6 +41,7 @@ type Connection struct {
|
||||
token int64
|
||||
cursors map[int64]*Cursor
|
||||
bad bool
|
||||
closed bool
|
||||
}
|
||||
|
||||
// NewConnection creates a new connection to the database server
|
||||
@@ -62,16 +63,14 @@ func NewConnection(address string, opts *ConnectOpts) (*Connection, error) {
|
||||
return nil, RQLConnectionError{rqlError(err.Error())}
|
||||
}
|
||||
|
||||
// Send handshake request
|
||||
if err = c.writeHandshakeReq(); err != nil {
|
||||
c.Close()
|
||||
return nil, RQLConnectionError{rqlError(err.Error())}
|
||||
}
|
||||
// Read handshake response
|
||||
err = c.readHandshakeSuccess()
|
||||
// Send handshake
|
||||
handshake, err := c.handshake(opts.HandshakeVersion)
|
||||
if err != nil {
|
||||
c.Close()
|
||||
return nil, RQLConnectionError{rqlError(err.Error())}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = handshake.Send(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return c, nil
|
||||
@@ -82,14 +81,15 @@ func (c *Connection) Close() error {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
|
||||
if c.Conn != nil {
|
||||
c.Conn.Close()
|
||||
c.Conn = nil
|
||||
var err error
|
||||
|
||||
if !c.closed {
|
||||
err = c.Conn.Close()
|
||||
c.closed = true
|
||||
c.cursors = make(map[int64]*Cursor)
|
||||
}
|
||||
|
||||
c.cursors = nil
|
||||
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
// Query sends a Query to the database, returning both the raw Response and a
|
||||
450
vendor/gopkg.in/dancannon/gorethink.v2/connection_handshake.go
generated
vendored
Normal file
450
vendor/gopkg.in/dancannon/gorethink.v2/connection_handshake.go
generated
vendored
Normal file
@@ -0,0 +1,450 @@
|
||||
package gorethink
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"crypto/hmac"
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"hash"
|
||||
"io"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/crypto/pbkdf2"
|
||||
|
||||
p "gopkg.in/dancannon/gorethink.v2/ql2"
|
||||
)
|
||||
|
||||
type HandshakeVersion int
|
||||
|
||||
const (
|
||||
HandshakeV1_0 HandshakeVersion = iota
|
||||
HandshakeV0_4
|
||||
)
|
||||
|
||||
type connectionHandshake interface {
|
||||
Send() error
|
||||
}
|
||||
|
||||
func (c *Connection) handshake(version HandshakeVersion) (connectionHandshake, error) {
|
||||
switch version {
|
||||
case HandshakeV0_4:
|
||||
return &connectionHandshakeV0_4{conn: c}, nil
|
||||
case HandshakeV1_0:
|
||||
return &connectionHandshakeV1_0{conn: c}, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("Unrecognised handshake version")
|
||||
}
|
||||
}
|
||||
|
||||
type connectionHandshakeV0_4 struct {
|
||||
conn *Connection
|
||||
}
|
||||
|
||||
func (c *connectionHandshakeV0_4) Send() error {
|
||||
// Send handshake request
|
||||
if err := c.writeHandshakeReq(); err != nil {
|
||||
c.conn.Close()
|
||||
return RQLConnectionError{rqlError(err.Error())}
|
||||
}
|
||||
// Read handshake response
|
||||
if err := c.readHandshakeSuccess(); err != nil {
|
||||
c.conn.Close()
|
||||
return RQLConnectionError{rqlError(err.Error())}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *connectionHandshakeV0_4) writeHandshakeReq() error {
|
||||
pos := 0
|
||||
dataLen := 4 + 4 + len(c.conn.opts.AuthKey) + 4
|
||||
data := make([]byte, dataLen)
|
||||
|
||||
// Send the protocol version to the server as a 4-byte little-endian-encoded integer
|
||||
binary.LittleEndian.PutUint32(data[pos:], uint32(p.VersionDummy_V0_4))
|
||||
pos += 4
|
||||
|
||||
// Send the length of the auth key to the server as a 4-byte little-endian-encoded integer
|
||||
binary.LittleEndian.PutUint32(data[pos:], uint32(len(c.conn.opts.AuthKey)))
|
||||
pos += 4
|
||||
|
||||
// Send the auth key as an ASCII string
|
||||
if len(c.conn.opts.AuthKey) > 0 {
|
||||
pos += copy(data[pos:], c.conn.opts.AuthKey)
|
||||
}
|
||||
|
||||
// Send the protocol type as a 4-byte little-endian-encoded integer
|
||||
binary.LittleEndian.PutUint32(data[pos:], uint32(p.VersionDummy_JSON))
|
||||
pos += 4
|
||||
|
||||
return c.conn.writeData(data)
|
||||
}
|
||||
|
||||
func (c *connectionHandshakeV0_4) readHandshakeSuccess() error {
|
||||
reader := bufio.NewReader(c.conn.Conn)
|
||||
line, err := reader.ReadBytes('\x00')
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
return fmt.Errorf("Unexpected EOF: %s", string(line))
|
||||
}
|
||||
return err
|
||||
}
|
||||
// convert to string and remove trailing NUL byte
|
||||
response := string(line[:len(line)-1])
|
||||
if response != "SUCCESS" {
|
||||
response = strings.TrimSpace(response)
|
||||
// we failed authorization or something else terrible happened
|
||||
return RQLDriverError{rqlError(fmt.Sprintf("Server dropped connection with message: \"%s\"", response))}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
const (
|
||||
handshakeV1_0_protocolVersionNumber = 0
|
||||
handshakeV1_0_authenticationMethod = "SCRAM-SHA-256"
|
||||
)
|
||||
|
||||
type connectionHandshakeV1_0 struct {
|
||||
conn *Connection
|
||||
reader *bufio.Reader
|
||||
|
||||
authMsg string
|
||||
}
|
||||
|
||||
func (c *connectionHandshakeV1_0) Send() error {
|
||||
c.reader = bufio.NewReader(c.conn.Conn)
|
||||
|
||||
// Generate client nonce
|
||||
clientNonce, err := c.generateNonce()
|
||||
if err != nil {
|
||||
c.conn.Close()
|
||||
return RQLDriverError{rqlError(fmt.Sprintf("Failed to generate client nonce: %s", err))}
|
||||
}
|
||||
// Send client first message
|
||||
if err := c.writeFirstMessage(clientNonce); err != nil {
|
||||
c.conn.Close()
|
||||
return err
|
||||
}
|
||||
// Read status
|
||||
if err := c.checkServerVersions(); err != nil {
|
||||
c.conn.Close()
|
||||
return err
|
||||
}
|
||||
|
||||
// Read server first message
|
||||
i, salt, serverNonce, err := c.readFirstMessage()
|
||||
if err != nil {
|
||||
c.conn.Close()
|
||||
return err
|
||||
}
|
||||
|
||||
// Check server nonce
|
||||
if !strings.HasPrefix(serverNonce, clientNonce) {
|
||||
return RQLAuthError{RQLDriverError{rqlError("Invalid nonce from server")}}
|
||||
}
|
||||
|
||||
// Generate proof
|
||||
saltedPass := c.saltPassword(i, salt)
|
||||
clientProof := c.calculateProof(saltedPass, clientNonce, serverNonce)
|
||||
serverSignature := c.serverSignature(saltedPass)
|
||||
|
||||
// Send client final message
|
||||
if err := c.writeFinalMessage(serverNonce, clientProof); err != nil {
|
||||
c.conn.Close()
|
||||
return err
|
||||
}
|
||||
// Read server final message
|
||||
if err := c.readFinalMessage(serverSignature); err != nil {
|
||||
c.conn.Close()
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *connectionHandshakeV1_0) writeFirstMessage(clientNonce string) error {
|
||||
// Default username to admin if not set
|
||||
username := "admin"
|
||||
if c.conn.opts.Username != "" {
|
||||
username = c.conn.opts.Username
|
||||
}
|
||||
|
||||
c.authMsg = fmt.Sprintf("n=%s,r=%s", username, clientNonce)
|
||||
msg := fmt.Sprintf(
|
||||
`{"protocol_version": %d,"authentication": "n,,%s","authentication_method": "%s"}`,
|
||||
handshakeV1_0_protocolVersionNumber, c.authMsg, handshakeV1_0_authenticationMethod,
|
||||
)
|
||||
|
||||
pos := 0
|
||||
dataLen := 4 + len(msg) + 1
|
||||
data := make([]byte, dataLen)
|
||||
|
||||
// Send the protocol version to the server as a 4-byte little-endian-encoded integer
|
||||
binary.LittleEndian.PutUint32(data[pos:], uint32(p.VersionDummy_V1_0))
|
||||
pos += 4
|
||||
|
||||
// Send the auth message as an ASCII string
|
||||
pos += copy(data[pos:], msg)
|
||||
|
||||
// Add null terminating byte
|
||||
data[pos] = '\x00'
|
||||
|
||||
return c.writeData(data)
|
||||
}
|
||||
|
||||
func (c *connectionHandshakeV1_0) checkServerVersions() error {
|
||||
b, err := c.readResponse()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Read status
|
||||
type versionsResponse struct {
|
||||
Success bool `json:"success"`
|
||||
MinProtocolVersion int `json:"min_protocol_version"`
|
||||
MaxProtocolVersion int `json:"max_protocol_version"`
|
||||
ServerVersion string `json:"server_version"`
|
||||
ErrorCode int `json:"error_code"`
|
||||
Error string `json:"error"`
|
||||
}
|
||||
var rsp *versionsResponse
|
||||
statusStr := string(b)
|
||||
|
||||
if err := json.Unmarshal(b, &rsp); err != nil {
|
||||
if strings.HasPrefix(statusStr, "ERROR: ") {
|
||||
statusStr = strings.TrimPrefix(statusStr, "ERROR: ")
|
||||
return RQLConnectionError{rqlError(statusStr)}
|
||||
}
|
||||
|
||||
return RQLDriverError{rqlError(fmt.Sprintf("Error reading versions: %s", err))}
|
||||
}
|
||||
|
||||
if !rsp.Success {
|
||||
return c.handshakeError(rsp.ErrorCode, rsp.Error)
|
||||
}
|
||||
if rsp.MinProtocolVersion > handshakeV1_0_protocolVersionNumber ||
|
||||
rsp.MaxProtocolVersion < handshakeV1_0_protocolVersionNumber {
|
||||
return RQLDriverError{rqlError(
|
||||
fmt.Sprintf(
|
||||
"Unsupported protocol version %d, expected between %d and %d.",
|
||||
handshakeV1_0_protocolVersionNumber,
|
||||
rsp.MinProtocolVersion,
|
||||
rsp.MaxProtocolVersion,
|
||||
),
|
||||
)}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *connectionHandshakeV1_0) readFirstMessage() (i int64, salt []byte, serverNonce string, err error) {
|
||||
b, err2 := c.readResponse()
|
||||
if err2 != nil {
|
||||
err = err2
|
||||
return
|
||||
}
|
||||
|
||||
// Read server message
|
||||
type firstMessageResponse struct {
|
||||
Success bool `json:"success"`
|
||||
Authentication string `json:"authentication"`
|
||||
ErrorCode int `json:"error_code"`
|
||||
Error string `json:"error"`
|
||||
}
|
||||
var rsp *firstMessageResponse
|
||||
|
||||
if err2 := json.Unmarshal(b, &rsp); err2 != nil {
|
||||
err = RQLDriverError{rqlError(fmt.Sprintf("Error parsing auth response: %s", err2))}
|
||||
return
|
||||
}
|
||||
if !rsp.Success {
|
||||
err = c.handshakeError(rsp.ErrorCode, rsp.Error)
|
||||
return
|
||||
}
|
||||
|
||||
c.authMsg += ","
|
||||
c.authMsg += rsp.Authentication
|
||||
|
||||
// Parse authentication field
|
||||
auth := map[string]string{}
|
||||
parts := strings.Split(rsp.Authentication, ",")
|
||||
for _, part := range parts {
|
||||
i := strings.Index(part, "=")
|
||||
if i != -1 {
|
||||
auth[part[:i]] = part[i+1:]
|
||||
}
|
||||
}
|
||||
|
||||
// Extract return values
|
||||
if v, ok := auth["i"]; ok {
|
||||
i, err = strconv.ParseInt(v, 10, 64)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
if v, ok := auth["s"]; ok {
|
||||
salt, err = base64.StdEncoding.DecodeString(v)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
if v, ok := auth["r"]; ok {
|
||||
serverNonce = v
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (c *connectionHandshakeV1_0) writeFinalMessage(serverNonce, clientProof string) error {
|
||||
authMsg := "c=biws,r="
|
||||
authMsg += serverNonce
|
||||
authMsg += ",p="
|
||||
authMsg += clientProof
|
||||
|
||||
msg := fmt.Sprintf(`{"authentication": "%s"}`, authMsg)
|
||||
|
||||
pos := 0
|
||||
dataLen := len(msg) + 1
|
||||
data := make([]byte, dataLen)
|
||||
|
||||
// Send the auth message as an ASCII string
|
||||
pos += copy(data[pos:], msg)
|
||||
|
||||
// Add null terminating byte
|
||||
data[pos] = '\x00'
|
||||
|
||||
return c.writeData(data)
|
||||
}
|
||||
|
||||
func (c *connectionHandshakeV1_0) readFinalMessage(serverSignature string) error {
|
||||
b, err := c.readResponse()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Read server message
|
||||
type finalMessageResponse struct {
|
||||
Success bool `json:"success"`
|
||||
Authentication string `json:"authentication"`
|
||||
ErrorCode int `json:"error_code"`
|
||||
Error string `json:"error"`
|
||||
}
|
||||
var rsp *finalMessageResponse
|
||||
|
||||
if err := json.Unmarshal(b, &rsp); err != nil {
|
||||
return RQLDriverError{rqlError(fmt.Sprintf("Error parsing auth response: %s", err))}
|
||||
}
|
||||
if !rsp.Success {
|
||||
return c.handshakeError(rsp.ErrorCode, rsp.Error)
|
||||
}
|
||||
|
||||
// Parse authentication field
|
||||
auth := map[string]string{}
|
||||
parts := strings.Split(rsp.Authentication, ",")
|
||||
for _, part := range parts {
|
||||
i := strings.Index(part, "=")
|
||||
if i != -1 {
|
||||
auth[part[:i]] = part[i+1:]
|
||||
}
|
||||
}
|
||||
|
||||
// Validate server response
|
||||
if serverSignature != auth["v"] {
|
||||
return RQLAuthError{RQLDriverError{rqlError("Invalid server signature")}}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *connectionHandshakeV1_0) writeData(data []byte) error {
|
||||
|
||||
if err := c.conn.writeData(data); err != nil {
|
||||
return RQLConnectionError{rqlError(err.Error())}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *connectionHandshakeV1_0) readResponse() ([]byte, error) {
|
||||
line, err := c.reader.ReadBytes('\x00')
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
return nil, RQLConnectionError{rqlError(fmt.Sprintf("Unexpected EOF: %s", string(line)))}
|
||||
}
|
||||
return nil, RQLConnectionError{rqlError(err.Error())}
|
||||
}
|
||||
|
||||
// Strip null byte and return
|
||||
return line[:len(line)-1], nil
|
||||
}
|
||||
|
||||
func (c *connectionHandshakeV1_0) generateNonce() (string, error) {
|
||||
const nonceSize = 24
|
||||
|
||||
b := make([]byte, nonceSize)
|
||||
_, err := rand.Read(b)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return base64.StdEncoding.EncodeToString(b), nil
|
||||
}
|
||||
|
||||
func (c *connectionHandshakeV1_0) saltPassword(iter int64, salt []byte) []byte {
|
||||
pass := []byte(c.conn.opts.Password)
|
||||
|
||||
return pbkdf2.Key(pass, salt, int(iter), sha256.Size, sha256.New)
|
||||
}
|
||||
|
||||
func (c *connectionHandshakeV1_0) calculateProof(saltedPass []byte, clientNonce, serverNonce string) string {
|
||||
// Generate proof
|
||||
c.authMsg += ",c=biws,r=" + serverNonce
|
||||
|
||||
mac := hmac.New(c.hashFunc(), saltedPass)
|
||||
mac.Write([]byte("Client Key"))
|
||||
clientKey := mac.Sum(nil)
|
||||
|
||||
hash := c.hashFunc()()
|
||||
hash.Write(clientKey)
|
||||
storedKey := hash.Sum(nil)
|
||||
|
||||
mac = hmac.New(c.hashFunc(), storedKey)
|
||||
mac.Write([]byte(c.authMsg))
|
||||
clientSignature := mac.Sum(nil)
|
||||
clientProof := make([]byte, len(clientKey))
|
||||
for i, _ := range clientKey {
|
||||
clientProof[i] = clientKey[i] ^ clientSignature[i]
|
||||
}
|
||||
|
||||
return base64.StdEncoding.EncodeToString(clientProof)
|
||||
}
|
||||
|
||||
func (c *connectionHandshakeV1_0) serverSignature(saltedPass []byte) string {
|
||||
mac := hmac.New(c.hashFunc(), saltedPass)
|
||||
mac.Write([]byte("Server Key"))
|
||||
serverKey := mac.Sum(nil)
|
||||
|
||||
mac = hmac.New(c.hashFunc(), serverKey)
|
||||
mac.Write([]byte(c.authMsg))
|
||||
serverSignature := mac.Sum(nil)
|
||||
|
||||
return base64.StdEncoding.EncodeToString(serverSignature)
|
||||
}
|
||||
|
||||
func (c *connectionHandshakeV1_0) handshakeError(code int, message string) error {
|
||||
if code >= 10 || code <= 20 {
|
||||
return RQLAuthError{RQLDriverError{rqlError(message)}}
|
||||
} else {
|
||||
return RQLDriverError{rqlError(message)}
|
||||
}
|
||||
}
|
||||
|
||||
func (c *connectionHandshakeV1_0) hashFunc() func() hash.Hash {
|
||||
return sha256.New
|
||||
}
|
||||
47
vendor/gopkg.in/dancannon/gorethink.v2/connection_helper.go
generated
vendored
Normal file
47
vendor/gopkg.in/dancannon/gorethink.v2/connection_helper.go
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
package gorethink
|
||||
|
||||
import "encoding/binary"
|
||||
|
||||
// Write 'data' to conn
|
||||
func (c *Connection) writeData(data []byte) error {
|
||||
_, err := c.Conn.Write(data[:])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Connection) read(buf []byte, length int) (total int, err error) {
|
||||
var n int
|
||||
for total < length {
|
||||
if n, err = c.Conn.Read(buf[total:length]); err != nil {
|
||||
break
|
||||
}
|
||||
total += n
|
||||
}
|
||||
if err != nil {
|
||||
return total, err
|
||||
}
|
||||
|
||||
return total, nil
|
||||
}
|
||||
|
||||
func (c *Connection) writeQuery(token int64, q []byte) error {
|
||||
pos := 0
|
||||
dataLen := 8 + 4 + len(q)
|
||||
data := make([]byte, dataLen)
|
||||
|
||||
// Send the protocol version to the server as a 4-byte little-endian-encoded integer
|
||||
binary.LittleEndian.PutUint64(data[pos:], uint64(token))
|
||||
pos += 8
|
||||
|
||||
// Send the length of the auth key to the server as a 4-byte little-endian-encoded integer
|
||||
binary.LittleEndian.PutUint32(data[pos:], uint32(len(q)))
|
||||
pos += 4
|
||||
|
||||
// Send the auth key as an ASCII string
|
||||
pos += copy(data[pos:], q)
|
||||
|
||||
return c.writeData(data)
|
||||
}
|
||||
@@ -7,8 +7,8 @@ import (
|
||||
"reflect"
|
||||
"sync"
|
||||
|
||||
"github.com/dancannon/gorethink/encoding"
|
||||
p "github.com/dancannon/gorethink/ql2"
|
||||
"gopkg.in/dancannon/gorethink.v2/encoding"
|
||||
p "gopkg.in/dancannon/gorethink.v2/ql2"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -57,15 +57,16 @@ type Cursor struct {
|
||||
term *Term
|
||||
opts map[string]interface{}
|
||||
|
||||
mu sync.RWMutex
|
||||
lastErr error
|
||||
fetching bool
|
||||
closed bool
|
||||
finished bool
|
||||
isAtom bool
|
||||
buffer []interface{}
|
||||
responses []json.RawMessage
|
||||
profile interface{}
|
||||
mu sync.RWMutex
|
||||
lastErr error
|
||||
fetching bool
|
||||
closed bool
|
||||
finished bool
|
||||
isAtom bool
|
||||
pendingSkips int
|
||||
buffer []interface{}
|
||||
responses []json.RawMessage
|
||||
profile interface{}
|
||||
}
|
||||
|
||||
// Profile returns the information returned from the query profiler.
|
||||
@@ -163,7 +164,7 @@ func (c *Cursor) Next(dest interface{}) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
hasMore, err := c.nextLocked(dest)
|
||||
hasMore, err := c.nextLocked(dest, true)
|
||||
if c.handleErrorLocked(err) != nil {
|
||||
c.mu.Unlock()
|
||||
c.Close()
|
||||
@@ -178,68 +179,21 @@ func (c *Cursor) Next(dest interface{}) bool {
|
||||
return hasMore
|
||||
}
|
||||
|
||||
func (c *Cursor) nextLocked(dest interface{}) (bool, error) {
|
||||
func (c *Cursor) nextLocked(dest interface{}, progressCursor bool) (bool, error) {
|
||||
for {
|
||||
if c.lastErr != nil {
|
||||
return false, c.lastErr
|
||||
if err := c.seekCursor(true); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
// Check if response is closed/finished
|
||||
if len(c.buffer) == 0 && len(c.responses) == 0 && c.closed {
|
||||
return false, errCursorClosed
|
||||
}
|
||||
|
||||
if len(c.buffer) == 0 && len(c.responses) == 0 && !c.finished {
|
||||
c.mu.Unlock()
|
||||
err := c.fetchMore()
|
||||
c.mu.Lock()
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
// Check if cursor was closed while fetching results
|
||||
if c.closed {
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
|
||||
if len(c.buffer) == 0 && len(c.responses) == 0 && c.finished {
|
||||
if len(c.buffer) == 0 && c.finished {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
if len(c.buffer) == 0 && len(c.responses) > 0 {
|
||||
var response json.RawMessage
|
||||
response, c.responses = c.responses[0], c.responses[1:]
|
||||
|
||||
var value interface{}
|
||||
decoder := json.NewDecoder(bytes.NewBuffer(response))
|
||||
if c.conn.opts.UseJSONNumber {
|
||||
decoder.UseNumber()
|
||||
}
|
||||
err := decoder.Decode(&value)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
value, err = recursivelyConvertPseudotype(value, c.opts)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
// If response is an ATOM then try and convert to an array
|
||||
if data, ok := value.([]interface{}); ok && c.isAtom {
|
||||
for _, v := range data {
|
||||
c.buffer = append(c.buffer, v)
|
||||
}
|
||||
} else if value == nil {
|
||||
c.buffer = append(c.buffer, nil)
|
||||
} else {
|
||||
c.buffer = append(c.buffer, value)
|
||||
}
|
||||
}
|
||||
|
||||
if len(c.buffer) > 0 {
|
||||
var data interface{}
|
||||
data, c.buffer = c.buffer[0], c.buffer[1:]
|
||||
data := c.buffer[0]
|
||||
if progressCursor {
|
||||
c.buffer = c.buffer[1:]
|
||||
}
|
||||
|
||||
err := encoding.Decode(dest, data)
|
||||
if err != nil {
|
||||
@@ -251,7 +205,56 @@ func (c *Cursor) nextLocked(dest interface{}) (bool, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// Next retrieves the next raw response from the result set, blocking if necessary.
|
||||
// Peek behaves similarly to Next, retreiving the next document from the result set
|
||||
// and blocking if necessary. Peek, however, does not progress the position of the cursor.
|
||||
// This can be useful for expressions which can return different types to attempt to
|
||||
// decode them into different interfaces.
|
||||
//
|
||||
// Like Next, it will also automatically retrieve another batch of documents from
|
||||
// the server when the current one is exhausted, or before that in background
|
||||
// if possible.
|
||||
//
|
||||
// Unlike Next, Peek does not progress the position of the cursor. Peek
|
||||
// will return errors from decoding, but they will not be persisted in the cursor
|
||||
// and therefore will not be available on cursor.Err(). This can be useful for
|
||||
// expressions that can return different types to attempt to decode them into
|
||||
// different interfaces.
|
||||
//
|
||||
// Peek returns true if a document was successfully unmarshalled onto result,
|
||||
// and false at the end of the result set or if an error happened. Peek also
|
||||
// returns the error (if any) that occured
|
||||
func (c *Cursor) Peek(dest interface{}) (bool, error) {
|
||||
c.mu.Lock()
|
||||
if c.closed {
|
||||
c.mu.Unlock()
|
||||
return false, nil
|
||||
}
|
||||
|
||||
hasMore, err := c.nextLocked(dest, false)
|
||||
if _, isDecodeErr := err.(*encoding.DecodeTypeError); isDecodeErr {
|
||||
c.mu.Unlock()
|
||||
return false, err
|
||||
}
|
||||
|
||||
if c.handleErrorLocked(err) != nil {
|
||||
c.mu.Unlock()
|
||||
c.Close()
|
||||
return false, err
|
||||
}
|
||||
c.mu.Unlock()
|
||||
|
||||
return hasMore, nil
|
||||
}
|
||||
|
||||
// Skip progresses the cursor by one record. It is useful after a successful
|
||||
// Peek to avoid duplicate decoding work.
|
||||
func (c *Cursor) Skip() {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
c.pendingSkips++
|
||||
}
|
||||
|
||||
// NextResponse retrieves the next raw response from the result set, blocking if necessary.
|
||||
// Unlike Next the returned response is the raw JSON document returned from the
|
||||
// database.
|
||||
//
|
||||
@@ -281,26 +284,8 @@ func (c *Cursor) NextResponse() ([]byte, bool) {
|
||||
|
||||
func (c *Cursor) nextResponseLocked() ([]byte, bool, error) {
|
||||
for {
|
||||
if c.lastErr != nil {
|
||||
return nil, false, c.lastErr
|
||||
}
|
||||
|
||||
// Check if response is closed/finished
|
||||
if len(c.responses) == 0 && c.closed {
|
||||
return nil, false, errCursorClosed
|
||||
}
|
||||
|
||||
if len(c.responses) == 0 && !c.finished {
|
||||
c.mu.Unlock()
|
||||
err := c.fetchMore()
|
||||
c.mu.Lock()
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
// Check if cursor was closed while fetching results
|
||||
if c.closed {
|
||||
return nil, false, nil
|
||||
}
|
||||
if err := c.seekCursor(false); err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
if len(c.responses) == 0 && c.finished {
|
||||
@@ -467,13 +452,11 @@ func (c *Cursor) IsNil() bool {
|
||||
func (c *Cursor) fetchMore() error {
|
||||
var err error
|
||||
|
||||
c.mu.Lock()
|
||||
fetching := c.fetching
|
||||
closed := c.closed
|
||||
|
||||
if !fetching {
|
||||
c.fetching = true
|
||||
c.mu.Unlock()
|
||||
|
||||
if closed {
|
||||
return errCursorClosed
|
||||
@@ -484,9 +467,9 @@ func (c *Cursor) fetchMore() error {
|
||||
Token: c.token,
|
||||
}
|
||||
|
||||
_, _, err = c.conn.Query(q)
|
||||
} else {
|
||||
c.mu.Unlock()
|
||||
_, _, err = c.conn.Query(q)
|
||||
c.mu.Lock()
|
||||
}
|
||||
|
||||
return err
|
||||
@@ -527,3 +510,110 @@ func (c *Cursor) extendLocked(response *Response) {
|
||||
|
||||
putResponse(response)
|
||||
}
|
||||
|
||||
// seekCursor takes care of loading more data if needed and applying pending skips
|
||||
//
|
||||
// bufferResponse determines whether the response will be parsed into the buffer
|
||||
func (c *Cursor) seekCursor(bufferResponse bool) error {
|
||||
if c.lastErr != nil {
|
||||
return c.lastErr
|
||||
}
|
||||
|
||||
if len(c.buffer) == 0 && len(c.responses) == 0 && c.closed {
|
||||
return errCursorClosed
|
||||
}
|
||||
|
||||
// Loop over loading data, applying skips as necessary and loading more data as needed
|
||||
// until either the cursor is closed or finished, or we have applied all outstanding
|
||||
// skips and data is available
|
||||
for {
|
||||
c.applyPendingSkips(bufferResponse) // if we are buffering the responses, skip can drain from the buffer
|
||||
|
||||
if bufferResponse && len(c.buffer) == 0 && len(c.responses) > 0 {
|
||||
if err := c.bufferNextResponse(); err != nil {
|
||||
return err
|
||||
}
|
||||
continue // go around the loop again to re-apply pending skips
|
||||
} else if len(c.buffer) == 0 && len(c.responses) == 0 && !c.finished && !c.closed {
|
||||
// We skipped all of our data, load some more
|
||||
if err := c.fetchMore(); err != nil {
|
||||
return err
|
||||
}
|
||||
continue // go around the loop again to re-apply pending skips
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// applyPendingSkips applies all pending skips to the buffer and
|
||||
// returns whether there are more pending skips to be applied
|
||||
//
|
||||
// if drainFromBuffer is true, we will drain from the buffer, otherwise
|
||||
// we drain from the responses
|
||||
func (c *Cursor) applyPendingSkips(drainFromBuffer bool) (stillPending bool) {
|
||||
if c.pendingSkips == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
if drainFromBuffer {
|
||||
if len(c.buffer) > c.pendingSkips {
|
||||
c.buffer = c.buffer[c.pendingSkips:]
|
||||
c.pendingSkips = 0
|
||||
return false
|
||||
}
|
||||
|
||||
c.pendingSkips -= len(c.buffer)
|
||||
c.buffer = c.buffer[:0]
|
||||
return c.pendingSkips > 0
|
||||
}
|
||||
|
||||
if len(c.responses) > c.pendingSkips {
|
||||
c.responses = c.responses[c.pendingSkips:]
|
||||
c.pendingSkips = 0
|
||||
return false
|
||||
}
|
||||
|
||||
c.pendingSkips -= len(c.responses)
|
||||
c.responses = c.responses[:0]
|
||||
return c.pendingSkips > 0
|
||||
}
|
||||
|
||||
// bufferResponse reads a single response and stores the result into the buffer
|
||||
// if the response is from an atomic response, it will check if the
|
||||
// response contains multiple records and store them all into the buffer
|
||||
func (c *Cursor) bufferNextResponse() error {
|
||||
// If there are no responses, nothing to do
|
||||
if len(c.responses) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
response := c.responses[0]
|
||||
c.responses = c.responses[1:]
|
||||
|
||||
var value interface{}
|
||||
decoder := json.NewDecoder(bytes.NewBuffer(response))
|
||||
if c.conn.opts.UseJSONNumber {
|
||||
decoder.UseNumber()
|
||||
}
|
||||
err := decoder.Decode(&value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
value, err = recursivelyConvertPseudotype(value, c.opts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// If response is an ATOM then try and convert to an array
|
||||
if data, ok := value.([]interface{}); ok && c.isAtom {
|
||||
for _, v := range data {
|
||||
c.buffer = append(c.buffer, v)
|
||||
}
|
||||
} else if value == nil {
|
||||
c.buffer = append(c.buffer, nil)
|
||||
} else {
|
||||
c.buffer = append(c.buffer, value)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
530
vendor/gopkg.in/dancannon/gorethink.v2/cursor_test.go
generated
vendored
Normal file
530
vendor/gopkg.in/dancannon/gorethink.v2/cursor_test.go
generated
vendored
Normal file
@@ -0,0 +1,530 @@
|
||||
package gorethink
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
test "gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
type object struct {
|
||||
ID int64 `gorethink:"id,omitempty"`
|
||||
Name string `gorethink:"name"`
|
||||
Attrs []attr
|
||||
}
|
||||
|
||||
type attr struct {
|
||||
Name string
|
||||
Value interface{}
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestCursorLiteral(c *test.C) {
|
||||
res, err := Expr(5).Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(res.Type(), test.Equals, "Cursor")
|
||||
|
||||
var response interface{}
|
||||
err = res.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, 5)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestCursorSlice(c *test.C) {
|
||||
res, err := Expr([]interface{}{1, 2, 3, 4, 5}).Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(res.Type(), test.Equals, "Cursor")
|
||||
|
||||
var response []interface{}
|
||||
err = res.All(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{1, 2, 3, 4, 5})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestCursorPartiallyNilSlice(c *test.C) {
|
||||
res, err := Expr(map[string]interface{}{
|
||||
"item": []interface{}{
|
||||
map[string]interface{}{"num": 1},
|
||||
nil,
|
||||
},
|
||||
}).Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(res.Type(), test.Equals, "Cursor")
|
||||
|
||||
var response map[string]interface{}
|
||||
err = res.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, map[string]interface{}{
|
||||
"item": []interface{}{
|
||||
map[string]interface{}{"num": 1},
|
||||
nil,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestCursorMap(c *test.C) {
|
||||
res, err := Expr(map[string]interface{}{
|
||||
"id": 2,
|
||||
"name": "Object 1",
|
||||
}).Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(res.Type(), test.Equals, "Cursor")
|
||||
|
||||
var response map[string]interface{}
|
||||
err = res.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, map[string]interface{}{
|
||||
"id": 2,
|
||||
"name": "Object 1",
|
||||
})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestCursorMapIntoInterface(c *test.C) {
|
||||
res, err := Expr(map[string]interface{}{
|
||||
"id": 2,
|
||||
"name": "Object 1",
|
||||
}).Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(res.Type(), test.Equals, "Cursor")
|
||||
|
||||
var response interface{}
|
||||
err = res.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, map[string]interface{}{
|
||||
"id": 2,
|
||||
"name": "Object 1",
|
||||
})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestCursorMapNested(c *test.C) {
|
||||
res, err := Expr(map[string]interface{}{
|
||||
"id": 2,
|
||||
"name": "Object 1",
|
||||
"attr": []interface{}{map[string]interface{}{
|
||||
"name": "attr 1",
|
||||
"value": "value 1",
|
||||
}},
|
||||
}).Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(res.Type(), test.Equals, "Cursor")
|
||||
|
||||
var response interface{}
|
||||
err = res.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, map[string]interface{}{
|
||||
"id": 2,
|
||||
"name": "Object 1",
|
||||
"attr": []interface{}{map[string]interface{}{
|
||||
"name": "attr 1",
|
||||
"value": "value 1",
|
||||
}},
|
||||
})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestCursorStruct(c *test.C) {
|
||||
res, err := Expr(map[string]interface{}{
|
||||
"id": 2,
|
||||
"name": "Object 1",
|
||||
"Attrs": []interface{}{map[string]interface{}{
|
||||
"Name": "attr 1",
|
||||
"Value": "value 1",
|
||||
}},
|
||||
}).Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(res.Type(), test.Equals, "Cursor")
|
||||
|
||||
var response object
|
||||
err = res.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.DeepEquals, object{
|
||||
ID: 2,
|
||||
Name: "Object 1",
|
||||
Attrs: []attr{attr{
|
||||
Name: "attr 1",
|
||||
Value: "value 1",
|
||||
}},
|
||||
})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestCursorStructPseudoTypes(c *test.C) {
|
||||
var zeroTime time.Time
|
||||
t := time.Now()
|
||||
|
||||
res, err := Expr(map[string]interface{}{
|
||||
"T": time.Unix(t.Unix(), 0).In(time.UTC),
|
||||
"Z": zeroTime,
|
||||
"B": []byte("hello"),
|
||||
}).Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
var response PseudoTypes
|
||||
err = res.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(res.Type(), test.Equals, "Cursor")
|
||||
|
||||
c.Assert(response.T.Equal(time.Unix(t.Unix(), 0)), test.Equals, true)
|
||||
c.Assert(response.Z.Equal(zeroTime), test.Equals, true)
|
||||
c.Assert(response.B, jsonEquals, []byte("hello"))
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestCursorAtomString(c *test.C) {
|
||||
res, err := Expr("a").Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(res.Type(), test.Equals, "Cursor")
|
||||
|
||||
var response string
|
||||
err = res.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, "a")
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestCursorAtomArray(c *test.C) {
|
||||
res, err := Expr([]interface{}{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}).Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(res.Type(), test.Equals, "Cursor")
|
||||
|
||||
var response []int
|
||||
err = res.All(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.DeepEquals, []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestEmptyResults(c *test.C) {
|
||||
DBCreate("test").Exec(session)
|
||||
DB("test").TableCreate("test").Exec(session)
|
||||
res, err := DB("test").Table("test").Get("missing value").Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(res.IsNil(), test.Equals, true)
|
||||
|
||||
res, err = DB("test").Table("test").Get("missing value").Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
var response interface{}
|
||||
err = res.One(&response)
|
||||
c.Assert(err, test.Equals, ErrEmptyResult)
|
||||
c.Assert(res.IsNil(), test.Equals, true)
|
||||
|
||||
res, err = Expr(nil).Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(res.IsNil(), test.Equals, true)
|
||||
|
||||
res, err = DB("test").Table("test").Get("missing value").Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(res.IsNil(), test.Equals, true)
|
||||
|
||||
res, err = DB("test").Table("test").GetAll("missing value", "another missing value").Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(res.Next(&response), test.Equals, false)
|
||||
|
||||
var obj object
|
||||
obj.Name = "missing value"
|
||||
res, err = DB("test").Table("test").Filter(obj).Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(res.IsNil(), test.Equals, true)
|
||||
|
||||
var objP *object
|
||||
|
||||
res, err = DB("test").Table("test").Get("missing value").Run(session)
|
||||
res.Next(&objP)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(objP, test.IsNil)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestCursorAll(c *test.C) {
|
||||
// Ensure table + database exist
|
||||
DBCreate("test").Exec(session)
|
||||
DB("test").TableDrop("Table3").Exec(session)
|
||||
DB("test").TableCreate("Table3").Exec(session)
|
||||
DB("test").Table("Table3").IndexCreate("num").Exec(session)
|
||||
DB("test").Table("Table3").IndexWait().Exec(session)
|
||||
|
||||
// Insert rows
|
||||
DB("test").Table("Table3").Insert([]interface{}{
|
||||
map[string]interface{}{
|
||||
"id": 2,
|
||||
"name": "Object 1",
|
||||
"Attrs": []interface{}{map[string]interface{}{
|
||||
"Name": "attr 1",
|
||||
"Value": "value 1",
|
||||
}},
|
||||
},
|
||||
map[string]interface{}{
|
||||
"id": 3,
|
||||
"name": "Object 2",
|
||||
"Attrs": []interface{}{map[string]interface{}{
|
||||
"Name": "attr 1",
|
||||
"Value": "value 1",
|
||||
}},
|
||||
},
|
||||
}).Exec(session)
|
||||
|
||||
// Test query
|
||||
query := DB("test").Table("Table3").OrderBy("id")
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
var response []object
|
||||
err = res.All(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.HasLen, 2)
|
||||
c.Assert(response, test.DeepEquals, []object{
|
||||
object{
|
||||
ID: 2,
|
||||
Name: "Object 1",
|
||||
Attrs: []attr{attr{
|
||||
Name: "attr 1",
|
||||
Value: "value 1",
|
||||
}},
|
||||
},
|
||||
object{
|
||||
ID: 3,
|
||||
Name: "Object 2",
|
||||
Attrs: []attr{attr{
|
||||
Name: "attr 1",
|
||||
Value: "value 1",
|
||||
}},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestCursorListen(c *test.C) {
|
||||
// Ensure table + database exist
|
||||
DBCreate("test").Exec(session)
|
||||
DB("test").TableDrop("Table3").Exec(session)
|
||||
DB("test").TableCreate("Table3").Exec(session)
|
||||
DB("test").Table("Table3").IndexCreate("num").Exec(session)
|
||||
DB("test").Table("Table3").IndexWait().Exec(session)
|
||||
|
||||
// Insert rows
|
||||
DB("test").Table("Table3").Insert([]interface{}{
|
||||
map[string]interface{}{
|
||||
"id": 2,
|
||||
"name": "Object 1",
|
||||
"Attrs": []interface{}{map[string]interface{}{
|
||||
"Name": "attr 1",
|
||||
"Value": "value 1",
|
||||
}},
|
||||
},
|
||||
map[string]interface{}{
|
||||
"id": 3,
|
||||
"name": "Object 2",
|
||||
"Attrs": []interface{}{map[string]interface{}{
|
||||
"Name": "attr 1",
|
||||
"Value": "value 1",
|
||||
}},
|
||||
},
|
||||
}).Exec(session)
|
||||
|
||||
// Test query
|
||||
query := DB("test").Table("Table3").OrderBy("id")
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
ch := make(chan object)
|
||||
res.Listen(ch)
|
||||
var response []object
|
||||
for v := range ch {
|
||||
response = append(response, v)
|
||||
}
|
||||
|
||||
c.Assert(response, test.HasLen, 2)
|
||||
c.Assert(response, test.DeepEquals, []object{
|
||||
object{
|
||||
ID: 2,
|
||||
Name: "Object 1",
|
||||
Attrs: []attr{attr{
|
||||
Name: "attr 1",
|
||||
Value: "value 1",
|
||||
}},
|
||||
},
|
||||
object{
|
||||
ID: 3,
|
||||
Name: "Object 2",
|
||||
Attrs: []attr{attr{
|
||||
Name: "attr 1",
|
||||
Value: "value 1",
|
||||
}},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestCursorChangesClose(c *test.C) {
|
||||
// Ensure table + database exist
|
||||
DBCreate("test").Exec(session)
|
||||
DB("test").TableDrop("Table3").Exec(session)
|
||||
DB("test").TableCreate("Table3").Exec(session)
|
||||
|
||||
// Test query
|
||||
// res, err := DB("test").Table("Table3").Changes().Run(session)
|
||||
res, err := DB("test").Table("Table3").Changes().Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(res, test.NotNil)
|
||||
|
||||
// Ensure that the cursor can be closed
|
||||
err = res.Close()
|
||||
c.Assert(err, test.IsNil)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestCursorReuseResult(c *test.C) {
|
||||
// Test query
|
||||
query := Expr([]interface{}{
|
||||
map[string]interface{}{
|
||||
"A": "a",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"B": 1,
|
||||
},
|
||||
map[string]interface{}{
|
||||
"A": "a",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"B": 1,
|
||||
},
|
||||
map[string]interface{}{
|
||||
"A": "a",
|
||||
"B": 1,
|
||||
},
|
||||
})
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
var i int
|
||||
var result SimpleT
|
||||
for res.Next(&result) {
|
||||
switch i {
|
||||
case 0:
|
||||
c.Assert(result, test.DeepEquals, SimpleT{
|
||||
A: "a",
|
||||
B: 0,
|
||||
})
|
||||
case 1:
|
||||
c.Assert(result, test.DeepEquals, SimpleT{
|
||||
A: "",
|
||||
B: 1,
|
||||
})
|
||||
case 2:
|
||||
c.Assert(result, test.DeepEquals, SimpleT{
|
||||
A: "a",
|
||||
B: 0,
|
||||
})
|
||||
case 3:
|
||||
c.Assert(result, test.DeepEquals, SimpleT{
|
||||
A: "",
|
||||
B: 1,
|
||||
})
|
||||
case 4:
|
||||
c.Assert(result, test.DeepEquals, SimpleT{
|
||||
A: "a",
|
||||
B: 1,
|
||||
})
|
||||
default:
|
||||
c.Fatalf("Unexpected number of results")
|
||||
}
|
||||
|
||||
i++
|
||||
}
|
||||
c.Assert(res.Err(), test.IsNil)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestCursorNextResponse(c *test.C) {
|
||||
res, err := Expr(5).Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(res.Type(), test.Equals, "Cursor")
|
||||
|
||||
b, ok := res.NextResponse()
|
||||
c.Assert(ok, test.Equals, true)
|
||||
c.Assert(b, jsonEquals, []byte(`5`))
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestCursorNextResponse_object(c *test.C) {
|
||||
res, err := Expr(map[string]string{"foo": "bar"}).Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(res.Type(), test.Equals, "Cursor")
|
||||
|
||||
b, ok := res.NextResponse()
|
||||
c.Assert(ok, test.Equals, true)
|
||||
c.Assert(b, jsonEquals, []byte(`{"foo":"bar"}`))
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestCursorPeek_idempotency(c *test.C) {
|
||||
res, err := Expr([]int{1, 2, 3}).Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
var result int
|
||||
|
||||
// Test idempotency
|
||||
for i := 0; i < 2; i++ {
|
||||
hasMore, err := res.Peek(&result)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(result, test.Equals, 1)
|
||||
c.Assert(hasMore, test.Equals, true)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestCursorPeek_wrong_type(c *test.C) {
|
||||
res, err := Expr([]int{1, 2, 3}).Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
// Test that wrongType doesn't break the cursor
|
||||
wrongType := struct {
|
||||
Name string
|
||||
Age int
|
||||
}{}
|
||||
|
||||
hasMore, err := res.Peek(&wrongType)
|
||||
c.Assert(err, test.NotNil)
|
||||
c.Assert(hasMore, test.Equals, false)
|
||||
c.Assert(res.Err(), test.IsNil)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestCursorPeek_usage(c *test.C) {
|
||||
res, err := Expr([]int{1, 2, 3}).Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
var result int
|
||||
|
||||
// Test that Skip progresses our cursor
|
||||
res.Skip()
|
||||
hasMore, err := res.Peek(&result)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(result, test.Equals, 2)
|
||||
c.Assert(hasMore, test.Equals, true)
|
||||
|
||||
// Test that we can use Next afterwards and we get the same result
|
||||
hasMore = res.Next(&result)
|
||||
c.Assert(result, test.Equals, 2)
|
||||
c.Assert(hasMore, test.Equals, true)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestCursorSkip(c *test.C) {
|
||||
res, err := Expr([]int{1, 2, 3}).Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
res.Skip()
|
||||
|
||||
var result int
|
||||
hasMore := res.Next(&result)
|
||||
c.Assert(result, test.Equals, 2)
|
||||
c.Assert(hasMore, test.Equals, true)
|
||||
}
|
||||
|
||||
func ExampleCursor_Peek() {
|
||||
res, err := Expr([]int{1, 2, 3}).Run(session)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
var result, altResult int
|
||||
wasRead, err := res.Peek(&result) // Result is now 1
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
} else if !wasRead {
|
||||
fmt.Print("No data to read!")
|
||||
}
|
||||
|
||||
res.Next(&altResult) // altResult is also 1, peek didn't progress the cursor
|
||||
|
||||
res.Skip() // progress the cursor, skipping 2
|
||||
res.Peek(&result) // result is now 3
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
// Package gorethink implements a Go driver for RethinkDB
|
||||
//
|
||||
// Current version: v1.4.0 (RethinkDB v2.2)
|
||||
// Current version: v2.0.0 (RethinkDB v2.3)
|
||||
// For more in depth information on how to use RethinkDB check out the API docs
|
||||
// at http://rethinkdb.com/api
|
||||
package gorethink
|
||||
466
vendor/gopkg.in/dancannon/gorethink.v2/encoding/decoder_test.go
generated
vendored
Normal file
466
vendor/gopkg.in/dancannon/gorethink.v2/encoding/decoder_test.go
generated
vendored
Normal file
@@ -0,0 +1,466 @@
|
||||
package encoding
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"image"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type T struct {
|
||||
X string
|
||||
Y int
|
||||
Z int `gorethink:"-"`
|
||||
}
|
||||
|
||||
type U struct {
|
||||
Alphabet string `gorethink:"alpha"`
|
||||
}
|
||||
|
||||
type V struct {
|
||||
F1 interface{}
|
||||
F2 int32
|
||||
F3 string
|
||||
}
|
||||
|
||||
type tx struct {
|
||||
x int
|
||||
}
|
||||
|
||||
var txType = reflect.TypeOf((*tx)(nil)).Elem()
|
||||
|
||||
// Test data structures for anonymous fields.
|
||||
|
||||
type Point struct {
|
||||
Z int
|
||||
}
|
||||
|
||||
type Top struct {
|
||||
Level0 int
|
||||
Embed0
|
||||
*Embed0a
|
||||
*Embed0b `gorethink:"e,omitempty"` // treated as named
|
||||
Embed0c `gorethink:"-"` // ignored
|
||||
Loop
|
||||
Embed0p // has Point with X, Y, used
|
||||
Embed0q // has Point with Z, used
|
||||
}
|
||||
|
||||
type Embed0 struct {
|
||||
Level1a int // overridden by Embed0a's Level1a with tag
|
||||
Level1b int // used because Embed0a's Level1b is renamed
|
||||
Level1c int // used because Embed0a's Level1c is ignored
|
||||
Level1d int // annihilated by Embed0a's Level1d
|
||||
Level1e int `gorethink:"x"` // annihilated by Embed0a.Level1e
|
||||
}
|
||||
|
||||
type Embed0a struct {
|
||||
Level1a int `gorethink:"Level1a,omitempty"`
|
||||
Level1b int `gorethink:"LEVEL1B,omitempty"`
|
||||
Level1c int `gorethink:"-"`
|
||||
Level1d int // annihilated by Embed0's Level1d
|
||||
Level1f int `gorethink:"x"` // annihilated by Embed0's Level1e
|
||||
}
|
||||
|
||||
type Embed0b Embed0
|
||||
|
||||
type Embed0c Embed0
|
||||
|
||||
type Embed0p struct {
|
||||
image.Point
|
||||
}
|
||||
|
||||
type Embed0q struct {
|
||||
Point
|
||||
}
|
||||
|
||||
type Loop struct {
|
||||
Loop1 int `gorethink:",omitempty"`
|
||||
Loop2 int `gorethink:",omitempty"`
|
||||
*Loop
|
||||
}
|
||||
|
||||
// From reflect test:
|
||||
// The X in S6 and S7 annihilate, but they also block the X in S8.S9.
|
||||
type S5 struct {
|
||||
S6
|
||||
S7
|
||||
S8
|
||||
}
|
||||
|
||||
type S6 struct {
|
||||
X int
|
||||
}
|
||||
|
||||
type S7 S6
|
||||
|
||||
type S8 struct {
|
||||
S9
|
||||
}
|
||||
|
||||
type S9 struct {
|
||||
X int
|
||||
Y int
|
||||
}
|
||||
|
||||
// From reflect test:
|
||||
// The X in S11.S6 and S12.S6 annihilate, but they also block the X in S13.S8.S9.
|
||||
type S10 struct {
|
||||
S11
|
||||
S12
|
||||
S13
|
||||
}
|
||||
|
||||
type S11 struct {
|
||||
S6
|
||||
}
|
||||
|
||||
type S12 struct {
|
||||
S6
|
||||
}
|
||||
|
||||
type S13 struct {
|
||||
S8
|
||||
}
|
||||
|
||||
type PointerBasic struct {
|
||||
X int
|
||||
Y *int
|
||||
}
|
||||
|
||||
type Pointer struct {
|
||||
PPoint *Point
|
||||
Point Point
|
||||
}
|
||||
|
||||
type decodeTest struct {
|
||||
in interface{}
|
||||
ptr interface{}
|
||||
out interface{}
|
||||
err error
|
||||
}
|
||||
|
||||
type Ambig struct {
|
||||
// Given "hello", the first match should win.
|
||||
First int `gorethink:"HELLO"`
|
||||
Second int `gorethink:"Hello"`
|
||||
}
|
||||
|
||||
// Decode test helper vars
|
||||
var (
|
||||
sampleInt = 2
|
||||
)
|
||||
|
||||
var decodeTests = []decodeTest{
|
||||
// basic types
|
||||
{in: true, ptr: new(bool), out: true},
|
||||
{in: 1, ptr: new(int), out: 1},
|
||||
{in: 1.2, ptr: new(float64), out: 1.2},
|
||||
{in: -5, ptr: new(int16), out: int16(-5)},
|
||||
{in: 2, ptr: new(string), out: string("2")},
|
||||
{in: float64(2.0), ptr: new(interface{}), out: float64(2.0)},
|
||||
{in: string("2"), ptr: new(interface{}), out: string("2")},
|
||||
{in: "a\u1234", ptr: new(string), out: "a\u1234"},
|
||||
{in: []interface{}{}, ptr: new([]string), out: []string{}},
|
||||
{in: map[string]interface{}{"X": []interface{}{1, 2, 3}, "Y": 4}, ptr: new(T), out: T{}, err: &DecodeTypeError{reflect.TypeOf(""), reflect.TypeOf([]interface{}{}), ""}},
|
||||
{in: map[string]interface{}{"x": 1}, ptr: new(tx), out: tx{}},
|
||||
{in: map[string]interface{}{"F1": float64(1), "F2": 2, "F3": 3}, ptr: new(V), out: V{F1: float64(1), F2: int32(2), F3: string("3")}},
|
||||
{in: map[string]interface{}{"F1": string("1"), "F2": 2, "F3": 3}, ptr: new(V), out: V{F1: string("1"), F2: int32(2), F3: string("3")}},
|
||||
{
|
||||
in: map[string]interface{}{"k1": int64(1), "k2": "s", "k3": []interface{}{int64(1), 2.0, 3e-3}, "k4": map[string]interface{}{"kk1": "s", "kk2": int64(2)}},
|
||||
out: map[string]interface{}{"k1": int64(1), "k2": "s", "k3": []interface{}{int64(1), 2.0, 3e-3}, "k4": map[string]interface{}{"kk1": "s", "kk2": int64(2)}},
|
||||
ptr: new(interface{}),
|
||||
},
|
||||
|
||||
// Z has a "-" tag.
|
||||
{in: map[string]interface{}{"Y": 1, "Z": 2}, ptr: new(T), out: T{Y: 1}},
|
||||
|
||||
{in: map[string]interface{}{"alpha": "abc", "alphabet": "xyz"}, ptr: new(U), out: U{Alphabet: "abc"}},
|
||||
{in: map[string]interface{}{"alpha": "abc"}, ptr: new(U), out: U{Alphabet: "abc"}},
|
||||
{in: map[string]interface{}{"alphabet": "xyz"}, ptr: new(U), out: U{}},
|
||||
|
||||
// array tests
|
||||
{in: []interface{}{1, 2, 3}, ptr: new([3]int), out: [3]int{1, 2, 3}},
|
||||
{in: []interface{}{1, 2, 3}, ptr: new([1]int), out: [1]int{1}},
|
||||
{in: []interface{}{1, 2, 3}, ptr: new([5]int), out: [5]int{1, 2, 3, 0, 0}},
|
||||
|
||||
// empty array to interface test
|
||||
{in: map[string]interface{}{"T": []interface{}{}}, ptr: new(map[string]interface{}), out: map[string]interface{}{"T": []interface{}{}}},
|
||||
|
||||
{
|
||||
in: map[string]interface{}{
|
||||
"Level0": 1,
|
||||
"Level1b": 2,
|
||||
"Level1c": 3,
|
||||
"level1d": 4,
|
||||
"Level1a": 5,
|
||||
"LEVEL1B": 6,
|
||||
"e": map[string]interface{}{
|
||||
"Level1a": 8,
|
||||
"Level1b": 9,
|
||||
"Level1c": 10,
|
||||
"Level1d": 11,
|
||||
"x": 12,
|
||||
},
|
||||
"Loop1": 13,
|
||||
"Loop2": 14,
|
||||
"X": 15,
|
||||
"Y": 16,
|
||||
"Z": 17,
|
||||
},
|
||||
ptr: new(Top),
|
||||
out: Top{
|
||||
Level0: 1,
|
||||
Embed0: Embed0{
|
||||
Level1b: 2,
|
||||
Level1c: 3,
|
||||
},
|
||||
Embed0a: &Embed0a{
|
||||
Level1a: 5,
|
||||
Level1b: 6,
|
||||
},
|
||||
Embed0b: &Embed0b{
|
||||
Level1a: 8,
|
||||
Level1b: 9,
|
||||
Level1c: 10,
|
||||
Level1d: 11,
|
||||
},
|
||||
Loop: Loop{
|
||||
Loop1: 13,
|
||||
Loop2: 14,
|
||||
},
|
||||
Embed0p: Embed0p{
|
||||
Point: image.Point{X: 15, Y: 16},
|
||||
},
|
||||
Embed0q: Embed0q{
|
||||
Point: Point{Z: 17},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
in: map[string]interface{}{"hello": 1},
|
||||
ptr: new(Ambig),
|
||||
out: Ambig{First: 1},
|
||||
},
|
||||
{
|
||||
in: map[string]interface{}{"X": 1, "Y": 2},
|
||||
ptr: new(S5),
|
||||
out: S5{S8: S8{S9: S9{Y: 2}}},
|
||||
},
|
||||
{
|
||||
in: map[string]interface{}{"X": 1, "Y": 2},
|
||||
ptr: new(S10),
|
||||
out: S10{S13: S13{S8: S8{S9: S9{Y: 2}}}},
|
||||
},
|
||||
{
|
||||
in: map[string]interface{}{"PPoint": map[string]interface{}{"Z": 1}, "Point": map[string]interface{}{"Z": 2}},
|
||||
ptr: new(Pointer),
|
||||
out: Pointer{PPoint: &Point{Z: 1}, Point: Point{Z: 2}},
|
||||
},
|
||||
{
|
||||
in: map[string]interface{}{"Point": map[string]interface{}{"Z": 2}},
|
||||
ptr: new(Pointer),
|
||||
out: Pointer{PPoint: nil, Point: Point{Z: 2}},
|
||||
},
|
||||
{
|
||||
in: map[string]interface{}{"x": 2},
|
||||
ptr: new(PointerBasic),
|
||||
out: PointerBasic{X: 2, Y: nil},
|
||||
},
|
||||
{
|
||||
in: map[string]interface{}{"x": 2, "y": 2},
|
||||
ptr: new(PointerBasic),
|
||||
out: PointerBasic{X: 2, Y: &sampleInt},
|
||||
},
|
||||
}
|
||||
|
||||
func TestDecode(t *testing.T) {
|
||||
for i, tt := range decodeTests {
|
||||
if tt.ptr == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
// v = new(right-type)
|
||||
v := reflect.New(reflect.TypeOf(tt.ptr).Elem())
|
||||
|
||||
err := Decode(v.Interface(), tt.in)
|
||||
if !jsonEqual(err, tt.err) {
|
||||
t.Errorf("#%d: got error %v want %v", i, err, tt.err)
|
||||
continue
|
||||
}
|
||||
|
||||
if tt.err == nil && !jsonEqual(v.Elem().Interface(), tt.out) {
|
||||
t.Errorf("#%d: mismatch\nhave: %+v\nwant: %+v", i, v.Elem().Interface(), tt.out)
|
||||
continue
|
||||
}
|
||||
|
||||
// Check round trip.
|
||||
if tt.err == nil {
|
||||
enc, err := Encode(v.Interface())
|
||||
if err != nil {
|
||||
t.Errorf("#%d: error re-marshaling: %v", i, err)
|
||||
continue
|
||||
}
|
||||
vv := reflect.New(reflect.TypeOf(tt.ptr).Elem())
|
||||
|
||||
if err := Decode(vv.Interface(), enc); err != nil {
|
||||
t.Errorf("#%d: error re-decodeing: %v", i, err)
|
||||
continue
|
||||
}
|
||||
if !jsonEqual(v.Elem().Interface(), vv.Elem().Interface()) {
|
||||
t.Errorf("#%d: mismatch\nhave: %#+v\nwant: %#+v", i, v.Elem().Interface(), vv.Elem().Interface())
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestStringKind(t *testing.T) {
|
||||
type aMap map[string]int
|
||||
|
||||
var m1, m2 map[string]int
|
||||
m1 = map[string]int{
|
||||
"foo": 42,
|
||||
}
|
||||
|
||||
data, err := Encode(m1)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error encoding: %v", err)
|
||||
}
|
||||
|
||||
err = Decode(&m2, data)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error decoding: %v", err)
|
||||
}
|
||||
|
||||
if !jsonEqual(m1, m2) {
|
||||
t.Error("Items should be equal after encoding and then decoding")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Test handling of unexported fields that should be ignored.
|
||||
type unexportedFields struct {
|
||||
Name string
|
||||
m map[string]interface{} `gorethink:"-"`
|
||||
m2 map[string]interface{} `gorethink:"abcd"`
|
||||
}
|
||||
|
||||
func TestDecodeUnexported(t *testing.T) {
|
||||
input := map[string]interface{}{
|
||||
"Name": "Bob",
|
||||
"m": map[string]interface{}{
|
||||
"x": 123,
|
||||
},
|
||||
"m2": map[string]interface{}{
|
||||
"y": 123,
|
||||
},
|
||||
"abcd": map[string]interface{}{
|
||||
"z": 789,
|
||||
},
|
||||
}
|
||||
want := &unexportedFields{Name: "Bob"}
|
||||
|
||||
out := &unexportedFields{}
|
||||
err := Decode(out, input)
|
||||
if err != nil {
|
||||
t.Errorf("got error %v, expected nil", err)
|
||||
}
|
||||
if !jsonEqual(out, want) {
|
||||
t.Errorf("got %q, want %q", out, want)
|
||||
}
|
||||
}
|
||||
|
||||
type Foo struct {
|
||||
FooBar interface{} `gorethink:"foobar"`
|
||||
}
|
||||
type Bar struct {
|
||||
Baz int `gorethink:"baz"`
|
||||
}
|
||||
|
||||
type UnmarshalerPointer struct {
|
||||
Value *UnmarshalerValue
|
||||
}
|
||||
|
||||
type UnmarshalerValue struct {
|
||||
ValueInt int64
|
||||
ValueString string
|
||||
}
|
||||
|
||||
func (v *UnmarshalerValue) MarshalRQL() (interface{}, error) {
|
||||
if v.ValueInt != int64(0) {
|
||||
return Encode(v.ValueInt)
|
||||
}
|
||||
if v.ValueString != "" {
|
||||
return Encode(v.ValueString)
|
||||
}
|
||||
|
||||
return Encode(nil)
|
||||
}
|
||||
|
||||
func (v *UnmarshalerValue) UnmarshalRQL(b interface{}) (err error) {
|
||||
n, s := int64(0), ""
|
||||
|
||||
if err = Decode(&s, b); err == nil {
|
||||
v.ValueString = s
|
||||
return
|
||||
}
|
||||
if err = Decode(&n, b); err == nil {
|
||||
v.ValueInt = n
|
||||
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func TestDecodeUnmarshalerPointer(t *testing.T) {
|
||||
input := map[string]interface{}{
|
||||
"Value": "abc",
|
||||
}
|
||||
want := &UnmarshalerPointer{
|
||||
Value: &UnmarshalerValue{ValueString: "abc"},
|
||||
}
|
||||
|
||||
out := &UnmarshalerPointer{}
|
||||
err := Decode(out, input)
|
||||
if err != nil {
|
||||
t.Errorf("got error %v, expected nil", err)
|
||||
}
|
||||
if !jsonEqual(out, want) {
|
||||
t.Errorf("got %q, want %q", out, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecodeMapIntKeys(t *testing.T) {
|
||||
input := map[string]int{"1": 1, "2": 2, "3": 3}
|
||||
want := map[int]int{1: 1, 2: 2, 3: 3}
|
||||
|
||||
out := map[int]int{}
|
||||
err := Decode(&out, input)
|
||||
if err != nil {
|
||||
t.Errorf("got error %v, expected nil", err)
|
||||
}
|
||||
if !jsonEqual(out, want) {
|
||||
t.Errorf("got %q, want %q", out, want)
|
||||
}
|
||||
}
|
||||
|
||||
func jsonEqual(a, b interface{}) bool {
|
||||
// First check using reflect.DeepEqual
|
||||
if reflect.DeepEqual(a, b) {
|
||||
return true
|
||||
}
|
||||
|
||||
// Then use jsonEqual
|
||||
ba, err := json.Marshal(a)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
bb, err := json.Marshal(b)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return bytes.Compare(ba, bb) == 0
|
||||
}
|
||||
349
vendor/gopkg.in/dancannon/gorethink.v2/encoding/encoder_test.go
generated
vendored
Normal file
349
vendor/gopkg.in/dancannon/gorethink.v2/encoding/encoder_test.go
generated
vendored
Normal file
@@ -0,0 +1,349 @@
|
||||
package encoding
|
||||
|
||||
import (
|
||||
"image"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
var encodeExpected = map[string]interface{}{
|
||||
"Level0": int64(1),
|
||||
"Level1b": int64(2),
|
||||
"Level1c": int64(3),
|
||||
"Level1a": int64(5),
|
||||
"LEVEL1B": int64(6),
|
||||
"e": map[string]interface{}{
|
||||
"Level1a": int64(8),
|
||||
"Level1b": int64(9),
|
||||
"Level1c": int64(10),
|
||||
"Level1d": int64(11),
|
||||
"x": int64(12),
|
||||
},
|
||||
"Loop1": int64(13),
|
||||
"Loop2": int64(14),
|
||||
"X": int64(15),
|
||||
"Y": int64(16),
|
||||
"Z": int64(17),
|
||||
}
|
||||
|
||||
func TestEncode(t *testing.T) {
|
||||
// Top is defined in decoder_test.go
|
||||
var in = Top{
|
||||
Level0: 1,
|
||||
Embed0: Embed0{
|
||||
Level1b: 2,
|
||||
Level1c: 3,
|
||||
},
|
||||
Embed0a: &Embed0a{
|
||||
Level1a: 5,
|
||||
Level1b: 6,
|
||||
},
|
||||
Embed0b: &Embed0b{
|
||||
Level1a: 8,
|
||||
Level1b: 9,
|
||||
Level1c: 10,
|
||||
Level1d: 11,
|
||||
Level1e: 12,
|
||||
},
|
||||
Loop: Loop{
|
||||
Loop1: 13,
|
||||
Loop2: 14,
|
||||
},
|
||||
Embed0p: Embed0p{
|
||||
Point: image.Point{X: 15, Y: 16},
|
||||
},
|
||||
Embed0q: Embed0q{
|
||||
Point: Point{Z: 17},
|
||||
},
|
||||
}
|
||||
|
||||
got, err := Encode(&in)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !reflect.DeepEqual(got, encodeExpected) {
|
||||
t.Errorf(" got: %v\nwant: %v\n", got, encodeExpected)
|
||||
}
|
||||
}
|
||||
|
||||
type Optionals struct {
|
||||
Sr string `gorethink:"sr"`
|
||||
So string `gorethink:"so,omitempty"`
|
||||
Sw string `gorethink:"-"`
|
||||
|
||||
Ir int `gorethink:"omitempty"` // actually named omitempty, not an option
|
||||
Io int `gorethink:"io,omitempty"`
|
||||
|
||||
Tr time.Time `gorethink:"tr"`
|
||||
To time.Time `gorethink:"to,omitempty"`
|
||||
|
||||
Slr []string `gorethink:"slr"`
|
||||
Slo []string `gorethink:"slo,omitempty"`
|
||||
|
||||
Mr map[string]interface{} `gorethink:"mr"`
|
||||
Mo map[string]interface{} `gorethink:",omitempty"`
|
||||
}
|
||||
|
||||
var optionalsExpected = map[string]interface{}{
|
||||
"sr": "",
|
||||
"omitempty": int64(0),
|
||||
"tr": map[string]interface{}{"$reql_type$": "TIME", "epoch_time": 0, "timezone": "+00:00"},
|
||||
"slr": []interface{}{},
|
||||
"mr": map[string]interface{}{},
|
||||
}
|
||||
|
||||
func TestOmitEmpty(t *testing.T) {
|
||||
var o Optionals
|
||||
o.Sw = "something"
|
||||
o.Tr = time.Unix(0, 0).In(time.UTC)
|
||||
o.Mr = map[string]interface{}{}
|
||||
o.Mo = map[string]interface{}{}
|
||||
|
||||
got, err := Encode(&o)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !jsonEqual(got, optionalsExpected) {
|
||||
t.Errorf("\ngot: %#v\nwant: %#v\n", got, optionalsExpected)
|
||||
}
|
||||
}
|
||||
|
||||
type IntType int
|
||||
|
||||
type MyStruct struct {
|
||||
IntType
|
||||
}
|
||||
|
||||
func TestAnonymousNonstruct(t *testing.T) {
|
||||
var i IntType = 11
|
||||
a := MyStruct{i}
|
||||
var want = map[string]interface{}{"IntType": int64(11)}
|
||||
|
||||
got, err := Encode(a)
|
||||
if err != nil {
|
||||
t.Fatalf("Encode: %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(got, want) {
|
||||
t.Errorf("got %v, want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncodePointer(t *testing.T) {
|
||||
v := Pointer{PPoint: &Point{Z: 1}, Point: Point{Z: 2}}
|
||||
var want = map[string]interface{}{
|
||||
"PPoint": map[string]interface{}{"Z": int64(1)},
|
||||
"Point": map[string]interface{}{"Z": int64(2)},
|
||||
}
|
||||
|
||||
got, err := Encode(v)
|
||||
if err != nil {
|
||||
t.Fatalf("Encode: %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(got, want) {
|
||||
t.Errorf("got %v, want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncodeNilPointer(t *testing.T) {
|
||||
v := Pointer{PPoint: nil, Point: Point{Z: 2}}
|
||||
var want = map[string]interface{}{
|
||||
"PPoint": nil,
|
||||
"Point": map[string]interface{}{"Z": int64(2)},
|
||||
}
|
||||
|
||||
got, err := Encode(v)
|
||||
if err != nil {
|
||||
t.Fatalf("Encode: %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(got, want) {
|
||||
t.Errorf("got %v, want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
type BugA struct {
|
||||
S string
|
||||
}
|
||||
|
||||
type BugB struct {
|
||||
BugA
|
||||
S string
|
||||
}
|
||||
|
||||
type BugC struct {
|
||||
S string
|
||||
}
|
||||
|
||||
// Legal Go: We never use the repeated embedded field (S).
|
||||
type BugX struct {
|
||||
A int
|
||||
BugA
|
||||
BugB
|
||||
}
|
||||
|
||||
// Issue 5245.
|
||||
func TestEmbeddedBug(t *testing.T) {
|
||||
v := BugB{
|
||||
BugA{"A"},
|
||||
"B",
|
||||
}
|
||||
got, err := Encode(v)
|
||||
if err != nil {
|
||||
t.Fatal("Encode:", err)
|
||||
}
|
||||
want := map[string]interface{}{"S": "B"}
|
||||
if !reflect.DeepEqual(got, want) {
|
||||
t.Fatalf("Encode: got %v want %v", got, want)
|
||||
}
|
||||
// Now check that the duplicate field, S, does not appear.
|
||||
x := BugX{
|
||||
A: 23,
|
||||
}
|
||||
got, err = Encode(x)
|
||||
if err != nil {
|
||||
t.Fatal("Encode:", err)
|
||||
}
|
||||
want = map[string]interface{}{"A": int64(23)}
|
||||
if !reflect.DeepEqual(got, want) {
|
||||
t.Fatalf("Encode: got %v want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
type BugD struct { // Same as BugA after tagging.
|
||||
XXX string `gorethink:"S"`
|
||||
}
|
||||
|
||||
// BugD's tagged S field should dominate BugA's.
|
||||
type BugY struct {
|
||||
BugA
|
||||
BugD
|
||||
}
|
||||
|
||||
// Test that a field with a tag dominates untagged fields.
|
||||
func TestTaggedFieldDominates(t *testing.T) {
|
||||
v := BugY{
|
||||
BugA{"BugA"},
|
||||
BugD{"BugD"},
|
||||
}
|
||||
got, err := Encode(v)
|
||||
if err != nil {
|
||||
t.Fatal("Encode:", err)
|
||||
}
|
||||
want := map[string]interface{}{"S": "BugD"}
|
||||
if !reflect.DeepEqual(got, want) {
|
||||
t.Fatalf("Encode: got %v want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
// There are no tags here, so S should not appear.
|
||||
type BugZ struct {
|
||||
BugA
|
||||
BugC
|
||||
BugY // Contains a tagged S field through BugD; should not dominate.
|
||||
}
|
||||
|
||||
func TestDuplicatedFieldDisappears(t *testing.T) {
|
||||
v := BugZ{
|
||||
BugA{"BugA"},
|
||||
BugC{"BugC"},
|
||||
BugY{
|
||||
BugA{"nested BugA"},
|
||||
BugD{"nested BugD"},
|
||||
},
|
||||
}
|
||||
got, err := Encode(v)
|
||||
if err != nil {
|
||||
t.Fatal("Encode:", err)
|
||||
}
|
||||
want := map[string]interface{}{}
|
||||
if !reflect.DeepEqual(got, want) {
|
||||
t.Fatalf("Encode: got %v want %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncodeMapIntKeys(t *testing.T) {
|
||||
input := map[int]int{1: 1, 2: 2, 3: 3}
|
||||
want := map[string]int{"1": 1, "2": 2, "3": 3}
|
||||
|
||||
out, err := Encode(input)
|
||||
if err != nil {
|
||||
t.Errorf("got error %v, expected nil", err)
|
||||
}
|
||||
if !jsonEqual(out, want) {
|
||||
t.Errorf("got %q, want %q", out, want)
|
||||
}
|
||||
}
|
||||
|
||||
type RefA struct {
|
||||
ID string `gorethink:"id,omitempty"`
|
||||
B *RefB `gorethink:"b_id,reference" gorethink_ref:"id"`
|
||||
}
|
||||
|
||||
type RefB struct {
|
||||
ID string `gorethink:"id,omitempty"`
|
||||
Name string `gorethink:"name"`
|
||||
}
|
||||
|
||||
func TestReferenceField(t *testing.T) {
|
||||
input := RefA{"1", &RefB{"2", "Name"}}
|
||||
want := map[string]interface{}{"id": "1", "b_id": "2"}
|
||||
|
||||
out, err := Encode(input)
|
||||
if err != nil {
|
||||
t.Errorf("got error %v, expected nil", err)
|
||||
}
|
||||
if !jsonEqual(out, want) {
|
||||
t.Errorf("got %q, want %q", out, want)
|
||||
}
|
||||
}
|
||||
|
||||
type RefC struct {
|
||||
ID string `gorethink:"id,omitempty"`
|
||||
B *RefB `gorethink:"b_id,reference" gorethink_ref:"b_id"`
|
||||
}
|
||||
|
||||
func TestReferenceFieldMissing(t *testing.T) {
|
||||
input := RefC{"1", &RefB{"2", "Name"}}
|
||||
|
||||
_, err := Encode(input)
|
||||
if err == nil {
|
||||
t.Errorf("expected non-nil error but got nil")
|
||||
}
|
||||
}
|
||||
|
||||
type RefD struct {
|
||||
ID string `gorethink:"id,omitempty"`
|
||||
B string `gorethink:"b_id,reference" gorethink_ref:"b_id"`
|
||||
}
|
||||
|
||||
func TestReferenceFieldInvalid(t *testing.T) {
|
||||
input := RefD{"1", "B"}
|
||||
|
||||
_, err := Encode(input)
|
||||
if err == nil {
|
||||
t.Errorf("expected non-nil error but got nil")
|
||||
}
|
||||
}
|
||||
|
||||
type RefE struct {
|
||||
ID string `gorethink:"id,omitempty"`
|
||||
FIDs *[]RefF `gorethink:"f_ids,reference" gorethink_ref:"id"`
|
||||
}
|
||||
|
||||
type RefF struct {
|
||||
ID string `gorethink:"id,omitempty"`
|
||||
Name string `gorethink:"name"`
|
||||
}
|
||||
|
||||
func TestReferenceFieldArray(t *testing.T) {
|
||||
input := RefE{"1", &[]RefF{RefF{"2", "Name2"}, RefF{"3", "Name3"}}}
|
||||
want := map[string]interface{}{"id": "1", "f_ids": []string{"2", "3"}}
|
||||
|
||||
out, err := Encode(input)
|
||||
if err != nil {
|
||||
t.Errorf("got error %v, expected nil", err)
|
||||
}
|
||||
if !jsonEqual(out, want) {
|
||||
t.Errorf("got %q, want %q", out, want)
|
||||
}
|
||||
}
|
||||
@@ -49,6 +49,12 @@ func newTypeEncoder(t reflect.Type, allowAddr bool) encoderFunc {
|
||||
return newArrayEncoder(t)
|
||||
case reflect.Ptr:
|
||||
return newPtrEncoder(t)
|
||||
case reflect.Func:
|
||||
// functions are a special case as they can be used internally for
|
||||
// optional arguments. Just return the raw function, if somebody tries
|
||||
// to pass a function to the database the JSON marshaller will catch this
|
||||
// anyway.
|
||||
return funcEncoder
|
||||
default:
|
||||
return unsupportedTypeEncoder
|
||||
}
|
||||
@@ -120,6 +126,13 @@ func interfaceEncoder(v reflect.Value) interface{} {
|
||||
return encode(v.Elem())
|
||||
}
|
||||
|
||||
func funcEncoder(v reflect.Value) interface{} {
|
||||
if v.IsNil() {
|
||||
return nil
|
||||
}
|
||||
return v.Interface()
|
||||
}
|
||||
|
||||
func asStringEncoder(v reflect.Value) interface{} {
|
||||
return fmt.Sprintf("%v", v.Interface())
|
||||
}
|
||||
@@ -135,7 +148,6 @@ type structEncoder struct {
|
||||
|
||||
func (se *structEncoder) encode(v reflect.Value) interface{} {
|
||||
m := make(map[string]interface{})
|
||||
|
||||
for i, f := range se.fields {
|
||||
fv := fieldByIndex(v, f.index)
|
||||
if !fv.IsValid() || f.omitEmpty && se.isEmptyValue(fv) {
|
||||
@@ -146,27 +158,8 @@ func (se *structEncoder) encode(v reflect.Value) interface{} {
|
||||
|
||||
// If this field is a referenced field then attempt to extract the value.
|
||||
if f.reference {
|
||||
refName := f.name
|
||||
if f.refName != "" {
|
||||
refName = f.refName
|
||||
}
|
||||
|
||||
// referenced fields can only handle maps so return an error if the
|
||||
// encoded field is of a different type
|
||||
m, ok := encField.(map[string]interface{})
|
||||
if !ok {
|
||||
err := fmt.Errorf("Error referencing field %s in %s, expected object but got %t", refName, f.name, encField)
|
||||
panic(&MarshalerError{v.Type(), err})
|
||||
}
|
||||
|
||||
refVal, ok := m[refName]
|
||||
if !ok {
|
||||
err := fmt.Errorf("Error referencing field %s in %s, could not find referenced field", refName, f.name)
|
||||
panic(&MarshalerError{v.Type(), err})
|
||||
}
|
||||
|
||||
// Override the encoded field with the referenced field
|
||||
encField = refVal
|
||||
encField = getReferenceField(f, v, encField)
|
||||
}
|
||||
|
||||
m[f.name] = encField
|
||||
@@ -175,6 +168,40 @@ func (se *structEncoder) encode(v reflect.Value) interface{} {
|
||||
return m
|
||||
}
|
||||
|
||||
func getReferenceField(f field, v reflect.Value, encField interface{}) interface{} {
|
||||
refName := f.name
|
||||
if f.refName != "" {
|
||||
refName = f.refName
|
||||
}
|
||||
|
||||
encFields, isArray := encField.([]interface{})
|
||||
if isArray {
|
||||
refVals := make([]interface{}, len(encFields))
|
||||
for i, e := range encFields {
|
||||
refVals[i] = extractValue(e, v, f.name, refName)
|
||||
}
|
||||
return refVals
|
||||
}
|
||||
refVal := extractValue(encField, v, f.name, refName)
|
||||
return refVal
|
||||
}
|
||||
|
||||
func extractValue(encField interface{}, v reflect.Value, name string, refName string) interface{} {
|
||||
// referenced fields can only handle maps so return an error if the
|
||||
// encoded field is of a different type
|
||||
m, ok := encField.(map[string]interface{})
|
||||
if !ok {
|
||||
err := fmt.Errorf("Error refing field %s in %s, expected object but got %t", refName, name, encField)
|
||||
panic(&MarshalerError{v.Type(), err})
|
||||
}
|
||||
refVal, ok := m[refName]
|
||||
if !ok {
|
||||
err := fmt.Errorf("Error refing field %s in %s, could not find referenced field", refName, name)
|
||||
panic(&MarshalerError{v.Type(), err})
|
||||
}
|
||||
return refVal
|
||||
}
|
||||
|
||||
func (se *structEncoder) isEmptyValue(v reflect.Value) bool {
|
||||
if v.Type() == timeType {
|
||||
return v.Interface().(time.Time) == time.Time{}
|
||||
6
vendor/gopkg.in/dancannon/gorethink.v2/encoding/encoding_test.go
generated
vendored
Normal file
6
vendor/gopkg.in/dancannon/gorethink.v2/encoding/encoding_test.go
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
package encoding
|
||||
|
||||
import (
|
||||
// Import gocheck so that flag are setup (but unused)
|
||||
_ "gopkg.in/check.v1"
|
||||
)
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
p "github.com/dancannon/gorethink/ql2"
|
||||
p "gopkg.in/dancannon/gorethink.v2/ql2"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -164,11 +164,19 @@ func createRuntimeError(errorType p.Response_ErrorType, response *Response, term
|
||||
// IsConflictErr returns true if the error is non-nil and the query failed
|
||||
// due to a duplicate primary key.
|
||||
func IsConflictErr(err error) bool {
|
||||
if err == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return strings.HasPrefix(err.Error(), "Duplicate primary key")
|
||||
}
|
||||
|
||||
// IsTypeErr returns true if the error is non-nil and the query failed due
|
||||
// to a type error.
|
||||
func IsTypeErr(err error) bool {
|
||||
if err == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return strings.HasPrefix(err.Error(), "Expected type")
|
||||
}
|
||||
135
vendor/gopkg.in/dancannon/gorethink.v2/example_query_aggregation_test.go
generated
vendored
Normal file
135
vendor/gopkg.in/dancannon/gorethink.v2/example_query_aggregation_test.go
generated
vendored
Normal file
@@ -0,0 +1,135 @@
|
||||
package gorethink
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Group games by player.
|
||||
func ExampleTerm_Group() {
|
||||
cur, err := DB("examples").Table("games").Group("player").Run(session)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
var res []interface{}
|
||||
err = cur.All(&res)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Print(res)
|
||||
}
|
||||
|
||||
// Group games by the index type.
|
||||
func ExampleTerm_GroupByIndex() {
|
||||
cur, err := DB("examples").Table("games").GroupByIndex("type").Run(session)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
var res []interface{}
|
||||
err = cur.All(&res)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Print(res)
|
||||
}
|
||||
|
||||
// Suppose that the table games2 has the following data:
|
||||
//
|
||||
// [
|
||||
// { id: 1, matches: {'a': [1, 2, 3], 'b': [4, 5, 6]} },
|
||||
// { id: 2, matches: {'b': [100], 'c': [7, 8, 9]} },
|
||||
// { id: 3, matches: {'a': [10, 20], 'c': [70, 80]} }
|
||||
// ]
|
||||
// Using MultiGroup we can group data by match A, B or C.
|
||||
func ExampleTerm_MultiGroup() {
|
||||
cur, err := DB("examples").Table("games2").MultiGroup(Row.Field("matches").Keys()).Run(session)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
var res []interface{}
|
||||
err = cur.All(&res)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Print(res)
|
||||
}
|
||||
|
||||
// Ungrouping grouped data.
|
||||
func ExampleTerm_Ungroup() {
|
||||
cur, err := DB("examples").Table("games").
|
||||
Group("player").
|
||||
Max("points").Field("points").
|
||||
Ungroup().
|
||||
Run(session)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
var res []interface{}
|
||||
err = cur.All(&res)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Print(res)
|
||||
}
|
||||
|
||||
// Return the number of documents in the table posts.
|
||||
func ExampleTerm_Reduce() {
|
||||
cur, err := DB("examples").Table("posts").
|
||||
Map(func(doc Term) interface{} {
|
||||
return 1
|
||||
}).
|
||||
Reduce(func(left, right Term) interface{} {
|
||||
return left.Add(right)
|
||||
}).
|
||||
Run(session)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
var res int
|
||||
err = cur.One(&res)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Print(res)
|
||||
}
|
||||
|
||||
// Concatenate words from a list.
|
||||
func ExampleTerm_Fold() {
|
||||
cur, err := Expr([]string{"a", "b", "c"}).Fold("", func(acc, word Term) Term {
|
||||
return acc.Add(Branch(acc.Eq(""), "", ", ")).Add(word)
|
||||
}).Run(session)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
var res string
|
||||
err = cur.One(&res)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Print(res)
|
||||
// Output:
|
||||
// a, b, c
|
||||
}
|
||||
240
vendor/gopkg.in/dancannon/gorethink.v2/example_query_control_test.go
generated
vendored
Normal file
240
vendor/gopkg.in/dancannon/gorethink.v2/example_query_control_test.go
generated
vendored
Normal file
@@ -0,0 +1,240 @@
|
||||
package gorethink
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Return heroes and superheroes.
|
||||
func ExampleBranch() {
|
||||
cur, err := DB("examples").Table("marvel").OrderBy("name").Map(Branch(
|
||||
Row.Field("victories").Gt(100),
|
||||
Row.Field("name").Add(" is a superhero"),
|
||||
Row.Field("name").Add(" is a hero"),
|
||||
)).Run(session)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
var strs []string
|
||||
err = cur.All(&strs)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, str := range strs {
|
||||
fmt.Println(str)
|
||||
}
|
||||
|
||||
// Output:
|
||||
// Iron Man is a superhero
|
||||
// Jubilee is a hero
|
||||
}
|
||||
|
||||
// Return an error
|
||||
func ExampleError() {
|
||||
err := Error("this is a runtime error").Exec(session)
|
||||
fmt.Println(err)
|
||||
}
|
||||
|
||||
// Suppose we want to retrieve the titles and authors of the table posts. In the
|
||||
// case where the author field is missing or null, we want to retrieve the
|
||||
// string "Anonymous".
|
||||
func ExampleTerm_Default() {
|
||||
cur, err := DB("examples").Table("posts").Map(map[string]interface{}{
|
||||
"title": Row.Field("title"),
|
||||
"author": Row.Field("author").Default("Anonymous"),
|
||||
}).Run(session)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
var res map[string]interface{}
|
||||
err = cur.One(&res)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Print(res)
|
||||
}
|
||||
|
||||
// Convert a Go integer to a ReQL object
|
||||
func ExampleExpr_int() {
|
||||
cur, err := Expr(1).Run(session)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
var res interface{}
|
||||
err = cur.One(&res)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
jsonPrint(res)
|
||||
|
||||
// Output: 1
|
||||
}
|
||||
|
||||
// Convert a Go slice to a ReQL object
|
||||
func ExampleExpr_slice() {
|
||||
cur, err := Expr([]int{1, 2, 3}).Run(session)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
var res []interface{}
|
||||
err = cur.All(&res)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
jsonPrint(res)
|
||||
|
||||
// Output:
|
||||
// [
|
||||
// 1,
|
||||
// 2,
|
||||
// 3
|
||||
// ]
|
||||
}
|
||||
|
||||
// Convert a Go slice to a ReQL object
|
||||
func ExampleExpr_map() {
|
||||
cur, err := Expr(map[string]interface{}{
|
||||
"a": 1,
|
||||
"b": "b",
|
||||
}).Run(session)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
var res interface{}
|
||||
err = cur.One(&res)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
jsonPrint(res)
|
||||
|
||||
// Output:
|
||||
// {
|
||||
// "a": 1,
|
||||
// "b": "b"
|
||||
// }
|
||||
}
|
||||
|
||||
// Convert a Go slice to a ReQL object
|
||||
func ExampleExpr_struct() {
|
||||
type ExampleTypeNested struct {
|
||||
N int
|
||||
}
|
||||
|
||||
type ExampleTypeEmbed struct {
|
||||
C string
|
||||
}
|
||||
|
||||
type ExampleTypeA struct {
|
||||
ExampleTypeEmbed
|
||||
|
||||
A int
|
||||
B string
|
||||
Nested ExampleTypeNested
|
||||
}
|
||||
|
||||
cur, err := Expr(ExampleTypeA{
|
||||
A: 1,
|
||||
B: "b",
|
||||
ExampleTypeEmbed: ExampleTypeEmbed{
|
||||
C: "c",
|
||||
},
|
||||
Nested: ExampleTypeNested{
|
||||
N: 2,
|
||||
},
|
||||
}).Run(session)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
var res interface{}
|
||||
err = cur.One(&res)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
jsonPrint(res)
|
||||
|
||||
// Output:
|
||||
// {
|
||||
// "A": 1,
|
||||
// "B": "b",
|
||||
// "C": "c",
|
||||
// "Nested": {
|
||||
// "N": 2
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
// Convert a Go struct (with gorethink tags) to a ReQL object. The tags allow
|
||||
// the field names to be changed.
|
||||
func ExampleExpr_structTags() {
|
||||
type ExampleType struct {
|
||||
A int `gorethink:"field_a"`
|
||||
B string `gorethink:"field_b"`
|
||||
}
|
||||
|
||||
cur, err := Expr(ExampleType{
|
||||
A: 1,
|
||||
B: "b",
|
||||
}).Run(session)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
var res interface{}
|
||||
err = cur.One(&res)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
jsonPrint(res)
|
||||
|
||||
// Output:
|
||||
// {
|
||||
// "field_a": 1,
|
||||
// "field_b": "b"
|
||||
// }
|
||||
}
|
||||
|
||||
// Execute a raw JSON query
|
||||
func ExampleRawQuery() {
|
||||
cur, err := RawQuery([]byte(`"hello world"`)).Run(session)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
var res interface{}
|
||||
err = cur.One(&res)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
jsonPrint(res)
|
||||
|
||||
// Output: "hello world"
|
||||
}
|
||||
34
vendor/gopkg.in/dancannon/gorethink.v2/example_query_db_test.go
generated
vendored
Normal file
34
vendor/gopkg.in/dancannon/gorethink.v2/example_query_db_test.go
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
package gorethink
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Create a database named ’superheroes’.
|
||||
func ExampleDBCreate() {
|
||||
resp, err := DBCreate("superheroes").RunWrite(session)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
}
|
||||
|
||||
fmt.Printf("%d DB created", resp.DBsCreated)
|
||||
// Output:
|
||||
// 1 DB created
|
||||
}
|
||||
|
||||
// Drop a database named ‘superheroes’.
|
||||
func ExampleDBDrop() {
|
||||
// Setup database + tables
|
||||
DBCreate("superheroes").Exec(session)
|
||||
DB("superheroes").TableCreate("superheroes").Exec(session)
|
||||
DB("superheroes").TableCreate("battles").Exec(session)
|
||||
|
||||
resp, err := DBDrop("superheroes").RunWrite(session)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
}
|
||||
|
||||
fmt.Printf("%d DB dropped, %d tables dropped", resp.DBsDropped, resp.TablesDropped)
|
||||
// Output:
|
||||
// 1 DB dropped, 2 tables dropped
|
||||
}
|
||||
25
vendor/gopkg.in/dancannon/gorethink.v2/example_query_manipulation_test.go
generated
vendored
Normal file
25
vendor/gopkg.in/dancannon/gorethink.v2/example_query_manipulation_test.go
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
package gorethink
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Get john's age
|
||||
func ExampleTerm_Field() {
|
||||
cur, err := DB("examples").Table("users").Get("john").Field("age").Run(session)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
var res int
|
||||
err = cur.One(&res)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Print(res)
|
||||
|
||||
// Output: 19
|
||||
}
|
||||
202
vendor/gopkg.in/dancannon/gorethink.v2/example_query_select_test.go
generated
vendored
Normal file
202
vendor/gopkg.in/dancannon/gorethink.v2/example_query_select_test.go
generated
vendored
Normal file
@@ -0,0 +1,202 @@
|
||||
package gorethink
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Find a document by ID.
|
||||
func ExampleTerm_Get() {
|
||||
// Fetch the row from the database
|
||||
res, err := DB("examples").Table("heroes").Get(2).Run(session)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
defer res.Close()
|
||||
|
||||
if res.IsNil() {
|
||||
fmt.Print("Row not found")
|
||||
return
|
||||
}
|
||||
|
||||
var hero map[string]interface{}
|
||||
err = res.One(&hero)
|
||||
if err != nil {
|
||||
fmt.Printf("Error scanning database result: %s", err)
|
||||
return
|
||||
}
|
||||
fmt.Print(hero["name"])
|
||||
|
||||
// Output: Superman
|
||||
}
|
||||
|
||||
// Find a document by ID.
|
||||
func ExampleTerm_GetAll() {
|
||||
// Fetch the row from the database
|
||||
res, err := DB("examples").Table("heroes").GetAll(2).Run(session)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
defer res.Close()
|
||||
|
||||
if res.IsNil() {
|
||||
fmt.Print("Row not found")
|
||||
return
|
||||
}
|
||||
|
||||
var hero map[string]interface{}
|
||||
err = res.One(&hero)
|
||||
if err != nil {
|
||||
fmt.Printf("Error scanning database result: %s", err)
|
||||
return
|
||||
}
|
||||
fmt.Print(hero["name"])
|
||||
|
||||
// Output: Superman
|
||||
}
|
||||
|
||||
// Find a document by ID.
|
||||
func ExampleTerm_GetAll_multiple() {
|
||||
// Fetch the row from the database
|
||||
res, err := DB("examples").Table("heroes").GetAll(1, 2).Run(session)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
defer res.Close()
|
||||
|
||||
var heroes []map[string]interface{}
|
||||
err = res.All(&heroes)
|
||||
if err != nil {
|
||||
fmt.Printf("Error scanning database result: %s", err)
|
||||
return
|
||||
}
|
||||
fmt.Print(heroes[0]["name"])
|
||||
|
||||
// Output: Superman
|
||||
}
|
||||
|
||||
// Find all document with an indexed value.
|
||||
func ExampleTerm_GetAllByIndex() {
|
||||
// Fetch the row from the database
|
||||
res, err := DB("examples").Table("heroes").GetAllByIndex("code_name", "man_of_steel").Run(session)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
defer res.Close()
|
||||
|
||||
if res.IsNil() {
|
||||
fmt.Print("Row not found")
|
||||
return
|
||||
}
|
||||
|
||||
var hero map[string]interface{}
|
||||
err = res.One(&hero)
|
||||
if err != nil {
|
||||
fmt.Printf("Error scanning database result: %s", err)
|
||||
return
|
||||
}
|
||||
fmt.Print(hero["name"])
|
||||
|
||||
// Output: Superman
|
||||
}
|
||||
|
||||
// Find a document and merge another document with it.
|
||||
func ExampleTerm_Get_merge() {
|
||||
// Fetch the row from the database
|
||||
res, err := DB("examples").Table("heroes").Get(4).Merge(map[string]interface{}{
|
||||
"powers": []string{"speed"},
|
||||
}).Run(session)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
defer res.Close()
|
||||
|
||||
if res.IsNil() {
|
||||
fmt.Print("Row not found")
|
||||
return
|
||||
}
|
||||
|
||||
var hero map[string]interface{}
|
||||
err = res.One(&hero)
|
||||
if err != nil {
|
||||
fmt.Printf("Error scanning database result: %s", err)
|
||||
return
|
||||
}
|
||||
fmt.Printf("%s: %v", hero["name"], hero["powers"])
|
||||
|
||||
// Output: The Flash: [speed]
|
||||
}
|
||||
|
||||
// Get all users who are 30 years old.
|
||||
func ExampleTerm_Filter() {
|
||||
// Fetch the row from the database
|
||||
res, err := DB("examples").Table("users").Filter(map[string]interface{}{
|
||||
"age": 30,
|
||||
}).Run(session)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
defer res.Close()
|
||||
|
||||
// Scan query result into the person variable
|
||||
var users []interface{}
|
||||
err = res.All(&users)
|
||||
if err != nil {
|
||||
fmt.Printf("Error scanning database result: %s", err)
|
||||
return
|
||||
}
|
||||
fmt.Printf("%d users", len(users))
|
||||
|
||||
// Output: 2 users
|
||||
}
|
||||
|
||||
// Get all users who are more than 25 years old.
|
||||
func ExampleTerm_Filter_row() {
|
||||
// Fetch the row from the database
|
||||
res, err := DB("examples").Table("users").Filter(Row.Field("age").Gt(25)).Run(session)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
defer res.Close()
|
||||
|
||||
// Scan query result into the person variable
|
||||
var users []interface{}
|
||||
err = res.All(&users)
|
||||
if err != nil {
|
||||
fmt.Printf("Error scanning database result: %s", err)
|
||||
return
|
||||
}
|
||||
fmt.Printf("%d users", len(users))
|
||||
|
||||
// Output: 3 users
|
||||
}
|
||||
|
||||
// Retrieve all users who have a gmail account (whose field email ends with @gmail.com).
|
||||
func ExampleTerm_Filter_function() {
|
||||
// Fetch the row from the database
|
||||
res, err := DB("examples").Table("users").Filter(func(user Term) Term {
|
||||
return user.Field("email").Match("@gmail.com$")
|
||||
}).Run(session)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
defer res.Close()
|
||||
|
||||
// Scan query result into the person variable
|
||||
var users []interface{}
|
||||
err = res.All(&users)
|
||||
if err != nil {
|
||||
fmt.Printf("Error scanning database result: %s", err)
|
||||
return
|
||||
}
|
||||
fmt.Printf("%d users", len(users))
|
||||
|
||||
// Output: 1 users
|
||||
}
|
||||
57
vendor/gopkg.in/dancannon/gorethink.v2/example_query_table_test.go
generated
vendored
Normal file
57
vendor/gopkg.in/dancannon/gorethink.v2/example_query_table_test.go
generated
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
package gorethink
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Create a table named "table" with the default settings.
|
||||
func ExampleTerm_TableCreate() {
|
||||
// Setup database
|
||||
DB("examples").TableDrop("table").Run(session)
|
||||
|
||||
response, err := DB("examples").TableCreate("table").RunWrite(session)
|
||||
if err != nil {
|
||||
Log.Fatalf("Error creating table: %s", err)
|
||||
}
|
||||
|
||||
fmt.Printf("%d table created", response.TablesCreated)
|
||||
|
||||
// Output:
|
||||
// 1 table created
|
||||
}
|
||||
|
||||
// Create a simple index based on the field name.
|
||||
func ExampleTerm_IndexCreate() {
|
||||
// Setup database
|
||||
DB("examples").TableDrop("table").Run(session)
|
||||
DB("examples").TableCreate("table").Run(session)
|
||||
|
||||
response, err := DB("examples").Table("table").IndexCreate("name").RunWrite(session)
|
||||
if err != nil {
|
||||
Log.Fatalf("Error creating index: %s", err)
|
||||
}
|
||||
|
||||
fmt.Printf("%d index created", response.Created)
|
||||
|
||||
// Output:
|
||||
// 1 index created
|
||||
}
|
||||
|
||||
// Create a compound index based on the fields first_name and last_name.
|
||||
func ExampleTerm_IndexCreate_compound() {
|
||||
// Setup database
|
||||
DB("examples").TableDrop("table").Run(session)
|
||||
DB("examples").TableCreate("table").Run(session)
|
||||
|
||||
response, err := DB("examples").Table("table").IndexCreateFunc("full_name", func(row Term) interface{} {
|
||||
return []interface{}{row.Field("first_name"), row.Field("last_name")}
|
||||
}).RunWrite(session)
|
||||
if err != nil {
|
||||
Log.Fatalf("Error creating index: %s", err)
|
||||
}
|
||||
|
||||
fmt.Printf("%d index created", response.Created)
|
||||
|
||||
// Output:
|
||||
// 1 index created
|
||||
}
|
||||
161
vendor/gopkg.in/dancannon/gorethink.v2/example_query_transformation_test.go
generated
vendored
Normal file
161
vendor/gopkg.in/dancannon/gorethink.v2/example_query_transformation_test.go
generated
vendored
Normal file
@@ -0,0 +1,161 @@
|
||||
package gorethink
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Return the first five squares.
|
||||
func ExampleTerm_Map() {
|
||||
cur, err := Expr([]int{1, 2, 3, 4, 5}).Map(func(val Term) Term {
|
||||
return val.Mul(val)
|
||||
}).Run(session)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
var res []int
|
||||
err = cur.All(&res)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Print(res)
|
||||
|
||||
// Output:
|
||||
// [1 4 9 16 25]
|
||||
}
|
||||
|
||||
// Sum the elements of three sequences.
|
||||
func ExampleMap_multipleSequences() {
|
||||
var sequence1 = []int{100, 200, 300, 400}
|
||||
var sequence2 = []int{10, 20, 30, 40}
|
||||
var sequence3 = []int{1, 2, 3, 4}
|
||||
|
||||
cur, err := Map(sequence1, sequence2, sequence3, func(val1, val2, val3 Term) Term {
|
||||
return val1.Add(val2).Add(val3)
|
||||
}).Run(session)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
var res []int
|
||||
err = cur.All(&res)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Print(res)
|
||||
|
||||
// Output:
|
||||
// [111 222 333 444]
|
||||
}
|
||||
|
||||
// Order all the posts using the index date.
|
||||
func ExampleTerm_OrderBy_index() {
|
||||
cur, err := DB("examples").Table("posts").OrderBy(OrderByOpts{
|
||||
Index: "date",
|
||||
}).Run(session)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
var res []interface{}
|
||||
err = cur.All(&res)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Print(res)
|
||||
}
|
||||
|
||||
// Order all the posts using the index date in descending order.
|
||||
func ExampleTerm_OrderBy_indexDesc() {
|
||||
cur, err := DB("examples").Table("posts").OrderBy(OrderByOpts{
|
||||
Index: Desc("date"),
|
||||
}).Run(session)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
var res []interface{}
|
||||
err = cur.All(&res)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Print(res)
|
||||
}
|
||||
|
||||
// You can efficiently order using multiple fields by using a compound index.
|
||||
// For example order by date and title.
|
||||
func ExampleTerm_OrderBy_compound() {
|
||||
cur, err := DB("examples").Table("posts").OrderBy(OrderByOpts{
|
||||
Index: Desc("dateAndTitle"),
|
||||
}).Run(session)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
var res []interface{}
|
||||
err = cur.All(&res)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Print(res)
|
||||
}
|
||||
|
||||
// If you have a sequence with fewer documents than the arrayLimit, you can order
|
||||
// it by multiple fields without an index.
|
||||
func ExampleTerm_OrderBy_multiple() {
|
||||
cur, err := DB("examples").Table("posts").OrderBy(
|
||||
"title",
|
||||
OrderByOpts{Index: Desc("date")},
|
||||
).Run(session)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
var res []interface{}
|
||||
err = cur.All(&res)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Print(res)
|
||||
}
|
||||
|
||||
// Notice that an index ordering always has highest precedence. The following
|
||||
// query orders posts by date, and if multiple posts were published on the same
|
||||
// date, they will be ordered by title.
|
||||
func ExampleTerm_OrderBy_multipleWithIndex() {
|
||||
cur, err := DB("examples").Table("posts").OrderBy(
|
||||
"title",
|
||||
OrderByOpts{Index: Desc("date")},
|
||||
).Run(session)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
var res []interface{}
|
||||
err = cur.All(&res)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Print(res)
|
||||
}
|
||||
228
vendor/gopkg.in/dancannon/gorethink.v2/example_query_write_test.go
generated
vendored
Normal file
228
vendor/gopkg.in/dancannon/gorethink.v2/example_query_write_test.go
generated
vendored
Normal file
@@ -0,0 +1,228 @@
|
||||
package gorethink
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// Insert a document into the table posts using a struct.
|
||||
func ExampleTerm_Insert_struct() {
|
||||
type Post struct {
|
||||
ID int `gorethink:"id"`
|
||||
Title string `gorethink:"title"`
|
||||
Content string `gorethink:"content"`
|
||||
}
|
||||
|
||||
resp, err := DB("examples").Table("posts").Insert(Post{
|
||||
ID: 1,
|
||||
Title: "Lorem ipsum",
|
||||
Content: "Dolor sit amet",
|
||||
}).RunWrite(session)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("%d row inserted", resp.Inserted)
|
||||
|
||||
// Output:
|
||||
// 1 row inserted
|
||||
}
|
||||
|
||||
// Insert a document without a defined primary key into the table posts where
|
||||
// the primary key is id.
|
||||
func ExampleTerm_Insert_generatedKey() {
|
||||
type Post struct {
|
||||
Title string `gorethink:"title"`
|
||||
Content string `gorethink:"content"`
|
||||
}
|
||||
|
||||
resp, err := DB("examples").Table("posts").Insert(map[string]interface{}{
|
||||
"title": "Lorem ipsum",
|
||||
"content": "Dolor sit amet",
|
||||
}).RunWrite(session)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("%d row inserted, %d key generated", resp.Inserted, len(resp.GeneratedKeys))
|
||||
|
||||
// Output:
|
||||
// 1 row inserted, 1 key generated
|
||||
}
|
||||
|
||||
// Insert a document into the table posts using a map.
|
||||
func ExampleTerm_Insert_map() {
|
||||
resp, err := DB("examples").Table("posts").Insert(map[string]interface{}{
|
||||
"id": 2,
|
||||
"title": "Lorem ipsum",
|
||||
"content": "Dolor sit amet",
|
||||
}).RunWrite(session)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("%d row inserted", resp.Inserted)
|
||||
|
||||
// Output:
|
||||
// 1 row inserted
|
||||
}
|
||||
|
||||
// Insert multiple documents into the table posts.
|
||||
func ExampleTerm_Insert_multiple() {
|
||||
resp, err := DB("examples").Table("posts").Insert([]interface{}{
|
||||
map[string]interface{}{
|
||||
"title": "Lorem ipsum",
|
||||
"content": "Dolor sit amet",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"title": "Lorem ipsum",
|
||||
"content": "Dolor sit amet",
|
||||
},
|
||||
}).RunWrite(session)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("%d rows inserted", resp.Inserted)
|
||||
|
||||
// Output:
|
||||
// 2 rows inserted
|
||||
}
|
||||
|
||||
// Insert a document into the table posts, replacing the document if it already
|
||||
// exists.
|
||||
func ExampleTerm_Insert_upsert() {
|
||||
resp, err := DB("examples").Table("posts").Insert(map[string]interface{}{
|
||||
"id": 1,
|
||||
"title": "Lorem ipsum 2",
|
||||
}, InsertOpts{
|
||||
Conflict: "replace",
|
||||
}).RunWrite(session)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("%d row replaced", resp.Replaced)
|
||||
|
||||
// Output:
|
||||
// 1 row replaced
|
||||
}
|
||||
|
||||
// Update the status of the post with id of 1 to published.
|
||||
func ExampleTerm_Update() {
|
||||
resp, err := DB("examples").Table("posts").Get(2).Update(map[string]interface{}{
|
||||
"status": "published",
|
||||
}).RunWrite(session)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("%d row replaced", resp.Replaced)
|
||||
|
||||
// Output:
|
||||
// 1 row replaced
|
||||
}
|
||||
|
||||
// Update bob's cell phone number.
|
||||
func ExampleTerm_Update_nested() {
|
||||
resp, err := DB("examples").Table("users").Get("bob").Update(map[string]interface{}{
|
||||
"contact": map[string]interface{}{
|
||||
"phone": "408-555-4242",
|
||||
},
|
||||
}).RunWrite(session)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("%d row replaced", resp.Replaced)
|
||||
|
||||
// Output:
|
||||
// 1 row replaced
|
||||
}
|
||||
|
||||
// Update the status of all posts to published.
|
||||
func ExampleTerm_Update_all() {
|
||||
resp, err := DB("examples").Table("posts").Update(map[string]interface{}{
|
||||
"status": "published",
|
||||
}).RunWrite(session)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("%d row replaced", resp.Replaced)
|
||||
|
||||
// Output:
|
||||
// 4 row replaced
|
||||
}
|
||||
|
||||
// Increment the field view of the post with id of 1. If the field views does not
|
||||
// exist, it will be set to 0.
|
||||
func ExampleTerm_Update_increment() {
|
||||
resp, err := DB("examples").Table("posts").Get(1).Update(map[string]interface{}{
|
||||
"views": Row.Field("views").Add(1).Default(0),
|
||||
}).RunWrite(session)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("%d row replaced", resp.Replaced)
|
||||
|
||||
// Output:
|
||||
// 1 row replaced
|
||||
}
|
||||
|
||||
// Update the status of the post with id of 1 using soft durability.
|
||||
func ExampleTerm_Update_softDurability() {
|
||||
resp, err := DB("examples").Table("posts").Get(2).Update(map[string]interface{}{
|
||||
"status": "draft",
|
||||
}, UpdateOpts{
|
||||
Durability: "soft",
|
||||
}).RunWrite(session)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("%d row replaced", resp.Replaced)
|
||||
|
||||
// Output:
|
||||
// 1 row replaced
|
||||
}
|
||||
|
||||
// Delete a single document from the table posts.
|
||||
func ExampleTerm_Delete() {
|
||||
resp, err := DB("examples").Table("posts").Get(2).Delete().RunWrite(session)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("%d row deleted", resp.Deleted)
|
||||
|
||||
// Output:
|
||||
// 1 row deleted
|
||||
}
|
||||
|
||||
// Delete all comments where the field status is published
|
||||
func ExampleTerm_Delete_many() {
|
||||
resp, err := DB("examples").Table("posts").Filter(map[string]interface{}{
|
||||
"status": "published",
|
||||
}).Delete().RunWrite(session)
|
||||
if err != nil {
|
||||
fmt.Print(err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Printf("%d rows deleted", resp.Deleted)
|
||||
|
||||
// Output:
|
||||
// 4 rows deleted
|
||||
}
|
||||
30
vendor/gopkg.in/dancannon/gorethink.v2/example_test.go
generated
vendored
Normal file
30
vendor/gopkg.in/dancannon/gorethink.v2/example_test.go
generated
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
package gorethink
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func Example() {
|
||||
session, err := Connect(ConnectOpts{
|
||||
Address: url,
|
||||
})
|
||||
if err != nil {
|
||||
Log.Fatalln(err.Error())
|
||||
}
|
||||
|
||||
res, err := Expr("Hello World").Run(session)
|
||||
if err != nil {
|
||||
Log.Fatalln(err.Error())
|
||||
}
|
||||
|
||||
var response string
|
||||
err = res.One(&response)
|
||||
if err != nil {
|
||||
Log.Fatalln(err.Error())
|
||||
}
|
||||
|
||||
fmt.Println(response)
|
||||
|
||||
// Output:
|
||||
// Hello World
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
|
||||
"github.com/Sirupsen/logrus"
|
||||
|
||||
"github.com/dancannon/gorethink/encoding"
|
||||
"gopkg.in/dancannon/gorethink.v2/encoding"
|
||||
)
|
||||
|
||||
var (
|
||||
448
vendor/gopkg.in/dancannon/gorethink.v2/gorethink_test.go
generated
vendored
Normal file
448
vendor/gopkg.in/dancannon/gorethink.v2/gorethink_test.go
generated
vendored
Normal file
@@ -0,0 +1,448 @@
|
||||
package gorethink
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"os"
|
||||
"runtime"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
test "gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
var session *Session
|
||||
var debug = flag.Bool("gorethink.debug", false, "print query trees")
|
||||
var testdata = flag.Bool("gorethink.testdata", true, "create test data")
|
||||
var url, url1, url2, url3, db, authKey string
|
||||
|
||||
func init() {
|
||||
flag.Parse()
|
||||
SetVerbose(true)
|
||||
|
||||
// If the test is being run by wercker look for the rethink url
|
||||
url = os.Getenv("RETHINKDB_URL")
|
||||
if url == "" {
|
||||
url = "localhost:28015"
|
||||
}
|
||||
|
||||
url1 = os.Getenv("RETHINKDB_URL_1")
|
||||
if url1 == "" {
|
||||
url1 = "localhost:28016"
|
||||
}
|
||||
|
||||
url2 = os.Getenv("RETHINKDB_URL_2")
|
||||
if url2 == "" {
|
||||
url2 = "localhost:28017"
|
||||
}
|
||||
|
||||
url3 = os.Getenv("RETHINKDB_URL_3")
|
||||
if url3 == "" {
|
||||
url3 = "localhost:28018"
|
||||
}
|
||||
|
||||
db = os.Getenv("RETHINKDB_DB")
|
||||
if db == "" {
|
||||
db = "test"
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Begin TestMain(), Setup, Teardown
|
||||
//
|
||||
func testSetup(m *testing.M) {
|
||||
var err error
|
||||
session, err = Connect(ConnectOpts{
|
||||
Address: url,
|
||||
})
|
||||
if err != nil {
|
||||
Log.Fatalln(err.Error())
|
||||
}
|
||||
|
||||
setupTestData()
|
||||
}
|
||||
func testTeardown(m *testing.M) {
|
||||
session.Close()
|
||||
}
|
||||
|
||||
func testBenchmarkSetup() {
|
||||
DBDrop("benchmarks").Exec(session)
|
||||
DBCreate("benchmarks").Exec(session)
|
||||
|
||||
DB("benchmarks").TableDrop("benchmarks").Run(session)
|
||||
DB("benchmarks").TableCreate("benchmarks").Run(session)
|
||||
}
|
||||
|
||||
func testBenchmarkTeardown() {
|
||||
DBDrop("benchmarks").Run(session)
|
||||
}
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
// seed randomness for use with tests
|
||||
rand.Seed(time.Now().UTC().UnixNano())
|
||||
|
||||
testSetup(m)
|
||||
testBenchmarkSetup()
|
||||
res := m.Run()
|
||||
testBenchmarkTeardown()
|
||||
testTeardown(m)
|
||||
|
||||
os.Exit(res)
|
||||
}
|
||||
|
||||
//
|
||||
// End TestMain(), Setup, Teardown
|
||||
//
|
||||
|
||||
// Hook up gocheck into the gotest runner.
|
||||
func Test(t *testing.T) { test.TestingT(t) }
|
||||
|
||||
type RethinkSuite struct{}
|
||||
|
||||
var _ = test.Suite(&RethinkSuite{})
|
||||
|
||||
// Expressions used in tests
|
||||
var now = time.Now()
|
||||
var arr = []interface{}{1, 2, 3, 4, 5, 6, 7, 8, 9}
|
||||
var darr = []interface{}{1, 1, 2, 2, 3, 3, 5, 5, 6}
|
||||
var narr = []interface{}{
|
||||
1, 2, 3, 4, 5, 6, []interface{}{
|
||||
7.1, 7.2, 7.3,
|
||||
},
|
||||
}
|
||||
var obj = map[string]interface{}{"a": 1, "b": 2, "c": 3}
|
||||
var nobj = map[string]interface{}{
|
||||
"A": 1,
|
||||
"B": 2,
|
||||
"C": map[string]interface{}{
|
||||
"1": 3,
|
||||
"2": 4,
|
||||
},
|
||||
}
|
||||
var noDupNumObjList = []interface{}{
|
||||
map[string]interface{}{"id": 1, "g1": 1, "g2": 1, "num": 0},
|
||||
map[string]interface{}{"id": 2, "g1": 2, "g2": 2, "num": 5},
|
||||
map[string]interface{}{"id": 3, "g1": 3, "g2": 2, "num": 10},
|
||||
map[string]interface{}{"id": 5, "g1": 2, "g2": 3, "num": 100},
|
||||
map[string]interface{}{"id": 6, "g1": 1, "g2": 1, "num": 15},
|
||||
map[string]interface{}{"id": 8, "g1": 4, "g2": 2, "num": 50},
|
||||
map[string]interface{}{"id": 9, "g1": 2, "g2": 3, "num": 25},
|
||||
}
|
||||
var objList = []interface{}{
|
||||
map[string]interface{}{"id": 1, "g1": 1, "g2": 1, "num": 0},
|
||||
map[string]interface{}{"id": 2, "g1": 2, "g2": 2, "num": 5},
|
||||
map[string]interface{}{"id": 3, "g1": 3, "g2": 2, "num": 10},
|
||||
map[string]interface{}{"id": 4, "g1": 2, "g2": 3, "num": 0},
|
||||
map[string]interface{}{"id": 5, "g1": 2, "g2": 3, "num": 100},
|
||||
map[string]interface{}{"id": 6, "g1": 1, "g2": 1, "num": 15},
|
||||
map[string]interface{}{"id": 7, "g1": 1, "g2": 2, "num": 0},
|
||||
map[string]interface{}{"id": 8, "g1": 4, "g2": 2, "num": 50},
|
||||
map[string]interface{}{"id": 9, "g1": 2, "g2": 3, "num": 25},
|
||||
}
|
||||
var nameList = []interface{}{
|
||||
map[string]interface{}{"id": 1, "first_name": "John", "last_name": "Smith", "gender": "M"},
|
||||
map[string]interface{}{"id": 2, "first_name": "Jane", "last_name": "Smith", "gender": "F"},
|
||||
}
|
||||
var defaultObjList = []interface{}{
|
||||
map[string]interface{}{"a": 1},
|
||||
map[string]interface{}{},
|
||||
}
|
||||
var joinTable1 = []interface{}{
|
||||
map[string]interface{}{"id": 0, "name": "bob"},
|
||||
map[string]interface{}{"id": 1, "name": "tom"},
|
||||
map[string]interface{}{"id": 2, "name": "joe"},
|
||||
}
|
||||
var joinTable2 = []interface{}{
|
||||
map[string]interface{}{"id": 0, "title": "goof"},
|
||||
map[string]interface{}{"id": 2, "title": "lmoe"},
|
||||
}
|
||||
var joinTable3 = []interface{}{
|
||||
map[string]interface{}{"it": 0, "title": "goof"},
|
||||
map[string]interface{}{"it": 2, "title": "lmoe"},
|
||||
}
|
||||
|
||||
type TStr string
|
||||
type TMap map[string]interface{}
|
||||
|
||||
type T struct {
|
||||
A string `gorethink:"id, omitempty"`
|
||||
B int
|
||||
C int `gorethink:"-"`
|
||||
D map[string]interface{}
|
||||
E []interface{}
|
||||
F X
|
||||
}
|
||||
|
||||
type SimpleT struct {
|
||||
A string
|
||||
B int
|
||||
}
|
||||
|
||||
type X struct {
|
||||
XA int
|
||||
XB string
|
||||
XC []string
|
||||
XD Y
|
||||
XE TStr
|
||||
XF []TStr
|
||||
}
|
||||
|
||||
type Y struct {
|
||||
YA int
|
||||
YB map[string]interface{}
|
||||
YC map[string]string
|
||||
YD TMap
|
||||
}
|
||||
|
||||
type PseudoTypes struct {
|
||||
T time.Time
|
||||
Z time.Time
|
||||
B []byte
|
||||
}
|
||||
|
||||
var str = T{
|
||||
A: "A",
|
||||
B: 1,
|
||||
C: 1,
|
||||
D: map[string]interface{}{
|
||||
"D1": 1,
|
||||
"D2": "2",
|
||||
},
|
||||
E: []interface{}{
|
||||
"E1", "E2", "E3", 4,
|
||||
},
|
||||
F: X{
|
||||
XA: 2,
|
||||
XB: "B",
|
||||
XC: []string{"XC1", "XC2"},
|
||||
XD: Y{
|
||||
YA: 3,
|
||||
YB: map[string]interface{}{
|
||||
"1": "1",
|
||||
"2": "2",
|
||||
"3": 3,
|
||||
},
|
||||
YC: map[string]string{
|
||||
"YC1": "YC1",
|
||||
},
|
||||
YD: TMap{
|
||||
"YD1": "YD1",
|
||||
},
|
||||
},
|
||||
XE: "XE",
|
||||
XF: []TStr{
|
||||
"XE1", "XE2",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
type Author struct {
|
||||
ID string `gorethink:"id,omitempty"`
|
||||
Name string `gorethink:"name"`
|
||||
}
|
||||
|
||||
type Book struct {
|
||||
ID string `gorethink:"id,omitempty"`
|
||||
Title string `gorethink:"title"`
|
||||
Author Author `gorethink:"author_id,reference" gorethink_ref:"id"`
|
||||
}
|
||||
|
||||
type TagsTest struct {
|
||||
A string `gorethink:"a"`
|
||||
B string `json:"b"`
|
||||
C string `gorethink:"c1" json:"c2"`
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) BenchmarkExpr(c *test.C) {
|
||||
for i := 0; i < c.N; i++ {
|
||||
// Test query
|
||||
query := Expr(true)
|
||||
err := query.Exec(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) BenchmarkNoReplyExpr(c *test.C) {
|
||||
for i := 0; i < c.N; i++ {
|
||||
// Test query
|
||||
query := Expr(true)
|
||||
err := query.Exec(session, ExecOpts{NoReply: true})
|
||||
c.Assert(err, test.IsNil)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) BenchmarkGet(c *test.C) {
|
||||
// Ensure table + database exist
|
||||
DBCreate("test").RunWrite(session)
|
||||
DB("test").TableCreate("TestMany").RunWrite(session)
|
||||
DB("test").Table("TestMany").Delete().RunWrite(session)
|
||||
|
||||
// Insert rows
|
||||
data := []interface{}{}
|
||||
for i := 0; i < 100; i++ {
|
||||
data = append(data, map[string]interface{}{
|
||||
"id": i,
|
||||
})
|
||||
}
|
||||
DB("test").Table("TestMany").Insert(data).Run(session)
|
||||
|
||||
for i := 0; i < c.N; i++ {
|
||||
n := rand.Intn(100)
|
||||
|
||||
// Test query
|
||||
var response interface{}
|
||||
query := DB("test").Table("TestMany").Get(n)
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, map[string]interface{}{"id": n})
|
||||
}
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) BenchmarkGetStruct(c *test.C) {
|
||||
// Ensure table + database exist
|
||||
DBCreate("test").RunWrite(session)
|
||||
DB("test").TableCreate("TestMany").RunWrite(session)
|
||||
DB("test").Table("TestMany").Delete().RunWrite(session)
|
||||
|
||||
// Insert rows
|
||||
data := []interface{}{}
|
||||
for i := 0; i < 100; i++ {
|
||||
data = append(data, map[string]interface{}{
|
||||
"id": i,
|
||||
"name": "Object 1",
|
||||
"Attrs": []interface{}{map[string]interface{}{
|
||||
"Name": "attr 1",
|
||||
"Value": "value 1",
|
||||
}},
|
||||
})
|
||||
}
|
||||
DB("test").Table("TestMany").Insert(data).Run(session)
|
||||
|
||||
for i := 0; i < c.N; i++ {
|
||||
n := rand.Intn(100)
|
||||
|
||||
// Test query
|
||||
var resObj object
|
||||
query := DB("test").Table("TestMany").Get(n)
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&resObj)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) BenchmarkSelectMany(c *test.C) {
|
||||
// Ensure table + database exist
|
||||
DBCreate("test").RunWrite(session)
|
||||
DB("test").TableCreate("TestMany").RunWrite(session)
|
||||
DB("test").Table("TestMany").Delete().RunWrite(session)
|
||||
|
||||
// Insert rows
|
||||
data := []interface{}{}
|
||||
for i := 0; i < 100; i++ {
|
||||
data = append(data, map[string]interface{}{
|
||||
"id": i,
|
||||
})
|
||||
}
|
||||
DB("test").Table("TestMany").Insert(data).Run(session)
|
||||
|
||||
for i := 0; i < c.N; i++ {
|
||||
// Test query
|
||||
res, err := DB("test").Table("TestMany").Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
var response []map[string]interface{}
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.HasLen, 100)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) BenchmarkSelectManyStruct(c *test.C) {
|
||||
// Ensure table + database exist
|
||||
DBCreate("test").RunWrite(session)
|
||||
DB("test").TableCreate("TestMany").RunWrite(session)
|
||||
DB("test").Table("TestMany").Delete().RunWrite(session)
|
||||
|
||||
// Insert rows
|
||||
data := []interface{}{}
|
||||
for i := 0; i < 100; i++ {
|
||||
data = append(data, map[string]interface{}{
|
||||
"id": i,
|
||||
"name": "Object 1",
|
||||
"Attrs": []interface{}{map[string]interface{}{
|
||||
"Name": "attr 1",
|
||||
"Value": "value 1",
|
||||
}},
|
||||
})
|
||||
}
|
||||
DB("test").Table("TestMany").Insert(data).Run(session)
|
||||
|
||||
for i := 0; i < c.N; i++ {
|
||||
// Test query
|
||||
res, err := DB("test").Table("TestMany").Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
var response []object
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.HasLen, 100)
|
||||
}
|
||||
}
|
||||
|
||||
func doConcurrentTest(c *test.C, ct func()) {
|
||||
maxProcs, numReqs := 1, 150
|
||||
if testing.Short() {
|
||||
maxProcs, numReqs = 4, 50
|
||||
}
|
||||
defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(maxProcs))
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(numReqs)
|
||||
|
||||
reqs := make(chan bool)
|
||||
defer close(reqs)
|
||||
|
||||
for i := 0; i < maxProcs*2; i++ {
|
||||
go func() {
|
||||
for _ = range reqs {
|
||||
ct()
|
||||
if c.Failed() {
|
||||
wg.Done()
|
||||
continue
|
||||
}
|
||||
wg.Done()
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
for i := 0; i < numReqs; i++ {
|
||||
reqs <- true
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
// Test utils
|
||||
|
||||
// Print variable as JSON
|
||||
func jsonPrint(v interface{}) {
|
||||
b, err := json.MarshalIndent(v, "", " ")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println(string(b))
|
||||
}
|
||||
@@ -3,8 +3,8 @@ package gorethink
|
||||
import (
|
||||
"sync"
|
||||
|
||||
p "github.com/dancannon/gorethink/ql2"
|
||||
"github.com/hailocab/go-hostpool"
|
||||
p "gopkg.in/dancannon/gorethink.v2/ql2"
|
||||
)
|
||||
|
||||
// Node represents a database server in the cluster
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/dancannon/gorethink/types"
|
||||
"gopkg.in/dancannon/gorethink.v2/types"
|
||||
|
||||
"fmt"
|
||||
)
|
||||
@@ -38,6 +38,7 @@ const (
|
||||
VersionDummy_V0_2 VersionDummy_Version = 1915781601
|
||||
VersionDummy_V0_3 VersionDummy_Version = 1601562686
|
||||
VersionDummy_V0_4 VersionDummy_Version = 1074539808
|
||||
VersionDummy_V1_0 VersionDummy_Version = 885177795
|
||||
)
|
||||
|
||||
var VersionDummy_Version_name = map[int32]string{
|
||||
@@ -45,12 +46,14 @@ var VersionDummy_Version_name = map[int32]string{
|
||||
1915781601: "V0_2",
|
||||
1601562686: "V0_3",
|
||||
1074539808: "V0_4",
|
||||
885177795: "V1_0",
|
||||
}
|
||||
var VersionDummy_Version_value = map[string]int32{
|
||||
"V0_1": 1063369270,
|
||||
"V0_2": 1915781601,
|
||||
"V0_3": 1601562686,
|
||||
"V0_4": 1074539808,
|
||||
"V1_0": 885177795,
|
||||
}
|
||||
|
||||
func (x VersionDummy_Version) Enum() *VersionDummy_Version {
|
||||
@@ -268,6 +271,7 @@ const (
|
||||
Response_OP_FAILED Response_ErrorType = 4100000
|
||||
Response_OP_INDETERMINATE Response_ErrorType = 4200000
|
||||
Response_USER Response_ErrorType = 5000000
|
||||
Response_PERMISSION_ERROR Response_ErrorType = 6000000
|
||||
)
|
||||
|
||||
var Response_ErrorType_name = map[int32]string{
|
||||
@@ -278,6 +282,7 @@ var Response_ErrorType_name = map[int32]string{
|
||||
4100000: "OP_FAILED",
|
||||
4200000: "OP_INDETERMINATE",
|
||||
5000000: "USER",
|
||||
6000000: "PERMISSION_ERROR",
|
||||
}
|
||||
var Response_ErrorType_value = map[string]int32{
|
||||
"INTERNAL": 1000000,
|
||||
@@ -287,6 +292,7 @@ var Response_ErrorType_value = map[string]int32{
|
||||
"OP_FAILED": 4100000,
|
||||
"OP_INDETERMINATE": 4200000,
|
||||
"USER": 5000000,
|
||||
"PERMISSION_ERROR": 6000000,
|
||||
}
|
||||
|
||||
func (x Response_ErrorType) Enum() *Response_ErrorType {
|
||||
@@ -536,6 +542,7 @@ const (
|
||||
Term_BETWEEN Term_TermType = 182
|
||||
Term_REDUCE Term_TermType = 37
|
||||
Term_MAP Term_TermType = 38
|
||||
Term_FOLD Term_TermType = 187
|
||||
// Filter a sequence with either a function or a shortcut
|
||||
// object (see API docs for details). The body of FILTER is
|
||||
// wrapped in an implicit `.default(false)`, and you can
|
||||
@@ -656,6 +663,8 @@ const (
|
||||
// Ensures that previously issued soft-durability writes are complete and
|
||||
// written to disk.
|
||||
Term_SYNC Term_TermType = 138
|
||||
// Set global, database, or table-specific permissions
|
||||
Term_GRANT Term_TermType = 188
|
||||
// * Secondary indexes OPs
|
||||
// Creates a new secondary index with a particular name and definition.
|
||||
Term_INDEX_CREATE Term_TermType = 75
|
||||
@@ -901,6 +910,7 @@ var Term_TermType_name = map[int32]string{
|
||||
182: "BETWEEN",
|
||||
37: "REDUCE",
|
||||
38: "MAP",
|
||||
187: "FOLD",
|
||||
39: "FILTER",
|
||||
40: "CONCAT_MAP",
|
||||
41: "ORDER_BY",
|
||||
@@ -937,6 +947,7 @@ var Term_TermType_name = map[int32]string{
|
||||
176: "RECONFIGURE",
|
||||
179: "REBALANCE",
|
||||
138: "SYNC",
|
||||
188: "GRANT",
|
||||
75: "INDEX_CREATE",
|
||||
76: "INDEX_DROP",
|
||||
77: "INDEX_LIST",
|
||||
@@ -1079,6 +1090,7 @@ var Term_TermType_value = map[string]int32{
|
||||
"BETWEEN": 182,
|
||||
"REDUCE": 37,
|
||||
"MAP": 38,
|
||||
"FOLD": 187,
|
||||
"FILTER": 39,
|
||||
"CONCAT_MAP": 40,
|
||||
"ORDER_BY": 41,
|
||||
@@ -1115,6 +1127,7 @@ var Term_TermType_value = map[string]int32{
|
||||
"RECONFIGURE": 176,
|
||||
"REBALANCE": 179,
|
||||
"SYNC": 138,
|
||||
"GRANT": 188,
|
||||
"INDEX_CREATE": 75,
|
||||
"INDEX_DROP": 76,
|
||||
"INDEX_LIST": 77,
|
||||
@@ -1392,7 +1405,7 @@ type Response struct {
|
||||
Response []*Datum `protobuf:"bytes,3,rep,name=response" json:"response,omitempty"`
|
||||
// If [type] is [CLIENT_ERROR], [TYPE_ERROR], or [RUNTIME_ERROR], then a
|
||||
// backtrace will be provided. The backtrace says where in the query the
|
||||
// error occured. Ideally this information will be presented to the user as
|
||||
// error occurred. Ideally this information will be presented to the user as
|
||||
// a pretty-printed version of their query with the erroneous section
|
||||
// underlined. A backtrace is a series of 0 or more [Frame]s, each of which
|
||||
// specifies either the index of a positional argument or the name of an
|
||||
@@ -48,6 +48,7 @@ message VersionDummy { // We need to wrap it like this for some
|
||||
V0_2 = 0x723081e1; // Authorization key during handshake
|
||||
V0_3 = 0x5f75e83e; // Authorization key and protocol during handshake
|
||||
V0_4 = 0x400c2d20; // Queries execute in parallel
|
||||
V1_0 = 0x34c2bdc3; // Users and permissions
|
||||
}
|
||||
|
||||
// The protocol to use after the handshake, specified in V0_3
|
||||
@@ -98,8 +99,8 @@ message Query {
|
||||
// A backtrace frame (see `backtrace` in Response below)
|
||||
message Frame {
|
||||
enum FrameType {
|
||||
POS = 1; // Error occured in a positional argument.
|
||||
OPT = 2; // Error occured in an optional argument.
|
||||
POS = 1; // Error occurred in a positional argument.
|
||||
OPT = 2; // Error occurred in an optional argument.
|
||||
}
|
||||
optional FrameType type = 1;
|
||||
optional int64 pos = 2; // The index of the positional argument.
|
||||
@@ -149,6 +150,7 @@ message Response {
|
||||
OP_FAILED = 4100000;
|
||||
OP_INDETERMINATE = 4200000;
|
||||
USER = 5000000;
|
||||
PERMISSION_ERROR = 6000000;
|
||||
}
|
||||
optional ErrorType error_type = 7;
|
||||
|
||||
@@ -186,7 +188,7 @@ message Response {
|
||||
|
||||
// If [type] is [CLIENT_ERROR], [TYPE_ERROR], or [RUNTIME_ERROR], then a
|
||||
// backtrace will be provided. The backtrace says where in the query the
|
||||
// error occured. Ideally this information will be presented to the user as
|
||||
// error occurred. Ideally this information will be presented to the user as
|
||||
// a pretty-printed version of their query with the erroneous section
|
||||
// underlined. A backtrace is a series of 0 or more [Frame]s, each of which
|
||||
// specifies either the index of a positional argument or the name of an
|
||||
@@ -418,6 +420,8 @@ message Term {
|
||||
// The arity of the function should be
|
||||
// Sequence..., Function(sizeof...(Sequence)) -> Sequence
|
||||
|
||||
FOLD = 187; // Sequence, Datum, Function(2), {Function(3), Function(1)
|
||||
|
||||
// Filter a sequence with either a function or a shortcut
|
||||
// object (see API docs for details). The body of FILTER is
|
||||
// wrapped in an implicit `.default(false)`, and you can
|
||||
@@ -550,6 +554,11 @@ message Term {
|
||||
// written to disk.
|
||||
SYNC = 138; // Table -> OBJECT
|
||||
|
||||
// Set global, database, or table-specific permissions
|
||||
GRANT = 188; // -> OBJECT
|
||||
// Database -> OBJECT
|
||||
// Table -> OBJECT
|
||||
|
||||
// * Secondary indexes OPs
|
||||
// Creates a new secondary index with a particular name and definition.
|
||||
INDEX_CREATE = 75; // Table, STRING, Function(1), {multi:BOOL} -> OBJECT
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
p "github.com/dancannon/gorethink/ql2"
|
||||
p "gopkg.in/dancannon/gorethink.v2/ql2"
|
||||
)
|
||||
|
||||
// A Query represents a query ready to be sent to the database, A Query differs
|
||||
@@ -156,6 +156,11 @@ func (t Term) String() string {
|
||||
if t.rootTerm {
|
||||
return fmt.Sprintf("r.%s(%s)", t.name, strings.Join(allArgsToStringSlice(t.args, t.optArgs), ", "))
|
||||
}
|
||||
|
||||
if t.args == nil {
|
||||
return "r"
|
||||
}
|
||||
|
||||
return fmt.Sprintf("%s.%s(%s)", t.args[0].String(), t.name, strings.Join(allArgsToStringSlice(t.args[1:], t.optArgs), ", "))
|
||||
}
|
||||
|
||||
@@ -201,6 +206,7 @@ type RunOpts struct {
|
||||
DB interface{} `gorethink:"db,omitempty"`
|
||||
Db interface{} `gorethink:"db,omitempty"` // Deprecated
|
||||
Profile interface{} `gorethink:"profile,omitempty"`
|
||||
Durability interface{} `gorethink:"durability,omitempty"`
|
||||
UseOutdated interface{} `gorethink:"use_outdated,omitempty"` // Deprecated
|
||||
ArrayLimit interface{} `gorethink:"array_limit,omitempty"`
|
||||
TimeFormat interface{} `gorethink:"time_format,omitempty"`
|
||||
@@ -265,12 +271,36 @@ func (t Term) RunWrite(s *Session, optArgs ...RunOpts) (WriteResponse, error) {
|
||||
}
|
||||
|
||||
if response.Errors > 0 {
|
||||
return response, fmt.Errorf(response.FirstError)
|
||||
return response, fmt.Errorf("%s", response.FirstError)
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
// ReadOne is a shortcut method that runs the query on the given connection
|
||||
// and reads one response from the cursor before closing it.
|
||||
//
|
||||
// It returns any errors encountered from running the query or reading the response
|
||||
func (t Term) ReadOne(dest interface{}, s *Session, optArgs ...RunOpts) error {
|
||||
res, err := t.Run(s, optArgs...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return res.One(dest)
|
||||
}
|
||||
|
||||
// ReadAll is a shortcut method that runs the query on the given connection
|
||||
// and reads all of the responses from the cursor before closing it.
|
||||
//
|
||||
// It returns any errors encountered from running the query or reading the responses
|
||||
func (t Term) ReadAll(dest interface{}, s *Session, optArgs ...RunOpts) error {
|
||||
res, err := t.Run(s, optArgs...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return res.All(dest)
|
||||
}
|
||||
|
||||
// ExecOpts contains the optional arguments for the Exec function and inherits
|
||||
// its options from RunOpts, the only difference is the addition of the NoReply
|
||||
// field.
|
||||
@@ -281,6 +311,7 @@ type ExecOpts struct {
|
||||
DB interface{} `gorethink:"db,omitempty"`
|
||||
Db interface{} `gorethink:"db,omitempty"` // Deprecated
|
||||
Profile interface{} `gorethink:"profile,omitempty"`
|
||||
Durability interface{} `gorethink:"durability,omitempty"`
|
||||
UseOutdated interface{} `gorethink:"use_outdated,omitempty"` // Deprecated
|
||||
ArrayLimit interface{} `gorethink:"array_limit,omitempty"`
|
||||
TimeFormat interface{} `gorethink:"time_format,omitempty"`
|
||||
@@ -1,7 +1,7 @@
|
||||
package gorethink
|
||||
|
||||
import (
|
||||
p "github.com/dancannon/gorethink/ql2"
|
||||
p "gopkg.in/dancannon/gorethink.v2/ql2"
|
||||
)
|
||||
|
||||
// Config can be used to read and/or update the configurations for individual
|
||||
@@ -20,7 +20,7 @@ func (t Term) Rebalance() Term {
|
||||
type ReconfigureOpts struct {
|
||||
Shards interface{} `gorethink:"shards,omitempty"`
|
||||
Replicas interface{} `gorethink:"replicas,omitempty"`
|
||||
PrimaryTag interface{} `gorethink:"primary_replicas_tag,omitempty"`
|
||||
PrimaryTag interface{} `gorethink:"primary_replica_tag,omitempty"`
|
||||
DryRun interface{} `gorethink:"dry_run,omitempty"`
|
||||
EmergencyRepair interface{} `gorethink:"emergency_repair,omitempty"`
|
||||
NonVotingReplicaTags interface{} `gorethink:"nonvoting_replica_tags,omitempty"`
|
||||
@@ -53,6 +53,8 @@ func (o *WaitOpts) toMap() map[string]interface{} {
|
||||
// Wait for a table or all the tables in a database to be ready. A table may be
|
||||
// temporarily unavailable after creation, rebalancing or reconfiguring. The
|
||||
// wait command blocks until the given table (or database) is fully up to date.
|
||||
//
|
||||
// Deprecated: This function is not supported by RethinkDB 2.3 and above.
|
||||
func Wait(optArgs ...WaitOpts) Term {
|
||||
opts := map[string]interface{}{}
|
||||
if len(optArgs) >= 1 {
|
||||
@@ -71,3 +73,9 @@ func (t Term) Wait(optArgs ...WaitOpts) Term {
|
||||
}
|
||||
return constructMethodTerm(t, "Wait", p.Term_WAIT, []interface{}{}, opts)
|
||||
}
|
||||
|
||||
// Grant modifies access permissions for a user account, globally or on a
|
||||
// per-database or per-table basis.
|
||||
func (t Term) Grant(args ...interface{}) Term {
|
||||
return constructMethodTerm(t, "Grant", p.Term_GRANT, args, map[string]interface{}{})
|
||||
}
|
||||
108
vendor/gopkg.in/dancannon/gorethink.v2/query_admin_test.go
generated
vendored
Normal file
108
vendor/gopkg.in/dancannon/gorethink.v2/query_admin_test.go
generated
vendored
Normal file
@@ -0,0 +1,108 @@
|
||||
package gorethink
|
||||
|
||||
import (
|
||||
test "gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
func (s *RethinkSuite) TestAdminDbConfig(c *test.C) {
|
||||
DB("test").TableDrop("test").Exec(session)
|
||||
DB("test").TableCreate("test").Exec(session)
|
||||
|
||||
// Test index rename
|
||||
query := DB("test").Table("test").Config()
|
||||
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
var response map[string]interface{}
|
||||
err = res.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
c.Assert(response["name"], test.Equals, "test")
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestAdminTableConfig(c *test.C) {
|
||||
DB("test").TableDrop("test").Exec(session)
|
||||
DB("test").TableCreate("test").Exec(session)
|
||||
|
||||
// Test index rename
|
||||
query := DB("test").Config()
|
||||
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
var response map[string]interface{}
|
||||
err = res.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
c.Assert(response["name"], test.Equals, "test")
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestAdminTableStatus(c *test.C) {
|
||||
DB("test").TableDrop("test").Exec(session)
|
||||
DB("test").TableCreate("test").Exec(session)
|
||||
|
||||
// Test index rename
|
||||
query := DB("test").Table("test").Status()
|
||||
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
var response map[string]interface{}
|
||||
err = res.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
c.Assert(response["name"], test.Equals, "test")
|
||||
c.Assert(response["status"], test.NotNil)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestAdminWaitOpts(c *test.C) {
|
||||
DB("test").TableDrop("test").Exec(session)
|
||||
DB("test").TableCreate("test").Exec(session)
|
||||
|
||||
query := DB("test").Table("test").Wait(WaitOpts{
|
||||
WaitFor: "all_replicas_ready",
|
||||
Timeout: 10,
|
||||
})
|
||||
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
var response map[string]interface{}
|
||||
err = res.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
c.Assert(response["ready"].(float64) > 0, test.Equals, true)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestAdminStatus(c *test.C) {
|
||||
DB("test").TableDrop("test").Exec(session)
|
||||
DB("test").TableCreate("test").Exec(session)
|
||||
|
||||
// Test index rename
|
||||
query := DB("test").Table("test").Wait()
|
||||
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
var response map[string]interface{}
|
||||
err = res.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
c.Assert(response["ready"], test.Equals, float64(1))
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestAdminGrantDatabase(c *test.C) {
|
||||
DB("rethinkdb").Table("users").Insert(map[string]string{
|
||||
"id": "test_user",
|
||||
"password": "password",
|
||||
}).Exec(session)
|
||||
|
||||
DB("test").TableDrop("test_grant").Exec(session)
|
||||
DB("test").TableCreate("test_grant").Exec(session)
|
||||
|
||||
err := DB("test").Table("test_grant").Grant("test_user", map[string]bool{
|
||||
"read": true, "write": true, "config": true,
|
||||
}).Exec(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
}
|
||||
@@ -1,8 +1,6 @@
|
||||
package gorethink
|
||||
|
||||
import (
|
||||
p "github.com/dancannon/gorethink/ql2"
|
||||
)
|
||||
import p "gopkg.in/dancannon/gorethink.v2/ql2"
|
||||
|
||||
// Aggregation
|
||||
// These commands are used to compute smaller values from large sequences.
|
||||
@@ -167,3 +165,43 @@ func (t Term) MaxIndex(index interface{}, args ...interface{}) Term {
|
||||
"index": index,
|
||||
})
|
||||
}
|
||||
|
||||
// FoldOpts contains the optional arguments for the Fold term
|
||||
type FoldOpts struct {
|
||||
Emit interface{} `gorethink:"emit,omitempty"`
|
||||
FinalEmit interface{} `gorethink:"finalEmit,omitempty"`
|
||||
}
|
||||
|
||||
func (o *FoldOpts) toMap() map[string]interface{} {
|
||||
return optArgsToMap(o)
|
||||
}
|
||||
|
||||
// Fold applies a function to a sequence in order, maintaining state via an
|
||||
// accumulator. The Fold command returns either a single value or a new sequence.
|
||||
//
|
||||
// In its first form, Fold operates like Reduce, returning a value by applying a
|
||||
// combining function to each element in a sequence, passing the current element
|
||||
// and the previous reduction result to the function. However, Fold has the
|
||||
// following differences from Reduce:
|
||||
// - it is guaranteed to proceed through the sequence from first element to last.
|
||||
// - it passes an initial base value to the function with the first element in
|
||||
// place of the previous reduction result.
|
||||
//
|
||||
// In its second form, Fold operates like ConcatMap, returning a new sequence
|
||||
// rather than a single value. When an emit function is provided, Fold will:
|
||||
// - proceed through the sequence in order and take an initial base value, as above.
|
||||
// - for each element in the sequence, call both the combining function and a
|
||||
// separate emitting function with the current element and previous reduction result.
|
||||
// - optionally pass the result of the combining function to the emitting function.
|
||||
//
|
||||
// If provided, the emitting function must return a list.
|
||||
func (t Term) Fold(base, fn interface{}, optArgs ...FoldOpts) Term {
|
||||
opts := map[string]interface{}{}
|
||||
if len(optArgs) >= 1 {
|
||||
opts = optArgs[0].toMap()
|
||||
}
|
||||
|
||||
args := []interface{}{base, funcWrap(fn)}
|
||||
|
||||
return constructMethodTerm(t, "Fold", p.Term_FOLD, args, opts)
|
||||
}
|
||||
357
vendor/gopkg.in/dancannon/gorethink.v2/query_aggregation_test.go
generated
vendored
Normal file
357
vendor/gopkg.in/dancannon/gorethink.v2/query_aggregation_test.go
generated
vendored
Normal file
@@ -0,0 +1,357 @@
|
||||
package gorethink
|
||||
|
||||
import test "gopkg.in/check.v1"
|
||||
|
||||
func (s *RethinkSuite) TestAggregationReduce(c *test.C) {
|
||||
var response int
|
||||
query := Expr(arr).Reduce(func(acc, val Term) Term {
|
||||
return acc.Add(val)
|
||||
})
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, 45)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestAggregationExprCount(c *test.C) {
|
||||
var response int
|
||||
query := Expr(arr).Count()
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, 9)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestAggregationDistinct(c *test.C) {
|
||||
var response []int
|
||||
query := Expr(darr).Distinct()
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.HasLen, 5)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestAggregationGroupMapReduce(c *test.C) {
|
||||
var response []interface{}
|
||||
query := Expr(objList).Group(func(row Term) Term {
|
||||
return row.Field("id").Mod(2).Eq(0)
|
||||
}).Map(func(row Term) Term {
|
||||
return row.Field("num")
|
||||
}).Reduce(func(acc, num Term) Term {
|
||||
return acc.Add(num)
|
||||
})
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{
|
||||
map[string]interface{}{"reduction": 135, "group": false},
|
||||
map[string]interface{}{"reduction": 70, "group": true},
|
||||
})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestAggregationGroupMapReduceUngroup(c *test.C) {
|
||||
var response []interface{}
|
||||
query := Expr(objList).Group(func(row Term) Term {
|
||||
return row.Field("id").Mod(2).Eq(0)
|
||||
}).Map(func(row Term) Term {
|
||||
return row.Field("num")
|
||||
}).Reduce(func(acc, num Term) Term {
|
||||
return acc.Add(num)
|
||||
}).Ungroup().OrderBy("reduction")
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{
|
||||
map[string]interface{}{"reduction": 70, "group": true},
|
||||
map[string]interface{}{"reduction": 135, "group": false},
|
||||
})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestAggregationGroupMapReduceTable(c *test.C) {
|
||||
// Ensure table + database exist
|
||||
DBCreate("test").Exec(session)
|
||||
DB("test").TableCreate("TestAggregationGroupedMapReduceTable").Exec(session)
|
||||
|
||||
// Insert rows
|
||||
err := DB("test").Table("TestAggregationGroupedMapReduceTable").Insert(objList).Exec(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
var response []interface{}
|
||||
query := DB("test").Table("TestAggregationGroupedMapReduceTable").Group(func(row Term) Term {
|
||||
return row.Field("id").Mod(2).Eq(0)
|
||||
}).Map(func(row Term) Term {
|
||||
return row.Field("num")
|
||||
}).Reduce(func(acc, num Term) Term {
|
||||
return acc.Add(num)
|
||||
})
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{
|
||||
map[string]interface{}{"reduction": 135, "group": false},
|
||||
map[string]interface{}{"reduction": 70, "group": true},
|
||||
})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestAggregationGroupCount(c *test.C) {
|
||||
var response []interface{}
|
||||
query := Expr(objList).Group("g1")
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{
|
||||
map[string]interface{}{"group": 1, "reduction": []interface{}{
|
||||
map[string]interface{}{"id": 1, "num": 0, "g1": 1, "g2": 1},
|
||||
map[string]interface{}{"num": 15, "g1": 1, "g2": 1, "id": 6},
|
||||
map[string]interface{}{"id": 7, "num": 0, "g1": 1, "g2": 2},
|
||||
}},
|
||||
map[string]interface{}{"group": 2, "reduction": []interface{}{
|
||||
map[string]interface{}{"g1": 2, "g2": 2, "id": 2, "num": 5},
|
||||
map[string]interface{}{"num": 0, "g1": 2, "g2": 3, "id": 4},
|
||||
map[string]interface{}{"num": 100, "g1": 2, "g2": 3, "id": 5},
|
||||
map[string]interface{}{"g2": 3, "id": 9, "num": 25, "g1": 2},
|
||||
}},
|
||||
map[string]interface{}{"group": 3, "reduction": []interface{}{
|
||||
map[string]interface{}{"num": 10, "g1": 3, "g2": 2, "id": 3},
|
||||
}},
|
||||
map[string]interface{}{"group": 4, "reduction": []interface{}{
|
||||
map[string]interface{}{"id": 8, "num": 50, "g1": 4, "g2": 2},
|
||||
}},
|
||||
})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestAggregationGroupSum(c *test.C) {
|
||||
var response []interface{}
|
||||
query := Expr(objList).Group("g1").Sum("num")
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{
|
||||
map[string]interface{}{"group": 1, "reduction": 15},
|
||||
map[string]interface{}{"reduction": 130, "group": 2},
|
||||
map[string]interface{}{"reduction": 10, "group": 3},
|
||||
map[string]interface{}{"group": 4, "reduction": 50},
|
||||
})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestAggregationGroupAvg(c *test.C) {
|
||||
var response []interface{}
|
||||
query := Expr(objList).Group("g1").Avg("num")
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{
|
||||
map[string]interface{}{"group": 1, "reduction": 5},
|
||||
map[string]interface{}{"group": 2, "reduction": 32.5},
|
||||
map[string]interface{}{"group": 3, "reduction": 10},
|
||||
map[string]interface{}{"group": 4, "reduction": 50},
|
||||
})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestAggregationGroupMin(c *test.C) {
|
||||
var response []interface{}
|
||||
query := Expr(objList).Group("g1").Min("num")
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{
|
||||
map[string]interface{}{"group": 1, "reduction": map[string]interface{}{"id": 1, "num": 0, "g1": 1, "g2": 1}},
|
||||
map[string]interface{}{"reduction": map[string]interface{}{"num": 0, "g1": 2, "g2": 3, "id": 4}, "group": 2},
|
||||
map[string]interface{}{"group": 3, "reduction": map[string]interface{}{"num": 10, "g1": 3, "g2": 2, "id": 3}},
|
||||
map[string]interface{}{"group": 4, "reduction": map[string]interface{}{"g2": 2, "id": 8, "num": 50, "g1": 4}},
|
||||
})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestAggregationGroupMax(c *test.C) {
|
||||
var response []interface{}
|
||||
query := Expr(objList).Group("g1").Max("num")
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{
|
||||
map[string]interface{}{"reduction": map[string]interface{}{"num": 15, "g1": 1, "g2": 1, "id": 6}, "group": 1},
|
||||
map[string]interface{}{"group": 2, "reduction": map[string]interface{}{"num": 100, "g1": 2, "g2": 3, "id": 5}},
|
||||
map[string]interface{}{"group": 3, "reduction": map[string]interface{}{"num": 10, "g1": 3, "g2": 2, "id": 3}},
|
||||
map[string]interface{}{"group": 4, "reduction": map[string]interface{}{"g2": 2, "id": 8, "num": 50, "g1": 4}},
|
||||
})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestAggregationMin(c *test.C) {
|
||||
// Ensure table + database exist
|
||||
DBCreate("test").Exec(session)
|
||||
DB("test").TableCreate("Table2").Exec(session)
|
||||
DB("test").Table("Table2").IndexCreate("num").Exec(session)
|
||||
DB("test").Table("Table2").IndexWait().Exec(session)
|
||||
|
||||
// Insert rows
|
||||
DB("test").Table("Table2").Insert(objList).Exec(session)
|
||||
|
||||
// Test query
|
||||
var response interface{}
|
||||
query := DB("test").Table("Table2").MinIndex("num")
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, map[string]interface{}{"id": 1, "g1": 1, "g2": 1, "num": 0})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestAggregationMaxIndex(c *test.C) {
|
||||
// Ensure table + database exist
|
||||
DBCreate("test").Exec(session)
|
||||
DB("test").TableCreate("Table2").Exec(session)
|
||||
DB("test").Table("Table2").IndexCreate("num").Exec(session)
|
||||
DB("test").Table("Table2").IndexWait().Exec(session)
|
||||
|
||||
// Insert rows
|
||||
DB("test").Table("Table2").Insert(objList).Exec(session)
|
||||
|
||||
// Test query
|
||||
var response interface{}
|
||||
query := DB("test").Table("Table2").MaxIndex("num")
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, map[string]interface{}{"id": 5, "g1": 2, "g2": 3, "num": 100})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestAggregationMultipleGroupSum(c *test.C) {
|
||||
var response []interface{}
|
||||
query := Expr(objList).Group("g1", "g2").Sum("num")
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{
|
||||
map[string]interface{}{"group": []interface{}{1, 1}, "reduction": 15},
|
||||
map[string]interface{}{"reduction": 0, "group": []interface{}{1, 2}},
|
||||
map[string]interface{}{"group": []interface{}{2, 2}, "reduction": 5},
|
||||
map[string]interface{}{"reduction": 125, "group": []interface{}{2, 3}},
|
||||
map[string]interface{}{"group": []interface{}{3, 2}, "reduction": 10},
|
||||
map[string]interface{}{"group": []interface{}{4, 2}, "reduction": 50},
|
||||
})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestAggregationGroupChained(c *test.C) {
|
||||
var response []interface{}
|
||||
query := Expr(objList).Group("g1").Max("num").Field("g2")
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{
|
||||
map[string]interface{}{"group": 1, "reduction": 1},
|
||||
map[string]interface{}{"group": 2, "reduction": 3},
|
||||
map[string]interface{}{"group": 3, "reduction": 2},
|
||||
map[string]interface{}{"group": 4, "reduction": 2},
|
||||
})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestAggregationGroupUngroup(c *test.C) {
|
||||
var response []interface{}
|
||||
query := Expr(objList).Group("g1", "g2").Max("num").Ungroup()
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{
|
||||
map[string]interface{}{"group": []interface{}{1, 1}, "reduction": map[string]interface{}{"g1": 1, "g2": 1, "id": 6, "num": 15}},
|
||||
map[string]interface{}{"group": []interface{}{1, 2}, "reduction": map[string]interface{}{"g1": 1, "g2": 2, "id": 7, "num": 0}},
|
||||
map[string]interface{}{"group": []interface{}{2, 2}, "reduction": map[string]interface{}{"g1": 2, "g2": 2, "id": 2, "num": 5}},
|
||||
map[string]interface{}{"group": []interface{}{2, 3}, "reduction": map[string]interface{}{"g1": 2, "g2": 3, "id": 5, "num": 100}},
|
||||
map[string]interface{}{"group": []interface{}{3, 2}, "reduction": map[string]interface{}{"g2": 2, "id": 3, "num": 10, "g1": 3}},
|
||||
map[string]interface{}{"reduction": map[string]interface{}{"num": 50, "g1": 4, "g2": 2, "id": 8}, "group": []interface{}{4, 2}},
|
||||
})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestAggregationContains(c *test.C) {
|
||||
var response interface{}
|
||||
query := Expr(arr).Contains(2)
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, true)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestAggregationFold(c *test.C) {
|
||||
var response int
|
||||
query := Expr(arr).Reduce(func(acc, val Term) Term {
|
||||
return acc.Add(val)
|
||||
})
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, 45)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestAggregationFoldEmit(c *test.C) {
|
||||
var response []interface{}
|
||||
query := Expr(objList).Fold(0, func(acc, row Term) Term {
|
||||
return acc.Add(1)
|
||||
}, FoldOpts{
|
||||
Emit: func(acc, row, cur Term) Term {
|
||||
return Branch(acc.Mod(2).Eq(0), []interface{}{row}, []interface{}{})
|
||||
},
|
||||
})
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{
|
||||
map[string]interface{}{"id": 1, "g1": 1, "g2": 1, "num": 0},
|
||||
map[string]interface{}{"id": 3, "g1": 3, "g2": 2, "num": 10},
|
||||
map[string]interface{}{"id": 5, "g1": 2, "g2": 3, "num": 100},
|
||||
map[string]interface{}{"id": 7, "g1": 1, "g2": 2, "num": 0},
|
||||
map[string]interface{}{"id": 9, "g1": 2, "g2": 3, "num": 25},
|
||||
})
|
||||
}
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
|
||||
"reflect"
|
||||
|
||||
p "github.com/dancannon/gorethink/ql2"
|
||||
p "gopkg.in/dancannon/gorethink.v2/ql2"
|
||||
)
|
||||
|
||||
// Expr converts any value to an expression and is also used by many other terms
|
||||
521
vendor/gopkg.in/dancannon/gorethink.v2/query_control_test.go
generated
vendored
Normal file
521
vendor/gopkg.in/dancannon/gorethink.v2/query_control_test.go
generated
vendored
Normal file
@@ -0,0 +1,521 @@
|
||||
package gorethink
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
test "gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
func (s *RethinkSuite) TestControlExprNil(c *test.C) {
|
||||
var response interface{}
|
||||
query := Expr(nil)
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
|
||||
c.Assert(err, test.Equals, ErrEmptyResult)
|
||||
c.Assert(response, test.Equals, nil)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestControlExprSimple(c *test.C) {
|
||||
var response int
|
||||
query := Expr(1)
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, 1)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestControlExprList(c *test.C) {
|
||||
var response []interface{}
|
||||
query := Expr(narr)
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{
|
||||
1, 2, 3, 4, 5, 6, []interface{}{
|
||||
7.1, 7.2, 7.3,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestControlExprObj(c *test.C) {
|
||||
var response map[string]interface{}
|
||||
query := Expr(nobj)
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, map[string]interface{}{
|
||||
"A": 1,
|
||||
"B": 2,
|
||||
"C": map[string]interface{}{
|
||||
"1": 3,
|
||||
"2": 4,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestControlStruct(c *test.C) {
|
||||
var response map[string]interface{}
|
||||
query := Expr(str)
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, map[string]interface{}{
|
||||
"id": "A",
|
||||
"B": 1,
|
||||
"D": map[string]interface{}{"D2": "2", "D1": 1},
|
||||
"E": []interface{}{"E1", "E2", "E3", 4},
|
||||
"F": map[string]interface{}{
|
||||
"XA": 2,
|
||||
"XB": "B",
|
||||
"XC": []interface{}{"XC1", "XC2"},
|
||||
"XD": map[string]interface{}{
|
||||
"YA": 3,
|
||||
"YB": map[string]interface{}{
|
||||
"1": "1",
|
||||
"2": "2",
|
||||
"3": 3,
|
||||
},
|
||||
"YC": map[string]interface{}{
|
||||
"YC1": "YC1",
|
||||
},
|
||||
"YD": map[string]interface{}{
|
||||
"YD1": "YD1",
|
||||
},
|
||||
},
|
||||
"XE": "XE",
|
||||
"XF": []interface{}{"XE1", "XE2"},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestControlStructTags(c *test.C) {
|
||||
SetTags("gorethink", "json")
|
||||
defer SetTags()
|
||||
|
||||
var response map[string]interface{}
|
||||
query := Expr(TagsTest{"1", "2", "3"})
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, map[string]interface{}{
|
||||
"a": "1", "b": "2", "c1": "3",
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestControlMapTypeAlias(c *test.C) {
|
||||
var response TMap
|
||||
query := Expr(TMap{"A": 1, "B": 2})
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, TMap{"A": 1, "B": 2})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestControlStringTypeAlias(c *test.C) {
|
||||
var response TStr
|
||||
query := Expr(TStr("Hello"))
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, TStr("Hello"))
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestControlExprTypes(c *test.C) {
|
||||
var response []interface{}
|
||||
query := Expr([]interface{}{int64(1), uint64(1), float64(1.0), int32(1), uint32(1), float32(1), "1", true, false})
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{int64(1), uint64(1), float64(1.0), int32(1), uint32(1), float32(1), "1", true, false})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestControlJs(c *test.C) {
|
||||
var response int
|
||||
query := JS("1;")
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, 1)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestControlHttp(c *test.C) {
|
||||
if testing.Short() {
|
||||
c.Skip("-short set")
|
||||
}
|
||||
|
||||
var response map[string]interface{}
|
||||
query := HTTP("httpbin.org/get?data=1")
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response["args"], jsonEquals, map[string]interface{}{
|
||||
"data": "1",
|
||||
})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestControlJson(c *test.C) {
|
||||
var response []int
|
||||
query := JSON("[1,2,3]")
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{1, 2, 3})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestControlError(c *test.C) {
|
||||
query := Error("An error occurred")
|
||||
err := query.Exec(session)
|
||||
c.Assert(err, test.NotNil)
|
||||
|
||||
c.Assert(err, test.NotNil)
|
||||
c.Assert(err, test.FitsTypeOf, RQLUserError{})
|
||||
|
||||
c.Assert(err.Error(), test.Equals, "gorethink: An error occurred in: \nr.Error(\"An error occurred\")")
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestControlDoNothing(c *test.C) {
|
||||
var response []interface{}
|
||||
query := Do([]interface{}{map[string]interface{}{"a": 1}, map[string]interface{}{"a": 2}, map[string]interface{}{"a": 3}})
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{map[string]interface{}{"a": 1}, map[string]interface{}{"a": 2}, map[string]interface{}{"a": 3}})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestControlArgs(c *test.C) {
|
||||
var response time.Time
|
||||
query := Time(Args(Expr([]interface{}{2014, 7, 12, "Z"})))
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response.Unix(), test.Equals, int64(1405123200))
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestControlBinaryByteArray(c *test.C) {
|
||||
var response []byte
|
||||
|
||||
query := Binary([]byte("Hello World"))
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(bytes.Equal(response, []byte("Hello World")), test.Equals, true)
|
||||
}
|
||||
|
||||
type byteArray []byte
|
||||
|
||||
func (s *RethinkSuite) TestControlBinaryByteArrayAlias(c *test.C) {
|
||||
var response []byte
|
||||
|
||||
query := Binary(byteArray("Hello World"))
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(bytes.Equal(response, []byte("Hello World")), test.Equals, true)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestControlBinaryExpr(c *test.C) {
|
||||
var response []byte
|
||||
|
||||
query := Expr([]byte("Hello World"))
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(bytes.Equal(response, []byte("Hello World")), test.Equals, true)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestControlBinaryExprAlias(c *test.C) {
|
||||
var response []byte
|
||||
|
||||
query := Expr(byteArray("Hello World"))
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(bytes.Equal(response, []byte("Hello World")), test.Equals, true)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestControlBinaryTerm(c *test.C) {
|
||||
var response []byte
|
||||
|
||||
query := Binary(Expr([]byte("Hello World")))
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(bytes.Equal(response, []byte("Hello World")), test.Equals, true)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestControlBinaryElemTerm(c *test.C) {
|
||||
var response map[string]interface{}
|
||||
|
||||
query := Expr(map[string]interface{}{
|
||||
"bytes": []byte("Hello World"),
|
||||
})
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(bytes.Equal(response["bytes"].([]byte), []byte("Hello World")), test.Equals, true)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestControlDo(c *test.C) {
|
||||
var response []interface{}
|
||||
query := Do([]interface{}{
|
||||
map[string]interface{}{"a": 1},
|
||||
map[string]interface{}{"a": 2},
|
||||
map[string]interface{}{"a": 3},
|
||||
}, func(row Term) Term {
|
||||
return row.Field("a")
|
||||
})
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{1, 2, 3})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestControlDoWithExpr(c *test.C) {
|
||||
var response []interface{}
|
||||
query := Expr([]interface{}{
|
||||
map[string]interface{}{"a": 1},
|
||||
map[string]interface{}{"a": 2},
|
||||
map[string]interface{}{"a": 3},
|
||||
}).Do(func(row Term) Term {
|
||||
return row.Field("a")
|
||||
})
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{1, 2, 3})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestControlBranchSimple(c *test.C) {
|
||||
var response int
|
||||
query := Branch(
|
||||
true,
|
||||
1,
|
||||
2,
|
||||
)
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, 1)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestControlBranchWithMapExpr(c *test.C) {
|
||||
var response []interface{}
|
||||
query := Expr([]interface{}{1, 2, 3}).Map(Branch(
|
||||
Row.Eq(2),
|
||||
Row.Sub(1),
|
||||
Row.Add(1),
|
||||
))
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{2, 1, 4})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestControlDefault(c *test.C) {
|
||||
var response []interface{}
|
||||
query := Expr(defaultObjList).Map(func(row Term) Term {
|
||||
return row.Field("a").Default(1)
|
||||
})
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{1, 1})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestControlCoerceTo(c *test.C) {
|
||||
var response string
|
||||
query := Expr(1).CoerceTo("STRING")
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, "1")
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestControlTypeOf(c *test.C) {
|
||||
var response string
|
||||
query := Expr(1).TypeOf()
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, "NUMBER")
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestControlRangeNoArgs(c *test.C) {
|
||||
var response []int
|
||||
query := Range().Limit(100)
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(len(response), test.Equals, 100)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestControlRangeSingleArgs(c *test.C) {
|
||||
var response []int
|
||||
query := Range(4)
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.DeepEquals, []int{0, 1, 2, 3})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestControlRangeTwoArgs(c *test.C) {
|
||||
var response []int
|
||||
query := Range(4, 6)
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.DeepEquals, []int{4, 5})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestControlToJSON(c *test.C) {
|
||||
var response string
|
||||
query := Expr([]int{4, 5}).ToJSON()
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, "[4,5]")
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestControlUUID(c *test.C) {
|
||||
var response string
|
||||
query := UUID()
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(len(response) == 36, test.Equals, true)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestControlUUIDString(c *test.C) {
|
||||
var response string
|
||||
query := UUID("rethinkdb")
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(len(response) == 36, test.Equals, true)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestControlInvalidType(c *test.C) {
|
||||
query := Expr(map[struct{ string }]string{})
|
||||
_, err := query.Run(session)
|
||||
c.Assert(err, test.NotNil)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestControlRawQuery(c *test.C) {
|
||||
var response int
|
||||
query := RawQuery([]byte(`1`))
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, 1)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestControlRawQuery_advanced(c *test.C) {
|
||||
var response []int
|
||||
// r.expr([1,2,3]).map(function(v) { return v.add(1)})
|
||||
query := RawQuery([]byte(`[38,[[2,[1,2,3]],[69,[[2,[25]],[24,[[10,[25]],1]]]]]]`))
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []int{2, 3, 4})
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package gorethink
|
||||
|
||||
import (
|
||||
p "github.com/dancannon/gorethink/ql2"
|
||||
p "gopkg.in/dancannon/gorethink.v2/ql2"
|
||||
)
|
||||
|
||||
// DBCreate creates a database. A RethinkDB database is a collection of tables,
|
||||
57
vendor/gopkg.in/dancannon/gorethink.v2/query_db_test.go
generated
vendored
Normal file
57
vendor/gopkg.in/dancannon/gorethink.v2/query_db_test.go
generated
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
package gorethink
|
||||
|
||||
import (
|
||||
test "gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
func (s *RethinkSuite) TestDbCreate(c *test.C) {
|
||||
// Delete the test2 database if it already exists
|
||||
DBDrop("test").Exec(session)
|
||||
|
||||
// Test database creation
|
||||
query := DBCreate("test")
|
||||
|
||||
response, err := query.RunWrite(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response.DBsCreated, jsonEquals, 1)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestDbList(c *test.C) {
|
||||
var response []interface{}
|
||||
|
||||
// create database
|
||||
DBCreate("test").Exec(session)
|
||||
|
||||
// Try and find it in the list
|
||||
success := false
|
||||
res, err := DBList().Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.FitsTypeOf, []interface{}{})
|
||||
|
||||
for _, db := range response {
|
||||
if db == "test" {
|
||||
success = true
|
||||
}
|
||||
}
|
||||
|
||||
c.Assert(success, test.Equals, true)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestDbDelete(c *test.C) {
|
||||
// Delete the test2 database if it already exists
|
||||
DBCreate("test").Exec(session)
|
||||
|
||||
// Test database creation
|
||||
query := DBDrop("test")
|
||||
|
||||
response, err := query.RunWrite(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response.DBsDropped, jsonEquals, 1)
|
||||
|
||||
// Ensure that there is still a test DB after the test has finished
|
||||
DBCreate("test").Exec(session)
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package gorethink
|
||||
|
||||
import (
|
||||
p "github.com/dancannon/gorethink/ql2"
|
||||
p "gopkg.in/dancannon/gorethink.v2/ql2"
|
||||
)
|
||||
|
||||
// CircleOpts contains the optional arguments for the Circle term.
|
||||
519
vendor/gopkg.in/dancannon/gorethink.v2/query_geospatial_test.go
generated
vendored
Normal file
519
vendor/gopkg.in/dancannon/gorethink.v2/query_geospatial_test.go
generated
vendored
Normal file
@@ -0,0 +1,519 @@
|
||||
package gorethink
|
||||
|
||||
import (
|
||||
test "gopkg.in/check.v1"
|
||||
|
||||
"gopkg.in/dancannon/gorethink.v2/types"
|
||||
)
|
||||
|
||||
func (s *RethinkSuite) TestGeospatialDecodeGeometryPseudoType(c *test.C) {
|
||||
var response types.Geometry
|
||||
|
||||
// setup coordinates
|
||||
coords := [][][]float64{
|
||||
{
|
||||
{-122.423246, 37.779388},
|
||||
{-122.423246, 37.329898},
|
||||
{-121.88642, 37.329898},
|
||||
{-121.88642, 37.329898},
|
||||
{-122.423246, 37.779388},
|
||||
},
|
||||
}
|
||||
|
||||
gt := "Polygon"
|
||||
res, err := Expr(map[string]interface{}{
|
||||
"$reql_type$": "GEOMETRY",
|
||||
"type": "Polygon",
|
||||
"coordinates": coords,
|
||||
}).Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
// test shape
|
||||
if response.Type != gt {
|
||||
c.Errorf("expected [%v], instead [%v]", gt, response.Type)
|
||||
}
|
||||
|
||||
// assert points are within threshold
|
||||
c.Assert(response, geometryEquals, "Polygon", coords)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestGeospatialEncodeGeometryPseudoType(c *test.C) {
|
||||
encoded, err := encode(types.Geometry{
|
||||
Type: "Polygon",
|
||||
Lines: types.Lines{
|
||||
types.Line{
|
||||
types.Point{Lon: -122.423246, Lat: 37.779388},
|
||||
types.Point{Lon: -122.423246, Lat: 37.329898},
|
||||
types.Point{Lon: -121.88642, Lat: 37.329898},
|
||||
types.Point{Lon: -121.88642, Lat: 37.779388},
|
||||
types.Point{Lon: -122.423246, Lat: 37.779388},
|
||||
},
|
||||
},
|
||||
})
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(encoded, jsonEquals, map[string]interface{}{
|
||||
"$reql_type$": "GEOMETRY",
|
||||
"type": "Polygon",
|
||||
"coordinates": []interface{}{
|
||||
[]interface{}{
|
||||
[]interface{}{-122.423246, 37.779388},
|
||||
[]interface{}{-122.423246, 37.329898},
|
||||
[]interface{}{-121.88642, 37.329898},
|
||||
[]interface{}{-121.88642, 37.779388},
|
||||
[]interface{}{-122.423246, 37.779388},
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestGeospatialCircle(c *test.C) {
|
||||
var response types.Geometry
|
||||
res, err := Circle([]float64{-122.423246, 37.779388}, 10).Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, geometryEquals, "Polygon", [][][]float64{
|
||||
{
|
||||
{-122.423246, 37.77929790366427},
|
||||
{-122.42326814543915, 37.77929963483801},
|
||||
{-122.4232894398445, 37.779304761831504},
|
||||
{-122.42330906488651, 37.77931308761787},
|
||||
{-122.42332626638755, 37.77932429224285},
|
||||
{-122.42334038330416, 37.77933794512014},
|
||||
{-122.42335087313059, 37.77935352157849},
|
||||
{-122.42335733274696, 37.77937042302436},
|
||||
{-122.4233595139113, 37.77938799994533},
|
||||
{-122.42335733279968, 37.7794055768704},
|
||||
{-122.42335087322802, 37.779422478327966},
|
||||
{-122.42334038343147, 37.77943805480385},
|
||||
{-122.42332626652532, 37.779451707701796},
|
||||
{-122.42330906501378, 37.77946291234741},
|
||||
{-122.42328943994191, 37.77947123815131},
|
||||
{-122.42326814549187, 37.77947636515649},
|
||||
{-122.423246, 37.779478096334365},
|
||||
{-122.42322385450814, 37.77947636515649},
|
||||
{-122.4232025600581, 37.77947123815131},
|
||||
{-122.42318293498623, 37.77946291234741},
|
||||
{-122.42316573347469, 37.779451707701796},
|
||||
{-122.42315161656855, 37.77943805480385},
|
||||
{-122.423141126772, 37.779422478327966},
|
||||
{-122.42313466720033, 37.7794055768704},
|
||||
{-122.42313248608872, 37.77938799994533},
|
||||
{-122.42313466725305, 37.77937042302436},
|
||||
{-122.42314112686942, 37.77935352157849},
|
||||
{-122.42315161669585, 37.77933794512014},
|
||||
{-122.42316573361246, 37.77932429224285},
|
||||
{-122.4231829351135, 37.77931308761787},
|
||||
{-122.42320256015552, 37.779304761831504},
|
||||
{-122.42322385456086, 37.77929963483801},
|
||||
{-122.423246, 37.77929790366427},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestGeospatialCirclePoint(c *test.C) {
|
||||
var response types.Geometry
|
||||
res, err := Circle(Point(-122.423246, 37.779388), 10).Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, geometryEquals, "Polygon", [][][]float64{
|
||||
{
|
||||
{-122.423246, 37.77929790366427},
|
||||
{-122.42326814543915, 37.77929963483801},
|
||||
{-122.4232894398445, 37.779304761831504},
|
||||
{-122.42330906488651, 37.77931308761787},
|
||||
{-122.42332626638755, 37.77932429224285},
|
||||
{-122.42334038330416, 37.77933794512014},
|
||||
{-122.42335087313059, 37.77935352157849},
|
||||
{-122.42335733274696, 37.77937042302436},
|
||||
{-122.4233595139113, 37.77938799994533},
|
||||
{-122.42335733279968, 37.7794055768704},
|
||||
{-122.42335087322802, 37.779422478327966},
|
||||
{-122.42334038343147, 37.77943805480385},
|
||||
{-122.42332626652532, 37.779451707701796},
|
||||
{-122.42330906501378, 37.77946291234741},
|
||||
{-122.42328943994191, 37.77947123815131},
|
||||
{-122.42326814549187, 37.77947636515649},
|
||||
{-122.423246, 37.779478096334365},
|
||||
{-122.42322385450814, 37.77947636515649},
|
||||
{-122.4232025600581, 37.77947123815131},
|
||||
{-122.42318293498623, 37.77946291234741},
|
||||
{-122.42316573347469, 37.779451707701796},
|
||||
{-122.42315161656855, 37.77943805480385},
|
||||
{-122.423141126772, 37.779422478327966},
|
||||
{-122.42313466720033, 37.7794055768704},
|
||||
{-122.42313248608872, 37.77938799994533},
|
||||
{-122.42313466725305, 37.77937042302436},
|
||||
{-122.42314112686942, 37.77935352157849},
|
||||
{-122.42315161669585, 37.77933794512014},
|
||||
{-122.42316573361246, 37.77932429224285},
|
||||
{-122.4231829351135, 37.77931308761787},
|
||||
{-122.42320256015552, 37.779304761831504},
|
||||
{-122.42322385456086, 37.77929963483801},
|
||||
{-122.423246, 37.77929790366427},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestGeospatialCirclePointFill(c *test.C) {
|
||||
var response types.Geometry
|
||||
res, err := Circle(Point(-122.423246, 37.779388), 10, CircleOpts{Fill: true}).Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, geometryEquals, "Polygon", [][][]float64{
|
||||
{
|
||||
{-122.423246, 37.77929790366427},
|
||||
{-122.42326814543915, 37.77929963483801},
|
||||
{-122.4232894398445, 37.779304761831504},
|
||||
{-122.42330906488651, 37.77931308761787},
|
||||
{-122.42332626638755, 37.77932429224285},
|
||||
{-122.42334038330416, 37.77933794512014},
|
||||
{-122.42335087313059, 37.77935352157849},
|
||||
{-122.42335733274696, 37.77937042302436},
|
||||
{-122.4233595139113, 37.77938799994533},
|
||||
{-122.42335733279968, 37.7794055768704},
|
||||
{-122.42335087322802, 37.779422478327966},
|
||||
{-122.42334038343147, 37.77943805480385},
|
||||
{-122.42332626652532, 37.779451707701796},
|
||||
{-122.42330906501378, 37.77946291234741},
|
||||
{-122.42328943994191, 37.77947123815131},
|
||||
{-122.42326814549187, 37.77947636515649},
|
||||
{-122.423246, 37.779478096334365},
|
||||
{-122.42322385450814, 37.77947636515649},
|
||||
{-122.4232025600581, 37.77947123815131},
|
||||
{-122.42318293498623, 37.77946291234741},
|
||||
{-122.42316573347469, 37.779451707701796},
|
||||
{-122.42315161656855, 37.77943805480385},
|
||||
{-122.423141126772, 37.779422478327966},
|
||||
{-122.42313466720033, 37.7794055768704},
|
||||
{-122.42313248608872, 37.77938799994533},
|
||||
{-122.42313466725305, 37.77937042302436},
|
||||
{-122.42314112686942, 37.77935352157849},
|
||||
{-122.42315161669585, 37.77933794512014},
|
||||
{-122.42316573361246, 37.77932429224285},
|
||||
{-122.4231829351135, 37.77931308761787},
|
||||
{-122.42320256015552, 37.779304761831504},
|
||||
{-122.42322385456086, 37.77929963483801},
|
||||
{-122.423246, 37.77929790366427},
|
||||
},
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestGeospatialPointDistanceMethod(c *test.C) {
|
||||
var response float64
|
||||
f := 734125.249602186
|
||||
res, err := Point(-122.423246, 37.779388).Distance(Point(-117.220406, 32.719464)).Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
if !kindaclose(response, f) {
|
||||
c.Errorf("the deviation between the compared floats is too great [%v:%v]", response, f)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestGeospatialPointDistanceRoot(c *test.C) {
|
||||
var response float64
|
||||
f := 734125.249602186
|
||||
res, err := Distance(Point(-122.423246, 37.779388), Point(-117.220406, 32.719464)).Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
if !kindaclose(response, f) {
|
||||
c.Errorf("the deviation between the compared floats is too great [%v:%v]", response, f)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestGeospatialPointDistanceRootKm(c *test.C) {
|
||||
var response float64
|
||||
f := 734.125249602186
|
||||
res, err := Distance(Point(-122.423246, 37.779388), Point(-117.220406, 32.719464), DistanceOpts{Unit: "km"}).Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
if !kindaclose(response, f) {
|
||||
c.Errorf("the deviation between the compared floats is too great [%v:%v]", response, f)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestGeospatialFill(c *test.C) {
|
||||
var response types.Geometry
|
||||
res, err := Line(
|
||||
[]float64{-122.423246, 37.779388},
|
||||
[]float64{-122.423246, 37.329898},
|
||||
[]float64{-121.886420, 37.329898},
|
||||
[]float64{-121.886420, 37.779388},
|
||||
).Fill().Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, geometryEquals, "Polygon", [][][]float64{
|
||||
{
|
||||
{-122.423246, 37.779388},
|
||||
{-122.423246, 37.329898},
|
||||
{-121.88642, 37.329898},
|
||||
{-121.88642, 37.779388},
|
||||
{-122.423246, 37.779388},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestGeospatialGeoJSON(c *test.C) {
|
||||
var response types.Geometry
|
||||
res, err := GeoJSON(map[string]interface{}{
|
||||
"type": "Point",
|
||||
"coordinates": []interface{}{-122.423246, 37.779388},
|
||||
}).Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, geometryEquals, "Point", []float64{-122.423246, 37.779388})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestGeospatialToGeoJSON(c *test.C) {
|
||||
var response map[string]interface{}
|
||||
res, err := Point(-122.423246, 37.779388).ToGeoJSON().Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, map[string]interface{}{
|
||||
"type": "Point",
|
||||
"coordinates": []interface{}{-122.423246, 37.779388},
|
||||
})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestGeospatialGetIntersecting(c *test.C) {
|
||||
// Setup table
|
||||
DB("test").TableDrop("geospatial").Exec(session)
|
||||
DB("test").TableCreate("geospatial").Exec(session)
|
||||
DB("test").Table("geospatial").IndexCreate("area", IndexCreateOpts{
|
||||
Geo: true,
|
||||
}).Exec(session)
|
||||
DB("test").Table("geospatial").IndexWait().Exec(session)
|
||||
|
||||
DB("test").Table("geospatial").Insert([]interface{}{
|
||||
map[string]interface{}{"area": Circle(Point(-117.220406, 32.719464), 100000)},
|
||||
map[string]interface{}{"area": Circle(Point(-100.220406, 20.719464), 100000)},
|
||||
map[string]interface{}{"area": Circle(Point(-117.200406, 32.723464), 100000)},
|
||||
}).Exec(session)
|
||||
|
||||
var response []interface{}
|
||||
res, err := DB("test").Table("geospatial").GetIntersecting(
|
||||
Circle(Point(-117.220406, 32.719464), 100000),
|
||||
GetIntersectingOpts{
|
||||
Index: "area",
|
||||
},
|
||||
).Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.HasLen, 2)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestGeospatialGetNearest(c *test.C) {
|
||||
// Setup table
|
||||
DB("test").TableDrop("geospatial").Exec(session)
|
||||
DB("test").TableCreate("geospatial").Exec(session)
|
||||
DB("test").Table("geospatial").IndexCreate("area", IndexCreateOpts{
|
||||
Geo: true,
|
||||
}).Exec(session)
|
||||
DB("test").Table("geospatial").IndexWait().Exec(session)
|
||||
|
||||
DB("test").Table("geospatial").Insert([]interface{}{
|
||||
map[string]interface{}{"area": Circle(Point(-117.220406, 32.719464), 100000)},
|
||||
map[string]interface{}{"area": Circle(Point(-100.220406, 20.719464), 100000)},
|
||||
map[string]interface{}{"area": Circle(Point(-115.210306, 32.733364), 100000)},
|
||||
}).Exec(session)
|
||||
|
||||
var response []interface{}
|
||||
res, err := DB("test").Table("geospatial").GetNearest(
|
||||
Point(-117.220406, 32.719464),
|
||||
GetNearestOpts{
|
||||
Index: "area",
|
||||
MaxDist: 1,
|
||||
},
|
||||
).Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.HasLen, 1)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestGeospatialIncludesTrue(c *test.C) {
|
||||
var response bool
|
||||
res, err := Polygon(
|
||||
Point(-122.4, 37.7),
|
||||
Point(-122.4, 37.3),
|
||||
Point(-121.8, 37.3),
|
||||
Point(-121.8, 37.7),
|
||||
).Includes(Point(-122.3, 37.4)).Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, true)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestGeospatialIncludesFalse(c *test.C) {
|
||||
var response bool
|
||||
res, err := Polygon(
|
||||
Point(-122.4, 37.7),
|
||||
Point(-122.4, 37.3),
|
||||
Point(-121.8, 37.3),
|
||||
Point(-121.8, 37.7),
|
||||
).Includes(Point(100.3, 37.4)).Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, false)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestGeospatialIntersectsTrue(c *test.C) {
|
||||
var response bool
|
||||
res, err := Polygon(
|
||||
Point(-122.4, 37.7),
|
||||
Point(-122.4, 37.3),
|
||||
Point(-121.8, 37.3),
|
||||
Point(-121.8, 37.7),
|
||||
).Intersects(Polygon(
|
||||
Point(-122.3, 37.4),
|
||||
Point(-122.4, 37.3),
|
||||
Point(-121.8, 37.3),
|
||||
Point(-121.8, 37.4),
|
||||
)).Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, true)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestGeospatialIntersectsFalse(c *test.C) {
|
||||
var response bool
|
||||
res, err := Polygon(
|
||||
Point(-122.4, 37.7),
|
||||
Point(-122.4, 37.3),
|
||||
Point(-121.8, 37.3),
|
||||
Point(-121.8, 37.7),
|
||||
).Intersects(Polygon(
|
||||
Point(-102.4, 37.7),
|
||||
Point(-102.4, 37.3),
|
||||
Point(-101.8, 37.3),
|
||||
Point(-101.8, 37.7),
|
||||
)).Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, false)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestGeospatialLineLatLon(c *test.C) {
|
||||
var response types.Geometry
|
||||
res, err := Line([]float64{-122.423246, 37.779388}, []float64{-121.886420, 37.329898}).Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, geometryEquals, "LineString", [][]float64{
|
||||
{-122.423246, 37.779388},
|
||||
{-121.886420, 37.329898},
|
||||
})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestGeospatialLinePoint(c *test.C) {
|
||||
var response types.Geometry
|
||||
res, err := Line(Point(-122.423246, 37.779388), Point(-121.886420, 37.329898)).Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, geometryEquals, "LineString", [][]float64{
|
||||
{-122.423246, 37.779388},
|
||||
{-121.886420, 37.329898},
|
||||
})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestGeospatialPoint(c *test.C) {
|
||||
var response types.Geometry
|
||||
res, err := Point(-122.423246, 37.779388).Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, types.Geometry{
|
||||
Type: "Point",
|
||||
Point: types.Point{Lon: -122.423246, Lat: 37.779388},
|
||||
})
|
||||
c.Assert(response, geometryEquals, "Point", []float64{-122.423246, 37.779388})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestGeospatialPolygon(c *test.C) {
|
||||
var response types.Geometry
|
||||
res, err := Polygon(Point(-122.423246, 37.779388), Point(-122.423246, 37.329898), Point(-121.886420, 37.329898)).Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, geometryEquals, "Polygon", [][][]float64{
|
||||
{
|
||||
{-122.423246, 37.779388},
|
||||
{-122.423246, 37.329898},
|
||||
{-121.88642, 37.329898},
|
||||
{-122.423246, 37.779388},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestGeospatialPolygonSub(c *test.C) {
|
||||
var response types.Geometry
|
||||
res, err := Polygon(
|
||||
Point(-122.4, 37.7),
|
||||
Point(-122.4, 37.3),
|
||||
Point(-121.8, 37.3),
|
||||
Point(-121.8, 37.7),
|
||||
).PolygonSub(Polygon(
|
||||
Point(-122.3, 37.4),
|
||||
Point(-122.3, 37.6),
|
||||
Point(-122.0, 37.6),
|
||||
Point(-122.0, 37.4),
|
||||
)).Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, geometryEquals, "Polygon", [][][]float64{
|
||||
{
|
||||
{-122.4, 37.7},
|
||||
{-122.4, 37.3},
|
||||
{-121.8, 37.3},
|
||||
{-121.8, 37.7},
|
||||
{-122.4, 37.7},
|
||||
},
|
||||
{
|
||||
{-122.3, 37.4},
|
||||
{-122.3, 37.6},
|
||||
{-122, 37.6},
|
||||
{-122, 37.4},
|
||||
{-122.3, 37.4},
|
||||
},
|
||||
})
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package gorethink
|
||||
|
||||
import (
|
||||
p "github.com/dancannon/gorethink/ql2"
|
||||
p "gopkg.in/dancannon/gorethink.v2/ql2"
|
||||
)
|
||||
|
||||
// InnerJoin returns the inner product of two sequences (e.g. a table, a filter result)
|
||||
@@ -21,7 +21,8 @@ func (t Term) OuterJoin(args ...interface{}) Term {
|
||||
|
||||
// EqJoinOpts contains the optional arguments for the EqJoin term.
|
||||
type EqJoinOpts struct {
|
||||
Index interface{} `gorethink:"index,omitempty"`
|
||||
Index interface{} `gorethink:"index,omitempty"`
|
||||
Ordered interface{} `gorethink:"ordered,omitempty"`
|
||||
}
|
||||
|
||||
func (o *EqJoinOpts) toMap() map[string]interface{} {
|
||||
181
vendor/gopkg.in/dancannon/gorethink.v2/query_join_test.go
generated
vendored
Normal file
181
vendor/gopkg.in/dancannon/gorethink.v2/query_join_test.go
generated
vendored
Normal file
@@ -0,0 +1,181 @@
|
||||
package gorethink
|
||||
|
||||
import (
|
||||
test "gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
func (s *RethinkSuite) TestJoinInnerJoin(c *test.C) {
|
||||
// Ensure table + database exist
|
||||
DBCreate("test").Exec(session)
|
||||
DB("test").TableCreate("Join1").Exec(session)
|
||||
DB("test").TableCreate("Join2").Exec(session)
|
||||
|
||||
// Insert rows
|
||||
DB("test").Table("Join1").Insert(joinTable1).Exec(session)
|
||||
DB("test").Table("Join2").Insert(joinTable2).Exec(session)
|
||||
|
||||
// Test query
|
||||
var response []interface{}
|
||||
query := DB("test").Table("Join1").InnerJoin(DB("test").Table("Join2"), func(a, b Term) Term {
|
||||
return a.Field("id").Eq(b.Field("id"))
|
||||
})
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(response, jsonEquals, []interface{}{
|
||||
map[string]interface{}{
|
||||
"right": map[string]interface{}{"title": "goof", "id": 0},
|
||||
"left": map[string]interface{}{"name": "bob", "id": 0},
|
||||
},
|
||||
map[string]interface{}{
|
||||
"right": map[string]interface{}{"title": "lmoe", "id": 2},
|
||||
"left": map[string]interface{}{"name": "joe", "id": 2},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestJoinInnerJoinZip(c *test.C) {
|
||||
// Ensure table + database exist
|
||||
DBCreate("test").Exec(session)
|
||||
DB("test").TableCreate("Join1").Exec(session)
|
||||
DB("test").TableCreate("Join2").Exec(session)
|
||||
|
||||
// Insert rows
|
||||
DB("test").Table("Join1").Insert(joinTable1).Exec(session)
|
||||
DB("test").Table("Join2").Insert(joinTable2).Exec(session)
|
||||
|
||||
// Test query
|
||||
var response []interface{}
|
||||
query := DB("test").Table("Join1").InnerJoin(DB("test").Table("Join2"), func(a, b Term) Term {
|
||||
return a.Field("id").Eq(b.Field("id"))
|
||||
}).Zip()
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{
|
||||
map[string]interface{}{"title": "goof", "name": "bob", "id": 0},
|
||||
map[string]interface{}{"title": "lmoe", "name": "joe", "id": 2},
|
||||
})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestJoinOuterJoinZip(c *test.C) {
|
||||
// Ensure table + database exist
|
||||
DBCreate("test").Exec(session)
|
||||
DB("test").TableCreate("Join1").Exec(session)
|
||||
DB("test").TableCreate("Join2").Exec(session)
|
||||
|
||||
// Insert rows
|
||||
DB("test").Table("Join1").Insert(joinTable1).Exec(session)
|
||||
DB("test").Table("Join2").Insert(joinTable2).Exec(session)
|
||||
|
||||
// Test query
|
||||
var response []interface{}
|
||||
query := DB("test").Table("Join1").OuterJoin(DB("test").Table("Join2"), func(a, b Term) Term {
|
||||
return a.Field("id").Eq(b.Field("id"))
|
||||
}).Zip().OrderBy("id")
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{
|
||||
map[string]interface{}{"title": "goof", "name": "bob", "id": 0},
|
||||
map[string]interface{}{"name": "tom", "id": 1},
|
||||
map[string]interface{}{"title": "lmoe", "name": "joe", "id": 2},
|
||||
})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestJoinEqJoinZip(c *test.C) {
|
||||
// Ensure table + database exist
|
||||
DBCreate("test").Exec(session)
|
||||
DB("test").TableCreate("Join1").Exec(session)
|
||||
DB("test").TableCreate("Join2").Exec(session)
|
||||
|
||||
// Insert rows
|
||||
DB("test").Table("Join1").Insert(joinTable1).Exec(session)
|
||||
DB("test").Table("Join2").Insert(joinTable2).Exec(session)
|
||||
|
||||
// Test query
|
||||
var response []interface{}
|
||||
query := DB("test").Table("Join1").EqJoin("id", DB("test").Table("Join2"), EqJoinOpts{
|
||||
Ordered: true,
|
||||
}).Zip()
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
c.Assert(response, jsonEquals, []interface{}{
|
||||
map[string]interface{}{"title": "goof", "name": "bob", "id": 0},
|
||||
map[string]interface{}{"title": "lmoe", "name": "joe", "id": 2},
|
||||
})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestJoinEqJoinDiffIdsZip(c *test.C) {
|
||||
// Ensure table + database exist
|
||||
DBCreate("test").Exec(session)
|
||||
DB("test").TableCreate("Join1").Exec(session)
|
||||
err := DB("test").TableCreate("Join3", TableCreateOpts{
|
||||
PrimaryKey: "it",
|
||||
}).Exec(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
DB("test").Table("Join3").IndexCreate("it").Exec(session)
|
||||
DB("test").Table("Join3").IndexWait().Exec(session)
|
||||
|
||||
// Insert rows
|
||||
DB("test").Table("Join1").Delete().Exec(session)
|
||||
DB("test").Table("Join3").Delete().Exec(session)
|
||||
DB("test").Table("Join1").Insert(joinTable1).Exec(session)
|
||||
DB("test").Table("Join3").Insert(joinTable3).Exec(session)
|
||||
|
||||
// Test query
|
||||
var response []interface{}
|
||||
query := DB("test").Table("Join1").EqJoin("id", DB("test").Table("Join3"), EqJoinOpts{
|
||||
Index: "it",
|
||||
Ordered: true,
|
||||
}).Zip()
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
c.Assert(response, jsonEquals, []interface{}{
|
||||
map[string]interface{}{"title": "goof", "name": "bob", "id": 0, "it": 0},
|
||||
map[string]interface{}{"title": "lmoe", "name": "joe", "id": 2, "it": 2},
|
||||
})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestOrderByJoinEq(c *test.C) {
|
||||
type Map map[string]interface{}
|
||||
var err error
|
||||
|
||||
// Ensure table + database exist
|
||||
DBCreate("test").Exec(session)
|
||||
DB("test").TableCreate("test").Exec(session)
|
||||
DB("test").TableCreate("test2").Exec(session)
|
||||
tab := DB("test").Table("test")
|
||||
tab2 := DB("test").Table("test2")
|
||||
|
||||
// insert rows
|
||||
err = tab.Insert(Map{"S": "s1", "T": 2}).Exec(session)
|
||||
err = tab.Insert(Map{"S": "s1", "T": 1}).Exec(session)
|
||||
err = tab.Insert(Map{"S": "s1", "T": 3}).Exec(session)
|
||||
err = tab.Insert(Map{"S": "s2", "T": 3}).Exec(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = tab2.Insert(Map{"id": "s1", "N": "Rob"}).Exec(session)
|
||||
err = tab2.Insert(Map{"id": "s2", "N": "Zar"}).Exec(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
// Test query
|
||||
var response []Map
|
||||
res, err := tab.OrderBy("T").EqJoin("S", tab2).Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Check(len(response), test.Equals, 4, test.Commentf("%v", response))
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package gorethink
|
||||
|
||||
import (
|
||||
p "github.com/dancannon/gorethink/ql2"
|
||||
p "gopkg.in/dancannon/gorethink.v2/ql2"
|
||||
)
|
||||
|
||||
// Row returns the currently visited document. Note that Row does not work within
|
||||
331
vendor/gopkg.in/dancannon/gorethink.v2/query_manipulation_test.go
generated
vendored
Normal file
331
vendor/gopkg.in/dancannon/gorethink.v2/query_manipulation_test.go
generated
vendored
Normal file
@@ -0,0 +1,331 @@
|
||||
package gorethink
|
||||
|
||||
import (
|
||||
test "gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
func (s *RethinkSuite) TestManipulationDocField(c *test.C) {
|
||||
query := Expr(map[string]interface{}{"a": 1}).Do(Row.Field("a"))
|
||||
|
||||
var response int
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, 1)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestManipulationPluck(c *test.C) {
|
||||
query := Expr(map[string]interface{}{"a": 1, "b": 2, "c": 3}).Pluck("a", "c")
|
||||
|
||||
var response map[string]interface{}
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, map[string]interface{}{"a": 1, "c": 3})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestManipulationWithout(c *test.C) {
|
||||
query := Expr(map[string]interface{}{"a": 1, "b": 2, "c": 3}).Pluck("a", "c")
|
||||
|
||||
var response map[string]interface{}
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, map[string]interface{}{"a": 1, "c": 3})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestManipulationMerge(c *test.C) {
|
||||
query := Expr(map[string]interface{}{"a": 1, "c": 3}).Merge(map[string]interface{}{"b": 2})
|
||||
|
||||
var response map[string]interface{}
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, map[string]interface{}{"a": 1, "b": 2, "c": 3})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestManipulationMergeLiteral(c *test.C) {
|
||||
query := Expr(map[string]interface{}{
|
||||
"a": map[string]interface{}{
|
||||
"aa": map[string]interface{}{
|
||||
"aaa": 1,
|
||||
"aab": 2,
|
||||
},
|
||||
"ab": map[string]interface{}{
|
||||
"aba": 3,
|
||||
"abb": 4,
|
||||
},
|
||||
},
|
||||
}).Merge(map[string]interface{}{"a": map[string]interface{}{"ab": Literal()}})
|
||||
|
||||
var response map[string]interface{}
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, map[string]interface{}{"a": map[string]interface{}{"aa": map[string]interface{}{"aab": 2, "aaa": 1}}})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestManipulationAppend(c *test.C) {
|
||||
query := Expr([]interface{}{1, 2, 3}).Append(4).Append(5)
|
||||
|
||||
var response []interface{}
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{1, 2, 3, 4, 5})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestManipulationPrepend(c *test.C) {
|
||||
query := Expr([]interface{}{3, 4, 5}).Prepend(2).Prepend(1)
|
||||
|
||||
var response []interface{}
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{1, 2, 3, 4, 5})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestManipulationDifference(c *test.C) {
|
||||
query := Expr([]interface{}{3, 4, 5}).Difference([]interface{}{3, 4})
|
||||
|
||||
var response []interface{}
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{5})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestManipulationSetInsert(c *test.C) {
|
||||
query := Expr([]interface{}{1, 2, 3}).SetInsert(3).SetInsert(4)
|
||||
|
||||
var response []interface{}
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{1, 2, 3, 4})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestManipulationSetUnion(c *test.C) {
|
||||
query := Expr([]interface{}{1, 2, 3}).SetUnion([]interface{}{3, 4})
|
||||
|
||||
var response []interface{}
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{1, 2, 3, 4})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestManipulationSetIntersection(c *test.C) {
|
||||
query := Expr([]interface{}{1, 2, 3}).SetIntersection([]interface{}{2, 3, 3, 4})
|
||||
|
||||
var response []interface{}
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{2, 3})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestManipulationSetDifference(c *test.C) {
|
||||
query := Expr([]interface{}{1, 2, 3}).SetDifference([]interface{}{2, 3, 4, 4})
|
||||
|
||||
var response []interface{}
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{1})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestManipulationHasFieldsTrue(c *test.C) {
|
||||
query := Expr(map[string]interface{}{"a": 1}).HasFields("a")
|
||||
|
||||
var response bool
|
||||
r, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = r.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, true)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestManipulationHasFieldsNested(c *test.C) {
|
||||
query := Expr(map[string]interface{}{"a": map[string]interface{}{"b": 1}}).HasFields(map[string]interface{}{"a": map[string]interface{}{"b": true}})
|
||||
|
||||
var response bool
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, true)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestManipulationHasFieldsNestedShort(c *test.C) {
|
||||
query := Expr(map[string]interface{}{"a": map[string]interface{}{"b": 1}}).HasFields(map[string]interface{}{"a": "b"})
|
||||
|
||||
var response bool
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, true)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestManipulationHasFieldsFalse(c *test.C) {
|
||||
query := Expr(map[string]interface{}{"a": 1}).HasFields("b")
|
||||
|
||||
var response bool
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, false)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestManipulationInsertAt(c *test.C) {
|
||||
query := Expr([]interface{}{1, 2, 3}).InsertAt(1, 1.5)
|
||||
|
||||
var response []interface{}
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{1, 1.5, 2, 3})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestManipulationSpliceAt(c *test.C) {
|
||||
query := Expr([]interface{}{1, 2, 3}).SpliceAt(1, []interface{}{1.25, 1.5, 1.75})
|
||||
|
||||
var response []interface{}
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{1, 1.25, 1.5, 1.75, 2, 3})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestManipulationDeleteAt(c *test.C) {
|
||||
query := Expr([]interface{}{1, 2, 3}).DeleteAt(1)
|
||||
|
||||
var response []interface{}
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{1, 3})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestManipulationDeleteAtRange(c *test.C) {
|
||||
query := Expr([]interface{}{1, 2, 3, 4}).DeleteAt(1, 3)
|
||||
|
||||
var response []interface{}
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{1, 4})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestManipulationChangeAt(c *test.C) {
|
||||
query := Expr([]interface{}{1, 5, 3, 4}).ChangeAt(1, 2)
|
||||
|
||||
var response []interface{}
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{1, 2, 3, 4})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestManipulationKeys(c *test.C) {
|
||||
query := Expr(map[string]interface{}{"a": 1, "b": 2, "c": 3}).Keys()
|
||||
|
||||
var response []interface{}
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{"a", "b", "c"})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestManipulationValues(c *test.C) {
|
||||
query := Expr(map[string]interface{}{"a": 1, "b": 2, "c": 3}).Values()
|
||||
|
||||
var response []interface{}
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{1, 2, 3})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestManipulationObject(c *test.C) {
|
||||
query := Object("a", 1, "b", 2)
|
||||
|
||||
var response interface{}
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, map[string]interface{}{
|
||||
"a": 1,
|
||||
"b": 2,
|
||||
})
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package gorethink
|
||||
|
||||
import (
|
||||
p "github.com/dancannon/gorethink/ql2"
|
||||
p "gopkg.in/dancannon/gorethink.v2/ql2"
|
||||
)
|
||||
|
||||
var (
|
||||
330
vendor/gopkg.in/dancannon/gorethink.v2/query_math_test.go
generated
vendored
Normal file
330
vendor/gopkg.in/dancannon/gorethink.v2/query_math_test.go
generated
vendored
Normal file
@@ -0,0 +1,330 @@
|
||||
package gorethink
|
||||
|
||||
import (
|
||||
test "gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
func (s *RethinkSuite) TestMathAdd(c *test.C) {
|
||||
query := Expr(1).Add(2)
|
||||
|
||||
var response int
|
||||
r, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = r.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, 3)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestMathSub(c *test.C) {
|
||||
query := Expr(2).Sub(1)
|
||||
|
||||
var response int
|
||||
r, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = r.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, 1)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestMathSubNegative(c *test.C) {
|
||||
query := Expr(1).Sub(2)
|
||||
|
||||
var response int
|
||||
r, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = r.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, -1)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestMathMul(c *test.C) {
|
||||
query := Expr(5).Mul(4)
|
||||
|
||||
var response int
|
||||
r, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = r.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, 20)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestMathDiv(c *test.C) {
|
||||
query := Expr(8).Div(4)
|
||||
|
||||
var response int
|
||||
r, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = r.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, 2)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestMathMod(c *test.C) {
|
||||
query := Expr(7).Mod(2)
|
||||
|
||||
var response int
|
||||
r, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = r.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, 1)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestMathEqTrue(c *test.C) {
|
||||
query := Expr(1).Eq(1)
|
||||
|
||||
var response bool
|
||||
r, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = r.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, true)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestMathEqFalse(c *test.C) {
|
||||
query := Expr(1).Eq(2)
|
||||
|
||||
var response bool
|
||||
r, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = r.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, false)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestMathEqStringTrue(c *test.C) {
|
||||
query := Expr("test").Eq("test")
|
||||
|
||||
var response bool
|
||||
r, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = r.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, true)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestCompareLt(c *test.C) {
|
||||
query := Expr(2).Lt(1)
|
||||
|
||||
var response bool
|
||||
r, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = r.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, false)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestCompareLe(c *test.C) {
|
||||
query := Expr(2).Le(1)
|
||||
|
||||
var response bool
|
||||
r, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = r.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, false)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestCompareLeEqual(c *test.C) {
|
||||
query := Expr(2).Le(2)
|
||||
|
||||
var response bool
|
||||
r, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = r.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, true)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestCompareGt(c *test.C) {
|
||||
query := Expr(2).Gt(1)
|
||||
|
||||
var response bool
|
||||
r, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = r.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, true)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestCompareGe(c *test.C) {
|
||||
query := Expr(2).Ge(1)
|
||||
|
||||
var response bool
|
||||
r, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = r.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, true)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestCompareGeEqual(c *test.C) {
|
||||
query := Expr(2).Le(2)
|
||||
|
||||
var response bool
|
||||
r, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = r.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, true)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestBoolNotTrue(c *test.C) {
|
||||
query := Expr(true).Not()
|
||||
|
||||
var response bool
|
||||
r, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = r.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, false)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestBoolAnd(c *test.C) {
|
||||
query := Expr(true).And(true)
|
||||
|
||||
var response bool
|
||||
r, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = r.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, true)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestBoolOr(c *test.C) {
|
||||
query := Expr(true).Or(false)
|
||||
|
||||
var response bool
|
||||
r, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = r.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, true)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestBoolDeMorgan(c *test.C) {
|
||||
query := Expr(true).And(false).Eq(Expr(true).Not().Or(Expr(false).Not()).Not())
|
||||
|
||||
var response bool
|
||||
r, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = r.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, true)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestMathRootRound(c *test.C) {
|
||||
query := Round(2.1)
|
||||
|
||||
var response int
|
||||
r, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = r.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, 2)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestMathMethodRound(c *test.C) {
|
||||
query := Expr(2.1).Round()
|
||||
|
||||
var response int
|
||||
r, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = r.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, 2)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestMathRootCeil(c *test.C) {
|
||||
query := Ceil(2.1)
|
||||
|
||||
var response int
|
||||
r, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = r.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, 3)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestMathMethodCeil(c *test.C) {
|
||||
query := Expr(2.1).Ceil()
|
||||
|
||||
var response int
|
||||
r, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = r.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, 3)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestMathRootFloor(c *test.C) {
|
||||
query := Floor(2.1)
|
||||
|
||||
var response int
|
||||
r, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = r.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, 2)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestMathMethodFloor(c *test.C) {
|
||||
query := Expr(2.1).Floor()
|
||||
|
||||
var response int
|
||||
r, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = r.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, 2)
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package gorethink
|
||||
|
||||
import (
|
||||
p "github.com/dancannon/gorethink/ql2"
|
||||
p "gopkg.in/dancannon/gorethink.v2/ql2"
|
||||
)
|
||||
|
||||
// DB references a database.
|
||||
527
vendor/gopkg.in/dancannon/gorethink.v2/query_select_test.go
generated
vendored
Normal file
527
vendor/gopkg.in/dancannon/gorethink.v2/query_select_test.go
generated
vendored
Normal file
@@ -0,0 +1,527 @@
|
||||
package gorethink
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
test "gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
func (s *RethinkSuite) TestSelectGet(c *test.C) {
|
||||
// Ensure table + database exist
|
||||
DBCreate("test").Exec(session)
|
||||
DB("test").TableCreate("Table1").Exec(session)
|
||||
|
||||
// Insert rows
|
||||
DB("test").Table("Table1").Insert(objList).Exec(session)
|
||||
|
||||
// Test query
|
||||
var response interface{}
|
||||
query := DB("test").Table("Table1").Get(6)
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, map[string]interface{}{"id": 6, "g1": 1, "g2": 1, "num": 15})
|
||||
|
||||
res.Close()
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestSelectJSONNumbers(c *test.C) {
|
||||
session, err := Connect(ConnectOpts{
|
||||
Address: url,
|
||||
UseJSONNumber: true,
|
||||
})
|
||||
c.Assert(err, test.IsNil)
|
||||
defer session.Close()
|
||||
// Ensure table + database exist
|
||||
DBCreate("test").Exec(session)
|
||||
DB("test").TableCreate("Table1").Exec(session)
|
||||
|
||||
// Insert rows
|
||||
DB("test").Table("Table1").Insert(objList).Exec(session)
|
||||
|
||||
// Test query
|
||||
var response interface{}
|
||||
query := DB("test").Table("Table1").Get(6)
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, map[string]interface{}{"id": json.Number("6"), "g1": json.Number("1"), "g2": json.Number("1"), "num": json.Number("15")})
|
||||
|
||||
res.Close()
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestSelectGetAll(c *test.C) {
|
||||
// Ensure table + database exist
|
||||
DBCreate("test").Exec(session)
|
||||
DB("test").TableCreate("Table1").Exec(session)
|
||||
DB("test").Table("Table1").IndexCreate("num").Exec(session)
|
||||
DB("test").Table("Table1").IndexWait().Exec(session)
|
||||
|
||||
// Insert rows
|
||||
DB("test").Table("Table1").Insert(objList).Exec(session)
|
||||
|
||||
// Test query
|
||||
var response []interface{}
|
||||
query := DB("test").Table("Table1").GetAll(6).OrderBy("id")
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{
|
||||
map[string]interface{}{"num": 15, "id": 6, "g2": 1, "g1": 1},
|
||||
})
|
||||
|
||||
res.Close()
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestSelectGetAllMultiple(c *test.C) {
|
||||
// Ensure table + database exist
|
||||
DBCreate("test").Exec(session)
|
||||
DB("test").TableCreate("Table1").Exec(session)
|
||||
DB("test").Table("Table1").IndexCreate("num").Exec(session)
|
||||
DB("test").Table("Table1").IndexWait().Exec(session)
|
||||
|
||||
// Insert rows
|
||||
DB("test").Table("Table1").Insert(objList).Exec(session)
|
||||
|
||||
// Test query
|
||||
var response []interface{}
|
||||
query := DB("test").Table("Table1").GetAll(1, 2, 3).OrderBy("id")
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{
|
||||
map[string]interface{}{"num": 0, "id": 1, "g2": 1, "g1": 1},
|
||||
map[string]interface{}{"num": 5, "id": 2, "g2": 2, "g1": 2},
|
||||
map[string]interface{}{"num": 10, "id": 3, "g2": 2, "g1": 3},
|
||||
})
|
||||
|
||||
res.Close()
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestSelectGetAllByIndex(c *test.C) {
|
||||
// Ensure table + database exist
|
||||
DBCreate("test").Exec(session)
|
||||
DB("test").TableCreate("Table1").Exec(session)
|
||||
DB("test").Table("Table1").IndexCreate("num").Exec(session)
|
||||
DB("test").Table("Table1").IndexWait().Exec(session)
|
||||
|
||||
// Insert rows
|
||||
DB("test").Table("Table1").Insert(objList).Exec(session)
|
||||
|
||||
// Test query
|
||||
var response interface{}
|
||||
query := DB("test").Table("Table1").GetAllByIndex("num", 15).OrderBy("id")
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, map[string]interface{}{"id": 6, "g1": 1, "g2": 1, "num": 15})
|
||||
|
||||
res.Close()
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestSelectGetAllMultipleByIndex(c *test.C) {
|
||||
// Ensure table + database exist
|
||||
DBCreate("test").Exec(session)
|
||||
DB("test").TableCreate("Table2").Exec(session)
|
||||
DB("test").Table("Table2").IndexCreate("num").Exec(session)
|
||||
DB("test").Table("Table2").IndexWait().Exec(session)
|
||||
|
||||
// Insert rows
|
||||
DB("test").Table("Table2").Insert(objList).Exec(session)
|
||||
|
||||
// Test query
|
||||
var response interface{}
|
||||
query := DB("test").Table("Table2").GetAllByIndex("num", 15).OrderBy("id")
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, map[string]interface{}{"id": 6, "g1": 1, "g2": 1, "num": 15})
|
||||
|
||||
res.Close()
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestSelectGetAllCompoundIndex(c *test.C) {
|
||||
// Ensure table + database exist
|
||||
DBCreate("test").Exec(session)
|
||||
DB("test").TableDrop("TableCompound").Exec(session)
|
||||
DB("test").TableCreate("TableCompound").Exec(session)
|
||||
write, err := DB("test").Table("TableCompound").IndexCreateFunc("full_name", func(row Term) interface{} {
|
||||
return []interface{}{row.Field("first_name"), row.Field("last_name")}
|
||||
}).RunWrite(session)
|
||||
DB("test").Table("TableCompound").IndexWait().Exec(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(write.Created, test.Equals, 1)
|
||||
|
||||
// Insert rows
|
||||
DB("test").Table("TableCompound").Insert(nameList).Exec(session)
|
||||
|
||||
// Test query
|
||||
var response interface{}
|
||||
query := DB("test").Table("TableCompound").GetAllByIndex("full_name", []interface{}{"John", "Smith"})
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, map[string]interface{}{"id": 1, "first_name": "John", "last_name": "Smith", "gender": "M"})
|
||||
|
||||
res.Close()
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestSelectBetween(c *test.C) {
|
||||
// Ensure table + database exist
|
||||
DBCreate("test").Exec(session)
|
||||
DB("test").TableCreate("Table1").Exec(session)
|
||||
|
||||
// Insert rows
|
||||
DB("test").Table("Table1").Insert(objList).Exec(session)
|
||||
|
||||
// Test query
|
||||
var response []interface{}
|
||||
query := DB("test").Table("Table1").Between(1, 3).OrderBy("id")
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{
|
||||
map[string]interface{}{"num": 0, "id": 1, "g2": 1, "g1": 1},
|
||||
map[string]interface{}{"num": 5, "id": 2, "g2": 2, "g1": 2},
|
||||
})
|
||||
|
||||
res.Close()
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestSelectBetweenWithIndex(c *test.C) {
|
||||
// Ensure table + database exist
|
||||
DBCreate("test").Exec(session)
|
||||
DB("test").TableCreate("Table2").Exec(session)
|
||||
DB("test").Table("Table2").IndexCreate("num").Exec(session)
|
||||
DB("test").Table("Table2").IndexWait().Exec(session)
|
||||
|
||||
// Insert rows
|
||||
DB("test").Table("Table2").Insert(objList).Exec(session)
|
||||
|
||||
// Test query
|
||||
var response []interface{}
|
||||
query := DB("test").Table("Table2").Between(10, 50, BetweenOpts{
|
||||
Index: "num",
|
||||
}).OrderBy("id")
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{
|
||||
map[string]interface{}{"num": 10, "id": 3, "g2": 2, "g1": 3},
|
||||
map[string]interface{}{"num": 15, "id": 6, "g2": 1, "g1": 1},
|
||||
map[string]interface{}{"num": 25, "id": 9, "g2": 3, "g1": 2},
|
||||
})
|
||||
|
||||
res.Close()
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestSelectBetweenWithOptions(c *test.C) {
|
||||
// Ensure table + database exist
|
||||
DBCreate("test").Exec(session)
|
||||
DB("test").TableCreate("Table2").Exec(session)
|
||||
DB("test").Table("Table2").IndexCreate("num").Exec(session)
|
||||
DB("test").Table("Table2").IndexWait().Exec(session)
|
||||
|
||||
// Insert rows
|
||||
DB("test").Table("Table2").Insert(objList).Exec(session)
|
||||
|
||||
// Test query
|
||||
var response []interface{}
|
||||
query := DB("test").Table("Table2").Between(10, 50, BetweenOpts{
|
||||
Index: "num",
|
||||
RightBound: "closed",
|
||||
}).OrderBy("id")
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{
|
||||
map[string]interface{}{"num": 10, "id": 3, "g2": 2, "g1": 3},
|
||||
map[string]interface{}{"num": 15, "id": 6, "g2": 1, "g1": 1},
|
||||
map[string]interface{}{"num": 50, "id": 8, "g2": 2, "g1": 4},
|
||||
map[string]interface{}{"num": 25, "id": 9, "g2": 3, "g1": 2},
|
||||
})
|
||||
|
||||
res.Close()
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestSelectFilterImplicit(c *test.C) {
|
||||
// Ensure table + database exist
|
||||
DBCreate("test").Exec(session)
|
||||
DB("test").TableCreate("Table1").Exec(session)
|
||||
|
||||
// Insert rows
|
||||
DB("test").Table("Table1").Insert(objList).Exec(session)
|
||||
|
||||
// Test query
|
||||
var response []interface{}
|
||||
query := DB("test").Table("Table1").Filter(Row.Field("num").Ge(50)).OrderBy("id")
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{
|
||||
map[string]interface{}{"num": 100, "id": 5, "g2": 3, "g1": 2},
|
||||
map[string]interface{}{"num": 50, "id": 8, "g2": 2, "g1": 4},
|
||||
})
|
||||
|
||||
res.Close()
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestSelectFilterFunc(c *test.C) {
|
||||
// Ensure table + database exist
|
||||
DBCreate("test").Exec(session)
|
||||
DB("test").TableCreate("Table1").Exec(session)
|
||||
|
||||
// Insert rows
|
||||
DB("test").Table("Table1").Insert(objList).Exec(session)
|
||||
|
||||
// Test query
|
||||
var response []interface{}
|
||||
query := DB("test").Table("Table1").Filter(func(row Term) Term {
|
||||
return row.Field("num").Ge(50)
|
||||
}).OrderBy("id")
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{
|
||||
map[string]interface{}{"num": 100, "id": 5, "g2": 3, "g1": 2},
|
||||
map[string]interface{}{"num": 50, "id": 8, "g2": 2, "g1": 4},
|
||||
})
|
||||
|
||||
res.Close()
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestSelectManyRows(c *test.C) {
|
||||
// Ensure table + database exist
|
||||
DBCreate("test").RunWrite(session)
|
||||
DB("test").TableCreate("TestMany").RunWrite(session)
|
||||
DB("test").Table("TestMany").Delete().RunWrite(session)
|
||||
|
||||
// Insert rows
|
||||
for i := 0; i < 100; i++ {
|
||||
data := []interface{}{}
|
||||
|
||||
for j := 0; j < 100; j++ {
|
||||
data = append(data, map[string]interface{}{
|
||||
"i": i,
|
||||
"j": j,
|
||||
})
|
||||
}
|
||||
|
||||
DB("test").Table("TestMany").Insert(data).RunWrite(session)
|
||||
}
|
||||
|
||||
// Test query
|
||||
res, err := DB("test").Table("TestMany").Run(session, RunOpts{
|
||||
MaxBatchRows: 1,
|
||||
})
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
var n int
|
||||
var response map[string]interface{}
|
||||
for res.Next(&response) {
|
||||
n++
|
||||
}
|
||||
|
||||
c.Assert(res.Err(), test.IsNil)
|
||||
c.Assert(n, test.Equals, 10000)
|
||||
|
||||
res.Close()
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestConcurrentSelectManyWorkers(c *test.C) {
|
||||
if testing.Short() {
|
||||
c.Skip("Skipping long test")
|
||||
}
|
||||
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
sess, _ := Connect(ConnectOpts{
|
||||
Address: url,
|
||||
MaxOpen: 200,
|
||||
MaxIdle: 200,
|
||||
})
|
||||
|
||||
// Ensure table + database exist
|
||||
DBCreate("test").RunWrite(sess)
|
||||
DB("test").TableDrop("TestConcurrent").RunWrite(sess)
|
||||
DB("test").TableCreate("TestConcurrent").RunWrite(sess)
|
||||
DB("test").TableDrop("TestConcurrent2").RunWrite(sess)
|
||||
DB("test").TableCreate("TestConcurrent2").RunWrite(sess)
|
||||
|
||||
// Insert rows
|
||||
for j := 0; j < 200; j++ {
|
||||
DB("test").Table("TestConcurrent").Insert(map[string]interface{}{
|
||||
"id": j,
|
||||
"i": j,
|
||||
}).Exec(sess)
|
||||
DB("test").Table("TestConcurrent2").Insert(map[string]interface{}{
|
||||
"j": j,
|
||||
"k": j * 2,
|
||||
}).Exec(sess)
|
||||
}
|
||||
|
||||
// Test queries concurrently
|
||||
numQueries := 1000
|
||||
numWorkers := 10
|
||||
queryChan := make(chan int)
|
||||
doneChan := make(chan error)
|
||||
|
||||
// Start workers
|
||||
for i := 0; i < numWorkers; i++ {
|
||||
go func() {
|
||||
for _ = range queryChan {
|
||||
res, err := DB("test").Table("TestConcurrent2").EqJoin("j", DB("test").Table("TestConcurrent")).Zip().Run(sess)
|
||||
if err != nil {
|
||||
doneChan <- err
|
||||
return
|
||||
}
|
||||
|
||||
var response []map[string]interface{}
|
||||
err = res.All(&response)
|
||||
if err != nil {
|
||||
doneChan <- err
|
||||
return
|
||||
}
|
||||
if err := res.Close(); err != nil {
|
||||
doneChan <- err
|
||||
return
|
||||
}
|
||||
|
||||
if len(response) != 200 {
|
||||
doneChan <- fmt.Errorf("expected response length 200, received %d", len(response))
|
||||
return
|
||||
}
|
||||
|
||||
res, err = DB("test").Table("TestConcurrent").Get(response[rand.Intn(len(response))]["id"]).Run(sess)
|
||||
if err != nil {
|
||||
doneChan <- err
|
||||
return
|
||||
}
|
||||
|
||||
err = res.All(&response)
|
||||
if err != nil {
|
||||
doneChan <- err
|
||||
return
|
||||
}
|
||||
if err := res.Close(); err != nil {
|
||||
doneChan <- err
|
||||
return
|
||||
}
|
||||
|
||||
if len(response) != 1 {
|
||||
doneChan <- fmt.Errorf("expected response length 1, received %d", len(response))
|
||||
return
|
||||
}
|
||||
|
||||
doneChan <- nil
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
go func() {
|
||||
for i := 0; i < numQueries; i++ {
|
||||
queryChan <- i
|
||||
}
|
||||
}()
|
||||
|
||||
for i := 0; i < numQueries; i++ {
|
||||
ret := <-doneChan
|
||||
if ret != nil {
|
||||
c.Fatalf("non-nil error returned (%s)", ret)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestConcurrentSelectManyRows(c *test.C) {
|
||||
if testing.Short() {
|
||||
c.Skip("Skipping long test")
|
||||
}
|
||||
|
||||
// Ensure table + database exist
|
||||
DBCreate("test").RunWrite(session)
|
||||
DB("test").TableCreate("TestMany").RunWrite(session)
|
||||
DB("test").Table("TestMany").Delete().RunWrite(session)
|
||||
|
||||
// Insert rows
|
||||
for i := 0; i < 100; i++ {
|
||||
DB("test").Table("TestMany").Insert(map[string]interface{}{
|
||||
"i": i,
|
||||
}).Exec(session)
|
||||
}
|
||||
|
||||
// Test queries concurrently
|
||||
attempts := 10
|
||||
waitChannel := make(chan error, attempts)
|
||||
|
||||
for i := 0; i < attempts; i++ {
|
||||
go func(i int, ch chan error) {
|
||||
res, err := DB("test").Table("TestMany").Run(session)
|
||||
if err != nil {
|
||||
ch <- err
|
||||
return
|
||||
}
|
||||
|
||||
var response []map[string]interface{}
|
||||
err = res.All(&response)
|
||||
if err != nil {
|
||||
ch <- err
|
||||
return
|
||||
}
|
||||
|
||||
if len(response) != 100 {
|
||||
ch <- fmt.Errorf("expected response length 100, received %d", len(response))
|
||||
return
|
||||
}
|
||||
|
||||
res.Close()
|
||||
|
||||
ch <- nil
|
||||
}(i, waitChannel)
|
||||
}
|
||||
|
||||
for i := 0; i < attempts; i++ {
|
||||
ret := <-waitChannel
|
||||
if ret != nil {
|
||||
c.Fatalf("non-nil error returned (%s)", ret)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package gorethink
|
||||
|
||||
import (
|
||||
p "github.com/dancannon/gorethink/ql2"
|
||||
p "gopkg.in/dancannon/gorethink.v2/ql2"
|
||||
)
|
||||
|
||||
// Match matches against a regular expression. If no match is found, returns
|
||||
91
vendor/gopkg.in/dancannon/gorethink.v2/query_string_test.go
generated
vendored
Normal file
91
vendor/gopkg.in/dancannon/gorethink.v2/query_string_test.go
generated
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
package gorethink
|
||||
|
||||
import (
|
||||
test "gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
func (s *RethinkSuite) TestStringMatchSuccess(c *test.C) {
|
||||
query := Expr("id:0,name:mlucy,foo:bar").Match("name:(\\w+)").Field("groups").Nth(0).Field("str")
|
||||
|
||||
var response string
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, "mlucy")
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestStringMatchFail(c *test.C) {
|
||||
query := Expr("id:0,foo:bar").Match("name:(\\w+)")
|
||||
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(res.IsNil(), test.Equals, true)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestStringSplit(c *test.C) {
|
||||
query := Expr("a,b,c").Split(",")
|
||||
|
||||
var response []string
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.DeepEquals, []string{"a", "b", "c"})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestStringSplitMax(c *test.C) {
|
||||
query := Expr("a,b,c").Split(",", 1)
|
||||
|
||||
var response []string
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.DeepEquals, []string{"a", "b,c"})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestStringSplitWhitespace(c *test.C) {
|
||||
query := Expr("a b c").Split()
|
||||
|
||||
var response []string
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.DeepEquals, []string{"a", "b", "c"})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestStringMatchUpcase(c *test.C) {
|
||||
query := Expr("tESt").Upcase()
|
||||
|
||||
var response string
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, "TEST")
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestStringMatchDowncase(c *test.C) {
|
||||
query := Expr("tESt").Downcase()
|
||||
|
||||
var response string
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, "test")
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package gorethink
|
||||
|
||||
import (
|
||||
p "github.com/dancannon/gorethink/ql2"
|
||||
p "gopkg.in/dancannon/gorethink.v2/ql2"
|
||||
)
|
||||
|
||||
// TableCreateOpts contains the optional arguments for the TableCreate term
|
||||
@@ -78,9 +78,8 @@ func (o *IndexCreateOpts) toMap() map[string]interface{} {
|
||||
// IndexCreate supports the creation of the following types of indexes, to create
|
||||
// indexes using arbitrary expressions use IndexCreateFunc.
|
||||
// - Simple indexes based on the value of a single field.
|
||||
// - Compound indexes based on multiple fields.
|
||||
// - Multi indexes based on arrays of values, created when the multi optional argument is true.
|
||||
// - Geospatial indexes based on indexes of geometry objects, created when the geo optional argument is true.
|
||||
// - Geospatial indexes based on indexes of geometry objects, created when the
|
||||
// geo optional argument is true.
|
||||
func (t Term) IndexCreate(name interface{}, optArgs ...IndexCreateOpts) Term {
|
||||
opts := map[string]interface{}{}
|
||||
if len(optArgs) >= 1 {
|
||||
@@ -91,10 +90,15 @@ func (t Term) IndexCreate(name interface{}, optArgs ...IndexCreateOpts) Term {
|
||||
|
||||
// IndexCreateFunc creates a new secondary index on a table. Secondary indexes
|
||||
// improve the speed of many read queries at the slight cost of increased
|
||||
// storage space and decreased write performance.
|
||||
// storage space and decreased write performance. The function takes a index
|
||||
// name and RQL term as the index value , the term can be an anonymous function
|
||||
// or a binary representation obtained from the function field of indexStatus.
|
||||
//
|
||||
// The indexFunction can be an anonymous function or a binary representation
|
||||
// obtained from the function field of indexStatus.
|
||||
// It supports the creation of the following types of indexes.
|
||||
// - Simple indexes based on the value of a single field where the index has a
|
||||
// different name to the field.
|
||||
// - Compound indexes based on multiple fields.
|
||||
// - Multi indexes based on arrays of values, created when the multi optional argument is true.
|
||||
func (t Term) IndexCreateFunc(name, indexFunction interface{}, optArgs ...IndexCreateOpts) Term {
|
||||
opts := map[string]interface{}{}
|
||||
if len(optArgs) >= 1 {
|
||||
344
vendor/gopkg.in/dancannon/gorethink.v2/query_table_test.go
generated
vendored
Normal file
344
vendor/gopkg.in/dancannon/gorethink.v2/query_table_test.go
generated
vendored
Normal file
@@ -0,0 +1,344 @@
|
||||
package gorethink
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
test "gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
func (s *RethinkSuite) TestTableCreate(c *test.C) {
|
||||
DB("test").TableDrop("test").Exec(session)
|
||||
|
||||
// Test database creation
|
||||
query := DB("test").TableCreate("test")
|
||||
|
||||
response, err := query.RunWrite(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response.TablesCreated, jsonEquals, 1)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestTableCreateSessionDatabase(c *test.C) {
|
||||
session, err := Connect(ConnectOpts{
|
||||
Address: url,
|
||||
})
|
||||
c.Assert(err, test.IsNil)
|
||||
TableDrop("test").Exec(session)
|
||||
|
||||
// Test database creation
|
||||
response, err := TableCreate("test").RunWrite(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response.TablesCreated, jsonEquals, 1)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestTableCreatePrimaryKey(c *test.C) {
|
||||
DB("test").TableDrop("testOpts").Exec(session)
|
||||
|
||||
// Test database creation
|
||||
query := DB("test").TableCreate("testOpts", TableCreateOpts{
|
||||
PrimaryKey: "it",
|
||||
})
|
||||
|
||||
response, err := query.RunWrite(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response.TablesCreated, jsonEquals, 1)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestTableCreateSoftDurability(c *test.C) {
|
||||
DB("test").TableDrop("testOpts").Exec(session)
|
||||
|
||||
// Test database creation
|
||||
query := DB("test").TableCreate("testOpts", TableCreateOpts{
|
||||
Durability: "soft",
|
||||
})
|
||||
|
||||
response, err := query.RunWrite(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response.TablesCreated, jsonEquals, 1)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestTableCreateSoftMultipleOpts(c *test.C) {
|
||||
DB("test").TableDrop("testOpts").Exec(session)
|
||||
|
||||
// Test database creation
|
||||
query := DB("test").TableCreate("testOpts", TableCreateOpts{
|
||||
PrimaryKey: "it",
|
||||
Durability: "soft",
|
||||
})
|
||||
|
||||
response, err := query.RunWrite(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response.TablesCreated, jsonEquals, 1)
|
||||
|
||||
DB("test").TableDrop("test").Exec(session)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestTableList(c *test.C) {
|
||||
var response []interface{}
|
||||
|
||||
DB("test").TableCreate("test").Exec(session)
|
||||
|
||||
// Try and find it in the list
|
||||
success := false
|
||||
res, err := DB("test").TableList().Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.FitsTypeOf, []interface{}{})
|
||||
|
||||
for _, db := range response {
|
||||
if db == "test" {
|
||||
success = true
|
||||
}
|
||||
}
|
||||
|
||||
c.Assert(success, test.Equals, true)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestTableDelete(c *test.C) {
|
||||
DB("test").TableCreate("test").Exec(session)
|
||||
|
||||
// Test database creation
|
||||
query := DB("test").TableDrop("test")
|
||||
|
||||
response, err := query.RunWrite(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response.TablesDropped, jsonEquals, 1)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestTableIndexCreate(c *test.C) {
|
||||
DB("test").TableCreate("test").Exec(session)
|
||||
DB("test").Table("test").IndexDrop("test").Exec(session)
|
||||
|
||||
// Test database creation
|
||||
query := DB("test").Table("test").IndexCreate("test", IndexCreateOpts{
|
||||
Multi: true,
|
||||
})
|
||||
|
||||
response, err := query.RunWrite(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response.Created, jsonEquals, 1)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestTableCompoundIndexCreate(c *test.C) {
|
||||
DBCreate("test").Exec(session)
|
||||
DB("test").TableDrop("TableCompound").Exec(session)
|
||||
DB("test").TableCreate("TableCompound").Exec(session)
|
||||
response, err := DB("test").Table("TableCompound").IndexCreateFunc("full_name", func(row Term) interface{} {
|
||||
return []interface{}{row.Field("first_name"), row.Field("last_name")}
|
||||
}).RunWrite(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response.Created, test.Equals, 1)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestTableIndexList(c *test.C) {
|
||||
var response []interface{}
|
||||
|
||||
DB("test").TableCreate("test").Exec(session)
|
||||
DB("test").Table("test").IndexCreate("test").Exec(session)
|
||||
DB("test").Table("test").IndexWait().Exec(session)
|
||||
|
||||
// Try and find it in the list
|
||||
success := false
|
||||
res, err := DB("test").Table("test").IndexList().Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.FitsTypeOf, []interface{}{})
|
||||
|
||||
for _, db := range response {
|
||||
if db == "test" {
|
||||
success = true
|
||||
}
|
||||
}
|
||||
|
||||
c.Assert(success, test.Equals, true)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestTableIndexDelete(c *test.C) {
|
||||
DB("test").TableCreate("test").Exec(session)
|
||||
DB("test").Table("test").IndexCreate("test").Exec(session)
|
||||
DB("test").Table("test").IndexWait().Exec(session)
|
||||
|
||||
// Test database creation
|
||||
query := DB("test").Table("test").IndexDrop("test")
|
||||
|
||||
response, err := query.RunWrite(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response.Dropped, jsonEquals, 1)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestTableIndexRename(c *test.C) {
|
||||
DB("test").TableDrop("test").Exec(session)
|
||||
DB("test").TableCreate("test").Exec(session)
|
||||
DB("test").Table("test").IndexCreate("test").Exec(session)
|
||||
DB("test").Table("test").IndexWait().Exec(session)
|
||||
|
||||
// Test index rename
|
||||
query := DB("test").Table("test").IndexRename("test", "test2")
|
||||
|
||||
response, err := query.RunWrite(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response.Renamed, jsonEquals, 1)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestTableChanges(c *test.C) {
|
||||
DB("test").TableDrop("changes").Exec(session)
|
||||
DB("test").TableCreate("changes").Exec(session)
|
||||
|
||||
var n int
|
||||
|
||||
res, err := DB("test").Table("changes").Changes().Run(session)
|
||||
if err != nil {
|
||||
c.Fatal(err.Error())
|
||||
}
|
||||
c.Assert(res.Type(), test.Equals, "Feed")
|
||||
|
||||
wg := &sync.WaitGroup{}
|
||||
wg.Add(1)
|
||||
|
||||
// Use goroutine to wait for changes. Prints the first 10 results
|
||||
go func() {
|
||||
var response interface{}
|
||||
for n < 10 && res.Next(&response) {
|
||||
n++
|
||||
}
|
||||
|
||||
if res.Err() != nil {
|
||||
c.Fatal(res.Err())
|
||||
}
|
||||
|
||||
wg.Done()
|
||||
}()
|
||||
|
||||
DB("test").Table("changes").Insert(map[string]interface{}{"n": 1}).Exec(session)
|
||||
DB("test").Table("changes").Insert(map[string]interface{}{"n": 2}).Exec(session)
|
||||
DB("test").Table("changes").Insert(map[string]interface{}{"n": 3}).Exec(session)
|
||||
DB("test").Table("changes").Insert(map[string]interface{}{"n": 4}).Exec(session)
|
||||
DB("test").Table("changes").Insert(map[string]interface{}{"n": 5}).Exec(session)
|
||||
DB("test").Table("changes").Insert(map[string]interface{}{"n": 6}).Exec(session)
|
||||
DB("test").Table("changes").Insert(map[string]interface{}{"n": 7}).Exec(session)
|
||||
DB("test").Table("changes").Insert(map[string]interface{}{"n": 8}).Exec(session)
|
||||
DB("test").Table("changes").Insert(map[string]interface{}{"n": 9}).Exec(session)
|
||||
DB("test").Table("changes").Insert(map[string]interface{}{"n": 10}).Exec(session)
|
||||
|
||||
wg.Wait()
|
||||
|
||||
c.Assert(n, test.Equals, 10)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestTableChangesExit(c *test.C) {
|
||||
DB("test").TableDrop("changes").Exec(session)
|
||||
DB("test").TableCreate("changes").Exec(session)
|
||||
|
||||
var n int
|
||||
|
||||
res, err := DB("test").Table("changes").Changes().Run(session)
|
||||
if err != nil {
|
||||
c.Fatal(err.Error())
|
||||
}
|
||||
c.Assert(res.Type(), test.Equals, "Feed")
|
||||
|
||||
change := make(chan ChangeResponse)
|
||||
|
||||
// Close cursor after one second
|
||||
go func() {
|
||||
<-time.After(time.Second)
|
||||
res.Close()
|
||||
}()
|
||||
|
||||
// Insert 5 docs
|
||||
DB("test").Table("changes").Insert(map[string]interface{}{"n": 1}).Exec(session)
|
||||
DB("test").Table("changes").Insert(map[string]interface{}{"n": 2}).Exec(session)
|
||||
DB("test").Table("changes").Insert(map[string]interface{}{"n": 3}).Exec(session)
|
||||
DB("test").Table("changes").Insert(map[string]interface{}{"n": 4}).Exec(session)
|
||||
DB("test").Table("changes").Insert(map[string]interface{}{"n": 5}).Exec(session)
|
||||
|
||||
// Listen for changes
|
||||
res.Listen(change)
|
||||
for _ = range change {
|
||||
n++
|
||||
}
|
||||
|
||||
c.Assert(n, test.Equals, 5)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestTableChangesExitNoResults(c *test.C) {
|
||||
DB("test").TableDrop("changes").Exec(session)
|
||||
DB("test").TableCreate("changes").Exec(session)
|
||||
|
||||
var n int
|
||||
|
||||
res, err := DB("test").Table("changes").Changes().Run(session)
|
||||
if err != nil {
|
||||
c.Fatal(err.Error())
|
||||
}
|
||||
c.Assert(res.Type(), test.Equals, "Feed")
|
||||
|
||||
change := make(chan ChangeResponse)
|
||||
|
||||
// Close cursor after one second
|
||||
go func() {
|
||||
<-time.After(time.Second)
|
||||
res.Close()
|
||||
}()
|
||||
|
||||
// Listen for changes
|
||||
res.Listen(change)
|
||||
for _ = range change {
|
||||
n++
|
||||
}
|
||||
|
||||
c.Assert(n, test.Equals, 0)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestTableChangesIncludeInitial(c *test.C) {
|
||||
DB("test").TableDrop("changes").Exec(session)
|
||||
DB("test").TableCreate("changes").Exec(session)
|
||||
|
||||
// Insert 5 documents to table initially
|
||||
DB("test").Table("changes").Insert(map[string]interface{}{"n": 1}).Exec(session)
|
||||
DB("test").Table("changes").Insert(map[string]interface{}{"n": 2}).Exec(session)
|
||||
DB("test").Table("changes").Insert(map[string]interface{}{"n": 3}).Exec(session)
|
||||
DB("test").Table("changes").Insert(map[string]interface{}{"n": 4}).Exec(session)
|
||||
DB("test").Table("changes").Insert(map[string]interface{}{"n": 5}).Exec(session)
|
||||
|
||||
var n int
|
||||
|
||||
res, err := DB("test").Table("changes").Changes(ChangesOpts{IncludeInitial: true}).Run(session)
|
||||
if err != nil {
|
||||
c.Fatal(err.Error())
|
||||
}
|
||||
c.Assert(res.Type(), test.Equals, "Feed")
|
||||
|
||||
wg := &sync.WaitGroup{}
|
||||
wg.Add(1)
|
||||
|
||||
// Use goroutine to wait for changes. Prints the first 10 results
|
||||
go func() {
|
||||
var response interface{}
|
||||
for n < 10 && res.Next(&response) {
|
||||
n++
|
||||
}
|
||||
|
||||
if res.Err() != nil {
|
||||
c.Fatal(res.Err())
|
||||
}
|
||||
|
||||
wg.Done()
|
||||
}()
|
||||
|
||||
DB("test").Table("changes").Insert(map[string]interface{}{"n": 6}).Exec(session)
|
||||
DB("test").Table("changes").Insert(map[string]interface{}{"n": 7}).Exec(session)
|
||||
DB("test").Table("changes").Insert(map[string]interface{}{"n": 8}).Exec(session)
|
||||
DB("test").Table("changes").Insert(map[string]interface{}{"n": 9}).Exec(session)
|
||||
DB("test").Table("changes").Insert(map[string]interface{}{"n": 10}).Exec(session)
|
||||
|
||||
wg.Wait()
|
||||
|
||||
c.Assert(n, test.Equals, 10)
|
||||
}
|
||||
67
vendor/gopkg.in/dancannon/gorethink.v2/query_test.go
generated
vendored
Normal file
67
vendor/gopkg.in/dancannon/gorethink.v2/query_test.go
generated
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
package gorethink
|
||||
|
||||
import test "gopkg.in/check.v1"
|
||||
|
||||
func (s *RethinkSuite) TestQueryRun(c *test.C) {
|
||||
var response string
|
||||
|
||||
res, err := Expr("Test").Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, "Test")
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestQueryReadOne(c *test.C) {
|
||||
var response string
|
||||
|
||||
err := Expr("Test").ReadOne(&response, session)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, "Test")
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestQueryReadAll(c *test.C) {
|
||||
var response []int
|
||||
|
||||
err := Expr([]int{1, 2, 3}).ReadAll(&response, session)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.HasLen, 3)
|
||||
c.Assert(response, test.DeepEquals, []int{1, 2, 3})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestQueryExec(c *test.C) {
|
||||
err := Expr("Test").Exec(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestQueryProfile(c *test.C) {
|
||||
var response string
|
||||
|
||||
res, err := Expr("Test").Run(session, RunOpts{
|
||||
Profile: true,
|
||||
})
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(res.Profile(), test.NotNil)
|
||||
c.Assert(response, test.Equals, "Test")
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestQueryRunRawTime(c *test.C) {
|
||||
var response map[string]interface{}
|
||||
|
||||
res, err := Now().Run(session, RunOpts{
|
||||
TimeFormat: "raw",
|
||||
})
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response["$reql_type$"], test.NotNil)
|
||||
c.Assert(response["$reql_type$"], test.Equals, "TIME")
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package gorethink
|
||||
|
||||
import (
|
||||
p "github.com/dancannon/gorethink/ql2"
|
||||
p "gopkg.in/dancannon/gorethink.v2/ql2"
|
||||
)
|
||||
|
||||
// Now returns a time object representing the current time in UTC
|
||||
135
vendor/gopkg.in/dancannon/gorethink.v2/query_time_test.go
generated
vendored
Normal file
135
vendor/gopkg.in/dancannon/gorethink.v2/query_time_test.go
generated
vendored
Normal file
@@ -0,0 +1,135 @@
|
||||
package gorethink
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
test "gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
func (s *RethinkSuite) TestTimeTime(c *test.C) {
|
||||
var response time.Time
|
||||
res, err := Time(1986, 11, 3, 12, 30, 15, "Z").Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response.Equal(time.Date(1986, 11, 3, 12, 30, 15, 0, time.UTC)), test.Equals, true)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestTimeTimeMillisecond(c *test.C) {
|
||||
var response time.Time
|
||||
res, err := Time(1986, 11, 3, 12, 30, 15.6790123, "Z").Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response.Equal(time.Date(1986, 11, 3, 12, 30, 15, 679*1000*1000, time.UTC)), test.Equals, true)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestTimeEpochTime(c *test.C) {
|
||||
var response time.Time
|
||||
res, err := EpochTime(531360000).Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response.Equal(time.Date(1986, 11, 3, 0, 0, 0, 0, time.UTC)), test.Equals, true)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestTimeExpr(c *test.C) {
|
||||
var response time.Time
|
||||
t := time.Unix(531360000, 0)
|
||||
res, err := Expr(Expr(t)).Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestTimeExprMillisecond(c *test.C) {
|
||||
var response time.Time
|
||||
t := time.Unix(531360000, 679000000)
|
||||
res, err := Expr(t).Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(float64(response.UnixNano()), test.Equals, float64(t.UnixNano()))
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestTimeISO8601(c *test.C) {
|
||||
var t1, t2 time.Time
|
||||
t2, _ = time.Parse("2006-01-02T15:04:05-07:00", "1986-11-03T08:30:00-07:00")
|
||||
res, err := ISO8601("1986-11-03T08:30:00-07:00").Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&t1)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(t1.Equal(t2), test.Equals, true)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestTimeInTimezone(c *test.C) {
|
||||
var response []time.Time
|
||||
res, err := Expr([]interface{}{Now(), Now().InTimezone("-07:00")}).Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response[1].Equal(response[0]), test.Equals, true)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestTimeBetween(c *test.C) {
|
||||
var response interface{}
|
||||
|
||||
times := Expr([]interface{}{
|
||||
Time(1986, 9, 3, 12, 30, 15, "Z"),
|
||||
Time(1986, 10, 3, 12, 30, 15, "Z"),
|
||||
Time(1986, 11, 3, 12, 30, 15, "Z"),
|
||||
Time(1986, 12, 3, 12, 30, 15, "Z"),
|
||||
})
|
||||
res, err := times.Filter(func(row Term) Term {
|
||||
return row.During(Time(1986, 9, 3, 12, 30, 15, "Z"), Time(1986, 11, 3, 12, 30, 15, "Z"))
|
||||
}).Count().Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(int(response.(float64)), test.Equals, 2)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestTimeYear(c *test.C) {
|
||||
var response interface{}
|
||||
|
||||
res, err := Time(1986, 12, 3, 12, 30, 15, "Z").Year().Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(int(response.(float64)), test.Equals, 1986)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestTimeMonth(c *test.C) {
|
||||
var response interface{}
|
||||
|
||||
res, err := Time(1986, 12, 3, 12, 30, 15, "Z").Month().Eq(December).Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response.(bool), test.Equals, true)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestTimeDay(c *test.C) {
|
||||
var response interface{}
|
||||
|
||||
res, err := Time(1986, 12, 3, 12, 30, 15, "Z").Day().Eq(Wednesday).Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response.(bool), test.Equals, true)
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package gorethink
|
||||
|
||||
import p "github.com/dancannon/gorethink/ql2"
|
||||
import p "gopkg.in/dancannon/gorethink.v2/ql2"
|
||||
|
||||
// Map transform each element of the sequence by applying the given mapping
|
||||
// function. It takes two arguments, a sequence and a function of type
|
||||
441
vendor/gopkg.in/dancannon/gorethink.v2/query_transformation_test.go
generated
vendored
Normal file
441
vendor/gopkg.in/dancannon/gorethink.v2/query_transformation_test.go
generated
vendored
Normal file
@@ -0,0 +1,441 @@
|
||||
package gorethink
|
||||
|
||||
import (
|
||||
test "gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
func (s *RethinkSuite) TestTransformationMapImplicit(c *test.C) {
|
||||
query := Expr(arr).Map(Row.Add(1))
|
||||
|
||||
var response []interface{}
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{2, 3, 4, 5, 6, 7, 8, 9, 10})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestTransformationMapFunc(c *test.C) {
|
||||
query := Expr(arr).Map(func(row Term) Term {
|
||||
return row.Add(1)
|
||||
})
|
||||
|
||||
var response []interface{}
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{2, 3, 4, 5, 6, 7, 8, 9, 10})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestTransformationWithFields(c *test.C) {
|
||||
query := Expr(objList).WithFields("id", "num").OrderBy("id")
|
||||
|
||||
var response []interface{}
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{
|
||||
map[string]interface{}{"num": 0, "id": 1},
|
||||
map[string]interface{}{"num": 5, "id": 2},
|
||||
map[string]interface{}{"num": 10, "id": 3},
|
||||
map[string]interface{}{"num": 0, "id": 4},
|
||||
map[string]interface{}{"num": 100, "id": 5},
|
||||
map[string]interface{}{"num": 15, "id": 6},
|
||||
map[string]interface{}{"num": 0, "id": 7},
|
||||
map[string]interface{}{"num": 50, "id": 8},
|
||||
map[string]interface{}{"num": 25, "id": 9},
|
||||
})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestTransformationConcatMap(c *test.C) {
|
||||
query := Expr(objList).ConcatMap(func(row Term) Term {
|
||||
return Expr([]interface{}{row.Field("num")})
|
||||
})
|
||||
|
||||
var response []interface{}
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{0, 5, 10, 0, 100, 15, 0, 50, 25})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestTransformationVariadicMap(c *test.C) {
|
||||
query := Range(5).Map(Range(5), func(a, b Term) interface{} {
|
||||
return []interface{}{a, b}
|
||||
})
|
||||
|
||||
var response []interface{}
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, [][]int{
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{3, 3},
|
||||
{4, 4},
|
||||
})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestTransformationVariadicRootMap(c *test.C) {
|
||||
query := Map(Range(5), Range(5), func(a, b Term) interface{} {
|
||||
return []interface{}{a, b}
|
||||
})
|
||||
|
||||
var response []interface{}
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, [][]int{
|
||||
{0, 0},
|
||||
{1, 1},
|
||||
{2, 2},
|
||||
{3, 3},
|
||||
{4, 4},
|
||||
})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestTransformationOrderByDesc(c *test.C) {
|
||||
query := Expr(noDupNumObjList).OrderBy(Desc("num"))
|
||||
|
||||
var response []interface{}
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{
|
||||
map[string]interface{}{"num": 100, "id": 5, "g2": 3, "g1": 2},
|
||||
map[string]interface{}{"num": 50, "id": 8, "g2": 2, "g1": 4},
|
||||
map[string]interface{}{"num": 25, "id": 9, "g2": 3, "g1": 2},
|
||||
map[string]interface{}{"num": 15, "id": 6, "g2": 1, "g1": 1},
|
||||
map[string]interface{}{"num": 10, "id": 3, "g2": 2, "g1": 3},
|
||||
map[string]interface{}{"num": 5, "id": 2, "g2": 2, "g1": 2},
|
||||
map[string]interface{}{"num": 0, "id": 1, "g2": 1, "g1": 1},
|
||||
})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestTransformationOrderByAsc(c *test.C) {
|
||||
query := Expr(noDupNumObjList).OrderBy(Asc("num"))
|
||||
|
||||
var response []interface{}
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{
|
||||
map[string]interface{}{"num": 0, "id": 1, "g2": 1, "g1": 1},
|
||||
map[string]interface{}{"num": 5, "id": 2, "g2": 2, "g1": 2},
|
||||
map[string]interface{}{"num": 10, "id": 3, "g2": 2, "g1": 3},
|
||||
map[string]interface{}{"num": 15, "id": 6, "g2": 1, "g1": 1},
|
||||
map[string]interface{}{"num": 25, "id": 9, "g2": 3, "g1": 2},
|
||||
map[string]interface{}{"num": 50, "id": 8, "g2": 2, "g1": 4},
|
||||
map[string]interface{}{"num": 100, "id": 5, "g2": 3, "g1": 2},
|
||||
})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestTransformationOrderByIndex(c *test.C) {
|
||||
DB("test").TableCreate("OrderByIndex").Exec(session)
|
||||
DB("test").Table("test").IndexDrop("OrderByIndex").Exec(session)
|
||||
|
||||
// Test database creation
|
||||
DB("test").Table("OrderByIndex").IndexCreateFunc("test", Row.Field("num")).Exec(session)
|
||||
DB("test").Table("OrderByIndex").IndexWait().Exec(session)
|
||||
DB("test").Table("OrderByIndex").Insert(noDupNumObjList).Exec(session)
|
||||
|
||||
query := DB("test").Table("OrderByIndex").OrderBy(OrderByOpts{
|
||||
Index: "test",
|
||||
})
|
||||
|
||||
var response []interface{}
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{
|
||||
map[string]interface{}{"num": 0, "id": 1, "g2": 1, "g1": 1},
|
||||
map[string]interface{}{"num": 5, "id": 2, "g2": 2, "g1": 2},
|
||||
map[string]interface{}{"num": 10, "id": 3, "g2": 2, "g1": 3},
|
||||
map[string]interface{}{"num": 15, "id": 6, "g2": 1, "g1": 1},
|
||||
map[string]interface{}{"num": 25, "id": 9, "g2": 3, "g1": 2},
|
||||
map[string]interface{}{"num": 50, "id": 8, "g2": 2, "g1": 4},
|
||||
map[string]interface{}{"num": 100, "id": 5, "g2": 3, "g1": 2},
|
||||
})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestTransformationOrderByIndexAsc(c *test.C) {
|
||||
DB("test").TableCreate("OrderByIndex").Exec(session)
|
||||
DB("test").Table("test").IndexDrop("OrderByIndex").Exec(session)
|
||||
|
||||
// Test database creation
|
||||
DB("test").Table("OrderByIndex").IndexCreateFunc("test", Row.Field("num")).Exec(session)
|
||||
DB("test").Table("OrderByIndex").IndexWait().Exec(session)
|
||||
DB("test").Table("OrderByIndex").Insert(noDupNumObjList).Exec(session)
|
||||
|
||||
query := DB("test").Table("OrderByIndex").OrderBy(OrderByOpts{
|
||||
Index: Asc("test"),
|
||||
})
|
||||
|
||||
var response []interface{}
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{
|
||||
map[string]interface{}{"num": 0, "id": 1, "g2": 1, "g1": 1},
|
||||
map[string]interface{}{"num": 5, "id": 2, "g2": 2, "g1": 2},
|
||||
map[string]interface{}{"num": 10, "id": 3, "g2": 2, "g1": 3},
|
||||
map[string]interface{}{"num": 15, "id": 6, "g2": 1, "g1": 1},
|
||||
map[string]interface{}{"num": 25, "id": 9, "g2": 3, "g1": 2},
|
||||
map[string]interface{}{"num": 50, "id": 8, "g2": 2, "g1": 4},
|
||||
map[string]interface{}{"num": 100, "id": 5, "g2": 3, "g1": 2},
|
||||
})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestTransformationOrderByMultiple(c *test.C) {
|
||||
query := Expr(objList).OrderBy(Desc("num"), Asc("id"))
|
||||
|
||||
var response []interface{}
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{
|
||||
map[string]interface{}{"num": 100, "id": 5, "g2": 3, "g1": 2},
|
||||
map[string]interface{}{"num": 50, "id": 8, "g2": 2, "g1": 4},
|
||||
map[string]interface{}{"num": 25, "id": 9, "g2": 3, "g1": 2},
|
||||
map[string]interface{}{"num": 15, "id": 6, "g2": 1, "g1": 1},
|
||||
map[string]interface{}{"num": 10, "id": 3, "g2": 2, "g1": 3},
|
||||
map[string]interface{}{"num": 5, "id": 2, "g2": 2, "g1": 2},
|
||||
map[string]interface{}{"num": 0, "id": 1, "g2": 1, "g1": 1},
|
||||
map[string]interface{}{"num": 0, "id": 4, "g2": 3, "g1": 2},
|
||||
map[string]interface{}{"num": 0, "id": 7, "g2": 2, "g1": 1},
|
||||
})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestTransformationOrderByFunc(c *test.C) {
|
||||
query := Expr(objList).OrderBy(func(row Term) Term {
|
||||
return row.Field("num").Add(row.Field("id"))
|
||||
})
|
||||
|
||||
var response []interface{}
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{
|
||||
map[string]interface{}{"num": 0, "id": 1, "g2": 1, "g1": 1},
|
||||
map[string]interface{}{"num": 0, "id": 4, "g2": 3, "g1": 2},
|
||||
map[string]interface{}{"num": 5, "id": 2, "g2": 2, "g1": 2},
|
||||
map[string]interface{}{"num": 0, "id": 7, "g2": 2, "g1": 1},
|
||||
map[string]interface{}{"num": 10, "id": 3, "g2": 2, "g1": 3},
|
||||
map[string]interface{}{"num": 15, "id": 6, "g2": 1, "g1": 1},
|
||||
map[string]interface{}{"num": 25, "id": 9, "g2": 3, "g1": 2},
|
||||
map[string]interface{}{"num": 50, "id": 8, "g2": 2, "g1": 4},
|
||||
map[string]interface{}{"num": 100, "id": 5, "g2": 3, "g1": 2},
|
||||
})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestTransformationSkip(c *test.C) {
|
||||
query := Expr(arr).Skip(7)
|
||||
|
||||
var response []interface{}
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{8, 9})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestTransformationLimit(c *test.C) {
|
||||
query := Expr(arr).Limit(2)
|
||||
|
||||
var response []interface{}
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{1, 2})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestTransformationSlice(c *test.C) {
|
||||
query := Expr(arr).Slice(4)
|
||||
|
||||
var response []interface{}
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{5, 6, 7, 8, 9})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestTransformationSliceRight(c *test.C) {
|
||||
query := Expr(arr).Slice(5, 6)
|
||||
|
||||
var response []interface{}
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{6})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestTransformationSliceOpts(c *test.C) {
|
||||
query := Expr(arr).Slice(4, SliceOpts{LeftBound: "open"})
|
||||
|
||||
var response []interface{}
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{6, 7, 8, 9})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestTransformationSliceRightOpts(c *test.C) {
|
||||
query := Expr(arr).Slice(5, 6, SliceOpts{RightBound: "closed"})
|
||||
|
||||
var response []interface{}
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{6, 7})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestTransformationNth(c *test.C) {
|
||||
query := Expr(arr).Nth(2)
|
||||
|
||||
var response interface{}
|
||||
r, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = r.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, 3)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestTransformationAtIndexNth(c *test.C) {
|
||||
query := Expr([]interface{}{1}).AtIndex(Expr(0))
|
||||
|
||||
var response interface{}
|
||||
r, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = r.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, 1)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestTransformationAtIndexField(c *test.C) {
|
||||
query := Expr(map[string]interface{}{"foo": 1}).AtIndex(Expr("foo"))
|
||||
|
||||
var response interface{}
|
||||
r, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = r.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, 1)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestTransformationAtIndexArrayField(c *test.C) {
|
||||
query := Expr([]interface{}{1}).AtIndex(Expr("foo"))
|
||||
|
||||
_, err := query.Run(session)
|
||||
c.Assert(err, test.NotNil)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestTransformationOffsetsOf(c *test.C) {
|
||||
query := Expr(arr).OffsetsOf(2)
|
||||
|
||||
var response []interface{}
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{1})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestTransformationIsEmpty(c *test.C) {
|
||||
query := Expr([]interface{}{}).IsEmpty()
|
||||
|
||||
var response bool
|
||||
r, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = r.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, true)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestTransformationUnion(c *test.C) {
|
||||
query := Expr(arr).Union(arr)
|
||||
|
||||
var response []interface{}
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9})
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestTransformationUnionRoot(c *test.C) {
|
||||
query := Union(arr, arr)
|
||||
|
||||
var response []interface{}
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.All(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, jsonEquals, []interface{}{1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9})
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package gorethink
|
||||
|
||||
import (
|
||||
p "github.com/dancannon/gorethink/ql2"
|
||||
p "gopkg.in/dancannon/gorethink.v2/ql2"
|
||||
)
|
||||
|
||||
// InsertOpts contains the optional arguments for the Insert term
|
||||
148
vendor/gopkg.in/dancannon/gorethink.v2/query_write_test.go
generated
vendored
Normal file
148
vendor/gopkg.in/dancannon/gorethink.v2/query_write_test.go
generated
vendored
Normal file
@@ -0,0 +1,148 @@
|
||||
package gorethink
|
||||
|
||||
import (
|
||||
test "gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
func (s *RethinkSuite) TestWriteInsert(c *test.C) {
|
||||
query := DB("test").Table("test").Insert(map[string]interface{}{"num": 1})
|
||||
_, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestWriteInsertChanges(c *test.C) {
|
||||
query := DB("test").Table("test").Insert([]interface{}{
|
||||
map[string]interface{}{"num": 1},
|
||||
map[string]interface{}{"num": 2},
|
||||
}, InsertOpts{ReturnChanges: true})
|
||||
res, err := query.RunWrite(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(res.Inserted, test.Equals, 2)
|
||||
c.Assert(len(res.Changes), test.Equals, 2)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestWriteInsertStruct(c *test.C) {
|
||||
var response map[string]interface{}
|
||||
o := object{
|
||||
Name: "map[string]interface{}ect 3",
|
||||
Attrs: []attr{
|
||||
attr{
|
||||
Name: "Attr 2",
|
||||
Value: "Value",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
query := DB("test").Table("test").Insert(o)
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response["inserted"], test.Equals, float64(1))
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestWriteInsertStructPointer(c *test.C) {
|
||||
var response map[string]interface{}
|
||||
o := object{
|
||||
Name: "map[string]interface{}ect 3",
|
||||
Attrs: []attr{
|
||||
attr{
|
||||
Name: "Attr 2",
|
||||
Value: "Value",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
query := DB("test").Table("test").Insert(&o)
|
||||
res, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = res.One(&response)
|
||||
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response["inserted"], test.Equals, float64(1))
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestWriteUpdate(c *test.C) {
|
||||
query := DB("test").Table("test").Insert(map[string]interface{}{"num": 1})
|
||||
_, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
// Update the first row in the table
|
||||
query = DB("test").Table("test").Sample(1).Update(map[string]interface{}{"num": 2})
|
||||
_, err = query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestWriteReplace(c *test.C) {
|
||||
query := DB("test").Table("test").Insert(map[string]interface{}{"num": 1})
|
||||
_, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
// Replace the first row in the table
|
||||
query = DB("test").Table("test").Sample(1).Update(map[string]interface{}{"num": 2})
|
||||
_, err = query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestWriteDelete(c *test.C) {
|
||||
query := DB("test").Table("test").Insert(map[string]interface{}{"num": 1})
|
||||
_, err := query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
// Delete the first row in the table
|
||||
query = DB("test").Table("test").Sample(1).Delete()
|
||||
_, err = query.Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestWriteReference(c *test.C) {
|
||||
author := Author{
|
||||
ID: "1",
|
||||
Name: "JRR Tolkien",
|
||||
}
|
||||
|
||||
book := Book{
|
||||
ID: "1",
|
||||
Title: "The Lord of the Rings",
|
||||
Author: author,
|
||||
}
|
||||
|
||||
DB("test").TableDrop("authors").Exec(session)
|
||||
DB("test").TableDrop("books").Exec(session)
|
||||
DB("test").TableCreate("authors").Exec(session)
|
||||
DB("test").TableCreate("books").Exec(session)
|
||||
|
||||
_, err := DB("test").Table("authors").Insert(author).RunWrite(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
_, err = DB("test").Table("books").Insert(book).RunWrite(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
// Read back book + author and check result
|
||||
cursor, err := DB("test").Table("books").Get("1").Merge(func(p Term) interface{} {
|
||||
return map[string]interface{}{
|
||||
"author_id": DB("test").Table("authors").Get(p.Field("author_id")),
|
||||
}
|
||||
}).Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
var out Book
|
||||
err = cursor.One(&out)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
c.Assert(out.Title, test.Equals, "The Lord of the Rings")
|
||||
c.Assert(out.Author.Name, test.Equals, "JRR Tolkien")
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestWriteConflict(c *test.C) {
|
||||
query := DB("test").Table("test").Insert(map[string]interface{}{"id": "a"})
|
||||
_, err := query.RunWrite(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
query = DB("test").Table("test").Insert(map[string]interface{}{"id": "a"})
|
||||
_, err = query.RunWrite(session)
|
||||
c.Assert(IsConflictErr(err), test.Equals, true)
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
p "github.com/dancannon/gorethink/ql2"
|
||||
p "gopkg.in/dancannon/gorethink.v2/ql2"
|
||||
)
|
||||
|
||||
// A Session represents a connection to a RethinkDB cluster and should be used
|
||||
@@ -24,13 +24,16 @@ type ConnectOpts struct {
|
||||
Address string `gorethink:"address,omitempty"`
|
||||
Addresses []string `gorethink:"addresses,omitempty"`
|
||||
Database string `gorethink:"database,omitempty"`
|
||||
AuthKey string `gorethink:"authkey,omitempty"`
|
||||
Username string `gorethink:"username,omitempty"`
|
||||
Password string `gorethink:"password,omitempty"`
|
||||
AuthKey string `gorethink:"authkey,omitempty"` // Deprecated
|
||||
Timeout time.Duration `gorethink:"timeout,omitempty"`
|
||||
WriteTimeout time.Duration `gorethink:"write_timeout,omitempty"`
|
||||
ReadTimeout time.Duration `gorethink:"read_timeout,omitempty"`
|
||||
// The duration in which a connection should send a keep-alive.
|
||||
KeepAlivePeriod time.Duration `gorethink:"keep_alive_timeout,omitempty"`
|
||||
TLSConfig *tls.Config `gorethink:"tlsconfig,omitempty"`
|
||||
KeepAlivePeriod time.Duration `gorethink:"keep_alive_timeout,omitempty"`
|
||||
TLSConfig *tls.Config `gorethink:"tlsconfig,omitempty"`
|
||||
HandshakeVersion HandshakeVersion `gorethink:"handshake_version,omitempty"`
|
||||
|
||||
MaxIdle int `gorethink:"max_idle,omitempty"`
|
||||
// By default a maximum of 2 connections are opened per host.
|
||||
131
vendor/gopkg.in/dancannon/gorethink.v2/session_test.go
generated
vendored
Normal file
131
vendor/gopkg.in/dancannon/gorethink.v2/session_test.go
generated
vendored
Normal file
@@ -0,0 +1,131 @@
|
||||
package gorethink
|
||||
|
||||
import (
|
||||
"os"
|
||||
"time"
|
||||
|
||||
test "gopkg.in/check.v1"
|
||||
)
|
||||
|
||||
func (s *RethinkSuite) TestSessionConnect(c *test.C) {
|
||||
session, err := Connect(ConnectOpts{
|
||||
Address: url,
|
||||
})
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
row, err := Expr("Hello World").Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
var response string
|
||||
err = row.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, "Hello World")
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestSessionConnectHandshakeV1_0(c *test.C) {
|
||||
session, err := Connect(ConnectOpts{
|
||||
Address: url,
|
||||
HandshakeVersion: HandshakeV1_0,
|
||||
})
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
row, err := Expr("Hello World").Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
var response string
|
||||
err = row.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, "Hello World")
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestSessionConnectHandshakeV0_4(c *test.C) {
|
||||
session, err := Connect(ConnectOpts{
|
||||
Address: url,
|
||||
HandshakeVersion: HandshakeV0_4,
|
||||
})
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
row, err := Expr("Hello World").Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
var response string
|
||||
err = row.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, "Hello World")
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestSessionReconnect(c *test.C) {
|
||||
session, err := Connect(ConnectOpts{
|
||||
Address: url,
|
||||
})
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
row, err := Expr("Hello World").Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
var response string
|
||||
err = row.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, "Hello World")
|
||||
|
||||
err = session.Reconnect()
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
row, err = Expr("Hello World 2").Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = row.One(&response)
|
||||
c.Assert(err, test.IsNil)
|
||||
c.Assert(response, test.Equals, "Hello World 2")
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestSessionConnectError(c *test.C) {
|
||||
var err error
|
||||
_, err = Connect(ConnectOpts{
|
||||
Address: "nonexistanturl",
|
||||
Timeout: time.Second,
|
||||
})
|
||||
c.Assert(err, test.NotNil)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestSessionClose(c *test.C) {
|
||||
session, err := Connect(ConnectOpts{
|
||||
Address: url,
|
||||
})
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
_, err = Expr("Hello World").Run(session)
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
err = session.Close()
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
_, err = Expr("Hello World").Run(session)
|
||||
c.Assert(err, test.NotNil)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestSessionServer(c *test.C) {
|
||||
session, err := Connect(ConnectOpts{
|
||||
Address: url,
|
||||
})
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
server, err := session.Server()
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
c.Assert(len(server.ID) > 0, test.Equals, true)
|
||||
c.Assert(len(server.Name) > 0, test.Equals, true)
|
||||
}
|
||||
|
||||
func (s *RethinkSuite) TestSessionConnectDatabase(c *test.C) {
|
||||
session, err := Connect(ConnectOpts{
|
||||
Address: url,
|
||||
AuthKey: os.Getenv("RETHINKDB_AUTHKEY"),
|
||||
Database: "test2",
|
||||
})
|
||||
c.Assert(err, test.IsNil)
|
||||
|
||||
_, err = Table("test2").Run(session)
|
||||
c.Assert(err, test.NotNil)
|
||||
c.Assert(err.Error(), test.Equals, "gorethink: Database `test2` does not exist. in: \nr.Table(\"test2\")")
|
||||
}
|
||||
112
vendor/gopkg.in/dancannon/gorethink.v2/testdata_test.go
generated
vendored
Normal file
112
vendor/gopkg.in/dancannon/gorethink.v2/testdata_test.go
generated
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
package gorethink
|
||||
|
||||
func setupTestData() {
|
||||
if *testdata {
|
||||
// Delete any preexisting databases
|
||||
DBDrop("test").Exec(session)
|
||||
DBDrop("examples").Exec(session)
|
||||
DBDrop("superheroes").Exec(session)
|
||||
|
||||
DBCreate("test").Exec(session)
|
||||
DBCreate("examples").Exec(session)
|
||||
|
||||
DB("examples").TableCreate("posts").Exec(session)
|
||||
DB("examples").TableCreate("heroes").Exec(session)
|
||||
DB("examples").TableCreate("users").Exec(session)
|
||||
DB("examples").TableCreate("games").Exec(session)
|
||||
DB("examples").TableCreate("games2").Exec(session)
|
||||
DB("examples").TableCreate("marvel").Exec(session)
|
||||
|
||||
DB("examples").Table("posts").IndexCreate("date").Exec(session)
|
||||
DB("examples").Table("posts").IndexWait().Exec(session)
|
||||
DB("examples").Table("posts").IndexCreateFunc(
|
||||
"dateAndTitle",
|
||||
[]interface{}{Row.Field("date"), Row.Field("title")},
|
||||
).Exec(session)
|
||||
|
||||
DB("examples").Table("heroes").IndexCreate("code_name").Exec(session)
|
||||
DB("examples").Table("heroes").IndexWait().Exec(session)
|
||||
|
||||
DB("examples").Table("games").IndexCreate("type").Exec(session)
|
||||
DB("examples").Table("games").IndexWait().Exec(session)
|
||||
|
||||
// Create heroes table
|
||||
DB("examples").Table("heroes").Insert([]interface{}{
|
||||
map[string]interface{}{
|
||||
"id": 1,
|
||||
"code_name": "batman",
|
||||
"name": "Batman",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"id": 2,
|
||||
"code_name": "man_of_steel",
|
||||
"name": "Superman",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"id": 3,
|
||||
"code_name": "ant_man",
|
||||
"name": "Ant Man",
|
||||
},
|
||||
map[string]interface{}{
|
||||
"id": 4,
|
||||
"code_name": "flash",
|
||||
"name": "The Flash",
|
||||
},
|
||||
}).Exec(session)
|
||||
|
||||
// Create users table
|
||||
DB("examples").Table("users").Insert([]interface{}{
|
||||
map[string]interface{}{
|
||||
"id": "william",
|
||||
"email": "william@rethinkdb.com",
|
||||
"age": 30,
|
||||
},
|
||||
map[string]interface{}{
|
||||
"id": "lara",
|
||||
"email": "lara@rethinkdb.com",
|
||||
"age": 30,
|
||||
},
|
||||
map[string]interface{}{
|
||||
"id": "john",
|
||||
"email": "john@rethinkdb.com",
|
||||
"age": 19,
|
||||
},
|
||||
map[string]interface{}{
|
||||
"id": "jane",
|
||||
"email": "jane@rethinkdb.com",
|
||||
"age": 45,
|
||||
},
|
||||
map[string]interface{}{
|
||||
"id": "bob",
|
||||
"email": "bob@rethinkdb.com",
|
||||
"age": 24,
|
||||
},
|
||||
map[string]interface{}{
|
||||
"id": "brad",
|
||||
"email": "brad@gmail.com",
|
||||
"age": 15,
|
||||
},
|
||||
}).Exec(session)
|
||||
|
||||
// Create games table
|
||||
DB("examples").Table("games").Insert([]interface{}{
|
||||
map[string]interface{}{"id": 2, "player": "Bob", "points": 15, "type": "ranked"},
|
||||
map[string]interface{}{"id": 5, "player": "Alice", "points": 7, "type": "free"},
|
||||
map[string]interface{}{"id": 11, "player": "Bob", "points": 10, "type": "free"},
|
||||
map[string]interface{}{"id": 12, "player": "Alice", "points": 2, "type": "free"},
|
||||
}).Exec(session)
|
||||
|
||||
// Create games2 table
|
||||
DB("examples").Table("games2").Insert([]interface{}{
|
||||
map[string]interface{}{"id": 1, "matches": map[string]interface{}{"a": []int{1, 2, 3}, "b": []int{4, 5, 6}}},
|
||||
map[string]interface{}{"id": 2, "matches": map[string]interface{}{"b": []int{100}, "c": []int{7, 8, 9}}},
|
||||
map[string]interface{}{"id": 3, "matches": map[string]interface{}{"a": []int{10, 20}, "c": []int{70, 80}}},
|
||||
}).Exec(session)
|
||||
|
||||
// Create marvel table
|
||||
DB("examples").Table("marvel").Insert([]interface{}{
|
||||
map[string]interface{}{"name": "Iron Man", "victories": 214},
|
||||
map[string]interface{}{"name": "Jubilee", "victories": 9},
|
||||
}).Exec(session)
|
||||
}
|
||||
}
|
||||
@@ -6,9 +6,8 @@ import (
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/dancannon/gorethink/encoding"
|
||||
|
||||
p "github.com/dancannon/gorethink/ql2"
|
||||
"gopkg.in/dancannon/gorethink.v2/encoding"
|
||||
p "gopkg.in/dancannon/gorethink.v2/ql2"
|
||||
)
|
||||
|
||||
// Helper functions for constructing terms
|
||||
@@ -98,9 +97,9 @@ func makeFunc(f interface{}) Term {
|
||||
var args = make([]reflect.Value, valueType.NumIn())
|
||||
for i := 0; i < valueType.NumIn(); i++ {
|
||||
// Get a slice of the VARs to use as the function arguments
|
||||
args[i] = reflect.ValueOf(constructRootTerm("var", p.Term_VAR, []interface{}{nextVarID}, map[string]interface{}{}))
|
||||
argNums[i] = nextVarID
|
||||
atomic.AddInt64(&nextVarID, 1)
|
||||
varID := atomic.AddInt64(&nextVarID, 1)
|
||||
args[i] = reflect.ValueOf(constructRootTerm("var", p.Term_VAR, []interface{}{varID}, map[string]interface{}{}))
|
||||
argNums[i] = varID
|
||||
|
||||
// make sure all input arguments are of type Term
|
||||
if valueType.In(i).String() != "gorethink.Term" {
|
||||
Reference in New Issue
Block a user