Upgrading server dependancies (#6431)
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
cd23b8139a
Коммит
d103ed6ca9
79
vendor/github.com/go-sql-driver/mysql/.travis.yml
сгенерированный
поставляемый
79
vendor/github.com/go-sql-driver/mysql/.travis.yml
сгенерированный
поставляемый
@@ -7,7 +7,86 @@ go:
|
||||
- 1.5
|
||||
- 1.6
|
||||
- 1.7
|
||||
- 1.8
|
||||
- tip
|
||||
|
||||
before_install:
|
||||
- go get golang.org/x/tools/cmd/cover
|
||||
- go get github.com/mattn/goveralls
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- env: DB=MYSQL57
|
||||
sudo: required
|
||||
dist: trusty
|
||||
go: 1.8
|
||||
services:
|
||||
- docker
|
||||
before_install:
|
||||
- go get golang.org/x/tools/cmd/cover
|
||||
- go get github.com/mattn/goveralls
|
||||
- docker pull mysql:5.7
|
||||
- docker run -d -p 127.0.0.1:3307:3306 --name mysqld -e MYSQL_DATABASE=gotest -e MYSQL_USER=gotest -e MYSQL_PASSWORD=secret -e MYSQL_ROOT_PASSWORD=verysecret
|
||||
mysql:5.7 --innodb_log_file_size=256MB --innodb_buffer_pool_size=512MB --max_allowed_packet=16MB
|
||||
- sleep 30
|
||||
- cp .travis/docker.cnf ~/.my.cnf
|
||||
- mysql --print-defaults
|
||||
- .travis/wait_mysql.sh
|
||||
before_script:
|
||||
- export MYSQL_TEST_USER=gotest
|
||||
- export MYSQL_TEST_PASS=secret
|
||||
- export MYSQL_TEST_ADDR=127.0.0.1:3307
|
||||
- export MYSQL_TEST_CONCURRENT=1
|
||||
|
||||
- env: DB=MARIA55
|
||||
sudo: required
|
||||
dist: trusty
|
||||
go: 1.8
|
||||
services:
|
||||
- docker
|
||||
before_install:
|
||||
- go get golang.org/x/tools/cmd/cover
|
||||
- go get github.com/mattn/goveralls
|
||||
- docker pull mariadb:5.5
|
||||
- docker run -d -p 127.0.0.1:3307:3306 --name mysqld -e MYSQL_DATABASE=gotest -e MYSQL_USER=gotest -e MYSQL_PASSWORD=secret -e MYSQL_ROOT_PASSWORD=verysecret
|
||||
mariadb:5.5 --innodb_log_file_size=256MB --innodb_buffer_pool_size=512MB --max_allowed_packet=16MB
|
||||
- sleep 30
|
||||
- cp .travis/docker.cnf ~/.my.cnf
|
||||
- mysql --print-defaults
|
||||
- .travis/wait_mysql.sh
|
||||
before_script:
|
||||
- export MYSQL_TEST_USER=gotest
|
||||
- export MYSQL_TEST_PASS=secret
|
||||
- export MYSQL_TEST_ADDR=127.0.0.1:3307
|
||||
- export MYSQL_TEST_CONCURRENT=1
|
||||
|
||||
- env: DB=MARIA10_1
|
||||
sudo: required
|
||||
dist: trusty
|
||||
go: 1.8
|
||||
services:
|
||||
- docker
|
||||
before_install:
|
||||
- go get golang.org/x/tools/cmd/cover
|
||||
- go get github.com/mattn/goveralls
|
||||
- docker pull mariadb:10.1
|
||||
- docker run -d -p 127.0.0.1:3307:3306 --name mysqld -e MYSQL_DATABASE=gotest -e MYSQL_USER=gotest -e MYSQL_PASSWORD=secret -e MYSQL_ROOT_PASSWORD=verysecret
|
||||
mariadb:10.1 --innodb_log_file_size=256MB --innodb_buffer_pool_size=512MB --max_allowed_packet=16MB
|
||||
- sleep 30
|
||||
- cp .travis/docker.cnf ~/.my.cnf
|
||||
- mysql --print-defaults
|
||||
- .travis/wait_mysql.sh
|
||||
before_script:
|
||||
- export MYSQL_TEST_USER=gotest
|
||||
- export MYSQL_TEST_PASS=secret
|
||||
- export MYSQL_TEST_ADDR=127.0.0.1:3307
|
||||
- export MYSQL_TEST_CONCURRENT=1
|
||||
|
||||
|
||||
before_script:
|
||||
- mysql -e 'create database gotest;'
|
||||
script:
|
||||
- go test -v -covermode=count -coverprofile=coverage.out
|
||||
- go vet ./...
|
||||
- test -z "$(gofmt -d -s . | tee /dev/stderr)"
|
||||
- $HOME/gopath/bin/goveralls -coverprofile=coverage.out -service=travis-ci
|
||||
|
||||
5
vendor/github.com/go-sql-driver/mysql/.travis/docker.cnf
сгенерированный
поставляемый
Обычный файл
5
vendor/github.com/go-sql-driver/mysql/.travis/docker.cnf
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1,5 @@
|
||||
[client]
|
||||
user = gotest
|
||||
password = secret
|
||||
host = 127.0.0.1
|
||||
port = 3307
|
||||
8
vendor/github.com/go-sql-driver/mysql/.travis/wait_mysql.sh
сгенерированный
поставляемый
Исполняемый файл
8
vendor/github.com/go-sql-driver/mysql/.travis/wait_mysql.sh
сгенерированный
поставляемый
Исполняемый файл
@@ -0,0 +1,8 @@
|
||||
#!/bin/sh
|
||||
while :
|
||||
do
|
||||
sleep 3
|
||||
if mysql -e 'select version()'; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
6
vendor/github.com/go-sql-driver/mysql/AUTHORS
сгенерированный
поставляемый
6
vendor/github.com/go-sql-driver/mysql/AUTHORS
сгенерированный
поставляемый
@@ -13,26 +13,31 @@
|
||||
|
||||
Aaron Hopkins <go-sql-driver at die.net>
|
||||
Arne Hormann <arnehormann at gmail.com>
|
||||
Asta Xie <xiemengjun at gmail.com>
|
||||
Carlos Nieto <jose.carlos at menteslibres.net>
|
||||
Chris Moos <chris at tech9computers.com>
|
||||
Daniel Nichter <nil at codenode.com>
|
||||
Daniël van Eeden <git at myname.nl>
|
||||
DisposaBoy <disposaboy at dby.me>
|
||||
Egor Smolyakov <egorsmkv at gmail.com>
|
||||
Frederick Mayle <frederickmayle at gmail.com>
|
||||
Gustavo Kristic <gkristic at gmail.com>
|
||||
Hanno Braun <mail at hannobraun.com>
|
||||
Henri Yandell <flamefew at gmail.com>
|
||||
Hirotaka Yamamoto <ymmt2005 at gmail.com>
|
||||
INADA Naoki <songofacandy at gmail.com>
|
||||
Jacek Szwec <szwec.jacek at gmail.com>
|
||||
James Harr <james.harr at gmail.com>
|
||||
Jian Zhen <zhenjl at gmail.com>
|
||||
Joshua Prunier <joshua.prunier at gmail.com>
|
||||
Julien Lefevre <julien.lefevr at gmail.com>
|
||||
Julien Schmidt <go-sql-driver at julienschmidt.com>
|
||||
Justin Nuß <nuss.justin at gmail.com>
|
||||
Kamil Dziedzic <kamil at klecza.pl>
|
||||
Kevin Malachowski <kevin at chowski.com>
|
||||
Lennart Rudolph <lrudolph at hmc.edu>
|
||||
Leonardo YongUk Kim <dalinaum at gmail.com>
|
||||
Lion Yang <lion at aosc.xyz>
|
||||
Luca Looz <luca.looz92 at gmail.com>
|
||||
Lucas Liu <extrafliu at gmail.com>
|
||||
Luke Scott <luke at webconnex.com>
|
||||
@@ -40,6 +45,7 @@ Michael Woolnough <michael.woolnough at gmail.com>
|
||||
Nicola Peduzzi <thenikso at gmail.com>
|
||||
Olivier Mengué <dolmen at cpan.org>
|
||||
Paul Bonser <misterpib at gmail.com>
|
||||
Peter Schultz <peter.schultz at classmarkets.com>
|
||||
Runrioter Wung <runrioter at gmail.com>
|
||||
Soroush Pour <me at soroushjp.com>
|
||||
Stan Putrya <root.vagner at gmail.com>
|
||||
|
||||
48
vendor/github.com/go-sql-driver/mysql/README.md
сгенерированный
поставляемый
48
vendor/github.com/go-sql-driver/mysql/README.md
сгенерированный
поставляемый
@@ -1,6 +1,6 @@
|
||||
# Go-MySQL-Driver
|
||||
|
||||
A MySQL-Driver for Go's [database/sql](http://golang.org/pkg/database/sql) package
|
||||
A MySQL-Driver for Go's [database/sql](https://golang.org/pkg/database/sql/) package
|
||||
|
||||

|
||||
|
||||
@@ -15,6 +15,7 @@ A MySQL-Driver for Go's [database/sql](http://golang.org/pkg/database/sql) packa
|
||||
* [Address](#address)
|
||||
* [Parameters](#parameters)
|
||||
* [Examples](#examples)
|
||||
* [Connection pool and timeouts](#connection-pool-and-timeouts)
|
||||
* [LOAD DATA LOCAL INFILE support](#load-data-local-infile-support)
|
||||
* [time.Time support](#timetime-support)
|
||||
* [Unicode support](#unicode-support)
|
||||
@@ -26,11 +27,11 @@ A MySQL-Driver for Go's [database/sql](http://golang.org/pkg/database/sql) packa
|
||||
## 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, Unix domain sockets or [custom protocols](http://godoc.org/github.com/go-sql-driver/mysql#DialFunc)
|
||||
* Connections over TCP/IPv4, TCP/IPv6, Unix domain sockets or [custom protocols](https://godoc.org/github.com/go-sql-driver/mysql#DialFunc)
|
||||
* 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.
|
||||
* Full [`sql.RawBytes`](https://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
|
||||
@@ -43,14 +44,14 @@ A MySQL-Driver for Go's [database/sql](http://golang.org/pkg/database/sql) packa
|
||||
---------------------------------------
|
||||
|
||||
## 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:
|
||||
Simple install the package to your [$GOPATH](https://github.com/golang/go/wiki/GOPATH "GOPATH") with the [go tool](https://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`.
|
||||
Make sure [Git is installed](https://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.
|
||||
_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`](https://golang.org/pkg/database/sql/) API then.
|
||||
|
||||
Use `mysql` as `driverName` and a valid [DSN](#dsn-data-source-name) as `dataSourceName`:
|
||||
```go
|
||||
@@ -95,13 +96,13 @@ Alternatively, [Config.FormatDSN](https://godoc.org/github.com/go-sql-driver/mys
|
||||
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.
|
||||
See [net.Dial](https://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.
|
||||
The functions [net.JoinHostPort](https://golang.org/pkg/net/#JoinHostPort) and [net.SplitHostPort](https://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`.
|
||||
|
||||
@@ -220,11 +221,11 @@ 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.
|
||||
Sets the location for time.Time values (when using `parseTime=true`). *"Local"* sets the system's location. See [time.LoadLocation](https://golang.org/pkg/time/#LoadLocation) for details.
|
||||
|
||||
Note that this sets the location for time.Time values but does not change MySQL's [time_zone setting](https://dev.mysql.com/doc/refman/5.5/en/time-zone-support.html). For that see the [time_zone system variable](#system-variables), which can also be set as a DSN parameter.
|
||||
|
||||
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`.
|
||||
Please keep in mind, that param values must be [url.QueryEscape](https://golang.org/pkg/net/url/#QueryEscape)'ed. Alternatively you can manually replace the `/` with `%2F`. For example `US/Pacific` would be `loc=US%2FPacific`.
|
||||
|
||||
##### `maxAllowedPacket`
|
||||
```
|
||||
@@ -260,11 +261,11 @@ Default: false
|
||||
##### `readTimeout`
|
||||
|
||||
```
|
||||
Type: decimal number
|
||||
Type: duration
|
||||
Default: 0
|
||||
```
|
||||
|
||||
I/O read timeout. The value must be a decimal number with an unit suffix ( *"ms"*, *"s"*, *"m"*, *"h"* ), such as *"30s"*, *"0.5m"* or *"1m30s"*.
|
||||
I/O read timeout. The value must be a decimal number with a unit suffix (*"ms"*, *"s"*, *"m"*, *"h"*), such as *"30s"*, *"0.5m"* or *"1m30s"*.
|
||||
|
||||
##### `strict`
|
||||
|
||||
@@ -283,11 +284,11 @@ By default MySQL also treats notes as warnings. Use [`sql_notes=false`](http://d
|
||||
##### `timeout`
|
||||
|
||||
```
|
||||
Type: decimal number
|
||||
Type: duration
|
||||
Default: OS default
|
||||
```
|
||||
|
||||
*Driver* side connection timeout. The value must be a decimal number with an 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).
|
||||
Timeout for establishing connections, aka dial timeout. The value must be a decimal number with a unit suffix (*"ms"*, *"s"*, *"m"*, *"h"*), such as *"30s"*, *"0.5m"* or *"1m30s"*.
|
||||
|
||||
##### `tls`
|
||||
|
||||
@@ -297,16 +298,16 @@ 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).
|
||||
`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`](https://godoc.org/github.com/go-sql-driver/mysql#RegisterTLSConfig).
|
||||
|
||||
##### `writeTimeout`
|
||||
|
||||
```
|
||||
Type: decimal number
|
||||
Type: duration
|
||||
Default: 0
|
||||
```
|
||||
|
||||
I/O write timeout. The value must be a decimal number with an unit suffix ( *"ms"*, *"s"*, *"m"*, *"h"* ), such as *"30s"*, *"0.5m"* or *"1m30s"*.
|
||||
I/O write timeout. The value must be a decimal number with a unit suffix (*"ms"*, *"s"*, *"m"*, *"h"*), such as *"30s"*, *"0.5m"* or *"1m30s"*.
|
||||
|
||||
|
||||
##### System Variables
|
||||
@@ -380,6 +381,11 @@ No Database preselected:
|
||||
user:password@/
|
||||
```
|
||||
|
||||
|
||||
### Connection pool and timeouts
|
||||
The connection pool is managed by Go's database/sql package. For details on how to configure the size of the pool and how long connections stay in the pool see `*DB.SetMaxOpenConns`, `*DB.SetMaxIdleConns`, and `*DB.SetConnMaxLifetime` in the [database/sql documentation](https://golang.org/pkg/database/sql/). The read, write, and dial timeouts for each individual connection are configured with the DSN parameters [`readTimeout`](#readtimeout), [`writeTimeout`](#writetimeout), and [`timeout`](#timeout), respectively.
|
||||
|
||||
|
||||
### `LOAD DATA LOCAL INFILE` support
|
||||
For this feature you need direct access to the package. Therefore you must change the import path (no `_`):
|
||||
```go
|
||||
@@ -390,17 +396,17 @@ Files must be whitelisted by registering them with `mysql.RegisterLocalFile(file
|
||||
|
||||
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. Choose different names for different handlers and `DeregisterReaderHandler` when you don't need it anymore.
|
||||
|
||||
See the [godoc of Go-MySQL-Driver](http://godoc.org/github.com/go-sql-driver/mysql "golang mysql driver documentation") for details.
|
||||
See the [godoc of Go-MySQL-Driver](https://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.
|
||||
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](https://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`.
|
||||
Alternatively you can use the [`NullTime`](https://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
|
||||
@@ -435,7 +441,7 @@ That means:
|
||||
* 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.
|
||||
Please read the [MPL 2.0 FAQ](https://www.mozilla.org/en-US/MPL/2.0/FAQ/) 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)
|
||||
|
||||
|
||||
36
vendor/github.com/go-sql-driver/mysql/connection.go
сгенерированный
поставляемый
36
vendor/github.com/go-sql-driver/mysql/connection.go
сгенерированный
поставляемый
@@ -10,6 +10,7 @@ package mysql
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"io"
|
||||
"net"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -271,7 +272,6 @@ func (mc *mysqlConn) Exec(query string, args []driver.Value) (driver.Result, err
|
||||
return nil, err
|
||||
}
|
||||
query = prepared
|
||||
args = nil
|
||||
}
|
||||
mc.affectedRows = 0
|
||||
mc.insertId = 0
|
||||
@@ -289,22 +289,29 @@ func (mc *mysqlConn) Exec(query string, args []driver.Value) (driver.Result, err
|
||||
// Internal function to execute commands
|
||||
func (mc *mysqlConn) exec(query string) error {
|
||||
// Send command
|
||||
err := mc.writeCommandPacketStr(comQuery, query)
|
||||
if err != nil {
|
||||
if err := mc.writeCommandPacketStr(comQuery, query); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Read Result
|
||||
resLen, err := mc.readResultSetHeaderPacket()
|
||||
if err == nil && resLen > 0 {
|
||||
if err = mc.readUntilEOF(); err != nil {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if resLen > 0 {
|
||||
// columns
|
||||
if err := mc.readUntilEOF(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = mc.readUntilEOF()
|
||||
// rows
|
||||
if err := mc.readUntilEOF(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
return mc.discardResults()
|
||||
}
|
||||
|
||||
func (mc *mysqlConn) Query(query string, args []driver.Value) (driver.Rows, error) {
|
||||
@@ -322,7 +329,6 @@ func (mc *mysqlConn) Query(query string, args []driver.Value) (driver.Rows, erro
|
||||
return nil, err
|
||||
}
|
||||
query = prepared
|
||||
args = nil
|
||||
}
|
||||
// Send command
|
||||
err := mc.writeCommandPacketStr(comQuery, query)
|
||||
@@ -335,11 +341,17 @@ func (mc *mysqlConn) Query(query string, args []driver.Value) (driver.Rows, erro
|
||||
rows.mc = mc
|
||||
|
||||
if resLen == 0 {
|
||||
// no columns, no more data
|
||||
return emptyRows{}, nil
|
||||
rows.rs.done = true
|
||||
|
||||
switch err := rows.NextResultSet(); err {
|
||||
case nil, io.EOF:
|
||||
return rows, nil
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
// Columns
|
||||
rows.columns, err = mc.readColumns(resLen)
|
||||
rows.rs.columns, err = mc.readColumns(resLen)
|
||||
return rows, err
|
||||
}
|
||||
}
|
||||
@@ -359,7 +371,7 @@ func (mc *mysqlConn) getSystemVar(name string) ([]byte, error) {
|
||||
if err == nil {
|
||||
rows := new(textRows)
|
||||
rows.mc = mc
|
||||
rows.columns = []mysqlField{{fieldType: fieldTypeVarChar}}
|
||||
rows.rs.columns = []mysqlField{{fieldType: fieldTypeVarChar}}
|
||||
|
||||
if resLen > 0 {
|
||||
// Columns
|
||||
|
||||
2
vendor/github.com/go-sql-driver/mysql/driver.go
сгенерированный
поставляемый
2
vendor/github.com/go-sql-driver/mysql/driver.go
сгенерированный
поставляемый
@@ -4,7 +4,7 @@
|
||||
// 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 provides a MySQL driver for Go's database/sql package
|
||||
// Package mysql provides a MySQL driver for Go's database/sql package.
|
||||
//
|
||||
// The driver should be used via the database/sql package:
|
||||
//
|
||||
|
||||
190
vendor/github.com/go-sql-driver/mysql/driver_go18_test.go
сгенерированный
поставляемый
Обычный файл
190
vendor/github.com/go-sql-driver/mysql/driver_go18_test.go
сгенерированный
поставляемый
Обычный файл
@@ -0,0 +1,190 @@
|
||||
// +build go1.8
|
||||
|
||||
package mysql
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMultiResultSet(t *testing.T) {
|
||||
type result struct {
|
||||
values [][]int
|
||||
columns []string
|
||||
}
|
||||
|
||||
// checkRows is a helper test function to validate rows containing 3 result
|
||||
// sets with specific values and columns. The basic query would look like this:
|
||||
//
|
||||
// SELECT 1 AS col1, 2 AS col2 UNION SELECT 3, 4;
|
||||
// SELECT 0 UNION SELECT 1;
|
||||
// SELECT 1 AS col1, 2 AS col2, 3 AS col3 UNION SELECT 4, 5, 6;
|
||||
//
|
||||
// to distinguish test cases the first string argument is put in front of
|
||||
// every error or fatal message.
|
||||
checkRows := func(desc string, rows *sql.Rows, dbt *DBTest) {
|
||||
expected := []result{
|
||||
{
|
||||
values: [][]int{{1, 2}, {3, 4}},
|
||||
columns: []string{"col1", "col2"},
|
||||
},
|
||||
{
|
||||
values: [][]int{{1, 2, 3}, {4, 5, 6}},
|
||||
columns: []string{"col1", "col2", "col3"},
|
||||
},
|
||||
}
|
||||
|
||||
var res1 result
|
||||
for rows.Next() {
|
||||
var res [2]int
|
||||
if err := rows.Scan(&res[0], &res[1]); err != nil {
|
||||
dbt.Fatal(err)
|
||||
}
|
||||
res1.values = append(res1.values, res[:])
|
||||
}
|
||||
|
||||
cols, err := rows.Columns()
|
||||
if err != nil {
|
||||
dbt.Fatal(desc, err)
|
||||
}
|
||||
res1.columns = cols
|
||||
|
||||
if !reflect.DeepEqual(expected[0], res1) {
|
||||
dbt.Error(desc, "want =", expected[0], "got =", res1)
|
||||
}
|
||||
|
||||
if !rows.NextResultSet() {
|
||||
dbt.Fatal(desc, "expected next result set")
|
||||
}
|
||||
|
||||
// ignoring one result set
|
||||
|
||||
if !rows.NextResultSet() {
|
||||
dbt.Fatal(desc, "expected next result set")
|
||||
}
|
||||
|
||||
var res2 result
|
||||
cols, err = rows.Columns()
|
||||
if err != nil {
|
||||
dbt.Fatal(desc, err)
|
||||
}
|
||||
res2.columns = cols
|
||||
|
||||
for rows.Next() {
|
||||
var res [3]int
|
||||
if err := rows.Scan(&res[0], &res[1], &res[2]); err != nil {
|
||||
dbt.Fatal(desc, err)
|
||||
}
|
||||
res2.values = append(res2.values, res[:])
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(expected[1], res2) {
|
||||
dbt.Error(desc, "want =", expected[1], "got =", res2)
|
||||
}
|
||||
|
||||
if rows.NextResultSet() {
|
||||
dbt.Error(desc, "unexpected next result set")
|
||||
}
|
||||
|
||||
if err := rows.Err(); err != nil {
|
||||
dbt.Error(desc, err)
|
||||
}
|
||||
}
|
||||
|
||||
runTestsWithMultiStatement(t, dsn, func(dbt *DBTest) {
|
||||
rows := dbt.mustQuery(`DO 1;
|
||||
SELECT 1 AS col1, 2 AS col2 UNION SELECT 3, 4;
|
||||
DO 1;
|
||||
SELECT 0 UNION SELECT 1;
|
||||
SELECT 1 AS col1, 2 AS col2, 3 AS col3 UNION SELECT 4, 5, 6;`)
|
||||
defer rows.Close()
|
||||
checkRows("query: ", rows, dbt)
|
||||
})
|
||||
|
||||
runTestsWithMultiStatement(t, dsn, func(dbt *DBTest) {
|
||||
queries := []string{
|
||||
`
|
||||
DROP PROCEDURE IF EXISTS test_mrss;
|
||||
CREATE PROCEDURE test_mrss()
|
||||
BEGIN
|
||||
DO 1;
|
||||
SELECT 1 AS col1, 2 AS col2 UNION SELECT 3, 4;
|
||||
DO 1;
|
||||
SELECT 0 UNION SELECT 1;
|
||||
SELECT 1 AS col1, 2 AS col2, 3 AS col3 UNION SELECT 4, 5, 6;
|
||||
END
|
||||
`,
|
||||
`
|
||||
DROP PROCEDURE IF EXISTS test_mrss;
|
||||
CREATE PROCEDURE test_mrss()
|
||||
BEGIN
|
||||
SELECT 1 AS col1, 2 AS col2 UNION SELECT 3, 4;
|
||||
SELECT 0 UNION SELECT 1;
|
||||
SELECT 1 AS col1, 2 AS col2, 3 AS col3 UNION SELECT 4, 5, 6;
|
||||
END
|
||||
`,
|
||||
}
|
||||
|
||||
defer dbt.mustExec("DROP PROCEDURE IF EXISTS test_mrss")
|
||||
|
||||
for i, query := range queries {
|
||||
dbt.mustExec(query)
|
||||
|
||||
stmt, err := dbt.db.Prepare("CALL test_mrss()")
|
||||
if err != nil {
|
||||
dbt.Fatalf("%v (i=%d)", err, i)
|
||||
}
|
||||
defer stmt.Close()
|
||||
|
||||
for j := 0; j < 2; j++ {
|
||||
rows, err := stmt.Query()
|
||||
if err != nil {
|
||||
dbt.Fatalf("%v (i=%d) (j=%d)", err, i, j)
|
||||
}
|
||||
checkRows(fmt.Sprintf("prepared stmt query (i=%d) (j=%d): ", i, j), rows, dbt)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestMultiResultSetNoSelect(t *testing.T) {
|
||||
runTestsWithMultiStatement(t, dsn, func(dbt *DBTest) {
|
||||
rows := dbt.mustQuery("DO 1; DO 2;")
|
||||
defer rows.Close()
|
||||
|
||||
if rows.Next() {
|
||||
dbt.Error("unexpected row")
|
||||
}
|
||||
|
||||
if rows.NextResultSet() {
|
||||
dbt.Error("unexpected next result set")
|
||||
}
|
||||
|
||||
if err := rows.Err(); err != nil {
|
||||
dbt.Error("expected nil; got ", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// tests if rows are set in a proper state if some results were ignored before
|
||||
// calling rows.NextResultSet.
|
||||
func TestSkipResults(t *testing.T) {
|
||||
runTests(t, dsn, func(dbt *DBTest) {
|
||||
rows := dbt.mustQuery("SELECT 1, 2")
|
||||
defer rows.Close()
|
||||
|
||||
if !rows.Next() {
|
||||
dbt.Error("expected row")
|
||||
}
|
||||
|
||||
if rows.NextResultSet() {
|
||||
dbt.Error("unexpected next result set")
|
||||
}
|
||||
|
||||
if err := rows.Err(); err != nil {
|
||||
dbt.Error("expected nil; got ", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
69
vendor/github.com/go-sql-driver/mysql/driver_test.go
сгенерированный
поставляемый
69
vendor/github.com/go-sql-driver/mysql/driver_test.go
сгенерированный
поставляемый
@@ -684,7 +684,7 @@ func TestDateTime(t *testing.T) {
|
||||
for _, setup := range setups.tests {
|
||||
allowBinTime := true
|
||||
if setup.s == "" {
|
||||
// fill time string whereever Go can reliable produce it
|
||||
// fill time string wherever Go can reliable produce it
|
||||
setup.s = setup.t.Format(setups.tlayout)
|
||||
} else if setup.s[0] == '!' {
|
||||
// skip tests using setup.t as source in queries
|
||||
@@ -856,14 +856,14 @@ func TestNULL(t *testing.T) {
|
||||
dbt.Fatal(err)
|
||||
}
|
||||
if b != nil {
|
||||
dbt.Error("non-nil []byte wich should be nil")
|
||||
dbt.Error("non-nil []byte which should be nil")
|
||||
}
|
||||
// Read non-nil
|
||||
if err = nonNullStmt.QueryRow().Scan(&b); err != nil {
|
||||
dbt.Fatal(err)
|
||||
}
|
||||
if b == nil {
|
||||
dbt.Error("nil []byte wich should be non-nil")
|
||||
dbt.Error("nil []byte which should be non-nil")
|
||||
}
|
||||
// Insert nil
|
||||
b = nil
|
||||
@@ -1054,22 +1054,36 @@ func TestLoadData(t *testing.T) {
|
||||
dbt.Fatalf("rows count mismatch. Got %d, want 4", i)
|
||||
}
|
||||
}
|
||||
file, err := ioutil.TempFile("", "gotest")
|
||||
defer os.Remove(file.Name())
|
||||
if err != nil {
|
||||
dbt.Fatal(err)
|
||||
}
|
||||
file.WriteString("1\ta string\n2\ta string containing a \\t\n3\ta string containing a \\n\n4\ta string containing both \\t\\n\n")
|
||||
file.Close()
|
||||
|
||||
dbt.db.Exec("DROP TABLE IF EXISTS test")
|
||||
dbt.mustExec("CREATE TABLE test (id INT NOT NULL PRIMARY KEY, value TEXT NOT NULL) CHARACTER SET utf8")
|
||||
|
||||
// Local File
|
||||
file, err := ioutil.TempFile("", "gotest")
|
||||
defer os.Remove(file.Name())
|
||||
if err != nil {
|
||||
dbt.Fatal(err)
|
||||
}
|
||||
RegisterLocalFile(file.Name())
|
||||
|
||||
// Try first with empty file
|
||||
dbt.mustExec(fmt.Sprintf("LOAD DATA LOCAL INFILE %q INTO TABLE test", file.Name()))
|
||||
var count int
|
||||
err = dbt.db.QueryRow("SELECT COUNT(*) FROM test").Scan(&count)
|
||||
if err != nil {
|
||||
dbt.Fatal(err.Error())
|
||||
}
|
||||
if count != 0 {
|
||||
dbt.Fatalf("unexpected row count: got %d, want 0", count)
|
||||
}
|
||||
|
||||
// Then fille File with data and try to load it
|
||||
file.WriteString("1\ta string\n2\ta string containing a \\t\n3\ta string containing a \\n\n4\ta string containing both \\t\\n\n")
|
||||
file.Close()
|
||||
dbt.mustExec(fmt.Sprintf("LOAD DATA LOCAL INFILE %q INTO TABLE test", file.Name()))
|
||||
verifyLoadDataResult()
|
||||
// negative test
|
||||
|
||||
// Try with non-existing file
|
||||
_, err = dbt.db.Exec("LOAD DATA LOCAL INFILE 'doesnotexist' INTO TABLE test")
|
||||
if err == nil {
|
||||
dbt.Fatal("load non-existent file didn't fail")
|
||||
@@ -1902,3 +1916,36 @@ func TestInterruptBySignal(t *testing.T) {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestColumnsReusesSlice(t *testing.T) {
|
||||
rows := mysqlRows{
|
||||
rs: resultSet{
|
||||
columns: []mysqlField{
|
||||
{
|
||||
tableName: "test",
|
||||
name: "A",
|
||||
},
|
||||
{
|
||||
tableName: "test",
|
||||
name: "B",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
allocs := testing.AllocsPerRun(1, func() {
|
||||
cols := rows.Columns()
|
||||
|
||||
if len(cols) != 2 {
|
||||
t.Fatalf("expected 2 columns, got %d", len(cols))
|
||||
}
|
||||
})
|
||||
|
||||
if allocs != 0 {
|
||||
t.Fatalf("expected 0 allocations, got %d", int(allocs))
|
||||
}
|
||||
|
||||
if rows.rs.columnNames == nil {
|
||||
t.Fatalf("expected columnNames to be set, got nil")
|
||||
}
|
||||
}
|
||||
|
||||
4
vendor/github.com/go-sql-driver/mysql/dsn.go
сгенерированный
поставляемый
4
vendor/github.com/go-sql-driver/mysql/dsn.go
сгенерированный
поставляемый
@@ -494,6 +494,10 @@ func parseDSNParams(cfg *Config, params string) (err error) {
|
||||
if boolValue {
|
||||
cfg.TLSConfig = "true"
|
||||
cfg.tls = &tls.Config{}
|
||||
host, _, err := net.SplitHostPort(cfg.Addr)
|
||||
if err == nil {
|
||||
cfg.tls.ServerName = host
|
||||
}
|
||||
} else {
|
||||
cfg.TLSConfig = "false"
|
||||
}
|
||||
|
||||
3
vendor/github.com/go-sql-driver/mysql/infile.go
сгенерированный
поставляемый
3
vendor/github.com/go-sql-driver/mysql/infile.go
сгенерированный
поставляемый
@@ -147,7 +147,8 @@ func (mc *mysqlConn) handleInFileRequest(name string) (err error) {
|
||||
}
|
||||
|
||||
// send content packets
|
||||
if err == nil {
|
||||
// if packetSize == 0, the Reader contains no data
|
||||
if err == nil && packetSize > 0 {
|
||||
data := make([]byte, 4+packetSize)
|
||||
var n int
|
||||
for err == nil {
|
||||
|
||||
77
vendor/github.com/go-sql-driver/mysql/packets.go
сгенерированный
поставляемый
77
vendor/github.com/go-sql-driver/mysql/packets.go
сгенерированный
поставляемый
@@ -486,23 +486,24 @@ func (mc *mysqlConn) readResultOK() ([]byte, error) {
|
||||
plugin := string(data[1:pluginEndIndex])
|
||||
cipher := data[pluginEndIndex+1 : len(data)-1]
|
||||
|
||||
if plugin == "mysql_old_password" {
|
||||
switch plugin {
|
||||
case "mysql_old_password":
|
||||
// using old_passwords
|
||||
return cipher, ErrOldPassword
|
||||
} else if plugin == "mysql_clear_password" {
|
||||
case "mysql_clear_password":
|
||||
// using clear text password
|
||||
return cipher, ErrCleartextPassword
|
||||
} else if plugin == "mysql_native_password" {
|
||||
case "mysql_native_password":
|
||||
// using mysql default authentication method
|
||||
return cipher, ErrNativePassword
|
||||
} else {
|
||||
default:
|
||||
return cipher, ErrUnknownPlugin
|
||||
}
|
||||
} else {
|
||||
// https://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::OldAuthSwitchRequest
|
||||
return nil, ErrOldPassword
|
||||
}
|
||||
|
||||
// https://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::OldAuthSwitchRequest
|
||||
return nil, ErrOldPassword
|
||||
|
||||
default: // Error otherwise
|
||||
return nil, mc.handleErrorPacket(data)
|
||||
}
|
||||
@@ -584,8 +585,8 @@ func (mc *mysqlConn) handleOkPacket(data []byte) error {
|
||||
|
||||
// server_status [2 bytes]
|
||||
mc.status = readStatus(data[1+n+m : 1+n+m+2])
|
||||
if err := mc.discardResults(); err != nil {
|
||||
return err
|
||||
if mc.status&statusMoreResultsExists != 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// warning count [2 bytes]
|
||||
@@ -698,6 +699,10 @@ func (mc *mysqlConn) readColumns(count int) ([]mysqlField, error) {
|
||||
func (rows *textRows) readRow(dest []driver.Value) error {
|
||||
mc := rows.mc
|
||||
|
||||
if rows.rs.done {
|
||||
return io.EOF
|
||||
}
|
||||
|
||||
data, err := mc.readPacket()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -707,15 +712,11 @@ func (rows *textRows) readRow(dest []driver.Value) error {
|
||||
if data[0] == iEOF && len(data) == 5 {
|
||||
// server_status [2 bytes]
|
||||
rows.mc.status = readStatus(data[3:])
|
||||
err = rows.mc.discardResults()
|
||||
if err == nil {
|
||||
err = io.EOF
|
||||
} else {
|
||||
// connection unusable
|
||||
rows.mc.Close()
|
||||
rows.rs.done = true
|
||||
if !rows.HasNextResultSet() {
|
||||
rows.mc = nil
|
||||
}
|
||||
rows.mc = nil
|
||||
return err
|
||||
return io.EOF
|
||||
}
|
||||
if data[0] == iERR {
|
||||
rows.mc = nil
|
||||
@@ -736,7 +737,7 @@ func (rows *textRows) readRow(dest []driver.Value) error {
|
||||
if !mc.parseTime {
|
||||
continue
|
||||
} else {
|
||||
switch rows.columns[i].fieldType {
|
||||
switch rows.rs.columns[i].fieldType {
|
||||
case fieldTypeTimestamp, fieldTypeDateTime,
|
||||
fieldTypeDate, fieldTypeNewDate:
|
||||
dest[i], err = parseDateTime(
|
||||
@@ -1097,8 +1098,6 @@ func (mc *mysqlConn) discardResults() error {
|
||||
if err := mc.readUntilEOF(); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
mc.status &^= statusMoreResultsExists
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@@ -1116,15 +1115,11 @@ func (rows *binaryRows) readRow(dest []driver.Value) error {
|
||||
// EOF Packet
|
||||
if data[0] == iEOF && len(data) == 5 {
|
||||
rows.mc.status = readStatus(data[3:])
|
||||
err = rows.mc.discardResults()
|
||||
if err == nil {
|
||||
err = io.EOF
|
||||
} else {
|
||||
// connection unusable
|
||||
rows.mc.Close()
|
||||
rows.rs.done = true
|
||||
if !rows.HasNextResultSet() {
|
||||
rows.mc = nil
|
||||
}
|
||||
rows.mc = nil
|
||||
return err
|
||||
return io.EOF
|
||||
}
|
||||
rows.mc = nil
|
||||
|
||||
@@ -1145,14 +1140,14 @@ func (rows *binaryRows) readRow(dest []driver.Value) error {
|
||||
}
|
||||
|
||||
// Convert to byte-coded string
|
||||
switch rows.columns[i].fieldType {
|
||||
switch rows.rs.columns[i].fieldType {
|
||||
case fieldTypeNULL:
|
||||
dest[i] = nil
|
||||
continue
|
||||
|
||||
// Numeric Types
|
||||
case fieldTypeTiny:
|
||||
if rows.columns[i].flags&flagUnsigned != 0 {
|
||||
if rows.rs.columns[i].flags&flagUnsigned != 0 {
|
||||
dest[i] = int64(data[pos])
|
||||
} else {
|
||||
dest[i] = int64(int8(data[pos]))
|
||||
@@ -1161,7 +1156,7 @@ func (rows *binaryRows) readRow(dest []driver.Value) error {
|
||||
continue
|
||||
|
||||
case fieldTypeShort, fieldTypeYear:
|
||||
if rows.columns[i].flags&flagUnsigned != 0 {
|
||||
if rows.rs.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])))
|
||||
@@ -1170,7 +1165,7 @@ func (rows *binaryRows) readRow(dest []driver.Value) error {
|
||||
continue
|
||||
|
||||
case fieldTypeInt24, fieldTypeLong:
|
||||
if rows.columns[i].flags&flagUnsigned != 0 {
|
||||
if rows.rs.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])))
|
||||
@@ -1179,7 +1174,7 @@ func (rows *binaryRows) readRow(dest []driver.Value) error {
|
||||
continue
|
||||
|
||||
case fieldTypeLongLong:
|
||||
if rows.columns[i].flags&flagUnsigned != 0 {
|
||||
if rows.rs.columns[i].flags&flagUnsigned != 0 {
|
||||
val := binary.LittleEndian.Uint64(data[pos : pos+8])
|
||||
if val > math.MaxInt64 {
|
||||
dest[i] = uint64ToString(val)
|
||||
@@ -1193,7 +1188,7 @@ func (rows *binaryRows) readRow(dest []driver.Value) error {
|
||||
continue
|
||||
|
||||
case fieldTypeFloat:
|
||||
dest[i] = float32(math.Float32frombits(binary.LittleEndian.Uint32(data[pos : pos+4])))
|
||||
dest[i] = math.Float32frombits(binary.LittleEndian.Uint32(data[pos : pos+4]))
|
||||
pos += 4
|
||||
continue
|
||||
|
||||
@@ -1233,10 +1228,10 @@ func (rows *binaryRows) readRow(dest []driver.Value) error {
|
||||
case isNull:
|
||||
dest[i] = nil
|
||||
continue
|
||||
case rows.columns[i].fieldType == fieldTypeTime:
|
||||
case rows.rs.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 {
|
||||
switch decimals := rows.rs.columns[i].decimals; decimals {
|
||||
case 0x00, 0x1f:
|
||||
dstlen = 8
|
||||
case 1, 2, 3, 4, 5, 6:
|
||||
@@ -1244,7 +1239,7 @@ func (rows *binaryRows) readRow(dest []driver.Value) error {
|
||||
default:
|
||||
return fmt.Errorf(
|
||||
"protocol error, illegal decimals value %d",
|
||||
rows.columns[i].decimals,
|
||||
rows.rs.columns[i].decimals,
|
||||
)
|
||||
}
|
||||
dest[i], err = formatBinaryDateTime(data[pos:pos+int(num)], dstlen, true)
|
||||
@@ -1252,10 +1247,10 @@ func (rows *binaryRows) readRow(dest []driver.Value) error {
|
||||
dest[i], err = parseBinaryDateTime(num, data[pos:], rows.mc.cfg.Loc)
|
||||
default:
|
||||
var dstlen uint8
|
||||
if rows.columns[i].fieldType == fieldTypeDate {
|
||||
if rows.rs.columns[i].fieldType == fieldTypeDate {
|
||||
dstlen = 10
|
||||
} else {
|
||||
switch decimals := rows.columns[i].decimals; decimals {
|
||||
switch decimals := rows.rs.columns[i].decimals; decimals {
|
||||
case 0x00, 0x1f:
|
||||
dstlen = 19
|
||||
case 1, 2, 3, 4, 5, 6:
|
||||
@@ -1263,7 +1258,7 @@ func (rows *binaryRows) readRow(dest []driver.Value) error {
|
||||
default:
|
||||
return fmt.Errorf(
|
||||
"protocol error, illegal decimals value %d",
|
||||
rows.columns[i].decimals,
|
||||
rows.rs.columns[i].decimals,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1279,7 +1274,7 @@ func (rows *binaryRows) readRow(dest []driver.Value) error {
|
||||
|
||||
// Please report if this happens!
|
||||
default:
|
||||
return fmt.Errorf("unknown field type %d", rows.columns[i].fieldType)
|
||||
return fmt.Errorf("unknown field type %d", rows.rs.columns[i].fieldType)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
8
vendor/github.com/go-sql-driver/mysql/packets_test.go
сгенерированный
поставляемый
8
vendor/github.com/go-sql-driver/mysql/packets_test.go
сгенерированный
поставляемый
@@ -101,7 +101,7 @@ func TestReadPacketSingleByte(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(packet) != 1 {
|
||||
t.Fatalf("unexpected packet lenght: expected %d, got %d", 1, len(packet))
|
||||
t.Fatalf("unexpected packet length: expected %d, got %d", 1, len(packet))
|
||||
}
|
||||
if packet[0] != 0xff {
|
||||
t.Fatalf("unexpected packet content: expected %x, got %x", 0xff, packet[0])
|
||||
@@ -171,7 +171,7 @@ func TestReadPacketSplit(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(packet) != maxPacketSize {
|
||||
t.Fatalf("unexpected packet lenght: expected %d, got %d", maxPacketSize, len(packet))
|
||||
t.Fatalf("unexpected packet length: expected %d, got %d", maxPacketSize, len(packet))
|
||||
}
|
||||
if packet[0] != 0x11 {
|
||||
t.Fatalf("unexpected payload start: expected %x, got %x", 0x11, packet[0])
|
||||
@@ -205,7 +205,7 @@ func TestReadPacketSplit(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(packet) != 2*maxPacketSize {
|
||||
t.Fatalf("unexpected packet lenght: expected %d, got %d", 2*maxPacketSize, len(packet))
|
||||
t.Fatalf("unexpected packet length: expected %d, got %d", 2*maxPacketSize, len(packet))
|
||||
}
|
||||
if packet[0] != 0x11 {
|
||||
t.Fatalf("unexpected payload start: expected %x, got %x", 0x11, packet[0])
|
||||
@@ -231,7 +231,7 @@ func TestReadPacketSplit(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(packet) != maxPacketSize+42 {
|
||||
t.Fatalf("unexpected packet lenght: expected %d, got %d", maxPacketSize+42, len(packet))
|
||||
t.Fatalf("unexpected packet length: expected %d, got %d", maxPacketSize+42, len(packet))
|
||||
}
|
||||
if packet[0] != 0x11 {
|
||||
t.Fatalf("unexpected payload start: expected %x, got %x", 0x11, packet[0])
|
||||
|
||||
112
vendor/github.com/go-sql-driver/mysql/rows.go
сгенерированный
поставляемый
112
vendor/github.com/go-sql-driver/mysql/rows.go
сгенерированный
поставляемый
@@ -21,9 +21,15 @@ type mysqlField struct {
|
||||
decimals byte
|
||||
}
|
||||
|
||||
type resultSet struct {
|
||||
columns []mysqlField
|
||||
columnNames []string
|
||||
done bool
|
||||
}
|
||||
|
||||
type mysqlRows struct {
|
||||
mc *mysqlConn
|
||||
columns []mysqlField
|
||||
mc *mysqlConn
|
||||
rs resultSet
|
||||
}
|
||||
|
||||
type binaryRows struct {
|
||||
@@ -34,27 +40,31 @@ type textRows struct {
|
||||
mysqlRows
|
||||
}
|
||||
|
||||
type emptyRows struct{}
|
||||
|
||||
func (rows *mysqlRows) Columns() []string {
|
||||
columns := make([]string, len(rows.columns))
|
||||
if rows.rs.columnNames != nil {
|
||||
return rows.rs.columnNames
|
||||
}
|
||||
|
||||
columns := make([]string, len(rows.rs.columns))
|
||||
if rows.mc != nil && rows.mc.cfg.ColumnsWithAlias {
|
||||
for i := range columns {
|
||||
if tableName := rows.columns[i].tableName; len(tableName) > 0 {
|
||||
columns[i] = tableName + "." + rows.columns[i].name
|
||||
if tableName := rows.rs.columns[i].tableName; len(tableName) > 0 {
|
||||
columns[i] = tableName + "." + rows.rs.columns[i].name
|
||||
} else {
|
||||
columns[i] = rows.columns[i].name
|
||||
columns[i] = rows.rs.columns[i].name
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for i := range columns {
|
||||
columns[i] = rows.columns[i].name
|
||||
columns[i] = rows.rs.columns[i].name
|
||||
}
|
||||
}
|
||||
|
||||
rows.rs.columnNames = columns
|
||||
return columns
|
||||
}
|
||||
|
||||
func (rows *mysqlRows) Close() error {
|
||||
func (rows *mysqlRows) Close() (err error) {
|
||||
mc := rows.mc
|
||||
if mc == nil {
|
||||
return nil
|
||||
@@ -64,7 +74,9 @@ func (rows *mysqlRows) Close() error {
|
||||
}
|
||||
|
||||
// Remove unread packets from stream
|
||||
err := mc.readUntilEOF()
|
||||
if !rows.rs.done {
|
||||
err = mc.readUntilEOF()
|
||||
}
|
||||
if err == nil {
|
||||
if err = mc.discardResults(); err != nil {
|
||||
return err
|
||||
@@ -75,6 +87,62 @@ func (rows *mysqlRows) Close() error {
|
||||
return err
|
||||
}
|
||||
|
||||
func (rows *mysqlRows) HasNextResultSet() (b bool) {
|
||||
if rows.mc == nil {
|
||||
return false
|
||||
}
|
||||
return rows.mc.status&statusMoreResultsExists != 0
|
||||
}
|
||||
|
||||
func (rows *mysqlRows) nextResultSet() (int, error) {
|
||||
if rows.mc == nil {
|
||||
return 0, io.EOF
|
||||
}
|
||||
if rows.mc.netConn == nil {
|
||||
return 0, ErrInvalidConn
|
||||
}
|
||||
|
||||
// Remove unread packets from stream
|
||||
if !rows.rs.done {
|
||||
if err := rows.mc.readUntilEOF(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
rows.rs.done = true
|
||||
}
|
||||
|
||||
if !rows.HasNextResultSet() {
|
||||
rows.mc = nil
|
||||
return 0, io.EOF
|
||||
}
|
||||
rows.rs = resultSet{}
|
||||
return rows.mc.readResultSetHeaderPacket()
|
||||
}
|
||||
|
||||
func (rows *mysqlRows) nextNotEmptyResultSet() (int, error) {
|
||||
for {
|
||||
resLen, err := rows.nextResultSet()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if resLen > 0 {
|
||||
return resLen, nil
|
||||
}
|
||||
|
||||
rows.rs.done = true
|
||||
}
|
||||
}
|
||||
|
||||
func (rows *binaryRows) NextResultSet() error {
|
||||
resLen, err := rows.nextNotEmptyResultSet()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rows.rs.columns, err = rows.mc.readColumns(resLen)
|
||||
return err
|
||||
}
|
||||
|
||||
func (rows *binaryRows) Next(dest []driver.Value) error {
|
||||
if mc := rows.mc; mc != nil {
|
||||
if mc.netConn == nil {
|
||||
@@ -87,6 +155,16 @@ func (rows *binaryRows) Next(dest []driver.Value) error {
|
||||
return io.EOF
|
||||
}
|
||||
|
||||
func (rows *textRows) NextResultSet() (err error) {
|
||||
resLen, err := rows.nextNotEmptyResultSet()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rows.rs.columns, err = rows.mc.readColumns(resLen)
|
||||
return err
|
||||
}
|
||||
|
||||
func (rows *textRows) Next(dest []driver.Value) error {
|
||||
if mc := rows.mc; mc != nil {
|
||||
if mc.netConn == nil {
|
||||
@@ -98,15 +176,3 @@ func (rows *textRows) Next(dest []driver.Value) error {
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
53
vendor/github.com/go-sql-driver/mysql/statement.go
сгенерированный
поставляемый
53
vendor/github.com/go-sql-driver/mysql/statement.go
сгенерированный
поставляемый
@@ -11,6 +11,7 @@ package mysql
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
"strconv"
|
||||
)
|
||||
@@ -19,7 +20,6 @@ type mysqlStmt struct {
|
||||
mc *mysqlConn
|
||||
id uint32
|
||||
paramCount int
|
||||
columns []mysqlField // cached from the first query
|
||||
}
|
||||
|
||||
func (stmt *mysqlStmt) Close() error {
|
||||
@@ -62,26 +62,30 @@ func (stmt *mysqlStmt) Exec(args []driver.Value) (driver.Result, error) {
|
||||
|
||||
// Read Result
|
||||
resLen, err := mc.readResultSetHeaderPacket()
|
||||
if err == nil {
|
||||
if resLen > 0 {
|
||||
// Columns
|
||||
err = mc.readUntilEOF()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Rows
|
||||
err = mc.readUntilEOF()
|
||||
if resLen > 0 {
|
||||
// Columns
|
||||
if err = mc.readUntilEOF(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err == nil {
|
||||
return &mysqlResult{
|
||||
affectedRows: int64(mc.affectedRows),
|
||||
insertId: int64(mc.insertId),
|
||||
}, nil
|
||||
|
||||
// Rows
|
||||
if err := mc.readUntilEOF(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return nil, err
|
||||
if err := mc.discardResults(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &mysqlResult{
|
||||
affectedRows: int64(mc.affectedRows),
|
||||
insertId: int64(mc.insertId),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (stmt *mysqlStmt) Query(args []driver.Value) (driver.Rows, error) {
|
||||
@@ -107,14 +111,15 @@ func (stmt *mysqlStmt) Query(args []driver.Value) (driver.Rows, error) {
|
||||
|
||||
if resLen > 0 {
|
||||
rows.mc = mc
|
||||
// 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()
|
||||
rows.rs.columns, err = mc.readColumns(resLen)
|
||||
} else {
|
||||
rows.rs.done = true
|
||||
|
||||
switch err := rows.NextResultSet(); err {
|
||||
case nil, io.EOF:
|
||||
return rows, nil
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Ссылка в новой задаче
Block a user