Tests can now use config files (#36)
This commit is contained in:
parent
67e94f95b0
commit
97febdb397
58 changed files with 16740 additions and 7785 deletions
39
.drone.yml
39
.drone.yml
|
@ -8,6 +8,13 @@ clone:
|
||||||
depth: 50
|
depth: 50
|
||||||
tags: true
|
tags: true
|
||||||
|
|
||||||
|
services:
|
||||||
|
database:
|
||||||
|
image: mariadb:10
|
||||||
|
environment:
|
||||||
|
- MYSQL_ROOT_PASSWORD=vikunjatest
|
||||||
|
- MYSQL_DATABASE=vikunjatest
|
||||||
|
|
||||||
pipeline:
|
pipeline:
|
||||||
build:
|
build:
|
||||||
image: vikunja/golang-build:latest
|
image: vikunja/golang-build:latest
|
||||||
|
@ -27,12 +34,41 @@ pipeline:
|
||||||
|
|
||||||
test:
|
test:
|
||||||
image: vikunja/golang-build:latest
|
image: vikunja/golang-build:latest
|
||||||
|
group: test
|
||||||
pull: true
|
pull: true
|
||||||
commands:
|
commands:
|
||||||
- make test
|
- make test
|
||||||
when:
|
when:
|
||||||
event: [ push, tag, pull_request ]
|
event: [ push, tag, pull_request ]
|
||||||
|
|
||||||
|
test-sqlite:
|
||||||
|
image: vikunja/golang-build:latest
|
||||||
|
group: test
|
||||||
|
pull: true
|
||||||
|
environment:
|
||||||
|
- VIKUNJA_TESTS_USE_CONFIG=1
|
||||||
|
- VIKUNJA_DATABASE_TYPE=sqlite
|
||||||
|
commands:
|
||||||
|
- make test
|
||||||
|
when:
|
||||||
|
event: [ push, tag, pull_request ]
|
||||||
|
|
||||||
|
test-mysql:
|
||||||
|
image: vikunja/golang-build:latest
|
||||||
|
group: test
|
||||||
|
pull: true
|
||||||
|
environment:
|
||||||
|
- VIKUNJA_TESTS_USE_CONFIG=1
|
||||||
|
- VIKUNJA_DATABASE_TYPE=mysql
|
||||||
|
- VIKUNJA_DATABASE_HOST=database
|
||||||
|
- VIKUNJA_DATABASE_USER=root
|
||||||
|
- VIKUNJA_DATABASE_PASSWORD=vikunjatest
|
||||||
|
- VIKUNJA_DATABASE_DATABASE=vikunjatest
|
||||||
|
commands:
|
||||||
|
- make test
|
||||||
|
when:
|
||||||
|
event: [ push, tag, pull_request ]
|
||||||
|
|
||||||
# Build a release when tagging
|
# Build a release when tagging
|
||||||
before-static-build:
|
before-static-build:
|
||||||
image: karalabe/xgo-latest:latest
|
image: karalabe/xgo-latest:latest
|
||||||
|
@ -159,3 +195,6 @@ pipeline:
|
||||||
{{repo.owner}}/{{repo.name}}: \[{{build.status}}] Build {{build.number}}
|
{{repo.owner}}/{{repo.name}}: \[{{build.status}}] Build {{build.number}}
|
||||||
{{commit.author}} pushed to {{commit.branch}} {{commit.sha}}: `{{commit.message}}`
|
{{commit.author}} pushed to {{commit.branch}} {{commit.sha}}: `{{commit.message}}`
|
||||||
Build started at {{datetime build.started "2006-Jan-02T15:04:05Z" "GMT+2"}} finished at {{datetime build.finished "2006-Jan-02T15:04:05Z" "GMT+2"}}.
|
Build started at {{datetime build.started "2006-Jan-02T15:04:05Z" "GMT+2"}} finished at {{datetime build.finished "2006-Jan-02T15:04:05Z" "GMT+2"}}.
|
||||||
|
when:
|
||||||
|
event: [ push, tag ]
|
||||||
|
branch: [ master ]
|
4
Makefile
4
Makefile
|
@ -21,7 +21,7 @@ EXTRA_GOFLAGS ?=
|
||||||
|
|
||||||
LDFLAGS := -X "main.Version=$(shell git describe --tags --always | sed 's/-/+/' | sed 's/^v//')" -X "main.Tags=$(TAGS)"
|
LDFLAGS := -X "main.Version=$(shell git describe --tags --always | sed 's/-/+/' | sed 's/^v//')" -X "main.Tags=$(TAGS)"
|
||||||
|
|
||||||
PACKAGES ?= $(filter-out code.vikunja.io/api/integrations,$(shell go list ./... | grep -v /vendor/))
|
PACKAGES ?= $(filter-out code.vikunja.io/api/integrations,$(shell go list -mod=vendor ./... | grep -v /vendor/))
|
||||||
SOURCES ?= $(shell find . -name "*.go" -type f)
|
SOURCES ?= $(shell find . -name "*.go" -type f)
|
||||||
|
|
||||||
TAGS ?=
|
TAGS ?=
|
||||||
|
@ -56,7 +56,7 @@ clean:
|
||||||
|
|
||||||
.PHONY: test
|
.PHONY: test
|
||||||
test:
|
test:
|
||||||
go test -cover -coverprofile cover.out $(PACKAGES)
|
VIKUNJA_SERVICE_ROOTPATH=$(shell pwd) go test $(GOFLAGS) -cover -coverprofile cover.out $(PACKAGES)
|
||||||
go tool cover -html=cover.out -o cover.html
|
go tool cover -html=cover.out -o cover.html
|
||||||
|
|
||||||
required-gofmt-version:
|
required-gofmt-version:
|
||||||
|
|
|
@ -7,11 +7,15 @@ service:
|
||||||
interface: ":3456"
|
interface: ":3456"
|
||||||
# The URL of the frontend, used to send password reset emails.
|
# The URL of the frontend, used to send password reset emails.
|
||||||
frontendurl: ""
|
frontendurl: ""
|
||||||
|
# The base path on the file system where the binary and assets are.
|
||||||
|
# Vikunja will also look in this path for a config file, so you could provide only this variable to point to a folder
|
||||||
|
# with a config file which will then be used.
|
||||||
|
rootpath: <the path of the executable>
|
||||||
# The number of items which gets returned per page
|
# The number of items which gets returned per page
|
||||||
pagecount: 50
|
pagecount: 50
|
||||||
# If set to true, enables a /metrics endpoint for prometheus to collect metrics about the system
|
# If set to true, enables a /metrics endpoint for prometheus to collect metrics about the system
|
||||||
# You'll need to use redis for this in order to enable common metrics over multiple nodes
|
# You'll need to use redis for this in order to enable common metrics over multiple nodes
|
||||||
enablemetrics: true
|
enablemetrics: false
|
||||||
|
|
||||||
database:
|
database:
|
||||||
# Database type to use. Supported types are mysql and sqlite.
|
# Database type to use. Supported types are mysql and sqlite.
|
||||||
|
@ -31,6 +35,14 @@ database:
|
||||||
# Sets the max open connections to the database. Only used when using mysql.
|
# Sets the max open connections to the database. Only used when using mysql.
|
||||||
openconnections: 100
|
openconnections: 100
|
||||||
|
|
||||||
|
cache:
|
||||||
|
# If cache is enabled or not
|
||||||
|
enabled: false
|
||||||
|
# Cache type. Possible values are memory or redis, you'll need to enable redis below when using redis
|
||||||
|
type: memory
|
||||||
|
# When using memory this defines the maximum size an element can take
|
||||||
|
maxelementsize: 1000
|
||||||
|
|
||||||
redis:
|
redis:
|
||||||
# Whether to enable redis or not
|
# Whether to enable redis or not
|
||||||
enabled: false
|
enabled: false
|
||||||
|
@ -41,24 +53,20 @@ redis:
|
||||||
# 0 means default database
|
# 0 means default database
|
||||||
db: 0
|
db: 0
|
||||||
|
|
||||||
cache:
|
|
||||||
# If cache is enabled or not
|
|
||||||
enabled: false
|
|
||||||
# Cache type. Possible values are memory or redis, you'll need to enable redis below when using redis
|
|
||||||
type: memory
|
|
||||||
# When using memory this defines the maximum size an element can take
|
|
||||||
maxelementsize: 1000
|
|
||||||
|
|
||||||
mailer:
|
mailer:
|
||||||
# SMTP Host
|
# SMTP Host
|
||||||
host: ''
|
host: ""
|
||||||
# SMTP Host port
|
# SMTP Host port
|
||||||
port: 587
|
port: 587
|
||||||
# SMTP username
|
# SMTP username
|
||||||
username: 'user'
|
username: "user"
|
||||||
# SMTP password
|
# SMTP password
|
||||||
password: ''
|
password: ""
|
||||||
# Wether to skip verification of the tls certificate on the server
|
# Wether to skip verification of the tls certificate on the server
|
||||||
skiptlsverify: false
|
skiptlsverify: false
|
||||||
# The default from address when sending emails
|
# The default from address when sending emails
|
||||||
fromemail: 'mail@vikunja'
|
fromemail: "mail@vikunja"
|
||||||
|
# The length of the mail queue.
|
||||||
|
queuelength: 100
|
||||||
|
# The timeout in seconds after which the current open connection to the mailserver will be closed.
|
||||||
|
queuetimeout: 30
|
|
@ -19,7 +19,7 @@ first:
|
||||||
|
|
||||||
# Default configuration with explanations
|
# Default configuration with explanations
|
||||||
|
|
||||||
This is the same as the `config.yaml` file you'll find in the root of vikunja.
|
This is the same as the `config.yml.sample` file you'll find in the root of vikunja.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
service:
|
service:
|
||||||
|
@ -31,7 +31,9 @@ service:
|
||||||
interface: ":3456"
|
interface: ":3456"
|
||||||
# The URL of the frontend, used to send password reset emails.
|
# The URL of the frontend, used to send password reset emails.
|
||||||
frontendurl: ""
|
frontendurl: ""
|
||||||
# The base path on the file system where the binary and assets are
|
# The base path on the file system where the binary and assets are.
|
||||||
|
# Vikunja will also look in this path for a config file, so you could provide only this variable to point to a folder
|
||||||
|
# with a config file which will then be used.
|
||||||
rootpath: <the path of the executable>
|
rootpath: <the path of the executable>
|
||||||
# The number of items which gets returned per page
|
# The number of items which gets returned per page
|
||||||
pagecount: 50
|
pagecount: 50
|
||||||
|
|
17
docs/test.md
Normal file
17
docs/test.md
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
# Testing
|
||||||
|
|
||||||
|
You can run unit tests with our `Makefile` with
|
||||||
|
|
||||||
|
```bash
|
||||||
|
make test
|
||||||
|
```
|
||||||
|
|
||||||
|
### Running tests with config
|
||||||
|
|
||||||
|
You can run tests with all available config variables if you want, enabeling you to run tests for a lot of scenarios.
|
||||||
|
|
||||||
|
To use the normal config set the enviroment variable `VIKUNJA_TESTS_USE_CONFIG=1`.
|
||||||
|
|
||||||
|
### Show sql queries
|
||||||
|
|
||||||
|
When `UNIT_TESTS_VERBOSE=1` is set, all sql queries will be shown when tests are run.
|
21
go.mod
21
go.mod
|
@ -17,13 +17,12 @@
|
||||||
module code.vikunja.io/api
|
module code.vikunja.io/api
|
||||||
|
|
||||||
require (
|
require (
|
||||||
cloud.google.com/go v0.30.0 // indirect
|
cloud.google.com/go v0.34.0 // indirect
|
||||||
code.vikunja.io/web v0.0.0-20181130231148-b061c20192fb
|
code.vikunja.io/web v0.0.0-20181130231148-b061c20192fb
|
||||||
github.com/BurntSushi/toml v0.3.1 // indirect
|
github.com/BurntSushi/toml v0.3.1 // indirect
|
||||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc
|
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc
|
||||||
github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf
|
github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf
|
||||||
github.com/client9/misspell v0.3.4
|
github.com/client9/misspell v0.3.4
|
||||||
github.com/denisenkom/go-mssqldb v0.0.0-20180901172138-1eb28afdf9b6 // indirect
|
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
||||||
github.com/fzipp/gocyclo v0.0.0-20150627053110-6acd4345c835
|
github.com/fzipp/gocyclo v0.0.0-20150627053110-6acd4345c835
|
||||||
github.com/garyburd/redigo v1.6.0 // indirect
|
github.com/garyburd/redigo v1.6.0 // indirect
|
||||||
|
@ -31,23 +30,22 @@ require (
|
||||||
github.com/go-openapi/spec v0.17.2 // indirect
|
github.com/go-openapi/spec v0.17.2 // indirect
|
||||||
github.com/go-openapi/swag v0.17.2 // indirect
|
github.com/go-openapi/swag v0.17.2 // indirect
|
||||||
github.com/go-redis/redis v6.14.2+incompatible
|
github.com/go-redis/redis v6.14.2+incompatible
|
||||||
github.com/go-sql-driver/mysql v0.0.0-20171007150158-ee359f95877b
|
github.com/go-sql-driver/mysql v1.4.1
|
||||||
github.com/go-xorm/builder v0.0.0-20170519032130-c8871c857d25 // indirect
|
github.com/go-xorm/builder v0.0.0-20170519032130-c8871c857d25 // indirect
|
||||||
github.com/go-xorm/core v0.5.8
|
github.com/go-xorm/core v0.5.8
|
||||||
github.com/go-xorm/tests v0.5.6 // indirect
|
github.com/go-xorm/tests v0.5.6 // indirect
|
||||||
github.com/go-xorm/xorm v0.0.0-20170930012613-29d4a0330a00
|
github.com/go-xorm/xorm v0.0.0-20170930012613-29d4a0330a00
|
||||||
github.com/go-xorm/xorm-redis-cache v0.0.0-20180727005610-859b313566b2
|
github.com/go-xorm/xorm-redis-cache v0.0.0-20180727005610-859b313566b2
|
||||||
github.com/google/go-cmp v0.2.0 // indirect
|
|
||||||
github.com/gordonklaus/ineffassign v0.0.0-20180909121442-1003c8bd00dc
|
github.com/gordonklaus/ineffassign v0.0.0-20180909121442-1003c8bd00dc
|
||||||
github.com/imdario/mergo v0.3.6
|
github.com/imdario/mergo v0.3.6
|
||||||
github.com/joho/godotenv v1.3.0 // indirect
|
|
||||||
github.com/karalabe/xgo v0.0.0-20181007145344-72da7d1d3970
|
github.com/karalabe/xgo v0.0.0-20181007145344-72da7d1d3970
|
||||||
github.com/labstack/echo v3.3.5+incompatible
|
github.com/labstack/echo v3.3.5+incompatible
|
||||||
github.com/labstack/gommon v0.2.8
|
github.com/labstack/gommon v0.2.8
|
||||||
github.com/lib/pq v1.0.0 // indirect
|
github.com/mattn/go-oci8 v0.0.0-20181130072307-052f5d97b9b6 // indirect
|
||||||
github.com/mattn/go-oci8 v0.0.0-20181011085415-1a014d1384b5 // indirect
|
github.com/mattn/go-sqlite3 v1.10.0
|
||||||
github.com/mattn/go-sqlite3 v1.9.0
|
|
||||||
github.com/mitchellh/mapstructure v1.1.2 // indirect
|
github.com/mitchellh/mapstructure v1.1.2 // indirect
|
||||||
|
github.com/onsi/ginkgo v1.7.0 // indirect
|
||||||
|
github.com/onsi/gomega v1.4.3 // indirect
|
||||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
|
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7
|
||||||
github.com/pkg/errors v0.8.0 // indirect
|
github.com/pkg/errors v0.8.0 // indirect
|
||||||
github.com/prometheus/client_golang v0.9.2
|
github.com/prometheus/client_golang v0.9.2
|
||||||
|
@ -59,10 +57,13 @@ require (
|
||||||
github.com/swaggo/swag v1.4.1-0.20181129020348-1c8533a91397
|
github.com/swaggo/swag v1.4.1-0.20181129020348-1c8533a91397
|
||||||
github.com/urfave/cli v1.20.0 // indirect
|
github.com/urfave/cli v1.20.0 // indirect
|
||||||
github.com/ziutek/mymysql v1.5.4 // indirect
|
github.com/ziutek/mymysql v1.5.4 // indirect
|
||||||
golang.org/x/crypto v0.0.0-20181127143415-eb0de9b17e85
|
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9
|
||||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3
|
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3
|
||||||
|
golang.org/x/net v0.0.0-20181217023233-e147a9138326 // indirect
|
||||||
golang.org/x/tools v0.0.0-20181026183834-f60e5f99f081 // indirect
|
golang.org/x/tools v0.0.0-20181026183834-f60e5f99f081 // indirect
|
||||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
|
||||||
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
|
||||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
|
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
|
||||||
gopkg.in/testfixtures.v2 v2.4.5
|
gopkg.in/testfixtures.v2 v2.5.3
|
||||||
|
gopkg.in/yaml.v2 v2.2.2 // indirect
|
||||||
)
|
)
|
||||||
|
|
37
go.sum
37
go.sum
|
@ -1,5 +1,7 @@
|
||||||
cloud.google.com/go v0.30.0 h1:xKvyLgk56d0nksWq49J0UyGEeUIicTl4+UBiX1NPX9g=
|
cloud.google.com/go v0.30.0 h1:xKvyLgk56d0nksWq49J0UyGEeUIicTl4+UBiX1NPX9g=
|
||||||
cloud.google.com/go v0.30.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.30.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
|
cloud.google.com/go v0.33.1/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
|
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
code.vikunja.io/web v0.0.0-20181130221802-d23d2a4c1efb h1:OyXe+z31V3xUUEOv/kVJmkfp/9y/YdlaKjfhGpDAmNQ=
|
code.vikunja.io/web v0.0.0-20181130221802-d23d2a4c1efb h1:OyXe+z31V3xUUEOv/kVJmkfp/9y/YdlaKjfhGpDAmNQ=
|
||||||
code.vikunja.io/web v0.0.0-20181130221802-d23d2a4c1efb/go.mod h1:PmGEu9qI7nbEKDn38H0SWgCoGO4GLdbjdlnWSzFi2PA=
|
code.vikunja.io/web v0.0.0-20181130221802-d23d2a4c1efb/go.mod h1:PmGEu9qI7nbEKDn38H0SWgCoGO4GLdbjdlnWSzFi2PA=
|
||||||
code.vikunja.io/web v0.0.0-20181130231148-b061c20192fb h1:LROmRUOGTxOpOxKy9S6XONDnT+t0v0j8+MZCedssTCc=
|
code.vikunja.io/web v0.0.0-20181130231148-b061c20192fb h1:LROmRUOGTxOpOxKy9S6XONDnT+t0v0j8+MZCedssTCc=
|
||||||
|
@ -23,6 +25,7 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/denisenkom/go-mssqldb v0.0.0-20180901172138-1eb28afdf9b6 h1:BZGp1dbKFjqlGmxEpwkDpCWNxVwEYnUPoncIzLiHlPo=
|
github.com/denisenkom/go-mssqldb v0.0.0-20180901172138-1eb28afdf9b6 h1:BZGp1dbKFjqlGmxEpwkDpCWNxVwEYnUPoncIzLiHlPo=
|
||||||
github.com/denisenkom/go-mssqldb v0.0.0-20180901172138-1eb28afdf9b6/go.mod h1:xN/JuLBIz4bjkxNmByTiV1IbhfnYb6oo99phBn4Eqhc=
|
github.com/denisenkom/go-mssqldb v0.0.0-20180901172138-1eb28afdf9b6/go.mod h1:xN/JuLBIz4bjkxNmByTiV1IbhfnYb6oo99phBn4Eqhc=
|
||||||
|
github.com/denisenkom/go-mssqldb v0.0.0-20181014144952-4e0d7dc8888f/go.mod h1:xN/JuLBIz4bjkxNmByTiV1IbhfnYb6oo99phBn4Eqhc=
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||||
|
@ -46,6 +49,8 @@ github.com/go-redis/redis v6.14.2+incompatible h1:UE9pLhzmWf+xHNmZsoccjXosPicuiN
|
||||||
github.com/go-redis/redis v6.14.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
github.com/go-redis/redis v6.14.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
|
||||||
github.com/go-sql-driver/mysql v0.0.0-20171007150158-ee359f95877b h1:/CMGgAYard7jx9+bI7tUIqafFDR7Pv2BRu2Tb5dDaqM=
|
github.com/go-sql-driver/mysql v0.0.0-20171007150158-ee359f95877b h1:/CMGgAYard7jx9+bI7tUIqafFDR7Pv2BRu2Tb5dDaqM=
|
||||||
github.com/go-sql-driver/mysql v0.0.0-20171007150158-ee359f95877b/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
github.com/go-sql-driver/mysql v0.0.0-20171007150158-ee359f95877b/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||||
|
github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA=
|
||||||
|
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||||
github.com/go-xorm/builder v0.0.0-20170519032130-c8871c857d25 h1:jUX9yw6+iKrs/WuysV2M6ap/ObK/07SE/a7I2uxitwM=
|
github.com/go-xorm/builder v0.0.0-20170519032130-c8871c857d25 h1:jUX9yw6+iKrs/WuysV2M6ap/ObK/07SE/a7I2uxitwM=
|
||||||
github.com/go-xorm/builder v0.0.0-20170519032130-c8871c857d25/go.mod h1:M+P3wv0K2C+ynucGDEqJCeOTc+6DcAtiiqU8GrCksXY=
|
github.com/go-xorm/builder v0.0.0-20170519032130-c8871c857d25/go.mod h1:M+P3wv0K2C+ynucGDEqJCeOTc+6DcAtiiqU8GrCksXY=
|
||||||
github.com/go-xorm/core v0.5.8 h1:vQ0ghlVGnlnFmm4SpHY+xNnPlH810paMcw+Hwz9BCqE=
|
github.com/go-xorm/core v0.5.8 h1:vQ0ghlVGnlnFmm4SpHY+xNnPlH810paMcw+Hwz9BCqE=
|
||||||
|
@ -64,6 +69,8 @@ github.com/gordonklaus/ineffassign v0.0.0-20180909121442-1003c8bd00dc h1:cJlkeAx
|
||||||
github.com/gordonklaus/ineffassign v0.0.0-20180909121442-1003c8bd00dc/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU=
|
github.com/gordonklaus/ineffassign v0.0.0-20180909121442-1003c8bd00dc/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU=
|
||||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||||
|
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||||
|
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||||
github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28=
|
github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28=
|
||||||
github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||||
github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
|
github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
|
||||||
|
@ -89,14 +96,23 @@ github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs
|
||||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||||
github.com/mattn/go-oci8 v0.0.0-20181011085415-1a014d1384b5 h1:+IPgoz43mdEYG5lrqNcjr3DQpAE38SqHtyx1IsqqQGM=
|
github.com/mattn/go-oci8 v0.0.0-20181011085415-1a014d1384b5 h1:+IPgoz43mdEYG5lrqNcjr3DQpAE38SqHtyx1IsqqQGM=
|
||||||
github.com/mattn/go-oci8 v0.0.0-20181011085415-1a014d1384b5/go.mod h1:/M9VLO+lUPmxvoOK2PfWRZ8mTtB4q1Hy9lEGijv9Nr8=
|
github.com/mattn/go-oci8 v0.0.0-20181011085415-1a014d1384b5/go.mod h1:/M9VLO+lUPmxvoOK2PfWRZ8mTtB4q1Hy9lEGijv9Nr8=
|
||||||
|
github.com/mattn/go-oci8 v0.0.0-20181115070430-6eefff3c767c/go.mod h1:/M9VLO+lUPmxvoOK2PfWRZ8mTtB4q1Hy9lEGijv9Nr8=
|
||||||
|
github.com/mattn/go-oci8 v0.0.0-20181130072307-052f5d97b9b6/go.mod h1:/M9VLO+lUPmxvoOK2PfWRZ8mTtB4q1Hy9lEGijv9Nr8=
|
||||||
github.com/mattn/go-sqlite3 v1.9.0 h1:pDRiWfl+++eC2FEFRy6jXmQlvp4Yh3z1MJKg4UeYM/4=
|
github.com/mattn/go-sqlite3 v1.9.0 h1:pDRiWfl+++eC2FEFRy6jXmQlvp4Yh3z1MJKg4UeYM/4=
|
||||||
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||||
|
github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o=
|
||||||
|
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||||
github.com/mitchellh/mapstructure v1.0.0 h1:vVpGvMXJPqSDh2VYHF7gsfQj8Ncx+Xw5Y1KHeTRY+7I=
|
github.com/mitchellh/mapstructure v1.0.0 h1:vVpGvMXJPqSDh2VYHF7gsfQj8Ncx+Xw5Y1KHeTRY+7I=
|
||||||
github.com/mitchellh/mapstructure v1.0.0/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
github.com/mitchellh/mapstructure v1.0.0/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||||
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
||||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||||
|
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
|
github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
|
||||||
|
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
|
github.com/onsi/gomega v1.4.3 h1:RE1xgDvH7imwFD45h+u2SgIfERHlS2yNG4DObb5BSKU=
|
||||||
|
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 h1:lDH9UUVJtmYCjyT0CI4q8xvlXPxeZ0gYCVvWbmPlp88=
|
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7 h1:lDH9UUVJtmYCjyT0CI4q8xvlXPxeZ0gYCVvWbmPlp88=
|
||||||
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
|
github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk=
|
||||||
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
|
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
|
||||||
|
@ -144,17 +160,27 @@ github.com/valyala/fasttemplate v0.0.0-20170224212429-dcecefd839c4/go.mod h1:50w
|
||||||
github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs=
|
github.com/ziutek/mymysql v1.5.4 h1:GB0qdRGsTwQSBVYuVShFBKaXSnSnYYC2d9knnE1LHFs=
|
||||||
github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
|
github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
|
||||||
golang.org/x/crypto v0.0.0-20181106171534-e4dc69e5b2fd/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20181106171534-e4dc69e5b2fd/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/crypto v0.0.0-20181112202954-3d3f9f413869/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20181127143415-eb0de9b17e85 h1:et7+NAX3lLIk5qUCTA9QelBjGE/NkhzYw/mhnr0s7nI=
|
golang.org/x/crypto v0.0.0-20181127143415-eb0de9b17e85 h1:et7+NAX3lLIk5qUCTA9QelBjGE/NkhzYw/mhnr0s7nI=
|
||||||
golang.org/x/crypto v0.0.0-20181127143415-eb0de9b17e85/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20181127143415-eb0de9b17e85/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9 h1:mKdxBk7AujPs8kU4m80U72y/zjbZ3UcXC7dClwKbUI0=
|
||||||
|
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3 h1:x/bBzNauLQAlE3fLku/xy92Y8QwKX5HZymrMz2IiKFc=
|
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3 h1:x/bBzNauLQAlE3fLku/xy92Y8QwKX5HZymrMz2IiKFc=
|
||||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20181005035420-146acd28ed58 h1:otZG8yDCO4LVps5+9bxOeNiCvgmOyt96J3roHTYs7oE=
|
golang.org/x/net v0.0.0-20181005035420-146acd28ed58 h1:otZG8yDCO4LVps5+9bxOeNiCvgmOyt96J3roHTYs7oE=
|
||||||
golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc h1:a3CU5tJYVj92DY2LaA1kUkrsqD5/3mLDhx2NcNqyW+0=
|
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc h1:a3CU5tJYVj92DY2LaA1kUkrsqD5/3mLDhx2NcNqyW+0=
|
||||||
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/net v0.0.0-20181217023233-e147a9138326 h1:iCzOf0xz39Tstp+Tu/WwyGjUXCk34QhQORRxBeXXTA4=
|
||||||
|
golang.org/x/net v0.0.0-20181217023233-e147a9138326/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f h1:Bl/8QSvNqXvPGPGXa2z5xUTmV7VDcZyvRZ+QQXkXTZQ=
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sys v0.0.0-20180906133057-8cf3aee42992 h1:BH3eQWeGbwRU2+wxxuuPOdFBmaiBH81O8BugSjHeTFg=
|
golang.org/x/sys v0.0.0-20180906133057-8cf3aee42992 h1:BH3eQWeGbwRU2+wxxuuPOdFBmaiBH81O8BugSjHeTFg=
|
||||||
golang.org/x/sys v0.0.0-20180906133057-8cf3aee42992/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180906133057-8cf3aee42992/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20181128092732-4ed8d59d0b35 h1:YAFjXN64LMvktoUZH9zgY4lGc/msGN7HQfoSuKCgaDU=
|
golang.org/x/sys v0.0.0-20181128092732-4ed8d59d0b35 h1:YAFjXN64LMvktoUZH9zgY4lGc/msGN7HQfoSuKCgaDU=
|
||||||
golang.org/x/sys v0.0.0-20181128092732-4ed8d59d0b35/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20181128092732-4ed8d59d0b35/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
@ -162,13 +188,24 @@ golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/tools v0.0.0-20181026183834-f60e5f99f081 h1:QJP9sxq2/KbTxFnGduVryxJOt6r/UVGyom3tLaqu7tc=
|
golang.org/x/tools v0.0.0-20181026183834-f60e5f99f081 h1:QJP9sxq2/KbTxFnGduVryxJOt6r/UVGyom3tLaqu7tc=
|
||||||
golang.org/x/tools v0.0.0-20181026183834-f60e5f99f081/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20181026183834-f60e5f99f081/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
|
google.golang.org/appengine v1.3.0 h1:FBSsiFRMz3LBeXIomRnVzrQwSDj4ibvcRexLG0LZGQk=
|
||||||
|
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
|
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
|
||||||
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
|
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
|
||||||
|
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AWRXxgwEyPp2z+p0+hgMuE=
|
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AWRXxgwEyPp2z+p0+hgMuE=
|
||||||
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw=
|
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw=
|
||||||
gopkg.in/testfixtures.v2 v2.4.5 h1:mnfYPBNoJnis+4crs6UzC4lv4GjTVoLXE9B/tW802q0=
|
gopkg.in/testfixtures.v2 v2.4.5 h1:mnfYPBNoJnis+4crs6UzC4lv4GjTVoLXE9B/tW802q0=
|
||||||
gopkg.in/testfixtures.v2 v2.4.5/go.mod h1:vyAq+MYCgNpR29qitQdLZhdbLFf4mR/2MFJRFoQZZ2M=
|
gopkg.in/testfixtures.v2 v2.4.5/go.mod h1:vyAq+MYCgNpR29qitQdLZhdbLFf4mR/2MFJRFoQZZ2M=
|
||||||
|
gopkg.in/testfixtures.v2 v2.5.3 h1:P8gDACSLJGxutzBqbzvfiXYgmQ2s00LIr4uAvWBCPAg=
|
||||||
|
gopkg.in/testfixtures.v2 v2.5.3/go.mod h1:rGPtsOtPcZhs7AsHYf1WmufW1hEsM6DXdLrYz60nrQQ=
|
||||||
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||||
|
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||||
gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
|
gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
|
||||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||||
|
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||||
|
|
|
@ -40,6 +40,7 @@ func init() {
|
||||||
viper.SetDefault("service.JWTSecret", random)
|
viper.SetDefault("service.JWTSecret", random)
|
||||||
viper.SetDefault("service.interface", ":3456")
|
viper.SetDefault("service.interface", ":3456")
|
||||||
viper.SetDefault("service.frontendurl", "")
|
viper.SetDefault("service.frontendurl", "")
|
||||||
|
|
||||||
ex, err := os.Executable()
|
ex, err := os.Executable()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
@ -82,6 +83,8 @@ func init() {
|
||||||
viper.AutomaticEnv()
|
viper.AutomaticEnv()
|
||||||
|
|
||||||
// Load the config file
|
// Load the config file
|
||||||
|
viper.AddConfigPath(exPath)
|
||||||
|
viper.AddConfigPath(viper.GetString("service.rootpath"))
|
||||||
viper.AddConfigPath(".")
|
viper.AddConfigPath(".")
|
||||||
viper.SetConfigName("config")
|
viper.SetConfigName("config")
|
||||||
err = viper.ReadInConfig()
|
err = viper.ReadInConfig()
|
||||||
|
|
|
@ -14,10 +14,29 @@
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
// Vikunja is a todo-list application to facilitate your life.
|
||||||
|
// Copyright 2018 Vikunja and contributors. All rights reserved.
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
package models
|
package models
|
||||||
|
|
||||||
import "testing"
|
import (
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
func TestMain(m *testing.M) {
|
func TestMain(m *testing.M) {
|
||||||
MainTest(m, "..")
|
MainTest(m, viper.GetString("service.rootpath"))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
// Vikunja is a todo-list application to facilitate your life.
|
|
||||||
// Copyright 2018 Vikunja and contributors. All rights reserved.
|
|
||||||
//
|
|
||||||
// This program is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
package models
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/spf13/viper"
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
"testing"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestSetEngine(t *testing.T) {
|
|
||||||
viper.Set("database.path", "file::memory:?cache=shared")
|
|
||||||
err := SetEngine()
|
|
||||||
assert.NoError(t, err)
|
|
||||||
}
|
|
|
@ -23,6 +23,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/go-xorm/core"
|
"github.com/go-xorm/core"
|
||||||
"github.com/go-xorm/xorm"
|
"github.com/go-xorm/xorm"
|
||||||
|
"github.com/spf13/viper"
|
||||||
"gopkg.in/testfixtures.v2"
|
"gopkg.in/testfixtures.v2"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
@ -36,7 +37,7 @@ var IsTesting bool
|
||||||
// MainTest creates the test engine
|
// MainTest creates the test engine
|
||||||
func MainTest(m *testing.M, pathToRoot string) {
|
func MainTest(m *testing.M, pathToRoot string) {
|
||||||
var err error
|
var err error
|
||||||
fixturesDir := filepath.Join(pathToRoot, "models", "fixtures")
|
fixturesDir := filepath.Join(pathToRoot, "pkg", "models", "fixtures")
|
||||||
if err = createTestEngine(fixturesDir); err != nil {
|
if err = createTestEngine(fixturesDir); err != nil {
|
||||||
log.Log.Fatalf("Error creating test engine: %v\n", err)
|
log.Log.Fatalf("Error creating test engine: %v\n", err)
|
||||||
}
|
}
|
||||||
|
@ -48,7 +49,7 @@ func MainTest(m *testing.M, pathToRoot string) {
|
||||||
|
|
||||||
// Create test database
|
// Create test database
|
||||||
if err = PrepareTestDatabase(); err != nil {
|
if err = PrepareTestDatabase(); err != nil {
|
||||||
log.Log.Fatal(err.Error())
|
log.Log.Fatalf("Error preparing test database: %v", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
os.Exit(m.Run())
|
os.Exit(m.Run())
|
||||||
|
@ -56,24 +57,39 @@ func MainTest(m *testing.M, pathToRoot string) {
|
||||||
|
|
||||||
func createTestEngine(fixturesDir string) error {
|
func createTestEngine(fixturesDir string) error {
|
||||||
var err error
|
var err error
|
||||||
x, err = xorm.NewEngine("sqlite3", "file::memory:?cache=shared")
|
// If set, use the config we provided instead of normal
|
||||||
//x, err = xorm.NewEngine("sqlite3", "db.db")
|
if os.Getenv("VIKUNJA_TESTS_USE_CONFIG") == "1" {
|
||||||
if err != nil {
|
err = SetEngine()
|
||||||
return err
|
if err != nil {
|
||||||
}
|
return err
|
||||||
x.SetMapper(core.GonicMapper{})
|
}
|
||||||
|
} else {
|
||||||
|
x, err = xorm.NewEngine("sqlite3", "file::memory:?cache=shared")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// Sync dat shit
|
x.SetMapper(core.GonicMapper{})
|
||||||
if err = x.StoreEngine("InnoDB").Sync2(tables...); err != nil {
|
|
||||||
return fmt.Errorf("sync database struct error: %v", err)
|
// Sync dat shit
|
||||||
|
if err := x.StoreEngine("InnoDB").Sync2(tables...); err != nil {
|
||||||
|
return fmt.Errorf("sync database struct error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show SQL-Queries if necessary
|
||||||
|
if os.Getenv("UNIT_TESTS_VERBOSE") == "1" {
|
||||||
|
x.ShowSQL(true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show SQL-Queries if necessary
|
var fixturesHelper testfixtures.Helper
|
||||||
if os.Getenv("UNIT_TESTS_VERBOSE") == "1" {
|
if viper.GetString("database.type") == "mysql" {
|
||||||
x.ShowSQL(true)
|
fixturesHelper = &testfixtures.MySQL{}
|
||||||
|
} else {
|
||||||
|
fixturesHelper = &testfixtures.SQLite{}
|
||||||
}
|
}
|
||||||
|
|
||||||
return InitFixtures(&testfixtures.SQLite{}, fixturesDir)
|
return InitFixtures(fixturesHelper, fixturesDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PrepareTestDatabase load test fixtures into test database
|
// PrepareTestDatabase load test fixtures into test database
|
||||||
|
|
52
vendor/github.com/go-sql-driver/mysql/.travis.yml
generated
vendored
52
vendor/github.com/go-sql-driver/mysql/.travis.yml
generated
vendored
|
@ -1,12 +1,11 @@
|
||||||
sudo: false
|
sudo: false
|
||||||
language: go
|
language: go
|
||||||
go:
|
go:
|
||||||
- 1.5
|
- 1.7.x
|
||||||
- 1.6
|
- 1.8.x
|
||||||
- 1.7
|
- 1.9.x
|
||||||
- 1.8
|
- 1.10.x
|
||||||
- 1.9
|
- master
|
||||||
- tip
|
|
||||||
|
|
||||||
before_install:
|
before_install:
|
||||||
- go get golang.org/x/tools/cmd/cover
|
- go get golang.org/x/tools/cmd/cover
|
||||||
|
@ -20,10 +19,30 @@ before_script:
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
|
- env: DB=MYSQL8
|
||||||
|
sudo: required
|
||||||
|
dist: trusty
|
||||||
|
go: 1.10.x
|
||||||
|
services:
|
||||||
|
- docker
|
||||||
|
before_install:
|
||||||
|
- go get golang.org/x/tools/cmd/cover
|
||||||
|
- go get github.com/mattn/goveralls
|
||||||
|
- docker pull mysql:8.0
|
||||||
|
- docker run -d -p 127.0.0.1:3307:3306 --name mysqld -e MYSQL_DATABASE=gotest -e MYSQL_USER=gotest -e MYSQL_PASSWORD=secret -e MYSQL_ROOT_PASSWORD=verysecret
|
||||||
|
mysql:8.0 --innodb_log_file_size=256MB --innodb_buffer_pool_size=512MB --max_allowed_packet=16MB --local-infile=1
|
||||||
|
- cp .travis/docker.cnf ~/.my.cnf
|
||||||
|
- .travis/wait_mysql.sh
|
||||||
|
before_script:
|
||||||
|
- export MYSQL_TEST_USER=gotest
|
||||||
|
- export MYSQL_TEST_PASS=secret
|
||||||
|
- export MYSQL_TEST_ADDR=127.0.0.1:3307
|
||||||
|
- export MYSQL_TEST_CONCURRENT=1
|
||||||
|
|
||||||
- env: DB=MYSQL57
|
- env: DB=MYSQL57
|
||||||
sudo: required
|
sudo: required
|
||||||
dist: trusty
|
dist: trusty
|
||||||
go: 1.9
|
go: 1.10.x
|
||||||
services:
|
services:
|
||||||
- docker
|
- docker
|
||||||
before_install:
|
before_install:
|
||||||
|
@ -31,10 +50,8 @@ matrix:
|
||||||
- go get github.com/mattn/goveralls
|
- go get github.com/mattn/goveralls
|
||||||
- docker pull mysql:5.7
|
- docker pull mysql:5.7
|
||||||
- docker run -d -p 127.0.0.1:3307:3306 --name mysqld -e MYSQL_DATABASE=gotest -e MYSQL_USER=gotest -e MYSQL_PASSWORD=secret -e MYSQL_ROOT_PASSWORD=verysecret
|
- docker run -d -p 127.0.0.1:3307:3306 --name mysqld -e MYSQL_DATABASE=gotest -e MYSQL_USER=gotest -e MYSQL_PASSWORD=secret -e MYSQL_ROOT_PASSWORD=verysecret
|
||||||
mysql:5.7 --innodb_log_file_size=256MB --innodb_buffer_pool_size=512MB --max_allowed_packet=16MB
|
mysql:5.7 --innodb_log_file_size=256MB --innodb_buffer_pool_size=512MB --max_allowed_packet=16MB --local-infile=1
|
||||||
- sleep 30
|
|
||||||
- cp .travis/docker.cnf ~/.my.cnf
|
- cp .travis/docker.cnf ~/.my.cnf
|
||||||
- mysql --print-defaults
|
|
||||||
- .travis/wait_mysql.sh
|
- .travis/wait_mysql.sh
|
||||||
before_script:
|
before_script:
|
||||||
- export MYSQL_TEST_USER=gotest
|
- export MYSQL_TEST_USER=gotest
|
||||||
|
@ -45,7 +62,7 @@ matrix:
|
||||||
- env: DB=MARIA55
|
- env: DB=MARIA55
|
||||||
sudo: required
|
sudo: required
|
||||||
dist: trusty
|
dist: trusty
|
||||||
go: 1.9
|
go: 1.10.x
|
||||||
services:
|
services:
|
||||||
- docker
|
- docker
|
||||||
before_install:
|
before_install:
|
||||||
|
@ -53,10 +70,8 @@ matrix:
|
||||||
- go get github.com/mattn/goveralls
|
- go get github.com/mattn/goveralls
|
||||||
- docker pull mariadb:5.5
|
- docker pull mariadb:5.5
|
||||||
- docker run -d -p 127.0.0.1:3307:3306 --name mysqld -e MYSQL_DATABASE=gotest -e MYSQL_USER=gotest -e MYSQL_PASSWORD=secret -e MYSQL_ROOT_PASSWORD=verysecret
|
- docker run -d -p 127.0.0.1:3307:3306 --name mysqld -e MYSQL_DATABASE=gotest -e MYSQL_USER=gotest -e MYSQL_PASSWORD=secret -e MYSQL_ROOT_PASSWORD=verysecret
|
||||||
mariadb:5.5 --innodb_log_file_size=256MB --innodb_buffer_pool_size=512MB --max_allowed_packet=16MB
|
mariadb:5.5 --innodb_log_file_size=256MB --innodb_buffer_pool_size=512MB --max_allowed_packet=16MB --local-infile=1
|
||||||
- sleep 30
|
|
||||||
- cp .travis/docker.cnf ~/.my.cnf
|
- cp .travis/docker.cnf ~/.my.cnf
|
||||||
- mysql --print-defaults
|
|
||||||
- .travis/wait_mysql.sh
|
- .travis/wait_mysql.sh
|
||||||
before_script:
|
before_script:
|
||||||
- export MYSQL_TEST_USER=gotest
|
- export MYSQL_TEST_USER=gotest
|
||||||
|
@ -67,7 +82,7 @@ matrix:
|
||||||
- env: DB=MARIA10_1
|
- env: DB=MARIA10_1
|
||||||
sudo: required
|
sudo: required
|
||||||
dist: trusty
|
dist: trusty
|
||||||
go: 1.9
|
go: 1.10.x
|
||||||
services:
|
services:
|
||||||
- docker
|
- docker
|
||||||
before_install:
|
before_install:
|
||||||
|
@ -75,10 +90,8 @@ matrix:
|
||||||
- go get github.com/mattn/goveralls
|
- go get github.com/mattn/goveralls
|
||||||
- docker pull mariadb:10.1
|
- docker pull mariadb:10.1
|
||||||
- docker run -d -p 127.0.0.1:3307:3306 --name mysqld -e MYSQL_DATABASE=gotest -e MYSQL_USER=gotest -e MYSQL_PASSWORD=secret -e MYSQL_ROOT_PASSWORD=verysecret
|
- docker run -d -p 127.0.0.1:3307:3306 --name mysqld -e MYSQL_DATABASE=gotest -e MYSQL_USER=gotest -e MYSQL_PASSWORD=secret -e MYSQL_ROOT_PASSWORD=verysecret
|
||||||
mariadb:10.1 --innodb_log_file_size=256MB --innodb_buffer_pool_size=512MB --max_allowed_packet=16MB
|
mariadb:10.1 --innodb_log_file_size=256MB --innodb_buffer_pool_size=512MB --max_allowed_packet=16MB --local-infile=1
|
||||||
- sleep 30
|
|
||||||
- cp .travis/docker.cnf ~/.my.cnf
|
- cp .travis/docker.cnf ~/.my.cnf
|
||||||
- mysql --print-defaults
|
|
||||||
- .travis/wait_mysql.sh
|
- .travis/wait_mysql.sh
|
||||||
before_script:
|
before_script:
|
||||||
- export MYSQL_TEST_USER=gotest
|
- export MYSQL_TEST_USER=gotest
|
||||||
|
@ -89,5 +102,6 @@ matrix:
|
||||||
script:
|
script:
|
||||||
- go test -v -covermode=count -coverprofile=coverage.out
|
- go test -v -covermode=count -coverprofile=coverage.out
|
||||||
- go vet ./...
|
- go vet ./...
|
||||||
- test -z "$(gofmt -d -s . | tee /dev/stderr)"
|
- .travis/gofmt.sh
|
||||||
|
after_script:
|
||||||
- $HOME/gopath/bin/goveralls -coverprofile=coverage.out -service=travis-ci
|
- $HOME/gopath/bin/goveralls -coverprofile=coverage.out -service=travis-ci
|
||||||
|
|
17
vendor/github.com/go-sql-driver/mysql/AUTHORS
generated
vendored
17
vendor/github.com/go-sql-driver/mysql/AUTHORS
generated
vendored
|
@ -13,11 +13,15 @@
|
||||||
|
|
||||||
Aaron Hopkins <go-sql-driver at die.net>
|
Aaron Hopkins <go-sql-driver at die.net>
|
||||||
Achille Roussel <achille.roussel at gmail.com>
|
Achille Roussel <achille.roussel at gmail.com>
|
||||||
|
Alexey Palazhchenko <alexey.palazhchenko at gmail.com>
|
||||||
|
Andrew Reid <andrew.reid at tixtrack.com>
|
||||||
Arne Hormann <arnehormann at gmail.com>
|
Arne Hormann <arnehormann at gmail.com>
|
||||||
Asta Xie <xiemengjun at gmail.com>
|
Asta Xie <xiemengjun at gmail.com>
|
||||||
Bulat Gaifullin <gaifullinbf 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>
|
||||||
|
Craig Wilson <craiggwilson at gmail.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>
|
Dave Protasowski <dprotaso at gmail.com>
|
||||||
|
@ -26,6 +30,7 @@ Egor Smolyakov <egorsmkv at gmail.com>
|
||||||
Evan Shaw <evan at vendhq.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>
|
||||||
|
Hajime Nakagami <nakagami 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>
|
||||||
|
@ -34,20 +39,24 @@ 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>
|
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>
|
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>
|
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>
|
Maciej Zimnoch <maciej.zimnoch at 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>
|
||||||
|
@ -55,6 +64,9 @@ 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>
|
Rebecca Chin <rchin at pivotal.io>
|
||||||
|
Reed Allman <rdallman10 at gmail.com>
|
||||||
|
Richard Wilkes <wilkes at me.com>
|
||||||
|
Robert Russell <robert at rrbrussell.com>
|
||||||
Runrioter Wung <runrioter at gmail.com>
|
Runrioter Wung <runrioter at gmail.com>
|
||||||
Shuode Li <elemount at qq.com>
|
Shuode Li <elemount at qq.com>
|
||||||
Soroush Pour <me at soroushjp.com>
|
Soroush Pour <me at soroushjp.com>
|
||||||
|
@ -68,7 +80,10 @@ Zhenye Xie <xiezhenye at gmail.com>
|
||||||
# Organizations
|
# Organizations
|
||||||
|
|
||||||
Barracuda Networks, Inc.
|
Barracuda Networks, Inc.
|
||||||
|
Counting Ltd.
|
||||||
Google Inc.
|
Google Inc.
|
||||||
|
InfoSum Ltd.
|
||||||
Keybase Inc.
|
Keybase Inc.
|
||||||
|
Percona LLC
|
||||||
Pivotal Inc.
|
Pivotal Inc.
|
||||||
Stripe Inc.
|
Stripe Inc.
|
||||||
|
|
59
vendor/github.com/go-sql-driver/mysql/CHANGELOG.md
generated
vendored
59
vendor/github.com/go-sql-driver/mysql/CHANGELOG.md
generated
vendored
|
@ -1,3 +1,62 @@
|
||||||
|
## Version 1.4.1 (2018-11-14)
|
||||||
|
|
||||||
|
Bugfixes:
|
||||||
|
|
||||||
|
- Fix TIME format for binary columns (#818)
|
||||||
|
- Fix handling of empty auth plugin names (#835)
|
||||||
|
- Fix caching_sha2_password with empty password (#826)
|
||||||
|
- Fix canceled context broke mysqlConn (#862)
|
||||||
|
- Fix OldAuthSwitchRequest support (#870)
|
||||||
|
- Fix Auth Response packet for cleartext password (#887)
|
||||||
|
|
||||||
|
## Version 1.4 (2018-06-03)
|
||||||
|
|
||||||
|
Changes:
|
||||||
|
|
||||||
|
- Documentation fixes (#530, #535, #567)
|
||||||
|
- Refactoring (#575, #579, #580, #581, #603, #615, #704)
|
||||||
|
- Cache column names (#444)
|
||||||
|
- Sort the DSN parameters in DSNs generated from a config (#637)
|
||||||
|
- Allow native password authentication by default (#644)
|
||||||
|
- Use the default port if it is missing in the DSN (#668)
|
||||||
|
- Removed the `strict` mode (#676)
|
||||||
|
- Do not query `max_allowed_packet` by default (#680)
|
||||||
|
- Dropped support Go 1.6 and lower (#696)
|
||||||
|
- Updated `ConvertValue()` to match the database/sql/driver implementation (#760)
|
||||||
|
- Document the usage of `0000-00-00T00:00:00` as the time.Time zero value (#783)
|
||||||
|
- Improved the compatibility of the authentication system (#807)
|
||||||
|
|
||||||
|
New Features:
|
||||||
|
|
||||||
|
- Multi-Results support (#537)
|
||||||
|
- `rejectReadOnly` DSN option (#604)
|
||||||
|
- `context.Context` support (#608, #612, #627, #761)
|
||||||
|
- Transaction isolation level support (#619, #744)
|
||||||
|
- Read-Only transactions support (#618, #634)
|
||||||
|
- `NewConfig` function which initializes a config with default values (#679)
|
||||||
|
- Implemented the `ColumnType` interfaces (#667, #724)
|
||||||
|
- Support for custom string types in `ConvertValue` (#623)
|
||||||
|
- Implemented `NamedValueChecker`, improving support for uint64 with high bit set (#690, #709, #710)
|
||||||
|
- `caching_sha2_password` authentication plugin support (#794, #800, #801, #802)
|
||||||
|
- Implemented `driver.SessionResetter` (#779)
|
||||||
|
- `sha256_password` authentication plugin support (#808)
|
||||||
|
|
||||||
|
Bugfixes:
|
||||||
|
|
||||||
|
- Use the DSN hostname as TLS default ServerName if `tls=true` (#564, #718)
|
||||||
|
- Fixed LOAD LOCAL DATA INFILE for empty files (#590)
|
||||||
|
- Removed columns definition cache since it sometimes cached invalid data (#592)
|
||||||
|
- Don't mutate registered TLS configs (#600)
|
||||||
|
- Make RegisterTLSConfig concurrency-safe (#613)
|
||||||
|
- Handle missing auth data in the handshake packet correctly (#646)
|
||||||
|
- Do not retry queries when data was written to avoid data corruption (#302, #736)
|
||||||
|
- Cache the connection pointer for error handling before invalidating it (#678)
|
||||||
|
- Fixed imports for appengine/cloudsql (#700)
|
||||||
|
- Fix sending STMT_LONG_DATA for 0 byte data (#734)
|
||||||
|
- Set correct capacity for []bytes read from length-encoded strings (#766)
|
||||||
|
- Make RegisterDial concurrency-safe (#773)
|
||||||
|
|
||||||
|
|
||||||
## Version 1.3 (2016-12-01)
|
## Version 1.3 (2016-12-01)
|
||||||
|
|
||||||
Changes:
|
Changes:
|
||||||
|
|
41
vendor/github.com/go-sql-driver/mysql/README.md
generated
vendored
41
vendor/github.com/go-sql-driver/mysql/README.md
generated
vendored
|
@ -16,10 +16,11 @@ 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)
|
||||||
* [context.Context Support](#contextcontext-support)
|
|
||||||
* [Testing / Development](#testing--development)
|
* [Testing / Development](#testing--development)
|
||||||
* [License](#license)
|
* [License](#license)
|
||||||
|
|
||||||
|
@ -39,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.5 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+)
|
||||||
|
|
||||||
---------------------------------------
|
---------------------------------------
|
||||||
|
@ -232,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`
|
||||||
|
|
||||||
|
@ -258,6 +259,7 @@ Default: false
|
||||||
```
|
```
|
||||||
|
|
||||||
`parseTime=true` changes the output type of `DATE` and `DATETIME` values to `time.Time` instead of `[]byte` / `string`
|
`parseTime=true` changes the output type of `DATE` and `DATETIME` values to `time.Time` instead of `[]byte` / `string`
|
||||||
|
The date or datetime like `0000-00-00 00:00:00` is converted into zero value of `time.Time`.
|
||||||
|
|
||||||
|
|
||||||
##### `readTimeout`
|
##### `readTimeout`
|
||||||
|
@ -278,7 +280,7 @@ Default: false
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
`rejectreadOnly=true` causes the driver to reject read-only connections. This
|
`rejectReadOnly=true` causes the driver to reject read-only connections. This
|
||||||
is for a possible race condition during an automatic failover, where the mysql
|
is for a possible race condition during an automatic failover, where the mysql
|
||||||
client gets connected to a read-only replica after the failover.
|
client gets connected to a read-only replica after the failover.
|
||||||
|
|
||||||
|
@ -293,6 +295,24 @@ 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)
|
supposed to happen, setting this on some MySQL providers (such as AWS Aurora)
|
||||||
is safer for failovers.
|
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.
|
||||||
|
|
||||||
|
|
||||||
|
##### `serverPubKey`
|
||||||
|
|
||||||
|
```
|
||||||
|
Type: string
|
||||||
|
Valid Values: <name>
|
||||||
|
Default: none
|
||||||
|
```
|
||||||
|
|
||||||
|
Server public keys can be registered with [`mysql.RegisterServerPubKey`](https://godoc.org/github.com/go-sql-driver/mysql#RegisterServerPubKey), which can then be used by the assigned name in the DSN.
|
||||||
|
Public keys are used to transmit encrypted data, e.g. for authentication.
|
||||||
|
If the server's public key is known, it should be set manually to avoid expensive and potentially insecure transmissions of the public key from the server to the client each time it is required.
|
||||||
|
|
||||||
|
|
||||||
##### `timeout`
|
##### `timeout`
|
||||||
|
|
||||||
|
@ -400,6 +420,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 `_`):
|
||||||
|
@ -433,10 +460,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.
|
||||||
|
|
||||||
## `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.
|
|
||||||
|
|
||||||
## 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.
|
||||||
|
|
||||||
|
|
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() {
|
||||||
|
|
420
vendor/github.com/go-sql-driver/mysql/auth.go
generated
vendored
Normal file
420
vendor/github.com/go-sql-driver/mysql/auth.go
generated
vendored
Normal file
|
@ -0,0 +1,420 @@
|
||||||
|
// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
|
||||||
|
//
|
||||||
|
// Copyright 2018 The Go-MySQL-Driver Authors. All rights reserved.
|
||||||
|
//
|
||||||
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||||
|
// You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
package mysql
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rand"
|
||||||
|
"crypto/rsa"
|
||||||
|
"crypto/sha1"
|
||||||
|
"crypto/sha256"
|
||||||
|
"crypto/x509"
|
||||||
|
"encoding/pem"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
|
// server pub keys registry
|
||||||
|
var (
|
||||||
|
serverPubKeyLock sync.RWMutex
|
||||||
|
serverPubKeyRegistry map[string]*rsa.PublicKey
|
||||||
|
)
|
||||||
|
|
||||||
|
// RegisterServerPubKey registers a server RSA public key which can be used to
|
||||||
|
// send data in a secure manner to the server without receiving the public key
|
||||||
|
// in a potentially insecure way from the server first.
|
||||||
|
// Registered keys can afterwards be used adding serverPubKey=<name> to the DSN.
|
||||||
|
//
|
||||||
|
// Note: The provided rsa.PublicKey instance is exclusively owned by the driver
|
||||||
|
// after registering it and may not be modified.
|
||||||
|
//
|
||||||
|
// data, err := ioutil.ReadFile("mykey.pem")
|
||||||
|
// if err != nil {
|
||||||
|
// log.Fatal(err)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// block, _ := pem.Decode(data)
|
||||||
|
// if block == nil || block.Type != "PUBLIC KEY" {
|
||||||
|
// log.Fatal("failed to decode PEM block containing public key")
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// pub, err := x509.ParsePKIXPublicKey(block.Bytes)
|
||||||
|
// if err != nil {
|
||||||
|
// log.Fatal(err)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if rsaPubKey, ok := pub.(*rsa.PublicKey); ok {
|
||||||
|
// mysql.RegisterServerPubKey("mykey", rsaPubKey)
|
||||||
|
// } else {
|
||||||
|
// log.Fatal("not a RSA public key")
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
func RegisterServerPubKey(name string, pubKey *rsa.PublicKey) {
|
||||||
|
serverPubKeyLock.Lock()
|
||||||
|
if serverPubKeyRegistry == nil {
|
||||||
|
serverPubKeyRegistry = make(map[string]*rsa.PublicKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
serverPubKeyRegistry[name] = pubKey
|
||||||
|
serverPubKeyLock.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeregisterServerPubKey removes the public key registered with the given name.
|
||||||
|
func DeregisterServerPubKey(name string) {
|
||||||
|
serverPubKeyLock.Lock()
|
||||||
|
if serverPubKeyRegistry != nil {
|
||||||
|
delete(serverPubKeyRegistry, name)
|
||||||
|
}
|
||||||
|
serverPubKeyLock.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
func getServerPubKey(name string) (pubKey *rsa.PublicKey) {
|
||||||
|
serverPubKeyLock.RLock()
|
||||||
|
if v, ok := serverPubKeyRegistry[name]; ok {
|
||||||
|
pubKey = v
|
||||||
|
}
|
||||||
|
serverPubKeyLock.RUnlock()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hash password using pre 4.1 (old password) method
|
||||||
|
// https://github.com/atcurtis/mariadb/blob/master/mysys/my_rnd.c
|
||||||
|
type myRnd struct {
|
||||||
|
seed1, seed2 uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
const myRndMaxVal = 0x3FFFFFFF
|
||||||
|
|
||||||
|
// Pseudo random number generator
|
||||||
|
func newMyRnd(seed1, seed2 uint32) *myRnd {
|
||||||
|
return &myRnd{
|
||||||
|
seed1: seed1 % myRndMaxVal,
|
||||||
|
seed2: seed2 % myRndMaxVal,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tested to be equivalent to MariaDB's floating point variant
|
||||||
|
// http://play.golang.org/p/QHvhd4qved
|
||||||
|
// http://play.golang.org/p/RG0q4ElWDx
|
||||||
|
func (r *myRnd) NextByte() byte {
|
||||||
|
r.seed1 = (r.seed1*3 + r.seed2) % myRndMaxVal
|
||||||
|
r.seed2 = (r.seed1 + r.seed2 + 33) % myRndMaxVal
|
||||||
|
|
||||||
|
return byte(uint64(r.seed1) * 31 / myRndMaxVal)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate binary hash from byte string using insecure pre 4.1 method
|
||||||
|
func pwHash(password []byte) (result [2]uint32) {
|
||||||
|
var add uint32 = 7
|
||||||
|
var tmp uint32
|
||||||
|
|
||||||
|
result[0] = 1345345333
|
||||||
|
result[1] = 0x12345671
|
||||||
|
|
||||||
|
for _, c := range password {
|
||||||
|
// skip spaces and tabs in password
|
||||||
|
if c == ' ' || c == '\t' {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp = uint32(c)
|
||||||
|
result[0] ^= (((result[0] & 63) + add) * tmp) + (result[0] << 8)
|
||||||
|
result[1] += (result[1] << 8) ^ result[0]
|
||||||
|
add += tmp
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove sign bit (1<<31)-1)
|
||||||
|
result[0] &= 0x7FFFFFFF
|
||||||
|
result[1] &= 0x7FFFFFFF
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hash password using insecure pre 4.1 method
|
||||||
|
func scrambleOldPassword(scramble []byte, password string) []byte {
|
||||||
|
if len(password) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
scramble = scramble[:8]
|
||||||
|
|
||||||
|
hashPw := pwHash([]byte(password))
|
||||||
|
hashSc := pwHash(scramble)
|
||||||
|
|
||||||
|
r := newMyRnd(hashPw[0]^hashSc[0], hashPw[1]^hashSc[1])
|
||||||
|
|
||||||
|
var out [8]byte
|
||||||
|
for i := range out {
|
||||||
|
out[i] = r.NextByte() + 64
|
||||||
|
}
|
||||||
|
|
||||||
|
mask := r.NextByte()
|
||||||
|
for i := range out {
|
||||||
|
out[i] ^= mask
|
||||||
|
}
|
||||||
|
|
||||||
|
return out[:]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hash password using 4.1+ method (SHA1)
|
||||||
|
func scramblePassword(scramble []byte, password string) []byte {
|
||||||
|
if len(password) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// stage1Hash = SHA1(password)
|
||||||
|
crypt := sha1.New()
|
||||||
|
crypt.Write([]byte(password))
|
||||||
|
stage1 := crypt.Sum(nil)
|
||||||
|
|
||||||
|
// scrambleHash = SHA1(scramble + SHA1(stage1Hash))
|
||||||
|
// inner Hash
|
||||||
|
crypt.Reset()
|
||||||
|
crypt.Write(stage1)
|
||||||
|
hash := crypt.Sum(nil)
|
||||||
|
|
||||||
|
// outer Hash
|
||||||
|
crypt.Reset()
|
||||||
|
crypt.Write(scramble)
|
||||||
|
crypt.Write(hash)
|
||||||
|
scramble = crypt.Sum(nil)
|
||||||
|
|
||||||
|
// token = scrambleHash XOR stage1Hash
|
||||||
|
for i := range scramble {
|
||||||
|
scramble[i] ^= stage1[i]
|
||||||
|
}
|
||||||
|
return scramble
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hash password using MySQL 8+ method (SHA256)
|
||||||
|
func scrambleSHA256Password(scramble []byte, password string) []byte {
|
||||||
|
if len(password) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// XOR(SHA256(password), SHA256(SHA256(SHA256(password)), scramble))
|
||||||
|
|
||||||
|
crypt := sha256.New()
|
||||||
|
crypt.Write([]byte(password))
|
||||||
|
message1 := crypt.Sum(nil)
|
||||||
|
|
||||||
|
crypt.Reset()
|
||||||
|
crypt.Write(message1)
|
||||||
|
message1Hash := crypt.Sum(nil)
|
||||||
|
|
||||||
|
crypt.Reset()
|
||||||
|
crypt.Write(message1Hash)
|
||||||
|
crypt.Write(scramble)
|
||||||
|
message2 := crypt.Sum(nil)
|
||||||
|
|
||||||
|
for i := range message1 {
|
||||||
|
message1[i] ^= message2[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
return message1
|
||||||
|
}
|
||||||
|
|
||||||
|
func encryptPassword(password string, seed []byte, pub *rsa.PublicKey) ([]byte, error) {
|
||||||
|
plain := make([]byte, len(password)+1)
|
||||||
|
copy(plain, password)
|
||||||
|
for i := range plain {
|
||||||
|
j := i % len(seed)
|
||||||
|
plain[i] ^= seed[j]
|
||||||
|
}
|
||||||
|
sha1 := sha1.New()
|
||||||
|
return rsa.EncryptOAEP(sha1, rand.Reader, pub, plain, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mc *mysqlConn) sendEncryptedPassword(seed []byte, pub *rsa.PublicKey) error {
|
||||||
|
enc, err := encryptPassword(mc.cfg.Passwd, seed, pub)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return mc.writeAuthSwitchPacket(enc)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mc *mysqlConn) auth(authData []byte, plugin string) ([]byte, error) {
|
||||||
|
switch plugin {
|
||||||
|
case "caching_sha2_password":
|
||||||
|
authResp := scrambleSHA256Password(authData, mc.cfg.Passwd)
|
||||||
|
return authResp, nil
|
||||||
|
|
||||||
|
case "mysql_old_password":
|
||||||
|
if !mc.cfg.AllowOldPasswords {
|
||||||
|
return nil, ErrOldPassword
|
||||||
|
}
|
||||||
|
// Note: there are edge cases where this should work but doesn't;
|
||||||
|
// this is currently "wontfix":
|
||||||
|
// https://github.com/go-sql-driver/mysql/issues/184
|
||||||
|
authResp := append(scrambleOldPassword(authData[:8], mc.cfg.Passwd), 0)
|
||||||
|
return authResp, nil
|
||||||
|
|
||||||
|
case "mysql_clear_password":
|
||||||
|
if !mc.cfg.AllowCleartextPasswords {
|
||||||
|
return nil, ErrCleartextPassword
|
||||||
|
}
|
||||||
|
// http://dev.mysql.com/doc/refman/5.7/en/cleartext-authentication-plugin.html
|
||||||
|
// http://dev.mysql.com/doc/refman/5.7/en/pam-authentication-plugin.html
|
||||||
|
return append([]byte(mc.cfg.Passwd), 0), nil
|
||||||
|
|
||||||
|
case "mysql_native_password":
|
||||||
|
if !mc.cfg.AllowNativePasswords {
|
||||||
|
return nil, ErrNativePassword
|
||||||
|
}
|
||||||
|
// https://dev.mysql.com/doc/internals/en/secure-password-authentication.html
|
||||||
|
// Native password authentication only need and will need 20-byte challenge.
|
||||||
|
authResp := scramblePassword(authData[:20], mc.cfg.Passwd)
|
||||||
|
return authResp, nil
|
||||||
|
|
||||||
|
case "sha256_password":
|
||||||
|
if len(mc.cfg.Passwd) == 0 {
|
||||||
|
return []byte{0}, nil
|
||||||
|
}
|
||||||
|
if mc.cfg.tls != nil || mc.cfg.Net == "unix" {
|
||||||
|
// write cleartext auth packet
|
||||||
|
return append([]byte(mc.cfg.Passwd), 0), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
pubKey := mc.cfg.pubKey
|
||||||
|
if pubKey == nil {
|
||||||
|
// request public key from server
|
||||||
|
return []byte{1}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// encrypted password
|
||||||
|
enc, err := encryptPassword(mc.cfg.Passwd, authData, pubKey)
|
||||||
|
return enc, err
|
||||||
|
|
||||||
|
default:
|
||||||
|
errLog.Print("unknown auth plugin:", plugin)
|
||||||
|
return nil, ErrUnknownPlugin
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mc *mysqlConn) handleAuthResult(oldAuthData []byte, plugin string) error {
|
||||||
|
// Read Result Packet
|
||||||
|
authData, newPlugin, err := mc.readAuthResult()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle auth plugin switch, if requested
|
||||||
|
if newPlugin != "" {
|
||||||
|
// If CLIENT_PLUGIN_AUTH capability is not supported, no new cipher is
|
||||||
|
// sent and we have to keep using the cipher sent in the init packet.
|
||||||
|
if authData == nil {
|
||||||
|
authData = oldAuthData
|
||||||
|
} else {
|
||||||
|
// copy data from read buffer to owned slice
|
||||||
|
copy(oldAuthData, authData)
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin = newPlugin
|
||||||
|
|
||||||
|
authResp, err := mc.auth(authData, plugin)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err = mc.writeAuthSwitchPacket(authResp); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read Result Packet
|
||||||
|
authData, newPlugin, err = mc.readAuthResult()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do not allow to change the auth plugin more than once
|
||||||
|
if newPlugin != "" {
|
||||||
|
return ErrMalformPkt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch plugin {
|
||||||
|
|
||||||
|
// https://insidemysql.com/preparing-your-community-connector-for-mysql-8-part-2-sha256/
|
||||||
|
case "caching_sha2_password":
|
||||||
|
switch len(authData) {
|
||||||
|
case 0:
|
||||||
|
return nil // auth successful
|
||||||
|
case 1:
|
||||||
|
switch authData[0] {
|
||||||
|
case cachingSha2PasswordFastAuthSuccess:
|
||||||
|
if err = mc.readResultOK(); err == nil {
|
||||||
|
return nil // auth successful
|
||||||
|
}
|
||||||
|
|
||||||
|
case cachingSha2PasswordPerformFullAuthentication:
|
||||||
|
if mc.cfg.tls != nil || mc.cfg.Net == "unix" {
|
||||||
|
// write cleartext auth packet
|
||||||
|
err = mc.writeAuthSwitchPacket(append([]byte(mc.cfg.Passwd), 0))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pubKey := mc.cfg.pubKey
|
||||||
|
if pubKey == nil {
|
||||||
|
// request public key from server
|
||||||
|
data := mc.buf.takeSmallBuffer(4 + 1)
|
||||||
|
data[4] = cachingSha2PasswordRequestPublicKey
|
||||||
|
mc.writePacket(data)
|
||||||
|
|
||||||
|
// parse public key
|
||||||
|
data, err := mc.readPacket()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
block, _ := pem.Decode(data[1:])
|
||||||
|
pkix, err := x509.ParsePKIXPublicKey(block.Bytes)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
pubKey = pkix.(*rsa.PublicKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
// send encrypted password
|
||||||
|
err = mc.sendEncryptedPassword(oldAuthData, pubKey)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mc.readResultOK()
|
||||||
|
|
||||||
|
default:
|
||||||
|
return ErrMalformPkt
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return ErrMalformPkt
|
||||||
|
}
|
||||||
|
|
||||||
|
case "sha256_password":
|
||||||
|
switch len(authData) {
|
||||||
|
case 0:
|
||||||
|
return nil // auth successful
|
||||||
|
default:
|
||||||
|
block, _ := pem.Decode(authData)
|
||||||
|
pub, err := x509.ParsePKIXPublicKey(block.Bytes)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// send encrypted password
|
||||||
|
err = mc.sendEncryptedPassword(oldAuthData, pub.(*rsa.PublicKey))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return mc.readResultOK()
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
return nil // auth successful
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
12
vendor/github.com/go-sql-driver/mysql/buffer.go
generated
vendored
12
vendor/github.com/go-sql-driver/mysql/buffer.go
generated
vendored
|
@ -130,18 +130,18 @@ func (b *buffer) takeBuffer(length int) []byte {
|
||||||
// smaller than defaultBufSize
|
// smaller than defaultBufSize
|
||||||
// Only one buffer (total) can be used at a time.
|
// Only one buffer (total) can be used at a time.
|
||||||
func (b *buffer) takeSmallBuffer(length int) []byte {
|
func (b *buffer) takeSmallBuffer(length int) []byte {
|
||||||
if b.length == 0 {
|
if b.length > 0 {
|
||||||
return b.buf[:length]
|
return nil
|
||||||
}
|
}
|
||||||
return nil
|
return b.buf[:length]
|
||||||
}
|
}
|
||||||
|
|
||||||
// takeCompleteBuffer returns the complete existing buffer.
|
// takeCompleteBuffer returns the complete existing buffer.
|
||||||
// This can be used if the necessary buffer size is unknown.
|
// This can be used if the necessary buffer size is unknown.
|
||||||
// Only one buffer (total) can be used at a time.
|
// Only one buffer (total) can be used at a time.
|
||||||
func (b *buffer) takeCompleteBuffer() []byte {
|
func (b *buffer) takeCompleteBuffer() []byte {
|
||||||
if b.length == 0 {
|
if b.length > 0 {
|
||||||
return b.buf
|
return nil
|
||||||
}
|
}
|
||||||
return nil
|
return b.buf
|
||||||
}
|
}
|
||||||
|
|
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:
|
||||||
|
|
1
vendor/github.com/go-sql-driver/mysql/connection.go
generated
vendored
1
vendor/github.com/go-sql-driver/mysql/connection.go
generated
vendored
|
@ -403,6 +403,7 @@ func (mc *mysqlConn) query(query string, args []driver.Value) (*textRows, error)
|
||||||
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
|
||||||
|
|
44
vendor/github.com/go-sql-driver/mysql/connection_go18.go
generated
vendored
44
vendor/github.com/go-sql-driver/mysql/connection_go18.go
generated
vendored
|
@ -17,25 +17,22 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// Ping implements driver.Pinger interface
|
// Ping implements driver.Pinger interface
|
||||||
func (mc *mysqlConn) Ping(ctx context.Context) error {
|
func (mc *mysqlConn) Ping(ctx context.Context) (err error) {
|
||||||
if mc.closed.IsSet() {
|
if mc.closed.IsSet() {
|
||||||
errLog.Print(ErrInvalidConn)
|
errLog.Print(ErrInvalidConn)
|
||||||
return driver.ErrBadConn
|
return driver.ErrBadConn
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := mc.watchCancel(ctx); err != nil {
|
if err = mc.watchCancel(ctx); err != nil {
|
||||||
return err
|
return
|
||||||
}
|
}
|
||||||
defer mc.finish()
|
defer mc.finish()
|
||||||
|
|
||||||
if err := mc.writeCommandPacket(comPing); err != nil {
|
if err = mc.writeCommandPacket(comPing); err != nil {
|
||||||
return err
|
return
|
||||||
}
|
|
||||||
if _, err := mc.readResultOK(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return mc.readResultOK()
|
||||||
}
|
}
|
||||||
|
|
||||||
// BeginTx implements driver.ConnBeginTx interface
|
// BeginTx implements driver.ConnBeginTx interface
|
||||||
|
@ -152,22 +149,21 @@ func (mc *mysqlConn) watchCancel(ctx context.Context) error {
|
||||||
mc.cleanup()
|
mc.cleanup()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
// When ctx is already cancelled, don't watch it.
|
||||||
|
if err := ctx.Err(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// When ctx is not cancellable, don't watch it.
|
||||||
if ctx.Done() == nil {
|
if ctx.Done() == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
// When watcher is not alive, can't watch it.
|
||||||
mc.watching = true
|
|
||||||
select {
|
|
||||||
default:
|
|
||||||
case <-ctx.Done():
|
|
||||||
return ctx.Err()
|
|
||||||
}
|
|
||||||
if mc.watcher == nil {
|
if mc.watcher == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mc.watching = true
|
||||||
mc.watcher <- ctx
|
mc.watcher <- ctx
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,3 +191,17 @@ func (mc *mysqlConn) startWatcher() {
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (mc *mysqlConn) CheckNamedValue(nv *driver.NamedValue) (err error) {
|
||||||
|
nv.Value, err = converter{}.ConvertValue(nv.Value)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResetSession implements driver.SessionResetter.
|
||||||
|
// (From Go 1.10)
|
||||||
|
func (mc *mysqlConn) ResetSession(ctx context.Context) error {
|
||||||
|
if mc.closed.IsSet() {
|
||||||
|
return driver.ErrBadConn
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
25
vendor/github.com/go-sql-driver/mysql/const.go
generated
vendored
25
vendor/github.com/go-sql-driver/mysql/const.go
generated
vendored
|
@ -9,7 +9,9 @@
|
||||||
package mysql
|
package mysql
|
||||||
|
|
||||||
const (
|
const (
|
||||||
minProtocolVersion byte = 10
|
defaultAuthPlugin = "mysql_native_password"
|
||||||
|
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"
|
||||||
)
|
)
|
||||||
|
@ -18,10 +20,11 @@ const (
|
||||||
// http://dev.mysql.com/doc/internals/en/client-server-protocol.html
|
// http://dev.mysql.com/doc/internals/en/client-server-protocol.html
|
||||||
|
|
||||||
const (
|
const (
|
||||||
iOK byte = 0x00
|
iOK byte = 0x00
|
||||||
iLocalInFile byte = 0xfb
|
iAuthMoreData byte = 0x01
|
||||||
iEOF byte = 0xfe
|
iLocalInFile byte = 0xfb
|
||||||
iERR byte = 0xff
|
iEOF byte = 0xfe
|
||||||
|
iERR byte = 0xff
|
||||||
)
|
)
|
||||||
|
|
||||||
// https://dev.mysql.com/doc/internals/en/capability-flags.html#packet-Protocol::CapabilityFlags
|
// https://dev.mysql.com/doc/internals/en/capability-flags.html#packet-Protocol::CapabilityFlags
|
||||||
|
@ -87,8 +90,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 +112,7 @@ const (
|
||||||
fieldTypeBit
|
fieldTypeBit
|
||||||
)
|
)
|
||||||
const (
|
const (
|
||||||
fieldTypeJSON byte = iota + 0xf5
|
fieldTypeJSON fieldType = iota + 0xf5
|
||||||
fieldTypeNewDecimal
|
fieldTypeNewDecimal
|
||||||
fieldTypeEnum
|
fieldTypeEnum
|
||||||
fieldTypeSet
|
fieldTypeSet
|
||||||
|
@ -161,3 +166,9 @@ const (
|
||||||
statusInTransReadonly
|
statusInTransReadonly
|
||||||
statusSessionStateChanged
|
statusSessionStateChanged
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
cachingSha2PasswordRequestPublicKey = 2
|
||||||
|
cachingSha2PasswordFastAuthSuccess = 3
|
||||||
|
cachingSha2PasswordPerformFullAuthentication = 4
|
||||||
|
)
|
||||||
|
|
77
vendor/github.com/go-sql-driver/mysql/driver.go
generated
vendored
77
vendor/github.com/go-sql-driver/mysql/driver.go
generated
vendored
|
@ -20,6 +20,7 @@ import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"database/sql/driver"
|
"database/sql/driver"
|
||||||
"net"
|
"net"
|
||||||
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
// watcher interface is used for context support (From Go 1.8)
|
// watcher interface is used for context support (From Go 1.8)
|
||||||
|
@ -35,12 +36,17 @@ type MySQLDriver struct{}
|
||||||
// Custom dial functions must be registered with RegisterDial
|
// Custom dial functions must be registered with RegisterDial
|
||||||
type DialFunc func(addr string) (net.Conn, error)
|
type DialFunc func(addr string) (net.Conn, error)
|
||||||
|
|
||||||
var dials map[string]DialFunc
|
var (
|
||||||
|
dialsLock sync.RWMutex
|
||||||
|
dials map[string]DialFunc
|
||||||
|
)
|
||||||
|
|
||||||
// RegisterDial registers a custom dial function. It can then be used by the
|
// RegisterDial registers a custom dial function. It can then be used by the
|
||||||
// network address mynet(addr), where mynet is the registered new network.
|
// network address mynet(addr), where mynet is the registered new network.
|
||||||
// addr is passed as a parameter to the dial function.
|
// addr is passed as a parameter to the dial function.
|
||||||
func RegisterDial(net string, dial DialFunc) {
|
func RegisterDial(net string, dial DialFunc) {
|
||||||
|
dialsLock.Lock()
|
||||||
|
defer dialsLock.Unlock()
|
||||||
if dials == nil {
|
if dials == nil {
|
||||||
dials = make(map[string]DialFunc)
|
dials = make(map[string]DialFunc)
|
||||||
}
|
}
|
||||||
|
@ -66,7 +72,10 @@ func (d MySQLDriver) Open(dsn string) (driver.Conn, error) {
|
||||||
mc.parseTime = mc.cfg.ParseTime
|
mc.parseTime = mc.cfg.ParseTime
|
||||||
|
|
||||||
// Connect to Server
|
// Connect to Server
|
||||||
if dial, ok := dials[mc.cfg.Net]; ok {
|
dialsLock.RLock()
|
||||||
|
dial, ok := dials[mc.cfg.Net]
|
||||||
|
dialsLock.RUnlock()
|
||||||
|
if ok {
|
||||||
mc.netConn, err = dial(mc.cfg.Addr)
|
mc.netConn, err = dial(mc.cfg.Addr)
|
||||||
} else {
|
} else {
|
||||||
nd := net.Dialer{Timeout: mc.cfg.Timeout}
|
nd := net.Dialer{Timeout: mc.cfg.Timeout}
|
||||||
|
@ -98,20 +107,34 @@ func (d MySQLDriver) Open(dsn string) (driver.Conn, error) {
|
||||||
mc.writeTimeout = mc.cfg.WriteTimeout
|
mc.writeTimeout = mc.cfg.WriteTimeout
|
||||||
|
|
||||||
// Reading Handshake Initialization Packet
|
// Reading Handshake Initialization Packet
|
||||||
cipher, err := mc.readInitPacket()
|
authData, plugin, err := mc.readHandshakePacket()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
mc.cleanup()
|
mc.cleanup()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if plugin == "" {
|
||||||
|
plugin = defaultAuthPlugin
|
||||||
|
}
|
||||||
|
|
||||||
// Send Client Authentication Packet
|
// Send Client Authentication Packet
|
||||||
if err = mc.writeAuthPacket(cipher); err != nil {
|
authResp, err := mc.auth(authData, plugin)
|
||||||
|
if err != nil {
|
||||||
|
// try the default auth plugin, if using the requested plugin failed
|
||||||
|
errLog.Print("could not use requested auth plugin '"+plugin+"': ", err.Error())
|
||||||
|
plugin = defaultAuthPlugin
|
||||||
|
authResp, err = mc.auth(authData, plugin)
|
||||||
|
if err != nil {
|
||||||
|
mc.cleanup()
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if err = mc.writeHandshakeResponsePacket(authResp, plugin); err != nil {
|
||||||
mc.cleanup()
|
mc.cleanup()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle response to auth packet, switch methods if possible
|
// Handle response to auth packet, switch methods if possible
|
||||||
if err = handleAuthResult(mc, cipher); err != nil {
|
if err = mc.handleAuthResult(authData, plugin); err != nil {
|
||||||
// Authentication failed and MySQL has already closed the connection
|
// Authentication failed and MySQL has already closed the connection
|
||||||
// (https://dev.mysql.com/doc/internals/en/authentication-fails.html).
|
// (https://dev.mysql.com/doc/internals/en/authentication-fails.html).
|
||||||
// Do not send COM_QUIT, just cleanup and return the error.
|
// Do not send COM_QUIT, just cleanup and return the error.
|
||||||
|
@ -144,50 +167,6 @@ func (d MySQLDriver) Open(dsn string) (driver.Conn, error) {
|
||||||
return mc, nil
|
return mc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleAuthResult(mc *mysqlConn, oldCipher []byte) error {
|
|
||||||
// Read Result Packet
|
|
||||||
cipher, err := mc.readResultOK()
|
|
||||||
if err == nil {
|
|
||||||
return nil // auth successful
|
|
||||||
}
|
|
||||||
|
|
||||||
if mc.cfg == nil {
|
|
||||||
return err // auth failed and retry not possible
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retry auth if configured to do so.
|
|
||||||
if mc.cfg.AllowOldPasswords && err == ErrOldPassword {
|
|
||||||
// Retry with old authentication method. Note: there are edge cases
|
|
||||||
// where this should work but doesn't; this is currently "wontfix":
|
|
||||||
// https://github.com/go-sql-driver/mysql/issues/184
|
|
||||||
|
|
||||||
// If CLIENT_PLUGIN_AUTH capability is not supported, no new cipher is
|
|
||||||
// sent and we have to keep using the cipher sent in the init packet.
|
|
||||||
if cipher == nil {
|
|
||||||
cipher = oldCipher
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = mc.writeOldAuthPacket(cipher); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_, err = mc.readResultOK()
|
|
||||||
} else if mc.cfg.AllowCleartextPasswords && err == ErrCleartextPassword {
|
|
||||||
// Retry with clear text password for
|
|
||||||
// http://dev.mysql.com/doc/refman/5.7/en/cleartext-authentication-plugin.html
|
|
||||||
// http://dev.mysql.com/doc/refman/5.7/en/pam-authentication-plugin.html
|
|
||||||
if err = mc.writeClearAuthPacket(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_, err = mc.readResultOK()
|
|
||||||
} else if mc.cfg.AllowNativePasswords && err == ErrNativePassword {
|
|
||||||
if err = mc.writeNativeAuthPacket(cipher); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_, err = mc.readResultOK()
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
sql.Register("mysql", &MySQLDriver{})
|
sql.Register("mysql", &MySQLDriver{})
|
||||||
}
|
}
|
||||||
|
|
51
vendor/github.com/go-sql-driver/mysql/dsn.go
generated
vendored
51
vendor/github.com/go-sql-driver/mysql/dsn.go
generated
vendored
|
@ -10,6 +10,7 @@ package mysql
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"crypto/rsa"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -41,6 +42,8 @@ type Config struct {
|
||||||
Collation string // Connection collation
|
Collation string // Connection collation
|
||||||
Loc *time.Location // Location for time.Time values
|
Loc *time.Location // Location for time.Time values
|
||||||
MaxAllowedPacket int // Max packet size allowed
|
MaxAllowedPacket int // Max packet size allowed
|
||||||
|
ServerPubKey string // Server public key name
|
||||||
|
pubKey *rsa.PublicKey // Server public key
|
||||||
TLSConfig string // TLS configuration name
|
TLSConfig string // TLS configuration name
|
||||||
tls *tls.Config // TLS configuration
|
tls *tls.Config // TLS configuration
|
||||||
Timeout time.Duration // Dial timeout
|
Timeout time.Duration // Dial timeout
|
||||||
|
@ -64,6 +67,7 @@ func NewConfig() *Config {
|
||||||
return &Config{
|
return &Config{
|
||||||
Collation: defaultCollation,
|
Collation: defaultCollation,
|
||||||
Loc: time.UTC,
|
Loc: time.UTC,
|
||||||
|
MaxAllowedPacket: defaultMaxAllowedPacket,
|
||||||
AllowNativePasswords: true,
|
AllowNativePasswords: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -93,6 +97,15 @@ func (cfg *Config) normalize() error {
|
||||||
cfg.Addr = ensureHavePort(cfg.Addr)
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -244,6 +257,16 @@ func (cfg *Config) FormatDSN() string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(cfg.ServerPubKey) > 0 {
|
||||||
|
if hasParam {
|
||||||
|
buf.WriteString("&serverPubKey=")
|
||||||
|
} else {
|
||||||
|
hasParam = true
|
||||||
|
buf.WriteString("?serverPubKey=")
|
||||||
|
}
|
||||||
|
buf.WriteString(url.QueryEscape(cfg.ServerPubKey))
|
||||||
|
}
|
||||||
|
|
||||||
if cfg.Timeout > 0 {
|
if cfg.Timeout > 0 {
|
||||||
if hasParam {
|
if hasParam {
|
||||||
buf.WriteString("&timeout=")
|
buf.WriteString("&timeout=")
|
||||||
|
@ -274,7 +297,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 {
|
||||||
|
@ -397,7 +420,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
|
||||||
|
@ -503,6 +525,20 @@ func parseDSNParams(cfg *Config, params string) (err error) {
|
||||||
return errors.New("invalid bool value: " + value)
|
return errors.New("invalid bool value: " + value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Server public key
|
||||||
|
case "serverPubKey":
|
||||||
|
name, err := url.QueryUnescape(value)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("invalid value for server pub key name: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if pubKey := getServerPubKey(name); pubKey != nil {
|
||||||
|
cfg.ServerPubKey = name
|
||||||
|
cfg.pubKey = pubKey
|
||||||
|
} else {
|
||||||
|
return errors.New("invalid value / unknown server pub key name: " + name)
|
||||||
|
}
|
||||||
|
|
||||||
// Strict mode
|
// Strict mode
|
||||||
case "strict":
|
case "strict":
|
||||||
panic("strict mode has been removed. See https://github.com/go-sql-driver/mysql/wiki/strict-mode")
|
panic("strict mode has been removed. See https://github.com/go-sql-driver/mysql/wiki/strict-mode")
|
||||||
|
@ -521,10 +557,6 @@ func parseDSNParams(cfg *Config, params string) (err error) {
|
||||||
if boolValue {
|
if boolValue {
|
||||||
cfg.TLSConfig = "true"
|
cfg.TLSConfig = "true"
|
||||||
cfg.tls = &tls.Config{}
|
cfg.tls = &tls.Config{}
|
||||||
host, _, err := net.SplitHostPort(cfg.Addr)
|
|
||||||
if err == nil {
|
|
||||||
cfg.tls.ServerName = host
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
cfg.TLSConfig = "false"
|
cfg.TLSConfig = "false"
|
||||||
}
|
}
|
||||||
|
@ -538,13 +570,6 @@ func parseDSNParams(cfg *Config, params string) (err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if tlsConfig := getTLSConfigClone(name); tlsConfig != nil {
|
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 {
|
||||||
|
|
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
|
@ -174,8 +174,7 @@ func (mc *mysqlConn) handleInFileRequest(name string) (err error) {
|
||||||
|
|
||||||
// read OK packet
|
// read OK packet
|
||||||
if err == nil {
|
if err == nil {
|
||||||
_, err = mc.readResultOK()
|
return mc.readResultOK()
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mc.readPacket()
|
mc.readPacket()
|
||||||
|
|
274
vendor/github.com/go-sql-driver/mysql/packets.go
generated
vendored
274
vendor/github.com/go-sql-driver/mysql/packets.go
generated
vendored
|
@ -149,24 +149,29 @@ func (mc *mysqlConn) writePacket(data []byte) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Initialisation Process *
|
* Initialization Process *
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
// Handshake Initialization Packet
|
// Handshake Initialization Packet
|
||||||
// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::Handshake
|
// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::Handshake
|
||||||
func (mc *mysqlConn) readInitPacket() ([]byte, error) {
|
func (mc *mysqlConn) readHandshakePacket() (data []byte, plugin string, err error) {
|
||||||
data, err := mc.readPacket()
|
data, err = mc.readPacket()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
// for init we can rewrite this to ErrBadConn for sql.Driver to retry, since
|
||||||
|
// in connection initialization we don't risk retrying non-idempotent actions.
|
||||||
|
if err == ErrInvalidConn {
|
||||||
|
return nil, "", driver.ErrBadConn
|
||||||
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if data[0] == iERR {
|
if data[0] == iERR {
|
||||||
return nil, mc.handleErrorPacket(data)
|
return nil, "", mc.handleErrorPacket(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// protocol version [1 byte]
|
// protocol version [1 byte]
|
||||||
if data[0] < minProtocolVersion {
|
if data[0] < minProtocolVersion {
|
||||||
return nil, fmt.Errorf(
|
return nil, "", fmt.Errorf(
|
||||||
"unsupported protocol version %d. Version %d or higher is required",
|
"unsupported protocol version %d. Version %d or higher is required",
|
||||||
data[0],
|
data[0],
|
||||||
minProtocolVersion,
|
minProtocolVersion,
|
||||||
|
@ -178,7 +183,7 @@ func (mc *mysqlConn) readInitPacket() ([]byte, error) {
|
||||||
pos := 1 + bytes.IndexByte(data[1:], 0x00) + 1 + 4
|
pos := 1 + bytes.IndexByte(data[1:], 0x00) + 1 + 4
|
||||||
|
|
||||||
// first part of the password cipher [8 bytes]
|
// first part of the password cipher [8 bytes]
|
||||||
cipher := data[pos : pos+8]
|
authData := data[pos : pos+8]
|
||||||
|
|
||||||
// (filler) always 0x00 [1 byte]
|
// (filler) always 0x00 [1 byte]
|
||||||
pos += 8 + 1
|
pos += 8 + 1
|
||||||
|
@ -186,10 +191,10 @@ func (mc *mysqlConn) readInitPacket() ([]byte, error) {
|
||||||
// capability flags (lower 2 bytes) [2 bytes]
|
// capability flags (lower 2 bytes) [2 bytes]
|
||||||
mc.flags = clientFlag(binary.LittleEndian.Uint16(data[pos : pos+2]))
|
mc.flags = clientFlag(binary.LittleEndian.Uint16(data[pos : pos+2]))
|
||||||
if mc.flags&clientProtocol41 == 0 {
|
if mc.flags&clientProtocol41 == 0 {
|
||||||
return nil, ErrOldProtocol
|
return nil, "", ErrOldProtocol
|
||||||
}
|
}
|
||||||
if mc.flags&clientSSL == 0 && mc.cfg.tls != nil {
|
if mc.flags&clientSSL == 0 && mc.cfg.tls != nil {
|
||||||
return nil, ErrNoTLS
|
return nil, "", ErrNoTLS
|
||||||
}
|
}
|
||||||
pos += 2
|
pos += 2
|
||||||
|
|
||||||
|
@ -213,32 +218,32 @@ func (mc *mysqlConn) readInitPacket() ([]byte, error) {
|
||||||
//
|
//
|
||||||
// The official Python library uses the fixed length 12
|
// The official Python library uses the fixed length 12
|
||||||
// which seems to work but technically could have a hidden bug.
|
// which seems to work but technically could have a hidden bug.
|
||||||
cipher = append(cipher, data[pos:pos+12]...)
|
authData = append(authData, data[pos:pos+12]...)
|
||||||
|
pos += 13
|
||||||
|
|
||||||
// TODO: Verify string termination
|
|
||||||
// EOF if version (>= 5.5.7 and < 5.5.10) or (>= 5.6.0 and < 5.6.2)
|
// EOF if version (>= 5.5.7 and < 5.5.10) or (>= 5.6.0 and < 5.6.2)
|
||||||
// \NUL otherwise
|
// \NUL otherwise
|
||||||
//
|
if end := bytes.IndexByte(data[pos:], 0x00); end != -1 {
|
||||||
//if data[len(data)-1] == 0 {
|
plugin = string(data[pos : pos+end])
|
||||||
// return
|
} else {
|
||||||
//}
|
plugin = string(data[pos:])
|
||||||
//return ErrMalformPkt
|
}
|
||||||
|
|
||||||
// make a memory safe copy of the cipher slice
|
// make a memory safe copy of the cipher slice
|
||||||
var b [20]byte
|
var b [20]byte
|
||||||
copy(b[:], cipher)
|
copy(b[:], authData)
|
||||||
return b[:], nil
|
return b[:], plugin, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// make a memory safe copy of the cipher slice
|
// make a memory safe copy of the cipher slice
|
||||||
var b [8]byte
|
var b [8]byte
|
||||||
copy(b[:], cipher)
|
copy(b[:], authData)
|
||||||
return b[:], nil
|
return b[:], plugin, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Client Authentication Packet
|
// Client Authentication Packet
|
||||||
// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::HandshakeResponse
|
// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::HandshakeResponse
|
||||||
func (mc *mysqlConn) writeAuthPacket(cipher []byte) error {
|
func (mc *mysqlConn) writeHandshakeResponsePacket(authResp []byte, plugin string) error {
|
||||||
// Adjust client flags based on server support
|
// Adjust client flags based on server support
|
||||||
clientFlags := clientProtocol41 |
|
clientFlags := clientProtocol41 |
|
||||||
clientSecureConn |
|
clientSecureConn |
|
||||||
|
@ -262,10 +267,17 @@ func (mc *mysqlConn) writeAuthPacket(cipher []byte) error {
|
||||||
clientFlags |= clientMultiStatements
|
clientFlags |= clientMultiStatements
|
||||||
}
|
}
|
||||||
|
|
||||||
// User Password
|
// encode length of the auth plugin data
|
||||||
scrambleBuff := scramblePassword(cipher, []byte(mc.cfg.Passwd))
|
var authRespLEIBuf [9]byte
|
||||||
|
authRespLen := len(authResp)
|
||||||
|
authRespLEI := appendLengthEncodedInteger(authRespLEIBuf[:0], uint64(authRespLen))
|
||||||
|
if len(authRespLEI) > 1 {
|
||||||
|
// if the length can not be written in 1 byte, it must be written as a
|
||||||
|
// length encoded integer
|
||||||
|
clientFlags |= clientPluginAuthLenEncClientData
|
||||||
|
}
|
||||||
|
|
||||||
pktLen := 4 + 4 + 1 + 23 + len(mc.cfg.User) + 1 + 1 + len(scrambleBuff) + 21 + 1
|
pktLen := 4 + 4 + 1 + 23 + len(mc.cfg.User) + 1 + len(authRespLEI) + len(authResp) + 21 + 1
|
||||||
|
|
||||||
// To specify a db name
|
// To specify a db name
|
||||||
if n := len(mc.cfg.DBName); n > 0 {
|
if n := len(mc.cfg.DBName); n > 0 {
|
||||||
|
@ -276,7 +288,7 @@ func (mc *mysqlConn) writeAuthPacket(cipher []byte) error {
|
||||||
// Calculate packet length and get buffer with that size
|
// Calculate packet length and get buffer with that size
|
||||||
data := mc.buf.takeSmallBuffer(pktLen + 4)
|
data := mc.buf.takeSmallBuffer(pktLen + 4)
|
||||||
if data == nil {
|
if data == nil {
|
||||||
// can not take the buffer. Something must be wrong with the connection
|
// cannot take the buffer. Something must be wrong with the connection
|
||||||
errLog.Print(ErrBusyBuffer)
|
errLog.Print(ErrBusyBuffer)
|
||||||
return errBadConnNoWrite
|
return errBadConnNoWrite
|
||||||
}
|
}
|
||||||
|
@ -333,9 +345,9 @@ func (mc *mysqlConn) writeAuthPacket(cipher []byte) error {
|
||||||
data[pos] = 0x00
|
data[pos] = 0x00
|
||||||
pos++
|
pos++
|
||||||
|
|
||||||
// ScrambleBuffer [length encoded integer]
|
// Auth Data [length encoded integer]
|
||||||
data[pos] = byte(len(scrambleBuff))
|
pos += copy(data[pos:], authRespLEI)
|
||||||
pos += 1 + copy(data[pos+1:], scrambleBuff)
|
pos += copy(data[pos:], authResp)
|
||||||
|
|
||||||
// Databasename [null terminated string]
|
// Databasename [null terminated string]
|
||||||
if len(mc.cfg.DBName) > 0 {
|
if len(mc.cfg.DBName) > 0 {
|
||||||
|
@ -344,76 +356,26 @@ func (mc *mysqlConn) writeAuthPacket(cipher []byte) error {
|
||||||
pos++
|
pos++
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assume native client during response
|
pos += copy(data[pos:], plugin)
|
||||||
pos += copy(data[pos:], "mysql_native_password")
|
|
||||||
data[pos] = 0x00
|
data[pos] = 0x00
|
||||||
|
pos++
|
||||||
|
|
||||||
// Send Auth packet
|
// Send Auth packet
|
||||||
return mc.writePacket(data)
|
return mc.writePacket(data[:pos])
|
||||||
}
|
}
|
||||||
|
|
||||||
// Client old authentication packet
|
|
||||||
// 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) writeAuthSwitchPacket(authData []byte) error {
|
||||||
// User password
|
pktLen := 4 + len(authData)
|
||||||
// https://dev.mysql.com/doc/internals/en/old-password-authentication.html
|
data := mc.buf.takeSmallBuffer(pktLen)
|
||||||
// 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
|
|
||||||
pktLen := len(scrambleBuff) + 1
|
|
||||||
data := mc.buf.takeSmallBuffer(4 + pktLen)
|
|
||||||
if data == nil {
|
if data == nil {
|
||||||
// can not take the buffer. Something must be wrong with the connection
|
// cannot take the buffer. Something must be wrong with the connection
|
||||||
errLog.Print(ErrBusyBuffer)
|
errLog.Print(ErrBusyBuffer)
|
||||||
return errBadConnNoWrite
|
return errBadConnNoWrite
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the scrambled password [null terminated string]
|
// Add the auth data [EOF]
|
||||||
copy(data[4:], scrambleBuff)
|
copy(data[4:], authData)
|
||||||
data[4+pktLen-1] = 0x00
|
|
||||||
|
|
||||||
return mc.writePacket(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Client clear text authentication packet
|
|
||||||
// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::AuthSwitchResponse
|
|
||||||
func (mc *mysqlConn) writeClearAuthPacket() error {
|
|
||||||
// Calculate the packet length and add a tailing 0
|
|
||||||
pktLen := len(mc.cfg.Passwd) + 1
|
|
||||||
data := mc.buf.takeSmallBuffer(4 + pktLen)
|
|
||||||
if data == nil {
|
|
||||||
// can not take the buffer. Something must be wrong with the connection
|
|
||||||
errLog.Print(ErrBusyBuffer)
|
|
||||||
return errBadConnNoWrite
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the clear password [null terminated string]
|
|
||||||
copy(data[4:], mc.cfg.Passwd)
|
|
||||||
data[4+pktLen-1] = 0x00
|
|
||||||
|
|
||||||
return mc.writePacket(data)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Native password authentication method
|
|
||||||
// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::AuthSwitchResponse
|
|
||||||
func (mc *mysqlConn) writeNativeAuthPacket(cipher []byte) error {
|
|
||||||
// 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
|
|
||||||
pktLen := len(scrambleBuff)
|
|
||||||
data := mc.buf.takeSmallBuffer(4 + pktLen)
|
|
||||||
if data == nil {
|
|
||||||
// can not take the buffer. Something must be wrong with the connection
|
|
||||||
errLog.Print(ErrBusyBuffer)
|
|
||||||
return errBadConnNoWrite
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the scramble
|
|
||||||
copy(data[4:], scrambleBuff)
|
|
||||||
|
|
||||||
return mc.writePacket(data)
|
return mc.writePacket(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -427,7 +389,7 @@ func (mc *mysqlConn) writeCommandPacket(command byte) error {
|
||||||
|
|
||||||
data := mc.buf.takeSmallBuffer(4 + 1)
|
data := mc.buf.takeSmallBuffer(4 + 1)
|
||||||
if data == nil {
|
if data == nil {
|
||||||
// can not take the buffer. Something must be wrong with the connection
|
// cannot take the buffer. Something must be wrong with the connection
|
||||||
errLog.Print(ErrBusyBuffer)
|
errLog.Print(ErrBusyBuffer)
|
||||||
return errBadConnNoWrite
|
return errBadConnNoWrite
|
||||||
}
|
}
|
||||||
|
@ -446,7 +408,7 @@ func (mc *mysqlConn) writeCommandPacketStr(command byte, arg string) error {
|
||||||
pktLen := 1 + len(arg)
|
pktLen := 1 + len(arg)
|
||||||
data := mc.buf.takeBuffer(pktLen + 4)
|
data := mc.buf.takeBuffer(pktLen + 4)
|
||||||
if data == nil {
|
if data == nil {
|
||||||
// can not take the buffer. Something must be wrong with the connection
|
// cannot take the buffer. Something must be wrong with the connection
|
||||||
errLog.Print(ErrBusyBuffer)
|
errLog.Print(ErrBusyBuffer)
|
||||||
return errBadConnNoWrite
|
return errBadConnNoWrite
|
||||||
}
|
}
|
||||||
|
@ -467,7 +429,7 @@ func (mc *mysqlConn) writeCommandPacketUint32(command byte, arg uint32) error {
|
||||||
|
|
||||||
data := mc.buf.takeSmallBuffer(4 + 1 + 4)
|
data := mc.buf.takeSmallBuffer(4 + 1 + 4)
|
||||||
if data == nil {
|
if data == nil {
|
||||||
// can not take the buffer. Something must be wrong with the connection
|
// cannot take the buffer. Something must be wrong with the connection
|
||||||
errLog.Print(ErrBusyBuffer)
|
errLog.Print(ErrBusyBuffer)
|
||||||
return errBadConnNoWrite
|
return errBadConnNoWrite
|
||||||
}
|
}
|
||||||
|
@ -489,45 +451,50 @@ func (mc *mysqlConn) writeCommandPacketUint32(command byte, arg uint32) error {
|
||||||
* Result Packets *
|
* Result Packets *
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
// Returns error if Packet is not an 'Result OK'-Packet
|
func (mc *mysqlConn) readAuthResult() ([]byte, string, error) {
|
||||||
func (mc *mysqlConn) readResultOK() ([]byte, error) {
|
|
||||||
data, err := mc.readPacket()
|
data, err := mc.readPacket()
|
||||||
if err == nil {
|
if err != nil {
|
||||||
// packet indicator
|
return nil, "", err
|
||||||
switch data[0] {
|
|
||||||
|
|
||||||
case iOK:
|
|
||||||
return nil, mc.handleOkPacket(data)
|
|
||||||
|
|
||||||
case iEOF:
|
|
||||||
if len(data) > 1 {
|
|
||||||
pluginEndIndex := bytes.IndexByte(data, 0x00)
|
|
||||||
plugin := string(data[1:pluginEndIndex])
|
|
||||||
cipher := data[pluginEndIndex+1:]
|
|
||||||
|
|
||||||
switch plugin {
|
|
||||||
case "mysql_old_password":
|
|
||||||
// using old_passwords
|
|
||||||
return cipher, ErrOldPassword
|
|
||||||
case "mysql_clear_password":
|
|
||||||
// using clear text password
|
|
||||||
return cipher, ErrCleartextPassword
|
|
||||||
case "mysql_native_password":
|
|
||||||
// using mysql default authentication method
|
|
||||||
return cipher, ErrNativePassword
|
|
||||||
default:
|
|
||||||
return cipher, ErrUnknownPlugin
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// https://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::OldAuthSwitchRequest
|
|
||||||
return nil, ErrOldPassword
|
|
||||||
|
|
||||||
default: // Error otherwise
|
|
||||||
return nil, mc.handleErrorPacket(data)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return nil, err
|
|
||||||
|
// packet indicator
|
||||||
|
switch data[0] {
|
||||||
|
|
||||||
|
case iOK:
|
||||||
|
return nil, "", mc.handleOkPacket(data)
|
||||||
|
|
||||||
|
case iAuthMoreData:
|
||||||
|
return data[1:], "", err
|
||||||
|
|
||||||
|
case iEOF:
|
||||||
|
if len(data) == 1 {
|
||||||
|
// https://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::OldAuthSwitchRequest
|
||||||
|
return nil, "mysql_old_password", nil
|
||||||
|
}
|
||||||
|
pluginEndIndex := bytes.IndexByte(data, 0x00)
|
||||||
|
if pluginEndIndex < 0 {
|
||||||
|
return nil, "", ErrMalformPkt
|
||||||
|
}
|
||||||
|
plugin := string(data[1:pluginEndIndex])
|
||||||
|
authData := data[pluginEndIndex+1:]
|
||||||
|
return authData, plugin, nil
|
||||||
|
|
||||||
|
default: // Error otherwise
|
||||||
|
return nil, "", mc.handleErrorPacket(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns error if Packet is not an 'Result OK'-Packet
|
||||||
|
func (mc *mysqlConn) readResultOK() error {
|
||||||
|
data, err := mc.readPacket()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if data[0] == iOK {
|
||||||
|
return mc.handleOkPacket(data)
|
||||||
|
}
|
||||||
|
return mc.handleErrorPacket(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Result Set Header Packet
|
// Result Set Header Packet
|
||||||
|
@ -571,7 +538,8 @@ func (mc *mysqlConn) handleErrorPacket(data []byte) error {
|
||||||
errno := binary.LittleEndian.Uint16(data[1:3])
|
errno := binary.LittleEndian.Uint16(data[1:3])
|
||||||
|
|
||||||
// 1792: ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION
|
// 1792: ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION
|
||||||
if errno == 1792 && mc.cfg.RejectReadOnly {
|
// 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
|
// Oops; we are connected to a read-only connection, and won't be able
|
||||||
// to issue any write statements. Since RejectReadOnly is configured,
|
// to issue any write statements. Since RejectReadOnly is configured,
|
||||||
// we throw away this connection hoping this one would have write
|
// we throw away this connection hoping this one would have write
|
||||||
|
@ -696,14 +664,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]
|
||||||
|
@ -853,7 +828,7 @@ func (stmt *mysqlStmt) writeCommandLongData(paramID int, arg []byte) error {
|
||||||
// 2 bytes paramID
|
// 2 bytes paramID
|
||||||
const dataOffset = 1 + 4 + 2
|
const dataOffset = 1 + 4 + 2
|
||||||
|
|
||||||
// Can not use the write buffer since
|
// Cannot use the write buffer since
|
||||||
// a) the buffer is too small
|
// a) the buffer is too small
|
||||||
// b) it is in use
|
// b) it is in use
|
||||||
data := make([]byte, 4+1+4+2+len(arg))
|
data := make([]byte, 4+1+4+2+len(arg))
|
||||||
|
@ -908,6 +883,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
|
||||||
|
|
||||||
|
@ -919,7 +900,7 @@ func (stmt *mysqlStmt) writeExecutePacket(args []driver.Value) error {
|
||||||
data = mc.buf.takeCompleteBuffer()
|
data = mc.buf.takeCompleteBuffer()
|
||||||
}
|
}
|
||||||
if data == nil {
|
if data == nil {
|
||||||
// can not take the buffer. Something must be wrong with the connection
|
// cannot take the buffer. Something must be wrong with the connection
|
||||||
errLog.Print(ErrBusyBuffer)
|
errLog.Print(ErrBusyBuffer)
|
||||||
return errBadConnNoWrite
|
return errBadConnNoWrite
|
||||||
}
|
}
|
||||||
|
@ -980,7 +961,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
|
||||||
}
|
}
|
||||||
|
@ -988,7 +969,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 {
|
||||||
|
@ -1004,7 +985,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 {
|
||||||
|
@ -1020,7 +1001,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 {
|
||||||
|
@ -1032,10 +1013,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)),
|
||||||
)
|
)
|
||||||
|
@ -1050,14 +1031,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)),
|
||||||
)
|
)
|
||||||
|
@ -1069,7 +1050,7 @@ 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 a [64]byte
|
var a [64]byte
|
||||||
|
@ -1087,7 +1068,7 @@ func (stmt *mysqlStmt) writeExecutePacket(args []driver.Value) error {
|
||||||
paramValues = append(paramValues, b...)
|
paramValues = append(paramValues, b...)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("can not convert type: %T", arg)
|
return fmt.Errorf("cannot convert type: %T", arg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1143,10 +1124,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]
|
||||||
|
@ -1264,7 +1246,7 @@ func (rows *binaryRows) readRow(dest []driver.Value) error {
|
||||||
rows.rs.columns[i].decimals,
|
rows.rs.columns[i].decimals,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
dest[i], err = formatBinaryDateTime(data[pos:pos+int(num)], dstlen, true)
|
dest[i], err = formatBinaryTime(data[pos:pos+int(num)], dstlen)
|
||||||
case rows.mc.parseTime:
|
case rows.mc.parseTime:
|
||||||
dest[i], err = parseBinaryDateTime(num, data[pos:], rows.mc.cfg.Loc)
|
dest[i], err = parseBinaryDateTime(num, data[pos:], rows.mc.cfg.Loc)
|
||||||
default:
|
default:
|
||||||
|
@ -1284,7 +1266,7 @@ func (rows *binaryRows) readRow(dest []driver.Value) error {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dest[i], err = formatBinaryDateTime(data[pos:pos+int(num)], dstlen, false)
|
dest[i], err = formatBinaryDateTime(data[pos:pos+int(num)], dstlen)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
|
48
vendor/github.com/go-sql-driver/mysql/rows.go
generated
vendored
48
vendor/github.com/go-sql-driver/mysql/rows.go
generated
vendored
|
@ -11,16 +11,10 @@ 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
|
columnNames []string
|
||||||
|
@ -65,6 +59,44 @@ func (rows *mysqlRows) Columns() []string {
|
||||||
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 {
|
if f := rows.finish; f != nil {
|
||||||
f()
|
f()
|
||||||
|
|
51
vendor/github.com/go-sql-driver/mysql/statement.go
generated
vendored
51
vendor/github.com/go-sql-driver/mysql/statement.go
generated
vendored
|
@ -132,19 +132,36 @@ func (stmt *mysqlStmt) query(args []driver.Value) (*binaryRows, error) {
|
||||||
|
|
||||||
type converter struct{}
|
type converter struct{}
|
||||||
|
|
||||||
|
// ConvertValue mirrors the reference/default converter in database/sql/driver
|
||||||
|
// with _one_ exception. We support uint64 with their high bit and the default
|
||||||
|
// implementation does not. This function should be kept in sync with
|
||||||
|
// database/sql/driver defaultConverter.ConvertValue() except for that
|
||||||
|
// deliberate difference.
|
||||||
func (c converter) ConvertValue(v interface{}) (driver.Value, error) {
|
func (c converter) ConvertValue(v interface{}) (driver.Value, error) {
|
||||||
if driver.IsValue(v) {
|
if driver.IsValue(v) {
|
||||||
return v, nil
|
return v, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if vr, ok := v.(driver.Valuer); ok {
|
||||||
|
sv, err := callValuerValue(vr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !driver.IsValue(sv) {
|
||||||
|
return nil, fmt.Errorf("non-Value type %T returned from Value", sv)
|
||||||
|
}
|
||||||
|
return sv, nil
|
||||||
|
}
|
||||||
|
|
||||||
rv := reflect.ValueOf(v)
|
rv := reflect.ValueOf(v)
|
||||||
switch rv.Kind() {
|
switch rv.Kind() {
|
||||||
case reflect.Ptr:
|
case reflect.Ptr:
|
||||||
// indirect pointers
|
// indirect pointers
|
||||||
if rv.IsNil() {
|
if rv.IsNil() {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
} else {
|
||||||
|
return c.ConvertValue(rv.Elem().Interface())
|
||||||
}
|
}
|
||||||
return c.ConvertValue(rv.Elem().Interface())
|
|
||||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
return rv.Int(), nil
|
return rv.Int(), nil
|
||||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32:
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32:
|
||||||
|
@ -157,6 +174,38 @@ 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())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var valuerReflectType = reflect.TypeOf((*driver.Valuer)(nil)).Elem()
|
||||||
|
|
||||||
|
// callValuerValue returns vr.Value(), with one exception:
|
||||||
|
// If vr.Value is an auto-generated method on a pointer type and the
|
||||||
|
// pointer is nil, it would panic at runtime in the panicwrap
|
||||||
|
// method. Treat it like nil instead.
|
||||||
|
//
|
||||||
|
// This is so people can implement driver.Value on value types and
|
||||||
|
// still use nil pointers to those types to mean nil/NULL, just like
|
||||||
|
// string/*string.
|
||||||
|
//
|
||||||
|
// This is an exact copy of the same-named unexported function from the
|
||||||
|
// database/sql package.
|
||||||
|
func callValuerValue(vr driver.Valuer) (v driver.Value, err error) {
|
||||||
|
if rv := reflect.ValueOf(vr); rv.Kind() == reflect.Ptr &&
|
||||||
|
rv.IsNil() &&
|
||||||
|
rv.Type().Elem().Implements(valuerReflectType) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
return vr.Value()
|
||||||
|
}
|
||||||
|
|
384
vendor/github.com/go-sql-driver/mysql/utils.go
generated
vendored
384
vendor/github.com/go-sql-driver/mysql/utils.go
generated
vendored
|
@ -9,27 +9,29 @@
|
||||||
package mysql
|
package mysql
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/sha1"
|
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"database/sql/driver"
|
"database/sql/driver"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Registry for custom tls.Configs
|
||||||
var (
|
var (
|
||||||
tlsConfigLock sync.RWMutex
|
tlsConfigLock sync.RWMutex
|
||||||
tlsConfigRegister map[string]*tls.Config // Register for custom tls.Configs
|
tlsConfigRegistry map[string]*tls.Config
|
||||||
)
|
)
|
||||||
|
|
||||||
// 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.
|
// Note: The provided tls.Config is exclusively owned by the driver after
|
||||||
|
// registering it.
|
||||||
//
|
//
|
||||||
// rootCertPool := x509.NewCertPool()
|
// rootCertPool := x509.NewCertPool()
|
||||||
// pem, err := ioutil.ReadFile("/path/ca-cert.pem")
|
// pem, err := ioutil.ReadFile("/path/ca-cert.pem")
|
||||||
|
@ -57,11 +59,11 @@ func RegisterTLSConfig(key string, config *tls.Config) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
tlsConfigLock.Lock()
|
tlsConfigLock.Lock()
|
||||||
if tlsConfigRegister == nil {
|
if tlsConfigRegistry == nil {
|
||||||
tlsConfigRegister = make(map[string]*tls.Config)
|
tlsConfigRegistry = make(map[string]*tls.Config)
|
||||||
}
|
}
|
||||||
|
|
||||||
tlsConfigRegister[key] = config
|
tlsConfigRegistry[key] = config
|
||||||
tlsConfigLock.Unlock()
|
tlsConfigLock.Unlock()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -69,15 +71,15 @@ func RegisterTLSConfig(key string, config *tls.Config) error {
|
||||||
// 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()
|
tlsConfigLock.Lock()
|
||||||
if tlsConfigRegister != nil {
|
if tlsConfigRegistry != nil {
|
||||||
delete(tlsConfigRegister, key)
|
delete(tlsConfigRegistry, key)
|
||||||
}
|
}
|
||||||
tlsConfigLock.Unlock()
|
tlsConfigLock.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func getTLSConfigClone(key string) (config *tls.Config) {
|
func getTLSConfigClone(key string) (config *tls.Config) {
|
||||||
tlsConfigLock.RLock()
|
tlsConfigLock.RLock()
|
||||||
if v, ok := tlsConfigRegister[key]; ok {
|
if v, ok := tlsConfigRegistry[key]; ok {
|
||||||
config = cloneTLSConfig(v)
|
config = cloneTLSConfig(v)
|
||||||
}
|
}
|
||||||
tlsConfigLock.RUnlock()
|
tlsConfigLock.RUnlock()
|
||||||
|
@ -98,119 +100,6 @@ func readBool(input string) (value bool, valid bool) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
|
||||||
* Authentication *
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
// Encrypt password using 4.1+ method
|
|
||||||
func scramblePassword(scramble, password []byte) []byte {
|
|
||||||
if len(password) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// stage1Hash = SHA1(password)
|
|
||||||
crypt := sha1.New()
|
|
||||||
crypt.Write(password)
|
|
||||||
stage1 := crypt.Sum(nil)
|
|
||||||
|
|
||||||
// scrambleHash = SHA1(scramble + SHA1(stage1Hash))
|
|
||||||
// inner Hash
|
|
||||||
crypt.Reset()
|
|
||||||
crypt.Write(stage1)
|
|
||||||
hash := crypt.Sum(nil)
|
|
||||||
|
|
||||||
// outer Hash
|
|
||||||
crypt.Reset()
|
|
||||||
crypt.Write(scramble)
|
|
||||||
crypt.Write(hash)
|
|
||||||
scramble = crypt.Sum(nil)
|
|
||||||
|
|
||||||
// token = scrambleHash XOR stage1Hash
|
|
||||||
for i := range scramble {
|
|
||||||
scramble[i] ^= stage1[i]
|
|
||||||
}
|
|
||||||
return scramble
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encrypt password using pre 4.1 (old password) method
|
|
||||||
// https://github.com/atcurtis/mariadb/blob/master/mysys/my_rnd.c
|
|
||||||
type myRnd struct {
|
|
||||||
seed1, seed2 uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
const myRndMaxVal = 0x3FFFFFFF
|
|
||||||
|
|
||||||
// Pseudo random number generator
|
|
||||||
func newMyRnd(seed1, seed2 uint32) *myRnd {
|
|
||||||
return &myRnd{
|
|
||||||
seed1: seed1 % myRndMaxVal,
|
|
||||||
seed2: seed2 % myRndMaxVal,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tested to be equivalent to MariaDB's floating point variant
|
|
||||||
// http://play.golang.org/p/QHvhd4qved
|
|
||||||
// http://play.golang.org/p/RG0q4ElWDx
|
|
||||||
func (r *myRnd) NextByte() byte {
|
|
||||||
r.seed1 = (r.seed1*3 + r.seed2) % myRndMaxVal
|
|
||||||
r.seed2 = (r.seed1 + r.seed2 + 33) % myRndMaxVal
|
|
||||||
|
|
||||||
return byte(uint64(r.seed1) * 31 / myRndMaxVal)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate binary hash from byte string using insecure pre 4.1 method
|
|
||||||
func pwHash(password []byte) (result [2]uint32) {
|
|
||||||
var add uint32 = 7
|
|
||||||
var tmp uint32
|
|
||||||
|
|
||||||
result[0] = 1345345333
|
|
||||||
result[1] = 0x12345671
|
|
||||||
|
|
||||||
for _, c := range password {
|
|
||||||
// skip spaces and tabs in password
|
|
||||||
if c == ' ' || c == '\t' {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp = uint32(c)
|
|
||||||
result[0] ^= (((result[0] & 63) + add) * tmp) + (result[0] << 8)
|
|
||||||
result[1] += (result[1] << 8) ^ result[0]
|
|
||||||
add += tmp
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove sign bit (1<<31)-1)
|
|
||||||
result[0] &= 0x7FFFFFFF
|
|
||||||
result[1] &= 0x7FFFFFFF
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encrypt password using insecure pre 4.1 method
|
|
||||||
func scrambleOldPassword(scramble, password []byte) []byte {
|
|
||||||
if len(password) == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
scramble = scramble[:8]
|
|
||||||
|
|
||||||
hashPw := pwHash(password)
|
|
||||||
hashSc := pwHash(scramble)
|
|
||||||
|
|
||||||
r := newMyRnd(hashPw[0]^hashSc[0], hashPw[1]^hashSc[1])
|
|
||||||
|
|
||||||
var out [8]byte
|
|
||||||
for i := range out {
|
|
||||||
out[i] = r.NextByte() + 64
|
|
||||||
}
|
|
||||||
|
|
||||||
mask := r.NextByte()
|
|
||||||
for i := range out {
|
|
||||||
out[i] ^= mask
|
|
||||||
}
|
|
||||||
|
|
||||||
return out[:]
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* Time related utils *
|
* Time related utils *
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
@ -339,87 +228,104 @@ var zeroDateTime = []byte("0000-00-00 00:00:00.000000")
|
||||||
const digits01 = "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"
|
const digits01 = "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"
|
||||||
const digits10 = "0000000000111111111122222222223333333333444444444455555555556666666666777777777788888888889999999999"
|
const digits10 = "0000000000111111111122222222223333333333444444444455555555556666666666777777777788888888889999999999"
|
||||||
|
|
||||||
func formatBinaryDateTime(src []byte, length uint8, justTime bool) (driver.Value, error) {
|
func appendMicrosecs(dst, src []byte, decimals int) []byte {
|
||||||
|
if decimals <= 0 {
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
if len(src) == 0 {
|
||||||
|
return append(dst, ".000000"[:decimals+1]...)
|
||||||
|
}
|
||||||
|
|
||||||
|
microsecs := binary.LittleEndian.Uint32(src[:4])
|
||||||
|
p1 := byte(microsecs / 10000)
|
||||||
|
microsecs -= 10000 * uint32(p1)
|
||||||
|
p2 := byte(microsecs / 100)
|
||||||
|
microsecs -= 100 * uint32(p2)
|
||||||
|
p3 := byte(microsecs)
|
||||||
|
|
||||||
|
switch decimals {
|
||||||
|
default:
|
||||||
|
return append(dst, '.',
|
||||||
|
digits10[p1], digits01[p1],
|
||||||
|
digits10[p2], digits01[p2],
|
||||||
|
digits10[p3], digits01[p3],
|
||||||
|
)
|
||||||
|
case 1:
|
||||||
|
return append(dst, '.',
|
||||||
|
digits10[p1],
|
||||||
|
)
|
||||||
|
case 2:
|
||||||
|
return append(dst, '.',
|
||||||
|
digits10[p1], digits01[p1],
|
||||||
|
)
|
||||||
|
case 3:
|
||||||
|
return append(dst, '.',
|
||||||
|
digits10[p1], digits01[p1],
|
||||||
|
digits10[p2],
|
||||||
|
)
|
||||||
|
case 4:
|
||||||
|
return append(dst, '.',
|
||||||
|
digits10[p1], digits01[p1],
|
||||||
|
digits10[p2], digits01[p2],
|
||||||
|
)
|
||||||
|
case 5:
|
||||||
|
return append(dst, '.',
|
||||||
|
digits10[p1], digits01[p1],
|
||||||
|
digits10[p2], digits01[p2],
|
||||||
|
digits10[p3],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func formatBinaryDateTime(src []byte, length uint8) (driver.Value, error) {
|
||||||
// length expects the deterministic length of the zero value,
|
// length expects the deterministic length of the zero value,
|
||||||
// negative time and 100+ hours are automatically added if needed
|
// negative time and 100+ hours are automatically added if needed
|
||||||
if len(src) == 0 {
|
if len(src) == 0 {
|
||||||
if justTime {
|
|
||||||
return zeroDateTime[11 : 11+length], nil
|
|
||||||
}
|
|
||||||
return zeroDateTime[:length], nil
|
return zeroDateTime[:length], nil
|
||||||
}
|
}
|
||||||
var dst []byte // return value
|
var dst []byte // return value
|
||||||
var pt, p1, p2, p3 byte // current digit pair
|
var p1, p2, p3 byte // current digit pair
|
||||||
var zOffs byte // offset of value in zeroDateTime
|
|
||||||
if justTime {
|
switch length {
|
||||||
switch length {
|
case 10, 19, 21, 22, 23, 24, 25, 26:
|
||||||
case
|
default:
|
||||||
8, // time (can be up to 10 when negative and 100+ hours)
|
t := "DATE"
|
||||||
10, 11, 12, 13, 14, 15: // time with fractional seconds
|
if length > 10 {
|
||||||
default:
|
t += "TIME"
|
||||||
return nil, fmt.Errorf("illegal TIME length %d", length)
|
|
||||||
}
|
}
|
||||||
switch len(src) {
|
return nil, fmt.Errorf("illegal %s length %d", t, length)
|
||||||
case 8, 12:
|
|
||||||
default:
|
|
||||||
return nil, fmt.Errorf("invalid TIME packet length %d", len(src))
|
|
||||||
}
|
|
||||||
// +2 to enable negative time and 100+ hours
|
|
||||||
dst = make([]byte, 0, length+2)
|
|
||||||
if src[0] == 1 {
|
|
||||||
dst = append(dst, '-')
|
|
||||||
}
|
|
||||||
if src[1] != 0 {
|
|
||||||
hour := uint16(src[1])*24 + uint16(src[5])
|
|
||||||
pt = byte(hour / 100)
|
|
||||||
p1 = byte(hour - 100*uint16(pt))
|
|
||||||
dst = append(dst, digits01[pt])
|
|
||||||
} else {
|
|
||||||
p1 = src[5]
|
|
||||||
}
|
|
||||||
zOffs = 11
|
|
||||||
src = src[6:]
|
|
||||||
} else {
|
|
||||||
switch length {
|
|
||||||
case 10, 19, 21, 22, 23, 24, 25, 26:
|
|
||||||
default:
|
|
||||||
t := "DATE"
|
|
||||||
if length > 10 {
|
|
||||||
t += "TIME"
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("illegal %s length %d", t, length)
|
|
||||||
}
|
|
||||||
switch len(src) {
|
|
||||||
case 4, 7, 11:
|
|
||||||
default:
|
|
||||||
t := "DATE"
|
|
||||||
if length > 10 {
|
|
||||||
t += "TIME"
|
|
||||||
}
|
|
||||||
return nil, fmt.Errorf("illegal %s packet length %d", t, len(src))
|
|
||||||
}
|
|
||||||
dst = make([]byte, 0, length)
|
|
||||||
// start with the date
|
|
||||||
year := binary.LittleEndian.Uint16(src[:2])
|
|
||||||
pt = byte(year / 100)
|
|
||||||
p1 = byte(year - 100*uint16(pt))
|
|
||||||
p2, p3 = src[2], src[3]
|
|
||||||
dst = append(dst,
|
|
||||||
digits10[pt], digits01[pt],
|
|
||||||
digits10[p1], digits01[p1], '-',
|
|
||||||
digits10[p2], digits01[p2], '-',
|
|
||||||
digits10[p3], digits01[p3],
|
|
||||||
)
|
|
||||||
if length == 10 {
|
|
||||||
return dst, nil
|
|
||||||
}
|
|
||||||
if len(src) == 4 {
|
|
||||||
return append(dst, zeroDateTime[10:length]...), nil
|
|
||||||
}
|
|
||||||
dst = append(dst, ' ')
|
|
||||||
p1 = src[4] // hour
|
|
||||||
src = src[5:]
|
|
||||||
}
|
}
|
||||||
|
switch len(src) {
|
||||||
|
case 4, 7, 11:
|
||||||
|
default:
|
||||||
|
t := "DATE"
|
||||||
|
if length > 10 {
|
||||||
|
t += "TIME"
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("illegal %s packet length %d", t, len(src))
|
||||||
|
}
|
||||||
|
dst = make([]byte, 0, length)
|
||||||
|
// start with the date
|
||||||
|
year := binary.LittleEndian.Uint16(src[:2])
|
||||||
|
pt := year / 100
|
||||||
|
p1 = byte(year - 100*uint16(pt))
|
||||||
|
p2, p3 = src[2], src[3]
|
||||||
|
dst = append(dst,
|
||||||
|
digits10[pt], digits01[pt],
|
||||||
|
digits10[p1], digits01[p1], '-',
|
||||||
|
digits10[p2], digits01[p2], '-',
|
||||||
|
digits10[p3], digits01[p3],
|
||||||
|
)
|
||||||
|
if length == 10 {
|
||||||
|
return dst, nil
|
||||||
|
}
|
||||||
|
if len(src) == 4 {
|
||||||
|
return append(dst, zeroDateTime[10:length]...), nil
|
||||||
|
}
|
||||||
|
dst = append(dst, ' ')
|
||||||
|
p1 = src[4] // hour
|
||||||
|
src = src[5:]
|
||||||
|
|
||||||
// p1 is 2-digit hour, src is after hour
|
// p1 is 2-digit hour, src is after hour
|
||||||
p2, p3 = src[0], src[1]
|
p2, p3 = src[0], src[1]
|
||||||
dst = append(dst,
|
dst = append(dst,
|
||||||
|
@ -427,51 +333,49 @@ func formatBinaryDateTime(src []byte, length uint8, justTime bool) (driver.Value
|
||||||
digits10[p2], digits01[p2], ':',
|
digits10[p2], digits01[p2], ':',
|
||||||
digits10[p3], digits01[p3],
|
digits10[p3], digits01[p3],
|
||||||
)
|
)
|
||||||
if length <= byte(len(dst)) {
|
return appendMicrosecs(dst, src[2:], int(length)-20), nil
|
||||||
return dst, nil
|
}
|
||||||
}
|
|
||||||
src = src[2:]
|
func formatBinaryTime(src []byte, length uint8) (driver.Value, error) {
|
||||||
|
// length expects the deterministic length of the zero value,
|
||||||
|
// negative time and 100+ hours are automatically added if needed
|
||||||
if len(src) == 0 {
|
if len(src) == 0 {
|
||||||
return append(dst, zeroDateTime[19:zOffs+length]...), nil
|
return zeroDateTime[11 : 11+length], nil
|
||||||
}
|
}
|
||||||
microsecs := binary.LittleEndian.Uint32(src[:4])
|
var dst []byte // return value
|
||||||
p1 = byte(microsecs / 10000)
|
|
||||||
microsecs -= 10000 * uint32(p1)
|
switch length {
|
||||||
p2 = byte(microsecs / 100)
|
case
|
||||||
microsecs -= 100 * uint32(p2)
|
8, // time (can be up to 10 when negative and 100+ hours)
|
||||||
p3 = byte(microsecs)
|
10, 11, 12, 13, 14, 15: // time with fractional seconds
|
||||||
switch decimals := zOffs + length - 20; decimals {
|
|
||||||
default:
|
default:
|
||||||
return append(dst, '.',
|
return nil, fmt.Errorf("illegal TIME length %d", length)
|
||||||
digits10[p1], digits01[p1],
|
|
||||||
digits10[p2], digits01[p2],
|
|
||||||
digits10[p3], digits01[p3],
|
|
||||||
), nil
|
|
||||||
case 1:
|
|
||||||
return append(dst, '.',
|
|
||||||
digits10[p1],
|
|
||||||
), nil
|
|
||||||
case 2:
|
|
||||||
return append(dst, '.',
|
|
||||||
digits10[p1], digits01[p1],
|
|
||||||
), nil
|
|
||||||
case 3:
|
|
||||||
return append(dst, '.',
|
|
||||||
digits10[p1], digits01[p1],
|
|
||||||
digits10[p2],
|
|
||||||
), nil
|
|
||||||
case 4:
|
|
||||||
return append(dst, '.',
|
|
||||||
digits10[p1], digits01[p1],
|
|
||||||
digits10[p2], digits01[p2],
|
|
||||||
), nil
|
|
||||||
case 5:
|
|
||||||
return append(dst, '.',
|
|
||||||
digits10[p1], digits01[p1],
|
|
||||||
digits10[p2], digits01[p2],
|
|
||||||
digits10[p3],
|
|
||||||
), nil
|
|
||||||
}
|
}
|
||||||
|
switch len(src) {
|
||||||
|
case 8, 12:
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("invalid TIME packet length %d", len(src))
|
||||||
|
}
|
||||||
|
// +2 to enable negative time and 100+ hours
|
||||||
|
dst = make([]byte, 0, length+2)
|
||||||
|
if src[0] == 1 {
|
||||||
|
dst = append(dst, '-')
|
||||||
|
}
|
||||||
|
days := binary.LittleEndian.Uint32(src[1:5])
|
||||||
|
hours := int64(days)*24 + int64(src[5])
|
||||||
|
|
||||||
|
if hours >= 100 {
|
||||||
|
dst = strconv.AppendInt(dst, hours, 10)
|
||||||
|
} else {
|
||||||
|
dst = append(dst, digits10[hours], digits01[hours])
|
||||||
|
}
|
||||||
|
|
||||||
|
min, sec := src[6], src[7]
|
||||||
|
dst = append(dst, ':',
|
||||||
|
digits10[min], digits01[min], ':',
|
||||||
|
digits10[sec], digits01[sec],
|
||||||
|
)
|
||||||
|
return appendMicrosecs(dst, src[8:], int(length)-9), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
|
@ -537,7 +441,7 @@ func readLengthEncodedString(b []byte) ([]byte, bool, int, error) {
|
||||||
|
|
||||||
// Check data length
|
// Check data length
|
||||||
if len(b) >= n {
|
if len(b) >= n {
|
||||||
return b[n-int(num) : n], false, n, nil
|
return b[n-int(num) : n : n], false, n, nil
|
||||||
}
|
}
|
||||||
return nil, false, n, io.EOF
|
return nil, false, n, io.EOF
|
||||||
}
|
}
|
||||||
|
@ -566,8 +470,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
|
||||||
|
@ -800,7 +704,7 @@ func (ab *atomicBool) TrySet(value bool) bool {
|
||||||
return atomic.SwapUint32(&ab.value, 0) > 0
|
return atomic.SwapUint32(&ab.value, 0) > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// atomicBool is a wrapper for atomically accessed error values
|
// atomicError is a wrapper for atomically accessed error values
|
||||||
type atomicError struct {
|
type atomicError struct {
|
||||||
_noCopy noCopy
|
_noCopy noCopy
|
||||||
value atomic.Value
|
value atomic.Value
|
||||||
|
|
3
vendor/github.com/go-sql-driver/mysql/utils_go18.go
generated
vendored
3
vendor/github.com/go-sql-driver/mysql/utils_go18.go
generated
vendored
|
@ -15,6 +15,7 @@ import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"database/sql/driver"
|
"database/sql/driver"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
)
|
)
|
||||||
|
|
||||||
func cloneTLSConfig(c *tls.Config) *tls.Config {
|
func cloneTLSConfig(c *tls.Config) *tls.Config {
|
||||||
|
@ -44,6 +45,6 @@ func mapIsolationLevel(level driver.IsolationLevel) (string, error) {
|
||||||
case sql.LevelSerializable:
|
case sql.LevelSerializable:
|
||||||
return "SERIALIZABLE", nil
|
return "SERIALIZABLE", nil
|
||||||
default:
|
default:
|
||||||
return "", errors.New("mysql: unsupported isolation level: " + string(level))
|
return "", fmt.Errorf("mysql: unsupported isolation level: %v", level)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
18
vendor/github.com/go-sql-driver/mysql/utils_legacy.go
generated
vendored
18
vendor/github.com/go-sql-driver/mysql/utils_legacy.go
generated
vendored
|
@ -1,18 +0,0 @@
|
||||||
// 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
|
|
||||||
|
|
||||||
package mysql
|
|
||||||
|
|
||||||
import "crypto/tls"
|
|
||||||
|
|
||||||
func cloneTLSConfig(c *tls.Config) *tls.Config {
|
|
||||||
clone := *c
|
|
||||||
return &clone
|
|
||||||
}
|
|
4
vendor/github.com/mattn/go-sqlite3/.travis.yml
generated
vendored
4
vendor/github.com/mattn/go-sqlite3/.travis.yml
generated
vendored
|
@ -12,18 +12,18 @@ env:
|
||||||
matrix:
|
matrix:
|
||||||
- GOTAGS=
|
- GOTAGS=
|
||||||
- GOTAGS=libsqlite3
|
- GOTAGS=libsqlite3
|
||||||
- GOTAGS="sqlite_allow_uri_authority sqlite_app_armor sqlite_foreign_keys sqlite_fts5 sqlite_icu sqlite_introspect sqlite_json sqlite_secure_delete sqlite_see sqlite_stat4 sqlite_trace sqlite_userauth sqlite_vacuum_incr sqlite_vtable"
|
- GOTAGS="sqlite_allow_uri_authority sqlite_app_armor sqlite_foreign_keys sqlite_fts5 sqlite_icu sqlite_introspect sqlite_json sqlite_secure_delete sqlite_see sqlite_stat4 sqlite_trace sqlite_userauth sqlite_vacuum_incr sqlite_vtable sqlite_unlock_notify"
|
||||||
- GOTAGS=sqlite_vacuum_full
|
- GOTAGS=sqlite_vacuum_full
|
||||||
|
|
||||||
go:
|
go:
|
||||||
- 1.9.x
|
- 1.9.x
|
||||||
- 1.10.x
|
- 1.10.x
|
||||||
|
- 1.11.x
|
||||||
|
|
||||||
before_install:
|
before_install:
|
||||||
- |
|
- |
|
||||||
if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
|
if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
|
||||||
brew update
|
brew update
|
||||||
brew upgrade icu4c
|
|
||||||
fi
|
fi
|
||||||
- |
|
- |
|
||||||
go get github.com/smartystreets/goconvey
|
go get github.com/smartystreets/goconvey
|
||||||
|
|
7
vendor/github.com/mattn/go-sqlite3/README.md
generated
vendored
7
vendor/github.com/mattn/go-sqlite3/README.md
generated
vendored
|
@ -67,6 +67,7 @@ This is also known as a DSN string. (Data Source Name).
|
||||||
|
|
||||||
Options are append after the filename of the SQLite database.
|
Options are append after the filename of the SQLite database.
|
||||||
The database filename and options are seperated by an `?` (Question Mark).
|
The database filename and options are seperated by an `?` (Question Mark).
|
||||||
|
Options should be URL-encoded (see [url.QueryEscape](https://golang.org/pkg/net/url/#QueryEscape)).
|
||||||
|
|
||||||
This also applies when using an in-memory database instead of a file.
|
This also applies when using an in-memory database instead of a file.
|
||||||
|
|
||||||
|
@ -198,7 +199,7 @@ Additional information:
|
||||||
|
|
||||||
# Google Cloud Platform
|
# Google Cloud Platform
|
||||||
|
|
||||||
Building on GCP is not possible because `Google Cloud Platform does not allow `gcc` to be executed.
|
Building on GCP is not possible because Google Cloud Platform does not allow `gcc` to be executed.
|
||||||
|
|
||||||
Please work only with compiled final binaries.
|
Please work only with compiled final binaries.
|
||||||
|
|
||||||
|
@ -290,7 +291,7 @@ For example the TDM-GCC Toolchain can be found [here](ttps://sourceforge.net/pro
|
||||||
When receiving a compile time error referencing recompile with `-FPIC` then you
|
When receiving a compile time error referencing recompile with `-FPIC` then you
|
||||||
are probably using a hardend system.
|
are probably using a hardend system.
|
||||||
|
|
||||||
You can copile the library on a hardend system with the following command.
|
You can compile the library on a hardend system with the following command.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
go build -ldflags '-extldflags=-fno-PIC'
|
go build -ldflags '-extldflags=-fno-PIC'
|
||||||
|
@ -473,7 +474,7 @@ For an example see [shaxbee/go-spatialite](https://github.com/shaxbee/go-spatial
|
||||||
|
|
||||||
For more information see [#289](https://github.com/mattn/go-sqlite3/issues/289)
|
For more information see [#289](https://github.com/mattn/go-sqlite3/issues/289)
|
||||||
|
|
||||||
- Trying to execure a `.` (dot) command throws an error.
|
- Trying to execute a `.` (dot) command throws an error.
|
||||||
|
|
||||||
Error: `Error: near ".": syntax error`
|
Error: `Error: near ".": syntax error`
|
||||||
Dot command are part of SQLite3 CLI not of this library.
|
Dot command are part of SQLite3 CLI not of this library.
|
||||||
|
|
6
vendor/github.com/mattn/go-sqlite3/callback.go
generated
vendored
6
vendor/github.com/mattn/go-sqlite3/callback.go
generated
vendored
|
@ -77,6 +77,12 @@ func updateHookTrampoline(handle uintptr, op int, db *C.char, table *C.char, row
|
||||||
callback(op, C.GoString(db), C.GoString(table), rowid)
|
callback(op, C.GoString(db), C.GoString(table), rowid)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//export authorizerTrampoline
|
||||||
|
func authorizerTrampoline(handle uintptr, op int, arg1 *C.char, arg2 *C.char, arg3 *C.char) int {
|
||||||
|
callback := lookupHandle(handle).(func(int, string, string, string) int)
|
||||||
|
return callback(op, C.GoString(arg1), C.GoString(arg2), C.GoString(arg3))
|
||||||
|
}
|
||||||
|
|
||||||
// Use handles to avoid passing Go pointers to C.
|
// Use handles to avoid passing Go pointers to C.
|
||||||
|
|
||||||
type handleVal struct {
|
type handleVal struct {
|
||||||
|
|
21393
vendor/github.com/mattn/go-sqlite3/sqlite3-binding.c
generated
vendored
21393
vendor/github.com/mattn/go-sqlite3/sqlite3-binding.c
generated
vendored
File diff suppressed because it is too large
Load diff
293
vendor/github.com/mattn/go-sqlite3/sqlite3-binding.h
generated
vendored
293
vendor/github.com/mattn/go-sqlite3/sqlite3-binding.h
generated
vendored
|
@ -124,9 +124,9 @@ extern "C" {
|
||||||
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
|
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
|
||||||
** [sqlite_version()] and [sqlite_source_id()].
|
** [sqlite_version()] and [sqlite_source_id()].
|
||||||
*/
|
*/
|
||||||
#define SQLITE_VERSION "3.24.0"
|
#define SQLITE_VERSION "3.25.2"
|
||||||
#define SQLITE_VERSION_NUMBER 3024000
|
#define SQLITE_VERSION_NUMBER 3025002
|
||||||
#define SQLITE_SOURCE_ID "2018-06-04 19:24:41 c7ee0833225bfd8c5ec2f9bf62b97c4e04d03bd9566366d5221ac8fb199a87ca"
|
#define SQLITE_SOURCE_ID "2018-09-25 19:08:10 fb90e7189ae6d62e77ba3a308ca5d683f90bbe633cf681865365b8e92792d1c7"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** CAPI3REF: Run-Time Library Version Numbers
|
** CAPI3REF: Run-Time Library Version Numbers
|
||||||
|
@ -473,6 +473,7 @@ SQLITE_API int sqlite3_exec(
|
||||||
*/
|
*/
|
||||||
#define SQLITE_ERROR_MISSING_COLLSEQ (SQLITE_ERROR | (1<<8))
|
#define SQLITE_ERROR_MISSING_COLLSEQ (SQLITE_ERROR | (1<<8))
|
||||||
#define SQLITE_ERROR_RETRY (SQLITE_ERROR | (2<<8))
|
#define SQLITE_ERROR_RETRY (SQLITE_ERROR | (2<<8))
|
||||||
|
#define SQLITE_ERROR_SNAPSHOT (SQLITE_ERROR | (3<<8))
|
||||||
#define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8))
|
#define SQLITE_IOERR_READ (SQLITE_IOERR | (1<<8))
|
||||||
#define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8))
|
#define SQLITE_IOERR_SHORT_READ (SQLITE_IOERR | (2<<8))
|
||||||
#define SQLITE_IOERR_WRITE (SQLITE_IOERR | (3<<8))
|
#define SQLITE_IOERR_WRITE (SQLITE_IOERR | (3<<8))
|
||||||
|
@ -512,6 +513,7 @@ SQLITE_API int sqlite3_exec(
|
||||||
#define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8))
|
#define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8))
|
||||||
#define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8))
|
#define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8))
|
||||||
#define SQLITE_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<8))
|
#define SQLITE_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<8))
|
||||||
|
#define SQLITE_CANTOPEN_DIRTYWAL (SQLITE_CANTOPEN | (5<<8)) /* Not Used */
|
||||||
#define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8))
|
#define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8))
|
||||||
#define SQLITE_CORRUPT_SEQUENCE (SQLITE_CORRUPT | (2<<8))
|
#define SQLITE_CORRUPT_SEQUENCE (SQLITE_CORRUPT | (2<<8))
|
||||||
#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8))
|
#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8))
|
||||||
|
@ -887,7 +889,8 @@ struct sqlite3_io_methods {
|
||||||
** <li>[[SQLITE_FCNTL_PERSIST_WAL]]
|
** <li>[[SQLITE_FCNTL_PERSIST_WAL]]
|
||||||
** ^The [SQLITE_FCNTL_PERSIST_WAL] opcode is used to set or query the
|
** ^The [SQLITE_FCNTL_PERSIST_WAL] opcode is used to set or query the
|
||||||
** persistent [WAL | Write Ahead Log] setting. By default, the auxiliary
|
** persistent [WAL | Write Ahead Log] setting. By default, the auxiliary
|
||||||
** write ahead log and shared memory files used for transaction control
|
** write ahead log ([WAL file]) and shared memory
|
||||||
|
** files used for transaction control
|
||||||
** are automatically deleted when the latest connection to the database
|
** are automatically deleted when the latest connection to the database
|
||||||
** closes. Setting persistent WAL mode causes those files to persist after
|
** closes. Setting persistent WAL mode causes those files to persist after
|
||||||
** close. Persisting the files is useful when other processes that do not
|
** close. Persisting the files is useful when other processes that do not
|
||||||
|
@ -1073,6 +1076,26 @@ struct sqlite3_io_methods {
|
||||||
** a file lock using the xLock or xShmLock methods of the VFS to wait
|
** a file lock using the xLock or xShmLock methods of the VFS to wait
|
||||||
** for up to M milliseconds before failing, where M is the single
|
** for up to M milliseconds before failing, where M is the single
|
||||||
** unsigned integer parameter.
|
** unsigned integer parameter.
|
||||||
|
**
|
||||||
|
** <li>[[SQLITE_FCNTL_DATA_VERSION]]
|
||||||
|
** The [SQLITE_FCNTL_DATA_VERSION] opcode is used to detect changes to
|
||||||
|
** a database file. The argument is a pointer to a 32-bit unsigned integer.
|
||||||
|
** The "data version" for the pager is written into the pointer. The
|
||||||
|
** "data version" changes whenever any change occurs to the corresponding
|
||||||
|
** database file, either through SQL statements on the same database
|
||||||
|
** connection or through transactions committed by separate database
|
||||||
|
** connections possibly in other processes. The [sqlite3_total_changes()]
|
||||||
|
** interface can be used to find if any database on the connection has changed,
|
||||||
|
** but that interface responds to changes on TEMP as well as MAIN and does
|
||||||
|
** not provide a mechanism to detect changes to MAIN only. Also, the
|
||||||
|
** [sqlite3_total_changes()] interface responds to internal changes only and
|
||||||
|
** omits changes made by other database connections. The
|
||||||
|
** [PRAGMA data_version] command provide a mechanism to detect changes to
|
||||||
|
** a single attached database that occur due to other database connections,
|
||||||
|
** but omits changes implemented by the database connection on which it is
|
||||||
|
** called. This file control is the only mechanism to detect changes that
|
||||||
|
** happen either internally or externally and that are associated with
|
||||||
|
** a particular attached database.
|
||||||
** </ul>
|
** </ul>
|
||||||
*/
|
*/
|
||||||
#define SQLITE_FCNTL_LOCKSTATE 1
|
#define SQLITE_FCNTL_LOCKSTATE 1
|
||||||
|
@ -1108,6 +1131,7 @@ struct sqlite3_io_methods {
|
||||||
#define SQLITE_FCNTL_COMMIT_ATOMIC_WRITE 32
|
#define SQLITE_FCNTL_COMMIT_ATOMIC_WRITE 32
|
||||||
#define SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE 33
|
#define SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE 33
|
||||||
#define SQLITE_FCNTL_LOCK_TIMEOUT 34
|
#define SQLITE_FCNTL_LOCK_TIMEOUT 34
|
||||||
|
#define SQLITE_FCNTL_DATA_VERSION 35
|
||||||
|
|
||||||
/* deprecated names */
|
/* deprecated names */
|
||||||
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
|
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
|
||||||
|
@ -2122,6 +2146,12 @@ struct sqlite3_mem_methods {
|
||||||
** with no schema and no content. The following process works even for
|
** with no schema and no content. The following process works even for
|
||||||
** a badly corrupted database file:
|
** a badly corrupted database file:
|
||||||
** <ol>
|
** <ol>
|
||||||
|
** <li> If the database connection is newly opened, make sure it has read the
|
||||||
|
** database schema by preparing then discarding some query against the
|
||||||
|
** database, or calling sqlite3_table_column_metadata(), ignoring any
|
||||||
|
** errors. This step is only necessary if the application desires to keep
|
||||||
|
** the database in WAL mode after the reset if it was in WAL mode before
|
||||||
|
** the reset.
|
||||||
** <li> sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 1, 0);
|
** <li> sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 1, 0);
|
||||||
** <li> [sqlite3_exec](db, "[VACUUM]", 0, 0, 0);
|
** <li> [sqlite3_exec](db, "[VACUUM]", 0, 0, 0);
|
||||||
** <li> sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0);
|
** <li> sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0);
|
||||||
|
@ -2270,12 +2300,17 @@ SQLITE_API void sqlite3_set_last_insert_rowid(sqlite3*,sqlite3_int64);
|
||||||
** program, the value returned reflects the number of rows modified by the
|
** program, the value returned reflects the number of rows modified by the
|
||||||
** previous INSERT, UPDATE or DELETE statement within the same trigger.
|
** previous INSERT, UPDATE or DELETE statement within the same trigger.
|
||||||
**
|
**
|
||||||
** See also the [sqlite3_total_changes()] interface, the
|
|
||||||
** [count_changes pragma], and the [changes() SQL function].
|
|
||||||
**
|
|
||||||
** If a separate thread makes changes on the same database connection
|
** If a separate thread makes changes on the same database connection
|
||||||
** while [sqlite3_changes()] is running then the value returned
|
** while [sqlite3_changes()] is running then the value returned
|
||||||
** is unpredictable and not meaningful.
|
** is unpredictable and not meaningful.
|
||||||
|
**
|
||||||
|
** See also:
|
||||||
|
** <ul>
|
||||||
|
** <li> the [sqlite3_total_changes()] interface
|
||||||
|
** <li> the [count_changes pragma]
|
||||||
|
** <li> the [changes() SQL function]
|
||||||
|
** <li> the [data_version pragma]
|
||||||
|
** </ul>
|
||||||
*/
|
*/
|
||||||
SQLITE_API int sqlite3_changes(sqlite3*);
|
SQLITE_API int sqlite3_changes(sqlite3*);
|
||||||
|
|
||||||
|
@ -2293,13 +2328,26 @@ SQLITE_API int sqlite3_changes(sqlite3*);
|
||||||
** count, but those made as part of REPLACE constraint resolution are
|
** count, but those made as part of REPLACE constraint resolution are
|
||||||
** not. ^Changes to a view that are intercepted by INSTEAD OF triggers
|
** not. ^Changes to a view that are intercepted by INSTEAD OF triggers
|
||||||
** are not counted.
|
** are not counted.
|
||||||
**
|
|
||||||
** See also the [sqlite3_changes()] interface, the
|
|
||||||
** [count_changes pragma], and the [total_changes() SQL function].
|
|
||||||
**
|
**
|
||||||
|
** This the [sqlite3_total_changes(D)] interface only reports the number
|
||||||
|
** of rows that changed due to SQL statement run against database
|
||||||
|
** connection D. Any changes by other database connections are ignored.
|
||||||
|
** To detect changes against a database file from other database
|
||||||
|
** connections use the [PRAGMA data_version] command or the
|
||||||
|
** [SQLITE_FCNTL_DATA_VERSION] [file control].
|
||||||
|
**
|
||||||
** If a separate thread makes changes on the same database connection
|
** If a separate thread makes changes on the same database connection
|
||||||
** while [sqlite3_total_changes()] is running then the value
|
** while [sqlite3_total_changes()] is running then the value
|
||||||
** returned is unpredictable and not meaningful.
|
** returned is unpredictable and not meaningful.
|
||||||
|
**
|
||||||
|
** See also:
|
||||||
|
** <ul>
|
||||||
|
** <li> the [sqlite3_changes()] interface
|
||||||
|
** <li> the [count_changes pragma]
|
||||||
|
** <li> the [changes() SQL function]
|
||||||
|
** <li> the [data_version pragma]
|
||||||
|
** <li> the [SQLITE_FCNTL_DATA_VERSION] [file control]
|
||||||
|
** </ul>
|
||||||
*/
|
*/
|
||||||
SQLITE_API int sqlite3_total_changes(sqlite3*);
|
SQLITE_API int sqlite3_total_changes(sqlite3*);
|
||||||
|
|
||||||
|
@ -3355,13 +3403,24 @@ SQLITE_API sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int
|
||||||
** [database connection] D failed, then the sqlite3_errcode(D) interface
|
** [database connection] D failed, then the sqlite3_errcode(D) interface
|
||||||
** returns the numeric [result code] or [extended result code] for that
|
** returns the numeric [result code] or [extended result code] for that
|
||||||
** API call.
|
** API call.
|
||||||
** If the most recent API call was successful,
|
|
||||||
** then the return value from sqlite3_errcode() is undefined.
|
|
||||||
** ^The sqlite3_extended_errcode()
|
** ^The sqlite3_extended_errcode()
|
||||||
** interface is the same except that it always returns the
|
** interface is the same except that it always returns the
|
||||||
** [extended result code] even when extended result codes are
|
** [extended result code] even when extended result codes are
|
||||||
** disabled.
|
** disabled.
|
||||||
**
|
**
|
||||||
|
** The values returned by sqlite3_errcode() and/or
|
||||||
|
** sqlite3_extended_errcode() might change with each API call.
|
||||||
|
** Except, there are some interfaces that are guaranteed to never
|
||||||
|
** change the value of the error code. The error-code preserving
|
||||||
|
** interfaces are:
|
||||||
|
**
|
||||||
|
** <ul>
|
||||||
|
** <li> sqlite3_errcode()
|
||||||
|
** <li> sqlite3_extended_errcode()
|
||||||
|
** <li> sqlite3_errmsg()
|
||||||
|
** <li> sqlite3_errmsg16()
|
||||||
|
** </ul>
|
||||||
|
**
|
||||||
** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language
|
** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language
|
||||||
** text that describes the error, as either UTF-8 or UTF-16 respectively.
|
** text that describes the error, as either UTF-8 or UTF-16 respectively.
|
||||||
** ^(Memory to hold the error message string is managed internally.
|
** ^(Memory to hold the error message string is managed internally.
|
||||||
|
@ -4515,11 +4574,25 @@ SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
|
||||||
** from [sqlite3_column_blob()], [sqlite3_column_text()], etc. into
|
** from [sqlite3_column_blob()], [sqlite3_column_text()], etc. into
|
||||||
** [sqlite3_free()].
|
** [sqlite3_free()].
|
||||||
**
|
**
|
||||||
** ^(If a memory allocation error occurs during the evaluation of any
|
** As long as the input parameters are correct, these routines will only
|
||||||
** of these routines, a default value is returned. The default value
|
** fail if an out-of-memory error occurs during a format conversion.
|
||||||
** is either the integer 0, the floating point number 0.0, or a NULL
|
** Only the following subset of interfaces are subject to out-of-memory
|
||||||
** pointer. Subsequent calls to [sqlite3_errcode()] will return
|
** errors:
|
||||||
** [SQLITE_NOMEM].)^
|
**
|
||||||
|
** <ul>
|
||||||
|
** <li> sqlite3_column_blob()
|
||||||
|
** <li> sqlite3_column_text()
|
||||||
|
** <li> sqlite3_column_text16()
|
||||||
|
** <li> sqlite3_column_bytes()
|
||||||
|
** <li> sqlite3_column_bytes16()
|
||||||
|
** </ul>
|
||||||
|
**
|
||||||
|
** If an out-of-memory error occurs, then the return value from these
|
||||||
|
** routines is the same as if the column had contained an SQL NULL value.
|
||||||
|
** Valid SQL NULL returns can be distinguished from out-of-memory errors
|
||||||
|
** by invoking the [sqlite3_errcode()] immediately after the suspect
|
||||||
|
** return value is obtained and before any
|
||||||
|
** other SQLite interface is called on the same [database connection].
|
||||||
*/
|
*/
|
||||||
SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
|
SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
|
||||||
SQLITE_API double sqlite3_column_double(sqlite3_stmt*, int iCol);
|
SQLITE_API double sqlite3_column_double(sqlite3_stmt*, int iCol);
|
||||||
|
@ -4596,11 +4669,13 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
|
||||||
**
|
**
|
||||||
** ^These functions (collectively known as "function creation routines")
|
** ^These functions (collectively known as "function creation routines")
|
||||||
** are used to add SQL functions or aggregates or to redefine the behavior
|
** are used to add SQL functions or aggregates or to redefine the behavior
|
||||||
** of existing SQL functions or aggregates. The only differences between
|
** of existing SQL functions or aggregates. The only differences between
|
||||||
** these routines are the text encoding expected for
|
** the three "sqlite3_create_function*" routines are the text encoding
|
||||||
** the second parameter (the name of the function being created)
|
** expected for the second parameter (the name of the function being
|
||||||
** and the presence or absence of a destructor callback for
|
** created) and the presence or absence of a destructor callback for
|
||||||
** the application data pointer.
|
** the application data pointer. Function sqlite3_create_window_function()
|
||||||
|
** is similar, but allows the user to supply the extra callback functions
|
||||||
|
** needed by [aggregate window functions].
|
||||||
**
|
**
|
||||||
** ^The first parameter is the [database connection] to which the SQL
|
** ^The first parameter is the [database connection] to which the SQL
|
||||||
** function is to be added. ^If an application uses more than one database
|
** function is to be added. ^If an application uses more than one database
|
||||||
|
@ -4646,7 +4721,8 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
|
||||||
** ^(The fifth parameter is an arbitrary pointer. The implementation of the
|
** ^(The fifth parameter is an arbitrary pointer. The implementation of the
|
||||||
** function can gain access to this pointer using [sqlite3_user_data()].)^
|
** function can gain access to this pointer using [sqlite3_user_data()].)^
|
||||||
**
|
**
|
||||||
** ^The sixth, seventh and eighth parameters, xFunc, xStep and xFinal, are
|
** ^The sixth, seventh and eighth parameters passed to the three
|
||||||
|
** "sqlite3_create_function*" functions, xFunc, xStep and xFinal, are
|
||||||
** pointers to C-language functions that implement the SQL function or
|
** pointers to C-language functions that implement the SQL function or
|
||||||
** aggregate. ^A scalar SQL function requires an implementation of the xFunc
|
** aggregate. ^A scalar SQL function requires an implementation of the xFunc
|
||||||
** callback only; NULL pointers must be passed as the xStep and xFinal
|
** callback only; NULL pointers must be passed as the xStep and xFinal
|
||||||
|
@ -4655,15 +4731,24 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
|
||||||
** SQL function or aggregate, pass NULL pointers for all three function
|
** SQL function or aggregate, pass NULL pointers for all three function
|
||||||
** callbacks.
|
** callbacks.
|
||||||
**
|
**
|
||||||
** ^(If the ninth parameter to sqlite3_create_function_v2() is not NULL,
|
** ^The sixth, seventh, eighth and ninth parameters (xStep, xFinal, xValue
|
||||||
** then it is destructor for the application data pointer.
|
** and xInverse) passed to sqlite3_create_window_function are pointers to
|
||||||
** The destructor is invoked when the function is deleted, either by being
|
** C-language callbacks that implement the new function. xStep and xFinal
|
||||||
** overloaded or when the database connection closes.)^
|
** must both be non-NULL. xValue and xInverse may either both be NULL, in
|
||||||
** ^The destructor is also invoked if the call to
|
** which case a regular aggregate function is created, or must both be
|
||||||
** sqlite3_create_function_v2() fails.
|
** non-NULL, in which case the new function may be used as either an aggregate
|
||||||
** ^When the destructor callback of the tenth parameter is invoked, it
|
** or aggregate window function. More details regarding the implementation
|
||||||
** is passed a single argument which is a copy of the application data
|
** of aggregate window functions are
|
||||||
** pointer which was the fifth parameter to sqlite3_create_function_v2().
|
** [user-defined window functions|available here].
|
||||||
|
**
|
||||||
|
** ^(If the final parameter to sqlite3_create_function_v2() or
|
||||||
|
** sqlite3_create_window_function() is not NULL, then it is destructor for
|
||||||
|
** the application data pointer. The destructor is invoked when the function
|
||||||
|
** is deleted, either by being overloaded or when the database connection
|
||||||
|
** closes.)^ ^The destructor is also invoked if the call to
|
||||||
|
** sqlite3_create_function_v2() fails. ^When the destructor callback is
|
||||||
|
** invoked, it is passed a single argument which is a copy of the application
|
||||||
|
** data pointer which was the fifth parameter to sqlite3_create_function_v2().
|
||||||
**
|
**
|
||||||
** ^It is permitted to register multiple implementations of the same
|
** ^It is permitted to register multiple implementations of the same
|
||||||
** functions with the same name but with either differing numbers of
|
** functions with the same name but with either differing numbers of
|
||||||
|
@ -4716,6 +4801,18 @@ SQLITE_API int sqlite3_create_function_v2(
|
||||||
void (*xFinal)(sqlite3_context*),
|
void (*xFinal)(sqlite3_context*),
|
||||||
void(*xDestroy)(void*)
|
void(*xDestroy)(void*)
|
||||||
);
|
);
|
||||||
|
SQLITE_API int sqlite3_create_window_function(
|
||||||
|
sqlite3 *db,
|
||||||
|
const char *zFunctionName,
|
||||||
|
int nArg,
|
||||||
|
int eTextRep,
|
||||||
|
void *pApp,
|
||||||
|
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
|
||||||
|
void (*xFinal)(sqlite3_context*),
|
||||||
|
void (*xValue)(sqlite3_context*),
|
||||||
|
void (*xInverse)(sqlite3_context*,int,sqlite3_value**),
|
||||||
|
void(*xDestroy)(void*)
|
||||||
|
);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** CAPI3REF: Text Encodings
|
** CAPI3REF: Text Encodings
|
||||||
|
@ -4858,6 +4955,28 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6
|
||||||
**
|
**
|
||||||
** These routines must be called from the same thread as
|
** These routines must be called from the same thread as
|
||||||
** the SQL function that supplied the [sqlite3_value*] parameters.
|
** the SQL function that supplied the [sqlite3_value*] parameters.
|
||||||
|
**
|
||||||
|
** As long as the input parameter is correct, these routines can only
|
||||||
|
** fail if an out-of-memory error occurs during a format conversion.
|
||||||
|
** Only the following subset of interfaces are subject to out-of-memory
|
||||||
|
** errors:
|
||||||
|
**
|
||||||
|
** <ul>
|
||||||
|
** <li> sqlite3_value_blob()
|
||||||
|
** <li> sqlite3_value_text()
|
||||||
|
** <li> sqlite3_value_text16()
|
||||||
|
** <li> sqlite3_value_text16le()
|
||||||
|
** <li> sqlite3_value_text16be()
|
||||||
|
** <li> sqlite3_value_bytes()
|
||||||
|
** <li> sqlite3_value_bytes16()
|
||||||
|
** </ul>
|
||||||
|
**
|
||||||
|
** If an out-of-memory error occurs, then the return value from these
|
||||||
|
** routines is the same as if the column had contained an SQL NULL value.
|
||||||
|
** Valid SQL NULL returns can be distinguished from out-of-memory errors
|
||||||
|
** by invoking the [sqlite3_errcode()] immediately after the suspect
|
||||||
|
** return value is obtained and before any
|
||||||
|
** other SQLite interface is called on the same [database connection].
|
||||||
*/
|
*/
|
||||||
SQLITE_API const void *sqlite3_value_blob(sqlite3_value*);
|
SQLITE_API const void *sqlite3_value_blob(sqlite3_value*);
|
||||||
SQLITE_API double sqlite3_value_double(sqlite3_value*);
|
SQLITE_API double sqlite3_value_double(sqlite3_value*);
|
||||||
|
@ -6324,6 +6443,7 @@ struct sqlite3_index_info {
|
||||||
#define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70
|
#define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70
|
||||||
#define SQLITE_INDEX_CONSTRAINT_ISNULL 71
|
#define SQLITE_INDEX_CONSTRAINT_ISNULL 71
|
||||||
#define SQLITE_INDEX_CONSTRAINT_IS 72
|
#define SQLITE_INDEX_CONSTRAINT_IS 72
|
||||||
|
#define SQLITE_INDEX_CONSTRAINT_FUNCTION 150
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** CAPI3REF: Register A Virtual Table Implementation
|
** CAPI3REF: Register A Virtual Table Implementation
|
||||||
|
@ -7000,6 +7120,7 @@ SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*);
|
||||||
/*
|
/*
|
||||||
** CAPI3REF: Low-Level Control Of Database Files
|
** CAPI3REF: Low-Level Control Of Database Files
|
||||||
** METHOD: sqlite3
|
** METHOD: sqlite3
|
||||||
|
** KEYWORDS: {file control}
|
||||||
**
|
**
|
||||||
** ^The [sqlite3_file_control()] interface makes a direct call to the
|
** ^The [sqlite3_file_control()] interface makes a direct call to the
|
||||||
** xFileControl method for the [sqlite3_io_methods] object associated
|
** xFileControl method for the [sqlite3_io_methods] object associated
|
||||||
|
@ -7014,11 +7135,18 @@ SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*);
|
||||||
** the xFileControl method. ^The return value of the xFileControl
|
** the xFileControl method. ^The return value of the xFileControl
|
||||||
** method becomes the return value of this routine.
|
** method becomes the return value of this routine.
|
||||||
**
|
**
|
||||||
|
** A few opcodes for [sqlite3_file_control()] are handled directly
|
||||||
|
** by the SQLite core and never invoke the
|
||||||
|
** sqlite3_io_methods.xFileControl method.
|
||||||
** ^The [SQLITE_FCNTL_FILE_POINTER] value for the op parameter causes
|
** ^The [SQLITE_FCNTL_FILE_POINTER] value for the op parameter causes
|
||||||
** a pointer to the underlying [sqlite3_file] object to be written into
|
** a pointer to the underlying [sqlite3_file] object to be written into
|
||||||
** the space pointed to by the 4th parameter. ^The [SQLITE_FCNTL_FILE_POINTER]
|
** the space pointed to by the 4th parameter. The
|
||||||
** case is a short-circuit path which does not actually invoke the
|
** [SQLITE_FCNTL_JOURNAL_POINTER] works similarly except that it returns
|
||||||
** underlying sqlite3_io_methods.xFileControl method.
|
** the [sqlite3_file] object associated with the journal file instead of
|
||||||
|
** the main database. The [SQLITE_FCNTL_VFS_POINTER] opcode returns
|
||||||
|
** a pointer to the underlying [sqlite3_vfs] object for the file.
|
||||||
|
** The [SQLITE_FCNTL_DATA_VERSION] returns the data version counter
|
||||||
|
** from the pager.
|
||||||
**
|
**
|
||||||
** ^If the second parameter (zDbName) does not match the name of any
|
** ^If the second parameter (zDbName) does not match the name of any
|
||||||
** open database file, then SQLITE_ERROR is returned. ^This error
|
** open database file, then SQLITE_ERROR is returned. ^This error
|
||||||
|
@ -8837,7 +8965,6 @@ SQLITE_API int sqlite3_system_errno(sqlite3*);
|
||||||
/*
|
/*
|
||||||
** CAPI3REF: Database Snapshot
|
** CAPI3REF: Database Snapshot
|
||||||
** KEYWORDS: {snapshot} {sqlite3_snapshot}
|
** KEYWORDS: {snapshot} {sqlite3_snapshot}
|
||||||
** EXPERIMENTAL
|
|
||||||
**
|
**
|
||||||
** An instance of the snapshot object records the state of a [WAL mode]
|
** An instance of the snapshot object records the state of a [WAL mode]
|
||||||
** database for some specific point in history.
|
** database for some specific point in history.
|
||||||
|
@ -8854,11 +8981,6 @@ SQLITE_API int sqlite3_system_errno(sqlite3*);
|
||||||
** version of the database file so that it is possible to later open a new read
|
** version of the database file so that it is possible to later open a new read
|
||||||
** transaction that sees that historical version of the database rather than
|
** transaction that sees that historical version of the database rather than
|
||||||
** the most recent version.
|
** the most recent version.
|
||||||
**
|
|
||||||
** The constructor for this object is [sqlite3_snapshot_get()]. The
|
|
||||||
** [sqlite3_snapshot_open()] method causes a fresh read transaction to refer
|
|
||||||
** to an historical snapshot (if possible). The destructor for
|
|
||||||
** sqlite3_snapshot objects is [sqlite3_snapshot_free()].
|
|
||||||
*/
|
*/
|
||||||
typedef struct sqlite3_snapshot {
|
typedef struct sqlite3_snapshot {
|
||||||
unsigned char hidden[48];
|
unsigned char hidden[48];
|
||||||
|
@ -8866,7 +8988,7 @@ typedef struct sqlite3_snapshot {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** CAPI3REF: Record A Database Snapshot
|
** CAPI3REF: Record A Database Snapshot
|
||||||
** EXPERIMENTAL
|
** CONSTRUCTOR: sqlite3_snapshot
|
||||||
**
|
**
|
||||||
** ^The [sqlite3_snapshot_get(D,S,P)] interface attempts to make a
|
** ^The [sqlite3_snapshot_get(D,S,P)] interface attempts to make a
|
||||||
** new [sqlite3_snapshot] object that records the current state of
|
** new [sqlite3_snapshot] object that records the current state of
|
||||||
|
@ -8882,7 +9004,7 @@ typedef struct sqlite3_snapshot {
|
||||||
** in this case.
|
** in this case.
|
||||||
**
|
**
|
||||||
** <ul>
|
** <ul>
|
||||||
** <li> The database handle must be in [autocommit mode].
|
** <li> The database handle must not be in [autocommit mode].
|
||||||
**
|
**
|
||||||
** <li> Schema S of [database connection] D must be a [WAL mode] database.
|
** <li> Schema S of [database connection] D must be a [WAL mode] database.
|
||||||
**
|
**
|
||||||
|
@ -8905,7 +9027,7 @@ typedef struct sqlite3_snapshot {
|
||||||
** to avoid a memory leak.
|
** to avoid a memory leak.
|
||||||
**
|
**
|
||||||
** The [sqlite3_snapshot_get()] interface is only available when the
|
** The [sqlite3_snapshot_get()] interface is only available when the
|
||||||
** SQLITE_ENABLE_SNAPSHOT compile-time option is used.
|
** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
|
||||||
*/
|
*/
|
||||||
SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_get(
|
SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_get(
|
||||||
sqlite3 *db,
|
sqlite3 *db,
|
||||||
|
@ -8915,24 +9037,35 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_get(
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** CAPI3REF: Start a read transaction on an historical snapshot
|
** CAPI3REF: Start a read transaction on an historical snapshot
|
||||||
** EXPERIMENTAL
|
** METHOD: sqlite3_snapshot
|
||||||
**
|
**
|
||||||
** ^The [sqlite3_snapshot_open(D,S,P)] interface starts a
|
** ^The [sqlite3_snapshot_open(D,S,P)] interface either starts a new read
|
||||||
** read transaction for schema S of
|
** transaction or upgrades an existing one for schema S of
|
||||||
** [database connection] D such that the read transaction
|
** [database connection] D such that the read transaction refers to
|
||||||
** refers to historical [snapshot] P, rather than the most
|
** historical [snapshot] P, rather than the most recent change to the
|
||||||
** recent change to the database.
|
** database. ^The [sqlite3_snapshot_open()] interface returns SQLITE_OK
|
||||||
** ^The [sqlite3_snapshot_open()] interface returns SQLITE_OK on success
|
** on success or an appropriate [error code] if it fails.
|
||||||
** or an appropriate [error code] if it fails.
|
**
|
||||||
|
** ^In order to succeed, the database connection must not be in
|
||||||
|
** [autocommit mode] when [sqlite3_snapshot_open(D,S,P)] is called. If there
|
||||||
|
** is already a read transaction open on schema S, then the database handle
|
||||||
|
** must have no active statements (SELECT statements that have been passed
|
||||||
|
** to sqlite3_step() but not sqlite3_reset() or sqlite3_finalize()).
|
||||||
|
** SQLITE_ERROR is returned if either of these conditions is violated, or
|
||||||
|
** if schema S does not exist, or if the snapshot object is invalid.
|
||||||
|
**
|
||||||
|
** ^A call to sqlite3_snapshot_open() will fail to open if the specified
|
||||||
|
** snapshot has been overwritten by a [checkpoint]. In this case
|
||||||
|
** SQLITE_ERROR_SNAPSHOT is returned.
|
||||||
|
**
|
||||||
|
** If there is already a read transaction open when this function is
|
||||||
|
** invoked, then the same read transaction remains open (on the same
|
||||||
|
** database snapshot) if SQLITE_ERROR, SQLITE_BUSY or SQLITE_ERROR_SNAPSHOT
|
||||||
|
** is returned. If another error code - for example SQLITE_PROTOCOL or an
|
||||||
|
** SQLITE_IOERR error code - is returned, then the final state of the
|
||||||
|
** read transaction is undefined. If SQLITE_OK is returned, then the
|
||||||
|
** read transaction is now open on database snapshot P.
|
||||||
**
|
**
|
||||||
** ^In order to succeed, a call to [sqlite3_snapshot_open(D,S,P)] must be
|
|
||||||
** the first operation following the [BEGIN] that takes the schema S
|
|
||||||
** out of [autocommit mode].
|
|
||||||
** ^In other words, schema S must not currently be in
|
|
||||||
** a transaction for [sqlite3_snapshot_open(D,S,P)] to work, but the
|
|
||||||
** database connection D must be out of [autocommit mode].
|
|
||||||
** ^A [snapshot] will fail to open if it has been overwritten by a
|
|
||||||
** [checkpoint].
|
|
||||||
** ^(A call to [sqlite3_snapshot_open(D,S,P)] will fail if the
|
** ^(A call to [sqlite3_snapshot_open(D,S,P)] will fail if the
|
||||||
** database connection D does not know that the database file for
|
** database connection D does not know that the database file for
|
||||||
** schema S is in [WAL mode]. A database connection might not know
|
** schema S is in [WAL mode]. A database connection might not know
|
||||||
|
@ -8943,7 +9076,7 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_get(
|
||||||
** database connection in order to make it ready to use snapshots.)
|
** database connection in order to make it ready to use snapshots.)
|
||||||
**
|
**
|
||||||
** The [sqlite3_snapshot_open()] interface is only available when the
|
** The [sqlite3_snapshot_open()] interface is only available when the
|
||||||
** SQLITE_ENABLE_SNAPSHOT compile-time option is used.
|
** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
|
||||||
*/
|
*/
|
||||||
SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_open(
|
SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_open(
|
||||||
sqlite3 *db,
|
sqlite3 *db,
|
||||||
|
@ -8953,20 +9086,20 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_open(
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** CAPI3REF: Destroy a snapshot
|
** CAPI3REF: Destroy a snapshot
|
||||||
** EXPERIMENTAL
|
** DESTRUCTOR: sqlite3_snapshot
|
||||||
**
|
**
|
||||||
** ^The [sqlite3_snapshot_free(P)] interface destroys [sqlite3_snapshot] P.
|
** ^The [sqlite3_snapshot_free(P)] interface destroys [sqlite3_snapshot] P.
|
||||||
** The application must eventually free every [sqlite3_snapshot] object
|
** The application must eventually free every [sqlite3_snapshot] object
|
||||||
** using this routine to avoid a memory leak.
|
** using this routine to avoid a memory leak.
|
||||||
**
|
**
|
||||||
** The [sqlite3_snapshot_free()] interface is only available when the
|
** The [sqlite3_snapshot_free()] interface is only available when the
|
||||||
** SQLITE_ENABLE_SNAPSHOT compile-time option is used.
|
** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used.
|
||||||
*/
|
*/
|
||||||
SQLITE_API SQLITE_EXPERIMENTAL void sqlite3_snapshot_free(sqlite3_snapshot*);
|
SQLITE_API SQLITE_EXPERIMENTAL void sqlite3_snapshot_free(sqlite3_snapshot*);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** CAPI3REF: Compare the ages of two snapshot handles.
|
** CAPI3REF: Compare the ages of two snapshot handles.
|
||||||
** EXPERIMENTAL
|
** METHOD: sqlite3_snapshot
|
||||||
**
|
**
|
||||||
** The sqlite3_snapshot_cmp(P1, P2) interface is used to compare the ages
|
** The sqlite3_snapshot_cmp(P1, P2) interface is used to compare the ages
|
||||||
** of two valid snapshot handles.
|
** of two valid snapshot handles.
|
||||||
|
@ -8985,6 +9118,9 @@ SQLITE_API SQLITE_EXPERIMENTAL void sqlite3_snapshot_free(sqlite3_snapshot*);
|
||||||
** Otherwise, this API returns a negative value if P1 refers to an older
|
** Otherwise, this API returns a negative value if P1 refers to an older
|
||||||
** snapshot than P2, zero if the two handles refer to the same database
|
** snapshot than P2, zero if the two handles refer to the same database
|
||||||
** snapshot, and a positive value if P1 is a newer snapshot than P2.
|
** snapshot, and a positive value if P1 is a newer snapshot than P2.
|
||||||
|
**
|
||||||
|
** This interface is only available if SQLite is compiled with the
|
||||||
|
** [SQLITE_ENABLE_SNAPSHOT] option.
|
||||||
*/
|
*/
|
||||||
SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp(
|
SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp(
|
||||||
sqlite3_snapshot *p1,
|
sqlite3_snapshot *p1,
|
||||||
|
@ -8993,23 +9129,26 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp(
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** CAPI3REF: Recover snapshots from a wal file
|
** CAPI3REF: Recover snapshots from a wal file
|
||||||
** EXPERIMENTAL
|
** METHOD: sqlite3_snapshot
|
||||||
**
|
**
|
||||||
** If all connections disconnect from a database file but do not perform
|
** If a [WAL file] remains on disk after all database connections close
|
||||||
** a checkpoint, the existing wal file is opened along with the database
|
** (either through the use of the [SQLITE_FCNTL_PERSIST_WAL] [file control]
|
||||||
** file the next time the database is opened. At this point it is only
|
** or because the last process to have the database opened exited without
|
||||||
** possible to successfully call sqlite3_snapshot_open() to open the most
|
** calling [sqlite3_close()]) and a new connection is subsequently opened
|
||||||
** recent snapshot of the database (the one at the head of the wal file),
|
** on that database and [WAL file], the [sqlite3_snapshot_open()] interface
|
||||||
** even though the wal file may contain other valid snapshots for which
|
** will only be able to open the last transaction added to the WAL file
|
||||||
** clients have sqlite3_snapshot handles.
|
** even though the WAL file contains other valid transactions.
|
||||||
**
|
**
|
||||||
** This function attempts to scan the wal file associated with database zDb
|
** This function attempts to scan the WAL file associated with database zDb
|
||||||
** of database handle db and make all valid snapshots available to
|
** of database handle db and make all valid snapshots available to
|
||||||
** sqlite3_snapshot_open(). It is an error if there is already a read
|
** sqlite3_snapshot_open(). It is an error if there is already a read
|
||||||
** transaction open on the database, or if the database is not a wal mode
|
** transaction open on the database, or if the database is not a WAL mode
|
||||||
** database.
|
** database.
|
||||||
**
|
**
|
||||||
** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
|
** SQLITE_OK is returned if successful, or an SQLite error code otherwise.
|
||||||
|
**
|
||||||
|
** This interface is only available if SQLite is compiled with the
|
||||||
|
** [SQLITE_ENABLE_SNAPSHOT] option.
|
||||||
*/
|
*/
|
||||||
SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb);
|
SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb);
|
||||||
|
|
||||||
|
@ -9120,7 +9259,7 @@ SQLITE_API int sqlite3_deserialize(
|
||||||
** in the P argument is held in memory obtained from [sqlite3_malloc64()]
|
** in the P argument is held in memory obtained from [sqlite3_malloc64()]
|
||||||
** and that SQLite should take ownership of this memory and automatically
|
** and that SQLite should take ownership of this memory and automatically
|
||||||
** free it when it has finished using it. Without this flag, the caller
|
** free it when it has finished using it. Without this flag, the caller
|
||||||
** is resposible for freeing any dynamically allocated memory.
|
** is responsible for freeing any dynamically allocated memory.
|
||||||
**
|
**
|
||||||
** The SQLITE_DESERIALIZE_RESIZEABLE flag means that SQLite is allowed to
|
** The SQLITE_DESERIALIZE_RESIZEABLE flag means that SQLite is allowed to
|
||||||
** grow the size of the database using calls to [sqlite3_realloc64()]. This
|
** grow the size of the database using calls to [sqlite3_realloc64()]. This
|
||||||
|
@ -11298,7 +11437,7 @@ struct Fts5ExtensionApi {
|
||||||
** This way, even if the tokenizer does not provide synonyms
|
** This way, even if the tokenizer does not provide synonyms
|
||||||
** when tokenizing query text (it should not - to do would be
|
** when tokenizing query text (it should not - to do would be
|
||||||
** inefficient), it doesn't matter if the user queries for
|
** inefficient), it doesn't matter if the user queries for
|
||||||
** 'first + place' or '1st + place', as there are entires in the
|
** 'first + place' or '1st + place', as there are entries in the
|
||||||
** FTS index corresponding to both forms of the first token.
|
** FTS index corresponding to both forms of the first token.
|
||||||
** </ol>
|
** </ol>
|
||||||
**
|
**
|
||||||
|
@ -11326,7 +11465,7 @@ struct Fts5ExtensionApi {
|
||||||
** extra data to the FTS index or require FTS5 to query for multiple terms,
|
** extra data to the FTS index or require FTS5 to query for multiple terms,
|
||||||
** so it is efficient in terms of disk space and query speed. However, it
|
** so it is efficient in terms of disk space and query speed. However, it
|
||||||
** does not support prefix queries very well. If, as suggested above, the
|
** does not support prefix queries very well. If, as suggested above, the
|
||||||
** token "first" is subsituted for "1st" by the tokenizer, then the query:
|
** token "first" is substituted for "1st" by the tokenizer, then the query:
|
||||||
**
|
**
|
||||||
** <codeblock>
|
** <codeblock>
|
||||||
** ... MATCH '1s*'</codeblock>
|
** ... MATCH '1s*'</codeblock>
|
||||||
|
|
116
vendor/github.com/mattn/go-sqlite3/sqlite3.go
generated
vendored
116
vendor/github.com/mattn/go-sqlite3/sqlite3.go
generated
vendored
|
@ -78,8 +78,38 @@ _sqlite3_exec(sqlite3* db, const char* pcmd, long long* rowid, long long* change
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
|
||||||
|
extern int _sqlite3_step_blocking(sqlite3_stmt *stmt);
|
||||||
|
extern int _sqlite3_step_row_blocking(sqlite3_stmt* stmt, long long* rowid, long long* changes);
|
||||||
|
extern int _sqlite3_prepare_v2_blocking(sqlite3 *db, const char *zSql, int nBytes, sqlite3_stmt **ppStmt, const char **pzTail);
|
||||||
|
|
||||||
static int
|
static int
|
||||||
_sqlite3_step(sqlite3_stmt* stmt, long long* rowid, long long* changes)
|
_sqlite3_step_internal(sqlite3_stmt *stmt)
|
||||||
|
{
|
||||||
|
return _sqlite3_step_blocking(stmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_sqlite3_step_row_internal(sqlite3_stmt* stmt, long long* rowid, long long* changes)
|
||||||
|
{
|
||||||
|
return _sqlite3_step_row_blocking(stmt, rowid, changes);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_sqlite3_prepare_v2_internal(sqlite3 *db, const char *zSql, int nBytes, sqlite3_stmt **ppStmt, const char **pzTail)
|
||||||
|
{
|
||||||
|
return _sqlite3_prepare_v2_blocking(db, zSql, nBytes, ppStmt, pzTail);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
static int
|
||||||
|
_sqlite3_step_internal(sqlite3_stmt *stmt)
|
||||||
|
{
|
||||||
|
return sqlite3_step(stmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_sqlite3_step_row_internal(sqlite3_stmt* stmt, long long* rowid, long long* changes)
|
||||||
{
|
{
|
||||||
int rv = sqlite3_step(stmt);
|
int rv = sqlite3_step(stmt);
|
||||||
sqlite3* db = sqlite3_db_handle(stmt);
|
sqlite3* db = sqlite3_db_handle(stmt);
|
||||||
|
@ -88,6 +118,13 @@ _sqlite3_step(sqlite3_stmt* stmt, long long* rowid, long long* changes)
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
_sqlite3_prepare_v2_internal(sqlite3 *db, const char *zSql, int nBytes, sqlite3_stmt **ppStmt, const char **pzTail)
|
||||||
|
{
|
||||||
|
return sqlite3_prepare_v2(db, zSql, nBytes, ppStmt, pzTail);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void _sqlite3_result_text(sqlite3_context* ctx, const char* s) {
|
void _sqlite3_result_text(sqlite3_context* ctx, const char* s) {
|
||||||
sqlite3_result_text(ctx, s, -1, &free);
|
sqlite3_result_text(ctx, s, -1, &free);
|
||||||
}
|
}
|
||||||
|
@ -119,6 +156,8 @@ int commitHookTrampoline(void*);
|
||||||
void rollbackHookTrampoline(void*);
|
void rollbackHookTrampoline(void*);
|
||||||
void updateHookTrampoline(void*, int, char*, char*, sqlite3_int64);
|
void updateHookTrampoline(void*, int, char*, char*, sqlite3_int64);
|
||||||
|
|
||||||
|
int authorizerTrampoline(void*, int, char*, char*, char*, char*);
|
||||||
|
|
||||||
#ifdef SQLITE_LIMIT_WORKER_THREADS
|
#ifdef SQLITE_LIMIT_WORKER_THREADS
|
||||||
# define _SQLITE_HAS_LIMIT
|
# define _SQLITE_HAS_LIMIT
|
||||||
# define SQLITE_LIMIT_LENGTH 0
|
# define SQLITE_LIMIT_LENGTH 0
|
||||||
|
@ -200,18 +239,57 @@ func Version() (libVersion string, libVersionNumber int, sourceID string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
// used by authorizer and pre_update_hook
|
||||||
SQLITE_DELETE = C.SQLITE_DELETE
|
SQLITE_DELETE = C.SQLITE_DELETE
|
||||||
SQLITE_INSERT = C.SQLITE_INSERT
|
SQLITE_INSERT = C.SQLITE_INSERT
|
||||||
SQLITE_UPDATE = C.SQLITE_UPDATE
|
SQLITE_UPDATE = C.SQLITE_UPDATE
|
||||||
|
|
||||||
|
// used by authorzier - as return value
|
||||||
|
SQLITE_OK = C.SQLITE_OK
|
||||||
|
SQLITE_IGNORE = C.SQLITE_IGNORE
|
||||||
|
SQLITE_DENY = C.SQLITE_DENY
|
||||||
|
|
||||||
|
// different actions query tries to do - passed as argument to authorizer
|
||||||
|
SQLITE_CREATE_INDEX = C.SQLITE_CREATE_INDEX
|
||||||
|
SQLITE_CREATE_TABLE = C.SQLITE_CREATE_TABLE
|
||||||
|
SQLITE_CREATE_TEMP_INDEX = C.SQLITE_CREATE_TEMP_INDEX
|
||||||
|
SQLITE_CREATE_TEMP_TABLE = C.SQLITE_CREATE_TEMP_TABLE
|
||||||
|
SQLITE_CREATE_TEMP_TRIGGER = C.SQLITE_CREATE_TEMP_TRIGGER
|
||||||
|
SQLITE_CREATE_TEMP_VIEW = C.SQLITE_CREATE_TEMP_VIEW
|
||||||
|
SQLITE_CREATE_TRIGGER = C.SQLITE_CREATE_TRIGGER
|
||||||
|
SQLITE_CREATE_VIEW = C.SQLITE_CREATE_VIEW
|
||||||
|
SQLITE_CREATE_VTABLE = C.SQLITE_CREATE_VTABLE
|
||||||
|
SQLITE_DROP_INDEX = C.SQLITE_DROP_INDEX
|
||||||
|
SQLITE_DROP_TABLE = C.SQLITE_DROP_TABLE
|
||||||
|
SQLITE_DROP_TEMP_INDEX = C.SQLITE_DROP_TEMP_INDEX
|
||||||
|
SQLITE_DROP_TEMP_TABLE = C.SQLITE_DROP_TEMP_TABLE
|
||||||
|
SQLITE_DROP_TEMP_TRIGGER = C.SQLITE_DROP_TEMP_TRIGGER
|
||||||
|
SQLITE_DROP_TEMP_VIEW = C.SQLITE_DROP_TEMP_VIEW
|
||||||
|
SQLITE_DROP_TRIGGER = C.SQLITE_DROP_TRIGGER
|
||||||
|
SQLITE_DROP_VIEW = C.SQLITE_DROP_VIEW
|
||||||
|
SQLITE_DROP_VTABLE = C.SQLITE_DROP_VTABLE
|
||||||
|
SQLITE_PRAGMA = C.SQLITE_PRAGMA
|
||||||
|
SQLITE_READ = C.SQLITE_READ
|
||||||
|
SQLITE_SELECT = C.SQLITE_SELECT
|
||||||
|
SQLITE_TRANSACTION = C.SQLITE_TRANSACTION
|
||||||
|
SQLITE_ATTACH = C.SQLITE_ATTACH
|
||||||
|
SQLITE_DETACH = C.SQLITE_DETACH
|
||||||
|
SQLITE_ALTER_TABLE = C.SQLITE_ALTER_TABLE
|
||||||
|
SQLITE_REINDEX = C.SQLITE_REINDEX
|
||||||
|
SQLITE_ANALYZE = C.SQLITE_ANALYZE
|
||||||
|
SQLITE_FUNCTION = C.SQLITE_FUNCTION
|
||||||
|
SQLITE_SAVEPOINT = C.SQLITE_SAVEPOINT
|
||||||
|
SQLITE_COPY = C.SQLITE_COPY
|
||||||
|
/*SQLITE_RECURSIVE = C.SQLITE_RECURSIVE*/
|
||||||
)
|
)
|
||||||
|
|
||||||
// SQLiteDriver implement sql.Driver.
|
// SQLiteDriver implements driver.Driver.
|
||||||
type SQLiteDriver struct {
|
type SQLiteDriver struct {
|
||||||
Extensions []string
|
Extensions []string
|
||||||
ConnectHook func(*SQLiteConn) error
|
ConnectHook func(*SQLiteConn) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// SQLiteConn implement sql.Conn.
|
// SQLiteConn implements driver.Conn.
|
||||||
type SQLiteConn struct {
|
type SQLiteConn struct {
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
db *C.sqlite3
|
db *C.sqlite3
|
||||||
|
@ -221,12 +299,12 @@ type SQLiteConn struct {
|
||||||
aggregators []*aggInfo
|
aggregators []*aggInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
// SQLiteTx implemen sql.Tx.
|
// SQLiteTx implements driver.Tx.
|
||||||
type SQLiteTx struct {
|
type SQLiteTx struct {
|
||||||
c *SQLiteConn
|
c *SQLiteConn
|
||||||
}
|
}
|
||||||
|
|
||||||
// SQLiteStmt implement sql.Stmt.
|
// SQLiteStmt implements driver.Stmt.
|
||||||
type SQLiteStmt struct {
|
type SQLiteStmt struct {
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
c *SQLiteConn
|
c *SQLiteConn
|
||||||
|
@ -236,13 +314,13 @@ type SQLiteStmt struct {
|
||||||
cls bool
|
cls bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// SQLiteResult implement sql.Result.
|
// SQLiteResult implements sql.Result.
|
||||||
type SQLiteResult struct {
|
type SQLiteResult struct {
|
||||||
id int64
|
id int64
|
||||||
changes int64
|
changes int64
|
||||||
}
|
}
|
||||||
|
|
||||||
// SQLiteRows implement sql.Rows.
|
// SQLiteRows implements driver.Rows.
|
||||||
type SQLiteRows struct {
|
type SQLiteRows struct {
|
||||||
s *SQLiteStmt
|
s *SQLiteStmt
|
||||||
nc int
|
nc int
|
||||||
|
@ -440,6 +518,20 @@ func (c *SQLiteConn) RegisterUpdateHook(callback func(int, string, string, int64
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RegisterAuthorizer sets the authorizer for connection.
|
||||||
|
//
|
||||||
|
// The parameters to the callback are the operation (one of the constants
|
||||||
|
// SQLITE_INSERT, SQLITE_DELETE, or SQLITE_UPDATE), and 1 to 3 arguments,
|
||||||
|
// depending on operation. More details see:
|
||||||
|
// https://www.sqlite.org/c3ref/c_alter_table.html
|
||||||
|
func (c *SQLiteConn) RegisterAuthorizer(callback func(int, string, string, string) int) {
|
||||||
|
if callback == nil {
|
||||||
|
C.sqlite3_set_authorizer(c.db, nil, nil)
|
||||||
|
} else {
|
||||||
|
C.sqlite3_set_authorizer(c.db, (*[0]byte)(C.authorizerTrampoline), unsafe.Pointer(newHandle(c, callback)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// RegisterFunc makes a Go function available as a SQLite function.
|
// RegisterFunc makes a Go function available as a SQLite function.
|
||||||
//
|
//
|
||||||
// The Go function can have arguments of the following types: any
|
// The Go function can have arguments of the following types: any
|
||||||
|
@ -1582,7 +1674,7 @@ func (c *SQLiteConn) prepare(ctx context.Context, query string) (driver.Stmt, er
|
||||||
defer C.free(unsafe.Pointer(pquery))
|
defer C.free(unsafe.Pointer(pquery))
|
||||||
var s *C.sqlite3_stmt
|
var s *C.sqlite3_stmt
|
||||||
var tail *C.char
|
var tail *C.char
|
||||||
rv := C.sqlite3_prepare_v2(c.db, pquery, -1, &s, &tail)
|
rv := C._sqlite3_prepare_v2_internal(c.db, pquery, -1, &s, &tail)
|
||||||
if rv != C.SQLITE_OK {
|
if rv != C.SQLITE_OK {
|
||||||
return nil, c.lastError()
|
return nil, c.lastError()
|
||||||
}
|
}
|
||||||
|
@ -1816,7 +1908,7 @@ func (s *SQLiteStmt) exec(ctx context.Context, args []namedValue) (driver.Result
|
||||||
}
|
}
|
||||||
|
|
||||||
var rowid, changes C.longlong
|
var rowid, changes C.longlong
|
||||||
rv := C._sqlite3_step(s.s, &rowid, &changes)
|
rv := C._sqlite3_step_row_internal(s.s, &rowid, &changes)
|
||||||
if rv != C.SQLITE_ROW && rv != C.SQLITE_OK && rv != C.SQLITE_DONE {
|
if rv != C.SQLITE_ROW && rv != C.SQLITE_OK && rv != C.SQLITE_DONE {
|
||||||
err := s.c.lastError()
|
err := s.c.lastError()
|
||||||
C.sqlite3_reset(s.s)
|
C.sqlite3_reset(s.s)
|
||||||
|
@ -1883,12 +1975,12 @@ func (rc *SQLiteRows) DeclTypes() []string {
|
||||||
|
|
||||||
// Next move cursor to next.
|
// Next move cursor to next.
|
||||||
func (rc *SQLiteRows) Next(dest []driver.Value) error {
|
func (rc *SQLiteRows) Next(dest []driver.Value) error {
|
||||||
|
rc.s.mu.Lock()
|
||||||
|
defer rc.s.mu.Unlock()
|
||||||
if rc.s.closed {
|
if rc.s.closed {
|
||||||
return io.EOF
|
return io.EOF
|
||||||
}
|
}
|
||||||
rc.s.mu.Lock()
|
rv := C._sqlite3_step_internal(rc.s.s)
|
||||||
defer rc.s.mu.Unlock()
|
|
||||||
rv := C.sqlite3_step(rc.s.s)
|
|
||||||
if rv == C.SQLITE_DONE {
|
if rv == C.SQLITE_DONE {
|
||||||
return io.EOF
|
return io.EOF
|
||||||
}
|
}
|
||||||
|
|
8
vendor/github.com/mattn/go-sqlite3/sqlite3_func_crypt.go
generated
vendored
8
vendor/github.com/mattn/go-sqlite3/sqlite3_func_crypt.go
generated
vendored
|
@ -83,13 +83,13 @@ func CryptEncoderSSHA256(salt string) func(pass []byte, hash interface{}) []byte
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// CryptEncoderSHA384 encodes a password with SHA256
|
// CryptEncoderSHA384 encodes a password with SHA384
|
||||||
func CryptEncoderSHA384(pass []byte, hash interface{}) []byte {
|
func CryptEncoderSHA384(pass []byte, hash interface{}) []byte {
|
||||||
h := sha512.Sum384(pass)
|
h := sha512.Sum384(pass)
|
||||||
return h[:]
|
return h[:]
|
||||||
}
|
}
|
||||||
|
|
||||||
// CryptEncoderSSHA384 encodes a password with SHA256
|
// CryptEncoderSSHA384 encodes a password with SHA384
|
||||||
// with the configured salt
|
// with the configured salt
|
||||||
func CryptEncoderSSHA384(salt string) func(pass []byte, hash interface{}) []byte {
|
func CryptEncoderSSHA384(salt string) func(pass []byte, hash interface{}) []byte {
|
||||||
return func(pass []byte, hash interface{}) []byte {
|
return func(pass []byte, hash interface{}) []byte {
|
||||||
|
@ -100,13 +100,13 @@ func CryptEncoderSSHA384(salt string) func(pass []byte, hash interface{}) []byte
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// CryptEncoderSHA512 encodes a password with SHA256
|
// CryptEncoderSHA512 encodes a password with SHA512
|
||||||
func CryptEncoderSHA512(pass []byte, hash interface{}) []byte {
|
func CryptEncoderSHA512(pass []byte, hash interface{}) []byte {
|
||||||
h := sha512.Sum512(pass)
|
h := sha512.Sum512(pass)
|
||||||
return h[:]
|
return h[:]
|
||||||
}
|
}
|
||||||
|
|
||||||
// CryptEncoderSSHA512 encodes a password with SHA256
|
// CryptEncoderSSHA512 encodes a password with SHA512
|
||||||
// with the configured salt
|
// with the configured salt
|
||||||
func CryptEncoderSSHA512(salt string) func(pass []byte, hash interface{}) []byte {
|
func CryptEncoderSSHA512(salt string) func(pass []byte, hash interface{}) []byte {
|
||||||
return func(pass []byte, hash interface{}) []byte {
|
return func(pass []byte, hash interface{}) []byte {
|
||||||
|
|
85
vendor/github.com/mattn/go-sqlite3/sqlite3_opt_unlock_notify.c
generated
vendored
Normal file
85
vendor/github.com/mattn/go-sqlite3/sqlite3_opt_unlock_notify.c
generated
vendored
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
// Copyright (C) 2018 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by an MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
#ifdef SQLITE_ENABLE_UNLOCK_NOTIFY
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sqlite3-binding.h>
|
||||||
|
|
||||||
|
extern int unlock_notify_wait(sqlite3 *db);
|
||||||
|
|
||||||
|
int
|
||||||
|
_sqlite3_step_blocking(sqlite3_stmt *stmt)
|
||||||
|
{
|
||||||
|
int rv;
|
||||||
|
sqlite3* db;
|
||||||
|
|
||||||
|
db = sqlite3_db_handle(stmt);
|
||||||
|
for (;;) {
|
||||||
|
rv = sqlite3_step(stmt);
|
||||||
|
if (rv != SQLITE_LOCKED) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (sqlite3_extended_errcode(db) != SQLITE_LOCKED_SHAREDCACHE) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
rv = unlock_notify_wait(db);
|
||||||
|
if (rv != SQLITE_OK) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sqlite3_reset(stmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
_sqlite3_step_row_blocking(sqlite3_stmt* stmt, long long* rowid, long long* changes)
|
||||||
|
{
|
||||||
|
int rv;
|
||||||
|
sqlite3* db;
|
||||||
|
|
||||||
|
db = sqlite3_db_handle(stmt);
|
||||||
|
for (;;) {
|
||||||
|
rv = sqlite3_step(stmt);
|
||||||
|
if (rv!=SQLITE_LOCKED) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (sqlite3_extended_errcode(db) != SQLITE_LOCKED_SHAREDCACHE) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
rv = unlock_notify_wait(db);
|
||||||
|
if (rv != SQLITE_OK) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
sqlite3_reset(stmt);
|
||||||
|
}
|
||||||
|
|
||||||
|
*rowid = (long long) sqlite3_last_insert_rowid(db);
|
||||||
|
*changes = (long long) sqlite3_changes(db);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
_sqlite3_prepare_v2_blocking(sqlite3 *db, const char *zSql, int nBytes, sqlite3_stmt **ppStmt, const char **pzTail)
|
||||||
|
{
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
rv = sqlite3_prepare_v2(db, zSql, nBytes, ppStmt, pzTail);
|
||||||
|
if (rv!=SQLITE_LOCKED) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (sqlite3_extended_errcode(db) != SQLITE_LOCKED_SHAREDCACHE) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
rv = unlock_notify_wait(db);
|
||||||
|
if (rv != SQLITE_OK) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
#endif
|
93
vendor/github.com/mattn/go-sqlite3/sqlite3_opt_unlock_notify.go
generated
vendored
Normal file
93
vendor/github.com/mattn/go-sqlite3/sqlite3_opt_unlock_notify.go
generated
vendored
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
// Copyright (C) 2018 Yasuhiro Matsumoto <mattn.jp@gmail.com>.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by an MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build cgo
|
||||||
|
// +build sqlite_unlock_notify
|
||||||
|
|
||||||
|
package sqlite3
|
||||||
|
|
||||||
|
/*
|
||||||
|
#cgo CFLAGS: -DSQLITE_ENABLE_UNLOCK_NOTIFY
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sqlite3-binding.h>
|
||||||
|
|
||||||
|
extern void unlock_notify_callback(void *arg, int argc);
|
||||||
|
*/
|
||||||
|
import "C"
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
"sync"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
type unlock_notify_table struct {
|
||||||
|
sync.Mutex
|
||||||
|
seqnum uint
|
||||||
|
table map[uint]chan struct{}
|
||||||
|
}
|
||||||
|
|
||||||
|
var unt unlock_notify_table = unlock_notify_table{table: make(map[uint]chan struct{})}
|
||||||
|
|
||||||
|
func (t *unlock_notify_table) add(c chan struct{}) uint {
|
||||||
|
t.Lock()
|
||||||
|
defer t.Unlock()
|
||||||
|
h := t.seqnum
|
||||||
|
t.table[h] = c
|
||||||
|
t.seqnum++
|
||||||
|
return h
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *unlock_notify_table) remove(h uint) {
|
||||||
|
t.Lock()
|
||||||
|
defer t.Unlock()
|
||||||
|
delete(t.table, h)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *unlock_notify_table) get(h uint) chan struct{} {
|
||||||
|
t.Lock()
|
||||||
|
defer t.Unlock()
|
||||||
|
c, ok := t.table[h]
|
||||||
|
if !ok {
|
||||||
|
panic(fmt.Sprintf("Non-existent key for unlcok-notify channel: %d", h))
|
||||||
|
}
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
//export unlock_notify_callback
|
||||||
|
func unlock_notify_callback(argv unsafe.Pointer, argc C.int) {
|
||||||
|
for i := 0; i < int(argc); i++ {
|
||||||
|
parg := ((*(*[(math.MaxInt32 - 1) / unsafe.Sizeof((*C.uint)(nil))]*[1]uint)(argv))[i])
|
||||||
|
arg := *parg
|
||||||
|
h := arg[0]
|
||||||
|
c := unt.get(h)
|
||||||
|
c <- struct{}{}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//export unlock_notify_wait
|
||||||
|
func unlock_notify_wait(db *C.sqlite3) C.int {
|
||||||
|
// It has to be a bufferred channel to not block in sqlite_unlock_notify
|
||||||
|
// as sqlite_unlock_notify could invoke the callback before it returns.
|
||||||
|
c := make(chan struct{}, 1)
|
||||||
|
defer close(c)
|
||||||
|
|
||||||
|
h := unt.add(c)
|
||||||
|
defer unt.remove(h)
|
||||||
|
|
||||||
|
pargv := C.malloc(C.sizeof_uint)
|
||||||
|
defer C.free(pargv)
|
||||||
|
|
||||||
|
argv := (*[1]uint)(pargv)
|
||||||
|
argv[0] = h
|
||||||
|
if rv := C.sqlite3_unlock_notify(db, (*[0]byte)(C.unlock_notify_callback), unsafe.Pointer(pargv)); rv != C.SQLITE_OK {
|
||||||
|
return rv
|
||||||
|
}
|
||||||
|
|
||||||
|
<-c
|
||||||
|
|
||||||
|
return C.SQLITE_OK
|
||||||
|
}
|
3
vendor/github.com/mattn/go-sqlite3/sqlite3_other.go
generated
vendored
3
vendor/github.com/mattn/go-sqlite3/sqlite3_other.go
generated
vendored
|
@ -10,5 +10,8 @@ package sqlite3
|
||||||
/*
|
/*
|
||||||
#cgo CFLAGS: -I.
|
#cgo CFLAGS: -I.
|
||||||
#cgo linux LDFLAGS: -ldl
|
#cgo linux LDFLAGS: -ldl
|
||||||
|
#cgo linux,ppc LDFLAGS: -lpthread
|
||||||
|
#cgo linux,ppc64 LDFLAGS: -lpthread
|
||||||
|
#cgo linux,ppc64le LDFLAGS: -lpthread
|
||||||
*/
|
*/
|
||||||
import "C"
|
import "C"
|
||||||
|
|
8
vendor/github.com/mattn/go-sqlite3/sqlite3ext.h
generated
vendored
8
vendor/github.com/mattn/go-sqlite3/sqlite3ext.h
generated
vendored
|
@ -311,6 +311,12 @@ struct sqlite3_api_routines {
|
||||||
int (*str_errcode)(sqlite3_str*);
|
int (*str_errcode)(sqlite3_str*);
|
||||||
int (*str_length)(sqlite3_str*);
|
int (*str_length)(sqlite3_str*);
|
||||||
char *(*str_value)(sqlite3_str*);
|
char *(*str_value)(sqlite3_str*);
|
||||||
|
int (*create_window_function)(sqlite3*,const char*,int,int,void*,
|
||||||
|
void (*xStep)(sqlite3_context*,int,sqlite3_value**),
|
||||||
|
void (*xFinal)(sqlite3_context*),
|
||||||
|
void (*xValue)(sqlite3_context*),
|
||||||
|
void (*xInv)(sqlite3_context*,int,sqlite3_value**),
|
||||||
|
void(*xDestroy)(void*));
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -596,6 +602,8 @@ typedef int (*sqlite3_loadext_entry)(
|
||||||
#define sqlite3_str_errcode sqlite3_api->str_errcode
|
#define sqlite3_str_errcode sqlite3_api->str_errcode
|
||||||
#define sqlite3_str_length sqlite3_api->str_length
|
#define sqlite3_str_length sqlite3_api->str_length
|
||||||
#define sqlite3_str_value sqlite3_api->str_value
|
#define sqlite3_str_value sqlite3_api->str_value
|
||||||
|
/* Version 3.25.0 and later */
|
||||||
|
#define sqlite3_create_window_function sqlite3_api->create_window_function
|
||||||
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
|
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
|
||||||
|
|
||||||
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
|
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
|
||||||
|
|
202
vendor/google.golang.org/appengine/LICENSE
generated
vendored
Normal file
202
vendor/google.golang.org/appengine/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,202 @@
|
||||||
|
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
62
vendor/google.golang.org/appengine/cloudsql/cloudsql.go
generated
vendored
Normal file
62
vendor/google.golang.org/appengine/cloudsql/cloudsql.go
generated
vendored
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
// Copyright 2013 Google Inc. All rights reserved.
|
||||||
|
// Use of this source code is governed by the Apache 2.0
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
/*
|
||||||
|
Package cloudsql exposes access to Google Cloud SQL databases.
|
||||||
|
|
||||||
|
This package does not work in App Engine "flexible environment".
|
||||||
|
|
||||||
|
This package is intended for MySQL drivers to make App Engine-specific
|
||||||
|
connections. Applications should use this package through database/sql:
|
||||||
|
Select a pure Go MySQL driver that supports this package, and use sql.Open
|
||||||
|
with protocol "cloudsql" and an address of the Cloud SQL instance.
|
||||||
|
|
||||||
|
A Go MySQL driver that has been tested to work well with Cloud SQL
|
||||||
|
is the go-sql-driver:
|
||||||
|
import "database/sql"
|
||||||
|
import _ "github.com/go-sql-driver/mysql"
|
||||||
|
|
||||||
|
db, err := sql.Open("mysql", "user@cloudsql(project-id:instance-name)/dbname")
|
||||||
|
|
||||||
|
|
||||||
|
Another driver that works well with Cloud SQL is the mymysql driver:
|
||||||
|
import "database/sql"
|
||||||
|
import _ "github.com/ziutek/mymysql/godrv"
|
||||||
|
|
||||||
|
db, err := sql.Open("mymysql", "cloudsql:instance-name*dbname/user/password")
|
||||||
|
|
||||||
|
|
||||||
|
Using either of these drivers, you can perform a standard SQL query.
|
||||||
|
This example assumes there is a table named 'users' with
|
||||||
|
columns 'first_name' and 'last_name':
|
||||||
|
|
||||||
|
rows, err := db.Query("SELECT first_name, last_name FROM users")
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf(ctx, "db.Query: %v", err)
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
for rows.Next() {
|
||||||
|
var firstName string
|
||||||
|
var lastName string
|
||||||
|
if err := rows.Scan(&firstName, &lastName); err != nil {
|
||||||
|
log.Errorf(ctx, "rows.Scan: %v", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
log.Infof(ctx, "First: %v - Last: %v", firstName, lastName)
|
||||||
|
}
|
||||||
|
if err := rows.Err(); err != nil {
|
||||||
|
log.Errorf(ctx, "Row error: %v", err)
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
package cloudsql
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Dial connects to the named Cloud SQL instance.
|
||||||
|
func Dial(instance string) (net.Conn, error) {
|
||||||
|
return connect(instance)
|
||||||
|
}
|
17
vendor/google.golang.org/appengine/cloudsql/cloudsql_classic.go
generated
vendored
Normal file
17
vendor/google.golang.org/appengine/cloudsql/cloudsql_classic.go
generated
vendored
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
// Copyright 2013 Google Inc. All rights reserved.
|
||||||
|
// Use of this source code is governed by the Apache 2.0
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build appengine
|
||||||
|
|
||||||
|
package cloudsql
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
|
||||||
|
"appengine/cloudsql"
|
||||||
|
)
|
||||||
|
|
||||||
|
func connect(instance string) (net.Conn, error) {
|
||||||
|
return cloudsql.Dial(instance)
|
||||||
|
}
|
16
vendor/google.golang.org/appengine/cloudsql/cloudsql_vm.go
generated
vendored
Normal file
16
vendor/google.golang.org/appengine/cloudsql/cloudsql_vm.go
generated
vendored
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
// Copyright 2013 Google Inc. All rights reserved.
|
||||||
|
// Use of this source code is governed by the Apache 2.0
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// +build !appengine
|
||||||
|
|
||||||
|
package cloudsql
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"net"
|
||||||
|
)
|
||||||
|
|
||||||
|
func connect(instance string) (net.Conn, error) {
|
||||||
|
return nil, errors.New(`cloudsql: not supported in App Engine "flexible environment"`)
|
||||||
|
}
|
2
vendor/gopkg.in/testfixtures.v2/.travis.yml
generated
vendored
2
vendor/gopkg.in/testfixtures.v2/.travis.yml
generated
vendored
|
@ -1,8 +1,8 @@
|
||||||
language: go
|
language: go
|
||||||
|
|
||||||
go:
|
go:
|
||||||
- '1.9'
|
|
||||||
- '1.10'
|
- '1.10'
|
||||||
|
- '1.11'
|
||||||
|
|
||||||
services:
|
services:
|
||||||
- postgresql
|
- postgresql
|
||||||
|
|
30
vendor/gopkg.in/testfixtures.v2/README.md
generated
vendored
30
vendor/gopkg.in/testfixtures.v2/README.md
generated
vendored
|
@ -229,6 +229,15 @@ errors with the previous approach. It is as simple as using:
|
||||||
&testfixtures.PostgreSQL{UseAlterConstraint: true}
|
&testfixtures.PostgreSQL{UseAlterConstraint: true}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Skipping reset of sequences
|
||||||
|
|
||||||
|
You can skip the reset of PostgreSQL sequences if you're debugging a problem
|
||||||
|
with it, but most of the time you shouldn't do it:
|
||||||
|
|
||||||
|
```go
|
||||||
|
&testfixtures.PostgreSQL{SkipResetSequences: true}
|
||||||
|
```
|
||||||
|
|
||||||
### MySQL / MariaDB
|
### MySQL / MariaDB
|
||||||
|
|
||||||
Just make sure the connection string have
|
Just make sure the connection string have
|
||||||
|
@ -302,6 +311,27 @@ if err != nil {
|
||||||
> This was thought to run in small sample databases. It will likely break
|
> This was thought to run in small sample databases. It will likely break
|
||||||
if run in a production/big database.
|
if run in a production/big database.
|
||||||
|
|
||||||
|
## Gotchas
|
||||||
|
|
||||||
|
### Parallel testing
|
||||||
|
|
||||||
|
This library doesn't yet support running tests in parallel! Running tests
|
||||||
|
in parallel can result in random data being present in the database, which
|
||||||
|
will likely cause tests to randomly/intermittently fail.
|
||||||
|
|
||||||
|
This is specially tricky since it's not immediately clear that `go test ./...`
|
||||||
|
run tests for each package in parallel. If more than one package use this
|
||||||
|
library, you can face this issue. Please, use `go test -p 1 ./...` or run tests
|
||||||
|
for each package in separated commands to fix this issue.
|
||||||
|
|
||||||
|
See [#40](https://github.com/go-testfixtures/testfixtures/issues/40)
|
||||||
|
and [golang/go#11521](https://github.com/golang/go/issues/11521) for more information.
|
||||||
|
|
||||||
|
We're also planning to implement transactional tests to allow running tests
|
||||||
|
in parallel (see [#24](https://github.com/go-testfixtures/testfixtures/issues/24)).
|
||||||
|
Running each test package in a separated database would also allow you to do that.
|
||||||
|
Open issues for other ideas :slightly_smiling_face:.
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
Tests were written to ensure everything work as expected. You can run the tests
|
Tests were written to ensure everything work as expected. You can run the tests
|
||||||
|
|
4
vendor/gopkg.in/testfixtures.v2/Taskfile.yml
generated
vendored
4
vendor/gopkg.in/testfixtures.v2/Taskfile.yml
generated
vendored
|
@ -1,4 +1,4 @@
|
||||||
# github.com/go-task/task
|
# https://taskfile.org
|
||||||
|
|
||||||
version: '2'
|
version: '2'
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ tasks:
|
||||||
dl-deps:
|
dl-deps:
|
||||||
desc: Download cli deps
|
desc: Download cli deps
|
||||||
cmds:
|
cmds:
|
||||||
- go get -u github.com/golang/lint/golint
|
- go get -u golang.org/x/lint/golint
|
||||||
|
|
||||||
lint:
|
lint:
|
||||||
desc: Runs golint
|
desc: Runs golint
|
||||||
|
|
2
vendor/gopkg.in/testfixtures.v2/appveyor.yml
generated
vendored
2
vendor/gopkg.in/testfixtures.v2/appveyor.yml
generated
vendored
|
@ -27,7 +27,7 @@ environment:
|
||||||
MINGW_PATH: C:\MinGW
|
MINGW_PATH: C:\MinGW
|
||||||
|
|
||||||
GOPATH: C:\GOPATH
|
GOPATH: C:\GOPATH
|
||||||
GOVERSION: 1.10.3
|
GOVERSION: 1.11.2
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- SET PATH=%POSTGRES_PATH%\bin;%MYSQL_PATH%\bin;%MINGW_PATH%\bin;%PATH%
|
- SET PATH=%POSTGRES_PATH%\bin;%MYSQL_PATH%\bin;%MINGW_PATH%\bin;%PATH%
|
||||||
|
|
15
vendor/gopkg.in/testfixtures.v2/go.mod
generated
vendored
Normal file
15
vendor/gopkg.in/testfixtures.v2/go.mod
generated
vendored
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
module gopkg.in/testfixtures.v2
|
||||||
|
|
||||||
|
require (
|
||||||
|
cloud.google.com/go v0.33.1 // indirect
|
||||||
|
github.com/denisenkom/go-mssqldb v0.0.0-20181014144952-4e0d7dc8888f
|
||||||
|
github.com/go-sql-driver/mysql v1.4.1
|
||||||
|
github.com/google/go-cmp v0.2.0 // indirect
|
||||||
|
github.com/joho/godotenv v1.3.0
|
||||||
|
github.com/lib/pq v1.0.0
|
||||||
|
github.com/mattn/go-oci8 v0.0.0-20181115070430-6eefff3c767c
|
||||||
|
github.com/mattn/go-sqlite3 v1.10.0
|
||||||
|
golang.org/x/crypto v0.0.0-20181112202954-3d3f9f413869 // indirect
|
||||||
|
google.golang.org/appengine v1.3.0 // indirect
|
||||||
|
gopkg.in/yaml.v2 v2.2.1
|
||||||
|
)
|
27
vendor/gopkg.in/testfixtures.v2/go.sum
generated
vendored
Normal file
27
vendor/gopkg.in/testfixtures.v2/go.sum
generated
vendored
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
cloud.google.com/go v0.33.1 h1:fmJQWZ1w9PGkHR1YL/P7HloDvqlmKQ4Vpb7PC2e+aCk=
|
||||||
|
cloud.google.com/go v0.33.1/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
|
github.com/denisenkom/go-mssqldb v0.0.0-20181014144952-4e0d7dc8888f h1:WH0w/R4Yoey+04HhFxqZ6VX6I0d7RMyw5aXQ9UTvQPs=
|
||||||
|
github.com/denisenkom/go-mssqldb v0.0.0-20181014144952-4e0d7dc8888f/go.mod h1:xN/JuLBIz4bjkxNmByTiV1IbhfnYb6oo99phBn4Eqhc=
|
||||||
|
github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA=
|
||||||
|
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||||
|
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
|
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
|
||||||
|
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||||
|
github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
|
||||||
|
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
|
||||||
|
github.com/lib/pq v1.0.0 h1:X5PMW56eZitiTeO7tKzZxFCSpbFZJtkMMooicw2us9A=
|
||||||
|
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||||
|
github.com/mattn/go-oci8 v0.0.0-20181115070430-6eefff3c767c h1:RkC3vqmJwowDCqtL7d8cFEMNdoGHBcqoR4jKO9/mWuA=
|
||||||
|
github.com/mattn/go-oci8 v0.0.0-20181115070430-6eefff3c767c/go.mod h1:/M9VLO+lUPmxvoOK2PfWRZ8mTtB4q1Hy9lEGijv9Nr8=
|
||||||
|
github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o=
|
||||||
|
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||||
|
golang.org/x/crypto v0.0.0-20181112202954-3d3f9f413869 h1:kkXA53yGe04D0adEYJwEVQjeBppL01Exg+fnMjfUraU=
|
||||||
|
golang.org/x/crypto v0.0.0-20181112202954-3d3f9f413869/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
google.golang.org/appengine v1.3.0 h1:FBSsiFRMz3LBeXIomRnVzrQwSDj4ibvcRexLG0LZGQk=
|
||||||
|
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/yaml.v2 v2.2.1 h1:mUhvW9EsL+naU5Q3cakzfE91YhliOondGd6ZrsDBHQE=
|
||||||
|
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
14
vendor/gopkg.in/testfixtures.v2/mysql.go
generated
vendored
14
vendor/gopkg.in/testfixtures.v2/mysql.go
generated
vendored
|
@ -70,13 +70,6 @@ func (h *MySQL) tableNames(q queryable) ([]string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *MySQL) disableReferentialIntegrity(db *sql.DB, loadFn loadFunction) (err error) {
|
func (h *MySQL) disableReferentialIntegrity(db *sql.DB, loadFn loadFunction) (err error) {
|
||||||
// re-enable after load
|
|
||||||
defer func() {
|
|
||||||
if _, err2 := db.Exec("SET FOREIGN_KEY_CHECKS = 1"); err2 != nil && err == nil {
|
|
||||||
err = err2
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
tx, err := db.Begin()
|
tx, err := db.Begin()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -87,9 +80,14 @@ func (h *MySQL) disableReferentialIntegrity(db *sql.DB, loadFn loadFunction) (er
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = loadFn(tx); err != nil {
|
err = loadFn(tx)
|
||||||
|
_, err2 := tx.Exec("SET FOREIGN_KEY_CHECKS = 1")
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if err2 != nil {
|
||||||
|
return err2
|
||||||
|
}
|
||||||
|
|
||||||
return tx.Commit()
|
return tx.Commit()
|
||||||
}
|
}
|
||||||
|
|
16
vendor/gopkg.in/testfixtures.v2/postgresql.go
generated
vendored
16
vendor/gopkg.in/testfixtures.v2/postgresql.go
generated
vendored
|
@ -16,6 +16,10 @@ type PostgreSQL struct {
|
||||||
// which requires SUPERUSER privileges.
|
// which requires SUPERUSER privileges.
|
||||||
UseAlterConstraint bool
|
UseAlterConstraint bool
|
||||||
|
|
||||||
|
// SkipResetSequences prevents the reset of the databases
|
||||||
|
// sequences after load fixtures time
|
||||||
|
SkipResetSequences bool
|
||||||
|
|
||||||
tables []string
|
tables []string
|
||||||
sequences []string
|
sequences []string
|
||||||
nonDeferrableConstraints []pgConstraint
|
nonDeferrableConstraints []pgConstraint
|
||||||
|
@ -216,11 +220,13 @@ func (h *PostgreSQL) makeConstraintsDeferrable(db *sql.DB, loadFn loadFunction)
|
||||||
|
|
||||||
func (h *PostgreSQL) disableReferentialIntegrity(db *sql.DB, loadFn loadFunction) (err error) {
|
func (h *PostgreSQL) disableReferentialIntegrity(db *sql.DB, loadFn loadFunction) (err error) {
|
||||||
// ensure sequences being reset after load
|
// ensure sequences being reset after load
|
||||||
defer func() {
|
if !h.SkipResetSequences {
|
||||||
if err2 := h.resetSequences(db); err2 != nil && err == nil {
|
defer func() {
|
||||||
err = err2
|
if err2 := h.resetSequences(db); err2 != nil && err == nil {
|
||||||
}
|
err = err2
|
||||||
}()
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
if h.UseAlterConstraint {
|
if h.UseAlterConstraint {
|
||||||
return h.makeConstraintsDeferrable(db, loadFn)
|
return h.makeConstraintsDeferrable(db, loadFn)
|
||||||
|
|
24
vendor/gopkg.in/testfixtures.v2/testfixtures.go
generated
vendored
24
vendor/gopkg.in/testfixtures.v2/testfixtures.go
generated
vendored
|
@ -89,19 +89,30 @@ func newContext(db *sql.DB, helper Helper, fixtures []*fixtureFile) (*Context, e
|
||||||
return c, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DetectTestDatabase returns nil if databaseName matches regexp
|
||||||
|
// if err := fixtures.DetectTestDatabase(); err != nil {
|
||||||
|
// log.Fatal(err)
|
||||||
|
// }
|
||||||
|
func (c *Context) DetectTestDatabase() error {
|
||||||
|
dbName, err := c.helper.databaseName(c.db)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !dbnameRegexp.MatchString(dbName) {
|
||||||
|
return ErrNotTestDatabase
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Load wipes and after load all fixtures in the database.
|
// Load wipes and after load all fixtures in the database.
|
||||||
// if err := fixtures.Load(); err != nil {
|
// if err := fixtures.Load(); err != nil {
|
||||||
// log.Fatal(err)
|
// log.Fatal(err)
|
||||||
// }
|
// }
|
||||||
func (c *Context) Load() error {
|
func (c *Context) Load() error {
|
||||||
if !skipDatabaseNameCheck {
|
if !skipDatabaseNameCheck {
|
||||||
dbName, err := c.helper.databaseName(c.db)
|
if err := c.DetectTestDatabase(); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if !dbnameRegexp.MatchString(dbName) {
|
|
||||||
return ErrNotTestDatabase
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err := c.helper.disableReferentialIntegrity(c.db, func(tx *sql.Tx) error {
|
err := c.helper.disableReferentialIntegrity(c.db, func(tx *sql.Tx) error {
|
||||||
|
@ -257,7 +268,8 @@ func fixturesFromFolder(folderName string) ([]*fixtureFile, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, fileinfo := range fileinfos {
|
for _, fileinfo := range fileinfos {
|
||||||
if !fileinfo.IsDir() && filepath.Ext(fileinfo.Name()) == ".yml" {
|
fileExt := filepath.Ext(fileinfo.Name())
|
||||||
|
if !fileinfo.IsDir() && (fileExt == ".yml" || fileExt == ".yaml") {
|
||||||
fixture := &fixtureFile{
|
fixture := &fixtureFile{
|
||||||
path: path.Join(folderName, fileinfo.Name()),
|
path: path.Join(folderName, fileinfo.Name()),
|
||||||
fileName: fileinfo.Name(),
|
fileName: fileinfo.Name(),
|
||||||
|
|
28
vendor/gopkg.in/yaml.v2/encode.go
generated
vendored
28
vendor/gopkg.in/yaml.v2/encode.go
generated
vendored
|
@ -13,6 +13,19 @@ import (
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// jsonNumber is the interface of the encoding/json.Number datatype.
|
||||||
|
// Repeating the interface here avoids a dependency on encoding/json, and also
|
||||||
|
// supports other libraries like jsoniter, which use a similar datatype with
|
||||||
|
// the same interface. Detecting this interface is useful when dealing with
|
||||||
|
// structures containing json.Number, which is a string under the hood. The
|
||||||
|
// encoder should prefer the use of Int64(), Float64() and string(), in that
|
||||||
|
// order, when encoding this type.
|
||||||
|
type jsonNumber interface {
|
||||||
|
Float64() (float64, error)
|
||||||
|
Int64() (int64, error)
|
||||||
|
String() string
|
||||||
|
}
|
||||||
|
|
||||||
type encoder struct {
|
type encoder struct {
|
||||||
emitter yaml_emitter_t
|
emitter yaml_emitter_t
|
||||||
event yaml_event_t
|
event yaml_event_t
|
||||||
|
@ -89,6 +102,21 @@ func (e *encoder) marshal(tag string, in reflect.Value) {
|
||||||
}
|
}
|
||||||
iface := in.Interface()
|
iface := in.Interface()
|
||||||
switch m := iface.(type) {
|
switch m := iface.(type) {
|
||||||
|
case jsonNumber:
|
||||||
|
integer, err := m.Int64()
|
||||||
|
if err == nil {
|
||||||
|
// In this case the json.Number is a valid int64
|
||||||
|
in = reflect.ValueOf(integer)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
float, err := m.Float64()
|
||||||
|
if err == nil {
|
||||||
|
// In this case the json.Number is a valid float64
|
||||||
|
in = reflect.ValueOf(float)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
// fallback case - no number could be obtained
|
||||||
|
in = reflect.ValueOf(m.String())
|
||||||
case time.Time, *time.Time:
|
case time.Time, *time.Time:
|
||||||
// Although time.Time implements TextMarshaler,
|
// Although time.Time implements TextMarshaler,
|
||||||
// we don't want to treat it as a string for YAML
|
// we don't want to treat it as a string for YAML
|
||||||
|
|
14
vendor/modules.txt
vendored
14
vendor/modules.txt
vendored
|
@ -45,7 +45,7 @@ github.com/go-redis/redis/internal/pool
|
||||||
github.com/go-redis/redis/internal/proto
|
github.com/go-redis/redis/internal/proto
|
||||||
github.com/go-redis/redis/internal/singleflight
|
github.com/go-redis/redis/internal/singleflight
|
||||||
github.com/go-redis/redis/internal/util
|
github.com/go-redis/redis/internal/util
|
||||||
# github.com/go-sql-driver/mysql v0.0.0-20171007150158-ee359f95877b
|
# github.com/go-sql-driver/mysql v1.4.1
|
||||||
github.com/go-sql-driver/mysql
|
github.com/go-sql-driver/mysql
|
||||||
# github.com/go-xorm/builder v0.0.0-20170519032130-c8871c857d25
|
# github.com/go-xorm/builder v0.0.0-20170519032130-c8871c857d25
|
||||||
github.com/go-xorm/builder
|
github.com/go-xorm/builder
|
||||||
|
@ -92,7 +92,7 @@ github.com/mailru/easyjson/buffer
|
||||||
github.com/mattn/go-colorable
|
github.com/mattn/go-colorable
|
||||||
# github.com/mattn/go-isatty v0.0.4
|
# github.com/mattn/go-isatty v0.0.4
|
||||||
github.com/mattn/go-isatty
|
github.com/mattn/go-isatty
|
||||||
# github.com/mattn/go-sqlite3 v1.9.0
|
# github.com/mattn/go-sqlite3 v1.10.0
|
||||||
github.com/mattn/go-sqlite3
|
github.com/mattn/go-sqlite3
|
||||||
# github.com/matttproud/golang_protobuf_extensions v1.0.1
|
# github.com/matttproud/golang_protobuf_extensions v1.0.1
|
||||||
github.com/matttproud/golang_protobuf_extensions/pbutil
|
github.com/matttproud/golang_protobuf_extensions/pbutil
|
||||||
|
@ -149,7 +149,7 @@ github.com/urfave/cli
|
||||||
github.com/valyala/bytebufferpool
|
github.com/valyala/bytebufferpool
|
||||||
# github.com/valyala/fasttemplate v0.0.0-20170224212429-dcecefd839c4
|
# github.com/valyala/fasttemplate v0.0.0-20170224212429-dcecefd839c4
|
||||||
github.com/valyala/fasttemplate
|
github.com/valyala/fasttemplate
|
||||||
# golang.org/x/crypto v0.0.0-20181127143415-eb0de9b17e85
|
# golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9
|
||||||
golang.org/x/crypto/bcrypt
|
golang.org/x/crypto/bcrypt
|
||||||
golang.org/x/crypto/acme/autocert
|
golang.org/x/crypto/acme/autocert
|
||||||
golang.org/x/crypto/blowfish
|
golang.org/x/crypto/blowfish
|
||||||
|
@ -157,7 +157,7 @@ golang.org/x/crypto/acme
|
||||||
# golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3
|
# golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3
|
||||||
golang.org/x/lint/golint
|
golang.org/x/lint/golint
|
||||||
golang.org/x/lint
|
golang.org/x/lint
|
||||||
# golang.org/x/net v0.0.0-20181201002055-351d144fa1fc
|
# golang.org/x/net v0.0.0-20181217023233-e147a9138326
|
||||||
golang.org/x/net/webdav
|
golang.org/x/net/webdav
|
||||||
golang.org/x/net/context
|
golang.org/x/net/context
|
||||||
golang.org/x/net/webdav/internal/xml
|
golang.org/x/net/webdav/internal/xml
|
||||||
|
@ -177,11 +177,13 @@ golang.org/x/tools/go/gcexportdata
|
||||||
golang.org/x/tools/go/buildutil
|
golang.org/x/tools/go/buildutil
|
||||||
golang.org/x/tools/go/internal/cgo
|
golang.org/x/tools/go/internal/cgo
|
||||||
golang.org/x/tools/go/internal/gcimporter
|
golang.org/x/tools/go/internal/gcimporter
|
||||||
|
# google.golang.org/appengine v1.3.0
|
||||||
|
google.golang.org/appengine/cloudsql
|
||||||
# gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc
|
# gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc
|
||||||
gopkg.in/alexcesaro/quotedprintable.v3
|
gopkg.in/alexcesaro/quotedprintable.v3
|
||||||
# gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
|
# gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
|
||||||
gopkg.in/gomail.v2
|
gopkg.in/gomail.v2
|
||||||
# gopkg.in/testfixtures.v2 v2.4.5
|
# gopkg.in/testfixtures.v2 v2.5.3
|
||||||
gopkg.in/testfixtures.v2
|
gopkg.in/testfixtures.v2
|
||||||
# gopkg.in/yaml.v2 v2.2.1
|
# gopkg.in/yaml.v2 v2.2.2
|
||||||
gopkg.in/yaml.v2
|
gopkg.in/yaml.v2
|
||||||
|
|
Loading…
Reference in a new issue