Browse Source

初始化

wangchuanjin 5 years ago
parent
commit
62d1784216
100 changed files with 0 additions and 20129 deletions
  1. 0 45
      src/github.com/garyburd/redigo/internal/commandinfo.go
  2. 0 65
      src/github.com/garyburd/redigo/internal/redistest/testdb.go
  3. 0 455
      src/github.com/garyburd/redigo/redis/conn.go
  4. 0 169
      src/github.com/garyburd/redigo/redis/doc.go
  5. 0 117
      src/github.com/garyburd/redigo/redis/log.go
  6. 0 389
      src/github.com/garyburd/redigo/redis/pool.go
  7. 0 129
      src/github.com/garyburd/redigo/redis/pubsub.go
  8. 0 44
      src/github.com/garyburd/redigo/redis/redis.go
  9. 0 312
      src/github.com/garyburd/redigo/redis/reply.go
  10. 0 513
      src/github.com/garyburd/redigo/redis/scan.go
  11. 0 86
      src/github.com/garyburd/redigo/redis/script.go
  12. 0 152
      src/github.com/garyburd/redigo/redisx/connmux.go
  13. 0 17
      src/github.com/garyburd/redigo/redisx/doc.go
  14. 0 92
      src/github.com/go-sql-driver/mysql/CHANGELOG.md
  15. 0 40
      src/github.com/go-sql-driver/mysql/CONTRIBUTING.md
  16. 0 374
      src/github.com/go-sql-driver/mysql/README.md
  17. 0 19
      src/github.com/go-sql-driver/mysql/appengine.go
  18. 0 136
      src/github.com/go-sql-driver/mysql/buffer.go
  19. 0 250
      src/github.com/go-sql-driver/mysql/collations.go
  20. 0 402
      src/github.com/go-sql-driver/mysql/connection.go
  21. 0 154
      src/github.com/go-sql-driver/mysql/const.go
  22. 0 140
      src/github.com/go-sql-driver/mysql/driver.go
  23. 0 129
      src/github.com/go-sql-driver/mysql/errors.go
  24. 0 162
      src/github.com/go-sql-driver/mysql/infile.go
  25. 0 1138
      src/github.com/go-sql-driver/mysql/packets.go
  26. 0 22
      src/github.com/go-sql-driver/mysql/result.go
  27. 0 102
      src/github.com/go-sql-driver/mysql/rows.go
  28. 0 112
      src/github.com/go-sql-driver/mysql/statement.go
  29. 0 31
      src/github.com/go-sql-driver/mysql/transaction.go
  30. 0 963
      src/github.com/go-sql-driver/mysql/utils.go
  31. 0 5
      src/github.com/gomodule/redigo/.github/CONTRIBUTING.md
  32. 0 1
      src/github.com/gomodule/redigo/.github/ISSUE_TEMPLATE.md
  33. 0 23
      src/github.com/gomodule/redigo/.travis.yml
  34. 0 175
      src/github.com/gomodule/redigo/LICENSE
  35. 0 51
      src/github.com/gomodule/redigo/README.markdown
  36. 0 55
      src/github.com/gomodule/redigo/redis/commandinfo.go
  37. 0 27
      src/github.com/gomodule/redigo/redis/commandinfo_test.go
  38. 0 704
      src/github.com/gomodule/redigo/redis/conn.go
  39. 0 946
      src/github.com/gomodule/redigo/redis/conn_test.go
  40. 0 177
      src/github.com/gomodule/redigo/redis/doc.go
  41. 0 29
      src/github.com/gomodule/redigo/redis/go17.go
  42. 0 9
      src/github.com/gomodule/redigo/redis/go18.go
  43. 0 85
      src/github.com/gomodule/redigo/redis/list_test.go
  44. 0 146
      src/github.com/gomodule/redigo/redis/log.go
  45. 0 621
      src/github.com/gomodule/redigo/redis/pool.go
  46. 0 875
      src/github.com/gomodule/redigo/redis/pool_test.go
  47. 0 148
      src/github.com/gomodule/redigo/redis/pubsub.go
  48. 0 165
      src/github.com/gomodule/redigo/redis/pubsub_example_test.go
  49. 0 74
      src/github.com/gomodule/redigo/redis/pubsub_test.go
  50. 0 117
      src/github.com/gomodule/redigo/redis/redis.go
  51. 0 71
      src/github.com/gomodule/redigo/redis/redis_test.go
  52. 0 479
      src/github.com/gomodule/redigo/redis/reply.go
  53. 0 209
      src/github.com/gomodule/redigo/redis/reply_test.go
  54. 0 630
      src/github.com/gomodule/redigo/redis/scan.go
  55. 0 513
      src/github.com/gomodule/redigo/redis/scan_test.go
  56. 0 91
      src/github.com/gomodule/redigo/redis/script.go
  57. 0 100
      src/github.com/gomodule/redigo/redis/script_test.go
  58. 0 183
      src/github.com/gomodule/redigo/redis/test_test.go
  59. 0 114
      src/github.com/gomodule/redigo/redis/zpop_example_test.go
  60. 0 54
      src/github.com/gomodule/redigo/redisx/commandinfo.go
  61. 0 11
      src/github.com/gomodule/redigo/redisx/commandinfo_test.go
  62. 0 151
      src/github.com/gomodule/redigo/redisx/connmux.go
  63. 0 258
      src/github.com/gomodule/redigo/redisx/connmux_test.go
  64. 0 68
      src/github.com/gomodule/redigo/redisx/db_test.go
  65. 0 17
      src/github.com/gomodule/redigo/redisx/doc.go
  66. 0 16
      src/go.mongodb.org/mongo-driver/.errcheck-excludes
  67. 0 911
      src/go.mongodb.org/mongo-driver/.evergreen/config.yml
  68. 0 8
      src/go.mongodb.org/mongo-driver/.evergreen/krb5.config
  69. 0 12
      src/go.mongodb.org/mongo-driver/.gitignore
  70. 0 3
      src/go.mongodb.org/mongo-driver/.gitmodules
  71. 0 64
      src/go.mongodb.org/mongo-driver/.lint-whitelist
  72. 0 37
      src/go.mongodb.org/mongo-driver/CONTRIBUTING.md
  73. 0 367
      src/go.mongodb.org/mongo-driver/Gopkg.lock
  74. 0 58
      src/go.mongodb.org/mongo-driver/Gopkg.toml
  75. 0 201
      src/go.mongodb.org/mongo-driver/LICENSE
  76. 0 147
      src/go.mongodb.org/mongo-driver/Makefile
  77. 0 193
      src/go.mongodb.org/mongo-driver/README.md
  78. 0 1336
      src/go.mongodb.org/mongo-driver/THIRD-PARTY-NOTICES
  79. 0 75
      src/go.mongodb.org/mongo-driver/benchmark/bson.go
  80. 0 123
      src/go.mongodb.org/mongo-driver/benchmark/bson_document.go
  81. 0 88
      src/go.mongodb.org/mongo-driver/benchmark/bson_map.go
  82. 0 103
      src/go.mongodb.org/mongo-driver/benchmark/bson_struct.go
  83. 0 35
      src/go.mongodb.org/mongo-driver/benchmark/bson_test.go
  84. 0 306
      src/go.mongodb.org/mongo-driver/benchmark/bson_types.go
  85. 0 29
      src/go.mongodb.org/mongo-driver/benchmark/canary.go
  86. 0 12
      src/go.mongodb.org/mongo-driver/benchmark/canary_test.go
  87. 0 226
      src/go.mongodb.org/mongo-driver/benchmark/harness.go
  88. 0 154
      src/go.mongodb.org/mongo-driver/benchmark/harness_case.go
  89. 0 69
      src/go.mongodb.org/mongo-driver/benchmark/harness_main.go
  90. 0 140
      src/go.mongodb.org/mongo-driver/benchmark/harness_results.go
  91. 0 142
      src/go.mongodb.org/mongo-driver/benchmark/multi.go
  92. 0 13
      src/go.mongodb.org/mongo-driver/benchmark/multi_test.go
  93. 0 174
      src/go.mongodb.org/mongo-driver/benchmark/single.go
  94. 0 14
      src/go.mongodb.org/mongo-driver/benchmark/single_test.go
  95. 0 134
      src/go.mongodb.org/mongo-driver/bson/benchmark_test.go
  96. 0 60
      src/go.mongodb.org/mongo-driver/bson/bson.go
  97. 0 91
      src/go.mongodb.org/mongo-driver/bson/bson_1_8.go
  98. 0 371
      src/go.mongodb.org/mongo-driver/bson/bson_corpus_spec_test.go
  99. 0 113
      src/go.mongodb.org/mongo-driver/bson/bson_test.go
  100. 0 163
      src/go.mongodb.org/mongo-driver/bson/bsoncodec/bsoncodec.go

+ 0 - 45
src/github.com/garyburd/redigo/internal/commandinfo.go

@@ -1,45 +0,0 @@
-// Copyright 2014 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package internal // import "github.com/garyburd/redigo/internal"
-
-import (
-	"strings"
-)
-
-const (
-	WatchState = 1 << iota
-	MultiState
-	SubscribeState
-	MonitorState
-)
-
-type CommandInfo struct {
-	Set, Clear int
-}
-
-var commandInfos = map[string]CommandInfo{
-	"WATCH":      {Set: WatchState},
-	"UNWATCH":    {Clear: WatchState},
-	"MULTI":      {Set: MultiState},
-	"EXEC":       {Clear: WatchState | MultiState},
-	"DISCARD":    {Clear: WatchState | MultiState},
-	"PSUBSCRIBE": {Set: SubscribeState},
-	"SUBSCRIBE":  {Set: SubscribeState},
-	"MONITOR":    {Set: MonitorState},
-}
-
-func LookupCommandInfo(commandName string) CommandInfo {
-	return commandInfos[strings.ToUpper(commandName)]
-}

+ 0 - 65
src/github.com/garyburd/redigo/internal/redistest/testdb.go

@@ -1,65 +0,0 @@
-// Copyright 2014 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-// Package redistest contains utilities for writing Redigo tests.
-package redistest
-
-import (
-	"errors"
-	"time"
-
-	"github.com/garyburd/redigo/redis"
-)
-
-type testConn struct {
-	redis.Conn
-}
-
-func (t testConn) Close() error {
-	_, err := t.Conn.Do("SELECT", "9")
-	if err != nil {
-		return nil
-	}
-	_, err = t.Conn.Do("FLUSHDB")
-	if err != nil {
-		return err
-	}
-	return t.Conn.Close()
-}
-
-// Dial dials the local Redis server and selects database 9. To prevent
-// stomping on real data, DialTestDB fails if database 9 contains data. The
-// returned connection flushes database 9 on close.
-func Dial() (redis.Conn, error) {
-	c, err := redis.DialTimeout("tcp", ":6379", 0, 1*time.Second, 1*time.Second)
-	if err != nil {
-		return nil, err
-	}
-
-	_, err = c.Do("SELECT", "9")
-	if err != nil {
-		return nil, err
-	}
-
-	n, err := redis.Int(c.Do("DBSIZE"))
-	if err != nil {
-		return nil, err
-	}
-
-	if n != 0 {
-		return nil, errors.New("database #9 is not empty, test can not continue")
-	}
-
-	return testConn{c}, nil
-}

+ 0 - 455
src/github.com/garyburd/redigo/redis/conn.go

@@ -1,455 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package redis
-
-import (
-	"bufio"
-	"bytes"
-	"errors"
-	"fmt"
-	"io"
-	"net"
-	"strconv"
-	"sync"
-	"time"
-)
-
-// conn is the low-level implementation of Conn
-type conn struct {
-
-	// Shared
-	mu      sync.Mutex
-	pending int
-	err     error
-	conn    net.Conn
-
-	// Read
-	readTimeout time.Duration
-	br          *bufio.Reader
-
-	// Write
-	writeTimeout time.Duration
-	bw           *bufio.Writer
-
-	// Scratch space for formatting argument length.
-	// '*' or '$', length, "\r\n"
-	lenScratch [32]byte
-
-	// Scratch space for formatting integers and floats.
-	numScratch [40]byte
-}
-
-// Dial connects to the Redis server at the given network and address.
-func Dial(network, address string) (Conn, error) {
-	dialer := xDialer{}
-	return dialer.Dial(network, address)
-}
-
-// DialTimeout acts like Dial but takes timeouts for establishing the
-// connection to the server, writing a command and reading a reply.
-func DialTimeout(network, address string, connectTimeout, readTimeout, writeTimeout time.Duration) (Conn, error) {
-	netDialer := net.Dialer{Timeout: connectTimeout}
-	dialer := xDialer{
-		NetDial:      netDialer.Dial,
-		ReadTimeout:  readTimeout,
-		WriteTimeout: writeTimeout,
-	}
-	return dialer.Dial(network, address)
-}
-
-// A Dialer specifies options for connecting to a Redis server.
-type xDialer struct {
-	// NetDial specifies the dial function for creating TCP connections. If
-	// NetDial is nil, then net.Dial is used.
-	NetDial func(network, addr string) (net.Conn, error)
-
-	// ReadTimeout specifies the timeout for reading a single command
-	// reply. If ReadTimeout is zero, then no timeout is used.
-	ReadTimeout time.Duration
-
-	// WriteTimeout specifies the timeout for writing a single command.  If
-	// WriteTimeout is zero, then no timeout is used.
-	WriteTimeout time.Duration
-}
-
-// Dial connects to the Redis server at address on the named network.
-func (d *xDialer) Dial(network, address string) (Conn, error) {
-	dial := d.NetDial
-	if dial == nil {
-		dial = net.Dial
-	}
-	netConn, err := dial(network, address)
-	if err != nil {
-		return nil, err
-	}
-	return &conn{
-		conn:         netConn,
-		bw:           bufio.NewWriter(netConn),
-		br:           bufio.NewReader(netConn),
-		readTimeout:  d.ReadTimeout,
-		writeTimeout: d.WriteTimeout,
-	}, nil
-}
-
-// NewConn returns a new Redigo connection for the given net connection.
-func NewConn(netConn net.Conn, readTimeout, writeTimeout time.Duration) Conn {
-	return &conn{
-		conn:         netConn,
-		bw:           bufio.NewWriter(netConn),
-		br:           bufio.NewReader(netConn),
-		readTimeout:  readTimeout,
-		writeTimeout: writeTimeout,
-	}
-}
-
-func (c *conn) Close() error {
-	c.mu.Lock()
-	err := c.err
-	if c.err == nil {
-		c.err = errors.New("redigo: closed")
-		err = c.conn.Close()
-	}
-	c.mu.Unlock()
-	return err
-}
-
-func (c *conn) fatal(err error) error {
-	c.mu.Lock()
-	if c.err == nil {
-		c.err = err
-		// Close connection to force errors on subsequent calls and to unblock
-		// other reader or writer.
-		c.conn.Close()
-	}
-	c.mu.Unlock()
-	return err
-}
-
-func (c *conn) Err() error {
-	c.mu.Lock()
-	err := c.err
-	c.mu.Unlock()
-	return err
-}
-
-func (c *conn) writeLen(prefix byte, n int) error {
-	c.lenScratch[len(c.lenScratch)-1] = '\n'
-	c.lenScratch[len(c.lenScratch)-2] = '\r'
-	i := len(c.lenScratch) - 3
-	for {
-		c.lenScratch[i] = byte('0' + n%10)
-		i -= 1
-		n = n / 10
-		if n == 0 {
-			break
-		}
-	}
-	c.lenScratch[i] = prefix
-	_, err := c.bw.Write(c.lenScratch[i:])
-	return err
-}
-
-func (c *conn) writeString(s string) error {
-	c.writeLen('$', len(s))
-	c.bw.WriteString(s)
-	_, err := c.bw.WriteString("\r\n")
-	return err
-}
-
-func (c *conn) writeBytes(p []byte) error {
-	c.writeLen('$', len(p))
-	c.bw.Write(p)
-	_, err := c.bw.WriteString("\r\n")
-	return err
-}
-
-func (c *conn) writeInt64(n int64) error {
-	return c.writeBytes(strconv.AppendInt(c.numScratch[:0], n, 10))
-}
-
-func (c *conn) writeFloat64(n float64) error {
-	return c.writeBytes(strconv.AppendFloat(c.numScratch[:0], n, 'g', -1, 64))
-}
-
-func (c *conn) writeCommand(cmd string, args []interface{}) (err error) {
-	c.writeLen('*', 1+len(args))
-	err = c.writeString(cmd)
-	for _, arg := range args {
-		if err != nil {
-			break
-		}
-		switch arg := arg.(type) {
-		case string:
-			err = c.writeString(arg)
-		case []byte:
-			err = c.writeBytes(arg)
-		case int:
-			err = c.writeInt64(int64(arg))
-		case int64:
-			err = c.writeInt64(arg)
-		case float64:
-			err = c.writeFloat64(arg)
-		case bool:
-			if arg {
-				err = c.writeString("1")
-			} else {
-				err = c.writeString("0")
-			}
-		case nil:
-			err = c.writeString("")
-		default:
-			var buf bytes.Buffer
-			fmt.Fprint(&buf, arg)
-			err = c.writeBytes(buf.Bytes())
-		}
-	}
-	return err
-}
-
-type protocolError string
-
-func (pe protocolError) Error() string {
-	return fmt.Sprintf("redigo: %s (possible server error or unsupported concurrent read by application)", string(pe))
-}
-
-func (c *conn) readLine() ([]byte, error) {
-	p, err := c.br.ReadSlice('\n')
-	if err == bufio.ErrBufferFull {
-		return nil, protocolError("long response line")
-	}
-	if err != nil {
-		return nil, err
-	}
-	i := len(p) - 2
-	if i < 0 || p[i] != '\r' {
-		return nil, protocolError("bad response line terminator")
-	}
-	return p[:i], nil
-}
-
-// parseLen parses bulk string and array lengths.
-func parseLen(p []byte) (int, error) {
-	if len(p) == 0 {
-		return -1, protocolError("malformed length")
-	}
-
-	if p[0] == '-' && len(p) == 2 && p[1] == '1' {
-		// handle $-1 and $-1 null replies.
-		return -1, nil
-	}
-
-	var n int
-	for _, b := range p {
-		n *= 10
-		if b < '0' || b > '9' {
-			return -1, protocolError("illegal bytes in length")
-		}
-		n += int(b - '0')
-	}
-
-	return n, nil
-}
-
-// parseInt parses an integer reply.
-func parseInt(p []byte) (interface{}, error) {
-	if len(p) == 0 {
-		return 0, protocolError("malformed integer")
-	}
-
-	var negate bool
-	if p[0] == '-' {
-		negate = true
-		p = p[1:]
-		if len(p) == 0 {
-			return 0, protocolError("malformed integer")
-		}
-	}
-
-	var n int64
-	for _, b := range p {
-		n *= 10
-		if b < '0' || b > '9' {
-			return 0, protocolError("illegal bytes in length")
-		}
-		n += int64(b - '0')
-	}
-
-	if negate {
-		n = -n
-	}
-	return n, nil
-}
-
-var (
-	okReply   interface{} = "OK"
-	pongReply interface{} = "PONG"
-)
-
-func (c *conn) readReply() (interface{}, error) {
-	line, err := c.readLine()
-	if err != nil {
-		return nil, err
-	}
-	if len(line) == 0 {
-		return nil, protocolError("short response line")
-	}
-	switch line[0] {
-	case '+':
-		switch {
-		case len(line) == 3 && line[1] == 'O' && line[2] == 'K':
-			// Avoid allocation for frequent "+OK" response.
-			return okReply, nil
-		case len(line) == 5 && line[1] == 'P' && line[2] == 'O' && line[3] == 'N' && line[4] == 'G':
-			// Avoid allocation in PING command benchmarks :)
-			return pongReply, nil
-		default:
-			return string(line[1:]), nil
-		}
-	case '-':
-		return Error(string(line[1:])), nil
-	case ':':
-		return parseInt(line[1:])
-	case '$':
-		n, err := parseLen(line[1:])
-		if n < 0 || err != nil {
-			return nil, err
-		}
-		p := make([]byte, n)
-		_, err = io.ReadFull(c.br, p)
-		if err != nil {
-			return nil, err
-		}
-		if line, err := c.readLine(); err != nil {
-			return nil, err
-		} else if len(line) != 0 {
-			return nil, protocolError("bad bulk string format")
-		}
-		return p, nil
-	case '*':
-		n, err := parseLen(line[1:])
-		if n < 0 || err != nil {
-			return nil, err
-		}
-		r := make([]interface{}, n)
-		for i := range r {
-			r[i], err = c.readReply()
-			if err != nil {
-				return nil, err
-			}
-		}
-		return r, nil
-	}
-	return nil, protocolError("unexpected response line")
-}
-
-func (c *conn) Send(cmd string, args ...interface{}) error {
-	c.mu.Lock()
-	c.pending += 1
-	c.mu.Unlock()
-	if c.writeTimeout != 0 {
-		c.conn.SetWriteDeadline(time.Now().Add(c.writeTimeout))
-	}
-	if err := c.writeCommand(cmd, args); err != nil {
-		return c.fatal(err)
-	}
-	return nil
-}
-
-func (c *conn) Flush() error {
-	if c.writeTimeout != 0 {
-		c.conn.SetWriteDeadline(time.Now().Add(c.writeTimeout))
-	}
-	if err := c.bw.Flush(); err != nil {
-		return c.fatal(err)
-	}
-	return nil
-}
-
-func (c *conn) Receive() (reply interface{}, err error) {
-	if c.readTimeout != 0 {
-		c.conn.SetReadDeadline(time.Now().Add(c.readTimeout))
-	}
-	if reply, err = c.readReply(); err != nil {
-		return nil, c.fatal(err)
-	}
-	// When using pub/sub, the number of receives can be greater than the
-	// number of sends. To enable normal use of the connection after
-	// unsubscribing from all channels, we do not decrement pending to a
-	// negative value.
-	//
-	// The pending field is decremented after the reply is read to handle the
-	// case where Receive is called before Send.
-	c.mu.Lock()
-	if c.pending > 0 {
-		c.pending -= 1
-	}
-	c.mu.Unlock()
-	if err, ok := reply.(Error); ok {
-		return nil, err
-	}
-	return
-}
-
-func (c *conn) Do(cmd string, args ...interface{}) (interface{}, error) {
-	c.mu.Lock()
-	pending := c.pending
-	c.pending = 0
-	c.mu.Unlock()
-
-	if cmd == "" && pending == 0 {
-		return nil, nil
-	}
-
-	if c.writeTimeout != 0 {
-		c.conn.SetWriteDeadline(time.Now().Add(c.writeTimeout))
-	}
-
-	if cmd != "" {
-		c.writeCommand(cmd, args)
-	}
-
-	if err := c.bw.Flush(); err != nil {
-		return nil, c.fatal(err)
-	}
-
-	if c.readTimeout != 0 {
-		c.conn.SetReadDeadline(time.Now().Add(c.readTimeout))
-	}
-
-	if cmd == "" {
-		reply := make([]interface{}, pending)
-		for i := range reply {
-			r, e := c.readReply()
-			if e != nil {
-				return nil, c.fatal(e)
-			}
-			reply[i] = r
-		}
-		return reply, nil
-	}
-
-	var err error
-	var reply interface{}
-	for i := 0; i <= pending; i++ {
-		var e error
-		if reply, e = c.readReply(); e != nil {
-			return nil, c.fatal(e)
-		}
-		if e, ok := reply.(Error); ok && err == nil {
-			err = e
-		}
-	}
-	return reply, err
-}

+ 0 - 169
src/github.com/garyburd/redigo/redis/doc.go

@@ -1,169 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-// Package redis is a client for the Redis database.
-//
-// The Redigo FAQ (https://github.com/garyburd/redigo/wiki/FAQ) contains more
-// documentation about this package.
-//
-// Connections
-//
-// The Conn interface is the primary interface for working with Redis.
-// Applications create connections by calling the Dial, DialWithTimeout or
-// NewConn functions. In the future, functions will be added for creating
-// sharded and other types of connections.
-//
-// The application must call the connection Close method when the application
-// is done with the connection.
-//
-// Executing Commands
-//
-// The Conn interface has a generic method for executing Redis commands:
-//
-//  Do(commandName string, args ...interface{}) (reply interface{}, err error)
-//
-// The Redis command reference (http://redis.io/commands) lists the available
-// commands. An example of using the Redis APPEND command is:
-//
-//  n, err := conn.Do("APPEND", "key", "value")
-//
-// The Do method converts command arguments to binary strings for transmission
-// to the server as follows:
-//
-//  Go Type                 Conversion
-//  []byte                  Sent as is
-//  string                  Sent as is
-//  int, int64              strconv.FormatInt(v)
-//  float64                 strconv.FormatFloat(v, 'g', -1, 64)
-//  bool                    true -> "1", false -> "0"
-//  nil                     ""
-//  all other types         fmt.Print(v)
-//
-// Redis command reply types are represented using the following Go types:
-//
-//  Redis type              Go type
-//  error                   redis.Error
-//  integer                 int64
-//  simple string           string
-//  bulk string             []byte or nil if value not present.
-//  array                   []interface{} or nil if value not present.
-//
-// Use type assertions or the reply helper functions to convert from
-// interface{} to the specific Go type for the command result.
-//
-// Pipelining
-//
-// Connections support pipelining using the Send, Flush and Receive methods.
-//
-//  Send(commandName string, args ...interface{}) error
-//  Flush() error
-//  Receive() (reply interface{}, err error)
-//
-// Send writes the command to the connection's output buffer. Flush flushes the
-// connection's output buffer to the server. Receive reads a single reply from
-// the server. The following example shows a simple pipeline.
-//
-//  c.Send("SET", "foo", "bar")
-//  c.Send("GET", "foo")
-//  c.Flush()
-//  c.Receive() // reply from SET
-//  v, err = c.Receive() // reply from GET
-//
-// The Do method combines the functionality of the Send, Flush and Receive
-// methods. The Do method starts by writing the command and flushing the output
-// buffer. Next, the Do method receives all pending replies including the reply
-// for the command just sent by Do. If any of the received replies is an error,
-// then Do returns the error. If there are no errors, then Do returns the last
-// reply. If the command argument to the Do method is "", then the Do method
-// will flush the output buffer and receive pending replies without sending a
-// command.
-//
-// Use the Send and Do methods to implement pipelined transactions.
-//
-//  c.Send("MULTI")
-//  c.Send("INCR", "foo")
-//  c.Send("INCR", "bar")
-//  r, err := c.Do("EXEC")
-//  fmt.Println(r) // prints [1, 1]
-//
-// Concurrency
-//
-// Connections do not support concurrent calls to the write methods (Send,
-// Flush) or concurrent calls to the read method (Receive). Connections do
-// allow a concurrent reader and writer.
-//
-// Because the Do method combines the functionality of Send, Flush and Receive,
-// the Do method cannot be called concurrently with the other methods.
-//
-// For full concurrent access to Redis, use the thread-safe Pool to get and
-// release connections from within a goroutine.
-//
-// Publish and Subscribe
-//
-// Use the Send, Flush and Receive methods to implement Pub/Sub subscribers.
-//
-//  c.Send("SUBSCRIBE", "example")
-//  c.Flush()
-//  for {
-//      reply, err := c.Receive()
-//      if err != nil {
-//          return err
-//      }
-//      // process pushed message
-//  }
-//
-// The PubSubConn type wraps a Conn with convenience methods for implementing
-// subscribers. The Subscribe, PSubscribe, Unsubscribe and PUnsubscribe methods
-// send and flush a subscription management command. The receive method
-// converts a pushed message to convenient types for use in a type switch.
-//
-//  psc := redis.PubSubConn{c}
-//  psc.Subscribe("example")
-//  for {
-//      switch v := psc.Receive().(type) {
-//      case redis.Message:
-//          fmt.Printf("%s: message: %s\n", v.Channel, v.Data)
-//      case redis.Subscription:
-//          fmt.Printf("%s: %s %d\n", v.Channel, v.Kind, v.Count)
-//      case error:
-//          return v
-//      }
-//  }
-//
-// Reply Helpers
-//
-// The Bool, Int, Bytes, String, Strings and Values functions convert a reply
-// to a value of a specific type. To allow convenient wrapping of calls to the
-// connection Do and Receive methods, the functions take a second argument of
-// type error.  If the error is non-nil, then the helper function returns the
-// error. If the error is nil, the function converts the reply to the specified
-// type:
-//
-//  exists, err := redis.Bool(c.Do("EXISTS", "foo"))
-//  if err != nil {
-//      // handle error return from c.Do or type conversion error.
-//  }
-//
-// The Scan function converts elements of a array reply to Go types:
-//
-//  var value1 int
-//  var value2 string
-//  reply, err := redis.Values(c.Do("MGET", "key1", "key2"))
-//  if err != nil {
-//      // handle error
-//  }
-//   if _, err := redis.Scan(reply, &value1, &value2); err != nil {
-//      // handle error
-//  }
-package redis // import "github.com/garyburd/redigo/redis"

+ 0 - 117
src/github.com/garyburd/redigo/redis/log.go

@@ -1,117 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package redis
-
-import (
-	"bytes"
-	"fmt"
-	"log"
-)
-
-// NewLoggingConn returns a logging wrapper around a connection.
-func NewLoggingConn(conn Conn, logger *log.Logger, prefix string) Conn {
-	if prefix != "" {
-		prefix = prefix + "."
-	}
-	return &loggingConn{conn, logger, prefix}
-}
-
-type loggingConn struct {
-	Conn
-	logger *log.Logger
-	prefix string
-}
-
-func (c *loggingConn) Close() error {
-	err := c.Conn.Close()
-	var buf bytes.Buffer
-	fmt.Fprintf(&buf, "%sClose() -> (%v)", c.prefix, err)
-	c.logger.Output(2, buf.String())
-	return err
-}
-
-func (c *loggingConn) printValue(buf *bytes.Buffer, v interface{}) {
-	const chop = 32
-	switch v := v.(type) {
-	case []byte:
-		if len(v) > chop {
-			fmt.Fprintf(buf, "%q...", v[:chop])
-		} else {
-			fmt.Fprintf(buf, "%q", v)
-		}
-	case string:
-		if len(v) > chop {
-			fmt.Fprintf(buf, "%q...", v[:chop])
-		} else {
-			fmt.Fprintf(buf, "%q", v)
-		}
-	case []interface{}:
-		if len(v) == 0 {
-			buf.WriteString("[]")
-		} else {
-			sep := "["
-			fin := "]"
-			if len(v) > chop {
-				v = v[:chop]
-				fin = "...]"
-			}
-			for _, vv := range v {
-				buf.WriteString(sep)
-				c.printValue(buf, vv)
-				sep = ", "
-			}
-			buf.WriteString(fin)
-		}
-	default:
-		fmt.Fprint(buf, v)
-	}
-}
-
-func (c *loggingConn) print(method, commandName string, args []interface{}, reply interface{}, err error) {
-	var buf bytes.Buffer
-	fmt.Fprintf(&buf, "%s%s(", c.prefix, method)
-	if method != "Receive" {
-		buf.WriteString(commandName)
-		for _, arg := range args {
-			buf.WriteString(", ")
-			c.printValue(&buf, arg)
-		}
-	}
-	buf.WriteString(") -> (")
-	if method != "Send" {
-		c.printValue(&buf, reply)
-		buf.WriteString(", ")
-	}
-	fmt.Fprintf(&buf, "%v)", err)
-	c.logger.Output(3, buf.String())
-}
-
-func (c *loggingConn) Do(commandName string, args ...interface{}) (interface{}, error) {
-	reply, err := c.Conn.Do(commandName, args...)
-	c.print("Do", commandName, args, reply, err)
-	return reply, err
-}
-
-func (c *loggingConn) Send(commandName string, args ...interface{}) error {
-	err := c.Conn.Send(commandName, args...)
-	c.print("Send", commandName, args, nil, err)
-	return err
-}
-
-func (c *loggingConn) Receive() (interface{}, error) {
-	reply, err := c.Conn.Receive()
-	c.print("Receive", "", nil, reply, err)
-	return reply, err
-}

+ 0 - 389
src/github.com/garyburd/redigo/redis/pool.go

@@ -1,389 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package redis
-
-import (
-	"bytes"
-	"container/list"
-	"crypto/rand"
-	"crypto/sha1"
-	"errors"
-	"io"
-	"strconv"
-	"sync"
-	"time"
-
-	"github.com/garyburd/redigo/internal"
-)
-
-var nowFunc = time.Now // for testing
-
-// ErrPoolExhausted is returned from a pool connection method (Do, Send,
-// Receive, Flush, Err) when the maximum number of database connections in the
-// pool has been reached.
-var ErrPoolExhausted = errors.New("redigo: connection pool exhausted")
-
-var (
-	errPoolClosed = errors.New("redigo: connection pool closed")
-	errConnClosed = errors.New("redigo: connection closed")
-)
-
-// Pool maintains a pool of connections. The application calls the Get method
-// to get a connection from the pool and the connection's Close method to
-// return the connection's resources to the pool.
-//
-// The following example shows how to use a pool in a web application. The
-// application creates a pool at application startup and makes it available to
-// request handlers using a global variable.
-//
-//  func newPool(server, password string) *redis.Pool {
-//      return &redis.Pool{
-//          MaxIdle: 3,
-//          IdleTimeout: 240 * time.Second,
-//          Dial: func () (redis.Conn, error) {
-//              c, err := redis.Dial("tcp", server)
-//              if err != nil {
-//                  return nil, err
-//              }
-//              if _, err := c.Do("AUTH", password); err != nil {
-//                  c.Close()
-//                  return nil, err
-//              }
-//              return c, err
-//          },
-//          TestOnBorrow: func(c redis.Conn, t time.Time) error {
-//              _, err := c.Do("PING")
-//              return err
-//          },
-//      }
-//  }
-//
-//  var (
-//      pool *redis.Pool
-//      redisServer = flag.String("redisServer", ":6379", "")
-//      redisPassword = flag.String("redisPassword", "", "")
-//  )
-//
-//  func main() {
-//      flag.Parse()
-//      pool = newPool(*redisServer, *redisPassword)
-//      ...
-//  }
-//
-// A request handler gets a connection from the pool and closes the connection
-// when the handler is done:
-//
-//  func serveHome(w http.ResponseWriter, r *http.Request) {
-//      conn := pool.Get()
-//      defer conn.Close()
-//      ....
-//  }
-//
-type Pool struct {
-
-	// Dial is an application supplied function for creating and configuring a
-	// connection
-	Dial func() (Conn, error)
-
-	// TestOnBorrow is an optional application supplied function for checking
-	// the health of an idle connection before the connection is used again by
-	// the application. Argument t is the time that the connection was returned
-	// to the pool. If the function returns an error, then the connection is
-	// closed.
-	TestOnBorrow func(c Conn, t time.Time) error
-
-	// Maximum number of idle connections in the pool.
-	MaxIdle int
-
-	// Maximum number of connections allocated by the pool at a given time.
-	// When zero, there is no limit on the number of connections in the pool.
-	MaxActive int
-
-	// Close connections after remaining idle for this duration. If the value
-	// is zero, then idle connections are not closed. Applications should set
-	// the timeout to a value less than the server's timeout.
-	IdleTimeout time.Duration
-
-	// If Wait is true and the pool is at the MaxIdle limit, then Get() waits
-	// for a connection to be returned to the pool before returning.
-	Wait bool
-
-	// mu protects fields defined below.
-	mu     sync.Mutex
-	cond   *sync.Cond
-	closed bool
-	active int
-
-	// Stack of idleConn with most recently used at the front.
-	idle list.List
-}
-
-type idleConn struct {
-	c Conn
-	t time.Time
-}
-
-// NewPool creates a new pool. This function is deprecated. Applications should
-// initialize the Pool fields directly as shown in example.
-func NewPool(newFn func() (Conn, error), maxIdle int) *Pool {
-	return &Pool{Dial: newFn, MaxIdle: maxIdle}
-}
-
-// Get gets a connection. The application must close the returned connection.
-// This method always returns a valid connection so that applications can defer
-// error handling to the first use of the connection. If there is an error
-// getting an underlying connection, then the connection Err, Do, Send, Flush
-// and Receive methods return that error.
-func (p *Pool) Get() Conn {
-	c, err := p.get()
-	if err != nil {
-		return errorConnection{err}
-	}
-	return &pooledConnection{p: p, c: c}
-}
-
-// ActiveCount returns the number of active connections in the pool.
-func (p *Pool) ActiveCount() int {
-	p.mu.Lock()
-	active := p.active
-	p.mu.Unlock()
-	return active
-}
-
-// Close releases the resources used by the pool.
-func (p *Pool) Close() error {
-	p.mu.Lock()
-	idle := p.idle
-	p.idle.Init()
-	p.closed = true
-	p.active -= idle.Len()
-	if p.cond != nil {
-		p.cond.Broadcast()
-	}
-	p.mu.Unlock()
-	for e := idle.Front(); e != nil; e = e.Next() {
-		e.Value.(idleConn).c.Close()
-	}
-	return nil
-}
-
-// release decrements the active count and signals waiters. The caller must
-// hold p.mu during the call.
-func (p *Pool) release() {
-	p.active -= 1
-	if p.cond != nil {
-		p.cond.Signal()
-	}
-}
-
-// get prunes stale connections and returns a connection from the idle list or
-// creates a new connection.
-func (p *Pool) get() (Conn, error) {
-	p.mu.Lock()
-
-	// Prune stale connections.
-
-	if timeout := p.IdleTimeout; timeout > 0 {
-		for i, n := 0, p.idle.Len(); i < n; i++ {
-			e := p.idle.Back()
-			if e == nil {
-				break
-			}
-			ic := e.Value.(idleConn)
-			if ic.t.Add(timeout).After(nowFunc()) {
-				break
-			}
-			p.idle.Remove(e)
-			p.release()
-			p.mu.Unlock()
-			ic.c.Close()
-			p.mu.Lock()
-		}
-	}
-
-	for {
-
-		// Get idle connection.
-
-		for i, n := 0, p.idle.Len(); i < n; i++ {
-			e := p.idle.Front()
-			if e == nil {
-				break
-			}
-			ic := e.Value.(idleConn)
-			p.idle.Remove(e)
-			test := p.TestOnBorrow
-			p.mu.Unlock()
-			if test == nil || test(ic.c, ic.t) == nil {
-				return ic.c, nil
-			}
-			ic.c.Close()
-			p.mu.Lock()
-			p.release()
-		}
-
-		// Check for pool closed before dialing a new connection.
-
-		if p.closed {
-			p.mu.Unlock()
-			return nil, errors.New("redigo: get on closed pool")
-		}
-
-		// Dial new connection if under limit.
-
-		if p.MaxActive == 0 || p.active < p.MaxActive {
-			dial := p.Dial
-			p.active += 1
-			p.mu.Unlock()
-			c, err := dial()
-			if err != nil {
-				p.mu.Lock()
-				p.release()
-				p.mu.Unlock()
-				c = nil
-			}
-			return c, err
-		}
-
-		if !p.Wait {
-			p.mu.Unlock()
-			return nil, ErrPoolExhausted
-		}
-
-		if p.cond == nil {
-			p.cond = sync.NewCond(&p.mu)
-		}
-		p.cond.Wait()
-	}
-}
-
-func (p *Pool) put(c Conn, forceClose bool) error {
-	err := c.Err()
-	p.mu.Lock()
-	if !p.closed && err == nil && !forceClose {
-		p.idle.PushFront(idleConn{t: nowFunc(), c: c})
-		if p.idle.Len() > p.MaxIdle {
-			c = p.idle.Remove(p.idle.Back()).(idleConn).c
-		} else {
-			c = nil
-		}
-	}
-
-	if c == nil {
-		if p.cond != nil {
-			p.cond.Signal()
-		}
-		p.mu.Unlock()
-		return nil
-	}
-
-	p.release()
-	p.mu.Unlock()
-	return c.Close()
-}
-
-type pooledConnection struct {
-	p     *Pool
-	c     Conn
-	state int
-}
-
-var (
-	sentinel     []byte
-	sentinelOnce sync.Once
-)
-
-func initSentinel() {
-	p := make([]byte, 64)
-	if _, err := rand.Read(p); err == nil {
-		sentinel = p
-	} else {
-		h := sha1.New()
-		io.WriteString(h, "Oops, rand failed. Use time instead.")
-		io.WriteString(h, strconv.FormatInt(time.Now().UnixNano(), 10))
-		sentinel = h.Sum(nil)
-	}
-}
-
-func (pc *pooledConnection) Close() error {
-	c := pc.c
-	if _, ok := c.(errorConnection); ok {
-		return nil
-	}
-	pc.c = errorConnection{errConnClosed}
-
-	if pc.state&internal.MultiState != 0 {
-		c.Send("DISCARD")
-		pc.state &^= (internal.MultiState | internal.WatchState)
-	} else if pc.state&internal.WatchState != 0 {
-		c.Send("UNWATCH")
-		pc.state &^= internal.WatchState
-	}
-	if pc.state&internal.SubscribeState != 0 {
-		c.Send("UNSUBSCRIBE")
-		c.Send("PUNSUBSCRIBE")
-		// To detect the end of the message stream, ask the server to echo
-		// a sentinel value and read until we see that value.
-		sentinelOnce.Do(initSentinel)
-		c.Send("ECHO", sentinel)
-		c.Flush()
-		for {
-			p, err := c.Receive()
-			if err != nil {
-				break
-			}
-			if p, ok := p.([]byte); ok && bytes.Equal(p, sentinel) {
-				pc.state &^= internal.SubscribeState
-				break
-			}
-		}
-	}
-	c.Do("")
-	pc.p.put(c, pc.state != 0)
-	return nil
-}
-
-func (pc *pooledConnection) Err() error {
-	return pc.c.Err()
-}
-
-func (pc *pooledConnection) Do(commandName string, args ...interface{}) (reply interface{}, err error) {
-	ci := internal.LookupCommandInfo(commandName)
-	pc.state = (pc.state | ci.Set) &^ ci.Clear
-	return pc.c.Do(commandName, args...)
-}
-
-func (pc *pooledConnection) Send(commandName string, args ...interface{}) error {
-	ci := internal.LookupCommandInfo(commandName)
-	pc.state = (pc.state | ci.Set) &^ ci.Clear
-	return pc.c.Send(commandName, args...)
-}
-
-func (pc *pooledConnection) Flush() error {
-	return pc.c.Flush()
-}
-
-func (pc *pooledConnection) Receive() (reply interface{}, err error) {
-	return pc.c.Receive()
-}
-
-type errorConnection struct{ err error }
-
-func (ec errorConnection) Do(string, ...interface{}) (interface{}, error) { return nil, ec.err }
-func (ec errorConnection) Send(string, ...interface{}) error              { return ec.err }
-func (ec errorConnection) Err() error                                     { return ec.err }
-func (ec errorConnection) Close() error                                   { return ec.err }
-func (ec errorConnection) Flush() error                                   { return ec.err }
-func (ec errorConnection) Receive() (interface{}, error)                  { return nil, ec.err }

+ 0 - 129
src/github.com/garyburd/redigo/redis/pubsub.go

@@ -1,129 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package redis
-
-import (
-	"errors"
-)
-
-// Subscription represents a subscribe or unsubscribe notification.
-type Subscription struct {
-
-	// Kind is "subscribe", "unsubscribe", "psubscribe" or "punsubscribe"
-	Kind string
-
-	// The channel that was changed.
-	Channel string
-
-	// The current number of subscriptions for connection.
-	Count int
-}
-
-// Message represents a message notification.
-type Message struct {
-
-	// The originating channel.
-	Channel string
-
-	// The message data.
-	Data []byte
-}
-
-// PMessage represents a pmessage notification.
-type PMessage struct {
-
-	// The matched pattern.
-	Pattern string
-
-	// The originating channel.
-	Channel string
-
-	// The message data.
-	Data []byte
-}
-
-// PubSubConn wraps a Conn with convenience methods for subscribers.
-type PubSubConn struct {
-	Conn Conn
-}
-
-// Close closes the connection.
-func (c PubSubConn) Close() error {
-	return c.Conn.Close()
-}
-
-// Subscribe subscribes the connection to the specified channels.
-func (c PubSubConn) Subscribe(channel ...interface{}) error {
-	c.Conn.Send("SUBSCRIBE", channel...)
-	return c.Conn.Flush()
-}
-
-// PSubscribe subscribes the connection to the given patterns.
-func (c PubSubConn) PSubscribe(channel ...interface{}) error {
-	c.Conn.Send("PSUBSCRIBE", channel...)
-	return c.Conn.Flush()
-}
-
-// Unsubscribe unsubscribes the connection from the given channels, or from all
-// of them if none is given.
-func (c PubSubConn) Unsubscribe(channel ...interface{}) error {
-	c.Conn.Send("UNSUBSCRIBE", channel...)
-	return c.Conn.Flush()
-}
-
-// PUnsubscribe unsubscribes the connection from the given patterns, or from all
-// of them if none is given.
-func (c PubSubConn) PUnsubscribe(channel ...interface{}) error {
-	c.Conn.Send("PUNSUBSCRIBE", channel...)
-	return c.Conn.Flush()
-}
-
-// Receive returns a pushed message as a Subscription, Message, PMessage or
-// error. The return value is intended to be used directly in a type switch as
-// illustrated in the PubSubConn example.
-func (c PubSubConn) Receive() interface{} {
-	reply, err := Values(c.Conn.Receive())
-	if err != nil {
-		return err
-	}
-
-	var kind string
-	reply, err = Scan(reply, &kind)
-	if err != nil {
-		return err
-	}
-
-	switch kind {
-	case "message":
-		var m Message
-		if _, err := Scan(reply, &m.Channel, &m.Data); err != nil {
-			return err
-		}
-		return m
-	case "pmessage":
-		var pm PMessage
-		if _, err := Scan(reply, &pm.Pattern, &pm.Channel, &pm.Data); err != nil {
-			return err
-		}
-		return pm
-	case "subscribe", "psubscribe", "unsubscribe", "punsubscribe":
-		s := Subscription{Kind: kind}
-		if _, err := Scan(reply, &s.Channel, &s.Count); err != nil {
-			return err
-		}
-		return s
-	}
-	return errors.New("redigo: unknown pubsub notification")
-}

+ 0 - 44
src/github.com/garyburd/redigo/redis/redis.go

@@ -1,44 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package redis
-
-// Error represents an error returned in a command reply.
-type Error string
-
-func (err Error) Error() string { return string(err) }
-
-// Conn represents a connection to a Redis server.
-type Conn interface {
-	// Close closes the connection.
-	Close() error
-
-	// Err returns a non-nil value if the connection is broken. The returned
-	// value is either the first non-nil value returned from the underlying
-	// network connection or a protocol parsing error. Applications should
-	// close broken connections.
-	Err() error
-
-	// Do sends a command to the server and returns the received reply.
-	Do(commandName string, args ...interface{}) (reply interface{}, err error)
-
-	// Send writes the command to the client's output buffer.
-	Send(commandName string, args ...interface{}) error
-
-	// Flush flushes the output buffer to the Redis server.
-	Flush() error
-
-	// Receive receives a single reply from the Redis server
-	Receive() (reply interface{}, err error)
-}

+ 0 - 312
src/github.com/garyburd/redigo/redis/reply.go

@@ -1,312 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package redis
-
-import (
-	"errors"
-	"fmt"
-	"strconv"
-)
-
-// ErrNil indicates that a reply value is nil.
-var ErrNil = errors.New("redigo: nil returned")
-
-// Int is a helper that converts a command reply to an integer. If err is not
-// equal to nil, then Int returns 0, err. Otherwise, Int converts the
-// reply to an int as follows:
-//
-//  Reply type    Result
-//  integer       int(reply), nil
-//  bulk string   parsed reply, nil
-//  nil           0, ErrNil
-//  other         0, error
-func Int(reply interface{}, err error) (int, error) {
-	if err != nil {
-		return 0, err
-	}
-	switch reply := reply.(type) {
-	case int64:
-		x := int(reply)
-		if int64(x) != reply {
-			return 0, strconv.ErrRange
-		}
-		return x, nil
-	case []byte:
-		n, err := strconv.ParseInt(string(reply), 10, 0)
-		return int(n), err
-	case nil:
-		return 0, ErrNil
-	case Error:
-		return 0, reply
-	}
-	return 0, fmt.Errorf("redigo: unexpected type for Int, got type %T", reply)
-}
-
-// Int64 is a helper that converts a command reply to 64 bit integer. If err is
-// not equal to nil, then Int returns 0, err. Otherwise, Int64 converts the
-// reply to an int64 as follows:
-//
-//  Reply type    Result
-//  integer       reply, nil
-//  bulk string   parsed reply, nil
-//  nil           0, ErrNil
-//  other         0, error
-func Int64(reply interface{}, err error) (int64, error) {
-	if err != nil {
-		return 0, err
-	}
-	switch reply := reply.(type) {
-	case int64:
-		return reply, nil
-	case []byte:
-		n, err := strconv.ParseInt(string(reply), 10, 64)
-		return n, err
-	case nil:
-		return 0, ErrNil
-	case Error:
-		return 0, reply
-	}
-	return 0, fmt.Errorf("redigo: unexpected type for Int64, got type %T", reply)
-}
-
-var errNegativeInt = errors.New("redigo: unexpected value for Uint64")
-
-// Uint64 is a helper that converts a command reply to 64 bit integer. If err is
-// not equal to nil, then Int returns 0, err. Otherwise, Int64 converts the
-// reply to an int64 as follows:
-//
-//  Reply type    Result
-//  integer       reply, nil
-//  bulk string   parsed reply, nil
-//  nil           0, ErrNil
-//  other         0, error
-func Uint64(reply interface{}, err error) (uint64, error) {
-	if err != nil {
-		return 0, err
-	}
-	switch reply := reply.(type) {
-	case int64:
-		if reply < 0 {
-			return 0, errNegativeInt
-		}
-		return uint64(reply), nil
-	case []byte:
-		n, err := strconv.ParseUint(string(reply), 10, 64)
-		return n, err
-	case nil:
-		return 0, ErrNil
-	case Error:
-		return 0, reply
-	}
-	return 0, fmt.Errorf("redigo: unexpected type for Uint64, got type %T", reply)
-}
-
-// Float64 is a helper that converts a command reply to 64 bit float. If err is
-// not equal to nil, then Float64 returns 0, err. Otherwise, Float64 converts
-// the reply to an int as follows:
-//
-//  Reply type    Result
-//  bulk string   parsed reply, nil
-//  nil           0, ErrNil
-//  other         0, error
-func Float64(reply interface{}, err error) (float64, error) {
-	if err != nil {
-		return 0, err
-	}
-	switch reply := reply.(type) {
-	case []byte:
-		n, err := strconv.ParseFloat(string(reply), 64)
-		return n, err
-	case nil:
-		return 0, ErrNil
-	case Error:
-		return 0, reply
-	}
-	return 0, fmt.Errorf("redigo: unexpected type for Float64, got type %T", reply)
-}
-
-// String is a helper that converts a command reply to a string. If err is not
-// equal to nil, then String returns "", err. Otherwise String converts the
-// reply to a string as follows:
-//
-//  Reply type      Result
-//  bulk string     string(reply), nil
-//  simple string   reply, nil
-//  nil             "",  ErrNil
-//  other           "",  error
-func String(reply interface{}, err error) (string, error) {
-	if err != nil {
-		return "", err
-	}
-	switch reply := reply.(type) {
-	case []byte:
-		return string(reply), nil
-	case string:
-		return reply, nil
-	case nil:
-		return "", ErrNil
-	case Error:
-		return "", reply
-	}
-	return "", fmt.Errorf("redigo: unexpected type for String, got type %T", reply)
-}
-
-// Bytes is a helper that converts a command reply to a slice of bytes. If err
-// is not equal to nil, then Bytes returns nil, err. Otherwise Bytes converts
-// the reply to a slice of bytes as follows:
-//
-//  Reply type      Result
-//  bulk string     reply, nil
-//  simple string   []byte(reply), nil
-//  nil             nil, ErrNil
-//  other           nil, error
-func Bytes(reply interface{}, err error) ([]byte, error) {
-	if err != nil {
-		return nil, err
-	}
-	switch reply := reply.(type) {
-	case []byte:
-		return reply, nil
-	case string:
-		return []byte(reply), nil
-	case nil:
-		return nil, ErrNil
-	case Error:
-		return nil, reply
-	}
-	return nil, fmt.Errorf("redigo: unexpected type for Bytes, got type %T", reply)
-}
-
-// Bool is a helper that converts a command reply to a boolean. If err is not
-// equal to nil, then Bool returns false, err. Otherwise Bool converts the
-// reply to boolean as follows:
-//
-//  Reply type      Result
-//  integer         value != 0, nil
-//  bulk string     strconv.ParseBool(reply)
-//  nil             false, ErrNil
-//  other           false, error
-func Bool(reply interface{}, err error) (bool, error) {
-	if err != nil {
-		return false, err
-	}
-	switch reply := reply.(type) {
-	case int64:
-		return reply != 0, nil
-	case []byte:
-		return strconv.ParseBool(string(reply))
-	case nil:
-		return false, ErrNil
-	case Error:
-		return false, reply
-	}
-	return false, fmt.Errorf("redigo: unexpected type for Bool, got type %T", reply)
-}
-
-// MultiBulk is deprecated. Use Values.
-func MultiBulk(reply interface{}, err error) ([]interface{}, error) { return Values(reply, err) }
-
-// Values is a helper that converts an array command reply to a []interface{}.
-// If err is not equal to nil, then Values returns nil, err. Otherwise, Values
-// converts the reply as follows:
-//
-//  Reply type      Result
-//  array           reply, nil
-//  nil             nil, ErrNil
-//  other           nil, error
-func Values(reply interface{}, err error) ([]interface{}, error) {
-	if err != nil {
-		return nil, err
-	}
-	switch reply := reply.(type) {
-	case []interface{}:
-		return reply, nil
-	case nil:
-		return nil, ErrNil
-	case Error:
-		return nil, reply
-	}
-	return nil, fmt.Errorf("redigo: unexpected type for Values, got type %T", reply)
-}
-
-// Strings is a helper that converts an array command reply to a []string. If
-// err is not equal to nil, then Strings returns nil, err. Nil array items are
-// converted to "" in the output slice. Strings returns an error if an array
-// item is not a bulk string or nil.
-func Strings(reply interface{}, err error) ([]string, error) {
-	if err != nil {
-		return nil, err
-	}
-	switch reply := reply.(type) {
-	case []interface{}:
-		result := make([]string, len(reply))
-		for i := range reply {
-			if reply[i] == nil {
-				continue
-			}
-			p, ok := reply[i].([]byte)
-			if !ok {
-				return nil, fmt.Errorf("redigo: unexpected element type for Strings, got type %T", reply[i])
-			}
-			result[i] = string(p)
-		}
-		return result, nil
-	case nil:
-		return nil, ErrNil
-	case Error:
-		return nil, reply
-	}
-	return nil, fmt.Errorf("redigo: unexpected type for Strings, got type %T", reply)
-}
-
-// Ints is a helper that converts an array command reply to a []int. If
-// err is not equal to nil, then Ints returns nil, err.
-func Ints(reply interface{}, err error) ([]int, error) {
-	var ints []int
-	if reply == nil {
-		return ints, ErrNil
-	}
-	values, err := Values(reply, err)
-	if err != nil {
-		return ints, err
-	}
-	if err := ScanSlice(values, &ints); err != nil {
-		return ints, err
-	}
-	return ints, nil
-}
-
-// StringMap is a helper that converts an array of strings (alternating key, value)
-// into a map[string]string. The HGETALL and CONFIG GET commands return replies in this format.
-// Requires an even number of values in result.
-func StringMap(result interface{}, err error) (map[string]string, error) {
-	values, err := Values(result, err)
-	if err != nil {
-		return nil, err
-	}
-	if len(values)%2 != 0 {
-		return nil, errors.New("redigo: StringMap expects even number of values result")
-	}
-	m := make(map[string]string, len(values)/2)
-	for i := 0; i < len(values); i += 2 {
-		key, okKey := values[i].([]byte)
-		value, okValue := values[i+1].([]byte)
-		if !okKey || !okValue {
-			return nil, errors.New("redigo: ScanMap key not a bulk string value")
-		}
-		m[string(key)] = string(value)
-	}
-	return m, nil
-}

+ 0 - 513
src/github.com/garyburd/redigo/redis/scan.go

@@ -1,513 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package redis
-
-import (
-	"errors"
-	"fmt"
-	"reflect"
-	"strconv"
-	"strings"
-	"sync"
-)
-
-func ensureLen(d reflect.Value, n int) {
-	if n > d.Cap() {
-		d.Set(reflect.MakeSlice(d.Type(), n, n))
-	} else {
-		d.SetLen(n)
-	}
-}
-
-func cannotConvert(d reflect.Value, s interface{}) error {
-	return fmt.Errorf("redigo: Scan cannot convert from %s to %s",
-		reflect.TypeOf(s), d.Type())
-}
-
-func convertAssignBytes(d reflect.Value, s []byte) (err error) {
-	switch d.Type().Kind() {
-	case reflect.Float32, reflect.Float64:
-		var x float64
-		x, err = strconv.ParseFloat(string(s), d.Type().Bits())
-		d.SetFloat(x)
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		var x int64
-		x, err = strconv.ParseInt(string(s), 10, d.Type().Bits())
-		d.SetInt(x)
-	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
-		var x uint64
-		x, err = strconv.ParseUint(string(s), 10, d.Type().Bits())
-		d.SetUint(x)
-	case reflect.Bool:
-		var x bool
-		x, err = strconv.ParseBool(string(s))
-		d.SetBool(x)
-	case reflect.String:
-		d.SetString(string(s))
-	case reflect.Slice:
-		if d.Type().Elem().Kind() != reflect.Uint8 {
-			err = cannotConvert(d, s)
-		} else {
-			d.SetBytes(s)
-		}
-	default:
-		err = cannotConvert(d, s)
-	}
-	return
-}
-
-func convertAssignInt(d reflect.Value, s int64) (err error) {
-	switch d.Type().Kind() {
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		d.SetInt(s)
-		if d.Int() != s {
-			err = strconv.ErrRange
-			d.SetInt(0)
-		}
-	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
-		if s < 0 {
-			err = strconv.ErrRange
-		} else {
-			x := uint64(s)
-			d.SetUint(x)
-			if d.Uint() != x {
-				err = strconv.ErrRange
-				d.SetUint(0)
-			}
-		}
-	case reflect.Bool:
-		d.SetBool(s != 0)
-	default:
-		err = cannotConvert(d, s)
-	}
-	return
-}
-
-func convertAssignValue(d reflect.Value, s interface{}) (err error) {
-	switch s := s.(type) {
-	case []byte:
-		err = convertAssignBytes(d, s)
-	case int64:
-		err = convertAssignInt(d, s)
-	default:
-		err = cannotConvert(d, s)
-	}
-	return err
-}
-
-func convertAssignValues(d reflect.Value, s []interface{}) error {
-	if d.Type().Kind() != reflect.Slice {
-		return cannotConvert(d, s)
-	}
-	ensureLen(d, len(s))
-	for i := 0; i < len(s); i++ {
-		if err := convertAssignValue(d.Index(i), s[i]); err != nil {
-			return err
-		}
-	}
-	return nil
-}
-
-func convertAssign(d interface{}, s interface{}) (err error) {
-	// Handle the most common destination types using type switches and
-	// fall back to reflection for all other types.
-	switch s := s.(type) {
-	case nil:
-		// ingore
-	case []byte:
-		switch d := d.(type) {
-		case *string:
-			*d = string(s)
-		case *int:
-			*d, err = strconv.Atoi(string(s))
-		case *bool:
-			*d, err = strconv.ParseBool(string(s))
-		case *[]byte:
-			*d = s
-		case *interface{}:
-			*d = s
-		case nil:
-			// skip value
-		default:
-			if d := reflect.ValueOf(d); d.Type().Kind() != reflect.Ptr {
-				err = cannotConvert(d, s)
-			} else {
-				err = convertAssignBytes(d.Elem(), s)
-			}
-		}
-	case int64:
-		switch d := d.(type) {
-		case *int:
-			x := int(s)
-			if int64(x) != s {
-				err = strconv.ErrRange
-				x = 0
-			}
-			*d = x
-		case *bool:
-			*d = s != 0
-		case *interface{}:
-			*d = s
-		case nil:
-			// skip value
-		default:
-			if d := reflect.ValueOf(d); d.Type().Kind() != reflect.Ptr {
-				err = cannotConvert(d, s)
-			} else {
-				err = convertAssignInt(d.Elem(), s)
-			}
-		}
-	case []interface{}:
-		switch d := d.(type) {
-		case *[]interface{}:
-			*d = s
-		case *interface{}:
-			*d = s
-		case nil:
-			// skip value
-		default:
-			if d := reflect.ValueOf(d); d.Type().Kind() != reflect.Ptr {
-				err = cannotConvert(d, s)
-			} else {
-				err = convertAssignValues(d.Elem(), s)
-			}
-		}
-	case Error:
-		err = s
-	default:
-		err = cannotConvert(reflect.ValueOf(d), s)
-	}
-	return
-}
-
-// Scan copies from src to the values pointed at by dest.
-//
-// The values pointed at by dest must be an integer, float, boolean, string,
-// []byte, interface{} or slices of these types. Scan uses the standard strconv
-// package to convert bulk strings to numeric and boolean types.
-//
-// If a dest value is nil, then the corresponding src value is skipped.
-//
-// If a src element is nil, then the corresponding dest value is not modified.
-//
-// To enable easy use of Scan in a loop, Scan returns the slice of src
-// following the copied values.
-func Scan(src []interface{}, dest ...interface{}) ([]interface{}, error) {
-	if len(src) < len(dest) {
-		return nil, errors.New("redigo: Scan array short")
-	}
-	var err error
-	for i, d := range dest {
-		err = convertAssign(d, src[i])
-		if err != nil {
-			break
-		}
-	}
-	return src[len(dest):], err
-}
-
-type fieldSpec struct {
-	name  string
-	index []int
-	//omitEmpty bool
-}
-
-type structSpec struct {
-	m map[string]*fieldSpec
-	l []*fieldSpec
-}
-
-func (ss *structSpec) fieldSpec(name []byte) *fieldSpec {
-	return ss.m[string(name)]
-}
-
-func compileStructSpec(t reflect.Type, depth map[string]int, index []int, ss *structSpec) {
-	for i := 0; i < t.NumField(); i++ {
-		f := t.Field(i)
-		switch {
-		case f.PkgPath != "":
-			// Ignore unexported fields.
-		case f.Anonymous:
-			// TODO: Handle pointers. Requires change to decoder and
-			// protection against infinite recursion.
-			if f.Type.Kind() == reflect.Struct {
-				compileStructSpec(f.Type, depth, append(index, i), ss)
-			}
-		default:
-			fs := &fieldSpec{name: f.Name}
-			tag := f.Tag.Get("redis")
-			p := strings.Split(tag, ",")
-			if len(p) > 0 {
-				if p[0] == "-" {
-					continue
-				}
-				if len(p[0]) > 0 {
-					fs.name = p[0]
-				}
-				for _, s := range p[1:] {
-					switch s {
-					//case "omitempty":
-					//  fs.omitempty = true
-					default:
-						panic(errors.New("redigo: unknown field flag " + s + " for type " + t.Name()))
-					}
-				}
-			}
-			d, found := depth[fs.name]
-			if !found {
-				d = 1 << 30
-			}
-			switch {
-			case len(index) == d:
-				// At same depth, remove from result.
-				delete(ss.m, fs.name)
-				j := 0
-				for i := 0; i < len(ss.l); i++ {
-					if fs.name != ss.l[i].name {
-						ss.l[j] = ss.l[i]
-						j += 1
-					}
-				}
-				ss.l = ss.l[:j]
-			case len(index) < d:
-				fs.index = make([]int, len(index)+1)
-				copy(fs.index, index)
-				fs.index[len(index)] = i
-				depth[fs.name] = len(index)
-				ss.m[fs.name] = fs
-				ss.l = append(ss.l, fs)
-			}
-		}
-	}
-}
-
-var (
-	structSpecMutex  sync.RWMutex
-	structSpecCache  = make(map[reflect.Type]*structSpec)
-	defaultFieldSpec = &fieldSpec{}
-)
-
-func structSpecForType(t reflect.Type) *structSpec {
-
-	structSpecMutex.RLock()
-	ss, found := structSpecCache[t]
-	structSpecMutex.RUnlock()
-	if found {
-		return ss
-	}
-
-	structSpecMutex.Lock()
-	defer structSpecMutex.Unlock()
-	ss, found = structSpecCache[t]
-	if found {
-		return ss
-	}
-
-	ss = &structSpec{m: make(map[string]*fieldSpec)}
-	compileStructSpec(t, make(map[string]int), nil, ss)
-	structSpecCache[t] = ss
-	return ss
-}
-
-var errScanStructValue = errors.New("redigo: ScanStruct value must be non-nil pointer to a struct")
-
-// ScanStruct scans alternating names and values from src to a struct. The
-// HGETALL and CONFIG GET commands return replies in this format.
-//
-// ScanStruct uses exported field names to match values in the response. Use
-// 'redis' field tag to override the name:
-//
-//      Field int `redis:"myName"`
-//
-// Fields with the tag redis:"-" are ignored.
-//
-// Integer, float, boolean, string and []byte fields are supported. Scan uses the
-// standard strconv package to convert bulk string values to numeric and
-// boolean types.
-//
-// If a src element is nil, then the corresponding field is not modified.
-func ScanStruct(src []interface{}, dest interface{}) error {
-	d := reflect.ValueOf(dest)
-	if d.Kind() != reflect.Ptr || d.IsNil() {
-		return errScanStructValue
-	}
-	d = d.Elem()
-	if d.Kind() != reflect.Struct {
-		return errScanStructValue
-	}
-	ss := structSpecForType(d.Type())
-
-	if len(src)%2 != 0 {
-		return errors.New("redigo: ScanStruct expects even number of values in values")
-	}
-
-	for i := 0; i < len(src); i += 2 {
-		s := src[i+1]
-		if s == nil {
-			continue
-		}
-		name, ok := src[i].([]byte)
-		if !ok {
-			return errors.New("redigo: ScanStruct key not a bulk string value")
-		}
-		fs := ss.fieldSpec(name)
-		if fs == nil {
-			continue
-		}
-		if err := convertAssignValue(d.FieldByIndex(fs.index), s); err != nil {
-			return err
-		}
-	}
-	return nil
-}
-
-var (
-	errScanSliceValue = errors.New("redigo: ScanSlice dest must be non-nil pointer to a struct")
-)
-
-// ScanSlice scans src to the slice pointed to by dest. The elements the dest
-// slice must be integer, float, boolean, string, struct or pointer to struct
-// values.
-//
-// Struct fields must be integer, float, boolean or string values. All struct
-// fields are used unless a subset is specified using fieldNames.
-func ScanSlice(src []interface{}, dest interface{}, fieldNames ...string) error {
-	d := reflect.ValueOf(dest)
-	if d.Kind() != reflect.Ptr || d.IsNil() {
-		return errScanSliceValue
-	}
-	d = d.Elem()
-	if d.Kind() != reflect.Slice {
-		return errScanSliceValue
-	}
-
-	isPtr := false
-	t := d.Type().Elem()
-	if t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Struct {
-		isPtr = true
-		t = t.Elem()
-	}
-
-	if t.Kind() != reflect.Struct {
-		ensureLen(d, len(src))
-		for i, s := range src {
-			if s == nil {
-				continue
-			}
-			if err := convertAssignValue(d.Index(i), s); err != nil {
-				return err
-			}
-		}
-		return nil
-	}
-
-	ss := structSpecForType(t)
-	fss := ss.l
-	if len(fieldNames) > 0 {
-		fss = make([]*fieldSpec, len(fieldNames))
-		for i, name := range fieldNames {
-			fss[i] = ss.m[name]
-			if fss[i] == nil {
-				return errors.New("redigo: ScanSlice bad field name " + name)
-			}
-		}
-	}
-
-	if len(fss) == 0 {
-		return errors.New("redigo: ScanSlice no struct fields")
-	}
-
-	n := len(src) / len(fss)
-	if n*len(fss) != len(src) {
-		return errors.New("redigo: ScanSlice length not a multiple of struct field count")
-	}
-
-	ensureLen(d, n)
-	for i := 0; i < n; i++ {
-		d := d.Index(i)
-		if isPtr {
-			if d.IsNil() {
-				d.Set(reflect.New(t))
-			}
-			d = d.Elem()
-		}
-		for j, fs := range fss {
-			s := src[i*len(fss)+j]
-			if s == nil {
-				continue
-			}
-			if err := convertAssignValue(d.FieldByIndex(fs.index), s); err != nil {
-				return err
-			}
-		}
-	}
-	return nil
-}
-
-// Args is a helper for constructing command arguments from structured values.
-type Args []interface{}
-
-// Add returns the result of appending value to args.
-func (args Args) Add(value ...interface{}) Args {
-	return append(args, value...)
-}
-
-// AddFlat returns the result of appending the flattened value of v to args.
-//
-// Maps are flattened by appending the alternating keys and map values to args.
-//
-// Slices are flattened by appending the slice elements to args.
-//
-// Structs are flattened by appending the alternating names and values of
-// exported fields to args. If v is a nil struct pointer, then nothing is
-// appended. The 'redis' field tag overrides struct field names. See ScanStruct
-// for more information on the use of the 'redis' field tag.
-//
-// Other types are appended to args as is.
-func (args Args) AddFlat(v interface{}) Args {
-	rv := reflect.ValueOf(v)
-	switch rv.Kind() {
-	case reflect.Struct:
-		args = flattenStruct(args, rv)
-	case reflect.Slice:
-		for i := 0; i < rv.Len(); i++ {
-			args = append(args, rv.Index(i).Interface())
-		}
-	case reflect.Map:
-		for _, k := range rv.MapKeys() {
-			args = append(args, k.Interface(), rv.MapIndex(k).Interface())
-		}
-	case reflect.Ptr:
-		if rv.Type().Elem().Kind() == reflect.Struct {
-			if !rv.IsNil() {
-				args = flattenStruct(args, rv.Elem())
-			}
-		} else {
-			args = append(args, v)
-		}
-	default:
-		args = append(args, v)
-	}
-	return args
-}
-
-func flattenStruct(args Args, v reflect.Value) Args {
-	ss := structSpecForType(v.Type())
-	for _, fs := range ss.l {
-		fv := v.FieldByIndex(fs.index)
-		args = append(args, fs.name, fv.Interface())
-	}
-	return args
-}

+ 0 - 86
src/github.com/garyburd/redigo/redis/script.go

@@ -1,86 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package redis
-
-import (
-	"crypto/sha1"
-	"encoding/hex"
-	"io"
-	"strings"
-)
-
-// Script encapsulates the source, hash and key count for a Lua script. See
-// http://redis.io/commands/eval for information on scripts in Redis.
-type Script struct {
-	keyCount int
-	src      string
-	hash     string
-}
-
-// NewScript returns a new script object. If keyCount is greater than or equal
-// to zero, then the count is automatically inserted in the EVAL command
-// argument list. If keyCount is less than zero, then the application supplies
-// the count as the first value in the keysAndArgs argument to the Do, Send and
-// SendHash methods.
-func NewScript(keyCount int, src string) *Script {
-	h := sha1.New()
-	io.WriteString(h, src)
-	return &Script{keyCount, src, hex.EncodeToString(h.Sum(nil))}
-}
-
-func (s *Script) args(spec string, keysAndArgs []interface{}) []interface{} {
-	var args []interface{}
-	if s.keyCount < 0 {
-		args = make([]interface{}, 1+len(keysAndArgs))
-		args[0] = spec
-		copy(args[1:], keysAndArgs)
-	} else {
-		args = make([]interface{}, 2+len(keysAndArgs))
-		args[0] = spec
-		args[1] = s.keyCount
-		copy(args[2:], keysAndArgs)
-	}
-	return args
-}
-
-// Do evaluates the script. Under the covers, Do optimistically evaluates the
-// script using the EVALSHA command. If the command fails because the script is
-// not loaded, then Do evaluates the script using the EVAL command (thus
-// causing the script to load).
-func (s *Script) Do(c Conn, keysAndArgs ...interface{}) (interface{}, error) {
-	v, err := c.Do("EVALSHA", s.args(s.hash, keysAndArgs)...)
-	if e, ok := err.(Error); ok && strings.HasPrefix(string(e), "NOSCRIPT ") {
-		v, err = c.Do("EVAL", s.args(s.src, keysAndArgs)...)
-	}
-	return v, err
-}
-
-// SendHash evaluates the script without waiting for the reply. The script is
-// evaluated with the EVALSHA command. The application must ensure that the
-// script is loaded by a previous call to Send, Do or Load methods.
-func (s *Script) SendHash(c Conn, keysAndArgs ...interface{}) error {
-	return c.Send("EVALSHA", s.args(s.hash, keysAndArgs)...)
-}
-
-// Send evaluates the script without waiting for the reply.
-func (s *Script) Send(c Conn, keysAndArgs ...interface{}) error {
-	return c.Send("EVAL", s.args(s.src, keysAndArgs)...)
-}
-
-// Load loads the script without evaluating it.
-func (s *Script) Load(c Conn) error {
-	_, err := c.Do("SCRIPT", "LOAD", s.src)
-	return err
-}

+ 0 - 152
src/github.com/garyburd/redigo/redisx/connmux.go

@@ -1,152 +0,0 @@
-// Copyright 2014 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package redisx
-
-import (
-	"errors"
-	"sync"
-
-	"github.com/garyburd/redigo/internal"
-	"github.com/garyburd/redigo/redis"
-)
-
-// ConnMux multiplexes one or more connections to a single underlying
-// connection. The ConnMux connections do not support concurrency, commands
-// that associate server side state with the connection or commands that put
-// the connection in a special mode.
-type ConnMux struct {
-	c redis.Conn
-
-	sendMu sync.Mutex
-	sendID uint
-
-	recvMu   sync.Mutex
-	recvID   uint
-	recvWait map[uint]chan struct{}
-}
-
-func NewConnMux(c redis.Conn) *ConnMux {
-	return &ConnMux{c: c, recvWait: make(map[uint]chan struct{})}
-}
-
-// Get gets a connection. The application must close the returned connection.
-func (p *ConnMux) Get() redis.Conn {
-	c := &muxConn{p: p}
-	c.ids = c.buf[:0]
-	return c
-}
-
-// Close closes the underlying connection.
-func (p *ConnMux) Close() error {
-	return p.c.Close()
-}
-
-type muxConn struct {
-	p   *ConnMux
-	ids []uint
-	buf [8]uint
-}
-
-func (c *muxConn) send(flush bool, cmd string, args ...interface{}) error {
-	if internal.LookupCommandInfo(cmd).Set != 0 {
-		return errors.New("command not supported by mux pool")
-	}
-	p := c.p
-	p.sendMu.Lock()
-	id := p.sendID
-	c.ids = append(c.ids, id)
-	p.sendID++
-	err := p.c.Send(cmd, args...)
-	if flush {
-		err = p.c.Flush()
-	}
-	p.sendMu.Unlock()
-	return err
-}
-
-func (c *muxConn) Send(cmd string, args ...interface{}) error {
-	return c.send(false, cmd, args...)
-}
-
-func (c *muxConn) Flush() error {
-	p := c.p
-	p.sendMu.Lock()
-	err := p.c.Flush()
-	p.sendMu.Unlock()
-	return err
-}
-
-func (c *muxConn) Receive() (interface{}, error) {
-	if len(c.ids) == 0 {
-		return nil, errors.New("mux pool underflow")
-	}
-
-	id := c.ids[0]
-	c.ids = c.ids[1:]
-	if len(c.ids) == 0 {
-		c.ids = c.buf[:0]
-	}
-
-	p := c.p
-	p.recvMu.Lock()
-	if p.recvID != id {
-		ch := make(chan struct{})
-		p.recvWait[id] = ch
-		p.recvMu.Unlock()
-		<-ch
-		p.recvMu.Lock()
-		if p.recvID != id {
-			panic("out of sync")
-		}
-	}
-
-	v, err := p.c.Receive()
-
-	id++
-	p.recvID = id
-	ch, ok := p.recvWait[id]
-	if ok {
-		delete(p.recvWait, id)
-	}
-	p.recvMu.Unlock()
-	if ok {
-		ch <- struct{}{}
-	}
-
-	return v, err
-}
-
-func (c *muxConn) Close() error {
-	var err error
-	if len(c.ids) == 0 {
-		return nil
-	}
-	c.Flush()
-	for _ = range c.ids {
-		_, err = c.Receive()
-	}
-	return err
-}
-
-func (c *muxConn) Do(cmd string, args ...interface{}) (interface{}, error) {
-	if err := c.send(true, cmd, args...); err != nil {
-		return nil, err
-	}
-	return c.Receive()
-}
-
-func (c *muxConn) Err() error {
-	return c.p.c.Err()
-}

+ 0 - 17
src/github.com/garyburd/redigo/redisx/doc.go

@@ -1,17 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-// Package redisx contains experimental features for Redigo. Features in this
-// package may be modified or deleted at any time.
-package redisx // import "github.com/garyburd/redigo/redisx"

+ 0 - 92
src/github.com/go-sql-driver/mysql/CHANGELOG.md

@@ -1,92 +0,0 @@
-## HEAD
-
-Changes:
-
- - Go 1.1 is no longer supported
- - Use decimals field from MySQL to format time types (#249)
- - Buffer optimizations (#269)
- - TLS ServerName defaults to the host (#283)
-
-Bugfixes:
-
- - Enable microsecond resolution on TIME, DATETIME and TIMESTAMP (#249)
- - Fixed handling of queries without columns and rows (#255)
- - Fixed a panic when SetKeepAlive() failed (#298)
-
-New Features:
- - Support for returning table alias on Columns() (#289)
- - Placeholder interpolation, can be actived with the DSN parameter `interpolateParams=true` (#309, #318)
-
-
-## Version 1.2 (2014-06-03)
-
-Changes:
-
- - We switched back to a "rolling release". `go get` installs the current master branch again
- - Version v1 of the driver will not be maintained anymore. Go 1.0 is no longer supported by this driver
- - Exported errors to allow easy checking from application code
- - Enabled TCP Keepalives on TCP connections
- - Optimized INFILE handling (better buffer size calculation, lazy init, ...)
- - The DSN parser also checks for a missing separating slash
- - Faster binary date / datetime to string formatting
- - Also exported the MySQLWarning type
- - mysqlConn.Close returns the first error encountered instead of ignoring all errors
- - writePacket() automatically writes the packet size to the header
- - readPacket() uses an iterative approach instead of the recursive approach to merge splitted packets
-
-New Features:
-
- - `RegisterDial` allows the usage of a custom dial function to establish the network connection
- - Setting the connection collation is possible with the `collation` DSN parameter. This parameter should be preferred over the `charset` parameter
- - Logging of critical errors is configurable with `SetLogger`
- - Google CloudSQL support
-
-Bugfixes:
-
- - Allow more than 32 parameters in prepared statements
- - Various old_password fixes
- - Fixed TestConcurrent test to pass Go's race detection
- - Fixed appendLengthEncodedInteger for large numbers
- - Renamed readLengthEnodedString to readLengthEncodedString and skipLengthEnodedString to skipLengthEncodedString (fixed typo)
-
-
-## Version 1.1 (2013-11-02)
-
-Changes:
-
-  - Go-MySQL-Driver now requires Go 1.1
-  - Connections now use the collation `utf8_general_ci` by default. Adding `&charset=UTF8` to the DSN should not be necessary anymore
-  - Made closing rows and connections error tolerant. This allows for example deferring rows.Close() without checking for errors
-  - `[]byte(nil)` is now treated as a NULL value. Before, it was treated like an empty string / `[]byte("")`
-  - DSN parameter values must now be url.QueryEscape'ed. This allows text values to contain special characters, such as '&'.
-  - Use the IO buffer also for writing. This results in zero allocations (by the driver) for most queries
-  - Optimized the buffer for reading
-  - stmt.Query now caches column metadata
-  - New Logo
-  - Changed the copyright header to include all contributors
-  - Improved the LOAD INFILE documentation
-  - The driver struct is now exported to make the driver directly accessible
-  - Refactored the driver tests
-  - Added more benchmarks and moved all to a separate file
-  - Other small refactoring
-
-New Features:
-
-  - Added *old_passwords* support: Required in some cases, but must be enabled by adding `allowOldPasswords=true` to the DSN since it is insecure
-  - Added a `clientFoundRows` parameter: Return the number of matching rows instead of the number of rows changed on UPDATEs
-  - Added TLS/SSL support: Use a TLS/SSL encrypted connection to the server. Custom TLS configs can be registered and used
-
-Bugfixes:
-
-  - Fixed MySQL 4.1 support: MySQL 4.1 sends packets with lengths which differ from the specification
-  - Convert to DB timezone when inserting `time.Time`
-  - Splitted packets (more than 16MB) are now merged correctly
-  - Fixed false positive `io.EOF` errors when the data was fully read
-  - Avoid panics on reuse of closed connections
-  - Fixed empty string producing false nil values
-  - Fixed sign byte for positive TIME fields
-
-
-## Version 1.0 (2013-05-14)
-
-Initial Release

+ 0 - 40
src/github.com/go-sql-driver/mysql/CONTRIBUTING.md

@@ -1,40 +0,0 @@
-# Contributing Guidelines
-
-## Reporting Issues
-
-Before creating a new Issue, please check first if a similar Issue [already exists](https://github.com/go-sql-driver/mysql/issues?state=open) or was [recently closed](https://github.com/go-sql-driver/mysql/issues?direction=desc&page=1&sort=updated&state=closed).
-
-Please provide the following minimum information:
-* Your Go-MySQL-Driver version (or git SHA)
-* Your Go version (run `go version` in your console)
-* A detailed issue description
-* Error Log if present
-* If possible, a short example
-
-
-## Contributing Code
-
-By contributing to this project, you share your code under the Mozilla Public License 2, as specified in the LICENSE file.
-Don't forget to add yourself to the AUTHORS file.
-
-### Pull Requests Checklist
-
-Please check the following points before submitting your pull request:
-- [x] Code compiles correctly
-- [x] Created tests, if possible
-- [x] All tests pass
-- [x] Extended the README / documentation, if necessary
-- [x] Added yourself to the AUTHORS file
-
-### Code Review
-
-Everyone is invited to review and comment on pull requests.
-If it looks fine to you, comment with "LGTM" (Looks good to me).
-
-If changes are required, notice the reviewers with "PTAL" (Please take another look) after committing the fixes.
-
-Before merging the Pull Request, at least one [team member](https://github.com/go-sql-driver?tab=members) must have commented with "LGTM".
-
-## Development Ideas
-
-If you are looking for ideas for code contributions, please check our [Development Ideas](https://github.com/go-sql-driver/mysql/wiki/Development-Ideas) Wiki page.

+ 0 - 374
src/github.com/go-sql-driver/mysql/README.md

@@ -1,374 +0,0 @@
-# Go-MySQL-Driver
-
-A MySQL-Driver for Go's [database/sql](http://golang.org/pkg/database/sql) package
-
-![Go-MySQL-Driver logo](https://raw.github.com/wiki/go-sql-driver/mysql/gomysql_m.png "Golang Gopher holding the MySQL Dolphin")
-
-**Latest stable Release:** [Version 1.2 (June 03, 2014)](https://github.com/go-sql-driver/mysql/releases)
-
-[![Build Status](https://travis-ci.org/go-sql-driver/mysql.png?branch=master)](https://travis-ci.org/go-sql-driver/mysql)
-
----------------------------------------
-  * [Features](#features)
-  * [Requirements](#requirements)
-  * [Installation](#installation)
-  * [Usage](#usage)
-    * [DSN (Data Source Name)](#dsn-data-source-name)
-      * [Password](#password)
-      * [Protocol](#protocol)
-      * [Address](#address)
-      * [Parameters](#parameters)
-      * [Examples](#examples)
-    * [LOAD DATA LOCAL INFILE support](#load-data-local-infile-support)
-    * [time.Time support](#timetime-support)
-    * [Unicode support](#unicode-support)
-  * [Testing / Development](#testing--development)
-  * [License](#license)
-
----------------------------------------
-
-## Features
-  * Lightweight and [fast](https://github.com/go-sql-driver/sql-benchmark "golang MySQL-Driver performance")
-  * Native Go implementation. No C-bindings, just pure Go
-  * Connections over TCP/IPv4, TCP/IPv6 or Unix domain sockets
-  * Automatic handling of broken connections
-  * Automatic Connection Pooling *(by database/sql package)*
-  * Supports queries larger than 16MB
-  * Full [`sql.RawBytes`](http://golang.org/pkg/database/sql/#RawBytes) support.
-  * Intelligent `LONG DATA` handling in prepared statements
-  * Secure `LOAD DATA LOCAL INFILE` support with file Whitelisting and `io.Reader` support
-  * Optional `time.Time` parsing
-  * Optional placeholder interpolation
-
-## Requirements
-  * Go 1.2 or higher
-  * MySQL (4.1+), MariaDB, Percona Server, Google CloudSQL or Sphinx (2.2.3+)
-
----------------------------------------
-
-## Installation
-Simple install the package to your [$GOPATH](http://code.google.com/p/go-wiki/wiki/GOPATH "GOPATH") with the [go tool](http://golang.org/cmd/go/ "go command") from shell:
-```bash
-$ go get github.com/go-sql-driver/mysql
-```
-Make sure [Git is installed](http://git-scm.com/downloads) on your machine and in your system's `PATH`.
-
-## Usage
-_Go MySQL Driver_ is an implementation of Go's `database/sql/driver` interface. You only need to import the driver and can use the full [`database/sql`](http://golang.org/pkg/database/sql) API then.
-
-Use `mysql` as `driverName` and a valid [DSN](#dsn-data-source-name)  as `dataSourceName`:
-```go
-import "database/sql"
-import _ "github.com/go-sql-driver/mysql"
-
-db, err := sql.Open("mysql", "user:password@/dbname")
-```
-
-[Examples are available in our Wiki](https://github.com/go-sql-driver/mysql/wiki/Examples "Go-MySQL-Driver Examples").
-
-
-### DSN (Data Source Name)
-
-The Data Source Name has a common format, like e.g. [PEAR DB](http://pear.php.net/manual/en/package.database.db.intro-dsn.php) uses it, but without type-prefix (optional parts marked by squared brackets):
-```
-[username[:password]@][protocol[(address)]]/dbname[?param1=value1&...&paramN=valueN]
-```
-
-A DSN in its fullest form:
-```
-username:password@protocol(address)/dbname?param=value
-```
-
-Except for the databasename, all values are optional. So the minimal DSN is:
-```
-/dbname
-```
-
-If you do not want to preselect a database, leave `dbname` empty:
-```
-/
-```
-This has the same effect as an empty DSN string:
-```
-
-```
-
-#### Password
-Passwords can consist of any character. Escaping is **not** necessary.
-
-#### Protocol
-See [net.Dial](http://golang.org/pkg/net/#Dial) for more information which networks are available.
-In general you should use an Unix domain socket if available and TCP otherwise for best performance.
-
-#### Address
-For TCP and UDP networks, addresses have the form `host:port`.
-If `host` is a literal IPv6 address, it must be enclosed in square brackets.
-The functions [net.JoinHostPort](http://golang.org/pkg/net/#JoinHostPort) and [net.SplitHostPort](http://golang.org/pkg/net/#SplitHostPort) manipulate addresses in this form.
-
-For Unix domain sockets the address is the absolute path to the MySQL-Server-socket, e.g. `/var/run/mysqld/mysqld.sock` or `/tmp/mysql.sock`.
-
-#### Parameters
-*Parameters are case-sensitive!*
-
-Notice that any of `true`, `TRUE`, `True` or `1` is accepted to stand for a true boolean value. Not surprisingly, false can be specified as any of: `false`, `FALSE`, `False` or `0`.
-
-##### `allowAllFiles`
-
-```
-Type:           bool
-Valid Values:   true, false
-Default:        false
-```
-
-`allowAllFiles=true` disables the file Whitelist for `LOAD DATA LOCAL INFILE` and allows *all* files.
-[*Might be insecure!*](http://dev.mysql.com/doc/refman/5.7/en/load-data-local.html)
-
-##### `allowOldPasswords`
-
-```
-Type:           bool
-Valid Values:   true, false
-Default:        false
-```
-`allowOldPasswords=true` allows the usage of the insecure old password method. This should be avoided, but is necessary in some cases. See also [the old_passwords wiki page](https://github.com/go-sql-driver/mysql/wiki/old_passwords).
-
-##### `charset`
-
-```
-Type:           string
-Valid Values:   <name>
-Default:        none
-```
-
-Sets the charset used for client-server interaction (`"SET NAMES <value>"`). If multiple charsets are set (separated by a comma), the following charset is used if setting the charset failes. This enables for example support for `utf8mb4` ([introduced in MySQL 5.5.3](http://dev.mysql.com/doc/refman/5.5/en/charset-unicode-utf8mb4.html)) with fallback to `utf8` for older servers (`charset=utf8mb4,utf8`).
-
-Usage of the `charset` parameter is discouraged because it issues additional queries to the server.
-Unless you need the fallback behavior, please use `collation` instead.
-
-##### `collation`
-
-```
-Type:           string
-Valid Values:   <name>
-Default:        utf8_general_ci
-```
-
-Sets the collation used for client-server interaction on connection. In contrast to `charset`, `collation` does not issue additional queries. If the specified collation is unavailable on the target server, the connection will fail.
-
-A list of valid charsets for a server is retrievable with `SHOW COLLATION`.
-
-##### `clientFoundRows`
-
-```
-Type:           bool
-Valid Values:   true, false
-Default:        false
-```
-
-`clientFoundRows=true` causes an UPDATE to return the number of matching rows instead of the number of rows changed.
-
-##### `columnsWithAlias`
-
-```
-Type:           bool
-Valid Values:   true, false
-Default:        false
-```
-
-When `columnsWithAlias` is true, calls to `sql.Rows.Columns()` will return the table alias and the column name separated by a dot. For example:
-
-```
-SELECT u.id FROM users as u
-```
-
-will return `u.id` instead of just `id` if `columnsWithAlias=true`.
-
-##### `interpolateParams`
-
-```
-Type:           bool
-Valid Values:   true, false
-Default:        false
-```
-
-If `interpolateParams` is true, placeholders (`?`) in calls to `db.Query()` and `db.Exec()` are interpolated into a single query string with given parameters. This reduces the number of roundtrips, since the driver has to prepare a statement, execute it with given parameters and close the statement again with `interpolateParams=false`.
-
-*This can not be used together with the multibyte encodings BIG5, CP932, GB2312, GBK or SJIS. These are blacklisted as they may [introduce a SQL injection vulnerability](http://stackoverflow.com/a/12118602/3430118)!*
-
-##### `loc`
-
-```
-Type:           string
-Valid Values:   <escaped name>
-Default:        UTC
-```
-
-Sets the location for time.Time values (when using `parseTime=true`). *"Local"* sets the system's location. See [time.LoadLocation](http://golang.org/pkg/time/#LoadLocation) for details.
-
-Please keep in mind, that param values must be [url.QueryEscape](http://golang.org/pkg/net/url/#QueryEscape)'ed. Alternatively you can manually replace the `/` with `%2F`. For example `US/Pacific` would be `loc=US%2FPacific`.
-
-
-##### `parseTime`
-
-```
-Type:           bool
-Valid Values:   true, false
-Default:        false
-```
-
-`parseTime=true` changes the output type of `DATE` and `DATETIME` values to `time.Time` instead of `[]byte` / `string`
-
-
-##### `strict`
-
-```
-Type:           bool
-Valid Values:   true, false
-Default:        false
-```
-
-`strict=true` enables the strict mode in which MySQL warnings are treated as errors.
-
-By default MySQL also treats notes as warnings. Use [`sql_notes=false`](http://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_sql_notes) to ignore notes. See the [examples](#examples) for an DSN example.
-
-
-##### `timeout`
-
-```
-Type:           decimal number
-Default:        OS default
-```
-
-*Driver* side connection timeout. The value must be a string of decimal numbers, each with optional fraction and a unit suffix ( *"ms"*, *"s"*, *"m"*, *"h"* ), such as *"30s"*, *"0.5m"* or *"1m30s"*. To set a server side timeout, use the parameter [`wait_timeout`](http://dev.mysql.com/doc/refman/5.6/en/server-system-variables.html#sysvar_wait_timeout).
-
-
-##### `tls`
-
-```
-Type:           bool / string
-Valid Values:   true, false, skip-verify, <name>
-Default:        false
-```
-
-`tls=true` enables TLS / SSL encrypted connection to the server. Use `skip-verify` if you want to use a self-signed or invalid certificate (server side). Use a custom value registered with [`mysql.RegisterTLSConfig`](http://godoc.org/github.com/go-sql-driver/mysql#RegisterTLSConfig).
-
-
-##### System Variables
-
-All other parameters are interpreted as system variables:
-  * `autocommit`: `"SET autocommit=<value>"`
-  * `time_zone`: `"SET time_zone=<value>"`
-  * [`tx_isolation`](https://dev.mysql.com/doc/refman/5.5/en/server-system-variables.html#sysvar_tx_isolation): `"SET tx_isolation=<value>"`
-  * `param`: `"SET <param>=<value>"`
-
-*The values must be [url.QueryEscape](http://golang.org/pkg/net/url/#QueryEscape)'ed!*
-
-#### Examples
-```
-user@unix(/path/to/socket)/dbname
-```
-
-```
-root:pw@unix(/tmp/mysql.sock)/myDatabase?loc=Local
-```
-
-```
-user:password@tcp(localhost:5555)/dbname?tls=skip-verify&autocommit=true
-```
-
-Use the [strict mode](#strict) but ignore notes:
-```
-user:password@/dbname?strict=true&sql_notes=false
-```
-
-TCP via IPv6:
-```
-user:password@tcp([de:ad:be:ef::ca:fe]:80)/dbname?timeout=90s&collation=utf8mb4_unicode_ci
-```
-
-TCP on a remote host, e.g. Amazon RDS:
-```
-id:password@tcp(your-amazonaws-uri.com:3306)/dbname
-```
-
-Google Cloud SQL on App Engine:
-```
-user@cloudsql(project-id:instance-name)/dbname
-```
-
-TCP using default port (3306) on localhost:
-```
-user:password@tcp/dbname?charset=utf8mb4,utf8&sys_var=esc%40ped
-```
-
-Use the default protocol (tcp) and host (localhost:3306):
-```
-user:password@/dbname
-```
-
-No Database preselected:
-```
-user:password@/
-```
-
-### `LOAD DATA LOCAL INFILE` support
-For this feature you need direct access to the package. Therefore you must change the import path (no `_`):
-```go
-import "github.com/go-sql-driver/mysql"
-```
-
-Files must be whitelisted by registering them with `mysql.RegisterLocalFile(filepath)` (recommended) or the Whitelist check must be deactivated by using the DSN parameter `allowAllFiles=true` ([*Might be insecure!*](http://dev.mysql.com/doc/refman/5.7/en/load-data-local.html)).
-
-To use a `io.Reader` a handler function must be registered with `mysql.RegisterReaderHandler(name, handler)` which returns a `io.Reader` or `io.ReadCloser`. The Reader is available with the filepath `Reader::<name>` then.
-
-See the [godoc of Go-MySQL-Driver](http://godoc.org/github.com/go-sql-driver/mysql "golang mysql driver documentation") for details.
-
-
-### `time.Time` support
-The default internal output type of MySQL `DATE` and `DATETIME` values is `[]byte` which allows you to scan the value into a `[]byte`, `string` or `sql.RawBytes` variable in your programm.
-
-However, many want to scan MySQL `DATE` and `DATETIME` values into `time.Time` variables, which is the logical opposite in Go to `DATE` and `DATETIME` in MySQL. You can do that by changing the internal output type from `[]byte` to `time.Time` with the DSN parameter `parseTime=true`. You can set the default [`time.Time` location](http://golang.org/pkg/time/#Location) with the `loc` DSN parameter.
-
-**Caution:** As of Go 1.1, this makes `time.Time` the only variable type you can scan `DATE` and `DATETIME` values into. This breaks for example [`sql.RawBytes` support](https://github.com/go-sql-driver/mysql/wiki/Examples#rawbytes).
-
-Alternatively you can use the [`NullTime`](http://godoc.org/github.com/go-sql-driver/mysql#NullTime) type as the scan destination, which works with both `time.Time` and `string` / `[]byte`.
-
-
-### Unicode support
-Since version 1.1 Go-MySQL-Driver automatically uses the collation `utf8_general_ci` by default.
-
-Other collations / charsets can be set using the [`collation`](#collation) DSN parameter.
-
-Version 1.0 of the driver recommended adding `&charset=utf8` (alias for `SET NAMES utf8`) to the DSN to enable proper UTF-8 support. This is not necessary anymore. The [`collation`](#collation) parameter should be preferred to set another collation / charset than the default.
-
-See http://dev.mysql.com/doc/refman/5.7/en/charset-unicode.html for more details on MySQL's Unicode support.
-
-
-## Testing / Development
-To run the driver tests you may need to adjust the configuration. See the [Testing Wiki-Page](https://github.com/go-sql-driver/mysql/wiki/Testing "Testing") for details.
-
-Go-MySQL-Driver is not feature-complete yet. Your help is very appreciated.
-If you want to contribute, you can work on an [open issue](https://github.com/go-sql-driver/mysql/issues?state=open) or review a [pull request](https://github.com/go-sql-driver/mysql/pulls).
-
-See the [Contribution Guidelines](https://github.com/go-sql-driver/mysql/blob/master/CONTRIBUTING.md) for details.
-
----------------------------------------
-
-## License
-Go-MySQL-Driver is licensed under the [Mozilla Public License Version 2.0](https://raw.github.com/go-sql-driver/mysql/master/LICENSE)
-
-Mozilla summarizes the license scope as follows:
-> MPL: The copyleft applies to any files containing MPLed code.
-
-
-That means:
-  * You can **use** the **unchanged** source code both in private and commercially
-  * When distributing, you **must publish** the source code of any **changed files** licensed under the MPL 2.0 under a) the MPL 2.0 itself or b) a compatible license (e.g. GPL 3.0 or Apache License 2.0)
-  * You **needn't publish** the source code of your library as long as the files licensed under the MPL 2.0 are **unchanged**
-
-Please read the [MPL 2.0 FAQ](http://www.mozilla.org/MPL/2.0/FAQ.html) if you have further questions regarding the license.
-
-You can read the full terms here: [LICENSE](https://raw.github.com/go-sql-driver/mysql/master/LICENSE)
-
-![Go Gopher and MySQL Dolphin](https://raw.github.com/wiki/go-sql-driver/mysql/go-mysql-driver_m.jpg "Golang Gopher transporting the MySQL Dolphin in a wheelbarrow")
-

+ 0 - 19
src/github.com/go-sql-driver/mysql/appengine.go

@@ -1,19 +0,0 @@
-// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
-//
-// Copyright 2013 The Go-MySQL-Driver Authors. All rights reserved.
-//
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this file,
-// You can obtain one at http://mozilla.org/MPL/2.0/.
-
-// +build appengine
-
-package mysql
-
-import (
-	"appengine/cloudsql"
-)
-
-func init() {
-	RegisterDial("cloudsql", cloudsql.Dial)
-}

+ 0 - 136
src/github.com/go-sql-driver/mysql/buffer.go

@@ -1,136 +0,0 @@
-// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
-//
-// Copyright 2013 The Go-MySQL-Driver Authors. All rights reserved.
-//
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this file,
-// You can obtain one at http://mozilla.org/MPL/2.0/.
-
-package mysql
-
-import "io"
-
-const defaultBufSize = 4096
-
-// A buffer which is used for both reading and writing.
-// This is possible since communication on each connection is synchronous.
-// In other words, we can't write and read simultaneously on the same connection.
-// The buffer is similar to bufio.Reader / Writer but zero-copy-ish
-// Also highly optimized for this particular use case.
-type buffer struct {
-	buf    []byte
-	rd     io.Reader
-	idx    int
-	length int
-}
-
-func newBuffer(rd io.Reader) buffer {
-	var b [defaultBufSize]byte
-	return buffer{
-		buf: b[:],
-		rd:  rd,
-	}
-}
-
-// fill reads into the buffer until at least _need_ bytes are in it
-func (b *buffer) fill(need int) error {
-	n := b.length
-
-	// move existing data to the beginning
-	if n > 0 && b.idx > 0 {
-		copy(b.buf[0:n], b.buf[b.idx:])
-	}
-
-	// grow buffer if necessary
-	// TODO: let the buffer shrink again at some point
-	//       Maybe keep the org buf slice and swap back?
-	if need > len(b.buf) {
-		// Round up to the next multiple of the default size
-		newBuf := make([]byte, ((need/defaultBufSize)+1)*defaultBufSize)
-		copy(newBuf, b.buf)
-		b.buf = newBuf
-	}
-
-	b.idx = 0
-
-	for {
-		nn, err := b.rd.Read(b.buf[n:])
-		n += nn
-
-		switch err {
-		case nil:
-			if n < need {
-				continue
-			}
-			b.length = n
-			return nil
-
-		case io.EOF:
-			if n >= need {
-				b.length = n
-				return nil
-			}
-			return io.ErrUnexpectedEOF
-
-		default:
-			return err
-		}
-	}
-}
-
-// returns next N bytes from buffer.
-// The returned slice is only guaranteed to be valid until the next read
-func (b *buffer) readNext(need int) ([]byte, error) {
-	if b.length < need {
-		// refill
-		if err := b.fill(need); err != nil {
-			return nil, err
-		}
-	}
-
-	offset := b.idx
-	b.idx += need
-	b.length -= need
-	return b.buf[offset:b.idx], nil
-}
-
-// returns a buffer with the requested size.
-// If possible, a slice from the existing buffer is returned.
-// Otherwise a bigger buffer is made.
-// Only one buffer (total) can be used at a time.
-func (b *buffer) takeBuffer(length int) []byte {
-	if b.length > 0 {
-		return nil
-	}
-
-	// test (cheap) general case first
-	if length <= defaultBufSize || length <= cap(b.buf) {
-		return b.buf[:length]
-	}
-
-	if length < maxPacketSize {
-		b.buf = make([]byte, length)
-		return b.buf
-	}
-	return make([]byte, length)
-}
-
-// shortcut which can be used if the requested buffer is guaranteed to be
-// smaller than defaultBufSize
-// Only one buffer (total) can be used at a time.
-func (b *buffer) takeSmallBuffer(length int) []byte {
-	if b.length == 0 {
-		return b.buf[:length]
-	}
-	return nil
-}
-
-// takeCompleteBuffer returns the complete existing buffer.
-// This can be used if the necessary buffer size is unknown.
-// Only one buffer (total) can be used at a time.
-func (b *buffer) takeCompleteBuffer() []byte {
-	if b.length == 0 {
-		return b.buf
-	}
-	return nil
-}

+ 0 - 250
src/github.com/go-sql-driver/mysql/collations.go

@@ -1,250 +0,0 @@
-// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
-//
-// Copyright 2014 The Go-MySQL-Driver Authors. All rights reserved.
-//
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this file,
-// You can obtain one at http://mozilla.org/MPL/2.0/.
-
-package mysql
-
-const defaultCollation byte = 33 // utf8_general_ci
-
-// A list of available collations mapped to the internal ID.
-// To update this map use the following MySQL query:
-//     SELECT COLLATION_NAME, ID FROM information_schema.COLLATIONS
-var collations = map[string]byte{
-	"big5_chinese_ci":          1,
-	"latin2_czech_cs":          2,
-	"dec8_swedish_ci":          3,
-	"cp850_general_ci":         4,
-	"latin1_german1_ci":        5,
-	"hp8_english_ci":           6,
-	"koi8r_general_ci":         7,
-	"latin1_swedish_ci":        8,
-	"latin2_general_ci":        9,
-	"swe7_swedish_ci":          10,
-	"ascii_general_ci":         11,
-	"ujis_japanese_ci":         12,
-	"sjis_japanese_ci":         13,
-	"cp1251_bulgarian_ci":      14,
-	"latin1_danish_ci":         15,
-	"hebrew_general_ci":        16,
-	"tis620_thai_ci":           18,
-	"euckr_korean_ci":          19,
-	"latin7_estonian_cs":       20,
-	"latin2_hungarian_ci":      21,
-	"koi8u_general_ci":         22,
-	"cp1251_ukrainian_ci":      23,
-	"gb2312_chinese_ci":        24,
-	"greek_general_ci":         25,
-	"cp1250_general_ci":        26,
-	"latin2_croatian_ci":       27,
-	"gbk_chinese_ci":           28,
-	"cp1257_lithuanian_ci":     29,
-	"latin5_turkish_ci":        30,
-	"latin1_german2_ci":        31,
-	"armscii8_general_ci":      32,
-	"utf8_general_ci":          33,
-	"cp1250_czech_cs":          34,
-	"ucs2_general_ci":          35,
-	"cp866_general_ci":         36,
-	"keybcs2_general_ci":       37,
-	"macce_general_ci":         38,
-	"macroman_general_ci":      39,
-	"cp852_general_ci":         40,
-	"latin7_general_ci":        41,
-	"latin7_general_cs":        42,
-	"macce_bin":                43,
-	"cp1250_croatian_ci":       44,
-	"utf8mb4_general_ci":       45,
-	"utf8mb4_bin":              46,
-	"latin1_bin":               47,
-	"latin1_general_ci":        48,
-	"latin1_general_cs":        49,
-	"cp1251_bin":               50,
-	"cp1251_general_ci":        51,
-	"cp1251_general_cs":        52,
-	"macroman_bin":             53,
-	"utf16_general_ci":         54,
-	"utf16_bin":                55,
-	"utf16le_general_ci":       56,
-	"cp1256_general_ci":        57,
-	"cp1257_bin":               58,
-	"cp1257_general_ci":        59,
-	"utf32_general_ci":         60,
-	"utf32_bin":                61,
-	"utf16le_bin":              62,
-	"binary":                   63,
-	"armscii8_bin":             64,
-	"ascii_bin":                65,
-	"cp1250_bin":               66,
-	"cp1256_bin":               67,
-	"cp866_bin":                68,
-	"dec8_bin":                 69,
-	"greek_bin":                70,
-	"hebrew_bin":               71,
-	"hp8_bin":                  72,
-	"keybcs2_bin":              73,
-	"koi8r_bin":                74,
-	"koi8u_bin":                75,
-	"latin2_bin":               77,
-	"latin5_bin":               78,
-	"latin7_bin":               79,
-	"cp850_bin":                80,
-	"cp852_bin":                81,
-	"swe7_bin":                 82,
-	"utf8_bin":                 83,
-	"big5_bin":                 84,
-	"euckr_bin":                85,
-	"gb2312_bin":               86,
-	"gbk_bin":                  87,
-	"sjis_bin":                 88,
-	"tis620_bin":               89,
-	"ucs2_bin":                 90,
-	"ujis_bin":                 91,
-	"geostd8_general_ci":       92,
-	"geostd8_bin":              93,
-	"latin1_spanish_ci":        94,
-	"cp932_japanese_ci":        95,
-	"cp932_bin":                96,
-	"eucjpms_japanese_ci":      97,
-	"eucjpms_bin":              98,
-	"cp1250_polish_ci":         99,
-	"utf16_unicode_ci":         101,
-	"utf16_icelandic_ci":       102,
-	"utf16_latvian_ci":         103,
-	"utf16_romanian_ci":        104,
-	"utf16_slovenian_ci":       105,
-	"utf16_polish_ci":          106,
-	"utf16_estonian_ci":        107,
-	"utf16_spanish_ci":         108,
-	"utf16_swedish_ci":         109,
-	"utf16_turkish_ci":         110,
-	"utf16_czech_ci":           111,
-	"utf16_danish_ci":          112,
-	"utf16_lithuanian_ci":      113,
-	"utf16_slovak_ci":          114,
-	"utf16_spanish2_ci":        115,
-	"utf16_roman_ci":           116,
-	"utf16_persian_ci":         117,
-	"utf16_esperanto_ci":       118,
-	"utf16_hungarian_ci":       119,
-	"utf16_sinhala_ci":         120,
-	"utf16_german2_ci":         121,
-	"utf16_croatian_ci":        122,
-	"utf16_unicode_520_ci":     123,
-	"utf16_vietnamese_ci":      124,
-	"ucs2_unicode_ci":          128,
-	"ucs2_icelandic_ci":        129,
-	"ucs2_latvian_ci":          130,
-	"ucs2_romanian_ci":         131,
-	"ucs2_slovenian_ci":        132,
-	"ucs2_polish_ci":           133,
-	"ucs2_estonian_ci":         134,
-	"ucs2_spanish_ci":          135,
-	"ucs2_swedish_ci":          136,
-	"ucs2_turkish_ci":          137,
-	"ucs2_czech_ci":            138,
-	"ucs2_danish_ci":           139,
-	"ucs2_lithuanian_ci":       140,
-	"ucs2_slovak_ci":           141,
-	"ucs2_spanish2_ci":         142,
-	"ucs2_roman_ci":            143,
-	"ucs2_persian_ci":          144,
-	"ucs2_esperanto_ci":        145,
-	"ucs2_hungarian_ci":        146,
-	"ucs2_sinhala_ci":          147,
-	"ucs2_german2_ci":          148,
-	"ucs2_croatian_ci":         149,
-	"ucs2_unicode_520_ci":      150,
-	"ucs2_vietnamese_ci":       151,
-	"ucs2_general_mysql500_ci": 159,
-	"utf32_unicode_ci":         160,
-	"utf32_icelandic_ci":       161,
-	"utf32_latvian_ci":         162,
-	"utf32_romanian_ci":        163,
-	"utf32_slovenian_ci":       164,
-	"utf32_polish_ci":          165,
-	"utf32_estonian_ci":        166,
-	"utf32_spanish_ci":         167,
-	"utf32_swedish_ci":         168,
-	"utf32_turkish_ci":         169,
-	"utf32_czech_ci":           170,
-	"utf32_danish_ci":          171,
-	"utf32_lithuanian_ci":      172,
-	"utf32_slovak_ci":          173,
-	"utf32_spanish2_ci":        174,
-	"utf32_roman_ci":           175,
-	"utf32_persian_ci":         176,
-	"utf32_esperanto_ci":       177,
-	"utf32_hungarian_ci":       178,
-	"utf32_sinhala_ci":         179,
-	"utf32_german2_ci":         180,
-	"utf32_croatian_ci":        181,
-	"utf32_unicode_520_ci":     182,
-	"utf32_vietnamese_ci":      183,
-	"utf8_unicode_ci":          192,
-	"utf8_icelandic_ci":        193,
-	"utf8_latvian_ci":          194,
-	"utf8_romanian_ci":         195,
-	"utf8_slovenian_ci":        196,
-	"utf8_polish_ci":           197,
-	"utf8_estonian_ci":         198,
-	"utf8_spanish_ci":          199,
-	"utf8_swedish_ci":          200,
-	"utf8_turkish_ci":          201,
-	"utf8_czech_ci":            202,
-	"utf8_danish_ci":           203,
-	"utf8_lithuanian_ci":       204,
-	"utf8_slovak_ci":           205,
-	"utf8_spanish2_ci":         206,
-	"utf8_roman_ci":            207,
-	"utf8_persian_ci":          208,
-	"utf8_esperanto_ci":        209,
-	"utf8_hungarian_ci":        210,
-	"utf8_sinhala_ci":          211,
-	"utf8_german2_ci":          212,
-	"utf8_croatian_ci":         213,
-	"utf8_unicode_520_ci":      214,
-	"utf8_vietnamese_ci":       215,
-	"utf8_general_mysql500_ci": 223,
-	"utf8mb4_unicode_ci":       224,
-	"utf8mb4_icelandic_ci":     225,
-	"utf8mb4_latvian_ci":       226,
-	"utf8mb4_romanian_ci":      227,
-	"utf8mb4_slovenian_ci":     228,
-	"utf8mb4_polish_ci":        229,
-	"utf8mb4_estonian_ci":      230,
-	"utf8mb4_spanish_ci":       231,
-	"utf8mb4_swedish_ci":       232,
-	"utf8mb4_turkish_ci":       233,
-	"utf8mb4_czech_ci":         234,
-	"utf8mb4_danish_ci":        235,
-	"utf8mb4_lithuanian_ci":    236,
-	"utf8mb4_slovak_ci":        237,
-	"utf8mb4_spanish2_ci":      238,
-	"utf8mb4_roman_ci":         239,
-	"utf8mb4_persian_ci":       240,
-	"utf8mb4_esperanto_ci":     241,
-	"utf8mb4_hungarian_ci":     242,
-	"utf8mb4_sinhala_ci":       243,
-	"utf8mb4_german2_ci":       244,
-	"utf8mb4_croatian_ci":      245,
-	"utf8mb4_unicode_520_ci":   246,
-	"utf8mb4_vietnamese_ci":    247,
-}
-
-// A blacklist of collations which is unsafe to interpolate parameters.
-// These multibyte encodings may contains 0x5c (`\`) in their trailing bytes.
-var unsafeCollations = map[byte]bool{
-	1:  true, // big5_chinese_ci
-	13: true, // sjis_japanese_ci
-	28: true, // gbk_chinese_ci
-	84: true, // big5_bin
-	86: true, // gb2312_bin
-	87: true, // gbk_bin
-	88: true, // sjis_bin
-	95: true, // cp932_japanese_ci
-	96: true, // cp932_bin
-}

+ 0 - 402
src/github.com/go-sql-driver/mysql/connection.go

@@ -1,402 +0,0 @@
-// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
-//
-// Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved.
-//
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this file,
-// You can obtain one at http://mozilla.org/MPL/2.0/.
-
-package mysql
-
-import (
-	"crypto/tls"
-	"database/sql/driver"
-	"errors"
-	"net"
-	"strconv"
-	"strings"
-	"time"
-)
-
-type mysqlConn struct {
-	buf              buffer
-	netConn          net.Conn
-	affectedRows     uint64
-	insertId         uint64
-	cfg              *config
-	maxPacketAllowed int
-	maxWriteSize     int
-	flags            clientFlag
-	status           statusFlag
-	sequence         uint8
-	parseTime        bool
-	strict           bool
-}
-
-type config struct {
-	user              string
-	passwd            string
-	net               string
-	addr              string
-	dbname            string
-	params            map[string]string
-	loc               *time.Location
-	tls               *tls.Config
-	timeout           time.Duration
-	collation         uint8
-	allowAllFiles     bool
-	allowOldPasswords bool
-	clientFoundRows   bool
-	columnsWithAlias  bool
-	interpolateParams bool
-}
-
-// Handles parameters set in DSN after the connection is established
-func (mc *mysqlConn) handleParams() (err error) {
-	for param, val := range mc.cfg.params {
-		switch param {
-		// Charset
-		case "charset":
-			charsets := strings.Split(val, ",")
-			for i := range charsets {
-				// ignore errors here - a charset may not exist
-				err = mc.exec("SET NAMES " + charsets[i])
-				if err == nil {
-					break
-				}
-			}
-			if err != nil {
-				return
-			}
-
-		// time.Time parsing
-		case "parseTime":
-			var isBool bool
-			mc.parseTime, isBool = readBool(val)
-			if !isBool {
-				return errors.New("Invalid Bool value: " + val)
-			}
-
-		// Strict mode
-		case "strict":
-			var isBool bool
-			mc.strict, isBool = readBool(val)
-			if !isBool {
-				return errors.New("Invalid Bool value: " + val)
-			}
-
-		// Compression
-		case "compress":
-			err = errors.New("Compression not implemented yet")
-			return
-
-		// System Vars
-		default:
-			err = mc.exec("SET " + param + "=" + val + "")
-			if err != nil {
-				return
-			}
-		}
-	}
-
-	return
-}
-
-func (mc *mysqlConn) Begin() (driver.Tx, error) {
-	if mc.netConn == nil {
-		errLog.Print(ErrInvalidConn)
-		return nil, driver.ErrBadConn
-	}
-	err := mc.exec("START TRANSACTION")
-	if err == nil {
-		return &mysqlTx{mc}, err
-	}
-
-	return nil, err
-}
-
-func (mc *mysqlConn) Close() (err error) {
-	// Makes Close idempotent
-	if mc.netConn != nil {
-		err = mc.writeCommandPacket(comQuit)
-		if err == nil {
-			err = mc.netConn.Close()
-		} else {
-			mc.netConn.Close()
-		}
-		mc.netConn = nil
-	}
-
-	mc.cfg = nil
-	mc.buf.rd = nil
-
-	return
-}
-
-func (mc *mysqlConn) Prepare(query string) (driver.Stmt, error) {
-	if mc.netConn == nil {
-		errLog.Print(ErrInvalidConn)
-		return nil, driver.ErrBadConn
-	}
-	// Send command
-	err := mc.writeCommandPacketStr(comStmtPrepare, query)
-	if err != nil {
-		return nil, err
-	}
-
-	stmt := &mysqlStmt{
-		mc: mc,
-	}
-
-	// Read Result
-	columnCount, err := stmt.readPrepareResultPacket()
-	if err == nil {
-		if stmt.paramCount > 0 {
-			if err = mc.readUntilEOF(); err != nil {
-				return nil, err
-			}
-		}
-
-		if columnCount > 0 {
-			err = mc.readUntilEOF()
-		}
-	}
-
-	return stmt, err
-}
-
-func (mc *mysqlConn) interpolateParams(query string, args []driver.Value) (string, error) {
-	buf := mc.buf.takeCompleteBuffer()
-	if buf == nil {
-		// can not take the buffer. Something must be wrong with the connection
-		errLog.Print(ErrBusyBuffer)
-		return "", driver.ErrBadConn
-	}
-	buf = buf[:0]
-	argPos := 0
-
-	for i := 0; i < len(query); i++ {
-		q := strings.IndexByte(query[i:], '?')
-		if q == -1 {
-			buf = append(buf, query[i:]...)
-			break
-		}
-		buf = append(buf, query[i:i+q]...)
-		i += q
-
-		arg := args[argPos]
-		argPos++
-
-		if arg == nil {
-			buf = append(buf, "NULL"...)
-			continue
-		}
-
-		switch v := arg.(type) {
-		case int64:
-			buf = strconv.AppendInt(buf, v, 10)
-		case float64:
-			buf = strconv.AppendFloat(buf, v, 'g', -1, 64)
-		case bool:
-			if v {
-				buf = append(buf, '1')
-			} else {
-				buf = append(buf, '0')
-			}
-		case time.Time:
-			if v.IsZero() {
-				buf = append(buf, "'0000-00-00'"...)
-			} else {
-				v := v.In(mc.cfg.loc)
-				v = v.Add(time.Nanosecond * 500) // To round under microsecond
-				year := v.Year()
-				year100 := year / 100
-				year1 := year % 100
-				month := v.Month()
-				day := v.Day()
-				hour := v.Hour()
-				minute := v.Minute()
-				second := v.Second()
-				micro := v.Nanosecond() / 1000
-
-				buf = append(buf, []byte{
-					'\'',
-					digits10[year100], digits01[year100],
-					digits10[year1], digits01[year1],
-					'-',
-					digits10[month], digits01[month],
-					'-',
-					digits10[day], digits01[day],
-					' ',
-					digits10[hour], digits01[hour],
-					':',
-					digits10[minute], digits01[minute],
-					':',
-					digits10[second], digits01[second],
-				}...)
-
-				if micro != 0 {
-					micro10000 := micro / 10000
-					micro100 := micro / 100 % 100
-					micro1 := micro % 100
-					buf = append(buf, []byte{
-						'.',
-						digits10[micro10000], digits01[micro10000],
-						digits10[micro100], digits01[micro100],
-						digits10[micro1], digits01[micro1],
-					}...)
-				}
-				buf = append(buf, '\'')
-			}
-		case []byte:
-			if v == nil {
-				buf = append(buf, "NULL"...)
-			} else {
-				buf = append(buf, '\'')
-				if mc.status&statusNoBackslashEscapes == 0 {
-					buf = escapeBytesBackslash(buf, v)
-				} else {
-					buf = escapeBytesQuotes(buf, v)
-				}
-				buf = append(buf, '\'')
-			}
-		case string:
-			buf = append(buf, '\'')
-			if mc.status&statusNoBackslashEscapes == 0 {
-				buf = escapeStringBackslash(buf, v)
-			} else {
-				buf = escapeStringQuotes(buf, v)
-			}
-			buf = append(buf, '\'')
-		default:
-			return "", driver.ErrSkip
-		}
-
-		if len(buf)+4 > mc.maxPacketAllowed {
-			return "", driver.ErrSkip
-		}
-	}
-	if argPos != len(args) {
-		return "", driver.ErrSkip
-	}
-	return string(buf), nil
-}
-
-func (mc *mysqlConn) Exec(query string, args []driver.Value) (driver.Result, error) {
-	if mc.netConn == nil {
-		errLog.Print(ErrInvalidConn)
-		return nil, driver.ErrBadConn
-	}
-	if len(args) != 0 {
-		if !mc.cfg.interpolateParams {
-			return nil, driver.ErrSkip
-		}
-		// try to interpolate the parameters to save extra roundtrips for preparing and closing a statement
-		prepared, err := mc.interpolateParams(query, args)
-		if err != nil {
-			return nil, err
-		}
-		query = prepared
-		args = nil
-	}
-	mc.affectedRows = 0
-	mc.insertId = 0
-
-	err := mc.exec(query)
-	if err == nil {
-		return &mysqlResult{
-			affectedRows: int64(mc.affectedRows),
-			insertId:     int64(mc.insertId),
-		}, err
-	}
-	return nil, err
-}
-
-// Internal function to execute commands
-func (mc *mysqlConn) exec(query string) error {
-	// Send command
-	err := mc.writeCommandPacketStr(comQuery, query)
-	if err != nil {
-		return err
-	}
-
-	// Read Result
-	resLen, err := mc.readResultSetHeaderPacket()
-	if err == nil && resLen > 0 {
-		if err = mc.readUntilEOF(); err != nil {
-			return err
-		}
-
-		err = mc.readUntilEOF()
-	}
-
-	return err
-}
-
-func (mc *mysqlConn) Query(query string, args []driver.Value) (driver.Rows, error) {
-	if mc.netConn == nil {
-		errLog.Print(ErrInvalidConn)
-		return nil, driver.ErrBadConn
-	}
-	if len(args) != 0 {
-		if !mc.cfg.interpolateParams {
-			return nil, driver.ErrSkip
-		}
-		// try client-side prepare to reduce roundtrip
-		prepared, err := mc.interpolateParams(query, args)
-		if err != nil {
-			return nil, err
-		}
-		query = prepared
-		args = nil
-	}
-	// Send command
-	err := mc.writeCommandPacketStr(comQuery, query)
-	if err == nil {
-		// Read Result
-		var resLen int
-		resLen, err = mc.readResultSetHeaderPacket()
-		if err == nil {
-			rows := new(textRows)
-			rows.mc = mc
-
-			if resLen == 0 {
-				// no columns, no more data
-				return emptyRows{}, nil
-			}
-			// Columns
-			rows.columns, err = mc.readColumns(resLen)
-			return rows, err
-		}
-	}
-	return nil, err
-}
-
-// Gets the value of the given MySQL System Variable
-// The returned byte slice is only valid until the next read
-func (mc *mysqlConn) getSystemVar(name string) ([]byte, error) {
-	// Send command
-	if err := mc.writeCommandPacketStr(comQuery, "SELECT @@"+name); err != nil {
-		return nil, err
-	}
-
-	// Read Result
-	resLen, err := mc.readResultSetHeaderPacket()
-	if err == nil {
-		rows := new(textRows)
-		rows.mc = mc
-
-		if resLen > 0 {
-			// Columns
-			if err := mc.readUntilEOF(); err != nil {
-				return nil, err
-			}
-		}
-
-		dest := make([]driver.Value, resLen)
-		if err = rows.readRow(dest); err == nil {
-			return dest[0].([]byte), mc.readUntilEOF()
-		}
-	}
-	return nil, err
-}

+ 0 - 154
src/github.com/go-sql-driver/mysql/const.go

@@ -1,154 +0,0 @@
-// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
-//
-// Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved.
-//
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this file,
-// You can obtain one at http://mozilla.org/MPL/2.0/.
-
-package mysql
-
-const (
-	minProtocolVersion byte = 10
-	maxPacketSize           = 1<<24 - 1
-	timeFormat              = "2006-01-02 15:04:05.999999"
-)
-
-// MySQL constants documentation:
-// http://dev.mysql.com/doc/internals/en/client-server-protocol.html
-
-const (
-	iOK          byte = 0x00
-	iLocalInFile byte = 0xfb
-	iEOF         byte = 0xfe
-	iERR         byte = 0xff
-)
-
-type clientFlag uint32
-
-const (
-	clientLongPassword clientFlag = 1 << iota
-	clientFoundRows
-	clientLongFlag
-	clientConnectWithDB
-	clientNoSchema
-	clientCompress
-	clientODBC
-	clientLocalFiles
-	clientIgnoreSpace
-	clientProtocol41
-	clientInteractive
-	clientSSL
-	clientIgnoreSIGPIPE
-	clientTransactions
-	clientReserved
-	clientSecureConn
-	clientMultiStatements
-	clientMultiResults
-)
-
-const (
-	comQuit byte = iota + 1
-	comInitDB
-	comQuery
-	comFieldList
-	comCreateDB
-	comDropDB
-	comRefresh
-	comShutdown
-	comStatistics
-	comProcessInfo
-	comConnect
-	comProcessKill
-	comDebug
-	comPing
-	comTime
-	comDelayedInsert
-	comChangeUser
-	comBinlogDump
-	comTableDump
-	comConnectOut
-	comRegisterSlave
-	comStmtPrepare
-	comStmtExecute
-	comStmtSendLongData
-	comStmtClose
-	comStmtReset
-	comSetOption
-	comStmtFetch
-)
-
-const (
-	fieldTypeDecimal byte = iota
-	fieldTypeTiny
-	fieldTypeShort
-	fieldTypeLong
-	fieldTypeFloat
-	fieldTypeDouble
-	fieldTypeNULL
-	fieldTypeTimestamp
-	fieldTypeLongLong
-	fieldTypeInt24
-	fieldTypeDate
-	fieldTypeTime
-	fieldTypeDateTime
-	fieldTypeYear
-	fieldTypeNewDate
-	fieldTypeVarChar
-	fieldTypeBit
-)
-const (
-	fieldTypeNewDecimal byte = iota + 0xf6
-	fieldTypeEnum
-	fieldTypeSet
-	fieldTypeTinyBLOB
-	fieldTypeMediumBLOB
-	fieldTypeLongBLOB
-	fieldTypeBLOB
-	fieldTypeVarString
-	fieldTypeString
-	fieldTypeGeometry
-)
-
-type fieldFlag uint16
-
-const (
-	flagNotNULL fieldFlag = 1 << iota
-	flagPriKey
-	flagUniqueKey
-	flagMultipleKey
-	flagBLOB
-	flagUnsigned
-	flagZeroFill
-	flagBinary
-	flagEnum
-	flagAutoIncrement
-	flagTimestamp
-	flagSet
-	flagUnknown1
-	flagUnknown2
-	flagUnknown3
-	flagUnknown4
-)
-
-// http://dev.mysql.com/doc/internals/en/status-flags.html
-
-type statusFlag uint16
-
-const (
-	statusInTrans statusFlag = 1 << iota
-	statusInAutocommit
-	statusReserved // Not in documentation
-	statusMoreResultsExists
-	statusNoGoodIndexUsed
-	statusNoIndexUsed
-	statusCursorExists
-	statusLastRowSent
-	statusDbDropped
-	statusNoBackslashEscapes
-	statusMetadataChanged
-	statusQueryWasSlow
-	statusPsOutParams
-	statusInTransReadonly
-	statusSessionStateChanged
-)

+ 0 - 140
src/github.com/go-sql-driver/mysql/driver.go

@@ -1,140 +0,0 @@
-// Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved.
-//
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this file,
-// You can obtain one at http://mozilla.org/MPL/2.0/.
-
-// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
-//
-// The driver should be used via the database/sql package:
-//
-//  import "database/sql"
-//  import _ "github.com/go-sql-driver/mysql"
-//
-//  db, err := sql.Open("mysql", "user:password@/dbname")
-//
-// See https://github.com/go-sql-driver/mysql#usage for details
-package mysql
-
-import (
-	"database/sql"
-	"database/sql/driver"
-	"net"
-)
-
-// This struct is exported to make the driver directly accessible.
-// In general the driver is used via the database/sql package.
-type MySQLDriver struct{}
-
-// DialFunc is a function which can be used to establish the network connection.
-// Custom dial functions must be registered with RegisterDial
-type DialFunc func(addr string) (net.Conn, error)
-
-var dials map[string]DialFunc
-
-// RegisterDial registers a custom dial function. It can then be used by the
-// network address mynet(addr), where mynet is the registered new network.
-// addr is passed as a parameter to the dial function.
-func RegisterDial(net string, dial DialFunc) {
-	if dials == nil {
-		dials = make(map[string]DialFunc)
-	}
-	dials[net] = dial
-}
-
-// Open new Connection.
-// See https://github.com/go-sql-driver/mysql#dsn-data-source-name for how
-// the DSN string is formated
-func (d MySQLDriver) Open(dsn string) (driver.Conn, error) {
-	var err error
-
-	// New mysqlConn
-	mc := &mysqlConn{
-		maxPacketAllowed: maxPacketSize,
-		maxWriteSize:     maxPacketSize - 1,
-	}
-	mc.cfg, err = parseDSN(dsn)
-	if err != nil {
-		return nil, err
-	}
-
-	// Connect to Server
-	if dial, ok := dials[mc.cfg.net]; ok {
-		mc.netConn, err = dial(mc.cfg.addr)
-	} else {
-		nd := net.Dialer{Timeout: mc.cfg.timeout}
-		mc.netConn, err = nd.Dial(mc.cfg.net, mc.cfg.addr)
-	}
-	if err != nil {
-		return nil, err
-	}
-
-	// Enable TCP Keepalives on TCP connections
-	if tc, ok := mc.netConn.(*net.TCPConn); ok {
-		if err := tc.SetKeepAlive(true); err != nil {
-			// Don't send COM_QUIT before handshake.
-			mc.netConn.Close()
-			mc.netConn = nil
-			return nil, err
-		}
-	}
-
-	mc.buf = newBuffer(mc.netConn)
-
-	// Reading Handshake Initialization Packet
-	cipher, err := mc.readInitPacket()
-	if err != nil {
-		mc.Close()
-		return nil, err
-	}
-
-	// Send Client Authentication Packet
-	if err = mc.writeAuthPacket(cipher); err != nil {
-		mc.Close()
-		return nil, err
-	}
-
-	// Read Result Packet
-	err = mc.readResultOK()
-	if err != nil {
-		// Retry with old authentication method, if allowed
-		if mc.cfg != nil && mc.cfg.allowOldPasswords && err == ErrOldPassword {
-			if err = mc.writeOldAuthPacket(cipher); err != nil {
-				mc.Close()
-				return nil, err
-			}
-			if err = mc.readResultOK(); err != nil {
-				mc.Close()
-				return nil, err
-			}
-		} else {
-			mc.Close()
-			return nil, err
-		}
-
-	}
-
-	// Get max allowed packet size
-	maxap, err := mc.getSystemVar("max_allowed_packet")
-	if err != nil {
-		mc.Close()
-		return nil, err
-	}
-	mc.maxPacketAllowed = stringToInt(maxap) - 1
-	if mc.maxPacketAllowed < maxPacketSize {
-		mc.maxWriteSize = mc.maxPacketAllowed
-	}
-
-	// Handle DSN Params
-	err = mc.handleParams()
-	if err != nil {
-		mc.Close()
-		return nil, err
-	}
-
-	return mc, nil
-}
-
-func init() {
-	sql.Register("mysql", &MySQLDriver{})
-}

+ 0 - 129
src/github.com/go-sql-driver/mysql/errors.go

@@ -1,129 +0,0 @@
-// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
-//
-// Copyright 2013 The Go-MySQL-Driver Authors. All rights reserved.
-//
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this file,
-// You can obtain one at http://mozilla.org/MPL/2.0/.
-
-package mysql
-
-import (
-	"database/sql/driver"
-	"errors"
-	"fmt"
-	"io"
-	"log"
-	"os"
-)
-
-// Various errors the driver might return. Can change between driver versions.
-var (
-	ErrInvalidConn = errors.New("Invalid Connection")
-	ErrMalformPkt  = errors.New("Malformed Packet")
-	ErrNoTLS       = errors.New("TLS encryption requested but server does not support TLS")
-	ErrOldPassword = errors.New("This server only supports the insecure old password authentication. If you still want to use it, please add 'allowOldPasswords=1' to your DSN. See also https://github.com/go-sql-driver/mysql/wiki/old_passwords")
-	ErrOldProtocol = errors.New("MySQL-Server does not support required Protocol 41+")
-	ErrPktSync     = errors.New("Commands out of sync. You can't run this command now")
-	ErrPktSyncMul  = errors.New("Commands out of sync. Did you run multiple statements at once?")
-	ErrPktTooLarge = errors.New("Packet for query is too large. You can change this value on the server by adjusting the 'max_allowed_packet' variable.")
-	ErrBusyBuffer  = errors.New("Busy buffer")
-)
-
-var errLog Logger = log.New(os.Stderr, "[MySQL] ", log.Ldate|log.Ltime|log.Lshortfile)
-
-// Logger is used to log critical error messages.
-type Logger interface {
-	Print(v ...interface{})
-}
-
-// SetLogger is used to set the logger for critical errors.
-// The initial logger is os.Stderr.
-func SetLogger(logger Logger) error {
-	if logger == nil {
-		return errors.New("logger is nil")
-	}
-	errLog = logger
-	return nil
-}
-
-// MySQLError is an error type which represents a single MySQL error
-type MySQLError struct {
-	Number  uint16
-	Message string
-}
-
-func (me *MySQLError) Error() string {
-	return fmt.Sprintf("Error %d: %s", me.Number, me.Message)
-}
-
-// MySQLWarnings is an error type which represents a group of one or more MySQL
-// warnings
-type MySQLWarnings []MySQLWarning
-
-func (mws MySQLWarnings) Error() string {
-	var msg string
-	for i, warning := range mws {
-		if i > 0 {
-			msg += "\r\n"
-		}
-		msg += fmt.Sprintf(
-			"%s %s: %s",
-			warning.Level,
-			warning.Code,
-			warning.Message,
-		)
-	}
-	return msg
-}
-
-// MySQLWarning is an error type which represents a single MySQL warning.
-// Warnings are returned in groups only. See MySQLWarnings
-type MySQLWarning struct {
-	Level   string
-	Code    string
-	Message string
-}
-
-func (mc *mysqlConn) getWarnings() (err error) {
-	rows, err := mc.Query("SHOW WARNINGS", nil)
-	if err != nil {
-		return
-	}
-
-	var warnings = MySQLWarnings{}
-	var values = make([]driver.Value, 3)
-
-	for {
-		err = rows.Next(values)
-		switch err {
-		case nil:
-			warning := MySQLWarning{}
-
-			if raw, ok := values[0].([]byte); ok {
-				warning.Level = string(raw)
-			} else {
-				warning.Level = fmt.Sprintf("%s", values[0])
-			}
-			if raw, ok := values[1].([]byte); ok {
-				warning.Code = string(raw)
-			} else {
-				warning.Code = fmt.Sprintf("%s", values[1])
-			}
-			if raw, ok := values[2].([]byte); ok {
-				warning.Message = string(raw)
-			} else {
-				warning.Message = fmt.Sprintf("%s", values[0])
-			}
-
-			warnings = append(warnings, warning)
-
-		case io.EOF:
-			return warnings
-
-		default:
-			rows.Close()
-			return
-		}
-	}
-}

+ 0 - 162
src/github.com/go-sql-driver/mysql/infile.go

@@ -1,162 +0,0 @@
-// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
-//
-// Copyright 2013 The Go-MySQL-Driver Authors. All rights reserved.
-//
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this file,
-// You can obtain one at http://mozilla.org/MPL/2.0/.
-
-package mysql
-
-import (
-	"fmt"
-	"io"
-	"os"
-	"strings"
-)
-
-var (
-	fileRegister   map[string]bool
-	readerRegister map[string]func() io.Reader
-)
-
-// RegisterLocalFile adds the given file to the file whitelist,
-// so that it can be used by "LOAD DATA LOCAL INFILE <filepath>".
-// Alternatively you can allow the use of all local files with
-// the DSN parameter 'allowAllFiles=true'
-//
-//  filePath := "/home/gopher/data.csv"
-//  mysql.RegisterLocalFile(filePath)
-//  err := db.Exec("LOAD DATA LOCAL INFILE '" + filePath + "' INTO TABLE foo")
-//  if err != nil {
-//  ...
-//
-func RegisterLocalFile(filePath string) {
-	// lazy map init
-	if fileRegister == nil {
-		fileRegister = make(map[string]bool)
-	}
-
-	fileRegister[strings.Trim(filePath, `"`)] = true
-}
-
-// DeregisterLocalFile removes the given filepath from the whitelist.
-func DeregisterLocalFile(filePath string) {
-	delete(fileRegister, strings.Trim(filePath, `"`))
-}
-
-// RegisterReaderHandler registers a handler function which is used
-// to receive a io.Reader.
-// The Reader can be used by "LOAD DATA LOCAL INFILE Reader::<name>".
-// If the handler returns a io.ReadCloser Close() is called when the
-// request is finished.
-//
-//  mysql.RegisterReaderHandler("data", func() io.Reader {
-//  	var csvReader io.Reader // Some Reader that returns CSV data
-//  	... // Open Reader here
-//  	return csvReader
-//  })
-//  err := db.Exec("LOAD DATA LOCAL INFILE 'Reader::data' INTO TABLE foo")
-//  if err != nil {
-//  ...
-//
-func RegisterReaderHandler(name string, handler func() io.Reader) {
-	// lazy map init
-	if readerRegister == nil {
-		readerRegister = make(map[string]func() io.Reader)
-	}
-
-	readerRegister[name] = handler
-}
-
-// DeregisterReaderHandler removes the ReaderHandler function with
-// the given name from the registry.
-func DeregisterReaderHandler(name string) {
-	delete(readerRegister, name)
-}
-
-func deferredClose(err *error, closer io.Closer) {
-	closeErr := closer.Close()
-	if *err == nil {
-		*err = closeErr
-	}
-}
-
-func (mc *mysqlConn) handleInFileRequest(name string) (err error) {
-	var rdr io.Reader
-	var data []byte
-
-	if strings.HasPrefix(name, "Reader::") { // io.Reader
-		name = name[8:]
-		if handler, inMap := readerRegister[name]; inMap {
-			rdr = handler()
-			if rdr != nil {
-				data = make([]byte, 4+mc.maxWriteSize)
-
-				if cl, ok := rdr.(io.Closer); ok {
-					defer deferredClose(&err, cl)
-				}
-			} else {
-				err = fmt.Errorf("Reader '%s' is <nil>", name)
-			}
-		} else {
-			err = fmt.Errorf("Reader '%s' is not registered", name)
-		}
-	} else { // File
-		name = strings.Trim(name, `"`)
-		if mc.cfg.allowAllFiles || fileRegister[name] {
-			var file *os.File
-			var fi os.FileInfo
-
-			if file, err = os.Open(name); err == nil {
-				defer deferredClose(&err, file)
-
-				// get file size
-				if fi, err = file.Stat(); err == nil {
-					rdr = file
-					if fileSize := int(fi.Size()); fileSize <= mc.maxWriteSize {
-						data = make([]byte, 4+fileSize)
-					} else if fileSize <= mc.maxPacketAllowed {
-						data = make([]byte, 4+mc.maxWriteSize)
-					} else {
-						err = fmt.Errorf("Local File '%s' too large: Size: %d, Max: %d", name, fileSize, mc.maxPacketAllowed)
-					}
-				}
-			}
-		} else {
-			err = fmt.Errorf("Local File '%s' is not registered. Use the DSN parameter 'allowAllFiles=true' to allow all files", name)
-		}
-	}
-
-	// send content packets
-	if err == nil {
-		var n int
-		for err == nil {
-			n, err = rdr.Read(data[4:])
-			if n > 0 {
-				if ioErr := mc.writePacket(data[:4+n]); ioErr != nil {
-					return ioErr
-				}
-			}
-		}
-		if err == io.EOF {
-			err = nil
-		}
-	}
-
-	// send empty packet (termination)
-	if data == nil {
-		data = make([]byte, 4)
-	}
-	if ioErr := mc.writePacket(data[:4]); ioErr != nil {
-		return ioErr
-	}
-
-	// read OK packet
-	if err == nil {
-		return mc.readResultOK()
-	} else {
-		mc.readPacket()
-	}
-	return err
-}

+ 0 - 1138
src/github.com/go-sql-driver/mysql/packets.go

@@ -1,1138 +0,0 @@
-// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
-//
-// Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved.
-//
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this file,
-// You can obtain one at http://mozilla.org/MPL/2.0/.
-
-package mysql
-
-import (
-	"bytes"
-	"crypto/tls"
-	"database/sql/driver"
-	"encoding/binary"
-	"fmt"
-	"io"
-	"math"
-	"time"
-)
-
-// Packets documentation:
-// http://dev.mysql.com/doc/internals/en/client-server-protocol.html
-
-// Read packet to buffer 'data'
-func (mc *mysqlConn) readPacket() ([]byte, error) {
-	var payload []byte
-	for {
-		// Read packet header
-		data, err := mc.buf.readNext(4)
-		if err != nil {
-			errLog.Print(err)
-			mc.Close()
-			return nil, driver.ErrBadConn
-		}
-
-		// Packet Length [24 bit]
-		pktLen := int(uint32(data[0]) | uint32(data[1])<<8 | uint32(data[2])<<16)
-
-		if pktLen < 1 {
-			errLog.Print(ErrMalformPkt)
-			mc.Close()
-			return nil, driver.ErrBadConn
-		}
-
-		// Check Packet Sync [8 bit]
-		if data[3] != mc.sequence {
-			if data[3] > mc.sequence {
-				return nil, ErrPktSyncMul
-			} else {
-				return nil, ErrPktSync
-			}
-		}
-		mc.sequence++
-
-		// Read packet body [pktLen bytes]
-		data, err = mc.buf.readNext(pktLen)
-		if err != nil {
-			errLog.Print(err)
-			mc.Close()
-			return nil, driver.ErrBadConn
-		}
-
-		isLastPacket := (pktLen < maxPacketSize)
-
-		// Zero allocations for non-splitting packets
-		if isLastPacket && payload == nil {
-			return data, nil
-		}
-
-		payload = append(payload, data...)
-
-		if isLastPacket {
-			return payload, nil
-		}
-	}
-}
-
-// Write packet buffer 'data'
-func (mc *mysqlConn) writePacket(data []byte) error {
-	pktLen := len(data) - 4
-
-	if pktLen > mc.maxPacketAllowed {
-		return ErrPktTooLarge
-	}
-
-	for {
-		var size int
-		if pktLen >= maxPacketSize {
-			data[0] = 0xff
-			data[1] = 0xff
-			data[2] = 0xff
-			size = maxPacketSize
-		} else {
-			data[0] = byte(pktLen)
-			data[1] = byte(pktLen >> 8)
-			data[2] = byte(pktLen >> 16)
-			size = pktLen
-		}
-		data[3] = mc.sequence
-
-		// Write packet
-		n, err := mc.netConn.Write(data[:4+size])
-		if err == nil && n == 4+size {
-			mc.sequence++
-			if size != maxPacketSize {
-				return nil
-			}
-			pktLen -= size
-			data = data[size:]
-			continue
-		}
-
-		// Handle error
-		if err == nil { // n != len(data)
-			errLog.Print(ErrMalformPkt)
-		} else {
-			errLog.Print(err)
-		}
-		return driver.ErrBadConn
-	}
-}
-
-/******************************************************************************
-*                           Initialisation Process                            *
-******************************************************************************/
-
-// Handshake Initialization Packet
-// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::Handshake
-func (mc *mysqlConn) readInitPacket() ([]byte, error) {
-	data, err := mc.readPacket()
-	if err != nil {
-		return nil, err
-	}
-
-	if data[0] == iERR {
-		return nil, mc.handleErrorPacket(data)
-	}
-
-	// protocol version [1 byte]
-	if data[0] < minProtocolVersion {
-		return nil, fmt.Errorf(
-			"Unsupported MySQL Protocol Version %d. Protocol Version %d or higher is required",
-			data[0],
-			minProtocolVersion,
-		)
-	}
-
-	// server version [null terminated string]
-	// connection id [4 bytes]
-	pos := 1 + bytes.IndexByte(data[1:], 0x00) + 1 + 4
-
-	// first part of the password cipher [8 bytes]
-	cipher := data[pos : pos+8]
-
-	// (filler) always 0x00 [1 byte]
-	pos += 8 + 1
-
-	// capability flags (lower 2 bytes) [2 bytes]
-	mc.flags = clientFlag(binary.LittleEndian.Uint16(data[pos : pos+2]))
-	if mc.flags&clientProtocol41 == 0 {
-		return nil, ErrOldProtocol
-	}
-	if mc.flags&clientSSL == 0 && mc.cfg.tls != nil {
-		return nil, ErrNoTLS
-	}
-	pos += 2
-
-	if len(data) > pos {
-		// character set [1 byte]
-		// status flags [2 bytes]
-		// capability flags (upper 2 bytes) [2 bytes]
-		// length of auth-plugin-data [1 byte]
-		// reserved (all [00]) [10 bytes]
-		pos += 1 + 2 + 2 + 1 + 10
-
-		// second part of the password cipher [mininum 13 bytes],
-		// where len=MAX(13, length of auth-plugin-data - 8)
-		//
-		// The web documentation is ambiguous about the length. However,
-		// according to mysql-5.7/sql/auth/sql_authentication.cc line 538,
-		// the 13th byte is "\0 byte, terminating the second part of
-		// a scramble". So the second part of the password cipher is
-		// a NULL terminated string that's at least 13 bytes with the
-		// last byte being NULL.
-		//
-		// The official Python library uses the fixed length 12
-		// which seems to work but technically could have a hidden bug.
-		cipher = append(cipher, data[pos:pos+12]...)
-
-		// TODO: Verify string termination
-		// EOF if version (>= 5.5.7 and < 5.5.10) or (>= 5.6.0 and < 5.6.2)
-		// \NUL otherwise
-		//
-		//if data[len(data)-1] == 0 {
-		//	return
-		//}
-		//return ErrMalformPkt
-		return cipher, nil
-	}
-
-	// make a memory safe copy of the cipher slice
-	var b [8]byte
-	copy(b[:], cipher)
-	return b[:], nil
-}
-
-// Client Authentication Packet
-// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::HandshakeResponse
-func (mc *mysqlConn) writeAuthPacket(cipher []byte) error {
-	// Adjust client flags based on server support
-	clientFlags := clientProtocol41 |
-		clientSecureConn |
-		clientLongPassword |
-		clientTransactions |
-		clientLocalFiles |
-		mc.flags&clientLongFlag
-
-	if mc.cfg.clientFoundRows {
-		clientFlags |= clientFoundRows
-	}
-
-	// To enable TLS / SSL
-	if mc.cfg.tls != nil {
-		clientFlags |= clientSSL
-	}
-
-	// User Password
-	scrambleBuff := scramblePassword(cipher, []byte(mc.cfg.passwd))
-
-	pktLen := 4 + 4 + 1 + 23 + len(mc.cfg.user) + 1 + 1 + len(scrambleBuff)
-
-	// To specify a db name
-	if n := len(mc.cfg.dbname); n > 0 {
-		clientFlags |= clientConnectWithDB
-		pktLen += n + 1
-	}
-
-	// Calculate packet length and get buffer with that size
-	data := mc.buf.takeSmallBuffer(pktLen + 4)
-	if data == nil {
-		// can not take the buffer. Something must be wrong with the connection
-		errLog.Print(ErrBusyBuffer)
-		return driver.ErrBadConn
-	}
-
-	// ClientFlags [32 bit]
-	data[4] = byte(clientFlags)
-	data[5] = byte(clientFlags >> 8)
-	data[6] = byte(clientFlags >> 16)
-	data[7] = byte(clientFlags >> 24)
-
-	// MaxPacketSize [32 bit] (none)
-	data[8] = 0x00
-	data[9] = 0x00
-	data[10] = 0x00
-	data[11] = 0x00
-
-	// Charset [1 byte]
-	data[12] = mc.cfg.collation
-
-	// SSL Connection Request Packet
-	// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::SSLRequest
-	if mc.cfg.tls != nil {
-		// Send TLS / SSL request packet
-		if err := mc.writePacket(data[:(4+4+1+23)+4]); err != nil {
-			return err
-		}
-
-		// Switch to TLS
-		tlsConn := tls.Client(mc.netConn, mc.cfg.tls)
-		if err := tlsConn.Handshake(); err != nil {
-			return err
-		}
-		mc.netConn = tlsConn
-		mc.buf.rd = tlsConn
-	}
-
-	// Filler [23 bytes] (all 0x00)
-	pos := 13 + 23
-
-	// User [null terminated string]
-	if len(mc.cfg.user) > 0 {
-		pos += copy(data[pos:], mc.cfg.user)
-	}
-	data[pos] = 0x00
-	pos++
-
-	// ScrambleBuffer [length encoded integer]
-	data[pos] = byte(len(scrambleBuff))
-	pos += 1 + copy(data[pos+1:], scrambleBuff)
-
-	// Databasename [null terminated string]
-	if len(mc.cfg.dbname) > 0 {
-		pos += copy(data[pos:], mc.cfg.dbname)
-		data[pos] = 0x00
-	}
-
-	// Send Auth packet
-	return mc.writePacket(data)
-}
-
-//  Client old authentication packet
-// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::AuthSwitchResponse
-func (mc *mysqlConn) writeOldAuthPacket(cipher []byte) error {
-	// User password
-	scrambleBuff := scrambleOldPassword(cipher, []byte(mc.cfg.passwd))
-
-	// Calculate the packet lenght and add a tailing 0
-	pktLen := len(scrambleBuff) + 1
-	data := mc.buf.takeSmallBuffer(4 + pktLen)
-	if data == nil {
-		// can not take the buffer. Something must be wrong with the connection
-		errLog.Print(ErrBusyBuffer)
-		return driver.ErrBadConn
-	}
-
-	// Add the scrambled password [null terminated string]
-	copy(data[4:], scrambleBuff)
-	data[4+pktLen-1] = 0x00
-
-	return mc.writePacket(data)
-}
-
-/******************************************************************************
-*                             Command Packets                                 *
-******************************************************************************/
-
-func (mc *mysqlConn) writeCommandPacket(command byte) error {
-	// Reset Packet Sequence
-	mc.sequence = 0
-
-	data := mc.buf.takeSmallBuffer(4 + 1)
-	if data == nil {
-		// can not take the buffer. Something must be wrong with the connection
-		errLog.Print(ErrBusyBuffer)
-		return driver.ErrBadConn
-	}
-
-	// Add command byte
-	data[4] = command
-
-	// Send CMD packet
-	return mc.writePacket(data)
-}
-
-func (mc *mysqlConn) writeCommandPacketStr(command byte, arg string) error {
-	// Reset Packet Sequence
-	mc.sequence = 0
-
-	pktLen := 1 + len(arg)
-	data := mc.buf.takeBuffer(pktLen + 4)
-	if data == nil {
-		// can not take the buffer. Something must be wrong with the connection
-		errLog.Print(ErrBusyBuffer)
-		return driver.ErrBadConn
-	}
-
-	// Add command byte
-	data[4] = command
-
-	// Add arg
-	copy(data[5:], arg)
-
-	// Send CMD packet
-	return mc.writePacket(data)
-}
-
-func (mc *mysqlConn) writeCommandPacketUint32(command byte, arg uint32) error {
-	// Reset Packet Sequence
-	mc.sequence = 0
-
-	data := mc.buf.takeSmallBuffer(4 + 1 + 4)
-	if data == nil {
-		// can not take the buffer. Something must be wrong with the connection
-		errLog.Print(ErrBusyBuffer)
-		return driver.ErrBadConn
-	}
-
-	// Add command byte
-	data[4] = command
-
-	// Add arg [32 bit]
-	data[5] = byte(arg)
-	data[6] = byte(arg >> 8)
-	data[7] = byte(arg >> 16)
-	data[8] = byte(arg >> 24)
-
-	// Send CMD packet
-	return mc.writePacket(data)
-}
-
-/******************************************************************************
-*                              Result Packets                                 *
-******************************************************************************/
-
-// Returns error if Packet is not an 'Result OK'-Packet
-func (mc *mysqlConn) readResultOK() error {
-	data, err := mc.readPacket()
-	if err == nil {
-		// packet indicator
-		switch data[0] {
-
-		case iOK:
-			return mc.handleOkPacket(data)
-
-		case iEOF:
-			// someone is using old_passwords
-			return ErrOldPassword
-
-		default: // Error otherwise
-			return mc.handleErrorPacket(data)
-		}
-	}
-	return err
-}
-
-// Result Set Header Packet
-// http://dev.mysql.com/doc/internals/en/com-query-response.html#packet-ProtocolText::Resultset
-func (mc *mysqlConn) readResultSetHeaderPacket() (int, error) {
-	data, err := mc.readPacket()
-	if err == nil {
-		switch data[0] {
-
-		case iOK:
-			return 0, mc.handleOkPacket(data)
-
-		case iERR:
-			return 0, mc.handleErrorPacket(data)
-
-		case iLocalInFile:
-			return 0, mc.handleInFileRequest(string(data[1:]))
-		}
-
-		// column count
-		num, _, n := readLengthEncodedInteger(data)
-		if n-len(data) == 0 {
-			return int(num), nil
-		}
-
-		return 0, ErrMalformPkt
-	}
-	return 0, err
-}
-
-// Error Packet
-// http://dev.mysql.com/doc/internals/en/generic-response-packets.html#packet-ERR_Packet
-func (mc *mysqlConn) handleErrorPacket(data []byte) error {
-	if data[0] != iERR {
-		return ErrMalformPkt
-	}
-
-	// 0xff [1 byte]
-
-	// Error Number [16 bit uint]
-	errno := binary.LittleEndian.Uint16(data[1:3])
-
-	pos := 3
-
-	// SQL State [optional: # + 5bytes string]
-	if data[3] == 0x23 {
-		//sqlstate := string(data[4 : 4+5])
-		pos = 9
-	}
-
-	// Error Message [string]
-	return &MySQLError{
-		Number:  errno,
-		Message: string(data[pos:]),
-	}
-}
-
-// Ok Packet
-// http://dev.mysql.com/doc/internals/en/generic-response-packets.html#packet-OK_Packet
-func (mc *mysqlConn) handleOkPacket(data []byte) error {
-	var n, m int
-
-	// 0x00 [1 byte]
-
-	// Affected rows [Length Coded Binary]
-	mc.affectedRows, _, n = readLengthEncodedInteger(data[1:])
-
-	// Insert id [Length Coded Binary]
-	mc.insertId, _, m = readLengthEncodedInteger(data[1+n:])
-
-	// server_status [2 bytes]
-	mc.status = statusFlag(data[1+n+m]) | statusFlag(data[1+n+m+1])<<8
-
-	// warning count [2 bytes]
-	if !mc.strict {
-		return nil
-	} else {
-		pos := 1 + n + m + 2
-		if binary.LittleEndian.Uint16(data[pos:pos+2]) > 0 {
-			return mc.getWarnings()
-		}
-		return nil
-	}
-}
-
-// Read Packets as Field Packets until EOF-Packet or an Error appears
-// http://dev.mysql.com/doc/internals/en/com-query-response.html#packet-Protocol::ColumnDefinition41
-func (mc *mysqlConn) readColumns(count int) ([]mysqlField, error) {
-	columns := make([]mysqlField, count)
-
-	for i := 0; ; i++ {
-		data, err := mc.readPacket()
-		if err != nil {
-			return nil, err
-		}
-
-		// EOF Packet
-		if data[0] == iEOF && (len(data) == 5 || len(data) == 1) {
-			if i == count {
-				return columns, nil
-			}
-			return nil, fmt.Errorf("ColumnsCount mismatch n:%d len:%d", count, len(columns))
-		}
-
-		// Catalog
-		pos, err := skipLengthEncodedString(data)
-		if err != nil {
-			return nil, err
-		}
-
-		// Database [len coded string]
-		n, err := skipLengthEncodedString(data[pos:])
-		if err != nil {
-			return nil, err
-		}
-		pos += n
-
-		// Table [len coded string]
-		if mc.cfg.columnsWithAlias {
-			tableName, _, n, err := readLengthEncodedString(data[pos:])
-			if err != nil {
-				return nil, err
-			}
-			pos += n
-			columns[i].tableName = string(tableName)
-		} else {
-			n, err = skipLengthEncodedString(data[pos:])
-			if err != nil {
-				return nil, err
-			}
-			pos += n
-		}
-
-		// Original table [len coded string]
-		n, err = skipLengthEncodedString(data[pos:])
-		if err != nil {
-			return nil, err
-		}
-		pos += n
-
-		// Name [len coded string]
-		name, _, n, err := readLengthEncodedString(data[pos:])
-		if err != nil {
-			return nil, err
-		}
-		columns[i].name = string(name)
-		pos += n
-
-		// Original name [len coded string]
-		n, err = skipLengthEncodedString(data[pos:])
-		if err != nil {
-			return nil, err
-		}
-
-		// Filler [uint8]
-		// Charset [charset, collation uint8]
-		// Length [uint32]
-		pos += n + 1 + 2 + 4
-
-		// Field type [uint8]
-		columns[i].fieldType = data[pos]
-		pos++
-
-		// Flags [uint16]
-		columns[i].flags = fieldFlag(binary.LittleEndian.Uint16(data[pos : pos+2]))
-		pos += 2
-
-		// Decimals [uint8]
-		columns[i].decimals = data[pos]
-		//pos++
-
-		// Default value [len coded binary]
-		//if pos < len(data) {
-		//	defaultVal, _, err = bytesToLengthCodedBinary(data[pos:])
-		//}
-	}
-}
-
-// Read Packets as Field Packets until EOF-Packet or an Error appears
-// http://dev.mysql.com/doc/internals/en/com-query-response.html#packet-ProtocolText::ResultsetRow
-func (rows *textRows) readRow(dest []driver.Value) error {
-	mc := rows.mc
-
-	data, err := mc.readPacket()
-	if err != nil {
-		return err
-	}
-
-	// EOF Packet
-	if data[0] == iEOF && len(data) == 5 {
-		rows.mc = nil
-		return io.EOF
-	}
-	if data[0] == iERR {
-		rows.mc = nil
-		return mc.handleErrorPacket(data)
-	}
-
-	// RowSet Packet
-	var n int
-	var isNull bool
-	pos := 0
-
-	for i := range dest {
-		// Read bytes and convert to string
-		dest[i], isNull, n, err = readLengthEncodedString(data[pos:])
-		pos += n
-		if err == nil {
-			if !isNull {
-				if !mc.parseTime {
-					continue
-				} else {
-					switch rows.columns[i].fieldType {
-					case fieldTypeTimestamp, fieldTypeDateTime,
-						fieldTypeDate, fieldTypeNewDate:
-						dest[i], err = parseDateTime(
-							string(dest[i].([]byte)),
-							mc.cfg.loc,
-						)
-						if err == nil {
-							continue
-						}
-					default:
-						continue
-					}
-				}
-
-			} else {
-				dest[i] = nil
-				continue
-			}
-		}
-		return err // err != nil
-	}
-
-	return nil
-}
-
-// Reads Packets until EOF-Packet or an Error appears. Returns count of Packets read
-func (mc *mysqlConn) readUntilEOF() error {
-	for {
-		data, err := mc.readPacket()
-
-		// No Err and no EOF Packet
-		if err == nil && data[0] != iEOF {
-			continue
-		}
-		return err // Err or EOF
-	}
-}
-
-/******************************************************************************
-*                           Prepared Statements                               *
-******************************************************************************/
-
-// Prepare Result Packets
-// http://dev.mysql.com/doc/internals/en/com-stmt-prepare-response.html
-func (stmt *mysqlStmt) readPrepareResultPacket() (uint16, error) {
-	data, err := stmt.mc.readPacket()
-	if err == nil {
-		// packet indicator [1 byte]
-		if data[0] != iOK {
-			return 0, stmt.mc.handleErrorPacket(data)
-		}
-
-		// statement id [4 bytes]
-		stmt.id = binary.LittleEndian.Uint32(data[1:5])
-
-		// Column count [16 bit uint]
-		columnCount := binary.LittleEndian.Uint16(data[5:7])
-
-		// Param count [16 bit uint]
-		stmt.paramCount = int(binary.LittleEndian.Uint16(data[7:9]))
-
-		// Reserved [8 bit]
-
-		// Warning count [16 bit uint]
-		if !stmt.mc.strict {
-			return columnCount, nil
-		} else {
-			// Check for warnings count > 0, only available in MySQL > 4.1
-			if len(data) >= 12 && binary.LittleEndian.Uint16(data[10:12]) > 0 {
-				return columnCount, stmt.mc.getWarnings()
-			}
-			return columnCount, nil
-		}
-	}
-	return 0, err
-}
-
-// http://dev.mysql.com/doc/internals/en/com-stmt-send-long-data.html
-func (stmt *mysqlStmt) writeCommandLongData(paramID int, arg []byte) error {
-	maxLen := stmt.mc.maxPacketAllowed - 1
-	pktLen := maxLen
-
-	// After the header (bytes 0-3) follows before the data:
-	// 1 byte command
-	// 4 bytes stmtID
-	// 2 bytes paramID
-	const dataOffset = 1 + 4 + 2
-
-	// Can not use the write buffer since
-	// a) the buffer is too small
-	// b) it is in use
-	data := make([]byte, 4+1+4+2+len(arg))
-
-	copy(data[4+dataOffset:], arg)
-
-	for argLen := len(arg); argLen > 0; argLen -= pktLen - dataOffset {
-		if dataOffset+argLen < maxLen {
-			pktLen = dataOffset + argLen
-		}
-
-		stmt.mc.sequence = 0
-		// Add command byte [1 byte]
-		data[4] = comStmtSendLongData
-
-		// Add stmtID [32 bit]
-		data[5] = byte(stmt.id)
-		data[6] = byte(stmt.id >> 8)
-		data[7] = byte(stmt.id >> 16)
-		data[8] = byte(stmt.id >> 24)
-
-		// Add paramID [16 bit]
-		data[9] = byte(paramID)
-		data[10] = byte(paramID >> 8)
-
-		// Send CMD packet
-		err := stmt.mc.writePacket(data[:4+pktLen])
-		if err == nil {
-			data = data[pktLen-dataOffset:]
-			continue
-		}
-		return err
-
-	}
-
-	// Reset Packet Sequence
-	stmt.mc.sequence = 0
-	return nil
-}
-
-// Execute Prepared Statement
-// http://dev.mysql.com/doc/internals/en/com-stmt-execute.html
-func (stmt *mysqlStmt) writeExecutePacket(args []driver.Value) error {
-	if len(args) != stmt.paramCount {
-		return fmt.Errorf(
-			"Arguments count mismatch (Got: %d Has: %d)",
-			len(args),
-			stmt.paramCount,
-		)
-	}
-
-	const minPktLen = 4 + 1 + 4 + 1 + 4
-	mc := stmt.mc
-
-	// Reset packet-sequence
-	mc.sequence = 0
-
-	var data []byte
-
-	if len(args) == 0 {
-		data = mc.buf.takeBuffer(minPktLen)
-	} else {
-		data = mc.buf.takeCompleteBuffer()
-	}
-	if data == nil {
-		// can not take the buffer. Something must be wrong with the connection
-		errLog.Print(ErrBusyBuffer)
-		return driver.ErrBadConn
-	}
-
-	// command [1 byte]
-	data[4] = comStmtExecute
-
-	// statement_id [4 bytes]
-	data[5] = byte(stmt.id)
-	data[6] = byte(stmt.id >> 8)
-	data[7] = byte(stmt.id >> 16)
-	data[8] = byte(stmt.id >> 24)
-
-	// flags (0: CURSOR_TYPE_NO_CURSOR) [1 byte]
-	data[9] = 0x00
-
-	// iteration_count (uint32(1)) [4 bytes]
-	data[10] = 0x01
-	data[11] = 0x00
-	data[12] = 0x00
-	data[13] = 0x00
-
-	if len(args) > 0 {
-		pos := minPktLen
-
-		var nullMask []byte
-		if maskLen, typesLen := (len(args)+7)/8, 1+2*len(args); pos+maskLen+typesLen >= len(data) {
-			// buffer has to be extended but we don't know by how much so
-			// we depend on append after all data with known sizes fit.
-			// We stop at that because we deal with a lot of columns here
-			// which makes the required allocation size hard to guess.
-			tmp := make([]byte, pos+maskLen+typesLen)
-			copy(tmp[:pos], data[:pos])
-			data = tmp
-			nullMask = data[pos : pos+maskLen]
-			pos += maskLen
-		} else {
-			nullMask = data[pos : pos+maskLen]
-			for i := 0; i < maskLen; i++ {
-				nullMask[i] = 0
-			}
-			pos += maskLen
-		}
-
-		// newParameterBoundFlag 1 [1 byte]
-		data[pos] = 0x01
-		pos++
-
-		// type of each parameter [len(args)*2 bytes]
-		paramTypes := data[pos:]
-		pos += len(args) * 2
-
-		// value of each parameter [n bytes]
-		paramValues := data[pos:pos]
-		valuesCap := cap(paramValues)
-
-		for i, arg := range args {
-			// build NULL-bitmap
-			if arg == nil {
-				nullMask[i/8] |= 1 << (uint(i) & 7)
-				paramTypes[i+i] = fieldTypeNULL
-				paramTypes[i+i+1] = 0x00
-				continue
-			}
-
-			// cache types and values
-			switch v := arg.(type) {
-			case int64:
-				paramTypes[i+i] = fieldTypeLongLong
-				paramTypes[i+i+1] = 0x00
-
-				if cap(paramValues)-len(paramValues)-8 >= 0 {
-					paramValues = paramValues[:len(paramValues)+8]
-					binary.LittleEndian.PutUint64(
-						paramValues[len(paramValues)-8:],
-						uint64(v),
-					)
-				} else {
-					paramValues = append(paramValues,
-						uint64ToBytes(uint64(v))...,
-					)
-				}
-
-			case float64:
-				paramTypes[i+i] = fieldTypeDouble
-				paramTypes[i+i+1] = 0x00
-
-				if cap(paramValues)-len(paramValues)-8 >= 0 {
-					paramValues = paramValues[:len(paramValues)+8]
-					binary.LittleEndian.PutUint64(
-						paramValues[len(paramValues)-8:],
-						math.Float64bits(v),
-					)
-				} else {
-					paramValues = append(paramValues,
-						uint64ToBytes(math.Float64bits(v))...,
-					)
-				}
-
-			case bool:
-				paramTypes[i+i] = fieldTypeTiny
-				paramTypes[i+i+1] = 0x00
-
-				if v {
-					paramValues = append(paramValues, 0x01)
-				} else {
-					paramValues = append(paramValues, 0x00)
-				}
-
-			case []byte:
-				// Common case (non-nil value) first
-				if v != nil {
-					paramTypes[i+i] = fieldTypeString
-					paramTypes[i+i+1] = 0x00
-
-					if len(v) < mc.maxPacketAllowed-pos-len(paramValues)-(len(args)-(i+1))*64 {
-						paramValues = appendLengthEncodedInteger(paramValues,
-							uint64(len(v)),
-						)
-						paramValues = append(paramValues, v...)
-					} else {
-						if err := stmt.writeCommandLongData(i, v); err != nil {
-							return err
-						}
-					}
-					continue
-				}
-
-				// Handle []byte(nil) as a NULL value
-				nullMask[i/8] |= 1 << (uint(i) & 7)
-				paramTypes[i+i] = fieldTypeNULL
-				paramTypes[i+i+1] = 0x00
-
-			case string:
-				paramTypes[i+i] = fieldTypeString
-				paramTypes[i+i+1] = 0x00
-
-				if len(v) < mc.maxPacketAllowed-pos-len(paramValues)-(len(args)-(i+1))*64 {
-					paramValues = appendLengthEncodedInteger(paramValues,
-						uint64(len(v)),
-					)
-					paramValues = append(paramValues, v...)
-				} else {
-					if err := stmt.writeCommandLongData(i, []byte(v)); err != nil {
-						return err
-					}
-				}
-
-			case time.Time:
-				paramTypes[i+i] = fieldTypeString
-				paramTypes[i+i+1] = 0x00
-
-				var val []byte
-				if v.IsZero() {
-					val = []byte("0000-00-00")
-				} else {
-					val = []byte(v.In(mc.cfg.loc).Format(timeFormat))
-				}
-
-				paramValues = appendLengthEncodedInteger(paramValues,
-					uint64(len(val)),
-				)
-				paramValues = append(paramValues, val...)
-
-			default:
-				return fmt.Errorf("Can't convert type: %T", arg)
-			}
-		}
-
-		// Check if param values exceeded the available buffer
-		// In that case we must build the data packet with the new values buffer
-		if valuesCap != cap(paramValues) {
-			data = append(data[:pos], paramValues...)
-			mc.buf.buf = data
-		}
-
-		pos += len(paramValues)
-		data = data[:pos]
-	}
-
-	return mc.writePacket(data)
-}
-
-// http://dev.mysql.com/doc/internals/en/binary-protocol-resultset-row.html
-func (rows *binaryRows) readRow(dest []driver.Value) error {
-	data, err := rows.mc.readPacket()
-	if err != nil {
-		return err
-	}
-
-	// packet indicator [1 byte]
-	if data[0] != iOK {
-		rows.mc = nil
-		// EOF Packet
-		if data[0] == iEOF && len(data) == 5 {
-			return io.EOF
-		}
-
-		// Error otherwise
-		return rows.mc.handleErrorPacket(data)
-	}
-
-	// NULL-bitmap,  [(column-count + 7 + 2) / 8 bytes]
-	pos := 1 + (len(dest)+7+2)>>3
-	nullMask := data[1:pos]
-
-	for i := range dest {
-		// Field is NULL
-		// (byte >> bit-pos) % 2 == 1
-		if ((nullMask[(i+2)>>3] >> uint((i+2)&7)) & 1) == 1 {
-			dest[i] = nil
-			continue
-		}
-
-		// Convert to byte-coded string
-		switch rows.columns[i].fieldType {
-		case fieldTypeNULL:
-			dest[i] = nil
-			continue
-
-		// Numeric Types
-		case fieldTypeTiny:
-			if rows.columns[i].flags&flagUnsigned != 0 {
-				dest[i] = int64(data[pos])
-			} else {
-				dest[i] = int64(int8(data[pos]))
-			}
-			pos++
-			continue
-
-		case fieldTypeShort, fieldTypeYear:
-			if rows.columns[i].flags&flagUnsigned != 0 {
-				dest[i] = int64(binary.LittleEndian.Uint16(data[pos : pos+2]))
-			} else {
-				dest[i] = int64(int16(binary.LittleEndian.Uint16(data[pos : pos+2])))
-			}
-			pos += 2
-			continue
-
-		case fieldTypeInt24, fieldTypeLong:
-			if rows.columns[i].flags&flagUnsigned != 0 {
-				dest[i] = int64(binary.LittleEndian.Uint32(data[pos : pos+4]))
-			} else {
-				dest[i] = int64(int32(binary.LittleEndian.Uint32(data[pos : pos+4])))
-			}
-			pos += 4
-			continue
-
-		case fieldTypeLongLong:
-			if rows.columns[i].flags&flagUnsigned != 0 {
-				val := binary.LittleEndian.Uint64(data[pos : pos+8])
-				if val > math.MaxInt64 {
-					dest[i] = uint64ToString(val)
-				} else {
-					dest[i] = int64(val)
-				}
-			} else {
-				dest[i] = int64(binary.LittleEndian.Uint64(data[pos : pos+8]))
-			}
-			pos += 8
-			continue
-
-		case fieldTypeFloat:
-			dest[i] = float64(math.Float32frombits(binary.LittleEndian.Uint32(data[pos : pos+4])))
-			pos += 4
-			continue
-
-		case fieldTypeDouble:
-			dest[i] = math.Float64frombits(binary.LittleEndian.Uint64(data[pos : pos+8]))
-			pos += 8
-			continue
-
-		// Length coded Binary Strings
-		case fieldTypeDecimal, fieldTypeNewDecimal, fieldTypeVarChar,
-			fieldTypeBit, fieldTypeEnum, fieldTypeSet, fieldTypeTinyBLOB,
-			fieldTypeMediumBLOB, fieldTypeLongBLOB, fieldTypeBLOB,
-			fieldTypeVarString, fieldTypeString, fieldTypeGeometry:
-			var isNull bool
-			var n int
-			dest[i], isNull, n, err = readLengthEncodedString(data[pos:])
-			pos += n
-			if err == nil {
-				if !isNull {
-					continue
-				} else {
-					dest[i] = nil
-					continue
-				}
-			}
-			return err
-
-		case
-			fieldTypeDate, fieldTypeNewDate, // Date YYYY-MM-DD
-			fieldTypeTime,                         // Time [-][H]HH:MM:SS[.fractal]
-			fieldTypeTimestamp, fieldTypeDateTime: // Timestamp YYYY-MM-DD HH:MM:SS[.fractal]
-
-			num, isNull, n := readLengthEncodedInteger(data[pos:])
-			pos += n
-
-			switch {
-			case isNull:
-				dest[i] = nil
-				continue
-			case rows.columns[i].fieldType == fieldTypeTime:
-				// database/sql does not support an equivalent to TIME, return a string
-				var dstlen uint8
-				switch decimals := rows.columns[i].decimals; decimals {
-				case 0x00, 0x1f:
-					dstlen = 8
-				case 1, 2, 3, 4, 5, 6:
-					dstlen = 8 + 1 + decimals
-				default:
-					return fmt.Errorf(
-						"MySQL protocol error, illegal decimals value %d",
-						rows.columns[i].decimals,
-					)
-				}
-				dest[i], err = formatBinaryDateTime(data[pos:pos+int(num)], dstlen, true)
-			case rows.mc.parseTime:
-				dest[i], err = parseBinaryDateTime(num, data[pos:], rows.mc.cfg.loc)
-			default:
-				var dstlen uint8
-				if rows.columns[i].fieldType == fieldTypeDate {
-					dstlen = 10
-				} else {
-					switch decimals := rows.columns[i].decimals; decimals {
-					case 0x00, 0x1f:
-						dstlen = 19
-					case 1, 2, 3, 4, 5, 6:
-						dstlen = 19 + 1 + decimals
-					default:
-						return fmt.Errorf(
-							"MySQL protocol error, illegal decimals value %d",
-							rows.columns[i].decimals,
-						)
-					}
-				}
-				dest[i], err = formatBinaryDateTime(data[pos:pos+int(num)], dstlen, false)
-			}
-
-			if err == nil {
-				pos += int(num)
-				continue
-			} else {
-				return err
-			}
-
-		// Please report if this happens!
-		default:
-			return fmt.Errorf("Unknown FieldType %d", rows.columns[i].fieldType)
-		}
-	}
-
-	return nil
-}

+ 0 - 22
src/github.com/go-sql-driver/mysql/result.go

@@ -1,22 +0,0 @@
-// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
-//
-// Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved.
-//
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this file,
-// You can obtain one at http://mozilla.org/MPL/2.0/.
-
-package mysql
-
-type mysqlResult struct {
-	affectedRows int64
-	insertId     int64
-}
-
-func (res *mysqlResult) LastInsertId() (int64, error) {
-	return res.insertId, nil
-}
-
-func (res *mysqlResult) RowsAffected() (int64, error) {
-	return res.affectedRows, nil
-}

+ 0 - 102
src/github.com/go-sql-driver/mysql/rows.go

@@ -1,102 +0,0 @@
-// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
-//
-// Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved.
-//
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this file,
-// You can obtain one at http://mozilla.org/MPL/2.0/.
-
-package mysql
-
-import (
-	"database/sql/driver"
-	"io"
-)
-
-type mysqlField struct {
-	tableName string
-	name      string
-	flags     fieldFlag
-	fieldType byte
-	decimals  byte
-}
-
-type mysqlRows struct {
-	mc      *mysqlConn
-	columns []mysqlField
-}
-
-type binaryRows struct {
-	mysqlRows
-}
-
-type textRows struct {
-	mysqlRows
-}
-
-type emptyRows struct{}
-
-func (rows *mysqlRows) Columns() []string {
-	columns := make([]string, len(rows.columns))
-	if rows.mc.cfg.columnsWithAlias {
-		for i := range columns {
-			columns[i] = rows.columns[i].tableName + "." + rows.columns[i].name
-		}
-	} else {
-		for i := range columns {
-			columns[i] = rows.columns[i].name
-		}
-	}
-	return columns
-}
-
-func (rows *mysqlRows) Close() error {
-	mc := rows.mc
-	if mc == nil {
-		return nil
-	}
-	if mc.netConn == nil {
-		return ErrInvalidConn
-	}
-
-	// Remove unread packets from stream
-	err := mc.readUntilEOF()
-	rows.mc = nil
-	return err
-}
-
-func (rows *binaryRows) Next(dest []driver.Value) error {
-	if mc := rows.mc; mc != nil {
-		if mc.netConn == nil {
-			return ErrInvalidConn
-		}
-
-		// Fetch next row from stream
-		return rows.readRow(dest)
-	}
-	return io.EOF
-}
-
-func (rows *textRows) Next(dest []driver.Value) error {
-	if mc := rows.mc; mc != nil {
-		if mc.netConn == nil {
-			return ErrInvalidConn
-		}
-
-		// Fetch next row from stream
-		return rows.readRow(dest)
-	}
-	return io.EOF
-}
-
-func (rows emptyRows) Columns() []string {
-	return nil
-}
-
-func (rows emptyRows) Close() error {
-	return nil
-}
-
-func (rows emptyRows) Next(dest []driver.Value) error {
-	return io.EOF
-}

+ 0 - 112
src/github.com/go-sql-driver/mysql/statement.go

@@ -1,112 +0,0 @@
-// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
-//
-// Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved.
-//
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this file,
-// You can obtain one at http://mozilla.org/MPL/2.0/.
-
-package mysql
-
-import (
-	"database/sql/driver"
-)
-
-type mysqlStmt struct {
-	mc         *mysqlConn
-	id         uint32
-	paramCount int
-	columns    []mysqlField // cached from the first query
-}
-
-func (stmt *mysqlStmt) Close() error {
-	if stmt.mc == nil || stmt.mc.netConn == nil {
-		errLog.Print(ErrInvalidConn)
-		return driver.ErrBadConn
-	}
-
-	err := stmt.mc.writeCommandPacketUint32(comStmtClose, stmt.id)
-	stmt.mc = nil
-	return err
-}
-
-func (stmt *mysqlStmt) NumInput() int {
-	return stmt.paramCount
-}
-
-func (stmt *mysqlStmt) Exec(args []driver.Value) (driver.Result, error) {
-	if stmt.mc.netConn == nil {
-		errLog.Print(ErrInvalidConn)
-		return nil, driver.ErrBadConn
-	}
-	// Send command
-	err := stmt.writeExecutePacket(args)
-	if err != nil {
-		return nil, err
-	}
-
-	mc := stmt.mc
-
-	mc.affectedRows = 0
-	mc.insertId = 0
-
-	// Read Result
-	resLen, err := mc.readResultSetHeaderPacket()
-	if err == nil {
-		if resLen > 0 {
-			// Columns
-			err = mc.readUntilEOF()
-			if err != nil {
-				return nil, err
-			}
-
-			// Rows
-			err = mc.readUntilEOF()
-		}
-		if err == nil {
-			return &mysqlResult{
-				affectedRows: int64(mc.affectedRows),
-				insertId:     int64(mc.insertId),
-			}, nil
-		}
-	}
-
-	return nil, err
-}
-
-func (stmt *mysqlStmt) Query(args []driver.Value) (driver.Rows, error) {
-	if stmt.mc.netConn == nil {
-		errLog.Print(ErrInvalidConn)
-		return nil, driver.ErrBadConn
-	}
-	// Send command
-	err := stmt.writeExecutePacket(args)
-	if err != nil {
-		return nil, err
-	}
-
-	mc := stmt.mc
-
-	// Read Result
-	resLen, err := mc.readResultSetHeaderPacket()
-	if err != nil {
-		return nil, err
-	}
-
-	rows := new(binaryRows)
-	rows.mc = mc
-
-	if resLen > 0 {
-		// Columns
-		// If not cached, read them and cache them
-		if stmt.columns == nil {
-			rows.columns, err = mc.readColumns(resLen)
-			stmt.columns = rows.columns
-		} else {
-			rows.columns = stmt.columns
-			err = mc.readUntilEOF()
-		}
-	}
-
-	return rows, err
-}

+ 0 - 31
src/github.com/go-sql-driver/mysql/transaction.go

@@ -1,31 +0,0 @@
-// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
-//
-// Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved.
-//
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this file,
-// You can obtain one at http://mozilla.org/MPL/2.0/.
-
-package mysql
-
-type mysqlTx struct {
-	mc *mysqlConn
-}
-
-func (tx *mysqlTx) Commit() (err error) {
-	if tx.mc == nil || tx.mc.netConn == nil {
-		return ErrInvalidConn
-	}
-	err = tx.mc.exec("COMMIT")
-	tx.mc = nil
-	return
-}
-
-func (tx *mysqlTx) Rollback() (err error) {
-	if tx.mc == nil || tx.mc.netConn == nil {
-		return ErrInvalidConn
-	}
-	err = tx.mc.exec("ROLLBACK")
-	tx.mc = nil
-	return
-}

+ 0 - 963
src/github.com/go-sql-driver/mysql/utils.go

@@ -1,963 +0,0 @@
-// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
-//
-// Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved.
-//
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this file,
-// You can obtain one at http://mozilla.org/MPL/2.0/.
-
-package mysql
-
-import (
-	"crypto/sha1"
-	"crypto/tls"
-	"database/sql/driver"
-	"encoding/binary"
-	"errors"
-	"fmt"
-	"io"
-	"net"
-	"net/url"
-	"strings"
-	"time"
-)
-
-var (
-	tlsConfigRegister map[string]*tls.Config // Register for custom tls.Configs
-
-	errInvalidDSNUnescaped       = errors.New("Invalid DSN: Did you forget to escape a param value?")
-	errInvalidDSNAddr            = errors.New("Invalid DSN: Network Address not terminated (missing closing brace)")
-	errInvalidDSNNoSlash         = errors.New("Invalid DSN: Missing the slash separating the database name")
-	errInvalidDSNUnsafeCollation = errors.New("Invalid DSN: interpolateParams can be used with ascii, latin1, utf8 and utf8mb4 charset")
-)
-
-func init() {
-	tlsConfigRegister = make(map[string]*tls.Config)
-}
-
-// RegisterTLSConfig registers a custom tls.Config to be used with sql.Open.
-// Use the key as a value in the DSN where tls=value.
-//
-//  rootCertPool := x509.NewCertPool()
-//  pem, err := ioutil.ReadFile("/path/ca-cert.pem")
-//  if err != nil {
-//      log.Fatal(err)
-//  }
-//  if ok := rootCertPool.AppendCertsFromPEM(pem); !ok {
-//      log.Fatal("Failed to append PEM.")
-//  }
-//  clientCert := make([]tls.Certificate, 0, 1)
-//  certs, err := tls.LoadX509KeyPair("/path/client-cert.pem", "/path/client-key.pem")
-//  if err != nil {
-//      log.Fatal(err)
-//  }
-//  clientCert = append(clientCert, certs)
-//  mysql.RegisterTLSConfig("custom", &tls.Config{
-//      RootCAs: rootCertPool,
-//      Certificates: clientCert,
-//  })
-//  db, err := sql.Open("mysql", "user@tcp(localhost:3306)/test?tls=custom")
-//
-func RegisterTLSConfig(key string, config *tls.Config) error {
-	if _, isBool := readBool(key); isBool || strings.ToLower(key) == "skip-verify" {
-		return fmt.Errorf("Key '%s' is reserved", key)
-	}
-
-	tlsConfigRegister[key] = config
-	return nil
-}
-
-// DeregisterTLSConfig removes the tls.Config associated with key.
-func DeregisterTLSConfig(key string) {
-	delete(tlsConfigRegister, key)
-}
-
-// parseDSN parses the DSN string to a config
-func parseDSN(dsn string) (cfg *config, err error) {
-	// New config with some default values
-	cfg = &config{
-		loc:       time.UTC,
-		collation: defaultCollation,
-	}
-
-	// TODO: use strings.IndexByte when we can depend on Go 1.2
-
-	// [user[:password]@][net[(addr)]]/dbname[?param1=value1&paramN=valueN]
-	// Find the last '/' (since the password or the net addr might contain a '/')
-	foundSlash := false
-	for i := len(dsn) - 1; i >= 0; i-- {
-		if dsn[i] == '/' {
-			foundSlash = true
-			var j, k int
-
-			// left part is empty if i <= 0
-			if i > 0 {
-				// [username[:password]@][protocol[(address)]]
-				// Find the last '@' in dsn[:i]
-				for j = i; j >= 0; j-- {
-					if dsn[j] == '@' {
-						// username[:password]
-						// Find the first ':' in dsn[:j]
-						for k = 0; k < j; k++ {
-							if dsn[k] == ':' {
-								cfg.passwd = dsn[k+1 : j]
-								break
-							}
-						}
-						cfg.user = dsn[:k]
-
-						break
-					}
-				}
-
-				// [protocol[(address)]]
-				// Find the first '(' in dsn[j+1:i]
-				for k = j + 1; k < i; k++ {
-					if dsn[k] == '(' {
-						// dsn[i-1] must be == ')' if an address is specified
-						if dsn[i-1] != ')' {
-							if strings.ContainsRune(dsn[k+1:i], ')') {
-								return nil, errInvalidDSNUnescaped
-							}
-							return nil, errInvalidDSNAddr
-						}
-						cfg.addr = dsn[k+1 : i-1]
-						break
-					}
-				}
-				cfg.net = dsn[j+1 : k]
-			}
-
-			// dbname[?param1=value1&...&paramN=valueN]
-			// Find the first '?' in dsn[i+1:]
-			for j = i + 1; j < len(dsn); j++ {
-				if dsn[j] == '?' {
-					if err = parseDSNParams(cfg, dsn[j+1:]); err != nil {
-						return
-					}
-					break
-				}
-			}
-			cfg.dbname = dsn[i+1 : j]
-
-			break
-		}
-	}
-
-	if !foundSlash && len(dsn) > 0 {
-		return nil, errInvalidDSNNoSlash
-	}
-
-	if cfg.interpolateParams && unsafeCollations[cfg.collation] {
-		return nil, errInvalidDSNUnsafeCollation
-	}
-
-	// Set default network if empty
-	if cfg.net == "" {
-		cfg.net = "tcp"
-	}
-
-	// Set default address if empty
-	if cfg.addr == "" {
-		switch cfg.net {
-		case "tcp":
-			cfg.addr = "127.0.0.1:3306"
-		case "unix":
-			cfg.addr = "/tmp/mysql.sock"
-		default:
-			return nil, errors.New("Default addr for network '" + cfg.net + "' unknown")
-		}
-
-	}
-
-	return
-}
-
-// parseDSNParams parses the DSN "query string"
-// Values must be url.QueryEscape'ed
-func parseDSNParams(cfg *config, params string) (err error) {
-	for _, v := range strings.Split(params, "&") {
-		param := strings.SplitN(v, "=", 2)
-		if len(param) != 2 {
-			continue
-		}
-
-		// cfg params
-		switch value := param[1]; param[0] {
-
-		// Enable client side placeholder substitution
-		case "interpolateParams":
-			var isBool bool
-			cfg.interpolateParams, isBool = readBool(value)
-			if !isBool {
-				return fmt.Errorf("Invalid Bool value: %s", value)
-			}
-
-		// Disable INFILE whitelist / enable all files
-		case "allowAllFiles":
-			var isBool bool
-			cfg.allowAllFiles, isBool = readBool(value)
-			if !isBool {
-				return fmt.Errorf("Invalid Bool value: %s", value)
-			}
-
-		// Use old authentication mode (pre MySQL 4.1)
-		case "allowOldPasswords":
-			var isBool bool
-			cfg.allowOldPasswords, isBool = readBool(value)
-			if !isBool {
-				return fmt.Errorf("Invalid Bool value: %s", value)
-			}
-
-		// Switch "rowsAffected" mode
-		case "clientFoundRows":
-			var isBool bool
-			cfg.clientFoundRows, isBool = readBool(value)
-			if !isBool {
-				return fmt.Errorf("Invalid Bool value: %s", value)
-			}
-
-		// Collation
-		case "collation":
-			collation, ok := collations[value]
-			if !ok {
-				// Note possibility for false negatives:
-				// could be triggered  although the collation is valid if the
-				// collations map does not contain entries the server supports.
-				err = errors.New("unknown collation")
-				return
-			}
-			cfg.collation = collation
-			break
-
-		case "columnsWithAlias":
-			var isBool bool
-			cfg.columnsWithAlias, isBool = readBool(value)
-			if !isBool {
-				return fmt.Errorf("Invalid Bool value: %s", value)
-			}
-
-		// Time Location
-		case "loc":
-			if value, err = url.QueryUnescape(value); err != nil {
-				return
-			}
-			cfg.loc, err = time.LoadLocation(value)
-			if err != nil {
-				return
-			}
-
-		// Dial Timeout
-		case "timeout":
-			cfg.timeout, err = time.ParseDuration(value)
-			if err != nil {
-				return
-			}
-
-		// TLS-Encryption
-		case "tls":
-			boolValue, isBool := readBool(value)
-			if isBool {
-				if boolValue {
-					cfg.tls = &tls.Config{}
-				}
-			} else {
-				if strings.ToLower(value) == "skip-verify" {
-					cfg.tls = &tls.Config{InsecureSkipVerify: true}
-				} else if tlsConfig, ok := tlsConfigRegister[value]; ok {
-					if len(tlsConfig.ServerName) == 0 && !tlsConfig.InsecureSkipVerify {
-						host, _, err := net.SplitHostPort(cfg.addr)
-						if err == nil {
-							tlsConfig.ServerName = host
-						}
-					}
-
-					cfg.tls = tlsConfig
-				} else {
-					return fmt.Errorf("Invalid value / unknown config name: %s", value)
-				}
-			}
-
-		default:
-			// lazy init
-			if cfg.params == nil {
-				cfg.params = make(map[string]string)
-			}
-
-			if cfg.params[param[0]], err = url.QueryUnescape(value); err != nil {
-				return
-			}
-		}
-	}
-
-	return
-}
-
-// Returns the bool value of the input.
-// The 2nd return value indicates if the input was a valid bool value
-func readBool(input string) (value bool, valid bool) {
-	switch input {
-	case "1", "true", "TRUE", "True":
-		return true, true
-	case "0", "false", "FALSE", "False":
-		return false, true
-	}
-
-	// Not a valid bool value
-	return
-}
-
-/******************************************************************************
-*                             Authentication                                  *
-******************************************************************************/
-
-// Encrypt password using 4.1+ method
-func scramblePassword(scramble, password []byte) []byte {
-	if len(password) == 0 {
-		return nil
-	}
-
-	// stage1Hash = SHA1(password)
-	crypt := sha1.New()
-	crypt.Write(password)
-	stage1 := crypt.Sum(nil)
-
-	// scrambleHash = SHA1(scramble + SHA1(stage1Hash))
-	// inner Hash
-	crypt.Reset()
-	crypt.Write(stage1)
-	hash := crypt.Sum(nil)
-
-	// outer Hash
-	crypt.Reset()
-	crypt.Write(scramble)
-	crypt.Write(hash)
-	scramble = crypt.Sum(nil)
-
-	// token = scrambleHash XOR stage1Hash
-	for i := range scramble {
-		scramble[i] ^= stage1[i]
-	}
-	return scramble
-}
-
-// Encrypt password using pre 4.1 (old password) method
-// https://github.com/atcurtis/mariadb/blob/master/mysys/my_rnd.c
-type myRnd struct {
-	seed1, seed2 uint32
-}
-
-const myRndMaxVal = 0x3FFFFFFF
-
-// Pseudo random number generator
-func newMyRnd(seed1, seed2 uint32) *myRnd {
-	return &myRnd{
-		seed1: seed1 % myRndMaxVal,
-		seed2: seed2 % myRndMaxVal,
-	}
-}
-
-// Tested to be equivalent to MariaDB's floating point variant
-// http://play.golang.org/p/QHvhd4qved
-// http://play.golang.org/p/RG0q4ElWDx
-func (r *myRnd) NextByte() byte {
-	r.seed1 = (r.seed1*3 + r.seed2) % myRndMaxVal
-	r.seed2 = (r.seed1 + r.seed2 + 33) % myRndMaxVal
-
-	return byte(uint64(r.seed1) * 31 / myRndMaxVal)
-}
-
-// Generate binary hash from byte string using insecure pre 4.1 method
-func pwHash(password []byte) (result [2]uint32) {
-	var add uint32 = 7
-	var tmp uint32
-
-	result[0] = 1345345333
-	result[1] = 0x12345671
-
-	for _, c := range password {
-		// skip spaces and tabs in password
-		if c == ' ' || c == '\t' {
-			continue
-		}
-
-		tmp = uint32(c)
-		result[0] ^= (((result[0] & 63) + add) * tmp) + (result[0] << 8)
-		result[1] += (result[1] << 8) ^ result[0]
-		add += tmp
-	}
-
-	// Remove sign bit (1<<31)-1)
-	result[0] &= 0x7FFFFFFF
-	result[1] &= 0x7FFFFFFF
-
-	return
-}
-
-// Encrypt password using insecure pre 4.1 method
-func scrambleOldPassword(scramble, password []byte) []byte {
-	if len(password) == 0 {
-		return nil
-	}
-
-	scramble = scramble[:8]
-
-	hashPw := pwHash(password)
-	hashSc := pwHash(scramble)
-
-	r := newMyRnd(hashPw[0]^hashSc[0], hashPw[1]^hashSc[1])
-
-	var out [8]byte
-	for i := range out {
-		out[i] = r.NextByte() + 64
-	}
-
-	mask := r.NextByte()
-	for i := range out {
-		out[i] ^= mask
-	}
-
-	return out[:]
-}
-
-/******************************************************************************
-*                           Time related utils                                *
-******************************************************************************/
-
-// NullTime represents a time.Time that may be NULL.
-// NullTime implements the Scanner interface so
-// it can be used as a scan destination:
-//
-//  var nt NullTime
-//  err := db.QueryRow("SELECT time FROM foo WHERE id=?", id).Scan(&nt)
-//  ...
-//  if nt.Valid {
-//     // use nt.Time
-//  } else {
-//     // NULL value
-//  }
-//
-// This NullTime implementation is not driver-specific
-type NullTime struct {
-	Time  time.Time
-	Valid bool // Valid is true if Time is not NULL
-}
-
-// Scan implements the Scanner interface.
-// The value type must be time.Time or string / []byte (formatted time-string),
-// otherwise Scan fails.
-func (nt *NullTime) Scan(value interface{}) (err error) {
-	if value == nil {
-		nt.Time, nt.Valid = time.Time{}, false
-		return
-	}
-
-	switch v := value.(type) {
-	case time.Time:
-		nt.Time, nt.Valid = v, true
-		return
-	case []byte:
-		nt.Time, err = parseDateTime(string(v), time.UTC)
-		nt.Valid = (err == nil)
-		return
-	case string:
-		nt.Time, err = parseDateTime(v, time.UTC)
-		nt.Valid = (err == nil)
-		return
-	}
-
-	nt.Valid = false
-	return fmt.Errorf("Can't convert %T to time.Time", value)
-}
-
-// Value implements the driver Valuer interface.
-func (nt NullTime) Value() (driver.Value, error) {
-	if !nt.Valid {
-		return nil, nil
-	}
-	return nt.Time, nil
-}
-
-func parseDateTime(str string, loc *time.Location) (t time.Time, err error) {
-	base := "0000-00-00 00:00:00.0000000"
-	switch len(str) {
-	case 10, 19, 21, 22, 23, 24, 25, 26: // up to "YYYY-MM-DD HH:MM:SS.MMMMMM"
-		if str == base[:len(str)] {
-			return
-		}
-		t, err = time.Parse(timeFormat[:len(str)], str)
-	default:
-		err = fmt.Errorf("Invalid Time-String: %s", str)
-		return
-	}
-
-	// Adjust location
-	if err == nil && loc != time.UTC {
-		y, mo, d := t.Date()
-		h, mi, s := t.Clock()
-		t, err = time.Date(y, mo, d, h, mi, s, t.Nanosecond(), loc), nil
-	}
-
-	return
-}
-
-func parseBinaryDateTime(num uint64, data []byte, loc *time.Location) (driver.Value, error) {
-	switch num {
-	case 0:
-		return time.Time{}, nil
-	case 4:
-		return time.Date(
-			int(binary.LittleEndian.Uint16(data[:2])), // year
-			time.Month(data[2]),                       // month
-			int(data[3]),                              // day
-			0, 0, 0, 0,
-			loc,
-		), nil
-	case 7:
-		return time.Date(
-			int(binary.LittleEndian.Uint16(data[:2])), // year
-			time.Month(data[2]),                       // month
-			int(data[3]),                              // day
-			int(data[4]),                              // hour
-			int(data[5]),                              // minutes
-			int(data[6]),                              // seconds
-			0,
-			loc,
-		), nil
-	case 11:
-		return time.Date(
-			int(binary.LittleEndian.Uint16(data[:2])), // year
-			time.Month(data[2]),                       // month
-			int(data[3]),                              // day
-			int(data[4]),                              // hour
-			int(data[5]),                              // minutes
-			int(data[6]),                              // seconds
-			int(binary.LittleEndian.Uint32(data[7:11]))*1000, // nanoseconds
-			loc,
-		), nil
-	}
-	return nil, fmt.Errorf("Invalid DATETIME-packet length %d", num)
-}
-
-// zeroDateTime is used in formatBinaryDateTime to avoid an allocation
-// if the DATE or DATETIME has the zero value.
-// It must never be changed.
-// The current behavior depends on database/sql copying the result.
-var zeroDateTime = []byte("0000-00-00 00:00:00.000000")
-
-const digits01 = "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"
-const digits10 = "0000000000111111111122222222223333333333444444444455555555556666666666777777777788888888889999999999"
-
-func formatBinaryDateTime(src []byte, length uint8, justTime bool) (driver.Value, error) {
-	// length expects the deterministic length of the zero value,
-	// negative time and 100+ hours are automatically added if needed
-	if len(src) == 0 {
-		if justTime {
-			return zeroDateTime[11 : 11+length], nil
-		}
-		return zeroDateTime[:length], nil
-	}
-	var dst []byte          // return value
-	var pt, p1, p2, p3 byte // current digit pair
-	var zOffs byte          // offset of value in zeroDateTime
-	if justTime {
-		switch length {
-		case
-			8,                      // time (can be up to 10 when negative and 100+ hours)
-			10, 11, 12, 13, 14, 15: // time with fractional seconds
-		default:
-			return nil, fmt.Errorf("illegal TIME length %d", length)
-		}
-		switch len(src) {
-		case 8, 12:
-		default:
-			return nil, fmt.Errorf("Invalid TIME-packet length %d", len(src))
-		}
-		// +2 to enable negative time and 100+ hours
-		dst = make([]byte, 0, length+2)
-		if src[0] == 1 {
-			dst = append(dst, '-')
-		}
-		if src[1] != 0 {
-			hour := uint16(src[1])*24 + uint16(src[5])
-			pt = byte(hour / 100)
-			p1 = byte(hour - 100*uint16(pt))
-			dst = append(dst, digits01[pt])
-		} else {
-			p1 = src[5]
-		}
-		zOffs = 11
-		src = src[6:]
-	} else {
-		switch length {
-		case 10, 19, 21, 22, 23, 24, 25, 26:
-		default:
-			t := "DATE"
-			if length > 10 {
-				t += "TIME"
-			}
-			return nil, fmt.Errorf("illegal %s length %d", t, length)
-		}
-		switch len(src) {
-		case 4, 7, 11:
-		default:
-			t := "DATE"
-			if length > 10 {
-				t += "TIME"
-			}
-			return nil, fmt.Errorf("illegal %s-packet length %d", t, len(src))
-		}
-		dst = make([]byte, 0, length)
-		// start with the date
-		year := binary.LittleEndian.Uint16(src[:2])
-		pt = byte(year / 100)
-		p1 = byte(year - 100*uint16(pt))
-		p2, p3 = src[2], src[3]
-		dst = append(dst,
-			digits10[pt], digits01[pt],
-			digits10[p1], digits01[p1], '-',
-			digits10[p2], digits01[p2], '-',
-			digits10[p3], digits01[p3],
-		)
-		if length == 10 {
-			return dst, nil
-		}
-		if len(src) == 4 {
-			return append(dst, zeroDateTime[10:length]...), nil
-		}
-		dst = append(dst, ' ')
-		p1 = src[4] // hour
-		src = src[5:]
-	}
-	// p1 is 2-digit hour, src is after hour
-	p2, p3 = src[0], src[1]
-	dst = append(dst,
-		digits10[p1], digits01[p1], ':',
-		digits10[p2], digits01[p2], ':',
-		digits10[p3], digits01[p3],
-	)
-	if length <= byte(len(dst)) {
-		return dst, nil
-	}
-	src = src[2:]
-	if len(src) == 0 {
-		return append(dst, zeroDateTime[19:zOffs+length]...), nil
-	}
-	microsecs := binary.LittleEndian.Uint32(src[:4])
-	p1 = byte(microsecs / 10000)
-	microsecs -= 10000 * uint32(p1)
-	p2 = byte(microsecs / 100)
-	microsecs -= 100 * uint32(p2)
-	p3 = byte(microsecs)
-	switch decimals := zOffs + length - 20; decimals {
-	default:
-		return append(dst, '.',
-			digits10[p1], digits01[p1],
-			digits10[p2], digits01[p2],
-			digits10[p3], digits01[p3],
-		), nil
-	case 1:
-		return append(dst, '.',
-			digits10[p1],
-		), nil
-	case 2:
-		return append(dst, '.',
-			digits10[p1], digits01[p1],
-		), nil
-	case 3:
-		return append(dst, '.',
-			digits10[p1], digits01[p1],
-			digits10[p2],
-		), nil
-	case 4:
-		return append(dst, '.',
-			digits10[p1], digits01[p1],
-			digits10[p2], digits01[p2],
-		), nil
-	case 5:
-		return append(dst, '.',
-			digits10[p1], digits01[p1],
-			digits10[p2], digits01[p2],
-			digits10[p3],
-		), nil
-	}
-}
-
-/******************************************************************************
-*                       Convert from and to bytes                             *
-******************************************************************************/
-
-func uint64ToBytes(n uint64) []byte {
-	return []byte{
-		byte(n),
-		byte(n >> 8),
-		byte(n >> 16),
-		byte(n >> 24),
-		byte(n >> 32),
-		byte(n >> 40),
-		byte(n >> 48),
-		byte(n >> 56),
-	}
-}
-
-func uint64ToString(n uint64) []byte {
-	var a [20]byte
-	i := 20
-
-	// U+0030 = 0
-	// ...
-	// U+0039 = 9
-
-	var q uint64
-	for n >= 10 {
-		i--
-		q = n / 10
-		a[i] = uint8(n-q*10) + 0x30
-		n = q
-	}
-
-	i--
-	a[i] = uint8(n) + 0x30
-
-	return a[i:]
-}
-
-// treats string value as unsigned integer representation
-func stringToInt(b []byte) int {
-	val := 0
-	for i := range b {
-		val *= 10
-		val += int(b[i] - 0x30)
-	}
-	return val
-}
-
-// returns the string read as a bytes slice, wheter the value is NULL,
-// the number of bytes read and an error, in case the string is longer than
-// the input slice
-func readLengthEncodedString(b []byte) ([]byte, bool, int, error) {
-	// Get length
-	num, isNull, n := readLengthEncodedInteger(b)
-	if num < 1 {
-		return b[n:n], isNull, n, nil
-	}
-
-	n += int(num)
-
-	// Check data length
-	if len(b) >= n {
-		return b[n-int(num) : n], false, n, nil
-	}
-	return nil, false, n, io.EOF
-}
-
-// returns the number of bytes skipped and an error, in case the string is
-// longer than the input slice
-func skipLengthEncodedString(b []byte) (int, error) {
-	// Get length
-	num, _, n := readLengthEncodedInteger(b)
-	if num < 1 {
-		return n, nil
-	}
-
-	n += int(num)
-
-	// Check data length
-	if len(b) >= n {
-		return n, nil
-	}
-	return n, io.EOF
-}
-
-// returns the number read, whether the value is NULL and the number of bytes read
-func readLengthEncodedInteger(b []byte) (uint64, bool, int) {
-	switch b[0] {
-
-	// 251: NULL
-	case 0xfb:
-		return 0, true, 1
-
-	// 252: value of following 2
-	case 0xfc:
-		return uint64(b[1]) | uint64(b[2])<<8, false, 3
-
-	// 253: value of following 3
-	case 0xfd:
-		return uint64(b[1]) | uint64(b[2])<<8 | uint64(b[3])<<16, false, 4
-
-	// 254: value of following 8
-	case 0xfe:
-		return uint64(b[1]) | uint64(b[2])<<8 | uint64(b[3])<<16 |
-				uint64(b[4])<<24 | uint64(b[5])<<32 | uint64(b[6])<<40 |
-				uint64(b[7])<<48 | uint64(b[8])<<56,
-			false, 9
-	}
-
-	// 0-250: value of first byte
-	return uint64(b[0]), false, 1
-}
-
-// encodes a uint64 value and appends it to the given bytes slice
-func appendLengthEncodedInteger(b []byte, n uint64) []byte {
-	switch {
-	case n <= 250:
-		return append(b, byte(n))
-
-	case n <= 0xffff:
-		return append(b, 0xfc, byte(n), byte(n>>8))
-
-	case n <= 0xffffff:
-		return append(b, 0xfd, byte(n), byte(n>>8), byte(n>>16))
-	}
-	return append(b, 0xfe, byte(n), byte(n>>8), byte(n>>16), byte(n>>24),
-		byte(n>>32), byte(n>>40), byte(n>>48), byte(n>>56))
-}
-
-// reserveBuffer checks cap(buf) and expand buffer to len(buf) + appendSize.
-// If cap(buf) is not enough, reallocate new buffer.
-func reserveBuffer(buf []byte, appendSize int) []byte {
-	newSize := len(buf) + appendSize
-	if cap(buf) < newSize {
-		// Grow buffer exponentially
-		newBuf := make([]byte, len(buf)*2+appendSize)
-		copy(newBuf, buf)
-		buf = newBuf
-	}
-	return buf[:newSize]
-}
-
-// escapeBytesBackslash escapes []byte with backslashes (\)
-// This escapes the contents of a string (provided as []byte) by adding backslashes before special
-// characters, and turning others into specific escape sequences, such as
-// turning newlines into \n and null bytes into \0.
-// https://github.com/mysql/mysql-server/blob/mysql-5.7.5/mysys/charset.c#L823-L932
-func escapeBytesBackslash(buf, v []byte) []byte {
-	pos := len(buf)
-	buf = reserveBuffer(buf, len(v)*2)
-
-	for _, c := range v {
-		switch c {
-		case '\x00':
-			buf[pos] = '\\'
-			buf[pos+1] = '0'
-			pos += 2
-		case '\n':
-			buf[pos] = '\\'
-			buf[pos+1] = 'n'
-			pos += 2
-		case '\r':
-			buf[pos] = '\\'
-			buf[pos+1] = 'r'
-			pos += 2
-		case '\x1a':
-			buf[pos] = '\\'
-			buf[pos+1] = 'Z'
-			pos += 2
-		case '\'':
-			buf[pos] = '\\'
-			buf[pos+1] = '\''
-			pos += 2
-		case '"':
-			buf[pos] = '\\'
-			buf[pos+1] = '"'
-			pos += 2
-		case '\\':
-			buf[pos] = '\\'
-			buf[pos+1] = '\\'
-			pos += 2
-		default:
-			buf[pos] = c
-			pos += 1
-		}
-	}
-
-	return buf[:pos]
-}
-
-// escapeStringBackslash is similar to escapeBytesBackslash but for string.
-func escapeStringBackslash(buf []byte, v string) []byte {
-	pos := len(buf)
-	buf = reserveBuffer(buf, len(v)*2)
-
-	for i := 0; i < len(v); i++ {
-		c := v[i]
-		switch c {
-		case '\x00':
-			buf[pos] = '\\'
-			buf[pos+1] = '0'
-			pos += 2
-		case '\n':
-			buf[pos] = '\\'
-			buf[pos+1] = 'n'
-			pos += 2
-		case '\r':
-			buf[pos] = '\\'
-			buf[pos+1] = 'r'
-			pos += 2
-		case '\x1a':
-			buf[pos] = '\\'
-			buf[pos+1] = 'Z'
-			pos += 2
-		case '\'':
-			buf[pos] = '\\'
-			buf[pos+1] = '\''
-			pos += 2
-		case '"':
-			buf[pos] = '\\'
-			buf[pos+1] = '"'
-			pos += 2
-		case '\\':
-			buf[pos] = '\\'
-			buf[pos+1] = '\\'
-			pos += 2
-		default:
-			buf[pos] = c
-			pos += 1
-		}
-	}
-
-	return buf[:pos]
-}
-
-// escapeBytesQuotes escapes apostrophes in []byte by doubling them up.
-// This escapes the contents of a string by doubling up any apostrophes that
-// it contains. This is used when the NO_BACKSLASH_ESCAPES SQL_MODE is in
-// effect on the server.
-// https://github.com/mysql/mysql-server/blob/mysql-5.7.5/mysys/charset.c#L963-L1038
-func escapeBytesQuotes(buf, v []byte) []byte {
-	pos := len(buf)
-	buf = reserveBuffer(buf, len(v)*2)
-
-	for _, c := range v {
-		if c == '\'' {
-			buf[pos] = '\''
-			buf[pos+1] = '\''
-			pos += 2
-		} else {
-			buf[pos] = c
-			pos++
-		}
-	}
-
-	return buf[:pos]
-}
-
-// escapeStringQuotes is similar to escapeBytesQuotes but for string.
-func escapeStringQuotes(buf []byte, v string) []byte {
-	pos := len(buf)
-	buf = reserveBuffer(buf, len(v)*2)
-
-	for i := 0; i < len(v); i++ {
-		c := v[i]
-		if c == '\'' {
-			buf[pos] = '\''
-			buf[pos+1] = '\''
-			pos += 2
-		} else {
-			buf[pos] = c
-			pos++
-		}
-	}
-
-	return buf[:pos]
-}

+ 0 - 5
src/github.com/gomodule/redigo/.github/CONTRIBUTING.md

@@ -1,5 +0,0 @@
-Ask questions at
-[StackOverflow](https://stackoverflow.com/questions/ask?tags=go+redis).
-
-[Open an issue](https://github.com/gomodule/redigo/issues/new) to discuss your
-plans before doing any work on Redigo.

+ 0 - 1
src/github.com/gomodule/redigo/.github/ISSUE_TEMPLATE.md

@@ -1 +0,0 @@
-Ask questions at https://stackoverflow.com/questions/ask?tags=go+redis

+ 0 - 23
src/github.com/gomodule/redigo/.travis.yml

@@ -1,23 +0,0 @@
-language: go
-sudo: false
-services:
-  - redis-server
-
-go:
-  - 1.7.x
-  - 1.8.x
-  - 1.9.x
-  - 1.10.x
-  - 1.11.x
-  - 1.12.x
-  - tip
-
-matrix:
-  allow_failures:
-    - go: tip
-
-script:
-  - go get -t -v ./...
-  - diff -u <(echo -n) <(gofmt -d .)
-  - go vet $(go list ./... | grep -v /vendor/)
-  - go test -v -race ./...

+ 0 - 175
src/github.com/gomodule/redigo/LICENSE

@@ -1,175 +0,0 @@
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.

+ 0 - 51
src/github.com/gomodule/redigo/README.markdown

@@ -1,51 +0,0 @@
-Redigo
-======
-
-[![Build Status](https://travis-ci.org/gomodule/redigo.svg?branch=master)](https://travis-ci.org/gomodule/redigo)
-[![GoDoc](https://godoc.org/github.com/gomodule/redigo/redis?status.svg)](https://godoc.org/github.com/gomodule/redigo/redis)
-
-Redigo is a [Go](http://golang.org/) client for the [Redis](http://redis.io/) database.
-
-Features
--------
-
-* A [Print-like](http://godoc.org/github.com/gomodule/redigo/redis#hdr-Executing_Commands) API with support for all Redis commands.
-* [Pipelining](http://godoc.org/github.com/gomodule/redigo/redis#hdr-Pipelining), including pipelined transactions.
-* [Publish/Subscribe](http://godoc.org/github.com/gomodule/redigo/redis#hdr-Publish_and_Subscribe).
-* [Connection pooling](http://godoc.org/github.com/gomodule/redigo/redis#Pool).
-* [Script helper type](http://godoc.org/github.com/gomodule/redigo/redis#Script) with optimistic use of EVALSHA.
-* [Helper functions](http://godoc.org/github.com/gomodule/redigo/redis#hdr-Reply_Helpers) for working with command replies.
-
-Documentation
--------------
-
-- [API Reference](http://godoc.org/github.com/gomodule/redigo/redis)
-- [FAQ](https://github.com/gomodule/redigo/wiki/FAQ)
-- [Examples](https://godoc.org/github.com/gomodule/redigo/redis#pkg-examples)
-
-Installation
-------------
-
-Install Redigo using the "go get" command:
-
-    go get github.com/gomodule/redigo/redis
-
-The Go distribution is Redigo's only dependency.
-
-Related Projects
-----------------
-
-- [rafaeljusto/redigomock](https://godoc.org/github.com/rafaeljusto/redigomock) - A mock library for Redigo.
-- [chasex/redis-go-cluster](https://github.com/chasex/redis-go-cluster) - A Redis cluster client implementation.
-- [FZambia/sentinel](https://github.com/FZambia/sentinel) - Redis Sentinel support for Redigo
-- [mna/redisc](https://github.com/mna/redisc) - Redis Cluster client built on top of Redigo
-
-Contributing
-------------
-
-See [CONTRIBUTING.md](https://github.com/gomodule/redigo/blob/master/.github/CONTRIBUTING.md).
-
-License
--------
-
-Redigo is available under the [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.html).

+ 0 - 55
src/github.com/gomodule/redigo/redis/commandinfo.go

@@ -1,55 +0,0 @@
-// Copyright 2014 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package redis
-
-import (
-	"strings"
-)
-
-const (
-	connectionWatchState = 1 << iota
-	connectionMultiState
-	connectionSubscribeState
-	connectionMonitorState
-)
-
-type commandInfo struct {
-	// Set or Clear these states on connection.
-	Set, Clear int
-}
-
-var commandInfos = map[string]commandInfo{
-	"WATCH":      {Set: connectionWatchState},
-	"UNWATCH":    {Clear: connectionWatchState},
-	"MULTI":      {Set: connectionMultiState},
-	"EXEC":       {Clear: connectionWatchState | connectionMultiState},
-	"DISCARD":    {Clear: connectionWatchState | connectionMultiState},
-	"PSUBSCRIBE": {Set: connectionSubscribeState},
-	"SUBSCRIBE":  {Set: connectionSubscribeState},
-	"MONITOR":    {Set: connectionMonitorState},
-}
-
-func init() {
-	for n, ci := range commandInfos {
-		commandInfos[strings.ToLower(n)] = ci
-	}
-}
-
-func lookupCommandInfo(commandName string) commandInfo {
-	if ci, ok := commandInfos[commandName]; ok {
-		return ci
-	}
-	return commandInfos[strings.ToUpper(commandName)]
-}

+ 0 - 27
src/github.com/gomodule/redigo/redis/commandinfo_test.go

@@ -1,27 +0,0 @@
-package redis
-
-import "testing"
-
-func TestLookupCommandInfo(t *testing.T) {
-	for _, n := range []string{"watch", "WATCH", "wAtch"} {
-		if lookupCommandInfo(n) == (commandInfo{}) {
-			t.Errorf("LookupCommandInfo(%q) = CommandInfo{}, expected non-zero value", n)
-		}
-	}
-}
-
-func benchmarkLookupCommandInfo(b *testing.B, names ...string) {
-	for i := 0; i < b.N; i++ {
-		for _, c := range names {
-			lookupCommandInfo(c)
-		}
-	}
-}
-
-func BenchmarkLookupCommandInfoCorrectCase(b *testing.B) {
-	benchmarkLookupCommandInfo(b, "watch", "WATCH", "monitor", "MONITOR")
-}
-
-func BenchmarkLookupCommandInfoMixedCase(b *testing.B) {
-	benchmarkLookupCommandInfo(b, "wAtch", "WeTCH", "monItor", "MONiTOR")
-}

+ 0 - 704
src/github.com/gomodule/redigo/redis/conn.go

@@ -1,704 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package redis
-
-import (
-	"bufio"
-	"bytes"
-	"crypto/tls"
-	"errors"
-	"fmt"
-	"io"
-	"net"
-	"net/url"
-	"regexp"
-	"strconv"
-	"sync"
-	"time"
-)
-
-var (
-	_ ConnWithTimeout = (*conn)(nil)
-)
-
-// conn is the low-level implementation of Conn
-type conn struct {
-	// Shared
-	mu      sync.Mutex
-	pending int
-	err     error
-	conn    net.Conn
-
-	// Read
-	readTimeout time.Duration
-	br          *bufio.Reader
-
-	// Write
-	writeTimeout time.Duration
-	bw           *bufio.Writer
-
-	// Scratch space for formatting argument length.
-	// '*' or '$', length, "\r\n"
-	lenScratch [32]byte
-
-	// Scratch space for formatting integers and floats.
-	numScratch [40]byte
-}
-
-// DialTimeout acts like Dial but takes timeouts for establishing the
-// connection to the server, writing a command and reading a reply.
-//
-// Deprecated: Use Dial with options instead.
-func DialTimeout(network, address string, connectTimeout, readTimeout, writeTimeout time.Duration) (Conn, error) {
-	return Dial(network, address,
-		DialConnectTimeout(connectTimeout),
-		DialReadTimeout(readTimeout),
-		DialWriteTimeout(writeTimeout))
-}
-
-// DialOption specifies an option for dialing a Redis server.
-type DialOption struct {
-	f func(*dialOptions)
-}
-
-type dialOptions struct {
-	readTimeout  time.Duration
-	writeTimeout time.Duration
-	dialer       *net.Dialer
-	dial         func(network, addr string) (net.Conn, error)
-	db           int
-	password     string
-	clientName   string
-	useTLS       bool
-	skipVerify   bool
-	tlsConfig    *tls.Config
-}
-
-// DialReadTimeout specifies the timeout for reading a single command reply.
-func DialReadTimeout(d time.Duration) DialOption {
-	return DialOption{func(do *dialOptions) {
-		do.readTimeout = d
-	}}
-}
-
-// DialWriteTimeout specifies the timeout for writing a single command.
-func DialWriteTimeout(d time.Duration) DialOption {
-	return DialOption{func(do *dialOptions) {
-		do.writeTimeout = d
-	}}
-}
-
-// DialConnectTimeout specifies the timeout for connecting to the Redis server when
-// no DialNetDial option is specified.
-func DialConnectTimeout(d time.Duration) DialOption {
-	return DialOption{func(do *dialOptions) {
-		do.dialer.Timeout = d
-	}}
-}
-
-// DialKeepAlive specifies the keep-alive period for TCP connections to the Redis server
-// when no DialNetDial option is specified.
-// If zero, keep-alives are not enabled. If no DialKeepAlive option is specified then
-// the default of 5 minutes is used to ensure that half-closed TCP sessions are detected.
-func DialKeepAlive(d time.Duration) DialOption {
-	return DialOption{func(do *dialOptions) {
-		do.dialer.KeepAlive = d
-	}}
-}
-
-// DialNetDial specifies a custom dial function for creating TCP
-// connections, otherwise a net.Dialer customized via the other options is used.
-// DialNetDial overrides DialConnectTimeout and DialKeepAlive.
-func DialNetDial(dial func(network, addr string) (net.Conn, error)) DialOption {
-	return DialOption{func(do *dialOptions) {
-		do.dial = dial
-	}}
-}
-
-// DialDatabase specifies the database to select when dialing a connection.
-func DialDatabase(db int) DialOption {
-	return DialOption{func(do *dialOptions) {
-		do.db = db
-	}}
-}
-
-// DialPassword specifies the password to use when connecting to
-// the Redis server.
-func DialPassword(password string) DialOption {
-	return DialOption{func(do *dialOptions) {
-		do.password = password
-	}}
-}
-
-// DialClientName specifies a client name to be used
-// by the Redis server connection.
-func DialClientName(name string) DialOption {
-	return DialOption{func(do *dialOptions) {
-		do.clientName = name
-	}}
-}
-
-// DialTLSConfig specifies the config to use when a TLS connection is dialed.
-// Has no effect when not dialing a TLS connection.
-func DialTLSConfig(c *tls.Config) DialOption {
-	return DialOption{func(do *dialOptions) {
-		do.tlsConfig = c
-	}}
-}
-
-// DialTLSSkipVerify disables server name verification when connecting over
-// TLS. Has no effect when not dialing a TLS connection.
-func DialTLSSkipVerify(skip bool) DialOption {
-	return DialOption{func(do *dialOptions) {
-		do.skipVerify = skip
-	}}
-}
-
-// DialUseTLS specifies whether TLS should be used when connecting to the
-// server. This option is ignore by DialURL.
-func DialUseTLS(useTLS bool) DialOption {
-	return DialOption{func(do *dialOptions) {
-		do.useTLS = useTLS
-	}}
-}
-
-// Dial connects to the Redis server at the given network and
-// address using the specified options.
-func Dial(network, address string, options ...DialOption) (Conn, error) {
-	do := dialOptions{
-		dialer: &net.Dialer{
-			KeepAlive: time.Minute * 5,
-		},
-	}
-	for _, option := range options {
-		option.f(&do)
-	}
-	if do.dial == nil {
-		do.dial = do.dialer.Dial
-	}
-
-	netConn, err := do.dial(network, address)
-	if err != nil {
-		return nil, err
-	}
-
-	if do.useTLS {
-		var tlsConfig *tls.Config
-		if do.tlsConfig == nil {
-			tlsConfig = &tls.Config{InsecureSkipVerify: do.skipVerify}
-		} else {
-			tlsConfig = cloneTLSConfig(do.tlsConfig)
-		}
-		if tlsConfig.ServerName == "" {
-			host, _, err := net.SplitHostPort(address)
-			if err != nil {
-				netConn.Close()
-				return nil, err
-			}
-			tlsConfig.ServerName = host
-		}
-
-		tlsConn := tls.Client(netConn, tlsConfig)
-		if err := tlsConn.Handshake(); err != nil {
-			netConn.Close()
-			return nil, err
-		}
-		netConn = tlsConn
-	}
-
-	c := &conn{
-		conn:         netConn,
-		bw:           bufio.NewWriter(netConn),
-		br:           bufio.NewReader(netConn),
-		readTimeout:  do.readTimeout,
-		writeTimeout: do.writeTimeout,
-	}
-
-	if do.password != "" {
-		if _, err := c.Do("AUTH", do.password); err != nil {
-			netConn.Close()
-			return nil, err
-		}
-	}
-
-	if do.clientName != "" {
-		if _, err := c.Do("CLIENT", "SETNAME", do.clientName); err != nil {
-			netConn.Close()
-			return nil, err
-		}
-	}
-
-	if do.db != 0 {
-		if _, err := c.Do("SELECT", do.db); err != nil {
-			netConn.Close()
-			return nil, err
-		}
-	}
-
-	return c, nil
-}
-
-var pathDBRegexp = regexp.MustCompile(`/(\d*)\z`)
-
-// DialURL connects to a Redis server at the given URL using the Redis
-// URI scheme. URLs should follow the draft IANA specification for the
-// scheme (https://www.iana.org/assignments/uri-schemes/prov/redis).
-func DialURL(rawurl string, options ...DialOption) (Conn, error) {
-	u, err := url.Parse(rawurl)
-	if err != nil {
-		return nil, err
-	}
-
-	if u.Scheme != "redis" && u.Scheme != "rediss" {
-		return nil, fmt.Errorf("invalid redis URL scheme: %s", u.Scheme)
-	}
-
-	if u.Opaque != "" {
-		return nil, fmt.Errorf("invalid redis URL, url is opaque: %s", rawurl)
-	}
-
-	// As per the IANA draft spec, the host defaults to localhost and
-	// the port defaults to 6379.
-	host, port, err := net.SplitHostPort(u.Host)
-	if err != nil {
-		// assume port is missing
-		host = u.Host
-		port = "6379"
-	}
-	if host == "" {
-		host = "localhost"
-	}
-	address := net.JoinHostPort(host, port)
-
-	if u.User != nil {
-		password, isSet := u.User.Password()
-		if isSet {
-			options = append(options, DialPassword(password))
-		}
-	}
-
-	match := pathDBRegexp.FindStringSubmatch(u.Path)
-	if len(match) == 2 {
-		db := 0
-		if len(match[1]) > 0 {
-			db, err = strconv.Atoi(match[1])
-			if err != nil {
-				return nil, fmt.Errorf("invalid database: %s", u.Path[1:])
-			}
-		}
-		if db != 0 {
-			options = append(options, DialDatabase(db))
-		}
-	} else if u.Path != "" {
-		return nil, fmt.Errorf("invalid database: %s", u.Path[1:])
-	}
-
-	options = append(options, DialUseTLS(u.Scheme == "rediss"))
-
-	return Dial("tcp", address, options...)
-}
-
-// NewConn returns a new Redigo connection for the given net connection.
-func NewConn(netConn net.Conn, readTimeout, writeTimeout time.Duration) Conn {
-	return &conn{
-		conn:         netConn,
-		bw:           bufio.NewWriter(netConn),
-		br:           bufio.NewReader(netConn),
-		readTimeout:  readTimeout,
-		writeTimeout: writeTimeout,
-	}
-}
-
-func (c *conn) Close() error {
-	c.mu.Lock()
-	err := c.err
-	if c.err == nil {
-		c.err = errors.New("redigo: closed")
-		err = c.conn.Close()
-	}
-	c.mu.Unlock()
-	return err
-}
-
-func (c *conn) fatal(err error) error {
-	c.mu.Lock()
-	if c.err == nil {
-		c.err = err
-		// Close connection to force errors on subsequent calls and to unblock
-		// other reader or writer.
-		c.conn.Close()
-	}
-	c.mu.Unlock()
-	return err
-}
-
-func (c *conn) Err() error {
-	c.mu.Lock()
-	err := c.err
-	c.mu.Unlock()
-	return err
-}
-
-func (c *conn) writeLen(prefix byte, n int) error {
-	c.lenScratch[len(c.lenScratch)-1] = '\n'
-	c.lenScratch[len(c.lenScratch)-2] = '\r'
-	i := len(c.lenScratch) - 3
-	for {
-		c.lenScratch[i] = byte('0' + n%10)
-		i -= 1
-		n = n / 10
-		if n == 0 {
-			break
-		}
-	}
-	c.lenScratch[i] = prefix
-	_, err := c.bw.Write(c.lenScratch[i:])
-	return err
-}
-
-func (c *conn) writeString(s string) error {
-	c.writeLen('$', len(s))
-	c.bw.WriteString(s)
-	_, err := c.bw.WriteString("\r\n")
-	return err
-}
-
-func (c *conn) writeBytes(p []byte) error {
-	c.writeLen('$', len(p))
-	c.bw.Write(p)
-	_, err := c.bw.WriteString("\r\n")
-	return err
-}
-
-func (c *conn) writeInt64(n int64) error {
-	return c.writeBytes(strconv.AppendInt(c.numScratch[:0], n, 10))
-}
-
-func (c *conn) writeFloat64(n float64) error {
-	return c.writeBytes(strconv.AppendFloat(c.numScratch[:0], n, 'g', -1, 64))
-}
-
-func (c *conn) writeCommand(cmd string, args []interface{}) error {
-	c.writeLen('*', 1+len(args))
-	if err := c.writeString(cmd); err != nil {
-		return err
-	}
-	for _, arg := range args {
-		if err := c.writeArg(arg, true); err != nil {
-			return err
-		}
-	}
-	return nil
-}
-
-func (c *conn) writeArg(arg interface{}, argumentTypeOK bool) (err error) {
-	switch arg := arg.(type) {
-	case string:
-		return c.writeString(arg)
-	case []byte:
-		return c.writeBytes(arg)
-	case int:
-		return c.writeInt64(int64(arg))
-	case int64:
-		return c.writeInt64(arg)
-	case float64:
-		return c.writeFloat64(arg)
-	case bool:
-		if arg {
-			return c.writeString("1")
-		} else {
-			return c.writeString("0")
-		}
-	case nil:
-		return c.writeString("")
-	case Argument:
-		if argumentTypeOK {
-			return c.writeArg(arg.RedisArg(), false)
-		}
-		// See comment in default clause below.
-		var buf bytes.Buffer
-		fmt.Fprint(&buf, arg)
-		return c.writeBytes(buf.Bytes())
-	default:
-		// This default clause is intended to handle builtin numeric types.
-		// The function should return an error for other types, but this is not
-		// done for compatibility with previous versions of the package.
-		var buf bytes.Buffer
-		fmt.Fprint(&buf, arg)
-		return c.writeBytes(buf.Bytes())
-	}
-}
-
-type protocolError string
-
-func (pe protocolError) Error() string {
-	return fmt.Sprintf("redigo: %s (possible server error or unsupported concurrent read by application)", string(pe))
-}
-
-// readLine reads a line of input from the RESP stream.
-func (c *conn) readLine() ([]byte, error) {
-	// To avoid allocations, attempt to read the line using ReadSlice. This
-	// call typically succeeds. The known case where the call fails is when
-	// reading the output from the MONITOR command.
-	p, err := c.br.ReadSlice('\n')
-	if err == bufio.ErrBufferFull {
-		// The line does not fit in the bufio.Reader's buffer. Fall back to
-		// allocating a buffer for the line.
-		buf := append([]byte{}, p...)
-		for err == bufio.ErrBufferFull {
-			p, err = c.br.ReadSlice('\n')
-			buf = append(buf, p...)
-		}
-		p = buf
-	}
-	if err != nil {
-		return nil, err
-	}
-	i := len(p) - 2
-	if i < 0 || p[i] != '\r' {
-		return nil, protocolError("bad response line terminator")
-	}
-	return p[:i], nil
-}
-
-// parseLen parses bulk string and array lengths.
-func parseLen(p []byte) (int, error) {
-	if len(p) == 0 {
-		return -1, protocolError("malformed length")
-	}
-
-	if p[0] == '-' && len(p) == 2 && p[1] == '1' {
-		// handle $-1 and $-1 null replies.
-		return -1, nil
-	}
-
-	var n int
-	for _, b := range p {
-		n *= 10
-		if b < '0' || b > '9' {
-			return -1, protocolError("illegal bytes in length")
-		}
-		n += int(b - '0')
-	}
-
-	return n, nil
-}
-
-// parseInt parses an integer reply.
-func parseInt(p []byte) (interface{}, error) {
-	if len(p) == 0 {
-		return 0, protocolError("malformed integer")
-	}
-
-	var negate bool
-	if p[0] == '-' {
-		negate = true
-		p = p[1:]
-		if len(p) == 0 {
-			return 0, protocolError("malformed integer")
-		}
-	}
-
-	var n int64
-	for _, b := range p {
-		n *= 10
-		if b < '0' || b > '9' {
-			return 0, protocolError("illegal bytes in length")
-		}
-		n += int64(b - '0')
-	}
-
-	if negate {
-		n = -n
-	}
-	return n, nil
-}
-
-var (
-	okReply   interface{} = "OK"
-	pongReply interface{} = "PONG"
-)
-
-func (c *conn) readReply() (interface{}, error) {
-	line, err := c.readLine()
-	if err != nil {
-		return nil, err
-	}
-	if len(line) == 0 {
-		return nil, protocolError("short response line")
-	}
-	switch line[0] {
-	case '+':
-		switch {
-		case len(line) == 3 && line[1] == 'O' && line[2] == 'K':
-			// Avoid allocation for frequent "+OK" response.
-			return okReply, nil
-		case len(line) == 5 && line[1] == 'P' && line[2] == 'O' && line[3] == 'N' && line[4] == 'G':
-			// Avoid allocation in PING command benchmarks :)
-			return pongReply, nil
-		default:
-			return string(line[1:]), nil
-		}
-	case '-':
-		return Error(string(line[1:])), nil
-	case ':':
-		return parseInt(line[1:])
-	case '$':
-		n, err := parseLen(line[1:])
-		if n < 0 || err != nil {
-			return nil, err
-		}
-		p := make([]byte, n)
-		_, err = io.ReadFull(c.br, p)
-		if err != nil {
-			return nil, err
-		}
-		if line, err := c.readLine(); err != nil {
-			return nil, err
-		} else if len(line) != 0 {
-			return nil, protocolError("bad bulk string format")
-		}
-		return p, nil
-	case '*':
-		n, err := parseLen(line[1:])
-		if n < 0 || err != nil {
-			return nil, err
-		}
-		r := make([]interface{}, n)
-		for i := range r {
-			r[i], err = c.readReply()
-			if err != nil {
-				return nil, err
-			}
-		}
-		return r, nil
-	}
-	return nil, protocolError("unexpected response line")
-}
-
-func (c *conn) Send(cmd string, args ...interface{}) error {
-	c.mu.Lock()
-	c.pending += 1
-	c.mu.Unlock()
-	if c.writeTimeout != 0 {
-		c.conn.SetWriteDeadline(time.Now().Add(c.writeTimeout))
-	}
-	if err := c.writeCommand(cmd, args); err != nil {
-		return c.fatal(err)
-	}
-	return nil
-}
-
-func (c *conn) Flush() error {
-	if c.writeTimeout != 0 {
-		c.conn.SetWriteDeadline(time.Now().Add(c.writeTimeout))
-	}
-	if err := c.bw.Flush(); err != nil {
-		return c.fatal(err)
-	}
-	return nil
-}
-
-func (c *conn) Receive() (interface{}, error) {
-	return c.ReceiveWithTimeout(c.readTimeout)
-}
-
-func (c *conn) ReceiveWithTimeout(timeout time.Duration) (reply interface{}, err error) {
-	var deadline time.Time
-	if timeout != 0 {
-		deadline = time.Now().Add(timeout)
-	}
-	c.conn.SetReadDeadline(deadline)
-
-	if reply, err = c.readReply(); err != nil {
-		return nil, c.fatal(err)
-	}
-	// When using pub/sub, the number of receives can be greater than the
-	// number of sends. To enable normal use of the connection after
-	// unsubscribing from all channels, we do not decrement pending to a
-	// negative value.
-	//
-	// The pending field is decremented after the reply is read to handle the
-	// case where Receive is called before Send.
-	c.mu.Lock()
-	if c.pending > 0 {
-		c.pending -= 1
-	}
-	c.mu.Unlock()
-	if err, ok := reply.(Error); ok {
-		return nil, err
-	}
-	return
-}
-
-func (c *conn) Do(cmd string, args ...interface{}) (interface{}, error) {
-	return c.DoWithTimeout(c.readTimeout, cmd, args...)
-}
-
-func (c *conn) DoWithTimeout(readTimeout time.Duration, cmd string, args ...interface{}) (interface{}, error) {
-	c.mu.Lock()
-	pending := c.pending
-	c.pending = 0
-	c.mu.Unlock()
-
-	if cmd == "" && pending == 0 {
-		return nil, nil
-	}
-
-	if c.writeTimeout != 0 {
-		c.conn.SetWriteDeadline(time.Now().Add(c.writeTimeout))
-	}
-
-	if cmd != "" {
-		if err := c.writeCommand(cmd, args); err != nil {
-			return nil, c.fatal(err)
-		}
-	}
-
-	if err := c.bw.Flush(); err != nil {
-		return nil, c.fatal(err)
-	}
-
-	var deadline time.Time
-	if readTimeout != 0 {
-		deadline = time.Now().Add(readTimeout)
-	}
-	c.conn.SetReadDeadline(deadline)
-
-	if cmd == "" {
-		reply := make([]interface{}, pending)
-		for i := range reply {
-			r, e := c.readReply()
-			if e != nil {
-				return nil, c.fatal(e)
-			}
-			reply[i] = r
-		}
-		return reply, nil
-	}
-
-	var err error
-	var reply interface{}
-	for i := 0; i <= pending; i++ {
-		var e error
-		if reply, e = c.readReply(); e != nil {
-			return nil, c.fatal(e)
-		}
-		if e, ok := reply.(Error); ok && err == nil {
-			err = e
-		}
-	}
-	return reply, err
-}

+ 0 - 946
src/github.com/gomodule/redigo/redis/conn_test.go

@@ -1,946 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package redis_test
-
-import (
-	"bytes"
-	"crypto/tls"
-	"crypto/x509"
-	"fmt"
-	"io"
-	"math"
-	"net"
-	"os"
-	"reflect"
-	"strings"
-	"testing"
-	"time"
-
-	"github.com/gomodule/redigo/redis"
-)
-
-type testConn struct {
-	io.Reader
-	io.Writer
-	readDeadline  time.Time
-	writeDeadline time.Time
-}
-
-func (*testConn) Close() error                         { return nil }
-func (*testConn) LocalAddr() net.Addr                  { return nil }
-func (*testConn) RemoteAddr() net.Addr                 { return nil }
-func (c *testConn) SetDeadline(t time.Time) error      { c.readDeadline = t; c.writeDeadline = t; return nil }
-func (c *testConn) SetReadDeadline(t time.Time) error  { c.readDeadline = t; return nil }
-func (c *testConn) SetWriteDeadline(t time.Time) error { c.writeDeadline = t; return nil }
-
-func dialTestConn(r string, w io.Writer) redis.DialOption {
-	return redis.DialNetDial(func(network, addr string) (net.Conn, error) {
-		return &testConn{Reader: strings.NewReader(r), Writer: w}, nil
-	})
-}
-
-type tlsTestConn struct {
-	net.Conn
-	done chan struct{}
-}
-
-func (c *tlsTestConn) Close() error {
-	c.Conn.Close()
-	<-c.done
-	return nil
-}
-
-func dialTestConnTLS(r string, w io.Writer) redis.DialOption {
-	return redis.DialNetDial(func(network, addr string) (net.Conn, error) {
-		client, server := net.Pipe()
-		tlsServer := tls.Server(server, &serverTLSConfig)
-		go io.Copy(tlsServer, strings.NewReader(r))
-		done := make(chan struct{})
-		go func() {
-			io.Copy(w, tlsServer)
-			close(done)
-		}()
-		return &tlsTestConn{Conn: client, done: done}, nil
-	})
-}
-
-type durationArg struct {
-	time.Duration
-}
-
-func (t durationArg) RedisArg() interface{} {
-	return t.Seconds()
-}
-
-type recursiveArg int
-
-func (v recursiveArg) RedisArg() interface{} { return v }
-
-var writeTests = []struct {
-	args     []interface{}
-	expected string
-}{
-	{
-		[]interface{}{"SET", "key", "value"},
-		"*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$5\r\nvalue\r\n",
-	},
-	{
-		[]interface{}{"SET", "key", "value"},
-		"*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$5\r\nvalue\r\n",
-	},
-	{
-		[]interface{}{"SET", "key", byte(100)},
-		"*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$3\r\n100\r\n",
-	},
-	{
-		[]interface{}{"SET", "key", 100},
-		"*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$3\r\n100\r\n",
-	},
-	{
-		[]interface{}{"SET", "key", int64(math.MinInt64)},
-		"*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$20\r\n-9223372036854775808\r\n",
-	},
-	{
-		[]interface{}{"SET", "key", float64(1349673917.939762)},
-		"*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$21\r\n1.349673917939762e+09\r\n",
-	},
-	{
-		[]interface{}{"SET", "key", ""},
-		"*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$0\r\n\r\n",
-	},
-	{
-		[]interface{}{"SET", "key", nil},
-		"*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$0\r\n\r\n",
-	},
-	{
-		[]interface{}{"SET", "key", durationArg{time.Minute}},
-		"*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$2\r\n60\r\n",
-	},
-	{
-		[]interface{}{"SET", "key", recursiveArg(123)},
-		"*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$3\r\n123\r\n",
-	},
-	{
-		[]interface{}{"ECHO", true, false},
-		"*3\r\n$4\r\nECHO\r\n$1\r\n1\r\n$1\r\n0\r\n",
-	},
-}
-
-func TestWrite(t *testing.T) {
-	for _, tt := range writeTests {
-		var buf bytes.Buffer
-		c, _ := redis.Dial("", "", dialTestConn("", &buf))
-		err := c.Send(tt.args[0].(string), tt.args[1:]...)
-		if err != nil {
-			t.Errorf("Send(%v) returned error %v", tt.args, err)
-			continue
-		}
-		c.Flush()
-		actual := buf.String()
-		if actual != tt.expected {
-			t.Errorf("Send(%v) = %q, want %q", tt.args, actual, tt.expected)
-		}
-	}
-}
-
-var errorSentinel = &struct{}{}
-
-var readTests = []struct {
-	reply    string
-	expected interface{}
-}{
-	{
-		"+OK\r\n",
-		"OK",
-	},
-	{
-		"+PONG\r\n",
-		"PONG",
-	},
-	{
-		"+OK\n\n", // no \r
-		errorSentinel,
-	},
-	{
-		"@OK\r\n",
-		errorSentinel,
-	},
-	{
-		"$6\r\nfoobar\r\n",
-		[]byte("foobar"),
-	},
-	{
-		"$-1\r\n",
-		nil,
-	},
-	{
-		":1\r\n",
-		int64(1),
-	},
-	{
-		":-2\r\n",
-		int64(-2),
-	},
-	{
-		"*0\r\n",
-		[]interface{}{},
-	},
-	{
-		"*-1\r\n",
-		nil,
-	},
-	{
-		"*4\r\n$3\r\nfoo\r\n$3\r\nbar\r\n$5\r\nHello\r\n$5\r\nWorld\r\n",
-		[]interface{}{[]byte("foo"), []byte("bar"), []byte("Hello"), []byte("World")},
-	},
-	{
-		"*3\r\n$3\r\nfoo\r\n$-1\r\n$3\r\nbar\r\n",
-		[]interface{}{[]byte("foo"), nil, []byte("bar")},
-	},
-
-	{
-		// "" is not a valid length
-		"$\r\nfoobar\r\n",
-		errorSentinel,
-	},
-	{
-		// "x" is not a valid length
-		"$x\r\nfoobar\r\n",
-		errorSentinel,
-	},
-	{
-		// -2 is not a valid length
-		"$-2\r\n",
-		errorSentinel,
-	},
-	{
-		// ""  is not a valid integer
-		":\r\n",
-		errorSentinel,
-	},
-	{
-		// "x"  is not a valid integer
-		":x\r\n",
-		errorSentinel,
-	},
-	{
-		// missing \r\n following value
-		"$6\r\nfoobar",
-		errorSentinel,
-	},
-	{
-		// short value
-		"$6\r\nxx",
-		errorSentinel,
-	},
-	{
-		// long value
-		"$6\r\nfoobarx\r\n",
-		errorSentinel,
-	},
-}
-
-func TestRead(t *testing.T) {
-	for _, tt := range readTests {
-		c, _ := redis.Dial("", "", dialTestConn(tt.reply, nil))
-		actual, err := c.Receive()
-		if tt.expected == errorSentinel {
-			if err == nil {
-				t.Errorf("Receive(%q) did not return expected error", tt.reply)
-			}
-		} else {
-			if err != nil {
-				t.Errorf("Receive(%q) returned error %v", tt.reply, err)
-				continue
-			}
-			if !reflect.DeepEqual(actual, tt.expected) {
-				t.Errorf("Receive(%q) = %v, want %v", tt.reply, actual, tt.expected)
-			}
-		}
-	}
-}
-
-func TestReadString(t *testing.T) {
-	// n is value of bufio.defaultBufSize
-	const n = 4096
-
-	// Test read string lengths near bufio.Reader buffer boundaries.
-	testRanges := [][2]int{{0, 64}, {n - 64, n + 64}, {2*n - 64, 2*n + 64}}
-
-	p := make([]byte, 2*n+64)
-	for i := range p {
-		p[i] = byte('a' + i%26)
-	}
-	s := string(p)
-
-	for _, r := range testRanges {
-		for i := r[0]; i < r[1]; i++ {
-			c, _ := redis.Dial("", "", dialTestConn("+"+s[:i]+"\r\n", nil))
-			actual, err := c.Receive()
-			if err != nil || actual != s[:i] {
-				t.Fatalf("Receive(string len %d) -> err=%v, equal=%v", i, err, actual != s[:i])
-			}
-		}
-	}
-}
-
-var testCommands = []struct {
-	args     []interface{}
-	expected interface{}
-}{
-	{
-		[]interface{}{"PING"},
-		"PONG",
-	},
-	{
-		[]interface{}{"SET", "foo", "bar"},
-		"OK",
-	},
-	{
-		[]interface{}{"GET", "foo"},
-		[]byte("bar"),
-	},
-	{
-		[]interface{}{"GET", "nokey"},
-		nil,
-	},
-	{
-		[]interface{}{"MGET", "nokey", "foo"},
-		[]interface{}{nil, []byte("bar")},
-	},
-	{
-		[]interface{}{"INCR", "mycounter"},
-		int64(1),
-	},
-	{
-		[]interface{}{"LPUSH", "mylist", "foo"},
-		int64(1),
-	},
-	{
-		[]interface{}{"LPUSH", "mylist", "bar"},
-		int64(2),
-	},
-	{
-		[]interface{}{"LRANGE", "mylist", 0, -1},
-		[]interface{}{[]byte("bar"), []byte("foo")},
-	},
-	{
-		[]interface{}{"MULTI"},
-		"OK",
-	},
-	{
-		[]interface{}{"LRANGE", "mylist", 0, -1},
-		"QUEUED",
-	},
-	{
-		[]interface{}{"PING"},
-		"QUEUED",
-	},
-	{
-		[]interface{}{"EXEC"},
-		[]interface{}{
-			[]interface{}{[]byte("bar"), []byte("foo")},
-			"PONG",
-		},
-	},
-}
-
-func TestDoCommands(t *testing.T) {
-	c, err := redis.DialDefaultServer()
-	if err != nil {
-		t.Fatalf("error connection to database, %v", err)
-	}
-	defer c.Close()
-
-	for _, cmd := range testCommands {
-		actual, err := c.Do(cmd.args[0].(string), cmd.args[1:]...)
-		if err != nil {
-			t.Errorf("Do(%v) returned error %v", cmd.args, err)
-			continue
-		}
-		if !reflect.DeepEqual(actual, cmd.expected) {
-			t.Errorf("Do(%v) = %v, want %v", cmd.args, actual, cmd.expected)
-		}
-	}
-}
-
-func TestPipelineCommands(t *testing.T) {
-	c, err := redis.DialDefaultServer()
-	if err != nil {
-		t.Fatalf("error connection to database, %v", err)
-	}
-	defer c.Close()
-
-	for _, cmd := range testCommands {
-		if err := c.Send(cmd.args[0].(string), cmd.args[1:]...); err != nil {
-			t.Fatalf("Send(%v) returned error %v", cmd.args, err)
-		}
-	}
-	if err := c.Flush(); err != nil {
-		t.Errorf("Flush() returned error %v", err)
-	}
-	for _, cmd := range testCommands {
-		actual, err := c.Receive()
-		if err != nil {
-			t.Fatalf("Receive(%v) returned error %v", cmd.args, err)
-		}
-		if !reflect.DeepEqual(actual, cmd.expected) {
-			t.Errorf("Receive(%v) = %v, want %v", cmd.args, actual, cmd.expected)
-		}
-	}
-}
-
-func TestBlankCommand(t *testing.T) {
-	c, err := redis.DialDefaultServer()
-	if err != nil {
-		t.Fatalf("error connection to database, %v", err)
-	}
-	defer c.Close()
-
-	for _, cmd := range testCommands {
-		if err := c.Send(cmd.args[0].(string), cmd.args[1:]...); err != nil {
-			t.Fatalf("Send(%v) returned error %v", cmd.args, err)
-		}
-	}
-	reply, err := redis.Values(c.Do(""))
-	if err != nil {
-		t.Fatalf("Do() returned error %v", err)
-	}
-	if len(reply) != len(testCommands) {
-		t.Fatalf("len(reply)=%d, want %d", len(reply), len(testCommands))
-	}
-	for i, cmd := range testCommands {
-		actual := reply[i]
-		if !reflect.DeepEqual(actual, cmd.expected) {
-			t.Errorf("Receive(%v) = %v, want %v", cmd.args, actual, cmd.expected)
-		}
-	}
-}
-
-func TestRecvBeforeSend(t *testing.T) {
-	c, err := redis.DialDefaultServer()
-	if err != nil {
-		t.Fatalf("error connection to database, %v", err)
-	}
-	defer c.Close()
-	done := make(chan struct{})
-	go func() {
-		c.Receive()
-		close(done)
-	}()
-	time.Sleep(time.Millisecond)
-	c.Send("PING")
-	c.Flush()
-	<-done
-	_, err = c.Do("")
-	if err != nil {
-		t.Fatalf("error=%v", err)
-	}
-}
-
-func TestError(t *testing.T) {
-	c, err := redis.DialDefaultServer()
-	if err != nil {
-		t.Fatalf("error connection to database, %v", err)
-	}
-	defer c.Close()
-
-	c.Do("SET", "key", "val")
-	_, err = c.Do("HSET", "key", "fld", "val")
-	if err == nil {
-		t.Errorf("Expected err for HSET on string key.")
-	}
-	if c.Err() != nil {
-		t.Errorf("Conn has Err()=%v, expect nil", c.Err())
-	}
-	_, err = c.Do("SET", "key", "val")
-	if err != nil {
-		t.Errorf("Do(SET, key, val) returned error %v, expected nil.", err)
-	}
-}
-
-func TestReadTimeout(t *testing.T) {
-	l, err := net.Listen("tcp", "127.0.0.1:0")
-	if err != nil {
-		t.Fatalf("net.Listen returned %v", err)
-	}
-	defer l.Close()
-
-	go func() {
-		for {
-			c, err := l.Accept()
-			if err != nil {
-				return
-			}
-			go func() {
-				time.Sleep(time.Second)
-				c.Write([]byte("+OK\r\n"))
-				c.Close()
-			}()
-		}
-	}()
-
-	// Do
-
-	c1, err := redis.Dial(l.Addr().Network(), l.Addr().String(), redis.DialReadTimeout(time.Millisecond))
-	if err != nil {
-		t.Fatalf("redis.Dial returned %v", err)
-	}
-	defer c1.Close()
-
-	_, err = c1.Do("PING")
-	if err == nil {
-		t.Fatalf("c1.Do() returned nil, expect error")
-	}
-	if c1.Err() == nil {
-		t.Fatalf("c1.Err() = nil, expect error")
-	}
-
-	// Send/Flush/Receive
-
-	c2, err := redis.Dial(l.Addr().Network(), l.Addr().String(), redis.DialReadTimeout(time.Millisecond))
-	if err != nil {
-		t.Fatalf("redis.Dial returned %v", err)
-	}
-	defer c2.Close()
-
-	c2.Send("PING")
-	c2.Flush()
-	_, err = c2.Receive()
-	if err == nil {
-		t.Fatalf("c2.Receive() returned nil, expect error")
-	}
-	if c2.Err() == nil {
-		t.Fatalf("c2.Err() = nil, expect error")
-	}
-}
-
-var dialErrors = []struct {
-	rawurl        string
-	expectedError string
-}{
-	{
-		"localhost",
-		"invalid redis URL scheme",
-	},
-	// The error message for invalid hosts is different in different
-	// versions of Go, so just check that there is an error message.
-	{
-		"redis://weird url",
-		"",
-	},
-	{
-		"redis://foo:bar:baz",
-		"",
-	},
-	{
-		"http://www.google.com",
-		"invalid redis URL scheme: http",
-	},
-	{
-		"redis://localhost:6379/abc123",
-		"invalid database: abc123",
-	},
-	{
-		"redis:foo//localhost:6379",
-		"invalid redis URL, url is opaque: redis:foo//localhost:6379",
-	},
-}
-
-func TestDialURLErrors(t *testing.T) {
-	for _, d := range dialErrors {
-		_, err := redis.DialURL(d.rawurl)
-		if err == nil || !strings.Contains(err.Error(), d.expectedError) {
-			t.Errorf("DialURL did not return expected error (expected %v to contain %s)", err, d.expectedError)
-		}
-	}
-}
-
-func TestDialURLPort(t *testing.T) {
-	checkPort := func(network, address string) (net.Conn, error) {
-		if address != "localhost:6379" {
-			t.Errorf("DialURL did not set port to 6379 by default (got %v)", address)
-		}
-		return nil, nil
-	}
-	_, err := redis.DialURL("redis://localhost", redis.DialNetDial(checkPort))
-	if err != nil {
-		t.Error("dial error:", err)
-	}
-}
-
-func TestDialURLHost(t *testing.T) {
-	checkHost := func(network, address string) (net.Conn, error) {
-		if address != "localhost:6379" {
-			t.Errorf("DialURL did not set host to localhost by default (got %v)", address)
-		}
-		return nil, nil
-	}
-	_, err := redis.DialURL("redis://:6379", redis.DialNetDial(checkHost))
-	if err != nil {
-		t.Error("dial error:", err)
-	}
-}
-
-var dialURLTests = []struct {
-	description string
-	url         string
-	r           string
-	w           string
-}{
-	{"password", "redis://x:abc123@localhost", "+OK\r\n", "*2\r\n$4\r\nAUTH\r\n$6\r\nabc123\r\n"},
-	{"database 3", "redis://localhost/3", "+OK\r\n", "*2\r\n$6\r\nSELECT\r\n$1\r\n3\r\n"},
-	{"database 99", "redis://localhost/99", "+OK\r\n", "*2\r\n$6\r\nSELECT\r\n$2\r\n99\r\n"},
-	{"no database", "redis://localhost/", "+OK\r\n", ""},
-}
-
-func TestDialURL(t *testing.T) {
-	for _, tt := range dialURLTests {
-		var buf bytes.Buffer
-		// UseTLS should be ignored in all of these tests.
-		_, err := redis.DialURL(tt.url, dialTestConn(tt.r, &buf), redis.DialUseTLS(true))
-		if err != nil {
-			t.Errorf("%s dial error: %v", tt.description, err)
-			continue
-		}
-		if w := buf.String(); w != tt.w {
-			t.Errorf("%s commands = %q, want %q", tt.description, w, tt.w)
-		}
-	}
-}
-
-func checkPingPong(t *testing.T, buf *bytes.Buffer, c redis.Conn) {
-	resp, err := c.Do("PING")
-	if err != nil {
-		t.Fatal("ping error:", err)
-	}
-	// Close connection to ensure that writes to buf are complete.
-	c.Close()
-	expected := "*1\r\n$4\r\nPING\r\n"
-	actual := buf.String()
-	if actual != expected {
-		t.Errorf("commands = %q, want %q", actual, expected)
-	}
-	if resp != "PONG" {
-		t.Errorf("resp = %v, want %v", resp, "PONG")
-	}
-}
-
-const pingResponse = "+PONG\r\n"
-
-func TestDialURLTLS(t *testing.T) {
-	var buf bytes.Buffer
-	c, err := redis.DialURL("rediss://example.com/",
-		redis.DialTLSConfig(&clientTLSConfig),
-		dialTestConnTLS(pingResponse, &buf))
-	if err != nil {
-		t.Fatal("dial error:", err)
-	}
-	checkPingPong(t, &buf, c)
-}
-
-func TestDialUseTLS(t *testing.T) {
-	var buf bytes.Buffer
-	c, err := redis.Dial("tcp", "example.com:6379",
-		redis.DialTLSConfig(&clientTLSConfig),
-		dialTestConnTLS(pingResponse, &buf),
-		redis.DialUseTLS(true))
-	if err != nil {
-		t.Fatal("dial error:", err)
-	}
-	checkPingPong(t, &buf, c)
-}
-
-func TestDialTLSSKipVerify(t *testing.T) {
-	var buf bytes.Buffer
-	c, err := redis.Dial("tcp", "example.com:6379",
-		dialTestConnTLS(pingResponse, &buf),
-		redis.DialTLSSkipVerify(true),
-		redis.DialUseTLS(true))
-	if err != nil {
-		t.Fatal("dial error:", err)
-	}
-	checkPingPong(t, &buf, c)
-}
-
-func TestDialClientName(t *testing.T) {
-	var buf bytes.Buffer
-	_, err := redis.Dial("tcp", ":6379",
-		dialTestConn(pingResponse, &buf),
-		redis.DialClientName("redis-connection"),
-	)
-	if err != nil {
-		t.Fatal("dial error:", err)
-	}
-	expected := "*3\r\n$6\r\nCLIENT\r\n$7\r\nSETNAME\r\n$16\r\nredis-connection\r\n"
-	if w := buf.String(); w != expected {
-		t.Errorf("got %q, want %q", w, expected)
-	}
-
-	// testing against a real server
-	connectionName := "test-connection"
-	c, err := redis.DialDefaultServer(redis.DialClientName(connectionName))
-	if err != nil {
-		t.Fatalf("error connection to database, %v", err)
-	}
-	defer c.Close()
-
-	v, err := c.Do("CLIENT", "GETNAME")
-	if err != nil {
-		t.Fatalf("CLIENT GETNAME returned error %v", err)
-	}
-
-	vs, err := redis.String(v, nil)
-	if err != nil {
-		t.Fatalf("String(v) returned error %v", err)
-	}
-
-	if vs != connectionName {
-		t.Fatalf("wrong connection name. Got '%s', expected '%s'", vs, connectionName)
-	}
-}
-
-// Connect to local instance of Redis running on the default port.
-func ExampleDial() {
-	c, err := redis.Dial("tcp", ":6379")
-	if err != nil {
-		// handle error
-	}
-	defer c.Close()
-}
-
-// Connect to remote instance of Redis using a URL.
-func ExampleDialURL() {
-	c, err := redis.DialURL(os.Getenv("REDIS_URL"))
-	if err != nil {
-		// handle connection error
-	}
-	defer c.Close()
-}
-
-// TextExecError tests handling of errors in a transaction. See
-// http://redis.io/topics/transactions for information on how Redis handles
-// errors in a transaction.
-func TestExecError(t *testing.T) {
-	c, err := redis.DialDefaultServer()
-	if err != nil {
-		t.Fatalf("error connection to database, %v", err)
-	}
-	defer c.Close()
-
-	// Execute commands that fail before EXEC is called.
-
-	c.Do("DEL", "k0")
-	c.Do("ZADD", "k0", 0, 0)
-	c.Send("MULTI")
-	c.Send("NOTACOMMAND", "k0", 0, 0)
-	c.Send("ZINCRBY", "k0", 0, 0)
-	v, err := c.Do("EXEC")
-	if err == nil {
-		t.Fatalf("EXEC returned values %v, expected error", v)
-	}
-
-	// Execute commands that fail after EXEC is called. The first command
-	// returns an error.
-
-	c.Do("DEL", "k1")
-	c.Do("ZADD", "k1", 0, 0)
-	c.Send("MULTI")
-	c.Send("HSET", "k1", 0, 0)
-	c.Send("ZINCRBY", "k1", 0, 0)
-	v, err = c.Do("EXEC")
-	if err != nil {
-		t.Fatalf("EXEC returned error %v", err)
-	}
-
-	vs, err := redis.Values(v, nil)
-	if err != nil {
-		t.Fatalf("Values(v) returned error %v", err)
-	}
-
-	if len(vs) != 2 {
-		t.Fatalf("len(vs) == %d, want 2", len(vs))
-	}
-
-	if _, ok := vs[0].(error); !ok {
-		t.Fatalf("first result is type %T, expected error", vs[0])
-	}
-
-	if _, ok := vs[1].([]byte); !ok {
-		t.Fatalf("second result is type %T, expected []byte", vs[1])
-	}
-
-	// Execute commands that fail after EXEC is called. The second command
-	// returns an error.
-
-	c.Do("ZADD", "k2", 0, 0)
-	c.Send("MULTI")
-	c.Send("ZINCRBY", "k2", 0, 0)
-	c.Send("HSET", "k2", 0, 0)
-	v, err = c.Do("EXEC")
-	if err != nil {
-		t.Fatalf("EXEC returned error %v", err)
-	}
-
-	vs, err = redis.Values(v, nil)
-	if err != nil {
-		t.Fatalf("Values(v) returned error %v", err)
-	}
-
-	if len(vs) != 2 {
-		t.Fatalf("len(vs) == %d, want 2", len(vs))
-	}
-
-	if _, ok := vs[0].([]byte); !ok {
-		t.Fatalf("first result is type %T, expected []byte", vs[0])
-	}
-
-	if _, ok := vs[1].(error); !ok {
-		t.Fatalf("second result is type %T, expected error", vs[2])
-	}
-}
-
-func BenchmarkDoEmpty(b *testing.B) {
-	b.StopTimer()
-	c, err := redis.DialDefaultServer()
-	if err != nil {
-		b.Fatal(err)
-	}
-	defer c.Close()
-	b.StartTimer()
-	for i := 0; i < b.N; i++ {
-		if _, err := c.Do(""); err != nil {
-			b.Fatal(err)
-		}
-	}
-}
-
-func BenchmarkDoPing(b *testing.B) {
-	b.StopTimer()
-	c, err := redis.DialDefaultServer()
-	if err != nil {
-		b.Fatal(err)
-	}
-	defer c.Close()
-	b.StartTimer()
-	for i := 0; i < b.N; i++ {
-		if _, err := c.Do("PING"); err != nil {
-			b.Fatal(err)
-		}
-	}
-}
-
-var clientTLSConfig, serverTLSConfig tls.Config
-
-func init() {
-	// The certificate and key for testing TLS dial options was created
-	// using the command
-	//
-	//   go run GOROOT/src/crypto/tls/generate_cert.go  \
-	//      --rsa-bits 1024 \
-	//      --host 127.0.0.1,::1,example.com --ca \
-	//      --start-date "Jan 1 00:00:00 1970" \
-	//      --duration=1000000h
-	//
-	// where GOROOT is the value of GOROOT reported by go env.
-	localhostCert := []byte(`
------BEGIN CERTIFICATE-----
-MIICFDCCAX2gAwIBAgIRAJfBL4CUxkXcdlFurb3K+iowDQYJKoZIhvcNAQELBQAw
-EjEQMA4GA1UEChMHQWNtZSBDbzAgFw03MDAxMDEwMDAwMDBaGA8yMDg0MDEyOTE2
-MDAwMFowEjEQMA4GA1UEChMHQWNtZSBDbzCBnzANBgkqhkiG9w0BAQEFAAOBjQAw
-gYkCgYEArizw8WxMUQ3bGHLeuJ4fDrEpy+L2pqrbYRlKk1DasJ/VkB8bImzIpe6+
-LGjiYIxvnDCOJ3f3QplcQuiuMyl6f2irJlJsbFT8Lo/3obnuTKAIaqUdJUqBg6y+
-JaL8Auk97FvunfKFv8U1AIhgiLzAfQ/3Eaq1yi87Ra6pMjGbTtcCAwEAAaNoMGYw
-DgYDVR0PAQH/BAQDAgKkMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA8GA1UdEwEB/wQF
-MAMBAf8wLgYDVR0RBCcwJYILZXhhbXBsZS5jb22HBH8AAAGHEAAAAAAAAAAAAAAA
-AAAAAAEwDQYJKoZIhvcNAQELBQADgYEAdZ8daIVkyhVwflt5I19m0oq1TycbGO1+
-ach7T6cZiBQeNR/SJtxr/wKPEpmvUgbv2BfFrKJ8QoIHYsbNSURTWSEa02pfw4k9
-6RQhij3ZkG79Ituj5OYRORV6Z0HUW32r670BtcuHuAhq7YA6Nxy4FtSt7bAlVdRt
-rrKgNsltzMk=
------END CERTIFICATE-----`)
-
-	localhostKey := []byte(`
------BEGIN RSA PRIVATE KEY-----
-MIICXAIBAAKBgQCuLPDxbExRDdsYct64nh8OsSnL4vamqtthGUqTUNqwn9WQHxsi
-bMil7r4saOJgjG+cMI4nd/dCmVxC6K4zKXp/aKsmUmxsVPwuj/ehue5MoAhqpR0l
-SoGDrL4lovwC6T3sW+6d8oW/xTUAiGCIvMB9D/cRqrXKLztFrqkyMZtO1wIDAQAB
-AoGACrc5G6FOEK6JjDeE/Fa+EmlT6PdNtXNNi+vCas3Opo8u1G8VfEi1D4BgstrB
-Eq+RLkrOdB8tVyuYQYWPMhabMqF+hhKJN72j0OwfuPlVvTInwb/cKjo/zbH1IA+Y
-HenHNK4ywv7/p/9/MvQPJ3I32cQBCgGUW5chVSH5M1sj5gECQQDabQAI1X0uDqCm
-KbX9gXVkAgxkFddrt6LBHt57xujFcqEKFE7nwKhDh7DweVs/VEJ+kpid4z+UnLOw
-KjtP9JolAkEAzCNBphQ//IsbH5rNs10wIUw3Ks/Oepicvr6kUFbIv+neRzi1iJHa
-m6H7EayK3PWgax6BAsR/t0Jc9XV7r2muSwJAVzN09BHnK+ADGtNEKLTqXMbEk6B0
-pDhn7ZmZUOkUPN+Kky+QYM11X6Bob1jDqQDGmymDbGUxGO+GfSofC8inUQJAGfci
-Eo3g1a6b9JksMPRZeuLG4ZstGErxJRH6tH1Va5PDwitka8qhk8o2tTjNMO3NSdLH
-diKoXBcE2/Pll5pJoQJBAIMiiMIzXJhnN4mX8may44J/HvMlMf2xuVH2gNMwmZuc
-Bjqn3yoLHaoZVvbWOi0C2TCN4FjXjaLNZGifQPbIcaA=
------END RSA PRIVATE KEY-----`)
-
-	cert, err := tls.X509KeyPair(localhostCert, localhostKey)
-	if err != nil {
-		panic(fmt.Sprintf("error creating key pair: %v", err))
-	}
-	serverTLSConfig.Certificates = []tls.Certificate{cert}
-
-	certificate, err := x509.ParseCertificate(serverTLSConfig.Certificates[0].Certificate[0])
-	if err != nil {
-		panic(fmt.Sprintf("error parsing x509 certificate: %v", err))
-	}
-
-	clientTLSConfig.RootCAs = x509.NewCertPool()
-	clientTLSConfig.RootCAs.AddCert(certificate)
-}
-
-func TestWithTimeout(t *testing.T) {
-	for _, recv := range []bool{true, false} {
-		for _, defaultTimout := range []time.Duration{0, time.Minute} {
-			var buf bytes.Buffer
-			nc := &testConn{Reader: strings.NewReader("+OK\r\n+OK\r\n+OK\r\n+OK\r\n+OK\r\n+OK\r\n+OK\r\n+OK\r\n+OK\r\n+OK\r\n"), Writer: &buf}
-			c, _ := redis.Dial("", "", redis.DialReadTimeout(defaultTimout), redis.DialNetDial(func(network, addr string) (net.Conn, error) { return nc, nil }))
-			for i := 0; i < 4; i++ {
-				var minDeadline, maxDeadline time.Time
-
-				// Alternate between default and specified timeout.
-				if i%2 == 0 {
-					if defaultTimout != 0 {
-						minDeadline = time.Now().Add(defaultTimout)
-					}
-					if recv {
-						c.Receive()
-					} else {
-						c.Do("PING")
-					}
-					if defaultTimout != 0 {
-						maxDeadline = time.Now().Add(defaultTimout)
-					}
-				} else {
-					timeout := 10 * time.Minute
-					minDeadline = time.Now().Add(timeout)
-					if recv {
-						redis.ReceiveWithTimeout(c, timeout)
-					} else {
-						redis.DoWithTimeout(c, timeout, "PING")
-					}
-					maxDeadline = time.Now().Add(timeout)
-				}
-
-				// Expect set deadline in expected range.
-				if nc.readDeadline.Before(minDeadline) || nc.readDeadline.After(maxDeadline) {
-					t.Errorf("recv %v, %d: do deadline error: %v, %v, %v", recv, i, minDeadline, nc.readDeadline, maxDeadline)
-				}
-			}
-		}
-	}
-}

+ 0 - 177
src/github.com/gomodule/redigo/redis/doc.go

@@ -1,177 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-// Package redis is a client for the Redis database.
-//
-// The Redigo FAQ (https://github.com/gomodule/redigo/wiki/FAQ) contains more
-// documentation about this package.
-//
-// Connections
-//
-// The Conn interface is the primary interface for working with Redis.
-// Applications create connections by calling the Dial, DialWithTimeout or
-// NewConn functions. In the future, functions will be added for creating
-// sharded and other types of connections.
-//
-// The application must call the connection Close method when the application
-// is done with the connection.
-//
-// Executing Commands
-//
-// The Conn interface has a generic method for executing Redis commands:
-//
-//  Do(commandName string, args ...interface{}) (reply interface{}, err error)
-//
-// The Redis command reference (http://redis.io/commands) lists the available
-// commands. An example of using the Redis APPEND command is:
-//
-//  n, err := conn.Do("APPEND", "key", "value")
-//
-// The Do method converts command arguments to bulk strings for transmission
-// to the server as follows:
-//
-//  Go Type                 Conversion
-//  []byte                  Sent as is
-//  string                  Sent as is
-//  int, int64              strconv.FormatInt(v)
-//  float64                 strconv.FormatFloat(v, 'g', -1, 64)
-//  bool                    true -> "1", false -> "0"
-//  nil                     ""
-//  all other types         fmt.Fprint(w, v)
-//
-// Redis command reply types are represented using the following Go types:
-//
-//  Redis type              Go type
-//  error                   redis.Error
-//  integer                 int64
-//  simple string           string
-//  bulk string             []byte or nil if value not present.
-//  array                   []interface{} or nil if value not present.
-//
-// Use type assertions or the reply helper functions to convert from
-// interface{} to the specific Go type for the command result.
-//
-// Pipelining
-//
-// Connections support pipelining using the Send, Flush and Receive methods.
-//
-//  Send(commandName string, args ...interface{}) error
-//  Flush() error
-//  Receive() (reply interface{}, err error)
-//
-// Send writes the command to the connection's output buffer. Flush flushes the
-// connection's output buffer to the server. Receive reads a single reply from
-// the server. The following example shows a simple pipeline.
-//
-//  c.Send("SET", "foo", "bar")
-//  c.Send("GET", "foo")
-//  c.Flush()
-//  c.Receive() // reply from SET
-//  v, err = c.Receive() // reply from GET
-//
-// The Do method combines the functionality of the Send, Flush and Receive
-// methods. The Do method starts by writing the command and flushing the output
-// buffer. Next, the Do method receives all pending replies including the reply
-// for the command just sent by Do. If any of the received replies is an error,
-// then Do returns the error. If there are no errors, then Do returns the last
-// reply. If the command argument to the Do method is "", then the Do method
-// will flush the output buffer and receive pending replies without sending a
-// command.
-//
-// Use the Send and Do methods to implement pipelined transactions.
-//
-//  c.Send("MULTI")
-//  c.Send("INCR", "foo")
-//  c.Send("INCR", "bar")
-//  r, err := c.Do("EXEC")
-//  fmt.Println(r) // prints [1, 1]
-//
-// Concurrency
-//
-// Connections support one concurrent caller to the Receive method and one
-// concurrent caller to the Send and Flush methods. No other concurrency is
-// supported including concurrent calls to the Do and Close methods.
-//
-// For full concurrent access to Redis, use the thread-safe Pool to get, use
-// and release a connection from within a goroutine. Connections returned from
-// a Pool have the concurrency restrictions described in the previous
-// paragraph.
-//
-// Publish and Subscribe
-//
-// Use the Send, Flush and Receive methods to implement Pub/Sub subscribers.
-//
-//  c.Send("SUBSCRIBE", "example")
-//  c.Flush()
-//  for {
-//      reply, err := c.Receive()
-//      if err != nil {
-//          return err
-//      }
-//      // process pushed message
-//  }
-//
-// The PubSubConn type wraps a Conn with convenience methods for implementing
-// subscribers. The Subscribe, PSubscribe, Unsubscribe and PUnsubscribe methods
-// send and flush a subscription management command. The receive method
-// converts a pushed message to convenient types for use in a type switch.
-//
-//  psc := redis.PubSubConn{Conn: c}
-//  psc.Subscribe("example")
-//  for {
-//      switch v := psc.Receive().(type) {
-//      case redis.Message:
-//          fmt.Printf("%s: message: %s\n", v.Channel, v.Data)
-//      case redis.Subscription:
-//          fmt.Printf("%s: %s %d\n", v.Channel, v.Kind, v.Count)
-//      case error:
-//          return v
-//      }
-//  }
-//
-// Reply Helpers
-//
-// The Bool, Int, Bytes, String, Strings and Values functions convert a reply
-// to a value of a specific type. To allow convenient wrapping of calls to the
-// connection Do and Receive methods, the functions take a second argument of
-// type error.  If the error is non-nil, then the helper function returns the
-// error. If the error is nil, the function converts the reply to the specified
-// type:
-//
-//  exists, err := redis.Bool(c.Do("EXISTS", "foo"))
-//  if err != nil {
-//      // handle error return from c.Do or type conversion error.
-//  }
-//
-// The Scan function converts elements of a array reply to Go types:
-//
-//  var value1 int
-//  var value2 string
-//  reply, err := redis.Values(c.Do("MGET", "key1", "key2"))
-//  if err != nil {
-//      // handle error
-//  }
-//   if _, err := redis.Scan(reply, &value1, &value2); err != nil {
-//      // handle error
-//  }
-//
-// Errors
-//
-// Connection methods return error replies from the server as type redis.Error.
-//
-// Call the connection Err() method to determine if the connection encountered
-// non-recoverable error such as a network error or protocol parsing error. If
-// Err() returns a non-nil value, then the connection is not usable and should
-// be closed.
-package redis

+ 0 - 29
src/github.com/gomodule/redigo/redis/go17.go

@@ -1,29 +0,0 @@
-// +build go1.7,!go1.8
-
-package redis
-
-import "crypto/tls"
-
-func cloneTLSConfig(cfg *tls.Config) *tls.Config {
-	return &tls.Config{
-		Rand:                        cfg.Rand,
-		Time:                        cfg.Time,
-		Certificates:                cfg.Certificates,
-		NameToCertificate:           cfg.NameToCertificate,
-		GetCertificate:              cfg.GetCertificate,
-		RootCAs:                     cfg.RootCAs,
-		NextProtos:                  cfg.NextProtos,
-		ServerName:                  cfg.ServerName,
-		ClientAuth:                  cfg.ClientAuth,
-		ClientCAs:                   cfg.ClientCAs,
-		InsecureSkipVerify:          cfg.InsecureSkipVerify,
-		CipherSuites:                cfg.CipherSuites,
-		PreferServerCipherSuites:    cfg.PreferServerCipherSuites,
-		ClientSessionCache:          cfg.ClientSessionCache,
-		MinVersion:                  cfg.MinVersion,
-		MaxVersion:                  cfg.MaxVersion,
-		CurvePreferences:            cfg.CurvePreferences,
-		DynamicRecordSizingDisabled: cfg.DynamicRecordSizingDisabled,
-		Renegotiation:               cfg.Renegotiation,
-	}
-}

+ 0 - 9
src/github.com/gomodule/redigo/redis/go18.go

@@ -1,9 +0,0 @@
-// +build go1.8
-
-package redis
-
-import "crypto/tls"
-
-func cloneTLSConfig(cfg *tls.Config) *tls.Config {
-	return cfg.Clone()
-}

+ 0 - 85
src/github.com/gomodule/redigo/redis/list_test.go

@@ -1,85 +0,0 @@
-// Copyright 2018 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-// +build go1.9
-
-package redis
-
-import "testing"
-
-func TestPoolList(t *testing.T) {
-	var idle idleList
-	var a, b, c poolConn
-
-	check := func(pcs ...*poolConn) {
-		if idle.count != len(pcs) {
-			t.Fatal("idle.count != len(pcs)")
-		}
-		if len(pcs) == 0 {
-			if idle.front != nil {
-				t.Fatalf("front not nil")
-			}
-			if idle.back != nil {
-				t.Fatalf("back not nil")
-			}
-			return
-		}
-		if idle.front != pcs[0] {
-			t.Fatal("front != pcs[0]")
-		}
-		if idle.back != pcs[len(pcs)-1] {
-			t.Fatal("back != pcs[len(pcs)-1]")
-		}
-		if idle.front.prev != nil {
-			t.Fatal("front.prev != nil")
-		}
-		if idle.back.next != nil {
-			t.Fatal("back.next != nil")
-		}
-		for i := 1; i < len(pcs)-1; i++ {
-			if pcs[i-1].next != pcs[i] {
-				t.Fatal("pcs[i-1].next != pcs[i]")
-			}
-			if pcs[i+1].prev != pcs[i] {
-				t.Fatal("pcs[i+1].prev != pcs[i]")
-			}
-		}
-	}
-
-	idle.pushFront(&c)
-	check(&c)
-	idle.pushFront(&b)
-	check(&b, &c)
-	idle.pushFront(&a)
-	check(&a, &b, &c)
-	idle.popFront()
-	check(&b, &c)
-	idle.popFront()
-	check(&c)
-	idle.popFront()
-	check()
-
-	idle.pushFront(&c)
-	check(&c)
-	idle.pushFront(&b)
-	check(&b, &c)
-	idle.pushFront(&a)
-	check(&a, &b, &c)
-	idle.popBack()
-	check(&a, &b)
-	idle.popBack()
-	check(&a)
-	idle.popBack()
-	check()
-}

+ 0 - 146
src/github.com/gomodule/redigo/redis/log.go

@@ -1,146 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package redis
-
-import (
-	"bytes"
-	"fmt"
-	"log"
-	"time"
-)
-
-var (
-	_ ConnWithTimeout = (*loggingConn)(nil)
-)
-
-// NewLoggingConn returns a logging wrapper around a connection.
-func NewLoggingConn(conn Conn, logger *log.Logger, prefix string) Conn {
-	if prefix != "" {
-		prefix = prefix + "."
-	}
-	return &loggingConn{conn, logger, prefix, nil}
-}
-
-//NewLoggingConnFilter returns a logging wrapper around a connection and a filter function.
-func NewLoggingConnFilter(conn Conn, logger *log.Logger, prefix string, skip func(cmdName string) bool) Conn {
-	if prefix != "" {
-		prefix = prefix + "."
-	}
-	return &loggingConn{conn, logger, prefix, skip}
-}
-
-type loggingConn struct {
-	Conn
-	logger *log.Logger
-	prefix string
-	skip   func(cmdName string) bool
-}
-
-func (c *loggingConn) Close() error {
-	err := c.Conn.Close()
-	var buf bytes.Buffer
-	fmt.Fprintf(&buf, "%sClose() -> (%v)", c.prefix, err)
-	c.logger.Output(2, buf.String())
-	return err
-}
-
-func (c *loggingConn) printValue(buf *bytes.Buffer, v interface{}) {
-	const chop = 32
-	switch v := v.(type) {
-	case []byte:
-		if len(v) > chop {
-			fmt.Fprintf(buf, "%q...", v[:chop])
-		} else {
-			fmt.Fprintf(buf, "%q", v)
-		}
-	case string:
-		if len(v) > chop {
-			fmt.Fprintf(buf, "%q...", v[:chop])
-		} else {
-			fmt.Fprintf(buf, "%q", v)
-		}
-	case []interface{}:
-		if len(v) == 0 {
-			buf.WriteString("[]")
-		} else {
-			sep := "["
-			fin := "]"
-			if len(v) > chop {
-				v = v[:chop]
-				fin = "...]"
-			}
-			for _, vv := range v {
-				buf.WriteString(sep)
-				c.printValue(buf, vv)
-				sep = ", "
-			}
-			buf.WriteString(fin)
-		}
-	default:
-		fmt.Fprint(buf, v)
-	}
-}
-
-func (c *loggingConn) print(method, commandName string, args []interface{}, reply interface{}, err error) {
-	if c.skip != nil && c.skip(commandName) {
-		return
-	}
-	var buf bytes.Buffer
-	fmt.Fprintf(&buf, "%s%s(", c.prefix, method)
-	if method != "Receive" {
-		buf.WriteString(commandName)
-		for _, arg := range args {
-			buf.WriteString(", ")
-			c.printValue(&buf, arg)
-		}
-	}
-	buf.WriteString(") -> (")
-	if method != "Send" {
-		c.printValue(&buf, reply)
-		buf.WriteString(", ")
-	}
-	fmt.Fprintf(&buf, "%v)", err)
-	c.logger.Output(3, buf.String())
-}
-
-func (c *loggingConn) Do(commandName string, args ...interface{}) (interface{}, error) {
-	reply, err := c.Conn.Do(commandName, args...)
-	c.print("Do", commandName, args, reply, err)
-	return reply, err
-}
-
-func (c *loggingConn) DoWithTimeout(timeout time.Duration, commandName string, args ...interface{}) (interface{}, error) {
-	reply, err := DoWithTimeout(c.Conn, timeout, commandName, args...)
-	c.print("DoWithTimeout", commandName, args, reply, err)
-	return reply, err
-}
-
-func (c *loggingConn) Send(commandName string, args ...interface{}) error {
-	err := c.Conn.Send(commandName, args...)
-	c.print("Send", commandName, args, nil, err)
-	return err
-}
-
-func (c *loggingConn) Receive() (interface{}, error) {
-	reply, err := c.Conn.Receive()
-	c.print("Receive", "", nil, reply, err)
-	return reply, err
-}
-
-func (c *loggingConn) ReceiveWithTimeout(timeout time.Duration) (interface{}, error) {
-	reply, err := ReceiveWithTimeout(c.Conn, timeout)
-	c.print("ReceiveWithTimeout", "", nil, reply, err)
-	return reply, err
-}

+ 0 - 621
src/github.com/gomodule/redigo/redis/pool.go

@@ -1,621 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package redis
-
-import (
-	"bytes"
-	"context"
-	"crypto/rand"
-	"crypto/sha1"
-	"errors"
-	"io"
-	"strconv"
-	"sync"
-	"sync/atomic"
-	"time"
-)
-
-var (
-	_ ConnWithTimeout = (*activeConn)(nil)
-	_ ConnWithTimeout = (*errorConn)(nil)
-)
-
-var nowFunc = time.Now // for testing
-
-// ErrPoolExhausted is returned from a pool connection method (Do, Send,
-// Receive, Flush, Err) when the maximum number of database connections in the
-// pool has been reached.
-var ErrPoolExhausted = errors.New("redigo: connection pool exhausted")
-
-var (
-	errPoolClosed = errors.New("redigo: connection pool closed")
-	errConnClosed = errors.New("redigo: connection closed")
-)
-
-// Pool maintains a pool of connections. The application calls the Get method
-// to get a connection from the pool and the connection's Close method to
-// return the connection's resources to the pool.
-//
-// The following example shows how to use a pool in a web application. The
-// application creates a pool at application startup and makes it available to
-// request handlers using a package level variable. The pool configuration used
-// here is an example, not a recommendation.
-//
-//  func newPool(addr string) *redis.Pool {
-//    return &redis.Pool{
-//      MaxIdle: 3,
-//      IdleTimeout: 240 * time.Second,
-//      // Dial or DialContext must be set. When both are set, DialContext takes precedence over Dial.
-//      Dial: func () (redis.Conn, error) { return redis.Dial("tcp", addr) },
-//    }
-//  }
-//
-//  var (
-//    pool *redis.Pool
-//    redisServer = flag.String("redisServer", ":6379", "")
-//  )
-//
-//  func main() {
-//    flag.Parse()
-//    pool = newPool(*redisServer)
-//    ...
-//  }
-//
-// A request handler gets a connection from the pool and closes the connection
-// when the handler is done:
-//
-//  func serveHome(w http.ResponseWriter, r *http.Request) {
-//      conn := pool.Get()
-//      defer conn.Close()
-//      ...
-//  }
-//
-// Use the Dial function to authenticate connections with the AUTH command or
-// select a database with the SELECT command:
-//
-//  pool := &redis.Pool{
-//    // Other pool configuration not shown in this example.
-//    Dial: func () (redis.Conn, error) {
-//      c, err := redis.Dial("tcp", server)
-//      if err != nil {
-//        return nil, err
-//      }
-//      if _, err := c.Do("AUTH", password); err != nil {
-//        c.Close()
-//        return nil, err
-//      }
-//      if _, err := c.Do("SELECT", db); err != nil {
-//        c.Close()
-//        return nil, err
-//      }
-//      return c, nil
-//    },
-//  }
-//
-// Use the TestOnBorrow function to check the health of an idle connection
-// before the connection is returned to the application. This example PINGs
-// connections that have been idle more than a minute:
-//
-//  pool := &redis.Pool{
-//    // Other pool configuration not shown in this example.
-//    TestOnBorrow: func(c redis.Conn, t time.Time) error {
-//      if time.Since(t) < time.Minute {
-//        return nil
-//      }
-//      _, err := c.Do("PING")
-//      return err
-//    },
-//  }
-//
-type Pool struct {
-	// Dial is an application supplied function for creating and configuring a
-	// connection.
-	//
-	// The connection returned from Dial must not be in a special state
-	// (subscribed to pubsub channel, transaction started, ...).
-	Dial func() (Conn, error)
-
-	// DialContext is an application supplied function for creating and configuring a
-	// connection with the given context.
-	//
-	// The connection returned from Dial must not be in a special state
-	// (subscribed to pubsub channel, transaction started, ...).
-	DialContext func(ctx context.Context) (Conn, error)
-
-	// TestOnBorrow is an optional application supplied function for checking
-	// the health of an idle connection before the connection is used again by
-	// the application. Argument t is the time that the connection was returned
-	// to the pool. If the function returns an error, then the connection is
-	// closed.
-	TestOnBorrow func(c Conn, t time.Time) error
-
-	// Maximum number of idle connections in the pool.
-	MaxIdle int
-
-	// Maximum number of connections allocated by the pool at a given time.
-	// When zero, there is no limit on the number of connections in the pool.
-	MaxActive int
-
-	// Close connections after remaining idle for this duration. If the value
-	// is zero, then idle connections are not closed. Applications should set
-	// the timeout to a value less than the server's timeout.
-	IdleTimeout time.Duration
-
-	// If Wait is true and the pool is at the MaxActive limit, then Get() waits
-	// for a connection to be returned to the pool before returning.
-	Wait bool
-
-	// Close connections older than this duration. If the value is zero, then
-	// the pool does not close connections based on age.
-	MaxConnLifetime time.Duration
-
-	chInitialized uint32 // set to 1 when field ch is initialized
-
-	mu           sync.Mutex    // mu protects the following fields
-	closed       bool          // set to true when the pool is closed.
-	active       int           // the number of open connections in the pool
-	ch           chan struct{} // limits open connections when p.Wait is true
-	idle         idleList      // idle connections
-	waitCount    int64         // total number of connections waited for.
-	waitDuration time.Duration // total time waited for new connections.
-}
-
-// NewPool creates a new pool.
-//
-// Deprecated: Initialize the Pool directory as shown in the example.
-func NewPool(newFn func() (Conn, error), maxIdle int) *Pool {
-	return &Pool{Dial: newFn, MaxIdle: maxIdle}
-}
-
-// Get gets a connection. The application must close the returned connection.
-// This method always returns a valid connection so that applications can defer
-// error handling to the first use of the connection. If there is an error
-// getting an underlying connection, then the connection Err, Do, Send, Flush
-// and Receive methods return that error.
-func (p *Pool) Get() Conn {
-	pc, err := p.get(nil)
-	if err != nil {
-		return errorConn{err}
-	}
-	return &activeConn{p: p, pc: pc}
-}
-
-// GetContext gets a connection using the provided context.
-//
-// The provided Context must be non-nil. If the context expires before the
-// connection is complete, an error is returned. Any expiration on the context
-// will not affect the returned connection.
-//
-// If the function completes without error, then the application must close the
-// returned connection.
-func (p *Pool) GetContext(ctx context.Context) (Conn, error) {
-	pc, err := p.get(ctx)
-	if err != nil {
-		return errorConn{err}, err
-	}
-	return &activeConn{p: p, pc: pc}, nil
-}
-
-// PoolStats contains pool statistics.
-type PoolStats struct {
-	// ActiveCount is the number of connections in the pool. The count includes
-	// idle connections and connections in use.
-	ActiveCount int
-	// IdleCount is the number of idle connections in the pool.
-	IdleCount int
-
-	// WaitCount is the total number of connections waited for.
-	// This value is currently not guaranteed to be 100% accurate.
-	WaitCount int64
-
-	// WaitDuration is the total time blocked waiting for a new connection.
-	// This value is currently not guaranteed to be 100% accurate.
-	WaitDuration time.Duration
-}
-
-// Stats returns pool's statistics.
-func (p *Pool) Stats() PoolStats {
-	p.mu.Lock()
-	stats := PoolStats{
-		ActiveCount:  p.active,
-		IdleCount:    p.idle.count,
-		WaitCount:    p.waitCount,
-		WaitDuration: p.waitDuration,
-	}
-	p.mu.Unlock()
-
-	return stats
-}
-
-// ActiveCount returns the number of connections in the pool. The count
-// includes idle connections and connections in use.
-func (p *Pool) ActiveCount() int {
-	p.mu.Lock()
-	active := p.active
-	p.mu.Unlock()
-	return active
-}
-
-// IdleCount returns the number of idle connections in the pool.
-func (p *Pool) IdleCount() int {
-	p.mu.Lock()
-	idle := p.idle.count
-	p.mu.Unlock()
-	return idle
-}
-
-// Close releases the resources used by the pool.
-func (p *Pool) Close() error {
-	p.mu.Lock()
-	if p.closed {
-		p.mu.Unlock()
-		return nil
-	}
-	p.closed = true
-	p.active -= p.idle.count
-	pc := p.idle.front
-	p.idle.count = 0
-	p.idle.front, p.idle.back = nil, nil
-	if p.ch != nil {
-		close(p.ch)
-	}
-	p.mu.Unlock()
-	for ; pc != nil; pc = pc.next {
-		pc.c.Close()
-	}
-	return nil
-}
-
-func (p *Pool) lazyInit() {
-	// Fast path.
-	if atomic.LoadUint32(&p.chInitialized) == 1 {
-		return
-	}
-	// Slow path.
-	p.mu.Lock()
-	if p.chInitialized == 0 {
-		p.ch = make(chan struct{}, p.MaxActive)
-		if p.closed {
-			close(p.ch)
-		} else {
-			for i := 0; i < p.MaxActive; i++ {
-				p.ch <- struct{}{}
-			}
-		}
-		atomic.StoreUint32(&p.chInitialized, 1)
-	}
-	p.mu.Unlock()
-}
-
-// get prunes stale connections and returns a connection from the idle list or
-// creates a new connection.
-func (p *Pool) get(ctx context.Context) (*poolConn, error) {
-
-	// Handle limit for p.Wait == true.
-	var waited time.Duration
-	if p.Wait && p.MaxActive > 0 {
-		p.lazyInit()
-
-		// wait indicates if we believe it will block so its not 100% accurate
-		// however for stats it should be good enough.
-		wait := len(p.ch) == 0
-		var start time.Time
-		if wait {
-			start = time.Now()
-		}
-		if ctx == nil {
-			<-p.ch
-		} else {
-			select {
-			case <-p.ch:
-			case <-ctx.Done():
-				return nil, ctx.Err()
-			}
-		}
-		if wait {
-			waited = time.Since(start)
-		}
-	}
-
-	p.mu.Lock()
-
-	if waited > 0 {
-		p.waitCount++
-		p.waitDuration += waited
-	}
-
-	// Prune stale connections at the back of the idle list.
-	if p.IdleTimeout > 0 {
-		n := p.idle.count
-		for i := 0; i < n && p.idle.back != nil && p.idle.back.t.Add(p.IdleTimeout).Before(nowFunc()); i++ {
-			pc := p.idle.back
-			p.idle.popBack()
-			p.mu.Unlock()
-			pc.c.Close()
-			p.mu.Lock()
-			p.active--
-		}
-	}
-
-	// Get idle connection from the front of idle list.
-	for p.idle.front != nil {
-		pc := p.idle.front
-		p.idle.popFront()
-		p.mu.Unlock()
-		if (p.TestOnBorrow == nil || p.TestOnBorrow(pc.c, pc.t) == nil) &&
-			(p.MaxConnLifetime == 0 || nowFunc().Sub(pc.created) < p.MaxConnLifetime) {
-			return pc, nil
-		}
-		pc.c.Close()
-		p.mu.Lock()
-		p.active--
-	}
-
-	// Check for pool closed before dialing a new connection.
-	if p.closed {
-		p.mu.Unlock()
-		return nil, errors.New("redigo: get on closed pool")
-	}
-
-	// Handle limit for p.Wait == false.
-	if !p.Wait && p.MaxActive > 0 && p.active >= p.MaxActive {
-		p.mu.Unlock()
-		return nil, ErrPoolExhausted
-	}
-
-	p.active++
-	p.mu.Unlock()
-	c, err := p.dial(ctx)
-	if err != nil {
-		c = nil
-		p.mu.Lock()
-		p.active--
-		if p.ch != nil && !p.closed {
-			p.ch <- struct{}{}
-		}
-		p.mu.Unlock()
-	}
-	return &poolConn{c: c, created: nowFunc()}, err
-}
-
-func (p *Pool) dial(ctx context.Context) (Conn, error) {
-	if p.DialContext != nil {
-		return p.DialContext(ctx)
-	}
-	if p.Dial != nil {
-		return p.Dial()
-	}
-	return nil, errors.New("redigo: must pass Dial or DialContext to pool")
-}
-
-func (p *Pool) put(pc *poolConn, forceClose bool) error {
-	p.mu.Lock()
-	if !p.closed && !forceClose {
-		pc.t = nowFunc()
-		p.idle.pushFront(pc)
-		if p.idle.count > p.MaxIdle {
-			pc = p.idle.back
-			p.idle.popBack()
-		} else {
-			pc = nil
-		}
-	}
-
-	if pc != nil {
-		p.mu.Unlock()
-		pc.c.Close()
-		p.mu.Lock()
-		p.active--
-	}
-
-	if p.ch != nil && !p.closed {
-		p.ch <- struct{}{}
-	}
-	p.mu.Unlock()
-	return nil
-}
-
-type activeConn struct {
-	p     *Pool
-	pc    *poolConn
-	state int
-}
-
-var (
-	sentinel     []byte
-	sentinelOnce sync.Once
-)
-
-func initSentinel() {
-	p := make([]byte, 64)
-	if _, err := rand.Read(p); err == nil {
-		sentinel = p
-	} else {
-		h := sha1.New()
-		io.WriteString(h, "Oops, rand failed. Use time instead.")
-		io.WriteString(h, strconv.FormatInt(time.Now().UnixNano(), 10))
-		sentinel = h.Sum(nil)
-	}
-}
-
-func (ac *activeConn) Close() error {
-	pc := ac.pc
-	if pc == nil {
-		return nil
-	}
-	ac.pc = nil
-
-	if ac.state&connectionMultiState != 0 {
-		pc.c.Send("DISCARD")
-		ac.state &^= (connectionMultiState | connectionWatchState)
-	} else if ac.state&connectionWatchState != 0 {
-		pc.c.Send("UNWATCH")
-		ac.state &^= connectionWatchState
-	}
-	if ac.state&connectionSubscribeState != 0 {
-		pc.c.Send("UNSUBSCRIBE")
-		pc.c.Send("PUNSUBSCRIBE")
-		// To detect the end of the message stream, ask the server to echo
-		// a sentinel value and read until we see that value.
-		sentinelOnce.Do(initSentinel)
-		pc.c.Send("ECHO", sentinel)
-		pc.c.Flush()
-		for {
-			p, err := pc.c.Receive()
-			if err != nil {
-				break
-			}
-			if p, ok := p.([]byte); ok && bytes.Equal(p, sentinel) {
-				ac.state &^= connectionSubscribeState
-				break
-			}
-		}
-	}
-	pc.c.Do("")
-	ac.p.put(pc, ac.state != 0 || pc.c.Err() != nil)
-	return nil
-}
-
-func (ac *activeConn) Err() error {
-	pc := ac.pc
-	if pc == nil {
-		return errConnClosed
-	}
-	return pc.c.Err()
-}
-
-func (ac *activeConn) Do(commandName string, args ...interface{}) (reply interface{}, err error) {
-	pc := ac.pc
-	if pc == nil {
-		return nil, errConnClosed
-	}
-	ci := lookupCommandInfo(commandName)
-	ac.state = (ac.state | ci.Set) &^ ci.Clear
-	return pc.c.Do(commandName, args...)
-}
-
-func (ac *activeConn) DoWithTimeout(timeout time.Duration, commandName string, args ...interface{}) (reply interface{}, err error) {
-	pc := ac.pc
-	if pc == nil {
-		return nil, errConnClosed
-	}
-	cwt, ok := pc.c.(ConnWithTimeout)
-	if !ok {
-		return nil, errTimeoutNotSupported
-	}
-	ci := lookupCommandInfo(commandName)
-	ac.state = (ac.state | ci.Set) &^ ci.Clear
-	return cwt.DoWithTimeout(timeout, commandName, args...)
-}
-
-func (ac *activeConn) Send(commandName string, args ...interface{}) error {
-	pc := ac.pc
-	if pc == nil {
-		return errConnClosed
-	}
-	ci := lookupCommandInfo(commandName)
-	ac.state = (ac.state | ci.Set) &^ ci.Clear
-	return pc.c.Send(commandName, args...)
-}
-
-func (ac *activeConn) Flush() error {
-	pc := ac.pc
-	if pc == nil {
-		return errConnClosed
-	}
-	return pc.c.Flush()
-}
-
-func (ac *activeConn) Receive() (reply interface{}, err error) {
-	pc := ac.pc
-	if pc == nil {
-		return nil, errConnClosed
-	}
-	return pc.c.Receive()
-}
-
-func (ac *activeConn) ReceiveWithTimeout(timeout time.Duration) (reply interface{}, err error) {
-	pc := ac.pc
-	if pc == nil {
-		return nil, errConnClosed
-	}
-	cwt, ok := pc.c.(ConnWithTimeout)
-	if !ok {
-		return nil, errTimeoutNotSupported
-	}
-	return cwt.ReceiveWithTimeout(timeout)
-}
-
-type errorConn struct{ err error }
-
-func (ec errorConn) Do(string, ...interface{}) (interface{}, error) { return nil, ec.err }
-func (ec errorConn) DoWithTimeout(time.Duration, string, ...interface{}) (interface{}, error) {
-	return nil, ec.err
-}
-func (ec errorConn) Send(string, ...interface{}) error                     { return ec.err }
-func (ec errorConn) Err() error                                            { return ec.err }
-func (ec errorConn) Close() error                                          { return nil }
-func (ec errorConn) Flush() error                                          { return ec.err }
-func (ec errorConn) Receive() (interface{}, error)                         { return nil, ec.err }
-func (ec errorConn) ReceiveWithTimeout(time.Duration) (interface{}, error) { return nil, ec.err }
-
-type idleList struct {
-	count       int
-	front, back *poolConn
-}
-
-type poolConn struct {
-	c          Conn
-	t          time.Time
-	created    time.Time
-	next, prev *poolConn
-}
-
-func (l *idleList) pushFront(pc *poolConn) {
-	pc.next = l.front
-	pc.prev = nil
-	if l.count == 0 {
-		l.back = pc
-	} else {
-		l.front.prev = pc
-	}
-	l.front = pc
-	l.count++
-	return
-}
-
-func (l *idleList) popFront() {
-	pc := l.front
-	l.count--
-	if l.count == 0 {
-		l.front, l.back = nil, nil
-	} else {
-		pc.next.prev = nil
-		l.front = pc.next
-	}
-	pc.next, pc.prev = nil, nil
-}
-
-func (l *idleList) popBack() {
-	pc := l.back
-	l.count--
-	if l.count == 0 {
-		l.front, l.back = nil, nil
-	} else {
-		pc.prev.next = nil
-		l.back = pc.prev
-	}
-	pc.next, pc.prev = nil, nil
-}

+ 0 - 875
src/github.com/gomodule/redigo/redis/pool_test.go

@@ -1,875 +0,0 @@
-// Copyright 2011 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package redis_test
-
-import (
-	"context"
-	"errors"
-	"io"
-	"reflect"
-	"sync"
-	"testing"
-	"time"
-
-	"github.com/gomodule/redigo/redis"
-)
-
-const (
-	testGoRoutines = 10
-)
-
-type poolTestConn struct {
-	d   *poolDialer
-	err error
-	redis.Conn
-}
-
-func (c *poolTestConn) Close() error {
-	c.d.mu.Lock()
-	c.d.open -= 1
-	c.d.mu.Unlock()
-	return c.Conn.Close()
-}
-
-func (c *poolTestConn) Err() error { return c.err }
-
-func (c *poolTestConn) Do(commandName string, args ...interface{}) (interface{}, error) {
-	if commandName == "ERR" {
-		c.err = args[0].(error)
-		commandName = "PING"
-	}
-	if commandName != "" {
-		c.d.commands = append(c.d.commands, commandName)
-	}
-	return c.Conn.Do(commandName, args...)
-}
-
-func (c *poolTestConn) Send(commandName string, args ...interface{}) error {
-	c.d.commands = append(c.d.commands, commandName)
-	return c.Conn.Send(commandName, args...)
-}
-
-type poolDialer struct {
-	mu       sync.Mutex
-	t        *testing.T
-	dialed   int
-	open     int
-	commands []string
-	dialErr  error
-}
-
-func (d *poolDialer) dial() (redis.Conn, error) {
-	d.mu.Lock()
-	d.dialed += 1
-	dialErr := d.dialErr
-	d.mu.Unlock()
-	if dialErr != nil {
-		return nil, d.dialErr
-	}
-	c, err := redis.DialDefaultServer()
-	if err != nil {
-		return nil, err
-	}
-	d.mu.Lock()
-	d.open += 1
-	d.mu.Unlock()
-	return &poolTestConn{d: d, Conn: c}, nil
-}
-
-func (d *poolDialer) dialContext(ctx context.Context) (redis.Conn, error) {
-	return d.dial()
-}
-
-func (d *poolDialer) check(message string, p *redis.Pool, dialed, open, inuse int) {
-	d.checkAll(message, p, dialed, open, inuse, 0, 0)
-}
-
-func (d *poolDialer) checkAll(message string, p *redis.Pool, dialed, open, inuse int, waitCountMax int64, waitDurationMax time.Duration) {
-	d.mu.Lock()
-	defer d.mu.Unlock()
-
-	if d.dialed != dialed {
-		d.t.Errorf("%s: dialed=%d, want %d", message, d.dialed, dialed)
-	}
-	if d.open != open {
-		d.t.Errorf("%s: open=%d, want %d", message, d.open, open)
-	}
-
-	stats := p.Stats()
-
-	if stats.ActiveCount != open {
-		d.t.Errorf("%s: active=%d, want %d", message, stats.ActiveCount, open)
-	}
-	if stats.IdleCount != open-inuse {
-		d.t.Errorf("%s: idle=%d, want %d", message, stats.IdleCount, open-inuse)
-	}
-
-	if stats.WaitCount > waitCountMax {
-		d.t.Errorf("%s: unexpected wait=%d want at most %d", message, stats.WaitCount, waitCountMax)
-	}
-
-	if waitCountMax == 0 {
-		if stats.WaitDuration != 0 {
-			d.t.Errorf("%s: unexpected waitDuration=%v want %v", message, stats.WaitDuration, 0)
-		}
-		return
-	}
-
-	if stats.WaitDuration > waitDurationMax {
-		d.t.Errorf("%s: unexpected waitDuration=%v want < %v", message, stats.WaitDuration, waitDurationMax)
-	}
-}
-
-func TestPoolReuse(t *testing.T) {
-	d := poolDialer{t: t}
-	p := &redis.Pool{
-		MaxIdle: 2,
-		Dial:    d.dial,
-	}
-
-	for i := 0; i < 10; i++ {
-		c1 := p.Get()
-		c1.Do("PING")
-		c2 := p.Get()
-		c2.Do("PING")
-		c1.Close()
-		c2.Close()
-	}
-
-	d.check("before close", p, 2, 2, 0)
-	p.Close()
-	d.check("after close", p, 2, 0, 0)
-}
-
-func TestPoolMaxIdle(t *testing.T) {
-	d := poolDialer{t: t}
-	p := &redis.Pool{
-		MaxIdle: 2,
-		Dial:    d.dial,
-	}
-	defer p.Close()
-
-	for i := 0; i < 10; i++ {
-		c1 := p.Get()
-		c1.Do("PING")
-		c2 := p.Get()
-		c2.Do("PING")
-		c3 := p.Get()
-		c3.Do("PING")
-		c1.Close()
-		c2.Close()
-		c3.Close()
-	}
-	d.check("before close", p, 12, 2, 0)
-	p.Close()
-	d.check("after close", p, 12, 0, 0)
-}
-
-func TestPoolError(t *testing.T) {
-	d := poolDialer{t: t}
-	p := &redis.Pool{
-		MaxIdle: 2,
-		Dial:    d.dial,
-	}
-	defer p.Close()
-
-	c := p.Get()
-	c.Do("ERR", io.EOF)
-	if c.Err() == nil {
-		t.Errorf("expected c.Err() != nil")
-	}
-	c.Close()
-
-	c = p.Get()
-	c.Do("ERR", io.EOF)
-	c.Close()
-
-	d.check(".", p, 2, 0, 0)
-}
-
-func TestPoolClose(t *testing.T) {
-	d := poolDialer{t: t}
-	p := &redis.Pool{
-		MaxIdle: 2,
-		Dial:    d.dial,
-	}
-	defer p.Close()
-
-	c1 := p.Get()
-	c1.Do("PING")
-	c2 := p.Get()
-	c2.Do("PING")
-	c3 := p.Get()
-	c3.Do("PING")
-
-	c1.Close()
-	if _, err := c1.Do("PING"); err == nil {
-		t.Errorf("expected error after connection closed")
-	}
-
-	c2.Close()
-	c2.Close()
-
-	p.Close()
-
-	d.check("after pool close", p, 3, 1, 1)
-
-	if _, err := c1.Do("PING"); err == nil {
-		t.Errorf("expected error after connection and pool closed")
-	}
-
-	c3.Close()
-
-	d.check("after conn close", p, 3, 0, 0)
-
-	c1 = p.Get()
-	if _, err := c1.Do("PING"); err == nil {
-		t.Errorf("expected error after pool closed")
-	}
-}
-
-func TestPoolClosedConn(t *testing.T) {
-	d := poolDialer{t: t}
-	p := &redis.Pool{
-		MaxIdle:     2,
-		IdleTimeout: 300 * time.Second,
-		Dial:        d.dial,
-	}
-	defer p.Close()
-	c := p.Get()
-	if c.Err() != nil {
-		t.Fatal("get failed")
-	}
-	c.Close()
-	if err := c.Err(); err == nil {
-		t.Fatal("Err on closed connection did not return error")
-	}
-	if _, err := c.Do("PING"); err == nil {
-		t.Fatal("Do on closed connection did not return error")
-	}
-	if err := c.Send("PING"); err == nil {
-		t.Fatal("Send on closed connection did not return error")
-	}
-	if err := c.Flush(); err == nil {
-		t.Fatal("Flush on closed connection did not return error")
-	}
-	if _, err := c.Receive(); err == nil {
-		t.Fatal("Receive on closed connection did not return error")
-	}
-}
-
-func TestPoolIdleTimeout(t *testing.T) {
-	d := poolDialer{t: t}
-	p := &redis.Pool{
-		MaxIdle:     2,
-		IdleTimeout: 300 * time.Second,
-		Dial:        d.dial,
-	}
-	defer p.Close()
-
-	now := time.Now()
-	redis.SetNowFunc(func() time.Time { return now })
-	defer redis.SetNowFunc(time.Now)
-
-	c := p.Get()
-	c.Do("PING")
-	c.Close()
-
-	d.check("1", p, 1, 1, 0)
-
-	now = now.Add(p.IdleTimeout + 1)
-
-	c = p.Get()
-	c.Do("PING")
-	c.Close()
-
-	d.check("2", p, 2, 1, 0)
-}
-
-func TestPoolMaxLifetime(t *testing.T) {
-	d := poolDialer{t: t}
-	p := &redis.Pool{
-		MaxIdle:         2,
-		MaxConnLifetime: 300 * time.Second,
-		Dial:            d.dial,
-	}
-	defer p.Close()
-
-	now := time.Now()
-	redis.SetNowFunc(func() time.Time { return now })
-	defer redis.SetNowFunc(time.Now)
-
-	c := p.Get()
-	c.Do("PING")
-	c.Close()
-
-	d.check("1", p, 1, 1, 0)
-
-	now = now.Add(p.MaxConnLifetime + 1)
-
-	c = p.Get()
-	c.Do("PING")
-	c.Close()
-
-	d.check("2", p, 2, 1, 0)
-}
-
-func TestPoolConcurrenSendReceive(t *testing.T) {
-	p := &redis.Pool{
-		Dial: func() (redis.Conn, error) { return redis.DialDefaultServer() },
-	}
-	defer p.Close()
-
-	c := p.Get()
-	done := make(chan error, 1)
-	go func() {
-		_, err := c.Receive()
-		done <- err
-	}()
-	c.Send("PING")
-	c.Flush()
-	err := <-done
-	if err != nil {
-		t.Fatalf("Receive() returned error %v", err)
-	}
-	_, err = c.Do("")
-	if err != nil {
-		t.Fatalf("Do() returned error %v", err)
-	}
-	c.Close()
-}
-
-func TestPoolBorrowCheck(t *testing.T) {
-	d := poolDialer{t: t}
-	p := &redis.Pool{
-		MaxIdle:      2,
-		Dial:         d.dial,
-		TestOnBorrow: func(redis.Conn, time.Time) error { return redis.Error("BLAH") },
-	}
-	defer p.Close()
-
-	for i := 0; i < 10; i++ {
-		c := p.Get()
-		c.Do("PING")
-		c.Close()
-	}
-	d.check("1", p, 10, 1, 0)
-}
-
-func TestPoolMaxActive(t *testing.T) {
-	d := poolDialer{t: t}
-	p := &redis.Pool{
-		MaxIdle:   2,
-		MaxActive: 2,
-		Dial:      d.dial,
-	}
-	defer p.Close()
-
-	c1 := p.Get()
-	c1.Do("PING")
-	c2 := p.Get()
-	c2.Do("PING")
-
-	d.check("1", p, 2, 2, 2)
-
-	c3 := p.Get()
-	if _, err := c3.Do("PING"); err != redis.ErrPoolExhausted {
-		t.Errorf("expected pool exhausted")
-	}
-
-	c3.Close()
-	d.check("2", p, 2, 2, 2)
-	c2.Close()
-	d.check("3", p, 2, 2, 1)
-
-	c3 = p.Get()
-	if _, err := c3.Do("PING"); err != nil {
-		t.Errorf("expected good channel, err=%v", err)
-	}
-	c3.Close()
-
-	d.check("4", p, 2, 2, 1)
-}
-
-func TestPoolWaitStats(t *testing.T) {
-	d := poolDialer{t: t}
-	p := &redis.Pool{
-		Wait:      true,
-		MaxIdle:   2,
-		MaxActive: 2,
-		Dial:      d.dial,
-	}
-	defer p.Close()
-
-	c1 := p.Get()
-	c1.Do("PING")
-	c2 := p.Get()
-	c2.Do("PING")
-
-	d.checkAll("1", p, 2, 2, 2, 0, 0)
-
-	start := time.Now()
-	go func() {
-		time.Sleep(time.Millisecond * 100)
-		c1.Close()
-	}()
-
-	c3 := p.Get()
-	d.checkAll("2", p, 2, 2, 2, 1, time.Since(start))
-
-	if _, err := c3.Do("PING"); err != nil {
-		t.Errorf("expected good channel, err=%v", err)
-	}
-}
-
-func TestPoolMonitorCleanup(t *testing.T) {
-	d := poolDialer{t: t}
-	p := &redis.Pool{
-		MaxIdle:   2,
-		MaxActive: 2,
-		Dial:      d.dial,
-	}
-	defer p.Close()
-
-	c := p.Get()
-	c.Send("MONITOR")
-	c.Close()
-
-	d.check("", p, 1, 0, 0)
-}
-
-func TestPoolPubSubCleanup(t *testing.T) {
-	d := poolDialer{t: t}
-	p := &redis.Pool{
-		MaxIdle:   2,
-		MaxActive: 2,
-		Dial:      d.dial,
-	}
-	defer p.Close()
-
-	c := p.Get()
-	c.Send("SUBSCRIBE", "x")
-	c.Close()
-
-	want := []string{"SUBSCRIBE", "UNSUBSCRIBE", "PUNSUBSCRIBE", "ECHO"}
-	if !reflect.DeepEqual(d.commands, want) {
-		t.Errorf("got commands %v, want %v", d.commands, want)
-	}
-	d.commands = nil
-
-	c = p.Get()
-	c.Send("PSUBSCRIBE", "x*")
-	c.Close()
-
-	want = []string{"PSUBSCRIBE", "UNSUBSCRIBE", "PUNSUBSCRIBE", "ECHO"}
-	if !reflect.DeepEqual(d.commands, want) {
-		t.Errorf("got commands %v, want %v", d.commands, want)
-	}
-	d.commands = nil
-}
-
-func TestPoolTransactionCleanup(t *testing.T) {
-	d := poolDialer{t: t}
-	p := &redis.Pool{
-		MaxIdle:   2,
-		MaxActive: 2,
-		Dial:      d.dial,
-	}
-	defer p.Close()
-
-	c := p.Get()
-	c.Do("WATCH", "key")
-	c.Do("PING")
-	c.Close()
-
-	want := []string{"WATCH", "PING", "UNWATCH"}
-	if !reflect.DeepEqual(d.commands, want) {
-		t.Errorf("got commands %v, want %v", d.commands, want)
-	}
-	d.commands = nil
-
-	c = p.Get()
-	c.Do("WATCH", "key")
-	c.Do("UNWATCH")
-	c.Do("PING")
-	c.Close()
-
-	want = []string{"WATCH", "UNWATCH", "PING"}
-	if !reflect.DeepEqual(d.commands, want) {
-		t.Errorf("got commands %v, want %v", d.commands, want)
-	}
-	d.commands = nil
-
-	c = p.Get()
-	c.Do("WATCH", "key")
-	c.Do("MULTI")
-	c.Do("PING")
-	c.Close()
-
-	want = []string{"WATCH", "MULTI", "PING", "DISCARD"}
-	if !reflect.DeepEqual(d.commands, want) {
-		t.Errorf("got commands %v, want %v", d.commands, want)
-	}
-	d.commands = nil
-
-	c = p.Get()
-	c.Do("WATCH", "key")
-	c.Do("MULTI")
-	c.Do("DISCARD")
-	c.Do("PING")
-	c.Close()
-
-	want = []string{"WATCH", "MULTI", "DISCARD", "PING"}
-	if !reflect.DeepEqual(d.commands, want) {
-		t.Errorf("got commands %v, want %v", d.commands, want)
-	}
-	d.commands = nil
-
-	c = p.Get()
-	c.Do("WATCH", "key")
-	c.Do("MULTI")
-	c.Do("EXEC")
-	c.Do("PING")
-	c.Close()
-
-	want = []string{"WATCH", "MULTI", "EXEC", "PING"}
-	if !reflect.DeepEqual(d.commands, want) {
-		t.Errorf("got commands %v, want %v", d.commands, want)
-	}
-	d.commands = nil
-}
-
-func startGoroutines(p *redis.Pool, cmd string, args ...interface{}) chan error {
-	errs := make(chan error, testGoRoutines)
-	for i := 0; i < cap(errs); i++ {
-		go func() {
-			c := p.Get()
-			_, err := c.Do(cmd, args...)
-			c.Close()
-			errs <- err
-		}()
-	}
-
-	return errs
-}
-
-func TestWaitPool(t *testing.T) {
-	d := poolDialer{t: t}
-	p := &redis.Pool{
-		MaxIdle:   1,
-		MaxActive: 1,
-		Dial:      d.dial,
-		Wait:      true,
-	}
-	defer p.Close()
-
-	c := p.Get()
-	start := time.Now()
-	errs := startGoroutines(p, "PING")
-	d.check("before close", p, 1, 1, 1)
-	c.Close()
-	timeout := time.After(2 * time.Second)
-	for i := 0; i < cap(errs); i++ {
-		select {
-		case err := <-errs:
-			if err != nil {
-				t.Fatal(err)
-			}
-		case <-timeout:
-			t.Fatalf("timeout waiting for blocked goroutine %d", i)
-		}
-	}
-	d.checkAll("done", p, 1, 1, 0, testGoRoutines, time.Since(start)*testGoRoutines)
-}
-
-func TestWaitPoolClose(t *testing.T) {
-	d := poolDialer{t: t}
-	p := &redis.Pool{
-		MaxIdle:   1,
-		MaxActive: 1,
-		Dial:      d.dial,
-		Wait:      true,
-	}
-	defer p.Close()
-
-	c := p.Get()
-	if _, err := c.Do("PING"); err != nil {
-		t.Fatal(err)
-	}
-	start := time.Now()
-	errs := startGoroutines(p, "PING")
-	d.check("before close", p, 1, 1, 1)
-	p.Close()
-	timeout := time.After(2 * time.Second)
-	for i := 0; i < cap(errs); i++ {
-		select {
-		case err := <-errs:
-			switch err {
-			case nil:
-				t.Fatal("blocked goroutine did not get error")
-			case redis.ErrPoolExhausted:
-				t.Fatal("blocked goroutine got pool exhausted error")
-			}
-		case <-timeout:
-			t.Fatal("timeout waiting for blocked goroutine")
-		}
-	}
-	c.Close()
-	d.checkAll("done", p, 1, 0, 0, testGoRoutines, time.Since(start)*testGoRoutines)
-}
-
-func TestWaitPoolCommandError(t *testing.T) {
-	testErr := errors.New("test")
-	d := poolDialer{t: t}
-	p := &redis.Pool{
-		MaxIdle:   1,
-		MaxActive: 1,
-		Dial:      d.dial,
-		Wait:      true,
-	}
-	defer p.Close()
-
-	c := p.Get()
-	start := time.Now()
-	errs := startGoroutines(p, "ERR", testErr)
-	d.check("before close", p, 1, 1, 1)
-	c.Close()
-	timeout := time.After(2 * time.Second)
-	for i := 0; i < cap(errs); i++ {
-		select {
-		case err := <-errs:
-			if err != nil {
-				t.Fatal(err)
-			}
-		case <-timeout:
-			t.Fatalf("timeout waiting for blocked goroutine %d", i)
-		}
-	}
-	d.checkAll("done", p, cap(errs), 0, 0, testGoRoutines, time.Since(start)*testGoRoutines)
-}
-
-func TestWaitPoolDialError(t *testing.T) {
-	testErr := errors.New("test")
-	d := poolDialer{t: t}
-	p := &redis.Pool{
-		MaxIdle:   1,
-		MaxActive: 1,
-		Dial:      d.dial,
-		Wait:      true,
-	}
-	defer p.Close()
-
-	c := p.Get()
-	start := time.Now()
-	errs := startGoroutines(p, "ERR", testErr)
-	d.check("before close", p, 1, 1, 1)
-
-	d.dialErr = errors.New("dial")
-	c.Close()
-
-	nilCount := 0
-	errCount := 0
-	timeout := time.After(2 * time.Second)
-	for i := 0; i < cap(errs); i++ {
-		select {
-		case err := <-errs:
-			switch err {
-			case nil:
-				nilCount++
-			case d.dialErr:
-				errCount++
-			default:
-				t.Fatalf("expected dial error or nil, got %v", err)
-			}
-		case <-timeout:
-			t.Fatalf("timeout waiting for blocked goroutine %d", i)
-		}
-	}
-	if nilCount != 1 {
-		t.Errorf("expected one nil error, got %d", nilCount)
-	}
-	if errCount != cap(errs)-1 {
-		t.Errorf("expected %d dial errors, got %d", cap(errs)-1, errCount)
-	}
-	d.checkAll("done", p, cap(errs), 0, 0, testGoRoutines, time.Since(start)*testGoRoutines)
-}
-
-// Borrowing requires us to iterate over the idle connections, unlock the pool,
-// and perform a blocking operation to check the connection still works. If
-// TestOnBorrow fails, we must reacquire the lock and continue iteration. This
-// test ensures that iteration will work correctly if multiple threads are
-// iterating simultaneously.
-func TestLocking_TestOnBorrowFails_PoolDoesntCrash(t *testing.T) {
-	const count = 100
-
-	// First we'll Create a pool where the pilfering of idle connections fails.
-	d := poolDialer{t: t}
-	p := &redis.Pool{
-		MaxIdle:   count,
-		MaxActive: count,
-		Dial:      d.dial,
-		TestOnBorrow: func(c redis.Conn, t time.Time) error {
-			return errors.New("No way back into the real world.")
-		},
-	}
-	defer p.Close()
-
-	// Fill the pool with idle connections.
-	conns := make([]redis.Conn, count)
-	for i := range conns {
-		conns[i] = p.Get()
-	}
-	for i := range conns {
-		conns[i].Close()
-	}
-
-	// Spawn a bunch of goroutines to thrash the pool.
-	var wg sync.WaitGroup
-	wg.Add(count)
-	for i := 0; i < count; i++ {
-		go func() {
-			c := p.Get()
-			if c.Err() != nil {
-				t.Errorf("pool get failed: %v", c.Err())
-			}
-			c.Close()
-			wg.Done()
-		}()
-	}
-	wg.Wait()
-	if d.dialed != count*2 {
-		t.Errorf("Expected %d dials, got %d", count*2, d.dialed)
-	}
-}
-
-func BenchmarkPoolGet(b *testing.B) {
-	b.StopTimer()
-	p := redis.Pool{Dial: func() (redis.Conn, error) { return redis.DialDefaultServer() }, MaxIdle: 2}
-	c := p.Get()
-	if err := c.Err(); err != nil {
-		b.Fatal(err)
-	}
-	c.Close()
-	defer p.Close()
-	b.StartTimer()
-	for i := 0; i < b.N; i++ {
-		c = p.Get()
-		c.Close()
-	}
-}
-
-func BenchmarkPoolGetErr(b *testing.B) {
-	b.StopTimer()
-	p := redis.Pool{Dial: func() (redis.Conn, error) { return redis.DialDefaultServer() }, MaxIdle: 2}
-	c := p.Get()
-	if err := c.Err(); err != nil {
-		b.Fatal(err)
-	}
-	c.Close()
-	defer p.Close()
-	b.StartTimer()
-	for i := 0; i < b.N; i++ {
-		c = p.Get()
-		if err := c.Err(); err != nil {
-			b.Fatal(err)
-		}
-		c.Close()
-	}
-}
-
-func BenchmarkPoolGetPing(b *testing.B) {
-	b.StopTimer()
-	p := redis.Pool{Dial: func() (redis.Conn, error) { return redis.DialDefaultServer() }, MaxIdle: 2}
-	c := p.Get()
-	if err := c.Err(); err != nil {
-		b.Fatal(err)
-	}
-	c.Close()
-	defer p.Close()
-	b.StartTimer()
-	for i := 0; i < b.N; i++ {
-		c = p.Get()
-		if _, err := c.Do("PING"); err != nil {
-			b.Fatal(err)
-		}
-		c.Close()
-	}
-}
-
-func TestWaitPoolGetContext(t *testing.T) {
-	d := poolDialer{t: t}
-	p := &redis.Pool{
-		MaxIdle:   1,
-		MaxActive: 1,
-		Dial:      d.dial,
-		Wait:      true,
-	}
-	defer p.Close()
-	c, err := p.GetContext(context.Background())
-	if err != nil {
-		t.Fatalf("GetContext returned %v", err)
-	}
-	defer c.Close()
-}
-
-func TestWaitPoolGetContextWithDialContext(t *testing.T) {
-	d := poolDialer{t: t}
-	p := &redis.Pool{
-		MaxIdle:     1,
-		MaxActive:   1,
-		DialContext: d.dialContext,
-		Wait:        true,
-	}
-	defer p.Close()
-	c, err := p.GetContext(context.Background())
-	if err != nil {
-		t.Fatalf("GetContext returned %v", err)
-	}
-	defer c.Close()
-}
-
-func TestWaitPoolGetAfterClose(t *testing.T) {
-	d := poolDialer{t: t}
-	p := &redis.Pool{
-		MaxIdle:   1,
-		MaxActive: 1,
-		Dial:      d.dial,
-		Wait:      true,
-	}
-	p.Close()
-	_, err := p.GetContext(context.Background())
-	if err == nil {
-		t.Fatal("expected error")
-	}
-}
-
-func TestWaitPoolGetCanceledContext(t *testing.T) {
-	d := poolDialer{t: t}
-	p := &redis.Pool{
-		MaxIdle:   1,
-		MaxActive: 1,
-		Dial:      d.dial,
-		Wait:      true,
-	}
-	defer p.Close()
-	ctx, f := context.WithCancel(context.Background())
-	f()
-	c := p.Get()
-	defer c.Close()
-	_, err := p.GetContext(ctx)
-	if err != context.Canceled {
-		t.Fatalf("got error %v, want %v", err, context.Canceled)
-	}
-}

+ 0 - 148
src/github.com/gomodule/redigo/redis/pubsub.go

@@ -1,148 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package redis
-
-import (
-	"errors"
-	"time"
-)
-
-// Subscription represents a subscribe or unsubscribe notification.
-type Subscription struct {
-	// Kind is "subscribe", "unsubscribe", "psubscribe" or "punsubscribe"
-	Kind string
-
-	// The channel that was changed.
-	Channel string
-
-	// The current number of subscriptions for connection.
-	Count int
-}
-
-// Message represents a message notification.
-type Message struct {
-	// The originating channel.
-	Channel string
-
-	// The matched pattern, if any
-	Pattern string
-
-	// The message data.
-	Data []byte
-}
-
-// Pong represents a pubsub pong notification.
-type Pong struct {
-	Data string
-}
-
-// PubSubConn wraps a Conn with convenience methods for subscribers.
-type PubSubConn struct {
-	Conn Conn
-}
-
-// Close closes the connection.
-func (c PubSubConn) Close() error {
-	return c.Conn.Close()
-}
-
-// Subscribe subscribes the connection to the specified channels.
-func (c PubSubConn) Subscribe(channel ...interface{}) error {
-	c.Conn.Send("SUBSCRIBE", channel...)
-	return c.Conn.Flush()
-}
-
-// PSubscribe subscribes the connection to the given patterns.
-func (c PubSubConn) PSubscribe(channel ...interface{}) error {
-	c.Conn.Send("PSUBSCRIBE", channel...)
-	return c.Conn.Flush()
-}
-
-// Unsubscribe unsubscribes the connection from the given channels, or from all
-// of them if none is given.
-func (c PubSubConn) Unsubscribe(channel ...interface{}) error {
-	c.Conn.Send("UNSUBSCRIBE", channel...)
-	return c.Conn.Flush()
-}
-
-// PUnsubscribe unsubscribes the connection from the given patterns, or from all
-// of them if none is given.
-func (c PubSubConn) PUnsubscribe(channel ...interface{}) error {
-	c.Conn.Send("PUNSUBSCRIBE", channel...)
-	return c.Conn.Flush()
-}
-
-// Ping sends a PING to the server with the specified data.
-//
-// The connection must be subscribed to at least one channel or pattern when
-// calling this method.
-func (c PubSubConn) Ping(data string) error {
-	c.Conn.Send("PING", data)
-	return c.Conn.Flush()
-}
-
-// Receive returns a pushed message as a Subscription, Message, Pong or error.
-// The return value is intended to be used directly in a type switch as
-// illustrated in the PubSubConn example.
-func (c PubSubConn) Receive() interface{} {
-	return c.receiveInternal(c.Conn.Receive())
-}
-
-// ReceiveWithTimeout is like Receive, but it allows the application to
-// override the connection's default timeout.
-func (c PubSubConn) ReceiveWithTimeout(timeout time.Duration) interface{} {
-	return c.receiveInternal(ReceiveWithTimeout(c.Conn, timeout))
-}
-
-func (c PubSubConn) receiveInternal(replyArg interface{}, errArg error) interface{} {
-	reply, err := Values(replyArg, errArg)
-	if err != nil {
-		return err
-	}
-
-	var kind string
-	reply, err = Scan(reply, &kind)
-	if err != nil {
-		return err
-	}
-
-	switch kind {
-	case "message":
-		var m Message
-		if _, err := Scan(reply, &m.Channel, &m.Data); err != nil {
-			return err
-		}
-		return m
-	case "pmessage":
-		var m Message
-		if _, err := Scan(reply, &m.Pattern, &m.Channel, &m.Data); err != nil {
-			return err
-		}
-		return m
-	case "subscribe", "psubscribe", "unsubscribe", "punsubscribe":
-		s := Subscription{Kind: kind}
-		if _, err := Scan(reply, &s.Channel, &s.Count); err != nil {
-			return err
-		}
-		return s
-	case "pong":
-		var p Pong
-		if _, err := Scan(reply, &p.Data); err != nil {
-			return err
-		}
-		return p
-	}
-	return errors.New("redigo: unknown pubsub notification")
-}

+ 0 - 165
src/github.com/gomodule/redigo/redis/pubsub_example_test.go

@@ -1,165 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-// +build go1.7
-
-package redis_test
-
-import (
-	"context"
-	"fmt"
-	"time"
-
-	"github.com/gomodule/redigo/redis"
-)
-
-// listenPubSubChannels listens for messages on Redis pubsub channels. The
-// onStart function is called after the channels are subscribed. The onMessage
-// function is called for each message.
-func listenPubSubChannels(ctx context.Context, redisServerAddr string,
-	onStart func() error,
-	onMessage func(channel string, data []byte) error,
-	channels ...string) error {
-	// A ping is set to the server with this period to test for the health of
-	// the connection and server.
-	const healthCheckPeriod = time.Minute
-
-	c, err := redis.Dial("tcp", redisServerAddr,
-		// Read timeout on server should be greater than ping period.
-		redis.DialReadTimeout(healthCheckPeriod+10*time.Second),
-		redis.DialWriteTimeout(10*time.Second))
-	if err != nil {
-		return err
-	}
-	defer c.Close()
-
-	psc := redis.PubSubConn{Conn: c}
-
-	if err := psc.Subscribe(redis.Args{}.AddFlat(channels)...); err != nil {
-		return err
-	}
-
-	done := make(chan error, 1)
-
-	// Start a goroutine to receive notifications from the server.
-	go func() {
-		for {
-			switch n := psc.Receive().(type) {
-			case error:
-				done <- n
-				return
-			case redis.Message:
-				if err := onMessage(n.Channel, n.Data); err != nil {
-					done <- err
-					return
-				}
-			case redis.Subscription:
-				switch n.Count {
-				case len(channels):
-					// Notify application when all channels are subscribed.
-					if err := onStart(); err != nil {
-						done <- err
-						return
-					}
-				case 0:
-					// Return from the goroutine when all channels are unsubscribed.
-					done <- nil
-					return
-				}
-			}
-		}
-	}()
-
-	ticker := time.NewTicker(healthCheckPeriod)
-	defer ticker.Stop()
-loop:
-	for err == nil {
-		select {
-		case <-ticker.C:
-			// Send ping to test health of connection and server. If
-			// corresponding pong is not received, then receive on the
-			// connection will timeout and the receive goroutine will exit.
-			if err = psc.Ping(""); err != nil {
-				break loop
-			}
-		case <-ctx.Done():
-			break loop
-		case err := <-done:
-			// Return error from the receive goroutine.
-			return err
-		}
-	}
-
-	// Signal the receiving goroutine to exit by unsubscribing from all channels.
-	psc.Unsubscribe()
-
-	// Wait for goroutine to complete.
-	return <-done
-}
-
-func publish() {
-	c, err := dial()
-	if err != nil {
-		fmt.Println(err)
-		return
-	}
-	defer c.Close()
-
-	c.Do("PUBLISH", "c1", "hello")
-	c.Do("PUBLISH", "c2", "world")
-	c.Do("PUBLISH", "c1", "goodbye")
-}
-
-// This example shows how receive pubsub notifications with cancelation and
-// health checks.
-func ExamplePubSubConn() {
-	redisServerAddr, err := serverAddr()
-	if err != nil {
-		fmt.Println(err)
-		return
-	}
-
-	ctx, cancel := context.WithCancel(context.Background())
-
-	err = listenPubSubChannels(ctx,
-		redisServerAddr,
-		func() error {
-			// The start callback is a good place to backfill missed
-			// notifications. For the purpose of this example, a goroutine is
-			// started to send notifications.
-			go publish()
-			return nil
-		},
-		func(channel string, message []byte) error {
-			fmt.Printf("channel: %s, message: %s\n", channel, message)
-
-			// For the purpose of this example, cancel the listener's context
-			// after receiving last message sent by publish().
-			if string(message) == "goodbye" {
-				cancel()
-			}
-			return nil
-		},
-		"c1", "c2")
-
-	if err != nil {
-		fmt.Println(err)
-		return
-	}
-
-	// Output:
-	// channel: c1, message: hello
-	// channel: c2, message: world
-	// channel: c1, message: goodbye
-}

+ 0 - 74
src/github.com/gomodule/redigo/redis/pubsub_test.go

@@ -1,74 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package redis_test
-
-import (
-	"reflect"
-	"testing"
-	"time"
-
-	"github.com/gomodule/redigo/redis"
-)
-
-func expectPushed(t *testing.T, c redis.PubSubConn, message string, expected interface{}) {
-	actual := c.Receive()
-	if !reflect.DeepEqual(actual, expected) {
-		t.Errorf("%s = %v, want %v", message, actual, expected)
-	}
-}
-
-func TestPushed(t *testing.T) {
-	pc, err := redis.DialDefaultServer()
-	if err != nil {
-		t.Fatalf("error connection to database, %v", err)
-	}
-	defer pc.Close()
-
-	sc, err := redis.DialDefaultServer()
-	if err != nil {
-		t.Fatalf("error connection to database, %v", err)
-	}
-	defer sc.Close()
-
-	c := redis.PubSubConn{Conn: sc}
-
-	c.Subscribe("c1")
-	expectPushed(t, c, "Subscribe(c1)", redis.Subscription{Kind: "subscribe", Channel: "c1", Count: 1})
-	c.Subscribe("c2")
-	expectPushed(t, c, "Subscribe(c2)", redis.Subscription{Kind: "subscribe", Channel: "c2", Count: 2})
-	c.PSubscribe("p1")
-	expectPushed(t, c, "PSubscribe(p1)", redis.Subscription{Kind: "psubscribe", Channel: "p1", Count: 3})
-	c.PSubscribe("p2")
-	expectPushed(t, c, "PSubscribe(p2)", redis.Subscription{Kind: "psubscribe", Channel: "p2", Count: 4})
-	c.PUnsubscribe()
-	expectPushed(t, c, "Punsubscribe(p1)", redis.Subscription{Kind: "punsubscribe", Channel: "p1", Count: 3})
-	expectPushed(t, c, "Punsubscribe()", redis.Subscription{Kind: "punsubscribe", Channel: "p2", Count: 2})
-
-	pc.Do("PUBLISH", "c1", "hello")
-	expectPushed(t, c, "PUBLISH c1 hello", redis.Message{Channel: "c1", Data: []byte("hello")})
-
-	c.Ping("hello")
-	expectPushed(t, c, `Ping("hello")`, redis.Pong{Data: "hello"})
-
-	c.Conn.Send("PING")
-	c.Conn.Flush()
-	expectPushed(t, c, `Send("PING")`, redis.Pong{})
-
-	c.Ping("timeout")
-	got := c.ReceiveWithTimeout(time.Minute)
-	if want := (redis.Pong{Data: "timeout"}); want != got {
-		t.Errorf("recv /w timeout got %v, want %v", got, want)
-	}
-}

+ 0 - 117
src/github.com/gomodule/redigo/redis/redis.go

@@ -1,117 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package redis
-
-import (
-	"errors"
-	"time"
-)
-
-// Error represents an error returned in a command reply.
-type Error string
-
-func (err Error) Error() string { return string(err) }
-
-// Conn represents a connection to a Redis server.
-type Conn interface {
-	// Close closes the connection.
-	Close() error
-
-	// Err returns a non-nil value when the connection is not usable.
-	Err() error
-
-	// Do sends a command to the server and returns the received reply.
-	Do(commandName string, args ...interface{}) (reply interface{}, err error)
-
-	// Send writes the command to the client's output buffer.
-	Send(commandName string, args ...interface{}) error
-
-	// Flush flushes the output buffer to the Redis server.
-	Flush() error
-
-	// Receive receives a single reply from the Redis server
-	Receive() (reply interface{}, err error)
-}
-
-// Argument is the interface implemented by an object which wants to control how
-// the object is converted to Redis bulk strings.
-type Argument interface {
-	// RedisArg returns a value to be encoded as a bulk string per the
-	// conversions listed in the section 'Executing Commands'.
-	// Implementations should typically return a []byte or string.
-	RedisArg() interface{}
-}
-
-// Scanner is implemented by an object which wants to control its value is
-// interpreted when read from Redis.
-type Scanner interface {
-	// RedisScan assigns a value from a Redis value. The argument src is one of
-	// the reply types listed in the section `Executing Commands`.
-	//
-	// An error should be returned if the value cannot be stored without
-	// loss of information.
-	RedisScan(src interface{}) error
-}
-
-// ConnWithTimeout is an optional interface that allows the caller to override
-// a connection's default read timeout. This interface is useful for executing
-// the BLPOP, BRPOP, BRPOPLPUSH, XREAD and other commands that block at the
-// server.
-//
-// A connection's default read timeout is set with the DialReadTimeout dial
-// option. Applications should rely on the default timeout for commands that do
-// not block at the server.
-//
-// All of the Conn implementations in this package satisfy the ConnWithTimeout
-// interface.
-//
-// Use the DoWithTimeout and ReceiveWithTimeout helper functions to simplify
-// use of this interface.
-type ConnWithTimeout interface {
-	Conn
-
-	// Do sends a command to the server and returns the received reply.
-	// The timeout overrides the read timeout set when dialing the
-	// connection.
-	DoWithTimeout(timeout time.Duration, commandName string, args ...interface{}) (reply interface{}, err error)
-
-	// Receive receives a single reply from the Redis server. The timeout
-	// overrides the read timeout set when dialing the connection.
-	ReceiveWithTimeout(timeout time.Duration) (reply interface{}, err error)
-}
-
-var errTimeoutNotSupported = errors.New("redis: connection does not support ConnWithTimeout")
-
-// DoWithTimeout executes a Redis command with the specified read timeout. If
-// the connection does not satisfy the ConnWithTimeout interface, then an error
-// is returned.
-func DoWithTimeout(c Conn, timeout time.Duration, cmd string, args ...interface{}) (interface{}, error) {
-	cwt, ok := c.(ConnWithTimeout)
-	if !ok {
-		return nil, errTimeoutNotSupported
-	}
-	return cwt.DoWithTimeout(timeout, cmd, args...)
-}
-
-// ReceiveWithTimeout receives a reply with the specified read timeout. If the
-// connection does not satisfy the ConnWithTimeout interface, then an error is
-// returned.
-func ReceiveWithTimeout(c Conn, timeout time.Duration) (interface{}, error) {
-	cwt, ok := c.(ConnWithTimeout)
-	if !ok {
-		return nil, errTimeoutNotSupported
-	}
-	return cwt.ReceiveWithTimeout(timeout)
-}

+ 0 - 71
src/github.com/gomodule/redigo/redis/redis_test.go

@@ -1,71 +0,0 @@
-// Copyright 2017 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package redis_test
-
-import (
-	"testing"
-	"time"
-
-	"github.com/gomodule/redigo/redis"
-)
-
-type timeoutTestConn int
-
-func (tc timeoutTestConn) Do(string, ...interface{}) (interface{}, error) {
-	return time.Duration(-1), nil
-}
-func (tc timeoutTestConn) DoWithTimeout(timeout time.Duration, cmd string, args ...interface{}) (interface{}, error) {
-	return timeout, nil
-}
-
-func (tc timeoutTestConn) Receive() (interface{}, error) {
-	return time.Duration(-1), nil
-}
-func (tc timeoutTestConn) ReceiveWithTimeout(timeout time.Duration) (interface{}, error) {
-	return timeout, nil
-}
-
-func (tc timeoutTestConn) Send(string, ...interface{}) error { return nil }
-func (tc timeoutTestConn) Err() error                        { return nil }
-func (tc timeoutTestConn) Close() error                      { return nil }
-func (tc timeoutTestConn) Flush() error                      { return nil }
-
-func testTimeout(t *testing.T, c redis.Conn) {
-	r, err := c.Do("PING")
-	if r != time.Duration(-1) || err != nil {
-		t.Errorf("Do() = %v, %v, want %v, %v", r, err, time.Duration(-1), nil)
-	}
-	r, err = redis.DoWithTimeout(c, time.Minute, "PING")
-	if r != time.Minute || err != nil {
-		t.Errorf("DoWithTimeout() = %v, %v, want %v, %v", r, err, time.Minute, nil)
-	}
-	r, err = c.Receive()
-	if r != time.Duration(-1) || err != nil {
-		t.Errorf("Receive() = %v, %v, want %v, %v", r, err, time.Duration(-1), nil)
-	}
-	r, err = redis.ReceiveWithTimeout(c, time.Minute)
-	if r != time.Minute || err != nil {
-		t.Errorf("ReceiveWithTimeout() = %v, %v, want %v, %v", r, err, time.Minute, nil)
-	}
-}
-
-func TestConnTimeout(t *testing.T) {
-	testTimeout(t, timeoutTestConn(0))
-}
-
-func TestPoolConnTimeout(t *testing.T) {
-	p := &redis.Pool{Dial: func() (redis.Conn, error) { return timeoutTestConn(0), nil }}
-	testTimeout(t, p.Get())
-}

+ 0 - 479
src/github.com/gomodule/redigo/redis/reply.go

@@ -1,479 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package redis
-
-import (
-	"errors"
-	"fmt"
-	"strconv"
-)
-
-// ErrNil indicates that a reply value is nil.
-var ErrNil = errors.New("redigo: nil returned")
-
-// Int is a helper that converts a command reply to an integer. If err is not
-// equal to nil, then Int returns 0, err. Otherwise, Int converts the
-// reply to an int as follows:
-//
-//  Reply type    Result
-//  integer       int(reply), nil
-//  bulk string   parsed reply, nil
-//  nil           0, ErrNil
-//  other         0, error
-func Int(reply interface{}, err error) (int, error) {
-	if err != nil {
-		return 0, err
-	}
-	switch reply := reply.(type) {
-	case int64:
-		x := int(reply)
-		if int64(x) != reply {
-			return 0, strconv.ErrRange
-		}
-		return x, nil
-	case []byte:
-		n, err := strconv.ParseInt(string(reply), 10, 0)
-		return int(n), err
-	case nil:
-		return 0, ErrNil
-	case Error:
-		return 0, reply
-	}
-	return 0, fmt.Errorf("redigo: unexpected type for Int, got type %T", reply)
-}
-
-// Int64 is a helper that converts a command reply to 64 bit integer. If err is
-// not equal to nil, then Int returns 0, err. Otherwise, Int64 converts the
-// reply to an int64 as follows:
-//
-//  Reply type    Result
-//  integer       reply, nil
-//  bulk string   parsed reply, nil
-//  nil           0, ErrNil
-//  other         0, error
-func Int64(reply interface{}, err error) (int64, error) {
-	if err != nil {
-		return 0, err
-	}
-	switch reply := reply.(type) {
-	case int64:
-		return reply, nil
-	case []byte:
-		n, err := strconv.ParseInt(string(reply), 10, 64)
-		return n, err
-	case nil:
-		return 0, ErrNil
-	case Error:
-		return 0, reply
-	}
-	return 0, fmt.Errorf("redigo: unexpected type for Int64, got type %T", reply)
-}
-
-var errNegativeInt = errors.New("redigo: unexpected value for Uint64")
-
-// Uint64 is a helper that converts a command reply to 64 bit integer. If err is
-// not equal to nil, then Int returns 0, err. Otherwise, Int64 converts the
-// reply to an int64 as follows:
-//
-//  Reply type    Result
-//  integer       reply, nil
-//  bulk string   parsed reply, nil
-//  nil           0, ErrNil
-//  other         0, error
-func Uint64(reply interface{}, err error) (uint64, error) {
-	if err != nil {
-		return 0, err
-	}
-	switch reply := reply.(type) {
-	case int64:
-		if reply < 0 {
-			return 0, errNegativeInt
-		}
-		return uint64(reply), nil
-	case []byte:
-		n, err := strconv.ParseUint(string(reply), 10, 64)
-		return n, err
-	case nil:
-		return 0, ErrNil
-	case Error:
-		return 0, reply
-	}
-	return 0, fmt.Errorf("redigo: unexpected type for Uint64, got type %T", reply)
-}
-
-// Float64 is a helper that converts a command reply to 64 bit float. If err is
-// not equal to nil, then Float64 returns 0, err. Otherwise, Float64 converts
-// the reply to an int as follows:
-//
-//  Reply type    Result
-//  bulk string   parsed reply, nil
-//  nil           0, ErrNil
-//  other         0, error
-func Float64(reply interface{}, err error) (float64, error) {
-	if err != nil {
-		return 0, err
-	}
-	switch reply := reply.(type) {
-	case []byte:
-		n, err := strconv.ParseFloat(string(reply), 64)
-		return n, err
-	case nil:
-		return 0, ErrNil
-	case Error:
-		return 0, reply
-	}
-	return 0, fmt.Errorf("redigo: unexpected type for Float64, got type %T", reply)
-}
-
-// String is a helper that converts a command reply to a string. If err is not
-// equal to nil, then String returns "", err. Otherwise String converts the
-// reply to a string as follows:
-//
-//  Reply type      Result
-//  bulk string     string(reply), nil
-//  simple string   reply, nil
-//  nil             "",  ErrNil
-//  other           "",  error
-func String(reply interface{}, err error) (string, error) {
-	if err != nil {
-		return "", err
-	}
-	switch reply := reply.(type) {
-	case []byte:
-		return string(reply), nil
-	case string:
-		return reply, nil
-	case nil:
-		return "", ErrNil
-	case Error:
-		return "", reply
-	}
-	return "", fmt.Errorf("redigo: unexpected type for String, got type %T", reply)
-}
-
-// Bytes is a helper that converts a command reply to a slice of bytes. If err
-// is not equal to nil, then Bytes returns nil, err. Otherwise Bytes converts
-// the reply to a slice of bytes as follows:
-//
-//  Reply type      Result
-//  bulk string     reply, nil
-//  simple string   []byte(reply), nil
-//  nil             nil, ErrNil
-//  other           nil, error
-func Bytes(reply interface{}, err error) ([]byte, error) {
-	if err != nil {
-		return nil, err
-	}
-	switch reply := reply.(type) {
-	case []byte:
-		return reply, nil
-	case string:
-		return []byte(reply), nil
-	case nil:
-		return nil, ErrNil
-	case Error:
-		return nil, reply
-	}
-	return nil, fmt.Errorf("redigo: unexpected type for Bytes, got type %T", reply)
-}
-
-// Bool is a helper that converts a command reply to a boolean. If err is not
-// equal to nil, then Bool returns false, err. Otherwise Bool converts the
-// reply to boolean as follows:
-//
-//  Reply type      Result
-//  integer         value != 0, nil
-//  bulk string     strconv.ParseBool(reply)
-//  nil             false, ErrNil
-//  other           false, error
-func Bool(reply interface{}, err error) (bool, error) {
-	if err != nil {
-		return false, err
-	}
-	switch reply := reply.(type) {
-	case int64:
-		return reply != 0, nil
-	case []byte:
-		return strconv.ParseBool(string(reply))
-	case nil:
-		return false, ErrNil
-	case Error:
-		return false, reply
-	}
-	return false, fmt.Errorf("redigo: unexpected type for Bool, got type %T", reply)
-}
-
-// MultiBulk is a helper that converts an array command reply to a []interface{}.
-//
-// Deprecated: Use Values instead.
-func MultiBulk(reply interface{}, err error) ([]interface{}, error) { return Values(reply, err) }
-
-// Values is a helper that converts an array command reply to a []interface{}.
-// If err is not equal to nil, then Values returns nil, err. Otherwise, Values
-// converts the reply as follows:
-//
-//  Reply type      Result
-//  array           reply, nil
-//  nil             nil, ErrNil
-//  other           nil, error
-func Values(reply interface{}, err error) ([]interface{}, error) {
-	if err != nil {
-		return nil, err
-	}
-	switch reply := reply.(type) {
-	case []interface{}:
-		return reply, nil
-	case nil:
-		return nil, ErrNil
-	case Error:
-		return nil, reply
-	}
-	return nil, fmt.Errorf("redigo: unexpected type for Values, got type %T", reply)
-}
-
-func sliceHelper(reply interface{}, err error, name string, makeSlice func(int), assign func(int, interface{}) error) error {
-	if err != nil {
-		return err
-	}
-	switch reply := reply.(type) {
-	case []interface{}:
-		makeSlice(len(reply))
-		for i := range reply {
-			if reply[i] == nil {
-				continue
-			}
-			if err := assign(i, reply[i]); err != nil {
-				return err
-			}
-		}
-		return nil
-	case nil:
-		return ErrNil
-	case Error:
-		return reply
-	}
-	return fmt.Errorf("redigo: unexpected type for %s, got type %T", name, reply)
-}
-
-// Float64s is a helper that converts an array command reply to a []float64. If
-// err is not equal to nil, then Float64s returns nil, err. Nil array items are
-// converted to 0 in the output slice. Floats64 returns an error if an array
-// item is not a bulk string or nil.
-func Float64s(reply interface{}, err error) ([]float64, error) {
-	var result []float64
-	err = sliceHelper(reply, err, "Float64s", func(n int) { result = make([]float64, n) }, func(i int, v interface{}) error {
-		p, ok := v.([]byte)
-		if !ok {
-			return fmt.Errorf("redigo: unexpected element type for Floats64, got type %T", v)
-		}
-		f, err := strconv.ParseFloat(string(p), 64)
-		result[i] = f
-		return err
-	})
-	return result, err
-}
-
-// Strings is a helper that converts an array command reply to a []string. If
-// err is not equal to nil, then Strings returns nil, err. Nil array items are
-// converted to "" in the output slice. Strings returns an error if an array
-// item is not a bulk string or nil.
-func Strings(reply interface{}, err error) ([]string, error) {
-	var result []string
-	err = sliceHelper(reply, err, "Strings", func(n int) { result = make([]string, n) }, func(i int, v interface{}) error {
-		switch v := v.(type) {
-		case string:
-			result[i] = v
-			return nil
-		case []byte:
-			result[i] = string(v)
-			return nil
-		default:
-			return fmt.Errorf("redigo: unexpected element type for Strings, got type %T", v)
-		}
-	})
-	return result, err
-}
-
-// ByteSlices is a helper that converts an array command reply to a [][]byte.
-// If err is not equal to nil, then ByteSlices returns nil, err. Nil array
-// items are stay nil. ByteSlices returns an error if an array item is not a
-// bulk string or nil.
-func ByteSlices(reply interface{}, err error) ([][]byte, error) {
-	var result [][]byte
-	err = sliceHelper(reply, err, "ByteSlices", func(n int) { result = make([][]byte, n) }, func(i int, v interface{}) error {
-		p, ok := v.([]byte)
-		if !ok {
-			return fmt.Errorf("redigo: unexpected element type for ByteSlices, got type %T", v)
-		}
-		result[i] = p
-		return nil
-	})
-	return result, err
-}
-
-// Int64s is a helper that converts an array command reply to a []int64.
-// If err is not equal to nil, then Int64s returns nil, err. Nil array
-// items are stay nil. Int64s returns an error if an array item is not a
-// bulk string or nil.
-func Int64s(reply interface{}, err error) ([]int64, error) {
-	var result []int64
-	err = sliceHelper(reply, err, "Int64s", func(n int) { result = make([]int64, n) }, func(i int, v interface{}) error {
-		switch v := v.(type) {
-		case int64:
-			result[i] = v
-			return nil
-		case []byte:
-			n, err := strconv.ParseInt(string(v), 10, 64)
-			result[i] = n
-			return err
-		default:
-			return fmt.Errorf("redigo: unexpected element type for Int64s, got type %T", v)
-		}
-	})
-	return result, err
-}
-
-// Ints is a helper that converts an array command reply to a []in.
-// If err is not equal to nil, then Ints returns nil, err. Nil array
-// items are stay nil. Ints returns an error if an array item is not a
-// bulk string or nil.
-func Ints(reply interface{}, err error) ([]int, error) {
-	var result []int
-	err = sliceHelper(reply, err, "Ints", func(n int) { result = make([]int, n) }, func(i int, v interface{}) error {
-		switch v := v.(type) {
-		case int64:
-			n := int(v)
-			if int64(n) != v {
-				return strconv.ErrRange
-			}
-			result[i] = n
-			return nil
-		case []byte:
-			n, err := strconv.Atoi(string(v))
-			result[i] = n
-			return err
-		default:
-			return fmt.Errorf("redigo: unexpected element type for Ints, got type %T", v)
-		}
-	})
-	return result, err
-}
-
-// StringMap is a helper that converts an array of strings (alternating key, value)
-// into a map[string]string. The HGETALL and CONFIG GET commands return replies in this format.
-// Requires an even number of values in result.
-func StringMap(result interface{}, err error) (map[string]string, error) {
-	values, err := Values(result, err)
-	if err != nil {
-		return nil, err
-	}
-	if len(values)%2 != 0 {
-		return nil, errors.New("redigo: StringMap expects even number of values result")
-	}
-	m := make(map[string]string, len(values)/2)
-	for i := 0; i < len(values); i += 2 {
-		key, okKey := values[i].([]byte)
-		value, okValue := values[i+1].([]byte)
-		if !okKey || !okValue {
-			return nil, errors.New("redigo: StringMap key not a bulk string value")
-		}
-		m[string(key)] = string(value)
-	}
-	return m, nil
-}
-
-// IntMap is a helper that converts an array of strings (alternating key, value)
-// into a map[string]int. The HGETALL commands return replies in this format.
-// Requires an even number of values in result.
-func IntMap(result interface{}, err error) (map[string]int, error) {
-	values, err := Values(result, err)
-	if err != nil {
-		return nil, err
-	}
-	if len(values)%2 != 0 {
-		return nil, errors.New("redigo: IntMap expects even number of values result")
-	}
-	m := make(map[string]int, len(values)/2)
-	for i := 0; i < len(values); i += 2 {
-		key, ok := values[i].([]byte)
-		if !ok {
-			return nil, errors.New("redigo: IntMap key not a bulk string value")
-		}
-		value, err := Int(values[i+1], nil)
-		if err != nil {
-			return nil, err
-		}
-		m[string(key)] = value
-	}
-	return m, nil
-}
-
-// Int64Map is a helper that converts an array of strings (alternating key, value)
-// into a map[string]int64. The HGETALL commands return replies in this format.
-// Requires an even number of values in result.
-func Int64Map(result interface{}, err error) (map[string]int64, error) {
-	values, err := Values(result, err)
-	if err != nil {
-		return nil, err
-	}
-	if len(values)%2 != 0 {
-		return nil, errors.New("redigo: Int64Map expects even number of values result")
-	}
-	m := make(map[string]int64, len(values)/2)
-	for i := 0; i < len(values); i += 2 {
-		key, ok := values[i].([]byte)
-		if !ok {
-			return nil, errors.New("redigo: Int64Map key not a bulk string value")
-		}
-		value, err := Int64(values[i+1], nil)
-		if err != nil {
-			return nil, err
-		}
-		m[string(key)] = value
-	}
-	return m, nil
-}
-
-// Positions is a helper that converts an array of positions (lat, long)
-// into a [][2]float64. The GEOPOS command returns replies in this format.
-func Positions(result interface{}, err error) ([]*[2]float64, error) {
-	values, err := Values(result, err)
-	if err != nil {
-		return nil, err
-	}
-	positions := make([]*[2]float64, len(values))
-	for i := range values {
-		if values[i] == nil {
-			continue
-		}
-		p, ok := values[i].([]interface{})
-		if !ok {
-			return nil, fmt.Errorf("redigo: unexpected element type for interface slice, got type %T", values[i])
-		}
-		if len(p) != 2 {
-			return nil, fmt.Errorf("redigo: unexpected number of values for a member position, got %d", len(p))
-		}
-		lat, err := Float64(p[0], nil)
-		if err != nil {
-			return nil, err
-		}
-		long, err := Float64(p[1], nil)
-		if err != nil {
-			return nil, err
-		}
-		positions[i] = &[2]float64{lat, long}
-	}
-	return positions, nil
-}

+ 0 - 209
src/github.com/gomodule/redigo/redis/reply_test.go

@@ -1,209 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package redis_test
-
-import (
-	"fmt"
-	"reflect"
-	"testing"
-
-	"github.com/gomodule/redigo/redis"
-)
-
-type valueError struct {
-	v   interface{}
-	err error
-}
-
-func ve(v interface{}, err error) valueError {
-	return valueError{v, err}
-}
-
-var replyTests = []struct {
-	name     interface{}
-	actual   valueError
-	expected valueError
-}{
-	{
-		"ints([[]byte, []byte])",
-		ve(redis.Ints([]interface{}{[]byte("4"), []byte("5")}, nil)),
-		ve([]int{4, 5}, nil),
-	},
-	{
-		"ints([nt64, int64])",
-		ve(redis.Ints([]interface{}{int64(4), int64(5)}, nil)),
-		ve([]int{4, 5}, nil),
-	},
-	{
-		"ints([[]byte, nil, []byte])",
-		ve(redis.Ints([]interface{}{[]byte("4"), nil, []byte("5")}, nil)),
-		ve([]int{4, 0, 5}, nil),
-	},
-	{
-		"ints(nil)",
-		ve(redis.Ints(nil, nil)),
-		ve([]int(nil), redis.ErrNil),
-	},
-	{
-		"int64s([[]byte, []byte])",
-		ve(redis.Int64s([]interface{}{[]byte("4"), []byte("5")}, nil)),
-		ve([]int64{4, 5}, nil),
-	},
-	{
-		"int64s([int64, int64])",
-		ve(redis.Int64s([]interface{}{int64(4), int64(5)}, nil)),
-		ve([]int64{4, 5}, nil),
-	},
-	{
-		"strings([[]byte, []bytev2])",
-		ve(redis.Strings([]interface{}{[]byte("v1"), []byte("v2")}, nil)),
-		ve([]string{"v1", "v2"}, nil),
-	},
-	{
-		"strings([string, string])",
-		ve(redis.Strings([]interface{}{"v1", "v2"}, nil)),
-		ve([]string{"v1", "v2"}, nil),
-	},
-	{
-		"byteslices([v1, v2])",
-		ve(redis.ByteSlices([]interface{}{[]byte("v1"), []byte("v2")}, nil)),
-		ve([][]byte{[]byte("v1"), []byte("v2")}, nil),
-	},
-	{
-		"float64s([v1, v2])",
-		ve(redis.Float64s([]interface{}{[]byte("1.234"), []byte("5.678")}, nil)),
-		ve([]float64{1.234, 5.678}, nil),
-	},
-	{
-		"values([v1, v2])",
-		ve(redis.Values([]interface{}{[]byte("v1"), []byte("v2")}, nil)),
-		ve([]interface{}{[]byte("v1"), []byte("v2")}, nil),
-	},
-	{
-		"values(nil)",
-		ve(redis.Values(nil, nil)),
-		ve([]interface{}(nil), redis.ErrNil),
-	},
-	{
-		"float64(1.0)",
-		ve(redis.Float64([]byte("1.0"), nil)),
-		ve(float64(1.0), nil),
-	},
-	{
-		"float64(nil)",
-		ve(redis.Float64(nil, nil)),
-		ve(float64(0.0), redis.ErrNil),
-	},
-	{
-		"uint64(1)",
-		ve(redis.Uint64(int64(1), nil)),
-		ve(uint64(1), nil),
-	},
-	{
-		"uint64(-1)",
-		ve(redis.Uint64(int64(-1), nil)),
-		ve(uint64(0), redis.ErrNegativeInt),
-	},
-	{
-		"positions([[1, 2], nil, [3, 4]])",
-		ve(redis.Positions([]interface{}{[]interface{}{[]byte("1"), []byte("2")}, nil, []interface{}{[]byte("3"), []byte("4")}}, nil)),
-		ve([]*[2]float64{{1.0, 2.0}, nil, {3.0, 4.0}}, nil),
-	},
-}
-
-func TestReply(t *testing.T) {
-	for _, rt := range replyTests {
-		if rt.actual.err != rt.expected.err {
-			t.Errorf("%s returned err %v, want %v", rt.name, rt.actual.err, rt.expected.err)
-			continue
-		}
-		if !reflect.DeepEqual(rt.actual.v, rt.expected.v) {
-			t.Errorf("%s=%+v, want %+v", rt.name, rt.actual.v, rt.expected.v)
-		}
-	}
-}
-
-// dial wraps DialDefaultServer() with a more suitable function name for examples.
-func dial() (redis.Conn, error) {
-	return redis.DialDefaultServer()
-}
-
-// serverAddr wraps DefaultServerAddr() with a more suitable function name for examples.
-func serverAddr() (string, error) {
-	return redis.DefaultServerAddr()
-}
-
-func ExampleBool() {
-	c, err := dial()
-	if err != nil {
-		fmt.Println(err)
-		return
-	}
-	defer c.Close()
-
-	c.Do("SET", "foo", 1)
-	exists, _ := redis.Bool(c.Do("EXISTS", "foo"))
-	fmt.Printf("%#v\n", exists)
-	// Output:
-	// true
-}
-
-func ExampleInt() {
-	c, err := dial()
-	if err != nil {
-		fmt.Println(err)
-		return
-	}
-	defer c.Close()
-
-	c.Do("SET", "k1", 1)
-	n, _ := redis.Int(c.Do("GET", "k1"))
-	fmt.Printf("%#v\n", n)
-	n, _ = redis.Int(c.Do("INCR", "k1"))
-	fmt.Printf("%#v\n", n)
-	// Output:
-	// 1
-	// 2
-}
-
-func ExampleInts() {
-	c, err := dial()
-	if err != nil {
-		fmt.Println(err)
-		return
-	}
-	defer c.Close()
-
-	c.Do("SADD", "set_with_integers", 4, 5, 6)
-	ints, _ := redis.Ints(c.Do("SMEMBERS", "set_with_integers"))
-	fmt.Printf("%#v\n", ints)
-	// Output:
-	// []int{4, 5, 6}
-}
-
-func ExampleString() {
-	c, err := dial()
-	if err != nil {
-		fmt.Println(err)
-		return
-	}
-	defer c.Close()
-
-	c.Do("SET", "hello", "world")
-	s, err := redis.String(c.Do("GET", "hello"))
-	fmt.Printf("%#v\n", s)
-	// Output:
-	// "world"
-}

+ 0 - 630
src/github.com/gomodule/redigo/redis/scan.go

@@ -1,630 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package redis
-
-import (
-	"errors"
-	"fmt"
-	"reflect"
-	"strconv"
-	"strings"
-	"sync"
-)
-
-func ensureLen(d reflect.Value, n int) {
-	if n > d.Cap() {
-		d.Set(reflect.MakeSlice(d.Type(), n, n))
-	} else {
-		d.SetLen(n)
-	}
-}
-
-func cannotConvert(d reflect.Value, s interface{}) error {
-	var sname string
-	switch s.(type) {
-	case string:
-		sname = "Redis simple string"
-	case Error:
-		sname = "Redis error"
-	case int64:
-		sname = "Redis integer"
-	case []byte:
-		sname = "Redis bulk string"
-	case []interface{}:
-		sname = "Redis array"
-	case nil:
-		sname = "Redis nil"
-	default:
-		sname = reflect.TypeOf(s).String()
-	}
-	return fmt.Errorf("cannot convert from %s to %s", sname, d.Type())
-}
-
-func convertAssignNil(d reflect.Value) (err error) {
-	switch d.Type().Kind() {
-	case reflect.Slice, reflect.Interface:
-		d.Set(reflect.Zero(d.Type()))
-	default:
-		err = cannotConvert(d, nil)
-	}
-	return err
-}
-
-func convertAssignError(d reflect.Value, s Error) (err error) {
-	if d.Kind() == reflect.String {
-		d.SetString(string(s))
-	} else if d.Kind() == reflect.Slice && d.Type().Elem().Kind() == reflect.Uint8 {
-		d.SetBytes([]byte(s))
-	} else {
-		err = cannotConvert(d, s)
-	}
-	return
-}
-
-func convertAssignString(d reflect.Value, s string) (err error) {
-	switch d.Type().Kind() {
-	case reflect.Float32, reflect.Float64:
-		var x float64
-		x, err = strconv.ParseFloat(s, d.Type().Bits())
-		d.SetFloat(x)
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		var x int64
-		x, err = strconv.ParseInt(s, 10, d.Type().Bits())
-		d.SetInt(x)
-	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
-		var x uint64
-		x, err = strconv.ParseUint(s, 10, d.Type().Bits())
-		d.SetUint(x)
-	case reflect.Bool:
-		var x bool
-		x, err = strconv.ParseBool(s)
-		d.SetBool(x)
-	case reflect.String:
-		d.SetString(s)
-	case reflect.Slice:
-		if d.Type().Elem().Kind() == reflect.Uint8 {
-			d.SetBytes([]byte(s))
-		} else {
-			err = cannotConvert(d, s)
-		}
-	default:
-		err = cannotConvert(d, s)
-	}
-	return
-}
-
-func convertAssignBulkString(d reflect.Value, s []byte) (err error) {
-	switch d.Type().Kind() {
-	case reflect.Slice:
-		// Handle []byte destination here to avoid unnecessary
-		// []byte -> string -> []byte converion.
-		if d.Type().Elem().Kind() == reflect.Uint8 {
-			d.SetBytes(s)
-		} else {
-			err = cannotConvert(d, s)
-		}
-	default:
-		err = convertAssignString(d, string(s))
-	}
-	return err
-}
-
-func convertAssignInt(d reflect.Value, s int64) (err error) {
-	switch d.Type().Kind() {
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		d.SetInt(s)
-		if d.Int() != s {
-			err = strconv.ErrRange
-			d.SetInt(0)
-		}
-	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
-		if s < 0 {
-			err = strconv.ErrRange
-		} else {
-			x := uint64(s)
-			d.SetUint(x)
-			if d.Uint() != x {
-				err = strconv.ErrRange
-				d.SetUint(0)
-			}
-		}
-	case reflect.Bool:
-		d.SetBool(s != 0)
-	default:
-		err = cannotConvert(d, s)
-	}
-	return
-}
-
-func convertAssignValue(d reflect.Value, s interface{}) (err error) {
-	if d.Kind() != reflect.Ptr {
-		if d.CanAddr() {
-			d2 := d.Addr()
-			if d2.CanInterface() {
-				if scanner, ok := d2.Interface().(Scanner); ok {
-					return scanner.RedisScan(s)
-				}
-			}
-		}
-	} else if d.CanInterface() {
-		// Already a reflect.Ptr
-		if d.IsNil() {
-			d.Set(reflect.New(d.Type().Elem()))
-		}
-		if scanner, ok := d.Interface().(Scanner); ok {
-			return scanner.RedisScan(s)
-		}
-	}
-
-	switch s := s.(type) {
-	case nil:
-		err = convertAssignNil(d)
-	case []byte:
-		err = convertAssignBulkString(d, s)
-	case int64:
-		err = convertAssignInt(d, s)
-	case string:
-		err = convertAssignString(d, s)
-	case Error:
-		err = convertAssignError(d, s)
-	default:
-		err = cannotConvert(d, s)
-	}
-	return err
-}
-
-func convertAssignArray(d reflect.Value, s []interface{}) error {
-	if d.Type().Kind() != reflect.Slice {
-		return cannotConvert(d, s)
-	}
-	ensureLen(d, len(s))
-	for i := 0; i < len(s); i++ {
-		if err := convertAssignValue(d.Index(i), s[i]); err != nil {
-			return err
-		}
-	}
-	return nil
-}
-
-func convertAssign(d interface{}, s interface{}) (err error) {
-	if scanner, ok := d.(Scanner); ok {
-		return scanner.RedisScan(s)
-	}
-
-	// Handle the most common destination types using type switches and
-	// fall back to reflection for all other types.
-	switch s := s.(type) {
-	case nil:
-		// ignore
-	case []byte:
-		switch d := d.(type) {
-		case *string:
-			*d = string(s)
-		case *int:
-			*d, err = strconv.Atoi(string(s))
-		case *bool:
-			*d, err = strconv.ParseBool(string(s))
-		case *[]byte:
-			*d = s
-		case *interface{}:
-			*d = s
-		case nil:
-			// skip value
-		default:
-			if d := reflect.ValueOf(d); d.Type().Kind() != reflect.Ptr {
-				err = cannotConvert(d, s)
-			} else {
-				err = convertAssignBulkString(d.Elem(), s)
-			}
-		}
-	case int64:
-		switch d := d.(type) {
-		case *int:
-			x := int(s)
-			if int64(x) != s {
-				err = strconv.ErrRange
-				x = 0
-			}
-			*d = x
-		case *bool:
-			*d = s != 0
-		case *interface{}:
-			*d = s
-		case nil:
-			// skip value
-		default:
-			if d := reflect.ValueOf(d); d.Type().Kind() != reflect.Ptr {
-				err = cannotConvert(d, s)
-			} else {
-				err = convertAssignInt(d.Elem(), s)
-			}
-		}
-	case string:
-		switch d := d.(type) {
-		case *string:
-			*d = s
-		case *interface{}:
-			*d = s
-		case nil:
-			// skip value
-		default:
-			err = cannotConvert(reflect.ValueOf(d), s)
-		}
-	case []interface{}:
-		switch d := d.(type) {
-		case *[]interface{}:
-			*d = s
-		case *interface{}:
-			*d = s
-		case nil:
-			// skip value
-		default:
-			if d := reflect.ValueOf(d); d.Type().Kind() != reflect.Ptr {
-				err = cannotConvert(d, s)
-			} else {
-				err = convertAssignArray(d.Elem(), s)
-			}
-		}
-	case Error:
-		err = s
-	default:
-		err = cannotConvert(reflect.ValueOf(d), s)
-	}
-	return
-}
-
-// Scan copies from src to the values pointed at by dest.
-//
-// Scan uses RedisScan if available otherwise:
-//
-// The values pointed at by dest must be an integer, float, boolean, string,
-// []byte, interface{} or slices of these types. Scan uses the standard strconv
-// package to convert bulk strings to numeric and boolean types.
-//
-// If a dest value is nil, then the corresponding src value is skipped.
-//
-// If a src element is nil, then the corresponding dest value is not modified.
-//
-// To enable easy use of Scan in a loop, Scan returns the slice of src
-// following the copied values.
-func Scan(src []interface{}, dest ...interface{}) ([]interface{}, error) {
-	if len(src) < len(dest) {
-		return nil, errors.New("redigo.Scan: array short")
-	}
-	var err error
-	for i, d := range dest {
-		err = convertAssign(d, src[i])
-		if err != nil {
-			err = fmt.Errorf("redigo.Scan: cannot assign to dest %d: %v", i, err)
-			break
-		}
-	}
-	return src[len(dest):], err
-}
-
-type fieldSpec struct {
-	name      string
-	index     []int
-	omitEmpty bool
-}
-
-type structSpec struct {
-	m map[string]*fieldSpec
-	l []*fieldSpec
-}
-
-func (ss *structSpec) fieldSpec(name []byte) *fieldSpec {
-	return ss.m[string(name)]
-}
-
-func compileStructSpec(t reflect.Type, depth map[string]int, index []int, ss *structSpec) {
-	for i := 0; i < t.NumField(); i++ {
-		f := t.Field(i)
-		switch {
-		case f.PkgPath != "" && !f.Anonymous:
-			// Ignore unexported fields.
-		case f.Anonymous:
-			// TODO: Handle pointers. Requires change to decoder and
-			// protection against infinite recursion.
-			if f.Type.Kind() == reflect.Struct {
-				compileStructSpec(f.Type, depth, append(index, i), ss)
-			}
-		default:
-			fs := &fieldSpec{name: f.Name}
-			tag := f.Tag.Get("redis")
-			p := strings.Split(tag, ",")
-			if len(p) > 0 {
-				if p[0] == "-" {
-					continue
-				}
-				if len(p[0]) > 0 {
-					fs.name = p[0]
-				}
-				for _, s := range p[1:] {
-					switch s {
-					case "omitempty":
-						fs.omitEmpty = true
-					default:
-						panic(fmt.Errorf("redigo: unknown field tag %s for type %s", s, t.Name()))
-					}
-				}
-			}
-			d, found := depth[fs.name]
-			if !found {
-				d = 1 << 30
-			}
-			switch {
-			case len(index) == d:
-				// At same depth, remove from result.
-				delete(ss.m, fs.name)
-				j := 0
-				for i := 0; i < len(ss.l); i++ {
-					if fs.name != ss.l[i].name {
-						ss.l[j] = ss.l[i]
-						j += 1
-					}
-				}
-				ss.l = ss.l[:j]
-			case len(index) < d:
-				fs.index = make([]int, len(index)+1)
-				copy(fs.index, index)
-				fs.index[len(index)] = i
-				depth[fs.name] = len(index)
-				ss.m[fs.name] = fs
-				ss.l = append(ss.l, fs)
-			}
-		}
-	}
-}
-
-var (
-	structSpecMutex  sync.RWMutex
-	structSpecCache  = make(map[reflect.Type]*structSpec)
-	defaultFieldSpec = &fieldSpec{}
-)
-
-func structSpecForType(t reflect.Type) *structSpec {
-
-	structSpecMutex.RLock()
-	ss, found := structSpecCache[t]
-	structSpecMutex.RUnlock()
-	if found {
-		return ss
-	}
-
-	structSpecMutex.Lock()
-	defer structSpecMutex.Unlock()
-	ss, found = structSpecCache[t]
-	if found {
-		return ss
-	}
-
-	ss = &structSpec{m: make(map[string]*fieldSpec)}
-	compileStructSpec(t, make(map[string]int), nil, ss)
-	structSpecCache[t] = ss
-	return ss
-}
-
-var errScanStructValue = errors.New("redigo.ScanStruct: value must be non-nil pointer to a struct")
-
-// ScanStruct scans alternating names and values from src to a struct. The
-// HGETALL and CONFIG GET commands return replies in this format.
-//
-// ScanStruct uses exported field names to match values in the response. Use
-// 'redis' field tag to override the name:
-//
-//      Field int `redis:"myName"`
-//
-// Fields with the tag redis:"-" are ignored.
-//
-// Each field uses RedisScan if available otherwise:
-// Integer, float, boolean, string and []byte fields are supported. Scan uses the
-// standard strconv package to convert bulk string values to numeric and
-// boolean types.
-//
-// If a src element is nil, then the corresponding field is not modified.
-func ScanStruct(src []interface{}, dest interface{}) error {
-	d := reflect.ValueOf(dest)
-	if d.Kind() != reflect.Ptr || d.IsNil() {
-		return errScanStructValue
-	}
-	d = d.Elem()
-	if d.Kind() != reflect.Struct {
-		return errScanStructValue
-	}
-	ss := structSpecForType(d.Type())
-
-	if len(src)%2 != 0 {
-		return errors.New("redigo.ScanStruct: number of values not a multiple of 2")
-	}
-
-	for i := 0; i < len(src); i += 2 {
-		s := src[i+1]
-		if s == nil {
-			continue
-		}
-		name, ok := src[i].([]byte)
-		if !ok {
-			return fmt.Errorf("redigo.ScanStruct: key %d not a bulk string value", i)
-		}
-		fs := ss.fieldSpec(name)
-		if fs == nil {
-			continue
-		}
-		if err := convertAssignValue(d.FieldByIndex(fs.index), s); err != nil {
-			return fmt.Errorf("redigo.ScanStruct: cannot assign field %s: %v", fs.name, err)
-		}
-	}
-	return nil
-}
-
-var (
-	errScanSliceValue = errors.New("redigo.ScanSlice: dest must be non-nil pointer to a struct")
-)
-
-// ScanSlice scans src to the slice pointed to by dest. The elements the dest
-// slice must be integer, float, boolean, string, struct or pointer to struct
-// values.
-//
-// Struct fields must be integer, float, boolean or string values. All struct
-// fields are used unless a subset is specified using fieldNames.
-func ScanSlice(src []interface{}, dest interface{}, fieldNames ...string) error {
-	d := reflect.ValueOf(dest)
-	if d.Kind() != reflect.Ptr || d.IsNil() {
-		return errScanSliceValue
-	}
-	d = d.Elem()
-	if d.Kind() != reflect.Slice {
-		return errScanSliceValue
-	}
-
-	isPtr := false
-	t := d.Type().Elem()
-	if t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Struct {
-		isPtr = true
-		t = t.Elem()
-	}
-
-	if t.Kind() != reflect.Struct {
-		ensureLen(d, len(src))
-		for i, s := range src {
-			if s == nil {
-				continue
-			}
-			if err := convertAssignValue(d.Index(i), s); err != nil {
-				return fmt.Errorf("redigo.ScanSlice: cannot assign element %d: %v", i, err)
-			}
-		}
-		return nil
-	}
-
-	ss := structSpecForType(t)
-	fss := ss.l
-	if len(fieldNames) > 0 {
-		fss = make([]*fieldSpec, len(fieldNames))
-		for i, name := range fieldNames {
-			fss[i] = ss.m[name]
-			if fss[i] == nil {
-				return fmt.Errorf("redigo.ScanSlice: ScanSlice bad field name %s", name)
-			}
-		}
-	}
-
-	if len(fss) == 0 {
-		return errors.New("redigo.ScanSlice: no struct fields")
-	}
-
-	n := len(src) / len(fss)
-	if n*len(fss) != len(src) {
-		return errors.New("redigo.ScanSlice: length not a multiple of struct field count")
-	}
-
-	ensureLen(d, n)
-	for i := 0; i < n; i++ {
-		d := d.Index(i)
-		if isPtr {
-			if d.IsNil() {
-				d.Set(reflect.New(t))
-			}
-			d = d.Elem()
-		}
-		for j, fs := range fss {
-			s := src[i*len(fss)+j]
-			if s == nil {
-				continue
-			}
-			if err := convertAssignValue(d.FieldByIndex(fs.index), s); err != nil {
-				return fmt.Errorf("redigo.ScanSlice: cannot assign element %d to field %s: %v", i*len(fss)+j, fs.name, err)
-			}
-		}
-	}
-	return nil
-}
-
-// Args is a helper for constructing command arguments from structured values.
-type Args []interface{}
-
-// Add returns the result of appending value to args.
-func (args Args) Add(value ...interface{}) Args {
-	return append(args, value...)
-}
-
-// AddFlat returns the result of appending the flattened value of v to args.
-//
-// Maps are flattened by appending the alternating keys and map values to args.
-//
-// Slices are flattened by appending the slice elements to args.
-//
-// Structs are flattened by appending the alternating names and values of
-// exported fields to args. If v is a nil struct pointer, then nothing is
-// appended. The 'redis' field tag overrides struct field names. See ScanStruct
-// for more information on the use of the 'redis' field tag.
-//
-// Other types are appended to args as is.
-func (args Args) AddFlat(v interface{}) Args {
-	rv := reflect.ValueOf(v)
-	switch rv.Kind() {
-	case reflect.Struct:
-		args = flattenStruct(args, rv)
-	case reflect.Slice:
-		for i := 0; i < rv.Len(); i++ {
-			args = append(args, rv.Index(i).Interface())
-		}
-	case reflect.Map:
-		for _, k := range rv.MapKeys() {
-			args = append(args, k.Interface(), rv.MapIndex(k).Interface())
-		}
-	case reflect.Ptr:
-		if rv.Type().Elem().Kind() == reflect.Struct {
-			if !rv.IsNil() {
-				args = flattenStruct(args, rv.Elem())
-			}
-		} else {
-			args = append(args, v)
-		}
-	default:
-		args = append(args, v)
-	}
-	return args
-}
-
-func flattenStruct(args Args, v reflect.Value) Args {
-	ss := structSpecForType(v.Type())
-	for _, fs := range ss.l {
-		fv := v.FieldByIndex(fs.index)
-		if fs.omitEmpty {
-			var empty = false
-			switch fv.Kind() {
-			case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
-				empty = fv.Len() == 0
-			case reflect.Bool:
-				empty = !fv.Bool()
-			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-				empty = fv.Int() == 0
-			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-				empty = fv.Uint() == 0
-			case reflect.Float32, reflect.Float64:
-				empty = fv.Float() == 0
-			case reflect.Interface, reflect.Ptr:
-				empty = fv.IsNil()
-			}
-			if empty {
-				continue
-			}
-		}
-		args = append(args, fs.name, fv.Interface())
-	}
-	return args
-}

+ 0 - 513
src/github.com/gomodule/redigo/redis/scan_test.go

@@ -1,513 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package redis_test
-
-import (
-	"fmt"
-	"math"
-	"reflect"
-	"testing"
-	"time"
-
-	"github.com/gomodule/redigo/redis"
-)
-
-type durationScan struct {
-	time.Duration `redis:"sd"`
-}
-
-func (t *durationScan) RedisScan(src interface{}) (err error) {
-	if t == nil {
-		return fmt.Errorf("nil pointer")
-	}
-	switch src := src.(type) {
-	case string:
-		t.Duration, err = time.ParseDuration(src)
-	case []byte:
-		t.Duration, err = time.ParseDuration(string(src))
-	case int64:
-		t.Duration = time.Duration(src)
-	default:
-		err = fmt.Errorf("cannot convert from %T to %T", src, t)
-	}
-	return err
-}
-
-var scanConversionTests = []struct {
-	src  interface{}
-	dest interface{}
-}{
-	{[]byte("-inf"), math.Inf(-1)},
-	{[]byte("+inf"), math.Inf(1)},
-	{[]byte("0"), float64(0)},
-	{[]byte("3.14159"), float64(3.14159)},
-	{[]byte("3.14"), float32(3.14)},
-	{[]byte("-100"), int(-100)},
-	{[]byte("101"), int(101)},
-	{int64(102), int(102)},
-	{[]byte("103"), uint(103)},
-	{int64(104), uint(104)},
-	{[]byte("105"), int8(105)},
-	{int64(106), int8(106)},
-	{[]byte("107"), uint8(107)},
-	{int64(108), uint8(108)},
-	{[]byte("0"), false},
-	{int64(0), false},
-	{[]byte("f"), false},
-	{[]byte("1"), true},
-	{int64(1), true},
-	{[]byte("t"), true},
-	{"hello", "hello"},
-	{[]byte("hello"), "hello"},
-	{[]byte("world"), []byte("world")},
-	{nil, ""},
-	{nil, []byte(nil)},
-
-	{[]interface{}{[]byte("b1")}, []interface{}{[]byte("b1")}},
-	{[]interface{}{[]byte("b2")}, []string{"b2"}},
-	{[]interface{}{[]byte("b3"), []byte("b4")}, []string{"b3", "b4"}},
-	{[]interface{}{[]byte("b5")}, [][]byte{[]byte("b5")}},
-	{[]interface{}{[]byte("1")}, []int{1}},
-	{[]interface{}{[]byte("1"), []byte("2")}, []int{1, 2}},
-	{[]interface{}{[]byte("1"), []byte("2")}, []float64{1, 2}},
-	{[]interface{}{[]byte("1")}, []byte{1}},
-	{[]interface{}{[]byte("1")}, []bool{true}},
-
-	{[]interface{}{"s1"}, []interface{}{"s1"}},
-	{[]interface{}{"s2"}, [][]byte{[]byte("s2")}},
-	{[]interface{}{"s3", "s4"}, []string{"s3", "s4"}},
-	{[]interface{}{"s5"}, [][]byte{[]byte("s5")}},
-	{[]interface{}{"1"}, []int{1}},
-	{[]interface{}{"1", "2"}, []int{1, 2}},
-	{[]interface{}{"1", "2"}, []float64{1, 2}},
-	{[]interface{}{"1"}, []byte{1}},
-	{[]interface{}{"1"}, []bool{true}},
-
-	{[]interface{}{nil, "2"}, []interface{}{nil, "2"}},
-	{[]interface{}{nil, []byte("2")}, [][]byte{nil, []byte("2")}},
-
-	{[]interface{}{redis.Error("e1")}, []interface{}{redis.Error("e1")}},
-	{[]interface{}{redis.Error("e2")}, [][]byte{[]byte("e2")}},
-	{[]interface{}{redis.Error("e3")}, []string{"e3"}},
-
-	{"1m", durationScan{Duration: time.Minute}},
-	{[]byte("1m"), durationScan{Duration: time.Minute}},
-	{time.Minute.Nanoseconds(), durationScan{Duration: time.Minute}},
-	{[]interface{}{[]byte("1m")}, []durationScan{{Duration: time.Minute}}},
-	{[]interface{}{[]byte("1m")}, []*durationScan{{Duration: time.Minute}}},
-}
-
-func TestScanConversion(t *testing.T) {
-	for _, tt := range scanConversionTests {
-		values := []interface{}{tt.src}
-		dest := reflect.New(reflect.TypeOf(tt.dest))
-		values, err := redis.Scan(values, dest.Interface())
-		if err != nil {
-			t.Errorf("Scan(%v) returned error %v", tt, err)
-			continue
-		}
-		if !reflect.DeepEqual(tt.dest, dest.Elem().Interface()) {
-			t.Errorf("Scan(%v) returned %v, want %v", tt, dest.Elem().Interface(), tt.dest)
-		}
-	}
-}
-
-var scanConversionErrorTests = []struct {
-	src  interface{}
-	dest interface{}
-}{
-	{[]byte("1234"), byte(0)},
-	{int64(1234), byte(0)},
-	{[]byte("-1"), byte(0)},
-	{int64(-1), byte(0)},
-	{[]byte("junk"), false},
-	{redis.Error("blah"), false},
-	{redis.Error("blah"), durationScan{Duration: time.Minute}},
-	{"invalid", durationScan{Duration: time.Minute}},
-}
-
-func TestScanConversionError(t *testing.T) {
-	for _, tt := range scanConversionErrorTests {
-		values := []interface{}{tt.src}
-		dest := reflect.New(reflect.TypeOf(tt.dest))
-		values, err := redis.Scan(values, dest.Interface())
-		if err == nil {
-			t.Errorf("Scan(%v) did not return error", tt)
-		}
-	}
-}
-
-func ExampleScan() {
-	c, err := dial()
-	if err != nil {
-		fmt.Println(err)
-		return
-	}
-	defer c.Close()
-
-	c.Send("HMSET", "album:1", "title", "Red", "rating", 5)
-	c.Send("HMSET", "album:2", "title", "Earthbound", "rating", 1)
-	c.Send("HMSET", "album:3", "title", "Beat")
-	c.Send("LPUSH", "albums", "1")
-	c.Send("LPUSH", "albums", "2")
-	c.Send("LPUSH", "albums", "3")
-	values, err := redis.Values(c.Do("SORT", "albums",
-		"BY", "album:*->rating",
-		"GET", "album:*->title",
-		"GET", "album:*->rating"))
-	if err != nil {
-		fmt.Println(err)
-		return
-	}
-
-	for len(values) > 0 {
-		var title string
-		rating := -1 // initialize to illegal value to detect nil.
-		values, err = redis.Scan(values, &title, &rating)
-		if err != nil {
-			fmt.Println(err)
-			return
-		}
-		if rating == -1 {
-			fmt.Println(title, "not-rated")
-		} else {
-			fmt.Println(title, rating)
-		}
-	}
-	// Output:
-	// Beat not-rated
-	// Earthbound 1
-	// Red 5
-}
-
-type s0 struct {
-	X  int
-	Y  int `redis:"y"`
-	Bt bool
-}
-
-type s1 struct {
-	X  int    `redis:"-"`
-	I  int    `redis:"i"`
-	U  uint   `redis:"u"`
-	S  string `redis:"s"`
-	P  []byte `redis:"p"`
-	B  bool   `redis:"b"`
-	Bt bool
-	Bf bool
-	s0
-	Sd  durationScan  `redis:"sd"`
-	Sdp *durationScan `redis:"sdp"`
-}
-
-var scanStructTests = []struct {
-	title string
-	reply []string
-	value interface{}
-}{
-	{"basic",
-		[]string{
-			"i", "-1234",
-			"u", "5678",
-			"s", "hello",
-			"p", "world",
-			"b", "t",
-			"Bt", "1",
-			"Bf", "0",
-			"X", "123",
-			"y", "456",
-			"sd", "1m",
-			"sdp", "1m",
-		},
-		&s1{
-			I:   -1234,
-			U:   5678,
-			S:   "hello",
-			P:   []byte("world"),
-			B:   true,
-			Bt:  true,
-			Bf:  false,
-			s0:  s0{X: 123, Y: 456},
-			Sd:  durationScan{Duration: time.Minute},
-			Sdp: &durationScan{Duration: time.Minute},
-		},
-	},
-	{"absent values",
-		[]string{},
-		&s1{},
-	},
-}
-
-func TestScanStruct(t *testing.T) {
-	for _, tt := range scanStructTests {
-
-		var reply []interface{}
-		for _, v := range tt.reply {
-			reply = append(reply, []byte(v))
-		}
-
-		value := reflect.New(reflect.ValueOf(tt.value).Type().Elem())
-
-		if err := redis.ScanStruct(reply, value.Interface()); err != nil {
-			t.Fatalf("ScanStruct(%s) returned error %v", tt.title, err)
-		}
-
-		if !reflect.DeepEqual(value.Interface(), tt.value) {
-			t.Fatalf("ScanStruct(%s) returned %v, want %v", tt.title, value.Interface(), tt.value)
-		}
-	}
-}
-
-func TestBadScanStructArgs(t *testing.T) {
-	x := []interface{}{"A", "b"}
-	test := func(v interface{}) {
-		if err := redis.ScanStruct(x, v); err == nil {
-			t.Errorf("Expect error for ScanStruct(%T, %T)", x, v)
-		}
-	}
-
-	test(nil)
-
-	var v0 *struct{}
-	test(v0)
-
-	var v1 int
-	test(&v1)
-
-	x = x[:1]
-	v2 := struct{ A string }{}
-	test(&v2)
-}
-
-var scanSliceTests = []struct {
-	src        []interface{}
-	fieldNames []string
-	ok         bool
-	dest       interface{}
-}{
-	{
-		[]interface{}{[]byte("1"), nil, []byte("-1")},
-		nil,
-		true,
-		[]int{1, 0, -1},
-	},
-	{
-		[]interface{}{[]byte("1"), nil, []byte("2")},
-		nil,
-		true,
-		[]uint{1, 0, 2},
-	},
-	{
-		[]interface{}{[]byte("-1")},
-		nil,
-		false,
-		[]uint{1},
-	},
-	{
-		[]interface{}{[]byte("hello"), nil, []byte("world")},
-		nil,
-		true,
-		[][]byte{[]byte("hello"), nil, []byte("world")},
-	},
-	{
-		[]interface{}{[]byte("hello"), nil, []byte("world")},
-		nil,
-		true,
-		[]string{"hello", "", "world"},
-	},
-	{
-		[]interface{}{[]byte("a1"), []byte("b1"), []byte("a2"), []byte("b2")},
-		nil,
-		true,
-		[]struct{ A, B string }{{"a1", "b1"}, {"a2", "b2"}},
-	},
-	{
-		[]interface{}{[]byte("a1"), []byte("b1")},
-		nil,
-		false,
-		[]struct{ A, B, C string }{{"a1", "b1", ""}},
-	},
-	{
-		[]interface{}{[]byte("a1"), []byte("b1"), []byte("a2"), []byte("b2")},
-		nil,
-		true,
-		[]*struct{ A, B string }{{A: "a1", B: "b1"}, {A: "a2", B: "b2"}},
-	},
-	{
-		[]interface{}{[]byte("a1"), []byte("b1"), []byte("a2"), []byte("b2")},
-		[]string{"A", "B"},
-		true,
-		[]struct{ A, C, B string }{{"a1", "", "b1"}, {"a2", "", "b2"}},
-	},
-	{
-		[]interface{}{[]byte("a1"), []byte("b1"), []byte("a2"), []byte("b2")},
-		nil,
-		false,
-		[]struct{}{},
-	},
-}
-
-func TestScanSlice(t *testing.T) {
-	for _, tt := range scanSliceTests {
-
-		typ := reflect.ValueOf(tt.dest).Type()
-		dest := reflect.New(typ)
-
-		err := redis.ScanSlice(tt.src, dest.Interface(), tt.fieldNames...)
-		if tt.ok != (err == nil) {
-			t.Errorf("ScanSlice(%v, []%s, %v) returned error %v", tt.src, typ, tt.fieldNames, err)
-			continue
-		}
-		if tt.ok && !reflect.DeepEqual(dest.Elem().Interface(), tt.dest) {
-			t.Errorf("ScanSlice(src, []%s) returned %#v, want %#v", typ, dest.Elem().Interface(), tt.dest)
-		}
-	}
-}
-
-func ExampleScanSlice() {
-	c, err := dial()
-	if err != nil {
-		fmt.Println(err)
-		return
-	}
-	defer c.Close()
-
-	c.Send("HMSET", "album:1", "title", "Red", "rating", 5)
-	c.Send("HMSET", "album:2", "title", "Earthbound", "rating", 1)
-	c.Send("HMSET", "album:3", "title", "Beat", "rating", 4)
-	c.Send("LPUSH", "albums", "1")
-	c.Send("LPUSH", "albums", "2")
-	c.Send("LPUSH", "albums", "3")
-	values, err := redis.Values(c.Do("SORT", "albums",
-		"BY", "album:*->rating",
-		"GET", "album:*->title",
-		"GET", "album:*->rating"))
-	if err != nil {
-		fmt.Println(err)
-		return
-	}
-
-	var albums []struct {
-		Title  string
-		Rating int
-	}
-	if err := redis.ScanSlice(values, &albums); err != nil {
-		fmt.Println(err)
-		return
-	}
-	fmt.Printf("%v\n", albums)
-	// Output:
-	// [{Earthbound 1} {Beat 4} {Red 5}]
-}
-
-var argsTests = []struct {
-	title    string
-	actual   redis.Args
-	expected redis.Args
-}{
-	{"struct ptr",
-		redis.Args{}.AddFlat(&struct {
-			I  int               `redis:"i"`
-			U  uint              `redis:"u"`
-			S  string            `redis:"s"`
-			P  []byte            `redis:"p"`
-			M  map[string]string `redis:"m"`
-			Bt bool
-			Bf bool
-		}{
-			-1234, 5678, "hello", []byte("world"), map[string]string{"hello": "world"}, true, false,
-		}),
-		redis.Args{"i", int(-1234), "u", uint(5678), "s", "hello", "p", []byte("world"), "m", map[string]string{"hello": "world"}, "Bt", true, "Bf", false},
-	},
-	{"struct",
-		redis.Args{}.AddFlat(struct{ I int }{123}),
-		redis.Args{"I", 123},
-	},
-	{"slice",
-		redis.Args{}.Add(1).AddFlat([]string{"a", "b", "c"}).Add(2),
-		redis.Args{1, "a", "b", "c", 2},
-	},
-	{"struct omitempty",
-		redis.Args{}.AddFlat(&struct {
-			Sdp *durationArg `redis:"Sdp,omitempty"`
-		}{
-			nil,
-		}),
-		redis.Args{},
-	},
-}
-
-func TestArgs(t *testing.T) {
-	for _, tt := range argsTests {
-		if !reflect.DeepEqual(tt.actual, tt.expected) {
-			t.Fatalf("%s is %v, want %v", tt.title, tt.actual, tt.expected)
-		}
-	}
-}
-
-func ExampleArgs() {
-	c, err := dial()
-	if err != nil {
-		fmt.Println(err)
-		return
-	}
-	defer c.Close()
-
-	var p1, p2 struct {
-		Title  string `redis:"title"`
-		Author string `redis:"author"`
-		Body   string `redis:"body"`
-	}
-
-	p1.Title = "Example"
-	p1.Author = "Gary"
-	p1.Body = "Hello"
-
-	if _, err := c.Do("HMSET", redis.Args{}.Add("id1").AddFlat(&p1)...); err != nil {
-		fmt.Println(err)
-		return
-	}
-
-	m := map[string]string{
-		"title":  "Example2",
-		"author": "Steve",
-		"body":   "Map",
-	}
-
-	if _, err := c.Do("HMSET", redis.Args{}.Add("id2").AddFlat(m)...); err != nil {
-		fmt.Println(err)
-		return
-	}
-
-	for _, id := range []string{"id1", "id2"} {
-
-		v, err := redis.Values(c.Do("HGETALL", id))
-		if err != nil {
-			fmt.Println(err)
-			return
-		}
-
-		if err := redis.ScanStruct(v, &p2); err != nil {
-			fmt.Println(err)
-			return
-		}
-
-		fmt.Printf("%+v\n", p2)
-	}
-
-	// Output:
-	// {Title:Example Author:Gary Body:Hello}
-	// {Title:Example2 Author:Steve Body:Map}
-}

+ 0 - 91
src/github.com/gomodule/redigo/redis/script.go

@@ -1,91 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package redis
-
-import (
-	"crypto/sha1"
-	"encoding/hex"
-	"io"
-	"strings"
-)
-
-// Script encapsulates the source, hash and key count for a Lua script. See
-// http://redis.io/commands/eval for information on scripts in Redis.
-type Script struct {
-	keyCount int
-	src      string
-	hash     string
-}
-
-// NewScript returns a new script object. If keyCount is greater than or equal
-// to zero, then the count is automatically inserted in the EVAL command
-// argument list. If keyCount is less than zero, then the application supplies
-// the count as the first value in the keysAndArgs argument to the Do, Send and
-// SendHash methods.
-func NewScript(keyCount int, src string) *Script {
-	h := sha1.New()
-	io.WriteString(h, src)
-	return &Script{keyCount, src, hex.EncodeToString(h.Sum(nil))}
-}
-
-func (s *Script) args(spec string, keysAndArgs []interface{}) []interface{} {
-	var args []interface{}
-	if s.keyCount < 0 {
-		args = make([]interface{}, 1+len(keysAndArgs))
-		args[0] = spec
-		copy(args[1:], keysAndArgs)
-	} else {
-		args = make([]interface{}, 2+len(keysAndArgs))
-		args[0] = spec
-		args[1] = s.keyCount
-		copy(args[2:], keysAndArgs)
-	}
-	return args
-}
-
-// Hash returns the script hash.
-func (s *Script) Hash() string {
-	return s.hash
-}
-
-// Do evaluates the script. Under the covers, Do optimistically evaluates the
-// script using the EVALSHA command. If the command fails because the script is
-// not loaded, then Do evaluates the script using the EVAL command (thus
-// causing the script to load).
-func (s *Script) Do(c Conn, keysAndArgs ...interface{}) (interface{}, error) {
-	v, err := c.Do("EVALSHA", s.args(s.hash, keysAndArgs)...)
-	if e, ok := err.(Error); ok && strings.HasPrefix(string(e), "NOSCRIPT ") {
-		v, err = c.Do("EVAL", s.args(s.src, keysAndArgs)...)
-	}
-	return v, err
-}
-
-// SendHash evaluates the script without waiting for the reply. The script is
-// evaluated with the EVALSHA command. The application must ensure that the
-// script is loaded by a previous call to Send, Do or Load methods.
-func (s *Script) SendHash(c Conn, keysAndArgs ...interface{}) error {
-	return c.Send("EVALSHA", s.args(s.hash, keysAndArgs)...)
-}
-
-// Send evaluates the script without waiting for the reply.
-func (s *Script) Send(c Conn, keysAndArgs ...interface{}) error {
-	return c.Send("EVAL", s.args(s.src, keysAndArgs)...)
-}
-
-// Load loads the script without evaluating it.
-func (s *Script) Load(c Conn) error {
-	_, err := c.Do("SCRIPT", "LOAD", s.src)
-	return err
-}

+ 0 - 100
src/github.com/gomodule/redigo/redis/script_test.go

@@ -1,100 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package redis_test
-
-import (
-	"fmt"
-	"reflect"
-	"testing"
-	"time"
-
-	"github.com/gomodule/redigo/redis"
-)
-
-var (
-	// These variables are declared at package level to remove distracting
-	// details from the examples.
-	c     redis.Conn
-	reply interface{}
-	err   error
-)
-
-func ExampleScript() {
-	// Initialize a package-level variable with a script.
-	var getScript = redis.NewScript(1, `return redis.call('get', KEYS[1])`)
-
-	// In a function, use the script Do method to evaluate the script. The Do
-	// method optimistically uses the EVALSHA command. If the script is not
-	// loaded, then the Do method falls back to the EVAL command.
-	reply, err = getScript.Do(c, "foo")
-}
-
-func TestScript(t *testing.T) {
-	c, err := redis.DialDefaultServer()
-	if err != nil {
-		t.Fatalf("error connection to database, %v", err)
-	}
-	defer c.Close()
-
-	// To test fall back in Do, we make script unique by adding comment with current time.
-	script := fmt.Sprintf("--%d\nreturn {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}", time.Now().UnixNano())
-	s := redis.NewScript(2, script)
-	reply := []interface{}{[]byte("key1"), []byte("key2"), []byte("arg1"), []byte("arg2")}
-
-	v, err := s.Do(c, "key1", "key2", "arg1", "arg2")
-	if err != nil {
-		t.Errorf("s.Do(c, ...) returned %v", err)
-	}
-
-	if !reflect.DeepEqual(v, reply) {
-		t.Errorf("s.Do(c, ..); = %v, want %v", v, reply)
-	}
-
-	err = s.Load(c)
-	if err != nil {
-		t.Errorf("s.Load(c) returned %v", err)
-	}
-
-	err = s.SendHash(c, "key1", "key2", "arg1", "arg2")
-	if err != nil {
-		t.Errorf("s.SendHash(c, ...) returned %v", err)
-	}
-
-	err = c.Flush()
-	if err != nil {
-		t.Errorf("c.Flush() returned %v", err)
-	}
-
-	v, err = c.Receive()
-	if !reflect.DeepEqual(v, reply) {
-		t.Errorf("s.SendHash(c, ..); c.Receive() = %v, want %v", v, reply)
-	}
-
-	err = s.Send(c, "key1", "key2", "arg1", "arg2")
-	if err != nil {
-		t.Errorf("s.Send(c, ...) returned %v", err)
-	}
-
-	err = c.Flush()
-	if err != nil {
-		t.Errorf("c.Flush() returned %v", err)
-	}
-
-	v, err = c.Receive()
-	if !reflect.DeepEqual(v, reply) {
-		t.Errorf("s.Send(c, ..); c.Receive() = %v, want %v", v, reply)
-	}
-
-}

+ 0 - 183
src/github.com/gomodule/redigo/redis/test_test.go

@@ -1,183 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package redis
-
-import (
-	"bufio"
-	"errors"
-	"flag"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"os"
-	"os/exec"
-	"strconv"
-	"strings"
-	"sync"
-	"testing"
-	"time"
-)
-
-func SetNowFunc(f func() time.Time) {
-	nowFunc = f
-}
-
-var (
-	ErrNegativeInt = errNegativeInt
-
-	serverPath     = flag.String("redis-server", "redis-server", "Path to redis server binary")
-	serverAddress  = flag.String("redis-address", "127.0.0.1", "The address of the server")
-	serverBasePort = flag.Int("redis-port", 16379, "Beginning of port range for test servers")
-	serverLogName  = flag.String("redis-log", "", "Write Redis server logs to `filename`")
-	serverLog      = ioutil.Discard
-
-	defaultServerMu  sync.Mutex
-	defaultServer    *Server
-	defaultServerErr error
-)
-
-type Server struct {
-	name string
-	cmd  *exec.Cmd
-	done chan struct{}
-}
-
-func NewServer(name string, args ...string) (*Server, error) {
-	s := &Server{
-		name: name,
-		cmd:  exec.Command(*serverPath, args...),
-		done: make(chan struct{}),
-	}
-
-	r, err := s.cmd.StdoutPipe()
-	if err != nil {
-		return nil, err
-	}
-
-	err = s.cmd.Start()
-	if err != nil {
-		return nil, err
-	}
-
-	ready := make(chan error, 1)
-	go s.watch(r, ready)
-
-	select {
-	case err = <-ready:
-	case <-time.After(time.Second * 10):
-		err = errors.New("timeout waiting for server to start")
-	}
-
-	if err != nil {
-		s.Stop()
-		return nil, err
-	}
-
-	return s, nil
-}
-
-func (s *Server) watch(r io.Reader, ready chan error) {
-	fmt.Fprintf(serverLog, "%d START %s \n", s.cmd.Process.Pid, s.name)
-	var listening bool
-	var text string
-	scn := bufio.NewScanner(r)
-	for scn.Scan() {
-		text = scn.Text()
-		fmt.Fprintf(serverLog, "%s\n", text)
-		if !listening {
-			if strings.Contains(text, " * Ready to accept connections") ||
-				strings.Contains(text, " * The server is now ready to accept connections on port") {
-				listening = true
-				ready <- nil
-			}
-		}
-	}
-	if !listening {
-		ready <- fmt.Errorf("server exited: %s", text)
-	}
-	s.cmd.Wait()
-	fmt.Fprintf(serverLog, "%d STOP %s \n", s.cmd.Process.Pid, s.name)
-	close(s.done)
-}
-
-func (s *Server) Stop() {
-	s.cmd.Process.Signal(os.Interrupt)
-	<-s.done
-}
-
-// stopDefaultServer stops the server created by DialDefaultServer.
-func stopDefaultServer() {
-	defaultServerMu.Lock()
-	defer defaultServerMu.Unlock()
-	if defaultServer != nil {
-		defaultServer.Stop()
-		defaultServer = nil
-	}
-}
-
-// DefaultServerAddr starts the test server if not already started and returns
-// the address of that server.
-func DefaultServerAddr() (string, error) {
-	defaultServerMu.Lock()
-	defer defaultServerMu.Unlock()
-	addr := fmt.Sprintf("%v:%d", *serverAddress, *serverBasePort)
-	if defaultServer != nil || defaultServerErr != nil {
-		return addr, defaultServerErr
-	}
-	defaultServer, defaultServerErr = NewServer(
-		"default",
-		"--port", strconv.Itoa(*serverBasePort),
-		"--bind", *serverAddress,
-		"--save", "",
-		"--appendonly", "no")
-	return addr, defaultServerErr
-}
-
-// DialDefaultServer starts the test server if not already started and dials a
-// connection to the server.
-func DialDefaultServer(options ...DialOption) (Conn, error) {
-	addr, err := DefaultServerAddr()
-	if err != nil {
-		return nil, err
-	}
-	c, err := Dial("tcp", addr, append([]DialOption{DialReadTimeout(1 * time.Second), DialWriteTimeout(1 * time.Second)}, options...)...)
-	if err != nil {
-		return nil, err
-	}
-	c.Do("FLUSHDB")
-	return c, nil
-}
-
-func TestMain(m *testing.M) {
-	os.Exit(func() int {
-		flag.Parse()
-
-		var f *os.File
-		if *serverLogName != "" {
-			var err error
-			f, err = os.OpenFile(*serverLogName, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0600)
-			if err != nil {
-				fmt.Fprintf(os.Stderr, "Error opening redis-log: %v\n", err)
-				return 1
-			}
-			defer f.Close()
-			serverLog = f
-		}
-
-		defer stopDefaultServer()
-
-		return m.Run()
-	}())
-}

+ 0 - 114
src/github.com/gomodule/redigo/redis/zpop_example_test.go

@@ -1,114 +0,0 @@
-// Copyright 2013 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package redis_test
-
-import (
-	"fmt"
-
-	"github.com/gomodule/redigo/redis"
-)
-
-// zpop pops a value from the ZSET key using WATCH/MULTI/EXEC commands.
-func zpop(c redis.Conn, key string) (result string, err error) {
-
-	defer func() {
-		// Return connection to normal state on error.
-		if err != nil {
-			c.Do("DISCARD")
-		}
-	}()
-
-	// Loop until transaction is successful.
-	for {
-		if _, err := c.Do("WATCH", key); err != nil {
-			return "", err
-		}
-
-		members, err := redis.Strings(c.Do("ZRANGE", key, 0, 0))
-		if err != nil {
-			return "", err
-		}
-		if len(members) != 1 {
-			return "", redis.ErrNil
-		}
-
-		c.Send("MULTI")
-		c.Send("ZREM", key, members[0])
-		queued, err := c.Do("EXEC")
-		if err != nil {
-			return "", err
-		}
-
-		if queued != nil {
-			result = members[0]
-			break
-		}
-	}
-
-	return result, nil
-}
-
-// zpopScript pops a value from a ZSET.
-var zpopScript = redis.NewScript(1, `
-    local r = redis.call('ZRANGE', KEYS[1], 0, 0)
-    if r ~= nil then
-        r = r[1]
-        redis.call('ZREM', KEYS[1], r)
-    end
-    return r
-`)
-
-// This example implements ZPOP as described at
-// http://redis.io/topics/transactions using WATCH/MULTI/EXEC and scripting.
-func Example_zpop() {
-	c, err := dial()
-	if err != nil {
-		fmt.Println(err)
-		return
-	}
-	defer c.Close()
-
-	// Add test data using a pipeline.
-
-	for i, member := range []string{"red", "blue", "green"} {
-		c.Send("ZADD", "zset", i, member)
-	}
-	if _, err := c.Do(""); err != nil {
-		fmt.Println(err)
-		return
-	}
-
-	// Pop using WATCH/MULTI/EXEC
-
-	v, err := zpop(c, "zset")
-	if err != nil {
-		fmt.Println(err)
-		return
-	}
-	fmt.Println(v)
-
-	// Pop using a script.
-
-	v, err = redis.String(zpopScript.Do(c, "zset"))
-	if err != nil {
-		fmt.Println(err)
-		return
-	}
-	fmt.Println(v)
-
-	// Output:
-	// red
-	// blue
-}

+ 0 - 54
src/github.com/gomodule/redigo/redisx/commandinfo.go

@@ -1,54 +0,0 @@
-// Copyright 2014 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package redisx
-
-import (
-	"strings"
-)
-
-const (
-	connectionWatchState = 1 << iota
-	connectionMultiState
-	connectionSubscribeState
-	connectionMonitorState
-)
-
-type commandInfo struct {
-	notMuxable bool
-}
-
-var commandInfos = map[string]commandInfo{
-	"WATCH":      {notMuxable: true},
-	"UNWATCH":    {notMuxable: true},
-	"MULTI":      {notMuxable: true},
-	"EXEC":       {notMuxable: true},
-	"DISCARD":    {notMuxable: true},
-	"PSUBSCRIBE": {notMuxable: true},
-	"SUBSCRIBE":  {notMuxable: true},
-	"MONITOR":    {notMuxable: true},
-}
-
-func init() {
-	for n, ci := range commandInfos {
-		commandInfos[strings.ToLower(n)] = ci
-	}
-}
-
-func lookupCommandInfo(commandName string) commandInfo {
-	if ci, ok := commandInfos[commandName]; ok {
-		return ci
-	}
-	return commandInfos[strings.ToUpper(commandName)]
-}

+ 0 - 11
src/github.com/gomodule/redigo/redisx/commandinfo_test.go

@@ -1,11 +0,0 @@
-package redisx
-
-import "testing"
-
-func TestLookupCommandInfo(t *testing.T) {
-	for _, n := range []string{"watch", "WATCH", "wAtch"} {
-		if lookupCommandInfo(n) == (commandInfo{}) {
-			t.Errorf("LookupCommandInfo(%q) = CommandInfo{}, expected non-zero value", n)
-		}
-	}
-}

+ 0 - 151
src/github.com/gomodule/redigo/redisx/connmux.go

@@ -1,151 +0,0 @@
-// Copyright 2014 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package redisx
-
-import (
-	"errors"
-	"sync"
-
-	"github.com/gomodule/redigo/redis"
-)
-
-// ConnMux multiplexes one or more connections to a single underlying
-// connection. The ConnMux connections do not support concurrency, commands
-// that associate server side state with the connection or commands that put
-// the connection in a special mode.
-type ConnMux struct {
-	c redis.Conn
-
-	sendMu sync.Mutex
-	sendID uint
-
-	recvMu   sync.Mutex
-	recvID   uint
-	recvWait map[uint]chan struct{}
-}
-
-func NewConnMux(c redis.Conn) *ConnMux {
-	return &ConnMux{c: c, recvWait: make(map[uint]chan struct{})}
-}
-
-// Get gets a connection. The application must close the returned connection.
-func (p *ConnMux) Get() redis.Conn {
-	c := &muxConn{p: p}
-	c.ids = c.buf[:0]
-	return c
-}
-
-// Close closes the underlying connection.
-func (p *ConnMux) Close() error {
-	return p.c.Close()
-}
-
-type muxConn struct {
-	p   *ConnMux
-	ids []uint
-	buf [8]uint
-}
-
-func (c *muxConn) send(flush bool, cmd string, args ...interface{}) error {
-	if lookupCommandInfo(cmd).notMuxable {
-		return errors.New("command not supported by mux pool")
-	}
-	p := c.p
-	p.sendMu.Lock()
-	id := p.sendID
-	c.ids = append(c.ids, id)
-	p.sendID++
-	err := p.c.Send(cmd, args...)
-	if flush {
-		err = p.c.Flush()
-	}
-	p.sendMu.Unlock()
-	return err
-}
-
-func (c *muxConn) Send(cmd string, args ...interface{}) error {
-	return c.send(false, cmd, args...)
-}
-
-func (c *muxConn) Flush() error {
-	p := c.p
-	p.sendMu.Lock()
-	err := p.c.Flush()
-	p.sendMu.Unlock()
-	return err
-}
-
-func (c *muxConn) Receive() (interface{}, error) {
-	if len(c.ids) == 0 {
-		return nil, errors.New("mux pool underflow")
-	}
-
-	id := c.ids[0]
-	c.ids = c.ids[1:]
-	if len(c.ids) == 0 {
-		c.ids = c.buf[:0]
-	}
-
-	p := c.p
-	p.recvMu.Lock()
-	if p.recvID != id {
-		ch := make(chan struct{})
-		p.recvWait[id] = ch
-		p.recvMu.Unlock()
-		<-ch
-		p.recvMu.Lock()
-		if p.recvID != id {
-			panic("out of sync")
-		}
-	}
-
-	v, err := p.c.Receive()
-
-	id++
-	p.recvID = id
-	ch, ok := p.recvWait[id]
-	if ok {
-		delete(p.recvWait, id)
-	}
-	p.recvMu.Unlock()
-	if ok {
-		ch <- struct{}{}
-	}
-
-	return v, err
-}
-
-func (c *muxConn) Close() error {
-	var err error
-	if len(c.ids) == 0 {
-		return nil
-	}
-	c.Flush()
-	for _ = range c.ids {
-		_, err = c.Receive()
-	}
-	return err
-}
-
-func (c *muxConn) Do(cmd string, args ...interface{}) (interface{}, error) {
-	if err := c.send(true, cmd, args...); err != nil {
-		return nil, err
-	}
-	return c.Receive()
-}
-
-func (c *muxConn) Err() error {
-	return c.p.c.Err()
-}

+ 0 - 258
src/github.com/gomodule/redigo/redisx/connmux_test.go

@@ -1,258 +0,0 @@
-// Copyright 2014 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package redisx_test
-
-import (
-	"net/textproto"
-	"sync"
-	"testing"
-
-	"github.com/gomodule/redigo/redis"
-	"github.com/gomodule/redigo/redisx"
-)
-
-func TestConnMux(t *testing.T) {
-	c, err := redisx.DialTest()
-	if err != nil {
-		t.Fatalf("error connection to database, %v", err)
-	}
-	m := redisx.NewConnMux(c)
-	defer m.Close()
-
-	c1 := m.Get()
-	c2 := m.Get()
-	c1.Send("ECHO", "hello")
-	c2.Send("ECHO", "world")
-	c1.Flush()
-	c2.Flush()
-	s, err := redis.String(c1.Receive())
-	if err != nil {
-		t.Fatal(err)
-	}
-	if s != "hello" {
-		t.Fatalf("echo returned %q, want %q", s, "hello")
-	}
-	s, err = redis.String(c2.Receive())
-	if err != nil {
-		t.Fatal(err)
-	}
-	if s != "world" {
-		t.Fatalf("echo returned %q, want %q", s, "world")
-	}
-	c1.Close()
-	c2.Close()
-}
-
-func TestConnMuxClose(t *testing.T) {
-	c, err := redisx.DialTest()
-	if err != nil {
-		t.Fatalf("error connection to database, %v", err)
-	}
-	m := redisx.NewConnMux(c)
-	defer m.Close()
-
-	c1 := m.Get()
-	c2 := m.Get()
-
-	if err := c1.Send("ECHO", "hello"); err != nil {
-		t.Fatal(err)
-	}
-	if err := c1.Close(); err != nil {
-		t.Fatal(err)
-	}
-
-	if err := c2.Send("ECHO", "world"); err != nil {
-		t.Fatal(err)
-	}
-	if err := c2.Flush(); err != nil {
-		t.Fatal(err)
-	}
-
-	s, err := redis.String(c2.Receive())
-	if err != nil {
-		t.Fatal(err)
-	}
-	if s != "world" {
-		t.Fatalf("echo returned %q, want %q", s, "world")
-	}
-	c2.Close()
-}
-
-func BenchmarkConn(b *testing.B) {
-	b.StopTimer()
-	c, err := redisx.DialTest()
-	if err != nil {
-		b.Fatalf("error connection to database, %v", err)
-	}
-	defer c.Close()
-	b.StartTimer()
-
-	for i := 0; i < b.N; i++ {
-		if _, err := c.Do("PING"); err != nil {
-			b.Fatal(err)
-		}
-	}
-}
-
-func BenchmarkConnMux(b *testing.B) {
-	b.StopTimer()
-	c, err := redisx.DialTest()
-	if err != nil {
-		b.Fatalf("error connection to database, %v", err)
-	}
-	m := redisx.NewConnMux(c)
-	defer m.Close()
-
-	b.StartTimer()
-
-	for i := 0; i < b.N; i++ {
-		c := m.Get()
-		if _, err := c.Do("PING"); err != nil {
-			b.Fatal(err)
-		}
-		c.Close()
-	}
-}
-
-func BenchmarkPool(b *testing.B) {
-	b.StopTimer()
-
-	p := redis.Pool{Dial: redisx.DialTest, MaxIdle: 1}
-	defer p.Close()
-
-	// Fill the pool.
-	c := p.Get()
-	if err := c.Err(); err != nil {
-		b.Fatal(err)
-	}
-	c.Close()
-
-	b.StartTimer()
-
-	for i := 0; i < b.N; i++ {
-		c := p.Get()
-		if _, err := c.Do("PING"); err != nil {
-			b.Fatal(err)
-		}
-		c.Close()
-	}
-}
-
-const numConcurrent = 10
-
-func BenchmarkConnMuxConcurrent(b *testing.B) {
-	b.StopTimer()
-	c, err := redisx.DialTest()
-	if err != nil {
-		b.Fatalf("error connection to database, %v", err)
-	}
-	defer c.Close()
-
-	m := redisx.NewConnMux(c)
-
-	var wg sync.WaitGroup
-	wg.Add(numConcurrent)
-
-	b.StartTimer()
-
-	for i := 0; i < numConcurrent; i++ {
-		go func() {
-			defer wg.Done()
-			for i := 0; i < b.N; i++ {
-				c := m.Get()
-				if _, err := c.Do("PING"); err != nil {
-					b.Fatal(err)
-				}
-				c.Close()
-			}
-		}()
-	}
-	wg.Wait()
-}
-
-func BenchmarkPoolConcurrent(b *testing.B) {
-	b.StopTimer()
-
-	p := redis.Pool{Dial: redisx.DialTest, MaxIdle: numConcurrent}
-	defer p.Close()
-
-	// Fill the pool.
-	conns := make([]redis.Conn, numConcurrent)
-	for i := range conns {
-		c := p.Get()
-		if err := c.Err(); err != nil {
-			b.Fatal(err)
-		}
-		conns[i] = c
-	}
-	for _, c := range conns {
-		c.Close()
-	}
-
-	var wg sync.WaitGroup
-	wg.Add(numConcurrent)
-
-	b.StartTimer()
-
-	for i := 0; i < numConcurrent; i++ {
-		go func() {
-			defer wg.Done()
-			for i := 0; i < b.N; i++ {
-				c := p.Get()
-				if _, err := c.Do("PING"); err != nil {
-					b.Fatal(err)
-				}
-				c.Close()
-			}
-		}()
-	}
-	wg.Wait()
-}
-
-func BenchmarkPipelineConcurrency(b *testing.B) {
-	b.StopTimer()
-	c, err := redisx.DialTest()
-	if err != nil {
-		b.Fatalf("error connection to database, %v", err)
-	}
-	defer c.Close()
-
-	var wg sync.WaitGroup
-	wg.Add(numConcurrent)
-
-	var pipeline textproto.Pipeline
-
-	b.StartTimer()
-
-	for i := 0; i < numConcurrent; i++ {
-		go func() {
-			defer wg.Done()
-			for i := 0; i < b.N; i++ {
-				id := pipeline.Next()
-				pipeline.StartRequest(id)
-				c.Send("PING")
-				c.Flush()
-				pipeline.EndRequest(id)
-				pipeline.StartResponse(id)
-				_, err := c.Receive()
-				if err != nil {
-					b.Fatal(err)
-				}
-				pipeline.EndResponse(id)
-			}
-		}()
-	}
-	wg.Wait()
-}

+ 0 - 68
src/github.com/gomodule/redigo/redisx/db_test.go

@@ -1,68 +0,0 @@
-// Copyright 2014 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-// Package redistest contains utilities for writing Redigo tests.
-package redisx
-
-import (
-	"errors"
-	"time"
-
-	"github.com/gomodule/redigo/redis"
-)
-
-type testConn struct {
-	redis.Conn
-}
-
-func (t testConn) Close() error {
-	_, err := t.Conn.Do("SELECT", "9")
-	if err != nil {
-		return nil
-	}
-	_, err = t.Conn.Do("FLUSHDB")
-	if err != nil {
-		return err
-	}
-	return t.Conn.Close()
-}
-
-// Dial dials the local Redis server and selects database 9. To prevent
-// stomping on real data, DialTestDB fails if database 9 contains data. The
-// returned connection flushes database 9 on close.
-func DialTest() (redis.Conn, error) {
-	c, err := redis.DialTimeout("tcp", ":6379", 0, 1*time.Second, 1*time.Second)
-	if err != nil {
-		return nil, err
-	}
-
-	_, err = c.Do("SELECT", "9")
-	if err != nil {
-		c.Close()
-		return nil, err
-	}
-
-	n, err := redis.Int(c.Do("DBSIZE"))
-	if err != nil {
-		c.Close()
-		return nil, err
-	}
-
-	if n != 0 {
-		c.Close()
-		return nil, errors.New("database #9 is not empty, test can not continue")
-	}
-
-	return testConn{c}, nil
-}

+ 0 - 17
src/github.com/gomodule/redigo/redisx/doc.go

@@ -1,17 +0,0 @@
-// Copyright 2012 Gary Burd
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-// Package redisx contains experimental features for Redigo. Features in this
-// package may be modified or deleted at any time.
-package redisx

+ 0 - 16
src/go.mongodb.org/mongo-driver/.errcheck-excludes

@@ -1,16 +0,0 @@
-(go.mongodb.org/mongo-driver/x/mongo/driver.Connection).Close
-(*go.mongodb.org/mongo-driver/x/network/connection.connection).Close
-(go.mongodb.org/mongo-driver/x/network/connection.Connection).Close
-(*go.mongodb.org/mongo-driver/x/mongo/driver/topology.connection).close
-(*go.mongodb.org/mongo-driver/x/mongo/driver/topology.Topology).Unsubscribe
-(*go.mongodb.org/mongo-driver/x/mongo/driver/topology.Server).Close
-(*go.mongodb.org/mongo-driver/x/network/connection.pool).closeConnection
-(*go.mongodb.org/mongo-driver/x/mongo/driver/topology.pool).close
-(go.mongodb.org/mongo-driver/x/network/wiremessage.ReadWriteCloser).Close
-(*go.mongodb.org/mongo-driver/mongo.Cursor).Close
-(*go.mongodb.org/mongo-driver/mongo.ChangeStream).Close
-(*go.mongodb.org/mongo-driver/mongo.Client).Disconnect
-(net.Conn).Close
-encoding/pem.Encode
-fmt.Fprintf
-fmt.Fprint

+ 0 - 911
src/go.mongodb.org/mongo-driver/.evergreen/config.yml

@@ -1,911 +0,0 @@
-########################################
-# Evergreen Template for MongoDB Drivers
-########################################
-
-# When a task that used to pass starts to fail
-# Go through all versions that may have been skipped to detect
-# when the task started failing
-stepback: true
-
-# Mark a failure as a system/bootstrap failure (purple box) rather then a task
-# failure by default.
-# Actual testing tasks are marked with `type: test`
-command_type: setup
-
-# Protect ourself against rogue test case, or curl gone wild, that runs forever
-# 12 minutes is the longest we'll ever run
-exec_timeout_secs: 3600 # 12 minutes is the longest we'll ever run
-
-# What to do when evergreen hits the timeout (`post:` tasks are run automatically)
-timeout:
-  - command: shell.exec
-    params:
-      script: |
-        ls -la
-functions:
-
-  fetch-source:
-    # Executes git clone and applies the submitted patch, if any
-    - command: git.get_project
-      type: system
-      params:
-        directory: src/go.mongodb.org/mongo-driver
-    # Make an evergreen expansion file with dynamic values
-    - command: shell.exec
-      params:
-        working_dir: src/go.mongodb.org/mongo-driver
-        script: |
-           if [ "Windows_NT" = "$OS" ]; then
-              export GOPATH=$(cygpath -w $(dirname $(dirname $(dirname `pwd`))))
-           else
-              export GOPATH=$(dirname $(dirname $(dirname `pwd`)))
-           fi;
-
-           # Get the current unique version of this checkout
-           if [ "${is_patch}" = "true" ]; then
-              CURRENT_VERSION=$(git describe)-patch-${version_id}
-           else
-              CURRENT_VERSION=latest
-           fi
-
-           export DRIVERS_TOOLS="$(pwd)/../drivers-tools"
-           export PROJECT_DIRECTORY="$(pwd)"
-           export GOCACHE="$(pwd)/.cache"
-
-           # Python has cygwin path problems on Windows. Detect prospective mongo-orchestration home directory
-           if [ "Windows_NT" = "$OS" ]; then # Magic variable in cygwin
-              export DRIVERS_TOOLS=$(cygpath -m $DRIVERS_TOOLS)
-              export PROJECT_DIRECTORY=$(cygpath -m $PROJECT_DIRECTORY)
-              export GOCACHE=$(cygpath -m $GOCACHE)
-           fi
-
-           export MONGO_ORCHESTRATION_HOME="$DRIVERS_TOOLS/.evergreen/orchestration"
-           export MONGODB_BINARIES="$DRIVERS_TOOLS/mongodb/bin"
-           export UPLOAD_BUCKET="${project}"
-           export PATH="${GO_DIST}/bin:${GCC_PATH}:$GOPATH/bin:$MONGODB_BINARIES:$PATH"
-           export PROJECT="${project}"
-
-           if [ "Windows_NT" = "$OS" ]; then
-              export USERPROFILE=$(cygpath -w $(dirname $(dirname $(dirname `pwd`))))
-              export HOME=$(cygpath -w $(dirname $(dirname $(dirname `pwd`))))
-           fi
-
-           go version
-           go env
-
-           if [ "Windows_NT" = "$OS" ]; then
-              mkdir -p c:/libmongocrypt/include
-              mkdir -p c:/libmongocrypt/bin
-              curl https://s3.amazonaws.com/mciuploads/libmongocrypt/windows-test/master/latest/libmongocrypt.tar.gz --output libmongocrypt.tar.gz
-              tar -xvzf libmongocrypt.tar.gz
-              cp ./bin/mongocrypt.dll c:/libmongocrypt/bin
-              cp ./include/mongocrypt/*.h c:/libmongocrypt/include
-              export PATH=$PATH:/cygdrive/c/libmongocrypt/bin
-           else
-              git clone https://github.com/mongodb/libmongocrypt
-              ./libmongocrypt/.evergreen/compile.sh
-           fi
-
-           cat <<EOT > expansion.yml
-           CURRENT_VERSION: "$CURRENT_VERSION"
-           DRIVERS_TOOLS: "$DRIVERS_TOOLS"
-           MONGO_ORCHESTRATION_HOME: "$MONGO_ORCHESTRATION_HOME"
-           MONGODB_BINARIES: "$MONGODB_BINARIES"
-           UPLOAD_BUCKET: "$UPLOAD_BUCKET"
-           PROJECT_DIRECTORY: "$PROJECT_DIRECTORY"
-           PREPARE_SHELL: |
-              set -o errexit
-              set -o xtrace
-              export GOPATH="$GOPATH"
-              export GOROOT="${GO_DIST}"
-              export GOCACHE="$GOCACHE"
-              export DRIVERS_TOOLS="$DRIVERS_TOOLS"
-              export MONGO_ORCHESTRATION_HOME="$MONGO_ORCHESTRATION_HOME"
-              export MONGODB_BINARIES="$MONGODB_BINARIES"
-              export UPLOAD_BUCKET="$UPLOAD_BUCKET"
-              export PROJECT_DIRECTORY="$PROJECT_DIRECTORY"
-              export TMPDIR="$MONGO_ORCHESTRATION_HOME/db"
-              export PATH="$PATH"
-              export PROJECT="$PROJECT"
-              export PKG_CONFIG_PATH=$(pwd)/install/libmongocrypt/lib/pkgconfig:$(pwd)/install/mongo-c-driver/lib/pkgconfig
-              export LD_LIBRARY_PATH=$(pwd)/install/libmongocrypt/lib
-           EOT
-           # See what we've done
-           cat expansion.yml
-    # Load the expansion file to make an evergreen variable with the current unique version
-    - command: expansions.update
-      params:
-        file: src/go.mongodb.org/mongo-driver/expansion.yml
-
-
-  prepare-resources:
-    - command: shell.exec
-      params:
-        script: |
-          ${PREPARE_SHELL}
-          rm -rf $DRIVERS_TOOLS
-          if [ "${project}" = "drivers-tools" ]; then
-            # If this was a patch build, doing a fresh clone would not actually test the patch
-            cp -R ${PROJECT_DIRECTORY}/ $DRIVERS_TOOLS
-          else
-            git clone git://github.com/mongodb-labs/drivers-evergreen-tools.git $DRIVERS_TOOLS
-          fi
-          echo "{ \"releases\": { \"default\": \"$MONGODB_BINARIES\" }}" > $MONGO_ORCHESTRATION_HOME/orchestration.config
-    - command: shell.exec
-      params:
-        working_dir: src/go.mongodb.org/mongo-driver
-        script: |
-           ${PREPARE_SHELL}
-           # any go tools that we need
-           go get -u golang.org/x/lint/golint
-           go get -u github.com/kisielk/errcheck
-
-           # initialize submodules
-           git submodule init
-           git submodule update
-
-           # generate any source code
-           make generate
-
-
-  upload-mo-artifacts:
-    - command: shell.exec
-      params:
-        script: |
-          ${PREPARE_SHELL}
-          find $MONGO_ORCHESTRATION_HOME -name \*.log | xargs tar czf mongodb-logs.tar.gz
-    - command: s3.put
-      params:
-        aws_key: ${aws_key}
-        aws_secret: ${aws_secret}
-        local_file: mongodb-logs.tar.gz
-        remote_file: ${UPLOAD_BUCKET}/${build_variant}/${revision}/${version_id}/${build_id}/logs/${task_id}-${execution}-mongodb-logs.tar.gz
-        bucket: mciuploads
-        permissions: public-read
-        content_type: ${content_type|application/x-gzip}
-        display_name: "mongodb-logs.tar.gz"
-
-  bootstrap-mongo-orchestration:
-    - command: shell.exec
-      params:
-        script: |
-          ${PREPARE_SHELL}
-
-          cp ${PROJECT_DIRECTORY}/data/certificates/server.pem ${DRIVERS_TOOLS}/.evergreen/x509gen/server.pem
-          cp ${PROJECT_DIRECTORY}/data/certificates/ca.pem ${DRIVERS_TOOLS}/.evergreen/x509gen/ca.pem
-          cp ${PROJECT_DIRECTORY}/data/certificates/client.pem ${DRIVERS_TOOLS}/.evergreen/x509gen/client.pem
-          cp ${PROJECT_DIRECTORY}/data/certificates/client.pem ${MONGO_ORCHESTRATION_HOME}/lib/client.pem
-
-          MONGODB_VERSION=${VERSION} AUTH=${AUTH} SSL=${SSL} sh ${DRIVERS_TOOLS}/.evergreen/run-orchestration.sh
-    - command: expansions.update
-      params:
-        file: mo-expansion.yml
-
-
-  cleanup:
-    - command: shell.exec
-      params:
-        script: |
-          ${PREPARE_SHELL}
-          cd "$MONGO_ORCHESTRATION_HOME"
-          # source the mongo-orchestration virtualenv if it exists
-          if [ -f venv/bin/activate ]; then
-            . venv/bin/activate
-          elif [ -f venv/Scripts/activate ]; then
-            . venv/Scripts/activate
-          fi
-          mongo-orchestration stop
-          cd -
-          rm -rf $DRIVERS_TOOLS || true
-
-
-  fix-absolute-paths:
-    - command: shell.exec
-      params:
-        script: |
-          ${PREPARE_SHELL}
-          for filename in $(find ${DRIVERS_TOOLS} -name \*.json); do
-            perl -p -i -e "s|ABSOLUTE_PATH_REPLACEMENT_TOKEN|${DRIVERS_TOOLS}|g" $filename
-          done
-
-
-  windows-fix:
-    - command: shell.exec
-      params:
-        script: |
-          ${PREPARE_SHELL}
-          for i in $(find ${DRIVERS_TOOLS}/.evergreen ${PROJECT_DIRECTORY} -name \*.sh); do
-            cat $i | tr -d '\r' > $i.new
-            mv $i.new $i
-          done
-
-
-  make-files-executable:
-    - command: shell.exec
-      params:
-        script: |
-          ${PREPARE_SHELL}
-          for i in $(find ${DRIVERS_TOOLS}/.evergreen ${PROJECT_DIRECTORY} -name \*.sh); do
-            chmod +x $i
-          done
-
-
-  run-make:
-    - command: shell.exec
-      type: test
-      params:
-        working_dir: src/go.mongodb.org/mongo-driver
-        script: |
-          ${PREPARE_SHELL}
-          ${BUILD_ENV|} make ${targets} BUILD_TAGS="-tags gssapi"
-
-
-  run-tests:
-    - command: shell.exec
-      type: test
-      params:
-        working_dir: src/go.mongodb.org/mongo-driver
-        script: |
-          ${PREPARE_SHELL}
-
-          if [ ${SSL} = "ssl" ]; then
-              export MONGO_GO_DRIVER_CA_FILE="$PROJECT_DIRECTORY/data/certificates/ca.pem"
-
-              if [ "Windows_NT" = "$OS" ]; then # Magic variable in cygwin
-                  export MONGO_GO_DRIVER_CA_FILE=$(cygpath -m $MONGO_GO_DRIVER_CA_FILE)
-              fi
-          fi
-
-          set +o xtrace
-          AUTH=${AUTH} \
-          SSL=${SSL} \
-          MONGODB_URI="${MONGODB_URI}" \
-          MONGO_GO_DRIVER_COMPRESSOR=${MONGO_GO_DRIVER_COMPRESSOR} \
-          BUILD_TAGS="-tags cse" \
-          AWS_ACCESS_KEY_ID="${cse_aws_access_key_id}" \
-          AWS_SECRET_ACCESS_KEY="${cse_aws_secret_access_key}" \
-          make evg-test \
-          PKG_CONFIG_PATH=$PKG_CONFIG_PATH \
-          LD_LIBRARY_PATH=$LD_LIBRARY_PATH
-
-  send-perf-data:
-   - command: json.send
-     params:
-       name: perf
-       file: src/go.mongodb.org/mongo-driver/perf.json
-
-
-  run-enterprise-auth-tests:
-    - command: shell.exec
-      type: test
-      params:
-        silent: true
-        working_dir: src/go.mongodb.org/mongo-driver
-        script: |
-          # DO NOT ECHO WITH XTRACE (which PREPARE_SHELL does)
-          if [ "Windows_NT" = "$OS" ]; then
-            export GOPATH=$(cygpath -w $(dirname $(dirname $(dirname `pwd`))))
-            export GOCACHE=$(cygpath -w "$(pwd)/.cache")
-          else
-            export GOPATH=$(dirname $(dirname $(dirname `pwd`)))
-            export GOCACHE="$(pwd)/.cache"
-          fi;
-          export GOPATH="$GOPATH"
-          export GOROOT="${GO_DIST}"
-          export GOCACHE="$GOCACHE"
-          export PATH="${GCC_PATH}:${GO_DIST}/bin:$PATH"
-          MONGODB_URI="${MONGODB_URI}" MONGO_GO_DRIVER_COMPRESSOR="${MONGO_GO_DRIVER_COMPRESSOR}" make -s evg-test-auth
-
-  run-enterprise-gssapi-auth-tests:
-    - command: shell.exec
-      type: test
-      params:
-        working_dir: src/go.mongodb.org/mongo-driver
-        script: |
-          # DO NOT ECHO WITH XTRACE (which PREPARE_SHELL does)
-          if [ "Windows_NT" = "$OS" ]; then
-            export GOPATH=$(cygpath -w $(dirname $(dirname $(dirname `pwd`))))
-            export GOCACHE=$(cygpath -w "$(pwd)/.cache")
-            export MONGODB_URI=${gssapi_auth_windows_mongodb_uri}
-          else
-            export GOPATH=$(dirname $(dirname $(dirname `pwd`)))
-            export GOCACHE="$(pwd)/.cache"
-            echo "${gssapi_auth_linux_keytab_base64}" > /tmp/drivers.keytab.base64
-            base64 --decode /tmp/drivers.keytab.base64 > ${PROJECT_DIRECTORY}/.evergreen/drivers.keytab
-            mkdir -p ~/.krb5
-            cat .evergreen/krb5.config | tee -a ~/.krb5/config
-            kinit -k -t ${PROJECT_DIRECTORY}/.evergreen/drivers.keytab -p "${gssapi_auth_username}"
-            export MONGODB_URI="${gssapi_auth_linux_mongodb_uri}"
-          fi;
-          export GOPATH="$GOPATH"
-          export GOROOT="${GO_DIST}"
-          export GOCACHE="$GOCACHE"
-          export PATH="${GCC_PATH}:${GO_DIST}/bin:$PATH"
-          MONGO_GO_DRIVER_COMPRESSOR="${MONGO_GO_DRIVER_COMPRESSOR}" make -s evg-test-auth
-
-  run-enterprise-gssapi-service-host-auth-tests:
-    - command: shell.exec
-      type: test
-      params:
-        working_dir: src/go.mongodb.org/mongo-driver
-        script: |
-          # DO NOT ECHO WITH XTRACE (which PREPARE_SHELL does)
-          if [ "Windows_NT" = "$OS" ]; then
-            export GOPATH=$(cygpath -w $(dirname $(dirname $(dirname `pwd`))))
-            export GOCACHE=$(cygpath -w "$(pwd)/.cache")
-            export MONGODB_URI="${gssapi_service_host_auth_windows_mongodb_uri}"
-          else
-            export GOPATH=$(dirname $(dirname $(dirname `pwd`)))
-            export GOCACHE="$(pwd)/.cache"
-            echo "${gssapi_auth_linux_keytab_base64}" > /tmp/drivers.keytab.base64
-            base64 --decode /tmp/drivers.keytab.base64 > ${PROJECT_DIRECTORY}/.evergreen/drivers.keytab
-            mkdir -p ~/.krb5
-            cat .evergreen/krb5.config | tee -a ~/.krb5/config
-            kinit -k -t ${PROJECT_DIRECTORY}/.evergreen/drivers.keytab -p "${gssapi_auth_username}"
-            export MONGODB_URI="${gssapi_service_host_auth_linux_mongodb_uri}"
-          fi;
-          export GOPATH="$GOPATH"
-          export GOROOT="${GO_DIST}"
-          export GOCACHE="$GOCACHE"
-          export PATH="${GCC_PATH}:${GO_DIST}/bin:$PATH"
-          MONGO_GO_DRIVER_COMPRESSOR="${MONGO_GO_DRIVER_COMPRESSOR}" make -s evg-test-auth
-
-  run-atlas-test:
-    - command: shell.exec
-      type: test
-      params:
-        working_dir: src/go.mongodb.org/mongo-driver
-        script: |
-          # DO NOT ECHO WITH XTRACE (which PREPARE_SHELL does)
-          if [ "Windows_NT" = "$OS" ]; then
-            export GOPATH=$(cygpath -w $(dirname $(dirname $(dirname `pwd`))))
-            export GOCACHE=$(cygpath -w "$(pwd)/.cache")
-          else
-            export GOPATH=$(dirname $(dirname $(dirname `pwd`)))
-            export GOCACHE="$(pwd)/.cache"
-          fi;
-          export GOPATH="$GOPATH"
-          export GOROOT="${GO_DIST}"
-          export GOCACHE="$GOCACHE"
-          export PATH="${GCC_PATH}:${GO_DIST}/bin:$PATH"
-          export ATLAS_FREE="${atlas_free_tier_uri}"
-          export ATLAS_REPLSET="${atlas_replica_set_uri}"
-          export ATLAS_SHARD="${atlas_sharded_uri}"
-          export ATLAS_TLS11="${atlas_tls_v11_uri}"
-          export ATLAS_TLS12="${atlas_tls_v12_uri}"
-          export ATLAS_FREE_SRV="${atlas_free_tier_uri_srv}"
-          export ATLAS_REPLSET_SRV="${atlas_replica_set_uri_srv}"
-          export ATLAS_SHARD_SRV="${atlas_sharded_uri_srv}"
-          export ATLAS_TLS11_SRV="${atlas_tls_v11_uri_srv}"
-          export ATLAS_TLS12_SRV="${atlas_tls_v12_uri_srv}"
-          make -s evg-test-atlas
-
-
-pre:
-  - func: fetch-source
-  - func: prepare-resources
-  - func: windows-fix
-  - func: fix-absolute-paths
-  - func: make-files-executable
-
-post:
-  - command: gotest.parse_files
-    params:
-      files:
-        - "src/go.mongodb.org/mongo-driver/*.suite"
-  - func: upload-mo-artifacts
-  - func: cleanup
-
-tasks:
-    - name: sa-fmt
-      tags: ["static-analysis"]
-      commands:
-        - func: run-make
-          vars:
-            targets: check-fmt
-
-    - name: sa-errcheck
-      tags: ["static-analysis"]
-      commands:
-        - func: run-make
-          vars:
-            targets: errcheck
-
-
-    - name: sa-lint
-      tags: ["static-analysis"]
-      commands:
-        - func: run-make
-          vars:
-            targets: lint
-
-    - name: sa-vet
-      tags: ["static-analysis"]
-      commands:
-        - func: run-make
-          vars:
-            targets: vet
-
-    - name: perf
-      tags: ["performance"]
-      exec_timeout_secs: 7200
-      commands:
-        - func: bootstrap-mongo-orchestration
-          vars:
-            AUTH: "noauth"
-            SSL: "nossl"
-        - func: run-make
-          vars:
-            targets: driver-benchmark
-        - func: send-perf-data
-
-    - name: sa-build-examples
-      tags: ["static-analysis"]
-      commands:
-        - func: run-make
-          vars:
-            targets: build-examples
-
-    - name: test-standalone-noauth-nossl
-      tags: ["test", "standalone"]
-      commands:
-        - func: bootstrap-mongo-orchestration
-          vars:
-            AUTH: "noauth"
-            SSL: "nossl"
-        - func: run-tests
-          vars:
-            AUTH: "noauth"
-            SSL: "nossl"
-
-    - name: test-standalone-noauth-nossl-snappy-compression
-      tags: ["test", "standalone", "compression", "snappy"]
-      commands:
-        - func: bootstrap-mongo-orchestration
-          vars:
-            AUTH: "noauth"
-            SSL: "nossl"
-        - func: run-tests
-          vars:
-            AUTH: "noauth"
-            SSL: "nossl"
-            MONGO_GO_DRIVER_COMPRESSOR: "snappy"
-
-    - name: test-standalone-noauth-nossl-zlib-compression
-      tags: ["test", "standalone", "compression", "zlib"]
-      commands:
-        - func: bootstrap-mongo-orchestration
-          vars:
-            AUTH: "noauth"
-            SSL: "nossl"
-        - func: run-tests
-          vars:
-            AUTH: "noauth"
-            SSL: "nossl"
-            MONGO_GO_DRIVER_COMPRESSOR: "zlib"
-
-    - name: test-standalone-noauth-nossl-zstd-compression
-      tags: ["test", "standalone", "compression", "zstd"]
-      commands:
-        - func: bootstrap-mongo-orchestration
-          vars:
-            AUTH: "noauth"
-            SSL: "nossl"
-        - func: run-tests
-          vars:
-            AUTH: "noauth"
-            SSL: "nossl"
-            MONGO_GO_DRIVER_COMPRESSOR: "zstd"
-
-    - name: test-standalone-auth-ssl
-      tags: ["test", "standalone", "authssl"]
-      commands:
-        - func: bootstrap-mongo-orchestration
-          vars:
-            AUTH: "auth"
-            SSL: "ssl"
-        - func: run-tests
-          vars:
-            AUTH: "auth"
-            SSL: "ssl"
-
-    - name: test-standalone-auth-ssl-snappy-compression
-      tags: ["test", "standalone", "authssl", "compression", "snappy"]
-      commands:
-        - func: bootstrap-mongo-orchestration
-          vars:
-            AUTH: "auth"
-            SSL: "ssl"
-        - func: run-tests
-          vars:
-            AUTH: "auth"
-            SSL: "ssl"
-            MONGO_GO_DRIVER_COMPRESSOR: "snappy"
-
-    - name: test-standalone-auth-ssl-zlib-compression
-      tags: ["test", "standalone", "authssl", "compression", "zlib"]
-      commands:
-        - func: bootstrap-mongo-orchestration
-          vars:
-            AUTH: "auth"
-            SSL: "ssl"
-        - func: run-tests
-          vars:
-            AUTH: "auth"
-            SSL: "ssl"
-            MONGO_GO_DRIVER_COMPRESSOR: "zlib"
-
-    - name: test-standalone-auth-ssl-zstd-compression
-      tags: ["test", "standalone", "authssl", "compression", "zstd"]
-      commands:
-        - func: bootstrap-mongo-orchestration
-          vars:
-            AUTH: "auth"
-            SSL: "ssl"
-        - func: run-tests
-          vars:
-            AUTH: "auth"
-            SSL: "ssl"
-            MONGO_GO_DRIVER_COMPRESSOR: "zstd"
-
-    - name: test-replicaset-noauth-nossl
-      tags: ["test", "replicaset"]
-      commands:
-        - func: bootstrap-mongo-orchestration
-          vars:
-            AUTH: "noauth"
-            SSL: "nossl"
-        - func: run-tests
-          vars:
-            AUTH: "noauth"
-            SSL: "nossl"
-
-    - name: test-replicaset-auth-ssl
-      tags: ["test", "replicaset", "authssl"]
-      commands:
-        - func: bootstrap-mongo-orchestration
-          vars:
-            AUTH: "auth"
-            SSL: "ssl"
-        - func: run-tests
-          vars:
-            AUTH: "auth"
-            SSL: "ssl"
-
-    - name: test-sharded-noauth-nossl
-      tags: ["test", "sharded"]
-      commands:
-        - func: bootstrap-mongo-orchestration
-          vars:
-            AUTH: "noauth"
-            SSL: "nossl"
-        - func: run-tests
-          vars:
-            AUTH: "noauth"
-            SSL: "nossl"
-
-    - name: test-sharded-noauth-nossl-snappy-compression
-      tags: ["test", "sharded", "compression", "snappy"]
-      commands:
-        - func: bootstrap-mongo-orchestration
-          vars:
-            AUTH: "noauth"
-            SSL: "nossl"
-        - func: run-tests
-          vars:
-            AUTH: "noauth"
-            SSL: "nossl"
-            MONGO_GO_DRIVER_COMPRESSOR: "snappy"
-
-    - name: test-sharded-noauth-nossl-zlib-compression
-      tags: ["test", "sharded", "compression", "zlib"]
-      commands:
-        - func: bootstrap-mongo-orchestration
-          vars:
-            AUTH: "noauth"
-            SSL: "nossl"
-        - func: run-tests
-          vars:
-            AUTH: "noauth"
-            SSL: "nossl"
-            MONGO_GO_DRIVER_COMPRESSOR: "zlib"
-
-    - name: test-sharded-noauth-nossl-zstd-compression
-      tags: ["test", "sharded", "compression", "zstd"]
-      commands:
-        - func: bootstrap-mongo-orchestration
-          vars:
-            AUTH: "noauth"
-            SSL: "nossl"
-        - func: run-tests
-          vars:
-            AUTH: "noauth"
-            SSL: "nossl"
-            MONGO_GO_DRIVER_COMPRESSOR: "zstd"
-
-    - name: test-sharded-auth-ssl
-      tags: ["test", "sharded", "authssl"]
-      commands:
-        - func: bootstrap-mongo-orchestration
-          vars:
-            AUTH: "auth"
-            SSL: "ssl"
-        - func: run-tests
-          vars:
-            AUTH: "auth"
-            SSL: "ssl"
-
-    - name: test-sharded-auth-ssl-snappy-compression
-      tags: ["test", "sharded", "authssl", "compression", "snappy"]
-      commands:
-        - func: bootstrap-mongo-orchestration
-          vars:
-            AUTH: "auth"
-            SSL: "ssl"
-        - func: run-tests
-          vars:
-            AUTH: "auth"
-            SSL: "ssl"
-            MONGO_GO_DRIVER_COMPRESSOR: "snappy"
-
-    - name: test-sharded-auth-ssl-zlib-compression
-      tags: ["test", "sharded", "authssl", "compression", "zlib"]
-      commands:
-        - func: bootstrap-mongo-orchestration
-          vars:
-            AUTH: "auth"
-            SSL: "ssl"
-        - func: run-tests
-          vars:
-            AUTH: "auth"
-            SSL: "ssl"
-            MONGO_GO_DRIVER_COMPRESSOR: "zlib"
-
-    - name: test-sharded-auth-ssl-zstd-compression
-      tags: ["test", "sharded", "authssl", "compression", "zstd"]
-      commands:
-        - func: bootstrap-mongo-orchestration
-          vars:
-            AUTH: "auth"
-            SSL: "ssl"
-        - func: run-tests
-          vars:
-            AUTH: "auth"
-            SSL: "ssl"
-            MONGO_GO_DRIVER_COMPRESSOR: "zstd"
-
-    - name: test-enterprise-auth-plain
-      tags: ["test", "enterprise-auth"]
-      commands:
-        - func: run-enterprise-auth-tests
-          vars:
-            MONGODB_URI: "${plain_auth_mongodb_uri}"
-
-    - name: test-enterprise-auth-gssapi
-      tags: ["test", "enterprise-auth"]
-      commands:
-        - func: run-enterprise-gssapi-auth-tests
-
-    - name: test-enterprise-auth-gssapi-service-host
-      tags: ["test", "enterprise-auth"]
-      commands:
-        - func: run-enterprise-gssapi-service-host-auth-tests
-          vars:
-            MONGO_GO_DRIVER_COMPRESSOR: "snappy"
-
-    - name: go1.9-build
-      tags: ["compile-check"]
-      commands:
-        - func: run-make
-          vars:
-            targets: "build"
-            BUILD_ENV: "PATH=/opt/golang/go1.9/bin:$PATH GOROOT=/opt/golang/go1.9"
-
-    - name: go1.9-build-nocgo
-      tags: ["compile-check"]
-      commands:
-        - func: run-make
-          vars:
-            targets: "build"
-            BUILD_ENV: "CGO_ENABLED=0 PATH=/opt/golang/go1.9/bin:$PATH GOROOT=/opt/golang/go1.9"
-
-    - name: go1.10-build
-      tags: ["compile-check"]
-      commands:
-        - func: run-make
-          vars:
-            targets: "build"
-            BUILD_ENV: "PATH=/opt/golang/go1.10/bin:$PATH GOROOT=/opt/golang/go1.10"
-
-    - name: go1.10-build-nocgo
-      tags: ["compile-check"]
-      commands:
-        - func: run-make
-          vars:
-            targets: "build"
-            BUILD_ENV: "CGO_ENABLED=0 PATH=/opt/golang/go1.10/bin:$PATH GOROOT=/opt/golang/go1.10"
-
-    - name: linux-32-bit
-      tags: ["compile-check"]
-      commands:
-        - func: run-make
-          vars:
-            targets: "build"
-            BUILD_ENV: "GOARCH=386"
-
-    - name: linux-arm64
-      tags: ["compile-check"]
-      commands:
-        - func: run-make
-          vars:
-            targets: "build"
-            BUILD_ENV: "GOARCH=arm64"
-
-    - name: linux-s390x
-      tags: ["compile-check"]
-      commands:
-        - func: run-make
-          vars:
-            targets: "build"
-            BUILD_ENV: "GOARCH=ppc64le"
-
-    - name: "atlas-test"
-      commands:
-        - func: "run-atlas-test"
-
-    - name: go1.10-build-cse
-      tags: ["compile-check"]
-      commands:
-        - func: run-make
-          vars:
-            targets: "build-cse"
-            BUILD_ENV: "PATH=/opt/golang/go1.10/bin:$PATH GOROOT=/opt/golang/go1.10"
-
-axes:
-  - id: version
-    display_name: MongoDB Version
-    values:
-      - id: "4.2"
-        display_name: "4.2"
-        variables:
-          VERSION: "4.2"
-      - id: "4.0"
-        display_name: "4.0"
-        variables:
-           VERSION: "4.0"
-      - id: "3.6"
-        display_name: "3.6"
-        variables:
-           VERSION: "3.6"
-      - id: "3.4"
-        display_name: "3.4"
-        variables:
-           VERSION: "3.4"
-      - id: "3.2"
-        display_name: "3.2"
-        variables:
-           VERSION: "3.2"
-      - id: "3.0"
-        display_name: "3.0"
-        variables:
-          VERSION: "3.0"
-      - id: "2.6"
-        display_name: "2.6"
-        variables:
-          VERSION: "2.6"
-      - id: "latest"
-        display_name: "latest"
-        variables:
-           VERSION: "latest"
-
-  # OSes that support versions of MongoDB >= 2.6 with SSL.
-  - id: os-ssl-legacy
-    display_name: OS
-    values:
-      - id: "ubuntu1404-go-1-12"
-        display_name: "Ubuntu 14.04"
-        run_on: ubuntu1404-test
-        variables:
-          GO_DIST: "/opt/golang/go1.12"
-
-  # OSes that require >= 3.2 for SSL
-  - id: os-ssl-32
-    display_name: OS
-    values:
-      - id: "windows-64-go-1-12"
-        display_name: "Windows 64-bit"
-        run_on:
-          - windows-64-vs2015-test
-        variables:
-          GCC_PATH: "/cygdrive/c/mingw-w64/x86_64-4.9.1-posix-seh-rt_v3-rev1/mingw64/bin"
-          GO_DIST: "C:\\golang\\go1.12"
-      - id: "ubuntu1604-64-go-1-12"
-        display_name: "Ubuntu 16.04"
-        run_on: ubuntu1604-build
-        variables:
-          GO_DIST: "/opt/golang/go1.12"
-      - id: "osx-go-1-12"
-        display_name: "MacOS 10.14"
-        run_on: macos-1014
-        variables:
-          GO_DIST: "/opt/golang/go1.12"
-
-
-buildvariants:
-- name: static-analysis
-  display_name: "Static Analysis"
-  run_on:
-    - ubuntu1604-build
-  expansions:
-    GO_DIST: "/opt/golang/go1.12"
-  tasks:
-    - name: ".static-analysis"
-
-- name: perf
-  display_name: "Performance"
-  run_on:
-    - ubuntu1604-build
-  expansions:
-    GO_DIST: "/opt/golang/go1.12"
-  tasks:
-    - name: ".performance"
-
-- name: build-check
-  display_name: "Compile Only Checks"
-  run_on:
-    - ubuntu1604-test
-  expansions:
-    GO_DIST: "/opt/golang/go1.12"
-  tasks:
-    - name: ".compile-check"
-
-- name: atlas-test
-  display_name: "Atlas test"
-  run_on:
-    - ubuntu1604-build
-  expansions:
-    GO_DIST: "/opt/golang/go1.12"
-  tasks:
-    - name: "atlas-test"
-
-- matrix_name: "tests-legacy-auth-ssl"
-  matrix_spec: { version: ["2.6", "3.0"], os-ssl-legacy: "*" }
-  display_name: "${version} ${os-ssl-legacy}"
-  tasks:
-    - name: ".test !.enterprise-auth !.compression"
-
-- matrix_name: "tests-legacy-noauth-nossl"
-  matrix_spec: { version: ["2.6", "3.0"], os-ssl-32: "*" }
-  display_name: "${version} ${os-ssl-32}"
-  tasks:
-    - name: ".test !.authssl !.enterprise-auth !.compression"
-
-- matrix_name: "tests-nonlegacy-servers"
-  matrix_spec: { version: "3.2", os-ssl-32: "*" }
-  display_name: "${version} ${os-ssl-32}"
-  tasks:
-    - name: ".test !.enterprise-auth !.compression"
-
-- matrix_name: "tests-nonlegacy-servers-with-snappy-support"
-  matrix_spec: { version: "3.4", os-ssl-32: "*" }
-  display_name: "${version} ${os-ssl-32}"
-  tasks:
-    - name: ".test !.enterprise-auth !.zlib !.zstd"
-
-- matrix_name: "tests-36-40-with-zlib-support"
-  matrix_spec: { version: ["3.6", "4.0"], os-ssl-32: "*" }
-  display_name: "${version} ${os-ssl-32}"
-  tasks:
-    - name: ".test !.enterprise-auth !.snappy !.zstd"
-
-- matrix_name: "tests-42-lts-zlib-zstd-support"
-  matrix_spec: { version: ["4.2", "latest"], os-ssl-32: "*" }
-  display_name: "${version} ${os-ssl-32}"
-  tasks:
-    - name: ".test !.enterprise-auth !.snappy"
-
-- matrix_name: "enterprise-auth-tests"
-  matrix_spec: { os-ssl-32: "*" }
-  display_name: "Enterprise Auth - ${os-ssl-32}"
-  tasks:
-     - name: ".test .enterprise-auth"

+ 0 - 8
src/go.mongodb.org/mongo-driver/.evergreen/krb5.config

@@ -1,8 +0,0 @@
-[realms]
-  LDAPTEST.10GEN.CC = {
-    kdc = ldaptest.10gen.cc
-    admin_server = ldaptest.10gen.cc
-  }
-
-[libdefaults]
-  rdns = false

+ 0 - 12
src/go.mongodb.org/mongo-driver/.gitignore

@@ -1,12 +0,0 @@
-.vscode
-debug
-.idea
-*.iml
-*.ipr
-*.iws
-.idea
-*.sublime-project
-*.sublime-workspace
-driver-test-data.tar.gz
-perf
-**mongocryptd.pid

+ 0 - 3
src/go.mongodb.org/mongo-driver/.gitmodules

@@ -1,3 +0,0 @@
-[submodule "specifications"]
-	path = specifications
-	url = git@github.com:mongodb/specifications.git

+ 0 - 64
src/go.mongodb.org/mongo-driver/.lint-whitelist

@@ -1,64 +0,0 @@
-bson/bson.go:103:5: error var SetZero should have name of the form ErrFoo
-bson/bson.go:187:6: type ObjectId should be ObjectID
-bson/bson.go:192:6: func ObjectIdHex should be ObjectIDHex
-bson/bson.go:202:6: func IsObjectIdHex should be IsObjectIDHex
-bson/bson.go:249:6: func NewObjectId should be NewObjectID
-bson/bson.go:273:6: func NewObjectIdWithTime should be NewObjectIDWithTime
-bson/bson.go:470:2: struct field Id should be ID
-bson/bson.go:587:21: error strings should not be capitalized or end with punctuation or a newline
-bson/bson.go:589:21: error strings should not be capitalized or end with punctuation or a newline
-bson/bson.go:613:21: error strings should not be capitalized or end with punctuation or a newline
-bson/bson.go:615:21: error strings should not be capitalized or end with punctuation or a newline
-bson/encode.go:46:2: var typeObjectId should be typeObjectID
-bson/internal/json/stream_test.go:196:3: struct field Id should be ID
-bson/internal/json/stream_test.go:221:3: struct field Id should be ID
-bson/internal/json/stream_test.go:285:22: should omit type []tokenStreamCase from declaration of var tokenStreamCases; it will be inferred from the right-hand side
-bson/internal/testutil/close_helper.go:14:1: exported function CloseReadOnlyFile should have comment or be unexported
-bson/internal/testutil/close_helper.go:8:1: exported function CloseOrError should have comment or be unexported
-bson/json.go:246:6: func jdecObjectId should be jdecObjectID
-bson/json.go:263:6: func jencObjectId should be jencObjectID
-mongo/internal/testutil/helpers/helpers.go:10:1: exported function RequireNoErrorOnClose should have comment or be unexported
-mongo/internal/testutil/helpers/helpers.go:14:1: exported function FindJSONFilesInDir should have comment or be unexported
-mongo/internal/testutil/helpers/helpers.go:45:1: exported function VerifyConnStringOptions should have comment or be unexported
-mongo/options/find_and_modify.go:19:1: exported function CopyFindOneAndReplaceOptions should have comment or be unexported
-mongo/options/find_and_modify.go:29:1: exported function CopyFindOneAndUpdateOptions should have comment or be unexported
-mongo/options/find_and_modify.go:9:1: exported function CopyFindOneAndDeleteOptions should have comment or be unexported
-mongo/options.go:157:1: exported function OplogReplay should have comment or be unexported
-mongo/options.go:177:56: exported func ReadPreference returns unexported type *mongo.optReadPreference, which can be annoying to use
-bson/internal/jsonparser/bytes.go:9:10: should omit type bool from declaration of var neg; it will be inferred from the right-hand side
-bson/internal/jsonparser/bytes.go:25:9: if block ends with a return statement, so drop this else and outdent its block
-bson/internal/jsonparser/escape.go:113:10: if block ends with a return statement, so drop this else and outdent its block (move short variable declaration to its own line if necessary)
-bson/internal/jsonparser/escape.go:123:1: comment on exported function Unescape should be of the form "Unescape ..."
-bson/internal/jsonparser/parser.go:14:2: error var KeyPathNotFoundError should have name of the form ErrFoo
-bson/internal/jsonparser/parser.go:15:2: error var UnknownValueTypeError should have name of the form ErrFoo
-bson/internal/jsonparser/parser.go:16:2: error var MalformedJsonError should have name of the form ErrFoo
-bson/internal/jsonparser/parser.go:16:2: var MalformedJsonError should be MalformedJSONError
-bson/internal/jsonparser/parser.go:17:2: error var MalformedStringError should have name of the form ErrFoo
-bson/internal/jsonparser/parser.go:18:2: error var MalformedArrayError should have name of the form ErrFoo
-bson/internal/jsonparser/parser.go:19:2: error var MalformedObjectError should have name of the form ErrFoo
-bson/internal/jsonparser/parser.go:20:2: error var MalformedValueError should have name of the form ErrFoo
-bson/internal/jsonparser/parser.go:21:2: error var MalformedStringEscapeError should have name of the form ErrFoo
-bson/internal/jsonparser/parser.go:147:11: if block ends with a return statement, so drop this else and outdent its block
-bson/internal/jsonparser/parser.go:285:6: should replace curIdx += 1 with curIdx++
-bson/internal/jsonparser/parser.go:292:12: if block ends with a return statement, so drop this else and outdent its block
-bson/internal/jsonparser/parser.go:303:12: if block ends with a return statement, so drop this else and outdent its block (move short variable declaration to its own line if necessary)
-bson/internal/jsonparser/parser.go:329:6: don't use underscores in Go names; range var pi_1 should be pi1
-bson/internal/jsonparser/parser.go:329:12: don't use underscores in Go names; range var p_1 should be p1
-bson/internal/jsonparser/parser.go:338:1: exported function EachKey should have comment or be unexported
-bson/internal/jsonparser/parser.go:489:6: should replace curIdx += 1 with curIdx++
-bson/internal/jsonparser/parser.go:503:12: if block ends with a return statement, so drop this else and outdent its block (move short variable declaration to its own line if necessary)
-bson/internal/jsonparser/parser.go:517:1: comment on exported type ValueType should be of the form "ValueType ..." (with optional leading article)
-bson/internal/jsonparser/parser.go:521:2: exported const NotExist should have comment (or a comment on this block) or be unexported
-bson/internal/jsonparser/parser.go:582:1: comment on exported function Delete should be of the form "Delete ..."
-bson/internal/jsonparser/parser.go:931:10: if block ends with a return statement, so drop this else and outdent its block (move short variable declaration to its own line if necessary)
-bson/internal/jsonparser/parser.go:971:10: if block ends with a return statement, so drop this else and outdent its block (move short variable declaration to its own line if necessary)
-bson/internal/jsonparser/parser.go:980:11: if block ends with a return statement, so drop this else and outdent its block (move short variable declaration to its own line if necessary)
-bson/internal/jsonparser/parser.go:1006:10: if block ends with a return statement, so drop this else and outdent its block (move short variable declaration to its own line if necessary)
-bson/internal/jsonparser/parser.go:1021:10: if block ends with a return statement, so drop this else and outdent its block (move short variable declaration to its own line if necessary)
-bson/internal/jsonparser/parser.go:1128:9: if block ends with a return statement, so drop this else and outdent its block (move short variable declaration to its own line if necessary)
-bson/internal/jsonparser/parser.go:1133:1: comment on exported function ParseFloat should be of the form "ParseFloat ..."
-bson/internal/jsonparser/parser.go:1137:9: if block ends with a return statement, so drop this else and outdent its block (move short variable declaration to its own line if necessary)
-bson/internal/jsonparser/parser.go:1146:9: if block ends with a return statement, so drop this else and outdent its block (move short variable declaration to its own line if necessary)
-bson/internal/jsonparser/parser_test.go:1361:5: var testJson should be testJSON
-bson/internal/jsonpretty/pretty.go:7:1: comment on exported type Options should be of the form "Options ..." (with optional leading article)
-examples/documentation_examples/examples.go:10:1: don't use an underscore in package name

+ 0 - 37
src/go.mongodb.org/mongo-driver/CONTRIBUTING.md

@@ -1,37 +0,0 @@
-# Contributing to the MongoDB Go Driver
-
-Thank you for your interest in contributing to the MongoDB Go driver.
-
-We are building this software together and strongly encourage contributions from the community that are within the guidelines set forth
-below.
-
-## Bug Fixes and New Features
-
-Before starting to write code, look for existing [tickets](https://jira.mongodb.org/browse/GODRIVER) or
-[create one](https://jira.mongodb.org/secure/CreateIssue!default.jspa) for your bug, issue, or feature request. This helps the community
-avoid working on something that might not be of interest or which has already been addressed.
-
-## Pull Requests & Patches
-
-The Go Driver team is experimenting with GerritHub for contributions. GerritHub uses GitHub for authentication and uses a patch based
-workflow. Since GerritHub supports importing of Pull Requests we will also accept Pull Requests, but Code Review will be done in
-GerritHub.
-
-Patches should generally be made against the master (default) branch and include relevant tests, if applicable.
-
-Code should compile and tests should pass under all go versions which the driver currently supports.  Currently the driver
-supports a minimum version of go 1.7. Please ensure the following tools have been run on the code: gofmt, golint, errcheck,
-go test (with coverage and with the race detector), and go vet. For convenience, you can run 'make' to run all these tools.
-**By default, running the tests requires that you have a mongod server running on localhost, listening on the default port.**
-At minimum, please test against the latest release version of the MongoDB server.
-
-If any tests do not pass, or relevant tests are not included, the patch will not be considered.
-
-If you are working on a bug or feature listed in Jira, please include the ticket number prefixed with GODRIVER in the commit,
-e.g. GODRIVER-123. For the patch commit message itself, please follow the [How to Write a Git Commit Message](https://chris.beams.io/posts/git-commit/) guide.
-
-## Talk To Us
-
-If you want to work on the driver, write documentation, or have questions/complaints, please reach out to use either via
-the [mongo-go-driver Google Group](https://groups.google.com/forum/#!forum/mongodb-go-driver) or by creating a Question
-issue at (https://jira.mongodb.org/secure/CreateIssue!default.jspa).

+ 0 - 367
src/go.mongodb.org/mongo-driver/Gopkg.lock

@@ -1,367 +0,0 @@
-# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
-
-
-[[projects]]
-  digest = "1:6d8a3b164679872fa5a4c44559235f7fb109c7b5cd0f456a2159d579b76cc9ba"
-  name = "github.com/DataDog/zstd"
-  packages = ["."]
-  pruneopts = "UT"
-  revision = "809b919c325d7887bff7bd876162af73db53e878"
-  version = "v1.4.0"
-
-[[projects]]
-  digest = "1:ffe9824d294da03b391f44e1ae8281281b4afc1bdaa9588c9097785e3af10cec"
-  name = "github.com/davecgh/go-spew"
-  packages = ["spew"]
-  pruneopts = "UT"
-  revision = "8991bc29aa16c548c550c7ff78260e27b9ab7c73"
-  version = "v1.1.1"
-
-[[projects]]
-  digest = "1:586ea76dbd0374d6fb649a91d70d652b7fe0ccffb8910a77468e7702e7901f3d"
-  name = "github.com/go-stack/stack"
-  packages = ["."]
-  pruneopts = "UT"
-  revision = "2fee6af1a9795aafbe0253a0cfbdf668e1fb8a9a"
-  version = "v1.8.0"
-
-[[projects]]
-  digest = "1:d29ee5ef14a7e0253facd0bcebe6a69a7a4e02a67eb24d2aacd8ccb4a7cea6fc"
-  name = "github.com/gobuffalo/envy"
-  packages = ["."]
-  pruneopts = "UT"
-  revision = "043cb4b8af871b49563291e32c66bb84378a60ac"
-  version = "v1.7.0"
-
-[[projects]]
-  digest = "1:149bf2c3b6b332f0cfefed9ae4b8c01c527927d369d7a0f41a211c8bf588b556"
-  name = "github.com/gobuffalo/genny"
-  packages = ["."]
-  pruneopts = "UT"
-  revision = "05dc5921e98daa5d406f90c2844ff163cb1e1c4e"
-  version = "v0.1.1"
-
-[[projects]]
-  digest = "1:3812ee37547a0d26633006c910672c42ddf6f932f79dea6a4446979a561f7d60"
-  name = "github.com/gobuffalo/gogen"
-  packages = [
-    ".",
-    "goimports",
-    "gomods",
-  ]
-  pruneopts = "UT"
-  revision = "5482e6ef5d999f8cfa9b038a53953c9b4ee090af"
-  version = "v0.1.1"
-
-[[projects]]
-  branch = "master"
-  digest = "1:f391538f4166f7c0aa50943372af196304488b039fe663c134d42f064e1ed92c"
-  name = "github.com/gobuffalo/logger"
-  packages = ["."]
-  pruneopts = "UT"
-  revision = "86e12af44bc273e0063fad5b6ad588890b8cfe6b"
-
-[[projects]]
-  digest = "1:a3259d2a6c245b62e40232800e3ebb4d7d5840940638de0e4754cb13cdd37790"
-  name = "github.com/gobuffalo/mapi"
-  packages = ["."]
-  pruneopts = "UT"
-  revision = "0bb5e840be332d4280e40f2e6c50777c615bbac5"
-  version = "v1.0.2"
-
-[[projects]]
-  digest = "1:1342bed0d7aded5e5c1c958675f0662c9dbaf2d61fa0a8c5918a144737cff3e4"
-  name = "github.com/gobuffalo/packd"
-  packages = ["."]
-  pruneopts = "UT"
-  revision = "9efbb667f2024a9370cadda45a57a0657c88a6fb"
-  version = "v0.1.0"
-
-[[projects]]
-  digest = "1:0fac441be66684180b031233313b8315644c0734fd73944c3e156e3cf5fbe203"
-  name = "github.com/gobuffalo/packr"
-  packages = [
-    "v2",
-    "v2/file",
-    "v2/file/resolver",
-    "v2/file/resolver/encoding/hex",
-    "v2/jam/parser",
-    "v2/plog",
-  ]
-  pruneopts = "UT"
-  revision = "cda4ac25577350dac682c8715dc6659327232596"
-  version = "v2.2.0"
-
-[[projects]]
-  branch = "master"
-  digest = "1:b90ac64448d67ef218124185a8524f3c665fb7f51f096d5dd51ce950a1775d89"
-  name = "github.com/gobuffalo/syncx"
-  packages = ["."]
-  pruneopts = "UT"
-  revision = "33c29581e754bd354236e977dfe426e55331c45d"
-
-[[projects]]
-  branch = "master"
-  digest = "1:e4f5819333ac698d294fe04dbf640f84719658d5c7ce195b10060cc37292ce79"
-  name = "github.com/golang/snappy"
-  packages = ["."]
-  pruneopts = "UT"
-  revision = "2a8bb927dd31d8daada140a5d09578521ce5c36a"
-
-[[projects]]
-  digest = "1:d2754cafcab0d22c13541618a8029a70a8959eb3525ff201fe971637e2274cd0"
-  name = "github.com/google/go-cmp"
-  packages = [
-    "cmp",
-    "cmp/cmpopts",
-    "cmp/internal/diff",
-    "cmp/internal/function",
-    "cmp/internal/value",
-  ]
-  pruneopts = "UT"
-  revision = "3af367b6b30c263d47e8895973edcca9a49cf029"
-  version = "v0.2.0"
-
-[[projects]]
-  digest = "1:ecd9aa82687cf31d1585d4ac61d0ba180e42e8a6182b85bd785fcca8dfeefc1b"
-  name = "github.com/joho/godotenv"
-  packages = ["."]
-  pruneopts = "UT"
-  revision = "23d116af351c84513e1946b527c88823e476be13"
-  version = "v1.3.0"
-
-[[projects]]
-  digest = "1:19cce3954c778b676622745e850f7d201eefffbb62d2c42ce87673617f96e95a"
-  name = "github.com/karrick/godirwalk"
-  packages = ["."]
-  pruneopts = "UT"
-  revision = "5e617d9cfec6f870e63b168e9a2fb7c490a1c108"
-  version = "v1.10.3"
-
-[[projects]]
-  digest = "1:31e761d97c76151dde79e9d28964a812c46efc5baee4085b86f68f0c654450de"
-  name = "github.com/konsorten/go-windows-terminal-sequences"
-  packages = ["."]
-  pruneopts = "UT"
-  revision = "f55edac94c9bbba5d6182a4be46d86a2c9b5b50e"
-  version = "v1.0.2"
-
-[[projects]]
-  digest = "1:ca955a9cd5b50b0f43d2cc3aeb35c951473eeca41b34eb67507f1dbcc0542394"
-  name = "github.com/kr/pretty"
-  packages = ["."]
-  pruneopts = "UT"
-  revision = "73f6ac0b30a98e433b289500d779f50c1a6f0712"
-  version = "v0.1.0"
-
-[[projects]]
-  digest = "1:15b5cc79aad436d47019f814fde81a10221c740dc8ddf769221a65097fb6c2e9"
-  name = "github.com/kr/text"
-  packages = ["."]
-  pruneopts = "UT"
-  revision = "e2ffdb16a802fe2bb95e2e35ff34f0e53aeef34f"
-  version = "v0.1.0"
-
-[[projects]]
-  branch = "master"
-  digest = "1:6e2ed1bdbf1d14b4d0be58bcd3f1c3000c1e226964354457b8e6ca69e83a1cbb"
-  name = "github.com/markbates/oncer"
-  packages = ["."]
-  pruneopts = "UT"
-  revision = "bf2de49a0be218916e69a11d22866e6cd0a560f2"
-
-[[projects]]
-  digest = "1:28687e854cec240942c103259668b132a8450b05a6cc677eea2282b26ae29310"
-  name = "github.com/markbates/safe"
-  packages = ["."]
-  pruneopts = "UT"
-  revision = "6fea05a5732486546a4836b7a1d596c5ec687b98"
-  version = "v1.0.1"
-
-[[projects]]
-  digest = "1:246ab598a22ea9d50f46e65f655f78161a19822f6597268b02f04af998684807"
-  name = "github.com/montanaflynn/stats"
-  packages = ["."]
-  pruneopts = "UT"
-  revision = "1bf9dbcd8cbe1fdb75add3785b1d4a9a646269ab"
-  version = "0.3.0"
-
-[[projects]]
-  digest = "1:93131d8002d7025da13582877c32d1fc302486775a1b06f62241741006428c5e"
-  name = "github.com/pelletier/go-toml"
-  packages = ["."]
-  pruneopts = "UT"
-  revision = "728039f679cbcd4f6a54e080d2219a4c4928c546"
-  version = "v1.4.0"
-
-[[projects]]
-  digest = "1:cf31692c14422fa27c83a05292eb5cbe0fb2775972e8f1f8446a71549bd8980b"
-  name = "github.com/pkg/errors"
-  packages = ["."]
-  pruneopts = "UT"
-  revision = "ba968bfe8b2f7e042a574c888954fccecfa385b4"
-  version = "v0.8.1"
-
-[[projects]]
-  digest = "1:0028cb19b2e4c3112225cd871870f2d9cf49b9b4276531f03438a88e94be86fe"
-  name = "github.com/pmezard/go-difflib"
-  packages = ["difflib"]
-  pruneopts = "UT"
-  revision = "792786c7400a136282c1664665ae0a8db921c6c2"
-  version = "v1.0.0"
-
-[[projects]]
-  digest = "1:e09ada96a5a41deda4748b1659cc8953961799e798aea557257b56baee4ecaf3"
-  name = "github.com/rogpeppe/go-internal"
-  packages = [
-    "modfile",
-    "module",
-    "semver",
-  ]
-  pruneopts = "UT"
-  revision = "438578804ca6f31be148c27683afc419ce47c06e"
-  version = "v1.3.0"
-
-[[projects]]
-  digest = "1:04457f9f6f3ffc5fea48e71d62f2ca256637dee0a04d710288e27e05c8b41976"
-  name = "github.com/sirupsen/logrus"
-  packages = ["."]
-  pruneopts = "UT"
-  revision = "839c75faf7f98a33d445d181f3018b5c3409a45e"
-  version = "v1.4.2"
-
-[[projects]]
-  digest = "1:5da8ce674952566deae4dbc23d07c85caafc6cfa815b0b3e03e41979cedb8750"
-  name = "github.com/stretchr/testify"
-  packages = [
-    "assert",
-    "require",
-  ]
-  pruneopts = "UT"
-  revision = "ffdc059bfe9ce6a4e144ba849dbedead332c6053"
-  version = "v1.3.0"
-
-[[projects]]
-  branch = "master"
-  digest = "1:ddfe0a54e5f9b29536a6d7b2defa376f2cb2b6e4234d676d7ff214d5b097cb50"
-  name = "github.com/tidwall/pretty"
-  packages = ["."]
-  pruneopts = "UT"
-  revision = "1166b9ac2b65e46a43d8618d30d1554f4652d49b"
-
-[[projects]]
-  branch = "master"
-  digest = "1:40fdfd6ab85ca32b6935853bbba35935dcb1d796c8135efd85947566c76e662e"
-  name = "github.com/xdg/scram"
-  packages = ["."]
-  pruneopts = "UT"
-  revision = "7eeb5667e42c09cb51bf7b7c28aea8c56767da90"
-
-[[projects]]
-  branch = "master"
-  digest = "1:f5c1d04bc09c644c592b45b9f0bad4030521b1a7d11c7dadbb272d9439fa6e8e"
-  name = "github.com/xdg/stringprep"
-  packages = ["."]
-  pruneopts = "UT"
-  revision = "73f8eece6fdcd902c185bf651de50f3828bed5ed"
-
-[[projects]]
-  branch = "master"
-  digest = "1:35ce874cf16f78a2da908ab28b0277497e36603d289db00d39da5200bc8ace08"
-  name = "golang.org/x/crypto"
-  packages = [
-    "pbkdf2",
-    "ssh/terminal",
-  ]
-  pruneopts = "UT"
-  revision = "20be4c3c3ed52bfccdb2d59a412ee1a936d175a7"
-
-[[projects]]
-  branch = "master"
-  digest = "1:76ee51c3f468493aff39dbacc401e8831fbb765104cbf613b89bef01cf4bad70"
-  name = "golang.org/x/net"
-  packages = ["context"]
-  pruneopts = "UT"
-  revision = "f3200d17e092c607f615320ecaad13d87ad9a2b3"
-
-[[projects]]
-  branch = "master"
-  digest = "1:382bb5a7fb4034db3b6a2d19e5a4a6bcf52f4750530603c01ca18a172fa3089b"
-  name = "golang.org/x/sync"
-  packages = ["semaphore"]
-  pruneopts = "UT"
-  revision = "112230192c580c3556b8cee6403af37a4fc5f28c"
-
-[[projects]]
-  branch = "master"
-  digest = "1:a02364950e8c7394b03f886e57a3f7acfc4fba32ce03c186dd9f36b501d0484b"
-  name = "golang.org/x/sys"
-  packages = [
-    "unix",
-    "windows",
-  ]
-  pruneopts = "UT"
-  revision = "4c3a928424d249a1013e789cf5e458d480bcba16"
-
-[[projects]]
-  digest = "1:1093f2eb4b344996604f7d8b29a16c5b22ab9e1b25652140d3fede39f640d5cd"
-  name = "golang.org/x/text"
-  packages = [
-    "internal/gen",
-    "internal/triegen",
-    "internal/ucd",
-    "transform",
-    "unicode/cldr",
-    "unicode/norm",
-  ]
-  pruneopts = "UT"
-  revision = "342b2e1fbaa52c93f31447ad2c6abc048c63e475"
-  version = "v0.3.2"
-
-[[projects]]
-  branch = "master"
-  digest = "1:7c7aa31cc6bc5c85038e46d8c6541a2fb2332b1687229a5a5a04d7b91cea0efe"
-  name = "golang.org/x/tools"
-  packages = [
-    "go/ast/astutil",
-    "go/gcexportdata",
-    "go/internal/gcimporter",
-    "go/internal/packagesdriver",
-    "go/packages",
-    "go/types/typeutil",
-    "imports",
-    "internal/fastwalk",
-    "internal/gopathwalk",
-    "internal/imports",
-    "internal/module",
-    "internal/semver",
-  ]
-  pruneopts = "UT"
-  revision = "b3315ee88b7da2b23cc6c62484a006958910e841"
-
-[solve-meta]
-  analyzer-name = "dep"
-  analyzer-version = 1
-  input-imports = [
-    "github.com/DataDog/zstd",
-    "github.com/go-stack/stack",
-    "github.com/gobuffalo/packr/v2",
-    "github.com/golang/snappy",
-    "github.com/google/go-cmp/cmp",
-    "github.com/google/go-cmp/cmp/cmpopts",
-    "github.com/kr/pretty",
-    "github.com/montanaflynn/stats",
-    "github.com/pelletier/go-toml",
-    "github.com/pkg/errors",
-    "github.com/stretchr/testify/assert",
-    "github.com/stretchr/testify/require",
-    "github.com/tidwall/pretty",
-    "github.com/xdg/scram",
-    "github.com/xdg/stringprep",
-    "golang.org/x/net/context",
-    "golang.org/x/sync/semaphore",
-    "golang.org/x/tools/go/packages",
-    "golang.org/x/tools/imports",
-  ]
-  solver-name = "gps-cdcl"
-  solver-version = 1

+ 0 - 58
src/go.mongodb.org/mongo-driver/Gopkg.toml

@@ -1,58 +0,0 @@
-# Gopkg.toml example
-#
-# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html
-# for detailed Gopkg.toml documentation.
-#
-# required = ["github.com/user/thing/cmd/thing"]
-# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
-#
-# [[constraint]]
-#   name = "github.com/user/project"
-#   version = "1.0.0"
-#
-# [[constraint]]
-#   name = "github.com/user/project2"
-#   branch = "dev"
-#   source = "github.com/myfork/project2"
-#
-# [[override]]
-#   name = "github.com/x/y"
-#   version = "2.4.0"
-#
-# [prune]
-#   non-go = false
-#   go-tests = true
-#   unused-packages = true
-
-
-[[constraint]]
-  name = "github.com/go-stack/stack"
-  version = "1.7.0"
-
-[[constraint]]
-  branch = "master"
-  name = "github.com/golang/snappy"
-
-[[constraint]]
-  name = "github.com/google/go-cmp"
-  version = "0.2.0"
-
-[[constraint]]
-  name = "github.com/montanaflynn/stats"
-  version = "0.3.0"
-
-[[constraint]]
-  branch = "master"
-  name = "github.com/tidwall/pretty"
-
-[[constraint]]
-  branch = "master"
-  name = "github.com/xdg/stringprep"
-
-[prune]
-  go-tests = true
-  unused-packages = true
-
-[[constraint]]
-  name = "github.com/DataDog/zstd"
-  version = "~1.4.0"

+ 0 - 201
src/go.mongodb.org/mongo-driver/LICENSE

@@ -1,201 +0,0 @@
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.

+ 0 - 147
src/go.mongodb.org/mongo-driver/Makefile

@@ -1,147 +0,0 @@
-BSON_PKGS = $(shell etc/list_pkgs.sh ./bson)
-BSON_TEST_PKGS = $(shell etc/list_test_pkgs.sh ./bson)
-MONGO_PKGS = $(shell etc/list_pkgs.sh ./mongo)
-MONGO_TEST_PKGS = $(shell etc/list_test_pkgs.sh ./mongo)
-UNSTABLE_PKGS = $(shell etc/list_pkgs.sh ./x)
-UNSTABLE_TEST_PKGS = $(shell etc/list_test_pkgs.sh ./x)
-TAG_PKG = $(shell etc/list_pkgs.sh ./tag)
-TAG_TEST_PKG = $(shell etc/list_test_pkgs.sh ./tag)
-EXAMPLES_PKGS = $(shell etc/list_pkgs.sh ./examples)
-EXAMPLES_TEST_PKGS = $(shell etc/list_test_pkgs.sh ./examples)
-PKGS = $(BSON_PKGS) $(MONGO_PKGS) $(UNSTABLE_PKGS) $(TAG_PKG) $(EXAMPLES_PKGS)
-TEST_PKGS = $(BSON_TEST_PKGS) $(MONGO_TEST_PKGS) $(UNSTABLE_TEST_PKGS) $(TAG_PKG) $(EXAMPLES_TEST_PKGS)
-ATLAS_URIS = "$(ATLAS_FREE)" "$(ATLAS_REPLSET)" "$(ATLAS_SHARD)" "$(ATLAS_TLS11)" "$(ATLAS_TLS12)" "$(ATLAS_FREE_SRV)" "$(ATLAS_REPLSET_SRV)" "$(ATLAS_SHARD_SRV)" "$(ATLAS_TLS11_SRV)" "$(ATLAS_TLS12_SRV)"
-
-TEST_TIMEOUT = 600
-
-.PHONY: default
-default: check-env check-fmt vet build-examples lint errcheck test-cover test-race
-
-.PHONY: check-env
-check-env:
-	etc/check_env.sh
-
-.PHONY: doc
-doc:
-	godoc -http=:6060 -index
-
-.PHONY: build-examples
-build-examples:
-	go build $(BUILD_TAGS) ./examples/... ./x/mongo/driver/examples/...
-
-.PHONY: build
-build:
-	go build $(filter-out ./core/auth/internal/gssapi,$(PKGS))
-
-.PHONY: build-cse
-build-cse:
-	go build -tags cse $(filter-out ./core/auth/internal/gssapi,$(PKGS))
-
-.PHONY: check-fmt
-check-fmt:
-	etc/check_fmt.sh $(PKGS)
-
-.PHONY: fmt
-fmt:
-	gofmt -l -s -w $(PKGS)
-
-.PHONY: lint
-lint:
-	golint $(PKGS) | ./etc/lintscreen.pl .lint-whitelist
-
-.PHONY: lint-add-whitelist
-lint-add-whitelist:
-	golint $(PKGS) | ./etc/lintscreen.pl -u .lint-whitelist
-	sort .lint-whitelist -o .lint-whitelist
-
-.PHONY: errcheck
-errcheck:
-	errcheck -exclude .errcheck-excludes ./bson/... ./mongo/... ./x/...
-
-.PHONY: test
-test:
-	for TEST in $(TEST_PKGS) ; do \
-		go test $(BUILD_TAGS) -timeout $(TEST_TIMEOUT)s $$TEST ; \
-	done
-
-.PHONY: test-cover
-test-cover:
-	for TEST in $(TEST_PKGS) ; do \
-    	go test $(BUILD_TAGS) -timeout $(TEST_TIMEOUT)s -cover $(COVER_ARGS) $$TEST ; \
-    done
-
-.PHONY: test-race
-test-race:
-	for TEST in $(TEST_PKGS) ; do \
-    	go test $(BUILD_TAGS) -timeout $(TEST_TIMEOUT)s -race $(COVER_ARGS) $$TEST ; \
-    done
-
-.PHONY: test-short
-test-short:
-	for TEST in $(TEST_PKGS) ; do \
-    	go test $(BUILD_TAGS) -timeout $(TEST_TIMEOUT)s -short $(COVER_ARGS) $$TEST ; \
-    done
-
-.PHONY: update-bson-corpus-tests
-update-bson-corpus-tests:
-	etc/update-spec-tests.sh bson-corpus
-
-.PHONY: update-connection-string-tests
-update-connection-string-tests:
-	etc/update-spec-tests.sh connection-string
-
-.PHONY: update-crud-tests
-update-crud-tests:
-	etc/update-spec-tests.sh crud
-
-.PHONY: update-initial-dns-seedlist-discovery-tests
-update-initial-dns-seedlist-discovery-tests:
-	etc/update-spec-tests.sh initial-dns-seedlist-discovery
-
-.PHONY: update-max-staleness-tests
-update-max-staleness-tests:
-	etc/update-spec-tests.sh max-staleness
-
-.PHONY: update-server-discovery-and-monitoring-tests
-update-server-discovery-and-monitoring-tests:
-	etc/update-spec-tests.sh server-discovery-and-monitoring
-
-.PHONY: update-server-selection-tests
-update-server-selection-tests:
-	etc/update-spec-tests.sh server-selection
-
-.PHONY: update-notices
-update-notices:
-	etc/generate-notices.pl > THIRD-PARTY-NOTICES
-
-.PHONY: vet
-vet:
-	go vet -cgocall=false -composites=false -unusedstringmethods="Error" $(PKGS)
-
-
-# Evergreen specific targets
-.PHONY: evg-test
-evg-test:
-	for TEST in $(TEST_PKGS) ; do \
-		LD_LIBRARY_PATH=$(LD_LIBRARY_PATH) PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) go test $(BUILD_TAGS) -v -timeout $(TEST_TIMEOUT)s $$TEST >> test.suite ; \
-	done
-
-.PHONY: evg-test-auth
-evg-test-auth:
-	go run -tags gssapi ./x/mongo/driver/examples/count/main.go -uri $(MONGODB_URI)
-
-.PHONY: evg-test-atlas
-evg-test-atlas:
-	go run ./mongo/testatlas/main.go $(ATLAS_URIS)
-
-# benchmark specific targets and support
-perf:driver-test-data.tar.gz
-	tar -zxf $< $(if $(eq $(UNAME_S),Darwin),-s , --transform=s)/data/perf/
-	@touch $@
-driver-test-data.tar.gz:
-	curl --retry 5 "https://s3.amazonaws.com/boxes.10gen.com/build/driver-test-data.tar.gz" -o driver-test-data.tar.gz --silent --max-time 120
-benchmark:perf
-	go test $(BUILD_TAGS) -benchmem -bench=. ./benchmark
-driver-benchmark:perf
-	@go run cmd/godriver-benchmark/main.go | tee perf.suite
-.PHONY:benchmark driver-benchmark

+ 0 - 193
src/go.mongodb.org/mongo-driver/README.md

@@ -1,193 +0,0 @@
-<p align="center"><img src="etc/assets/mongo-gopher.png" width="250"></p>
-<p align="center">
-  <a href="https://goreportcard.com/report/go.mongodb.org/mongo-driver"><img src="https://goreportcard.com/badge/go.mongodb.org/mongo-driver"></a>
-  <a href="https://godoc.org/go.mongodb.org/mongo-driver/mongo"><img src="etc/assets/godoc-mongo-blue.svg" alt="GoDoc"></a>
-  <a href="https://godoc.org/go.mongodb.org/mongo-driver/bson"><img src="etc/assets/godoc-bson-blue.svg" alt="GoDoc"></a>
-  <a href="https://docs.mongodb.com/ecosystem/drivers/go/"><img src="etc/assets/docs-mongodb-green.svg"></a>
-</p>
-
-# MongoDB Go Driver
-
-The MongoDB supported driver for Go.
-
--------------------------
-- [Requirements](#requirements)
-- [Installation](#installation)
-- [Usage](#usage)
-- [Bugs / Feature Reporting](#bugs--feature-reporting)
-- [Testing / Development](#testing--development)
-- [Continuous Integration](#continuous-integration)
-- [License](#license)
-
--------------------------
-## Requirements
-
-- Go 1.10 or higher. We aim to support the latest supported versions of go.
-- MongoDB 2.6 and higher.
-
--------------------------
-## Installation
-
-The recommended way to get started using the MongoDB Go driver is by using `dep` to install the dependency in your project.
-
-```bash
-dep ensure -add "go.mongodb.org/mongo-driver/mongo@~1.1.0"
-```
-
--------------------------
-## Usage
-
-To get started with the driver, import the `mongo` package, create a `mongo.Client`:
-
-```go
-import (
-    "go.mongodb.org/mongo-driver/mongo"
-    "go.mongodb.org/mongo-driver/mongo/options"
-)
-
-client, err := mongo.NewClient(options.Client().ApplyURI("mongodb://localhost:27017"))
-```
-
-And connect it to your running MongoDB server:
-
-```go
-ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)
-err = client.Connect(ctx)
-```
-
-To do this in a single step, you can use the `Connect` function:
-
-```go
-ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)
-client, err := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://localhost:27017"))
-```
-
-Calling `Connect` does not block for server discovery. If you wish to know if a MongoDB server has been found and connected to,
-use the `Ping` method:
-
-```go
-ctx, _ = context.WithTimeout(context.Background(), 2*time.Second)
-err = client.Ping(ctx, readpref.Primary())
-```
-
-To insert a document into a collection, first retrieve a `Database` and then `Collection` instance from the `Client`:
-
-```go
-collection := client.Database("testing").Collection("numbers")
-```
-
-The `Collection` instance can then be used to insert documents:
-
-```go
-ctx, _ = context.WithTimeout(context.Background(), 5*time.Second)
-res, err := collection.InsertOne(ctx, bson.M{"name": "pi", "value": 3.14159})
-id := res.InsertedID
-```
-
-Several query methods return a cursor, which can be used like this:
-
-```go
-ctx, _ = context.WithTimeout(context.Background(), 30*time.Second)
-cur, err := collection.Find(ctx, bson.D{})
-if err != nil { log.Fatal(err) }
-defer cur.Close(ctx)
-for cur.Next(ctx) {
-   var result bson.M
-   err := cur.Decode(&result)
-   if err != nil { log.Fatal(err) }
-   // do something with result....
-}
-if err := cur.Err(); err != nil {
-  log.Fatal(err)
-}
-```
-
-For methods that return a single item, a `SingleResult` instance is returned:
-
-```go
-var result struct {
-    Value float64
-}
-filter := bson.M{"name": "pi"}
-ctx, _ = context.WithTimeout(context.Background(), 5*time.Second)
-err = collection.FindOne(ctx, filter).Decode(&result)
-if err != nil {
-    log.Fatal(err)
-}
-// Do something with result...
-```
-
-Additional examples and documentation can be found under the examples directory and [on the MongoDB Documentation website](https://docs.mongodb.com/ecosystem/drivers/go/).
-
--------------------------
-## Bugs / Feature Reporting
-
-New Features and bugs can be reported on jira: https://jira.mongodb.org/browse/GODRIVER
-
--------------------------
-## Testing / Development
-
-The driver tests can be run against several database configurations. The most simple configuration is a standalone mongod with no auth, no ssl, and no compression. To run these basic driver tests, make sure a standalone MongoDB server instance is running at localhost:27017. To run the tests, you can run `make` (on Windows, run `nmake`). This will run coverage, run go-lint, run go-vet, and build the examples.
-
-### Testing Different Topologies
-
-To test a **replica set** or **sharded cluster**, set `MONGODB_URI="<connection-string>"` for the `make` command.
-For example, for a local replica set named `rs1` comprised of three nodes on ports 27017, 27018, and 27019:
-
-```
-MONGODB_URI="mongodb://localhost:27017,localhost:27018,localhost:27018/?replicaSet=rs1" make
-```
-
-### Testing Auth and SSL
-
-To test authentication and SSL, first set up a MongoDB cluster with auth and SSL configured. Testing authentication requires a user with the `root` role on the `admin` database. The Go Driver repository comes with example certificates in the `data/certificates` directory. These certs can be used for testing. Here is an example command that would run a mongod with SSL correctly configured for tests:
-
-```
-mongod \
---auth \
---sslMode requireSSL \
---sslPEMKeyFile $(pwd)/data/certificates/server.pem \
---sslCAFile $(pwd)/data/certificates/ca.pem \
---sslWeakCertificateValidation
-```
-
-To run the tests with `make`, set `MONGO_GO_DRIVER_CA_FILE` to the location of the CA file used by the database, set `MONGODB_URI` to the connection string of the server, set `AUTH=auth`, and set `SSL=ssl`. For example:
-
-```
-AUTH=auth SSL=ssl MONGO_GO_DRIVER_CA_FILE=$(pwd)/data/certificates/ca.pem  MONGODB_URI="mongodb://user:password@localhost:27017/?authSource=admin" make
-```
-
-Notes:
-- The `--sslWeakCertificateValidation` flag is required on the server for the test suite to work correctly.
-- The test suite requires the auth database to be set with `?authSource=admin`, not `/admin`.
-
-### Testing Compression
-
-The MongoDB Go Driver supports wire protocol compression using Snappy, zLib, or zstd. To run tests with wire protocol compression, set `MONGO_GO_DRIVER_COMPRESSOR` to `snappy`, `zlib`, or `zstd`.  For example:
-
-```
-MONGO_GO_DRIVER_COMPRESSOR=snappy make
-```
-
-Ensure the [`--networkMessageCompressors` flag](https://docs.mongodb.com/manual/reference/program/mongod/#cmdoption-mongod-networkmessagecompressors) on mongod or mongos includes `zlib` if testing zLib compression.
-
--------------------------
-## Feedback
-
-The MongoDB Go Driver is not feature complete, so any help is appreciated. Check out the [project page](https://jira.mongodb.org/browse/GODRIVER)
-for tickets that need completing. See our [contribution guidelines](CONTRIBUTING.md) for details.
-
--------------------------
-## Continuous Integration
-
-Commits to master are run automatically on [evergreen](https://evergreen.mongodb.com/waterfall/mongo-go-driver).
-
--------------------------
-## Thanks and Acknowledgement 
-
-<a href="https://github.com/ashleymcnamara">@ashleymcnamara</a> - Mongo Gopher Artwork
-
--------------------------
-## License
-
-The MongoDB Go Driver is licensed under the [Apache License](LICENSE).

+ 0 - 1336
src/go.mongodb.org/mongo-driver/THIRD-PARTY-NOTICES

@@ -1,1336 +0,0 @@
----------------------------------------------------------------------
-License notice for gopkg.in/mgo.v2/bson
----------------------------------------------------------------------
-
-BSON library for Go
-
-Copyright (c) 2010-2013 - Gustavo Niemeyer <gustavo@niemeyer.net>
-
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met: 
-
-1. Redistributions of source code must retain the above copyright notice, this
-   list of conditions and the following disclaimer. 
-2. Redistributions in binary form must reproduce the above copyright notice,
-   this list of conditions and the following disclaimer in the documentation
-   and/or other materials provided with the distribution. 
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
----------------------------------------------------------------------
-License notice for JSON and CSV code from github.com/golang/go
----------------------------------------------------------------------
-
-Copyright (c) 2009 The Go Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-   * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-   * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
-   * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-License notice for github.com/davecgh/go-spew
-----------------------------------------------------------------------
-
-ISC License
-
-Copyright (c) 2012-2016 Dave Collins <dave@davec.name>
-
-Permission to use, copy, modify, and/or distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-----------------------------------------------------------------------
-License notice for github.com/gobuffalo/genny
-----------------------------------------------------------------------
-
-The MIT License (MIT)
-
-Copyright (c) 2019 Mark Bates
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-
-----------------------------------------------------------------------
-License notice for github.com/gobuffalo/genny/genny
-----------------------------------------------------------------------
-
-The MIT License (MIT)
-
-Copyright © 2018 Mark Bates
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
-----------------------------------------------------------------------
-License notice for github.com/gobuffalo/gogen
-----------------------------------------------------------------------
-
-The MIT License (MIT)
-
-Copyright (c) 2019 Mark Bates
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-
-----------------------------------------------------------------------
-License notice for github.com/gobuffalo/gogen/goimports
-----------------------------------------------------------------------
-
-Copyright (c) 2009 The Go Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-   * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-   * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
-   * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-License notice for github.com/gobuffalo/logger
-----------------------------------------------------------------------
-
-The MIT License (MIT)
-
-Copyright (c) 2018 Mark Bates
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-
-----------------------------------------------------------------------
-License notice for github.com/gobuffalo/mapi
-----------------------------------------------------------------------
-
-The MIT License (MIT)
-
-Copyright (c) 2018 Mark Bates
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-
-----------------------------------------------------------------------
-License notice for github.com/gobuffalo/packd
-----------------------------------------------------------------------
-
-The MIT License (MIT)
-
-Copyright (c) 2018 Mark Bates
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-
-----------------------------------------------------------------------
-License notice for github.com/gobuffalo/packr/v2/packr2
-----------------------------------------------------------------------
-
-The MIT License (MIT)
-
-Copyright © 2018 Mark Bates
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
-----------------------------------------------------------------------
-License notice for github.com/gobuffalo/syncx
-----------------------------------------------------------------------
-
-The MIT License (MIT)
-
-Copyright (c) 2018 Mark Bates
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-
-----------------------------------------------------------------------
-License notice for github.com/golang/snappy
-----------------------------------------------------------------------
-
-Copyright (c) 2011 The Snappy-Go Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-   * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-   * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
-   * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-License notice for github.com/google/go-cmp
-----------------------------------------------------------------------
-
-Copyright (c) 2017 The Go Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-   * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-   * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
-   * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-License notice for github.com/karrick/godirwalk
-----------------------------------------------------------------------
-
-BSD 2-Clause License
-
-Copyright (c) 2017, Karrick McDermott
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-* Redistributions of source code must retain the above copyright notice, this
-  list of conditions and the following disclaimer.
-
-* Redistributions in binary form must reproduce the above copyright notice,
-  this list of conditions and the following disclaimer in the documentation
-  and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-License notice for github.com/konsorten/go-windows-terminal-sequences
-----------------------------------------------------------------------
-
-(The MIT License)
-
-Copyright (c) 2017 marvin + konsorten GmbH (open-source@konsorten.de)
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-----------------------------------------------------------------------
-License notice for github.com/kr/pretty
-----------------------------------------------------------------------
-
-The MIT License (MIT)
-
-Copyright 2012 Keith Rarick
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
-----------------------------------------------------------------------
-License notice for github.com/kr/text
-----------------------------------------------------------------------
-
-Copyright 2012 Keith Rarick
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
-----------------------------------------------------------------------
-License notice for github.com/markbates/oncer
-----------------------------------------------------------------------
-
-The MIT License (MIT)
-
-Copyright (c) 2018 Mark Bates
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-
-----------------------------------------------------------------------
-License notice for github.com/markbates/safe
-----------------------------------------------------------------------
-
-The MIT License (MIT)
-
-Copyright (c) 2018 Mark Bates
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-
-----------------------------------------------------------------------
-License notice for github.com/montanaflynn/stats
-----------------------------------------------------------------------
-
-The MIT License (MIT)
-
-Copyright (c) 2014-2015 Montana Flynn (https://anonfunction.com)
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-
-----------------------------------------------------------------------
-License notice for github.com/pelletier/go-toml
-----------------------------------------------------------------------
-
-The MIT License (MIT)
-
-Copyright (c) 2013 - 2017 Thomas Pelletier, Eric Anderton
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-
-----------------------------------------------------------------------
-License notice for github.com/pkg/errors
-----------------------------------------------------------------------
-
-Copyright (c) 2015, Dave Cheney <dave@cheney.net>
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-* Redistributions of source code must retain the above copyright notice, this
-  list of conditions and the following disclaimer.
-
-* Redistributions in binary form must reproduce the above copyright notice,
-  this list of conditions and the following disclaimer in the documentation
-  and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-License notice for github.com/pmezard/go-difflib
-----------------------------------------------------------------------
-
-Copyright (c) 2013, Patrick Mezard
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-    Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-    Redistributions in binary form must reproduce the above copyright
-notice, this list of conditions and the following disclaimer in the
-documentation and/or other materials provided with the distribution.
-    The names of its contributors may not be used to endorse or promote
-products derived from this software without specific prior written
-permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-License notice for github.com/rogpeppe/go-internal
-----------------------------------------------------------------------
-
-Copyright (c) 2018 The Go Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-   * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-   * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
-   * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-License notice for github.com/sirupsen/logrus
-----------------------------------------------------------------------
-
-The MIT License (MIT)
-
-Copyright (c) 2014 Simon Eskildsen
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
-----------------------------------------------------------------------
-License notice for github.com/stretchr/testify
-----------------------------------------------------------------------
-
-MIT License
-
-Copyright (c) 2012-2018 Mat Ryer and Tyler Bunnell
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-
-----------------------------------------------------------------------
-License notice for github.com/tidwall/pretty
-----------------------------------------------------------------------
-
-The MIT License (MIT)
-
-Copyright (c) 2017 Josh Baker
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-----------------------------------------------------------------------
-License notice for github.com/xdg/scram
-----------------------------------------------------------------------
-
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-----------------------------------------------------------------------
-License notice for github.com/xdg/stringprep
-----------------------------------------------------------------------
-
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-----------------------------------------------------------------------
-License notice for golang.org/x/crypto
-----------------------------------------------------------------------
-
-Copyright (c) 2009 The Go Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-   * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-   * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
-   * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-License notice for golang.org/x/net
-----------------------------------------------------------------------
-
-Copyright (c) 2009 The Go Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-   * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-   * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
-   * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-License notice for golang.org/x/sync
-----------------------------------------------------------------------
-
-Copyright (c) 2009 The Go Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-   * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-   * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
-   * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-License notice for golang.org/x/sys
-----------------------------------------------------------------------
-
-Copyright (c) 2009 The Go Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-   * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-   * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
-   * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-License notice for golang.org/x/text
-----------------------------------------------------------------------
-
-Copyright (c) 2009 The Go Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-   * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-   * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
-   * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-License notice for golang.org/x/tools
-----------------------------------------------------------------------
-
-Copyright (c) 2009 The Go Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-   * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-   * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
-   * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-License notice for golang.org/x/tools/cmd/getgo
-----------------------------------------------------------------------
-
-Copyright (c) 2017 The Go Authors. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-   * Redistributions of source code must retain the above copyright
-notice, this list of conditions and the following disclaimer.
-   * Redistributions in binary form must reproduce the above
-copyright notice, this list of conditions and the following disclaimer
-in the documentation and/or other materials provided with the
-distribution.
-   * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ 0 - 75
src/go.mongodb.org/mongo-driver/benchmark/bson.go

@@ -1,75 +0,0 @@
-// Copyright (C) MongoDB, Inc. 2017-present.
-//
-// Licensed under the Apache License, Version 2.0 (the "License"); you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
-
-package benchmark
-
-import (
-	"errors"
-	"io/ioutil"
-	"path/filepath"
-
-	"go.mongodb.org/mongo-driver/bson"
-	"go.mongodb.org/mongo-driver/x/bsonx"
-)
-
-const (
-	perfDataDir  = "perf"
-	bsonDataDir  = "extended_bson"
-	flatBSONData = "flat_bson.json"
-	deepBSONData = "deep_bson.json"
-	fullBSONData = "full_bson.json"
-)
-
-// utility functions for the bson benchmarks
-
-func loadSourceDocument(pathParts ...string) (bsonx.Doc, error) {
-	data, err := ioutil.ReadFile(filepath.Join(pathParts...))
-	if err != nil {
-		return nil, err
-	}
-	doc := bsonx.Doc{}
-	err = bson.UnmarshalExtJSON(data, true, &doc)
-	if err != nil {
-		return nil, err
-	}
-
-	if len(doc) == 0 {
-		return nil, errors.New("empty bson document")
-	}
-
-	return doc, nil
-}
-
-func loadSourceRaw(pathParts ...string) (bson.Raw, error) {
-	doc, err := loadSourceDocument(pathParts...)
-	if err != nil {
-		return nil, err
-	}
-	raw, err := doc.MarshalBSON()
-	if err != nil {
-		return nil, err
-	}
-
-	return bson.Raw(raw), nil
-}
-
-func loadSourceD(pathParts ...string) (bson.D, error) {
-	data, err := ioutil.ReadFile(filepath.Join(pathParts...))
-	if err != nil {
-		return nil, err
-	}
-	doc := bson.D{}
-	err = bson.UnmarshalExtJSON(data, true, &doc)
-	if err != nil {
-		return nil, err
-	}
-
-	if len(doc) == 0 {
-		return nil, errors.New("empty bson document")
-	}
-
-	return doc, nil
-}

+ 0 - 123
src/go.mongodb.org/mongo-driver/benchmark/bson_document.go

@@ -1,123 +0,0 @@
-// Copyright (C) MongoDB, Inc. 2017-present.
-//
-// Licensed under the Apache License, Version 2.0 (the "License"); you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
-
-package benchmark
-
-import (
-	"context"
-	"errors"
-
-	"go.mongodb.org/mongo-driver/x/bsonx"
-)
-
-func bsonDocumentEncoding(ctx context.Context, tm TimerManager, iters int, source string) error {
-	doc, err := loadSourceDocument(getProjectRoot(), perfDataDir, bsonDataDir, source)
-	if err != nil {
-		return err
-	}
-
-	tm.ResetTimer()
-
-	for i := 0; i < iters; i++ {
-		out, err := doc.MarshalBSON()
-		if err != nil {
-			return err
-		}
-		if len(out) == 0 {
-			return errors.New("marshaling error")
-		}
-	}
-
-	return nil
-}
-
-func bsonDocumentDecodingLazy(ctx context.Context, tm TimerManager, iters int, source string) error {
-	doc, err := loadSourceDocument(getProjectRoot(), perfDataDir, bsonDataDir, source)
-	if err != nil {
-		return err
-	}
-
-	raw, err := doc.MarshalBSON()
-	if err != nil {
-		return err
-	}
-
-	tm.ResetTimer()
-
-	for i := 0; i < iters; i++ {
-		out, err := bsonx.ReadDoc(raw)
-		if err != nil {
-			return err
-		}
-		if len(out) == 0 {
-			return errors.New("marshaling error")
-		}
-	}
-	return nil
-}
-
-func bsonDocumentDecoding(ctx context.Context, tm TimerManager, iters, numKeys int, source string) error {
-	doc, err := loadSourceDocument(getProjectRoot(), perfDataDir, bsonDataDir, source)
-	if err != nil {
-		return err
-	}
-
-	raw, err := doc.MarshalBSON()
-	if err != nil {
-		return err
-	}
-
-	tm.ResetTimer()
-
-	for i := 0; i < iters; i++ {
-		out, err := bsonx.ReadDoc(raw)
-		if err != nil {
-			return err
-		}
-
-		if len(out) != numKeys {
-			return errors.New("document parsing error")
-		}
-	}
-	return nil
-
-}
-
-func BSONFlatDocumentEncoding(ctx context.Context, tm TimerManager, iters int) error {
-	return bsonDocumentEncoding(ctx, tm, iters, flatBSONData)
-}
-
-func BSONFlatDocumentDecodingLazy(ctx context.Context, tm TimerManager, iters int) error {
-	return bsonDocumentDecodingLazy(ctx, tm, iters, flatBSONData)
-}
-
-func BSONFlatDocumentDecoding(ctx context.Context, tm TimerManager, iters int) error {
-	return bsonDocumentDecoding(ctx, tm, iters, 145, flatBSONData)
-}
-
-func BSONDeepDocumentEncoding(ctx context.Context, tm TimerManager, iters int) error {
-	return bsonDocumentEncoding(ctx, tm, iters, deepBSONData)
-}
-
-func BSONDeepDocumentDecodingLazy(ctx context.Context, tm TimerManager, iters int) error {
-	return bsonDocumentDecodingLazy(ctx, tm, iters, deepBSONData)
-}
-
-func BSONDeepDocumentDecoding(ctx context.Context, tm TimerManager, iters int) error {
-	return bsonDocumentDecoding(ctx, tm, iters, 126, deepBSONData)
-}
-
-func BSONFullDocumentEncoding(ctx context.Context, tm TimerManager, iters int) error {
-	return bsonDocumentEncoding(ctx, tm, iters, fullBSONData)
-}
-
-func BSONFullDocumentDecodingLazy(ctx context.Context, tm TimerManager, iters int) error {
-	return bsonDocumentDecodingLazy(ctx, tm, iters, fullBSONData)
-}
-
-func BSONFullDocumentDecoding(ctx context.Context, tm TimerManager, iters int) error {
-	return bsonDocumentDecoding(ctx, tm, iters, 145, fullBSONData)
-}

+ 0 - 88
src/go.mongodb.org/mongo-driver/benchmark/bson_map.go

@@ -1,88 +0,0 @@
-// Copyright (C) MongoDB, Inc. 2017-present.
-//
-// Licensed under the Apache License, Version 2.0 (the "License"); you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
-
-package benchmark
-
-import (
-	"context"
-	"errors"
-	"fmt"
-
-	"go.mongodb.org/mongo-driver/bson"
-)
-
-func bsonMapDecoding(ctx context.Context, tm TimerManager, iters int, dataSet string) error {
-	r, err := loadSourceRaw(getProjectRoot(), perfDataDir, bsonDataDir, dataSet)
-	if err != nil {
-		return err
-	}
-
-	tm.ResetTimer()
-
-	for i := 0; i < iters; i++ {
-		out := make(map[string]interface{})
-		err := bson.Unmarshal(r, &out)
-		if err != nil {
-			return nil
-		}
-		if len(out) == 0 {
-			return fmt.Errorf("decoding failed")
-		}
-	}
-	return nil
-}
-
-func bsonMapEncoding(ctx context.Context, tm TimerManager, iters int, dataSet string) error {
-	r, err := loadSourceRaw(getProjectRoot(), perfDataDir, bsonDataDir, dataSet)
-	if err != nil {
-		return err
-	}
-
-	doc := make(map[string]interface{})
-	err = bson.Unmarshal(r, &doc)
-	if err != nil {
-		return err
-	}
-
-	var buf []byte
-	tm.ResetTimer()
-	for i := 0; i < iters; i++ {
-		buf, err = bson.MarshalAppend(buf[:0], doc)
-		if err != nil {
-			return nil
-		}
-
-		if len(buf) == 0 {
-			return errors.New("encoding failed")
-		}
-	}
-
-	return nil
-}
-
-func BSONFlatMapDecoding(ctx context.Context, tm TimerManager, iters int) error {
-	return bsonMapDecoding(ctx, tm, iters, flatBSONData)
-}
-
-func BSONFlatMapEncoding(ctx context.Context, tm TimerManager, iters int) error {
-	return bsonMapEncoding(ctx, tm, iters, flatBSONData)
-}
-
-func BSONDeepMapDecoding(ctx context.Context, tm TimerManager, iters int) error {
-	return bsonMapDecoding(ctx, tm, iters, deepBSONData)
-}
-
-func BSONDeepMapEncoding(ctx context.Context, tm TimerManager, iters int) error {
-	return bsonMapEncoding(ctx, tm, iters, deepBSONData)
-}
-
-func BSONFullMapDecoding(ctx context.Context, tm TimerManager, iters int) error {
-	return bsonMapDecoding(ctx, tm, iters, fullBSONData)
-}
-
-func BSONFullMapEncoding(ctx context.Context, tm TimerManager, iters int) error {
-	return bsonMapEncoding(ctx, tm, iters, fullBSONData)
-}

+ 0 - 103
src/go.mongodb.org/mongo-driver/benchmark/bson_struct.go

@@ -1,103 +0,0 @@
-// Copyright (C) MongoDB, Inc. 2017-present.
-//
-// Licensed under the Apache License, Version 2.0 (the "License"); you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
-
-package benchmark
-
-import (
-	"context"
-	"errors"
-
-	"go.mongodb.org/mongo-driver/bson"
-)
-
-func BSONFlatStructDecoding(ctx context.Context, tm TimerManager, iters int) error {
-	r, err := loadSourceRaw(getProjectRoot(), perfDataDir, bsonDataDir, flatBSONData)
-	if err != nil {
-		return err
-	}
-
-	tm.ResetTimer()
-
-	for i := 0; i < iters; i++ {
-		out := flatBSON{}
-		err := bson.Unmarshal(r, &out)
-		if err != nil {
-			return err
-		}
-	}
-	return nil
-}
-
-func BSONFlatStructEncoding(ctx context.Context, tm TimerManager, iters int) error {
-	r, err := loadSourceRaw(getProjectRoot(), perfDataDir, bsonDataDir, flatBSONData)
-	if err != nil {
-		return err
-	}
-
-	doc := flatBSON{}
-	err = bson.Unmarshal(r, &doc)
-	if err != nil {
-		return err
-	}
-
-	var buf []byte
-
-	tm.ResetTimer()
-	for i := 0; i < iters; i++ {
-		buf, err = bson.Marshal(doc)
-		if err != nil {
-			return err
-		}
-		if len(buf) == 0 {
-			return errors.New("encoding failed")
-		}
-	}
-	return nil
-}
-
-func BSONFlatStructTagsEncoding(ctx context.Context, tm TimerManager, iters int) error {
-	r, err := loadSourceRaw(getProjectRoot(), perfDataDir, bsonDataDir, flatBSONData)
-	if err != nil {
-		return err
-	}
-
-	doc := flatBSONTags{}
-	err = bson.Unmarshal(r, &doc)
-	if err != nil {
-		return err
-	}
-
-	var buf []byte
-
-	tm.ResetTimer()
-	for i := 0; i < iters; i++ {
-		buf, err = bson.MarshalAppend(buf[:0], doc)
-		if err != nil {
-			return err
-		}
-		if len(buf) == 0 {
-			return errors.New("encoding failed")
-		}
-	}
-	return nil
-}
-
-func BSONFlatStructTagsDecoding(ctx context.Context, tm TimerManager, iters int) error {
-	r, err := loadSourceRaw(getProjectRoot(), perfDataDir, bsonDataDir, flatBSONData)
-	if err != nil {
-		return err
-	}
-
-	tm.ResetTimer()
-	for i := 0; i < iters; i++ {
-		out := flatBSONTags{}
-		err := bson.Unmarshal(r, &out)
-		if err != nil {
-			return err
-		}
-	}
-	return nil
-}

+ 0 - 35
src/go.mongodb.org/mongo-driver/benchmark/bson_test.go

@@ -1,35 +0,0 @@
-// Copyright (C) MongoDB, Inc. 2017-present.
-//
-// Licensed under the Apache License, Version 2.0 (the "License"); you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
-
-package benchmark
-
-import "testing"
-
-// func BenchmarkBSONFullReaderDecoding(b *testing.B)       { WrapCase(BSONFullReaderDecoding)(b) }
-
-func BenchmarkBSONFlatDocumentEncoding(b *testing.B)     { WrapCase(BSONFlatDocumentEncoding)(b) }
-func BenchmarkBSONFlatDocumentDecodingLazy(b *testing.B) { WrapCase(BSONFlatDocumentDecodingLazy)(b) }
-func BenchmarkBSONFlatDocumentDecoding(b *testing.B)     { WrapCase(BSONFlatDocumentDecoding)(b) }
-func BenchmarkBSONDeepDocumentEncoding(b *testing.B)     { WrapCase(BSONDeepDocumentEncoding)(b) }
-func BenchmarkBSONDeepDocumentDecodingLazy(b *testing.B) { WrapCase(BSONDeepDocumentDecodingLazy)(b) }
-func BenchmarkBSONDeepDocumentDecoding(b *testing.B)     { WrapCase(BSONDeepDocumentDecoding)(b) }
-
-// func BenchmarkBSONFullDocumentEncoding(b *testing.B)     { WrapCase(BSONFullDocumentEncoding)(b) }
-// func BenchmarkBSONFullDocumentDecodingLazy(b *testing.B) { WrapCase(BSONFullDocumentDecodingLazy)(b) }
-// func BenchmarkBSONFullDocumentDecoding(b *testing.B)     { WrapCase(BSONFullDocumentDecoding)(b) }
-
-func BenchmarkBSONFlatMapDecoding(b *testing.B) { WrapCase(BSONFlatMapDecoding)(b) }
-func BenchmarkBSONFlatMapEncoding(b *testing.B) { WrapCase(BSONFlatMapEncoding)(b) }
-func BenchmarkBSONDeepMapDecoding(b *testing.B) { WrapCase(BSONDeepMapDecoding)(b) }
-func BenchmarkBSONDeepMapEncoding(b *testing.B) { WrapCase(BSONDeepMapEncoding)(b) }
-
-// func BenchmarkBSONFullMapDecoding(b *testing.B)       { WrapCase(BSONFullMapDecoding)(b) }
-// func BenchmarkBSONFullMapEncoding(b *testing.B)       { WrapCase(BSONFullMapEncoding)(b) }
-
-func BenchmarkBSONFlatStructDecoding(b *testing.B)     { WrapCase(BSONFlatStructDecoding)(b) }
-func BenchmarkBSONFlatStructTagsDecoding(b *testing.B) { WrapCase(BSONFlatStructTagsDecoding)(b) }
-func BenchmarkBSONFlatStructEncoding(b *testing.B)     { WrapCase(BSONFlatStructEncoding)(b) }
-func BenchmarkBSONFlatStructTagsEncoding(b *testing.B) { WrapCase(BSONFlatStructTagsEncoding)(b) }

+ 0 - 306
src/go.mongodb.org/mongo-driver/benchmark/bson_types.go

@@ -1,306 +0,0 @@
-// Copyright (C) MongoDB, Inc. 2017-present.
-//
-// Licensed under the Apache License, Version 2.0 (the "License"); you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
-
-package benchmark
-
-import "go.mongodb.org/mongo-driver/bson/primitive"
-
-type flatBSONTags struct {
-	ID primitive.ObjectID `bson:"_id"`
-
-	AA  int64  `bson:"AAgSNVyBb"`
-	AI  bool   `bson:"aicoMxZq"`
-	AM  int64  `bson:"AMQrGQmu"`
-	Ag  int    `bson:"AgYYbYPr"`
-	Ah  int64  `bson:"ahFCBmqT"`
-	At  int64  `bson:"AtWNZJXa"`
-	BB  string `bson:"BBqZInWV"`
-	BK  int64  `bson:"bkuaZWRT"`
-	Bw  int    `bson:"BwTXiovJ"`
-	CD  int    `bson:"CDIGOuIZ"`
-	CEA string `bson:"CEtYKsdd"`
-	CEB string `bson:"cepcgozk"`
-	CF  int    `bson:"CFujXoob"`
-	CV  int64  `bson:"cVjWCrlu"`
-	CX  string `bson:"cxOHMeDJ"`
-	CY  string `bson:"CYhSCkWB"`
-	Cq  string `bson:"CqCssWxW"`
-	DC  int    `bson:"dCLfYqqM"`
-	DDA int    `bson:"ddPdLgGg"`
-	DDB int    `bson:"ddVenEkK"`
-	DH  string `bson:"dHsYhRbV"`
-	DJ  int    `bson:"DJsnHZIC"`
-	DN  string `bson:"dNSuxlSU"`
-	DO  int64  `bson:"doshbrpF"`
-	DP  string `bson:"dpbwfSRb"`
-	DQ  int64  `bson:"DQBQcQFj"`
-	DT  string `bson:"dtywOLeD"`
-	DV  int    `bson:"dVkWIafN"`
-	EG  bool   `bson:"egxZaSsw"`
-	ER  string `bson:"eRTIdIJR"`
-	FD  int64  `bson:"FDYGeSiR"`
-	FE  string `bson:"fEheUtop"`
-	Fp  bool   `bson:"FpduyhQP"`
-	GE  string `bson:"gErhgZTh"`
-	GY  int    `bson:"gySFZeAE"`
-	Gi  uint   `bson:"GiAHzFII"`
-	HN  string `bson:"hnVgYIQi"`
-	HQA int    `bson:"HQeCoswW"`
-	HQB int    `bson:"HQiykral"`
-	HV  int64  `bson:"HVHyetUM"`
-	HW  int    `bson:"hwHOTmmW"`
-	Hi  bool   `bson:"HicJbMpj"`
-	Hr  int    `bson:"HrUPbFHD"`
-	IF  string `bson:"iFFGfTXc"`
-	IJ  int    `bson:"ijwXMKqI"`
-	IW  int    `bson:"iwfbMdcv"`
-	Ib  string `bson:"Ibrdrtgg"`
-	Is  bool   `bson:"IsorvnMR"`
-	JB  string `bson:"jbUymqiB"`
-	JM  string `bson:"jmglLvAS"`
-	JW  int    `bson:"jWaFvVAz"`
-	JX  int    `bson:"JXMyYkfb"`
-	Jh  bool   `bson:"JhImQOkw"`
-	Jr  string `bson:"JrJzKiIx"`
-	Jz  int    `bson:"JzgaUWVG"`
-	KF  bool   `bson:"kfvcFmKw"`
-	KM  int64  `bson:"KMKBtlov"`
-	Kn  string `bson:"KnhgtAOJ"`
-	Ky  int    `bson:"KyxOoCqS"`
-	LU  string `bson:"LUPqMOHS"`
-	LV  bool   `bson:"LVNIFCYm"`
-	Ln  int    `bson:"LngvlnTV"`
-	ML  int    `bson:"mlfZVfVT"`
-	MN  bool   `bson:"MNuWZMLP"`
-	MX  int    `bson:"MXMxLVBk"`
-	Mc  string `bson:"McpOBmaR"`
-	Me  string `bson:"MeUYSkPS"`
-	Mq  int    `bson:"MqfkBZJF"`
-	NB  int    `bson:"nBKWWUWk"`
-	NK  int    `bson:"nKhiSITP"`
-	OB  int    `bson:"obcwwqWZ"`
-	OC  string `bson:"OCsIhHxq"`
-	OM  int    `bson:"omnwvBbA"`
-	OR  string `bson:"oRWMNJTE"`
-	Of  string `bson:"OfTmCvDx"`
-	PA  int    `bson:"pacTBmxE"`
-	PF  int    `bson:"PFZSRHNN"`
-	PK  bool   `bson:"pKjOghFa"`
-	PO  int    `bson:"pOMEwSod"`
-	PP  string `bson:"pPtPsgRl"`
-	PQ  int    `bson:"pQyCJaEd"`
-	Pj  int    `bson:"PjKiuWnQ"`
-	Pv  int    `bson:"PvfnpsMV"`
-	QH  int    `bson:"qHzOMXeT"`
-	QR  bool   `bson:"qrJASGzU"`
-	Qo  string `bson:"QobifTeZ"`
-	RE  int64  `bson:"reiKnuza"`
-	RM  string `bson:"rmzUAgmk"`
-	RP  string `bson:"RPsQhgRD"`
-	Rb  uint   `bson:"Rbxpznea"`
-	ReA bool   `bson:"RemSsnnR"`
-	ReB int    `bson:"ReOZakjB"`
-	Rw  string `bson:"RwAVVKHM"`
-	SG  bool   `bson:"sGWJTAcT"`
-	SU  uint8  `bson:"SUWXijHT"`
-	SYA int64  `bson:"sYtnozSc"`
-	SYB string `bson:"SYtZkQbC"`
-	Sq  int64  `bson:"SqNvlUZF"`
-	TA  int    `bson:"taoNnQYY"`
-	TD  string `bson:"TDUzNJiH"`
-	TI  string `bson:"tIJEYSYM"`
-	TR  bool   `bson:"TRpgnInA"`
-	Tg  int    `bson:"TgSwBbgp"`
-	Tk  int64  `bson:"TkXMwZlU"`
-	Tm  int64  `bson:"TmUnYUrv"`
-	UK  int    `bson:"UKwbAKGw"`
-	UM  string `bson:"uMDWqLMf"`
-	Up  bool   `bson:"UpdMADoN"`
-	Ut  int64  `bson:"UtbwOKLt"`
-	VC  int64  `bson:"VCSKFCoE"`
-	VK  string `bson:"vkEDWgmN"`
-	VL  string `bson:"vlSZaxCV"`
-	VS  string `bson:"vSLTtfDF"`
-	VVA bool   `bson:"vvUeXASH"`
-	VVB int    `bson:"VVvwKVRG"`
-	Vc  bool   `bson:"VcCSqSmp"`
-	Vp  int16  `bson:"VplFgewF"`
-	Vt  string `bson:"VtzeOlCT"`
-	WH  bool   `bson:"WHSQVLKG"`
-	WJA bool   `bson:"wjfyueDC"`
-	WJB string `bson:"wjAWaOog"`
-	WM  int64  `bson:"wmDLUkXt"`
-	WY  string `bson:"WYJdGJLu"`
-	Wm  bool   `bson:"WmMOvgFc"`
-	Wo  string `bson:"WoFGfdvb"`
-	XE  int    `bson:"XEBqaXkB"`
-	XG  bool   `bson:"XGxlHrXf"`
-	XR  string `bson:"xrzGnsEK"`
-	XWA int64  `bson:"xWpeGNjl"`
-	XWB string `bson:"xWUlYggc"`
-	XX  int64  `bson:"XXKbyIXG"`
-	XZ  int64  `bson:"xZOksssj"`
-	Xe  uint   `bson:"XeRkAyCq"`
-	Xx  int    `bson:"XxvXmHiQ"`
-	YD  string `bson:"YDHWnEXV"`
-	YE  bool   `bson:"yeTUgNrU"`
-	YK  int    `bson:"yKfZnGKG"`
-	YX  string `bson:"yXSBbPeT"`
-	ZD  bool   `bson:"zDzSGNnW"`
-	ZE  bool   `bson:"zEgGhhZf"`
-	ZM  string `bson:"zMCFzcWY"`
-	ZSA int64  `bson:"zSYvADVf"`
-	ZSB int64  `bson:"zswQbWEI"`
-	Zm  string `bson:"ZmtEJFSO"`
-}
-
-type flatBSON struct {
-	AMQrGQmu  int64
-	AAgSNVyBb int64
-	AgYYbYPr  int
-	AtWNZJXa  int64
-	BBqZInWV  string
-	BwTXiovJ  int
-	CDIGOuIZ  int
-	CEtYKsdd  string
-	CFujXoob  int
-	CYhSCkWB  string
-	CqCssWxW  string
-	DJsnHZIC  int
-	DQBQcQFj  int64
-	FDYGeSiR  int64
-	FpduyhQP  bool
-	GiAHzFII  uint
-	HQeCoswW  int
-	HQiykral  int
-	HVHyetUM  int64
-	HicJbMpj  bool
-	HrUPbFHD  int
-	Ibrdrtgg  string
-	IsorvnMR  bool
-	JXMyYkfb  int
-	JhImQOkw  bool
-	JrJzKiIx  string
-	JzgaUWVG  int
-	KMKBtlov  int64
-	KnhgtAOJ  string
-	KyxOoCqS  int
-	LUPqMOHS  string
-	LVNIFCYm  bool
-	LngvlnTV  int
-	MNuWZMLP  bool
-	MXMxLVBk  int
-	McpOBmaR  string
-	MeUYSkPS  string
-	MqfkBZJF  int
-	OCsIhHxq  string
-	OfTmCvDx  string
-	PjKiuWnQ  int
-	PvfnpsMV  int
-	QobifTeZ  string
-	RPsQhgRD  string
-	Rbxpznea  uint
-	ReOZakjB  int
-	RemSsnnR  bool
-	RwAVVKHM  string
-	SUWXijHT  uint8
-	SYtZkQbC  string
-	SqNvlUZF  int64
-	TDUzNJiH  string
-	TRpgnInA  bool
-	TgSwBbgp  int
-	TkXMwZlU  int64
-	TmUnYUrv  int64
-	UKwbAKGw  int
-	UpdMADoN  bool
-	UtbwOKLt  int64
-	VCSKFCoE  int64
-	VVvwKVRG  int
-	VcCSqSmp  bool
-	VplFgewF  int16
-	VtzeOlCT  string
-	WHSQVLKG  bool
-	WYJdGJLu  string
-	WmMOvgFc  bool
-	WoFGfdvb  string
-	XEBqaXkB  int
-	XGxlHrXf  bool
-	XXKbyIXG  int64
-	XeRkAyCq  uint
-	XxvXmHiQ  int
-	YDHWnEXV  string
-	ZmtEJFSO  string
-	ID        primitive.ObjectID `bson:"_id"`
-	AhFCBmqT  int64
-	AicoMxZq  bool
-	BkuaZWRT  int64
-	CVjWCrlu  int64
-	Cepcgozk  string
-	CxOHMeDJ  string
-	DCLfYqqM  int
-	DHsYhRbV  string
-	DNSuxlSU  string
-	DVkWIafN  int
-	DdPdLgGg  int
-	DdVenEkK  int
-	DoshbrpF  int64
-	DpbwfSRb  string
-	DtywOLeD  string
-	ERTIdIJR  string
-	EgxZaSsw  bool
-	FEheUtop  string
-	GErhgZTh  string
-	GySFZeAE  int
-	HnVgYIQi  string
-	HwHOTmmW  int
-	IFFGfTXc  string
-	IjwXMKqI  int
-	IwfbMdcv  int
-	JWaFvVAz  int
-	JbUymqiB  string
-	JmglLvAS  string
-	KfvcFmKw  bool
-	MlfZVfVT  int
-	NBKWWUWk  int
-	NKhiSITP  int
-	ORWMNJTE  string
-	ObcwwqWZ  int
-	OmnwvBbA  int
-	PKjOghFa  bool
-	POMEwSod  int
-	PPtPsgRl  string
-	PQyCJaEd  int
-	PacTBmxE  int
-	QHzOMXeT  int
-	QrJASGzU  bool
-	ReiKnuza  int64
-	RmzUAgmk  string
-	SGWJTAcT  bool
-	SYtnozSc  int64
-	TIJEYSYM  string
-	TaoNnQYY  int
-	UMDWqLMf  string
-	VSLTtfDF  string
-	VkEDWgmN  string
-	VlSZaxCV  string
-	VvUeXASH  bool
-	WjAWaOog  string
-	WjfyueDC  bool
-	WmDLUkXt  int64
-	XWUlYggc  string
-	XWpeGNjl  int64
-	XZOksssj  int64
-	XrzGnsEK  string
-	YKfZnGKG  int
-	YXSBbPeT  string
-	YeTUgNrU  bool
-	ZDzSGNnW  bool
-	ZEgGhhZf  bool
-	ZMCFzcWY  string
-	ZSYvADVf  int64
-	ZswQbWEI  int64
-	PfZSRHnn  int
-}

+ 0 - 29
src/go.mongodb.org/mongo-driver/benchmark/canary.go

@@ -1,29 +0,0 @@
-// Copyright (C) MongoDB, Inc. 2017-present.
-//
-// Licensed under the Apache License, Version 2.0 (the "License"); you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
-
-package benchmark
-
-import (
-	"context"
-)
-
-func CanaryIncCase(ctx context.Context, tm TimerManager, iters int) error {
-	var canaryCount int
-	for i := 0; i < iters; i++ {
-		canaryCount++
-	}
-	return nil
-}
-
-var globalCanaryCount int
-
-func GlobalCanaryIncCase(ctx context.Context, tm TimerManager, iters int) error {
-	for i := 0; i < iters; i++ {
-		globalCanaryCount++
-	}
-
-	return nil
-}

+ 0 - 12
src/go.mongodb.org/mongo-driver/benchmark/canary_test.go

@@ -1,12 +0,0 @@
-// Copyright (C) MongoDB, Inc. 2017-present.
-//
-// Licensed under the Apache License, Version 2.0 (the "License"); you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
-
-package benchmark
-
-import "testing"
-
-func BenchmarkCanaryInc(b *testing.B)       { WrapCase(CanaryIncCase)(b) }
-func BenchmarkGlobalCanaryInc(b *testing.B) { WrapCase(GlobalCanaryIncCase)(b) }

+ 0 - 226
src/go.mongodb.org/mongo-driver/benchmark/harness.go

@@ -1,226 +0,0 @@
-// Copyright (C) MongoDB, Inc. 2017-present.
-//
-// Licensed under the Apache License, Version 2.0 (the "License"); you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
-
-package benchmark // import "go.mongodb.org/mongo-driver/benchmark"
-
-import (
-	"context"
-	"testing"
-	"time"
-
-	"github.com/stretchr/testify/require"
-)
-
-const (
-	five            = 5
-	ten             = 2 * five
-	hundred         = ten * ten
-	thousand        = ten * hundred
-	tenThousand     = ten * thousand
-	hundredThousand = hundred * thousand
-	million         = hundred * hundredThousand
-	halfMillion     = five * hundredThousand
-
-	ExecutionTimeout = five * time.Minute
-	StandardRuntime  = time.Minute
-	MinimumRuntime   = five * time.Second
-	MinIterations    = hundred
-)
-
-type BenchCase func(context.Context, TimerManager, int) error
-type BenchFunction func(*testing.B)
-
-func WrapCase(bench BenchCase) BenchFunction {
-	name := getName(bench)
-	return func(b *testing.B) {
-		ctx := context.Background()
-		b.ResetTimer()
-		err := bench(ctx, b, b.N)
-		require.NoError(b, err, "case='%s'", name)
-	}
-}
-
-func getAllCases() []*CaseDefinition {
-	return []*CaseDefinition{
-		{
-			Bench:              CanaryIncCase,
-			Count:              million,
-			Size:               -1,
-			Runtime:            MinimumRuntime,
-			RequiredIterations: ten,
-		},
-		{
-			Bench:              GlobalCanaryIncCase,
-			Count:              million,
-			Size:               -1,
-			Runtime:            MinimumRuntime,
-			RequiredIterations: ten,
-		},
-		{
-			Bench:   BSONFlatDocumentEncoding,
-			Count:   tenThousand,
-			Size:    75310000,
-			Runtime: StandardRuntime,
-		},
-		{
-			Bench:   BSONFlatDocumentDecodingLazy,
-			Count:   tenThousand,
-			Size:    75310000,
-			Runtime: StandardRuntime,
-		},
-		{
-			Bench:   BSONFlatDocumentDecoding,
-			Count:   tenThousand,
-			Size:    75310000,
-			Runtime: StandardRuntime,
-		},
-		{
-			Bench:   BSONDeepDocumentEncoding,
-			Count:   tenThousand,
-			Size:    19640000,
-			Runtime: StandardRuntime,
-		},
-		{
-			Bench:   BSONDeepDocumentDecodingLazy,
-			Count:   tenThousand,
-			Size:    19640000,
-			Runtime: StandardRuntime,
-		},
-		{
-			Bench:   BSONDeepDocumentDecoding,
-			Count:   tenThousand,
-			Size:    19640000,
-			Runtime: StandardRuntime,
-		},
-		// {
-		//	Bench:   BSONFullDocumentEncoding,
-		//	Count:   tenThousand,
-		//	Size:    57340000,
-		//	Runtime: StandardRuntime,
-		// },
-		// {
-		//	Bench:   BSONFullDocumentDecodingLazy,
-		//	Count:   tenThousand,
-		//	Size:    57340000,
-		//	Runtime: StandardRuntime,
-		// },
-		// {
-		//	Bench:   BSONFullDocumentDecoding,
-		//	Count:   tenThousand,
-		//	Size:    57340000,
-		//	Runtime: StandardRuntime,
-		// },
-		// {
-		//	Bench:   BSONFullReaderDecoding,
-		//	Count:   tenThousand,
-		//	Size:    57340000,
-		//	Runtime: StandardRuntime,
-		// },
-		{
-			Bench:   BSONFlatMapDecoding,
-			Count:   tenThousand,
-			Size:    75310000,
-			Runtime: StandardRuntime,
-		},
-		{
-			Bench:   BSONFlatMapEncoding,
-			Count:   tenThousand,
-			Size:    75310000,
-			Runtime: StandardRuntime,
-		},
-		{
-			Bench:   BSONDeepMapDecoding,
-			Count:   tenThousand,
-			Size:    19640000,
-			Runtime: StandardRuntime,
-		},
-		{
-			Bench:   BSONDeepMapEncoding,
-			Count:   tenThousand,
-			Size:    19640000,
-			Runtime: StandardRuntime,
-		},
-		// {
-		//	Bench:   BSONFullMapDecoding,
-		//	Count:   tenThousand,
-		//	Size:    57340000,
-		//	Runtime: StandardRuntime,
-		// },
-		// {
-		//	Bench:   BSONFullMapEncoding,
-		//	Count:   tenThousand,
-		//	Size:    57340000,
-		//	Runtime: StandardRuntime,
-		// },
-		{
-			Bench:   BSONFlatStructDecoding,
-			Count:   tenThousand,
-			Size:    75310000,
-			Runtime: StandardRuntime,
-		},
-		{
-			Bench:   BSONFlatStructTagsDecoding,
-			Count:   tenThousand,
-			Size:    75310000,
-			Runtime: StandardRuntime,
-		},
-		{
-			Bench:   BSONFlatStructEncoding,
-			Count:   tenThousand,
-			Size:    75310000,
-			Runtime: StandardRuntime,
-		},
-		{
-			Bench:   BSONFlatStructTagsEncoding,
-			Count:   tenThousand,
-			Size:    75310000,
-			Runtime: StandardRuntime,
-		},
-		{
-			Bench:   SingleRunCommand,
-			Count:   tenThousand,
-			Size:    160000,
-			Runtime: StandardRuntime,
-		},
-		{
-			Bench:   SingleFindOneByID,
-			Count:   tenThousand,
-			Size:    16220000,
-			Runtime: StandardRuntime,
-		},
-		{
-			Bench:   SingleInsertSmallDocument,
-			Count:   tenThousand,
-			Size:    2750000,
-			Runtime: StandardRuntime,
-		},
-		{
-			Bench:   SingleInsertLargeDocument,
-			Count:   ten,
-			Size:    27310890,
-			Runtime: StandardRuntime,
-		},
-		{
-			Bench:   MultiFindMany,
-			Count:   tenThousand,
-			Size:    16220000,
-			Runtime: StandardRuntime,
-		},
-		{
-			Bench:   MultiInsertSmallDocument,
-			Count:   tenThousand,
-			Size:    2750000,
-			Runtime: StandardRuntime,
-		},
-		{
-			Bench:              MultiInsertLargeDocument,
-			Count:              ten,
-			Size:               27310890,
-			Runtime:            StandardRuntime,
-			RequiredIterations: tenThousand,
-		},
-	}
-}

+ 0 - 154
src/go.mongodb.org/mongo-driver/benchmark/harness_case.go

@@ -1,154 +0,0 @@
-// Copyright (C) MongoDB, Inc. 2017-present.
-//
-// Licensed under the Apache License, Version 2.0 (the "License"); you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
-
-package benchmark
-
-import (
-	"context"
-	"fmt"
-	"path/filepath"
-	"reflect"
-	"runtime"
-	"strings"
-	"time"
-)
-
-type CaseDefinition struct {
-	Bench              BenchCase
-	Count              int
-	Size               int
-	RequiredIterations int
-	Runtime            time.Duration
-
-	cumulativeRuntime time.Duration
-	elapsed           time.Duration
-	startAt           time.Time
-	isRunning         bool
-}
-
-// TimerManager is a subset of the testing.B tool, used to manage
-// setup code.
-type TimerManager interface {
-	ResetTimer()
-	StartTimer()
-	StopTimer()
-}
-
-func (c *CaseDefinition) ResetTimer() {
-	c.startAt = time.Now()
-	c.elapsed = 0
-	c.isRunning = true
-}
-
-func (c *CaseDefinition) StartTimer() {
-	c.startAt = time.Now()
-	c.isRunning = true
-}
-
-func (c *CaseDefinition) StopTimer() {
-	if !c.isRunning {
-		return
-	}
-	c.elapsed += time.Since(c.startAt)
-	c.isRunning = false
-}
-
-func (c *CaseDefinition) roundedRuntime() time.Duration {
-	return roundDurationMS(c.Runtime)
-}
-
-func (c *CaseDefinition) Run(ctx context.Context) *BenchResult {
-	out := &BenchResult{
-		Trials:     1,
-		DataSize:   c.Size,
-		Name:       c.Name(),
-		Operations: c.Count,
-	}
-	var cancel context.CancelFunc
-	ctx, cancel = context.WithTimeout(ctx, 2*ExecutionTimeout)
-	defer cancel()
-
-	fmt.Println("=== RUN", out.Name)
-	if c.RequiredIterations == 0 {
-		c.RequiredIterations = MinIterations
-	}
-
-benchRepeat:
-	for {
-		if ctx.Err() != nil {
-			break
-		}
-		if c.cumulativeRuntime >= c.Runtime {
-			if out.Trials >= c.RequiredIterations {
-				break
-			} else if c.cumulativeRuntime >= ExecutionTimeout {
-				break
-			}
-		}
-
-		res := Result{
-			Iterations: c.Count,
-		}
-
-		c.StartTimer()
-		res.Error = c.Bench(ctx, c, c.Count)
-		c.StopTimer()
-		res.Duration = c.elapsed
-		c.cumulativeRuntime += res.Duration
-
-		switch res.Error {
-		case context.DeadlineExceeded:
-			break benchRepeat
-		case context.Canceled:
-			break benchRepeat
-		case nil:
-			out.Trials++
-			c.elapsed = 0
-			out.Raw = append(out.Raw, res)
-		default:
-			continue
-		}
-
-	}
-
-	out.Duration = out.totalDuration()
-	fmt.Printf("    --- REPORT: count=%d trials=%d requiredTrials=%d runtime=%s\n",
-		c.Count, out.Trials, c.RequiredIterations, c.Runtime)
-	if out.HasErrors() {
-		fmt.Printf("    --- ERRORS: %s\n", strings.Join(out.errReport(), "\n       "))
-		fmt.Printf("--- FAIL: %s (%s)\n", out.Name, out.roundedRuntime())
-	} else {
-		fmt.Printf("--- PASS: %s (%s)\n", out.Name, out.roundedRuntime())
-	}
-
-	return out
-
-}
-
-func (c *CaseDefinition) String() string {
-	return fmt.Sprintf("name=%s, count=%d, runtime=%s timeout=%s",
-		c.Name(), c.Count, c.Runtime, ExecutionTimeout)
-}
-
-func (c *CaseDefinition) Name() string { return getName(c.Bench) }
-func getName(i interface{}) string {
-	n := runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name()
-	parts := strings.Split(n, ".")
-	if len(parts) > 1 {
-		return parts[len(parts)-1]
-	}
-
-	return n
-
-}
-
-func getProjectRoot() string { return filepath.Dir(getDirectoryOfFile()) }
-
-func getDirectoryOfFile() string {
-	_, file, _, _ := runtime.Caller(1)
-
-	return filepath.Dir(file)
-}

+ 0 - 69
src/go.mongodb.org/mongo-driver/benchmark/harness_main.go

@@ -1,69 +0,0 @@
-// Copyright (C) MongoDB, Inc. 2017-present.
-//
-// Licensed under the Apache License, Version 2.0 (the "License"); you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
-
-package benchmark
-
-import (
-	"context"
-	"encoding/json"
-	"flag"
-	"fmt"
-	"io/ioutil"
-	"os"
-)
-
-func DriverBenchmarkMain() int {
-	var hasErrors bool
-	var outputFileName string
-	flag.StringVar(&outputFileName, "output", "perf.json", "path to write the 'perf.json' file")
-	flag.Parse()
-
-	ctx := context.Background()
-	output := []interface{}{}
-	for _, res := range runDriverCases(ctx) {
-		if res.HasErrors() {
-			hasErrors = true
-		}
-
-		evg, err := res.EvergreenPerfFormat()
-		if err != nil {
-			hasErrors = true
-			continue
-		}
-
-		output = append(output, evg...)
-	}
-
-	evgOutput, err := json.MarshalIndent(map[string]interface{}{"results": output}, "", "   ")
-	if err != nil {
-		return 1
-	}
-	evgOutput = append(evgOutput, []byte("\n")...)
-
-	if outputFileName == "" {
-		fmt.Println(string(evgOutput))
-	} else if err := ioutil.WriteFile(outputFileName, evgOutput, 0644); err != nil {
-		fmt.Fprintf(os.Stderr, "problem writing file '%s': %s", outputFileName, err.Error())
-		return 1
-	}
-
-	if hasErrors {
-		return 1
-	}
-
-	return 0
-}
-
-func runDriverCases(ctx context.Context) []*BenchResult {
-	cases := getAllCases()
-
-	results := []*BenchResult{}
-	for _, bc := range cases {
-		results = append(results, bc.Run(ctx))
-	}
-
-	return results
-}

+ 0 - 140
src/go.mongodb.org/mongo-driver/benchmark/harness_results.go

@@ -1,140 +0,0 @@
-// Copyright (C) MongoDB, Inc. 2017-present.
-//
-// Licensed under the Apache License, Version 2.0 (the "License"); you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
-
-package benchmark
-
-import (
-	"fmt"
-	"time"
-
-	"github.com/montanaflynn/stats"
-)
-
-type BenchResult struct {
-	Name       string
-	Trials     int
-	Duration   time.Duration
-	Raw        []Result
-	DataSize   int
-	Operations int
-	hasErrors  *bool
-}
-
-func (r *BenchResult) EvergreenPerfFormat() ([]interface{}, error) {
-	timings := r.timings()
-
-	median, err := stats.Median(timings)
-	if err != nil {
-		return nil, err
-	}
-
-	min, err := stats.Min(timings)
-	if err != nil {
-		return nil, err
-	}
-
-	max, err := stats.Max(timings)
-	if err != nil {
-		return nil, err
-	}
-
-	out := []interface{}{
-		map[string]interface{}{
-			"name": r.Name + "-throughput",
-			"results": map[string]interface{}{
-				"1": map[string]interface{}{
-					"seconds":        r.Duration.Round(time.Millisecond).Seconds(),
-					"ops_per_second": r.getThroughput(median),
-					"ops_per_second_values": []float64{
-						r.getThroughput(min),
-						r.getThroughput(max),
-					},
-				},
-			},
-		},
-	}
-
-	if r.DataSize > 0 {
-		out = append(out, interface{}(map[string]interface{}{
-			"name": r.Name + "-MB-adjusted",
-			"results": map[string]interface{}{
-				"1": map[string]interface{}{
-					"seconds":        r.Duration.Round(time.Millisecond).Seconds(),
-					"ops_per_second": r.adjustResults(median),
-					"ops_per_second_values": []float64{
-						r.adjustResults(min),
-						r.adjustResults(max),
-					},
-				},
-			},
-		}))
-	}
-
-	return out, nil
-}
-
-func (r *BenchResult) timings() []float64 {
-	out := []float64{}
-	for _, r := range r.Raw {
-		out = append(out, r.Duration.Seconds())
-	}
-	return out
-}
-
-func (r *BenchResult) totalDuration() time.Duration {
-	var out time.Duration
-	for _, trial := range r.Raw {
-		out += trial.Duration
-	}
-	return out
-}
-
-func (r *BenchResult) adjustResults(data float64) float64 { return float64(r.DataSize) / data }
-func (r *BenchResult) getThroughput(data float64) float64 { return float64(r.Operations) / data }
-func (r *BenchResult) roundedRuntime() time.Duration      { return roundDurationMS(r.Duration) }
-
-func (r *BenchResult) String() string {
-	return fmt.Sprintf("name=%s, trials=%d, secs=%s", r.Name, r.Trials, r.Duration)
-}
-
-func (r *BenchResult) HasErrors() bool {
-	if r.hasErrors == nil {
-		var val bool
-		for _, res := range r.Raw {
-			if res.Error != nil {
-				val = true
-				break
-			}
-		}
-		r.hasErrors = &val
-	}
-
-	return *r.hasErrors
-}
-
-func (r *BenchResult) errReport() []string {
-	errs := []string{}
-	for _, res := range r.Raw {
-		if res.Error != nil {
-			errs = append(errs, res.Error.Error())
-		}
-	}
-	return errs
-}
-
-type Result struct {
-	Duration   time.Duration
-	Iterations int
-	Error      error
-}
-
-func roundDurationMS(d time.Duration) time.Duration {
-	rounded := d.Round(time.Millisecond)
-	if rounded == 1<<63-1 {
-		return 0
-	}
-	return rounded
-}

+ 0 - 142
src/go.mongodb.org/mongo-driver/benchmark/multi.go

@@ -1,142 +0,0 @@
-// Copyright (C) MongoDB, Inc. 2017-present.
-//
-// Licensed under the Apache License, Version 2.0 (the "License"); you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
-
-package benchmark
-
-import (
-	"context"
-	"errors"
-
-	"go.mongodb.org/mongo-driver/x/bsonx"
-)
-
-func MultiFindMany(ctx context.Context, tm TimerManager, iters int) error {
-	ctx, cancel := context.WithCancel(ctx)
-	defer cancel()
-
-	db, err := getClientDB(ctx)
-	if err != nil {
-		return err
-	}
-	defer db.Client().Disconnect(ctx)
-
-	db = db.Client().Database("perftest")
-	if err = db.Drop(ctx); err != nil {
-		return err
-	}
-
-	doc, err := loadSourceDocument(getProjectRoot(), perfDataDir, singleAndMultiDataDir, tweetData)
-	if err != nil {
-		return err
-	}
-
-	coll := db.Collection("corpus")
-
-	payload := make([]interface{}, iters)
-	for idx := range payload {
-		payload[idx] = doc
-	}
-
-	if _, err = coll.InsertMany(ctx, payload); err != nil {
-		return err
-	}
-
-	tm.ResetTimer()
-
-	cursor, err := coll.Find(ctx, bsonx.Doc{})
-	if err != nil {
-		return err
-	}
-	defer cursor.Close(ctx)
-
-	counter := 0
-	for cursor.Next(ctx) {
-		err = cursor.Err()
-		if err != nil {
-			return err
-		}
-		if len(cursor.Current) == 0 {
-			return errors.New("error retrieving document")
-		}
-
-		counter++
-	}
-
-	if counter != iters {
-		return errors.New("problem iterating cursors")
-
-	}
-
-	tm.StopTimer()
-
-	if err = cursor.Close(ctx); err != nil {
-		return err
-	}
-
-	if err = db.Drop(ctx); err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func multiInsertCase(ctx context.Context, tm TimerManager, iters int, data string) error {
-	ctx, cancel := context.WithCancel(ctx)
-	defer cancel()
-
-	db, err := getClientDB(ctx)
-	if err != nil {
-		return err
-	}
-	defer db.Client().Disconnect(ctx)
-
-	db = db.Client().Database("perftest")
-	if err = db.Drop(ctx); err != nil {
-		return err
-	}
-
-	doc, err := loadSourceDocument(getProjectRoot(), perfDataDir, singleAndMultiDataDir, data)
-	if err != nil {
-		return err
-	}
-
-	err = db.RunCommand(ctx, bsonx.Doc{{"create", bsonx.String("corpus")}}).Err()
-	if err != nil {
-		return err
-	}
-
-	payload := make([]interface{}, iters)
-	for idx := range payload {
-		payload[idx] = doc
-	}
-
-	coll := db.Collection("corpus")
-
-	tm.ResetTimer()
-	res, err := coll.InsertMany(ctx, payload)
-	if err != nil {
-		return err
-	}
-	tm.StopTimer()
-
-	if len(res.InsertedIDs) != iters {
-		return errors.New("bulk operation did not complete")
-	}
-
-	if err = db.Drop(ctx); err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func MultiInsertSmallDocument(ctx context.Context, tm TimerManager, iters int) error {
-	return multiInsertCase(ctx, tm, iters, smallData)
-}
-
-func MultiInsertLargeDocument(ctx context.Context, tm TimerManager, iters int) error {
-	return multiInsertCase(ctx, tm, iters, largeData)
-}

+ 0 - 13
src/go.mongodb.org/mongo-driver/benchmark/multi_test.go

@@ -1,13 +0,0 @@
-// Copyright (C) MongoDB, Inc. 2017-present.
-//
-// Licensed under the Apache License, Version 2.0 (the "License"); you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
-
-package benchmark
-
-import "testing"
-
-func BenchmarkMultiFindMany(b *testing.B)            { WrapCase(MultiFindMany)(b) }
-func BenchmarkMultiInsertSmallDocument(b *testing.B) { WrapCase(MultiInsertSmallDocument)(b) }
-func BenchmarkMultiInsertLargeDocument(b *testing.B) { WrapCase(MultiInsertLargeDocument)(b) }

+ 0 - 174
src/go.mongodb.org/mongo-driver/benchmark/single.go

@@ -1,174 +0,0 @@
-// Copyright (C) MongoDB, Inc. 2017-present.
-//
-// Licensed under the Apache License, Version 2.0 (the "License"); you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
-
-package benchmark
-
-import (
-	"context"
-	"errors"
-
-	"go.mongodb.org/mongo-driver/internal/testutil"
-	"go.mongodb.org/mongo-driver/mongo"
-	"go.mongodb.org/mongo-driver/mongo/options"
-	"go.mongodb.org/mongo-driver/x/bsonx"
-)
-
-const (
-	singleAndMultiDataDir = "single_and_multi_document"
-	tweetData             = "tweet.json"
-	smallData             = "small_doc.json"
-	largeData             = "large_doc.json"
-)
-
-func getClientDB(ctx context.Context) (*mongo.Database, error) {
-	cs, err := testutil.GetConnString()
-	if err != nil {
-		return nil, err
-	}
-	client, err := mongo.NewClient(options.Client().ApplyURI(cs.String()))
-	if err != nil {
-		return nil, err
-	}
-	if err = client.Connect(ctx); err != nil {
-		return nil, err
-	}
-
-	db := client.Database(testutil.GetDBName(cs))
-	return db, nil
-}
-
-func SingleRunCommand(ctx context.Context, tm TimerManager, iters int) error {
-	ctx, cancel := context.WithCancel(ctx)
-	defer cancel()
-
-	db, err := getClientDB(ctx)
-	if err != nil {
-		return err
-	}
-	defer db.Client().Disconnect(ctx)
-
-	cmd := bsonx.Doc{{"ismaster", bsonx.Boolean(true)}}
-
-	tm.ResetTimer()
-	for i := 0; i < iters; i++ {
-		var doc bsonx.Doc
-		err := db.RunCommand(ctx, cmd).Decode(&doc)
-		if err != nil {
-			return err
-		}
-		// read the document and then throw it away to prevent
-		out, err := doc.MarshalBSON()
-		if len(out) == 0 {
-			return errors.New("output of ismaster is empty")
-		}
-	}
-	tm.StopTimer()
-
-	return nil
-}
-
-func SingleFindOneByID(ctx context.Context, tm TimerManager, iters int) error {
-	ctx, cancel := context.WithCancel(ctx)
-	defer cancel()
-
-	db, err := getClientDB(ctx)
-	if err != nil {
-		return err
-	}
-
-	db = db.Client().Database("perftest")
-	if err = db.Drop(ctx); err != nil {
-		return err
-	}
-
-	doc, err := loadSourceDocument(getProjectRoot(), perfDataDir, singleAndMultiDataDir, tweetData)
-	if err != nil {
-		return err
-	}
-	coll := db.Collection("corpus")
-	for i := 0; i < iters; i++ {
-		id := int32(i)
-		res, err := coll.InsertOne(ctx, doc.Set("_id", bsonx.Int32(id)))
-		if err != nil {
-			return err
-		}
-		if res.InsertedID == nil {
-			return errors.New("insert failed")
-		}
-	}
-
-	tm.ResetTimer()
-
-	for i := 0; i < iters; i++ {
-		res := coll.FindOne(ctx, bsonx.Doc{{"_id", bsonx.Int32(int32(i))}})
-		if res == nil {
-			return errors.New("find one query produced nil result")
-		}
-	}
-
-	tm.StopTimer()
-
-	if err = db.Drop(ctx); err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func singleInsertCase(ctx context.Context, tm TimerManager, iters int, data string) error {
-	ctx, cancel := context.WithCancel(ctx)
-	defer cancel()
-
-	db, err := getClientDB(ctx)
-	if err != nil {
-		return err
-	}
-	defer db.Client().Disconnect(ctx)
-
-	db = db.Client().Database("perftest")
-	if err = db.Drop(ctx); err != nil {
-		return err
-	}
-
-	doc, err := loadSourceDocument(getProjectRoot(), perfDataDir, singleAndMultiDataDir, data)
-	if err != nil {
-		return err
-	}
-
-	err = db.RunCommand(ctx, bsonx.Doc{{"create", bsonx.String("corpus")}}).Err()
-	if err != nil {
-		return err
-	}
-
-	coll := db.Collection("corpus")
-
-	tm.ResetTimer()
-
-	for i := 0; i < iters; i++ {
-		if _, err = coll.InsertOne(ctx, doc); err != nil {
-			return err
-		}
-
-		// TODO: should be remove after resolving GODRIVER-468
-		_ = doc.Delete("_id")
-	}
-
-	tm.StopTimer()
-
-	if err = db.Drop(ctx); err != nil {
-		return err
-	}
-
-	return nil
-}
-
-func SingleInsertSmallDocument(ctx context.Context, tm TimerManager, iters int) error {
-	return singleInsertCase(ctx, tm, iters, smallData)
-}
-
-func SingleInsertLargeDocument(ctx context.Context, tm TimerManager, iters int) error {
-	return singleInsertCase(ctx, tm, iters, largeData)
-}

+ 0 - 14
src/go.mongodb.org/mongo-driver/benchmark/single_test.go

@@ -1,14 +0,0 @@
-// Copyright (C) MongoDB, Inc. 2017-present.
-//
-// Licensed under the Apache License, Version 2.0 (the "License"); you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
-
-package benchmark
-
-import "testing"
-
-func BenchmarkSingleRunCommand(b *testing.B)          { WrapCase(SingleRunCommand)(b) }
-func BenchmarkSingleFindOneByID(b *testing.B)         { WrapCase(SingleFindOneByID)(b) }
-func BenchmarkSingleInsertSmallDocument(b *testing.B) { WrapCase(SingleInsertSmallDocument)(b) }
-func BenchmarkSingleInsertLargeDocument(b *testing.B) { WrapCase(SingleInsertLargeDocument)(b) }

+ 0 - 134
src/go.mongodb.org/mongo-driver/bson/benchmark_test.go

@@ -1,134 +0,0 @@
-// Copyright (C) MongoDB, Inc. 2017-present.
-//
-// Licensed under the Apache License, Version 2.0 (the "License"); you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
-
-package bson
-
-import (
-	"testing"
-)
-
-type encodetest struct {
-	Field1String  string
-	Field1Int64   int64
-	Field1Float64 float64
-	Field2String  string
-	Field2Int64   int64
-	Field2Float64 float64
-	Field3String  string
-	Field3Int64   int64
-	Field3Float64 float64
-	Field4String  string
-	Field4Int64   int64
-	Field4Float64 float64
-}
-
-type nestedtest1 struct {
-	Nested nestedtest2
-}
-
-type nestedtest2 struct {
-	Nested nestedtest3
-}
-
-type nestedtest3 struct {
-	Nested nestedtest4
-}
-
-type nestedtest4 struct {
-	Nested nestedtest5
-}
-
-type nestedtest5 struct {
-	Nested nestedtest6
-}
-
-type nestedtest6 struct {
-	Nested nestedtest7
-}
-
-type nestedtest7 struct {
-	Nested nestedtest8
-}
-
-type nestedtest8 struct {
-	Nested nestedtest9
-}
-
-type nestedtest9 struct {
-	Nested nestedtest10
-}
-
-type nestedtest10 struct {
-	Nested nestedtest11
-}
-
-type nestedtest11 struct {
-	Nested encodetest
-}
-
-var encodetestInstance = encodetest{
-	Field1String:  "foo",
-	Field1Int64:   1,
-	Field1Float64: 3.0,
-	Field2String:  "bar",
-	Field2Int64:   2,
-	Field2Float64: 3.1,
-	Field3String:  "baz",
-	Field3Int64:   3,
-	Field3Float64: 3.14,
-	Field4String:  "qux",
-	Field4Int64:   4,
-	Field4Float64: 3.141,
-}
-
-var nestedInstance = nestedtest1{
-	nestedtest2{
-		nestedtest3{
-			nestedtest4{
-				nestedtest5{
-					nestedtest6{
-						nestedtest7{
-							nestedtest8{
-								nestedtest9{
-									nestedtest10{
-										nestedtest11{
-											encodetest{
-												Field1String:  "foo",
-												Field1Int64:   1,
-												Field1Float64: 3.0,
-												Field2String:  "bar",
-												Field2Int64:   2,
-												Field2Float64: 3.1,
-												Field3String:  "baz",
-												Field3Int64:   3,
-												Field3Float64: 3.14,
-												Field4String:  "qux",
-												Field4Int64:   4,
-												Field4Float64: 3.141,
-											},
-										},
-									},
-								},
-							},
-						},
-					},
-				},
-			},
-		},
-	},
-}
-
-func BenchmarkEncoding(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		_, _ = Marshal(encodetestInstance)
-	}
-}
-
-func BenchmarkEncodingNested(b *testing.B) {
-	for i := 0; i < b.N; i++ {
-		_, _ = Marshal(nestedInstance)
-	}
-}

+ 0 - 60
src/go.mongodb.org/mongo-driver/bson/bson.go

@@ -1,60 +0,0 @@
-// Copyright (C) MongoDB, Inc. 2017-present.
-//
-// Licensed under the Apache License, Version 2.0 (the "License"); you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
-//
-// Based on gopkg.in/mgo.v2/bson by Gustavo Niemeyer
-// See THIRD-PARTY-NOTICES for original license terms.
-
-// +build go1.9
-
-package bson // import "go.mongodb.org/mongo-driver/bson"
-
-import (
-	"go.mongodb.org/mongo-driver/bson/primitive"
-)
-
-// Zeroer allows custom struct types to implement a report of zero
-// state. All struct types that don't implement Zeroer or where IsZero
-// returns false are considered to be not zero.
-type Zeroer interface {
-	IsZero() bool
-}
-
-// D represents a BSON Document. This type can be used to represent BSON in a concise and readable
-// manner. It should generally be used when serializing to BSON. For deserializing, the Raw or
-// Document types should be used.
-//
-// Example usage:
-//
-// 		bson.D{{"foo", "bar"}, {"hello", "world"}, {"pi", 3.14159}}
-//
-// This type should be used in situations where order matters, such as MongoDB commands. If the
-// order is not important, a map is more comfortable and concise.
-type D = primitive.D
-
-// E represents a BSON element for a D. It is usually used inside a D.
-type E = primitive.E
-
-// M is an unordered, concise representation of a BSON Document. It should generally be used to
-// serialize BSON when the order of the elements of a BSON document do not matter. If the element
-// order matters, use a D instead.
-//
-// Example usage:
-//
-// 		bson.M{"foo": "bar", "hello": "world", "pi": 3.14159}
-//
-// This type is handled in the encoders as a regular map[string]interface{}. The elements will be
-// serialized in an undefined, random order, and the order will be different each time.
-type M = primitive.M
-
-// An A represents a BSON array. This type can be used to represent a BSON array in a concise and
-// readable manner. It should generally be used when serializing to BSON. For deserializing, the
-// RawArray or Array types should be used.
-//
-// Example usage:
-//
-// 		bson.A{"bar", "world", 3.14159, bson.D{{"qux", 12345}}}
-//
-type A = primitive.A

+ 0 - 91
src/go.mongodb.org/mongo-driver/bson/bson_1_8.go

@@ -1,91 +0,0 @@
-// Copyright (C) MongoDB, Inc. 2017-present.
-//
-// Licensed under the Apache License, Version 2.0 (the "License"); you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
-
-// +build !go1.9
-
-package bson // import "go.mongodb.org/mongo-driver/bson"
-
-import (
-	"math"
-	"strconv"
-	"strings"
-)
-
-// Zeroer allows custom struct types to implement a report of zero
-// state. All struct types that don't implement Zeroer or where IsZero
-// returns false are considered to be not zero.
-type Zeroer interface {
-	IsZero() bool
-}
-
-// D represents a BSON Document. This type can be used to represent BSON in a concise and readable
-// manner. It should generally be used when serializing to BSON. For deserializing, the Raw or
-// Document types should be used.
-//
-// Example usage:
-//
-// 		primitive.D{{"foo", "bar"}, {"hello", "world"}, {"pi", 3.14159}}
-//
-// This type should be used in situations where order matters, such as MongoDB commands. If the
-// order is not important, a map is more comfortable and concise.
-type D []E
-
-// Map creates a map from the elements of the D.
-func (d D) Map() M {
-	m := make(M, len(d))
-	for _, e := range d {
-		m[e.Key] = e.Value
-	}
-	return m
-}
-
-// E represents a BSON element for a D. It is usually used inside a D.
-type E struct {
-	Key   string
-	Value interface{}
-}
-
-// M is an unordered, concise representation of a BSON Document. It should generally be used to
-// serialize BSON when the order of the elements of a BSON document do not matter. If the element
-// order matters, use a D instead.
-//
-// Example usage:
-//
-// 		primitive.M{"foo": "bar", "hello": "world", "pi": 3.14159}
-//
-// This type is handled in the encoders as a regular map[string]interface{}. The elements will be
-// serialized in an undefined, random order, and the order will be different each time.
-type M map[string]interface{}
-
-// An A represents a BSON array. This type can be used to represent a BSON array in a concise and
-// readable manner. It should generally be used when serializing to BSON. For deserializing, the
-// RawArray or Array types should be used.
-//
-// Example usage:
-//
-// 		primitive.A{"bar", "world", 3.14159, primitive.D{{"qux", 12345}}}
-//
-type A []interface{}
-
-func formatDouble(f float64) string {
-	var s string
-	if math.IsInf(f, 1) {
-		s = "Infinity"
-	} else if math.IsInf(f, -1) {
-		s = "-Infinity"
-	} else if math.IsNaN(f) {
-		s = "NaN"
-	} else {
-		// Print exactly one decimalType place for integers; otherwise, print as many are necessary to
-		// perfectly represent it.
-		s = strconv.FormatFloat(f, 'G', -1, 64)
-		if !strings.ContainsRune(s, '.') {
-			s += ".0"
-		}
-	}
-
-	return s
-}

+ 0 - 371
src/go.mongodb.org/mongo-driver/bson/bson_corpus_spec_test.go

@@ -1,371 +0,0 @@
-// Copyright (C) MongoDB, Inc. 2017-present.
-//
-// Licensed under the Apache License, Version 2.0 (the "License"); you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
-
-package bson
-
-import (
-	"encoding/hex"
-	"encoding/json"
-	"fmt"
-	"io/ioutil"
-	"math"
-	"path"
-	"strconv"
-	"strings"
-	"testing"
-	"unicode"
-	"unicode/utf8"
-
-	"github.com/google/go-cmp/cmp"
-	"github.com/stretchr/testify/require"
-	"github.com/tidwall/pretty"
-	"go.mongodb.org/mongo-driver/bson/bsoncodec"
-	"go.mongodb.org/mongo-driver/bson/bsonrw"
-)
-
-type testCase struct {
-	Description  string                `json:"description"`
-	BsonType     string                `json:"bson_type"`
-	TestKey      *string               `json:"test_key"`
-	Valid        []validityTestCase    `json:"valid"`
-	DecodeErrors []decodeErrorTestCase `json:"decodeErrors"`
-	ParseErrors  []parseErrorTestCase  `json:"parseErrors"`
-	Deprecated   *bool                 `json:"deprecated"`
-}
-
-type validityTestCase struct {
-	Description       string  `json:"description"`
-	CanonicalBson     string  `json:"canonical_bson"`
-	CanonicalExtJSON  string  `json:"canonical_extjson"`
-	RelaxedExtJSON    *string `json:"relaxed_extjson"`
-	DegenerateBSON    *string `json:"degenerate_bson"`
-	DegenerateExtJSON *string `json:"degenerate_extjson"`
-	ConvertedBSON     *string `json:"converted_bson"`
-	ConvertedExtJSON  *string `json:"converted_extjson"`
-	Lossy             *bool   `json:"lossy"`
-}
-
-type decodeErrorTestCase struct {
-	Description string `json:"description"`
-	Bson        string `json:"bson"`
-}
-
-type parseErrorTestCase struct {
-	Description string `json:"description"`
-	String      string `json:"string"`
-}
-
-const dataDir = "../data"
-
-var dvd bsoncodec.DefaultValueDecoders
-var dve bsoncodec.DefaultValueEncoders
-
-var dc = bsoncodec.DecodeContext{Registry: NewRegistryBuilder().Build()}
-var ec = bsoncodec.EncodeContext{Registry: NewRegistryBuilder().Build()}
-
-func findJSONFilesInDir(t *testing.T, dir string) []string {
-	files := make([]string, 0)
-
-	entries, err := ioutil.ReadDir(dir)
-	require.NoError(t, err)
-
-	for _, entry := range entries {
-		if entry.IsDir() || path.Ext(entry.Name()) != ".json" {
-			continue
-		}
-
-		files = append(files, entry.Name())
-	}
-
-	return files
-}
-
-func needsEscapedUnicode(bsonType string) bool {
-	return bsonType == "0x02" || bsonType == "0x0D" || bsonType == "0x0E" || bsonType == "0x0F"
-}
-
-func unescapeUnicode(s, bsonType string) string {
-	if !needsEscapedUnicode(bsonType) {
-		return s
-	}
-
-	newS := ""
-
-	for i := 0; i < len(s); i++ {
-		c := s[i]
-		switch c {
-		case '\\':
-			switch s[i+1] {
-			case 'u':
-				us := s[i : i+6]
-				u, err := strconv.Unquote(strings.Replace(strconv.Quote(us), `\\u`, `\u`, 1))
-				if err != nil {
-					return ""
-				}
-				for _, r := range u {
-					if r < ' ' {
-						newS += fmt.Sprintf(`\u%04x`, r)
-					} else {
-						newS += string(r)
-					}
-				}
-				i += 5
-			default:
-				newS += string(c)
-			}
-		default:
-			if c > unicode.MaxASCII {
-				r, size := utf8.DecodeRune([]byte(s[i:]))
-				newS += string(r)
-				i += size - 1
-			} else {
-				newS += string(c)
-			}
-		}
-	}
-
-	return newS
-}
-
-func formatDouble(f float64) string {
-	var s string
-	if math.IsInf(f, 1) {
-		s = "Infinity"
-	} else if math.IsInf(f, -1) {
-		s = "-Infinity"
-	} else if math.IsNaN(f) {
-		s = "NaN"
-	} else {
-		// Print exactly one decimalType place for integers; otherwise, print as many are necessary to
-		// perfectly represent it.
-		s = strconv.FormatFloat(f, 'G', -1, 64)
-		if !strings.ContainsRune(s, 'E') && !strings.ContainsRune(s, '.') {
-			s += ".0"
-		}
-	}
-
-	return s
-}
-
-func normalizeCanonicalDouble(t *testing.T, key string, cEJ string) string {
-	// Unmarshal string into map
-	cEJMap := make(map[string]map[string]string)
-	err := json.Unmarshal([]byte(cEJ), &cEJMap)
-	require.NoError(t, err)
-
-	// Parse the float contained by the map.
-	expectedString := cEJMap[key]["$numberDouble"]
-	expectedFloat, err := strconv.ParseFloat(expectedString, 64)
-
-	// Normalize the string
-	return fmt.Sprintf(`{"%s":{"$numberDouble":"%s"}}`, key, formatDouble(expectedFloat))
-}
-
-func normalizeRelaxedDouble(t *testing.T, key string, rEJ string) string {
-	// Unmarshal string into map
-	rEJMap := make(map[string]float64)
-	err := json.Unmarshal([]byte(rEJ), &rEJMap)
-	if err != nil {
-		return normalizeCanonicalDouble(t, key, rEJ)
-	}
-
-	// Parse the float contained by the map.
-	expectedFloat := rEJMap[key]
-
-	// Normalize the string
-	return fmt.Sprintf(`{"%s":%s}`, key, formatDouble(expectedFloat))
-}
-
-// bsonToNative decodes the BSON bytes (b) into a native Document
-func bsonToNative(t *testing.T, b []byte, bType, testDesc string) D {
-	var doc D
-	err := Unmarshal(b, &doc)
-	expectNoError(t, err, fmt.Sprintf("%s: decoding %s BSON", testDesc, bType))
-	return doc
-}
-
-// nativeToBSON encodes the native Document (doc) into canonical BSON and compares it to the expected
-// canonical BSON (cB)
-func nativeToBSON(t *testing.T, cB []byte, doc D, testDesc, bType, docSrcDesc string) {
-	actual, err := Marshal(doc)
-	expectNoError(t, err, fmt.Sprintf("%s: encoding %s BSON", testDesc, bType))
-
-	if diff := cmp.Diff(cB, actual); diff != "" {
-		t.Errorf("%s: 'native_to_bson(%s) = cB' failed (-want, +got):\n-%v\n+%v\n",
-			testDesc, docSrcDesc, cB, actual)
-		t.FailNow()
-	}
-}
-
-// jsonToNative decodes the extended JSON string (ej) into a native Document
-func jsonToNative(t *testing.T, ej, ejType, testDesc string) D {
-	var doc D
-	err := UnmarshalExtJSON([]byte(ej), ejType != "relaxed", &doc)
-	expectNoError(t, err, fmt.Sprintf("%s: decoding %s extended JSON", testDesc, ejType))
-	return doc
-}
-
-// nativeToJSON encodes the native Document (doc) into an extended JSON string
-func nativeToJSON(t *testing.T, ej string, doc D, testDesc, ejType, ejShortName, docSrcDesc string) {
-	actualEJ, err := MarshalExtJSON(doc, ejType != "relaxed", true)
-	expectNoError(t, err, fmt.Sprintf("%s: encoding %s extended JSON", testDesc, ejType))
-
-	if diff := cmp.Diff(ej, string(actualEJ)); diff != "" {
-		t.Errorf("%s: 'native_to_%s_extended_json(%s) = %s' failed (-want, +got):\n%s\n",
-			testDesc, ejType, docSrcDesc, ejShortName, diff)
-		t.FailNow()
-	}
-}
-
-func runTest(t *testing.T, file string) {
-	filepath := path.Join(dataDir, file)
-	content, err := ioutil.ReadFile(filepath)
-	require.NoError(t, err)
-
-	// Remove ".json" from filename.
-	file = file[:len(file)-5]
-	testName := "bson_corpus--" + file
-
-	t.Run(testName, func(t *testing.T) {
-		var test testCase
-		require.NoError(t, json.Unmarshal(content, &test))
-
-		for _, v := range test.Valid {
-			// get canonical BSON
-			cB, err := hex.DecodeString(v.CanonicalBson)
-			expectNoError(t, err, fmt.Sprintf("%s: reading canonical BSON", v.Description))
-
-			// get canonical extended JSON
-			cEJ := unescapeUnicode(string(pretty.Ugly([]byte(v.CanonicalExtJSON))), test.BsonType)
-			if test.BsonType == "0x01" {
-				cEJ = normalizeCanonicalDouble(t, *test.TestKey, cEJ)
-			}
-
-			/*** canonical BSON round-trip tests ***/
-			doc := bsonToNative(t, cB, "canonical", v.Description)
-
-			// native_to_bson(bson_to_native(cB)) = cB
-			nativeToBSON(t, cB, doc, v.Description, "canonical", "bson_to_native(cB)")
-
-			// native_to_canonical_extended_json(bson_to_native(cB)) = cEJ
-			nativeToJSON(t, cEJ, doc, v.Description, "canonical", "cEJ", "bson_to_native(cB)")
-
-			// native_to_relaxed_extended_json(bson_to_native(cB)) = rEJ (if rEJ exists)
-			if v.RelaxedExtJSON != nil {
-				rEJ := unescapeUnicode(string(pretty.Ugly([]byte(*v.RelaxedExtJSON))), test.BsonType)
-				if test.BsonType == "0x01" {
-					rEJ = normalizeRelaxedDouble(t, *test.TestKey, rEJ)
-				}
-
-				nativeToJSON(t, rEJ, doc, v.Description, "relaxed", "rEJ", "bson_to_native(cB)")
-
-				/*** relaxed extended JSON round-trip tests (if exists) ***/
-				doc = jsonToNative(t, rEJ, "relaxed", v.Description)
-
-				// native_to_relaxed_extended_json(json_to_native(rEJ)) = rEJ
-				nativeToJSON(t, rEJ, doc, v.Description, "relaxed", "eJR", "json_to_native(rEJ)")
-			}
-
-			/*** canonical extended JSON round-trip tests ***/
-			doc = jsonToNative(t, cEJ, "canonical", v.Description)
-
-			// native_to_canonical_extended_json(json_to_native(cEJ)) = cEJ
-			nativeToJSON(t, cEJ, doc, v.Description, "canonical", "cEJ", "json_to_native(cEJ)")
-
-			// native_to_bson(json_to_native(cEJ)) = cb (unless lossy)
-			if v.Lossy == nil || !*v.Lossy {
-				nativeToBSON(t, cB, doc, v.Description, "canonical", "json_to_native(cEJ)")
-			}
-
-			/*** degenerate BSON round-trip tests (if exists) ***/
-			if v.DegenerateBSON != nil {
-				dB, err := hex.DecodeString(*v.DegenerateBSON)
-				expectNoError(t, err, fmt.Sprintf("%s: reading degenerate BSON", v.Description))
-
-				doc = bsonToNative(t, dB, "degenerate", v.Description)
-
-				// native_to_bson(bson_to_native(dB)) = cB
-				nativeToBSON(t, cB, doc, v.Description, "degenerate", "bson_to_native(dB)")
-			}
-
-			/*** degenerate JSON round-trip tests (if exists) ***/
-			if v.DegenerateExtJSON != nil {
-				dEJ := unescapeUnicode(string(pretty.Ugly([]byte(*v.DegenerateExtJSON))), test.BsonType)
-				if test.BsonType == "0x01" {
-					dEJ = normalizeCanonicalDouble(t, *test.TestKey, dEJ)
-				}
-
-				doc = jsonToNative(t, dEJ, "degenerate canonical", v.Description)
-
-				// native_to_canonical_extended_json(json_to_native(dEJ)) = cEJ
-				nativeToJSON(t, cEJ, doc, v.Description, "degenerate canonical", "cEJ", "json_to_native(dEJ)")
-
-				// native_to_bson(json_to_native(dEJ)) = cB (unless lossy)
-				if v.Lossy == nil || !*v.Lossy {
-					nativeToBSON(t, cB, doc, v.Description, "canonical", "json_to_native(dEJ)")
-				}
-			}
-		}
-
-		for _, d := range test.DecodeErrors {
-			b, err := hex.DecodeString(d.Bson)
-			expectNoError(t, err, d.Description)
-
-			var doc D
-			err = Unmarshal(b, &doc)
-			expectError(t, err, fmt.Sprintf("%s: expected decode error", d.Description))
-		}
-
-		for _, p := range test.ParseErrors {
-			// skip DBRef tests
-			if strings.Contains(p.Description, "Bad DBRef") {
-				continue
-			}
-
-			s := unescapeUnicode(p.String, test.BsonType)
-			if test.BsonType == "0x13" {
-				s = fmt.Sprintf(`{"$numberDecimal": "%s"}`, s)
-			}
-
-			switch test.BsonType {
-			case "0x00":
-				var doc D
-				err := UnmarshalExtJSON([]byte(s), true, &doc)
-				expectError(t, err, fmt.Sprintf("%s: expected parse error", p.Description))
-			case "0x13":
-				ejvr, err := bsonrw.NewExtJSONValueReader(strings.NewReader(s), true)
-				expectNoError(t, err, fmt.Sprintf("error creating value reader: %s", err))
-				_, err = ejvr.ReadDecimal128()
-				expectError(t, err, fmt.Sprintf("%s: expected parse error", p.Description))
-			default:
-				t.Errorf("Update test to check for parse errors for type %s", test.BsonType)
-				t.Fail()
-			}
-		}
-	})
-}
-
-func Test_BsonCorpus(t *testing.T) {
-	for _, file := range findJSONFilesInDir(t, dataDir) {
-		runTest(t, file)
-	}
-}
-
-func expectNoError(t *testing.T, err error, desc string) {
-	if err != nil {
-		t.Helper()
-		t.Errorf("%s: Unepexted error: %v", desc, err)
-		t.FailNow()
-	}
-}
-
-func expectError(t *testing.T, err error, desc string) {
-	if err == nil {
-		t.Helper()
-		t.Errorf("%s: Expected error", desc)
-		t.FailNow()
-	}
-}

+ 0 - 113
src/go.mongodb.org/mongo-driver/bson/bson_test.go

@@ -1,113 +0,0 @@
-// Copyright (C) MongoDB, Inc. 2017-present.
-//
-// Licensed under the Apache License, Version 2.0 (the "License"); you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
-
-package bson
-
-import (
-	"bytes"
-	"testing"
-	"time"
-
-	"github.com/google/go-cmp/cmp"
-	"github.com/stretchr/testify/require"
-	"go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
-)
-
-func noerr(t *testing.T, err error) {
-	if err != nil {
-		t.Helper()
-		t.Errorf("Unexpected error: (%T)%v", err, err)
-		t.FailNow()
-	}
-}
-
-func requireErrEqual(t *testing.T, err1 error, err2 error) { require.True(t, compareErrors(err1, err2)) }
-
-func TestTimeRoundTrip(t *testing.T) {
-	val := struct {
-		Value time.Time
-		ID    string
-	}{
-		ID: "time-rt-test",
-	}
-
-	if !val.Value.IsZero() {
-		t.Errorf("Did not get zero time as expected.")
-	}
-
-	bsonOut, err := Marshal(val)
-	noerr(t, err)
-	rtval := struct {
-		Value time.Time
-		ID    string
-	}{}
-
-	err = Unmarshal(bsonOut, &rtval)
-	noerr(t, err)
-	if !cmp.Equal(val, rtval) {
-		t.Errorf("Did not round trip properly. got %v; want %v", val, rtval)
-	}
-	if !rtval.Value.IsZero() {
-		t.Errorf("Did not get zero time as expected.")
-	}
-}
-
-func TestNonNullTimeRoundTrip(t *testing.T) {
-	now := time.Now()
-	now = time.Unix(now.Unix(), 0)
-	val := struct {
-		Value time.Time
-		ID    string
-	}{
-		ID:    "time-rt-test",
-		Value: now,
-	}
-
-	bsonOut, err := Marshal(val)
-	noerr(t, err)
-	rtval := struct {
-		Value time.Time
-		ID    string
-	}{}
-
-	err = Unmarshal(bsonOut, &rtval)
-	noerr(t, err)
-	if !cmp.Equal(val, rtval) {
-		t.Errorf("Did not round trip properly. got %v; want %v", val, rtval)
-	}
-}
-
-func TestD(t *testing.T) {
-	t.Run("can marshal", func(t *testing.T) {
-		d := D{{"foo", "bar"}, {"hello", "world"}, {"pi", 3.14159}}
-		idx, want := bsoncore.AppendDocumentStart(nil)
-		want = bsoncore.AppendStringElement(want, "foo", "bar")
-		want = bsoncore.AppendStringElement(want, "hello", "world")
-		want = bsoncore.AppendDoubleElement(want, "pi", 3.14159)
-		want, err := bsoncore.AppendDocumentEnd(want, idx)
-		noerr(t, err)
-		got, err := Marshal(d)
-		noerr(t, err)
-		if !bytes.Equal(got, want) {
-			t.Errorf("Marshaled documents do not match. got %v; want %v", Raw(got), Raw(want))
-		}
-	})
-	t.Run("can unmarshal", func(t *testing.T) {
-		want := D{{"foo", "bar"}, {"hello", "world"}, {"pi", 3.14159}}
-		idx, doc := bsoncore.AppendDocumentStart(nil)
-		doc = bsoncore.AppendStringElement(doc, "foo", "bar")
-		doc = bsoncore.AppendStringElement(doc, "hello", "world")
-		doc = bsoncore.AppendDoubleElement(doc, "pi", 3.14159)
-		doc, err := bsoncore.AppendDocumentEnd(doc, idx)
-		noerr(t, err)
-		var got D
-		err = Unmarshal(doc, &got)
-		noerr(t, err)
-		if !cmp.Equal(got, want) {
-			t.Errorf("Unmarshaled documents do not match. got %v; want %v", got, want)
-		}
-	})
-}

+ 0 - 163
src/go.mongodb.org/mongo-driver/bson/bsoncodec/bsoncodec.go

@@ -1,163 +0,0 @@
-// Copyright (C) MongoDB, Inc. 2017-present.
-//
-// Licensed under the Apache License, Version 2.0 (the "License"); you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
-
-package bsoncodec // import "go.mongodb.org/mongo-driver/bson/bsoncodec"
-
-import (
-	"fmt"
-	"reflect"
-	"strings"
-
-	"go.mongodb.org/mongo-driver/bson/bsonrw"
-	"go.mongodb.org/mongo-driver/bson/bsontype"
-)
-
-// Marshaler is an interface implemented by types that can marshal themselves
-// into a BSON document represented as bytes. The bytes returned must be a valid
-// BSON document if the error is nil.
-type Marshaler interface {
-	MarshalBSON() ([]byte, error)
-}
-
-// ValueMarshaler is an interface implemented by types that can marshal
-// themselves into a BSON value as bytes. The type must be the valid type for
-// the bytes returned. The bytes and byte type together must be valid if the
-// error is nil.
-type ValueMarshaler interface {
-	MarshalBSONValue() (bsontype.Type, []byte, error)
-}
-
-// Unmarshaler is an interface implemented by types that can unmarshal a BSON
-// document representation of themselves. The BSON bytes can be assumed to be
-// valid. UnmarshalBSON must copy the BSON bytes if it wishes to retain the data
-// after returning.
-type Unmarshaler interface {
-	UnmarshalBSON([]byte) error
-}
-
-// ValueUnmarshaler is an interface implemented by types that can unmarshal a
-// BSON value representaiton of themselves. The BSON bytes and type can be
-// assumed to be valid. UnmarshalBSONValue must copy the BSON value bytes if it
-// wishes to retain the data after returning.
-type ValueUnmarshaler interface {
-	UnmarshalBSONValue(bsontype.Type, []byte) error
-}
-
-// ValueEncoderError is an error returned from a ValueEncoder when the provided value can't be
-// encoded by the ValueEncoder.
-type ValueEncoderError struct {
-	Name     string
-	Types    []reflect.Type
-	Kinds    []reflect.Kind
-	Received reflect.Value
-}
-
-func (vee ValueEncoderError) Error() string {
-	typeKinds := make([]string, 0, len(vee.Types)+len(vee.Kinds))
-	for _, t := range vee.Types {
-		typeKinds = append(typeKinds, t.String())
-	}
-	for _, k := range vee.Kinds {
-		if k == reflect.Map {
-			typeKinds = append(typeKinds, "map[string]*")
-			continue
-		}
-		typeKinds = append(typeKinds, k.String())
-	}
-	received := vee.Received.Kind().String()
-	if vee.Received.IsValid() {
-		received = vee.Received.Type().String()
-	}
-	return fmt.Sprintf("%s can only encode valid %s, but got %s", vee.Name, strings.Join(typeKinds, ", "), received)
-}
-
-// ValueDecoderError is an error returned from a ValueDecoder when the provided value can't be
-// decoded by the ValueDecoder.
-type ValueDecoderError struct {
-	Name     string
-	Types    []reflect.Type
-	Kinds    []reflect.Kind
-	Received reflect.Value
-}
-
-func (vde ValueDecoderError) Error() string {
-	typeKinds := make([]string, 0, len(vde.Types)+len(vde.Kinds))
-	for _, t := range vde.Types {
-		typeKinds = append(typeKinds, t.String())
-	}
-	for _, k := range vde.Kinds {
-		if k == reflect.Map {
-			typeKinds = append(typeKinds, "map[string]*")
-			continue
-		}
-		typeKinds = append(typeKinds, k.String())
-	}
-	received := vde.Received.Kind().String()
-	if vde.Received.IsValid() {
-		received = vde.Received.Type().String()
-	}
-	return fmt.Sprintf("%s can only decode valid and settable %s, but got %s", vde.Name, strings.Join(typeKinds, ", "), received)
-}
-
-// EncodeContext is the contextual information required for a Codec to encode a
-// value.
-type EncodeContext struct {
-	*Registry
-	MinSize bool
-}
-
-// DecodeContext is the contextual information required for a Codec to decode a
-// value.
-type DecodeContext struct {
-	*Registry
-	Truncate bool
-	// Ancestor is the type of a containing document. This is mainly used to determine what type
-	// should be used when decoding an embedded document into an empty interface. For example, if
-	// Ancestor is a bson.M, BSON embedded document values being decoded into an empty interface
-	// will be decoded into a bson.M.
-	Ancestor reflect.Type
-}
-
-// ValueCodec is the interface that groups the methods to encode and decode
-// values.
-type ValueCodec interface {
-	ValueEncoder
-	ValueDecoder
-}
-
-// ValueEncoder is the interface implemented by types that can handle the encoding of a value.
-type ValueEncoder interface {
-	EncodeValue(EncodeContext, bsonrw.ValueWriter, reflect.Value) error
-}
-
-// ValueEncoderFunc is an adapter function that allows a function with the correct signature to be
-// used as a ValueEncoder.
-type ValueEncoderFunc func(EncodeContext, bsonrw.ValueWriter, reflect.Value) error
-
-// EncodeValue implements the ValueEncoder interface.
-func (fn ValueEncoderFunc) EncodeValue(ec EncodeContext, vw bsonrw.ValueWriter, val reflect.Value) error {
-	return fn(ec, vw, val)
-}
-
-// ValueDecoder is the interface implemented by types that can handle the decoding of a value.
-type ValueDecoder interface {
-	DecodeValue(DecodeContext, bsonrw.ValueReader, reflect.Value) error
-}
-
-// ValueDecoderFunc is an adapter function that allows a function with the correct signature to be
-// used as a ValueDecoder.
-type ValueDecoderFunc func(DecodeContext, bsonrw.ValueReader, reflect.Value) error
-
-// DecodeValue implements the ValueDecoder interface.
-func (fn ValueDecoderFunc) DecodeValue(dc DecodeContext, vr bsonrw.ValueReader, val reflect.Value) error {
-	return fn(dc, vr, val)
-}
-
-// CodecZeroer is the interface implemented by Codecs that can also determine if
-// a value of the type that would be encoded is zero.
-type CodecZeroer interface {
-	IsTypeZero(interface{}) bool
-}

Some files were not shown because too many files changed in this diff