mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
mysql: update mysql driver to latest master
The latest master implements the ColumnType interface. See https://github.com/go-sql-driver/mysql/issues/495 This removes the custom code in the vendor folder that did a ColumnType mapping.
This commit is contained in:
23
vendor/github.com/go-sql-driver/mysql/AUTHORS
generated
vendored
23
vendor/github.com/go-sql-driver/mysql/AUTHORS
generated
vendored
@@ -12,38 +12,57 @@
|
|||||||
# Individual Persons
|
# Individual Persons
|
||||||
|
|
||||||
Aaron Hopkins <go-sql-driver at die.net>
|
Aaron Hopkins <go-sql-driver at die.net>
|
||||||
|
Achille Roussel <achille.roussel at gmail.com>
|
||||||
Arne Hormann <arnehormann at gmail.com>
|
Arne Hormann <arnehormann at gmail.com>
|
||||||
|
Asta Xie <xiemengjun at gmail.com>
|
||||||
|
Bulat Gaifullin <gaifullinbf at gmail.com>
|
||||||
Carlos Nieto <jose.carlos at menteslibres.net>
|
Carlos Nieto <jose.carlos at menteslibres.net>
|
||||||
Chris Moos <chris at tech9computers.com>
|
Chris Moos <chris at tech9computers.com>
|
||||||
|
Daniel Montoya <dsmontoyam at gmail.com>
|
||||||
Daniel Nichter <nil at codenode.com>
|
Daniel Nichter <nil at codenode.com>
|
||||||
Daniël van Eeden <git at myname.nl>
|
Daniël van Eeden <git at myname.nl>
|
||||||
|
Dave Protasowski <dprotaso at gmail.com>
|
||||||
DisposaBoy <disposaboy at dby.me>
|
DisposaBoy <disposaboy at dby.me>
|
||||||
Egor Smolyakov <egorsmkv at gmail.com>
|
Egor Smolyakov <egorsmkv at gmail.com>
|
||||||
|
Evan Shaw <evan at vendhq.com>
|
||||||
Frederick Mayle <frederickmayle at gmail.com>
|
Frederick Mayle <frederickmayle at gmail.com>
|
||||||
Gustavo Kristic <gkristic at gmail.com>
|
Gustavo Kristic <gkristic at gmail.com>
|
||||||
Hanno Braun <mail at hannobraun.com>
|
Hanno Braun <mail at hannobraun.com>
|
||||||
Henri Yandell <flamefew at gmail.com>
|
Henri Yandell <flamefew at gmail.com>
|
||||||
Hirotaka Yamamoto <ymmt2005 at gmail.com>
|
Hirotaka Yamamoto <ymmt2005 at gmail.com>
|
||||||
|
ICHINOSE Shogo <shogo82148 at gmail.com>
|
||||||
INADA Naoki <songofacandy at gmail.com>
|
INADA Naoki <songofacandy at gmail.com>
|
||||||
Jacek Szwec <szwec.jacek at gmail.com>
|
Jacek Szwec <szwec.jacek at gmail.com>
|
||||||
James Harr <james.harr at gmail.com>
|
James Harr <james.harr at gmail.com>
|
||||||
|
Jeff Hodges <jeff at somethingsimilar.com>
|
||||||
|
Jeffrey Charles <jeffreycharles at gmail.com>
|
||||||
Jian Zhen <zhenjl at gmail.com>
|
Jian Zhen <zhenjl at gmail.com>
|
||||||
Joshua Prunier <joshua.prunier at gmail.com>
|
Joshua Prunier <joshua.prunier at gmail.com>
|
||||||
Julien Lefevre <julien.lefevr at gmail.com>
|
Julien Lefevre <julien.lefevr at gmail.com>
|
||||||
Julien Schmidt <go-sql-driver at julienschmidt.com>
|
Julien Schmidt <go-sql-driver at julienschmidt.com>
|
||||||
|
Justin Li <jli at j-li.net>
|
||||||
|
Justin Nuß <nuss.justin at gmail.com>
|
||||||
Kamil Dziedzic <kamil at klecza.pl>
|
Kamil Dziedzic <kamil at klecza.pl>
|
||||||
Kevin Malachowski <kevin at chowski.com>
|
Kevin Malachowski <kevin at chowski.com>
|
||||||
|
Kieron Woodhouse <kieron.woodhouse at infosum.com>
|
||||||
Lennart Rudolph <lrudolph at hmc.edu>
|
Lennart Rudolph <lrudolph at hmc.edu>
|
||||||
Leonardo YongUk Kim <dalinaum at gmail.com>
|
Leonardo YongUk Kim <dalinaum at gmail.com>
|
||||||
|
Linh Tran Tuan <linhduonggnu at gmail.com>
|
||||||
|
Lion Yang <lion at aosc.xyz>
|
||||||
Luca Looz <luca.looz92 at gmail.com>
|
Luca Looz <luca.looz92 at gmail.com>
|
||||||
Lucas Liu <extrafliu at gmail.com>
|
Lucas Liu <extrafliu at gmail.com>
|
||||||
Luke Scott <luke at webconnex.com>
|
Luke Scott <luke at webconnex.com>
|
||||||
|
Maciej Zimnoch <maciej.zimnoch@codilime.com>
|
||||||
Michael Woolnough <michael.woolnough at gmail.com>
|
Michael Woolnough <michael.woolnough at gmail.com>
|
||||||
Nicola Peduzzi <thenikso at gmail.com>
|
Nicola Peduzzi <thenikso at gmail.com>
|
||||||
Olivier Mengué <dolmen at cpan.org>
|
Olivier Mengué <dolmen at cpan.org>
|
||||||
|
oscarzhao <oscarzhaosl at gmail.com>
|
||||||
Paul Bonser <misterpib at gmail.com>
|
Paul Bonser <misterpib at gmail.com>
|
||||||
Peter Schultz <peter.schultz at classmarkets.com>
|
Peter Schultz <peter.schultz at classmarkets.com>
|
||||||
|
Rebecca Chin <rchin at pivotal.io>
|
||||||
Runrioter Wung <runrioter at gmail.com>
|
Runrioter Wung <runrioter at gmail.com>
|
||||||
|
Robert Russell <robert at rrbrussell.com>
|
||||||
|
Shuode Li <elemount at qq.com>
|
||||||
Soroush Pour <me at soroushjp.com>
|
Soroush Pour <me at soroushjp.com>
|
||||||
Stan Putrya <root.vagner at gmail.com>
|
Stan Putrya <root.vagner at gmail.com>
|
||||||
Stanley Gunawan <gunawan.stanley at gmail.com>
|
Stanley Gunawan <gunawan.stanley at gmail.com>
|
||||||
@@ -55,5 +74,9 @@ Zhenye Xie <xiezhenye at gmail.com>
|
|||||||
# Organizations
|
# Organizations
|
||||||
|
|
||||||
Barracuda Networks, Inc.
|
Barracuda Networks, Inc.
|
||||||
|
Counting Ltd.
|
||||||
Google Inc.
|
Google Inc.
|
||||||
|
InfoSum Ltd.
|
||||||
|
Keybase Inc.
|
||||||
|
Pivotal Inc.
|
||||||
Stripe Inc.
|
Stripe Inc.
|
||||||
|
|||||||
65
vendor/github.com/go-sql-driver/mysql/README.md
generated
vendored
65
vendor/github.com/go-sql-driver/mysql/README.md
generated
vendored
@@ -16,6 +16,8 @@ A MySQL-Driver for Go's [database/sql](https://golang.org/pkg/database/sql/) pac
|
|||||||
* [Parameters](#parameters)
|
* [Parameters](#parameters)
|
||||||
* [Examples](#examples)
|
* [Examples](#examples)
|
||||||
* [Connection pool and timeouts](#connection-pool-and-timeouts)
|
* [Connection pool and timeouts](#connection-pool-and-timeouts)
|
||||||
|
* [context.Context Support](#contextcontext-support)
|
||||||
|
* [ColumnType Support](#columntype-support)
|
||||||
* [LOAD DATA LOCAL INFILE support](#load-data-local-infile-support)
|
* [LOAD DATA LOCAL INFILE support](#load-data-local-infile-support)
|
||||||
* [time.Time support](#timetime-support)
|
* [time.Time support](#timetime-support)
|
||||||
* [Unicode support](#unicode-support)
|
* [Unicode support](#unicode-support)
|
||||||
@@ -38,7 +40,7 @@ A MySQL-Driver for Go's [database/sql](https://golang.org/pkg/database/sql/) pac
|
|||||||
* Optional placeholder interpolation
|
* Optional placeholder interpolation
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
* Go 1.2 or higher
|
* Go 1.7 or higher. We aim to support the 3 latest versions of Go.
|
||||||
* MySQL (4.1+), MariaDB, Percona Server, Google CloudSQL or Sphinx (2.2.3+)
|
* MySQL (4.1+), MariaDB, Percona Server, Google CloudSQL or Sphinx (2.2.3+)
|
||||||
|
|
||||||
---------------------------------------
|
---------------------------------------
|
||||||
@@ -46,7 +48,7 @@ A MySQL-Driver for Go's [database/sql](https://golang.org/pkg/database/sql/) pac
|
|||||||
## Installation
|
## Installation
|
||||||
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:
|
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
|
```bash
|
||||||
$ go get github.com/go-sql-driver/mysql
|
$ go get -u github.com/go-sql-driver/mysql
|
||||||
```
|
```
|
||||||
Make sure [Git is installed](https://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`.
|
||||||
|
|
||||||
@@ -100,7 +102,8 @@ See [net.Dial](https://golang.org/pkg/net/#Dial) for more information which netw
|
|||||||
In general you should use an Unix domain socket if available and TCP otherwise for best performance.
|
In general you should use an Unix domain socket if available and TCP otherwise for best performance.
|
||||||
|
|
||||||
#### Address
|
#### Address
|
||||||
For TCP and UDP networks, addresses have the form `host:port`.
|
For TCP and UDP networks, addresses have the form `host[:port]`.
|
||||||
|
If `port` is omitted, the default port will be used.
|
||||||
If `host` is a literal IPv6 address, it must be enclosed in square brackets.
|
If `host` is a literal IPv6 address, it must be enclosed in square brackets.
|
||||||
The functions [net.JoinHostPort](https://golang.org/pkg/net/#JoinHostPort) and [net.SplitHostPort](https://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.
|
||||||
|
|
||||||
@@ -137,9 +140,9 @@ Default: false
|
|||||||
```
|
```
|
||||||
Type: bool
|
Type: bool
|
||||||
Valid Values: true, false
|
Valid Values: true, false
|
||||||
Default: false
|
Default: true
|
||||||
```
|
```
|
||||||
`allowNativePasswords=true` allows the usage of the mysql native password method.
|
`allowNativePasswords=false` disallows the usage of MySQL native password method.
|
||||||
|
|
||||||
##### `allowOldPasswords`
|
##### `allowOldPasswords`
|
||||||
|
|
||||||
@@ -230,10 +233,10 @@ Please keep in mind, that param values must be [url.QueryEscape](https://golang.
|
|||||||
##### `maxAllowedPacket`
|
##### `maxAllowedPacket`
|
||||||
```
|
```
|
||||||
Type: decimal number
|
Type: decimal number
|
||||||
Default: 0
|
Default: 4194304
|
||||||
```
|
```
|
||||||
|
|
||||||
Max packet size allowed in bytes. Use `maxAllowedPacket=0` to automatically fetch the `max_allowed_packet` variable from server.
|
Max packet size allowed in bytes. The default value is 4 MiB and should be adjusted to match the server settings. `maxAllowedPacket=0` can be used to automatically fetch the `max_allowed_packet` variable from server *on every connection*.
|
||||||
|
|
||||||
##### `multiStatements`
|
##### `multiStatements`
|
||||||
|
|
||||||
@@ -267,7 +270,7 @@ Default: 0
|
|||||||
|
|
||||||
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"*.
|
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`
|
##### `rejectReadOnly`
|
||||||
|
|
||||||
```
|
```
|
||||||
Type: bool
|
Type: bool
|
||||||
@@ -275,11 +278,27 @@ Valid Values: true, false
|
|||||||
Default: false
|
Default: false
|
||||||
```
|
```
|
||||||
|
|
||||||
`strict=true` enables a driver-side strict mode in which MySQL warnings are treated as errors. This mode should not be used in production as it may lead to data corruption in certain situations.
|
|
||||||
|
|
||||||
A server-side strict mode, which is safe for production use, can be set via the [`sql_mode`](https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html) system variable.
|
`rejectReadOnly=true` causes the driver to reject read-only connections. This
|
||||||
|
is for a possible race condition during an automatic failover, where the mysql
|
||||||
|
client gets connected to a read-only replica after the failover.
|
||||||
|
|
||||||
|
Note that this should be a fairly rare case, as an automatic failover normally
|
||||||
|
happens when the primary is down, and the race condition shouldn't happen
|
||||||
|
unless it comes back up online as soon as the failover is kicked off. On the
|
||||||
|
other hand, when this happens, a MySQL application can get stuck on a
|
||||||
|
read-only connection until restarted. It is however fairly easy to reproduce,
|
||||||
|
for example, using a manual failover on AWS Aurora's MySQL-compatible cluster.
|
||||||
|
|
||||||
|
If you are not relying on read-only transactions to reject writes that aren't
|
||||||
|
supposed to happen, setting this on some MySQL providers (such as AWS Aurora)
|
||||||
|
is safer for failovers.
|
||||||
|
|
||||||
|
Note that ERROR 1290 can be returned for a `read-only` server and this option will
|
||||||
|
cause a retry for that error. However the same error number is used for some
|
||||||
|
other cases. You should ensure your application will never cause an ERROR 1290
|
||||||
|
except for `read-only` mode when enabling this option.
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
##### `timeout`
|
##### `timeout`
|
||||||
|
|
||||||
@@ -290,6 +309,7 @@ Default: OS default
|
|||||||
|
|
||||||
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"*.
|
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`
|
##### `tls`
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -300,6 +320,7 @@ 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`](https://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`
|
##### `writeTimeout`
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -318,9 +339,9 @@ Any other parameters are interpreted as system variables:
|
|||||||
* `<string_var>=%27<value>%27`: `SET <string_var>='<value>'`
|
* `<string_var>=%27<value>%27`: `SET <string_var>='<value>'`
|
||||||
|
|
||||||
Rules:
|
Rules:
|
||||||
* The values for string variables must be quoted with '
|
* The values for string variables must be quoted with `'`.
|
||||||
* The values must also be [url.QueryEscape](http://golang.org/pkg/net/url/#QueryEscape)'ed!
|
* The values must also be [url.QueryEscape](http://golang.org/pkg/net/url/#QueryEscape)'ed!
|
||||||
(which implies values of string variables must be wrapped with `%27`)
|
(which implies values of string variables must be wrapped with `%27`).
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
* `autocommit=1`: `SET autocommit=1`
|
* `autocommit=1`: `SET autocommit=1`
|
||||||
@@ -385,6 +406,13 @@ user:password@/
|
|||||||
### Connection pool and timeouts
|
### 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.
|
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.
|
||||||
|
|
||||||
|
## `ColumnType` Support
|
||||||
|
This driver supports the [`ColumnType` interface](https://golang.org/pkg/database/sql/#ColumnType) introduced in Go 1.8, with the exception of [`ColumnType.Length()`](https://golang.org/pkg/database/sql/#ColumnType.Length), which is currently not supported.
|
||||||
|
|
||||||
|
## `context.Context` Support
|
||||||
|
Go 1.8 added `database/sql` support for `context.Context`. This driver supports query timeouts and cancellation via contexts.
|
||||||
|
See [context support in the database/sql package](https://golang.org/doc/go1.8#database_sql) for more details.
|
||||||
|
|
||||||
|
|
||||||
### `LOAD DATA LOCAL INFILE` support
|
### `LOAD DATA LOCAL INFILE` support
|
||||||
For this feature you need direct access to the package. Therefore you must change the import path (no `_`):
|
For this feature you need direct access to the package. Therefore you must change the import path (no `_`):
|
||||||
@@ -400,7 +428,7 @@ See the [godoc of Go-MySQL-Driver](https://godoc.org/github.com/go-sql-driver/my
|
|||||||
|
|
||||||
|
|
||||||
### `time.Time` support
|
### `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.
|
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 program.
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
@@ -418,7 +446,6 @@ Version 1.0 of the driver recommended adding `&charset=utf8` (alias for `SET NAM
|
|||||||
|
|
||||||
See http://dev.mysql.com/doc/refman/5.7/en/charset-unicode.html for more details on MySQL's Unicode support.
|
See http://dev.mysql.com/doc/refman/5.7/en/charset-unicode.html for more details on MySQL's Unicode support.
|
||||||
|
|
||||||
|
|
||||||
## Testing / Development
|
## 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.
|
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.
|
||||||
|
|
||||||
@@ -437,13 +464,13 @@ Mozilla summarizes the license scope as follows:
|
|||||||
|
|
||||||
|
|
||||||
That means:
|
That means:
|
||||||
* You can **use** the **unchanged** source code both in private and commercially
|
* 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)
|
* 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**
|
* 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](https://www.mozilla.org/en-US/MPL/2.0/FAQ/) 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)
|
You can read the full terms here: [LICENSE](https://raw.github.com/go-sql-driver/mysql/master/LICENSE).
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|||||||
2
vendor/github.com/go-sql-driver/mysql/appengine.go
generated
vendored
2
vendor/github.com/go-sql-driver/mysql/appengine.go
generated
vendored
@@ -11,7 +11,7 @@
|
|||||||
package mysql
|
package mysql
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"appengine/cloudsql"
|
"google.golang.org/appengine/cloudsql"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
|||||||
1
vendor/github.com/go-sql-driver/mysql/collations.go
generated
vendored
1
vendor/github.com/go-sql-driver/mysql/collations.go
generated
vendored
@@ -9,6 +9,7 @@
|
|||||||
package mysql
|
package mysql
|
||||||
|
|
||||||
const defaultCollation = "utf8_general_ci"
|
const defaultCollation = "utf8_general_ci"
|
||||||
|
const binaryCollation = "binary"
|
||||||
|
|
||||||
// A list of available collations mapped to the internal ID.
|
// A list of available collations mapped to the internal ID.
|
||||||
// To update this map use the following MySQL query:
|
// To update this map use the following MySQL query:
|
||||||
|
|||||||
110
vendor/github.com/go-sql-driver/mysql/connection.go
generated
vendored
110
vendor/github.com/go-sql-driver/mysql/connection.go
generated
vendored
@@ -17,6 +17,16 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// a copy of context.Context for Go 1.7 and earlier
|
||||||
|
type mysqlContext interface {
|
||||||
|
Done() <-chan struct{}
|
||||||
|
Err() error
|
||||||
|
|
||||||
|
// defined in context.Context, but not used in this driver:
|
||||||
|
// Deadline() (deadline time.Time, ok bool)
|
||||||
|
// Value(key interface{}) interface{}
|
||||||
|
}
|
||||||
|
|
||||||
type mysqlConn struct {
|
type mysqlConn struct {
|
||||||
buf buffer
|
buf buffer
|
||||||
netConn net.Conn
|
netConn net.Conn
|
||||||
@@ -30,7 +40,14 @@ type mysqlConn struct {
|
|||||||
status statusFlag
|
status statusFlag
|
||||||
sequence uint8
|
sequence uint8
|
||||||
parseTime bool
|
parseTime bool
|
||||||
strict bool
|
|
||||||
|
// for context support (Go 1.8+)
|
||||||
|
watching bool
|
||||||
|
watcher chan<- mysqlContext
|
||||||
|
closech chan struct{}
|
||||||
|
finished chan<- struct{}
|
||||||
|
canceled atomicError // set non-nil if conn is canceled
|
||||||
|
closed atomicBool // set when conn is closed, before closech is closed
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handles parameters set in DSN after the connection is established
|
// Handles parameters set in DSN after the connection is established
|
||||||
@@ -63,22 +80,41 @@ func (mc *mysqlConn) handleParams() (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (mc *mysqlConn) markBadConn(err error) error {
|
||||||
|
if mc == nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err != errBadConnNoWrite {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return driver.ErrBadConn
|
||||||
|
}
|
||||||
|
|
||||||
func (mc *mysqlConn) Begin() (driver.Tx, error) {
|
func (mc *mysqlConn) Begin() (driver.Tx, error) {
|
||||||
if mc.netConn == nil {
|
return mc.begin(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mc *mysqlConn) begin(readOnly bool) (driver.Tx, error) {
|
||||||
|
if mc.closed.IsSet() {
|
||||||
errLog.Print(ErrInvalidConn)
|
errLog.Print(ErrInvalidConn)
|
||||||
return nil, driver.ErrBadConn
|
return nil, driver.ErrBadConn
|
||||||
}
|
}
|
||||||
err := mc.exec("START TRANSACTION")
|
var q string
|
||||||
|
if readOnly {
|
||||||
|
q = "START TRANSACTION READ ONLY"
|
||||||
|
} else {
|
||||||
|
q = "START TRANSACTION"
|
||||||
|
}
|
||||||
|
err := mc.exec(q)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return &mysqlTx{mc}, err
|
return &mysqlTx{mc}, err
|
||||||
}
|
}
|
||||||
|
return nil, mc.markBadConn(err)
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mc *mysqlConn) Close() (err error) {
|
func (mc *mysqlConn) Close() (err error) {
|
||||||
// Makes Close idempotent
|
// Makes Close idempotent
|
||||||
if mc.netConn != nil {
|
if !mc.closed.IsSet() {
|
||||||
err = mc.writeCommandPacket(comQuit)
|
err = mc.writeCommandPacket(comQuit)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,26 +128,39 @@ func (mc *mysqlConn) Close() (err error) {
|
|||||||
// is called before auth or on auth failure because MySQL will have already
|
// is called before auth or on auth failure because MySQL will have already
|
||||||
// closed the network connection.
|
// closed the network connection.
|
||||||
func (mc *mysqlConn) cleanup() {
|
func (mc *mysqlConn) cleanup() {
|
||||||
|
if !mc.closed.TrySet(true) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Makes cleanup idempotent
|
// Makes cleanup idempotent
|
||||||
if mc.netConn != nil {
|
close(mc.closech)
|
||||||
|
if mc.netConn == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
if err := mc.netConn.Close(); err != nil {
|
if err := mc.netConn.Close(); err != nil {
|
||||||
errLog.Print(err)
|
errLog.Print(err)
|
||||||
}
|
}
|
||||||
mc.netConn = nil
|
|
||||||
}
|
}
|
||||||
mc.cfg = nil
|
|
||||||
mc.buf.nc = nil
|
func (mc *mysqlConn) error() error {
|
||||||
|
if mc.closed.IsSet() {
|
||||||
|
if err := mc.canceled.Value(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return ErrInvalidConn
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mc *mysqlConn) Prepare(query string) (driver.Stmt, error) {
|
func (mc *mysqlConn) Prepare(query string) (driver.Stmt, error) {
|
||||||
if mc.netConn == nil {
|
if mc.closed.IsSet() {
|
||||||
errLog.Print(ErrInvalidConn)
|
errLog.Print(ErrInvalidConn)
|
||||||
return nil, driver.ErrBadConn
|
return nil, driver.ErrBadConn
|
||||||
}
|
}
|
||||||
// Send command
|
// Send command
|
||||||
err := mc.writeCommandPacketStr(comStmtPrepare, query)
|
err := mc.writeCommandPacketStr(comStmtPrepare, query)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, mc.markBadConn(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
stmt := &mysqlStmt{
|
stmt := &mysqlStmt{
|
||||||
@@ -145,7 +194,7 @@ func (mc *mysqlConn) interpolateParams(query string, args []driver.Value) (strin
|
|||||||
if buf == nil {
|
if buf == nil {
|
||||||
// can not take the buffer. Something must be wrong with the connection
|
// can not take the buffer. Something must be wrong with the connection
|
||||||
errLog.Print(ErrBusyBuffer)
|
errLog.Print(ErrBusyBuffer)
|
||||||
return "", driver.ErrBadConn
|
return "", ErrInvalidConn
|
||||||
}
|
}
|
||||||
buf = buf[:0]
|
buf = buf[:0]
|
||||||
argPos := 0
|
argPos := 0
|
||||||
@@ -258,7 +307,7 @@ func (mc *mysqlConn) interpolateParams(query string, args []driver.Value) (strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (mc *mysqlConn) Exec(query string, args []driver.Value) (driver.Result, error) {
|
func (mc *mysqlConn) Exec(query string, args []driver.Value) (driver.Result, error) {
|
||||||
if mc.netConn == nil {
|
if mc.closed.IsSet() {
|
||||||
errLog.Print(ErrInvalidConn)
|
errLog.Print(ErrInvalidConn)
|
||||||
return nil, driver.ErrBadConn
|
return nil, driver.ErrBadConn
|
||||||
}
|
}
|
||||||
@@ -272,7 +321,6 @@ func (mc *mysqlConn) Exec(query string, args []driver.Value) (driver.Result, err
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
query = prepared
|
query = prepared
|
||||||
args = nil
|
|
||||||
}
|
}
|
||||||
mc.affectedRows = 0
|
mc.affectedRows = 0
|
||||||
mc.insertId = 0
|
mc.insertId = 0
|
||||||
@@ -284,14 +332,14 @@ func (mc *mysqlConn) Exec(query string, args []driver.Value) (driver.Result, err
|
|||||||
insertId: int64(mc.insertId),
|
insertId: int64(mc.insertId),
|
||||||
}, err
|
}, err
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, mc.markBadConn(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Internal function to execute commands
|
// Internal function to execute commands
|
||||||
func (mc *mysqlConn) exec(query string) error {
|
func (mc *mysqlConn) exec(query string) error {
|
||||||
// Send command
|
// Send command
|
||||||
if err := mc.writeCommandPacketStr(comQuery, query); err != nil {
|
if err := mc.writeCommandPacketStr(comQuery, query); err != nil {
|
||||||
return err
|
return mc.markBadConn(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read Result
|
// Read Result
|
||||||
@@ -316,7 +364,11 @@ func (mc *mysqlConn) exec(query string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (mc *mysqlConn) Query(query string, args []driver.Value) (driver.Rows, error) {
|
func (mc *mysqlConn) Query(query string, args []driver.Value) (driver.Rows, error) {
|
||||||
if mc.netConn == nil {
|
return mc.query(query, args)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mc *mysqlConn) query(query string, args []driver.Value) (*textRows, error) {
|
||||||
|
if mc.closed.IsSet() {
|
||||||
errLog.Print(ErrInvalidConn)
|
errLog.Print(ErrInvalidConn)
|
||||||
return nil, driver.ErrBadConn
|
return nil, driver.ErrBadConn
|
||||||
}
|
}
|
||||||
@@ -330,7 +382,6 @@ func (mc *mysqlConn) Query(query string, args []driver.Value) (driver.Rows, erro
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
query = prepared
|
query = prepared
|
||||||
args = nil
|
|
||||||
}
|
}
|
||||||
// Send command
|
// Send command
|
||||||
err := mc.writeCommandPacketStr(comQuery, query)
|
err := mc.writeCommandPacketStr(comQuery, query)
|
||||||
@@ -352,12 +403,13 @@ func (mc *mysqlConn) Query(query string, args []driver.Value) (driver.Rows, erro
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Columns
|
// Columns
|
||||||
rows.rs.columns, err = mc.readColumns(resLen)
|
rows.rs.columns, err = mc.readColumns(resLen)
|
||||||
return rows, err
|
return rows, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, mc.markBadConn(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets the value of the given MySQL System Variable
|
// Gets the value of the given MySQL System Variable
|
||||||
@@ -389,3 +441,21 @@ func (mc *mysqlConn) getSystemVar(name string) ([]byte, error) {
|
|||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// finish is called when the query has canceled.
|
||||||
|
func (mc *mysqlConn) cancel(err error) {
|
||||||
|
mc.canceled.Set(err)
|
||||||
|
mc.cleanup()
|
||||||
|
}
|
||||||
|
|
||||||
|
// finish is called when the query has succeeded.
|
||||||
|
func (mc *mysqlConn) finish() {
|
||||||
|
if !mc.watching || mc.finished == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
select {
|
||||||
|
case mc.finished <- struct{}{}:
|
||||||
|
mc.watching = false
|
||||||
|
case <-mc.closech:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
202
vendor/github.com/go-sql-driver/mysql/connection_go18.go
generated
vendored
Normal file
202
vendor/github.com/go-sql-driver/mysql/connection_go18.go
generated
vendored
Normal file
@@ -0,0 +1,202 @@
|
|||||||
|
// 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/.
|
||||||
|
|
||||||
|
// +build go1.8
|
||||||
|
|
||||||
|
package mysql
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
"database/sql/driver"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Ping implements driver.Pinger interface
|
||||||
|
func (mc *mysqlConn) Ping(ctx context.Context) error {
|
||||||
|
if mc.closed.IsSet() {
|
||||||
|
errLog.Print(ErrInvalidConn)
|
||||||
|
return driver.ErrBadConn
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := mc.watchCancel(ctx); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer mc.finish()
|
||||||
|
|
||||||
|
if err := mc.writeCommandPacket(comPing); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err := mc.readResultOK(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// BeginTx implements driver.ConnBeginTx interface
|
||||||
|
func (mc *mysqlConn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, error) {
|
||||||
|
if err := mc.watchCancel(ctx); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer mc.finish()
|
||||||
|
|
||||||
|
if sql.IsolationLevel(opts.Isolation) != sql.LevelDefault {
|
||||||
|
level, err := mapIsolationLevel(opts.Isolation)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
err = mc.exec("SET TRANSACTION ISOLATION LEVEL " + level)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mc.begin(opts.ReadOnly)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mc *mysqlConn) QueryContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Rows, error) {
|
||||||
|
dargs, err := namedValueToValue(args)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := mc.watchCancel(ctx); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
rows, err := mc.query(query, dargs)
|
||||||
|
if err != nil {
|
||||||
|
mc.finish()
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
rows.finish = mc.finish
|
||||||
|
return rows, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mc *mysqlConn) ExecContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Result, error) {
|
||||||
|
dargs, err := namedValueToValue(args)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := mc.watchCancel(ctx); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer mc.finish()
|
||||||
|
|
||||||
|
return mc.Exec(query, dargs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mc *mysqlConn) PrepareContext(ctx context.Context, query string) (driver.Stmt, error) {
|
||||||
|
if err := mc.watchCancel(ctx); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
stmt, err := mc.Prepare(query)
|
||||||
|
mc.finish()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
default:
|
||||||
|
case <-ctx.Done():
|
||||||
|
stmt.Close()
|
||||||
|
return nil, ctx.Err()
|
||||||
|
}
|
||||||
|
return stmt, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (stmt *mysqlStmt) QueryContext(ctx context.Context, args []driver.NamedValue) (driver.Rows, error) {
|
||||||
|
dargs, err := namedValueToValue(args)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := stmt.mc.watchCancel(ctx); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
rows, err := stmt.query(dargs)
|
||||||
|
if err != nil {
|
||||||
|
stmt.mc.finish()
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
rows.finish = stmt.mc.finish
|
||||||
|
return rows, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (stmt *mysqlStmt) ExecContext(ctx context.Context, args []driver.NamedValue) (driver.Result, error) {
|
||||||
|
dargs, err := namedValueToValue(args)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := stmt.mc.watchCancel(ctx); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer stmt.mc.finish()
|
||||||
|
|
||||||
|
return stmt.Exec(dargs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mc *mysqlConn) watchCancel(ctx context.Context) error {
|
||||||
|
if mc.watching {
|
||||||
|
// Reach here if canceled,
|
||||||
|
// so the connection is already invalid
|
||||||
|
mc.cleanup()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
if ctx.Done() == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
mc.watching = true
|
||||||
|
select {
|
||||||
|
default:
|
||||||
|
case <-ctx.Done():
|
||||||
|
return ctx.Err()
|
||||||
|
}
|
||||||
|
if mc.watcher == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
mc.watcher <- ctx
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mc *mysqlConn) startWatcher() {
|
||||||
|
watcher := make(chan mysqlContext, 1)
|
||||||
|
mc.watcher = watcher
|
||||||
|
finished := make(chan struct{})
|
||||||
|
mc.finished = finished
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
var ctx mysqlContext
|
||||||
|
select {
|
||||||
|
case ctx = <-watcher:
|
||||||
|
case <-mc.closech:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
mc.cancel(ctx.Err())
|
||||||
|
case <-finished:
|
||||||
|
case <-mc.closech:
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mc *mysqlConn) CheckNamedValue(nv *driver.NamedValue) (err error) {
|
||||||
|
nv.Value, err = converter{}.ConvertValue(nv.Value)
|
||||||
|
return
|
||||||
|
}
|
||||||
9
vendor/github.com/go-sql-driver/mysql/const.go
generated
vendored
9
vendor/github.com/go-sql-driver/mysql/const.go
generated
vendored
@@ -9,7 +9,8 @@
|
|||||||
package mysql
|
package mysql
|
||||||
|
|
||||||
const (
|
const (
|
||||||
minProtocolVersion byte = 10
|
defaultMaxAllowedPacket = 4 << 20 // 4 MiB
|
||||||
|
minProtocolVersion = 10
|
||||||
maxPacketSize = 1<<24 - 1
|
maxPacketSize = 1<<24 - 1
|
||||||
timeFormat = "2006-01-02 15:04:05.999999"
|
timeFormat = "2006-01-02 15:04:05.999999"
|
||||||
)
|
)
|
||||||
@@ -87,8 +88,10 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// https://dev.mysql.com/doc/internals/en/com-query-response.html#packet-Protocol::ColumnType
|
// https://dev.mysql.com/doc/internals/en/com-query-response.html#packet-Protocol::ColumnType
|
||||||
|
type fieldType byte
|
||||||
|
|
||||||
const (
|
const (
|
||||||
fieldTypeDecimal byte = iota
|
fieldTypeDecimal fieldType = iota
|
||||||
fieldTypeTiny
|
fieldTypeTiny
|
||||||
fieldTypeShort
|
fieldTypeShort
|
||||||
fieldTypeLong
|
fieldTypeLong
|
||||||
@@ -107,7 +110,7 @@ const (
|
|||||||
fieldTypeBit
|
fieldTypeBit
|
||||||
)
|
)
|
||||||
const (
|
const (
|
||||||
fieldTypeJSON byte = iota + 0xf5
|
fieldTypeJSON fieldType = iota + 0xf5
|
||||||
fieldTypeNewDecimal
|
fieldTypeNewDecimal
|
||||||
fieldTypeEnum
|
fieldTypeEnum
|
||||||
fieldTypeSet
|
fieldTypeSet
|
||||||
|
|||||||
14
vendor/github.com/go-sql-driver/mysql/driver.go
generated
vendored
14
vendor/github.com/go-sql-driver/mysql/driver.go
generated
vendored
@@ -4,7 +4,7 @@
|
|||||||
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
// 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/.
|
// 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:
|
// The driver should be used via the database/sql package:
|
||||||
//
|
//
|
||||||
@@ -22,6 +22,11 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// watcher interface is used for context support (From Go 1.8)
|
||||||
|
type watcher interface {
|
||||||
|
startWatcher()
|
||||||
|
}
|
||||||
|
|
||||||
// MySQLDriver is exported to make the driver directly accessible.
|
// MySQLDriver is exported to make the driver directly accessible.
|
||||||
// In general the driver is used via the database/sql package.
|
// In general the driver is used via the database/sql package.
|
||||||
type MySQLDriver struct{}
|
type MySQLDriver struct{}
|
||||||
@@ -52,13 +57,13 @@ func (d MySQLDriver) Open(dsn string) (driver.Conn, error) {
|
|||||||
mc := &mysqlConn{
|
mc := &mysqlConn{
|
||||||
maxAllowedPacket: maxPacketSize,
|
maxAllowedPacket: maxPacketSize,
|
||||||
maxWriteSize: maxPacketSize - 1,
|
maxWriteSize: maxPacketSize - 1,
|
||||||
|
closech: make(chan struct{}),
|
||||||
}
|
}
|
||||||
mc.cfg, err = ParseDSN(dsn)
|
mc.cfg, err = ParseDSN(dsn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
mc.parseTime = mc.cfg.ParseTime
|
mc.parseTime = mc.cfg.ParseTime
|
||||||
mc.strict = mc.cfg.Strict
|
|
||||||
|
|
||||||
// Connect to Server
|
// Connect to Server
|
||||||
if dial, ok := dials[mc.cfg.Net]; ok {
|
if dial, ok := dials[mc.cfg.Net]; ok {
|
||||||
@@ -81,6 +86,11 @@ func (d MySQLDriver) Open(dsn string) (driver.Conn, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Call startWatcher for context support (From Go 1.8)
|
||||||
|
if s, ok := interface{}(mc).(watcher); ok {
|
||||||
|
s.startWatcher()
|
||||||
|
}
|
||||||
|
|
||||||
mc.buf = newBuffer(mc.netConn)
|
mc.buf = newBuffer(mc.netConn)
|
||||||
|
|
||||||
// Set I/O timeouts
|
// Set I/O timeouts
|
||||||
|
|||||||
132
vendor/github.com/go-sql-driver/mysql/dsn.go
generated
vendored
132
vendor/github.com/go-sql-driver/mysql/dsn.go
generated
vendored
@@ -15,6 +15,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@@ -27,7 +28,9 @@ var (
|
|||||||
errInvalidDSNUnsafeCollation = errors.New("invalid DSN: interpolateParams can not be used with unsafe collations")
|
errInvalidDSNUnsafeCollation = errors.New("invalid DSN: interpolateParams can not be used with unsafe collations")
|
||||||
)
|
)
|
||||||
|
|
||||||
// Config is a configuration parsed from a DSN string
|
// Config is a configuration parsed from a DSN string.
|
||||||
|
// If a new Config is created instead of being parsed from a DSN string,
|
||||||
|
// the NewConfig function should be used, which sets default values.
|
||||||
type Config struct {
|
type Config struct {
|
||||||
User string // Username
|
User string // Username
|
||||||
Passwd string // Password (requires User)
|
Passwd string // Password (requires User)
|
||||||
@@ -53,7 +56,54 @@ type Config struct {
|
|||||||
InterpolateParams bool // Interpolate placeholders into query string
|
InterpolateParams bool // Interpolate placeholders into query string
|
||||||
MultiStatements bool // Allow multiple statements in one query
|
MultiStatements bool // Allow multiple statements in one query
|
||||||
ParseTime bool // Parse time values to time.Time
|
ParseTime bool // Parse time values to time.Time
|
||||||
Strict bool // Return warnings as errors
|
RejectReadOnly bool // Reject read-only connections
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewConfig creates a new Config and sets default values.
|
||||||
|
func NewConfig() *Config {
|
||||||
|
return &Config{
|
||||||
|
Collation: defaultCollation,
|
||||||
|
Loc: time.UTC,
|
||||||
|
MaxAllowedPacket: defaultMaxAllowedPacket,
|
||||||
|
AllowNativePasswords: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *Config) normalize() error {
|
||||||
|
if cfg.InterpolateParams && unsafeCollations[cfg.Collation] {
|
||||||
|
return 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 errors.New("default addr for network '" + cfg.Net + "' unknown")
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if cfg.Net == "tcp" {
|
||||||
|
cfg.Addr = ensureHavePort(cfg.Addr)
|
||||||
|
}
|
||||||
|
|
||||||
|
if cfg.tls != nil {
|
||||||
|
if cfg.tls.ServerName == "" && !cfg.tls.InsecureSkipVerify {
|
||||||
|
host, _, err := net.SplitHostPort(cfg.Addr)
|
||||||
|
if err == nil {
|
||||||
|
cfg.tls.ServerName = host
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// FormatDSN formats the given Config into a DSN string which can be passed to
|
// FormatDSN formats the given Config into a DSN string which can be passed to
|
||||||
@@ -102,12 +152,12 @@ func (cfg *Config) FormatDSN() string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if cfg.AllowNativePasswords {
|
if !cfg.AllowNativePasswords {
|
||||||
if hasParam {
|
if hasParam {
|
||||||
buf.WriteString("&allowNativePasswords=true")
|
buf.WriteString("&allowNativePasswords=false")
|
||||||
} else {
|
} else {
|
||||||
hasParam = true
|
hasParam = true
|
||||||
buf.WriteString("?allowNativePasswords=true")
|
buf.WriteString("?allowNativePasswords=false")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -195,12 +245,12 @@ func (cfg *Config) FormatDSN() string {
|
|||||||
buf.WriteString(cfg.ReadTimeout.String())
|
buf.WriteString(cfg.ReadTimeout.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
if cfg.Strict {
|
if cfg.RejectReadOnly {
|
||||||
if hasParam {
|
if hasParam {
|
||||||
buf.WriteString("&strict=true")
|
buf.WriteString("&rejectReadOnly=true")
|
||||||
} else {
|
} else {
|
||||||
hasParam = true
|
hasParam = true
|
||||||
buf.WriteString("?strict=true")
|
buf.WriteString("?rejectReadOnly=true")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,7 +284,7 @@ func (cfg *Config) FormatDSN() string {
|
|||||||
buf.WriteString(cfg.WriteTimeout.String())
|
buf.WriteString(cfg.WriteTimeout.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
if cfg.MaxAllowedPacket > 0 {
|
if cfg.MaxAllowedPacket != defaultMaxAllowedPacket {
|
||||||
if hasParam {
|
if hasParam {
|
||||||
buf.WriteString("&maxAllowedPacket=")
|
buf.WriteString("&maxAllowedPacket=")
|
||||||
} else {
|
} else {
|
||||||
@@ -247,7 +297,12 @@ func (cfg *Config) FormatDSN() string {
|
|||||||
|
|
||||||
// other params
|
// other params
|
||||||
if cfg.Params != nil {
|
if cfg.Params != nil {
|
||||||
for param, value := range cfg.Params {
|
var params []string
|
||||||
|
for param := range cfg.Params {
|
||||||
|
params = append(params, param)
|
||||||
|
}
|
||||||
|
sort.Strings(params)
|
||||||
|
for _, param := range params {
|
||||||
if hasParam {
|
if hasParam {
|
||||||
buf.WriteByte('&')
|
buf.WriteByte('&')
|
||||||
} else {
|
} else {
|
||||||
@@ -257,7 +312,7 @@ func (cfg *Config) FormatDSN() string {
|
|||||||
|
|
||||||
buf.WriteString(param)
|
buf.WriteString(param)
|
||||||
buf.WriteByte('=')
|
buf.WriteByte('=')
|
||||||
buf.WriteString(url.QueryEscape(value))
|
buf.WriteString(url.QueryEscape(cfg.Params[param]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -267,10 +322,7 @@ func (cfg *Config) FormatDSN() string {
|
|||||||
// ParseDSN parses the DSN string to a Config
|
// ParseDSN parses the DSN string to a Config
|
||||||
func ParseDSN(dsn string) (cfg *Config, err error) {
|
func ParseDSN(dsn string) (cfg *Config, err error) {
|
||||||
// New config with some default values
|
// New config with some default values
|
||||||
cfg = &Config{
|
cfg = NewConfig()
|
||||||
Loc: time.UTC,
|
|
||||||
Collation: defaultCollation,
|
|
||||||
}
|
|
||||||
|
|
||||||
// [user[:password]@][net[(addr)]]/dbname[?param1=value1¶mN=valueN]
|
// [user[:password]@][net[(addr)]]/dbname[?param1=value1¶mN=valueN]
|
||||||
// Find the last '/' (since the password or the net addr might contain a '/')
|
// Find the last '/' (since the password or the net addr might contain a '/')
|
||||||
@@ -338,28 +390,9 @@ func ParseDSN(dsn string) (cfg *Config, err error) {
|
|||||||
return nil, errInvalidDSNNoSlash
|
return nil, errInvalidDSNNoSlash
|
||||||
}
|
}
|
||||||
|
|
||||||
if cfg.InterpolateParams && unsafeCollations[cfg.Collation] {
|
if err = cfg.normalize(); err != nil {
|
||||||
return nil, errInvalidDSNUnsafeCollation
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -374,7 +407,6 @@ func parseDSNParams(cfg *Config, params string) (err error) {
|
|||||||
|
|
||||||
// cfg params
|
// cfg params
|
||||||
switch value := param[1]; param[0] {
|
switch value := param[1]; param[0] {
|
||||||
|
|
||||||
// Disable INFILE whitelist / enable all files
|
// Disable INFILE whitelist / enable all files
|
||||||
case "allowAllFiles":
|
case "allowAllFiles":
|
||||||
var isBool bool
|
var isBool bool
|
||||||
@@ -472,14 +504,18 @@ func parseDSNParams(cfg *Config, params string) (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Strict mode
|
// Reject read-only connections
|
||||||
case "strict":
|
case "rejectReadOnly":
|
||||||
var isBool bool
|
var isBool bool
|
||||||
cfg.Strict, isBool = readBool(value)
|
cfg.RejectReadOnly, isBool = readBool(value)
|
||||||
if !isBool {
|
if !isBool {
|
||||||
return errors.New("invalid bool value: " + value)
|
return errors.New("invalid bool value: " + value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Strict mode
|
||||||
|
case "strict":
|
||||||
|
panic("strict mode has been removed. See https://github.com/go-sql-driver/mysql/wiki/strict-mode")
|
||||||
|
|
||||||
// Dial Timeout
|
// Dial Timeout
|
||||||
case "timeout":
|
case "timeout":
|
||||||
cfg.Timeout, err = time.ParseDuration(value)
|
cfg.Timeout, err = time.ParseDuration(value)
|
||||||
@@ -506,14 +542,7 @@ func parseDSNParams(cfg *Config, params string) (err error) {
|
|||||||
return fmt.Errorf("invalid value for TLS config name: %v", err)
|
return fmt.Errorf("invalid value for TLS config name: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if tlsConfig, ok := tlsConfigRegister[name]; ok {
|
if tlsConfig := getTLSConfigClone(name); tlsConfig != nil {
|
||||||
if len(tlsConfig.ServerName) == 0 && !tlsConfig.InsecureSkipVerify {
|
|
||||||
host, _, err := net.SplitHostPort(cfg.Addr)
|
|
||||||
if err == nil {
|
|
||||||
tlsConfig.ServerName = host
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cfg.TLSConfig = name
|
cfg.TLSConfig = name
|
||||||
cfg.tls = tlsConfig
|
cfg.tls = tlsConfig
|
||||||
} else {
|
} else {
|
||||||
@@ -546,3 +575,10 @@ func parseDSNParams(cfg *Config, params string) (err error) {
|
|||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ensureHavePort(addr string) string {
|
||||||
|
if _, _, err := net.SplitHostPort(addr); err != nil {
|
||||||
|
return net.JoinHostPort(addr, "3306")
|
||||||
|
}
|
||||||
|
return addr
|
||||||
|
}
|
||||||
|
|||||||
79
vendor/github.com/go-sql-driver/mysql/errors.go
generated
vendored
79
vendor/github.com/go-sql-driver/mysql/errors.go
generated
vendored
@@ -9,10 +9,8 @@
|
|||||||
package mysql
|
package mysql
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql/driver"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
@@ -31,6 +29,12 @@ var (
|
|||||||
ErrPktSyncMul = errors.New("commands out of sync. Did you run multiple statements at once?")
|
ErrPktSyncMul = errors.New("commands out of sync. Did you run multiple statements at once?")
|
||||||
ErrPktTooLarge = errors.New("packet for query is too large. Try adjusting the 'max_allowed_packet' variable on the server")
|
ErrPktTooLarge = errors.New("packet for query is too large. Try adjusting the 'max_allowed_packet' variable on the server")
|
||||||
ErrBusyBuffer = errors.New("busy buffer")
|
ErrBusyBuffer = errors.New("busy buffer")
|
||||||
|
|
||||||
|
// errBadConnNoWrite is used for connection errors where nothing was sent to the database yet.
|
||||||
|
// If this happens first in a function starting a database interaction, it should be replaced by driver.ErrBadConn
|
||||||
|
// to trigger a resend.
|
||||||
|
// See https://github.com/go-sql-driver/mysql/pull/302
|
||||||
|
errBadConnNoWrite = errors.New("bad connection")
|
||||||
)
|
)
|
||||||
|
|
||||||
var errLog = Logger(log.New(os.Stderr, "[mysql] ", log.Ldate|log.Ltime|log.Lshortfile))
|
var errLog = Logger(log.New(os.Stderr, "[mysql] ", log.Ldate|log.Ltime|log.Lshortfile))
|
||||||
@@ -59,74 +63,3 @@ type MySQLError struct {
|
|||||||
func (me *MySQLError) Error() string {
|
func (me *MySQLError) Error() string {
|
||||||
return fmt.Sprintf("Error %d: %s", me.Number, me.Message)
|
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
194
vendor/github.com/go-sql-driver/mysql/fields.go
generated
vendored
Normal file
194
vendor/github.com/go-sql-driver/mysql/fields.go
generated
vendored
Normal file
@@ -0,0 +1,194 @@
|
|||||||
|
// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
|
||||||
|
//
|
||||||
|
// Copyright 2017 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"
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (mf *mysqlField) typeDatabaseName() string {
|
||||||
|
switch mf.fieldType {
|
||||||
|
case fieldTypeBit:
|
||||||
|
return "BIT"
|
||||||
|
case fieldTypeBLOB:
|
||||||
|
if mf.charSet != collations[binaryCollation] {
|
||||||
|
return "TEXT"
|
||||||
|
}
|
||||||
|
return "BLOB"
|
||||||
|
case fieldTypeDate:
|
||||||
|
return "DATE"
|
||||||
|
case fieldTypeDateTime:
|
||||||
|
return "DATETIME"
|
||||||
|
case fieldTypeDecimal:
|
||||||
|
return "DECIMAL"
|
||||||
|
case fieldTypeDouble:
|
||||||
|
return "DOUBLE"
|
||||||
|
case fieldTypeEnum:
|
||||||
|
return "ENUM"
|
||||||
|
case fieldTypeFloat:
|
||||||
|
return "FLOAT"
|
||||||
|
case fieldTypeGeometry:
|
||||||
|
return "GEOMETRY"
|
||||||
|
case fieldTypeInt24:
|
||||||
|
return "MEDIUMINT"
|
||||||
|
case fieldTypeJSON:
|
||||||
|
return "JSON"
|
||||||
|
case fieldTypeLong:
|
||||||
|
return "INT"
|
||||||
|
case fieldTypeLongBLOB:
|
||||||
|
if mf.charSet != collations[binaryCollation] {
|
||||||
|
return "LONGTEXT"
|
||||||
|
}
|
||||||
|
return "LONGBLOB"
|
||||||
|
case fieldTypeLongLong:
|
||||||
|
return "BIGINT"
|
||||||
|
case fieldTypeMediumBLOB:
|
||||||
|
if mf.charSet != collations[binaryCollation] {
|
||||||
|
return "MEDIUMTEXT"
|
||||||
|
}
|
||||||
|
return "MEDIUMBLOB"
|
||||||
|
case fieldTypeNewDate:
|
||||||
|
return "DATE"
|
||||||
|
case fieldTypeNewDecimal:
|
||||||
|
return "DECIMAL"
|
||||||
|
case fieldTypeNULL:
|
||||||
|
return "NULL"
|
||||||
|
case fieldTypeSet:
|
||||||
|
return "SET"
|
||||||
|
case fieldTypeShort:
|
||||||
|
return "SMALLINT"
|
||||||
|
case fieldTypeString:
|
||||||
|
if mf.charSet == collations[binaryCollation] {
|
||||||
|
return "BINARY"
|
||||||
|
}
|
||||||
|
return "CHAR"
|
||||||
|
case fieldTypeTime:
|
||||||
|
return "TIME"
|
||||||
|
case fieldTypeTimestamp:
|
||||||
|
return "TIMESTAMP"
|
||||||
|
case fieldTypeTiny:
|
||||||
|
return "TINYINT"
|
||||||
|
case fieldTypeTinyBLOB:
|
||||||
|
if mf.charSet != collations[binaryCollation] {
|
||||||
|
return "TINYTEXT"
|
||||||
|
}
|
||||||
|
return "TINYBLOB"
|
||||||
|
case fieldTypeVarChar:
|
||||||
|
if mf.charSet == collations[binaryCollation] {
|
||||||
|
return "VARBINARY"
|
||||||
|
}
|
||||||
|
return "VARCHAR"
|
||||||
|
case fieldTypeVarString:
|
||||||
|
if mf.charSet == collations[binaryCollation] {
|
||||||
|
return "VARBINARY"
|
||||||
|
}
|
||||||
|
return "VARCHAR"
|
||||||
|
case fieldTypeYear:
|
||||||
|
return "YEAR"
|
||||||
|
default:
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
scanTypeFloat32 = reflect.TypeOf(float32(0))
|
||||||
|
scanTypeFloat64 = reflect.TypeOf(float64(0))
|
||||||
|
scanTypeInt8 = reflect.TypeOf(int8(0))
|
||||||
|
scanTypeInt16 = reflect.TypeOf(int16(0))
|
||||||
|
scanTypeInt32 = reflect.TypeOf(int32(0))
|
||||||
|
scanTypeInt64 = reflect.TypeOf(int64(0))
|
||||||
|
scanTypeNullFloat = reflect.TypeOf(sql.NullFloat64{})
|
||||||
|
scanTypeNullInt = reflect.TypeOf(sql.NullInt64{})
|
||||||
|
scanTypeNullTime = reflect.TypeOf(NullTime{})
|
||||||
|
scanTypeUint8 = reflect.TypeOf(uint8(0))
|
||||||
|
scanTypeUint16 = reflect.TypeOf(uint16(0))
|
||||||
|
scanTypeUint32 = reflect.TypeOf(uint32(0))
|
||||||
|
scanTypeUint64 = reflect.TypeOf(uint64(0))
|
||||||
|
scanTypeRawBytes = reflect.TypeOf(sql.RawBytes{})
|
||||||
|
scanTypeUnknown = reflect.TypeOf(new(interface{}))
|
||||||
|
)
|
||||||
|
|
||||||
|
type mysqlField struct {
|
||||||
|
tableName string
|
||||||
|
name string
|
||||||
|
length uint32
|
||||||
|
flags fieldFlag
|
||||||
|
fieldType fieldType
|
||||||
|
decimals byte
|
||||||
|
charSet uint8
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mf *mysqlField) scanType() reflect.Type {
|
||||||
|
switch mf.fieldType {
|
||||||
|
case fieldTypeTiny:
|
||||||
|
if mf.flags&flagNotNULL != 0 {
|
||||||
|
if mf.flags&flagUnsigned != 0 {
|
||||||
|
return scanTypeUint8
|
||||||
|
}
|
||||||
|
return scanTypeInt8
|
||||||
|
}
|
||||||
|
return scanTypeNullInt
|
||||||
|
|
||||||
|
case fieldTypeShort, fieldTypeYear:
|
||||||
|
if mf.flags&flagNotNULL != 0 {
|
||||||
|
if mf.flags&flagUnsigned != 0 {
|
||||||
|
return scanTypeUint16
|
||||||
|
}
|
||||||
|
return scanTypeInt16
|
||||||
|
}
|
||||||
|
return scanTypeNullInt
|
||||||
|
|
||||||
|
case fieldTypeInt24, fieldTypeLong:
|
||||||
|
if mf.flags&flagNotNULL != 0 {
|
||||||
|
if mf.flags&flagUnsigned != 0 {
|
||||||
|
return scanTypeUint32
|
||||||
|
}
|
||||||
|
return scanTypeInt32
|
||||||
|
}
|
||||||
|
return scanTypeNullInt
|
||||||
|
|
||||||
|
case fieldTypeLongLong:
|
||||||
|
if mf.flags&flagNotNULL != 0 {
|
||||||
|
if mf.flags&flagUnsigned != 0 {
|
||||||
|
return scanTypeUint64
|
||||||
|
}
|
||||||
|
return scanTypeInt64
|
||||||
|
}
|
||||||
|
return scanTypeNullInt
|
||||||
|
|
||||||
|
case fieldTypeFloat:
|
||||||
|
if mf.flags&flagNotNULL != 0 {
|
||||||
|
return scanTypeFloat32
|
||||||
|
}
|
||||||
|
return scanTypeNullFloat
|
||||||
|
|
||||||
|
case fieldTypeDouble:
|
||||||
|
if mf.flags&flagNotNULL != 0 {
|
||||||
|
return scanTypeFloat64
|
||||||
|
}
|
||||||
|
return scanTypeNullFloat
|
||||||
|
|
||||||
|
case fieldTypeDecimal, fieldTypeNewDecimal, fieldTypeVarChar,
|
||||||
|
fieldTypeBit, fieldTypeEnum, fieldTypeSet, fieldTypeTinyBLOB,
|
||||||
|
fieldTypeMediumBLOB, fieldTypeLongBLOB, fieldTypeBLOB,
|
||||||
|
fieldTypeVarString, fieldTypeString, fieldTypeGeometry, fieldTypeJSON,
|
||||||
|
fieldTypeTime:
|
||||||
|
return scanTypeRawBytes
|
||||||
|
|
||||||
|
case fieldTypeDate, fieldTypeNewDate,
|
||||||
|
fieldTypeTimestamp, fieldTypeDateTime:
|
||||||
|
// NullTime is always returned for more consistent behavior as it can
|
||||||
|
// handle both cases of parseTime regardless if the field is nullable.
|
||||||
|
return scanTypeNullTime
|
||||||
|
|
||||||
|
default:
|
||||||
|
return scanTypeUnknown
|
||||||
|
}
|
||||||
|
}
|
||||||
3
vendor/github.com/go-sql-driver/mysql/infile.go
generated
vendored
3
vendor/github.com/go-sql-driver/mysql/infile.go
generated
vendored
@@ -147,7 +147,8 @@ func (mc *mysqlConn) handleInFileRequest(name string) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// send content packets
|
// send content packets
|
||||||
if err == nil {
|
// if packetSize == 0, the Reader contains no data
|
||||||
|
if err == nil && packetSize > 0 {
|
||||||
data := make([]byte, 4+packetSize)
|
data := make([]byte, 4+packetSize)
|
||||||
var n int
|
var n int
|
||||||
for err == nil {
|
for err == nil {
|
||||||
|
|||||||
146
vendor/github.com/go-sql-driver/mysql/packets.go
generated
vendored
146
vendor/github.com/go-sql-driver/mysql/packets.go
generated
vendored
@@ -30,9 +30,12 @@ func (mc *mysqlConn) readPacket() ([]byte, error) {
|
|||||||
// read packet header
|
// read packet header
|
||||||
data, err := mc.buf.readNext(4)
|
data, err := mc.buf.readNext(4)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if cerr := mc.canceled.Value(); cerr != nil {
|
||||||
|
return nil, cerr
|
||||||
|
}
|
||||||
errLog.Print(err)
|
errLog.Print(err)
|
||||||
mc.Close()
|
mc.Close()
|
||||||
return nil, driver.ErrBadConn
|
return nil, ErrInvalidConn
|
||||||
}
|
}
|
||||||
|
|
||||||
// packet length [24 bit]
|
// packet length [24 bit]
|
||||||
@@ -54,7 +57,7 @@ func (mc *mysqlConn) readPacket() ([]byte, error) {
|
|||||||
if prevData == nil {
|
if prevData == nil {
|
||||||
errLog.Print(ErrMalformPkt)
|
errLog.Print(ErrMalformPkt)
|
||||||
mc.Close()
|
mc.Close()
|
||||||
return nil, driver.ErrBadConn
|
return nil, ErrInvalidConn
|
||||||
}
|
}
|
||||||
|
|
||||||
return prevData, nil
|
return prevData, nil
|
||||||
@@ -63,9 +66,12 @@ func (mc *mysqlConn) readPacket() ([]byte, error) {
|
|||||||
// read packet body [pktLen bytes]
|
// read packet body [pktLen bytes]
|
||||||
data, err = mc.buf.readNext(pktLen)
|
data, err = mc.buf.readNext(pktLen)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if cerr := mc.canceled.Value(); cerr != nil {
|
||||||
|
return nil, cerr
|
||||||
|
}
|
||||||
errLog.Print(err)
|
errLog.Print(err)
|
||||||
mc.Close()
|
mc.Close()
|
||||||
return nil, driver.ErrBadConn
|
return nil, ErrInvalidConn
|
||||||
}
|
}
|
||||||
|
|
||||||
// return data if this was the last packet
|
// return data if this was the last packet
|
||||||
@@ -125,11 +131,20 @@ func (mc *mysqlConn) writePacket(data []byte) error {
|
|||||||
|
|
||||||
// Handle error
|
// Handle error
|
||||||
if err == nil { // n != len(data)
|
if err == nil { // n != len(data)
|
||||||
|
mc.cleanup()
|
||||||
errLog.Print(ErrMalformPkt)
|
errLog.Print(ErrMalformPkt)
|
||||||
} else {
|
} else {
|
||||||
|
if cerr := mc.canceled.Value(); cerr != nil {
|
||||||
|
return cerr
|
||||||
|
}
|
||||||
|
if n == 0 && pktLen == len(data)-4 {
|
||||||
|
// only for the first loop iteration when nothing was written yet
|
||||||
|
return errBadConnNoWrite
|
||||||
|
}
|
||||||
|
mc.cleanup()
|
||||||
errLog.Print(err)
|
errLog.Print(err)
|
||||||
}
|
}
|
||||||
return driver.ErrBadConn
|
return ErrInvalidConn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -263,7 +278,7 @@ func (mc *mysqlConn) writeAuthPacket(cipher []byte) error {
|
|||||||
if data == nil {
|
if data == nil {
|
||||||
// can not take the buffer. Something must be wrong with the connection
|
// can not take the buffer. Something must be wrong with the connection
|
||||||
errLog.Print(ErrBusyBuffer)
|
errLog.Print(ErrBusyBuffer)
|
||||||
return driver.ErrBadConn
|
return errBadConnNoWrite
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClientFlags [32 bit]
|
// ClientFlags [32 bit]
|
||||||
@@ -341,7 +356,9 @@ func (mc *mysqlConn) writeAuthPacket(cipher []byte) error {
|
|||||||
// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::AuthSwitchResponse
|
// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::AuthSwitchResponse
|
||||||
func (mc *mysqlConn) writeOldAuthPacket(cipher []byte) error {
|
func (mc *mysqlConn) writeOldAuthPacket(cipher []byte) error {
|
||||||
// User password
|
// User password
|
||||||
scrambleBuff := scrambleOldPassword(cipher, []byte(mc.cfg.Passwd))
|
// https://dev.mysql.com/doc/internals/en/old-password-authentication.html
|
||||||
|
// Old password authentication only need and will need 8-byte challenge.
|
||||||
|
scrambleBuff := scrambleOldPassword(cipher[:8], []byte(mc.cfg.Passwd))
|
||||||
|
|
||||||
// Calculate the packet length and add a tailing 0
|
// Calculate the packet length and add a tailing 0
|
||||||
pktLen := len(scrambleBuff) + 1
|
pktLen := len(scrambleBuff) + 1
|
||||||
@@ -349,7 +366,7 @@ func (mc *mysqlConn) writeOldAuthPacket(cipher []byte) error {
|
|||||||
if data == nil {
|
if data == nil {
|
||||||
// can not take the buffer. Something must be wrong with the connection
|
// can not take the buffer. Something must be wrong with the connection
|
||||||
errLog.Print(ErrBusyBuffer)
|
errLog.Print(ErrBusyBuffer)
|
||||||
return driver.ErrBadConn
|
return errBadConnNoWrite
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the scrambled password [null terminated string]
|
// Add the scrambled password [null terminated string]
|
||||||
@@ -368,7 +385,7 @@ func (mc *mysqlConn) writeClearAuthPacket() error {
|
|||||||
if data == nil {
|
if data == nil {
|
||||||
// can not take the buffer. Something must be wrong with the connection
|
// can not take the buffer. Something must be wrong with the connection
|
||||||
errLog.Print(ErrBusyBuffer)
|
errLog.Print(ErrBusyBuffer)
|
||||||
return driver.ErrBadConn
|
return errBadConnNoWrite
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the clear password [null terminated string]
|
// Add the clear password [null terminated string]
|
||||||
@@ -381,7 +398,9 @@ func (mc *mysqlConn) writeClearAuthPacket() error {
|
|||||||
// Native password authentication method
|
// Native password authentication method
|
||||||
// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::AuthSwitchResponse
|
// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::AuthSwitchResponse
|
||||||
func (mc *mysqlConn) writeNativeAuthPacket(cipher []byte) error {
|
func (mc *mysqlConn) writeNativeAuthPacket(cipher []byte) error {
|
||||||
scrambleBuff := scramblePassword(cipher, []byte(mc.cfg.Passwd))
|
// https://dev.mysql.com/doc/internals/en/secure-password-authentication.html
|
||||||
|
// Native password authentication only need and will need 20-byte challenge.
|
||||||
|
scrambleBuff := scramblePassword(cipher[0:20], []byte(mc.cfg.Passwd))
|
||||||
|
|
||||||
// Calculate the packet length and add a tailing 0
|
// Calculate the packet length and add a tailing 0
|
||||||
pktLen := len(scrambleBuff)
|
pktLen := len(scrambleBuff)
|
||||||
@@ -389,7 +408,7 @@ func (mc *mysqlConn) writeNativeAuthPacket(cipher []byte) error {
|
|||||||
if data == nil {
|
if data == nil {
|
||||||
// can not take the buffer. Something must be wrong with the connection
|
// can not take the buffer. Something must be wrong with the connection
|
||||||
errLog.Print(ErrBusyBuffer)
|
errLog.Print(ErrBusyBuffer)
|
||||||
return driver.ErrBadConn
|
return errBadConnNoWrite
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the scramble
|
// Add the scramble
|
||||||
@@ -410,7 +429,7 @@ func (mc *mysqlConn) writeCommandPacket(command byte) error {
|
|||||||
if data == nil {
|
if data == nil {
|
||||||
// can not take the buffer. Something must be wrong with the connection
|
// can not take the buffer. Something must be wrong with the connection
|
||||||
errLog.Print(ErrBusyBuffer)
|
errLog.Print(ErrBusyBuffer)
|
||||||
return driver.ErrBadConn
|
return errBadConnNoWrite
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add command byte
|
// Add command byte
|
||||||
@@ -429,7 +448,7 @@ func (mc *mysqlConn) writeCommandPacketStr(command byte, arg string) error {
|
|||||||
if data == nil {
|
if data == nil {
|
||||||
// can not take the buffer. Something must be wrong with the connection
|
// can not take the buffer. Something must be wrong with the connection
|
||||||
errLog.Print(ErrBusyBuffer)
|
errLog.Print(ErrBusyBuffer)
|
||||||
return driver.ErrBadConn
|
return errBadConnNoWrite
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add command byte
|
// Add command byte
|
||||||
@@ -450,7 +469,7 @@ func (mc *mysqlConn) writeCommandPacketUint32(command byte, arg uint32) error {
|
|||||||
if data == nil {
|
if data == nil {
|
||||||
// can not take the buffer. Something must be wrong with the connection
|
// can not take the buffer. Something must be wrong with the connection
|
||||||
errLog.Print(ErrBusyBuffer)
|
errLog.Print(ErrBusyBuffer)
|
||||||
return driver.ErrBadConn
|
return errBadConnNoWrite
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add command byte
|
// Add command byte
|
||||||
@@ -484,24 +503,25 @@ func (mc *mysqlConn) readResultOK() ([]byte, error) {
|
|||||||
if len(data) > 1 {
|
if len(data) > 1 {
|
||||||
pluginEndIndex := bytes.IndexByte(data, 0x00)
|
pluginEndIndex := bytes.IndexByte(data, 0x00)
|
||||||
plugin := string(data[1:pluginEndIndex])
|
plugin := string(data[1:pluginEndIndex])
|
||||||
cipher := data[pluginEndIndex+1 : len(data)-1]
|
cipher := data[pluginEndIndex+1:]
|
||||||
|
|
||||||
if plugin == "mysql_old_password" {
|
switch plugin {
|
||||||
|
case "mysql_old_password":
|
||||||
// using old_passwords
|
// using old_passwords
|
||||||
return cipher, ErrOldPassword
|
return cipher, ErrOldPassword
|
||||||
} else if plugin == "mysql_clear_password" {
|
case "mysql_clear_password":
|
||||||
// using clear text password
|
// using clear text password
|
||||||
return cipher, ErrCleartextPassword
|
return cipher, ErrCleartextPassword
|
||||||
} else if plugin == "mysql_native_password" {
|
case "mysql_native_password":
|
||||||
// using mysql default authentication method
|
// using mysql default authentication method
|
||||||
return cipher, ErrNativePassword
|
return cipher, ErrNativePassword
|
||||||
} else {
|
default:
|
||||||
return cipher, ErrUnknownPlugin
|
return cipher, ErrUnknownPlugin
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
|
||||||
// https://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::OldAuthSwitchRequest
|
// https://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::OldAuthSwitchRequest
|
||||||
return nil, ErrOldPassword
|
return nil, ErrOldPassword
|
||||||
}
|
|
||||||
|
|
||||||
default: // Error otherwise
|
default: // Error otherwise
|
||||||
return nil, mc.handleErrorPacket(data)
|
return nil, mc.handleErrorPacket(data)
|
||||||
@@ -550,6 +570,22 @@ func (mc *mysqlConn) handleErrorPacket(data []byte) error {
|
|||||||
// Error Number [16 bit uint]
|
// Error Number [16 bit uint]
|
||||||
errno := binary.LittleEndian.Uint16(data[1:3])
|
errno := binary.LittleEndian.Uint16(data[1:3])
|
||||||
|
|
||||||
|
// 1792: ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION
|
||||||
|
// 1290: ER_OPTION_PREVENTS_STATEMENT (returned by Aurora during failover)
|
||||||
|
if (errno == 1792 || errno == 1290) && mc.cfg.RejectReadOnly {
|
||||||
|
// Oops; we are connected to a read-only connection, and won't be able
|
||||||
|
// to issue any write statements. Since RejectReadOnly is configured,
|
||||||
|
// we throw away this connection hoping this one would have write
|
||||||
|
// permission. This is specifically for a possible race condition
|
||||||
|
// during failover (e.g. on AWS Aurora). See README.md for more.
|
||||||
|
//
|
||||||
|
// We explicitly close the connection before returning
|
||||||
|
// driver.ErrBadConn to ensure that `database/sql` purges this
|
||||||
|
// connection and initiates a new one for next statement next time.
|
||||||
|
mc.Close()
|
||||||
|
return driver.ErrBadConn
|
||||||
|
}
|
||||||
|
|
||||||
pos := 3
|
pos := 3
|
||||||
|
|
||||||
// SQL State [optional: # + 5bytes string]
|
// SQL State [optional: # + 5bytes string]
|
||||||
@@ -589,14 +625,7 @@ func (mc *mysqlConn) handleOkPacket(data []byte) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// warning count [2 bytes]
|
// warning count [2 bytes]
|
||||||
if !mc.strict {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
pos := 1 + n + m + 2
|
|
||||||
if binary.LittleEndian.Uint16(data[pos:pos+2]) > 0 {
|
|
||||||
return mc.getWarnings()
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -668,14 +697,21 @@ func (mc *mysqlConn) readColumns(count int) ([]mysqlField, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
pos += n
|
||||||
|
|
||||||
// Filler [uint8]
|
// Filler [uint8]
|
||||||
|
pos++
|
||||||
|
|
||||||
// Charset [charset, collation uint8]
|
// Charset [charset, collation uint8]
|
||||||
|
columns[i].charSet = data[pos]
|
||||||
|
pos += 2
|
||||||
|
|
||||||
// Length [uint32]
|
// Length [uint32]
|
||||||
pos += n + 1 + 2 + 4
|
columns[i].length = binary.LittleEndian.Uint32(data[pos : pos+4])
|
||||||
|
pos += 4
|
||||||
|
|
||||||
// Field type [uint8]
|
// Field type [uint8]
|
||||||
columns[i].fieldType = data[pos]
|
columns[i].fieldType = fieldType(data[pos])
|
||||||
pos++
|
pos++
|
||||||
|
|
||||||
// Flags [uint16]
|
// Flags [uint16]
|
||||||
@@ -808,14 +844,7 @@ func (stmt *mysqlStmt) readPrepareResultPacket() (uint16, error) {
|
|||||||
// Reserved [8 bit]
|
// Reserved [8 bit]
|
||||||
|
|
||||||
// Warning count [16 bit uint]
|
// Warning count [16 bit uint]
|
||||||
if !stmt.mc.strict {
|
|
||||||
return columnCount, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 columnCount, nil
|
||||||
}
|
}
|
||||||
return 0, err
|
return 0, err
|
||||||
@@ -887,6 +916,12 @@ func (stmt *mysqlStmt) writeExecutePacket(args []driver.Value) error {
|
|||||||
const minPktLen = 4 + 1 + 4 + 1 + 4
|
const minPktLen = 4 + 1 + 4 + 1 + 4
|
||||||
mc := stmt.mc
|
mc := stmt.mc
|
||||||
|
|
||||||
|
// Determine threshould dynamically to avoid packet size shortage.
|
||||||
|
longDataSize := mc.maxAllowedPacket / (stmt.paramCount + 1)
|
||||||
|
if longDataSize < 64 {
|
||||||
|
longDataSize = 64
|
||||||
|
}
|
||||||
|
|
||||||
// Reset packet-sequence
|
// Reset packet-sequence
|
||||||
mc.sequence = 0
|
mc.sequence = 0
|
||||||
|
|
||||||
@@ -900,7 +935,7 @@ func (stmt *mysqlStmt) writeExecutePacket(args []driver.Value) error {
|
|||||||
if data == nil {
|
if data == nil {
|
||||||
// can not take the buffer. Something must be wrong with the connection
|
// can not take the buffer. Something must be wrong with the connection
|
||||||
errLog.Print(ErrBusyBuffer)
|
errLog.Print(ErrBusyBuffer)
|
||||||
return driver.ErrBadConn
|
return errBadConnNoWrite
|
||||||
}
|
}
|
||||||
|
|
||||||
// command [1 byte]
|
// command [1 byte]
|
||||||
@@ -959,7 +994,7 @@ func (stmt *mysqlStmt) writeExecutePacket(args []driver.Value) error {
|
|||||||
// build NULL-bitmap
|
// build NULL-bitmap
|
||||||
if arg == nil {
|
if arg == nil {
|
||||||
nullMask[i/8] |= 1 << (uint(i) & 7)
|
nullMask[i/8] |= 1 << (uint(i) & 7)
|
||||||
paramTypes[i+i] = fieldTypeNULL
|
paramTypes[i+i] = byte(fieldTypeNULL)
|
||||||
paramTypes[i+i+1] = 0x00
|
paramTypes[i+i+1] = 0x00
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -967,7 +1002,7 @@ func (stmt *mysqlStmt) writeExecutePacket(args []driver.Value) error {
|
|||||||
// cache types and values
|
// cache types and values
|
||||||
switch v := arg.(type) {
|
switch v := arg.(type) {
|
||||||
case int64:
|
case int64:
|
||||||
paramTypes[i+i] = fieldTypeLongLong
|
paramTypes[i+i] = byte(fieldTypeLongLong)
|
||||||
paramTypes[i+i+1] = 0x00
|
paramTypes[i+i+1] = 0x00
|
||||||
|
|
||||||
if cap(paramValues)-len(paramValues)-8 >= 0 {
|
if cap(paramValues)-len(paramValues)-8 >= 0 {
|
||||||
@@ -983,7 +1018,7 @@ func (stmt *mysqlStmt) writeExecutePacket(args []driver.Value) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case float64:
|
case float64:
|
||||||
paramTypes[i+i] = fieldTypeDouble
|
paramTypes[i+i] = byte(fieldTypeDouble)
|
||||||
paramTypes[i+i+1] = 0x00
|
paramTypes[i+i+1] = 0x00
|
||||||
|
|
||||||
if cap(paramValues)-len(paramValues)-8 >= 0 {
|
if cap(paramValues)-len(paramValues)-8 >= 0 {
|
||||||
@@ -999,7 +1034,7 @@ func (stmt *mysqlStmt) writeExecutePacket(args []driver.Value) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case bool:
|
case bool:
|
||||||
paramTypes[i+i] = fieldTypeTiny
|
paramTypes[i+i] = byte(fieldTypeTiny)
|
||||||
paramTypes[i+i+1] = 0x00
|
paramTypes[i+i+1] = 0x00
|
||||||
|
|
||||||
if v {
|
if v {
|
||||||
@@ -1011,10 +1046,10 @@ func (stmt *mysqlStmt) writeExecutePacket(args []driver.Value) error {
|
|||||||
case []byte:
|
case []byte:
|
||||||
// Common case (non-nil value) first
|
// Common case (non-nil value) first
|
||||||
if v != nil {
|
if v != nil {
|
||||||
paramTypes[i+i] = fieldTypeString
|
paramTypes[i+i] = byte(fieldTypeString)
|
||||||
paramTypes[i+i+1] = 0x00
|
paramTypes[i+i+1] = 0x00
|
||||||
|
|
||||||
if len(v) < mc.maxAllowedPacket-pos-len(paramValues)-(len(args)-(i+1))*64 {
|
if len(v) < longDataSize {
|
||||||
paramValues = appendLengthEncodedInteger(paramValues,
|
paramValues = appendLengthEncodedInteger(paramValues,
|
||||||
uint64(len(v)),
|
uint64(len(v)),
|
||||||
)
|
)
|
||||||
@@ -1029,14 +1064,14 @@ func (stmt *mysqlStmt) writeExecutePacket(args []driver.Value) error {
|
|||||||
|
|
||||||
// Handle []byte(nil) as a NULL value
|
// Handle []byte(nil) as a NULL value
|
||||||
nullMask[i/8] |= 1 << (uint(i) & 7)
|
nullMask[i/8] |= 1 << (uint(i) & 7)
|
||||||
paramTypes[i+i] = fieldTypeNULL
|
paramTypes[i+i] = byte(fieldTypeNULL)
|
||||||
paramTypes[i+i+1] = 0x00
|
paramTypes[i+i+1] = 0x00
|
||||||
|
|
||||||
case string:
|
case string:
|
||||||
paramTypes[i+i] = fieldTypeString
|
paramTypes[i+i] = byte(fieldTypeString)
|
||||||
paramTypes[i+i+1] = 0x00
|
paramTypes[i+i+1] = 0x00
|
||||||
|
|
||||||
if len(v) < mc.maxAllowedPacket-pos-len(paramValues)-(len(args)-(i+1))*64 {
|
if len(v) < longDataSize {
|
||||||
paramValues = appendLengthEncodedInteger(paramValues,
|
paramValues = appendLengthEncodedInteger(paramValues,
|
||||||
uint64(len(v)),
|
uint64(len(v)),
|
||||||
)
|
)
|
||||||
@@ -1048,20 +1083,22 @@ func (stmt *mysqlStmt) writeExecutePacket(args []driver.Value) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case time.Time:
|
case time.Time:
|
||||||
paramTypes[i+i] = fieldTypeString
|
paramTypes[i+i] = byte(fieldTypeString)
|
||||||
paramTypes[i+i+1] = 0x00
|
paramTypes[i+i+1] = 0x00
|
||||||
|
|
||||||
var val []byte
|
var a [64]byte
|
||||||
|
var b = a[:0]
|
||||||
|
|
||||||
if v.IsZero() {
|
if v.IsZero() {
|
||||||
val = []byte("0000-00-00")
|
b = append(b, "0000-00-00"...)
|
||||||
} else {
|
} else {
|
||||||
val = []byte(v.In(mc.cfg.Loc).Format(timeFormat))
|
b = v.In(mc.cfg.Loc).AppendFormat(b, timeFormat)
|
||||||
}
|
}
|
||||||
|
|
||||||
paramValues = appendLengthEncodedInteger(paramValues,
|
paramValues = appendLengthEncodedInteger(paramValues,
|
||||||
uint64(len(val)),
|
uint64(len(b)),
|
||||||
)
|
)
|
||||||
paramValues = append(paramValues, val...)
|
paramValues = append(paramValues, b...)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("can not convert type: %T", arg)
|
return fmt.Errorf("can not convert type: %T", arg)
|
||||||
@@ -1120,10 +1157,11 @@ func (rows *binaryRows) readRow(dest []driver.Value) error {
|
|||||||
}
|
}
|
||||||
return io.EOF
|
return io.EOF
|
||||||
}
|
}
|
||||||
|
mc := rows.mc
|
||||||
rows.mc = nil
|
rows.mc = nil
|
||||||
|
|
||||||
// Error otherwise
|
// Error otherwise
|
||||||
return rows.mc.handleErrorPacket(data)
|
return mc.handleErrorPacket(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NULL-bitmap, [(column-count + 7 + 2) / 8 bytes]
|
// NULL-bitmap, [(column-count + 7 + 2) / 8 bytes]
|
||||||
@@ -1187,7 +1225,7 @@ func (rows *binaryRows) readRow(dest []driver.Value) error {
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
case fieldTypeFloat:
|
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
|
pos += 4
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|||||||
78
vendor/github.com/go-sql-driver/mysql/row_columntypes.go
generated
vendored
78
vendor/github.com/go-sql-driver/mysql/row_columntypes.go
generated
vendored
@@ -1,78 +0,0 @@
|
|||||||
package mysql
|
|
||||||
|
|
||||||
const (
|
|
||||||
// In case we get something unexpected
|
|
||||||
FieldTypeUnknown = "UNKNOWN"
|
|
||||||
|
|
||||||
// Human-readable names for each distinct type byte
|
|
||||||
FieldTypeNameDecimal = "DECIMAL"
|
|
||||||
FieldTypeNameTiny = "TINY"
|
|
||||||
FieldTypeNameShort = "SHORT"
|
|
||||||
FieldTypeNameLong = "LONG"
|
|
||||||
FieldTypeNameFloat = "FLOAT"
|
|
||||||
FieldTypeNameDouble = "DOUBLE"
|
|
||||||
FieldTypeNameNULL = "NULL"
|
|
||||||
FieldTypeNameTimestamp = "TIMESTAMP"
|
|
||||||
FieldTypeNameLongLong = "LONGLONG"
|
|
||||||
FieldTypeNameInt24 = "INT24"
|
|
||||||
FieldTypeNameDate = "DATE"
|
|
||||||
FieldTypeNameTime = "TIME"
|
|
||||||
FieldTypeNameDateTime = "DATETIME"
|
|
||||||
FieldTypeNameYear = "YEAR"
|
|
||||||
FieldTypeNameNewDate = "NEWDATE"
|
|
||||||
FieldTypeNameVarChar = "VARCHAR"
|
|
||||||
FieldTypeNameBit = "BIT"
|
|
||||||
FieldTypeNameJSON = "JSON"
|
|
||||||
FieldTypeNameNewDecimal = "NEWDECIMAL"
|
|
||||||
FieldTypeNameEnum = "ENUM"
|
|
||||||
FieldTypeNameSet = "SET"
|
|
||||||
FieldTypeNameTinyBLOB = "TINYBLOB"
|
|
||||||
FieldTypeNameMediumBLOB = "MEDIUMBLOB"
|
|
||||||
FieldTypeNameLongBLOB = "LONGBLOB"
|
|
||||||
FieldTypeNameBLOB = "BLOB"
|
|
||||||
FieldTypeNameVarString = "VARSTRING"
|
|
||||||
FieldTypeNameString = "STRING"
|
|
||||||
FieldTypeNameGeometry = "GEOMETRY"
|
|
||||||
)
|
|
||||||
|
|
||||||
// mapping from each type identifier to human readable string
|
|
||||||
var mysqlTypeMap = map[byte]string{
|
|
||||||
fieldTypeDecimal: FieldTypeNameDecimal,
|
|
||||||
fieldTypeTiny: FieldTypeNameTiny,
|
|
||||||
fieldTypeShort: FieldTypeNameShort,
|
|
||||||
fieldTypeLong: FieldTypeNameLong,
|
|
||||||
fieldTypeFloat: FieldTypeNameFloat,
|
|
||||||
fieldTypeDouble: FieldTypeNameDouble,
|
|
||||||
fieldTypeNULL: FieldTypeNameNULL,
|
|
||||||
fieldTypeTimestamp: FieldTypeNameTimestamp,
|
|
||||||
fieldTypeLongLong: FieldTypeNameLongLong,
|
|
||||||
fieldTypeInt24: FieldTypeNameInt24,
|
|
||||||
fieldTypeDate: FieldTypeNameDate,
|
|
||||||
fieldTypeTime: FieldTypeNameTime,
|
|
||||||
fieldTypeDateTime: FieldTypeNameDateTime,
|
|
||||||
fieldTypeYear: FieldTypeNameYear,
|
|
||||||
fieldTypeNewDate: FieldTypeNameNewDate,
|
|
||||||
fieldTypeVarChar: FieldTypeNameVarChar,
|
|
||||||
fieldTypeBit: FieldTypeNameBit,
|
|
||||||
fieldTypeJSON: FieldTypeNameJSON,
|
|
||||||
fieldTypeNewDecimal: FieldTypeNameNewDecimal,
|
|
||||||
fieldTypeEnum: FieldTypeNameEnum,
|
|
||||||
fieldTypeSet: FieldTypeNameSet,
|
|
||||||
fieldTypeTinyBLOB: FieldTypeNameTinyBLOB,
|
|
||||||
fieldTypeMediumBLOB: FieldTypeNameMediumBLOB,
|
|
||||||
fieldTypeLongBLOB: FieldTypeNameLongBLOB,
|
|
||||||
fieldTypeBLOB: FieldTypeNameBLOB,
|
|
||||||
fieldTypeVarString: FieldTypeNameVarString,
|
|
||||||
fieldTypeString: FieldTypeNameString,
|
|
||||||
fieldTypeGeometry: FieldTypeNameGeometry,
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make Rows implement the optional RowsColumnTypeDatabaseTypeName interface.
|
|
||||||
// See https://github.com/golang/go/commit/2a85578b0ecd424e95b29d810b7a414a299fd6a7
|
|
||||||
// - (go 1.8 required for this to have any effect)
|
|
||||||
func (rows *mysqlRows) ColumnTypeDatabaseTypeName(index int) string {
|
|
||||||
if typeName, ok := mysqlTypeMap[rows.rs.columns[index].fieldType]; ok {
|
|
||||||
return typeName
|
|
||||||
}
|
|
||||||
return FieldTypeUnknown
|
|
||||||
}
|
|
||||||
96
vendor/github.com/go-sql-driver/mysql/rows.go
generated
vendored
96
vendor/github.com/go-sql-driver/mysql/rows.go
generated
vendored
@@ -11,34 +11,24 @@ package mysql
|
|||||||
import (
|
import (
|
||||||
"database/sql/driver"
|
"database/sql/driver"
|
||||||
"io"
|
"io"
|
||||||
|
"math"
|
||||||
|
"reflect"
|
||||||
)
|
)
|
||||||
|
|
||||||
type mysqlField struct {
|
|
||||||
tableName string
|
|
||||||
name string
|
|
||||||
flags fieldFlag
|
|
||||||
fieldType byte
|
|
||||||
decimals byte
|
|
||||||
}
|
|
||||||
|
|
||||||
type resultSet struct {
|
type resultSet struct {
|
||||||
columns []mysqlField
|
columns []mysqlField
|
||||||
|
columnNames []string
|
||||||
done bool
|
done bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type mysqlRows struct {
|
type mysqlRows struct {
|
||||||
mc *mysqlConn
|
mc *mysqlConn
|
||||||
rs resultSet
|
rs resultSet
|
||||||
|
finish func()
|
||||||
}
|
}
|
||||||
|
|
||||||
type binaryRows struct {
|
type binaryRows struct {
|
||||||
mysqlRows
|
mysqlRows
|
||||||
// stmtCols is a pointer to the statement's cached columns for different
|
|
||||||
// result sets.
|
|
||||||
stmtCols *[][]mysqlField
|
|
||||||
// i is a number of the current result set. It is used to fetch proper
|
|
||||||
// columns from stmtCols.
|
|
||||||
i int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type textRows struct {
|
type textRows struct {
|
||||||
@@ -46,6 +36,10 @@ type textRows struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (rows *mysqlRows) Columns() []string {
|
func (rows *mysqlRows) Columns() []string {
|
||||||
|
if rows.rs.columnNames != nil {
|
||||||
|
return rows.rs.columnNames
|
||||||
|
}
|
||||||
|
|
||||||
columns := make([]string, len(rows.rs.columns))
|
columns := make([]string, len(rows.rs.columns))
|
||||||
if rows.mc != nil && rows.mc.cfg.ColumnsWithAlias {
|
if rows.mc != nil && rows.mc.cfg.ColumnsWithAlias {
|
||||||
for i := range columns {
|
for i := range columns {
|
||||||
@@ -60,16 +54,61 @@ func (rows *mysqlRows) Columns() []string {
|
|||||||
columns[i] = rows.rs.columns[i].name
|
columns[i] = rows.rs.columns[i].name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rows.rs.columnNames = columns
|
||||||
return columns
|
return columns
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (rows *mysqlRows) ColumnTypeDatabaseTypeName(i int) string {
|
||||||
|
return rows.rs.columns[i].typeDatabaseName()
|
||||||
|
}
|
||||||
|
|
||||||
|
// func (rows *mysqlRows) ColumnTypeLength(i int) (length int64, ok bool) {
|
||||||
|
// return int64(rows.rs.columns[i].length), true
|
||||||
|
// }
|
||||||
|
|
||||||
|
func (rows *mysqlRows) ColumnTypeNullable(i int) (nullable, ok bool) {
|
||||||
|
return rows.rs.columns[i].flags&flagNotNULL == 0, true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rows *mysqlRows) ColumnTypePrecisionScale(i int) (int64, int64, bool) {
|
||||||
|
column := rows.rs.columns[i]
|
||||||
|
decimals := int64(column.decimals)
|
||||||
|
|
||||||
|
switch column.fieldType {
|
||||||
|
case fieldTypeDecimal, fieldTypeNewDecimal:
|
||||||
|
if decimals > 0 {
|
||||||
|
return int64(column.length) - 2, decimals, true
|
||||||
|
}
|
||||||
|
return int64(column.length) - 1, decimals, true
|
||||||
|
case fieldTypeTimestamp, fieldTypeDateTime, fieldTypeTime:
|
||||||
|
return decimals, decimals, true
|
||||||
|
case fieldTypeFloat, fieldTypeDouble:
|
||||||
|
if decimals == 0x1f {
|
||||||
|
return math.MaxInt64, math.MaxInt64, true
|
||||||
|
}
|
||||||
|
return math.MaxInt64, decimals, true
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0, 0, false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rows *mysqlRows) ColumnTypeScanType(i int) reflect.Type {
|
||||||
|
return rows.rs.columns[i].scanType()
|
||||||
|
}
|
||||||
|
|
||||||
func (rows *mysqlRows) Close() (err error) {
|
func (rows *mysqlRows) Close() (err error) {
|
||||||
|
if f := rows.finish; f != nil {
|
||||||
|
f()
|
||||||
|
rows.finish = nil
|
||||||
|
}
|
||||||
|
|
||||||
mc := rows.mc
|
mc := rows.mc
|
||||||
if mc == nil {
|
if mc == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if mc.netConn == nil {
|
if err := mc.error(); err != nil {
|
||||||
return ErrInvalidConn
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove unread packets from stream
|
// Remove unread packets from stream
|
||||||
@@ -97,8 +136,8 @@ func (rows *mysqlRows) nextResultSet() (int, error) {
|
|||||||
if rows.mc == nil {
|
if rows.mc == nil {
|
||||||
return 0, io.EOF
|
return 0, io.EOF
|
||||||
}
|
}
|
||||||
if rows.mc.netConn == nil {
|
if err := rows.mc.error(); err != nil {
|
||||||
return 0, ErrInvalidConn
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove unread packets from stream
|
// Remove unread packets from stream
|
||||||
@@ -132,31 +171,20 @@ func (rows *mysqlRows) nextNotEmptyResultSet() (int, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rows *binaryRows) NextResultSet() (err error) {
|
func (rows *binaryRows) NextResultSet() error {
|
||||||
resLen, err := rows.nextNotEmptyResultSet()
|
resLen, err := rows.nextNotEmptyResultSet()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// get columns, if not cached, read them and cache them.
|
|
||||||
if rows.i >= len(*rows.stmtCols) {
|
|
||||||
rows.rs.columns, err = rows.mc.readColumns(resLen)
|
rows.rs.columns, err = rows.mc.readColumns(resLen)
|
||||||
*rows.stmtCols = append(*rows.stmtCols, rows.rs.columns)
|
|
||||||
} else {
|
|
||||||
rows.rs.columns = (*rows.stmtCols)[rows.i]
|
|
||||||
if err := rows.mc.readUntilEOF(); err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
rows.i++
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (rows *binaryRows) Next(dest []driver.Value) error {
|
func (rows *binaryRows) Next(dest []driver.Value) error {
|
||||||
if mc := rows.mc; mc != nil {
|
if mc := rows.mc; mc != nil {
|
||||||
if mc.netConn == nil {
|
if err := mc.error(); err != nil {
|
||||||
return ErrInvalidConn
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch next row from stream
|
// Fetch next row from stream
|
||||||
@@ -177,8 +205,8 @@ func (rows *textRows) NextResultSet() (err error) {
|
|||||||
|
|
||||||
func (rows *textRows) Next(dest []driver.Value) error {
|
func (rows *textRows) Next(dest []driver.Value) error {
|
||||||
if mc := rows.mc; mc != nil {
|
if mc := rows.mc; mc != nil {
|
||||||
if mc.netConn == nil {
|
if err := mc.error(); err != nil {
|
||||||
return ErrInvalidConn
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch next row from stream
|
// Fetch next row from stream
|
||||||
|
|||||||
41
vendor/github.com/go-sql-driver/mysql/statement.go
generated
vendored
41
vendor/github.com/go-sql-driver/mysql/statement.go
generated
vendored
@@ -20,11 +20,10 @@ type mysqlStmt struct {
|
|||||||
mc *mysqlConn
|
mc *mysqlConn
|
||||||
id uint32
|
id uint32
|
||||||
paramCount int
|
paramCount int
|
||||||
columns [][]mysqlField // cached from the first query
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (stmt *mysqlStmt) Close() error {
|
func (stmt *mysqlStmt) Close() error {
|
||||||
if stmt.mc == nil || stmt.mc.netConn == nil {
|
if stmt.mc == nil || stmt.mc.closed.IsSet() {
|
||||||
// driver.Stmt.Close can be called more than once, thus this function
|
// driver.Stmt.Close can be called more than once, thus this function
|
||||||
// has to be idempotent.
|
// has to be idempotent.
|
||||||
// See also Issue #450 and golang/go#16019.
|
// See also Issue #450 and golang/go#16019.
|
||||||
@@ -46,14 +45,14 @@ func (stmt *mysqlStmt) ColumnConverter(idx int) driver.ValueConverter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (stmt *mysqlStmt) Exec(args []driver.Value) (driver.Result, error) {
|
func (stmt *mysqlStmt) Exec(args []driver.Value) (driver.Result, error) {
|
||||||
if stmt.mc.netConn == nil {
|
if stmt.mc.closed.IsSet() {
|
||||||
errLog.Print(ErrInvalidConn)
|
errLog.Print(ErrInvalidConn)
|
||||||
return nil, driver.ErrBadConn
|
return nil, driver.ErrBadConn
|
||||||
}
|
}
|
||||||
// Send command
|
// Send command
|
||||||
err := stmt.writeExecutePacket(args)
|
err := stmt.writeExecutePacket(args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, stmt.mc.markBadConn(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
mc := stmt.mc
|
mc := stmt.mc
|
||||||
@@ -90,14 +89,18 @@ func (stmt *mysqlStmt) Exec(args []driver.Value) (driver.Result, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (stmt *mysqlStmt) Query(args []driver.Value) (driver.Rows, error) {
|
func (stmt *mysqlStmt) Query(args []driver.Value) (driver.Rows, error) {
|
||||||
if stmt.mc.netConn == nil {
|
return stmt.query(args)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (stmt *mysqlStmt) query(args []driver.Value) (*binaryRows, error) {
|
||||||
|
if stmt.mc.closed.IsSet() {
|
||||||
errLog.Print(ErrInvalidConn)
|
errLog.Print(ErrInvalidConn)
|
||||||
return nil, driver.ErrBadConn
|
return nil, driver.ErrBadConn
|
||||||
}
|
}
|
||||||
// Send command
|
// Send command
|
||||||
err := stmt.writeExecutePacket(args)
|
err := stmt.writeExecutePacket(args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, stmt.mc.markBadConn(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
mc := stmt.mc
|
mc := stmt.mc
|
||||||
@@ -109,20 +112,10 @@ func (stmt *mysqlStmt) Query(args []driver.Value) (driver.Rows, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
rows := new(binaryRows)
|
rows := new(binaryRows)
|
||||||
rows.stmtCols = &stmt.columns
|
|
||||||
|
|
||||||
if resLen > 0 {
|
if resLen > 0 {
|
||||||
rows.mc = mc
|
rows.mc = mc
|
||||||
rows.i++
|
|
||||||
// Columns
|
|
||||||
// If not cached, read them and cache them
|
|
||||||
if len(stmt.columns) == 0 {
|
|
||||||
rows.rs.columns, err = mc.readColumns(resLen)
|
rows.rs.columns, err = mc.readColumns(resLen)
|
||||||
stmt.columns = append(stmt.columns, rows.rs.columns)
|
|
||||||
} else {
|
|
||||||
rows.rs.columns = stmt.columns[0]
|
|
||||||
err = mc.readUntilEOF()
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
rows.rs.done = true
|
rows.rs.done = true
|
||||||
|
|
||||||
@@ -144,6 +137,12 @@ func (c converter) ConvertValue(v interface{}) (driver.Value, error) {
|
|||||||
return v, nil
|
return v, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if v != nil {
|
||||||
|
if valuer, ok := v.(driver.Valuer); ok {
|
||||||
|
return valuer.Value()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rv := reflect.ValueOf(v)
|
rv := reflect.ValueOf(v)
|
||||||
switch rv.Kind() {
|
switch rv.Kind() {
|
||||||
case reflect.Ptr:
|
case reflect.Ptr:
|
||||||
@@ -164,6 +163,16 @@ func (c converter) ConvertValue(v interface{}) (driver.Value, error) {
|
|||||||
return int64(u64), nil
|
return int64(u64), nil
|
||||||
case reflect.Float32, reflect.Float64:
|
case reflect.Float32, reflect.Float64:
|
||||||
return rv.Float(), nil
|
return rv.Float(), nil
|
||||||
|
case reflect.Bool:
|
||||||
|
return rv.Bool(), nil
|
||||||
|
case reflect.Slice:
|
||||||
|
ek := rv.Type().Elem().Kind()
|
||||||
|
if ek == reflect.Uint8 {
|
||||||
|
return rv.Bytes(), nil
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("unsupported type %T, a slice of %s", v, ek)
|
||||||
|
case reflect.String:
|
||||||
|
return rv.String(), nil
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("unsupported type %T, a %s", v, rv.Kind())
|
return nil, fmt.Errorf("unsupported type %T, a %s", v, rv.Kind())
|
||||||
}
|
}
|
||||||
|
|||||||
4
vendor/github.com/go-sql-driver/mysql/transaction.go
generated
vendored
4
vendor/github.com/go-sql-driver/mysql/transaction.go
generated
vendored
@@ -13,7 +13,7 @@ type mysqlTx struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (tx *mysqlTx) Commit() (err error) {
|
func (tx *mysqlTx) Commit() (err error) {
|
||||||
if tx.mc == nil || tx.mc.netConn == nil {
|
if tx.mc == nil || tx.mc.closed.IsSet() {
|
||||||
return ErrInvalidConn
|
return ErrInvalidConn
|
||||||
}
|
}
|
||||||
err = tx.mc.exec("COMMIT")
|
err = tx.mc.exec("COMMIT")
|
||||||
@@ -22,7 +22,7 @@ func (tx *mysqlTx) Commit() (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (tx *mysqlTx) Rollback() (err error) {
|
func (tx *mysqlTx) Rollback() (err error) {
|
||||||
if tx.mc == nil || tx.mc.netConn == nil {
|
if tx.mc == nil || tx.mc.closed.IsSet() {
|
||||||
return ErrInvalidConn
|
return ErrInvalidConn
|
||||||
}
|
}
|
||||||
err = tx.mc.exec("ROLLBACK")
|
err = tx.mc.exec("ROLLBACK")
|
||||||
|
|||||||
84
vendor/github.com/go-sql-driver/mysql/utils.go
generated
vendored
84
vendor/github.com/go-sql-driver/mysql/utils.go
generated
vendored
@@ -16,16 +16,21 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
tlsConfigLock sync.RWMutex
|
||||||
tlsConfigRegister map[string]*tls.Config // Register for custom tls.Configs
|
tlsConfigRegister map[string]*tls.Config // Register for custom tls.Configs
|
||||||
)
|
)
|
||||||
|
|
||||||
// RegisterTLSConfig registers a custom tls.Config to be used with sql.Open.
|
// RegisterTLSConfig registers a custom tls.Config to be used with sql.Open.
|
||||||
// Use the key as a value in the DSN where tls=value.
|
// Use the key as a value in the DSN where tls=value.
|
||||||
//
|
//
|
||||||
|
// Note: The tls.Config provided to needs to be exclusively owned by the driver after registering.
|
||||||
|
//
|
||||||
// rootCertPool := x509.NewCertPool()
|
// rootCertPool := x509.NewCertPool()
|
||||||
// pem, err := ioutil.ReadFile("/path/ca-cert.pem")
|
// pem, err := ioutil.ReadFile("/path/ca-cert.pem")
|
||||||
// if err != nil {
|
// if err != nil {
|
||||||
@@ -51,19 +56,32 @@ func RegisterTLSConfig(key string, config *tls.Config) error {
|
|||||||
return fmt.Errorf("key '%s' is reserved", key)
|
return fmt.Errorf("key '%s' is reserved", key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tlsConfigLock.Lock()
|
||||||
if tlsConfigRegister == nil {
|
if tlsConfigRegister == nil {
|
||||||
tlsConfigRegister = make(map[string]*tls.Config)
|
tlsConfigRegister = make(map[string]*tls.Config)
|
||||||
}
|
}
|
||||||
|
|
||||||
tlsConfigRegister[key] = config
|
tlsConfigRegister[key] = config
|
||||||
|
tlsConfigLock.Unlock()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeregisterTLSConfig removes the tls.Config associated with key.
|
// DeregisterTLSConfig removes the tls.Config associated with key.
|
||||||
func DeregisterTLSConfig(key string) {
|
func DeregisterTLSConfig(key string) {
|
||||||
|
tlsConfigLock.Lock()
|
||||||
if tlsConfigRegister != nil {
|
if tlsConfigRegister != nil {
|
||||||
delete(tlsConfigRegister, key)
|
delete(tlsConfigRegister, key)
|
||||||
}
|
}
|
||||||
|
tlsConfigLock.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
func getTLSConfigClone(key string) (config *tls.Config) {
|
||||||
|
tlsConfigLock.RLock()
|
||||||
|
if v, ok := tlsConfigRegister[key]; ok {
|
||||||
|
config = cloneTLSConfig(v)
|
||||||
|
}
|
||||||
|
tlsConfigLock.RUnlock()
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the bool value of the input.
|
// Returns the bool value of the input.
|
||||||
@@ -548,8 +566,8 @@ func readLengthEncodedInteger(b []byte) (uint64, bool, int) {
|
|||||||
if len(b) == 0 {
|
if len(b) == 0 {
|
||||||
return 0, true, 1
|
return 0, true, 1
|
||||||
}
|
}
|
||||||
switch b[0] {
|
|
||||||
|
|
||||||
|
switch b[0] {
|
||||||
// 251: NULL
|
// 251: NULL
|
||||||
case 0xfb:
|
case 0xfb:
|
||||||
return 0, true, 1
|
return 0, true, 1
|
||||||
@@ -738,3 +756,67 @@ func escapeStringQuotes(buf []byte, v string) []byte {
|
|||||||
|
|
||||||
return buf[:pos]
|
return buf[:pos]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Sync utils *
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
// noCopy may be embedded into structs which must not be copied
|
||||||
|
// after the first use.
|
||||||
|
//
|
||||||
|
// See https://github.com/golang/go/issues/8005#issuecomment-190753527
|
||||||
|
// for details.
|
||||||
|
type noCopy struct{}
|
||||||
|
|
||||||
|
// Lock is a no-op used by -copylocks checker from `go vet`.
|
||||||
|
func (*noCopy) Lock() {}
|
||||||
|
|
||||||
|
// atomicBool is a wrapper around uint32 for usage as a boolean value with
|
||||||
|
// atomic access.
|
||||||
|
type atomicBool struct {
|
||||||
|
_noCopy noCopy
|
||||||
|
value uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsSet returns wether the current boolean value is true
|
||||||
|
func (ab *atomicBool) IsSet() bool {
|
||||||
|
return atomic.LoadUint32(&ab.value) > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set sets the value of the bool regardless of the previous value
|
||||||
|
func (ab *atomicBool) Set(value bool) {
|
||||||
|
if value {
|
||||||
|
atomic.StoreUint32(&ab.value, 1)
|
||||||
|
} else {
|
||||||
|
atomic.StoreUint32(&ab.value, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TrySet sets the value of the bool and returns wether the value changed
|
||||||
|
func (ab *atomicBool) TrySet(value bool) bool {
|
||||||
|
if value {
|
||||||
|
return atomic.SwapUint32(&ab.value, 1) == 0
|
||||||
|
}
|
||||||
|
return atomic.SwapUint32(&ab.value, 0) > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// atomicBool is a wrapper for atomically accessed error values
|
||||||
|
type atomicError struct {
|
||||||
|
_noCopy noCopy
|
||||||
|
value atomic.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set sets the error value regardless of the previous value.
|
||||||
|
// The value must not be nil
|
||||||
|
func (ae *atomicError) Set(value error) {
|
||||||
|
ae.value.Store(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Value returns the current error value
|
||||||
|
func (ae *atomicError) Value() error {
|
||||||
|
if v := ae.value.Load(); v != nil {
|
||||||
|
// this will panic if the value doesn't implement the error interface
|
||||||
|
return v.(error)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
40
vendor/github.com/go-sql-driver/mysql/utils_go17.go
generated
vendored
Normal file
40
vendor/github.com/go-sql-driver/mysql/utils_go17.go
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
|
||||||
|
//
|
||||||
|
// Copyright 2017 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 go1.7
|
||||||
|
// +build !go1.8
|
||||||
|
|
||||||
|
package mysql
|
||||||
|
|
||||||
|
import "crypto/tls"
|
||||||
|
|
||||||
|
func cloneTLSConfig(c *tls.Config) *tls.Config {
|
||||||
|
return &tls.Config{
|
||||||
|
Rand: c.Rand,
|
||||||
|
Time: c.Time,
|
||||||
|
Certificates: c.Certificates,
|
||||||
|
NameToCertificate: c.NameToCertificate,
|
||||||
|
GetCertificate: c.GetCertificate,
|
||||||
|
RootCAs: c.RootCAs,
|
||||||
|
NextProtos: c.NextProtos,
|
||||||
|
ServerName: c.ServerName,
|
||||||
|
ClientAuth: c.ClientAuth,
|
||||||
|
ClientCAs: c.ClientCAs,
|
||||||
|
InsecureSkipVerify: c.InsecureSkipVerify,
|
||||||
|
CipherSuites: c.CipherSuites,
|
||||||
|
PreferServerCipherSuites: c.PreferServerCipherSuites,
|
||||||
|
SessionTicketsDisabled: c.SessionTicketsDisabled,
|
||||||
|
SessionTicketKey: c.SessionTicketKey,
|
||||||
|
ClientSessionCache: c.ClientSessionCache,
|
||||||
|
MinVersion: c.MinVersion,
|
||||||
|
MaxVersion: c.MaxVersion,
|
||||||
|
CurvePreferences: c.CurvePreferences,
|
||||||
|
DynamicRecordSizingDisabled: c.DynamicRecordSizingDisabled,
|
||||||
|
Renegotiation: c.Renegotiation,
|
||||||
|
}
|
||||||
|
}
|
||||||
49
vendor/github.com/go-sql-driver/mysql/utils_go18.go
generated
vendored
Normal file
49
vendor/github.com/go-sql-driver/mysql/utils_go18.go
generated
vendored
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
|
||||||
|
//
|
||||||
|
// Copyright 2017 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 go1.8
|
||||||
|
|
||||||
|
package mysql
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/tls"
|
||||||
|
"database/sql"
|
||||||
|
"database/sql/driver"
|
||||||
|
"errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
func cloneTLSConfig(c *tls.Config) *tls.Config {
|
||||||
|
return c.Clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
func namedValueToValue(named []driver.NamedValue) ([]driver.Value, error) {
|
||||||
|
dargs := make([]driver.Value, len(named))
|
||||||
|
for n, param := range named {
|
||||||
|
if len(param.Name) > 0 {
|
||||||
|
// TODO: support the use of Named Parameters #561
|
||||||
|
return nil, errors.New("mysql: driver does not support the use of Named Parameters")
|
||||||
|
}
|
||||||
|
dargs[n] = param.Value
|
||||||
|
}
|
||||||
|
return dargs, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func mapIsolationLevel(level driver.IsolationLevel) (string, error) {
|
||||||
|
switch sql.IsolationLevel(level) {
|
||||||
|
case sql.LevelRepeatableRead:
|
||||||
|
return "REPEATABLE READ", nil
|
||||||
|
case sql.LevelReadCommitted:
|
||||||
|
return "READ COMMITTED", nil
|
||||||
|
case sql.LevelReadUncommitted:
|
||||||
|
return "READ UNCOMMITTED", nil
|
||||||
|
case sql.LevelSerializable:
|
||||||
|
return "SERIALIZABLE", nil
|
||||||
|
default:
|
||||||
|
return "", errors.New("mysql: unsupported isolation level: " + string(level))
|
||||||
|
}
|
||||||
|
}
|
||||||
14
vendor/vendor.json
vendored
14
vendor/vendor.json
vendored
@@ -409,10 +409,12 @@
|
|||||||
"revisionTime": "2017-03-20T17:22:09Z"
|
"revisionTime": "2017-03-20T17:22:09Z"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "42vkdsxNaLyPu+FktCzZ/8zsNSE=",
|
"checksumSHA1": "178ebwKMX/plldM2EKeT7pj3vs8=",
|
||||||
"path": "github.com/go-sql-driver/mysql",
|
"path": "github.com/go-sql-driver/mysql",
|
||||||
"revision": "9dee4ca50b83acdf57a35fb9e6fb4be640afa2f3",
|
"revision": "2cc627ac8defc45d65066ae98f898166f580f9a4",
|
||||||
"revisionTime": "2017-03-27T11:30:21Z"
|
"revisionTime": "2018-01-13T20:07:44Z",
|
||||||
|
"version": "master",
|
||||||
|
"versionExact": "master"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "luu+ud4XYZhlCoNnSAwCJlbh0Bg=",
|
"checksumSHA1": "luu+ud4XYZhlCoNnSAwCJlbh0Bg=",
|
||||||
@@ -830,6 +832,12 @@
|
|||||||
"revision": "1cbadb444a806fd9430d14ad08967ed91da4fa0a",
|
"revision": "1cbadb444a806fd9430d14ad08967ed91da4fa0a",
|
||||||
"revisionTime": "2017-09-13T19:45:57Z"
|
"revisionTime": "2017-09-13T19:45:57Z"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"checksumSHA1": "LiyXfqOzaeQ8vgYZH3t2hUEdVTw=",
|
||||||
|
"path": "google.golang.org/appengine/cloudsql",
|
||||||
|
"revision": "5bee14b453b4c71be47ec1781b0fa61c2ea182db",
|
||||||
|
"revisionTime": "2017-12-12T22:30:47Z"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "Tc3BU26zThLzcyqbVtiSEp7EpU8=",
|
"checksumSHA1": "Tc3BU26zThLzcyqbVtiSEp7EpU8=",
|
||||||
"path": "google.golang.org/genproto/googleapis/rpc/status",
|
"path": "google.golang.org/genproto/googleapis/rpc/status",
|
||||||
|
|||||||
Reference in New Issue
Block a user