From 1ea000f41eb68a19b1d00bf5b61b60275f41a4e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20F=2E=20R=C3=B8dseth?= Date: Thu, 9 May 2024 15:02:06 +0200 Subject: [PATCH] Update dependencies --- v2/go.mod | 15 +- v2/go.sum | 146 +- v2/vendor/filippo.io/edwards25519/README.md | 14 - v2/vendor/filippo.io/edwards25519/doc.go | 20 - .../filippo.io/edwards25519/edwards25519.go | 427 ----- v2/vendor/filippo.io/edwards25519/extra.go | 349 ---- v2/vendor/filippo.io/edwards25519/field/fe.go | 420 ----- .../filippo.io/edwards25519/field/fe_amd64.go | 16 - .../filippo.io/edwards25519/field/fe_amd64.s | 379 ----- .../edwards25519/field/fe_amd64_noasm.go | 12 - .../filippo.io/edwards25519/field/fe_arm64.go | 16 - .../filippo.io/edwards25519/field/fe_arm64.s | 42 - .../edwards25519/field/fe_arm64_noasm.go | 12 - .../filippo.io/edwards25519/field/fe_extra.go | 50 - .../edwards25519/field/fe_generic.go | 266 ---- v2/vendor/filippo.io/edwards25519/scalar.go | 343 ---- .../filippo.io/edwards25519/scalar_fiat.go | 1147 -------------- .../filippo.io/edwards25519/scalarmult.go | 214 --- v2/vendor/filippo.io/edwards25519/tables.go | 129 -- .../github.com/go-mysql-org/go-mysql/LICENSE | 20 + .../go-mysql-org/go-mysql/client/auth.go | 297 ++++ .../go-mysql-org/go-mysql/client/conn.go | 400 +++++ .../go-mysql-org/go-mysql/client/pool.go | 477 ++++++ .../go-mysql-org/go-mysql/client/req.go | 68 + .../go-mysql-org/go-mysql/client/resp.go | 469 ++++++ .../go-mysql-org/go-mysql/client/stmt.go | 232 +++ .../go-mysql-org/go-mysql/client/tls.go | 40 + .../go-mysql-org/go-mysql/driver/driver.go | 326 ++++ .../go-mysql-org/go-mysql/mysql/const.go | 175 ++ .../go-mysql-org/go-mysql/mysql/errcode.go | 870 ++++++++++ .../go-mysql-org/go-mysql/mysql/errname.go | 868 ++++++++++ .../go-mysql-org/go-mysql/mysql/error.go | 66 + .../go-mysql-org/go-mysql/mysql/field.go | 212 +++ .../go-mysql-org/go-mysql/mysql/gtid.go | 31 + .../go-mysql/mysql/mariadb_gtid.go | 238 +++ .../go-mysql-org/go-mysql/mysql/mysql_gtid.go | 598 +++++++ .../go-mysql/mysql/parse_binary.go | 53 + .../go-mysql-org/go-mysql/mysql/position.go | 80 + .../go-mysql-org/go-mysql/mysql/result.go | 22 + .../go-mysql-org/go-mysql/mysql/resultset.go | 287 ++++ .../go-mysql/mysql/resultset_helper.go | 254 +++ .../go-mysql-org/go-mysql/mysql/rowdata.go | 258 +++ .../go-mysql-org/go-mysql/mysql/state.go | 233 +++ .../go-mysql-org/go-mysql/mysql/util.go | 403 +++++ .../go-mysql-org/go-mysql/packet/conn.go | 305 ++++ .../go-mysql/utils/byte_slice_pool.go | 30 + .../go-mysql/utils/bytes_buffer_pool.go | 31 + .../go-mysql-org/go-mysql/utils/zeroalloc.go | 27 + .../github.com/go-sql-driver/mysql/.gitignore | 9 - .../github.com/go-sql-driver/mysql/AUTHORS | 142 -- .../go-sql-driver/mysql/CHANGELOG.md | 308 ---- .../github.com/go-sql-driver/mysql/LICENSE | 373 ----- .../github.com/go-sql-driver/mysql/README.md | 581 ------- .../go-sql-driver/mysql/atomic_bool.go | 19 - .../go-sql-driver/mysql/atomic_bool_go118.go | 47 - .../github.com/go-sql-driver/mysql/auth.go | 484 ------ .../github.com/go-sql-driver/mysql/buffer.go | 182 --- .../go-sql-driver/mysql/collations.go | 266 ---- .../go-sql-driver/mysql/conncheck.go | 55 - .../go-sql-driver/mysql/conncheck_dummy.go | 18 - .../go-sql-driver/mysql/connection.go | 688 -------- .../go-sql-driver/mysql/connector.go | 197 --- .../github.com/go-sql-driver/mysql/const.go | 187 --- .../github.com/go-sql-driver/mysql/driver.go | 118 -- .../github.com/go-sql-driver/mysql/dsn.go | 653 -------- .../github.com/go-sql-driver/mysql/errors.go | 83 - .../github.com/go-sql-driver/mysql/fields.go | 222 --- .../github.com/go-sql-driver/mysql/infile.go | 182 --- .../go-sql-driver/mysql/nulltime.go | 71 - .../github.com/go-sql-driver/mysql/packets.go | 1406 ----------------- .../github.com/go-sql-driver/mysql/result.go | 50 - .../github.com/go-sql-driver/mysql/rows.go | 232 --- .../go-sql-driver/mysql/statement.go | 217 --- .../go-sql-driver/mysql/transaction.go | 31 - .../github.com/go-sql-driver/mysql/utils.go | 843 ---------- v2/vendor/github.com/google/uuid/CHANGELOG.md | 41 + .../github.com/google/uuid/CONTRIBUTING.md | 26 + v2/vendor/github.com/google/uuid/CONTRIBUTORS | 9 + .../google/uuid}/LICENSE | 2 +- v2/vendor/github.com/google/uuid/README.md | 21 + v2/vendor/github.com/google/uuid/dce.go | 80 + v2/vendor/github.com/google/uuid/doc.go | 12 + v2/vendor/github.com/google/uuid/hash.go | 59 + v2/vendor/github.com/google/uuid/marshal.go | 38 + v2/vendor/github.com/google/uuid/node.go | 90 ++ v2/vendor/github.com/google/uuid/node_js.go | 12 + v2/vendor/github.com/google/uuid/node_net.go | 33 + v2/vendor/github.com/google/uuid/null.go | 118 ++ v2/vendor/github.com/google/uuid/sql.go | 59 + v2/vendor/github.com/google/uuid/time.go | 134 ++ v2/vendor/github.com/google/uuid/util.go | 43 + v2/vendor/github.com/google/uuid/uuid.go | 365 +++++ v2/vendor/github.com/google/uuid/version1.go | 44 + v2/vendor/github.com/google/uuid/version4.go | 76 + v2/vendor/github.com/google/uuid/version6.go | 56 + v2/vendor/github.com/google/uuid/version7.go | 104 ++ .../github.com/pingcap/errors/.gitignore | 25 + .../github.com/pingcap/errors/.travis.yml | 11 + v2/vendor/github.com/pingcap/errors/LICENSE | 23 + v2/vendor/github.com/pingcap/errors/README.md | 52 + .../pingcap/errors/compatible_shim.go | 98 ++ v2/vendor/github.com/pingcap/errors/errors.go | 324 ++++ v2/vendor/github.com/pingcap/errors/group.go | 42 + .../github.com/pingcap/errors/juju_adaptor.go | 145 ++ .../github.com/pingcap/errors/normalize.go | 316 ++++ v2/vendor/github.com/pingcap/errors/stack.go | 226 +++ .../github.com/siddontang/go-log/LICENSE | 21 + .../github.com/siddontang/go-log/log/doc.go | 20 + .../siddontang/go-log/log/filehandler.go | 230 +++ .../siddontang/go-log/log/handler.go | 54 + .../github.com/siddontang/go-log/log/log.go | 157 ++ .../siddontang/go-log/log/logger.go | 358 +++++ .../siddontang/go-log/loggers/loggers.go | 68 + v2/vendor/github.com/siddontang/go/LICENSE | 20 + .../github.com/siddontang/go/hack/hack.go | 27 + .../github.com/xyproto/cookie/v2/cookie.go | 6 +- v2/vendor/github.com/xyproto/env/v2/LICENSE | 11 + v2/vendor/github.com/xyproto/env/v2/cache.go | 109 ++ v2/vendor/github.com/xyproto/env/v2/env.go | 302 ++++ v2/vendor/github.com/xyproto/env/v2/etc.go | 36 + .../github.com/xyproto/env/v2/session.go | 25 + .../github.com/xyproto/simplemaria/.gitignore | 8 +- .../xyproto/simplemaria/.travis.yml | 21 - .../github.com/xyproto/simplemaria/README.md | 4 +- .../github.com/xyproto/simplemaria/encdec.go | 4 +- .../github.com/xyproto/simplemaria/helpers.go | 33 +- .../xyproto/simplemaria/simplemaria.go | 50 +- v2/vendor/go.uber.org/atomic/.codecov.yml | 19 + v2/vendor/go.uber.org/atomic/.gitignore | 15 + v2/vendor/go.uber.org/atomic/CHANGELOG.md | 127 ++ v2/vendor/go.uber.org/atomic/LICENSE.txt | 19 + v2/vendor/go.uber.org/atomic/Makefile | 79 + v2/vendor/go.uber.org/atomic/README.md | 63 + v2/vendor/go.uber.org/atomic/bool.go | 88 ++ v2/vendor/go.uber.org/atomic/bool_ext.go | 53 + v2/vendor/go.uber.org/atomic/doc.go | 23 + v2/vendor/go.uber.org/atomic/duration.go | 89 ++ v2/vendor/go.uber.org/atomic/duration_ext.go | 40 + v2/vendor/go.uber.org/atomic/error.go | 72 + v2/vendor/go.uber.org/atomic/error_ext.go | 39 + v2/vendor/go.uber.org/atomic/float32.go | 77 + v2/vendor/go.uber.org/atomic/float32_ext.go | 76 + v2/vendor/go.uber.org/atomic/float64.go | 77 + v2/vendor/go.uber.org/atomic/float64_ext.go | 76 + v2/vendor/go.uber.org/atomic/gen.go | 27 + v2/vendor/go.uber.org/atomic/int32.go | 109 ++ v2/vendor/go.uber.org/atomic/int64.go | 109 ++ v2/vendor/go.uber.org/atomic/nocmp.go | 35 + v2/vendor/go.uber.org/atomic/pointer_go118.go | 31 + .../atomic/pointer_go118_pre119.go | 60 + v2/vendor/go.uber.org/atomic/pointer_go119.go | 61 + v2/vendor/go.uber.org/atomic/string.go | 72 + v2/vendor/go.uber.org/atomic/string_ext.go | 54 + v2/vendor/go.uber.org/atomic/time.go | 55 + v2/vendor/go.uber.org/atomic/time_ext.go | 36 + v2/vendor/go.uber.org/atomic/uint32.go | 109 ++ v2/vendor/go.uber.org/atomic/uint64.go | 109 ++ v2/vendor/go.uber.org/atomic/uintptr.go | 109 ++ .../go.uber.org/atomic/unsafe_pointer.go | 65 + v2/vendor/go.uber.org/atomic/value.go | 31 + v2/vendor/modules.txt | 39 +- 161 files changed, 13805 insertions(+), 11637 deletions(-) delete mode 100644 v2/vendor/filippo.io/edwards25519/README.md delete mode 100644 v2/vendor/filippo.io/edwards25519/doc.go delete mode 100644 v2/vendor/filippo.io/edwards25519/edwards25519.go delete mode 100644 v2/vendor/filippo.io/edwards25519/extra.go delete mode 100644 v2/vendor/filippo.io/edwards25519/field/fe.go delete mode 100644 v2/vendor/filippo.io/edwards25519/field/fe_amd64.go delete mode 100644 v2/vendor/filippo.io/edwards25519/field/fe_amd64.s delete mode 100644 v2/vendor/filippo.io/edwards25519/field/fe_amd64_noasm.go delete mode 100644 v2/vendor/filippo.io/edwards25519/field/fe_arm64.go delete mode 100644 v2/vendor/filippo.io/edwards25519/field/fe_arm64.s delete mode 100644 v2/vendor/filippo.io/edwards25519/field/fe_arm64_noasm.go delete mode 100644 v2/vendor/filippo.io/edwards25519/field/fe_extra.go delete mode 100644 v2/vendor/filippo.io/edwards25519/field/fe_generic.go delete mode 100644 v2/vendor/filippo.io/edwards25519/scalar.go delete mode 100644 v2/vendor/filippo.io/edwards25519/scalar_fiat.go delete mode 100644 v2/vendor/filippo.io/edwards25519/scalarmult.go delete mode 100644 v2/vendor/filippo.io/edwards25519/tables.go create mode 100644 v2/vendor/github.com/go-mysql-org/go-mysql/LICENSE create mode 100644 v2/vendor/github.com/go-mysql-org/go-mysql/client/auth.go create mode 100644 v2/vendor/github.com/go-mysql-org/go-mysql/client/conn.go create mode 100644 v2/vendor/github.com/go-mysql-org/go-mysql/client/pool.go create mode 100644 v2/vendor/github.com/go-mysql-org/go-mysql/client/req.go create mode 100644 v2/vendor/github.com/go-mysql-org/go-mysql/client/resp.go create mode 100644 v2/vendor/github.com/go-mysql-org/go-mysql/client/stmt.go create mode 100644 v2/vendor/github.com/go-mysql-org/go-mysql/client/tls.go create mode 100644 v2/vendor/github.com/go-mysql-org/go-mysql/driver/driver.go create mode 100644 v2/vendor/github.com/go-mysql-org/go-mysql/mysql/const.go create mode 100644 v2/vendor/github.com/go-mysql-org/go-mysql/mysql/errcode.go create mode 100644 v2/vendor/github.com/go-mysql-org/go-mysql/mysql/errname.go create mode 100644 v2/vendor/github.com/go-mysql-org/go-mysql/mysql/error.go create mode 100644 v2/vendor/github.com/go-mysql-org/go-mysql/mysql/field.go create mode 100644 v2/vendor/github.com/go-mysql-org/go-mysql/mysql/gtid.go create mode 100644 v2/vendor/github.com/go-mysql-org/go-mysql/mysql/mariadb_gtid.go create mode 100644 v2/vendor/github.com/go-mysql-org/go-mysql/mysql/mysql_gtid.go create mode 100644 v2/vendor/github.com/go-mysql-org/go-mysql/mysql/parse_binary.go create mode 100644 v2/vendor/github.com/go-mysql-org/go-mysql/mysql/position.go create mode 100644 v2/vendor/github.com/go-mysql-org/go-mysql/mysql/result.go create mode 100644 v2/vendor/github.com/go-mysql-org/go-mysql/mysql/resultset.go create mode 100644 v2/vendor/github.com/go-mysql-org/go-mysql/mysql/resultset_helper.go create mode 100644 v2/vendor/github.com/go-mysql-org/go-mysql/mysql/rowdata.go create mode 100644 v2/vendor/github.com/go-mysql-org/go-mysql/mysql/state.go create mode 100644 v2/vendor/github.com/go-mysql-org/go-mysql/mysql/util.go create mode 100644 v2/vendor/github.com/go-mysql-org/go-mysql/packet/conn.go create mode 100644 v2/vendor/github.com/go-mysql-org/go-mysql/utils/byte_slice_pool.go create mode 100644 v2/vendor/github.com/go-mysql-org/go-mysql/utils/bytes_buffer_pool.go create mode 100644 v2/vendor/github.com/go-mysql-org/go-mysql/utils/zeroalloc.go delete mode 100644 v2/vendor/github.com/go-sql-driver/mysql/.gitignore delete mode 100644 v2/vendor/github.com/go-sql-driver/mysql/AUTHORS delete mode 100644 v2/vendor/github.com/go-sql-driver/mysql/CHANGELOG.md delete mode 100644 v2/vendor/github.com/go-sql-driver/mysql/LICENSE delete mode 100644 v2/vendor/github.com/go-sql-driver/mysql/README.md delete mode 100644 v2/vendor/github.com/go-sql-driver/mysql/atomic_bool.go delete mode 100644 v2/vendor/github.com/go-sql-driver/mysql/atomic_bool_go118.go delete mode 100644 v2/vendor/github.com/go-sql-driver/mysql/auth.go delete mode 100644 v2/vendor/github.com/go-sql-driver/mysql/buffer.go delete mode 100644 v2/vendor/github.com/go-sql-driver/mysql/collations.go delete mode 100644 v2/vendor/github.com/go-sql-driver/mysql/conncheck.go delete mode 100644 v2/vendor/github.com/go-sql-driver/mysql/conncheck_dummy.go delete mode 100644 v2/vendor/github.com/go-sql-driver/mysql/connection.go delete mode 100644 v2/vendor/github.com/go-sql-driver/mysql/connector.go delete mode 100644 v2/vendor/github.com/go-sql-driver/mysql/const.go delete mode 100644 v2/vendor/github.com/go-sql-driver/mysql/driver.go delete mode 100644 v2/vendor/github.com/go-sql-driver/mysql/dsn.go delete mode 100644 v2/vendor/github.com/go-sql-driver/mysql/errors.go delete mode 100644 v2/vendor/github.com/go-sql-driver/mysql/fields.go delete mode 100644 v2/vendor/github.com/go-sql-driver/mysql/infile.go delete mode 100644 v2/vendor/github.com/go-sql-driver/mysql/nulltime.go delete mode 100644 v2/vendor/github.com/go-sql-driver/mysql/packets.go delete mode 100644 v2/vendor/github.com/go-sql-driver/mysql/result.go delete mode 100644 v2/vendor/github.com/go-sql-driver/mysql/rows.go delete mode 100644 v2/vendor/github.com/go-sql-driver/mysql/statement.go delete mode 100644 v2/vendor/github.com/go-sql-driver/mysql/transaction.go delete mode 100644 v2/vendor/github.com/go-sql-driver/mysql/utils.go create mode 100644 v2/vendor/github.com/google/uuid/CHANGELOG.md create mode 100644 v2/vendor/github.com/google/uuid/CONTRIBUTING.md create mode 100644 v2/vendor/github.com/google/uuid/CONTRIBUTORS rename v2/vendor/{filippo.io/edwards25519 => github.com/google/uuid}/LICENSE (96%) create mode 100644 v2/vendor/github.com/google/uuid/README.md create mode 100644 v2/vendor/github.com/google/uuid/dce.go create mode 100644 v2/vendor/github.com/google/uuid/doc.go create mode 100644 v2/vendor/github.com/google/uuid/hash.go create mode 100644 v2/vendor/github.com/google/uuid/marshal.go create mode 100644 v2/vendor/github.com/google/uuid/node.go create mode 100644 v2/vendor/github.com/google/uuid/node_js.go create mode 100644 v2/vendor/github.com/google/uuid/node_net.go create mode 100644 v2/vendor/github.com/google/uuid/null.go create mode 100644 v2/vendor/github.com/google/uuid/sql.go create mode 100644 v2/vendor/github.com/google/uuid/time.go create mode 100644 v2/vendor/github.com/google/uuid/util.go create mode 100644 v2/vendor/github.com/google/uuid/uuid.go create mode 100644 v2/vendor/github.com/google/uuid/version1.go create mode 100644 v2/vendor/github.com/google/uuid/version4.go create mode 100644 v2/vendor/github.com/google/uuid/version6.go create mode 100644 v2/vendor/github.com/google/uuid/version7.go create mode 100644 v2/vendor/github.com/pingcap/errors/.gitignore create mode 100644 v2/vendor/github.com/pingcap/errors/.travis.yml create mode 100644 v2/vendor/github.com/pingcap/errors/LICENSE create mode 100644 v2/vendor/github.com/pingcap/errors/README.md create mode 100644 v2/vendor/github.com/pingcap/errors/compatible_shim.go create mode 100644 v2/vendor/github.com/pingcap/errors/errors.go create mode 100644 v2/vendor/github.com/pingcap/errors/group.go create mode 100644 v2/vendor/github.com/pingcap/errors/juju_adaptor.go create mode 100644 v2/vendor/github.com/pingcap/errors/normalize.go create mode 100644 v2/vendor/github.com/pingcap/errors/stack.go create mode 100644 v2/vendor/github.com/siddontang/go-log/LICENSE create mode 100644 v2/vendor/github.com/siddontang/go-log/log/doc.go create mode 100644 v2/vendor/github.com/siddontang/go-log/log/filehandler.go create mode 100644 v2/vendor/github.com/siddontang/go-log/log/handler.go create mode 100644 v2/vendor/github.com/siddontang/go-log/log/log.go create mode 100644 v2/vendor/github.com/siddontang/go-log/log/logger.go create mode 100644 v2/vendor/github.com/siddontang/go-log/loggers/loggers.go create mode 100644 v2/vendor/github.com/siddontang/go/LICENSE create mode 100644 v2/vendor/github.com/siddontang/go/hack/hack.go create mode 100644 v2/vendor/github.com/xyproto/env/v2/LICENSE create mode 100644 v2/vendor/github.com/xyproto/env/v2/cache.go create mode 100644 v2/vendor/github.com/xyproto/env/v2/env.go create mode 100644 v2/vendor/github.com/xyproto/env/v2/etc.go create mode 100644 v2/vendor/github.com/xyproto/env/v2/session.go delete mode 100644 v2/vendor/github.com/xyproto/simplemaria/.travis.yml create mode 100644 v2/vendor/go.uber.org/atomic/.codecov.yml create mode 100644 v2/vendor/go.uber.org/atomic/.gitignore create mode 100644 v2/vendor/go.uber.org/atomic/CHANGELOG.md create mode 100644 v2/vendor/go.uber.org/atomic/LICENSE.txt create mode 100644 v2/vendor/go.uber.org/atomic/Makefile create mode 100644 v2/vendor/go.uber.org/atomic/README.md create mode 100644 v2/vendor/go.uber.org/atomic/bool.go create mode 100644 v2/vendor/go.uber.org/atomic/bool_ext.go create mode 100644 v2/vendor/go.uber.org/atomic/doc.go create mode 100644 v2/vendor/go.uber.org/atomic/duration.go create mode 100644 v2/vendor/go.uber.org/atomic/duration_ext.go create mode 100644 v2/vendor/go.uber.org/atomic/error.go create mode 100644 v2/vendor/go.uber.org/atomic/error_ext.go create mode 100644 v2/vendor/go.uber.org/atomic/float32.go create mode 100644 v2/vendor/go.uber.org/atomic/float32_ext.go create mode 100644 v2/vendor/go.uber.org/atomic/float64.go create mode 100644 v2/vendor/go.uber.org/atomic/float64_ext.go create mode 100644 v2/vendor/go.uber.org/atomic/gen.go create mode 100644 v2/vendor/go.uber.org/atomic/int32.go create mode 100644 v2/vendor/go.uber.org/atomic/int64.go create mode 100644 v2/vendor/go.uber.org/atomic/nocmp.go create mode 100644 v2/vendor/go.uber.org/atomic/pointer_go118.go create mode 100644 v2/vendor/go.uber.org/atomic/pointer_go118_pre119.go create mode 100644 v2/vendor/go.uber.org/atomic/pointer_go119.go create mode 100644 v2/vendor/go.uber.org/atomic/string.go create mode 100644 v2/vendor/go.uber.org/atomic/string_ext.go create mode 100644 v2/vendor/go.uber.org/atomic/time.go create mode 100644 v2/vendor/go.uber.org/atomic/time_ext.go create mode 100644 v2/vendor/go.uber.org/atomic/uint32.go create mode 100644 v2/vendor/go.uber.org/atomic/uint64.go create mode 100644 v2/vendor/go.uber.org/atomic/uintptr.go create mode 100644 v2/vendor/go.uber.org/atomic/unsafe_pointer.go create mode 100644 v2/vendor/go.uber.org/atomic/value.go diff --git a/v2/go.mod b/v2/go.mod index a542510..0d70c2a 100644 --- a/v2/go.mod +++ b/v2/go.mod @@ -1,16 +1,21 @@ module github.com/xyproto/permissionsql/v2 -go 1.17 +go 1.21 require ( - github.com/xyproto/cookie/v2 v2.2.4 + github.com/xyproto/cookie/v2 v2.2.5 github.com/xyproto/pinterface v1.5.3 - github.com/xyproto/simplemaria v1.3.2 + github.com/xyproto/simplemaria v1.3.4 golang.org/x/crypto v0.23.0 ) require ( - filippo.io/edwards25519 v1.1.0 // indirect - github.com/go-sql-driver/mysql v1.8.1 // indirect + github.com/go-mysql-org/go-mysql v1.7.0 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/pingcap/errors v0.11.5-0.20210425183316-da1aaba5fb63 // indirect + github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726 // indirect + github.com/siddontang/go-log v0.0.0-20190221022429-1e957dd83bed // indirect + github.com/xyproto/env/v2 v2.2.5 // indirect github.com/xyproto/randomstring v1.0.5 // indirect + go.uber.org/atomic v1.11.0 // indirect ) diff --git a/v2/go.sum b/v2/go.sum index 0386925..86421bb 100644 --- a/v2/go.sum +++ b/v2/go.sum @@ -1,60 +1,120 @@ -filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= -filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= -github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= -github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= -github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= -github.com/xyproto/cookie/v2 v2.2.4 h1:McHpNU+5r1jpMxGwCoUCoHQHElrW2wr7cXomBauuJ9I= -github.com/xyproto/cookie/v2 v2.2.4/go.mod h1:SkeeteOip8UEegYTF4H+WIzrgKVrqh7o0t97i3vymjw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548/go.mod h1:e6NPNENfs9mPDVNRekM7lKScauxd5kXTr1Mfyig6TDM= +github.com/cznic/sortutil v0.0.0-20181122101858-f5f958428db8/go.mod h1:q2w6Bg5jeox1B+QkJ6Wp/+Vn0G/bo3f1uY7Fn3vivIQ= +github.com/cznic/strutil v0.0.0-20171016134553-529a34b1c186/go.mod h1:AHHPPPXTw0h6pVabbcbyGRK1DckRn7r/STdZEeIDzZc= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +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/go-mysql-org/go-mysql v1.7.0 h1:qE5FTRb3ZeTQmlk3pjE+/m2ravGxxRDrVDTyDe9tvqI= +github.com/go-mysql-org/go-mysql v1.7.0/go.mod h1:9cRWLtuXNKhamUPMkrDVzBhaomGvqLRLtBiyjvjc4pk= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/jmoiron/sqlx v1.3.3 h1:j82X0bf7oQ27XeqxicSZsTU5suPwKElg3oyxNn43iTk= +github.com/jmoiron/sqlx v1.3.3/go.mod h1:2BljVx/86SuTyjE+aPYlHCTNvZrnJXghYGpNiXLBMCQ= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +github.com/pingcap/check v0.0.0-20190102082844-67f458068fc8 h1:USx2/E1bX46VG32FIw034Au6seQ2fY9NEILmNh/UlQg= +github.com/pingcap/check v0.0.0-20190102082844-67f458068fc8/go.mod h1:B1+S9LNcuMyLH/4HMTViQOJevkGiik3wW2AN9zb2fNQ= +github.com/pingcap/errors v0.11.0/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= +github.com/pingcap/errors v0.11.5-0.20210425183316-da1aaba5fb63 h1:+FZIDR/D97YOPik4N4lPDaUcLDF/EQPogxtlHB2ZZRM= +github.com/pingcap/errors v0.11.5-0.20210425183316-da1aaba5fb63/go.mod h1:X2r9ueLEUZgtx2cIogM0v4Zj5uvvzhuuiu7Pn8HzMPg= +github.com/pingcap/log v0.0.0-20210625125904-98ed8e2eb1c7/go.mod h1:8AanEdAHATuRurdGxZXBz0At+9avep+ub7U1AGYLIMM= +github.com/pingcap/tidb/parser v0.0.0-20221126021158-6b02a5d8ba7d/go.mod h1:ElJiub4lRy6UZDb+0JHDkGEdr6aOli+ykhyej7VCLoI= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= +github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= +github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726 h1:xT+JlYxNGqyT+XcU8iUrN18JYed2TvG9yN5ULG2jATM= +github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw= +github.com/siddontang/go-log v0.0.0-20180807004314-8d05993dda07/go.mod h1:yFdBgwXP24JziuRl2NMUahT7nGLNOKi1SIiFxMttVD4= +github.com/siddontang/go-log v0.0.0-20190221022429-1e957dd83bed h1:KMgQoLJGCq1IoZpLZE3AIffh9veYWoVlsvA4ib55TMM= +github.com/siddontang/go-log v0.0.0-20190221022429-1e957dd83bed/go.mod h1:yFdBgwXP24JziuRl2NMUahT7nGLNOKi1SIiFxMttVD4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/xyproto/cookie/v2 v2.2.5 h1:g4v1/1hpVbacK+PklgzujnUYgGFmT2riz/cZfePD04k= +github.com/xyproto/cookie/v2 v2.2.5/go.mod h1:SkeeteOip8UEegYTF4H+WIzrgKVrqh7o0t97i3vymjw= +github.com/xyproto/env/v2 v2.2.5 h1:FNrp56sptc7ebC2QpM8lqKSGEb3UoYUJZZFl4bmcrPs= +github.com/xyproto/env/v2 v2.2.5/go.mod h1:F81ZEzu15s3TWUZJ1uzBl9iNeq9zcfHvxMkQJaLZUl0= github.com/xyproto/pinterface v1.5.3 h1:RKkNT88cwrSqD9hU4cYAO5yeo8srg4TG+74Pcj88iz0= github.com/xyproto/pinterface v1.5.3/go.mod h1:X5B5pKE49ak7SpyDh5QvJvLH9cC9XuZNDcl5hEyYc34= github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU= github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E= -github.com/xyproto/simplemaria v1.3.2 h1:mzvS8fZXQ955vaGrjpbyJqISbEPUrY+RotjSDOaqLwk= -github.com/xyproto/simplemaria v1.3.2/go.mod h1:fyWLd+6+AAae+Wk2BgRDujDF2IZqJOxLWeaGl0roIS8= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/xyproto/simplemaria v1.3.4 h1:ayTJYiYUGwR/4CLnvUJHN8fwBr4j9cpkSZ/OQX61qdY= +github.com/xyproto/simplemaria v1.3.4/go.mod h1:vvT4KbkBY3KcODvOlytGiMy7xqhpLcqtmBA+/Gsybd8= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= +go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/exp v0.0.0-20181106170214-d68db9428509/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= -golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.0.0-20201125231158-b5590deeca9b/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +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/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +modernc.org/fileutil v1.0.0/go.mod h1:JHsWpkrk/CnVV1H/eGlFf85BEpfkrp56ro8nojIq9Q8= +modernc.org/golex v1.0.1/go.mod h1:QCA53QtsT1NdGkaZZkF5ezFwk4IXh4BGNafAARTC254= +modernc.org/lex v1.0.0/go.mod h1:G6rxMTy3cH2iA0iXL/HRRv4Znu8MK4higxph/lE7ypk= +modernc.org/lexer v1.0.0/go.mod h1:F/Dld0YKYdZCLQ7bD0USbWL4YKCyTDRDHiDTOs0q0vk= +modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k= +modernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= +modernc.org/parser v1.0.0/go.mod h1:H20AntYJ2cHHL6MHthJ8LZzXCdDCHMWt1KZXtIMjejA= +modernc.org/parser v1.0.2/go.mod h1:TXNq3HABP3HMaqLK7brD1fLA/LfN0KS6JxZn71QdDqs= +modernc.org/scanner v1.0.1/go.mod h1:OIzD2ZtjYk6yTuyqZr57FmifbM9fIH74SumloSsajuE= +modernc.org/sortutil v1.0.0/go.mod h1:1QO0q8IlIlmjBIwm6t/7sof874+xCfZouyqZMLIAtxM= +modernc.org/strutil v1.0.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs= +modernc.org/strutil v1.1.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs= +modernc.org/y v1.0.1/go.mod h1:Ho86I+LVHEI+LYXoUKlmOMAM1JTXOCfj8qi1T8PsClE= diff --git a/v2/vendor/filippo.io/edwards25519/README.md b/v2/vendor/filippo.io/edwards25519/README.md deleted file mode 100644 index 24e2457..0000000 --- a/v2/vendor/filippo.io/edwards25519/README.md +++ /dev/null @@ -1,14 +0,0 @@ -# filippo.io/edwards25519 - -``` -import "filippo.io/edwards25519" -``` - -This library implements the edwards25519 elliptic curve, exposing the necessary APIs to build a wide array of higher-level primitives. -Read the docs at [pkg.go.dev/filippo.io/edwards25519](https://pkg.go.dev/filippo.io/edwards25519). - -The code is originally derived from Adam Langley's internal implementation in the Go standard library, and includes George Tankersley's [performance improvements](https://golang.org/cl/71950). It was then further developed by Henry de Valence for use in ristretto255, and was finally [merged back into the Go standard library](https://golang.org/cl/276272) as of Go 1.17. It now tracks the upstream codebase and extends it with additional functionality. - -Most users don't need this package, and should instead use `crypto/ed25519` for signatures, `golang.org/x/crypto/curve25519` for Diffie-Hellman, or `github.com/gtank/ristretto255` for prime order group logic. However, for anyone currently using a fork of `crypto/internal/edwards25519`/`crypto/ed25519/internal/edwards25519` or `github.com/agl/edwards25519`, this package should be a safer, faster, and more powerful alternative. - -Since this package is meant to curb proliferation of edwards25519 implementations in the Go ecosystem, it welcomes requests for new APIs or reviewable performance improvements. diff --git a/v2/vendor/filippo.io/edwards25519/doc.go b/v2/vendor/filippo.io/edwards25519/doc.go deleted file mode 100644 index ab6aaeb..0000000 --- a/v2/vendor/filippo.io/edwards25519/doc.go +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package edwards25519 implements group logic for the twisted Edwards curve -// -// -x^2 + y^2 = 1 + -(121665/121666)*x^2*y^2 -// -// This is better known as the Edwards curve equivalent to Curve25519, and is -// the curve used by the Ed25519 signature scheme. -// -// Most users don't need this package, and should instead use crypto/ed25519 for -// signatures, golang.org/x/crypto/curve25519 for Diffie-Hellman, or -// github.com/gtank/ristretto255 for prime order group logic. -// -// However, developers who do need to interact with low-level edwards25519 -// operations can use this package, which is an extended version of -// crypto/internal/edwards25519 from the standard library repackaged as -// an importable module. -package edwards25519 diff --git a/v2/vendor/filippo.io/edwards25519/edwards25519.go b/v2/vendor/filippo.io/edwards25519/edwards25519.go deleted file mode 100644 index a744da2..0000000 --- a/v2/vendor/filippo.io/edwards25519/edwards25519.go +++ /dev/null @@ -1,427 +0,0 @@ -// Copyright (c) 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package edwards25519 - -import ( - "errors" - - "filippo.io/edwards25519/field" -) - -// Point types. - -type projP1xP1 struct { - X, Y, Z, T field.Element -} - -type projP2 struct { - X, Y, Z field.Element -} - -// Point represents a point on the edwards25519 curve. -// -// This type works similarly to math/big.Int, and all arguments and receivers -// are allowed to alias. -// -// The zero value is NOT valid, and it may be used only as a receiver. -type Point struct { - // Make the type not comparable (i.e. used with == or as a map key), as - // equivalent points can be represented by different Go values. - _ incomparable - - // The point is internally represented in extended coordinates (X, Y, Z, T) - // where x = X/Z, y = Y/Z, and xy = T/Z per https://eprint.iacr.org/2008/522. - x, y, z, t field.Element -} - -type incomparable [0]func() - -func checkInitialized(points ...*Point) { - for _, p := range points { - if p.x == (field.Element{}) && p.y == (field.Element{}) { - panic("edwards25519: use of uninitialized Point") - } - } -} - -type projCached struct { - YplusX, YminusX, Z, T2d field.Element -} - -type affineCached struct { - YplusX, YminusX, T2d field.Element -} - -// Constructors. - -func (v *projP2) Zero() *projP2 { - v.X.Zero() - v.Y.One() - v.Z.One() - return v -} - -// identity is the point at infinity. -var identity, _ = new(Point).SetBytes([]byte{ - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}) - -// NewIdentityPoint returns a new Point set to the identity. -func NewIdentityPoint() *Point { - return new(Point).Set(identity) -} - -// generator is the canonical curve basepoint. See TestGenerator for the -// correspondence of this encoding with the values in RFC 8032. -var generator, _ = new(Point).SetBytes([]byte{ - 0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, - 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, - 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, - 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66}) - -// NewGeneratorPoint returns a new Point set to the canonical generator. -func NewGeneratorPoint() *Point { - return new(Point).Set(generator) -} - -func (v *projCached) Zero() *projCached { - v.YplusX.One() - v.YminusX.One() - v.Z.One() - v.T2d.Zero() - return v -} - -func (v *affineCached) Zero() *affineCached { - v.YplusX.One() - v.YminusX.One() - v.T2d.Zero() - return v -} - -// Assignments. - -// Set sets v = u, and returns v. -func (v *Point) Set(u *Point) *Point { - *v = *u - return v -} - -// Encoding. - -// Bytes returns the canonical 32-byte encoding of v, according to RFC 8032, -// Section 5.1.2. -func (v *Point) Bytes() []byte { - // This function is outlined to make the allocations inline in the caller - // rather than happen on the heap. - var buf [32]byte - return v.bytes(&buf) -} - -func (v *Point) bytes(buf *[32]byte) []byte { - checkInitialized(v) - - var zInv, x, y field.Element - zInv.Invert(&v.z) // zInv = 1 / Z - x.Multiply(&v.x, &zInv) // x = X / Z - y.Multiply(&v.y, &zInv) // y = Y / Z - - out := copyFieldElement(buf, &y) - out[31] |= byte(x.IsNegative() << 7) - return out -} - -var feOne = new(field.Element).One() - -// SetBytes sets v = x, where x is a 32-byte encoding of v. If x does not -// represent a valid point on the curve, SetBytes returns nil and an error and -// the receiver is unchanged. Otherwise, SetBytes returns v. -// -// Note that SetBytes accepts all non-canonical encodings of valid points. -// That is, it follows decoding rules that match most implementations in -// the ecosystem rather than RFC 8032. -func (v *Point) SetBytes(x []byte) (*Point, error) { - // Specifically, the non-canonical encodings that are accepted are - // 1) the ones where the field element is not reduced (see the - // (*field.Element).SetBytes docs) and - // 2) the ones where the x-coordinate is zero and the sign bit is set. - // - // Read more at https://hdevalence.ca/blog/2020-10-04-its-25519am, - // specifically the "Canonical A, R" section. - - y, err := new(field.Element).SetBytes(x) - if err != nil { - return nil, errors.New("edwards25519: invalid point encoding length") - } - - // -x² + y² = 1 + dx²y² - // x² + dx²y² = x²(dy² + 1) = y² - 1 - // x² = (y² - 1) / (dy² + 1) - - // u = y² - 1 - y2 := new(field.Element).Square(y) - u := new(field.Element).Subtract(y2, feOne) - - // v = dy² + 1 - vv := new(field.Element).Multiply(y2, d) - vv = vv.Add(vv, feOne) - - // x = +√(u/v) - xx, wasSquare := new(field.Element).SqrtRatio(u, vv) - if wasSquare == 0 { - return nil, errors.New("edwards25519: invalid point encoding") - } - - // Select the negative square root if the sign bit is set. - xxNeg := new(field.Element).Negate(xx) - xx = xx.Select(xxNeg, xx, int(x[31]>>7)) - - v.x.Set(xx) - v.y.Set(y) - v.z.One() - v.t.Multiply(xx, y) // xy = T / Z - - return v, nil -} - -func copyFieldElement(buf *[32]byte, v *field.Element) []byte { - copy(buf[:], v.Bytes()) - return buf[:] -} - -// Conversions. - -func (v *projP2) FromP1xP1(p *projP1xP1) *projP2 { - v.X.Multiply(&p.X, &p.T) - v.Y.Multiply(&p.Y, &p.Z) - v.Z.Multiply(&p.Z, &p.T) - return v -} - -func (v *projP2) FromP3(p *Point) *projP2 { - v.X.Set(&p.x) - v.Y.Set(&p.y) - v.Z.Set(&p.z) - return v -} - -func (v *Point) fromP1xP1(p *projP1xP1) *Point { - v.x.Multiply(&p.X, &p.T) - v.y.Multiply(&p.Y, &p.Z) - v.z.Multiply(&p.Z, &p.T) - v.t.Multiply(&p.X, &p.Y) - return v -} - -func (v *Point) fromP2(p *projP2) *Point { - v.x.Multiply(&p.X, &p.Z) - v.y.Multiply(&p.Y, &p.Z) - v.z.Square(&p.Z) - v.t.Multiply(&p.X, &p.Y) - return v -} - -// d is a constant in the curve equation. -var d, _ = new(field.Element).SetBytes([]byte{ - 0xa3, 0x78, 0x59, 0x13, 0xca, 0x4d, 0xeb, 0x75, - 0xab, 0xd8, 0x41, 0x41, 0x4d, 0x0a, 0x70, 0x00, - 0x98, 0xe8, 0x79, 0x77, 0x79, 0x40, 0xc7, 0x8c, - 0x73, 0xfe, 0x6f, 0x2b, 0xee, 0x6c, 0x03, 0x52}) -var d2 = new(field.Element).Add(d, d) - -func (v *projCached) FromP3(p *Point) *projCached { - v.YplusX.Add(&p.y, &p.x) - v.YminusX.Subtract(&p.y, &p.x) - v.Z.Set(&p.z) - v.T2d.Multiply(&p.t, d2) - return v -} - -func (v *affineCached) FromP3(p *Point) *affineCached { - v.YplusX.Add(&p.y, &p.x) - v.YminusX.Subtract(&p.y, &p.x) - v.T2d.Multiply(&p.t, d2) - - var invZ field.Element - invZ.Invert(&p.z) - v.YplusX.Multiply(&v.YplusX, &invZ) - v.YminusX.Multiply(&v.YminusX, &invZ) - v.T2d.Multiply(&v.T2d, &invZ) - return v -} - -// (Re)addition and subtraction. - -// Add sets v = p + q, and returns v. -func (v *Point) Add(p, q *Point) *Point { - checkInitialized(p, q) - qCached := new(projCached).FromP3(q) - result := new(projP1xP1).Add(p, qCached) - return v.fromP1xP1(result) -} - -// Subtract sets v = p - q, and returns v. -func (v *Point) Subtract(p, q *Point) *Point { - checkInitialized(p, q) - qCached := new(projCached).FromP3(q) - result := new(projP1xP1).Sub(p, qCached) - return v.fromP1xP1(result) -} - -func (v *projP1xP1) Add(p *Point, q *projCached) *projP1xP1 { - var YplusX, YminusX, PP, MM, TT2d, ZZ2 field.Element - - YplusX.Add(&p.y, &p.x) - YminusX.Subtract(&p.y, &p.x) - - PP.Multiply(&YplusX, &q.YplusX) - MM.Multiply(&YminusX, &q.YminusX) - TT2d.Multiply(&p.t, &q.T2d) - ZZ2.Multiply(&p.z, &q.Z) - - ZZ2.Add(&ZZ2, &ZZ2) - - v.X.Subtract(&PP, &MM) - v.Y.Add(&PP, &MM) - v.Z.Add(&ZZ2, &TT2d) - v.T.Subtract(&ZZ2, &TT2d) - return v -} - -func (v *projP1xP1) Sub(p *Point, q *projCached) *projP1xP1 { - var YplusX, YminusX, PP, MM, TT2d, ZZ2 field.Element - - YplusX.Add(&p.y, &p.x) - YminusX.Subtract(&p.y, &p.x) - - PP.Multiply(&YplusX, &q.YminusX) // flipped sign - MM.Multiply(&YminusX, &q.YplusX) // flipped sign - TT2d.Multiply(&p.t, &q.T2d) - ZZ2.Multiply(&p.z, &q.Z) - - ZZ2.Add(&ZZ2, &ZZ2) - - v.X.Subtract(&PP, &MM) - v.Y.Add(&PP, &MM) - v.Z.Subtract(&ZZ2, &TT2d) // flipped sign - v.T.Add(&ZZ2, &TT2d) // flipped sign - return v -} - -func (v *projP1xP1) AddAffine(p *Point, q *affineCached) *projP1xP1 { - var YplusX, YminusX, PP, MM, TT2d, Z2 field.Element - - YplusX.Add(&p.y, &p.x) - YminusX.Subtract(&p.y, &p.x) - - PP.Multiply(&YplusX, &q.YplusX) - MM.Multiply(&YminusX, &q.YminusX) - TT2d.Multiply(&p.t, &q.T2d) - - Z2.Add(&p.z, &p.z) - - v.X.Subtract(&PP, &MM) - v.Y.Add(&PP, &MM) - v.Z.Add(&Z2, &TT2d) - v.T.Subtract(&Z2, &TT2d) - return v -} - -func (v *projP1xP1) SubAffine(p *Point, q *affineCached) *projP1xP1 { - var YplusX, YminusX, PP, MM, TT2d, Z2 field.Element - - YplusX.Add(&p.y, &p.x) - YminusX.Subtract(&p.y, &p.x) - - PP.Multiply(&YplusX, &q.YminusX) // flipped sign - MM.Multiply(&YminusX, &q.YplusX) // flipped sign - TT2d.Multiply(&p.t, &q.T2d) - - Z2.Add(&p.z, &p.z) - - v.X.Subtract(&PP, &MM) - v.Y.Add(&PP, &MM) - v.Z.Subtract(&Z2, &TT2d) // flipped sign - v.T.Add(&Z2, &TT2d) // flipped sign - return v -} - -// Doubling. - -func (v *projP1xP1) Double(p *projP2) *projP1xP1 { - var XX, YY, ZZ2, XplusYsq field.Element - - XX.Square(&p.X) - YY.Square(&p.Y) - ZZ2.Square(&p.Z) - ZZ2.Add(&ZZ2, &ZZ2) - XplusYsq.Add(&p.X, &p.Y) - XplusYsq.Square(&XplusYsq) - - v.Y.Add(&YY, &XX) - v.Z.Subtract(&YY, &XX) - - v.X.Subtract(&XplusYsq, &v.Y) - v.T.Subtract(&ZZ2, &v.Z) - return v -} - -// Negation. - -// Negate sets v = -p, and returns v. -func (v *Point) Negate(p *Point) *Point { - checkInitialized(p) - v.x.Negate(&p.x) - v.y.Set(&p.y) - v.z.Set(&p.z) - v.t.Negate(&p.t) - return v -} - -// Equal returns 1 if v is equivalent to u, and 0 otherwise. -func (v *Point) Equal(u *Point) int { - checkInitialized(v, u) - - var t1, t2, t3, t4 field.Element - t1.Multiply(&v.x, &u.z) - t2.Multiply(&u.x, &v.z) - t3.Multiply(&v.y, &u.z) - t4.Multiply(&u.y, &v.z) - - return t1.Equal(&t2) & t3.Equal(&t4) -} - -// Constant-time operations - -// Select sets v to a if cond == 1 and to b if cond == 0. -func (v *projCached) Select(a, b *projCached, cond int) *projCached { - v.YplusX.Select(&a.YplusX, &b.YplusX, cond) - v.YminusX.Select(&a.YminusX, &b.YminusX, cond) - v.Z.Select(&a.Z, &b.Z, cond) - v.T2d.Select(&a.T2d, &b.T2d, cond) - return v -} - -// Select sets v to a if cond == 1 and to b if cond == 0. -func (v *affineCached) Select(a, b *affineCached, cond int) *affineCached { - v.YplusX.Select(&a.YplusX, &b.YplusX, cond) - v.YminusX.Select(&a.YminusX, &b.YminusX, cond) - v.T2d.Select(&a.T2d, &b.T2d, cond) - return v -} - -// CondNeg negates v if cond == 1 and leaves it unchanged if cond == 0. -func (v *projCached) CondNeg(cond int) *projCached { - v.YplusX.Swap(&v.YminusX, cond) - v.T2d.Select(new(field.Element).Negate(&v.T2d), &v.T2d, cond) - return v -} - -// CondNeg negates v if cond == 1 and leaves it unchanged if cond == 0. -func (v *affineCached) CondNeg(cond int) *affineCached { - v.YplusX.Swap(&v.YminusX, cond) - v.T2d.Select(new(field.Element).Negate(&v.T2d), &v.T2d, cond) - return v -} diff --git a/v2/vendor/filippo.io/edwards25519/extra.go b/v2/vendor/filippo.io/edwards25519/extra.go deleted file mode 100644 index d152d68..0000000 --- a/v2/vendor/filippo.io/edwards25519/extra.go +++ /dev/null @@ -1,349 +0,0 @@ -// Copyright (c) 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package edwards25519 - -// This file contains additional functionality that is not included in the -// upstream crypto/internal/edwards25519 package. - -import ( - "errors" - - "filippo.io/edwards25519/field" -) - -// ExtendedCoordinates returns v in extended coordinates (X:Y:Z:T) where -// x = X/Z, y = Y/Z, and xy = T/Z as in https://eprint.iacr.org/2008/522. -func (v *Point) ExtendedCoordinates() (X, Y, Z, T *field.Element) { - // This function is outlined to make the allocations inline in the caller - // rather than happen on the heap. Don't change the style without making - // sure it doesn't increase the inliner cost. - var e [4]field.Element - X, Y, Z, T = v.extendedCoordinates(&e) - return -} - -func (v *Point) extendedCoordinates(e *[4]field.Element) (X, Y, Z, T *field.Element) { - checkInitialized(v) - X = e[0].Set(&v.x) - Y = e[1].Set(&v.y) - Z = e[2].Set(&v.z) - T = e[3].Set(&v.t) - return -} - -// SetExtendedCoordinates sets v = (X:Y:Z:T) in extended coordinates where -// x = X/Z, y = Y/Z, and xy = T/Z as in https://eprint.iacr.org/2008/522. -// -// If the coordinates are invalid or don't represent a valid point on the curve, -// SetExtendedCoordinates returns nil and an error and the receiver is -// unchanged. Otherwise, SetExtendedCoordinates returns v. -func (v *Point) SetExtendedCoordinates(X, Y, Z, T *field.Element) (*Point, error) { - if !isOnCurve(X, Y, Z, T) { - return nil, errors.New("edwards25519: invalid point coordinates") - } - v.x.Set(X) - v.y.Set(Y) - v.z.Set(Z) - v.t.Set(T) - return v, nil -} - -func isOnCurve(X, Y, Z, T *field.Element) bool { - var lhs, rhs field.Element - XX := new(field.Element).Square(X) - YY := new(field.Element).Square(Y) - ZZ := new(field.Element).Square(Z) - TT := new(field.Element).Square(T) - // -x² + y² = 1 + dx²y² - // -(X/Z)² + (Y/Z)² = 1 + d(T/Z)² - // -X² + Y² = Z² + dT² - lhs.Subtract(YY, XX) - rhs.Multiply(d, TT).Add(&rhs, ZZ) - if lhs.Equal(&rhs) != 1 { - return false - } - // xy = T/Z - // XY/Z² = T/Z - // XY = TZ - lhs.Multiply(X, Y) - rhs.Multiply(T, Z) - return lhs.Equal(&rhs) == 1 -} - -// BytesMontgomery converts v to a point on the birationally-equivalent -// Curve25519 Montgomery curve, and returns its canonical 32 bytes encoding -// according to RFC 7748. -// -// Note that BytesMontgomery only encodes the u-coordinate, so v and -v encode -// to the same value. If v is the identity point, BytesMontgomery returns 32 -// zero bytes, analogously to the X25519 function. -// -// The lack of an inverse operation (such as SetMontgomeryBytes) is deliberate: -// while every valid edwards25519 point has a unique u-coordinate Montgomery -// encoding, X25519 accepts inputs on the quadratic twist, which don't correspond -// to any edwards25519 point, and every other X25519 input corresponds to two -// edwards25519 points. -func (v *Point) BytesMontgomery() []byte { - // This function is outlined to make the allocations inline in the caller - // rather than happen on the heap. - var buf [32]byte - return v.bytesMontgomery(&buf) -} - -func (v *Point) bytesMontgomery(buf *[32]byte) []byte { - checkInitialized(v) - - // RFC 7748, Section 4.1 provides the bilinear map to calculate the - // Montgomery u-coordinate - // - // u = (1 + y) / (1 - y) - // - // where y = Y / Z. - - var y, recip, u field.Element - - y.Multiply(&v.y, y.Invert(&v.z)) // y = Y / Z - recip.Invert(recip.Subtract(feOne, &y)) // r = 1/(1 - y) - u.Multiply(u.Add(feOne, &y), &recip) // u = (1 + y)*r - - return copyFieldElement(buf, &u) -} - -// MultByCofactor sets v = 8 * p, and returns v. -func (v *Point) MultByCofactor(p *Point) *Point { - checkInitialized(p) - result := projP1xP1{} - pp := (&projP2{}).FromP3(p) - result.Double(pp) - pp.FromP1xP1(&result) - result.Double(pp) - pp.FromP1xP1(&result) - result.Double(pp) - return v.fromP1xP1(&result) -} - -// Given k > 0, set s = s**(2*i). -func (s *Scalar) pow2k(k int) { - for i := 0; i < k; i++ { - s.Multiply(s, s) - } -} - -// Invert sets s to the inverse of a nonzero scalar v, and returns s. -// -// If t is zero, Invert returns zero. -func (s *Scalar) Invert(t *Scalar) *Scalar { - // Uses a hardcoded sliding window of width 4. - var table [8]Scalar - var tt Scalar - tt.Multiply(t, t) - table[0] = *t - for i := 0; i < 7; i++ { - table[i+1].Multiply(&table[i], &tt) - } - // Now table = [t**1, t**3, t**5, t**7, t**9, t**11, t**13, t**15] - // so t**k = t[k/2] for odd k - - // To compute the sliding window digits, use the following Sage script: - - // sage: import itertools - // sage: def sliding_window(w,k): - // ....: digits = [] - // ....: while k > 0: - // ....: if k % 2 == 1: - // ....: kmod = k % (2**w) - // ....: digits.append(kmod) - // ....: k = k - kmod - // ....: else: - // ....: digits.append(0) - // ....: k = k // 2 - // ....: return digits - - // Now we can compute s roughly as follows: - - // sage: s = 1 - // sage: for coeff in reversed(sliding_window(4,l-2)): - // ....: s = s*s - // ....: if coeff > 0 : - // ....: s = s*t**coeff - - // This works on one bit at a time, with many runs of zeros. - // The digits can be collapsed into [(count, coeff)] as follows: - - // sage: [(len(list(group)),d) for d,group in itertools.groupby(sliding_window(4,l-2))] - - // Entries of the form (k, 0) turn into pow2k(k) - // Entries of the form (1, coeff) turn into a squaring and then a table lookup. - // We can fold the squaring into the previous pow2k(k) as pow2k(k+1). - - *s = table[1/2] - s.pow2k(127 + 1) - s.Multiply(s, &table[1/2]) - s.pow2k(4 + 1) - s.Multiply(s, &table[9/2]) - s.pow2k(3 + 1) - s.Multiply(s, &table[11/2]) - s.pow2k(3 + 1) - s.Multiply(s, &table[13/2]) - s.pow2k(3 + 1) - s.Multiply(s, &table[15/2]) - s.pow2k(4 + 1) - s.Multiply(s, &table[7/2]) - s.pow2k(4 + 1) - s.Multiply(s, &table[15/2]) - s.pow2k(3 + 1) - s.Multiply(s, &table[5/2]) - s.pow2k(3 + 1) - s.Multiply(s, &table[1/2]) - s.pow2k(4 + 1) - s.Multiply(s, &table[15/2]) - s.pow2k(4 + 1) - s.Multiply(s, &table[15/2]) - s.pow2k(4 + 1) - s.Multiply(s, &table[7/2]) - s.pow2k(3 + 1) - s.Multiply(s, &table[3/2]) - s.pow2k(4 + 1) - s.Multiply(s, &table[11/2]) - s.pow2k(5 + 1) - s.Multiply(s, &table[11/2]) - s.pow2k(9 + 1) - s.Multiply(s, &table[9/2]) - s.pow2k(3 + 1) - s.Multiply(s, &table[3/2]) - s.pow2k(4 + 1) - s.Multiply(s, &table[3/2]) - s.pow2k(4 + 1) - s.Multiply(s, &table[3/2]) - s.pow2k(4 + 1) - s.Multiply(s, &table[9/2]) - s.pow2k(3 + 1) - s.Multiply(s, &table[7/2]) - s.pow2k(3 + 1) - s.Multiply(s, &table[3/2]) - s.pow2k(3 + 1) - s.Multiply(s, &table[13/2]) - s.pow2k(3 + 1) - s.Multiply(s, &table[7/2]) - s.pow2k(4 + 1) - s.Multiply(s, &table[9/2]) - s.pow2k(3 + 1) - s.Multiply(s, &table[15/2]) - s.pow2k(4 + 1) - s.Multiply(s, &table[11/2]) - - return s -} - -// MultiScalarMult sets v = sum(scalars[i] * points[i]), and returns v. -// -// Execution time depends only on the lengths of the two slices, which must match. -func (v *Point) MultiScalarMult(scalars []*Scalar, points []*Point) *Point { - if len(scalars) != len(points) { - panic("edwards25519: called MultiScalarMult with different size inputs") - } - checkInitialized(points...) - - // Proceed as in the single-base case, but share doublings - // between each point in the multiscalar equation. - - // Build lookup tables for each point - tables := make([]projLookupTable, len(points)) - for i := range tables { - tables[i].FromP3(points[i]) - } - // Compute signed radix-16 digits for each scalar - digits := make([][64]int8, len(scalars)) - for i := range digits { - digits[i] = scalars[i].signedRadix16() - } - - // Unwrap first loop iteration to save computing 16*identity - multiple := &projCached{} - tmp1 := &projP1xP1{} - tmp2 := &projP2{} - // Lookup-and-add the appropriate multiple of each input point - for j := range tables { - tables[j].SelectInto(multiple, digits[j][63]) - tmp1.Add(v, multiple) // tmp1 = v + x_(j,63)*Q in P1xP1 coords - v.fromP1xP1(tmp1) // update v - } - tmp2.FromP3(v) // set up tmp2 = v in P2 coords for next iteration - for i := 62; i >= 0; i-- { - tmp1.Double(tmp2) // tmp1 = 2*(prev) in P1xP1 coords - tmp2.FromP1xP1(tmp1) // tmp2 = 2*(prev) in P2 coords - tmp1.Double(tmp2) // tmp1 = 4*(prev) in P1xP1 coords - tmp2.FromP1xP1(tmp1) // tmp2 = 4*(prev) in P2 coords - tmp1.Double(tmp2) // tmp1 = 8*(prev) in P1xP1 coords - tmp2.FromP1xP1(tmp1) // tmp2 = 8*(prev) in P2 coords - tmp1.Double(tmp2) // tmp1 = 16*(prev) in P1xP1 coords - v.fromP1xP1(tmp1) // v = 16*(prev) in P3 coords - // Lookup-and-add the appropriate multiple of each input point - for j := range tables { - tables[j].SelectInto(multiple, digits[j][i]) - tmp1.Add(v, multiple) // tmp1 = v + x_(j,i)*Q in P1xP1 coords - v.fromP1xP1(tmp1) // update v - } - tmp2.FromP3(v) // set up tmp2 = v in P2 coords for next iteration - } - return v -} - -// VarTimeMultiScalarMult sets v = sum(scalars[i] * points[i]), and returns v. -// -// Execution time depends on the inputs. -func (v *Point) VarTimeMultiScalarMult(scalars []*Scalar, points []*Point) *Point { - if len(scalars) != len(points) { - panic("edwards25519: called VarTimeMultiScalarMult with different size inputs") - } - checkInitialized(points...) - - // Generalize double-base NAF computation to arbitrary sizes. - // Here all the points are dynamic, so we only use the smaller - // tables. - - // Build lookup tables for each point - tables := make([]nafLookupTable5, len(points)) - for i := range tables { - tables[i].FromP3(points[i]) - } - // Compute a NAF for each scalar - nafs := make([][256]int8, len(scalars)) - for i := range nafs { - nafs[i] = scalars[i].nonAdjacentForm(5) - } - - multiple := &projCached{} - tmp1 := &projP1xP1{} - tmp2 := &projP2{} - tmp2.Zero() - - // Move from high to low bits, doubling the accumulator - // at each iteration and checking whether there is a nonzero - // coefficient to look up a multiple of. - // - // Skip trying to find the first nonzero coefficent, because - // searching might be more work than a few extra doublings. - for i := 255; i >= 0; i-- { - tmp1.Double(tmp2) - - for j := range nafs { - if nafs[j][i] > 0 { - v.fromP1xP1(tmp1) - tables[j].SelectInto(multiple, nafs[j][i]) - tmp1.Add(v, multiple) - } else if nafs[j][i] < 0 { - v.fromP1xP1(tmp1) - tables[j].SelectInto(multiple, -nafs[j][i]) - tmp1.Sub(v, multiple) - } - } - - tmp2.FromP1xP1(tmp1) - } - - v.fromP2(tmp2) - return v -} diff --git a/v2/vendor/filippo.io/edwards25519/field/fe.go b/v2/vendor/filippo.io/edwards25519/field/fe.go deleted file mode 100644 index 5518ef2..0000000 --- a/v2/vendor/filippo.io/edwards25519/field/fe.go +++ /dev/null @@ -1,420 +0,0 @@ -// Copyright (c) 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package field implements fast arithmetic modulo 2^255-19. -package field - -import ( - "crypto/subtle" - "encoding/binary" - "errors" - "math/bits" -) - -// Element represents an element of the field GF(2^255-19). Note that this -// is not a cryptographically secure group, and should only be used to interact -// with edwards25519.Point coordinates. -// -// This type works similarly to math/big.Int, and all arguments and receivers -// are allowed to alias. -// -// The zero value is a valid zero element. -type Element struct { - // An element t represents the integer - // t.l0 + t.l1*2^51 + t.l2*2^102 + t.l3*2^153 + t.l4*2^204 - // - // Between operations, all limbs are expected to be lower than 2^52. - l0 uint64 - l1 uint64 - l2 uint64 - l3 uint64 - l4 uint64 -} - -const maskLow51Bits uint64 = (1 << 51) - 1 - -var feZero = &Element{0, 0, 0, 0, 0} - -// Zero sets v = 0, and returns v. -func (v *Element) Zero() *Element { - *v = *feZero - return v -} - -var feOne = &Element{1, 0, 0, 0, 0} - -// One sets v = 1, and returns v. -func (v *Element) One() *Element { - *v = *feOne - return v -} - -// reduce reduces v modulo 2^255 - 19 and returns it. -func (v *Element) reduce() *Element { - v.carryPropagate() - - // After the light reduction we now have a field element representation - // v < 2^255 + 2^13 * 19, but need v < 2^255 - 19. - - // If v >= 2^255 - 19, then v + 19 >= 2^255, which would overflow 2^255 - 1, - // generating a carry. That is, c will be 0 if v < 2^255 - 19, and 1 otherwise. - c := (v.l0 + 19) >> 51 - c = (v.l1 + c) >> 51 - c = (v.l2 + c) >> 51 - c = (v.l3 + c) >> 51 - c = (v.l4 + c) >> 51 - - // If v < 2^255 - 19 and c = 0, this will be a no-op. Otherwise, it's - // effectively applying the reduction identity to the carry. - v.l0 += 19 * c - - v.l1 += v.l0 >> 51 - v.l0 = v.l0 & maskLow51Bits - v.l2 += v.l1 >> 51 - v.l1 = v.l1 & maskLow51Bits - v.l3 += v.l2 >> 51 - v.l2 = v.l2 & maskLow51Bits - v.l4 += v.l3 >> 51 - v.l3 = v.l3 & maskLow51Bits - // no additional carry - v.l4 = v.l4 & maskLow51Bits - - return v -} - -// Add sets v = a + b, and returns v. -func (v *Element) Add(a, b *Element) *Element { - v.l0 = a.l0 + b.l0 - v.l1 = a.l1 + b.l1 - v.l2 = a.l2 + b.l2 - v.l3 = a.l3 + b.l3 - v.l4 = a.l4 + b.l4 - // Using the generic implementation here is actually faster than the - // assembly. Probably because the body of this function is so simple that - // the compiler can figure out better optimizations by inlining the carry - // propagation. - return v.carryPropagateGeneric() -} - -// Subtract sets v = a - b, and returns v. -func (v *Element) Subtract(a, b *Element) *Element { - // We first add 2 * p, to guarantee the subtraction won't underflow, and - // then subtract b (which can be up to 2^255 + 2^13 * 19). - v.l0 = (a.l0 + 0xFFFFFFFFFFFDA) - b.l0 - v.l1 = (a.l1 + 0xFFFFFFFFFFFFE) - b.l1 - v.l2 = (a.l2 + 0xFFFFFFFFFFFFE) - b.l2 - v.l3 = (a.l3 + 0xFFFFFFFFFFFFE) - b.l3 - v.l4 = (a.l4 + 0xFFFFFFFFFFFFE) - b.l4 - return v.carryPropagate() -} - -// Negate sets v = -a, and returns v. -func (v *Element) Negate(a *Element) *Element { - return v.Subtract(feZero, a) -} - -// Invert sets v = 1/z mod p, and returns v. -// -// If z == 0, Invert returns v = 0. -func (v *Element) Invert(z *Element) *Element { - // Inversion is implemented as exponentiation with exponent p − 2. It uses the - // same sequence of 255 squarings and 11 multiplications as [Curve25519]. - var z2, z9, z11, z2_5_0, z2_10_0, z2_20_0, z2_50_0, z2_100_0, t Element - - z2.Square(z) // 2 - t.Square(&z2) // 4 - t.Square(&t) // 8 - z9.Multiply(&t, z) // 9 - z11.Multiply(&z9, &z2) // 11 - t.Square(&z11) // 22 - z2_5_0.Multiply(&t, &z9) // 31 = 2^5 - 2^0 - - t.Square(&z2_5_0) // 2^6 - 2^1 - for i := 0; i < 4; i++ { - t.Square(&t) // 2^10 - 2^5 - } - z2_10_0.Multiply(&t, &z2_5_0) // 2^10 - 2^0 - - t.Square(&z2_10_0) // 2^11 - 2^1 - for i := 0; i < 9; i++ { - t.Square(&t) // 2^20 - 2^10 - } - z2_20_0.Multiply(&t, &z2_10_0) // 2^20 - 2^0 - - t.Square(&z2_20_0) // 2^21 - 2^1 - for i := 0; i < 19; i++ { - t.Square(&t) // 2^40 - 2^20 - } - t.Multiply(&t, &z2_20_0) // 2^40 - 2^0 - - t.Square(&t) // 2^41 - 2^1 - for i := 0; i < 9; i++ { - t.Square(&t) // 2^50 - 2^10 - } - z2_50_0.Multiply(&t, &z2_10_0) // 2^50 - 2^0 - - t.Square(&z2_50_0) // 2^51 - 2^1 - for i := 0; i < 49; i++ { - t.Square(&t) // 2^100 - 2^50 - } - z2_100_0.Multiply(&t, &z2_50_0) // 2^100 - 2^0 - - t.Square(&z2_100_0) // 2^101 - 2^1 - for i := 0; i < 99; i++ { - t.Square(&t) // 2^200 - 2^100 - } - t.Multiply(&t, &z2_100_0) // 2^200 - 2^0 - - t.Square(&t) // 2^201 - 2^1 - for i := 0; i < 49; i++ { - t.Square(&t) // 2^250 - 2^50 - } - t.Multiply(&t, &z2_50_0) // 2^250 - 2^0 - - t.Square(&t) // 2^251 - 2^1 - t.Square(&t) // 2^252 - 2^2 - t.Square(&t) // 2^253 - 2^3 - t.Square(&t) // 2^254 - 2^4 - t.Square(&t) // 2^255 - 2^5 - - return v.Multiply(&t, &z11) // 2^255 - 21 -} - -// Set sets v = a, and returns v. -func (v *Element) Set(a *Element) *Element { - *v = *a - return v -} - -// SetBytes sets v to x, where x is a 32-byte little-endian encoding. If x is -// not of the right length, SetBytes returns nil and an error, and the -// receiver is unchanged. -// -// Consistent with RFC 7748, the most significant bit (the high bit of the -// last byte) is ignored, and non-canonical values (2^255-19 through 2^255-1) -// are accepted. Note that this is laxer than specified by RFC 8032, but -// consistent with most Ed25519 implementations. -func (v *Element) SetBytes(x []byte) (*Element, error) { - if len(x) != 32 { - return nil, errors.New("edwards25519: invalid field element input size") - } - - // Bits 0:51 (bytes 0:8, bits 0:64, shift 0, mask 51). - v.l0 = binary.LittleEndian.Uint64(x[0:8]) - v.l0 &= maskLow51Bits - // Bits 51:102 (bytes 6:14, bits 48:112, shift 3, mask 51). - v.l1 = binary.LittleEndian.Uint64(x[6:14]) >> 3 - v.l1 &= maskLow51Bits - // Bits 102:153 (bytes 12:20, bits 96:160, shift 6, mask 51). - v.l2 = binary.LittleEndian.Uint64(x[12:20]) >> 6 - v.l2 &= maskLow51Bits - // Bits 153:204 (bytes 19:27, bits 152:216, shift 1, mask 51). - v.l3 = binary.LittleEndian.Uint64(x[19:27]) >> 1 - v.l3 &= maskLow51Bits - // Bits 204:255 (bytes 24:32, bits 192:256, shift 12, mask 51). - // Note: not bytes 25:33, shift 4, to avoid overread. - v.l4 = binary.LittleEndian.Uint64(x[24:32]) >> 12 - v.l4 &= maskLow51Bits - - return v, nil -} - -// Bytes returns the canonical 32-byte little-endian encoding of v. -func (v *Element) Bytes() []byte { - // This function is outlined to make the allocations inline in the caller - // rather than happen on the heap. - var out [32]byte - return v.bytes(&out) -} - -func (v *Element) bytes(out *[32]byte) []byte { - t := *v - t.reduce() - - var buf [8]byte - for i, l := range [5]uint64{t.l0, t.l1, t.l2, t.l3, t.l4} { - bitsOffset := i * 51 - binary.LittleEndian.PutUint64(buf[:], l<= len(out) { - break - } - out[off] |= bb - } - } - - return out[:] -} - -// Equal returns 1 if v and u are equal, and 0 otherwise. -func (v *Element) Equal(u *Element) int { - sa, sv := u.Bytes(), v.Bytes() - return subtle.ConstantTimeCompare(sa, sv) -} - -// mask64Bits returns 0xffffffff if cond is 1, and 0 otherwise. -func mask64Bits(cond int) uint64 { return ^(uint64(cond) - 1) } - -// Select sets v to a if cond == 1, and to b if cond == 0. -func (v *Element) Select(a, b *Element, cond int) *Element { - m := mask64Bits(cond) - v.l0 = (m & a.l0) | (^m & b.l0) - v.l1 = (m & a.l1) | (^m & b.l1) - v.l2 = (m & a.l2) | (^m & b.l2) - v.l3 = (m & a.l3) | (^m & b.l3) - v.l4 = (m & a.l4) | (^m & b.l4) - return v -} - -// Swap swaps v and u if cond == 1 or leaves them unchanged if cond == 0, and returns v. -func (v *Element) Swap(u *Element, cond int) { - m := mask64Bits(cond) - t := m & (v.l0 ^ u.l0) - v.l0 ^= t - u.l0 ^= t - t = m & (v.l1 ^ u.l1) - v.l1 ^= t - u.l1 ^= t - t = m & (v.l2 ^ u.l2) - v.l2 ^= t - u.l2 ^= t - t = m & (v.l3 ^ u.l3) - v.l3 ^= t - u.l3 ^= t - t = m & (v.l4 ^ u.l4) - v.l4 ^= t - u.l4 ^= t -} - -// IsNegative returns 1 if v is negative, and 0 otherwise. -func (v *Element) IsNegative() int { - return int(v.Bytes()[0] & 1) -} - -// Absolute sets v to |u|, and returns v. -func (v *Element) Absolute(u *Element) *Element { - return v.Select(new(Element).Negate(u), u, u.IsNegative()) -} - -// Multiply sets v = x * y, and returns v. -func (v *Element) Multiply(x, y *Element) *Element { - feMul(v, x, y) - return v -} - -// Square sets v = x * x, and returns v. -func (v *Element) Square(x *Element) *Element { - feSquare(v, x) - return v -} - -// Mult32 sets v = x * y, and returns v. -func (v *Element) Mult32(x *Element, y uint32) *Element { - x0lo, x0hi := mul51(x.l0, y) - x1lo, x1hi := mul51(x.l1, y) - x2lo, x2hi := mul51(x.l2, y) - x3lo, x3hi := mul51(x.l3, y) - x4lo, x4hi := mul51(x.l4, y) - v.l0 = x0lo + 19*x4hi // carried over per the reduction identity - v.l1 = x1lo + x0hi - v.l2 = x2lo + x1hi - v.l3 = x3lo + x2hi - v.l4 = x4lo + x3hi - // The hi portions are going to be only 32 bits, plus any previous excess, - // so we can skip the carry propagation. - return v -} - -// mul51 returns lo + hi * 2⁵¹ = a * b. -func mul51(a uint64, b uint32) (lo uint64, hi uint64) { - mh, ml := bits.Mul64(a, uint64(b)) - lo = ml & maskLow51Bits - hi = (mh << 13) | (ml >> 51) - return -} - -// Pow22523 set v = x^((p-5)/8), and returns v. (p-5)/8 is 2^252-3. -func (v *Element) Pow22523(x *Element) *Element { - var t0, t1, t2 Element - - t0.Square(x) // x^2 - t1.Square(&t0) // x^4 - t1.Square(&t1) // x^8 - t1.Multiply(x, &t1) // x^9 - t0.Multiply(&t0, &t1) // x^11 - t0.Square(&t0) // x^22 - t0.Multiply(&t1, &t0) // x^31 - t1.Square(&t0) // x^62 - for i := 1; i < 5; i++ { // x^992 - t1.Square(&t1) - } - t0.Multiply(&t1, &t0) // x^1023 -> 1023 = 2^10 - 1 - t1.Square(&t0) // 2^11 - 2 - for i := 1; i < 10; i++ { // 2^20 - 2^10 - t1.Square(&t1) - } - t1.Multiply(&t1, &t0) // 2^20 - 1 - t2.Square(&t1) // 2^21 - 2 - for i := 1; i < 20; i++ { // 2^40 - 2^20 - t2.Square(&t2) - } - t1.Multiply(&t2, &t1) // 2^40 - 1 - t1.Square(&t1) // 2^41 - 2 - for i := 1; i < 10; i++ { // 2^50 - 2^10 - t1.Square(&t1) - } - t0.Multiply(&t1, &t0) // 2^50 - 1 - t1.Square(&t0) // 2^51 - 2 - for i := 1; i < 50; i++ { // 2^100 - 2^50 - t1.Square(&t1) - } - t1.Multiply(&t1, &t0) // 2^100 - 1 - t2.Square(&t1) // 2^101 - 2 - for i := 1; i < 100; i++ { // 2^200 - 2^100 - t2.Square(&t2) - } - t1.Multiply(&t2, &t1) // 2^200 - 1 - t1.Square(&t1) // 2^201 - 2 - for i := 1; i < 50; i++ { // 2^250 - 2^50 - t1.Square(&t1) - } - t0.Multiply(&t1, &t0) // 2^250 - 1 - t0.Square(&t0) // 2^251 - 2 - t0.Square(&t0) // 2^252 - 4 - return v.Multiply(&t0, x) // 2^252 - 3 -> x^(2^252-3) -} - -// sqrtM1 is 2^((p-1)/4), which squared is equal to -1 by Euler's Criterion. -var sqrtM1 = &Element{1718705420411056, 234908883556509, - 2233514472574048, 2117202627021982, 765476049583133} - -// SqrtRatio sets r to the non-negative square root of the ratio of u and v. -// -// If u/v is square, SqrtRatio returns r and 1. If u/v is not square, SqrtRatio -// sets r according to Section 4.3 of draft-irtf-cfrg-ristretto255-decaf448-00, -// and returns r and 0. -func (r *Element) SqrtRatio(u, v *Element) (R *Element, wasSquare int) { - t0 := new(Element) - - // r = (u * v3) * (u * v7)^((p-5)/8) - v2 := new(Element).Square(v) - uv3 := new(Element).Multiply(u, t0.Multiply(v2, v)) - uv7 := new(Element).Multiply(uv3, t0.Square(v2)) - rr := new(Element).Multiply(uv3, t0.Pow22523(uv7)) - - check := new(Element).Multiply(v, t0.Square(rr)) // check = v * r^2 - - uNeg := new(Element).Negate(u) - correctSignSqrt := check.Equal(u) - flippedSignSqrt := check.Equal(uNeg) - flippedSignSqrtI := check.Equal(t0.Multiply(uNeg, sqrtM1)) - - rPrime := new(Element).Multiply(rr, sqrtM1) // r_prime = SQRT_M1 * r - // r = CT_SELECT(r_prime IF flipped_sign_sqrt | flipped_sign_sqrt_i ELSE r) - rr.Select(rPrime, rr, flippedSignSqrt|flippedSignSqrtI) - - r.Absolute(rr) // Choose the nonnegative square root. - return r, correctSignSqrt | flippedSignSqrt -} diff --git a/v2/vendor/filippo.io/edwards25519/field/fe_amd64.go b/v2/vendor/filippo.io/edwards25519/field/fe_amd64.go deleted file mode 100644 index edcf163..0000000 --- a/v2/vendor/filippo.io/edwards25519/field/fe_amd64.go +++ /dev/null @@ -1,16 +0,0 @@ -// Code generated by command: go run fe_amd64_asm.go -out ../fe_amd64.s -stubs ../fe_amd64.go -pkg field. DO NOT EDIT. - -//go:build amd64 && gc && !purego -// +build amd64,gc,!purego - -package field - -// feMul sets out = a * b. It works like feMulGeneric. -// -//go:noescape -func feMul(out *Element, a *Element, b *Element) - -// feSquare sets out = a * a. It works like feSquareGeneric. -// -//go:noescape -func feSquare(out *Element, a *Element) diff --git a/v2/vendor/filippo.io/edwards25519/field/fe_amd64.s b/v2/vendor/filippo.io/edwards25519/field/fe_amd64.s deleted file mode 100644 index 293f013..0000000 --- a/v2/vendor/filippo.io/edwards25519/field/fe_amd64.s +++ /dev/null @@ -1,379 +0,0 @@ -// Code generated by command: go run fe_amd64_asm.go -out ../fe_amd64.s -stubs ../fe_amd64.go -pkg field. DO NOT EDIT. - -//go:build amd64 && gc && !purego -// +build amd64,gc,!purego - -#include "textflag.h" - -// func feMul(out *Element, a *Element, b *Element) -TEXT ·feMul(SB), NOSPLIT, $0-24 - MOVQ a+8(FP), CX - MOVQ b+16(FP), BX - - // r0 = a0×b0 - MOVQ (CX), AX - MULQ (BX) - MOVQ AX, DI - MOVQ DX, SI - - // r0 += 19×a1×b4 - MOVQ 8(CX), AX - IMUL3Q $0x13, AX, AX - MULQ 32(BX) - ADDQ AX, DI - ADCQ DX, SI - - // r0 += 19×a2×b3 - MOVQ 16(CX), AX - IMUL3Q $0x13, AX, AX - MULQ 24(BX) - ADDQ AX, DI - ADCQ DX, SI - - // r0 += 19×a3×b2 - MOVQ 24(CX), AX - IMUL3Q $0x13, AX, AX - MULQ 16(BX) - ADDQ AX, DI - ADCQ DX, SI - - // r0 += 19×a4×b1 - MOVQ 32(CX), AX - IMUL3Q $0x13, AX, AX - MULQ 8(BX) - ADDQ AX, DI - ADCQ DX, SI - - // r1 = a0×b1 - MOVQ (CX), AX - MULQ 8(BX) - MOVQ AX, R9 - MOVQ DX, R8 - - // r1 += a1×b0 - MOVQ 8(CX), AX - MULQ (BX) - ADDQ AX, R9 - ADCQ DX, R8 - - // r1 += 19×a2×b4 - MOVQ 16(CX), AX - IMUL3Q $0x13, AX, AX - MULQ 32(BX) - ADDQ AX, R9 - ADCQ DX, R8 - - // r1 += 19×a3×b3 - MOVQ 24(CX), AX - IMUL3Q $0x13, AX, AX - MULQ 24(BX) - ADDQ AX, R9 - ADCQ DX, R8 - - // r1 += 19×a4×b2 - MOVQ 32(CX), AX - IMUL3Q $0x13, AX, AX - MULQ 16(BX) - ADDQ AX, R9 - ADCQ DX, R8 - - // r2 = a0×b2 - MOVQ (CX), AX - MULQ 16(BX) - MOVQ AX, R11 - MOVQ DX, R10 - - // r2 += a1×b1 - MOVQ 8(CX), AX - MULQ 8(BX) - ADDQ AX, R11 - ADCQ DX, R10 - - // r2 += a2×b0 - MOVQ 16(CX), AX - MULQ (BX) - ADDQ AX, R11 - ADCQ DX, R10 - - // r2 += 19×a3×b4 - MOVQ 24(CX), AX - IMUL3Q $0x13, AX, AX - MULQ 32(BX) - ADDQ AX, R11 - ADCQ DX, R10 - - // r2 += 19×a4×b3 - MOVQ 32(CX), AX - IMUL3Q $0x13, AX, AX - MULQ 24(BX) - ADDQ AX, R11 - ADCQ DX, R10 - - // r3 = a0×b3 - MOVQ (CX), AX - MULQ 24(BX) - MOVQ AX, R13 - MOVQ DX, R12 - - // r3 += a1×b2 - MOVQ 8(CX), AX - MULQ 16(BX) - ADDQ AX, R13 - ADCQ DX, R12 - - // r3 += a2×b1 - MOVQ 16(CX), AX - MULQ 8(BX) - ADDQ AX, R13 - ADCQ DX, R12 - - // r3 += a3×b0 - MOVQ 24(CX), AX - MULQ (BX) - ADDQ AX, R13 - ADCQ DX, R12 - - // r3 += 19×a4×b4 - MOVQ 32(CX), AX - IMUL3Q $0x13, AX, AX - MULQ 32(BX) - ADDQ AX, R13 - ADCQ DX, R12 - - // r4 = a0×b4 - MOVQ (CX), AX - MULQ 32(BX) - MOVQ AX, R15 - MOVQ DX, R14 - - // r4 += a1×b3 - MOVQ 8(CX), AX - MULQ 24(BX) - ADDQ AX, R15 - ADCQ DX, R14 - - // r4 += a2×b2 - MOVQ 16(CX), AX - MULQ 16(BX) - ADDQ AX, R15 - ADCQ DX, R14 - - // r4 += a3×b1 - MOVQ 24(CX), AX - MULQ 8(BX) - ADDQ AX, R15 - ADCQ DX, R14 - - // r4 += a4×b0 - MOVQ 32(CX), AX - MULQ (BX) - ADDQ AX, R15 - ADCQ DX, R14 - - // First reduction chain - MOVQ $0x0007ffffffffffff, AX - SHLQ $0x0d, DI, SI - SHLQ $0x0d, R9, R8 - SHLQ $0x0d, R11, R10 - SHLQ $0x0d, R13, R12 - SHLQ $0x0d, R15, R14 - ANDQ AX, DI - IMUL3Q $0x13, R14, R14 - ADDQ R14, DI - ANDQ AX, R9 - ADDQ SI, R9 - ANDQ AX, R11 - ADDQ R8, R11 - ANDQ AX, R13 - ADDQ R10, R13 - ANDQ AX, R15 - ADDQ R12, R15 - - // Second reduction chain (carryPropagate) - MOVQ DI, SI - SHRQ $0x33, SI - MOVQ R9, R8 - SHRQ $0x33, R8 - MOVQ R11, R10 - SHRQ $0x33, R10 - MOVQ R13, R12 - SHRQ $0x33, R12 - MOVQ R15, R14 - SHRQ $0x33, R14 - ANDQ AX, DI - IMUL3Q $0x13, R14, R14 - ADDQ R14, DI - ANDQ AX, R9 - ADDQ SI, R9 - ANDQ AX, R11 - ADDQ R8, R11 - ANDQ AX, R13 - ADDQ R10, R13 - ANDQ AX, R15 - ADDQ R12, R15 - - // Store output - MOVQ out+0(FP), AX - MOVQ DI, (AX) - MOVQ R9, 8(AX) - MOVQ R11, 16(AX) - MOVQ R13, 24(AX) - MOVQ R15, 32(AX) - RET - -// func feSquare(out *Element, a *Element) -TEXT ·feSquare(SB), NOSPLIT, $0-16 - MOVQ a+8(FP), CX - - // r0 = l0×l0 - MOVQ (CX), AX - MULQ (CX) - MOVQ AX, SI - MOVQ DX, BX - - // r0 += 38×l1×l4 - MOVQ 8(CX), AX - IMUL3Q $0x26, AX, AX - MULQ 32(CX) - ADDQ AX, SI - ADCQ DX, BX - - // r0 += 38×l2×l3 - MOVQ 16(CX), AX - IMUL3Q $0x26, AX, AX - MULQ 24(CX) - ADDQ AX, SI - ADCQ DX, BX - - // r1 = 2×l0×l1 - MOVQ (CX), AX - SHLQ $0x01, AX - MULQ 8(CX) - MOVQ AX, R8 - MOVQ DX, DI - - // r1 += 38×l2×l4 - MOVQ 16(CX), AX - IMUL3Q $0x26, AX, AX - MULQ 32(CX) - ADDQ AX, R8 - ADCQ DX, DI - - // r1 += 19×l3×l3 - MOVQ 24(CX), AX - IMUL3Q $0x13, AX, AX - MULQ 24(CX) - ADDQ AX, R8 - ADCQ DX, DI - - // r2 = 2×l0×l2 - MOVQ (CX), AX - SHLQ $0x01, AX - MULQ 16(CX) - MOVQ AX, R10 - MOVQ DX, R9 - - // r2 += l1×l1 - MOVQ 8(CX), AX - MULQ 8(CX) - ADDQ AX, R10 - ADCQ DX, R9 - - // r2 += 38×l3×l4 - MOVQ 24(CX), AX - IMUL3Q $0x26, AX, AX - MULQ 32(CX) - ADDQ AX, R10 - ADCQ DX, R9 - - // r3 = 2×l0×l3 - MOVQ (CX), AX - SHLQ $0x01, AX - MULQ 24(CX) - MOVQ AX, R12 - MOVQ DX, R11 - - // r3 += 2×l1×l2 - MOVQ 8(CX), AX - IMUL3Q $0x02, AX, AX - MULQ 16(CX) - ADDQ AX, R12 - ADCQ DX, R11 - - // r3 += 19×l4×l4 - MOVQ 32(CX), AX - IMUL3Q $0x13, AX, AX - MULQ 32(CX) - ADDQ AX, R12 - ADCQ DX, R11 - - // r4 = 2×l0×l4 - MOVQ (CX), AX - SHLQ $0x01, AX - MULQ 32(CX) - MOVQ AX, R14 - MOVQ DX, R13 - - // r4 += 2×l1×l3 - MOVQ 8(CX), AX - IMUL3Q $0x02, AX, AX - MULQ 24(CX) - ADDQ AX, R14 - ADCQ DX, R13 - - // r4 += l2×l2 - MOVQ 16(CX), AX - MULQ 16(CX) - ADDQ AX, R14 - ADCQ DX, R13 - - // First reduction chain - MOVQ $0x0007ffffffffffff, AX - SHLQ $0x0d, SI, BX - SHLQ $0x0d, R8, DI - SHLQ $0x0d, R10, R9 - SHLQ $0x0d, R12, R11 - SHLQ $0x0d, R14, R13 - ANDQ AX, SI - IMUL3Q $0x13, R13, R13 - ADDQ R13, SI - ANDQ AX, R8 - ADDQ BX, R8 - ANDQ AX, R10 - ADDQ DI, R10 - ANDQ AX, R12 - ADDQ R9, R12 - ANDQ AX, R14 - ADDQ R11, R14 - - // Second reduction chain (carryPropagate) - MOVQ SI, BX - SHRQ $0x33, BX - MOVQ R8, DI - SHRQ $0x33, DI - MOVQ R10, R9 - SHRQ $0x33, R9 - MOVQ R12, R11 - SHRQ $0x33, R11 - MOVQ R14, R13 - SHRQ $0x33, R13 - ANDQ AX, SI - IMUL3Q $0x13, R13, R13 - ADDQ R13, SI - ANDQ AX, R8 - ADDQ BX, R8 - ANDQ AX, R10 - ADDQ DI, R10 - ANDQ AX, R12 - ADDQ R9, R12 - ANDQ AX, R14 - ADDQ R11, R14 - - // Store output - MOVQ out+0(FP), AX - MOVQ SI, (AX) - MOVQ R8, 8(AX) - MOVQ R10, 16(AX) - MOVQ R12, 24(AX) - MOVQ R14, 32(AX) - RET diff --git a/v2/vendor/filippo.io/edwards25519/field/fe_amd64_noasm.go b/v2/vendor/filippo.io/edwards25519/field/fe_amd64_noasm.go deleted file mode 100644 index ddb6c9b..0000000 --- a/v2/vendor/filippo.io/edwards25519/field/fe_amd64_noasm.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !amd64 || !gc || purego -// +build !amd64 !gc purego - -package field - -func feMul(v, x, y *Element) { feMulGeneric(v, x, y) } - -func feSquare(v, x *Element) { feSquareGeneric(v, x) } diff --git a/v2/vendor/filippo.io/edwards25519/field/fe_arm64.go b/v2/vendor/filippo.io/edwards25519/field/fe_arm64.go deleted file mode 100644 index af459ef..0000000 --- a/v2/vendor/filippo.io/edwards25519/field/fe_arm64.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build arm64 && gc && !purego -// +build arm64,gc,!purego - -package field - -//go:noescape -func carryPropagate(v *Element) - -func (v *Element) carryPropagate() *Element { - carryPropagate(v) - return v -} diff --git a/v2/vendor/filippo.io/edwards25519/field/fe_arm64.s b/v2/vendor/filippo.io/edwards25519/field/fe_arm64.s deleted file mode 100644 index 3126a43..0000000 --- a/v2/vendor/filippo.io/edwards25519/field/fe_arm64.s +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (c) 2020 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build arm64 && gc && !purego - -#include "textflag.h" - -// carryPropagate works exactly like carryPropagateGeneric and uses the -// same AND, ADD, and LSR+MADD instructions emitted by the compiler, but -// avoids loading R0-R4 twice and uses LDP and STP. -// -// See https://golang.org/issues/43145 for the main compiler issue. -// -// func carryPropagate(v *Element) -TEXT ·carryPropagate(SB),NOFRAME|NOSPLIT,$0-8 - MOVD v+0(FP), R20 - - LDP 0(R20), (R0, R1) - LDP 16(R20), (R2, R3) - MOVD 32(R20), R4 - - AND $0x7ffffffffffff, R0, R10 - AND $0x7ffffffffffff, R1, R11 - AND $0x7ffffffffffff, R2, R12 - AND $0x7ffffffffffff, R3, R13 - AND $0x7ffffffffffff, R4, R14 - - ADD R0>>51, R11, R11 - ADD R1>>51, R12, R12 - ADD R2>>51, R13, R13 - ADD R3>>51, R14, R14 - // R4>>51 * 19 + R10 -> R10 - LSR $51, R4, R21 - MOVD $19, R22 - MADD R22, R10, R21, R10 - - STP (R10, R11), 0(R20) - STP (R12, R13), 16(R20) - MOVD R14, 32(R20) - - RET diff --git a/v2/vendor/filippo.io/edwards25519/field/fe_arm64_noasm.go b/v2/vendor/filippo.io/edwards25519/field/fe_arm64_noasm.go deleted file mode 100644 index 234a5b2..0000000 --- a/v2/vendor/filippo.io/edwards25519/field/fe_arm64_noasm.go +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright (c) 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -//go:build !arm64 || !gc || purego -// +build !arm64 !gc purego - -package field - -func (v *Element) carryPropagate() *Element { - return v.carryPropagateGeneric() -} diff --git a/v2/vendor/filippo.io/edwards25519/field/fe_extra.go b/v2/vendor/filippo.io/edwards25519/field/fe_extra.go deleted file mode 100644 index 1ef503b..0000000 --- a/v2/vendor/filippo.io/edwards25519/field/fe_extra.go +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) 2021 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package field - -import "errors" - -// This file contains additional functionality that is not included in the -// upstream crypto/ed25519/edwards25519/field package. - -// SetWideBytes sets v to x, where x is a 64-byte little-endian encoding, which -// is reduced modulo the field order. If x is not of the right length, -// SetWideBytes returns nil and an error, and the receiver is unchanged. -// -// SetWideBytes is not necessary to select a uniformly distributed value, and is -// only provided for compatibility: SetBytes can be used instead as the chance -// of bias is less than 2⁻²⁵⁰. -func (v *Element) SetWideBytes(x []byte) (*Element, error) { - if len(x) != 64 { - return nil, errors.New("edwards25519: invalid SetWideBytes input size") - } - - // Split the 64 bytes into two elements, and extract the most significant - // bit of each, which is ignored by SetBytes. - lo, _ := new(Element).SetBytes(x[:32]) - loMSB := uint64(x[31] >> 7) - hi, _ := new(Element).SetBytes(x[32:]) - hiMSB := uint64(x[63] >> 7) - - // The output we want is - // - // v = lo + loMSB * 2²⁵⁵ + hi * 2²⁵⁶ + hiMSB * 2⁵¹¹ - // - // which applying the reduction identity comes out to - // - // v = lo + loMSB * 19 + hi * 2 * 19 + hiMSB * 2 * 19² - // - // l0 will be the sum of a 52 bits value (lo.l0), plus a 5 bits value - // (loMSB * 19), a 6 bits value (hi.l0 * 2 * 19), and a 10 bits value - // (hiMSB * 2 * 19²), so it fits in a uint64. - - v.l0 = lo.l0 + loMSB*19 + hi.l0*2*19 + hiMSB*2*19*19 - v.l1 = lo.l1 + hi.l1*2*19 - v.l2 = lo.l2 + hi.l2*2*19 - v.l3 = lo.l3 + hi.l3*2*19 - v.l4 = lo.l4 + hi.l4*2*19 - - return v.carryPropagate(), nil -} diff --git a/v2/vendor/filippo.io/edwards25519/field/fe_generic.go b/v2/vendor/filippo.io/edwards25519/field/fe_generic.go deleted file mode 100644 index 86f5fd9..0000000 --- a/v2/vendor/filippo.io/edwards25519/field/fe_generic.go +++ /dev/null @@ -1,266 +0,0 @@ -// Copyright (c) 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package field - -import "math/bits" - -// uint128 holds a 128-bit number as two 64-bit limbs, for use with the -// bits.Mul64 and bits.Add64 intrinsics. -type uint128 struct { - lo, hi uint64 -} - -// mul64 returns a * b. -func mul64(a, b uint64) uint128 { - hi, lo := bits.Mul64(a, b) - return uint128{lo, hi} -} - -// addMul64 returns v + a * b. -func addMul64(v uint128, a, b uint64) uint128 { - hi, lo := bits.Mul64(a, b) - lo, c := bits.Add64(lo, v.lo, 0) - hi, _ = bits.Add64(hi, v.hi, c) - return uint128{lo, hi} -} - -// shiftRightBy51 returns a >> 51. a is assumed to be at most 115 bits. -func shiftRightBy51(a uint128) uint64 { - return (a.hi << (64 - 51)) | (a.lo >> 51) -} - -func feMulGeneric(v, a, b *Element) { - a0 := a.l0 - a1 := a.l1 - a2 := a.l2 - a3 := a.l3 - a4 := a.l4 - - b0 := b.l0 - b1 := b.l1 - b2 := b.l2 - b3 := b.l3 - b4 := b.l4 - - // Limb multiplication works like pen-and-paper columnar multiplication, but - // with 51-bit limbs instead of digits. - // - // a4 a3 a2 a1 a0 x - // b4 b3 b2 b1 b0 = - // ------------------------ - // a4b0 a3b0 a2b0 a1b0 a0b0 + - // a4b1 a3b1 a2b1 a1b1 a0b1 + - // a4b2 a3b2 a2b2 a1b2 a0b2 + - // a4b3 a3b3 a2b3 a1b3 a0b3 + - // a4b4 a3b4 a2b4 a1b4 a0b4 = - // ---------------------------------------------- - // r8 r7 r6 r5 r4 r3 r2 r1 r0 - // - // We can then use the reduction identity (a * 2²⁵⁵ + b = a * 19 + b) to - // reduce the limbs that would overflow 255 bits. r5 * 2²⁵⁵ becomes 19 * r5, - // r6 * 2³⁰⁶ becomes 19 * r6 * 2⁵¹, etc. - // - // Reduction can be carried out simultaneously to multiplication. For - // example, we do not compute r5: whenever the result of a multiplication - // belongs to r5, like a1b4, we multiply it by 19 and add the result to r0. - // - // a4b0 a3b0 a2b0 a1b0 a0b0 + - // a3b1 a2b1 a1b1 a0b1 19×a4b1 + - // a2b2 a1b2 a0b2 19×a4b2 19×a3b2 + - // a1b3 a0b3 19×a4b3 19×a3b3 19×a2b3 + - // a0b4 19×a4b4 19×a3b4 19×a2b4 19×a1b4 = - // -------------------------------------- - // r4 r3 r2 r1 r0 - // - // Finally we add up the columns into wide, overlapping limbs. - - a1_19 := a1 * 19 - a2_19 := a2 * 19 - a3_19 := a3 * 19 - a4_19 := a4 * 19 - - // r0 = a0×b0 + 19×(a1×b4 + a2×b3 + a3×b2 + a4×b1) - r0 := mul64(a0, b0) - r0 = addMul64(r0, a1_19, b4) - r0 = addMul64(r0, a2_19, b3) - r0 = addMul64(r0, a3_19, b2) - r0 = addMul64(r0, a4_19, b1) - - // r1 = a0×b1 + a1×b0 + 19×(a2×b4 + a3×b3 + a4×b2) - r1 := mul64(a0, b1) - r1 = addMul64(r1, a1, b0) - r1 = addMul64(r1, a2_19, b4) - r1 = addMul64(r1, a3_19, b3) - r1 = addMul64(r1, a4_19, b2) - - // r2 = a0×b2 + a1×b1 + a2×b0 + 19×(a3×b4 + a4×b3) - r2 := mul64(a0, b2) - r2 = addMul64(r2, a1, b1) - r2 = addMul64(r2, a2, b0) - r2 = addMul64(r2, a3_19, b4) - r2 = addMul64(r2, a4_19, b3) - - // r3 = a0×b3 + a1×b2 + a2×b1 + a3×b0 + 19×a4×b4 - r3 := mul64(a0, b3) - r3 = addMul64(r3, a1, b2) - r3 = addMul64(r3, a2, b1) - r3 = addMul64(r3, a3, b0) - r3 = addMul64(r3, a4_19, b4) - - // r4 = a0×b4 + a1×b3 + a2×b2 + a3×b1 + a4×b0 - r4 := mul64(a0, b4) - r4 = addMul64(r4, a1, b3) - r4 = addMul64(r4, a2, b2) - r4 = addMul64(r4, a3, b1) - r4 = addMul64(r4, a4, b0) - - // After the multiplication, we need to reduce (carry) the five coefficients - // to obtain a result with limbs that are at most slightly larger than 2⁵¹, - // to respect the Element invariant. - // - // Overall, the reduction works the same as carryPropagate, except with - // wider inputs: we take the carry for each coefficient by shifting it right - // by 51, and add it to the limb above it. The top carry is multiplied by 19 - // according to the reduction identity and added to the lowest limb. - // - // The largest coefficient (r0) will be at most 111 bits, which guarantees - // that all carries are at most 111 - 51 = 60 bits, which fits in a uint64. - // - // r0 = a0×b0 + 19×(a1×b4 + a2×b3 + a3×b2 + a4×b1) - // r0 < 2⁵²×2⁵² + 19×(2⁵²×2⁵² + 2⁵²×2⁵² + 2⁵²×2⁵² + 2⁵²×2⁵²) - // r0 < (1 + 19 × 4) × 2⁵² × 2⁵² - // r0 < 2⁷ × 2⁵² × 2⁵² - // r0 < 2¹¹¹ - // - // Moreover, the top coefficient (r4) is at most 107 bits, so c4 is at most - // 56 bits, and c4 * 19 is at most 61 bits, which again fits in a uint64 and - // allows us to easily apply the reduction identity. - // - // r4 = a0×b4 + a1×b3 + a2×b2 + a3×b1 + a4×b0 - // r4 < 5 × 2⁵² × 2⁵² - // r4 < 2¹⁰⁷ - // - - c0 := shiftRightBy51(r0) - c1 := shiftRightBy51(r1) - c2 := shiftRightBy51(r2) - c3 := shiftRightBy51(r3) - c4 := shiftRightBy51(r4) - - rr0 := r0.lo&maskLow51Bits + c4*19 - rr1 := r1.lo&maskLow51Bits + c0 - rr2 := r2.lo&maskLow51Bits + c1 - rr3 := r3.lo&maskLow51Bits + c2 - rr4 := r4.lo&maskLow51Bits + c3 - - // Now all coefficients fit into 64-bit registers but are still too large to - // be passed around as an Element. We therefore do one last carry chain, - // where the carries will be small enough to fit in the wiggle room above 2⁵¹. - *v = Element{rr0, rr1, rr2, rr3, rr4} - v.carryPropagate() -} - -func feSquareGeneric(v, a *Element) { - l0 := a.l0 - l1 := a.l1 - l2 := a.l2 - l3 := a.l3 - l4 := a.l4 - - // Squaring works precisely like multiplication above, but thanks to its - // symmetry we get to group a few terms together. - // - // l4 l3 l2 l1 l0 x - // l4 l3 l2 l1 l0 = - // ------------------------ - // l4l0 l3l0 l2l0 l1l0 l0l0 + - // l4l1 l3l1 l2l1 l1l1 l0l1 + - // l4l2 l3l2 l2l2 l1l2 l0l2 + - // l4l3 l3l3 l2l3 l1l3 l0l3 + - // l4l4 l3l4 l2l4 l1l4 l0l4 = - // ---------------------------------------------- - // r8 r7 r6 r5 r4 r3 r2 r1 r0 - // - // l4l0 l3l0 l2l0 l1l0 l0l0 + - // l3l1 l2l1 l1l1 l0l1 19×l4l1 + - // l2l2 l1l2 l0l2 19×l4l2 19×l3l2 + - // l1l3 l0l3 19×l4l3 19×l3l3 19×l2l3 + - // l0l4 19×l4l4 19×l3l4 19×l2l4 19×l1l4 = - // -------------------------------------- - // r4 r3 r2 r1 r0 - // - // With precomputed 2×, 19×, and 2×19× terms, we can compute each limb with - // only three Mul64 and four Add64, instead of five and eight. - - l0_2 := l0 * 2 - l1_2 := l1 * 2 - - l1_38 := l1 * 38 - l2_38 := l2 * 38 - l3_38 := l3 * 38 - - l3_19 := l3 * 19 - l4_19 := l4 * 19 - - // r0 = l0×l0 + 19×(l1×l4 + l2×l3 + l3×l2 + l4×l1) = l0×l0 + 19×2×(l1×l4 + l2×l3) - r0 := mul64(l0, l0) - r0 = addMul64(r0, l1_38, l4) - r0 = addMul64(r0, l2_38, l3) - - // r1 = l0×l1 + l1×l0 + 19×(l2×l4 + l3×l3 + l4×l2) = 2×l0×l1 + 19×2×l2×l4 + 19×l3×l3 - r1 := mul64(l0_2, l1) - r1 = addMul64(r1, l2_38, l4) - r1 = addMul64(r1, l3_19, l3) - - // r2 = l0×l2 + l1×l1 + l2×l0 + 19×(l3×l4 + l4×l3) = 2×l0×l2 + l1×l1 + 19×2×l3×l4 - r2 := mul64(l0_2, l2) - r2 = addMul64(r2, l1, l1) - r2 = addMul64(r2, l3_38, l4) - - // r3 = l0×l3 + l1×l2 + l2×l1 + l3×l0 + 19×l4×l4 = 2×l0×l3 + 2×l1×l2 + 19×l4×l4 - r3 := mul64(l0_2, l3) - r3 = addMul64(r3, l1_2, l2) - r3 = addMul64(r3, l4_19, l4) - - // r4 = l0×l4 + l1×l3 + l2×l2 + l3×l1 + l4×l0 = 2×l0×l4 + 2×l1×l3 + l2×l2 - r4 := mul64(l0_2, l4) - r4 = addMul64(r4, l1_2, l3) - r4 = addMul64(r4, l2, l2) - - c0 := shiftRightBy51(r0) - c1 := shiftRightBy51(r1) - c2 := shiftRightBy51(r2) - c3 := shiftRightBy51(r3) - c4 := shiftRightBy51(r4) - - rr0 := r0.lo&maskLow51Bits + c4*19 - rr1 := r1.lo&maskLow51Bits + c0 - rr2 := r2.lo&maskLow51Bits + c1 - rr3 := r3.lo&maskLow51Bits + c2 - rr4 := r4.lo&maskLow51Bits + c3 - - *v = Element{rr0, rr1, rr2, rr3, rr4} - v.carryPropagate() -} - -// carryPropagateGeneric brings the limbs below 52 bits by applying the reduction -// identity (a * 2²⁵⁵ + b = a * 19 + b) to the l4 carry. -func (v *Element) carryPropagateGeneric() *Element { - c0 := v.l0 >> 51 - c1 := v.l1 >> 51 - c2 := v.l2 >> 51 - c3 := v.l3 >> 51 - c4 := v.l4 >> 51 - - // c4 is at most 64 - 51 = 13 bits, so c4*19 is at most 18 bits, and - // the final l0 will be at most 52 bits. Similarly for the rest. - v.l0 = v.l0&maskLow51Bits + c4*19 - v.l1 = v.l1&maskLow51Bits + c0 - v.l2 = v.l2&maskLow51Bits + c1 - v.l3 = v.l3&maskLow51Bits + c2 - v.l4 = v.l4&maskLow51Bits + c3 - - return v -} diff --git a/v2/vendor/filippo.io/edwards25519/scalar.go b/v2/vendor/filippo.io/edwards25519/scalar.go deleted file mode 100644 index 3fd1653..0000000 --- a/v2/vendor/filippo.io/edwards25519/scalar.go +++ /dev/null @@ -1,343 +0,0 @@ -// Copyright (c) 2016 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package edwards25519 - -import ( - "encoding/binary" - "errors" -) - -// A Scalar is an integer modulo -// -// l = 2^252 + 27742317777372353535851937790883648493 -// -// which is the prime order of the edwards25519 group. -// -// This type works similarly to math/big.Int, and all arguments and -// receivers are allowed to alias. -// -// The zero value is a valid zero element. -type Scalar struct { - // s is the scalar in the Montgomery domain, in the format of the - // fiat-crypto implementation. - s fiatScalarMontgomeryDomainFieldElement -} - -// The field implementation in scalar_fiat.go is generated by the fiat-crypto -// project (https://github.com/mit-plv/fiat-crypto) at version v0.0.9 (23d2dbc) -// from a formally verified model. -// -// fiat-crypto code comes under the following license. -// -// Copyright (c) 2015-2020 The fiat-crypto Authors. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// 1. Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// THIS SOFTWARE IS PROVIDED BY the fiat-crypto authors "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Berkeley Software Design, -// Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// - -// NewScalar returns a new zero Scalar. -func NewScalar() *Scalar { - return &Scalar{} -} - -// MultiplyAdd sets s = x * y + z mod l, and returns s. It is equivalent to -// using Multiply and then Add. -func (s *Scalar) MultiplyAdd(x, y, z *Scalar) *Scalar { - // Make a copy of z in case it aliases s. - zCopy := new(Scalar).Set(z) - return s.Multiply(x, y).Add(s, zCopy) -} - -// Add sets s = x + y mod l, and returns s. -func (s *Scalar) Add(x, y *Scalar) *Scalar { - // s = 1 * x + y mod l - fiatScalarAdd(&s.s, &x.s, &y.s) - return s -} - -// Subtract sets s = x - y mod l, and returns s. -func (s *Scalar) Subtract(x, y *Scalar) *Scalar { - // s = -1 * y + x mod l - fiatScalarSub(&s.s, &x.s, &y.s) - return s -} - -// Negate sets s = -x mod l, and returns s. -func (s *Scalar) Negate(x *Scalar) *Scalar { - // s = -1 * x + 0 mod l - fiatScalarOpp(&s.s, &x.s) - return s -} - -// Multiply sets s = x * y mod l, and returns s. -func (s *Scalar) Multiply(x, y *Scalar) *Scalar { - // s = x * y + 0 mod l - fiatScalarMul(&s.s, &x.s, &y.s) - return s -} - -// Set sets s = x, and returns s. -func (s *Scalar) Set(x *Scalar) *Scalar { - *s = *x - return s -} - -// SetUniformBytes sets s = x mod l, where x is a 64-byte little-endian integer. -// If x is not of the right length, SetUniformBytes returns nil and an error, -// and the receiver is unchanged. -// -// SetUniformBytes can be used to set s to a uniformly distributed value given -// 64 uniformly distributed random bytes. -func (s *Scalar) SetUniformBytes(x []byte) (*Scalar, error) { - if len(x) != 64 { - return nil, errors.New("edwards25519: invalid SetUniformBytes input length") - } - - // We have a value x of 512 bits, but our fiatScalarFromBytes function - // expects an input lower than l, which is a little over 252 bits. - // - // Instead of writing a reduction function that operates on wider inputs, we - // can interpret x as the sum of three shorter values a, b, and c. - // - // x = a + b * 2^168 + c * 2^336 mod l - // - // We then precompute 2^168 and 2^336 modulo l, and perform the reduction - // with two multiplications and two additions. - - s.setShortBytes(x[:21]) - t := new(Scalar).setShortBytes(x[21:42]) - s.Add(s, t.Multiply(t, scalarTwo168)) - t.setShortBytes(x[42:]) - s.Add(s, t.Multiply(t, scalarTwo336)) - - return s, nil -} - -// scalarTwo168 and scalarTwo336 are 2^168 and 2^336 modulo l, encoded as a -// fiatScalarMontgomeryDomainFieldElement, which is a little-endian 4-limb value -// in the 2^256 Montgomery domain. -var scalarTwo168 = &Scalar{s: [4]uint64{0x5b8ab432eac74798, 0x38afddd6de59d5d7, - 0xa2c131b399411b7c, 0x6329a7ed9ce5a30}} -var scalarTwo336 = &Scalar{s: [4]uint64{0xbd3d108e2b35ecc5, 0x5c3a3718bdf9c90b, - 0x63aa97a331b4f2ee, 0x3d217f5be65cb5c}} - -// setShortBytes sets s = x mod l, where x is a little-endian integer shorter -// than 32 bytes. -func (s *Scalar) setShortBytes(x []byte) *Scalar { - if len(x) >= 32 { - panic("edwards25519: internal error: setShortBytes called with a long string") - } - var buf [32]byte - copy(buf[:], x) - fiatScalarFromBytes((*[4]uint64)(&s.s), &buf) - fiatScalarToMontgomery(&s.s, (*fiatScalarNonMontgomeryDomainFieldElement)(&s.s)) - return s -} - -// SetCanonicalBytes sets s = x, where x is a 32-byte little-endian encoding of -// s, and returns s. If x is not a canonical encoding of s, SetCanonicalBytes -// returns nil and an error, and the receiver is unchanged. -func (s *Scalar) SetCanonicalBytes(x []byte) (*Scalar, error) { - if len(x) != 32 { - return nil, errors.New("invalid scalar length") - } - if !isReduced(x) { - return nil, errors.New("invalid scalar encoding") - } - - fiatScalarFromBytes((*[4]uint64)(&s.s), (*[32]byte)(x)) - fiatScalarToMontgomery(&s.s, (*fiatScalarNonMontgomeryDomainFieldElement)(&s.s)) - - return s, nil -} - -// scalarMinusOneBytes is l - 1 in little endian. -var scalarMinusOneBytes = [32]byte{236, 211, 245, 92, 26, 99, 18, 88, 214, 156, 247, 162, 222, 249, 222, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16} - -// isReduced returns whether the given scalar in 32-byte little endian encoded -// form is reduced modulo l. -func isReduced(s []byte) bool { - if len(s) != 32 { - return false - } - - for i := len(s) - 1; i >= 0; i-- { - switch { - case s[i] > scalarMinusOneBytes[i]: - return false - case s[i] < scalarMinusOneBytes[i]: - return true - } - } - return true -} - -// SetBytesWithClamping applies the buffer pruning described in RFC 8032, -// Section 5.1.5 (also known as clamping) and sets s to the result. The input -// must be 32 bytes, and it is not modified. If x is not of the right length, -// SetBytesWithClamping returns nil and an error, and the receiver is unchanged. -// -// Note that since Scalar values are always reduced modulo the prime order of -// the curve, the resulting value will not preserve any of the cofactor-clearing -// properties that clamping is meant to provide. It will however work as -// expected as long as it is applied to points on the prime order subgroup, like -// in Ed25519. In fact, it is lost to history why RFC 8032 adopted the -// irrelevant RFC 7748 clamping, but it is now required for compatibility. -func (s *Scalar) SetBytesWithClamping(x []byte) (*Scalar, error) { - // The description above omits the purpose of the high bits of the clamping - // for brevity, but those are also lost to reductions, and are also - // irrelevant to edwards25519 as they protect against a specific - // implementation bug that was once observed in a generic Montgomery ladder. - if len(x) != 32 { - return nil, errors.New("edwards25519: invalid SetBytesWithClamping input length") - } - - // We need to use the wide reduction from SetUniformBytes, since clamping - // sets the 2^254 bit, making the value higher than the order. - var wideBytes [64]byte - copy(wideBytes[:], x[:]) - wideBytes[0] &= 248 - wideBytes[31] &= 63 - wideBytes[31] |= 64 - return s.SetUniformBytes(wideBytes[:]) -} - -// Bytes returns the canonical 32-byte little-endian encoding of s. -func (s *Scalar) Bytes() []byte { - // This function is outlined to make the allocations inline in the caller - // rather than happen on the heap. - var encoded [32]byte - return s.bytes(&encoded) -} - -func (s *Scalar) bytes(out *[32]byte) []byte { - var ss fiatScalarNonMontgomeryDomainFieldElement - fiatScalarFromMontgomery(&ss, &s.s) - fiatScalarToBytes(out, (*[4]uint64)(&ss)) - return out[:] -} - -// Equal returns 1 if s and t are equal, and 0 otherwise. -func (s *Scalar) Equal(t *Scalar) int { - var diff fiatScalarMontgomeryDomainFieldElement - fiatScalarSub(&diff, &s.s, &t.s) - var nonzero uint64 - fiatScalarNonzero(&nonzero, (*[4]uint64)(&diff)) - nonzero |= nonzero >> 32 - nonzero |= nonzero >> 16 - nonzero |= nonzero >> 8 - nonzero |= nonzero >> 4 - nonzero |= nonzero >> 2 - nonzero |= nonzero >> 1 - return int(^nonzero) & 1 -} - -// nonAdjacentForm computes a width-w non-adjacent form for this scalar. -// -// w must be between 2 and 8, or nonAdjacentForm will panic. -func (s *Scalar) nonAdjacentForm(w uint) [256]int8 { - // This implementation is adapted from the one - // in curve25519-dalek and is documented there: - // https://github.com/dalek-cryptography/curve25519-dalek/blob/f630041af28e9a405255f98a8a93adca18e4315b/src/scalar.rs#L800-L871 - b := s.Bytes() - if b[31] > 127 { - panic("scalar has high bit set illegally") - } - if w < 2 { - panic("w must be at least 2 by the definition of NAF") - } else if w > 8 { - panic("NAF digits must fit in int8") - } - - var naf [256]int8 - var digits [5]uint64 - - for i := 0; i < 4; i++ { - digits[i] = binary.LittleEndian.Uint64(b[i*8:]) - } - - width := uint64(1 << w) - windowMask := uint64(width - 1) - - pos := uint(0) - carry := uint64(0) - for pos < 256 { - indexU64 := pos / 64 - indexBit := pos % 64 - var bitBuf uint64 - if indexBit < 64-w { - // This window's bits are contained in a single u64 - bitBuf = digits[indexU64] >> indexBit - } else { - // Combine the current 64 bits with bits from the next 64 - bitBuf = (digits[indexU64] >> indexBit) | (digits[1+indexU64] << (64 - indexBit)) - } - - // Add carry into the current window - window := carry + (bitBuf & windowMask) - - if window&1 == 0 { - // If the window value is even, preserve the carry and continue. - // Why is the carry preserved? - // If carry == 0 and window & 1 == 0, - // then the next carry should be 0 - // If carry == 1 and window & 1 == 0, - // then bit_buf & 1 == 1 so the next carry should be 1 - pos += 1 - continue - } - - if window < width/2 { - carry = 0 - naf[pos] = int8(window) - } else { - carry = 1 - naf[pos] = int8(window) - int8(width) - } - - pos += w - } - return naf -} - -func (s *Scalar) signedRadix16() [64]int8 { - b := s.Bytes() - if b[31] > 127 { - panic("scalar has high bit set illegally") - } - - var digits [64]int8 - - // Compute unsigned radix-16 digits: - for i := 0; i < 32; i++ { - digits[2*i] = int8(b[i] & 15) - digits[2*i+1] = int8((b[i] >> 4) & 15) - } - - // Recenter coefficients: - for i := 0; i < 63; i++ { - carry := (digits[i] + 8) >> 4 - digits[i] -= carry << 4 - digits[i+1] += carry - } - - return digits -} diff --git a/v2/vendor/filippo.io/edwards25519/scalar_fiat.go b/v2/vendor/filippo.io/edwards25519/scalar_fiat.go deleted file mode 100644 index 2e5782b..0000000 --- a/v2/vendor/filippo.io/edwards25519/scalar_fiat.go +++ /dev/null @@ -1,1147 +0,0 @@ -// Code generated by Fiat Cryptography. DO NOT EDIT. -// -// Autogenerated: word_by_word_montgomery --lang Go --cmovznz-by-mul --relax-primitive-carry-to-bitwidth 32,64 --public-function-case camelCase --public-type-case camelCase --private-function-case camelCase --private-type-case camelCase --doc-text-before-function-name '' --doc-newline-before-package-declaration --doc-prepend-header 'Code generated by Fiat Cryptography. DO NOT EDIT.' --package-name edwards25519 Scalar 64 '2^252 + 27742317777372353535851937790883648493' mul add sub opp nonzero from_montgomery to_montgomery to_bytes from_bytes -// -// curve description: Scalar -// -// machine_wordsize = 64 (from "64") -// -// requested operations: mul, add, sub, opp, nonzero, from_montgomery, to_montgomery, to_bytes, from_bytes -// -// m = 0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed (from "2^252 + 27742317777372353535851937790883648493") -// -// -// -// NOTE: In addition to the bounds specified above each function, all -// -// functions synthesized for this Montgomery arithmetic require the -// -// input to be strictly less than the prime modulus (m), and also -// -// require the input to be in the unique saturated representation. -// -// All functions also ensure that these two properties are true of -// -// return values. -// -// -// -// Computed values: -// -// eval z = z[0] + (z[1] << 64) + (z[2] << 128) + (z[3] << 192) -// -// bytes_eval z = z[0] + (z[1] << 8) + (z[2] << 16) + (z[3] << 24) + (z[4] << 32) + (z[5] << 40) + (z[6] << 48) + (z[7] << 56) + (z[8] << 64) + (z[9] << 72) + (z[10] << 80) + (z[11] << 88) + (z[12] << 96) + (z[13] << 104) + (z[14] << 112) + (z[15] << 120) + (z[16] << 128) + (z[17] << 136) + (z[18] << 144) + (z[19] << 152) + (z[20] << 160) + (z[21] << 168) + (z[22] << 176) + (z[23] << 184) + (z[24] << 192) + (z[25] << 200) + (z[26] << 208) + (z[27] << 216) + (z[28] << 224) + (z[29] << 232) + (z[30] << 240) + (z[31] << 248) -// -// twos_complement_eval z = let x1 := z[0] + (z[1] << 64) + (z[2] << 128) + (z[3] << 192) in -// -// if x1 & (2^256-1) < 2^255 then x1 & (2^256-1) else (x1 & (2^256-1)) - 2^256 - -package edwards25519 - -import "math/bits" - -type fiatScalarUint1 uint64 // We use uint64 instead of a more narrow type for performance reasons; see https://github.com/mit-plv/fiat-crypto/pull/1006#issuecomment-892625927 -type fiatScalarInt1 int64 // We use uint64 instead of a more narrow type for performance reasons; see https://github.com/mit-plv/fiat-crypto/pull/1006#issuecomment-892625927 - -// The type fiatScalarMontgomeryDomainFieldElement is a field element in the Montgomery domain. -// -// Bounds: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] -type fiatScalarMontgomeryDomainFieldElement [4]uint64 - -// The type fiatScalarNonMontgomeryDomainFieldElement is a field element NOT in the Montgomery domain. -// -// Bounds: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] -type fiatScalarNonMontgomeryDomainFieldElement [4]uint64 - -// fiatScalarCmovznzU64 is a single-word conditional move. -// -// Postconditions: -// -// out1 = (if arg1 = 0 then arg2 else arg3) -// -// Input Bounds: -// -// arg1: [0x0 ~> 0x1] -// arg2: [0x0 ~> 0xffffffffffffffff] -// arg3: [0x0 ~> 0xffffffffffffffff] -// -// Output Bounds: -// -// out1: [0x0 ~> 0xffffffffffffffff] -func fiatScalarCmovznzU64(out1 *uint64, arg1 fiatScalarUint1, arg2 uint64, arg3 uint64) { - x1 := (uint64(arg1) * 0xffffffffffffffff) - x2 := ((x1 & arg3) | ((^x1) & arg2)) - *out1 = x2 -} - -// fiatScalarMul multiplies two field elements in the Montgomery domain. -// -// Preconditions: -// -// 0 ≤ eval arg1 < m -// 0 ≤ eval arg2 < m -// -// Postconditions: -// -// eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) * eval (from_montgomery arg2)) mod m -// 0 ≤ eval out1 < m -func fiatScalarMul(out1 *fiatScalarMontgomeryDomainFieldElement, arg1 *fiatScalarMontgomeryDomainFieldElement, arg2 *fiatScalarMontgomeryDomainFieldElement) { - x1 := arg1[1] - x2 := arg1[2] - x3 := arg1[3] - x4 := arg1[0] - var x5 uint64 - var x6 uint64 - x6, x5 = bits.Mul64(x4, arg2[3]) - var x7 uint64 - var x8 uint64 - x8, x7 = bits.Mul64(x4, arg2[2]) - var x9 uint64 - var x10 uint64 - x10, x9 = bits.Mul64(x4, arg2[1]) - var x11 uint64 - var x12 uint64 - x12, x11 = bits.Mul64(x4, arg2[0]) - var x13 uint64 - var x14 uint64 - x13, x14 = bits.Add64(x12, x9, uint64(0x0)) - var x15 uint64 - var x16 uint64 - x15, x16 = bits.Add64(x10, x7, uint64(fiatScalarUint1(x14))) - var x17 uint64 - var x18 uint64 - x17, x18 = bits.Add64(x8, x5, uint64(fiatScalarUint1(x16))) - x19 := (uint64(fiatScalarUint1(x18)) + x6) - var x20 uint64 - _, x20 = bits.Mul64(x11, 0xd2b51da312547e1b) - var x22 uint64 - var x23 uint64 - x23, x22 = bits.Mul64(x20, 0x1000000000000000) - var x24 uint64 - var x25 uint64 - x25, x24 = bits.Mul64(x20, 0x14def9dea2f79cd6) - var x26 uint64 - var x27 uint64 - x27, x26 = bits.Mul64(x20, 0x5812631a5cf5d3ed) - var x28 uint64 - var x29 uint64 - x28, x29 = bits.Add64(x27, x24, uint64(0x0)) - x30 := (uint64(fiatScalarUint1(x29)) + x25) - var x32 uint64 - _, x32 = bits.Add64(x11, x26, uint64(0x0)) - var x33 uint64 - var x34 uint64 - x33, x34 = bits.Add64(x13, x28, uint64(fiatScalarUint1(x32))) - var x35 uint64 - var x36 uint64 - x35, x36 = bits.Add64(x15, x30, uint64(fiatScalarUint1(x34))) - var x37 uint64 - var x38 uint64 - x37, x38 = bits.Add64(x17, x22, uint64(fiatScalarUint1(x36))) - var x39 uint64 - var x40 uint64 - x39, x40 = bits.Add64(x19, x23, uint64(fiatScalarUint1(x38))) - var x41 uint64 - var x42 uint64 - x42, x41 = bits.Mul64(x1, arg2[3]) - var x43 uint64 - var x44 uint64 - x44, x43 = bits.Mul64(x1, arg2[2]) - var x45 uint64 - var x46 uint64 - x46, x45 = bits.Mul64(x1, arg2[1]) - var x47 uint64 - var x48 uint64 - x48, x47 = bits.Mul64(x1, arg2[0]) - var x49 uint64 - var x50 uint64 - x49, x50 = bits.Add64(x48, x45, uint64(0x0)) - var x51 uint64 - var x52 uint64 - x51, x52 = bits.Add64(x46, x43, uint64(fiatScalarUint1(x50))) - var x53 uint64 - var x54 uint64 - x53, x54 = bits.Add64(x44, x41, uint64(fiatScalarUint1(x52))) - x55 := (uint64(fiatScalarUint1(x54)) + x42) - var x56 uint64 - var x57 uint64 - x56, x57 = bits.Add64(x33, x47, uint64(0x0)) - var x58 uint64 - var x59 uint64 - x58, x59 = bits.Add64(x35, x49, uint64(fiatScalarUint1(x57))) - var x60 uint64 - var x61 uint64 - x60, x61 = bits.Add64(x37, x51, uint64(fiatScalarUint1(x59))) - var x62 uint64 - var x63 uint64 - x62, x63 = bits.Add64(x39, x53, uint64(fiatScalarUint1(x61))) - var x64 uint64 - var x65 uint64 - x64, x65 = bits.Add64(uint64(fiatScalarUint1(x40)), x55, uint64(fiatScalarUint1(x63))) - var x66 uint64 - _, x66 = bits.Mul64(x56, 0xd2b51da312547e1b) - var x68 uint64 - var x69 uint64 - x69, x68 = bits.Mul64(x66, 0x1000000000000000) - var x70 uint64 - var x71 uint64 - x71, x70 = bits.Mul64(x66, 0x14def9dea2f79cd6) - var x72 uint64 - var x73 uint64 - x73, x72 = bits.Mul64(x66, 0x5812631a5cf5d3ed) - var x74 uint64 - var x75 uint64 - x74, x75 = bits.Add64(x73, x70, uint64(0x0)) - x76 := (uint64(fiatScalarUint1(x75)) + x71) - var x78 uint64 - _, x78 = bits.Add64(x56, x72, uint64(0x0)) - var x79 uint64 - var x80 uint64 - x79, x80 = bits.Add64(x58, x74, uint64(fiatScalarUint1(x78))) - var x81 uint64 - var x82 uint64 - x81, x82 = bits.Add64(x60, x76, uint64(fiatScalarUint1(x80))) - var x83 uint64 - var x84 uint64 - x83, x84 = bits.Add64(x62, x68, uint64(fiatScalarUint1(x82))) - var x85 uint64 - var x86 uint64 - x85, x86 = bits.Add64(x64, x69, uint64(fiatScalarUint1(x84))) - x87 := (uint64(fiatScalarUint1(x86)) + uint64(fiatScalarUint1(x65))) - var x88 uint64 - var x89 uint64 - x89, x88 = bits.Mul64(x2, arg2[3]) - var x90 uint64 - var x91 uint64 - x91, x90 = bits.Mul64(x2, arg2[2]) - var x92 uint64 - var x93 uint64 - x93, x92 = bits.Mul64(x2, arg2[1]) - var x94 uint64 - var x95 uint64 - x95, x94 = bits.Mul64(x2, arg2[0]) - var x96 uint64 - var x97 uint64 - x96, x97 = bits.Add64(x95, x92, uint64(0x0)) - var x98 uint64 - var x99 uint64 - x98, x99 = bits.Add64(x93, x90, uint64(fiatScalarUint1(x97))) - var x100 uint64 - var x101 uint64 - x100, x101 = bits.Add64(x91, x88, uint64(fiatScalarUint1(x99))) - x102 := (uint64(fiatScalarUint1(x101)) + x89) - var x103 uint64 - var x104 uint64 - x103, x104 = bits.Add64(x79, x94, uint64(0x0)) - var x105 uint64 - var x106 uint64 - x105, x106 = bits.Add64(x81, x96, uint64(fiatScalarUint1(x104))) - var x107 uint64 - var x108 uint64 - x107, x108 = bits.Add64(x83, x98, uint64(fiatScalarUint1(x106))) - var x109 uint64 - var x110 uint64 - x109, x110 = bits.Add64(x85, x100, uint64(fiatScalarUint1(x108))) - var x111 uint64 - var x112 uint64 - x111, x112 = bits.Add64(x87, x102, uint64(fiatScalarUint1(x110))) - var x113 uint64 - _, x113 = bits.Mul64(x103, 0xd2b51da312547e1b) - var x115 uint64 - var x116 uint64 - x116, x115 = bits.Mul64(x113, 0x1000000000000000) - var x117 uint64 - var x118 uint64 - x118, x117 = bits.Mul64(x113, 0x14def9dea2f79cd6) - var x119 uint64 - var x120 uint64 - x120, x119 = bits.Mul64(x113, 0x5812631a5cf5d3ed) - var x121 uint64 - var x122 uint64 - x121, x122 = bits.Add64(x120, x117, uint64(0x0)) - x123 := (uint64(fiatScalarUint1(x122)) + x118) - var x125 uint64 - _, x125 = bits.Add64(x103, x119, uint64(0x0)) - var x126 uint64 - var x127 uint64 - x126, x127 = bits.Add64(x105, x121, uint64(fiatScalarUint1(x125))) - var x128 uint64 - var x129 uint64 - x128, x129 = bits.Add64(x107, x123, uint64(fiatScalarUint1(x127))) - var x130 uint64 - var x131 uint64 - x130, x131 = bits.Add64(x109, x115, uint64(fiatScalarUint1(x129))) - var x132 uint64 - var x133 uint64 - x132, x133 = bits.Add64(x111, x116, uint64(fiatScalarUint1(x131))) - x134 := (uint64(fiatScalarUint1(x133)) + uint64(fiatScalarUint1(x112))) - var x135 uint64 - var x136 uint64 - x136, x135 = bits.Mul64(x3, arg2[3]) - var x137 uint64 - var x138 uint64 - x138, x137 = bits.Mul64(x3, arg2[2]) - var x139 uint64 - var x140 uint64 - x140, x139 = bits.Mul64(x3, arg2[1]) - var x141 uint64 - var x142 uint64 - x142, x141 = bits.Mul64(x3, arg2[0]) - var x143 uint64 - var x144 uint64 - x143, x144 = bits.Add64(x142, x139, uint64(0x0)) - var x145 uint64 - var x146 uint64 - x145, x146 = bits.Add64(x140, x137, uint64(fiatScalarUint1(x144))) - var x147 uint64 - var x148 uint64 - x147, x148 = bits.Add64(x138, x135, uint64(fiatScalarUint1(x146))) - x149 := (uint64(fiatScalarUint1(x148)) + x136) - var x150 uint64 - var x151 uint64 - x150, x151 = bits.Add64(x126, x141, uint64(0x0)) - var x152 uint64 - var x153 uint64 - x152, x153 = bits.Add64(x128, x143, uint64(fiatScalarUint1(x151))) - var x154 uint64 - var x155 uint64 - x154, x155 = bits.Add64(x130, x145, uint64(fiatScalarUint1(x153))) - var x156 uint64 - var x157 uint64 - x156, x157 = bits.Add64(x132, x147, uint64(fiatScalarUint1(x155))) - var x158 uint64 - var x159 uint64 - x158, x159 = bits.Add64(x134, x149, uint64(fiatScalarUint1(x157))) - var x160 uint64 - _, x160 = bits.Mul64(x150, 0xd2b51da312547e1b) - var x162 uint64 - var x163 uint64 - x163, x162 = bits.Mul64(x160, 0x1000000000000000) - var x164 uint64 - var x165 uint64 - x165, x164 = bits.Mul64(x160, 0x14def9dea2f79cd6) - var x166 uint64 - var x167 uint64 - x167, x166 = bits.Mul64(x160, 0x5812631a5cf5d3ed) - var x168 uint64 - var x169 uint64 - x168, x169 = bits.Add64(x167, x164, uint64(0x0)) - x170 := (uint64(fiatScalarUint1(x169)) + x165) - var x172 uint64 - _, x172 = bits.Add64(x150, x166, uint64(0x0)) - var x173 uint64 - var x174 uint64 - x173, x174 = bits.Add64(x152, x168, uint64(fiatScalarUint1(x172))) - var x175 uint64 - var x176 uint64 - x175, x176 = bits.Add64(x154, x170, uint64(fiatScalarUint1(x174))) - var x177 uint64 - var x178 uint64 - x177, x178 = bits.Add64(x156, x162, uint64(fiatScalarUint1(x176))) - var x179 uint64 - var x180 uint64 - x179, x180 = bits.Add64(x158, x163, uint64(fiatScalarUint1(x178))) - x181 := (uint64(fiatScalarUint1(x180)) + uint64(fiatScalarUint1(x159))) - var x182 uint64 - var x183 uint64 - x182, x183 = bits.Sub64(x173, 0x5812631a5cf5d3ed, uint64(0x0)) - var x184 uint64 - var x185 uint64 - x184, x185 = bits.Sub64(x175, 0x14def9dea2f79cd6, uint64(fiatScalarUint1(x183))) - var x186 uint64 - var x187 uint64 - x186, x187 = bits.Sub64(x177, uint64(0x0), uint64(fiatScalarUint1(x185))) - var x188 uint64 - var x189 uint64 - x188, x189 = bits.Sub64(x179, 0x1000000000000000, uint64(fiatScalarUint1(x187))) - var x191 uint64 - _, x191 = bits.Sub64(x181, uint64(0x0), uint64(fiatScalarUint1(x189))) - var x192 uint64 - fiatScalarCmovznzU64(&x192, fiatScalarUint1(x191), x182, x173) - var x193 uint64 - fiatScalarCmovznzU64(&x193, fiatScalarUint1(x191), x184, x175) - var x194 uint64 - fiatScalarCmovznzU64(&x194, fiatScalarUint1(x191), x186, x177) - var x195 uint64 - fiatScalarCmovznzU64(&x195, fiatScalarUint1(x191), x188, x179) - out1[0] = x192 - out1[1] = x193 - out1[2] = x194 - out1[3] = x195 -} - -// fiatScalarAdd adds two field elements in the Montgomery domain. -// -// Preconditions: -// -// 0 ≤ eval arg1 < m -// 0 ≤ eval arg2 < m -// -// Postconditions: -// -// eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) + eval (from_montgomery arg2)) mod m -// 0 ≤ eval out1 < m -func fiatScalarAdd(out1 *fiatScalarMontgomeryDomainFieldElement, arg1 *fiatScalarMontgomeryDomainFieldElement, arg2 *fiatScalarMontgomeryDomainFieldElement) { - var x1 uint64 - var x2 uint64 - x1, x2 = bits.Add64(arg1[0], arg2[0], uint64(0x0)) - var x3 uint64 - var x4 uint64 - x3, x4 = bits.Add64(arg1[1], arg2[1], uint64(fiatScalarUint1(x2))) - var x5 uint64 - var x6 uint64 - x5, x6 = bits.Add64(arg1[2], arg2[2], uint64(fiatScalarUint1(x4))) - var x7 uint64 - var x8 uint64 - x7, x8 = bits.Add64(arg1[3], arg2[3], uint64(fiatScalarUint1(x6))) - var x9 uint64 - var x10 uint64 - x9, x10 = bits.Sub64(x1, 0x5812631a5cf5d3ed, uint64(0x0)) - var x11 uint64 - var x12 uint64 - x11, x12 = bits.Sub64(x3, 0x14def9dea2f79cd6, uint64(fiatScalarUint1(x10))) - var x13 uint64 - var x14 uint64 - x13, x14 = bits.Sub64(x5, uint64(0x0), uint64(fiatScalarUint1(x12))) - var x15 uint64 - var x16 uint64 - x15, x16 = bits.Sub64(x7, 0x1000000000000000, uint64(fiatScalarUint1(x14))) - var x18 uint64 - _, x18 = bits.Sub64(uint64(fiatScalarUint1(x8)), uint64(0x0), uint64(fiatScalarUint1(x16))) - var x19 uint64 - fiatScalarCmovznzU64(&x19, fiatScalarUint1(x18), x9, x1) - var x20 uint64 - fiatScalarCmovznzU64(&x20, fiatScalarUint1(x18), x11, x3) - var x21 uint64 - fiatScalarCmovznzU64(&x21, fiatScalarUint1(x18), x13, x5) - var x22 uint64 - fiatScalarCmovznzU64(&x22, fiatScalarUint1(x18), x15, x7) - out1[0] = x19 - out1[1] = x20 - out1[2] = x21 - out1[3] = x22 -} - -// fiatScalarSub subtracts two field elements in the Montgomery domain. -// -// Preconditions: -// -// 0 ≤ eval arg1 < m -// 0 ≤ eval arg2 < m -// -// Postconditions: -// -// eval (from_montgomery out1) mod m = (eval (from_montgomery arg1) - eval (from_montgomery arg2)) mod m -// 0 ≤ eval out1 < m -func fiatScalarSub(out1 *fiatScalarMontgomeryDomainFieldElement, arg1 *fiatScalarMontgomeryDomainFieldElement, arg2 *fiatScalarMontgomeryDomainFieldElement) { - var x1 uint64 - var x2 uint64 - x1, x2 = bits.Sub64(arg1[0], arg2[0], uint64(0x0)) - var x3 uint64 - var x4 uint64 - x3, x4 = bits.Sub64(arg1[1], arg2[1], uint64(fiatScalarUint1(x2))) - var x5 uint64 - var x6 uint64 - x5, x6 = bits.Sub64(arg1[2], arg2[2], uint64(fiatScalarUint1(x4))) - var x7 uint64 - var x8 uint64 - x7, x8 = bits.Sub64(arg1[3], arg2[3], uint64(fiatScalarUint1(x6))) - var x9 uint64 - fiatScalarCmovznzU64(&x9, fiatScalarUint1(x8), uint64(0x0), 0xffffffffffffffff) - var x10 uint64 - var x11 uint64 - x10, x11 = bits.Add64(x1, (x9 & 0x5812631a5cf5d3ed), uint64(0x0)) - var x12 uint64 - var x13 uint64 - x12, x13 = bits.Add64(x3, (x9 & 0x14def9dea2f79cd6), uint64(fiatScalarUint1(x11))) - var x14 uint64 - var x15 uint64 - x14, x15 = bits.Add64(x5, uint64(0x0), uint64(fiatScalarUint1(x13))) - var x16 uint64 - x16, _ = bits.Add64(x7, (x9 & 0x1000000000000000), uint64(fiatScalarUint1(x15))) - out1[0] = x10 - out1[1] = x12 - out1[2] = x14 - out1[3] = x16 -} - -// fiatScalarOpp negates a field element in the Montgomery domain. -// -// Preconditions: -// -// 0 ≤ eval arg1 < m -// -// Postconditions: -// -// eval (from_montgomery out1) mod m = -eval (from_montgomery arg1) mod m -// 0 ≤ eval out1 < m -func fiatScalarOpp(out1 *fiatScalarMontgomeryDomainFieldElement, arg1 *fiatScalarMontgomeryDomainFieldElement) { - var x1 uint64 - var x2 uint64 - x1, x2 = bits.Sub64(uint64(0x0), arg1[0], uint64(0x0)) - var x3 uint64 - var x4 uint64 - x3, x4 = bits.Sub64(uint64(0x0), arg1[1], uint64(fiatScalarUint1(x2))) - var x5 uint64 - var x6 uint64 - x5, x6 = bits.Sub64(uint64(0x0), arg1[2], uint64(fiatScalarUint1(x4))) - var x7 uint64 - var x8 uint64 - x7, x8 = bits.Sub64(uint64(0x0), arg1[3], uint64(fiatScalarUint1(x6))) - var x9 uint64 - fiatScalarCmovznzU64(&x9, fiatScalarUint1(x8), uint64(0x0), 0xffffffffffffffff) - var x10 uint64 - var x11 uint64 - x10, x11 = bits.Add64(x1, (x9 & 0x5812631a5cf5d3ed), uint64(0x0)) - var x12 uint64 - var x13 uint64 - x12, x13 = bits.Add64(x3, (x9 & 0x14def9dea2f79cd6), uint64(fiatScalarUint1(x11))) - var x14 uint64 - var x15 uint64 - x14, x15 = bits.Add64(x5, uint64(0x0), uint64(fiatScalarUint1(x13))) - var x16 uint64 - x16, _ = bits.Add64(x7, (x9 & 0x1000000000000000), uint64(fiatScalarUint1(x15))) - out1[0] = x10 - out1[1] = x12 - out1[2] = x14 - out1[3] = x16 -} - -// fiatScalarNonzero outputs a single non-zero word if the input is non-zero and zero otherwise. -// -// Preconditions: -// -// 0 ≤ eval arg1 < m -// -// Postconditions: -// -// out1 = 0 ↔ eval (from_montgomery arg1) mod m = 0 -// -// Input Bounds: -// -// arg1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff]] -// -// Output Bounds: -// -// out1: [0x0 ~> 0xffffffffffffffff] -func fiatScalarNonzero(out1 *uint64, arg1 *[4]uint64) { - x1 := (arg1[0] | (arg1[1] | (arg1[2] | arg1[3]))) - *out1 = x1 -} - -// fiatScalarFromMontgomery translates a field element out of the Montgomery domain. -// -// Preconditions: -// -// 0 ≤ eval arg1 < m -// -// Postconditions: -// -// eval out1 mod m = (eval arg1 * ((2^64)⁻¹ mod m)^4) mod m -// 0 ≤ eval out1 < m -func fiatScalarFromMontgomery(out1 *fiatScalarNonMontgomeryDomainFieldElement, arg1 *fiatScalarMontgomeryDomainFieldElement) { - x1 := arg1[0] - var x2 uint64 - _, x2 = bits.Mul64(x1, 0xd2b51da312547e1b) - var x4 uint64 - var x5 uint64 - x5, x4 = bits.Mul64(x2, 0x1000000000000000) - var x6 uint64 - var x7 uint64 - x7, x6 = bits.Mul64(x2, 0x14def9dea2f79cd6) - var x8 uint64 - var x9 uint64 - x9, x8 = bits.Mul64(x2, 0x5812631a5cf5d3ed) - var x10 uint64 - var x11 uint64 - x10, x11 = bits.Add64(x9, x6, uint64(0x0)) - var x13 uint64 - _, x13 = bits.Add64(x1, x8, uint64(0x0)) - var x14 uint64 - var x15 uint64 - x14, x15 = bits.Add64(uint64(0x0), x10, uint64(fiatScalarUint1(x13))) - var x16 uint64 - var x17 uint64 - x16, x17 = bits.Add64(x14, arg1[1], uint64(0x0)) - var x18 uint64 - _, x18 = bits.Mul64(x16, 0xd2b51da312547e1b) - var x20 uint64 - var x21 uint64 - x21, x20 = bits.Mul64(x18, 0x1000000000000000) - var x22 uint64 - var x23 uint64 - x23, x22 = bits.Mul64(x18, 0x14def9dea2f79cd6) - var x24 uint64 - var x25 uint64 - x25, x24 = bits.Mul64(x18, 0x5812631a5cf5d3ed) - var x26 uint64 - var x27 uint64 - x26, x27 = bits.Add64(x25, x22, uint64(0x0)) - var x29 uint64 - _, x29 = bits.Add64(x16, x24, uint64(0x0)) - var x30 uint64 - var x31 uint64 - x30, x31 = bits.Add64((uint64(fiatScalarUint1(x17)) + (uint64(fiatScalarUint1(x15)) + (uint64(fiatScalarUint1(x11)) + x7))), x26, uint64(fiatScalarUint1(x29))) - var x32 uint64 - var x33 uint64 - x32, x33 = bits.Add64(x4, (uint64(fiatScalarUint1(x27)) + x23), uint64(fiatScalarUint1(x31))) - var x34 uint64 - var x35 uint64 - x34, x35 = bits.Add64(x5, x20, uint64(fiatScalarUint1(x33))) - var x36 uint64 - var x37 uint64 - x36, x37 = bits.Add64(x30, arg1[2], uint64(0x0)) - var x38 uint64 - var x39 uint64 - x38, x39 = bits.Add64(x32, uint64(0x0), uint64(fiatScalarUint1(x37))) - var x40 uint64 - var x41 uint64 - x40, x41 = bits.Add64(x34, uint64(0x0), uint64(fiatScalarUint1(x39))) - var x42 uint64 - _, x42 = bits.Mul64(x36, 0xd2b51da312547e1b) - var x44 uint64 - var x45 uint64 - x45, x44 = bits.Mul64(x42, 0x1000000000000000) - var x46 uint64 - var x47 uint64 - x47, x46 = bits.Mul64(x42, 0x14def9dea2f79cd6) - var x48 uint64 - var x49 uint64 - x49, x48 = bits.Mul64(x42, 0x5812631a5cf5d3ed) - var x50 uint64 - var x51 uint64 - x50, x51 = bits.Add64(x49, x46, uint64(0x0)) - var x53 uint64 - _, x53 = bits.Add64(x36, x48, uint64(0x0)) - var x54 uint64 - var x55 uint64 - x54, x55 = bits.Add64(x38, x50, uint64(fiatScalarUint1(x53))) - var x56 uint64 - var x57 uint64 - x56, x57 = bits.Add64(x40, (uint64(fiatScalarUint1(x51)) + x47), uint64(fiatScalarUint1(x55))) - var x58 uint64 - var x59 uint64 - x58, x59 = bits.Add64((uint64(fiatScalarUint1(x41)) + (uint64(fiatScalarUint1(x35)) + x21)), x44, uint64(fiatScalarUint1(x57))) - var x60 uint64 - var x61 uint64 - x60, x61 = bits.Add64(x54, arg1[3], uint64(0x0)) - var x62 uint64 - var x63 uint64 - x62, x63 = bits.Add64(x56, uint64(0x0), uint64(fiatScalarUint1(x61))) - var x64 uint64 - var x65 uint64 - x64, x65 = bits.Add64(x58, uint64(0x0), uint64(fiatScalarUint1(x63))) - var x66 uint64 - _, x66 = bits.Mul64(x60, 0xd2b51da312547e1b) - var x68 uint64 - var x69 uint64 - x69, x68 = bits.Mul64(x66, 0x1000000000000000) - var x70 uint64 - var x71 uint64 - x71, x70 = bits.Mul64(x66, 0x14def9dea2f79cd6) - var x72 uint64 - var x73 uint64 - x73, x72 = bits.Mul64(x66, 0x5812631a5cf5d3ed) - var x74 uint64 - var x75 uint64 - x74, x75 = bits.Add64(x73, x70, uint64(0x0)) - var x77 uint64 - _, x77 = bits.Add64(x60, x72, uint64(0x0)) - var x78 uint64 - var x79 uint64 - x78, x79 = bits.Add64(x62, x74, uint64(fiatScalarUint1(x77))) - var x80 uint64 - var x81 uint64 - x80, x81 = bits.Add64(x64, (uint64(fiatScalarUint1(x75)) + x71), uint64(fiatScalarUint1(x79))) - var x82 uint64 - var x83 uint64 - x82, x83 = bits.Add64((uint64(fiatScalarUint1(x65)) + (uint64(fiatScalarUint1(x59)) + x45)), x68, uint64(fiatScalarUint1(x81))) - x84 := (uint64(fiatScalarUint1(x83)) + x69) - var x85 uint64 - var x86 uint64 - x85, x86 = bits.Sub64(x78, 0x5812631a5cf5d3ed, uint64(0x0)) - var x87 uint64 - var x88 uint64 - x87, x88 = bits.Sub64(x80, 0x14def9dea2f79cd6, uint64(fiatScalarUint1(x86))) - var x89 uint64 - var x90 uint64 - x89, x90 = bits.Sub64(x82, uint64(0x0), uint64(fiatScalarUint1(x88))) - var x91 uint64 - var x92 uint64 - x91, x92 = bits.Sub64(x84, 0x1000000000000000, uint64(fiatScalarUint1(x90))) - var x94 uint64 - _, x94 = bits.Sub64(uint64(0x0), uint64(0x0), uint64(fiatScalarUint1(x92))) - var x95 uint64 - fiatScalarCmovznzU64(&x95, fiatScalarUint1(x94), x85, x78) - var x96 uint64 - fiatScalarCmovznzU64(&x96, fiatScalarUint1(x94), x87, x80) - var x97 uint64 - fiatScalarCmovznzU64(&x97, fiatScalarUint1(x94), x89, x82) - var x98 uint64 - fiatScalarCmovznzU64(&x98, fiatScalarUint1(x94), x91, x84) - out1[0] = x95 - out1[1] = x96 - out1[2] = x97 - out1[3] = x98 -} - -// fiatScalarToMontgomery translates a field element into the Montgomery domain. -// -// Preconditions: -// -// 0 ≤ eval arg1 < m -// -// Postconditions: -// -// eval (from_montgomery out1) mod m = eval arg1 mod m -// 0 ≤ eval out1 < m -func fiatScalarToMontgomery(out1 *fiatScalarMontgomeryDomainFieldElement, arg1 *fiatScalarNonMontgomeryDomainFieldElement) { - x1 := arg1[1] - x2 := arg1[2] - x3 := arg1[3] - x4 := arg1[0] - var x5 uint64 - var x6 uint64 - x6, x5 = bits.Mul64(x4, 0x399411b7c309a3d) - var x7 uint64 - var x8 uint64 - x8, x7 = bits.Mul64(x4, 0xceec73d217f5be65) - var x9 uint64 - var x10 uint64 - x10, x9 = bits.Mul64(x4, 0xd00e1ba768859347) - var x11 uint64 - var x12 uint64 - x12, x11 = bits.Mul64(x4, 0xa40611e3449c0f01) - var x13 uint64 - var x14 uint64 - x13, x14 = bits.Add64(x12, x9, uint64(0x0)) - var x15 uint64 - var x16 uint64 - x15, x16 = bits.Add64(x10, x7, uint64(fiatScalarUint1(x14))) - var x17 uint64 - var x18 uint64 - x17, x18 = bits.Add64(x8, x5, uint64(fiatScalarUint1(x16))) - var x19 uint64 - _, x19 = bits.Mul64(x11, 0xd2b51da312547e1b) - var x21 uint64 - var x22 uint64 - x22, x21 = bits.Mul64(x19, 0x1000000000000000) - var x23 uint64 - var x24 uint64 - x24, x23 = bits.Mul64(x19, 0x14def9dea2f79cd6) - var x25 uint64 - var x26 uint64 - x26, x25 = bits.Mul64(x19, 0x5812631a5cf5d3ed) - var x27 uint64 - var x28 uint64 - x27, x28 = bits.Add64(x26, x23, uint64(0x0)) - var x30 uint64 - _, x30 = bits.Add64(x11, x25, uint64(0x0)) - var x31 uint64 - var x32 uint64 - x31, x32 = bits.Add64(x13, x27, uint64(fiatScalarUint1(x30))) - var x33 uint64 - var x34 uint64 - x33, x34 = bits.Add64(x15, (uint64(fiatScalarUint1(x28)) + x24), uint64(fiatScalarUint1(x32))) - var x35 uint64 - var x36 uint64 - x35, x36 = bits.Add64(x17, x21, uint64(fiatScalarUint1(x34))) - var x37 uint64 - var x38 uint64 - x38, x37 = bits.Mul64(x1, 0x399411b7c309a3d) - var x39 uint64 - var x40 uint64 - x40, x39 = bits.Mul64(x1, 0xceec73d217f5be65) - var x41 uint64 - var x42 uint64 - x42, x41 = bits.Mul64(x1, 0xd00e1ba768859347) - var x43 uint64 - var x44 uint64 - x44, x43 = bits.Mul64(x1, 0xa40611e3449c0f01) - var x45 uint64 - var x46 uint64 - x45, x46 = bits.Add64(x44, x41, uint64(0x0)) - var x47 uint64 - var x48 uint64 - x47, x48 = bits.Add64(x42, x39, uint64(fiatScalarUint1(x46))) - var x49 uint64 - var x50 uint64 - x49, x50 = bits.Add64(x40, x37, uint64(fiatScalarUint1(x48))) - var x51 uint64 - var x52 uint64 - x51, x52 = bits.Add64(x31, x43, uint64(0x0)) - var x53 uint64 - var x54 uint64 - x53, x54 = bits.Add64(x33, x45, uint64(fiatScalarUint1(x52))) - var x55 uint64 - var x56 uint64 - x55, x56 = bits.Add64(x35, x47, uint64(fiatScalarUint1(x54))) - var x57 uint64 - var x58 uint64 - x57, x58 = bits.Add64(((uint64(fiatScalarUint1(x36)) + (uint64(fiatScalarUint1(x18)) + x6)) + x22), x49, uint64(fiatScalarUint1(x56))) - var x59 uint64 - _, x59 = bits.Mul64(x51, 0xd2b51da312547e1b) - var x61 uint64 - var x62 uint64 - x62, x61 = bits.Mul64(x59, 0x1000000000000000) - var x63 uint64 - var x64 uint64 - x64, x63 = bits.Mul64(x59, 0x14def9dea2f79cd6) - var x65 uint64 - var x66 uint64 - x66, x65 = bits.Mul64(x59, 0x5812631a5cf5d3ed) - var x67 uint64 - var x68 uint64 - x67, x68 = bits.Add64(x66, x63, uint64(0x0)) - var x70 uint64 - _, x70 = bits.Add64(x51, x65, uint64(0x0)) - var x71 uint64 - var x72 uint64 - x71, x72 = bits.Add64(x53, x67, uint64(fiatScalarUint1(x70))) - var x73 uint64 - var x74 uint64 - x73, x74 = bits.Add64(x55, (uint64(fiatScalarUint1(x68)) + x64), uint64(fiatScalarUint1(x72))) - var x75 uint64 - var x76 uint64 - x75, x76 = bits.Add64(x57, x61, uint64(fiatScalarUint1(x74))) - var x77 uint64 - var x78 uint64 - x78, x77 = bits.Mul64(x2, 0x399411b7c309a3d) - var x79 uint64 - var x80 uint64 - x80, x79 = bits.Mul64(x2, 0xceec73d217f5be65) - var x81 uint64 - var x82 uint64 - x82, x81 = bits.Mul64(x2, 0xd00e1ba768859347) - var x83 uint64 - var x84 uint64 - x84, x83 = bits.Mul64(x2, 0xa40611e3449c0f01) - var x85 uint64 - var x86 uint64 - x85, x86 = bits.Add64(x84, x81, uint64(0x0)) - var x87 uint64 - var x88 uint64 - x87, x88 = bits.Add64(x82, x79, uint64(fiatScalarUint1(x86))) - var x89 uint64 - var x90 uint64 - x89, x90 = bits.Add64(x80, x77, uint64(fiatScalarUint1(x88))) - var x91 uint64 - var x92 uint64 - x91, x92 = bits.Add64(x71, x83, uint64(0x0)) - var x93 uint64 - var x94 uint64 - x93, x94 = bits.Add64(x73, x85, uint64(fiatScalarUint1(x92))) - var x95 uint64 - var x96 uint64 - x95, x96 = bits.Add64(x75, x87, uint64(fiatScalarUint1(x94))) - var x97 uint64 - var x98 uint64 - x97, x98 = bits.Add64(((uint64(fiatScalarUint1(x76)) + (uint64(fiatScalarUint1(x58)) + (uint64(fiatScalarUint1(x50)) + x38))) + x62), x89, uint64(fiatScalarUint1(x96))) - var x99 uint64 - _, x99 = bits.Mul64(x91, 0xd2b51da312547e1b) - var x101 uint64 - var x102 uint64 - x102, x101 = bits.Mul64(x99, 0x1000000000000000) - var x103 uint64 - var x104 uint64 - x104, x103 = bits.Mul64(x99, 0x14def9dea2f79cd6) - var x105 uint64 - var x106 uint64 - x106, x105 = bits.Mul64(x99, 0x5812631a5cf5d3ed) - var x107 uint64 - var x108 uint64 - x107, x108 = bits.Add64(x106, x103, uint64(0x0)) - var x110 uint64 - _, x110 = bits.Add64(x91, x105, uint64(0x0)) - var x111 uint64 - var x112 uint64 - x111, x112 = bits.Add64(x93, x107, uint64(fiatScalarUint1(x110))) - var x113 uint64 - var x114 uint64 - x113, x114 = bits.Add64(x95, (uint64(fiatScalarUint1(x108)) + x104), uint64(fiatScalarUint1(x112))) - var x115 uint64 - var x116 uint64 - x115, x116 = bits.Add64(x97, x101, uint64(fiatScalarUint1(x114))) - var x117 uint64 - var x118 uint64 - x118, x117 = bits.Mul64(x3, 0x399411b7c309a3d) - var x119 uint64 - var x120 uint64 - x120, x119 = bits.Mul64(x3, 0xceec73d217f5be65) - var x121 uint64 - var x122 uint64 - x122, x121 = bits.Mul64(x3, 0xd00e1ba768859347) - var x123 uint64 - var x124 uint64 - x124, x123 = bits.Mul64(x3, 0xa40611e3449c0f01) - var x125 uint64 - var x126 uint64 - x125, x126 = bits.Add64(x124, x121, uint64(0x0)) - var x127 uint64 - var x128 uint64 - x127, x128 = bits.Add64(x122, x119, uint64(fiatScalarUint1(x126))) - var x129 uint64 - var x130 uint64 - x129, x130 = bits.Add64(x120, x117, uint64(fiatScalarUint1(x128))) - var x131 uint64 - var x132 uint64 - x131, x132 = bits.Add64(x111, x123, uint64(0x0)) - var x133 uint64 - var x134 uint64 - x133, x134 = bits.Add64(x113, x125, uint64(fiatScalarUint1(x132))) - var x135 uint64 - var x136 uint64 - x135, x136 = bits.Add64(x115, x127, uint64(fiatScalarUint1(x134))) - var x137 uint64 - var x138 uint64 - x137, x138 = bits.Add64(((uint64(fiatScalarUint1(x116)) + (uint64(fiatScalarUint1(x98)) + (uint64(fiatScalarUint1(x90)) + x78))) + x102), x129, uint64(fiatScalarUint1(x136))) - var x139 uint64 - _, x139 = bits.Mul64(x131, 0xd2b51da312547e1b) - var x141 uint64 - var x142 uint64 - x142, x141 = bits.Mul64(x139, 0x1000000000000000) - var x143 uint64 - var x144 uint64 - x144, x143 = bits.Mul64(x139, 0x14def9dea2f79cd6) - var x145 uint64 - var x146 uint64 - x146, x145 = bits.Mul64(x139, 0x5812631a5cf5d3ed) - var x147 uint64 - var x148 uint64 - x147, x148 = bits.Add64(x146, x143, uint64(0x0)) - var x150 uint64 - _, x150 = bits.Add64(x131, x145, uint64(0x0)) - var x151 uint64 - var x152 uint64 - x151, x152 = bits.Add64(x133, x147, uint64(fiatScalarUint1(x150))) - var x153 uint64 - var x154 uint64 - x153, x154 = bits.Add64(x135, (uint64(fiatScalarUint1(x148)) + x144), uint64(fiatScalarUint1(x152))) - var x155 uint64 - var x156 uint64 - x155, x156 = bits.Add64(x137, x141, uint64(fiatScalarUint1(x154))) - x157 := ((uint64(fiatScalarUint1(x156)) + (uint64(fiatScalarUint1(x138)) + (uint64(fiatScalarUint1(x130)) + x118))) + x142) - var x158 uint64 - var x159 uint64 - x158, x159 = bits.Sub64(x151, 0x5812631a5cf5d3ed, uint64(0x0)) - var x160 uint64 - var x161 uint64 - x160, x161 = bits.Sub64(x153, 0x14def9dea2f79cd6, uint64(fiatScalarUint1(x159))) - var x162 uint64 - var x163 uint64 - x162, x163 = bits.Sub64(x155, uint64(0x0), uint64(fiatScalarUint1(x161))) - var x164 uint64 - var x165 uint64 - x164, x165 = bits.Sub64(x157, 0x1000000000000000, uint64(fiatScalarUint1(x163))) - var x167 uint64 - _, x167 = bits.Sub64(uint64(0x0), uint64(0x0), uint64(fiatScalarUint1(x165))) - var x168 uint64 - fiatScalarCmovznzU64(&x168, fiatScalarUint1(x167), x158, x151) - var x169 uint64 - fiatScalarCmovznzU64(&x169, fiatScalarUint1(x167), x160, x153) - var x170 uint64 - fiatScalarCmovznzU64(&x170, fiatScalarUint1(x167), x162, x155) - var x171 uint64 - fiatScalarCmovznzU64(&x171, fiatScalarUint1(x167), x164, x157) - out1[0] = x168 - out1[1] = x169 - out1[2] = x170 - out1[3] = x171 -} - -// fiatScalarToBytes serializes a field element NOT in the Montgomery domain to bytes in little-endian order. -// -// Preconditions: -// -// 0 ≤ eval arg1 < m -// -// Postconditions: -// -// out1 = map (λ x, ⌊((eval arg1 mod m) mod 2^(8 * (x + 1))) / 2^(8 * x)⌋) [0..31] -// -// Input Bounds: -// -// arg1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0x1fffffffffffffff]] -// -// Output Bounds: -// -// out1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0x1f]] -func fiatScalarToBytes(out1 *[32]uint8, arg1 *[4]uint64) { - x1 := arg1[3] - x2 := arg1[2] - x3 := arg1[1] - x4 := arg1[0] - x5 := (uint8(x4) & 0xff) - x6 := (x4 >> 8) - x7 := (uint8(x6) & 0xff) - x8 := (x6 >> 8) - x9 := (uint8(x8) & 0xff) - x10 := (x8 >> 8) - x11 := (uint8(x10) & 0xff) - x12 := (x10 >> 8) - x13 := (uint8(x12) & 0xff) - x14 := (x12 >> 8) - x15 := (uint8(x14) & 0xff) - x16 := (x14 >> 8) - x17 := (uint8(x16) & 0xff) - x18 := uint8((x16 >> 8)) - x19 := (uint8(x3) & 0xff) - x20 := (x3 >> 8) - x21 := (uint8(x20) & 0xff) - x22 := (x20 >> 8) - x23 := (uint8(x22) & 0xff) - x24 := (x22 >> 8) - x25 := (uint8(x24) & 0xff) - x26 := (x24 >> 8) - x27 := (uint8(x26) & 0xff) - x28 := (x26 >> 8) - x29 := (uint8(x28) & 0xff) - x30 := (x28 >> 8) - x31 := (uint8(x30) & 0xff) - x32 := uint8((x30 >> 8)) - x33 := (uint8(x2) & 0xff) - x34 := (x2 >> 8) - x35 := (uint8(x34) & 0xff) - x36 := (x34 >> 8) - x37 := (uint8(x36) & 0xff) - x38 := (x36 >> 8) - x39 := (uint8(x38) & 0xff) - x40 := (x38 >> 8) - x41 := (uint8(x40) & 0xff) - x42 := (x40 >> 8) - x43 := (uint8(x42) & 0xff) - x44 := (x42 >> 8) - x45 := (uint8(x44) & 0xff) - x46 := uint8((x44 >> 8)) - x47 := (uint8(x1) & 0xff) - x48 := (x1 >> 8) - x49 := (uint8(x48) & 0xff) - x50 := (x48 >> 8) - x51 := (uint8(x50) & 0xff) - x52 := (x50 >> 8) - x53 := (uint8(x52) & 0xff) - x54 := (x52 >> 8) - x55 := (uint8(x54) & 0xff) - x56 := (x54 >> 8) - x57 := (uint8(x56) & 0xff) - x58 := (x56 >> 8) - x59 := (uint8(x58) & 0xff) - x60 := uint8((x58 >> 8)) - out1[0] = x5 - out1[1] = x7 - out1[2] = x9 - out1[3] = x11 - out1[4] = x13 - out1[5] = x15 - out1[6] = x17 - out1[7] = x18 - out1[8] = x19 - out1[9] = x21 - out1[10] = x23 - out1[11] = x25 - out1[12] = x27 - out1[13] = x29 - out1[14] = x31 - out1[15] = x32 - out1[16] = x33 - out1[17] = x35 - out1[18] = x37 - out1[19] = x39 - out1[20] = x41 - out1[21] = x43 - out1[22] = x45 - out1[23] = x46 - out1[24] = x47 - out1[25] = x49 - out1[26] = x51 - out1[27] = x53 - out1[28] = x55 - out1[29] = x57 - out1[30] = x59 - out1[31] = x60 -} - -// fiatScalarFromBytes deserializes a field element NOT in the Montgomery domain from bytes in little-endian order. -// -// Preconditions: -// -// 0 ≤ bytes_eval arg1 < m -// -// Postconditions: -// -// eval out1 mod m = bytes_eval arg1 mod m -// 0 ≤ eval out1 < m -// -// Input Bounds: -// -// arg1: [[0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0xff], [0x0 ~> 0x1f]] -// -// Output Bounds: -// -// out1: [[0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0xffffffffffffffff], [0x0 ~> 0x1fffffffffffffff]] -func fiatScalarFromBytes(out1 *[4]uint64, arg1 *[32]uint8) { - x1 := (uint64(arg1[31]) << 56) - x2 := (uint64(arg1[30]) << 48) - x3 := (uint64(arg1[29]) << 40) - x4 := (uint64(arg1[28]) << 32) - x5 := (uint64(arg1[27]) << 24) - x6 := (uint64(arg1[26]) << 16) - x7 := (uint64(arg1[25]) << 8) - x8 := arg1[24] - x9 := (uint64(arg1[23]) << 56) - x10 := (uint64(arg1[22]) << 48) - x11 := (uint64(arg1[21]) << 40) - x12 := (uint64(arg1[20]) << 32) - x13 := (uint64(arg1[19]) << 24) - x14 := (uint64(arg1[18]) << 16) - x15 := (uint64(arg1[17]) << 8) - x16 := arg1[16] - x17 := (uint64(arg1[15]) << 56) - x18 := (uint64(arg1[14]) << 48) - x19 := (uint64(arg1[13]) << 40) - x20 := (uint64(arg1[12]) << 32) - x21 := (uint64(arg1[11]) << 24) - x22 := (uint64(arg1[10]) << 16) - x23 := (uint64(arg1[9]) << 8) - x24 := arg1[8] - x25 := (uint64(arg1[7]) << 56) - x26 := (uint64(arg1[6]) << 48) - x27 := (uint64(arg1[5]) << 40) - x28 := (uint64(arg1[4]) << 32) - x29 := (uint64(arg1[3]) << 24) - x30 := (uint64(arg1[2]) << 16) - x31 := (uint64(arg1[1]) << 8) - x32 := arg1[0] - x33 := (x31 + uint64(x32)) - x34 := (x30 + x33) - x35 := (x29 + x34) - x36 := (x28 + x35) - x37 := (x27 + x36) - x38 := (x26 + x37) - x39 := (x25 + x38) - x40 := (x23 + uint64(x24)) - x41 := (x22 + x40) - x42 := (x21 + x41) - x43 := (x20 + x42) - x44 := (x19 + x43) - x45 := (x18 + x44) - x46 := (x17 + x45) - x47 := (x15 + uint64(x16)) - x48 := (x14 + x47) - x49 := (x13 + x48) - x50 := (x12 + x49) - x51 := (x11 + x50) - x52 := (x10 + x51) - x53 := (x9 + x52) - x54 := (x7 + uint64(x8)) - x55 := (x6 + x54) - x56 := (x5 + x55) - x57 := (x4 + x56) - x58 := (x3 + x57) - x59 := (x2 + x58) - x60 := (x1 + x59) - out1[0] = x39 - out1[1] = x46 - out1[2] = x53 - out1[3] = x60 -} diff --git a/v2/vendor/filippo.io/edwards25519/scalarmult.go b/v2/vendor/filippo.io/edwards25519/scalarmult.go deleted file mode 100644 index f7ca3ce..0000000 --- a/v2/vendor/filippo.io/edwards25519/scalarmult.go +++ /dev/null @@ -1,214 +0,0 @@ -// Copyright (c) 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package edwards25519 - -import "sync" - -// basepointTable is a set of 32 affineLookupTables, where table i is generated -// from 256i * basepoint. It is precomputed the first time it's used. -func basepointTable() *[32]affineLookupTable { - basepointTablePrecomp.initOnce.Do(func() { - p := NewGeneratorPoint() - for i := 0; i < 32; i++ { - basepointTablePrecomp.table[i].FromP3(p) - for j := 0; j < 8; j++ { - p.Add(p, p) - } - } - }) - return &basepointTablePrecomp.table -} - -var basepointTablePrecomp struct { - table [32]affineLookupTable - initOnce sync.Once -} - -// ScalarBaseMult sets v = x * B, where B is the canonical generator, and -// returns v. -// -// The scalar multiplication is done in constant time. -func (v *Point) ScalarBaseMult(x *Scalar) *Point { - basepointTable := basepointTable() - - // Write x = sum(x_i * 16^i) so x*B = sum( B*x_i*16^i ) - // as described in the Ed25519 paper - // - // Group even and odd coefficients - // x*B = x_0*16^0*B + x_2*16^2*B + ... + x_62*16^62*B - // + x_1*16^1*B + x_3*16^3*B + ... + x_63*16^63*B - // x*B = x_0*16^0*B + x_2*16^2*B + ... + x_62*16^62*B - // + 16*( x_1*16^0*B + x_3*16^2*B + ... + x_63*16^62*B) - // - // We use a lookup table for each i to get x_i*16^(2*i)*B - // and do four doublings to multiply by 16. - digits := x.signedRadix16() - - multiple := &affineCached{} - tmp1 := &projP1xP1{} - tmp2 := &projP2{} - - // Accumulate the odd components first - v.Set(NewIdentityPoint()) - for i := 1; i < 64; i += 2 { - basepointTable[i/2].SelectInto(multiple, digits[i]) - tmp1.AddAffine(v, multiple) - v.fromP1xP1(tmp1) - } - - // Multiply by 16 - tmp2.FromP3(v) // tmp2 = v in P2 coords - tmp1.Double(tmp2) // tmp1 = 2*v in P1xP1 coords - tmp2.FromP1xP1(tmp1) // tmp2 = 2*v in P2 coords - tmp1.Double(tmp2) // tmp1 = 4*v in P1xP1 coords - tmp2.FromP1xP1(tmp1) // tmp2 = 4*v in P2 coords - tmp1.Double(tmp2) // tmp1 = 8*v in P1xP1 coords - tmp2.FromP1xP1(tmp1) // tmp2 = 8*v in P2 coords - tmp1.Double(tmp2) // tmp1 = 16*v in P1xP1 coords - v.fromP1xP1(tmp1) // now v = 16*(odd components) - - // Accumulate the even components - for i := 0; i < 64; i += 2 { - basepointTable[i/2].SelectInto(multiple, digits[i]) - tmp1.AddAffine(v, multiple) - v.fromP1xP1(tmp1) - } - - return v -} - -// ScalarMult sets v = x * q, and returns v. -// -// The scalar multiplication is done in constant time. -func (v *Point) ScalarMult(x *Scalar, q *Point) *Point { - checkInitialized(q) - - var table projLookupTable - table.FromP3(q) - - // Write x = sum(x_i * 16^i) - // so x*Q = sum( Q*x_i*16^i ) - // = Q*x_0 + 16*(Q*x_1 + 16*( ... + Q*x_63) ... ) - // <------compute inside out--------- - // - // We use the lookup table to get the x_i*Q values - // and do four doublings to compute 16*Q - digits := x.signedRadix16() - - // Unwrap first loop iteration to save computing 16*identity - multiple := &projCached{} - tmp1 := &projP1xP1{} - tmp2 := &projP2{} - table.SelectInto(multiple, digits[63]) - - v.Set(NewIdentityPoint()) - tmp1.Add(v, multiple) // tmp1 = x_63*Q in P1xP1 coords - for i := 62; i >= 0; i-- { - tmp2.FromP1xP1(tmp1) // tmp2 = (prev) in P2 coords - tmp1.Double(tmp2) // tmp1 = 2*(prev) in P1xP1 coords - tmp2.FromP1xP1(tmp1) // tmp2 = 2*(prev) in P2 coords - tmp1.Double(tmp2) // tmp1 = 4*(prev) in P1xP1 coords - tmp2.FromP1xP1(tmp1) // tmp2 = 4*(prev) in P2 coords - tmp1.Double(tmp2) // tmp1 = 8*(prev) in P1xP1 coords - tmp2.FromP1xP1(tmp1) // tmp2 = 8*(prev) in P2 coords - tmp1.Double(tmp2) // tmp1 = 16*(prev) in P1xP1 coords - v.fromP1xP1(tmp1) // v = 16*(prev) in P3 coords - table.SelectInto(multiple, digits[i]) - tmp1.Add(v, multiple) // tmp1 = x_i*Q + 16*(prev) in P1xP1 coords - } - v.fromP1xP1(tmp1) - return v -} - -// basepointNafTable is the nafLookupTable8 for the basepoint. -// It is precomputed the first time it's used. -func basepointNafTable() *nafLookupTable8 { - basepointNafTablePrecomp.initOnce.Do(func() { - basepointNafTablePrecomp.table.FromP3(NewGeneratorPoint()) - }) - return &basepointNafTablePrecomp.table -} - -var basepointNafTablePrecomp struct { - table nafLookupTable8 - initOnce sync.Once -} - -// VarTimeDoubleScalarBaseMult sets v = a * A + b * B, where B is the canonical -// generator, and returns v. -// -// Execution time depends on the inputs. -func (v *Point) VarTimeDoubleScalarBaseMult(a *Scalar, A *Point, b *Scalar) *Point { - checkInitialized(A) - - // Similarly to the single variable-base approach, we compute - // digits and use them with a lookup table. However, because - // we are allowed to do variable-time operations, we don't - // need constant-time lookups or constant-time digit - // computations. - // - // So we use a non-adjacent form of some width w instead of - // radix 16. This is like a binary representation (one digit - // for each binary place) but we allow the digits to grow in - // magnitude up to 2^{w-1} so that the nonzero digits are as - // sparse as possible. Intuitively, this "condenses" the - // "mass" of the scalar onto sparse coefficients (meaning - // fewer additions). - - basepointNafTable := basepointNafTable() - var aTable nafLookupTable5 - aTable.FromP3(A) - // Because the basepoint is fixed, we can use a wider NAF - // corresponding to a bigger table. - aNaf := a.nonAdjacentForm(5) - bNaf := b.nonAdjacentForm(8) - - // Find the first nonzero coefficient. - i := 255 - for j := i; j >= 0; j-- { - if aNaf[j] != 0 || bNaf[j] != 0 { - break - } - } - - multA := &projCached{} - multB := &affineCached{} - tmp1 := &projP1xP1{} - tmp2 := &projP2{} - tmp2.Zero() - - // Move from high to low bits, doubling the accumulator - // at each iteration and checking whether there is a nonzero - // coefficient to look up a multiple of. - for ; i >= 0; i-- { - tmp1.Double(tmp2) - - // Only update v if we have a nonzero coeff to add in. - if aNaf[i] > 0 { - v.fromP1xP1(tmp1) - aTable.SelectInto(multA, aNaf[i]) - tmp1.Add(v, multA) - } else if aNaf[i] < 0 { - v.fromP1xP1(tmp1) - aTable.SelectInto(multA, -aNaf[i]) - tmp1.Sub(v, multA) - } - - if bNaf[i] > 0 { - v.fromP1xP1(tmp1) - basepointNafTable.SelectInto(multB, bNaf[i]) - tmp1.AddAffine(v, multB) - } else if bNaf[i] < 0 { - v.fromP1xP1(tmp1) - basepointNafTable.SelectInto(multB, -bNaf[i]) - tmp1.SubAffine(v, multB) - } - - tmp2.FromP1xP1(tmp1) - } - - v.fromP2(tmp2) - return v -} diff --git a/v2/vendor/filippo.io/edwards25519/tables.go b/v2/vendor/filippo.io/edwards25519/tables.go deleted file mode 100644 index 83234bb..0000000 --- a/v2/vendor/filippo.io/edwards25519/tables.go +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright (c) 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package edwards25519 - -import ( - "crypto/subtle" -) - -// A dynamic lookup table for variable-base, constant-time scalar muls. -type projLookupTable struct { - points [8]projCached -} - -// A precomputed lookup table for fixed-base, constant-time scalar muls. -type affineLookupTable struct { - points [8]affineCached -} - -// A dynamic lookup table for variable-base, variable-time scalar muls. -type nafLookupTable5 struct { - points [8]projCached -} - -// A precomputed lookup table for fixed-base, variable-time scalar muls. -type nafLookupTable8 struct { - points [64]affineCached -} - -// Constructors. - -// Builds a lookup table at runtime. Fast. -func (v *projLookupTable) FromP3(q *Point) { - // Goal: v.points[i] = (i+1)*Q, i.e., Q, 2Q, ..., 8Q - // This allows lookup of -8Q, ..., -Q, 0, Q, ..., 8Q - v.points[0].FromP3(q) - tmpP3 := Point{} - tmpP1xP1 := projP1xP1{} - for i := 0; i < 7; i++ { - // Compute (i+1)*Q as Q + i*Q and convert to a projCached - // This is needlessly complicated because the API has explicit - // receivers instead of creating stack objects and relying on RVO - v.points[i+1].FromP3(tmpP3.fromP1xP1(tmpP1xP1.Add(q, &v.points[i]))) - } -} - -// This is not optimised for speed; fixed-base tables should be precomputed. -func (v *affineLookupTable) FromP3(q *Point) { - // Goal: v.points[i] = (i+1)*Q, i.e., Q, 2Q, ..., 8Q - // This allows lookup of -8Q, ..., -Q, 0, Q, ..., 8Q - v.points[0].FromP3(q) - tmpP3 := Point{} - tmpP1xP1 := projP1xP1{} - for i := 0; i < 7; i++ { - // Compute (i+1)*Q as Q + i*Q and convert to affineCached - v.points[i+1].FromP3(tmpP3.fromP1xP1(tmpP1xP1.AddAffine(q, &v.points[i]))) - } -} - -// Builds a lookup table at runtime. Fast. -func (v *nafLookupTable5) FromP3(q *Point) { - // Goal: v.points[i] = (2*i+1)*Q, i.e., Q, 3Q, 5Q, ..., 15Q - // This allows lookup of -15Q, ..., -3Q, -Q, 0, Q, 3Q, ..., 15Q - v.points[0].FromP3(q) - q2 := Point{} - q2.Add(q, q) - tmpP3 := Point{} - tmpP1xP1 := projP1xP1{} - for i := 0; i < 7; i++ { - v.points[i+1].FromP3(tmpP3.fromP1xP1(tmpP1xP1.Add(&q2, &v.points[i]))) - } -} - -// This is not optimised for speed; fixed-base tables should be precomputed. -func (v *nafLookupTable8) FromP3(q *Point) { - v.points[0].FromP3(q) - q2 := Point{} - q2.Add(q, q) - tmpP3 := Point{} - tmpP1xP1 := projP1xP1{} - for i := 0; i < 63; i++ { - v.points[i+1].FromP3(tmpP3.fromP1xP1(tmpP1xP1.AddAffine(&q2, &v.points[i]))) - } -} - -// Selectors. - -// Set dest to x*Q, where -8 <= x <= 8, in constant time. -func (v *projLookupTable) SelectInto(dest *projCached, x int8) { - // Compute xabs = |x| - xmask := x >> 7 - xabs := uint8((x + xmask) ^ xmask) - - dest.Zero() - for j := 1; j <= 8; j++ { - // Set dest = j*Q if |x| = j - cond := subtle.ConstantTimeByteEq(xabs, uint8(j)) - dest.Select(&v.points[j-1], dest, cond) - } - // Now dest = |x|*Q, conditionally negate to get x*Q - dest.CondNeg(int(xmask & 1)) -} - -// Set dest to x*Q, where -8 <= x <= 8, in constant time. -func (v *affineLookupTable) SelectInto(dest *affineCached, x int8) { - // Compute xabs = |x| - xmask := x >> 7 - xabs := uint8((x + xmask) ^ xmask) - - dest.Zero() - for j := 1; j <= 8; j++ { - // Set dest = j*Q if |x| = j - cond := subtle.ConstantTimeByteEq(xabs, uint8(j)) - dest.Select(&v.points[j-1], dest, cond) - } - // Now dest = |x|*Q, conditionally negate to get x*Q - dest.CondNeg(int(xmask & 1)) -} - -// Given odd x with 0 < x < 2^4, return x*Q (in variable time). -func (v *nafLookupTable5) SelectInto(dest *projCached, x int8) { - *dest = v.points[x/2] -} - -// Given odd x with 0 < x < 2^7, return x*Q (in variable time). -func (v *nafLookupTable8) SelectInto(dest *affineCached, x int8) { - *dest = v.points[x/2] -} diff --git a/v2/vendor/github.com/go-mysql-org/go-mysql/LICENSE b/v2/vendor/github.com/go-mysql-org/go-mysql/LICENSE new file mode 100644 index 0000000..80511a0 --- /dev/null +++ b/v2/vendor/github.com/go-mysql-org/go-mysql/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2014 siddontang + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/v2/vendor/github.com/go-mysql-org/go-mysql/client/auth.go b/v2/vendor/github.com/go-mysql-org/go-mysql/client/auth.go new file mode 100644 index 0000000..eb2db6e --- /dev/null +++ b/v2/vendor/github.com/go-mysql-org/go-mysql/client/auth.go @@ -0,0 +1,297 @@ +package client + +import ( + "bytes" + "crypto/tls" + "encoding/binary" + "fmt" + + . "github.com/go-mysql-org/go-mysql/mysql" + "github.com/go-mysql-org/go-mysql/packet" + "github.com/pingcap/errors" +) + +const defaultAuthPluginName = AUTH_NATIVE_PASSWORD + +// defines the supported auth plugins +var supportedAuthPlugins = []string{AUTH_NATIVE_PASSWORD, AUTH_SHA256_PASSWORD, AUTH_CACHING_SHA2_PASSWORD} + +// helper function to determine what auth methods are allowed by this client +func authPluginAllowed(pluginName string) bool { + for _, p := range supportedAuthPlugins { + if pluginName == p { + return true + } + } + return false +} + +// See: http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::Handshake +func (c *Conn) readInitialHandshake() error { + data, err := c.ReadPacket() + if err != nil { + return errors.Trace(err) + } + + if data[0] == ERR_HEADER { + return errors.Annotate(c.handleErrorPacket(data), "read initial handshake error") + } + + if data[0] < MinProtocolVersion { + return errors.Errorf("invalid protocol version %d, must >= 10", data[0]) + } + + // skip mysql version + // mysql version end with 0x00 + pos := 1 + bytes.IndexByte(data[1:], 0x00) + 1 + + // connection id length is 4 + c.connectionID = binary.LittleEndian.Uint32(data[pos : pos+4]) + pos += 4 + + c.salt = []byte{} + c.salt = append(c.salt, data[pos:pos+8]...) + + // skip filter + pos += 8 + 1 + + // capability lower 2 bytes + c.capability = uint32(binary.LittleEndian.Uint16(data[pos : pos+2])) + // check protocol + if c.capability&CLIENT_PROTOCOL_41 == 0 { + return errors.New("the MySQL server can not support protocol 41 and above required by the client") + } + if c.capability&CLIENT_SSL == 0 && c.tlsConfig != nil { + return errors.New("the MySQL Server does not support TLS required by the client") + } + pos += 2 + + if len(data) > pos { + // skip server charset + //c.charset = data[pos] + pos += 1 + + c.status = binary.LittleEndian.Uint16(data[pos : pos+2]) + pos += 2 + // capability flags (upper 2 bytes) + c.capability = uint32(binary.LittleEndian.Uint16(data[pos:pos+2]))<<16 | c.capability + pos += 2 + + // auth_data is end with 0x00, min data length is 13 + 8 = 21 + // ref to https://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::Handshake + maxAuthDataLen := 21 + if c.capability&CLIENT_PLUGIN_AUTH != 0 && int(data[pos]) > maxAuthDataLen { + maxAuthDataLen = int(data[pos]) + } + + // skip reserved (all [00]) + pos += 10 + 1 + + // auth_data is end with 0x00, so we need to trim 0x00 + resetOfAuthDataEndPos := pos + maxAuthDataLen - 8 - 1 + c.salt = append(c.salt, data[pos:resetOfAuthDataEndPos]...) + + // skip reset of end pos + pos = resetOfAuthDataEndPos + 1 + + if c.capability&CLIENT_PLUGIN_AUTH != 0 { + c.authPluginName = string(data[pos : len(data)-1]) + } + } + + // if server gives no default auth plugin name, use a client default + if c.authPluginName == "" { + c.authPluginName = defaultAuthPluginName + } + + return nil +} + +// generate auth response data according to auth plugin +// +// NOTE: the returned boolean value indicates whether to add a \NUL to the end of data. +// it is quite tricky because MySQL server expects different formats of responses in different auth situations. +// here the \NUL needs to be added when sending back the empty password or cleartext password in 'sha256_password' +// authentication. +func (c *Conn) genAuthResponse(authData []byte) ([]byte, bool, error) { + // password hashing + switch c.authPluginName { + case AUTH_NATIVE_PASSWORD: + return CalcPassword(authData[:20], []byte(c.password)), false, nil + case AUTH_CACHING_SHA2_PASSWORD: + return CalcCachingSha2Password(authData, c.password), false, nil + case AUTH_CLEAR_PASSWORD: + return []byte(c.password), true, nil + case AUTH_SHA256_PASSWORD: + if len(c.password) == 0 { + return nil, true, nil + } + if c.tlsConfig != nil || c.proto == "unix" { + // write cleartext auth packet + // see: https://dev.mysql.com/doc/refman/8.0/en/sha256-pluggable-authentication.html + return []byte(c.password), true, nil + } else { + // request public key from server + // see: https://dev.mysql.com/doc/internals/en/public-key-retrieval.html + return []byte{1}, false, nil + } + default: + // not reachable + return nil, false, fmt.Errorf("auth plugin '%s' is not supported", c.authPluginName) + } +} + +// generate connection attributes data +func (c *Conn) genAttributes() []byte { + if len(c.attributes) == 0 { + return nil + } + + attrData := make([]byte, 0) + for k, v := range c.attributes { + attrData = append(attrData, PutLengthEncodedString([]byte(k))...) + attrData = append(attrData, PutLengthEncodedString([]byte(v))...) + } + return append(PutLengthEncodedInt(uint64(len(attrData))), attrData...) +} + +// See: http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::HandshakeResponse +func (c *Conn) writeAuthHandshake() error { + if !authPluginAllowed(c.authPluginName) { + return fmt.Errorf("unknow auth plugin name '%s'", c.authPluginName) + } + + // Set default client capabilities that reflect the abilities of this library + capability := CLIENT_PROTOCOL_41 | CLIENT_SECURE_CONNECTION | + CLIENT_LONG_PASSWORD | CLIENT_TRANSACTIONS | CLIENT_PLUGIN_AUTH + // Adjust client capability flags based on server support + capability |= c.capability & CLIENT_LONG_FLAG + // Adjust client capability flags on specific client requests + // Only flags that would make any sense setting and aren't handled elsewhere + // in the library are supported here + capability |= c.ccaps&CLIENT_FOUND_ROWS | c.ccaps&CLIENT_IGNORE_SPACE | + c.ccaps&CLIENT_MULTI_STATEMENTS | c.ccaps&CLIENT_MULTI_RESULTS | + c.ccaps&CLIENT_PS_MULTI_RESULTS | c.ccaps&CLIENT_CONNECT_ATTRS + + // To enable TLS / SSL + if c.tlsConfig != nil { + capability |= CLIENT_SSL + } + + auth, addNull, err := c.genAuthResponse(c.salt) + if err != nil { + return err + } + + // encode length of the auth plugin data + // here we use the Length-Encoded-Integer(LEI) as the data length may not fit into one byte + // see: https://dev.mysql.com/doc/internals/en/integer.html#length-encoded-integer + var authRespLEIBuf [9]byte + authRespLEI := AppendLengthEncodedInteger(authRespLEIBuf[:0], uint64(len(auth))) + if len(authRespLEI) > 1 { + // if the length can not be written in 1 byte, it must be written as a + // length encoded integer + capability |= CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA + } + + //packet length + //capability 4 + //max-packet size 4 + //charset 1 + //reserved all[0] 23 + //username + //auth + //mysql_native_password + null-terminated + length := 4 + 4 + 1 + 23 + len(c.user) + 1 + len(authRespLEI) + len(auth) + 21 + 1 + if addNull { + length++ + } + // db name + if len(c.db) > 0 { + capability |= CLIENT_CONNECT_WITH_DB + length += len(c.db) + 1 + } + // connection attributes + attrData := c.genAttributes() + if len(attrData) > 0 { + capability |= CLIENT_CONNECT_ATTRS + length += len(attrData) + } + + data := make([]byte, length+4) + + // capability [32 bit] + data[4] = byte(capability) + data[5] = byte(capability >> 8) + data[6] = byte(capability >> 16) + data[7] = byte(capability >> 24) + + // MaxPacketSize [32 bit] (none) + data[8] = 0x00 + data[9] = 0x00 + data[10] = 0x00 + data[11] = 0x00 + + // Charset [1 byte] + // use default collation id 33 here, is utf-8 + data[12] = DEFAULT_COLLATION_ID + + // SSL Connection Request Packet + // http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::SSLRequest + if c.tlsConfig != nil { + // Send TLS / SSL request packet + if err := c.WritePacket(data[:(4+4+1+23)+4]); err != nil { + return err + } + + // Switch to TLS + tlsConn := tls.Client(c.Conn.Conn, c.tlsConfig) + if err := tlsConn.Handshake(); err != nil { + return err + } + + currentSequence := c.Sequence + c.Conn = packet.NewConn(tlsConn) + c.Sequence = currentSequence + } + + // Filler [23 bytes] (all 0x00) + pos := 13 + for ; pos < 13+23; pos++ { + data[pos] = 0 + } + + // User [null terminated string] + if len(c.user) > 0 { + pos += copy(data[pos:], c.user) + } + data[pos] = 0x00 + pos++ + + // auth [length encoded integer] + pos += copy(data[pos:], authRespLEI) + pos += copy(data[pos:], auth) + if addNull { + data[pos] = 0x00 + pos++ + } + + // db [null terminated string] + if len(c.db) > 0 { + pos += copy(data[pos:], c.db) + data[pos] = 0x00 + pos++ + } + + // Assume native client during response + pos += copy(data[pos:], c.authPluginName) + data[pos] = 0x00 + pos++ + + // connection attributes + if len(attrData) > 0 { + copy(data[pos:], attrData) + } + + return c.WritePacket(data) +} diff --git a/v2/vendor/github.com/go-mysql-org/go-mysql/client/conn.go b/v2/vendor/github.com/go-mysql-org/go-mysql/client/conn.go new file mode 100644 index 0000000..5b65af8 --- /dev/null +++ b/v2/vendor/github.com/go-mysql-org/go-mysql/client/conn.go @@ -0,0 +1,400 @@ +package client + +import ( + "bytes" + "context" + "crypto/tls" + "fmt" + "net" + "strings" + "time" + + . "github.com/go-mysql-org/go-mysql/mysql" + "github.com/go-mysql-org/go-mysql/packet" + "github.com/go-mysql-org/go-mysql/utils" + "github.com/pingcap/errors" +) + +type Conn struct { + *packet.Conn + + user string + password string + db string + tlsConfig *tls.Config + proto string + + // server capabilities + capability uint32 + // client-set capabilities only + ccaps uint32 + + attributes map[string]string + + status uint16 + + charset string + + salt []byte + authPluginName string + + connectionID uint32 +} + +// This function will be called for every row in resultset from ExecuteSelectStreaming. +type SelectPerRowCallback func(row []FieldValue) error + +// This function will be called once per result from ExecuteSelectStreaming +type SelectPerResultCallback func(result *Result) error + +// This function will be called once per result from ExecuteMultiple +type ExecPerResultCallback func(result *Result, err error) + +func getNetProto(addr string) string { + proto := "tcp" + if strings.Contains(addr, "/") { + proto = "unix" + } + return proto +} + +// Connect to a MySQL server, addr can be ip:port, or a unix socket domain like /var/sock. +// Accepts a series of configuration functions as a variadic argument. +func Connect(addr string, user string, password string, dbName string, options ...func(*Conn)) (*Conn, error) { + ctx, cancel := context.WithTimeout(context.Background(), time.Second*10) + defer cancel() + + dialer := &net.Dialer{} + + return ConnectWithDialer(ctx, "", addr, user, password, dbName, dialer.DialContext, options...) +} + +// Dialer connects to the address on the named network using the provided context. +type Dialer func(ctx context.Context, network, address string) (net.Conn, error) + +// Connect to a MySQL server using the given Dialer. +func ConnectWithDialer(ctx context.Context, network string, addr string, user string, password string, dbName string, dialer Dialer, options ...func(*Conn)) (*Conn, error) { + c := new(Conn) + + if network == "" { + network = getNetProto(addr) + } + + var err error + conn, err := dialer(ctx, network, addr) + if err != nil { + return nil, errors.Trace(err) + } + + c.user = user + c.password = password + c.db = dbName + c.proto = network + c.Conn = packet.NewConn(conn) + + // use default charset here, utf-8 + c.charset = DEFAULT_CHARSET + + // Apply configuration functions. + for i := range options { + options[i](c) + } + + if c.tlsConfig != nil { + seq := c.Conn.Sequence + c.Conn = packet.NewTLSConn(conn) + c.Conn.Sequence = seq + } + + if err = c.handshake(); err != nil { + return nil, errors.Trace(err) + } + + return c, nil +} + +func (c *Conn) handshake() error { + var err error + if err = c.readInitialHandshake(); err != nil { + c.Close() + return errors.Trace(err) + } + + if err := c.writeAuthHandshake(); err != nil { + c.Close() + + return errors.Trace(err) + } + + if err := c.handleAuthResult(); err != nil { + c.Close() + return errors.Trace(err) + } + + return nil +} + +func (c *Conn) Close() error { + return c.Conn.Close() +} + +func (c *Conn) Ping() error { + if err := c.writeCommand(COM_PING); err != nil { + return errors.Trace(err) + } + + if _, err := c.readOK(); err != nil { + return errors.Trace(err) + } + + return nil +} + +// SetCapability enables the use of a specific capability +func (c *Conn) SetCapability(cap uint32) { + c.ccaps |= cap +} + +// UnsetCapability disables the use of a specific capability +func (c *Conn) UnsetCapability(cap uint32) { + c.ccaps &= ^cap +} + +// UseSSL: use default SSL +// pass to options when connect +func (c *Conn) UseSSL(insecureSkipVerify bool) { + c.tlsConfig = &tls.Config{InsecureSkipVerify: insecureSkipVerify} +} + +// SetTLSConfig: use user-specified TLS config +// pass to options when connect +func (c *Conn) SetTLSConfig(config *tls.Config) { + c.tlsConfig = config +} + +func (c *Conn) UseDB(dbName string) error { + if c.db == dbName { + return nil + } + + if err := c.writeCommandStr(COM_INIT_DB, dbName); err != nil { + return errors.Trace(err) + } + + if _, err := c.readOK(); err != nil { + return errors.Trace(err) + } + + c.db = dbName + return nil +} + +func (c *Conn) GetDB() string { + return c.db +} + +func (c *Conn) Execute(command string, args ...interface{}) (*Result, error) { + if len(args) == 0 { + return c.exec(command) + } else { + if s, err := c.Prepare(command); err != nil { + return nil, errors.Trace(err) + } else { + var r *Result + r, err = s.Execute(args...) + s.Close() + return r, err + } + } +} + +// ExecuteMultiple will call perResultCallback for every result of the multiple queries +// that are executed. +// +// When ExecuteMultiple is used, the connection should have the SERVER_MORE_RESULTS_EXISTS +// flag set to signal the server multiple queries are executed. Handling the responses +// is up to the implementation of perResultCallback. +// +// Example: +// +// queries := "SELECT 1; SELECT NOW();" +// conn.ExecuteMultiple(queries, func(result *mysql.Result, err error) { +// // Use the result as you want +// }) +func (c *Conn) ExecuteMultiple(query string, perResultCallback ExecPerResultCallback) (*Result, error) { + if err := c.writeCommandStr(COM_QUERY, query); err != nil { + return nil, errors.Trace(err) + } + + var err error + var result *Result + + bs := utils.ByteSliceGet(16) + defer utils.ByteSlicePut(bs) + + for { + bs.B, err = c.ReadPacketReuseMem(bs.B[:0]) + if err != nil { + return nil, errors.Trace(err) + } + + switch bs.B[0] { + case OK_HEADER: + result, err = c.handleOKPacket(bs.B) + case ERR_HEADER: + err = c.handleErrorPacket(bytes.Repeat(bs.B, 1)) + result = nil + case LocalInFile_HEADER: + err = ErrMalformPacket + result = nil + default: + result, err = c.readResultset(bs.B, false) + } + // call user-defined callback + perResultCallback(result, err) + + // if there was an error of this was the last result, stop looping + if err != nil || result.Status&SERVER_MORE_RESULTS_EXISTS == 0 { + break + } + } + + // return an empty result(set) signaling we're done streaming a multiple + // streaming session + // if this would end up in WriteValue, it would just be ignored as all + // responses should have been handled in perResultCallback + return &Result{Resultset: &Resultset{ + Streaming: StreamingMultiple, + StreamingDone: true, + }}, nil +} + +// ExecuteSelectStreaming will call perRowCallback for every row in resultset +// WITHOUT saving any row data to Result.{Values/RawPkg/RowDatas} fields. +// When given, perResultCallback will be called once per result +// +// ExecuteSelectStreaming should be used only for SELECT queries with a large response resultset for memory preserving. +// +// Example: +// +// var result mysql.Result +// conn.ExecuteSelectStreaming(`SELECT ... LIMIT 100500`, &result, func(row []mysql.FieldValue) error { +// // Use the row as you want. +// // You must not save FieldValue.AsString() value after this callback is done. Copy it if you need. +// return nil +// }, nil) +func (c *Conn) ExecuteSelectStreaming(command string, result *Result, perRowCallback SelectPerRowCallback, perResultCallback SelectPerResultCallback) error { + if err := c.writeCommandStr(COM_QUERY, command); err != nil { + return errors.Trace(err) + } + + return c.readResultStreaming(false, result, perRowCallback, perResultCallback) +} + +func (c *Conn) Begin() error { + _, err := c.exec("BEGIN") + return errors.Trace(err) +} + +func (c *Conn) Commit() error { + _, err := c.exec("COMMIT") + return errors.Trace(err) +} + +func (c *Conn) Rollback() error { + _, err := c.exec("ROLLBACK") + return errors.Trace(err) +} + +func (c *Conn) SetAttributes(attributes map[string]string) { + c.attributes = attributes +} + +func (c *Conn) SetCharset(charset string) error { + if c.charset == charset { + return nil + } + + if _, err := c.exec(fmt.Sprintf("SET NAMES %s", charset)); err != nil { + return errors.Trace(err) + } else { + c.charset = charset + return nil + } +} + +func (c *Conn) FieldList(table string, wildcard string) ([]*Field, error) { + if err := c.writeCommandStrStr(COM_FIELD_LIST, table, wildcard); err != nil { + return nil, errors.Trace(err) + } + + fs := make([]*Field, 0, 4) + var f *Field + for { + data, err := c.ReadPacket() + if err != nil { + return nil, errors.Trace(err) + } + + // ERR Packet + if data[0] == ERR_HEADER { + return nil, c.handleErrorPacket(data) + } + + // EOF Packet + if c.isEOFPacket(data) { + return fs, nil + } + + if f, err = FieldData(data).Parse(); err != nil { + return nil, errors.Trace(err) + } + fs = append(fs, f) + } +} + +func (c *Conn) SetAutoCommit() error { + if !c.IsAutoCommit() { + if _, err := c.exec("SET AUTOCOMMIT = 1"); err != nil { + return errors.Trace(err) + } + } + return nil +} + +func (c *Conn) IsAutoCommit() bool { + return c.status&SERVER_STATUS_AUTOCOMMIT > 0 +} + +func (c *Conn) IsInTransaction() bool { + return c.status&SERVER_STATUS_IN_TRANS > 0 +} + +func (c *Conn) GetCharset() string { + return c.charset +} + +func (c *Conn) GetConnectionID() uint32 { + return c.connectionID +} + +func (c *Conn) HandleOKPacket(data []byte) *Result { + r, _ := c.handleOKPacket(data) + return r +} + +func (c *Conn) HandleErrorPacket(data []byte) error { + return c.handleErrorPacket(data) +} + +func (c *Conn) ReadOKPacket() (*Result, error) { + return c.readOK() +} + +func (c *Conn) exec(query string) (*Result, error) { + if err := c.writeCommandStr(COM_QUERY, query); err != nil { + return nil, errors.Trace(err) + } + + return c.readResult(false) +} diff --git a/v2/vendor/github.com/go-mysql-org/go-mysql/client/pool.go b/v2/vendor/github.com/go-mysql-org/go-mysql/client/pool.go new file mode 100644 index 0000000..263d527 --- /dev/null +++ b/v2/vendor/github.com/go-mysql-org/go-mysql/client/pool.go @@ -0,0 +1,477 @@ +package client + +import ( + "context" + "math" + "math/rand" + "sync" + "time" + + "github.com/pingcap/errors" +) + +/* +Pool for efficient reuse of connections. + +Usage: + pool := client.NewPool(log.Debugf, 100, 400, 5, `127.0.0.1:3306`, `username`, `userpwd`, `dbname`) + ... + conn, _ := pool.GetConn(ctx) + defer pool.PutConn(conn) + conn.Execute/conn.Begin/etc... +*/ + +type ( + Timestamp int64 + + LogFunc func(format string, args ...interface{}) + + Pool struct { + logFunc LogFunc + minAlive int + maxAlive int + maxIdle int + idleCloseTimeout Timestamp + idlePingTimeout Timestamp + connect func() (*Conn, error) + + synchro struct { + sync.Mutex + idleConnections []Connection + stats ConnectionStats + } + + readyConnection chan Connection + } + + ConnectionStats struct { + // Uses internally + TotalCount int + + // Only for stats + IdleCount int + CreatedCount int64 + } + + Connection struct { + conn *Conn + lastUseAt Timestamp + } +) + +var ( + // MaxIdleTimeoutWithoutPing - If the connection has been idle for more than this time, + // then ping will be performed before use to check if it alive + MaxIdleTimeoutWithoutPing = 10 * time.Second + + // DefaultIdleTimeout - If the connection has been idle for more than this time, + // we can close it (but we should remember about Pool.minAlive) + DefaultIdleTimeout = 30 * time.Second + + // MaxNewConnectionAtOnce - If we need to create new connections, + // then we will create no more than this number of connections at a time. + // This restriction will be ignored on pool initialization. + MaxNewConnectionAtOnce = 5 +) + +// NewPool initializes new connection pool and uses params: addr, user, password, dbName and options. +// minAlive specifies the minimum number of open connections that the pool will try to maintain. +// maxAlive specifies the maximum number of open connections (for internal reasons, +// may be greater by 1 inside newConnectionProducer). +// maxIdle specifies the maximum number of idle connections (see DefaultIdleTimeout). +func NewPool( + logFunc LogFunc, + minAlive int, + maxAlive int, + maxIdle int, + addr string, + user string, + password string, + dbName string, + options ...func(conn *Conn), +) *Pool { + if minAlive > maxAlive { + minAlive = maxAlive + } + if maxIdle > maxAlive { + maxIdle = maxAlive + } + if maxIdle <= minAlive { + maxIdle = minAlive + } + + pool := &Pool{ + logFunc: logFunc, + minAlive: minAlive, + maxAlive: maxAlive, + maxIdle: maxIdle, + + idleCloseTimeout: Timestamp(math.Ceil(DefaultIdleTimeout.Seconds())), + idlePingTimeout: Timestamp(math.Ceil(MaxIdleTimeoutWithoutPing.Seconds())), + + connect: func() (*Conn, error) { + return Connect(addr, user, password, dbName, options...) + }, + + readyConnection: make(chan Connection), + } + + pool.synchro.idleConnections = make([]Connection, 0, pool.maxIdle) + + go pool.newConnectionProducer() + + if pool.minAlive > 0 { + pool.logFunc(`Pool: Setup %d new connections (minimal pool size)...`, pool.minAlive) + pool.startNewConnections(pool.minAlive) + } + + go pool.closeOldIdleConnections() + + return pool +} + +func (pool *Pool) GetStats(stats *ConnectionStats) { + pool.synchro.Lock() + + *stats = pool.synchro.stats + + stats.IdleCount = len(pool.synchro.idleConnections) + + pool.synchro.Unlock() +} + +// GetConn returns connection from the pool or create new +func (pool *Pool) GetConn(ctx context.Context) (*Conn, error) { + for { + connection, err := pool.getConnection(ctx) + if err != nil { + return nil, err + } + + // For long time idle connections, we do a ping check + if delta := pool.nowTs() - connection.lastUseAt; delta > pool.idlePingTimeout { + if err := pool.ping(connection.conn); err != nil { + pool.closeConn(connection.conn) + continue + } + } + + return connection.conn, nil + } +} + +// PutConn returns working connection back to pool +func (pool *Pool) PutConn(conn *Conn) { + pool.putConnection(Connection{ + conn: conn, + lastUseAt: pool.nowTs(), + }) +} + +// DropConn closes the connection without any checks +func (pool *Pool) DropConn(conn *Conn) { + pool.closeConn(conn) +} + +func (pool *Pool) putConnection(connection Connection) { + pool.synchro.Lock() + defer pool.synchro.Unlock() + + // If someone is already waiting for a connection, then we return it to him + select { + case pool.readyConnection <- connection: + return + default: + } + + // Nobody needs this connection + + pool.putConnectionUnsafe(connection) +} + +func (pool *Pool) nowTs() Timestamp { + return Timestamp(time.Now().Unix()) +} + +func (pool *Pool) getConnection(ctx context.Context) (Connection, error) { + pool.synchro.Lock() + + connection := pool.getIdleConnectionUnsafe() + if connection.conn != nil { + pool.synchro.Unlock() + return connection, nil + } + pool.synchro.Unlock() + + // No idle connections are available + + select { + case connection := <-pool.readyConnection: + return connection, nil + + case <-ctx.Done(): + return Connection{}, ctx.Err() + } +} + +func (pool *Pool) putConnectionUnsafe(connection Connection) { + if len(pool.synchro.idleConnections) == cap(pool.synchro.idleConnections) { + pool.synchro.stats.TotalCount-- + _ = connection.conn.Close() // Could it be more effective to close older connections? + } else { + pool.synchro.idleConnections = append(pool.synchro.idleConnections, connection) + } +} + +func (pool *Pool) newConnectionProducer() { + var connection Connection + var err error + + for { + connection.conn = nil + + pool.synchro.Lock() + + connection = pool.getIdleConnectionUnsafe() + if connection.conn == nil { + if pool.synchro.stats.TotalCount >= pool.maxAlive { + // Can't create more connections + pool.synchro.Unlock() + time.Sleep(10 * time.Millisecond) + continue + } + pool.synchro.stats.TotalCount++ // "Reserving" new connection + } + + pool.synchro.Unlock() + + if connection.conn == nil { + connection, err = pool.createNewConnection() + if err != nil { + pool.synchro.Lock() + pool.synchro.stats.TotalCount-- // Bad luck, should try again + pool.synchro.Unlock() + + time.Sleep(time.Duration(10+rand.Intn(90)) * time.Millisecond) + continue + } + } + + pool.readyConnection <- connection + } +} + +func (pool *Pool) createNewConnection() (Connection, error) { + var connection Connection + var err error + + connection.conn, err = pool.connect() + if err != nil { + return Connection{}, errors.Errorf(`Could not connect to mysql: %s`, err) + } + connection.lastUseAt = pool.nowTs() + + pool.synchro.Lock() + pool.synchro.stats.CreatedCount++ + pool.synchro.Unlock() + + return connection, nil +} + +func (pool *Pool) getIdleConnectionUnsafe() Connection { + cnt := len(pool.synchro.idleConnections) + if cnt == 0 { + return Connection{} + } + + last := cnt - 1 + connection := pool.synchro.idleConnections[last] + pool.synchro.idleConnections[last].conn = nil + pool.synchro.idleConnections = pool.synchro.idleConnections[:last] + + return connection +} + +func (pool *Pool) closeOldIdleConnections() { + var toPing []Connection + + ticker := time.NewTicker(5 * time.Second) + + for range ticker.C { + toPing = pool.getOldIdleConnections(toPing[:0]) + if len(toPing) == 0 { + continue + } + pool.recheckConnections(toPing) + + if !pool.spawnConnectionsIfNeeded() { + pool.closeIdleConnectionsIfCan() + } + } +} + +func (pool *Pool) getOldIdleConnections(dst []Connection) []Connection { + dst = dst[:0] + + pool.synchro.Lock() + + synchro := &pool.synchro + + idleCnt := len(synchro.idleConnections) + checkBefore := pool.nowTs() - pool.idlePingTimeout + + for i := idleCnt - 1; i >= 0; i-- { + if synchro.idleConnections[i].lastUseAt > checkBefore { + continue + } + + dst = append(dst, synchro.idleConnections[i]) + + last := idleCnt - 1 + if i < last { + // Removing an item from the middle of a slice + synchro.idleConnections[i], synchro.idleConnections[last] = synchro.idleConnections[last], synchro.idleConnections[i] + } + + synchro.idleConnections[last].conn = nil + synchro.idleConnections = synchro.idleConnections[:last] + idleCnt-- + } + + pool.synchro.Unlock() + + return dst +} + +func (pool *Pool) recheckConnections(connections []Connection) { + const workerCnt = 2 // Heuristic :) + + queue := make(chan Connection, len(connections)) + for _, connection := range connections { + queue <- connection + } + close(queue) + + var wg sync.WaitGroup + wg.Add(workerCnt) + for worker := 0; worker < workerCnt; worker++ { + go func() { + defer wg.Done() + for connection := range queue { + if err := pool.ping(connection.conn); err != nil { + pool.closeConn(connection.conn) + } else { + pool.putConnection(connection) + } + } + }() + } + + wg.Wait() +} + +// spawnConnectionsIfNeeded creates new connections if there are not enough of them and returns true in this case +func (pool *Pool) spawnConnectionsIfNeeded() bool { + pool.synchro.Lock() + totalCount := pool.synchro.stats.TotalCount + idleCount := len(pool.synchro.idleConnections) + needSpanNew := pool.minAlive - totalCount + pool.synchro.Unlock() + + if needSpanNew <= 0 { + return false + } + + // Не хватает соединений, нужно создать еще + + if needSpanNew > MaxNewConnectionAtOnce { + needSpanNew = MaxNewConnectionAtOnce + } + + pool.logFunc(`Pool: Setup %d new connections (total: %d idle: %d)...`, needSpanNew, totalCount, idleCount) + pool.startNewConnections(needSpanNew) + + return true +} + +func (pool *Pool) closeIdleConnectionsIfCan() { + pool.synchro.Lock() + + canCloseCnt := pool.synchro.stats.TotalCount - pool.minAlive + canCloseCnt-- // -1 to account for an open but unused connection (pool.readyConnection <- connection in newConnectionProducer) + + idleCnt := len(pool.synchro.idleConnections) + + inFly := pool.synchro.stats.TotalCount - idleCnt + + // We can close no more than 10% connections at a time, but at least 1, if possible + idleCanCloseCnt := idleCnt / 10 + if idleCanCloseCnt == 0 { + idleCanCloseCnt = 1 + } + if canCloseCnt > idleCanCloseCnt { + canCloseCnt = idleCanCloseCnt + } + if canCloseCnt <= 0 { + pool.synchro.Unlock() + return + } + + closeFromIdx := idleCnt - canCloseCnt + if closeFromIdx < 0 { + // If there are enough requests in the "flight" now, then we can close all unnecessary + closeFromIdx = 0 + } + + toClose := append([]Connection{}, pool.synchro.idleConnections[closeFromIdx:]...) + + for i := closeFromIdx; i < idleCnt; i++ { + pool.synchro.idleConnections[i].conn = nil + } + pool.synchro.idleConnections = pool.synchro.idleConnections[:closeFromIdx] + + pool.synchro.Unlock() + + pool.logFunc(`Pool: Close %d idle connections (in fly %d)`, len(toClose), inFly) + for _, connection := range toClose { + pool.closeConn(connection.conn) + } +} + +func (pool *Pool) closeConn(conn *Conn) { + pool.synchro.Lock() + pool.synchro.stats.TotalCount-- + pool.synchro.Unlock() + + _ = conn.Close() // Closing is not an instant action, so do it outside the lock +} + +func (pool *Pool) startNewConnections(count int) { + connections := make([]Connection, 0, count) + for i := 0; i < count; i++ { + if conn, err := pool.createNewConnection(); err == nil { + pool.synchro.Lock() + pool.synchro.stats.TotalCount++ + pool.synchro.Unlock() + connections = append(connections, conn) + } + } + + pool.synchro.Lock() + for _, connection := range connections { + pool.putConnectionUnsafe(connection) + } + pool.synchro.Unlock() +} + +func (pool *Pool) ping(conn *Conn) error { + deadline := time.Now().Add(100 * time.Millisecond) + _ = conn.SetDeadline(deadline) + err := conn.Ping() + if err != nil { + pool.logFunc(`Pool: ping query fail: %s`, err.Error()) + } else { + _ = conn.SetDeadline(time.Time{}) + } + return err +} diff --git a/v2/vendor/github.com/go-mysql-org/go-mysql/client/req.go b/v2/vendor/github.com/go-mysql-org/go-mysql/client/req.go new file mode 100644 index 0000000..eaa64b0 --- /dev/null +++ b/v2/vendor/github.com/go-mysql-org/go-mysql/client/req.go @@ -0,0 +1,68 @@ +package client + +import ( + "github.com/go-mysql-org/go-mysql/utils" +) + +func (c *Conn) writeCommand(command byte) error { + c.ResetSequence() + + return c.WritePacket([]byte{ + 0x01, //1 bytes long + 0x00, + 0x00, + 0x00, //sequence + command, + }) +} + +func (c *Conn) writeCommandBuf(command byte, arg []byte) error { + c.ResetSequence() + + length := len(arg) + 1 + data := utils.ByteSliceGet(length + 4) + data.B[4] = command + + copy(data.B[5:], arg) + + err := c.WritePacket(data.B) + + utils.ByteSlicePut(data) + + return err +} + +func (c *Conn) writeCommandStr(command byte, arg string) error { + return c.writeCommandBuf(command, utils.StringToByteSlice(arg)) +} + +func (c *Conn) writeCommandUint32(command byte, arg uint32) error { + c.ResetSequence() + + return c.WritePacket([]byte{ + 0x05, //5 bytes long + 0x00, + 0x00, + 0x00, //sequence + + command, + + byte(arg), + byte(arg >> 8), + byte(arg >> 16), + byte(arg >> 24), + }) +} + +func (c *Conn) writeCommandStrStr(command byte, arg1 string, arg2 string) error { + c.ResetSequence() + + data := make([]byte, 4, 6+len(arg1)+len(arg2)) + + data = append(data, command) + data = append(data, arg1...) + data = append(data, 0) + data = append(data, arg2...) + + return c.WritePacket(data) +} diff --git a/v2/vendor/github.com/go-mysql-org/go-mysql/client/resp.go b/v2/vendor/github.com/go-mysql-org/go-mysql/client/resp.go new file mode 100644 index 0000000..ab809cc --- /dev/null +++ b/v2/vendor/github.com/go-mysql-org/go-mysql/client/resp.go @@ -0,0 +1,469 @@ +package client + +import ( + "bytes" + "crypto/rsa" + "crypto/x509" + "encoding/binary" + "encoding/pem" + + "github.com/pingcap/errors" + "github.com/siddontang/go/hack" + + . "github.com/go-mysql-org/go-mysql/mysql" + "github.com/go-mysql-org/go-mysql/utils" +) + +func (c *Conn) readUntilEOF() (err error) { + var data []byte + + for { + data, err = c.ReadPacket() + + if err != nil { + return + } + + // EOF Packet + if c.isEOFPacket(data) { + return + } + } +} + +func (c *Conn) isEOFPacket(data []byte) bool { + return data[0] == EOF_HEADER && len(data) <= 5 +} + +func (c *Conn) handleOKPacket(data []byte) (*Result, error) { + var n int + var pos = 1 + + r := new(Result) + + r.AffectedRows, _, n = LengthEncodedInt(data[pos:]) + pos += n + r.InsertId, _, n = LengthEncodedInt(data[pos:]) + pos += n + + if c.capability&CLIENT_PROTOCOL_41 > 0 { + r.Status = binary.LittleEndian.Uint16(data[pos:]) + c.status = r.Status + pos += 2 + + //todo:strict_mode, check warnings as error + r.Warnings = binary.LittleEndian.Uint16(data[pos:]) + // pos += 2 + } else if c.capability&CLIENT_TRANSACTIONS > 0 { + r.Status = binary.LittleEndian.Uint16(data[pos:]) + c.status = r.Status + // pos += 2 + } + + //new ok package will check CLIENT_SESSION_TRACK too, but I don't support it now. + + //skip info + return r, nil +} + +func (c *Conn) handleErrorPacket(data []byte) error { + e := new(MyError) + + var pos = 1 + + e.Code = binary.LittleEndian.Uint16(data[pos:]) + pos += 2 + + if c.capability&CLIENT_PROTOCOL_41 > 0 { + //skip '#' + pos++ + e.State = hack.String(data[pos : pos+5]) + pos += 5 + } + + e.Message = hack.String(data[pos:]) + + return e +} + +func (c *Conn) handleAuthResult() error { + data, switchToPlugin, err := c.readAuthResult() + if err != nil { + return err + } + // handle auth switch, only support 'sha256_password', and 'caching_sha2_password' + if switchToPlugin != "" { + //fmt.Printf("now switching auth plugin to '%s'\n", switchToPlugin) + if data == nil { + data = c.salt + } else { + copy(c.salt, data) + } + c.authPluginName = switchToPlugin + auth, addNull, err := c.genAuthResponse(data) + if err != nil { + return err + } + + if err = c.WriteAuthSwitchPacket(auth, addNull); err != nil { + return err + } + + // Read Result Packet + data, switchToPlugin, err = c.readAuthResult() + if err != nil { + return err + } + + // Do not allow to change the auth plugin more than once + if switchToPlugin != "" { + return errors.Errorf("can not switch auth plugin more than once") + } + } + + // handle caching_sha2_password + if c.authPluginName == AUTH_CACHING_SHA2_PASSWORD { + if data == nil { + return nil // auth already succeeded + } + if data[0] == CACHE_SHA2_FAST_AUTH { + _, err = c.readOK() + return err + } else if data[0] == CACHE_SHA2_FULL_AUTH { + // need full authentication + if c.tlsConfig != nil || c.proto == "unix" { + if err = c.WriteClearAuthPacket(c.password); err != nil { + return err + } + } else { + if err = c.WritePublicKeyAuthPacket(c.password, c.salt); err != nil { + return err + } + } + _, err = c.readOK() + return err + } else { + return errors.Errorf("invalid packet %x", data[0]) + } + } else if c.authPluginName == AUTH_SHA256_PASSWORD { + if len(data) == 0 { + return nil // auth already succeeded + } + block, _ := pem.Decode(data) + pub, err := x509.ParsePKIXPublicKey(block.Bytes) + if err != nil { + return err + } + // send encrypted password + err = c.WriteEncryptedPassword(c.password, c.salt, pub.(*rsa.PublicKey)) + if err != nil { + return err + } + _, err = c.readOK() + return err + } + return nil +} + +func (c *Conn) readAuthResult() ([]byte, string, error) { + data, err := c.ReadPacket() + if err != nil { + return nil, "", err + } + + // see: https://insidemysql.com/preparing-your-community-connector-for-mysql-8-part-2-sha256/ + // packet indicator + switch data[0] { + case OK_HEADER: + _, err := c.handleOKPacket(data) + return nil, "", err + + case MORE_DATE_HEADER: + return data[1:], "", err + + case EOF_HEADER: + // server wants to switch auth + if len(data) < 1 { + // https://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::OldAuthSwitchRequest + return nil, AUTH_MYSQL_OLD_PASSWORD, nil + } + pluginEndIndex := bytes.IndexByte(data, 0x00) + if pluginEndIndex < 0 { + return nil, "", errors.New("invalid packet") + } + plugin := string(data[1:pluginEndIndex]) + authData := data[pluginEndIndex+1:] + return authData, plugin, nil + + default: // Error otherwise + return nil, "", c.handleErrorPacket(data) + } +} + +func (c *Conn) readOK() (*Result, error) { + data, err := c.ReadPacket() + if err != nil { + return nil, errors.Trace(err) + } + + if data[0] == OK_HEADER { + return c.handleOKPacket(data) + } else if data[0] == ERR_HEADER { + return nil, c.handleErrorPacket(data) + } else { + return nil, errors.New("invalid ok packet") + } +} + +func (c *Conn) readResult(binary bool) (*Result, error) { + bs := utils.ByteSliceGet(16) + defer utils.ByteSlicePut(bs) + var err error + bs.B, err = c.ReadPacketReuseMem(bs.B[:0]) + if err != nil { + return nil, errors.Trace(err) + } + + switch bs.B[0] { + case OK_HEADER: + return c.handleOKPacket(bs.B) + case ERR_HEADER: + return nil, c.handleErrorPacket(bytes.Repeat(bs.B, 1)) + case LocalInFile_HEADER: + return nil, ErrMalformPacket + default: + return c.readResultset(bs.B, binary) + } +} + +func (c *Conn) readResultStreaming(binary bool, result *Result, perRowCb SelectPerRowCallback, perResCb SelectPerResultCallback) error { + bs := utils.ByteSliceGet(16) + defer utils.ByteSlicePut(bs) + var err error + bs.B, err = c.ReadPacketReuseMem(bs.B[:0]) + if err != nil { + return errors.Trace(err) + } + + switch bs.B[0] { + case OK_HEADER: + // https://dev.mysql.com/doc/internals/en/com-query-response.html + // 14.6.4.1 COM_QUERY Response + // If the number of columns in the resultset is 0, this is a OK_Packet. + + okResult, err := c.handleOKPacket(bs.B) + if err != nil { + return errors.Trace(err) + } + + result.Status = okResult.Status + result.AffectedRows = okResult.AffectedRows + result.InsertId = okResult.InsertId + result.Warnings = okResult.Warnings + if result.Resultset == nil { + result.Resultset = NewResultset(0) + } else { + result.Reset(0) + } + return nil + case ERR_HEADER: + return c.handleErrorPacket(bytes.Repeat(bs.B, 1)) + case LocalInFile_HEADER: + return ErrMalformPacket + default: + return c.readResultsetStreaming(bs.B, binary, result, perRowCb, perResCb) + } +} + +func (c *Conn) readResultset(data []byte, binary bool) (*Result, error) { + // column count + count, _, n := LengthEncodedInt(data) + + if n-len(data) != 0 { + return nil, ErrMalformPacket + } + + result := &Result{ + Resultset: NewResultset(int(count)), + } + + if err := c.readResultColumns(result); err != nil { + return nil, errors.Trace(err) + } + + if err := c.readResultRows(result, binary); err != nil { + return nil, errors.Trace(err) + } + + return result, nil +} + +func (c *Conn) readResultsetStreaming(data []byte, binary bool, result *Result, perRowCb SelectPerRowCallback, perResCb SelectPerResultCallback) error { + columnCount, _, n := LengthEncodedInt(data) + + if n-len(data) != 0 { + return ErrMalformPacket + } + + if result.Resultset == nil { + result.Resultset = NewResultset(int(columnCount)) + } else { + // Reuse memory if can + result.Reset(int(columnCount)) + } + + // this is a streaming resultset + result.Resultset.Streaming = StreamingSelect + + if err := c.readResultColumns(result); err != nil { + return errors.Trace(err) + } + + if perResCb != nil { + if err := perResCb(result); err != nil { + return err + } + } + + if err := c.readResultRowsStreaming(result, binary, perRowCb); err != nil { + return errors.Trace(err) + } + + // this resultset is done streaming + result.Resultset.StreamingDone = true + + return nil +} + +func (c *Conn) readResultColumns(result *Result) (err error) { + var i = 0 + var data []byte + + for { + rawPkgLen := len(result.RawPkg) + result.RawPkg, err = c.ReadPacketReuseMem(result.RawPkg) + if err != nil { + return + } + data = result.RawPkg[rawPkgLen:] + + // EOF Packet + if c.isEOFPacket(data) { + if c.capability&CLIENT_PROTOCOL_41 > 0 { + result.Warnings = binary.LittleEndian.Uint16(data[1:]) + //todo add strict_mode, warning will be treat as error + result.Status = binary.LittleEndian.Uint16(data[3:]) + c.status = result.Status + } + + if i != len(result.Fields) { + err = ErrMalformPacket + } + + return + } + + if result.Fields[i] == nil { + result.Fields[i] = &Field{} + } + err = result.Fields[i].Parse(data) + if err != nil { + return + } + + result.FieldNames[hack.String(result.Fields[i].Name)] = i + + i++ + } +} + +func (c *Conn) readResultRows(result *Result, isBinary bool) (err error) { + var data []byte + + for { + rawPkgLen := len(result.RawPkg) + result.RawPkg, err = c.ReadPacketReuseMem(result.RawPkg) + if err != nil { + return + } + data = result.RawPkg[rawPkgLen:] + + // EOF Packet + if c.isEOFPacket(data) { + if c.capability&CLIENT_PROTOCOL_41 > 0 { + result.Warnings = binary.LittleEndian.Uint16(data[1:]) + //todo add strict_mode, warning will be treat as error + result.Status = binary.LittleEndian.Uint16(data[3:]) + c.status = result.Status + } + + break + } + + if data[0] == ERR_HEADER { + return c.handleErrorPacket(data) + } + + result.RowDatas = append(result.RowDatas, data) + } + + if cap(result.Values) < len(result.RowDatas) { + result.Values = make([][]FieldValue, len(result.RowDatas)) + } else { + result.Values = result.Values[:len(result.RowDatas)] + } + + for i := range result.Values { + result.Values[i], err = result.RowDatas[i].Parse(result.Fields, isBinary, result.Values[i]) + + if err != nil { + return errors.Trace(err) + } + } + + return nil +} + +func (c *Conn) readResultRowsStreaming(result *Result, isBinary bool, perRowCb SelectPerRowCallback) (err error) { + var ( + data []byte + row []FieldValue + ) + + for { + data, err = c.ReadPacketReuseMem(data[:0]) + if err != nil { + return + } + + // EOF Packet + if c.isEOFPacket(data) { + if c.capability&CLIENT_PROTOCOL_41 > 0 { + result.Warnings = binary.LittleEndian.Uint16(data[1:]) + // todo add strict_mode, warning will be treat as error + result.Status = binary.LittleEndian.Uint16(data[3:]) + c.status = result.Status + } + + break + } + + if data[0] == ERR_HEADER { + return c.handleErrorPacket(data) + } + + // Parse this row + row, err = RowData(data).Parse(result.Fields, isBinary, row) + if err != nil { + return errors.Trace(err) + } + + // Send the row to "userland" code + err = perRowCb(row) + if err != nil { + return errors.Trace(err) + } + } + + return nil +} diff --git a/v2/vendor/github.com/go-mysql-org/go-mysql/client/stmt.go b/v2/vendor/github.com/go-mysql-org/go-mysql/client/stmt.go new file mode 100644 index 0000000..dd2cb79 --- /dev/null +++ b/v2/vendor/github.com/go-mysql-org/go-mysql/client/stmt.go @@ -0,0 +1,232 @@ +package client + +import ( + "encoding/binary" + "encoding/json" + "fmt" + "math" + + . "github.com/go-mysql-org/go-mysql/mysql" + "github.com/pingcap/errors" +) + +type Stmt struct { + conn *Conn + id uint32 + + params int + columns int + warnings int +} + +func (s *Stmt) ParamNum() int { + return s.params +} + +func (s *Stmt) ColumnNum() int { + return s.columns +} + +func (s *Stmt) WarningsNum() int { + return s.warnings +} + +func (s *Stmt) Execute(args ...interface{}) (*Result, error) { + if err := s.write(args...); err != nil { + return nil, errors.Trace(err) + } + + return s.conn.readResult(true) +} + +func (s *Stmt) ExecuteSelectStreaming(result *Result, perRowCb SelectPerRowCallback, perResCb SelectPerResultCallback, args ...interface{}) error { + if err := s.write(args...); err != nil { + return errors.Trace(err) + } + + return s.conn.readResultStreaming(true, result, perRowCb, perResCb) +} + +func (s *Stmt) Close() error { + if err := s.conn.writeCommandUint32(COM_STMT_CLOSE, s.id); err != nil { + return errors.Trace(err) + } + + return nil +} + +func (s *Stmt) write(args ...interface{}) error { + paramsNum := s.params + + if len(args) != paramsNum { + return fmt.Errorf("argument mismatch, need %d but got %d", s.params, len(args)) + } + + paramTypes := make([]byte, paramsNum<<1) + paramValues := make([][]byte, paramsNum) + + //NULL-bitmap, length: (num-params+7) + nullBitmap := make([]byte, (paramsNum+7)>>3) + + length := 1 + 4 + 1 + 4 + ((paramsNum + 7) >> 3) + 1 + (paramsNum << 1) + + var newParamBoundFlag byte = 0 + + for i := range args { + if args[i] == nil { + nullBitmap[i/8] |= 1 << (uint(i) % 8) + paramTypes[i<<1] = MYSQL_TYPE_NULL + continue + } + + newParamBoundFlag = 1 + + switch v := args[i].(type) { + case int8: + paramTypes[i<<1] = MYSQL_TYPE_TINY + paramValues[i] = []byte{byte(v)} + case int16: + paramTypes[i<<1] = MYSQL_TYPE_SHORT + paramValues[i] = Uint16ToBytes(uint16(v)) + case int32: + paramTypes[i<<1] = MYSQL_TYPE_LONG + paramValues[i] = Uint32ToBytes(uint32(v)) + case int: + paramTypes[i<<1] = MYSQL_TYPE_LONGLONG + paramValues[i] = Uint64ToBytes(uint64(v)) + case int64: + paramTypes[i<<1] = MYSQL_TYPE_LONGLONG + paramValues[i] = Uint64ToBytes(uint64(v)) + case uint8: + paramTypes[i<<1] = MYSQL_TYPE_TINY + paramTypes[(i<<1)+1] = 0x80 + paramValues[i] = []byte{v} + case uint16: + paramTypes[i<<1] = MYSQL_TYPE_SHORT + paramTypes[(i<<1)+1] = 0x80 + paramValues[i] = Uint16ToBytes(v) + case uint32: + paramTypes[i<<1] = MYSQL_TYPE_LONG + paramTypes[(i<<1)+1] = 0x80 + paramValues[i] = Uint32ToBytes(v) + case uint: + paramTypes[i<<1] = MYSQL_TYPE_LONGLONG + paramTypes[(i<<1)+1] = 0x80 + paramValues[i] = Uint64ToBytes(uint64(v)) + case uint64: + paramTypes[i<<1] = MYSQL_TYPE_LONGLONG + paramTypes[(i<<1)+1] = 0x80 + paramValues[i] = Uint64ToBytes(v) + case bool: + paramTypes[i<<1] = MYSQL_TYPE_TINY + if v { + paramValues[i] = []byte{1} + } else { + paramValues[i] = []byte{0} + } + case float32: + paramTypes[i<<1] = MYSQL_TYPE_FLOAT + paramValues[i] = Uint32ToBytes(math.Float32bits(v)) + case float64: + paramTypes[i<<1] = MYSQL_TYPE_DOUBLE + paramValues[i] = Uint64ToBytes(math.Float64bits(v)) + case string: + paramTypes[i<<1] = MYSQL_TYPE_STRING + paramValues[i] = append(PutLengthEncodedInt(uint64(len(v))), v...) + case []byte: + paramTypes[i<<1] = MYSQL_TYPE_STRING + paramValues[i] = append(PutLengthEncodedInt(uint64(len(v))), v...) + case json.RawMessage: + paramTypes[i<<1] = MYSQL_TYPE_STRING + paramValues[i] = append(PutLengthEncodedInt(uint64(len(v))), v...) + default: + return fmt.Errorf("invalid argument type %T", args[i]) + } + + length += len(paramValues[i]) + } + + data := make([]byte, 4, 4+length) + + data = append(data, COM_STMT_EXECUTE) + data = append(data, byte(s.id), byte(s.id>>8), byte(s.id>>16), byte(s.id>>24)) + + //flag: CURSOR_TYPE_NO_CURSOR + data = append(data, 0x00) + + //iteration-count, always 1 + data = append(data, 1, 0, 0, 0) + + if s.params > 0 { + data = append(data, nullBitmap...) + + //new-params-bound-flag + data = append(data, newParamBoundFlag) + + if newParamBoundFlag == 1 { + //type of each parameter, length: num-params * 2 + data = append(data, paramTypes...) + + //value of each parameter + for _, v := range paramValues { + data = append(data, v...) + } + } + } + + s.conn.ResetSequence() + + return s.conn.WritePacket(data) +} + +func (c *Conn) Prepare(query string) (*Stmt, error) { + if err := c.writeCommandStr(COM_STMT_PREPARE, query); err != nil { + return nil, errors.Trace(err) + } + + data, err := c.ReadPacket() + if err != nil { + return nil, errors.Trace(err) + } + + if data[0] == ERR_HEADER { + return nil, c.handleErrorPacket(data) + } else if data[0] != OK_HEADER { + return nil, ErrMalformPacket + } + + s := new(Stmt) + s.conn = c + + pos := 1 + + //for statement id + s.id = binary.LittleEndian.Uint32(data[pos:]) + pos += 4 + + //number columns + s.columns = int(binary.LittleEndian.Uint16(data[pos:])) + pos += 2 + + //number params + s.params = int(binary.LittleEndian.Uint16(data[pos:])) + pos += 2 + + //warnings + s.warnings = int(binary.LittleEndian.Uint16(data[pos:])) + // pos += 2 + + if s.params > 0 { + if err := s.conn.readUntilEOF(); err != nil { + return nil, errors.Trace(err) + } + } + + if s.columns > 0 { + if err := s.conn.readUntilEOF(); err != nil { + return nil, errors.Trace(err) + } + } + + return s, nil +} diff --git a/v2/vendor/github.com/go-mysql-org/go-mysql/client/tls.go b/v2/vendor/github.com/go-mysql-org/go-mysql/client/tls.go new file mode 100644 index 0000000..b2fe6da --- /dev/null +++ b/v2/vendor/github.com/go-mysql-org/go-mysql/client/tls.go @@ -0,0 +1,40 @@ +package client + +import ( + "crypto/tls" + "crypto/x509" +) + +// NewClientTLSConfig: generate TLS config for client side +// if insecureSkipVerify is set to true, serverName will not be validated +func NewClientTLSConfig(caPem, certPem, keyPem []byte, insecureSkipVerify bool, serverName string) *tls.Config { + pool := x509.NewCertPool() + if !pool.AppendCertsFromPEM(caPem) { + panic("failed to add ca PEM") + } + + var config *tls.Config + + // Allow cert and key to be optional + // Send through `make([]byte, 0)` for "nil" + if string(certPem) != "" && string(keyPem) != "" { + cert, err := tls.X509KeyPair(certPem, keyPem) + if err != nil { + panic(err) + } + config = &tls.Config{ + RootCAs: pool, + Certificates: []tls.Certificate{cert}, + InsecureSkipVerify: insecureSkipVerify, + ServerName: serverName, + } + } else { + config = &tls.Config{ + RootCAs: pool, + InsecureSkipVerify: insecureSkipVerify, + ServerName: serverName, + } + } + + return config +} diff --git a/v2/vendor/github.com/go-mysql-org/go-mysql/driver/driver.go b/v2/vendor/github.com/go-mysql-org/go-mysql/driver/driver.go new file mode 100644 index 0000000..b86c4b3 --- /dev/null +++ b/v2/vendor/github.com/go-mysql-org/go-mysql/driver/driver.go @@ -0,0 +1,326 @@ +// This package implements database/sql/driver interface, +// so we can use go-mysql with database/sql +package driver + +import ( + "crypto/tls" + "database/sql" + sqldriver "database/sql/driver" + "fmt" + "io" + "net/url" + "regexp" + "sync" + + "github.com/go-mysql-org/go-mysql/client" + "github.com/go-mysql-org/go-mysql/mysql" + "github.com/pingcap/errors" + "github.com/siddontang/go/hack" +) + +var customTLSMutex sync.Mutex + +// Map of dsn address (makes more sense than full dsn?) to tls Config +var customTLSConfigMap = make(map[string]*tls.Config) + +type driver struct { +} + +type connInfo struct { + standardDSN bool + addr string + user string + password string + db string + params url.Values +} + +// ParseDSN takes a DSN string and splits it up into struct containing addr, +// user, password and db. +// It returns an error if unable to parse. +// The struct also contains a boolean indicating if the DSN is in legacy or +// standard form. +// +// Legacy form uses a `?` is used as the path separator: user:password@addr[?db] +// Standard form uses a `/`: user:password@addr/db?param=value +// +// Optional parameters are supported in the standard DSN form +func parseDSN(dsn string) (connInfo, error) { + var matchErr error + ci := connInfo{} + + // If a "/" occurs after "@" and then no more "@" or "/" occur after that + ci.standardDSN, matchErr = regexp.MatchString("@[^@]+/[^@/]+", dsn) + if matchErr != nil { + return ci, errors.Errorf("invalid dsn, must be user:password@addr[/db[?param=X]]") + } + + // Add a prefix so we can parse with url.Parse + dsn = "mysql://" + dsn + parsedDSN, parseErr := url.Parse(dsn) + if parseErr != nil { + return ci, errors.Errorf("invalid dsn, must be user:password@addr[/db[?param=X]]") + } + + ci.addr = parsedDSN.Host + ci.user = parsedDSN.User.Username() + // We ignore the second argument as that is just a flag for existence of a password + // If not set we get empty string anyway + ci.password, _ = parsedDSN.User.Password() + + if ci.standardDSN { + ci.db = parsedDSN.Path[1:] + ci.params = parsedDSN.Query() + } else { + ci.db = parsedDSN.RawQuery + // This is the equivalent to a "nil" list of parameters + ci.params = url.Values{} + } + + return ci, nil +} + +// Open takes a supplied DSN string and opens a connection +// See ParseDSN for more information on the form of the DSN +func (d driver) Open(dsn string) (sqldriver.Conn, error) { + var c *client.Conn + + ci, err := parseDSN(dsn) + + if err != nil { + return nil, err + } + + if ci.standardDSN { + if ci.params["ssl"] != nil { + tlsConfigName := ci.params.Get("ssl") + switch tlsConfigName { + case "true": + // This actually does insecureSkipVerify + // But not even sure if it makes sense to handle false? According to + // client_test.go it doesn't - it'd result in an error + c, err = client.Connect(ci.addr, ci.user, ci.password, ci.db, func(c *client.Conn) { c.UseSSL(true) }) + case "custom": + // I was too concerned about mimicking what go-sql-driver/mysql does which will + // allow any name for a custom tls profile and maps the query parameter value to + // that TLSConfig variable... there is no need to be that clever. + // Instead of doing that, let's store required custom TLSConfigs in a map that + // uses the DSN address as the key + c, err = client.Connect(ci.addr, ci.user, ci.password, ci.db, func(c *client.Conn) { c.SetTLSConfig(customTLSConfigMap[ci.addr]) }) + default: + return nil, errors.Errorf("Supported options are ssl=true or ssl=custom") + } + } else { + c, err = client.Connect(ci.addr, ci.user, ci.password, ci.db) + } + } else { + // No more processing here. Let's only support url parameters with the newer style DSN + c, err = client.Connect(ci.addr, ci.user, ci.password, ci.db) + } + if err != nil { + return nil, err + } + + return &conn{c}, nil +} + +type conn struct { + *client.Conn +} + +func (c *conn) Prepare(query string) (sqldriver.Stmt, error) { + st, err := c.Conn.Prepare(query) + if err != nil { + return nil, errors.Trace(err) + } + + return &stmt{st}, nil +} + +func (c *conn) Close() error { + return c.Conn.Close() +} + +func (c *conn) Begin() (sqldriver.Tx, error) { + err := c.Conn.Begin() + if err != nil { + return nil, errors.Trace(err) + } + + return &tx{c.Conn}, nil +} + +func buildArgs(args []sqldriver.Value) []interface{} { + a := make([]interface{}, len(args)) + + for i, arg := range args { + a[i] = arg + } + + return a +} + +func replyError(err error) error { + if mysql.ErrorEqual(err, mysql.ErrBadConn) { + return sqldriver.ErrBadConn + } else { + return errors.Trace(err) + } +} + +func (c *conn) Exec(query string, args []sqldriver.Value) (sqldriver.Result, error) { + a := buildArgs(args) + r, err := c.Conn.Execute(query, a...) + if err != nil { + return nil, replyError(err) + } + return &result{r}, nil +} + +func (c *conn) Query(query string, args []sqldriver.Value) (sqldriver.Rows, error) { + a := buildArgs(args) + r, err := c.Conn.Execute(query, a...) + if err != nil { + return nil, replyError(err) + } + return newRows(r.Resultset) +} + +type stmt struct { + *client.Stmt +} + +func (s *stmt) Close() error { + return s.Stmt.Close() +} + +func (s *stmt) NumInput() int { + return s.Stmt.ParamNum() +} + +func (s *stmt) Exec(args []sqldriver.Value) (sqldriver.Result, error) { + a := buildArgs(args) + r, err := s.Stmt.Execute(a...) + if err != nil { + return nil, replyError(err) + } + return &result{r}, nil +} + +func (s *stmt) Query(args []sqldriver.Value) (sqldriver.Rows, error) { + a := buildArgs(args) + r, err := s.Stmt.Execute(a...) + if err != nil { + return nil, replyError(err) + } + return newRows(r.Resultset) +} + +type tx struct { + *client.Conn +} + +func (t *tx) Commit() error { + return t.Conn.Commit() +} + +func (t *tx) Rollback() error { + return t.Conn.Rollback() +} + +type result struct { + *mysql.Result +} + +func (r *result) LastInsertId() (int64, error) { + return int64(r.Result.InsertId), nil +} + +func (r *result) RowsAffected() (int64, error) { + return int64(r.Result.AffectedRows), nil +} + +type rows struct { + *mysql.Resultset + + columns []string + step int +} + +func newRows(r *mysql.Resultset) (*rows, error) { + if r == nil { + return nil, fmt.Errorf("invalid mysql query, no correct result") + } + + rs := new(rows) + rs.Resultset = r + + rs.columns = make([]string, len(r.Fields)) + + for i, f := range r.Fields { + rs.columns[i] = hack.String(f.Name) + } + rs.step = 0 + + return rs, nil +} + +func (r *rows) Columns() []string { + return r.columns +} + +func (r *rows) Close() error { + r.step = -1 + return nil +} + +func (r *rows) Next(dest []sqldriver.Value) error { + if r.step >= r.Resultset.RowNumber() { + return io.EOF + } else if r.step == -1 { + return io.ErrUnexpectedEOF + } + + for i := 0; i < r.Resultset.ColumnNumber(); i++ { + value, err := r.Resultset.GetValue(r.step, i) + if err != nil { + return err + } + + dest[i] = sqldriver.Value(value) + } + + r.step++ + + return nil +} + +func init() { + sql.Register("mysql", driver{}) +} + +// SetCustomTLSConfig sets a custom TLSConfig for the address (host:port) of the supplied DSN. +// It requires a full import of the driver (not by side-effects only). +// Example of supplying a custom CA, no client cert, no key, validating the +// certificate, and supplying a serverName for the validation: +// +// driver.SetCustomTLSConfig(CaPem, make([]byte, 0), make([]byte, 0), false, "my.domain.name") +func SetCustomTLSConfig(dsn string, caPem []byte, certPem []byte, keyPem []byte, insecureSkipVerify bool, serverName string) error { + // Extract addr from dsn + parsed, err := url.Parse(dsn) + if err != nil { + return errors.Errorf("Unable to parse DSN. Need to extract address to use as key for storing custom TLS config") + } + addr := parsed.Host + + // I thought about using serverName instead of addr below, but decided against that as + // having multiple CA certs for one hostname is likely when you have services running on + // different ports. + + customTLSMutex.Lock() + // Basic pass-through function so we can just import the driver + customTLSConfigMap[addr] = client.NewClientTLSConfig(caPem, certPem, keyPem, insecureSkipVerify, serverName) + customTLSMutex.Unlock() + + return nil +} diff --git a/v2/vendor/github.com/go-mysql-org/go-mysql/mysql/const.go b/v2/vendor/github.com/go-mysql-org/go-mysql/mysql/const.go new file mode 100644 index 0000000..e2f3a0a --- /dev/null +++ b/v2/vendor/github.com/go-mysql-org/go-mysql/mysql/const.go @@ -0,0 +1,175 @@ +package mysql + +const ( + MinProtocolVersion byte = 10 + MaxPayloadLen int = 1<<24 - 1 + TimeFormat string = "2006-01-02 15:04:05" +) + +const ( + OK_HEADER byte = 0x00 + MORE_DATE_HEADER byte = 0x01 + ERR_HEADER byte = 0xff + EOF_HEADER byte = 0xfe + LocalInFile_HEADER byte = 0xfb + + CACHE_SHA2_FAST_AUTH byte = 0x03 + CACHE_SHA2_FULL_AUTH byte = 0x04 +) + +const ( + AUTH_MYSQL_OLD_PASSWORD = "mysql_old_password" + AUTH_NATIVE_PASSWORD = "mysql_native_password" + AUTH_CLEAR_PASSWORD = "mysql_clear_password" + AUTH_CACHING_SHA2_PASSWORD = "caching_sha2_password" + AUTH_SHA256_PASSWORD = "sha256_password" +) + +const ( + SERVER_STATUS_IN_TRANS uint16 = 0x0001 + SERVER_STATUS_AUTOCOMMIT uint16 = 0x0002 + SERVER_MORE_RESULTS_EXISTS uint16 = 0x0008 + SERVER_STATUS_NO_GOOD_INDEX_USED uint16 = 0x0010 + SERVER_STATUS_NO_INDEX_USED uint16 = 0x0020 + SERVER_STATUS_CURSOR_EXISTS uint16 = 0x0040 + SERVER_STATUS_LAST_ROW_SEND uint16 = 0x0080 + SERVER_STATUS_DB_DROPPED uint16 = 0x0100 + SERVER_STATUS_NO_BACKSLASH_ESCAPED uint16 = 0x0200 + SERVER_STATUS_METADATA_CHANGED uint16 = 0x0400 + SERVER_QUERY_WAS_SLOW uint16 = 0x0800 + SERVER_PS_OUT_PARAMS uint16 = 0x1000 +) + +const ( + COM_SLEEP byte = iota + COM_QUIT + COM_INIT_DB + COM_QUERY + COM_FIELD_LIST + COM_CREATE_DB + COM_DROP_DB + COM_REFRESH + COM_SHUTDOWN + COM_STATISTICS + COM_PROCESS_INFO + COM_CONNECT + COM_PROCESS_KILL + COM_DEBUG + COM_PING + COM_TIME + COM_DELAYED_INSERT + COM_CHANGE_USER + COM_BINLOG_DUMP + COM_TABLE_DUMP + COM_CONNECT_OUT + COM_REGISTER_SLAVE + COM_STMT_PREPARE + COM_STMT_EXECUTE + COM_STMT_SEND_LONG_DATA + COM_STMT_CLOSE + COM_STMT_RESET + COM_SET_OPTION + COM_STMT_FETCH + COM_DAEMON + COM_BINLOG_DUMP_GTID + COM_RESET_CONNECTION +) + +const ( + CLIENT_LONG_PASSWORD uint32 = 1 << iota + CLIENT_FOUND_ROWS + CLIENT_LONG_FLAG + CLIENT_CONNECT_WITH_DB + CLIENT_NO_SCHEMA + CLIENT_COMPRESS + CLIENT_ODBC + CLIENT_LOCAL_FILES + CLIENT_IGNORE_SPACE + CLIENT_PROTOCOL_41 + CLIENT_INTERACTIVE + CLIENT_SSL + CLIENT_IGNORE_SIGPIPE + CLIENT_TRANSACTIONS + CLIENT_RESERVED + CLIENT_SECURE_CONNECTION + CLIENT_MULTI_STATEMENTS + CLIENT_MULTI_RESULTS + CLIENT_PS_MULTI_RESULTS + CLIENT_PLUGIN_AUTH + CLIENT_CONNECT_ATTRS + CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA +) + +const ( + MYSQL_TYPE_DECIMAL byte = iota + MYSQL_TYPE_TINY + MYSQL_TYPE_SHORT + MYSQL_TYPE_LONG + MYSQL_TYPE_FLOAT + MYSQL_TYPE_DOUBLE + MYSQL_TYPE_NULL + MYSQL_TYPE_TIMESTAMP + MYSQL_TYPE_LONGLONG + MYSQL_TYPE_INT24 + MYSQL_TYPE_DATE + MYSQL_TYPE_TIME + MYSQL_TYPE_DATETIME + MYSQL_TYPE_YEAR + MYSQL_TYPE_NEWDATE + MYSQL_TYPE_VARCHAR + MYSQL_TYPE_BIT + + //mysql 5.6 + MYSQL_TYPE_TIMESTAMP2 + MYSQL_TYPE_DATETIME2 + MYSQL_TYPE_TIME2 +) + +const ( + MYSQL_TYPE_JSON byte = iota + 0xf5 + MYSQL_TYPE_NEWDECIMAL + MYSQL_TYPE_ENUM + MYSQL_TYPE_SET + MYSQL_TYPE_TINY_BLOB + MYSQL_TYPE_MEDIUM_BLOB + MYSQL_TYPE_LONG_BLOB + MYSQL_TYPE_BLOB + MYSQL_TYPE_VAR_STRING + MYSQL_TYPE_STRING + MYSQL_TYPE_GEOMETRY +) + +const ( + NOT_NULL_FLAG = 1 + PRI_KEY_FLAG = 2 + UNIQUE_KEY_FLAG = 4 + BLOB_FLAG = 16 + UNSIGNED_FLAG = 32 + ZEROFILL_FLAG = 64 + BINARY_FLAG = 128 + ENUM_FLAG = 256 + AUTO_INCREMENT_FLAG = 512 + TIMESTAMP_FLAG = 1024 + SET_FLAG = 2048 + NUM_FLAG = 32768 + PART_KEY_FLAG = 16384 + GROUP_FLAG = 32768 + UNIQUE_FLAG = 65536 +) + +const ( + DEFAULT_CHARSET = "utf8" + DEFAULT_COLLATION_ID uint8 = 33 + DEFAULT_COLLATION_NAME string = "utf8_general_ci" +) + +// Like vitess, use flavor for different MySQL versions, +const ( + MySQLFlavor = "mysql" + MariaDBFlavor = "mariadb" +) + +const ( + MYSQL_OPTION_MULTI_STATEMENTS_ON = iota + MYSQL_OPTION_MULTI_STATEMENTS_OFF +) diff --git a/v2/vendor/github.com/go-mysql-org/go-mysql/mysql/errcode.go b/v2/vendor/github.com/go-mysql-org/go-mysql/mysql/errcode.go new file mode 100644 index 0000000..1be5c44 --- /dev/null +++ b/v2/vendor/github.com/go-mysql-org/go-mysql/mysql/errcode.go @@ -0,0 +1,870 @@ +package mysql + +const ( + ER_ERROR_FIRST = 1000 + ER_HASHCHK = 1000 + ER_NISAMCHK = 1001 + ER_NO = 1002 + ER_YES = 1003 + ER_CANT_CREATE_FILE = 1004 + ER_CANT_CREATE_TABLE = 1005 + ER_CANT_CREATE_DB = 1006 + ER_DB_CREATE_EXISTS = 1007 + ER_DB_DROP_EXISTS = 1008 + ER_DB_DROP_DELETE = 1009 + ER_DB_DROP_RMDIR = 1010 + ER_CANT_DELETE_FILE = 1011 + ER_CANT_FIND_SYSTEM_REC = 1012 + ER_CANT_GET_STAT = 1013 + ER_CANT_GET_WD = 1014 + ER_CANT_LOCK = 1015 + ER_CANT_OPEN_FILE = 1016 + ER_FILE_NOT_FOUND = 1017 + ER_CANT_READ_DIR = 1018 + ER_CANT_SET_WD = 1019 + ER_CHECKREAD = 1020 + ER_DISK_FULL = 1021 + ER_DUP_KEY = 1022 + ER_ERROR_ON_CLOSE = 1023 + ER_ERROR_ON_READ = 1024 + ER_ERROR_ON_RENAME = 1025 + ER_ERROR_ON_WRITE = 1026 + ER_FILE_USED = 1027 + ER_FILSORT_ABORT = 1028 + ER_FORM_NOT_FOUND = 1029 + ER_GET_ERRNO = 1030 + ER_ILLEGAL_HA = 1031 + ER_KEY_NOT_FOUND = 1032 + ER_NOT_FORM_FILE = 1033 + ER_NOT_KEYFILE = 1034 + ER_OLD_KEYFILE = 1035 + ER_OPEN_AS_READONLY = 1036 + ER_OUTOFMEMORY = 1037 + ER_OUT_OF_SORTMEMORY = 1038 + ER_UNEXPECTED_EOF = 1039 + ER_CON_COUNT_ERROR = 1040 + ER_OUT_OF_RESOURCES = 1041 + ER_BAD_HOST_ERROR = 1042 + ER_HANDSHAKE_ERROR = 1043 + ER_DBACCESS_DENIED_ERROR = 1044 + ER_ACCESS_DENIED_ERROR = 1045 + ER_NO_DB_ERROR = 1046 + ER_UNKNOWN_COM_ERROR = 1047 + ER_BAD_NULL_ERROR = 1048 + ER_BAD_DB_ERROR = 1049 + ER_TABLE_EXISTS_ERROR = 1050 + ER_BAD_TABLE_ERROR = 1051 + ER_NON_UNIQ_ERROR = 1052 + ER_SERVER_SHUTDOWN = 1053 + ER_BAD_FIELD_ERROR = 1054 + ER_WRONG_FIELD_WITH_GROUP = 1055 + ER_WRONG_GROUP_FIELD = 1056 + ER_WRONG_SUM_SELECT = 1057 + ER_WRONG_VALUE_COUNT = 1058 + ER_TOO_LONG_IDENT = 1059 + ER_DUP_FIELDNAME = 1060 + ER_DUP_KEYNAME = 1061 + ER_DUP_ENTRY = 1062 + ER_WRONG_FIELD_SPEC = 1063 + ER_PARSE_ERROR = 1064 + ER_EMPTY_QUERY = 1065 + ER_NONUNIQ_TABLE = 1066 + ER_INVALID_DEFAULT = 1067 + ER_MULTIPLE_PRI_KEY = 1068 + ER_TOO_MANY_KEYS = 1069 + ER_TOO_MANY_KEY_PARTS = 1070 + ER_TOO_LONG_KEY = 1071 + ER_KEY_COLUMN_DOES_NOT_EXITS = 1072 + ER_BLOB_USED_AS_KEY = 1073 + ER_TOO_BIG_FIELDLENGTH = 1074 + ER_WRONG_AUTO_KEY = 1075 + ER_READY = 1076 + ER_NORMAL_SHUTDOWN = 1077 + ER_GOT_SIGNAL = 1078 + ER_SHUTDOWN_COMPLETE = 1079 + ER_FORCING_CLOSE = 1080 + ER_IPSOCK_ERROR = 1081 + ER_NO_SUCH_INDEX = 1082 + ER_WRONG_FIELD_TERMINATORS = 1083 + ER_BLOBS_AND_NO_TERMINATED = 1084 + ER_TEXTFILE_NOT_READABLE = 1085 + ER_FILE_EXISTS_ERROR = 1086 + ER_LOAD_INFO = 1087 + ER_ALTER_INFO = 1088 + ER_WRONG_SUB_KEY = 1089 + ER_CANT_REMOVE_ALL_FIELDS = 1090 + ER_CANT_DROP_FIELD_OR_KEY = 1091 + ER_INSERT_INFO = 1092 + ER_UPDATE_TABLE_USED = 1093 + ER_NO_SUCH_THREAD = 1094 + ER_KILL_DENIED_ERROR = 1095 + ER_NO_TABLES_USED = 1096 + ER_TOO_BIG_SET = 1097 + ER_NO_UNIQUE_LOGFILE = 1098 + ER_TABLE_NOT_LOCKED_FOR_WRITE = 1099 + ER_TABLE_NOT_LOCKED = 1100 + ER_BLOB_CANT_HAVE_DEFAULT = 1101 + ER_WRONG_DB_NAME = 1102 + ER_WRONG_TABLE_NAME = 1103 + ER_TOO_BIG_SELECT = 1104 + ER_UNKNOWN_ERROR = 1105 + ER_UNKNOWN_PROCEDURE = 1106 + ER_WRONG_PARAMCOUNT_TO_PROCEDURE = 1107 + ER_WRONG_PARAMETERS_TO_PROCEDURE = 1108 + ER_UNKNOWN_TABLE = 1109 + ER_FIELD_SPECIFIED_TWICE = 1110 + ER_INVALID_GROUP_FUNC_USE = 1111 + ER_UNSUPPORTED_EXTENSION = 1112 + ER_TABLE_MUST_HAVE_COLUMNS = 1113 + ER_RECORD_FILE_FULL = 1114 + ER_UNKNOWN_CHARACTER_SET = 1115 + ER_TOO_MANY_TABLES = 1116 + ER_TOO_MANY_FIELDS = 1117 + ER_TOO_BIG_ROWSIZE = 1118 + ER_STACK_OVERRUN = 1119 + ER_WRONG_OUTER_JOIN = 1120 + ER_NULL_COLUMN_IN_INDEX = 1121 + ER_CANT_FIND_UDF = 1122 + ER_CANT_INITIALIZE_UDF = 1123 + ER_UDF_NO_PATHS = 1124 + ER_UDF_EXISTS = 1125 + ER_CANT_OPEN_LIBRARY = 1126 + ER_CANT_FIND_DL_ENTRY = 1127 + ER_FUNCTION_NOT_DEFINED = 1128 + ER_HOST_IS_BLOCKED = 1129 + ER_HOST_NOT_PRIVILEGED = 1130 + ER_PASSWORD_ANONYMOUS_USER = 1131 + ER_PASSWORD_NOT_ALLOWED = 1132 + ER_PASSWORD_NO_MATCH = 1133 + ER_UPDATE_INFO = 1134 + ER_CANT_CREATE_THREAD = 1135 + ER_WRONG_VALUE_COUNT_ON_ROW = 1136 + ER_CANT_REOPEN_TABLE = 1137 + ER_INVALID_USE_OF_NULL = 1138 + ER_REGEXP_ERROR = 1139 + ER_MIX_OF_GROUP_FUNC_AND_FIELDS = 1140 + ER_NONEXISTING_GRANT = 1141 + ER_TABLEACCESS_DENIED_ERROR = 1142 + ER_COLUMNACCESS_DENIED_ERROR = 1143 + ER_ILLEGAL_GRANT_FOR_TABLE = 1144 + ER_GRANT_WRONG_HOST_OR_USER = 1145 + ER_NO_SUCH_TABLE = 1146 + ER_NONEXISTING_TABLE_GRANT = 1147 + ER_NOT_ALLOWED_COMMAND = 1148 + ER_SYNTAX_ERROR = 1149 + ER_DELAYED_CANT_CHANGE_LOCK = 1150 + ER_TOO_MANY_DELAYED_THREADS = 1151 + ER_ABORTING_CONNECTION = 1152 + ER_NET_PACKET_TOO_LARGE = 1153 + ER_NET_READ_ERROR_FROM_PIPE = 1154 + ER_NET_FCNTL_ERROR = 1155 + ER_NET_PACKETS_OUT_OF_ORDER = 1156 + ER_NET_UNCOMPRESS_ERROR = 1157 + ER_NET_READ_ERROR = 1158 + ER_NET_READ_INTERRUPTED = 1159 + ER_NET_ERROR_ON_WRITE = 1160 + ER_NET_WRITE_INTERRUPTED = 1161 + ER_TOO_LONG_STRING = 1162 + ER_TABLE_CANT_HANDLE_BLOB = 1163 + ER_TABLE_CANT_HANDLE_AUTO_INCREMENT = 1164 + ER_DELAYED_INSERT_TABLE_LOCKED = 1165 + ER_WRONG_COLUMN_NAME = 1166 + ER_WRONG_KEY_COLUMN = 1167 + ER_WRONG_MRG_TABLE = 1168 + ER_DUP_UNIQUE = 1169 + ER_BLOB_KEY_WITHOUT_LENGTH = 1170 + ER_PRIMARY_CANT_HAVE_NULL = 1171 + ER_TOO_MANY_ROWS = 1172 + ER_REQUIRES_PRIMARY_KEY = 1173 + ER_NO_RAID_COMPILED = 1174 + ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE = 1175 + ER_KEY_DOES_NOT_EXITS = 1176 + ER_CHECK_NO_SUCH_TABLE = 1177 + ER_CHECK_NOT_IMPLEMENTED = 1178 + ER_CANT_DO_THIS_DURING_AN_TRANSACTION = 1179 + ER_ERROR_DURING_COMMIT = 1180 + ER_ERROR_DURING_ROLLBACK = 1181 + ER_ERROR_DURING_FLUSH_LOGS = 1182 + ER_ERROR_DURING_CHECKPOINT = 1183 + ER_NEW_ABORTING_CONNECTION = 1184 + ER_DUMP_NOT_IMPLEMENTED = 1185 + ER_FLUSH_MASTER_BINLOG_CLOSED = 1186 + ER_INDEX_REBUILD = 1187 + ER_MASTER = 1188 + ER_MASTER_NET_READ = 1189 + ER_MASTER_NET_WRITE = 1190 + ER_FT_MATCHING_KEY_NOT_FOUND = 1191 + ER_LOCK_OR_ACTIVE_TRANSACTION = 1192 + ER_UNKNOWN_SYSTEM_VARIABLE = 1193 + ER_CRASHED_ON_USAGE = 1194 + ER_CRASHED_ON_REPAIR = 1195 + ER_WARNING_NOT_COMPLETE_ROLLBACK = 1196 + ER_TRANS_CACHE_FULL = 1197 + ER_SLAVE_MUST_STOP = 1198 + ER_SLAVE_NOT_RUNNING = 1199 + ER_BAD_SLAVE = 1200 + ER_MASTER_INFO = 1201 + ER_SLAVE_THREAD = 1202 + ER_TOO_MANY_USER_CONNECTIONS = 1203 + ER_SET_CONSTANTS_ONLY = 1204 + ER_LOCK_WAIT_TIMEOUT = 1205 + ER_LOCK_TABLE_FULL = 1206 + ER_READ_ONLY_TRANSACTION = 1207 + ER_DROP_DB_WITH_READ_LOCK = 1208 + ER_CREATE_DB_WITH_READ_LOCK = 1209 + ER_WRONG_ARGUMENTS = 1210 + ER_NO_PERMISSION_TO_CREATE_USER = 1211 + ER_UNION_TABLES_IN_DIFFERENT_DIR = 1212 + ER_LOCK_DEADLOCK = 1213 + ER_TABLE_CANT_HANDLE_FT = 1214 + ER_CANNOT_ADD_FOREIGN = 1215 + ER_NO_REFERENCED_ROW = 1216 + ER_ROW_IS_REFERENCED = 1217 + ER_CONNECT_TO_MASTER = 1218 + ER_QUERY_ON_MASTER = 1219 + ER_ERROR_WHEN_EXECUTING_COMMAND = 1220 + ER_WRONG_USAGE = 1221 + ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT = 1222 + ER_CANT_UPDATE_WITH_READLOCK = 1223 + ER_MIXING_NOT_ALLOWED = 1224 + ER_DUP_ARGUMENT = 1225 + ER_USER_LIMIT_REACHED = 1226 + ER_SPECIFIC_ACCESS_DENIED_ERROR = 1227 + ER_LOCAL_VARIABLE = 1228 + ER_GLOBAL_VARIABLE = 1229 + ER_NO_DEFAULT = 1230 + ER_WRONG_VALUE_FOR_VAR = 1231 + ER_WRONG_TYPE_FOR_VAR = 1232 + ER_VAR_CANT_BE_READ = 1233 + ER_CANT_USE_OPTION_HERE = 1234 + ER_NOT_SUPPORTED_YET = 1235 + ER_MASTER_FATAL_ERROR_READING_BINLOG = 1236 + ER_SLAVE_IGNORED_TABLE = 1237 + ER_INCORRECT_GLOBAL_LOCAL_VAR = 1238 + ER_WRONG_FK_DEF = 1239 + ER_KEY_REF_DO_NOT_MATCH_TABLE_REF = 1240 + ER_OPERAND_COLUMNS = 1241 + ER_SUBQUERY_NO_1_ROW = 1242 + ER_UNKNOWN_STMT_HANDLER = 1243 + ER_CORRUPT_HELP_DB = 1244 + ER_CYCLIC_REFERENCE = 1245 + ER_AUTO_CONVERT = 1246 + ER_ILLEGAL_REFERENCE = 1247 + ER_DERIVED_MUST_HAVE_ALIAS = 1248 + ER_SELECT_REDUCED = 1249 + ER_TABLENAME_NOT_ALLOWED_HERE = 1250 + ER_NOT_SUPPORTED_AUTH_MODE = 1251 + ER_SPATIAL_CANT_HAVE_NULL = 1252 + ER_COLLATION_CHARSET_MISMATCH = 1253 + ER_SLAVE_WAS_RUNNING = 1254 + ER_SLAVE_WAS_NOT_RUNNING = 1255 + ER_TOO_BIG_FOR_UNCOMPRESS = 1256 + ER_ZLIB_Z_MEM_ERROR = 1257 + ER_ZLIB_Z_BUF_ERROR = 1258 + ER_ZLIB_Z_DATA_ERROR = 1259 + ER_CUT_VALUE_GROUP_CONCAT = 1260 + ER_WARN_TOO_FEW_RECORDS = 1261 + ER_WARN_TOO_MANY_RECORDS = 1262 + ER_WARN_NULL_TO_NOTNULL = 1263 + ER_WARN_DATA_OUT_OF_RANGE = 1264 + WARN_DATA_TRUNCATED = 1265 + ER_WARN_USING_OTHER_HANDLER = 1266 + ER_CANT_AGGREGATE_2COLLATIONS = 1267 + ER_DROP_USER = 1268 + ER_REVOKE_GRANTS = 1269 + ER_CANT_AGGREGATE_3COLLATIONS = 1270 + ER_CANT_AGGREGATE_NCOLLATIONS = 1271 + ER_VARIABLE_IS_NOT_STRUCT = 1272 + ER_UNKNOWN_COLLATION = 1273 + ER_SLAVE_IGNORED_SSL_PARAMS = 1274 + ER_SERVER_IS_IN_SECURE_AUTH_MODE = 1275 + ER_WARN_FIELD_RESOLVED = 1276 + ER_BAD_SLAVE_UNTIL_COND = 1277 + ER_MISSING_SKIP_SLAVE = 1278 + ER_UNTIL_COND_IGNORED = 1279 + ER_WRONG_NAME_FOR_INDEX = 1280 + ER_WRONG_NAME_FOR_CATALOG = 1281 + ER_WARN_QC_RESIZE = 1282 + ER_BAD_FT_COLUMN = 1283 + ER_UNKNOWN_KEY_CACHE = 1284 + ER_WARN_HOSTNAME_WONT_WORK = 1285 + ER_UNKNOWN_STORAGE_ENGINE = 1286 + ER_WARN_DEPRECATED_SYNTAX = 1287 + ER_NON_UPDATABLE_TABLE = 1288 + ER_FEATURE_DISABLED = 1289 + ER_OPTION_PREVENTS_STATEMENT = 1290 + ER_DUPLICATED_VALUE_IN_TYPE = 1291 + ER_TRUNCATED_WRONG_VALUE = 1292 + ER_TOO_MUCH_AUTO_TIMESTAMP_COLS = 1293 + ER_INVALID_ON_UPDATE = 1294 + ER_UNSUPPORTED_PS = 1295 + ER_GET_ERRMSG = 1296 + ER_GET_TEMPORARY_ERRMSG = 1297 + ER_UNKNOWN_TIME_ZONE = 1298 + ER_WARN_INVALID_TIMESTAMP = 1299 + ER_INVALID_CHARACTER_STRING = 1300 + ER_WARN_ALLOWED_PACKET_OVERFLOWED = 1301 + ER_CONFLICTING_DECLARATIONS = 1302 + ER_SP_NO_RECURSIVE_CREATE = 1303 + ER_SP_ALREADY_EXISTS = 1304 + ER_SP_DOES_NOT_EXIST = 1305 + ER_SP_DROP_FAILED = 1306 + ER_SP_STORE_FAILED = 1307 + ER_SP_LILABEL_MISMATCH = 1308 + ER_SP_LABEL_REDEFINE = 1309 + ER_SP_LABEL_MISMATCH = 1310 + ER_SP_UNINIT_VAR = 1311 + ER_SP_BADSELECT = 1312 + ER_SP_BADRETURN = 1313 + ER_SP_BADSTATEMENT = 1314 + ER_UPDATE_LOG_DEPRECATED_IGNORED = 1315 + ER_UPDATE_LOG_DEPRECATED_TRANSLATED = 1316 + ER_QUERY_INTERRUPTED = 1317 + ER_SP_WRONG_NO_OF_ARGS = 1318 + ER_SP_COND_MISMATCH = 1319 + ER_SP_NORETURN = 1320 + ER_SP_NORETURNEND = 1321 + ER_SP_BAD_CURSOR_QUERY = 1322 + ER_SP_BAD_CURSOR_SELECT = 1323 + ER_SP_CURSOR_MISMATCH = 1324 + ER_SP_CURSOR_ALREADY_OPEN = 1325 + ER_SP_CURSOR_NOT_OPEN = 1326 + ER_SP_UNDECLARED_VAR = 1327 + ER_SP_WRONG_NO_OF_FETCH_ARGS = 1328 + ER_SP_FETCH_NO_DATA = 1329 + ER_SP_DUP_PARAM = 1330 + ER_SP_DUP_VAR = 1331 + ER_SP_DUP_COND = 1332 + ER_SP_DUP_CURS = 1333 + ER_SP_CANT_ALTER = 1334 + ER_SP_SUBSELECT_NYI = 1335 + ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG = 1336 + ER_SP_VARCOND_AFTER_CURSHNDLR = 1337 + ER_SP_CURSOR_AFTER_HANDLER = 1338 + ER_SP_CASE_NOT_FOUND = 1339 + ER_FPARSER_TOO_BIG_FILE = 1340 + ER_FPARSER_BAD_HEADER = 1341 + ER_FPARSER_EOF_IN_COMMENT = 1342 + ER_FPARSER_ERROR_IN_PARAMETER = 1343 + ER_FPARSER_EOF_IN_UNKNOWN_PARAMETER = 1344 + ER_VIEW_NO_EXPLAIN = 1345 + ER_FRM_UNKNOWN_TYPE = 1346 + ER_WRONG_OBJECT = 1347 + ER_NONUPDATEABLE_COLUMN = 1348 + ER_VIEW_SELECT_DERIVED = 1349 + ER_VIEW_SELECT_CLAUSE = 1350 + ER_VIEW_SELECT_VARIABLE = 1351 + ER_VIEW_SELECT_TMPTABLE = 1352 + ER_VIEW_WRONG_LIST = 1353 + ER_WARN_VIEW_MERGE = 1354 + ER_WARN_VIEW_WITHOUT_KEY = 1355 + ER_VIEW_INVALID = 1356 + ER_SP_NO_DROP_SP = 1357 + ER_SP_GOTO_IN_HNDLR = 1358 + ER_TRG_ALREADY_EXISTS = 1359 + ER_TRG_DOES_NOT_EXIST = 1360 + ER_TRG_ON_VIEW_OR_TEMP_TABLE = 1361 + ER_TRG_CANT_CHANGE_ROW = 1362 + ER_TRG_NO_SUCH_ROW_IN_TRG = 1363 + ER_NO_DEFAULT_FOR_FIELD = 1364 + ER_DIVISION_BY_ZERO = 1365 + ER_TRUNCATED_WRONG_VALUE_FOR_FIELD = 1366 + ER_ILLEGAL_VALUE_FOR_TYPE = 1367 + ER_VIEW_NONUPD_CHECK = 1368 + ER_VIEW_CHECK_FAILED = 1369 + ER_PROCACCESS_DENIED_ERROR = 1370 + ER_RELAY_LOG_FAIL = 1371 + ER_PASSWD_LENGTH = 1372 + ER_UNKNOWN_TARGET_BINLOG = 1373 + ER_IO_ERR_LOG_INDEX_READ = 1374 + ER_BINLOG_PURGE_PROHIBITED = 1375 + ER_FSEEK_FAIL = 1376 + ER_BINLOG_PURGE_FATAL_ERR = 1377 + ER_LOG_IN_USE = 1378 + ER_LOG_PURGE_UNKNOWN_ERR = 1379 + ER_RELAY_LOG_INIT = 1380 + ER_NO_BINARY_LOGGING = 1381 + ER_RESERVED_SYNTAX = 1382 + ER_WSAS_FAILED = 1383 + ER_DIFF_GROUPS_PROC = 1384 + ER_NO_GROUP_FOR_PROC = 1385 + ER_ORDER_WITH_PROC = 1386 + ER_LOGGING_PROHIBIT_CHANGING_OF = 1387 + ER_NO_FILE_MAPPING = 1388 + ER_WRONG_MAGIC = 1389 + ER_PS_MANY_PARAM = 1390 + ER_KEY_PART_0 = 1391 + ER_VIEW_CHECKSUM = 1392 + ER_VIEW_MULTIUPDATE = 1393 + ER_VIEW_NO_INSERT_FIELD_LIST = 1394 + ER_VIEW_DELETE_MERGE_VIEW = 1395 + ER_CANNOT_USER = 1396 + ER_XAER_NOTA = 1397 + ER_XAER_INVAL = 1398 + ER_XAER_RMFAIL = 1399 + ER_XAER_OUTSIDE = 1400 + ER_XAER_RMERR = 1401 + ER_XA_RBROLLBACK = 1402 + ER_NONEXISTING_PROC_GRANT = 1403 + ER_PROC_AUTO_GRANT_FAIL = 1404 + ER_PROC_AUTO_REVOKE_FAIL = 1405 + ER_DATA_TOO_LONG = 1406 + ER_SP_BAD_SQLSTATE = 1407 + ER_STARTUP = 1408 + ER_LOAD_FROM_FIXED_SIZE_ROWS_TO_VAR = 1409 + ER_CANT_CREATE_USER_WITH_GRANT = 1410 + ER_WRONG_VALUE_FOR_TYPE = 1411 + ER_TABLE_DEF_CHANGED = 1412 + ER_SP_DUP_HANDLER = 1413 + ER_SP_NOT_VAR_ARG = 1414 + ER_SP_NO_RETSET = 1415 + ER_CANT_CREATE_GEOMETRY_OBJECT = 1416 + ER_FAILED_ROUTINE_BREAK_BINLOG = 1417 + ER_BINLOG_UNSAFE_ROUTINE = 1418 + ER_BINLOG_CREATE_ROUTINE_NEED_SUPER = 1419 + ER_EXEC_STMT_WITH_OPEN_CURSOR = 1420 + ER_STMT_HAS_NO_OPEN_CURSOR = 1421 + ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG = 1422 + ER_NO_DEFAULT_FOR_VIEW_FIELD = 1423 + ER_SP_NO_RECURSION = 1424 + ER_TOO_BIG_SCALE = 1425 + ER_TOO_BIG_PRECISION = 1426 + ER_M_BIGGER_THAN_D = 1427 + ER_WRONG_LOCK_OF_SYSTEM_TABLE = 1428 + ER_CONNECT_TO_FOREIGN_DATA_SOURCE = 1429 + ER_QUERY_ON_FOREIGN_DATA_SOURCE = 1430 + ER_FOREIGN_DATA_SOURCE_DOESNT_EXIST = 1431 + ER_FOREIGN_DATA_STRING_INVALID_CANT_CREATE = 1432 + ER_FOREIGN_DATA_STRING_INVALID = 1433 + ER_CANT_CREATE_FEDERATED_TABLE = 1434 + ER_TRG_IN_WRONG_SCHEMA = 1435 + ER_STACK_OVERRUN_NEED_MORE = 1436 + ER_TOO_LONG_BODY = 1437 + ER_WARN_CANT_DROP_DEFAULT_KEYCACHE = 1438 + ER_TOO_BIG_DISPLAYWIDTH = 1439 + ER_XAER_DUPID = 1440 + ER_DATETIME_FUNCTION_OVERFLOW = 1441 + ER_CANT_UPDATE_USED_TABLE_IN_SF_OR_TRG = 1442 + ER_VIEW_PREVENT_UPDATE = 1443 + ER_PS_NO_RECURSION = 1444 + ER_SP_CANT_SET_AUTOCOMMIT = 1445 + ER_MALFORMED_DEFINER = 1446 + ER_VIEW_FRM_NO_USER = 1447 + ER_VIEW_OTHER_USER = 1448 + ER_NO_SUCH_USER = 1449 + ER_FORBID_SCHEMA_CHANGE = 1450 + ER_ROW_IS_REFERENCED_2 = 1451 + ER_NO_REFERENCED_ROW_2 = 1452 + ER_SP_BAD_VAR_SHADOW = 1453 + ER_TRG_NO_DEFINER = 1454 + ER_OLD_FILE_FORMAT = 1455 + ER_SP_RECURSION_LIMIT = 1456 + ER_SP_PROC_TABLE_CORRUPT = 1457 + ER_SP_WRONG_NAME = 1458 + ER_TABLE_NEEDS_UPGRADE = 1459 + ER_SP_NO_AGGREGATE = 1460 + ER_MAX_PREPARED_STMT_COUNT_REACHED = 1461 + ER_VIEW_RECURSIVE = 1462 + ER_NON_GROUPING_FIELD_USED = 1463 + ER_TABLE_CANT_HANDLE_SPKEYS = 1464 + ER_NO_TRIGGERS_ON_SYSTEM_SCHEMA = 1465 + ER_REMOVED_SPACES = 1466 + ER_AUTOINC_READ_FAILED = 1467 + ER_USERNAME = 1468 + ER_HOSTNAME = 1469 + ER_WRONG_STRING_LENGTH = 1470 + ER_NON_INSERTABLE_TABLE = 1471 + ER_ADMIN_WRONG_MRG_TABLE = 1472 + ER_TOO_HIGH_LEVEL_OF_NESTING_FOR_SELECT = 1473 + ER_NAME_BECOMES_EMPTY = 1474 + ER_AMBIGUOUS_FIELD_TERM = 1475 + ER_FOREIGN_SERVER_EXISTS = 1476 + ER_FOREIGN_SERVER_DOESNT_EXIST = 1477 + ER_ILLEGAL_HA_CREATE_OPTION = 1478 + ER_PARTITION_REQUIRES_VALUES_ERROR = 1479 + ER_PARTITION_WRONG_VALUES_ERROR = 1480 + ER_PARTITION_MAXVALUE_ERROR = 1481 + ER_PARTITION_SUBPARTITION_ERROR = 1482 + ER_PARTITION_SUBPART_MIX_ERROR = 1483 + ER_PARTITION_WRONG_NO_PART_ERROR = 1484 + ER_PARTITION_WRONG_NO_SUBPART_ERROR = 1485 + ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR = 1486 + ER_NO_CONST_EXPR_IN_RANGE_OR_LIST_ERROR = 1487 + ER_FIELD_NOT_FOUND_PART_ERROR = 1488 + ER_LIST_OF_FIELDS_ONLY_IN_HASH_ERROR = 1489 + ER_INCONSISTENT_PARTITION_INFO_ERROR = 1490 + ER_PARTITION_FUNC_NOT_ALLOWED_ERROR = 1491 + ER_PARTITIONS_MUST_BE_DEFINED_ERROR = 1492 + ER_RANGE_NOT_INCREASING_ERROR = 1493 + ER_INCONSISTENT_TYPE_OF_FUNCTIONS_ERROR = 1494 + ER_MULTIPLE_DEF_CONST_IN_LIST_PART_ERROR = 1495 + ER_PARTITION_ENTRY_ERROR = 1496 + ER_MIX_HANDLER_ERROR = 1497 + ER_PARTITION_NOT_DEFINED_ERROR = 1498 + ER_TOO_MANY_PARTITIONS_ERROR = 1499 + ER_SUBPARTITION_ERROR = 1500 + ER_CANT_CREATE_HANDLER_FILE = 1501 + ER_BLOB_FIELD_IN_PART_FUNC_ERROR = 1502 + ER_UNIQUE_KEY_NEED_ALL_FIELDS_IN_PF = 1503 + ER_NO_PARTS_ERROR = 1504 + ER_PARTITION_MGMT_ON_NONPARTITIONED = 1505 + ER_FOREIGN_KEY_ON_PARTITIONED = 1506 + ER_DROP_PARTITION_NON_EXISTENT = 1507 + ER_DROP_LAST_PARTITION = 1508 + ER_COALESCE_ONLY_ON_HASH_PARTITION = 1509 + ER_REORG_HASH_ONLY_ON_SAME_NO = 1510 + ER_REORG_NO_PARAM_ERROR = 1511 + ER_ONLY_ON_RANGE_LIST_PARTITION = 1512 + ER_ADD_PARTITION_SUBPART_ERROR = 1513 + ER_ADD_PARTITION_NO_NEW_PARTITION = 1514 + ER_COALESCE_PARTITION_NO_PARTITION = 1515 + ER_REORG_PARTITION_NOT_EXIST = 1516 + ER_SAME_NAME_PARTITION = 1517 + ER_NO_BINLOG_ERROR = 1518 + ER_CONSECUTIVE_REORG_PARTITIONS = 1519 + ER_REORG_OUTSIDE_RANGE = 1520 + ER_PARTITION_FUNCTION_FAILURE = 1521 + ER_PART_STATE_ERROR = 1522 + ER_LIMITED_PART_RANGE = 1523 + ER_PLUGIN_IS_NOT_LOADED = 1524 + ER_WRONG_VALUE = 1525 + ER_NO_PARTITION_FOR_GIVEN_VALUE = 1526 + ER_FILEGROUP_OPTION_ONLY_ONCE = 1527 + ER_CREATE_FILEGROUP_FAILED = 1528 + ER_DROP_FILEGROUP_FAILED = 1529 + ER_TABLESPACE_AUTO_EXTEND_ERROR = 1530 + ER_WRONG_SIZE_NUMBER = 1531 + ER_SIZE_OVERFLOW_ERROR = 1532 + ER_ALTER_FILEGROUP_FAILED = 1533 + ER_BINLOG_ROW_LOGGING_FAILED = 1534 + ER_BINLOG_ROW_WRONG_TABLE_DEF = 1535 + ER_BINLOG_ROW_RBR_TO_SBR = 1536 + ER_EVENT_ALREADY_EXISTS = 1537 + ER_EVENT_STORE_FAILED = 1538 + ER_EVENT_DOES_NOT_EXIST = 1539 + ER_EVENT_CANT_ALTER = 1540 + ER_EVENT_DROP_FAILED = 1541 + ER_EVENT_INTERVAL_NOT_POSITIVE_OR_TOO_BIG = 1542 + ER_EVENT_ENDS_BEFORE_STARTS = 1543 + ER_EVENT_EXEC_TIME_IN_THE_PAST = 1544 + ER_EVENT_OPEN_TABLE_FAILED = 1545 + ER_EVENT_NEITHER_M_EXPR_NOR_M_AT = 1546 + ER_OBSOLETE_COL_COUNT_DOESNT_MATCH_CORRUPTED = 1547 + ER_OBSOLETE_CANNOT_LOAD_FROM_TABLE = 1548 + ER_EVENT_CANNOT_DELETE = 1549 + ER_EVENT_COMPILE_ERROR = 1550 + ER_EVENT_SAME_NAME = 1551 + ER_EVENT_DATA_TOO_LONG = 1552 + ER_DROP_INDEX_FK = 1553 + ER_WARN_DEPRECATED_SYNTAX_WITH_VER = 1554 + ER_CANT_WRITE_LOCK_LOG_TABLE = 1555 + ER_CANT_LOCK_LOG_TABLE = 1556 + ER_FOREIGN_DUPLICATE_KEY_OLD_UNUSED = 1557 + ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE = 1558 + ER_TEMP_TABLE_PREVENTS_SWITCH_OUT_OF_RBR = 1559 + ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_FORMAT = 1560 + ER_NDB_CANT_SWITCH_BINLOG_FORMAT = 1561 + ER_PARTITION_NO_TEMPORARY = 1562 + ER_PARTITION_CONST_DOMAIN_ERROR = 1563 + ER_PARTITION_FUNCTION_IS_NOT_ALLOWED = 1564 + ER_DDL_LOG_ERROR = 1565 + ER_NULL_IN_VALUES_LESS_THAN = 1566 + ER_WRONG_PARTITION_NAME = 1567 + ER_CANT_CHANGE_TX_CHARACTERISTICS = 1568 + ER_DUP_ENTRY_AUTOINCREMENT_CASE = 1569 + ER_EVENT_MODIFY_QUEUE_ERROR = 1570 + ER_EVENT_SET_VAR_ERROR = 1571 + ER_PARTITION_MERGE_ERROR = 1572 + ER_CANT_ACTIVATE_LOG = 1573 + ER_RBR_NOT_AVAILABLE = 1574 + ER_BASE64_DECODE_ERROR = 1575 + ER_EVENT_RECURSION_FORBIDDEN = 1576 + ER_EVENTS_DB_ERROR = 1577 + ER_ONLY_INTEGERS_ALLOWED = 1578 + ER_UNSUPORTED_LOG_ENGINE = 1579 + ER_BAD_LOG_STATEMENT = 1580 + ER_CANT_RENAME_LOG_TABLE = 1581 + ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT = 1582 + ER_WRONG_PARAMETERS_TO_NATIVE_FCT = 1583 + ER_WRONG_PARAMETERS_TO_STORED_FCT = 1584 + ER_NATIVE_FCT_NAME_COLLISION = 1585 + ER_DUP_ENTRY_WITH_KEY_NAME = 1586 + ER_BINLOG_PURGE_EMFILE = 1587 + ER_EVENT_CANNOT_CREATE_IN_THE_PAST = 1588 + ER_EVENT_CANNOT_ALTER_IN_THE_PAST = 1589 + ER_SLAVE_INCIDENT = 1590 + ER_NO_PARTITION_FOR_GIVEN_VALUE_SILENT = 1591 + ER_BINLOG_UNSAFE_STATEMENT = 1592 + ER_SLAVE_FATAL_ERROR = 1593 + ER_SLAVE_RELAY_LOG_READ_FAILURE = 1594 + ER_SLAVE_RELAY_LOG_WRITE_FAILURE = 1595 + ER_SLAVE_CREATE_EVENT_FAILURE = 1596 + ER_SLAVE_MASTER_COM_FAILURE = 1597 + ER_BINLOG_LOGGING_IMPOSSIBLE = 1598 + ER_VIEW_NO_CREATION_CTX = 1599 + ER_VIEW_INVALID_CREATION_CTX = 1600 + ER_SR_INVALID_CREATION_CTX = 1601 + ER_TRG_CORRUPTED_FILE = 1602 + ER_TRG_NO_CREATION_CTX = 1603 + ER_TRG_INVALID_CREATION_CTX = 1604 + ER_EVENT_INVALID_CREATION_CTX = 1605 + ER_TRG_CANT_OPEN_TABLE = 1606 + ER_CANT_CREATE_SROUTINE = 1607 + ER_NEVER_USED = 1608 + ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENT = 1609 + ER_SLAVE_CORRUPT_EVENT = 1610 + ER_LOAD_DATA_INVALID_COLUMN = 1611 + ER_LOG_PURGE_NO_FILE = 1612 + ER_XA_RBTIMEOUT = 1613 + ER_XA_RBDEADLOCK = 1614 + ER_NEED_REPREPARE = 1615 + ER_DELAYED_NOT_SUPPORTED = 1616 + WARN_NO_MASTER_INFO = 1617 + WARN_OPTION_IGNORED = 1618 + WARN_PLUGIN_DELETE_BUILTIN = 1619 + WARN_PLUGIN_BUSY = 1620 + ER_VARIABLE_IS_READONLY = 1621 + ER_WARN_ENGINE_TRANSACTION_ROLLBACK = 1622 + ER_SLAVE_HEARTBEAT_FAILURE = 1623 + ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE = 1624 + ER_NDB_REPLICATION_SCHEMA_ERROR = 1625 + ER_CONFLICT_FN_PARSE_ERROR = 1626 + ER_EXCEPTIONS_WRITE_ERROR = 1627 + ER_TOO_LONG_TABLE_COMMENT = 1628 + ER_TOO_LONG_FIELD_COMMENT = 1629 + ER_FUNC_INEXISTENT_NAME_COLLISION = 1630 + ER_DATABASE_NAME = 1631 + ER_TABLE_NAME = 1632 + ER_PARTITION_NAME = 1633 + ER_SUBPARTITION_NAME = 1634 + ER_TEMPORARY_NAME = 1635 + ER_RENAMED_NAME = 1636 + ER_TOO_MANY_CONCURRENT_TRXS = 1637 + WARN_NON_ASCII_SEPARATOR_NOT_IMPLEMENTED = 1638 + ER_DEBUG_SYNC_TIMEOUT = 1639 + ER_DEBUG_SYNC_HIT_LIMIT = 1640 + ER_DUP_SIGNAL_SET = 1641 + ER_SIGNAL_WARN = 1642 + ER_SIGNAL_NOT_FOUND = 1643 + ER_SIGNAL_EXCEPTION = 1644 + ER_RESIGNAL_WITHOUT_ACTIVE_HANDLER = 1645 + ER_SIGNAL_BAD_CONDITION_TYPE = 1646 + WARN_COND_ITEM_TRUNCATED = 1647 + ER_COND_ITEM_TOO_LONG = 1648 + ER_UNKNOWN_LOCALE = 1649 + ER_SLAVE_IGNORE_SERVER_IDS = 1650 + ER_QUERY_CACHE_DISABLED = 1651 + ER_SAME_NAME_PARTITION_FIELD = 1652 + ER_PARTITION_COLUMN_LIST_ERROR = 1653 + ER_WRONG_TYPE_COLUMN_VALUE_ERROR = 1654 + ER_TOO_MANY_PARTITION_FUNC_FIELDS_ERROR = 1655 + ER_MAXVALUE_IN_VALUES_IN = 1656 + ER_TOO_MANY_VALUES_ERROR = 1657 + ER_ROW_SINGLE_PARTITION_FIELD_ERROR = 1658 + ER_FIELD_TYPE_NOT_ALLOWED_AS_PARTITION_FIELD = 1659 + ER_PARTITION_FIELDS_TOO_LONG = 1660 + ER_BINLOG_ROW_ENGINE_AND_STMT_ENGINE = 1661 + ER_BINLOG_ROW_MODE_AND_STMT_ENGINE = 1662 + ER_BINLOG_UNSAFE_AND_STMT_ENGINE = 1663 + ER_BINLOG_ROW_INJECTION_AND_STMT_ENGINE = 1664 + ER_BINLOG_STMT_MODE_AND_ROW_ENGINE = 1665 + ER_BINLOG_ROW_INJECTION_AND_STMT_MODE = 1666 + ER_BINLOG_MULTIPLE_ENGINES_AND_SELF_LOGGING_ENGINE = 1667 + ER_BINLOG_UNSAFE_LIMIT = 1668 + ER_BINLOG_UNSAFE_INSERT_DELAYED = 1669 + ER_BINLOG_UNSAFE_SYSTEM_TABLE = 1670 + ER_BINLOG_UNSAFE_AUTOINC_COLUMNS = 1671 + ER_BINLOG_UNSAFE_UDF = 1672 + ER_BINLOG_UNSAFE_SYSTEM_VARIABLE = 1673 + ER_BINLOG_UNSAFE_SYSTEM_FUNCTION = 1674 + ER_BINLOG_UNSAFE_NONTRANS_AFTER_TRANS = 1675 + ER_MESSAGE_AND_STATEMENT = 1676 + ER_SLAVE_CONVERSION_FAILED = 1677 + ER_SLAVE_CANT_CREATE_CONVERSION = 1678 + ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_FORMAT = 1679 + ER_PATH_LENGTH = 1680 + ER_WARN_DEPRECATED_SYNTAX_NO_REPLACEMENT = 1681 + ER_WRONG_NATIVE_TABLE_STRUCTURE = 1682 + ER_WRONG_PERFSCHEMA_USAGE = 1683 + ER_WARN_I_S_SKIPPED_TABLE = 1684 + ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_DIRECT = 1685 + ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_DIRECT = 1686 + ER_SPATIAL_MUST_HAVE_GEOM_COL = 1687 + ER_TOO_LONG_INDEX_COMMENT = 1688 + ER_LOCK_ABORTED = 1689 + ER_DATA_OUT_OF_RANGE = 1690 + ER_WRONG_SPVAR_TYPE_IN_LIMIT = 1691 + ER_BINLOG_UNSAFE_MULTIPLE_ENGINES_AND_SELF_LOGGING_ENGINE = 1692 + ER_BINLOG_UNSAFE_MIXED_STATEMENT = 1693 + ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_SQL_LOG_BIN = 1694 + ER_STORED_FUNCTION_PREVENTS_SWITCH_SQL_LOG_BIN = 1695 + ER_FAILED_READ_FROM_PAR_FILE = 1696 + ER_VALUES_IS_NOT_INT_TYPE_ERROR = 1697 + ER_ACCESS_DENIED_NO_PASSWORD_ERROR = 1698 + ER_SET_PASSWORD_AUTH_PLUGIN = 1699 + ER_GRANT_PLUGIN_USER_EXISTS = 1700 + ER_TRUNCATE_ILLEGAL_FK = 1701 + ER_PLUGIN_IS_PERMANENT = 1702 + ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MIN = 1703 + ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MAX = 1704 + ER_STMT_CACHE_FULL = 1705 + ER_MULTI_UPDATE_KEY_CONFLICT = 1706 + ER_TABLE_NEEDS_REBUILD = 1707 + WARN_OPTION_BELOW_LIMIT = 1708 + ER_INDEX_COLUMN_TOO_LONG = 1709 + ER_ERROR_IN_TRIGGER_BODY = 1710 + ER_ERROR_IN_UNKNOWN_TRIGGER_BODY = 1711 + ER_INDEX_CORRUPT = 1712 + ER_UNDO_RECORD_TOO_BIG = 1713 + ER_BINLOG_UNSAFE_INSERT_IGNORE_SELECT = 1714 + ER_BINLOG_UNSAFE_INSERT_SELECT_UPDATE = 1715 + ER_BINLOG_UNSAFE_REPLACE_SELECT = 1716 + ER_BINLOG_UNSAFE_CREATE_IGNORE_SELECT = 1717 + ER_BINLOG_UNSAFE_CREATE_REPLACE_SELECT = 1718 + ER_BINLOG_UNSAFE_UPDATE_IGNORE = 1719 + ER_PLUGIN_NO_UNINSTALL = 1720 + ER_PLUGIN_NO_INSTALL = 1721 + ER_BINLOG_UNSAFE_WRITE_AUTOINC_SELECT = 1722 + ER_BINLOG_UNSAFE_CREATE_SELECT_AUTOINC = 1723 + ER_BINLOG_UNSAFE_INSERT_TWO_KEYS = 1724 + ER_TABLE_IN_FK_CHECK = 1725 + ER_UNSUPPORTED_ENGINE = 1726 + ER_BINLOG_UNSAFE_AUTOINC_NOT_FIRST = 1727 + ER_CANNOT_LOAD_FROM_TABLE_V2 = 1728 + ER_MASTER_DELAY_VALUE_OUT_OF_RANGE = 1729 + ER_ONLY_FD_AND_RBR_EVENTS_ALLOWED_IN_BINLOG_STATEMENT = 1730 + ER_PARTITION_EXCHANGE_DIFFERENT_OPTION = 1731 + ER_PARTITION_EXCHANGE_PART_TABLE = 1732 + ER_PARTITION_EXCHANGE_TEMP_TABLE = 1733 + ER_PARTITION_INSTEAD_OF_SUBPARTITION = 1734 + ER_UNKNOWN_PARTITION = 1735 + ER_TABLES_DIFFERENT_METADATA = 1736 + ER_ROW_DOES_NOT_MATCH_PARTITION = 1737 + ER_BINLOG_CACHE_SIZE_GREATER_THAN_MAX = 1738 + ER_WARN_INDEX_NOT_APPLICABLE = 1739 + ER_PARTITION_EXCHANGE_FOREIGN_KEY = 1740 + ER_NO_SUCH_KEY_VALUE = 1741 + ER_RPL_INFO_DATA_TOO_LONG = 1742 + ER_NETWORK_READ_EVENT_CHECKSUM_FAILURE = 1743 + ER_BINLOG_READ_EVENT_CHECKSUM_FAILURE = 1744 + ER_BINLOG_STMT_CACHE_SIZE_GREATER_THAN_MAX = 1745 + ER_CANT_UPDATE_TABLE_IN_CREATE_TABLE_SELECT = 1746 + ER_PARTITION_CLAUSE_ON_NONPARTITIONED = 1747 + ER_ROW_DOES_NOT_MATCH_GIVEN_PARTITION_SET = 1748 + ER_NO_SUCH_PARTITION__UNUSED = 1749 + ER_CHANGE_RPL_INFO_REPOSITORY_FAILURE = 1750 + ER_WARNING_NOT_COMPLETE_ROLLBACK_WITH_CREATED_TEMP_TABLE = 1751 + ER_WARNING_NOT_COMPLETE_ROLLBACK_WITH_DROPPED_TEMP_TABLE = 1752 + ER_MTS_FEATURE_IS_NOT_SUPPORTED = 1753 + ER_MTS_UPDATED_DBS_GREATER_MAX = 1754 + ER_MTS_CANT_PARALLEL = 1755 + ER_MTS_INCONSISTENT_DATA = 1756 + ER_FULLTEXT_NOT_SUPPORTED_WITH_PARTITIONING = 1757 + ER_DA_INVALID_CONDITION_NUMBER = 1758 + ER_INSECURE_PLAIN_TEXT = 1759 + ER_INSECURE_CHANGE_MASTER = 1760 + ER_FOREIGN_DUPLICATE_KEY_WITH_CHILD_INFO = 1761 + ER_FOREIGN_DUPLICATE_KEY_WITHOUT_CHILD_INFO = 1762 + ER_SQLTHREAD_WITH_SECURE_SLAVE = 1763 + ER_TABLE_HAS_NO_FT = 1764 + ER_VARIABLE_NOT_SETTABLE_IN_SF_OR_TRIGGER = 1765 + ER_VARIABLE_NOT_SETTABLE_IN_TRANSACTION = 1766 + ER_GTID_NEXT_IS_NOT_IN_GTID_NEXT_LIST = 1767 + ER_CANT_CHANGE_GTID_NEXT_IN_TRANSACTION_WHEN_GTID_NEXT_LIST_IS_NULL = 1768 + ER_SET_STATEMENT_CANNOT_INVOKE_FUNCTION = 1769 + ER_GTID_NEXT_CANT_BE_AUTOMATIC_IF_GTID_NEXT_LIST_IS_NON_NULL = 1770 + ER_SKIPPING_LOGGED_TRANSACTION = 1771 + ER_MALFORMED_GTID_SET_SPECIFICATION = 1772 + ER_MALFORMED_GTID_SET_ENCODING = 1773 + ER_MALFORMED_GTID_SPECIFICATION = 1774 + ER_GNO_EXHAUSTED = 1775 + ER_BAD_SLAVE_AUTO_POSITION = 1776 + ER_AUTO_POSITION_REQUIRES_GTID_MODE_ON = 1777 + ER_CANT_DO_IMPLICIT_COMMIT_IN_TRX_WHEN_GTID_NEXT_IS_SET = 1778 + ER_GTID_MODE_2_OR_3_REQUIRES_ENFORCE_GTID_CONSISTENCY_ON = 1779 + ER_GTID_MODE_REQUIRES_BINLOG = 1780 + ER_CANT_SET_GTID_NEXT_TO_GTID_WHEN_GTID_MODE_IS_OFF = 1781 + ER_CANT_SET_GTID_NEXT_TO_ANONYMOUS_WHEN_GTID_MODE_IS_ON = 1782 + ER_CANT_SET_GTID_NEXT_LIST_TO_NON_NULL_WHEN_GTID_MODE_IS_OFF = 1783 + ER_FOUND_GTID_EVENT_WHEN_GTID_MODE_IS_OFF = 1784 + ER_GTID_UNSAFE_NON_TRANSACTIONAL_TABLE = 1785 + ER_GTID_UNSAFE_CREATE_SELECT = 1786 + ER_GTID_UNSAFE_CREATE_DROP_TEMPORARY_TABLE_IN_TRANSACTION = 1787 + ER_GTID_MODE_CAN_ONLY_CHANGE_ONE_STEP_AT_A_TIME = 1788 + ER_MASTER_HAS_PURGED_REQUIRED_GTIDS = 1789 + ER_CANT_SET_GTID_NEXT_WHEN_OWNING_GTID = 1790 + ER_UNKNOWN_EXPLAIN_FORMAT = 1791 + ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION = 1792 + ER_TOO_LONG_TABLE_PARTITION_COMMENT = 1793 + ER_SLAVE_CONFIGURATION = 1794 + ER_INNODB_FT_LIMIT = 1795 + ER_INNODB_NO_FT_TEMP_TABLE = 1796 + ER_INNODB_FT_WRONG_DOCID_COLUMN = 1797 + ER_INNODB_FT_WRONG_DOCID_INDEX = 1798 + ER_INNODB_ONLINE_LOG_TOO_BIG = 1799 + ER_UNKNOWN_ALTER_ALGORITHM = 1800 + ER_UNKNOWN_ALTER_LOCK = 1801 + ER_MTS_CHANGE_MASTER_CANT_RUN_WITH_GAPS = 1802 + ER_MTS_RECOVERY_FAILURE = 1803 + ER_MTS_RESET_WORKERS = 1804 + ER_COL_COUNT_DOESNT_MATCH_CORRUPTED_V2 = 1805 + ER_SLAVE_SILENT_RETRY_TRANSACTION = 1806 + ER_DISCARD_FK_CHECKS_RUNNING = 1807 + ER_TABLE_SCHEMA_MISMATCH = 1808 + ER_TABLE_IN_SYSTEM_TABLESPACE = 1809 + ER_IO_READ_ERROR = 1810 + ER_IO_WRITE_ERROR = 1811 + ER_TABLESPACE_MISSING = 1812 + ER_TABLESPACE_EXISTS = 1813 + ER_TABLESPACE_DISCARDED = 1814 + ER_INTERNAL_ERROR = 1815 + ER_INNODB_IMPORT_ERROR = 1816 + ER_INNODB_INDEX_CORRUPT = 1817 + ER_INVALID_YEAR_COLUMN_LENGTH = 1818 + ER_NOT_VALID_PASSWORD = 1819 + ER_MUST_CHANGE_PASSWORD = 1820 + ER_FK_NO_INDEX_CHILD = 1821 + ER_FK_NO_INDEX_PARENT = 1822 + ER_FK_FAIL_ADD_SYSTEM = 1823 + ER_FK_CANNOT_OPEN_PARENT = 1824 + ER_FK_INCORRECT_OPTION = 1825 + ER_FK_DUP_NAME = 1826 + ER_PASSWORD_FORMAT = 1827 + ER_FK_COLUMN_CANNOT_DROP = 1828 + ER_FK_COLUMN_CANNOT_DROP_CHILD = 1829 + ER_FK_COLUMN_NOT_NULL = 1830 + ER_DUP_INDEX = 1831 + ER_FK_COLUMN_CANNOT_CHANGE = 1832 + ER_FK_COLUMN_CANNOT_CHANGE_CHILD = 1833 + ER_FK_CANNOT_DELETE_PARENT = 1834 + ER_MALFORMED_PACKET = 1835 + ER_READ_ONLY_MODE = 1836 + ER_GTID_NEXT_TYPE_UNDEFINED_GROUP = 1837 + ER_VARIABLE_NOT_SETTABLE_IN_SP = 1838 + ER_CANT_SET_GTID_PURGED_WHEN_GTID_MODE_IS_OFF = 1839 + ER_CANT_SET_GTID_PURGED_WHEN_GTID_EXECUTED_IS_NOT_EMPTY = 1840 + ER_CANT_SET_GTID_PURGED_WHEN_OWNED_GTIDS_IS_NOT_EMPTY = 1841 + ER_GTID_PURGED_WAS_CHANGED = 1842 + ER_GTID_EXECUTED_WAS_CHANGED = 1843 + ER_BINLOG_STMT_MODE_AND_NO_REPL_TABLES = 1844 + ER_ALTER_OPERATION_NOT_SUPPORTED = 1845 + ER_ALTER_OPERATION_NOT_SUPPORTED_REASON = 1846 + ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_COPY = 1847 + ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_PARTITION = 1848 + ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_FK_RENAME = 1849 + ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_COLUMN_TYPE = 1850 + ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_FK_CHECK = 1851 + ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_IGNORE = 1852 + ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_NOPK = 1853 + ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_AUTOINC = 1854 + ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_HIDDEN_FTS = 1855 + ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_CHANGE_FTS = 1856 + ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_FTS = 1857 + ER_SQL_SLAVE_SKIP_COUNTER_NOT_SETTABLE_IN_GTID_MODE = 1858 + ER_DUP_UNKNOWN_IN_INDEX = 1859 + ER_IDENT_CAUSES_TOO_LONG_PATH = 1860 + ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_NOT_NULL = 1861 + ER_MUST_CHANGE_PASSWORD_LOGIN = 1862 + ER_ROW_IN_WRONG_PARTITION = 1863 + ER_ERROR_LAST = 1863 +) diff --git a/v2/vendor/github.com/go-mysql-org/go-mysql/mysql/errname.go b/v2/vendor/github.com/go-mysql-org/go-mysql/mysql/errname.go new file mode 100644 index 0000000..592f4bb --- /dev/null +++ b/v2/vendor/github.com/go-mysql-org/go-mysql/mysql/errname.go @@ -0,0 +1,868 @@ +package mysql + +var MySQLErrName = map[uint16]string{ + ER_HASHCHK: "hashchk", + ER_NISAMCHK: "isamchk", + ER_NO: "NO", + ER_YES: "YES", + ER_CANT_CREATE_FILE: "Can't create file '%-.200s' (errno: %d - %s)", + ER_CANT_CREATE_TABLE: "Can't create table '%-.200s' (errno: %d)", + ER_CANT_CREATE_DB: "Can't create database '%-.192s' (errno: %d)", + ER_DB_CREATE_EXISTS: "Can't create database '%-.192s'; database exists", + ER_DB_DROP_EXISTS: "Can't drop database '%-.192s'; database doesn't exist", + ER_DB_DROP_DELETE: "Error dropping database (can't delete '%-.192s', errno: %d)", + ER_DB_DROP_RMDIR: "Error dropping database (can't rmdir '%-.192s', errno: %d)", + ER_CANT_DELETE_FILE: "Error on delete of '%-.192s' (errno: %d - %s)", + ER_CANT_FIND_SYSTEM_REC: "Can't read record in system table", + ER_CANT_GET_STAT: "Can't get status of '%-.200s' (errno: %d - %s)", + ER_CANT_GET_WD: "Can't get working directory (errno: %d - %s)", + ER_CANT_LOCK: "Can't lock file (errno: %d - %s)", + ER_CANT_OPEN_FILE: "Can't open file: '%-.200s' (errno: %d - %s)", + ER_FILE_NOT_FOUND: "Can't find file: '%-.200s' (errno: %d - %s)", + ER_CANT_READ_DIR: "Can't read dir of '%-.192s' (errno: %d - %s)", + ER_CANT_SET_WD: "Can't change dir to '%-.192s' (errno: %d - %s)", + ER_CHECKREAD: "Record has changed since last read in table '%-.192s'", + ER_DISK_FULL: "Disk full (%s); waiting for someone to free some space... (errno: %d - %s)", + ER_DUP_KEY: "Can't write; duplicate key in table '%-.192s'", + ER_ERROR_ON_CLOSE: "Error on close of '%-.192s' (errno: %d - %s)", + ER_ERROR_ON_READ: "Error reading file '%-.200s' (errno: %d - %s)", + ER_ERROR_ON_RENAME: "Error on rename of '%-.210s' to '%-.210s' (errno: %d - %s)", + ER_ERROR_ON_WRITE: "Error writing file '%-.200s' (errno: %d - %s)", + ER_FILE_USED: "'%-.192s' is locked against change", + ER_FILSORT_ABORT: "Sort aborted", + ER_FORM_NOT_FOUND: "View '%-.192s' doesn't exist for '%-.192s'", + ER_GET_ERRNO: "Got error %d from storage engine", + ER_ILLEGAL_HA: "Table storage engine for '%-.192s' doesn't have this option", + ER_KEY_NOT_FOUND: "Can't find record in '%-.192s'", + ER_NOT_FORM_FILE: "Incorrect information in file: '%-.200s'", + ER_NOT_KEYFILE: "Incorrect key file for table '%-.200s'; try to repair it", + ER_OLD_KEYFILE: "Old key file for table '%-.192s'; repair it!", + ER_OPEN_AS_READONLY: "Table '%-.192s' is read only", + ER_OUTOFMEMORY: "Out of memory; restart server and try again (needed %d bytes)", + ER_OUT_OF_SORTMEMORY: "Out of sort memory, consider increasing server sort buffer size", + ER_UNEXPECTED_EOF: "Unexpected EOF found when reading file '%-.192s' (errno: %d - %s)", + ER_CON_COUNT_ERROR: "Too many connections", + ER_OUT_OF_RESOURCES: "Out of memory; check if mysqld or some other process uses all available memory; if not, you may have to use 'ulimit' to allow mysqld to use more memory or you can add more swap space", + ER_BAD_HOST_ERROR: "Can't get hostname for your address", + ER_HANDSHAKE_ERROR: "Bad handshake", + ER_DBACCESS_DENIED_ERROR: "Access denied for user '%-.48s'@'%-.64s' to database '%-.192s'", + ER_ACCESS_DENIED_ERROR: "Access denied for user '%-.48s'@'%-.64s' (using password: %s)", + ER_NO_DB_ERROR: "No database selected", + ER_UNKNOWN_COM_ERROR: "Unknown command", + ER_BAD_NULL_ERROR: "Column '%-.192s' cannot be null", + ER_BAD_DB_ERROR: "Unknown database '%-.192s'", + ER_TABLE_EXISTS_ERROR: "Table '%-.192s' already exists", + ER_BAD_TABLE_ERROR: "Unknown table '%-.100s'", + ER_NON_UNIQ_ERROR: "Column '%-.192s' in %-.192s is ambiguous", + ER_SERVER_SHUTDOWN: "Server shutdown in progress", + ER_BAD_FIELD_ERROR: "Unknown column '%-.192s' in '%-.192s'", + ER_WRONG_FIELD_WITH_GROUP: "'%-.192s' isn't in GROUP BY", + ER_WRONG_GROUP_FIELD: "Can't group on '%-.192s'", + ER_WRONG_SUM_SELECT: "Statement has sum functions and columns in same statement", + ER_WRONG_VALUE_COUNT: "Column count doesn't match value count", + ER_TOO_LONG_IDENT: "Identifier name '%-.100s' is too long", + ER_DUP_FIELDNAME: "Duplicate column name '%-.192s'", + ER_DUP_KEYNAME: "Duplicate key name '%-.192s'", + ER_DUP_ENTRY: "Duplicate entry '%-.192s' for key %d", + ER_WRONG_FIELD_SPEC: "Incorrect column specifier for column '%-.192s'", + ER_PARSE_ERROR: "%s near '%-.80s' at line %d", + ER_EMPTY_QUERY: "Query was empty", + ER_NONUNIQ_TABLE: "Not unique table/alias: '%-.192s'", + ER_INVALID_DEFAULT: "Invalid default value for '%-.192s'", + ER_MULTIPLE_PRI_KEY: "Multiple primary key defined", + ER_TOO_MANY_KEYS: "Too many keys specified; max %d keys allowed", + ER_TOO_MANY_KEY_PARTS: "Too many key parts specified; max %d parts allowed", + ER_TOO_LONG_KEY: "Specified key was too long; max key length is %d bytes", + ER_KEY_COLUMN_DOES_NOT_EXITS: "Key column '%-.192s' doesn't exist in table", + ER_BLOB_USED_AS_KEY: "BLOB column '%-.192s' can't be used in key specification with the used table type", + ER_TOO_BIG_FIELDLENGTH: "Column length too big for column '%-.192s' (max = %d); use BLOB or TEXT instead", + ER_WRONG_AUTO_KEY: "Incorrect table definition; there can be only one auto column and it must be defined as a key", + ER_READY: "%s: ready for connections.\nVersion: '%s' socket: '%s' port: %d", + ER_NORMAL_SHUTDOWN: "%s: Normal shutdown\n", + ER_GOT_SIGNAL: "%s: Got signal %d. Aborting!\n", + ER_SHUTDOWN_COMPLETE: "%s: Shutdown complete\n", + ER_FORCING_CLOSE: "%s: Forcing close of thread %d user: '%-.48s'\n", + ER_IPSOCK_ERROR: "Can't create IP socket", + ER_NO_SUCH_INDEX: "Table '%-.192s' has no index like the one used in CREATE INDEX; recreate the table", + ER_WRONG_FIELD_TERMINATORS: "Field separator argument is not what is expected; check the manual", + ER_BLOBS_AND_NO_TERMINATED: "You can't use fixed rowlength with BLOBs; please use 'fields terminated by'", + ER_TEXTFILE_NOT_READABLE: "The file '%-.128s' must be in the database directory or be readable by all", + ER_FILE_EXISTS_ERROR: "File '%-.200s' already exists", + ER_LOAD_INFO: "Records: %d Deleted: %d Skipped: %d Warnings: %d", + ER_ALTER_INFO: "Records: %d Duplicates: %d", + ER_WRONG_SUB_KEY: "Incorrect prefix key; the used key part isn't a string, the used length is longer than the key part, or the storage engine doesn't support unique prefix keys", + ER_CANT_REMOVE_ALL_FIELDS: "You can't delete all columns with ALTER TABLE; use DROP TABLE instead", + ER_CANT_DROP_FIELD_OR_KEY: "Can't DROP '%-.192s'; check that column/key exists", + ER_INSERT_INFO: "Records: %d Duplicates: %d Warnings: %d", + ER_UPDATE_TABLE_USED: "You can't specify target table '%-.192s' for update in FROM clause", + ER_NO_SUCH_THREAD: "Unknown thread id: %d", + ER_KILL_DENIED_ERROR: "You are not owner of thread %d", + ER_NO_TABLES_USED: "No tables used", + ER_TOO_BIG_SET: "Too many strings for column %-.192s and SET", + ER_NO_UNIQUE_LOGFILE: "Can't generate a unique log-filename %-.200s.(1-999)\n", + ER_TABLE_NOT_LOCKED_FOR_WRITE: "Table '%-.192s' was locked with a READ lock and can't be updated", + ER_TABLE_NOT_LOCKED: "Table '%-.192s' was not locked with LOCK TABLES", + ER_BLOB_CANT_HAVE_DEFAULT: "BLOB/TEXT column '%-.192s' can't have a default value", + ER_WRONG_DB_NAME: "Incorrect database name '%-.100s'", + ER_WRONG_TABLE_NAME: "Incorrect table name '%-.100s'", + ER_TOO_BIG_SELECT: "The SELECT would examine more than MAX_JOIN_SIZE rows; check your WHERE and use SET SQL_BIG_SELECTS=1 or SET MAX_JOIN_SIZE=# if the SELECT is okay", + ER_UNKNOWN_ERROR: "Unknown error", + ER_UNKNOWN_PROCEDURE: "Unknown procedure '%-.192s'", + ER_WRONG_PARAMCOUNT_TO_PROCEDURE: "Incorrect parameter count to procedure '%-.192s'", + ER_WRONG_PARAMETERS_TO_PROCEDURE: "Incorrect parameters to procedure '%-.192s'", + ER_UNKNOWN_TABLE: "Unknown table '%-.192s' in %-.32s", + ER_FIELD_SPECIFIED_TWICE: "Column '%-.192s' specified twice", + ER_INVALID_GROUP_FUNC_USE: "Invalid use of group function", + ER_UNSUPPORTED_EXTENSION: "Table '%-.192s' uses an extension that doesn't exist in this MySQL version", + ER_TABLE_MUST_HAVE_COLUMNS: "A table must have at least 1 column", + ER_RECORD_FILE_FULL: "The table '%-.192s' is full", + ER_UNKNOWN_CHARACTER_SET: "Unknown character set: '%-.64s'", + ER_TOO_MANY_TABLES: "Too many tables; MySQL can only use %d tables in a join", + ER_TOO_MANY_FIELDS: "Too many columns", + ER_TOO_BIG_ROWSIZE: "Row size too large. The maximum row size for the used table type, not counting BLOBs, is %d. This includes storage overhead, check the manual. You have to change some columns to TEXT or BLOBs", + ER_STACK_OVERRUN: "Thread stack overrun: Used: %d of a %d stack. Use 'mysqld --thread_stack=#' to specify a bigger stack if needed", + ER_WRONG_OUTER_JOIN: "Cross dependency found in OUTER JOIN; examine your ON conditions", + ER_NULL_COLUMN_IN_INDEX: "Table handler doesn't support NULL in given index. Please change column '%-.192s' to be NOT NULL or use another handler", + ER_CANT_FIND_UDF: "Can't load function '%-.192s'", + ER_CANT_INITIALIZE_UDF: "Can't initialize function '%-.192s'; %-.80s", + ER_UDF_NO_PATHS: "No paths allowed for shared library", + ER_UDF_EXISTS: "Function '%-.192s' already exists", + ER_CANT_OPEN_LIBRARY: "Can't open shared library '%-.192s' (errno: %d %-.128s)", + ER_CANT_FIND_DL_ENTRY: "Can't find symbol '%-.128s' in library", + ER_FUNCTION_NOT_DEFINED: "Function '%-.192s' is not defined", + ER_HOST_IS_BLOCKED: "Host '%-.64s' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts'", + ER_HOST_NOT_PRIVILEGED: "Host '%-.64s' is not allowed to connect to this MySQL server", + ER_PASSWORD_ANONYMOUS_USER: "You are using MySQL as an anonymous user and anonymous users are not allowed to change passwords", + ER_PASSWORD_NOT_ALLOWED: "You must have privileges to update tables in the mysql database to be able to change passwords for others", + ER_PASSWORD_NO_MATCH: "Can't find any matching row in the user table", + ER_UPDATE_INFO: "Rows matched: %d Changed: %d Warnings: %d", + ER_CANT_CREATE_THREAD: "Can't create a new thread (errno %d); if you are not out of available memory, you can consult the manual for a possible OS-dependent bug", + ER_WRONG_VALUE_COUNT_ON_ROW: "Column count doesn't match value count at row %d", + ER_CANT_REOPEN_TABLE: "Can't reopen table: '%-.192s'", + ER_INVALID_USE_OF_NULL: "Invalid use of NULL value", + ER_REGEXP_ERROR: "Got error '%-.64s' from regexp", + ER_MIX_OF_GROUP_FUNC_AND_FIELDS: "Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there is no GROUP BY clause", + ER_NONEXISTING_GRANT: "There is no such grant defined for user '%-.48s' on host '%-.64s'", + ER_TABLEACCESS_DENIED_ERROR: "%-.128s command denied to user '%-.48s'@'%-.64s' for table '%-.64s'", + ER_COLUMNACCESS_DENIED_ERROR: "%-.16s command denied to user '%-.48s'@'%-.64s' for column '%-.192s' in table '%-.192s'", + ER_ILLEGAL_GRANT_FOR_TABLE: "Illegal GRANT/REVOKE command; please consult the manual to see which privileges can be used", + ER_GRANT_WRONG_HOST_OR_USER: "The host or user argument to GRANT is too long", + ER_NO_SUCH_TABLE: "Table '%-.192s.%-.192s' doesn't exist", + ER_NONEXISTING_TABLE_GRANT: "There is no such grant defined for user '%-.48s' on host '%-.64s' on table '%-.192s'", + ER_NOT_ALLOWED_COMMAND: "The used command is not allowed with this MySQL version", + ER_SYNTAX_ERROR: "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use", + ER_DELAYED_CANT_CHANGE_LOCK: "Delayed insert thread couldn't get requested lock for table %-.192s", + ER_TOO_MANY_DELAYED_THREADS: "Too many delayed threads in use", + ER_ABORTING_CONNECTION: "Aborted connection %d to db: '%-.192s' user: '%-.48s' (%-.64s)", + ER_NET_PACKET_TOO_LARGE: "Got a packet bigger than 'max_allowed_packet' bytes", + ER_NET_READ_ERROR_FROM_PIPE: "Got a read error from the connection pipe", + ER_NET_FCNTL_ERROR: "Got an error from fcntl()", + ER_NET_PACKETS_OUT_OF_ORDER: "Got packets out of order", + ER_NET_UNCOMPRESS_ERROR: "Couldn't uncompress communication packet", + ER_NET_READ_ERROR: "Got an error reading communication packets", + ER_NET_READ_INTERRUPTED: "Got timeout reading communication packets", + ER_NET_ERROR_ON_WRITE: "Got an error writing communication packets", + ER_NET_WRITE_INTERRUPTED: "Got timeout writing communication packets", + ER_TOO_LONG_STRING: "Result string is longer than 'max_allowed_packet' bytes", + ER_TABLE_CANT_HANDLE_BLOB: "The used table type doesn't support BLOB/TEXT columns", + ER_TABLE_CANT_HANDLE_AUTO_INCREMENT: "The used table type doesn't support AUTO_INCREMENT columns", + ER_DELAYED_INSERT_TABLE_LOCKED: "INSERT DELAYED can't be used with table '%-.192s' because it is locked with LOCK TABLES", + ER_WRONG_COLUMN_NAME: "Incorrect column name '%-.100s'", + ER_WRONG_KEY_COLUMN: "The used storage engine can't index column '%-.192s'", + ER_WRONG_MRG_TABLE: "Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist", + ER_DUP_UNIQUE: "Can't write, because of unique constraint, to table '%-.192s'", + ER_BLOB_KEY_WITHOUT_LENGTH: "BLOB/TEXT column '%-.192s' used in key specification without a key length", + ER_PRIMARY_CANT_HAVE_NULL: "All parts of a PRIMARY KEY must be NOT NULL; if you need NULL in a key, use UNIQUE instead", + ER_TOO_MANY_ROWS: "Result consisted of more than one row", + ER_REQUIRES_PRIMARY_KEY: "This table type requires a primary key", + ER_NO_RAID_COMPILED: "This version of MySQL is not compiled with RAID support", + ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE: "You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column", + ER_KEY_DOES_NOT_EXITS: "Key '%-.192s' doesn't exist in table '%-.192s'", + ER_CHECK_NO_SUCH_TABLE: "Can't open table", + ER_CHECK_NOT_IMPLEMENTED: "The storage engine for the table doesn't support %s", + ER_CANT_DO_THIS_DURING_AN_TRANSACTION: "You are not allowed to execute this command in a transaction", + ER_ERROR_DURING_COMMIT: "Got error %d during COMMIT", + ER_ERROR_DURING_ROLLBACK: "Got error %d during ROLLBACK", + ER_ERROR_DURING_FLUSH_LOGS: "Got error %d during FLUSH_LOGS", + ER_ERROR_DURING_CHECKPOINT: "Got error %d during CHECKPOINT", + ER_NEW_ABORTING_CONNECTION: "Aborted connection %d to db: '%-.192s' user: '%-.48s' host: '%-.64s' (%-.64s)", + ER_DUMP_NOT_IMPLEMENTED: "The storage engine for the table does not support binary table dump", + ER_FLUSH_MASTER_BINLOG_CLOSED: "Binlog closed, cannot RESET MASTER", + ER_INDEX_REBUILD: "Failed rebuilding the index of dumped table '%-.192s'", + ER_MASTER: "Error from master: '%-.64s'", + ER_MASTER_NET_READ: "Net error reading from master", + ER_MASTER_NET_WRITE: "Net error writing to master", + ER_FT_MATCHING_KEY_NOT_FOUND: "Can't find FULLTEXT index matching the column list", + ER_LOCK_OR_ACTIVE_TRANSACTION: "Can't execute the given command because you have active locked tables or an active transaction", + ER_UNKNOWN_SYSTEM_VARIABLE: "Unknown system variable '%-.64s'", + ER_CRASHED_ON_USAGE: "Table '%-.192s' is marked as crashed and should be repaired", + ER_CRASHED_ON_REPAIR: "Table '%-.192s' is marked as crashed and last (automatic?) repair failed", + ER_WARNING_NOT_COMPLETE_ROLLBACK: "Some non-transactional changed tables couldn't be rolled back", + ER_TRANS_CACHE_FULL: "Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage; increase this mysqld variable and try again", + ER_SLAVE_MUST_STOP: "This operation cannot be performed with a running slave; run STOP SLAVE first", + ER_SLAVE_NOT_RUNNING: "This operation requires a running slave; configure slave and do START SLAVE", + ER_BAD_SLAVE: "The server is not configured as slave; fix in config file or with CHANGE MASTER TO", + ER_MASTER_INFO: "Could not initialize master info structure; more error messages can be found in the MySQL error log", + ER_SLAVE_THREAD: "Could not create slave thread; check system resources", + ER_TOO_MANY_USER_CONNECTIONS: "User %-.64s already has more than 'max_user_connections' active connections", + ER_SET_CONSTANTS_ONLY: "You may only use constant expressions with SET", + ER_LOCK_WAIT_TIMEOUT: "Lock wait timeout exceeded; try restarting transaction", + ER_LOCK_TABLE_FULL: "The total number of locks exceeds the lock table size", + ER_READ_ONLY_TRANSACTION: "Update locks cannot be acquired during a READ UNCOMMITTED transaction", + ER_DROP_DB_WITH_READ_LOCK: "DROP DATABASE not allowed while thread is holding global read lock", + ER_CREATE_DB_WITH_READ_LOCK: "CREATE DATABASE not allowed while thread is holding global read lock", + ER_WRONG_ARGUMENTS: "Incorrect arguments to %s", + ER_NO_PERMISSION_TO_CREATE_USER: "'%-.48s'@'%-.64s' is not allowed to create new users", + ER_UNION_TABLES_IN_DIFFERENT_DIR: "Incorrect table definition; all MERGE tables must be in the same database", + ER_LOCK_DEADLOCK: "Deadlock found when trying to get lock; try restarting transaction", + ER_TABLE_CANT_HANDLE_FT: "The used table type doesn't support FULLTEXT indexes", + ER_CANNOT_ADD_FOREIGN: "Cannot add foreign key constraint", + ER_NO_REFERENCED_ROW: "Cannot add or update a child row: a foreign key constraint fails", + ER_ROW_IS_REFERENCED: "Cannot delete or update a parent row: a foreign key constraint fails", + ER_CONNECT_TO_MASTER: "Error connecting to master: %-.128s", + ER_QUERY_ON_MASTER: "Error running query on master: %-.128s", + ER_ERROR_WHEN_EXECUTING_COMMAND: "Error when executing command %s: %-.128s", + ER_WRONG_USAGE: "Incorrect usage of %s and %s", + ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT: "The used SELECT statements have a different number of columns", + ER_CANT_UPDATE_WITH_READLOCK: "Can't execute the query because you have a conflicting read lock", + ER_MIXING_NOT_ALLOWED: "Mixing of transactional and non-transactional tables is disabled", + ER_DUP_ARGUMENT: "Option '%s' used twice in statement", + ER_USER_LIMIT_REACHED: "User '%-.64s' has exceeded the '%s' resource (current value: %d)", + ER_SPECIFIC_ACCESS_DENIED_ERROR: "Access denied; you need (at least one of) the %-.128s privilege(s) for this operation", + ER_LOCAL_VARIABLE: "Variable '%-.64s' is a SESSION variable and can't be used with SET GLOBAL", + ER_GLOBAL_VARIABLE: "Variable '%-.64s' is a GLOBAL variable and should be set with SET GLOBAL", + ER_NO_DEFAULT: "Variable '%-.64s' doesn't have a default value", + ER_WRONG_VALUE_FOR_VAR: "Variable '%-.64s' can't be set to the value of '%-.200s'", + ER_WRONG_TYPE_FOR_VAR: "Incorrect argument type to variable '%-.64s'", + ER_VAR_CANT_BE_READ: "Variable '%-.64s' can only be set, not read", + ER_CANT_USE_OPTION_HERE: "Incorrect usage/placement of '%s'", + ER_NOT_SUPPORTED_YET: "This version of MySQL doesn't yet support '%s'", + ER_MASTER_FATAL_ERROR_READING_BINLOG: "Got fatal error %d from master when reading data from binary log: '%-.320s'", + ER_SLAVE_IGNORED_TABLE: "Slave SQL thread ignored the query because of replicate-*-table rules", + ER_INCORRECT_GLOBAL_LOCAL_VAR: "Variable '%-.192s' is a %s variable", + ER_WRONG_FK_DEF: "Incorrect foreign key definition for '%-.192s': %s", + ER_KEY_REF_DO_NOT_MATCH_TABLE_REF: "Key reference and table reference don't match", + ER_OPERAND_COLUMNS: "Operand should contain %d column(s)", + ER_SUBQUERY_NO_1_ROW: "Subquery returns more than 1 row", + ER_UNKNOWN_STMT_HANDLER: "Unknown prepared statement handler (%.*s) given to %s", + ER_CORRUPT_HELP_DB: "Help database is corrupt or does not exist", + ER_CYCLIC_REFERENCE: "Cyclic reference on subqueries", + ER_AUTO_CONVERT: "Converting column '%s' from %s to %s", + ER_ILLEGAL_REFERENCE: "Reference '%-.64s' not supported (%s)", + ER_DERIVED_MUST_HAVE_ALIAS: "Every derived table must have its own alias", + ER_SELECT_REDUCED: "Select %d was reduced during optimization", + ER_TABLENAME_NOT_ALLOWED_HERE: "Table '%-.192s' from one of the SELECTs cannot be used in %-.32s", + ER_NOT_SUPPORTED_AUTH_MODE: "Client does not support authentication protocol requested by server; consider upgrading MySQL client", + ER_SPATIAL_CANT_HAVE_NULL: "All parts of a SPATIAL index must be NOT NULL", + ER_COLLATION_CHARSET_MISMATCH: "COLLATION '%s' is not valid for CHARACTER SET '%s'", + ER_SLAVE_WAS_RUNNING: "Slave is already running", + ER_SLAVE_WAS_NOT_RUNNING: "Slave already has been stopped", + ER_TOO_BIG_FOR_UNCOMPRESS: "Uncompressed data size too large; the maximum size is %d (probably, length of uncompressed data was corrupted)", + ER_ZLIB_Z_MEM_ERROR: "ZLIB: Not enough memory", + ER_ZLIB_Z_BUF_ERROR: "ZLIB: Not enough room in the output buffer (probably, length of uncompressed data was corrupted)", + ER_ZLIB_Z_DATA_ERROR: "ZLIB: Input data corrupted", + ER_CUT_VALUE_GROUP_CONCAT: "Row %d was cut by GROUP_CONCAT()", + ER_WARN_TOO_FEW_RECORDS: "Row %d doesn't contain data for all columns", + ER_WARN_TOO_MANY_RECORDS: "Row %d was truncated; it contained more data than there were input columns", + ER_WARN_NULL_TO_NOTNULL: "Column set to default value; NULL supplied to NOT NULL column '%s' at row %d", + ER_WARN_DATA_OUT_OF_RANGE: "Out of range value for column '%s' at row %d", + WARN_DATA_TRUNCATED: "Data truncated for column '%s' at row %d", + ER_WARN_USING_OTHER_HANDLER: "Using storage engine %s for table '%s'", + ER_CANT_AGGREGATE_2COLLATIONS: "Illegal mix of collations (%s,%s) and (%s,%s) for operation '%s'", + ER_DROP_USER: "Cannot drop one or more of the requested users", + ER_REVOKE_GRANTS: "Can't revoke all privileges for one or more of the requested users", + ER_CANT_AGGREGATE_3COLLATIONS: "Illegal mix of collations (%s,%s), (%s,%s), (%s,%s) for operation '%s'", + ER_CANT_AGGREGATE_NCOLLATIONS: "Illegal mix of collations for operation '%s'", + ER_VARIABLE_IS_NOT_STRUCT: "Variable '%-.64s' is not a variable component (can't be used as XXXX.variable_name)", + ER_UNKNOWN_COLLATION: "Unknown collation: '%-.64s'", + ER_SLAVE_IGNORED_SSL_PARAMS: "SSL parameters in CHANGE MASTER are ignored because this MySQL slave was compiled without SSL support; they can be used later if MySQL slave with SSL is started", + ER_SERVER_IS_IN_SECURE_AUTH_MODE: "Server is running in --secure-auth mode, but '%s'@'%s' has a password in the old format; please change the password to the new format", + ER_WARN_FIELD_RESOLVED: "Field or reference '%-.192s%s%-.192s%s%-.192s' of SELECT #%d was resolved in SELECT #%d", + ER_BAD_SLAVE_UNTIL_COND: "Incorrect parameter or combination of parameters for START SLAVE UNTIL", + ER_MISSING_SKIP_SLAVE: "It is recommended to use --skip-slave-start when doing step-by-step replication with START SLAVE UNTIL; otherwise, you will get problems if you get an unexpected slave's mysqld restart", + ER_UNTIL_COND_IGNORED: "SQL thread is not to be started so UNTIL options are ignored", + ER_WRONG_NAME_FOR_INDEX: "Incorrect index name '%-.100s'", + ER_WRONG_NAME_FOR_CATALOG: "Incorrect catalog name '%-.100s'", + ER_WARN_QC_RESIZE: "Query cache failed to set size %d; new query cache size is %d", + ER_BAD_FT_COLUMN: "Column '%-.192s' cannot be part of FULLTEXT index", + ER_UNKNOWN_KEY_CACHE: "Unknown key cache '%-.100s'", + ER_WARN_HOSTNAME_WONT_WORK: "MySQL is started in --skip-name-resolve mode; you must restart it without this switch for this grant to work", + ER_UNKNOWN_STORAGE_ENGINE: "Unknown storage engine '%s'", + ER_WARN_DEPRECATED_SYNTAX: "'%s' is deprecated and will be removed in a future release. Please use %s instead", + ER_NON_UPDATABLE_TABLE: "The target table %-.100s of the %s is not updatable", + ER_FEATURE_DISABLED: "The '%s' feature is disabled; you need MySQL built with '%s' to have it working", + ER_OPTION_PREVENTS_STATEMENT: "The MySQL server is running with the %s option so it cannot execute this statement", + ER_DUPLICATED_VALUE_IN_TYPE: "Column '%-.100s' has duplicated value '%-.64s' in %s", + ER_TRUNCATED_WRONG_VALUE: "Truncated incorrect %-.32s value: '%-.128s'", + ER_TOO_MUCH_AUTO_TIMESTAMP_COLS: "Incorrect table definition; there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause", + ER_INVALID_ON_UPDATE: "Invalid ON UPDATE clause for '%-.192s' column", + ER_UNSUPPORTED_PS: "This command is not supported in the prepared statement protocol yet", + ER_GET_ERRMSG: "Got error %d '%-.100s' from %s", + ER_GET_TEMPORARY_ERRMSG: "Got temporary error %d '%-.100s' from %s", + ER_UNKNOWN_TIME_ZONE: "Unknown or incorrect time zone: '%-.64s'", + ER_WARN_INVALID_TIMESTAMP: "Invalid TIMESTAMP value in column '%s' at row %d", + ER_INVALID_CHARACTER_STRING: "Invalid %s character string: '%.64s'", + ER_WARN_ALLOWED_PACKET_OVERFLOWED: "Result of %s() was larger than max_allowed_packet (%d) - truncated", + ER_CONFLICTING_DECLARATIONS: "Conflicting declarations: '%s%s' and '%s%s'", + ER_SP_NO_RECURSIVE_CREATE: "Can't create a %s from within another stored routine", + ER_SP_ALREADY_EXISTS: "%s %s already exists", + ER_SP_DOES_NOT_EXIST: "%s %s does not exist", + ER_SP_DROP_FAILED: "Failed to DROP %s %s", + ER_SP_STORE_FAILED: "Failed to CREATE %s %s", + ER_SP_LILABEL_MISMATCH: "%s with no matching label: %s", + ER_SP_LABEL_REDEFINE: "Redefining label %s", + ER_SP_LABEL_MISMATCH: "End-label %s without match", + ER_SP_UNINIT_VAR: "Referring to uninitialized variable %s", + ER_SP_BADSELECT: "PROCEDURE %s can't return a result set in the given context", + ER_SP_BADRETURN: "RETURN is only allowed in a FUNCTION", + ER_SP_BADSTATEMENT: "%s is not allowed in stored procedures", + ER_UPDATE_LOG_DEPRECATED_IGNORED: "The update log is deprecated and replaced by the binary log; SET SQL_LOG_UPDATE has been ignored.", + ER_UPDATE_LOG_DEPRECATED_TRANSLATED: "The update log is deprecated and replaced by the binary log; SET SQL_LOG_UPDATE has been translated to SET SQL_LOG_BIN.", + ER_QUERY_INTERRUPTED: "Query execution was interrupted", + ER_SP_WRONG_NO_OF_ARGS: "Incorrect number of arguments for %s %s; expected %d, got %d", + ER_SP_COND_MISMATCH: "Undefined CONDITION: %s", + ER_SP_NORETURN: "No RETURN found in FUNCTION %s", + ER_SP_NORETURNEND: "FUNCTION %s ended without RETURN", + ER_SP_BAD_CURSOR_QUERY: "Cursor statement must be a SELECT", + ER_SP_BAD_CURSOR_SELECT: "Cursor SELECT must not have INTO", + ER_SP_CURSOR_MISMATCH: "Undefined CURSOR: %s", + ER_SP_CURSOR_ALREADY_OPEN: "Cursor is already open", + ER_SP_CURSOR_NOT_OPEN: "Cursor is not open", + ER_SP_UNDECLARED_VAR: "Undeclared variable: %s", + ER_SP_WRONG_NO_OF_FETCH_ARGS: "Incorrect number of FETCH variables", + ER_SP_FETCH_NO_DATA: "No data - zero rows fetched, selected, or processed", + ER_SP_DUP_PARAM: "Duplicate parameter: %s", + ER_SP_DUP_VAR: "Duplicate variable: %s", + ER_SP_DUP_COND: "Duplicate condition: %s", + ER_SP_DUP_CURS: "Duplicate cursor: %s", + ER_SP_CANT_ALTER: "Failed to ALTER %s %s", + ER_SP_SUBSELECT_NYI: "Subquery value not supported", + ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG: "%s is not allowed in stored function or trigger", + ER_SP_VARCOND_AFTER_CURSHNDLR: "Variable or condition declaration after cursor or handler declaration", + ER_SP_CURSOR_AFTER_HANDLER: "Cursor declaration after handler declaration", + ER_SP_CASE_NOT_FOUND: "Case not found for CASE statement", + ER_FPARSER_TOO_BIG_FILE: "Configuration file '%-.192s' is too big", + ER_FPARSER_BAD_HEADER: "Malformed file type header in file '%-.192s'", + ER_FPARSER_EOF_IN_COMMENT: "Unexpected end of file while parsing comment '%-.200s'", + ER_FPARSER_ERROR_IN_PARAMETER: "Error while parsing parameter '%-.192s' (line: '%-.192s')", + ER_FPARSER_EOF_IN_UNKNOWN_PARAMETER: "Unexpected end of file while skipping unknown parameter '%-.192s'", + ER_VIEW_NO_EXPLAIN: "EXPLAIN/SHOW can not be issued; lacking privileges for underlying table", + ER_FRM_UNKNOWN_TYPE: "File '%-.192s' has unknown type '%-.64s' in its header", + ER_WRONG_OBJECT: "'%-.192s.%-.192s' is not %s", + ER_NONUPDATEABLE_COLUMN: "Column '%-.192s' is not updatable", + ER_VIEW_SELECT_DERIVED: "View's SELECT contains a subquery in the FROM clause", + ER_VIEW_SELECT_CLAUSE: "View's SELECT contains a '%s' clause", + ER_VIEW_SELECT_VARIABLE: "View's SELECT contains a variable or parameter", + ER_VIEW_SELECT_TMPTABLE: "View's SELECT refers to a temporary table '%-.192s'", + ER_VIEW_WRONG_LIST: "View's SELECT and view's field list have different column counts", + ER_WARN_VIEW_MERGE: "View merge algorithm can't be used here for now (assumed undefined algorithm)", + ER_WARN_VIEW_WITHOUT_KEY: "View being updated does not have complete key of underlying table in it", + ER_VIEW_INVALID: "View '%-.192s.%-.192s' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them", + ER_SP_NO_DROP_SP: "Can't drop or alter a %s from within another stored routine", + ER_SP_GOTO_IN_HNDLR: "GOTO is not allowed in a stored procedure handler", + ER_TRG_ALREADY_EXISTS: "Trigger already exists", + ER_TRG_DOES_NOT_EXIST: "Trigger does not exist", + ER_TRG_ON_VIEW_OR_TEMP_TABLE: "Trigger's '%-.192s' is view or temporary table", + ER_TRG_CANT_CHANGE_ROW: "Updating of %s row is not allowed in %strigger", + ER_TRG_NO_SUCH_ROW_IN_TRG: "There is no %s row in %s trigger", + ER_NO_DEFAULT_FOR_FIELD: "Field '%-.192s' doesn't have a default value", + ER_DIVISION_BY_ZERO: "Division by 0", + ER_TRUNCATED_WRONG_VALUE_FOR_FIELD: "Incorrect %-.32s value: '%-.128s' for column '%.192s' at row %d", + ER_ILLEGAL_VALUE_FOR_TYPE: "Illegal %s '%-.192s' value found during parsing", + ER_VIEW_NONUPD_CHECK: "CHECK OPTION on non-updatable view '%-.192s.%-.192s'", + ER_VIEW_CHECK_FAILED: "CHECK OPTION failed '%-.192s.%-.192s'", + ER_PROCACCESS_DENIED_ERROR: "%-.16s command denied to user '%-.48s'@'%-.64s' for routine '%-.192s'", + ER_RELAY_LOG_FAIL: "Failed purging old relay logs: %s", + ER_PASSWD_LENGTH: "Password hash should be a %d-digit hexadecimal number", + ER_UNKNOWN_TARGET_BINLOG: "Target log not found in binlog index", + ER_IO_ERR_LOG_INDEX_READ: "I/O error reading log index file", + ER_BINLOG_PURGE_PROHIBITED: "Server configuration does not permit binlog purge", + ER_FSEEK_FAIL: "Failed on fseek()", + ER_BINLOG_PURGE_FATAL_ERR: "Fatal error during log purge", + ER_LOG_IN_USE: "A purgeable log is in use, will not purge", + ER_LOG_PURGE_UNKNOWN_ERR: "Unknown error during log purge", + ER_RELAY_LOG_INIT: "Failed initializing relay log position: %s", + ER_NO_BINARY_LOGGING: "You are not using binary logging", + ER_RESERVED_SYNTAX: "The '%-.64s' syntax is reserved for purposes internal to the MySQL server", + ER_WSAS_FAILED: "WSAStartup Failed", + ER_DIFF_GROUPS_PROC: "Can't handle procedures with different groups yet", + ER_NO_GROUP_FOR_PROC: "Select must have a group with this procedure", + ER_ORDER_WITH_PROC: "Can't use ORDER clause with this procedure", + ER_LOGGING_PROHIBIT_CHANGING_OF: "Binary logging and replication forbid changing the global server %s", + ER_NO_FILE_MAPPING: "Can't map file: %-.200s, errno: %d", + ER_WRONG_MAGIC: "Wrong magic in %-.64s", + ER_PS_MANY_PARAM: "Prepared statement contains too many placeholders", + ER_KEY_PART_0: "Key part '%-.192s' length cannot be 0", + ER_VIEW_CHECKSUM: "View text checksum failed", + ER_VIEW_MULTIUPDATE: "Can not modify more than one base table through a join view '%-.192s.%-.192s'", + ER_VIEW_NO_INSERT_FIELD_LIST: "Can not insert into join view '%-.192s.%-.192s' without fields list", + ER_VIEW_DELETE_MERGE_VIEW: "Can not delete from join view '%-.192s.%-.192s'", + ER_CANNOT_USER: "Operation %s failed for %.256s", + ER_XAER_NOTA: "XAER_NOTA: Unknown XID", + ER_XAER_INVAL: "XAER_INVAL: Invalid arguments (or unsupported command)", + ER_XAER_RMFAIL: "XAER_RMFAIL: The command cannot be executed when global transaction is in the %.64s state", + ER_XAER_OUTSIDE: "XAER_OUTSIDE: Some work is done outside global transaction", + ER_XAER_RMERR: "XAER_RMERR: Fatal error occurred in the transaction branch - check your data for consistency", + ER_XA_RBROLLBACK: "XA_RBROLLBACK: Transaction branch was rolled back", + ER_NONEXISTING_PROC_GRANT: "There is no such grant defined for user '%-.48s' on host '%-.64s' on routine '%-.192s'", + ER_PROC_AUTO_GRANT_FAIL: "Failed to grant EXECUTE and ALTER ROUTINE privileges", + ER_PROC_AUTO_REVOKE_FAIL: "Failed to revoke all privileges to dropped routine", + ER_DATA_TOO_LONG: "Data too long for column '%s' at row %d", + ER_SP_BAD_SQLSTATE: "Bad SQLSTATE: '%s'", + ER_STARTUP: "%s: ready for connections.\nVersion: '%s' socket: '%s' port: %d %s", + ER_LOAD_FROM_FIXED_SIZE_ROWS_TO_VAR: "Can't load value from file with fixed size rows to variable", + ER_CANT_CREATE_USER_WITH_GRANT: "You are not allowed to create a user with GRANT", + ER_WRONG_VALUE_FOR_TYPE: "Incorrect %-.32s value: '%-.128s' for function %-.32s", + ER_TABLE_DEF_CHANGED: "Table definition has changed, please retry transaction", + ER_SP_DUP_HANDLER: "Duplicate handler declared in the same block", + ER_SP_NOT_VAR_ARG: "OUT or INOUT argument %d for routine %s is not a variable or NEW pseudo-variable in BEFORE trigger", + ER_SP_NO_RETSET: "Not allowed to return a result set from a %s", + ER_CANT_CREATE_GEOMETRY_OBJECT: "Cannot get geometry object from data you send to the GEOMETRY field", + ER_FAILED_ROUTINE_BREAK_BINLOG: "A routine failed and has neither NO SQL nor READS SQL DATA in its declaration and binary logging is enabled; if non-transactional tables were updated, the binary log will miss their changes", + ER_BINLOG_UNSAFE_ROUTINE: "This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable)", + ER_BINLOG_CREATE_ROUTINE_NEED_SUPER: "You do not have the SUPER privilege and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable)", + ER_EXEC_STMT_WITH_OPEN_CURSOR: "You can't execute a prepared statement which has an open cursor associated with it. Reset the statement to re-execute it.", + ER_STMT_HAS_NO_OPEN_CURSOR: "The statement (%d) has no open cursor.", + ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG: "Explicit or implicit commit is not allowed in stored function or trigger.", + ER_NO_DEFAULT_FOR_VIEW_FIELD: "Field of view '%-.192s.%-.192s' underlying table doesn't have a default value", + ER_SP_NO_RECURSION: "Recursive stored functions and triggers are not allowed.", + ER_TOO_BIG_SCALE: "Too big scale %d specified for column '%-.192s'. Maximum is %d.", + ER_TOO_BIG_PRECISION: "Too big precision %d specified for column '%-.192s'. Maximum is %d.", + ER_M_BIGGER_THAN_D: "For float(M,D), double(M,D) or decimal(M,D), M must be >= D (column '%-.192s').", + ER_WRONG_LOCK_OF_SYSTEM_TABLE: "You can't combine write-locking of system tables with other tables or lock types", + ER_CONNECT_TO_FOREIGN_DATA_SOURCE: "Unable to connect to foreign data source: %.64s", + ER_QUERY_ON_FOREIGN_DATA_SOURCE: "There was a problem processing the query on the foreign data source. Data source error: %-.64s", + ER_FOREIGN_DATA_SOURCE_DOESNT_EXIST: "The foreign data source you are trying to reference does not exist. Data source error: %-.64s", + ER_FOREIGN_DATA_STRING_INVALID_CANT_CREATE: "Can't create federated table. The data source connection string '%-.64s' is not in the correct format", + ER_FOREIGN_DATA_STRING_INVALID: "The data source connection string '%-.64s' is not in the correct format", + ER_CANT_CREATE_FEDERATED_TABLE: "Can't create federated table. Foreign data src error: %-.64s", + ER_TRG_IN_WRONG_SCHEMA: "Trigger in wrong schema", + ER_STACK_OVERRUN_NEED_MORE: "Thread stack overrun: %d bytes used of a %d byte stack, and %d bytes needed. Use 'mysqld --thread_stack=#' to specify a bigger stack.", + ER_TOO_LONG_BODY: "Routine body for '%-.100s' is too long", + ER_WARN_CANT_DROP_DEFAULT_KEYCACHE: "Cannot drop default keycache", + ER_TOO_BIG_DISPLAYWIDTH: "Display width out of range for column '%-.192s' (max = %d)", + ER_XAER_DUPID: "XAER_DUPID: The XID already exists", + ER_DATETIME_FUNCTION_OVERFLOW: "Datetime function: %-.32s field overflow", + ER_CANT_UPDATE_USED_TABLE_IN_SF_OR_TRG: "Can't update table '%-.192s' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.", + ER_VIEW_PREVENT_UPDATE: "The definition of table '%-.192s' prevents operation %.192s on table '%-.192s'.", + ER_PS_NO_RECURSION: "The prepared statement contains a stored routine call that refers to that same statement. It's not allowed to execute a prepared statement in such a recursive manner", + ER_SP_CANT_SET_AUTOCOMMIT: "Not allowed to set autocommit from a stored function or trigger", + ER_MALFORMED_DEFINER: "Definer is not fully qualified", + ER_VIEW_FRM_NO_USER: "View '%-.192s'.'%-.192s' has no definer information (old table format). Current user is used as definer. Please recreate the view!", + ER_VIEW_OTHER_USER: "You need the SUPER privilege for creation view with '%-.192s'@'%-.192s' definer", + ER_NO_SUCH_USER: "The user specified as a definer ('%-.64s'@'%-.64s') does not exist", + ER_FORBID_SCHEMA_CHANGE: "Changing schema from '%-.192s' to '%-.192s' is not allowed.", + ER_ROW_IS_REFERENCED_2: "Cannot delete or update a parent row: a foreign key constraint fails (%.192s)", + ER_NO_REFERENCED_ROW_2: "Cannot add or update a child row: a foreign key constraint fails (%.192s)", + ER_SP_BAD_VAR_SHADOW: "Variable '%-.64s' must be quoted with `...`, or renamed", + ER_TRG_NO_DEFINER: "No definer attribute for trigger '%-.192s'.'%-.192s'. The trigger will be activated under the authorization of the invoker, which may have insufficient privileges. Please recreate the trigger.", + ER_OLD_FILE_FORMAT: "'%-.192s' has an old format, you should re-create the '%s' object(s)", + ER_SP_RECURSION_LIMIT: "Recursive limit %d (as set by the max_sp_recursion_depth variable) was exceeded for routine %.192s", + ER_SP_PROC_TABLE_CORRUPT: "Failed to load routine %-.192s. The table mysql.proc is missing, corrupt, or contains bad data (internal code %d)", + ER_SP_WRONG_NAME: "Incorrect routine name '%-.192s'", + ER_TABLE_NEEDS_UPGRADE: "Table upgrade required. Please do \"REPAIR TABLE `%-.32s`\" or dump/reload to fix it!", + ER_SP_NO_AGGREGATE: "AGGREGATE is not supported for stored functions", + ER_MAX_PREPARED_STMT_COUNT_REACHED: "Can't create more than max_prepared_stmt_count statements (current value: %d)", + ER_VIEW_RECURSIVE: "`%-.192s`.`%-.192s` contains view recursion", + ER_NON_GROUPING_FIELD_USED: "Non-grouping field '%-.192s' is used in %-.64s clause", + ER_TABLE_CANT_HANDLE_SPKEYS: "The used table type doesn't support SPATIAL indexes", + ER_NO_TRIGGERS_ON_SYSTEM_SCHEMA: "Triggers can not be created on system tables", + ER_REMOVED_SPACES: "Leading spaces are removed from name '%s'", + ER_AUTOINC_READ_FAILED: "Failed to read auto-increment value from storage engine", + ER_USERNAME: "user name", + ER_HOSTNAME: "host name", + ER_WRONG_STRING_LENGTH: "String '%-.70s' is too long for %s (should be no longer than %d)", + ER_NON_INSERTABLE_TABLE: "The target table %-.100s of the %s is not insertable-into", + ER_ADMIN_WRONG_MRG_TABLE: "Table '%-.64s' is differently defined or of non-MyISAM type or doesn't exist", + ER_TOO_HIGH_LEVEL_OF_NESTING_FOR_SELECT: "Too high level of nesting for select", + ER_NAME_BECOMES_EMPTY: "Name '%-.64s' has become ''", + ER_AMBIGUOUS_FIELD_TERM: "First character of the FIELDS TERMINATED string is ambiguous; please use non-optional and non-empty FIELDS ENCLOSED BY", + ER_FOREIGN_SERVER_EXISTS: "The foreign server, %s, you are trying to create already exists.", + ER_FOREIGN_SERVER_DOESNT_EXIST: "The foreign server name you are trying to reference does not exist. Data source error: %-.64s", + ER_ILLEGAL_HA_CREATE_OPTION: "Table storage engine '%-.64s' does not support the create option '%.64s'", + ER_PARTITION_REQUIRES_VALUES_ERROR: "Syntax error: %-.64s PARTITIONING requires definition of VALUES %-.64s for each partition", + ER_PARTITION_WRONG_VALUES_ERROR: "Only %-.64s PARTITIONING can use VALUES %-.64s in partition definition", + ER_PARTITION_MAXVALUE_ERROR: "MAXVALUE can only be used in last partition definition", + ER_PARTITION_SUBPARTITION_ERROR: "Subpartitions can only be hash partitions and by key", + ER_PARTITION_SUBPART_MIX_ERROR: "Must define subpartitions on all partitions if on one partition", + ER_PARTITION_WRONG_NO_PART_ERROR: "Wrong number of partitions defined, mismatch with previous setting", + ER_PARTITION_WRONG_NO_SUBPART_ERROR: "Wrong number of subpartitions defined, mismatch with previous setting", + ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR: "Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed", + ER_NO_CONST_EXPR_IN_RANGE_OR_LIST_ERROR: "Expression in RANGE/LIST VALUES must be constant", + ER_FIELD_NOT_FOUND_PART_ERROR: "Field in list of fields for partition function not found in table", + ER_LIST_OF_FIELDS_ONLY_IN_HASH_ERROR: "List of fields is only allowed in KEY partitions", + ER_INCONSISTENT_PARTITION_INFO_ERROR: "The partition info in the frm file is not consistent with what can be written into the frm file", + ER_PARTITION_FUNC_NOT_ALLOWED_ERROR: "The %-.192s function returns the wrong type", + ER_PARTITIONS_MUST_BE_DEFINED_ERROR: "For %-.64s partitions each partition must be defined", + ER_RANGE_NOT_INCREASING_ERROR: "VALUES LESS THAN value must be strictly increasing for each partition", + ER_INCONSISTENT_TYPE_OF_FUNCTIONS_ERROR: "VALUES value must be of same type as partition function", + ER_MULTIPLE_DEF_CONST_IN_LIST_PART_ERROR: "Multiple definition of same constant in list partitioning", + ER_PARTITION_ENTRY_ERROR: "Partitioning can not be used stand-alone in query", + ER_MIX_HANDLER_ERROR: "The mix of handlers in the partitions is not allowed in this version of MySQL", + ER_PARTITION_NOT_DEFINED_ERROR: "For the partitioned engine it is necessary to define all %-.64s", + ER_TOO_MANY_PARTITIONS_ERROR: "Too many partitions (including subpartitions) were defined", + ER_SUBPARTITION_ERROR: "It is only possible to mix RANGE/LIST partitioning with HASH/KEY partitioning for subpartitioning", + ER_CANT_CREATE_HANDLER_FILE: "Failed to create specific handler file", + ER_BLOB_FIELD_IN_PART_FUNC_ERROR: "A BLOB field is not allowed in partition function", + ER_UNIQUE_KEY_NEED_ALL_FIELDS_IN_PF: "A %-.192s must include all columns in the table's partitioning function", + ER_NO_PARTS_ERROR: "Number of %-.64s = 0 is not an allowed value", + ER_PARTITION_MGMT_ON_NONPARTITIONED: "Partition management on a not partitioned table is not possible", + ER_FOREIGN_KEY_ON_PARTITIONED: "Foreign key clause is not yet supported in conjunction with partitioning", + ER_DROP_PARTITION_NON_EXISTENT: "Error in list of partitions to %-.64s", + ER_DROP_LAST_PARTITION: "Cannot remove all partitions, use DROP TABLE instead", + ER_COALESCE_ONLY_ON_HASH_PARTITION: "COALESCE PARTITION can only be used on HASH/KEY partitions", + ER_REORG_HASH_ONLY_ON_SAME_NO: "REORGANIZE PARTITION can only be used to reorganize partitions not to change their numbers", + ER_REORG_NO_PARAM_ERROR: "REORGANIZE PARTITION without parameters can only be used on auto-partitioned tables using HASH PARTITIONs", + ER_ONLY_ON_RANGE_LIST_PARTITION: "%-.64s PARTITION can only be used on RANGE/LIST partitions", + ER_ADD_PARTITION_SUBPART_ERROR: "Trying to Add partition(s) with wrong number of subpartitions", + ER_ADD_PARTITION_NO_NEW_PARTITION: "At least one partition must be added", + ER_COALESCE_PARTITION_NO_PARTITION: "At least one partition must be coalesced", + ER_REORG_PARTITION_NOT_EXIST: "More partitions to reorganize than there are partitions", + ER_SAME_NAME_PARTITION: "Duplicate partition name %-.192s", + ER_NO_BINLOG_ERROR: "It is not allowed to shut off binlog on this command", + ER_CONSECUTIVE_REORG_PARTITIONS: "When reorganizing a set of partitions they must be in consecutive order", + ER_REORG_OUTSIDE_RANGE: "Reorganize of range partitions cannot change total ranges except for last partition where it can extend the range", + ER_PARTITION_FUNCTION_FAILURE: "Partition function not supported in this version for this handler", + ER_PART_STATE_ERROR: "Partition state cannot be defined from CREATE/ALTER TABLE", + ER_LIMITED_PART_RANGE: "The %-.64s handler only supports 32 bit integers in VALUES", + ER_PLUGIN_IS_NOT_LOADED: "Plugin '%-.192s' is not loaded", + ER_WRONG_VALUE: "Incorrect %-.32s value: '%-.128s'", + ER_NO_PARTITION_FOR_GIVEN_VALUE: "Table has no partition for value %-.64s", + ER_FILEGROUP_OPTION_ONLY_ONCE: "It is not allowed to specify %s more than once", + ER_CREATE_FILEGROUP_FAILED: "Failed to create %s", + ER_DROP_FILEGROUP_FAILED: "Failed to drop %s", + ER_TABLESPACE_AUTO_EXTEND_ERROR: "The handler doesn't support autoextend of tablespaces", + ER_WRONG_SIZE_NUMBER: "A size parameter was incorrectly specified, either number or on the form 10M", + ER_SIZE_OVERFLOW_ERROR: "The size number was correct but we don't allow the digit part to be more than 2 billion", + ER_ALTER_FILEGROUP_FAILED: "Failed to alter: %s", + ER_BINLOG_ROW_LOGGING_FAILED: "Writing one row to the row-based binary log failed", + ER_BINLOG_ROW_WRONG_TABLE_DEF: "Table definition on master and slave does not match: %s", + ER_BINLOG_ROW_RBR_TO_SBR: "Slave running with --log-slave-updates must use row-based binary logging to be able to replicate row-based binary log events", + ER_EVENT_ALREADY_EXISTS: "Event '%-.192s' already exists", + ER_EVENT_STORE_FAILED: "Failed to store event %s. Error code %d from storage engine.", + ER_EVENT_DOES_NOT_EXIST: "Unknown event '%-.192s'", + ER_EVENT_CANT_ALTER: "Failed to alter event '%-.192s'", + ER_EVENT_DROP_FAILED: "Failed to drop %s", + ER_EVENT_INTERVAL_NOT_POSITIVE_OR_TOO_BIG: "INTERVAL is either not positive or too big", + ER_EVENT_ENDS_BEFORE_STARTS: "ENDS is either invalid or before STARTS", + ER_EVENT_EXEC_TIME_IN_THE_PAST: "Event execution time is in the past. Event has been disabled", + ER_EVENT_OPEN_TABLE_FAILED: "Failed to open mysql.event", + ER_EVENT_NEITHER_M_EXPR_NOR_M_AT: "No datetime expression provided", + ER_OBSOLETE_COL_COUNT_DOESNT_MATCH_CORRUPTED: "Column count of mysql.%s is wrong. Expected %d, found %d. The table is probably corrupted", + ER_OBSOLETE_CANNOT_LOAD_FROM_TABLE: "Cannot load from mysql.%s. The table is probably corrupted", + ER_EVENT_CANNOT_DELETE: "Failed to delete the event from mysql.event", + ER_EVENT_COMPILE_ERROR: "Error during compilation of event's body", + ER_EVENT_SAME_NAME: "Same old and new event name", + ER_EVENT_DATA_TOO_LONG: "Data for column '%s' too long", + ER_DROP_INDEX_FK: "Cannot drop index '%-.192s': needed in a foreign key constraint", + ER_WARN_DEPRECATED_SYNTAX_WITH_VER: "The syntax '%s' is deprecated and will be removed in MySQL %s. Please use %s instead", + ER_CANT_WRITE_LOCK_LOG_TABLE: "You can't write-lock a log table. Only read access is possible", + ER_CANT_LOCK_LOG_TABLE: "You can't use locks with log tables.", + ER_FOREIGN_DUPLICATE_KEY_OLD_UNUSED: "Upholding foreign key constraints for table '%.192s', entry '%-.192s', key %d would lead to a duplicate entry", + ER_COL_COUNT_DOESNT_MATCH_PLEASE_UPDATE: "Column count of mysql.%s is wrong. Expected %d, found %d. Created with MySQL %d, now running %d. Please use mysql_upgrade to fix this error.", + ER_TEMP_TABLE_PREVENTS_SWITCH_OUT_OF_RBR: "Cannot switch out of the row-based binary log format when the session has open temporary tables", + ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_FORMAT: "Cannot change the binary logging format inside a stored function or trigger", + ER_NDB_CANT_SWITCH_BINLOG_FORMAT: "The NDB cluster engine does not support changing the binlog format on the fly yet", + ER_PARTITION_NO_TEMPORARY: "Cannot create temporary table with partitions", + ER_PARTITION_CONST_DOMAIN_ERROR: "Partition constant is out of partition function domain", + ER_PARTITION_FUNCTION_IS_NOT_ALLOWED: "This partition function is not allowed", + ER_DDL_LOG_ERROR: "Error in DDL log", + ER_NULL_IN_VALUES_LESS_THAN: "Not allowed to use NULL value in VALUES LESS THAN", + ER_WRONG_PARTITION_NAME: "Incorrect partition name", + ER_CANT_CHANGE_TX_CHARACTERISTICS: "Transaction characteristics can't be changed while a transaction is in progress", + ER_DUP_ENTRY_AUTOINCREMENT_CASE: "ALTER TABLE causes auto_increment resequencing, resulting in duplicate entry '%-.192s' for key '%-.192s'", + ER_EVENT_MODIFY_QUEUE_ERROR: "Internal scheduler error %d", + ER_EVENT_SET_VAR_ERROR: "Error during starting/stopping of the scheduler. Error code %d", + ER_PARTITION_MERGE_ERROR: "Engine cannot be used in partitioned tables", + ER_CANT_ACTIVATE_LOG: "Cannot activate '%-.64s' log", + ER_RBR_NOT_AVAILABLE: "The server was not built with row-based replication", + ER_BASE64_DECODE_ERROR: "Decoding of base64 string failed", + ER_EVENT_RECURSION_FORBIDDEN: "Recursion of EVENT DDL statements is forbidden when body is present", + ER_EVENTS_DB_ERROR: "Cannot proceed because system tables used by Event Scheduler were found damaged at server start", + ER_ONLY_INTEGERS_ALLOWED: "Only integers allowed as number here", + ER_UNSUPORTED_LOG_ENGINE: "This storage engine cannot be used for log tables\"", + ER_BAD_LOG_STATEMENT: "You cannot '%s' a log table if logging is enabled", + ER_CANT_RENAME_LOG_TABLE: "Cannot rename '%s'. When logging enabled, rename to/from log table must rename two tables: the log table to an archive table and another table back to '%s'", + ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT: "Incorrect parameter count in the call to native function '%-.192s'", + ER_WRONG_PARAMETERS_TO_NATIVE_FCT: "Incorrect parameters in the call to native function '%-.192s'", + ER_WRONG_PARAMETERS_TO_STORED_FCT: "Incorrect parameters in the call to stored function '%-.192s'", + ER_NATIVE_FCT_NAME_COLLISION: "This function '%-.192s' has the same name as a native function", + ER_DUP_ENTRY_WITH_KEY_NAME: "Duplicate entry '%-.64s' for key '%-.192s'", + ER_BINLOG_PURGE_EMFILE: "Too many files opened, please execute the command again", + ER_EVENT_CANNOT_CREATE_IN_THE_PAST: "Event execution time is in the past and ON COMPLETION NOT PRESERVE is set. The event was dropped immediately after creation.", + ER_EVENT_CANNOT_ALTER_IN_THE_PAST: "Event execution time is in the past and ON COMPLETION NOT PRESERVE is set. The event was not changed. Specify a time in the future.", + ER_SLAVE_INCIDENT: "The incident %s occurred on the master. Message: %-.64s", + ER_NO_PARTITION_FOR_GIVEN_VALUE_SILENT: "Table has no partition for some existing values", + ER_BINLOG_UNSAFE_STATEMENT: "Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. %s", + ER_SLAVE_FATAL_ERROR: "Fatal error: %s", + ER_SLAVE_RELAY_LOG_READ_FAILURE: "Relay log read failure: %s", + ER_SLAVE_RELAY_LOG_WRITE_FAILURE: "Relay log write failure: %s", + ER_SLAVE_CREATE_EVENT_FAILURE: "Failed to create %s", + ER_SLAVE_MASTER_COM_FAILURE: "Master command %s failed: %s", + ER_BINLOG_LOGGING_IMPOSSIBLE: "Binary logging not possible. Message: %s", + ER_VIEW_NO_CREATION_CTX: "View `%-.64s`.`%-.64s` has no creation context", + ER_VIEW_INVALID_CREATION_CTX: "Creation context of view `%-.64s`.`%-.64s' is invalid", + ER_SR_INVALID_CREATION_CTX: "Creation context of stored routine `%-.64s`.`%-.64s` is invalid", + ER_TRG_CORRUPTED_FILE: "Corrupted TRG file for table `%-.64s`.`%-.64s`", + ER_TRG_NO_CREATION_CTX: "Triggers for table `%-.64s`.`%-.64s` have no creation context", + ER_TRG_INVALID_CREATION_CTX: "Trigger creation context of table `%-.64s`.`%-.64s` is invalid", + ER_EVENT_INVALID_CREATION_CTX: "Creation context of event `%-.64s`.`%-.64s` is invalid", + ER_TRG_CANT_OPEN_TABLE: "Cannot open table for trigger `%-.64s`.`%-.64s`", + ER_CANT_CREATE_SROUTINE: "Cannot create stored routine `%-.64s`. Check warnings", + ER_NEVER_USED: "Ambiguous slave modes combination. %s", + ER_NO_FORMAT_DESCRIPTION_EVENT_BEFORE_BINLOG_STATEMENT: "The BINLOG statement of type `%s` was not preceded by a format description BINLOG statement.", + ER_SLAVE_CORRUPT_EVENT: "Corrupted replication event was detected", + ER_LOAD_DATA_INVALID_COLUMN: "Invalid column reference (%-.64s) in LOAD DATA", + ER_LOG_PURGE_NO_FILE: "Being purged log %s was not found", + ER_XA_RBTIMEOUT: "XA_RBTIMEOUT: Transaction branch was rolled back: took too long", + ER_XA_RBDEADLOCK: "XA_RBDEADLOCK: Transaction branch was rolled back: deadlock was detected", + ER_NEED_REPREPARE: "Prepared statement needs to be re-prepared", + ER_DELAYED_NOT_SUPPORTED: "DELAYED option not supported for table '%-.192s'", + WARN_NO_MASTER_INFO: "The master info structure does not exist", + WARN_OPTION_IGNORED: "<%-.64s> option ignored", + WARN_PLUGIN_DELETE_BUILTIN: "Built-in plugins cannot be deleted", + WARN_PLUGIN_BUSY: "Plugin is busy and will be uninstalled on shutdown", + ER_VARIABLE_IS_READONLY: "%s variable '%s' is read-only. Use SET %s to assign the value", + ER_WARN_ENGINE_TRANSACTION_ROLLBACK: "Storage engine %s does not support rollback for this statement. Transaction rolled back and must be restarted", + ER_SLAVE_HEARTBEAT_FAILURE: "Unexpected master's heartbeat data: %s", + ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE: "The requested value for the heartbeat period is either negative or exceeds the maximum allowed (%s seconds).", + ER_NDB_REPLICATION_SCHEMA_ERROR: "Bad schema for mysql.ndb_replication table. Message: %-.64s", + ER_CONFLICT_FN_PARSE_ERROR: "Error in parsing conflict function. Message: %-.64s", + ER_EXCEPTIONS_WRITE_ERROR: "Write to exceptions table failed. Message: %-.128s\"", + ER_TOO_LONG_TABLE_COMMENT: "Comment for table '%-.64s' is too long (max = %d)", + ER_TOO_LONG_FIELD_COMMENT: "Comment for field '%-.64s' is too long (max = %d)", + ER_FUNC_INEXISTENT_NAME_COLLISION: "FUNCTION %s does not exist. Check the 'Function Name Parsing and Resolution' section in the Reference Manual", + ER_DATABASE_NAME: "Database", + ER_TABLE_NAME: "Table", + ER_PARTITION_NAME: "Partition", + ER_SUBPARTITION_NAME: "Subpartition", + ER_TEMPORARY_NAME: "Temporary", + ER_RENAMED_NAME: "Renamed", + ER_TOO_MANY_CONCURRENT_TRXS: "Too many active concurrent transactions", + WARN_NON_ASCII_SEPARATOR_NOT_IMPLEMENTED: "Non-ASCII separator arguments are not fully supported", + ER_DEBUG_SYNC_TIMEOUT: "debug sync point wait timed out", + ER_DEBUG_SYNC_HIT_LIMIT: "debug sync point hit limit reached", + ER_DUP_SIGNAL_SET: "Duplicate condition information item '%s'", + ER_SIGNAL_WARN: "Unhandled user-defined warning condition", + ER_SIGNAL_NOT_FOUND: "Unhandled user-defined not found condition", + ER_SIGNAL_EXCEPTION: "Unhandled user-defined exception condition", + ER_RESIGNAL_WITHOUT_ACTIVE_HANDLER: "RESIGNAL when handler not active", + ER_SIGNAL_BAD_CONDITION_TYPE: "SIGNAL/RESIGNAL can only use a CONDITION defined with SQLSTATE", + WARN_COND_ITEM_TRUNCATED: "Data truncated for condition item '%s'", + ER_COND_ITEM_TOO_LONG: "Data too long for condition item '%s'", + ER_UNKNOWN_LOCALE: "Unknown locale: '%-.64s'", + ER_SLAVE_IGNORE_SERVER_IDS: "The requested server id %d clashes with the slave startup option --replicate-same-server-id", + ER_QUERY_CACHE_DISABLED: "Query cache is disabled; restart the server with query_cache_type=1 to enable it", + ER_SAME_NAME_PARTITION_FIELD: "Duplicate partition field name '%-.192s'", + ER_PARTITION_COLUMN_LIST_ERROR: "Inconsistency in usage of column lists for partitioning", + ER_WRONG_TYPE_COLUMN_VALUE_ERROR: "Partition column values of incorrect type", + ER_TOO_MANY_PARTITION_FUNC_FIELDS_ERROR: "Too many fields in '%-.192s'", + ER_MAXVALUE_IN_VALUES_IN: "Cannot use MAXVALUE as value in VALUES IN", + ER_TOO_MANY_VALUES_ERROR: "Cannot have more than one value for this type of %-.64s partitioning", + ER_ROW_SINGLE_PARTITION_FIELD_ERROR: "Row expressions in VALUES IN only allowed for multi-field column partitioning", + ER_FIELD_TYPE_NOT_ALLOWED_AS_PARTITION_FIELD: "Field '%-.192s' is of a not allowed type for this type of partitioning", + ER_PARTITION_FIELDS_TOO_LONG: "The total length of the partitioning fields is too large", + ER_BINLOG_ROW_ENGINE_AND_STMT_ENGINE: "Cannot execute statement: impossible to write to binary log since both row-incapable engines and statement-incapable engines are involved.", + ER_BINLOG_ROW_MODE_AND_STMT_ENGINE: "Cannot execute statement: impossible to write to binary log since BINLOG_FORMAT = ROW and at least one table uses a storage engine limited to statement-based logging.", + ER_BINLOG_UNSAFE_AND_STMT_ENGINE: "Cannot execute statement: impossible to write to binary log since statement is unsafe, storage engine is limited to statement-based logging, and BINLOG_FORMAT = MIXED. %s", + ER_BINLOG_ROW_INJECTION_AND_STMT_ENGINE: "Cannot execute statement: impossible to write to binary log since statement is in row format and at least one table uses a storage engine limited to statement-based logging.", + ER_BINLOG_STMT_MODE_AND_ROW_ENGINE: "Cannot execute statement: impossible to write to binary log since BINLOG_FORMAT = STATEMENT and at least one table uses a storage engine limited to row-based logging.%s", + ER_BINLOG_ROW_INJECTION_AND_STMT_MODE: "Cannot execute statement: impossible to write to binary log since statement is in row format and BINLOG_FORMAT = STATEMENT.", + ER_BINLOG_MULTIPLE_ENGINES_AND_SELF_LOGGING_ENGINE: "Cannot execute statement: impossible to write to binary log since more than one engine is involved and at least one engine is self-logging.", + ER_BINLOG_UNSAFE_LIMIT: "The statement is unsafe because it uses a LIMIT clause. This is unsafe because the set of rows included cannot be predicted.", + ER_BINLOG_UNSAFE_INSERT_DELAYED: "The statement is unsafe because it uses INSERT DELAYED. This is unsafe because the times when rows are inserted cannot be predicted.", + ER_BINLOG_UNSAFE_SYSTEM_TABLE: "The statement is unsafe because it uses the general log, slow query log, or performance_schema table(s). This is unsafe because system tables may differ on slaves.", + ER_BINLOG_UNSAFE_AUTOINC_COLUMNS: "Statement is unsafe because it invokes a trigger or a stored function that inserts into an AUTO_INCREMENT column. Inserted values cannot be logged correctly.", + ER_BINLOG_UNSAFE_UDF: "Statement is unsafe because it uses a UDF which may not return the same value on the slave.", + ER_BINLOG_UNSAFE_SYSTEM_VARIABLE: "Statement is unsafe because it uses a system variable that may have a different value on the slave.", + ER_BINLOG_UNSAFE_SYSTEM_FUNCTION: "Statement is unsafe because it uses a system function that may return a different value on the slave.", + ER_BINLOG_UNSAFE_NONTRANS_AFTER_TRANS: "Statement is unsafe because it accesses a non-transactional table after accessing a transactional table within the same transaction.", + ER_MESSAGE_AND_STATEMENT: "%s Statement: %s", + ER_SLAVE_CONVERSION_FAILED: "Column %d of table '%-.192s.%-.192s' cannot be converted from type '%-.32s' to type '%-.32s'", + ER_SLAVE_CANT_CREATE_CONVERSION: "Can't create conversion table for table '%-.192s.%-.192s'", + ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_FORMAT: "Cannot modify @@session.binlog_format inside a transaction", + ER_PATH_LENGTH: "The path specified for %.64s is too long.", + ER_WARN_DEPRECATED_SYNTAX_NO_REPLACEMENT: "'%s' is deprecated and will be removed in a future release.", + ER_WRONG_NATIVE_TABLE_STRUCTURE: "Native table '%-.64s'.'%-.64s' has the wrong structure", + ER_WRONG_PERFSCHEMA_USAGE: "Invalid performance_schema usage.", + ER_WARN_I_S_SKIPPED_TABLE: "Table '%s'.'%s' was skipped since its definition is being modified by concurrent DDL statement", + ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_DIRECT: "Cannot modify @@session.binlog_direct_non_transactional_updates inside a transaction", + ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_DIRECT: "Cannot change the binlog direct flag inside a stored function or trigger", + ER_SPATIAL_MUST_HAVE_GEOM_COL: "A SPATIAL index may only contain a geometrical type column", + ER_TOO_LONG_INDEX_COMMENT: "Comment for index '%-.64s' is too long (max = %d)", + ER_LOCK_ABORTED: "Wait on a lock was aborted due to a pending exclusive lock", + ER_DATA_OUT_OF_RANGE: "%s value is out of range in '%s'", + ER_WRONG_SPVAR_TYPE_IN_LIMIT: "A variable of a non-integer based type in LIMIT clause", + ER_BINLOG_UNSAFE_MULTIPLE_ENGINES_AND_SELF_LOGGING_ENGINE: "Mixing self-logging and non-self-logging engines in a statement is unsafe.", + ER_BINLOG_UNSAFE_MIXED_STATEMENT: "Statement accesses nontransactional table as well as transactional or temporary table, and writes to any of them.", + ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_SQL_LOG_BIN: "Cannot modify @@session.sql_log_bin inside a transaction", + ER_STORED_FUNCTION_PREVENTS_SWITCH_SQL_LOG_BIN: "Cannot change the sql_log_bin inside a stored function or trigger", + ER_FAILED_READ_FROM_PAR_FILE: "Failed to read from the .par file", + ER_VALUES_IS_NOT_INT_TYPE_ERROR: "VALUES value for partition '%-.64s' must have type INT", + ER_ACCESS_DENIED_NO_PASSWORD_ERROR: "Access denied for user '%-.48s'@'%-.64s'", + ER_SET_PASSWORD_AUTH_PLUGIN: "SET PASSWORD has no significance for users authenticating via plugins", + ER_GRANT_PLUGIN_USER_EXISTS: "GRANT with IDENTIFIED WITH is illegal because the user %-.*s already exists", + ER_TRUNCATE_ILLEGAL_FK: "Cannot truncate a table referenced in a foreign key constraint (%.192s)", + ER_PLUGIN_IS_PERMANENT: "Plugin '%s' is force_plus_permanent and can not be unloaded", + ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MIN: "The requested value for the heartbeat period is less than 1 millisecond. The value is reset to 0, meaning that heartbeating will effectively be disabled.", + ER_SLAVE_HEARTBEAT_VALUE_OUT_OF_RANGE_MAX: "The requested value for the heartbeat period exceeds the value of `slave_net_timeout' seconds. A sensible value for the period should be less than the timeout.", + ER_STMT_CACHE_FULL: "Multi-row statements required more than 'max_binlog_stmt_cache_size' bytes of storage; increase this mysqld variable and try again", + ER_MULTI_UPDATE_KEY_CONFLICT: "Primary key/partition key update is not allowed since the table is updated both as '%-.192s' and '%-.192s'.", + ER_TABLE_NEEDS_REBUILD: "Table rebuild required. Please do \"ALTER TABLE `%-.32s` FORCE\" or dump/reload to fix it!", + WARN_OPTION_BELOW_LIMIT: "The value of '%s' should be no less than the value of '%s'", + ER_INDEX_COLUMN_TOO_LONG: "Index column size too large. The maximum column size is %d bytes.", + ER_ERROR_IN_TRIGGER_BODY: "Trigger '%-.64s' has an error in its body: '%-.256s'", + ER_ERROR_IN_UNKNOWN_TRIGGER_BODY: "Unknown trigger has an error in its body: '%-.256s'", + ER_INDEX_CORRUPT: "Index %s is corrupted", + ER_UNDO_RECORD_TOO_BIG: "Undo log record is too big.", + ER_BINLOG_UNSAFE_INSERT_IGNORE_SELECT: "INSERT IGNORE... SELECT is unsafe because the order in which rows are retrieved by the SELECT determines which (if any) rows are ignored. This order cannot be predicted and may differ on master and the slave.", + ER_BINLOG_UNSAFE_INSERT_SELECT_UPDATE: "INSERT... SELECT... ON DUPLICATE KEY UPDATE is unsafe because the order in which rows are retrieved by the SELECT determines which (if any) rows are updated. This order cannot be predicted and may differ on master and the slave.", + ER_BINLOG_UNSAFE_REPLACE_SELECT: "REPLACE... SELECT is unsafe because the order in which rows are retrieved by the SELECT determines which (if any) rows are replaced. This order cannot be predicted and may differ on master and the slave.", + ER_BINLOG_UNSAFE_CREATE_IGNORE_SELECT: "CREATE... IGNORE SELECT is unsafe because the order in which rows are retrieved by the SELECT determines which (if any) rows are ignored. This order cannot be predicted and may differ on master and the slave.", + ER_BINLOG_UNSAFE_CREATE_REPLACE_SELECT: "CREATE... REPLACE SELECT is unsafe because the order in which rows are retrieved by the SELECT determines which (if any) rows are replaced. This order cannot be predicted and may differ on master and the slave.", + ER_BINLOG_UNSAFE_UPDATE_IGNORE: "UPDATE IGNORE is unsafe because the order in which rows are updated determines which (if any) rows are ignored. This order cannot be predicted and may differ on master and the slave.", + ER_PLUGIN_NO_UNINSTALL: "Plugin '%s' is marked as not dynamically uninstallable. You have to stop the server to uninstall it.", + ER_PLUGIN_NO_INSTALL: "Plugin '%s' is marked as not dynamically installable. You have to stop the server to install it.", + ER_BINLOG_UNSAFE_WRITE_AUTOINC_SELECT: "Statements writing to a table with an auto-increment column after selecting from another table are unsafe because the order in which rows are retrieved determines what (if any) rows will be written. This order cannot be predicted and may differ on master and the slave.", + ER_BINLOG_UNSAFE_CREATE_SELECT_AUTOINC: "CREATE TABLE... SELECT... on a table with an auto-increment column is unsafe because the order in which rows are retrieved by the SELECT determines which (if any) rows are inserted. This order cannot be predicted and may differ on master and the slave.", + ER_BINLOG_UNSAFE_INSERT_TWO_KEYS: "INSERT... ON DUPLICATE KEY UPDATE on a table with more than one UNIQUE KEY is unsafe", + ER_TABLE_IN_FK_CHECK: "Table is being used in foreign key check.", + ER_UNSUPPORTED_ENGINE: "Storage engine '%s' does not support system tables. [%s.%s]", + ER_BINLOG_UNSAFE_AUTOINC_NOT_FIRST: "INSERT into autoincrement field which is not the first part in the composed primary key is unsafe.", + ER_CANNOT_LOAD_FROM_TABLE_V2: "Cannot load from %s.%s. The table is probably corrupted", + ER_MASTER_DELAY_VALUE_OUT_OF_RANGE: "The requested value %d for the master delay exceeds the maximum %d", + ER_ONLY_FD_AND_RBR_EVENTS_ALLOWED_IN_BINLOG_STATEMENT: "Only Format_description_log_event and row events are allowed in BINLOG statements (but %s was provided)", + ER_PARTITION_EXCHANGE_DIFFERENT_OPTION: "Non matching attribute '%-.64s' between partition and table", + ER_PARTITION_EXCHANGE_PART_TABLE: "Table to exchange with partition is partitioned: '%-.64s'", + ER_PARTITION_EXCHANGE_TEMP_TABLE: "Table to exchange with partition is temporary: '%-.64s'", + ER_PARTITION_INSTEAD_OF_SUBPARTITION: "Subpartitioned table, use subpartition instead of partition", + ER_UNKNOWN_PARTITION: "Unknown partition '%-.64s' in table '%-.64s'", + ER_TABLES_DIFFERENT_METADATA: "Tables have different definitions", + ER_ROW_DOES_NOT_MATCH_PARTITION: "Found a row that does not match the partition", + ER_BINLOG_CACHE_SIZE_GREATER_THAN_MAX: "Option binlog_cache_size (%d) is greater than max_binlog_cache_size (%d); setting binlog_cache_size equal to max_binlog_cache_size.", + ER_WARN_INDEX_NOT_APPLICABLE: "Cannot use %-.64s access on index '%-.64s' due to type or collation conversion on field '%-.64s'", + ER_PARTITION_EXCHANGE_FOREIGN_KEY: "Table to exchange with partition has foreign key references: '%-.64s'", + ER_NO_SUCH_KEY_VALUE: "Key value '%-.192s' was not found in table '%-.192s.%-.192s'", + ER_RPL_INFO_DATA_TOO_LONG: "Data for column '%s' too long", + ER_NETWORK_READ_EVENT_CHECKSUM_FAILURE: "Replication event checksum verification failed while reading from network.", + ER_BINLOG_READ_EVENT_CHECKSUM_FAILURE: "Replication event checksum verification failed while reading from a log file.", + ER_BINLOG_STMT_CACHE_SIZE_GREATER_THAN_MAX: "Option binlog_stmt_cache_size (%d) is greater than max_binlog_stmt_cache_size (%d); setting binlog_stmt_cache_size equal to max_binlog_stmt_cache_size.", + ER_CANT_UPDATE_TABLE_IN_CREATE_TABLE_SELECT: "Can't update table '%-.192s' while '%-.192s' is being created.", + ER_PARTITION_CLAUSE_ON_NONPARTITIONED: "PARTITION () clause on non partitioned table", + ER_ROW_DOES_NOT_MATCH_GIVEN_PARTITION_SET: "Found a row not matching the given partition set", + ER_NO_SUCH_PARTITION__UNUSED: "partition '%-.64s' doesn't exist", + ER_CHANGE_RPL_INFO_REPOSITORY_FAILURE: "Failure while changing the type of replication repository: %s.", + ER_WARNING_NOT_COMPLETE_ROLLBACK_WITH_CREATED_TEMP_TABLE: "The creation of some temporary tables could not be rolled back.", + ER_WARNING_NOT_COMPLETE_ROLLBACK_WITH_DROPPED_TEMP_TABLE: "Some temporary tables were dropped, but these operations could not be rolled back.", + ER_MTS_FEATURE_IS_NOT_SUPPORTED: "%s is not supported in multi-threaded slave mode. %s", + ER_MTS_UPDATED_DBS_GREATER_MAX: "The number of modified databases exceeds the maximum %d; the database names will not be included in the replication event metadata.", + ER_MTS_CANT_PARALLEL: "Cannot execute the current event group in the parallel mode. Encountered event %s, relay-log name %s, position %s which prevents execution of this event group in parallel mode. Reason: %s.", + ER_MTS_INCONSISTENT_DATA: "%s", + ER_FULLTEXT_NOT_SUPPORTED_WITH_PARTITIONING: "FULLTEXT index is not supported for partitioned tables.", + ER_DA_INVALID_CONDITION_NUMBER: "Invalid condition number", + ER_INSECURE_PLAIN_TEXT: "Sending passwords in plain text without SSL/TLS is extremely insecure.", + ER_INSECURE_CHANGE_MASTER: "Storing MySQL user name or password information in the master.info repository is not secure and is therefore not recommended. Please see the MySQL Manual for more about this issue and possible alternatives.", + ER_FOREIGN_DUPLICATE_KEY_WITH_CHILD_INFO: "Foreign key constraint for table '%.192s', record '%-.192s' would lead to a duplicate entry in table '%.192s', key '%.192s'", + ER_FOREIGN_DUPLICATE_KEY_WITHOUT_CHILD_INFO: "Foreign key constraint for table '%.192s', record '%-.192s' would lead to a duplicate entry in a child table", + ER_SQLTHREAD_WITH_SECURE_SLAVE: "Setting authentication options is not possible when only the Slave SQL Thread is being started.", + ER_TABLE_HAS_NO_FT: "The table does not have FULLTEXT index to support this query", + ER_VARIABLE_NOT_SETTABLE_IN_SF_OR_TRIGGER: "The system variable %.200s cannot be set in stored functions or triggers.", + ER_VARIABLE_NOT_SETTABLE_IN_TRANSACTION: "The system variable %.200s cannot be set when there is an ongoing transaction.", + ER_GTID_NEXT_IS_NOT_IN_GTID_NEXT_LIST: "The system variable @@SESSION.GTID_NEXT has the value %.200s, which is not listed in @@SESSION.GTID_NEXT_LIST.", + ER_CANT_CHANGE_GTID_NEXT_IN_TRANSACTION_WHEN_GTID_NEXT_LIST_IS_NULL: "When @@SESSION.GTID_NEXT_LIST == NULL, the system variable @@SESSION.GTID_NEXT cannot change inside a transaction.", + ER_SET_STATEMENT_CANNOT_INVOKE_FUNCTION: "The statement 'SET %.200s' cannot invoke a stored function.", + ER_GTID_NEXT_CANT_BE_AUTOMATIC_IF_GTID_NEXT_LIST_IS_NON_NULL: "The system variable @@SESSION.GTID_NEXT cannot be 'AUTOMATIC' when @@SESSION.GTID_NEXT_LIST is non-NULL.", + ER_SKIPPING_LOGGED_TRANSACTION: "Skipping transaction %.200s because it has already been executed and logged.", + ER_MALFORMED_GTID_SET_SPECIFICATION: "Malformed GTID set specification '%.200s'.", + ER_MALFORMED_GTID_SET_ENCODING: "Malformed GTID set encoding.", + ER_MALFORMED_GTID_SPECIFICATION: "Malformed GTID specification '%.200s'.", + ER_GNO_EXHAUSTED: "Impossible to generate Global Transaction Identifier: the integer component reached the maximal value. Restart the server with a new server_uuid.", + ER_BAD_SLAVE_AUTO_POSITION: "Parameters MASTER_LOG_FILE, MASTER_LOG_POS, RELAY_LOG_FILE and RELAY_LOG_POS cannot be set when MASTER_AUTO_POSITION is active.", + ER_AUTO_POSITION_REQUIRES_GTID_MODE_ON: "CHANGE MASTER TO MASTER_AUTO_POSITION = 1 can only be executed when @@GLOBAL.GTID_MODE = ON.", + ER_CANT_DO_IMPLICIT_COMMIT_IN_TRX_WHEN_GTID_NEXT_IS_SET: "Cannot execute statements with implicit commit inside a transaction when @@SESSION.GTID_NEXT != AUTOMATIC or @@SESSION.GTID_NEXT_LIST != NULL.", + ER_GTID_MODE_2_OR_3_REQUIRES_ENFORCE_GTID_CONSISTENCY_ON: "@@GLOBAL.GTID_MODE = ON or UPGRADE_STEP_2 requires @@GLOBAL.ENFORCE_GTID_CONSISTENCY = 1.", + ER_GTID_MODE_REQUIRES_BINLOG: "@@GLOBAL.GTID_MODE = ON or UPGRADE_STEP_1 or UPGRADE_STEP_2 requires --log-bin and --log-slave-updates.", + ER_CANT_SET_GTID_NEXT_TO_GTID_WHEN_GTID_MODE_IS_OFF: "@@SESSION.GTID_NEXT cannot be set to UUID:NUMBER when @@GLOBAL.GTID_MODE = OFF.", + ER_CANT_SET_GTID_NEXT_TO_ANONYMOUS_WHEN_GTID_MODE_IS_ON: "@@SESSION.GTID_NEXT cannot be set to ANONYMOUS when @@GLOBAL.GTID_MODE = ON.", + ER_CANT_SET_GTID_NEXT_LIST_TO_NON_NULL_WHEN_GTID_MODE_IS_OFF: "@@SESSION.GTID_NEXT_LIST cannot be set to a non-NULL value when @@GLOBAL.GTID_MODE = OFF.", + ER_FOUND_GTID_EVENT_WHEN_GTID_MODE_IS_OFF: "Found a Gtid_log_event or Previous_gtids_log_event when @@GLOBAL.GTID_MODE = OFF.", + ER_GTID_UNSAFE_NON_TRANSACTIONAL_TABLE: "When @@GLOBAL.ENFORCE_GTID_CONSISTENCY = 1, updates to non-transactional tables can only be done in either autocommitted statements or single-statement transactions, and never in the same statement as updates to transactional tables.", + ER_GTID_UNSAFE_CREATE_SELECT: "CREATE TABLE ... SELECT is forbidden when @@GLOBAL.ENFORCE_GTID_CONSISTENCY = 1.", + ER_GTID_UNSAFE_CREATE_DROP_TEMPORARY_TABLE_IN_TRANSACTION: "When @@GLOBAL.ENFORCE_GTID_CONSISTENCY = 1, the statements CREATE TEMPORARY TABLE and DROP TEMPORARY TABLE can be executed in a non-transactional context only, and require that AUTOCOMMIT = 1.", + ER_GTID_MODE_CAN_ONLY_CHANGE_ONE_STEP_AT_A_TIME: "The value of @@GLOBAL.GTID_MODE can only change one step at a time: OFF <-> UPGRADE_STEP_1 <-> UPGRADE_STEP_2 <-> ON. Also note that this value must be stepped up or down simultaneously on all servers; see the Manual for instructions.", + ER_MASTER_HAS_PURGED_REQUIRED_GTIDS: "The slave is connecting using CHANGE MASTER TO MASTER_AUTO_POSITION = 1, but the master has purged binary logs containing GTIDs that the slave requires.", + ER_CANT_SET_GTID_NEXT_WHEN_OWNING_GTID: "@@SESSION.GTID_NEXT cannot be changed by a client that owns a GTID. The client owns %s. Ownership is released on COMMIT or ROLLBACK.", + ER_UNKNOWN_EXPLAIN_FORMAT: "Unknown EXPLAIN format name: '%s'", + ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION: "Cannot execute statement in a READ ONLY transaction.", + ER_TOO_LONG_TABLE_PARTITION_COMMENT: "Comment for table partition '%-.64s' is too long (max = %d)", + ER_SLAVE_CONFIGURATION: "Slave is not configured or failed to initialize properly. You must at least set --server-id to enable either a master or a slave. Additional error messages can be found in the MySQL error log.", + ER_INNODB_FT_LIMIT: "InnoDB presently supports one FULLTEXT index creation at a time", + ER_INNODB_NO_FT_TEMP_TABLE: "Cannot create FULLTEXT index on temporary InnoDB table", + ER_INNODB_FT_WRONG_DOCID_COLUMN: "Column '%-.192s' is of wrong type for an InnoDB FULLTEXT index", + ER_INNODB_FT_WRONG_DOCID_INDEX: "Index '%-.192s' is of wrong type for an InnoDB FULLTEXT index", + ER_INNODB_ONLINE_LOG_TOO_BIG: "Creating index '%-.192s' required more than 'innodb_online_alter_log_max_size' bytes of modification log. Please try again.", + ER_UNKNOWN_ALTER_ALGORITHM: "Unknown ALGORITHM '%s'", + ER_UNKNOWN_ALTER_LOCK: "Unknown LOCK type '%s'", + ER_MTS_CHANGE_MASTER_CANT_RUN_WITH_GAPS: "CHANGE MASTER cannot be executed when the slave was stopped with an error or killed in MTS mode. Consider using RESET SLAVE or START SLAVE UNTIL.", + ER_MTS_RECOVERY_FAILURE: "Cannot recover after SLAVE errored out in parallel execution mode. Additional error messages can be found in the MySQL error log.", + ER_MTS_RESET_WORKERS: "Cannot clean up worker info tables. Additional error messages can be found in the MySQL error log.", + ER_COL_COUNT_DOESNT_MATCH_CORRUPTED_V2: "Column count of %s.%s is wrong. Expected %d, found %d. The table is probably corrupted", + ER_SLAVE_SILENT_RETRY_TRANSACTION: "Slave must silently retry current transaction", + ER_DISCARD_FK_CHECKS_RUNNING: "There is a foreign key check running on table '%-.192s'. Cannot discard the table.", + ER_TABLE_SCHEMA_MISMATCH: "Schema mismatch (%s)", + ER_TABLE_IN_SYSTEM_TABLESPACE: "Table '%-.192s' in system tablespace", + ER_IO_READ_ERROR: "IO Read error: (%d, %s) %s", + ER_IO_WRITE_ERROR: "IO Write error: (%d, %s) %s", + ER_TABLESPACE_MISSING: "Tablespace is missing for table '%-.192s'", + ER_TABLESPACE_EXISTS: "Tablespace for table '%-.192s' exists. Please DISCARD the tablespace before IMPORT.", + ER_TABLESPACE_DISCARDED: "Tablespace has been discarded for table '%-.192s'", + ER_INTERNAL_ERROR: "Internal error: %s", + ER_INNODB_IMPORT_ERROR: "ALTER TABLE '%-.192s' IMPORT TABLESPACE failed with error %d : '%s'", + ER_INNODB_INDEX_CORRUPT: "Index corrupt: %s", + ER_INVALID_YEAR_COLUMN_LENGTH: "YEAR(%d) column type is deprecated. Creating YEAR(4) column instead.", + ER_NOT_VALID_PASSWORD: "Your password does not satisfy the current policy requirements", + ER_MUST_CHANGE_PASSWORD: "You must SET PASSWORD before executing this statement", + ER_FK_NO_INDEX_CHILD: "Failed to add the foreign key constaint. Missing index for constraint '%s' in the foreign table '%s'", + ER_FK_NO_INDEX_PARENT: "Failed to add the foreign key constaint. Missing index for constraint '%s' in the referenced table '%s'", + ER_FK_FAIL_ADD_SYSTEM: "Failed to add the foreign key constraint '%s' to system tables", + ER_FK_CANNOT_OPEN_PARENT: "Failed to open the referenced table '%s'", + ER_FK_INCORRECT_OPTION: "Failed to add the foreign key constraint on table '%s'. Incorrect options in FOREIGN KEY constraint '%s'", + ER_FK_DUP_NAME: "Duplicate foreign key constraint name '%s'", + ER_PASSWORD_FORMAT: "The password hash doesn't have the expected format. Check if the correct password algorithm is being used with the PASSWORD() function.", + ER_FK_COLUMN_CANNOT_DROP: "Cannot drop column '%-.192s': needed in a foreign key constraint '%-.192s'", + ER_FK_COLUMN_CANNOT_DROP_CHILD: "Cannot drop column '%-.192s': needed in a foreign key constraint '%-.192s' of table '%-.192s'", + ER_FK_COLUMN_NOT_NULL: "Column '%-.192s' cannot be NOT NULL: needed in a foreign key constraint '%-.192s' SET NULL", + ER_DUP_INDEX: "Duplicate index '%-.64s' defined on the table '%-.64s.%-.64s'. This is deprecated and will be disallowed in a future release.", + ER_FK_COLUMN_CANNOT_CHANGE: "Cannot change column '%-.192s': used in a foreign key constraint '%-.192s'", + ER_FK_COLUMN_CANNOT_CHANGE_CHILD: "Cannot change column '%-.192s': used in a foreign key constraint '%-.192s' of table '%-.192s'", + ER_FK_CANNOT_DELETE_PARENT: "Cannot delete rows from table which is parent in a foreign key constraint '%-.192s' of table '%-.192s'", + ER_MALFORMED_PACKET: "Malformed communication packet.", + ER_READ_ONLY_MODE: "Running in read-only mode", + ER_GTID_NEXT_TYPE_UNDEFINED_GROUP: "When @@SESSION.GTID_NEXT is set to a GTID, you must explicitly set it again after a COMMIT or ROLLBACK. If you see this error message in the slave SQL thread, it means that a table in the current transaction is transactional on the master and non-transactional on the slave. In a client connection, it means that you executed SET @@SESSION.GTID_NEXT before a transaction and forgot to set @@SESSION.GTID_NEXT to a different identifier or to 'AUTOMATIC' after COMMIT or ROLLBACK. Current @@SESSION.GTID_NEXT is '%s'.", + ER_VARIABLE_NOT_SETTABLE_IN_SP: "The system variable %.200s cannot be set in stored procedures.", + ER_CANT_SET_GTID_PURGED_WHEN_GTID_MODE_IS_OFF: "@@GLOBAL.GTID_PURGED can only be set when @@GLOBAL.GTID_MODE = ON.", + ER_CANT_SET_GTID_PURGED_WHEN_GTID_EXECUTED_IS_NOT_EMPTY: "@@GLOBAL.GTID_PURGED can only be set when @@GLOBAL.GTID_EXECUTED is empty.", + ER_CANT_SET_GTID_PURGED_WHEN_OWNED_GTIDS_IS_NOT_EMPTY: "@@GLOBAL.GTID_PURGED can only be set when there are no ongoing transactions (not even in other clients).", + ER_GTID_PURGED_WAS_CHANGED: "@@GLOBAL.GTID_PURGED was changed from '%s' to '%s'.", + ER_GTID_EXECUTED_WAS_CHANGED: "@@GLOBAL.GTID_EXECUTED was changed from '%s' to '%s'.", + ER_BINLOG_STMT_MODE_AND_NO_REPL_TABLES: "Cannot execute statement: impossible to write to binary log since BINLOG_FORMAT = STATEMENT, and both replicated and non replicated tables are written to.", + ER_ALTER_OPERATION_NOT_SUPPORTED: "%s is not supported for this operation. Try %s.", + ER_ALTER_OPERATION_NOT_SUPPORTED_REASON: "%s is not supported. Reason: %s. Try %s.", + ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_COPY: "COPY algorithm requires a lock", + ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_PARTITION: "Partition specific operations do not yet support LOCK/ALGORITHM", + ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_FK_RENAME: "Columns participating in a foreign key are renamed", + ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_COLUMN_TYPE: "Cannot change column type INPLACE", + ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_FK_CHECK: "Adding foreign keys needs foreign_key_checks=OFF", + ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_IGNORE: "Creating unique indexes with IGNORE requires COPY algorithm to remove duplicate rows", + ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_NOPK: "Dropping a primary key is not allowed without also adding a new primary key", + ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_AUTOINC: "Adding an auto-increment column requires a lock", + ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_HIDDEN_FTS: "Cannot replace hidden FTS_DOC_ID with a user-visible one", + ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_CHANGE_FTS: "Cannot drop or rename FTS_DOC_ID", + ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_FTS: "Fulltext index creation requires a lock", + ER_SQL_SLAVE_SKIP_COUNTER_NOT_SETTABLE_IN_GTID_MODE: "sql_slave_skip_counter can not be set when the server is running with @@GLOBAL.GTID_MODE = ON. Instead, for each transaction that you want to skip, generate an empty transaction with the same GTID as the transaction", + ER_DUP_UNKNOWN_IN_INDEX: "Duplicate entry for key '%-.192s'", + ER_IDENT_CAUSES_TOO_LONG_PATH: "Long database name and identifier for object resulted in path length exceeding %d characters. Path: '%s'.", + ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_NOT_NULL: "cannot silently convert NULL values, as required in this SQL_MODE", + ER_MUST_CHANGE_PASSWORD_LOGIN: "Your password has expired. To log in you must change it using a client that supports expired passwords.", + ER_ROW_IN_WRONG_PARTITION: "Found a row in wrong partition %s", +} diff --git a/v2/vendor/github.com/go-mysql-org/go-mysql/mysql/error.go b/v2/vendor/github.com/go-mysql-org/go-mysql/mysql/error.go new file mode 100644 index 0000000..abda6de --- /dev/null +++ b/v2/vendor/github.com/go-mysql-org/go-mysql/mysql/error.go @@ -0,0 +1,66 @@ +package mysql + +import ( + "fmt" + + "github.com/pingcap/errors" +) + +var ( + ErrBadConn = errors.New("connection was bad") + ErrMalformPacket = errors.New("Malform packet error") + + ErrTxDone = errors.New("sql: Transaction has already been committed or rolled back") +) + +type MyError struct { + Code uint16 + Message string + State string +} + +func (e *MyError) Error() string { + return fmt.Sprintf("ERROR %d (%s): %s", e.Code, e.State, e.Message) +} + +// NewDefaultError: default mysql error, must adapt errname message format +func NewDefaultError(errCode uint16, args ...interface{}) *MyError { + e := new(MyError) + e.Code = errCode + + if s, ok := MySQLState[errCode]; ok { + e.State = s + } else { + e.State = DEFAULT_MYSQL_STATE + } + + if format, ok := MySQLErrName[errCode]; ok { + e.Message = fmt.Sprintf(format, args...) + } else { + e.Message = fmt.Sprint(args...) + } + + return e +} + +func NewError(errCode uint16, message string) *MyError { + e := new(MyError) + e.Code = errCode + + if s, ok := MySQLState[errCode]; ok { + e.State = s + } else { + e.State = DEFAULT_MYSQL_STATE + } + + e.Message = message + + return e +} + +func ErrorCode(errMsg string) (code int) { + var tmpStr string + // golang scanf doesn't support %*,so I used a temporary variable + fmt.Sscanf(errMsg, "%s%d", &tmpStr, &code) + return +} diff --git a/v2/vendor/github.com/go-mysql-org/go-mysql/mysql/field.go b/v2/vendor/github.com/go-mysql-org/go-mysql/mysql/field.go new file mode 100644 index 0000000..7ffce40 --- /dev/null +++ b/v2/vendor/github.com/go-mysql-org/go-mysql/mysql/field.go @@ -0,0 +1,212 @@ +package mysql + +import ( + "encoding/binary" + + "github.com/go-mysql-org/go-mysql/utils" +) + +type FieldData []byte + +type Field struct { + Data FieldData + Schema []byte + Table []byte + OrgTable []byte + Name []byte + OrgName []byte + Charset uint16 + ColumnLength uint32 + Type uint8 + Flag uint16 + Decimal uint8 + + DefaultValueLength uint64 + DefaultValue []byte +} + +type FieldValueType uint8 + +type FieldValue struct { + Type FieldValueType + value uint64 // Also for int64 and float64 + str []byte +} + +const ( + FieldValueTypeNull = iota + FieldValueTypeUnsigned + FieldValueTypeSigned + FieldValueTypeFloat + FieldValueTypeString +) + +func (f *Field) Parse(p FieldData) (err error) { + f.Data = p + + var n int + pos := 0 + //skip catelog, always def + n, err = SkipLengthEncodedString(p) + if err != nil { + return + } + pos += n + + //schema + f.Schema, _, n, err = LengthEncodedString(p[pos:]) + if err != nil { + return + } + pos += n + + //table + f.Table, _, n, err = LengthEncodedString(p[pos:]) + if err != nil { + return + } + pos += n + + //org_table + f.OrgTable, _, n, err = LengthEncodedString(p[pos:]) + if err != nil { + return + } + pos += n + + //name + f.Name, _, n, err = LengthEncodedString(p[pos:]) + if err != nil { + return + } + pos += n + + //org_name + f.OrgName, _, n, err = LengthEncodedString(p[pos:]) + if err != nil { + return + } + pos += n + + //skip oc + pos += 1 + + //charset + f.Charset = binary.LittleEndian.Uint16(p[pos:]) + pos += 2 + + //column length + f.ColumnLength = binary.LittleEndian.Uint32(p[pos:]) + pos += 4 + + //type + f.Type = p[pos] + pos++ + + //flag + f.Flag = binary.LittleEndian.Uint16(p[pos:]) + pos += 2 + + //decimals 1 + f.Decimal = p[pos] + pos++ + + //filter [0x00][0x00] + pos += 2 + + f.DefaultValue = nil + //if more data, command was field list + if len(p) > pos { + //length of default value lenenc-int + f.DefaultValueLength, _, n = LengthEncodedInt(p[pos:]) + pos += n + + if pos+int(f.DefaultValueLength) > len(p) { + err = ErrMalformPacket + return + } + + //default value string[$len] + f.DefaultValue = p[pos:(pos + int(f.DefaultValueLength))] + } + + return nil +} + +func (p FieldData) Parse() (f *Field, err error) { + f = new(Field) + if err = f.Parse(p); err != nil { + return nil, err + } + return f, nil +} + +func (f *Field) Dump() []byte { + if f == nil { + f = &Field{} + } + if f.Data != nil { + return f.Data + } + + l := len(f.Schema) + len(f.Table) + len(f.OrgTable) + len(f.Name) + len(f.OrgName) + len(f.DefaultValue) + 48 + + data := make([]byte, 0, l) + + data = append(data, PutLengthEncodedString([]byte("def"))...) + + data = append(data, PutLengthEncodedString(f.Schema)...) + + data = append(data, PutLengthEncodedString(f.Table)...) + data = append(data, PutLengthEncodedString(f.OrgTable)...) + + data = append(data, PutLengthEncodedString(f.Name)...) + data = append(data, PutLengthEncodedString(f.OrgName)...) + + data = append(data, 0x0c) + + data = append(data, Uint16ToBytes(f.Charset)...) + data = append(data, Uint32ToBytes(f.ColumnLength)...) + data = append(data, f.Type) + data = append(data, Uint16ToBytes(f.Flag)...) + data = append(data, f.Decimal) + data = append(data, 0, 0) + + if f.DefaultValue != nil { + data = append(data, Uint64ToBytes(f.DefaultValueLength)...) + data = append(data, f.DefaultValue...) + } + + return data +} + +func (fv *FieldValue) AsUint64() uint64 { + return fv.value +} + +func (fv *FieldValue) AsInt64() int64 { + return utils.Uint64ToInt64(fv.value) +} + +func (fv *FieldValue) AsFloat64() float64 { + return utils.Uint64ToFloat64(fv.value) +} + +func (fv *FieldValue) AsString() []byte { + return fv.str +} + +func (fv *FieldValue) Value() interface{} { + switch fv.Type { + case FieldValueTypeUnsigned: + return fv.AsUint64() + case FieldValueTypeSigned: + return fv.AsInt64() + case FieldValueTypeFloat: + return fv.AsFloat64() + case FieldValueTypeString: + return fv.AsString() + default: // FieldValueTypeNull + return nil + } +} diff --git a/v2/vendor/github.com/go-mysql-org/go-mysql/mysql/gtid.go b/v2/vendor/github.com/go-mysql-org/go-mysql/mysql/gtid.go new file mode 100644 index 0000000..ae519ef --- /dev/null +++ b/v2/vendor/github.com/go-mysql-org/go-mysql/mysql/gtid.go @@ -0,0 +1,31 @@ +package mysql + +import ( + "github.com/pingcap/errors" +) + +type GTIDSet interface { + String() string + + // Encode GTID set into binary format used in binlog dump commands + Encode() []byte + + Equal(o GTIDSet) bool + + Contain(o GTIDSet) bool + + Update(GTIDStr string) error + + Clone() GTIDSet +} + +func ParseGTIDSet(flavor string, s string) (GTIDSet, error) { + switch flavor { + case MySQLFlavor: + return ParseMysqlGTIDSet(s) + case MariaDBFlavor: + return ParseMariadbGTIDSet(s) + default: + return nil, errors.Errorf("invalid flavor %s", flavor) + } +} diff --git a/v2/vendor/github.com/go-mysql-org/go-mysql/mysql/mariadb_gtid.go b/v2/vendor/github.com/go-mysql-org/go-mysql/mysql/mariadb_gtid.go new file mode 100644 index 0000000..8bfffd0 --- /dev/null +++ b/v2/vendor/github.com/go-mysql-org/go-mysql/mysql/mariadb_gtid.go @@ -0,0 +1,238 @@ +package mysql + +import ( + "bytes" + "fmt" + "sort" + "strconv" + "strings" + + "github.com/pingcap/errors" + "github.com/siddontang/go-log/log" +) + +// MariadbGTID represent mariadb gtid, [domain ID]-[server-id]-[sequence] +type MariadbGTID struct { + DomainID uint32 + ServerID uint32 + SequenceNumber uint64 +} + +// ParseMariadbGTID parses mariadb gtid, [domain ID]-[server-id]-[sequence] +func ParseMariadbGTID(str string) (*MariadbGTID, error) { + if len(str) == 0 { + return &MariadbGTID{0, 0, 0}, nil + } + + seps := strings.Split(str, "-") + + gtid := new(MariadbGTID) + + if len(seps) != 3 { + return gtid, errors.Errorf("invalid Mariadb GTID %v, must domain-server-sequence", str) + } + + domainID, err := strconv.ParseUint(seps[0], 10, 32) + if err != nil { + return gtid, errors.Errorf("invalid MariaDB GTID Domain ID (%v): %v", seps[0], err) + } + + serverID, err := strconv.ParseUint(seps[1], 10, 32) + if err != nil { + return gtid, errors.Errorf("invalid MariaDB GTID Server ID (%v): %v", seps[1], err) + } + + sequenceID, err := strconv.ParseUint(seps[2], 10, 64) + if err != nil { + return gtid, errors.Errorf("invalid MariaDB GTID Sequence number (%v): %v", seps[2], err) + } + + return &MariadbGTID{ + DomainID: uint32(domainID), + ServerID: uint32(serverID), + SequenceNumber: sequenceID}, nil +} + +func (gtid *MariadbGTID) String() string { + if gtid.DomainID == 0 && gtid.ServerID == 0 && gtid.SequenceNumber == 0 { + return "" + } + + return fmt.Sprintf("%d-%d-%d", gtid.DomainID, gtid.ServerID, gtid.SequenceNumber) +} + +// Contain return whether one mariadb gtid covers another mariadb gtid +func (gtid *MariadbGTID) Contain(other *MariadbGTID) bool { + return gtid.DomainID == other.DomainID && gtid.SequenceNumber >= other.SequenceNumber +} + +// Clone clones a mariadb gtid +func (gtid *MariadbGTID) Clone() *MariadbGTID { + o := new(MariadbGTID) + *o = *gtid + return o +} + +func (gtid *MariadbGTID) forward(newer *MariadbGTID) error { + if newer.DomainID != gtid.DomainID { + return errors.Errorf("%s is not same with doamin of %s", newer, gtid) + } + + /* + Here's a simplified example of binlog events. + Although I think one domain should have only one update at same time, we can't limit the user's usage. + we just output a warn log and let it go on + | mysqld-bin.000001 | 1453 | Gtid | 112 | 1495 | BEGIN GTID 0-112-6 | + | mysqld-bin.000001 | 1624 | Xid | 112 | 1655 | COMMIT xid=74 | + | mysqld-bin.000001 | 1655 | Gtid | 112 | 1697 | BEGIN GTID 0-112-7 | + | mysqld-bin.000001 | 1826 | Xid | 112 | 1857 | COMMIT xid=75 | + | mysqld-bin.000001 | 1857 | Gtid | 111 | 1899 | BEGIN GTID 0-111-5 | + | mysqld-bin.000001 | 1981 | Xid | 111 | 2012 | COMMIT xid=77 | + | mysqld-bin.000001 | 2012 | Gtid | 112 | 2054 | BEGIN GTID 0-112-8 | + | mysqld-bin.000001 | 2184 | Xid | 112 | 2215 | COMMIT xid=116 | + | mysqld-bin.000001 | 2215 | Gtid | 111 | 2257 | BEGIN GTID 0-111-6 | + */ + if newer.SequenceNumber <= gtid.SequenceNumber { + log.Warnf("out of order binlog appears with gtid %s vs current position gtid %s", newer, gtid) + } + + gtid.ServerID = newer.ServerID + gtid.SequenceNumber = newer.SequenceNumber + return nil +} + +// MariadbGTIDSet is a set of mariadb gtid +type MariadbGTIDSet struct { + Sets map[uint32]*MariadbGTID +} + +// ParseMariadbGTIDSet parses str into mariadb gtid sets +func ParseMariadbGTIDSet(str string) (GTIDSet, error) { + s := new(MariadbGTIDSet) + s.Sets = make(map[uint32]*MariadbGTID) + if str == "" { + return s, nil + } + err := s.Update(str) + if err != nil { + return nil, err + } + return s, nil +} + +// AddSet adds mariadb gtid into mariadb gtid set +func (s *MariadbGTIDSet) AddSet(gtid *MariadbGTID) error { + if gtid == nil { + return nil + } + + o, ok := s.Sets[gtid.DomainID] + if ok { + err := o.forward(gtid) + if err != nil { + return errors.Trace(err) + } + } else { + s.Sets[gtid.DomainID] = gtid + } + + return nil +} + +// Update updates mariadb gtid set +func (s *MariadbGTIDSet) Update(GTIDStr string) error { + sp := strings.Split(GTIDStr, ",") + //todo, handle redundant same uuid + for i := 0; i < len(sp); i++ { + gtid, err := ParseMariadbGTID(sp[i]) + if err != nil { + return errors.Trace(err) + } + err = s.AddSet(gtid) + if err != nil { + return errors.Trace(err) + } + } + return nil +} + +func (s *MariadbGTIDSet) String() string { + sets := make([]string, 0, len(s.Sets)) + for _, set := range s.Sets { + sets = append(sets, set.String()) + } + sort.Strings(sets) + + return strings.Join(sets, ",") +} + +// Encode encodes mariadb gtid set +func (s *MariadbGTIDSet) Encode() []byte { + var buf bytes.Buffer + sep := "" + for _, gtid := range s.Sets { + buf.WriteString(sep) + buf.WriteString(gtid.String()) + sep = "," + } + + return buf.Bytes() +} + +// Clone clones a mariadb gtid set +func (s *MariadbGTIDSet) Clone() GTIDSet { + clone := &MariadbGTIDSet{ + Sets: make(map[uint32]*MariadbGTID), + } + for domainID, gtid := range s.Sets { + clone.Sets[domainID] = gtid.Clone() + } + + return clone +} + +// Equal returns true if two mariadb gtid set is same, otherwise return false +func (s *MariadbGTIDSet) Equal(o GTIDSet) bool { + other, ok := o.(*MariadbGTIDSet) + if !ok { + return false + } + + if len(other.Sets) != len(s.Sets) { + return false + } + + for domainID, gtid := range other.Sets { + o, ok := s.Sets[domainID] + if !ok { + return false + } + + if *gtid != *o { + return false + } + } + + return true +} + +// Contain return whether one mariadb gtid set covers another mariadb gtid set +func (s *MariadbGTIDSet) Contain(o GTIDSet) bool { + other, ok := o.(*MariadbGTIDSet) + if !ok { + return false + } + + for doaminID, gtid := range other.Sets { + o, ok := s.Sets[doaminID] + if !ok { + return false + } + + if !o.Contain(gtid) { + return false + } + } + + return true +} diff --git a/v2/vendor/github.com/go-mysql-org/go-mysql/mysql/mysql_gtid.go b/v2/vendor/github.com/go-mysql-org/go-mysql/mysql/mysql_gtid.go new file mode 100644 index 0000000..47eae62 --- /dev/null +++ b/v2/vendor/github.com/go-mysql-org/go-mysql/mysql/mysql_gtid.go @@ -0,0 +1,598 @@ +package mysql + +import ( + "bytes" + "encoding/binary" + "fmt" + "io" + "math" + "sort" + "strconv" + "strings" + + "github.com/google/uuid" + "github.com/pingcap/errors" + "github.com/siddontang/go/hack" +) + +// Like MySQL GTID Interval struct, [start, stop), left closed and right open +// See MySQL rpl_gtid.h +type Interval struct { + // The first GID of this interval. + Start int64 + // The first GID after this interval. + Stop int64 +} + +// Interval is [start, stop), but the GTID string's format is [n] or [n1-n2], closed interval +func parseInterval(str string) (i Interval, err error) { + p := strings.Split(str, "-") + switch len(p) { + case 1: + i.Start, err = strconv.ParseInt(p[0], 10, 64) + i.Stop = i.Start + 1 + case 2: + i.Start, err = strconv.ParseInt(p[0], 10, 64) + if err == nil { + i.Stop, err = strconv.ParseInt(p[1], 10, 64) + i.Stop++ + } + default: + err = errors.Errorf("invalid interval format, must n[-n]") + } + + if err != nil { + return + } + + if i.Stop <= i.Start { + err = errors.Errorf("invalid interval format, must n[-n] and the end must >= start") + } + + return +} + +func (i Interval) String() string { + if i.Stop == i.Start+1 { + return fmt.Sprintf("%d", i.Start) + } else { + return fmt.Sprintf("%d-%d", i.Start, i.Stop-1) + } +} + +type IntervalSlice []Interval + +func (s IntervalSlice) Len() int { + return len(s) +} + +func (s IntervalSlice) Less(i, j int) bool { + if s[i].Start < s[j].Start { + return true + } else if s[i].Start > s[j].Start { + return false + } else { + return s[i].Stop < s[j].Stop + } +} + +func (s IntervalSlice) Swap(i, j int) { + s[i], s[j] = s[j], s[i] +} + +func (s IntervalSlice) Sort() { + sort.Sort(s) +} + +func (s IntervalSlice) Normalize() IntervalSlice { + var n IntervalSlice + if len(s) == 0 { + return n + } + + s.Sort() + + n = append(n, s[0]) + + for i := 1; i < len(s); i++ { + last := n[len(n)-1] + if s[i].Start > last.Stop { + n = append(n, s[i]) + continue + } else { + stop := s[i].Stop + if last.Stop > stop { + stop = last.Stop + } + n[len(n)-1] = Interval{last.Start, stop} + } + } + + return n +} + +func min(a, b int64) int64 { + if a < b { + return a + } + return b +} + +func max(a, b int64) int64 { + if a > b { + return a + } + return b +} + +func (s *IntervalSlice) InsertInterval(interval Interval) { + var ( + count int + i int + ) + + *s = append(*s, interval) + total := len(*s) + for i = total - 1; i > 0; i-- { + if (*s)[i].Stop < (*s)[i-1].Start { + (*s)[i], (*s)[i-1] = (*s)[i-1], (*s)[i] + } else if (*s)[i].Start > (*s)[i-1].Stop { + break + } else { + (*s)[i-1].Start = min((*s)[i-1].Start, (*s)[i].Start) + (*s)[i-1].Stop = max((*s)[i-1].Stop, (*s)[i].Stop) + count++ + } + } + if count > 0 { + i++ + if i+count < total { + copy((*s)[i:], (*s)[i+count:]) + } + *s = (*s)[:total-count] + } +} + +// Contain returns true if sub in s +func (s IntervalSlice) Contain(sub IntervalSlice) bool { + j := 0 + for i := 0; i < len(sub); i++ { + for ; j < len(s); j++ { + if sub[i].Start > s[j].Stop { + continue + } else { + break + } + } + if j == len(s) { + return false + } + + if sub[i].Start < s[j].Start || sub[i].Stop > s[j].Stop { + return false + } + } + + return true +} + +func (s IntervalSlice) Equal(o IntervalSlice) bool { + if len(s) != len(o) { + return false + } + + for i := 0; i < len(s); i++ { + if s[i].Start != o[i].Start || s[i].Stop != o[i].Stop { + return false + } + } + + return true +} + +func (s IntervalSlice) Compare(o IntervalSlice) int { + if s.Equal(o) { + return 0 + } else if s.Contain(o) { + return 1 + } else { + return -1 + } +} + +// Refer http://dev.mysql.com/doc/refman/5.6/en/replication-gtids-concepts.html +type UUIDSet struct { + SID uuid.UUID + + Intervals IntervalSlice +} + +func ParseUUIDSet(str string) (*UUIDSet, error) { + str = strings.TrimSpace(str) + sep := strings.Split(str, ":") + if len(sep) < 2 { + return nil, errors.Errorf("invalid GTID format, must UUID:interval[:interval]") + } + + var err error + s := new(UUIDSet) + if s.SID, err = uuid.Parse(sep[0]); err != nil { + return nil, errors.Trace(err) + } + + // Handle interval + for i := 1; i < len(sep); i++ { + if in, err := parseInterval(sep[i]); err != nil { + return nil, errors.Trace(err) + } else { + s.Intervals = append(s.Intervals, in) + } + } + + s.Intervals = s.Intervals.Normalize() + + return s, nil +} + +func NewUUIDSet(sid uuid.UUID, in ...Interval) *UUIDSet { + s := new(UUIDSet) + s.SID = sid + + s.Intervals = in + s.Intervals = s.Intervals.Normalize() + + return s +} + +func (s *UUIDSet) Contain(sub *UUIDSet) bool { + if s.SID != sub.SID { + return false + } + + return s.Intervals.Contain(sub.Intervals) +} + +func (s *UUIDSet) Bytes() []byte { + var buf bytes.Buffer + + buf.WriteString(s.SID.String()) + + for _, i := range s.Intervals { + buf.WriteString(":") + buf.WriteString(i.String()) + } + + return buf.Bytes() +} + +func (s *UUIDSet) AddInterval(in IntervalSlice) { + s.Intervals = append(s.Intervals, in...) + s.Intervals = s.Intervals.Normalize() +} + +func (s *UUIDSet) MinusInterval(in IntervalSlice) { + var n IntervalSlice + in = in.Normalize() + + i, j := 0, 0 + var minuend Interval + var subtrahend Interval + for i < len(s.Intervals) { + if minuend.Stop != s.Intervals[i].Stop { // `i` changed? + minuend = s.Intervals[i] + } + if j < len(in) { + subtrahend = in[j] + } else { + subtrahend = Interval{math.MaxInt64, math.MaxInt64} + } + + if minuend.Stop <= subtrahend.Start { + // no overlapping + n = append(n, minuend) + i++ + } else if minuend.Start >= subtrahend.Stop { + // no overlapping + j++ + } else { + if minuend.Start < subtrahend.Start && minuend.Stop <= subtrahend.Stop { + n = append(n, Interval{minuend.Start, subtrahend.Start}) + i++ + } else if minuend.Start >= subtrahend.Start && minuend.Stop > subtrahend.Stop { + minuend = Interval{subtrahend.Stop, minuend.Stop} + j++ + } else if minuend.Start >= subtrahend.Start && minuend.Stop <= subtrahend.Stop { + // minuend is completely removed + i++ + } else if minuend.Start < subtrahend.Start && minuend.Stop > subtrahend.Stop { + n = append(n, Interval{minuend.Start, subtrahend.Start}) + minuend = Interval{subtrahend.Stop, minuend.Stop} + j++ + } else { + panic("should never be here") + } + } + } + + s.Intervals = n.Normalize() +} + +func (s *UUIDSet) String() string { + return hack.String(s.Bytes()) +} + +func (s *UUIDSet) encode(w io.Writer) { + b, _ := s.SID.MarshalBinary() + + _, _ = w.Write(b) + n := int64(len(s.Intervals)) + + _ = binary.Write(w, binary.LittleEndian, n) + + for _, i := range s.Intervals { + _ = binary.Write(w, binary.LittleEndian, i.Start) + _ = binary.Write(w, binary.LittleEndian, i.Stop) + } +} + +func (s *UUIDSet) Encode() []byte { + var buf bytes.Buffer + + s.encode(&buf) + + return buf.Bytes() +} + +func (s *UUIDSet) decode(data []byte) (int, error) { + if len(data) < 24 { + return 0, errors.Errorf("invalid uuid set buffer, less 24") + } + + pos := 0 + var err error + if s.SID, err = uuid.FromBytes(data[0:16]); err != nil { + return 0, err + } + pos += 16 + + n := int64(binary.LittleEndian.Uint64(data[pos : pos+8])) + pos += 8 + if len(data) < int(16*n)+pos { + return 0, errors.Errorf("invalid uuid set buffer, must %d, but %d", pos+int(16*n), len(data)) + } + + s.Intervals = make([]Interval, 0, n) + + var in Interval + for i := int64(0); i < n; i++ { + in.Start = int64(binary.LittleEndian.Uint64(data[pos : pos+8])) + pos += 8 + in.Stop = int64(binary.LittleEndian.Uint64(data[pos : pos+8])) + pos += 8 + s.Intervals = append(s.Intervals, in) + } + + return pos, nil +} + +func (s *UUIDSet) Decode(data []byte) error { + n, err := s.decode(data) + if n != len(data) { + return errors.Errorf("invalid uuid set buffer, must %d, but %d", n, len(data)) + } + return err +} + +func (s *UUIDSet) Clone() *UUIDSet { + clone := new(UUIDSet) + clone.SID = s.SID + clone.Intervals = make([]Interval, len(s.Intervals)) + copy(clone.Intervals, s.Intervals) + return clone +} + +type MysqlGTIDSet struct { + Sets map[string]*UUIDSet +} + +var _ GTIDSet = &MysqlGTIDSet{} + +func ParseMysqlGTIDSet(str string) (GTIDSet, error) { + s := new(MysqlGTIDSet) + s.Sets = make(map[string]*UUIDSet) + if str == "" { + return s, nil + } + + sp := strings.Split(str, ",") + + //todo, handle redundant same uuid + for i := 0; i < len(sp); i++ { + if set, err := ParseUUIDSet(sp[i]); err != nil { + return nil, errors.Trace(err) + } else { + s.AddSet(set) + } + } + return s, nil +} + +func DecodeMysqlGTIDSet(data []byte) (*MysqlGTIDSet, error) { + s := new(MysqlGTIDSet) + + if len(data) < 8 { + return nil, errors.Errorf("invalid gtid set buffer, less 4") + } + + n := int(binary.LittleEndian.Uint64(data)) + s.Sets = make(map[string]*UUIDSet, n) + + pos := 8 + + for i := 0; i < n; i++ { + set := new(UUIDSet) + if n, err := set.decode(data[pos:]); err != nil { + return nil, errors.Trace(err) + } else { + pos += n + + s.AddSet(set) + } + } + return s, nil +} + +func (s *MysqlGTIDSet) AddSet(set *UUIDSet) { + if set == nil { + return + } + sid := set.SID.String() + o, ok := s.Sets[sid] + if ok { + o.AddInterval(set.Intervals) + } else { + s.Sets[sid] = set + } +} + +func (s *MysqlGTIDSet) MinusSet(set *UUIDSet) { + if set == nil { + return + } + sid := set.SID.String() + uuidSet, ok := s.Sets[sid] + if ok { + uuidSet.MinusInterval(set.Intervals) + if uuidSet.Intervals == nil { + delete(s.Sets, sid) + } + } +} + +func (s *MysqlGTIDSet) Update(GTIDStr string) error { + gtidSet, err := ParseMysqlGTIDSet(GTIDStr) + if err != nil { + return err + } + for _, uuidSet := range gtidSet.(*MysqlGTIDSet).Sets { + s.AddSet(uuidSet) + } + return nil +} + +func (s *MysqlGTIDSet) AddGTID(uuid uuid.UUID, gno int64) { + sid := uuid.String() + o, ok := s.Sets[sid] + if ok { + o.Intervals.InsertInterval(Interval{gno, gno + 1}) + } else { + s.Sets[sid] = &UUIDSet{uuid, IntervalSlice{Interval{gno, gno + 1}}} + } +} + +func (s *MysqlGTIDSet) Add(addend MysqlGTIDSet) error { + for _, uuidSet := range addend.Sets { + s.AddSet(uuidSet) + } + return nil +} + +func (s *MysqlGTIDSet) Minus(subtrahend MysqlGTIDSet) error { + for _, uuidSet := range subtrahend.Sets { + s.MinusSet(uuidSet) + } + return nil +} + +func (s *MysqlGTIDSet) Contain(o GTIDSet) bool { + sub, ok := o.(*MysqlGTIDSet) + if !ok { + return false + } + + for key, set := range sub.Sets { + o, ok := s.Sets[key] + if !ok { + return false + } + + if !o.Contain(set) { + return false + } + } + + return true +} + +func (s *MysqlGTIDSet) Equal(o GTIDSet) bool { + sub, ok := o.(*MysqlGTIDSet) + if !ok { + return false + } + + if len(sub.Sets) != len(s.Sets) { + return false + } + + for key, set := range sub.Sets { + o, ok := s.Sets[key] + if !ok { + return false + } + + if !o.Intervals.Equal(set.Intervals) { + return false + } + } + + return true +} + +func (s *MysqlGTIDSet) String() string { + // there is only one element in gtid set + if len(s.Sets) == 1 { + for _, set := range s.Sets { + return set.String() + } + } + + // sort multi set + var buf bytes.Buffer + sets := make([]string, 0, len(s.Sets)) + for _, set := range s.Sets { + sets = append(sets, set.String()) + } + sort.Strings(sets) + + sep := "" + for _, set := range sets { + buf.WriteString(sep) + buf.WriteString(set) + sep = "," + } + + return hack.String(buf.Bytes()) +} + +func (s *MysqlGTIDSet) Encode() []byte { + var buf bytes.Buffer + + _ = binary.Write(&buf, binary.LittleEndian, uint64(len(s.Sets))) + + for i := range s.Sets { + s.Sets[i].encode(&buf) + } + + return buf.Bytes() +} + +func (gtid *MysqlGTIDSet) Clone() GTIDSet { + clone := &MysqlGTIDSet{ + Sets: make(map[string]*UUIDSet), + } + for sid, uuidSet := range gtid.Sets { + clone.Sets[sid] = uuidSet.Clone() + } + + return clone +} diff --git a/v2/vendor/github.com/go-mysql-org/go-mysql/mysql/parse_binary.go b/v2/vendor/github.com/go-mysql-org/go-mysql/mysql/parse_binary.go new file mode 100644 index 0000000..03b35ca --- /dev/null +++ b/v2/vendor/github.com/go-mysql-org/go-mysql/mysql/parse_binary.go @@ -0,0 +1,53 @@ +package mysql + +import ( + "encoding/binary" + "math" +) + +func ParseBinaryInt8(data []byte) int8 { + return int8(data[0]) +} +func ParseBinaryUint8(data []byte) uint8 { + return data[0] +} + +func ParseBinaryInt16(data []byte) int16 { + return int16(binary.LittleEndian.Uint16(data)) +} +func ParseBinaryUint16(data []byte) uint16 { + return binary.LittleEndian.Uint16(data) +} + +func ParseBinaryInt24(data []byte) int32 { + u32 := ParseBinaryUint24(data) + if u32&0x00800000 != 0 { + u32 |= 0xFF000000 + } + return int32(u32) +} +func ParseBinaryUint24(data []byte) uint32 { + return uint32(data[0]) | uint32(data[1])<<8 | uint32(data[2])<<16 +} + +func ParseBinaryInt32(data []byte) int32 { + return int32(binary.LittleEndian.Uint32(data)) +} +func ParseBinaryUint32(data []byte) uint32 { + return binary.LittleEndian.Uint32(data) +} + +func ParseBinaryInt64(data []byte) int64 { + return int64(binary.LittleEndian.Uint64(data)) +} +func ParseBinaryUint64(data []byte) uint64 { + return binary.LittleEndian.Uint64(data) +} + +func ParseBinaryFloat32(data []byte) float32 { + return math.Float32frombits(binary.LittleEndian.Uint32(data)) +} + +func ParseBinaryFloat64(data []byte) float64 { + return math.Float64frombits(binary.LittleEndian.Uint64(data)) +} diff --git a/v2/vendor/github.com/go-mysql-org/go-mysql/mysql/position.go b/v2/vendor/github.com/go-mysql-org/go-mysql/mysql/position.go new file mode 100644 index 0000000..c592d63 --- /dev/null +++ b/v2/vendor/github.com/go-mysql-org/go-mysql/mysql/position.go @@ -0,0 +1,80 @@ +package mysql + +import ( + "fmt" + "strconv" + "strings" +) + +// For binlog filename + position based replication +type Position struct { + Name string + Pos uint32 +} + +func (p Position) Compare(o Position) int { + // First compare binlog name + nameCmp := CompareBinlogFileName(p.Name, o.Name) + if nameCmp != 0 { + return nameCmp + } + // Same binlog file, compare position + if p.Pos > o.Pos { + return 1 + } else if p.Pos < o.Pos { + return -1 + } else { + return 0 + } +} + +func (p Position) String() string { + return fmt.Sprintf("(%s, %d)", p.Name, p.Pos) +} + +func CompareBinlogFileName(a, b string) int { + // sometimes it's convenient to construct a `Position` literal with no `Name` + if a == "" && b == "" { + return 0 + } else if a == "" { + return -1 + } else if b == "" { + return 1 + } + + splitBinlogName := func(n string) (string, int) { + // mysqld appends a numeric extension to the binary log base name to generate binary log file names + // ... + // If you supply an extension in the log name (for example, --log-bin=base_name.extension), + // the extension is silently removed and ignored. + // ref: https://dev.mysql.com/doc/refman/8.0/en/binary-log.html + i := strings.LastIndexByte(n, '.') + if i == -1 { + // try keeping backward compatibility + return n, 0 + } + + seq, err := strconv.Atoi(n[i+1:]) + if err != nil { + panic(fmt.Sprintf("binlog file %s doesn't contain numeric extension", err)) + } + return n[:i], seq + } + + aBase, aSeq := splitBinlogName(a) + bBase, bSeq := splitBinlogName(b) + + if aBase > bBase { + return 1 + } else if aBase < bBase { + return -1 + } + + if aSeq > bSeq { + return 1 + } else if aSeq < bSeq { + return -1 + } else { + return 0 + } +} diff --git a/v2/vendor/github.com/go-mysql-org/go-mysql/mysql/result.go b/v2/vendor/github.com/go-mysql-org/go-mysql/mysql/result.go new file mode 100644 index 0000000..a4dbb0e --- /dev/null +++ b/v2/vendor/github.com/go-mysql-org/go-mysql/mysql/result.go @@ -0,0 +1,22 @@ +package mysql + +type Result struct { + Status uint16 + Warnings uint16 + + InsertId uint64 + AffectedRows uint64 + + *Resultset +} + +type Executer interface { + Execute(query string, args ...interface{}) (*Result, error) +} + +func (r *Result) Close() { + if r.Resultset != nil { + r.Resultset.returnToPool() + r.Resultset = nil + } +} diff --git a/v2/vendor/github.com/go-mysql-org/go-mysql/mysql/resultset.go b/v2/vendor/github.com/go-mysql-org/go-mysql/mysql/resultset.go new file mode 100644 index 0000000..d90796b --- /dev/null +++ b/v2/vendor/github.com/go-mysql-org/go-mysql/mysql/resultset.go @@ -0,0 +1,287 @@ +package mysql + +import ( + "fmt" + "strconv" + "sync" + + "github.com/pingcap/errors" + "github.com/siddontang/go/hack" +) + +type StreamingType int + +const ( + // StreamingNone means there is no streaming + StreamingNone StreamingType = iota + // StreamingSelect is used with select queries for which each result is + // directly returned to the client + StreamingSelect + // StreamingMultiple is used when multiple queries are given at once + // usually in combination with SERVER_MORE_RESULTS_EXISTS flag set + StreamingMultiple +) + +type Resultset struct { + Fields []*Field + FieldNames map[string]int + Values [][]FieldValue + + RawPkg []byte + + RowDatas []RowData + + Streaming StreamingType + StreamingDone bool +} + +var ( + resultsetPool = sync.Pool{ + New: func() interface{} { + return &Resultset{} + }, + } +) + +func NewResultset(fieldsCount int) *Resultset { + r := resultsetPool.Get().(*Resultset) + r.Reset(fieldsCount) + return r +} + +func (r *Resultset) returnToPool() { + resultsetPool.Put(r) +} + +func (r *Resultset) Reset(fieldsCount int) { + r.RawPkg = r.RawPkg[:0] + + r.Fields = r.Fields[:0] + r.Values = r.Values[:0] + r.RowDatas = r.RowDatas[:0] + + if r.FieldNames != nil { + for k := range r.FieldNames { + delete(r.FieldNames, k) + } + } else { + r.FieldNames = make(map[string]int) + } + + if fieldsCount == 0 { + return + } + + if cap(r.Fields) < fieldsCount { + r.Fields = make([]*Field, fieldsCount) + } else { + r.Fields = r.Fields[:fieldsCount] + } +} + +func (r *Resultset) RowNumber() int { + if r == nil { + return 0 + } + return len(r.Values) +} + +func (r *Resultset) ColumnNumber() int { + return len(r.Fields) +} + +func (r *Resultset) GetValue(row, column int) (interface{}, error) { + if row >= len(r.Values) || row < 0 { + return nil, errors.Errorf("invalid row index %d", row) + } + + if column >= len(r.Fields) || column < 0 { + return nil, errors.Errorf("invalid column index %d", column) + } + + return r.Values[row][column].Value(), nil +} + +func (r *Resultset) NameIndex(name string) (int, error) { + if column, ok := r.FieldNames[name]; ok { + return column, nil + } else { + return 0, errors.Errorf("invalid field name %s", name) + } +} + +func (r *Resultset) GetValueByName(row int, name string) (interface{}, error) { + if column, err := r.NameIndex(name); err != nil { + return nil, errors.Trace(err) + } else { + return r.GetValue(row, column) + } +} + +func (r *Resultset) IsNull(row, column int) (bool, error) { + d, err := r.GetValue(row, column) + if err != nil { + return false, err + } + + return d == nil, nil +} + +func (r *Resultset) IsNullByName(row int, name string) (bool, error) { + if column, err := r.NameIndex(name); err != nil { + return false, err + } else { + return r.IsNull(row, column) + } +} + +func (r *Resultset) GetUint(row, column int) (uint64, error) { + d, err := r.GetValue(row, column) + if err != nil { + return 0, err + } + + switch v := d.(type) { + case int: + return uint64(v), nil + case int8: + return uint64(v), nil + case int16: + return uint64(v), nil + case int32: + return uint64(v), nil + case int64: + return uint64(v), nil + case uint: + return uint64(v), nil + case uint8: + return uint64(v), nil + case uint16: + return uint64(v), nil + case uint32: + return uint64(v), nil + case uint64: + return v, nil + case float32: + return uint64(v), nil + case float64: + return uint64(v), nil + case string: + return strconv.ParseUint(v, 10, 64) + case []byte: + return strconv.ParseUint(string(v), 10, 64) + case nil: + return 0, nil + default: + return 0, errors.Errorf("data type is %T", v) + } +} + +func (r *Resultset) GetUintByName(row int, name string) (uint64, error) { + if column, err := r.NameIndex(name); err != nil { + return 0, err + } else { + return r.GetUint(row, column) + } +} + +func (r *Resultset) GetInt(row, column int) (int64, error) { + v, err := r.GetUint(row, column) + if err != nil { + return 0, err + } + + return int64(v), nil +} + +func (r *Resultset) GetIntByName(row int, name string) (int64, error) { + v, err := r.GetUintByName(row, name) + if err != nil { + return 0, err + } + + return int64(v), nil +} + +func (r *Resultset) GetFloat(row, column int) (float64, error) { + d, err := r.GetValue(row, column) + if err != nil { + return 0, err + } + + switch v := d.(type) { + case int: + return float64(v), nil + case int8: + return float64(v), nil + case int16: + return float64(v), nil + case int32: + return float64(v), nil + case int64: + return float64(v), nil + case uint: + return float64(v), nil + case uint8: + return float64(v), nil + case uint16: + return float64(v), nil + case uint32: + return float64(v), nil + case uint64: + return float64(v), nil + case float32: + return float64(v), nil + case float64: + return v, nil + case string: + return strconv.ParseFloat(v, 64) + case []byte: + return strconv.ParseFloat(string(v), 64) + case nil: + return 0, nil + default: + return 0, errors.Errorf("data type is %T", v) + } +} + +func (r *Resultset) GetFloatByName(row int, name string) (float64, error) { + if column, err := r.NameIndex(name); err != nil { + return 0, err + } else { + return r.GetFloat(row, column) + } +} + +func (r *Resultset) GetString(row, column int) (string, error) { + d, err := r.GetValue(row, column) + if err != nil { + return "", err + } + + switch v := d.(type) { + case string: + return v, nil + case []byte: + return hack.String(v), nil + case int, int8, int16, int32, int64, + uint, uint8, uint16, uint32, uint64: + return fmt.Sprintf("%d", v), nil + case float32: + return strconv.FormatFloat(float64(v), 'f', -1, 64), nil + case float64: + return strconv.FormatFloat(v, 'f', -1, 64), nil + case nil: + return "", nil + default: + return "", errors.Errorf("data type is %T", v) + } +} + +func (r *Resultset) GetStringByName(row int, name string) (string, error) { + if column, err := r.NameIndex(name); err != nil { + return "", err + } else { + return r.GetString(row, column) + } +} diff --git a/v2/vendor/github.com/go-mysql-org/go-mysql/mysql/resultset_helper.go b/v2/vendor/github.com/go-mysql-org/go-mysql/mysql/resultset_helper.go new file mode 100644 index 0000000..8c63206 --- /dev/null +++ b/v2/vendor/github.com/go-mysql-org/go-mysql/mysql/resultset_helper.go @@ -0,0 +1,254 @@ +package mysql + +import ( + "math" + "strconv" + + "github.com/pingcap/errors" + "github.com/siddontang/go/hack" +) + +func FormatTextValue(value interface{}) ([]byte, error) { + switch v := value.(type) { + case int8: + return strconv.AppendInt(nil, int64(v), 10), nil + case int16: + return strconv.AppendInt(nil, int64(v), 10), nil + case int32: + return strconv.AppendInt(nil, int64(v), 10), nil + case int64: + return strconv.AppendInt(nil, v, 10), nil + case int: + return strconv.AppendInt(nil, int64(v), 10), nil + case uint8: + return strconv.AppendUint(nil, uint64(v), 10), nil + case uint16: + return strconv.AppendUint(nil, uint64(v), 10), nil + case uint32: + return strconv.AppendUint(nil, uint64(v), 10), nil + case uint64: + return strconv.AppendUint(nil, v, 10), nil + case uint: + return strconv.AppendUint(nil, uint64(v), 10), nil + case float32: + return strconv.AppendFloat(nil, float64(v), 'f', -1, 64), nil + case float64: + return strconv.AppendFloat(nil, v, 'f', -1, 64), nil + case []byte: + return v, nil + case string: + return hack.Slice(v), nil + case nil: + return nil, nil + default: + return nil, errors.Errorf("invalid type %T", value) + } +} + +func formatBinaryValue(value interface{}) ([]byte, error) { + switch v := value.(type) { + case int8: + return Uint64ToBytes(uint64(v)), nil + case int16: + return Uint64ToBytes(uint64(v)), nil + case int32: + return Uint64ToBytes(uint64(v)), nil + case int64: + return Uint64ToBytes(uint64(v)), nil + case int: + return Uint64ToBytes(uint64(v)), nil + case uint8: + return Uint64ToBytes(uint64(v)), nil + case uint16: + return Uint64ToBytes(uint64(v)), nil + case uint32: + return Uint64ToBytes(uint64(v)), nil + case uint64: + return Uint64ToBytes(v), nil + case uint: + return Uint64ToBytes(uint64(v)), nil + case float32: + return Uint64ToBytes(math.Float64bits(float64(v))), nil + case float64: + return Uint64ToBytes(math.Float64bits(v)), nil + case []byte: + return v, nil + case string: + return hack.Slice(v), nil + default: + return nil, errors.Errorf("invalid type %T", value) + } +} + +func fieldType(value interface{}) (typ uint8, err error) { + switch value.(type) { + case int8, int16, int32, int64, int: + typ = MYSQL_TYPE_LONGLONG + case uint8, uint16, uint32, uint64, uint: + typ = MYSQL_TYPE_LONGLONG + case float32, float64: + typ = MYSQL_TYPE_DOUBLE + case string, []byte: + typ = MYSQL_TYPE_VAR_STRING + case nil: + typ = MYSQL_TYPE_NULL + default: + err = errors.Errorf("unsupport type %T for resultset", value) + } + return +} + +func formatField(field *Field, value interface{}) error { + switch value.(type) { + case int8, int16, int32, int64, int: + field.Charset = 63 + field.Flag = BINARY_FLAG | NOT_NULL_FLAG + case uint8, uint16, uint32, uint64, uint: + field.Charset = 63 + field.Flag = BINARY_FLAG | NOT_NULL_FLAG | UNSIGNED_FLAG + case float32, float64: + field.Charset = 63 + field.Flag = BINARY_FLAG | NOT_NULL_FLAG + case string, []byte: + field.Charset = 33 + case nil: + field.Charset = 33 + default: + return errors.Errorf("unsupport type %T for resultset", value) + } + return nil +} + +func BuildSimpleTextResultset(names []string, values [][]interface{}) (*Resultset, error) { + r := new(Resultset) + + r.Fields = make([]*Field, len(names)) + + var b []byte + + if len(values) == 0 { + for i, name := range names { + r.Fields[i] = &Field{Name: hack.Slice(name), Charset: 33, Type: MYSQL_TYPE_NULL} + } + return r, nil + } + + for i, vs := range values { + if len(vs) != len(r.Fields) { + return nil, errors.Errorf("row %d has %d column not equal %d", i, len(vs), len(r.Fields)) + } + + var row []byte + for j, value := range vs { + typ, err := fieldType(value) + if err != nil { + return nil, errors.Trace(err) + } + if r.Fields[j] == nil { + r.Fields[j] = &Field{Name: hack.Slice(names[j]), Type: typ} + err = formatField(r.Fields[j], value) + if err != nil { + return nil, errors.Trace(err) + } + } else if typ != r.Fields[j].Type { + // we got another type in the same column. in general, we treat it as an error, except + // the case, when old value was null, and the new one isn't null, so we can update + // type info for fields. + oldIsNull, newIsNull := r.Fields[j].Type == MYSQL_TYPE_NULL, typ == MYSQL_TYPE_NULL + if oldIsNull && !newIsNull { // old is null, new isn't, update type info. + r.Fields[j].Type = typ + err = formatField(r.Fields[j], value) + if err != nil { + return nil, errors.Trace(err) + } + } else if !oldIsNull && !newIsNull { // different non-null types, that's an error. + return nil, errors.Errorf("row types aren't consistent") + } + } + b, err = FormatTextValue(value) + + if err != nil { + return nil, errors.Trace(err) + } + + if b == nil { + // NULL value is encoded as 0xfb here (without additional info about length) + row = append(row, 0xfb) + } else { + row = append(row, PutLengthEncodedString(b)...) + } + } + + r.RowDatas = append(r.RowDatas, row) + } + + return r, nil +} + +func BuildSimpleBinaryResultset(names []string, values [][]interface{}) (*Resultset, error) { + r := new(Resultset) + + r.Fields = make([]*Field, len(names)) + + var b []byte + + bitmapLen := (len(names) + 7 + 2) >> 3 + + for i, vs := range values { + if len(vs) != len(r.Fields) { + return nil, errors.Errorf("row %d has %d column not equal %d", i, len(vs), len(r.Fields)) + } + + var row []byte + nullBitmap := make([]byte, bitmapLen) + + row = append(row, 0) + row = append(row, nullBitmap...) + + for j, value := range vs { + typ, err := fieldType(value) + if err != nil { + return nil, errors.Trace(err) + } + if i == 0 { + field := &Field{Type: typ} + r.Fields[j] = field + field.Name = hack.Slice(names[j]) + + if err = formatField(field, value); err != nil { + return nil, errors.Trace(err) + } + } + if value == nil { + nullBitmap[(i+2)/8] |= 1 << (uint(i+2) % 8) + continue + } + + b, err = formatBinaryValue(value) + + if err != nil { + return nil, errors.Trace(err) + } + + if r.Fields[j].Type == MYSQL_TYPE_VAR_STRING { + row = append(row, PutLengthEncodedString(b)...) + } else { + row = append(row, b...) + } + } + + copy(row[1:], nullBitmap) + + r.RowDatas = append(r.RowDatas, row) + } + + return r, nil +} + +func BuildSimpleResultset(names []string, values [][]interface{}, binary bool) (*Resultset, error) { + if binary { + return BuildSimpleBinaryResultset(names, values) + } else { + return BuildSimpleTextResultset(names, values) + } +} diff --git a/v2/vendor/github.com/go-mysql-org/go-mysql/mysql/rowdata.go b/v2/vendor/github.com/go-mysql-org/go-mysql/mysql/rowdata.go new file mode 100644 index 0000000..d55178f --- /dev/null +++ b/v2/vendor/github.com/go-mysql-org/go-mysql/mysql/rowdata.go @@ -0,0 +1,258 @@ +package mysql + +import ( + "strconv" + + "github.com/go-mysql-org/go-mysql/utils" + "github.com/pingcap/errors" +) + +type RowData []byte + +func (p RowData) Parse(f []*Field, binary bool, dst []FieldValue) ([]FieldValue, error) { + if binary { + return p.ParseBinary(f, dst) + } else { + return p.ParseText(f, dst) + } +} + +func (p RowData) ParseText(f []*Field, dst []FieldValue) ([]FieldValue, error) { + for len(dst) < len(f) { + dst = append(dst, FieldValue{}) + } + data := dst[:len(f)] + + var err error + var v []byte + var isNull bool + var pos, n int + + for i := range f { + v, isNull, n, err = LengthEncodedString(p[pos:]) + if err != nil { + return nil, errors.Trace(err) + } + + pos += n + + if isNull { + data[i].Type = FieldValueTypeNull + } else { + isUnsigned := f[i].Flag&UNSIGNED_FLAG != 0 + + switch f[i].Type { + case MYSQL_TYPE_TINY, MYSQL_TYPE_SHORT, MYSQL_TYPE_INT24, + MYSQL_TYPE_LONGLONG, MYSQL_TYPE_LONG, MYSQL_TYPE_YEAR: + if isUnsigned { + var val uint64 + data[i].Type = FieldValueTypeUnsigned + val, err = strconv.ParseUint(utils.ByteSliceToString(v), 10, 64) + data[i].value = val + } else { + var val int64 + data[i].Type = FieldValueTypeSigned + val, err = strconv.ParseInt(utils.ByteSliceToString(v), 10, 64) + data[i].value = utils.Int64ToUint64(val) + } + case MYSQL_TYPE_FLOAT, MYSQL_TYPE_DOUBLE: + var val float64 + data[i].Type = FieldValueTypeFloat + val, err = strconv.ParseFloat(utils.ByteSliceToString(v), 64) + data[i].value = utils.Float64ToUint64(val) + default: + data[i].Type = FieldValueTypeString + data[i].str = append(data[i].str[:0], v...) + } + + if err != nil { + return nil, errors.Trace(err) + } + } + } + + return data, nil +} + +// ParseBinary parses the binary format of data +// see https://dev.mysql.com/doc/internals/en/binary-protocol-value.html +func (p RowData) ParseBinary(f []*Field, dst []FieldValue) ([]FieldValue, error) { + for len(dst) < len(f) { + dst = append(dst, FieldValue{}) + } + data := dst[:len(f)] + + if p[0] != OK_HEADER { + return nil, ErrMalformPacket + } + + pos := 1 + ((len(f) + 7 + 2) >> 3) + + nullBitmap := p[1:pos] + + var isNull bool + var n int + var err error + var v []byte + for i := range data { + if nullBitmap[(i+2)/8]&(1<<(uint(i+2)%8)) > 0 { + data[i].Type = FieldValueTypeNull + continue + } + + isUnsigned := f[i].Flag&UNSIGNED_FLAG != 0 + + switch f[i].Type { + case MYSQL_TYPE_NULL: + data[i].Type = FieldValueTypeNull + continue + + case MYSQL_TYPE_TINY: + if isUnsigned { + v := ParseBinaryUint8(p[pos : pos+1]) + data[i].Type = FieldValueTypeUnsigned + data[i].value = uint64(v) + } else { + v := ParseBinaryInt8(p[pos : pos+1]) + data[i].Type = FieldValueTypeSigned + data[i].value = utils.Int64ToUint64(int64(v)) + } + pos++ + continue + + case MYSQL_TYPE_SHORT, MYSQL_TYPE_YEAR: + if isUnsigned { + v := ParseBinaryUint16(p[pos : pos+2]) + data[i].Type = FieldValueTypeUnsigned + data[i].value = uint64(v) + } else { + v := ParseBinaryInt16(p[pos : pos+2]) + data[i].Type = FieldValueTypeSigned + data[i].value = utils.Int64ToUint64(int64(v)) + } + pos += 2 + continue + + case MYSQL_TYPE_INT24, MYSQL_TYPE_LONG: + if isUnsigned { + v := ParseBinaryUint32(p[pos : pos+4]) + data[i].Type = FieldValueTypeUnsigned + data[i].value = uint64(v) + } else { + v := ParseBinaryInt32(p[pos : pos+4]) + data[i].Type = FieldValueTypeSigned + data[i].value = utils.Int64ToUint64(int64(v)) + } + pos += 4 + continue + + case MYSQL_TYPE_LONGLONG: + if isUnsigned { + v := ParseBinaryUint64(p[pos : pos+8]) + data[i].Type = FieldValueTypeUnsigned + data[i].value = v + } else { + v := ParseBinaryInt64(p[pos : pos+8]) + data[i].Type = FieldValueTypeSigned + data[i].value = utils.Int64ToUint64(v) + } + pos += 8 + continue + + case MYSQL_TYPE_FLOAT: + v := ParseBinaryFloat32(p[pos : pos+4]) + data[i].Type = FieldValueTypeFloat + data[i].value = utils.Float64ToUint64(float64(v)) + pos += 4 + continue + + case MYSQL_TYPE_DOUBLE: + v := ParseBinaryFloat64(p[pos : pos+8]) + data[i].Type = FieldValueTypeFloat + data[i].value = utils.Float64ToUint64(v) + pos += 8 + continue + + case MYSQL_TYPE_DECIMAL, MYSQL_TYPE_NEWDECIMAL, MYSQL_TYPE_VARCHAR, + MYSQL_TYPE_BIT, MYSQL_TYPE_ENUM, MYSQL_TYPE_SET, MYSQL_TYPE_TINY_BLOB, + MYSQL_TYPE_MEDIUM_BLOB, MYSQL_TYPE_LONG_BLOB, MYSQL_TYPE_BLOB, + MYSQL_TYPE_VAR_STRING, MYSQL_TYPE_STRING, MYSQL_TYPE_GEOMETRY, MYSQL_TYPE_JSON: + v, isNull, n, err = LengthEncodedString(p[pos:]) + pos += n + if err != nil { + return nil, errors.Trace(err) + } + + if !isNull { + data[i].Type = FieldValueTypeString + data[i].str = append(data[i].str[:0], v...) + continue + } else { + data[i].Type = FieldValueTypeNull + continue + } + + case MYSQL_TYPE_DATE, MYSQL_TYPE_NEWDATE: + var num uint64 + num, isNull, n = LengthEncodedInt(p[pos:]) + + pos += n + + if isNull { + data[i].Type = FieldValueTypeNull + continue + } + + data[i].Type = FieldValueTypeString + data[i].str, err = FormatBinaryDate(int(num), p[pos:]) + pos += int(num) + + if err != nil { + return nil, errors.Trace(err) + } + + case MYSQL_TYPE_TIMESTAMP, MYSQL_TYPE_DATETIME: + var num uint64 + num, isNull, n = LengthEncodedInt(p[pos:]) + + pos += n + + if isNull { + data[i].Type = FieldValueTypeNull + continue + } + + data[i].Type = FieldValueTypeString + data[i].str, err = FormatBinaryDateTime(int(num), p[pos:]) + pos += int(num) + + if err != nil { + return nil, errors.Trace(err) + } + + case MYSQL_TYPE_TIME: + var num uint64 + num, isNull, n = LengthEncodedInt(p[pos:]) + + pos += n + + if isNull { + data[i].Type = FieldValueTypeNull + continue + } + + data[i].Type = FieldValueTypeString + data[i].str, err = FormatBinaryTime(int(num), p[pos:]) + pos += int(num) + + if err != nil { + return nil, errors.Trace(err) + } + + default: + return nil, errors.Errorf("Stmt Unknown FieldType %d %s", f[i].Type, f[i].Name) + } + } + + return data, nil +} diff --git a/v2/vendor/github.com/go-mysql-org/go-mysql/mysql/state.go b/v2/vendor/github.com/go-mysql-org/go-mysql/mysql/state.go new file mode 100644 index 0000000..568d84b --- /dev/null +++ b/v2/vendor/github.com/go-mysql-org/go-mysql/mysql/state.go @@ -0,0 +1,233 @@ +package mysql + +const ( + DEFAULT_MYSQL_STATE = "HY000" +) + +var MySQLState = map[uint16]string{ + ER_DUP_KEY: "23000", + ER_OUTOFMEMORY: "HY001", + ER_OUT_OF_SORTMEMORY: "HY001", + ER_CON_COUNT_ERROR: "08004", + ER_BAD_HOST_ERROR: "08S01", + ER_HANDSHAKE_ERROR: "08S01", + ER_DBACCESS_DENIED_ERROR: "42000", + ER_ACCESS_DENIED_ERROR: "28000", + ER_NO_DB_ERROR: "3D000", + ER_UNKNOWN_COM_ERROR: "08S01", + ER_BAD_NULL_ERROR: "23000", + ER_BAD_DB_ERROR: "42000", + ER_TABLE_EXISTS_ERROR: "42S01", + ER_BAD_TABLE_ERROR: "42S02", + ER_NON_UNIQ_ERROR: "23000", + ER_SERVER_SHUTDOWN: "08S01", + ER_BAD_FIELD_ERROR: "42S22", + ER_WRONG_FIELD_WITH_GROUP: "42000", + ER_WRONG_SUM_SELECT: "42000", + ER_WRONG_GROUP_FIELD: "42000", + ER_WRONG_VALUE_COUNT: "21S01", + ER_TOO_LONG_IDENT: "42000", + ER_DUP_FIELDNAME: "42S21", + ER_DUP_KEYNAME: "42000", + ER_DUP_ENTRY: "23000", + ER_WRONG_FIELD_SPEC: "42000", + ER_PARSE_ERROR: "42000", + ER_EMPTY_QUERY: "42000", + ER_NONUNIQ_TABLE: "42000", + ER_INVALID_DEFAULT: "42000", + ER_MULTIPLE_PRI_KEY: "42000", + ER_TOO_MANY_KEYS: "42000", + ER_TOO_MANY_KEY_PARTS: "42000", + ER_TOO_LONG_KEY: "42000", + ER_KEY_COLUMN_DOES_NOT_EXITS: "42000", + ER_BLOB_USED_AS_KEY: "42000", + ER_TOO_BIG_FIELDLENGTH: "42000", + ER_WRONG_AUTO_KEY: "42000", + ER_FORCING_CLOSE: "08S01", + ER_IPSOCK_ERROR: "08S01", + ER_NO_SUCH_INDEX: "42S12", + ER_WRONG_FIELD_TERMINATORS: "42000", + ER_BLOBS_AND_NO_TERMINATED: "42000", + ER_CANT_REMOVE_ALL_FIELDS: "42000", + ER_CANT_DROP_FIELD_OR_KEY: "42000", + ER_BLOB_CANT_HAVE_DEFAULT: "42000", + ER_WRONG_DB_NAME: "42000", + ER_WRONG_TABLE_NAME: "42000", + ER_TOO_BIG_SELECT: "42000", + ER_UNKNOWN_PROCEDURE: "42000", + ER_WRONG_PARAMCOUNT_TO_PROCEDURE: "42000", + ER_UNKNOWN_TABLE: "42S02", + ER_FIELD_SPECIFIED_TWICE: "42000", + ER_UNSUPPORTED_EXTENSION: "42000", + ER_TABLE_MUST_HAVE_COLUMNS: "42000", + ER_UNKNOWN_CHARACTER_SET: "42000", + ER_TOO_BIG_ROWSIZE: "42000", + ER_WRONG_OUTER_JOIN: "42000", + ER_NULL_COLUMN_IN_INDEX: "42000", + ER_PASSWORD_ANONYMOUS_USER: "42000", + ER_PASSWORD_NOT_ALLOWED: "42000", + ER_PASSWORD_NO_MATCH: "42000", + ER_WRONG_VALUE_COUNT_ON_ROW: "21S01", + ER_INVALID_USE_OF_NULL: "22004", + ER_REGEXP_ERROR: "42000", + ER_MIX_OF_GROUP_FUNC_AND_FIELDS: "42000", + ER_NONEXISTING_GRANT: "42000", + ER_TABLEACCESS_DENIED_ERROR: "42000", + ER_COLUMNACCESS_DENIED_ERROR: "42000", + ER_ILLEGAL_GRANT_FOR_TABLE: "42000", + ER_GRANT_WRONG_HOST_OR_USER: "42000", + ER_NO_SUCH_TABLE: "42S02", + ER_NONEXISTING_TABLE_GRANT: "42000", + ER_NOT_ALLOWED_COMMAND: "42000", + ER_SYNTAX_ERROR: "42000", + ER_ABORTING_CONNECTION: "08S01", + ER_NET_PACKET_TOO_LARGE: "08S01", + ER_NET_READ_ERROR_FROM_PIPE: "08S01", + ER_NET_FCNTL_ERROR: "08S01", + ER_NET_PACKETS_OUT_OF_ORDER: "08S01", + ER_NET_UNCOMPRESS_ERROR: "08S01", + ER_NET_READ_ERROR: "08S01", + ER_NET_READ_INTERRUPTED: "08S01", + ER_NET_ERROR_ON_WRITE: "08S01", + ER_NET_WRITE_INTERRUPTED: "08S01", + ER_TOO_LONG_STRING: "42000", + ER_TABLE_CANT_HANDLE_BLOB: "42000", + ER_TABLE_CANT_HANDLE_AUTO_INCREMENT: "42000", + ER_WRONG_COLUMN_NAME: "42000", + ER_WRONG_KEY_COLUMN: "42000", + ER_DUP_UNIQUE: "23000", + ER_BLOB_KEY_WITHOUT_LENGTH: "42000", + ER_PRIMARY_CANT_HAVE_NULL: "42000", + ER_TOO_MANY_ROWS: "42000", + ER_REQUIRES_PRIMARY_KEY: "42000", + ER_KEY_DOES_NOT_EXITS: "42000", + ER_CHECK_NO_SUCH_TABLE: "42000", + ER_CHECK_NOT_IMPLEMENTED: "42000", + ER_CANT_DO_THIS_DURING_AN_TRANSACTION: "25000", + ER_NEW_ABORTING_CONNECTION: "08S01", + ER_MASTER_NET_READ: "08S01", + ER_MASTER_NET_WRITE: "08S01", + ER_TOO_MANY_USER_CONNECTIONS: "42000", + ER_READ_ONLY_TRANSACTION: "25000", + ER_NO_PERMISSION_TO_CREATE_USER: "42000", + ER_LOCK_DEADLOCK: "40001", + ER_NO_REFERENCED_ROW: "23000", + ER_ROW_IS_REFERENCED: "23000", + ER_CONNECT_TO_MASTER: "08S01", + ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT: "21000", + ER_USER_LIMIT_REACHED: "42000", + ER_SPECIFIC_ACCESS_DENIED_ERROR: "42000", + ER_NO_DEFAULT: "42000", + ER_WRONG_VALUE_FOR_VAR: "42000", + ER_WRONG_TYPE_FOR_VAR: "42000", + ER_CANT_USE_OPTION_HERE: "42000", + ER_NOT_SUPPORTED_YET: "42000", + ER_WRONG_FK_DEF: "42000", + ER_OPERAND_COLUMNS: "21000", + ER_SUBQUERY_NO_1_ROW: "21000", + ER_ILLEGAL_REFERENCE: "42S22", + ER_DERIVED_MUST_HAVE_ALIAS: "42000", + ER_SELECT_REDUCED: "01000", + ER_TABLENAME_NOT_ALLOWED_HERE: "42000", + ER_NOT_SUPPORTED_AUTH_MODE: "08004", + ER_SPATIAL_CANT_HAVE_NULL: "42000", + ER_COLLATION_CHARSET_MISMATCH: "42000", + ER_WARN_TOO_FEW_RECORDS: "01000", + ER_WARN_TOO_MANY_RECORDS: "01000", + ER_WARN_NULL_TO_NOTNULL: "22004", + ER_WARN_DATA_OUT_OF_RANGE: "22003", + WARN_DATA_TRUNCATED: "01000", + ER_WRONG_NAME_FOR_INDEX: "42000", + ER_WRONG_NAME_FOR_CATALOG: "42000", + ER_UNKNOWN_STORAGE_ENGINE: "42000", + ER_TRUNCATED_WRONG_VALUE: "22007", + ER_SP_NO_RECURSIVE_CREATE: "2F003", + ER_SP_ALREADY_EXISTS: "42000", + ER_SP_DOES_NOT_EXIST: "42000", + ER_SP_LILABEL_MISMATCH: "42000", + ER_SP_LABEL_REDEFINE: "42000", + ER_SP_LABEL_MISMATCH: "42000", + ER_SP_UNINIT_VAR: "01000", + ER_SP_BADSELECT: "0A000", + ER_SP_BADRETURN: "42000", + ER_SP_BADSTATEMENT: "0A000", + ER_UPDATE_LOG_DEPRECATED_IGNORED: "42000", + ER_UPDATE_LOG_DEPRECATED_TRANSLATED: "42000", + ER_QUERY_INTERRUPTED: "70100", + ER_SP_WRONG_NO_OF_ARGS: "42000", + ER_SP_COND_MISMATCH: "42000", + ER_SP_NORETURN: "42000", + ER_SP_NORETURNEND: "2F005", + ER_SP_BAD_CURSOR_QUERY: "42000", + ER_SP_BAD_CURSOR_SELECT: "42000", + ER_SP_CURSOR_MISMATCH: "42000", + ER_SP_CURSOR_ALREADY_OPEN: "24000", + ER_SP_CURSOR_NOT_OPEN: "24000", + ER_SP_UNDECLARED_VAR: "42000", + ER_SP_FETCH_NO_DATA: "02000", + ER_SP_DUP_PARAM: "42000", + ER_SP_DUP_VAR: "42000", + ER_SP_DUP_COND: "42000", + ER_SP_DUP_CURS: "42000", + ER_SP_SUBSELECT_NYI: "0A000", + ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG: "0A000", + ER_SP_VARCOND_AFTER_CURSHNDLR: "42000", + ER_SP_CURSOR_AFTER_HANDLER: "42000", + ER_SP_CASE_NOT_FOUND: "20000", + ER_DIVISION_BY_ZERO: "22012", + ER_ILLEGAL_VALUE_FOR_TYPE: "22007", + ER_PROCACCESS_DENIED_ERROR: "42000", + ER_XAER_NOTA: "XAE04", + ER_XAER_INVAL: "XAE05", + ER_XAER_RMFAIL: "XAE07", + ER_XAER_OUTSIDE: "XAE09", + ER_XAER_RMERR: "XAE03", + ER_XA_RBROLLBACK: "XA100", + ER_NONEXISTING_PROC_GRANT: "42000", + ER_DATA_TOO_LONG: "22001", + ER_SP_BAD_SQLSTATE: "42000", + ER_CANT_CREATE_USER_WITH_GRANT: "42000", + ER_SP_DUP_HANDLER: "42000", + ER_SP_NOT_VAR_ARG: "42000", + ER_SP_NO_RETSET: "0A000", + ER_CANT_CREATE_GEOMETRY_OBJECT: "22003", + ER_TOO_BIG_SCALE: "42000", + ER_TOO_BIG_PRECISION: "42000", + ER_M_BIGGER_THAN_D: "42000", + ER_TOO_LONG_BODY: "42000", + ER_TOO_BIG_DISPLAYWIDTH: "42000", + ER_XAER_DUPID: "XAE08", + ER_DATETIME_FUNCTION_OVERFLOW: "22008", + ER_ROW_IS_REFERENCED_2: "23000", + ER_NO_REFERENCED_ROW_2: "23000", + ER_SP_BAD_VAR_SHADOW: "42000", + ER_SP_WRONG_NAME: "42000", + ER_SP_NO_AGGREGATE: "42000", + ER_MAX_PREPARED_STMT_COUNT_REACHED: "42000", + ER_NON_GROUPING_FIELD_USED: "42000", + ER_FOREIGN_DUPLICATE_KEY_OLD_UNUSED: "23000", + ER_CANT_CHANGE_TX_CHARACTERISTICS: "25001", + ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT: "42000", + ER_WRONG_PARAMETERS_TO_NATIVE_FCT: "42000", + ER_WRONG_PARAMETERS_TO_STORED_FCT: "42000", + ER_DUP_ENTRY_WITH_KEY_NAME: "23000", + ER_XA_RBTIMEOUT: "XA106", + ER_XA_RBDEADLOCK: "XA102", + ER_FUNC_INEXISTENT_NAME_COLLISION: "42000", + ER_DUP_SIGNAL_SET: "42000", + ER_SIGNAL_WARN: "01000", + ER_SIGNAL_NOT_FOUND: "02000", + ER_SIGNAL_EXCEPTION: "HY000", + ER_RESIGNAL_WITHOUT_ACTIVE_HANDLER: "0K000", + ER_SPATIAL_MUST_HAVE_GEOM_COL: "42000", + ER_DATA_OUT_OF_RANGE: "22003", + ER_ACCESS_DENIED_NO_PASSWORD_ERROR: "28000", + ER_TRUNCATE_ILLEGAL_FK: "42000", + ER_DA_INVALID_CONDITION_NUMBER: "35000", + ER_FOREIGN_DUPLICATE_KEY_WITH_CHILD_INFO: "23000", + ER_FOREIGN_DUPLICATE_KEY_WITHOUT_CHILD_INFO: "23000", + ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION: "25006", + ER_ALTER_OPERATION_NOT_SUPPORTED: "0A000", + ER_ALTER_OPERATION_NOT_SUPPORTED_REASON: "0A000", + ER_DUP_UNKNOWN_IN_INDEX: "23000", +} diff --git a/v2/vendor/github.com/go-mysql-org/go-mysql/mysql/util.go b/v2/vendor/github.com/go-mysql-org/go-mysql/mysql/util.go new file mode 100644 index 0000000..e8d436f --- /dev/null +++ b/v2/vendor/github.com/go-mysql-org/go-mysql/mysql/util.go @@ -0,0 +1,403 @@ +package mysql + +import ( + "crypto/rand" + "crypto/rsa" + "crypto/sha1" + "crypto/sha256" + "encoding/binary" + "fmt" + "io" + mrand "math/rand" + "runtime" + "strings" + "time" + + "github.com/pingcap/errors" + "github.com/siddontang/go/hack" +) + +func Pstack() string { + buf := make([]byte, 1024) + n := runtime.Stack(buf, false) + return string(buf[0:n]) +} + +func CalcPassword(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 +} + +// CalcCachingSha2Password: Hash password using MySQL 8+ method (SHA256) +func CalcCachingSha2Password(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] + } + sha1v := sha1.New() + return rsa.EncryptOAEP(sha1v, rand.Reader, pub, plain, nil) +} + +// AppendLengthEncodedInteger: encodes a uint64 value and appends it to the given bytes slice +func AppendLengthEncodedInteger(b []byte, n uint64) []byte { + switch { + case n <= 250: + return append(b, byte(n)) + + case n <= 0xffff: + return append(b, 0xfc, byte(n), byte(n>>8)) + + case n <= 0xffffff: + return append(b, 0xfd, byte(n), byte(n>>8), byte(n>>16)) + } + return append(b, 0xfe, byte(n), byte(n>>8), byte(n>>16), byte(n>>24), + byte(n>>32), byte(n>>40), byte(n>>48), byte(n>>56)) +} + +func RandomBuf(size int) []byte { + buf := make([]byte, size) + mrand.Seed(time.Now().UTC().UnixNano()) + min, max := 30, 127 + for i := 0; i < size; i++ { + buf[i] = byte(min + mrand.Intn(max-min)) + } + return buf +} + +// FixedLengthInt: little endian +func FixedLengthInt(buf []byte) uint64 { + var num uint64 = 0 + for i, b := range buf { + num |= uint64(b) << (uint(i) * 8) + } + return num +} + +// BFixedLengthInt: big endian +func BFixedLengthInt(buf []byte) uint64 { + var num uint64 = 0 + for i, b := range buf { + num |= uint64(b) << (uint(len(buf)-i-1) * 8) + } + return num +} + +func LengthEncodedInt(b []byte) (num uint64, isNull bool, n int) { + if len(b) == 0 { + return 0, true, 0 + } + + switch b[0] { + // 251: NULL + case 0xfb: + return 0, true, 1 + + // 252: value of following 2 + case 0xfc: + return uint64(b[1]) | uint64(b[2])<<8, false, 3 + + // 253: value of following 3 + case 0xfd: + return uint64(b[1]) | uint64(b[2])<<8 | uint64(b[3])<<16, false, 4 + + // 254: value of following 8 + case 0xfe: + return uint64(b[1]) | uint64(b[2])<<8 | uint64(b[3])<<16 | + uint64(b[4])<<24 | uint64(b[5])<<32 | uint64(b[6])<<40 | + uint64(b[7])<<48 | uint64(b[8])<<56, + false, 9 + } + + // 0-250: value of first byte + return uint64(b[0]), false, 1 +} + +func PutLengthEncodedInt(n uint64) []byte { + switch { + case n <= 250: + return []byte{byte(n)} + + case n <= 0xffff: + return []byte{0xfc, byte(n), byte(n >> 8)} + + case n <= 0xffffff: + return []byte{0xfd, byte(n), byte(n >> 8), byte(n >> 16)} + + case n <= 0xffffffffffffffff: + return []byte{0xfe, byte(n), byte(n >> 8), byte(n >> 16), byte(n >> 24), + byte(n >> 32), byte(n >> 40), byte(n >> 48), byte(n >> 56)} + } + return nil +} + +// LengthEncodedString returns the string read as a bytes slice, whether the value is NULL, +// the number of bytes read and an error, in case the string is longer than +// the input slice +func LengthEncodedString(b []byte) ([]byte, bool, int, error) { + // Get length + num, isNull, n := LengthEncodedInt(b) + if num < 1 { + return b[n:n], isNull, n, nil + } + + n += int(num) + + // Check data length + if len(b) >= n { + return b[n-int(num) : n : n], false, n, nil + } + return nil, false, n, io.EOF +} + +func SkipLengthEncodedString(b []byte) (int, error) { + // Get length + num, _, n := LengthEncodedInt(b) + if num < 1 { + return n, nil + } + + n += int(num) + + // Check data length + if len(b) >= n { + return n, nil + } + return n, io.EOF +} + +func PutLengthEncodedString(b []byte) []byte { + data := make([]byte, 0, len(b)+9) + data = append(data, PutLengthEncodedInt(uint64(len(b)))...) + data = append(data, b...) + return data +} + +func Uint16ToBytes(n uint16) []byte { + return []byte{ + byte(n), + byte(n >> 8), + } +} + +func Uint32ToBytes(n uint32) []byte { + return []byte{ + byte(n), + byte(n >> 8), + byte(n >> 16), + byte(n >> 24), + } +} + +func Uint64ToBytes(n uint64) []byte { + return []byte{ + byte(n), + byte(n >> 8), + byte(n >> 16), + byte(n >> 24), + byte(n >> 32), + byte(n >> 40), + byte(n >> 48), + byte(n >> 56), + } +} + +func FormatBinaryDate(n int, data []byte) ([]byte, error) { + switch n { + case 0: + return []byte("0000-00-00"), nil + case 4: + return []byte(fmt.Sprintf("%04d-%02d-%02d", + binary.LittleEndian.Uint16(data[:2]), + data[2], + data[3])), nil + default: + return nil, errors.Errorf("invalid date packet length %d", n) + } +} + +func FormatBinaryDateTime(n int, data []byte) ([]byte, error) { + switch n { + case 0: + return []byte("0000-00-00 00:00:00"), nil + case 4: + return []byte(fmt.Sprintf("%04d-%02d-%02d 00:00:00", + binary.LittleEndian.Uint16(data[:2]), + data[2], + data[3])), nil + case 7: + return []byte(fmt.Sprintf( + "%04d-%02d-%02d %02d:%02d:%02d", + binary.LittleEndian.Uint16(data[:2]), + data[2], + data[3], + data[4], + data[5], + data[6])), nil + case 11: + return []byte(fmt.Sprintf( + "%04d-%02d-%02d %02d:%02d:%02d.%06d", + binary.LittleEndian.Uint16(data[:2]), + data[2], + data[3], + data[4], + data[5], + data[6], + binary.LittleEndian.Uint32(data[7:11]))), nil + default: + return nil, errors.Errorf("invalid datetime packet length %d", n) + } +} + +func FormatBinaryTime(n int, data []byte) ([]byte, error) { + if n == 0 { + return []byte("0000-00-00"), nil + } + + var sign byte + if data[0] == 1 { + sign = byte('-') + } + + switch n { + case 8: + return []byte(fmt.Sprintf( + "%c%02d:%02d:%02d", + sign, + uint16(data[1])*24+uint16(data[5]), + data[6], + data[7], + )), nil + case 12: + return []byte(fmt.Sprintf( + "%c%02d:%02d:%02d.%06d", + sign, + uint16(data[1])*24+uint16(data[5]), + data[6], + data[7], + binary.LittleEndian.Uint32(data[8:12]), + )), nil + default: + return nil, errors.Errorf("invalid time packet length %d", n) + } +} + +var ( + DONTESCAPE = byte(255) + + EncodeMap [256]byte +) + +// Escape: only support utf-8 +func Escape(sql string) string { + dest := make([]byte, 0, 2*len(sql)) + + for _, w := range hack.Slice(sql) { + if c := EncodeMap[w]; c == DONTESCAPE { + dest = append(dest, w) + } else { + dest = append(dest, '\\', c) + } + } + + return string(dest) +} + +func GetNetProto(addr string) string { + if strings.Contains(addr, "/") { + return "unix" + } else { + return "tcp" + } +} + +// ErrorEqual returns a boolean indicating whether err1 is equal to err2. +func ErrorEqual(err1, err2 error) bool { + e1 := errors.Cause(err1) + e2 := errors.Cause(err2) + + if e1 == e2 { + return true + } + + if e1 == nil || e2 == nil { + return e1 == e2 + } + + return e1.Error() == e2.Error() +} + +var encodeRef = map[byte]byte{ + '\x00': '0', + '\'': '\'', + '"': '"', + '\b': 'b', + '\n': 'n', + '\r': 'r', + '\t': 't', + 26: 'Z', // ctl-Z + '\\': '\\', +} + +func init() { + for i := range EncodeMap { + EncodeMap[i] = DONTESCAPE + } + for i := range EncodeMap { + if to, ok := encodeRef[byte(i)]; ok { + EncodeMap[byte(i)] = to + } + } +} diff --git a/v2/vendor/github.com/go-mysql-org/go-mysql/packet/conn.go b/v2/vendor/github.com/go-mysql-org/go-mysql/packet/conn.go new file mode 100644 index 0000000..8d020fe --- /dev/null +++ b/v2/vendor/github.com/go-mysql-org/go-mysql/packet/conn.go @@ -0,0 +1,305 @@ +package packet + +import ( + "bufio" + "bytes" + "crypto/rand" + "crypto/rsa" + "crypto/sha1" + "crypto/x509" + "encoding/pem" + "io" + "net" + "sync" + + . "github.com/go-mysql-org/go-mysql/mysql" + "github.com/go-mysql-org/go-mysql/utils" + "github.com/pingcap/errors" +) + +type BufPool struct { + pool *sync.Pool +} + +func NewBufPool() *BufPool { + return &BufPool{ + pool: &sync.Pool{ + New: func() interface{} { + return new(bytes.Buffer) + }, + }, + } +} + +func (b *BufPool) Get() *bytes.Buffer { + return b.pool.Get().(*bytes.Buffer) +} + +func (b *BufPool) Return(buf *bytes.Buffer) { + buf.Reset() + b.pool.Put(buf) +} + +// Conn is the base class to handle MySQL protocol. +type Conn struct { + net.Conn + + // we removed the buffer reader because it will cause the SSLRequest to block (tls connection handshake won't be + // able to read the "Client Hello" data since it has been buffered into the buffer reader) + + bufPool *BufPool + br *bufio.Reader + reader io.Reader + + copyNBuf []byte + + header [4]byte + + Sequence uint8 +} + +func NewConn(conn net.Conn) *Conn { + c := new(Conn) + c.Conn = conn + + c.bufPool = NewBufPool() + c.br = bufio.NewReaderSize(c, 65536) // 64kb + c.reader = c.br + + c.copyNBuf = make([]byte, 16*1024) + + return c +} + +func NewTLSConn(conn net.Conn) *Conn { + c := new(Conn) + c.Conn = conn + + c.bufPool = NewBufPool() + c.reader = c + + c.copyNBuf = make([]byte, 16*1024) + + return c +} + +func (c *Conn) ReadPacket() ([]byte, error) { + return c.ReadPacketReuseMem(nil) +} + +func (c *Conn) ReadPacketReuseMem(dst []byte) ([]byte, error) { + // Here we use `sync.Pool` to avoid allocate/destroy buffers frequently. + buf := utils.BytesBufferGet() + defer func() { + utils.BytesBufferPut(buf) + }() + + if err := c.ReadPacketTo(buf); err != nil { + return nil, errors.Trace(err) + } + + readBytes := buf.Bytes() + readSize := len(readBytes) + var result []byte + if len(dst) > 0 { + result = append(dst, readBytes...) + // if read block is big, do not cache buf any more + if readSize > utils.TooBigBlockSize { + buf = nil + } + } else { + if readSize > utils.TooBigBlockSize { + // if read block is big, use read block as result and do not cache buf any more + result = readBytes + buf = nil + } else { + result = append(dst, readBytes...) + } + } + + return result, nil +} + +func (c *Conn) copyN(dst io.Writer, src io.Reader, n int64) (written int64, err error) { + for n > 0 { + bcap := cap(c.copyNBuf) + if int64(bcap) > n { + bcap = int(n) + } + buf := c.copyNBuf[:bcap] + + rd, err := io.ReadAtLeast(src, buf, bcap) + n -= int64(rd) + + if err != nil { + return written, errors.Trace(err) + } + + wr, err := dst.Write(buf) + written += int64(wr) + if err != nil { + return written, errors.Trace(err) + } + } + + return written, nil +} + +func (c *Conn) ReadPacketTo(w io.Writer) error { + if _, err := io.ReadFull(c.reader, c.header[:4]); err != nil { + return errors.Wrapf(ErrBadConn, "io.ReadFull(header) failed. err %v", err) + } + + length := int(uint32(c.header[0]) | uint32(c.header[1])<<8 | uint32(c.header[2])<<16) + sequence := c.header[3] + + if sequence != c.Sequence { + return errors.Errorf("invalid sequence %d != %d", sequence, c.Sequence) + } + + c.Sequence++ + + if buf, ok := w.(*bytes.Buffer); ok { + // Allocate the buffer with expected length directly instead of call `grow` and migrate data many times. + buf.Grow(length) + } + + if n, err := c.copyN(w, c.reader, int64(length)); err != nil { + return errors.Wrapf(ErrBadConn, "io.CopyN failed. err %v, copied %v, expected %v", err, n, length) + } else if n != int64(length) { + return errors.Wrapf(ErrBadConn, "io.CopyN failed(n != int64(length)). %v bytes copied, while %v expected", n, length) + } else { + if length < MaxPayloadLen { + return nil + } + + if err := c.ReadPacketTo(w); err != nil { + return errors.Wrap(err, "ReadPacketTo failed") + } + } + + return nil +} + +// WritePacket: data already has 4 bytes header +// will modify data inplace +func (c *Conn) WritePacket(data []byte) error { + length := len(data) - 4 + + for length >= MaxPayloadLen { + data[0] = 0xff + data[1] = 0xff + data[2] = 0xff + + data[3] = c.Sequence + + if n, err := c.Write(data[:4+MaxPayloadLen]); err != nil { + return errors.Wrapf(ErrBadConn, "Write(payload portion) failed. err %v", err) + } else if n != (4 + MaxPayloadLen) { + return errors.Wrapf(ErrBadConn, "Write(payload portion) failed. only %v bytes written, while %v expected", n, 4+MaxPayloadLen) + } else { + c.Sequence++ + length -= MaxPayloadLen + data = data[MaxPayloadLen:] + } + } + + data[0] = byte(length) + data[1] = byte(length >> 8) + data[2] = byte(length >> 16) + data[3] = c.Sequence + + if n, err := c.Write(data); err != nil { + return errors.Wrapf(ErrBadConn, "Write failed. err %v", err) + } else if n != len(data) { + return errors.Wrapf(ErrBadConn, "Write failed. only %v bytes written, while %v expected", n, len(data)) + } else { + c.Sequence++ + return nil + } +} + +// WriteClearAuthPacket: Client clear text authentication packet +// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::AuthSwitchResponse +func (c *Conn) WriteClearAuthPacket(password string) error { + // Calculate the packet length and add a tailing 0 + pktLen := len(password) + 1 + data := make([]byte, 4+pktLen) + + // Add the clear password [null terminated string] + copy(data[4:], password) + data[4+pktLen-1] = 0x00 + + return errors.Wrap(c.WritePacket(data), "WritePacket failed") +} + +// WritePublicKeyAuthPacket: Caching sha2 authentication. Public key request and send encrypted password +// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::AuthSwitchResponse +func (c *Conn) WritePublicKeyAuthPacket(password string, cipher []byte) error { + // request public key + data := make([]byte, 4+1) + data[4] = 2 // cachingSha2PasswordRequestPublicKey + if err := c.WritePacket(data); err != nil { + return errors.Wrap(err, "WritePacket(single byte) failed") + } + + data, err := c.ReadPacket() + if err != nil { + return errors.Wrap(err, "ReadPacket failed") + } + + block, _ := pem.Decode(data[1:]) + pub, err := x509.ParsePKIXPublicKey(block.Bytes) + if err != nil { + return errors.Wrap(err, "x509.ParsePKIXPublicKey failed") + } + + plain := make([]byte, len(password)+1) + copy(plain, password) + for i := range plain { + j := i % len(cipher) + plain[i] ^= cipher[j] + } + sha1v := sha1.New() + enc, _ := rsa.EncryptOAEP(sha1v, rand.Reader, pub.(*rsa.PublicKey), plain, nil) + data = make([]byte, 4+len(enc)) + copy(data[4:], enc) + return errors.Wrap(c.WritePacket(data), "WritePacket failed") +} + +func (c *Conn) WriteEncryptedPassword(password string, seed []byte, pub *rsa.PublicKey) error { + enc, err := EncryptPassword(password, seed, pub) + if err != nil { + return errors.Wrap(err, "EncryptPassword failed") + } + return errors.Wrap(c.WriteAuthSwitchPacket(enc, false), "WriteAuthSwitchPacket failed") +} + +// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::AuthSwitchResponse +func (c *Conn) WriteAuthSwitchPacket(authData []byte, addNUL bool) error { + pktLen := 4 + len(authData) + if addNUL { + pktLen++ + } + data := make([]byte, pktLen) + + // Add the auth data [EOF] + copy(data[4:], authData) + if addNUL { + data[pktLen-1] = 0x00 + } + + return errors.Wrap(c.WritePacket(data), "WritePacket failed") +} + +func (c *Conn) ResetSequence() { + c.Sequence = 0 +} + +func (c *Conn) Close() error { + c.Sequence = 0 + if c.Conn != nil { + return errors.Wrap(c.Conn.Close(), "Conn.Close failed") + } + return nil +} diff --git a/v2/vendor/github.com/go-mysql-org/go-mysql/utils/byte_slice_pool.go b/v2/vendor/github.com/go-mysql-org/go-mysql/utils/byte_slice_pool.go new file mode 100644 index 0000000..8dace14 --- /dev/null +++ b/v2/vendor/github.com/go-mysql-org/go-mysql/utils/byte_slice_pool.go @@ -0,0 +1,30 @@ +package utils + +import "sync" + +type ByteSlice struct { + B []byte +} + +var ( + byteSlicePool = sync.Pool{ + New: func() interface{} { + return new(ByteSlice) + }, + } +) + +func ByteSliceGet(length int) *ByteSlice { + data := byteSlicePool.Get().(*ByteSlice) + if cap(data.B) < length { + data.B = make([]byte, length) + } else { + data.B = data.B[:length] + } + return data +} + +func ByteSlicePut(data *ByteSlice) { + data.B = data.B[:0] + byteSlicePool.Put(data) +} diff --git a/v2/vendor/github.com/go-mysql-org/go-mysql/utils/bytes_buffer_pool.go b/v2/vendor/github.com/go-mysql-org/go-mysql/utils/bytes_buffer_pool.go new file mode 100644 index 0000000..60b820f --- /dev/null +++ b/v2/vendor/github.com/go-mysql-org/go-mysql/utils/bytes_buffer_pool.go @@ -0,0 +1,31 @@ +package utils + +import ( + "bytes" + "sync" +) + +const ( + TooBigBlockSize = 1024 * 1024 * 4 +) + +var ( + bytesBufferPool = sync.Pool{ + New: func() interface{} { + return &bytes.Buffer{} + }, + } +) + +func BytesBufferGet() (data *bytes.Buffer) { + data = bytesBufferPool.Get().(*bytes.Buffer) + data.Reset() + return data +} + +func BytesBufferPut(data *bytes.Buffer) { + if data == nil || data.Len() > TooBigBlockSize { + return + } + bytesBufferPool.Put(data) +} diff --git a/v2/vendor/github.com/go-mysql-org/go-mysql/utils/zeroalloc.go b/v2/vendor/github.com/go-mysql-org/go-mysql/utils/zeroalloc.go new file mode 100644 index 0000000..ca3798c --- /dev/null +++ b/v2/vendor/github.com/go-mysql-org/go-mysql/utils/zeroalloc.go @@ -0,0 +1,27 @@ +package utils + +import "unsafe" + +func StringToByteSlice(s string) []byte { + return *(*[]byte)(unsafe.Pointer(&s)) +} + +func ByteSliceToString(b []byte) string { + return *(*string)(unsafe.Pointer(&b)) +} + +func Uint64ToInt64(val uint64) int64 { + return *(*int64)(unsafe.Pointer(&val)) +} + +func Uint64ToFloat64(val uint64) float64 { + return *(*float64)(unsafe.Pointer(&val)) +} + +func Int64ToUint64(val int64) uint64 { + return *(*uint64)(unsafe.Pointer(&val)) +} + +func Float64ToUint64(val float64) uint64 { + return *(*uint64)(unsafe.Pointer(&val)) +} diff --git a/v2/vendor/github.com/go-sql-driver/mysql/.gitignore b/v2/vendor/github.com/go-sql-driver/mysql/.gitignore deleted file mode 100644 index 2de28da..0000000 --- a/v2/vendor/github.com/go-sql-driver/mysql/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ -.DS_Store -.DS_Store? -._* -.Spotlight-V100 -.Trashes -Icon? -ehthumbs.db -Thumbs.db -.idea diff --git a/v2/vendor/github.com/go-sql-driver/mysql/AUTHORS b/v2/vendor/github.com/go-sql-driver/mysql/AUTHORS deleted file mode 100644 index 4021b96..0000000 --- a/v2/vendor/github.com/go-sql-driver/mysql/AUTHORS +++ /dev/null @@ -1,142 +0,0 @@ -# This is the official list of Go-MySQL-Driver authors for copyright purposes. - -# If you are submitting a patch, please add your name or the name of the -# organization which holds the copyright to this list in alphabetical order. - -# Names should be added to this file as -# Name -# The email address is not required for organizations. -# Please keep the list sorted. - - -# Individual Persons - -Aaron Hopkins -Achille Roussel -Aidan -Alex Snast -Alexey Palazhchenko -Andrew Reid -Animesh Ray -Arne Hormann -Ariel Mashraki -Asta Xie -Brian Hendriks -Bulat Gaifullin -Caine Jette -Carlos Nieto -Chris Kirkland -Chris Moos -Craig Wilson -Daemonxiao <735462752 at qq.com> -Daniel Montoya -Daniel Nichter -Daniël van Eeden -Dave Protasowski -DisposaBoy -Egor Smolyakov -Erwan Martin -Evan Elias -Evan Shaw -Frederick Mayle -Gustavo Kristic -Gusted -Hajime Nakagami -Hanno Braun -Henri Yandell -Hirotaka Yamamoto -Huyiguang -ICHINOSE Shogo -Ilia Cimpoes -INADA Naoki -Jacek Szwec -James Harr -Janek Vedock -Jason Ng -Jean-Yves Pellé -Jeff Hodges -Jeffrey Charles -Jennifer Purevsuren -Jerome Meyer -Jiajia Zhong -Jian Zhen -Joshua Prunier -Julien Lefevre -Julien Schmidt -Justin Li -Justin Nuß -Kamil Dziedzic -Kei Kamikawa -Kevin Malachowski -Kieron Woodhouse -Lance Tian -Lennart Rudolph -Leonardo YongUk Kim -Linh Tran Tuan -Lion Yang -Luca Looz -Lucas Liu -Lunny Xiao -Luke Scott -Maciej Zimnoch -Michael Woolnough -Nathanial Murphy -Nicola Peduzzi -Oliver Bone -Olivier Mengué -oscarzhao -Paul Bonser -Paulius Lozys -Peter Schultz -Phil Porada -Rebecca Chin -Reed Allman -Richard Wilkes -Robert Russell -Runrioter Wung -Samantha Frank -Santhosh Kumar Tekuri -Sho Iizuka -Sho Ikeda -Shuode Li -Simon J Mudd -Soroush Pour -Stan Putrya -Stanley Gunawan -Steven Hartland -Tan Jinhua <312841925 at qq.com> -Tetsuro Aoki -Thomas Wodarek -Tim Ruffles -Tom Jenkinson -Vladimir Kovpak -Vladyslav Zhelezniak -Xiangyu Hu -Xiaobing Jiang -Xiuming Chen -Xuehong Chan -Zhang Xiang -Zhenye Xie -Zhixin Wen -Ziheng Lyu - -# Organizations - -Barracuda Networks, Inc. -Counting Ltd. -DigitalOcean Inc. -Dolthub Inc. -dyves labs AG -Facebook Inc. -GitHub Inc. -Google Inc. -InfoSum Ltd. -Keybase Inc. -Microsoft Corp. -Multiplay Ltd. -Percona LLC -PingCAP Inc. -Pivotal Inc. -Shattered Silicon Ltd. -Stripe Inc. -Zendesk Inc. diff --git a/v2/vendor/github.com/go-sql-driver/mysql/CHANGELOG.md b/v2/vendor/github.com/go-sql-driver/mysql/CHANGELOG.md deleted file mode 100644 index 0c9bd9b..0000000 --- a/v2/vendor/github.com/go-sql-driver/mysql/CHANGELOG.md +++ /dev/null @@ -1,308 +0,0 @@ -## Version 1.8.1 (2024-03-26) - -Bugfixes: - -- fix race condition when context is canceled in [#1562](https://github.com/go-sql-driver/mysql/pull/1562) and [#1570](https://github.com/go-sql-driver/mysql/pull/1570) - -## Version 1.8.0 (2024-03-09) - -Major Changes: - -- Use `SET NAMES charset COLLATE collation`. by @methane in [#1437](https://github.com/go-sql-driver/mysql/pull/1437) - - Older go-mysql-driver used `collation_id` in the handshake packet. But it caused collation mismatch in some situation. - - If you don't specify charset nor collation, go-mysql-driver sends `SET NAMES utf8mb4` for new connection. This uses server's default collation for utf8mb4. - - If you specify charset, go-mysql-driver sends `SET NAMES `. This uses the server's default collation for ``. - - If you specify collation and/or charset, go-mysql-driver sends `SET NAMES charset COLLATE collation`. -- PathEscape dbname in DSN. by @methane in [#1432](https://github.com/go-sql-driver/mysql/pull/1432) - - This is backward incompatible in rare case. Check your DSN. -- Drop Go 1.13-17 support by @methane in [#1420](https://github.com/go-sql-driver/mysql/pull/1420) - - Use Go 1.18+ -- Parse numbers on text protocol too by @methane in [#1452](https://github.com/go-sql-driver/mysql/pull/1452) - - When text protocol is used, go-mysql-driver passed bare `[]byte` to database/sql for avoid unnecessary allocation and conversion. - - If user specified `*any` to `Scan()`, database/sql passed the `[]byte` into the target variable. - - This confused users because most user doesn't know when text/binary protocol used. - - go-mysql-driver 1.8 converts integer/float values into int64/double even in text protocol. This doesn't increase allocation compared to `[]byte` and conversion cost is negatable. -- New options start using the Functional Option Pattern to avoid increasing technical debt in the Config object. Future version may introduce Functional Option for existing options, but not for now. - - Make TimeTruncate functional option by @methane in [1552](https://github.com/go-sql-driver/mysql/pull/1552) - - Add BeforeConnect callback to configuration object by @ItalyPaleAle in [#1469](https://github.com/go-sql-driver/mysql/pull/1469) - - -Other changes: - -- Adding DeregisterDialContext to prevent memory leaks with dialers we don't need anymore by @jypelle in https://github.com/go-sql-driver/mysql/pull/1422 -- Make logger configurable per connection by @frozenbonito in https://github.com/go-sql-driver/mysql/pull/1408 -- Fix ColumnType.DatabaseTypeName for mediumint unsigned by @evanelias in https://github.com/go-sql-driver/mysql/pull/1428 -- Add connection attributes by @Daemonxiao in https://github.com/go-sql-driver/mysql/pull/1389 -- Stop `ColumnTypeScanType()` from returning `sql.RawBytes` by @methane in https://github.com/go-sql-driver/mysql/pull/1424 -- Exec() now provides access to status of multiple statements. by @mherr-google in https://github.com/go-sql-driver/mysql/pull/1309 -- Allow to change (or disable) the default driver name for registration by @dolmen in https://github.com/go-sql-driver/mysql/pull/1499 -- Add default connection attribute '_server_host' by @oblitorum in https://github.com/go-sql-driver/mysql/pull/1506 -- QueryUnescape DSN ConnectionAttribute value by @zhangyangyu in https://github.com/go-sql-driver/mysql/pull/1470 -- Add client_ed25519 authentication by @Gusted in https://github.com/go-sql-driver/mysql/pull/1518 - -## Version 1.7.1 (2023-04-25) - -Changes: - - - bump actions/checkout@v3 and actions/setup-go@v3 (#1375) - - Add go1.20 and mariadb10.11 to the testing matrix (#1403) - - Increase default maxAllowedPacket size. (#1411) - -Bugfixes: - - - Use SET syntax as specified in the MySQL documentation (#1402) - - -## Version 1.7 (2022-11-29) - -Changes: - - - Drop support of Go 1.12 (#1211) - - Refactoring `(*textRows).readRow` in a more clear way (#1230) - - util: Reduce boundary check in escape functions. (#1316) - - enhancement for mysqlConn handleAuthResult (#1250) - -New Features: - - - support Is comparison on MySQLError (#1210) - - return unsigned in database type name when necessary (#1238) - - Add API to express like a --ssl-mode=PREFERRED MySQL client (#1370) - - Add SQLState to MySQLError (#1321) - -Bugfixes: - - - Fix parsing 0 year. (#1257) - - -## Version 1.6 (2021-04-01) - -Changes: - - - Migrate the CI service from travis-ci to GitHub Actions (#1176, #1183, #1190) - - `NullTime` is deprecated (#960, #1144) - - Reduce allocations when building SET command (#1111) - - Performance improvement for time formatting (#1118) - - Performance improvement for time parsing (#1098, #1113) - -New Features: - - - Implement `driver.Validator` interface (#1106, #1174) - - Support returning `uint64` from `Valuer` in `ConvertValue` (#1143) - - Add `json.RawMessage` for converter and prepared statement (#1059) - - Interpolate `json.RawMessage` as `string` (#1058) - - Implements `CheckNamedValue` (#1090) - -Bugfixes: - - - Stop rounding times (#1121, #1172) - - Put zero filler into the SSL handshake packet (#1066) - - Fix checking cancelled connections back into the connection pool (#1095) - - Fix remove last 0 byte for mysql_old_password when password is empty (#1133) - - -## Version 1.5 (2020-01-07) - -Changes: - - - Dropped support Go 1.9 and lower (#823, #829, #886, #1016, #1017) - - Improve buffer handling (#890) - - Document potentially insecure TLS configs (#901) - - Use a double-buffering scheme to prevent data races (#943) - - Pass uint64 values without converting them to string (#838, #955) - - Update collations and make utf8mb4 default (#877, #1054) - - Make NullTime compatible with sql.NullTime in Go 1.13+ (#995) - - Removed CloudSQL support (#993, #1007) - - Add Go Module support (#1003) - -New Features: - - - Implement support of optional TLS (#900) - - Check connection liveness (#934, #964, #997, #1048, #1051, #1052) - - Implement Connector Interface (#941, #958, #1020, #1035) - -Bugfixes: - - - Mark connections as bad on error during ping (#875) - - Mark connections as bad on error during dial (#867) - - Fix connection leak caused by rapid context cancellation (#1024) - - Mark connections as bad on error during Conn.Prepare (#1030) - - -## 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) - -Changes: - - - Go 1.1 is no longer supported - - Use decimals fields in MySQL to format time types (#249) - - Buffer optimizations (#269) - - TLS ServerName defaults to the host (#283) - - Refactoring (#400, #410, #437) - - Adjusted documentation for second generation CloudSQL (#485) - - Documented DSN system var quoting rules (#502) - - Made statement.Close() calls idempotent to avoid errors in Go 1.6+ (#512) - -New Features: - - - Enable microsecond resolution on TIME, DATETIME and TIMESTAMP (#249) - - Support for returning table alias on Columns() (#289, #359, #382) - - Placeholder interpolation, can be activated with the DSN parameter `interpolateParams=true` (#309, #318, #490) - - Support for uint64 parameters with high bit set (#332, #345) - - Cleartext authentication plugin support (#327) - - Exported ParseDSN function and the Config struct (#403, #419, #429) - - Read / Write timeouts (#401) - - Support for JSON field type (#414) - - Support for multi-statements and multi-results (#411, #431) - - DSN parameter to set the driver-side max_allowed_packet value manually (#489) - - Native password authentication plugin support (#494, #524) - -Bugfixes: - - - Fixed handling of queries without columns and rows (#255) - - Fixed a panic when SetKeepAlive() failed (#298) - - Handle ERR packets while reading rows (#321) - - Fixed reading NULL length-encoded integers in MySQL 5.6+ (#349) - - Fixed absolute paths support in LOAD LOCAL DATA INFILE (#356) - - Actually zero out bytes in handshake response (#378) - - Fixed race condition in registering LOAD DATA INFILE handler (#383) - - Fixed tests with MySQL 5.7.9+ (#380) - - QueryUnescape TLS config names (#397) - - Fixed "broken pipe" error by writing to closed socket (#390) - - Fixed LOAD LOCAL DATA INFILE buffering (#424) - - Fixed parsing of floats into float64 when placeholders are used (#434) - - Fixed DSN tests with Go 1.7+ (#459) - - Handle ERR packets while waiting for EOF (#473) - - Invalidate connection on error while discarding additional results (#513) - - Allow terminating packets of length 0 (#516) - - -## Version 1.2 (2014-06-03) - -Changes: - - - We switched back to a "rolling release". `go get` installs the current master branch again - - Version v1 of the driver will not be maintained anymore. Go 1.0 is no longer supported by this driver - - Exported errors to allow easy checking from application code - - Enabled TCP Keepalives on TCP connections - - Optimized INFILE handling (better buffer size calculation, lazy init, ...) - - The DSN parser also checks for a missing separating slash - - Faster binary date / datetime to string formatting - - Also exported the MySQLWarning type - - mysqlConn.Close returns the first error encountered instead of ignoring all errors - - writePacket() automatically writes the packet size to the header - - readPacket() uses an iterative approach instead of the recursive approach to merge split packets - -New Features: - - - `RegisterDial` allows the usage of a custom dial function to establish the network connection - - Setting the connection collation is possible with the `collation` DSN parameter. This parameter should be preferred over the `charset` parameter - - Logging of critical errors is configurable with `SetLogger` - - Google CloudSQL support - -Bugfixes: - - - Allow more than 32 parameters in prepared statements - - Various old_password fixes - - Fixed TestConcurrent test to pass Go's race detection - - Fixed appendLengthEncodedInteger for large numbers - - Renamed readLengthEnodedString to readLengthEncodedString and skipLengthEnodedString to skipLengthEncodedString (fixed typo) - - -## Version 1.1 (2013-11-02) - -Changes: - - - Go-MySQL-Driver now requires Go 1.1 - - Connections now use the collation `utf8_general_ci` by default. Adding `&charset=UTF8` to the DSN should not be necessary anymore - - Made closing rows and connections error tolerant. This allows for example deferring rows.Close() without checking for errors - - `[]byte(nil)` is now treated as a NULL value. Before, it was treated like an empty string / `[]byte("")` - - DSN parameter values must now be url.QueryEscape'ed. This allows text values to contain special characters, such as '&'. - - Use the IO buffer also for writing. This results in zero allocations (by the driver) for most queries - - Optimized the buffer for reading - - stmt.Query now caches column metadata - - New Logo - - Changed the copyright header to include all contributors - - Improved the LOAD INFILE documentation - - The driver struct is now exported to make the driver directly accessible - - Refactored the driver tests - - Added more benchmarks and moved all to a separate file - - Other small refactoring - -New Features: - - - Added *old_passwords* support: Required in some cases, but must be enabled by adding `allowOldPasswords=true` to the DSN since it is insecure - - Added a `clientFoundRows` parameter: Return the number of matching rows instead of the number of rows changed on UPDATEs - - Added TLS/SSL support: Use a TLS/SSL encrypted connection to the server. Custom TLS configs can be registered and used - -Bugfixes: - - - Fixed MySQL 4.1 support: MySQL 4.1 sends packets with lengths which differ from the specification - - Convert to DB timezone when inserting `time.Time` - - Split packets (more than 16MB) are now merged correctly - - Fixed false positive `io.EOF` errors when the data was fully read - - Avoid panics on reuse of closed connections - - Fixed empty string producing false nil values - - Fixed sign byte for positive TIME fields - - -## Version 1.0 (2013-05-14) - -Initial Release diff --git a/v2/vendor/github.com/go-sql-driver/mysql/LICENSE b/v2/vendor/github.com/go-sql-driver/mysql/LICENSE deleted file mode 100644 index 14e2f77..0000000 --- a/v2/vendor/github.com/go-sql-driver/mysql/LICENSE +++ /dev/null @@ -1,373 +0,0 @@ -Mozilla Public License Version 2.0 -================================== - -1. Definitions --------------- - -1.1. "Contributor" - means each individual or legal entity that creates, contributes to - the creation of, or owns Covered Software. - -1.2. "Contributor Version" - means the combination of the Contributions of others (if any) used - by a Contributor and that particular Contributor's Contribution. - -1.3. "Contribution" - means Covered Software of a particular Contributor. - -1.4. "Covered Software" - means Source Code Form to which the initial Contributor has attached - the notice in Exhibit A, the Executable Form of such Source Code - Form, and Modifications of such Source Code Form, in each case - including portions thereof. - -1.5. "Incompatible With Secondary Licenses" - means - - (a) that the initial Contributor has attached the notice described - in Exhibit B to the Covered Software; or - - (b) that the Covered Software was made available under the terms of - version 1.1 or earlier of the License, but not also under the - terms of a Secondary License. - -1.6. "Executable Form" - means any form of the work other than Source Code Form. - -1.7. "Larger Work" - means a work that combines Covered Software with other material, in - a separate file or files, that is not Covered Software. - -1.8. "License" - means this document. - -1.9. "Licensable" - means having the right to grant, to the maximum extent possible, - whether at the time of the initial grant or subsequently, any and - all of the rights conveyed by this License. - -1.10. "Modifications" - means any of the following: - - (a) any file in Source Code Form that results from an addition to, - deletion from, or modification of the contents of Covered - Software; or - - (b) any new file in Source Code Form that contains any Covered - Software. - -1.11. "Patent Claims" of a Contributor - means any patent claim(s), including without limitation, method, - process, and apparatus claims, in any patent Licensable by such - Contributor that would be infringed, but for the grant of the - License, by the making, using, selling, offering for sale, having - made, import, or transfer of either its Contributions or its - Contributor Version. - -1.12. "Secondary License" - means either the GNU General Public License, Version 2.0, the GNU - Lesser General Public License, Version 2.1, the GNU Affero General - Public License, Version 3.0, or any later versions of those - licenses. - -1.13. "Source Code Form" - means the form of the work preferred for making modifications. - -1.14. "You" (or "Your") - means an individual or a legal entity exercising rights under this - License. For legal entities, "You" includes any entity that - controls, is controlled by, or is under common control with You. For - purposes of this definition, "control" means (a) the power, direct - or indirect, to cause the direction or management of such entity, - whether by contract or otherwise, or (b) ownership of more than - fifty percent (50%) of the outstanding shares or beneficial - ownership of such entity. - -2. License Grants and Conditions --------------------------------- - -2.1. Grants - -Each Contributor hereby grants You a world-wide, royalty-free, -non-exclusive license: - -(a) under intellectual property rights (other than patent or trademark) - Licensable by such Contributor to use, reproduce, make available, - modify, display, perform, distribute, and otherwise exploit its - Contributions, either on an unmodified basis, with Modifications, or - as part of a Larger Work; and - -(b) under Patent Claims of such Contributor to make, use, sell, offer - for sale, have made, import, and otherwise transfer either its - Contributions or its Contributor Version. - -2.2. Effective Date - -The licenses granted in Section 2.1 with respect to any Contribution -become effective for each Contribution on the date the Contributor first -distributes such Contribution. - -2.3. Limitations on Grant Scope - -The licenses granted in this Section 2 are the only rights granted under -this License. No additional rights or licenses will be implied from the -distribution or licensing of Covered Software under this License. -Notwithstanding Section 2.1(b) above, no patent license is granted by a -Contributor: - -(a) for any code that a Contributor has removed from Covered Software; - or - -(b) for infringements caused by: (i) Your and any other third party's - modifications of Covered Software, or (ii) the combination of its - Contributions with other software (except as part of its Contributor - Version); or - -(c) under Patent Claims infringed by Covered Software in the absence of - its Contributions. - -This License does not grant any rights in the trademarks, service marks, -or logos of any Contributor (except as may be necessary to comply with -the notice requirements in Section 3.4). - -2.4. Subsequent Licenses - -No Contributor makes additional grants as a result of Your choice to -distribute the Covered Software under a subsequent version of this -License (see Section 10.2) or under the terms of a Secondary License (if -permitted under the terms of Section 3.3). - -2.5. Representation - -Each Contributor represents that the Contributor believes its -Contributions are its original creation(s) or it has sufficient rights -to grant the rights to its Contributions conveyed by this License. - -2.6. Fair Use - -This License is not intended to limit any rights You have under -applicable copyright doctrines of fair use, fair dealing, or other -equivalents. - -2.7. Conditions - -Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted -in Section 2.1. - -3. Responsibilities -------------------- - -3.1. Distribution of Source Form - -All distribution of Covered Software in Source Code Form, including any -Modifications that You create or to which You contribute, must be under -the terms of this License. You must inform recipients that the Source -Code Form of the Covered Software is governed by the terms of this -License, and how they can obtain a copy of this License. You may not -attempt to alter or restrict the recipients' rights in the Source Code -Form. - -3.2. Distribution of Executable Form - -If You distribute Covered Software in Executable Form then: - -(a) such Covered Software must also be made available in Source Code - Form, as described in Section 3.1, and You must inform recipients of - the Executable Form how they can obtain a copy of such Source Code - Form by reasonable means in a timely manner, at a charge no more - than the cost of distribution to the recipient; and - -(b) You may distribute such Executable Form under the terms of this - License, or sublicense it under different terms, provided that the - license for the Executable Form does not attempt to limit or alter - the recipients' rights in the Source Code Form under this License. - -3.3. Distribution of a Larger Work - -You may create and distribute a Larger Work under terms of Your choice, -provided that You also comply with the requirements of this License for -the Covered Software. If the Larger Work is a combination of Covered -Software with a work governed by one or more Secondary Licenses, and the -Covered Software is not Incompatible With Secondary Licenses, this -License permits You to additionally distribute such Covered Software -under the terms of such Secondary License(s), so that the recipient of -the Larger Work may, at their option, further distribute the Covered -Software under the terms of either this License or such Secondary -License(s). - -3.4. Notices - -You may not remove or alter the substance of any license notices -(including copyright notices, patent notices, disclaimers of warranty, -or limitations of liability) contained within the Source Code Form of -the Covered Software, except that You may alter any license notices to -the extent required to remedy known factual inaccuracies. - -3.5. Application of Additional Terms - -You may choose to offer, and to charge a fee for, warranty, support, -indemnity or liability obligations to one or more recipients of Covered -Software. However, You may do so only on Your own behalf, and not on -behalf of any Contributor. You must make it absolutely clear that any -such warranty, support, indemnity, or liability obligation is offered by -You alone, and You hereby agree to indemnify every Contributor for any -liability incurred by such Contributor as a result of warranty, support, -indemnity or liability terms You offer. You may include additional -disclaimers of warranty and limitations of liability specific to any -jurisdiction. - -4. Inability to Comply Due to Statute or Regulation ---------------------------------------------------- - -If it is impossible for You to comply with any of the terms of this -License with respect to some or all of the Covered Software due to -statute, judicial order, or regulation then You must: (a) comply with -the terms of this License to the maximum extent possible; and (b) -describe the limitations and the code they affect. Such description must -be placed in a text file included with all distributions of the Covered -Software under this License. Except to the extent prohibited by statute -or regulation, such description must be sufficiently detailed for a -recipient of ordinary skill to be able to understand it. - -5. Termination --------------- - -5.1. The rights granted under this License will terminate automatically -if You fail to comply with any of its terms. However, if You become -compliant, then the rights granted under this License from a particular -Contributor are reinstated (a) provisionally, unless and until such -Contributor explicitly and finally terminates Your grants, and (b) on an -ongoing basis, if such Contributor fails to notify You of the -non-compliance by some reasonable means prior to 60 days after You have -come back into compliance. Moreover, Your grants from a particular -Contributor are reinstated on an ongoing basis if such Contributor -notifies You of the non-compliance by some reasonable means, this is the -first time You have received notice of non-compliance with this License -from such Contributor, and You become compliant prior to 30 days after -Your receipt of the notice. - -5.2. If You initiate litigation against any entity by asserting a patent -infringement claim (excluding declaratory judgment actions, -counter-claims, and cross-claims) alleging that a Contributor Version -directly or indirectly infringes any patent, then the rights granted to -You by any and all Contributors for the Covered Software under Section -2.1 of this License shall terminate. - -5.3. In the event of termination under Sections 5.1 or 5.2 above, all -end user license agreements (excluding distributors and resellers) which -have been validly granted by You or Your distributors under this License -prior to termination shall survive termination. - -************************************************************************ -* * -* 6. Disclaimer of Warranty * -* ------------------------- * -* * -* Covered Software is provided under this License on an "as is" * -* basis, without warranty of any kind, either expressed, implied, or * -* statutory, including, without limitation, warranties that the * -* Covered Software is free of defects, merchantable, fit for a * -* particular purpose or non-infringing. The entire risk as to the * -* quality and performance of the Covered Software is with You. * -* Should any Covered Software prove defective in any respect, You * -* (not any Contributor) assume the cost of any necessary servicing, * -* repair, or correction. This disclaimer of warranty constitutes an * -* essential part of this License. No use of any Covered Software is * -* authorized under this License except under this disclaimer. * -* * -************************************************************************ - -************************************************************************ -* * -* 7. Limitation of Liability * -* -------------------------- * -* * -* Under no circumstances and under no legal theory, whether tort * -* (including negligence), contract, or otherwise, shall any * -* Contributor, or anyone who distributes Covered Software as * -* permitted above, be liable to You for any direct, indirect, * -* special, incidental, or consequential damages of any character * -* including, without limitation, damages for lost profits, loss of * -* goodwill, work stoppage, computer failure or malfunction, or any * -* and all other commercial damages or losses, even if such party * -* shall have been informed of the possibility of such damages. This * -* limitation of liability shall not apply to liability for death or * -* personal injury resulting from such party's negligence to the * -* extent applicable law prohibits such limitation. Some * -* jurisdictions do not allow the exclusion or limitation of * -* incidental or consequential damages, so this exclusion and * -* limitation may not apply to You. * -* * -************************************************************************ - -8. Litigation -------------- - -Any litigation relating to this License may be brought only in the -courts of a jurisdiction where the defendant maintains its principal -place of business and such litigation shall be governed by laws of that -jurisdiction, without reference to its conflict-of-law provisions. -Nothing in this Section shall prevent a party's ability to bring -cross-claims or counter-claims. - -9. Miscellaneous ----------------- - -This License represents the complete agreement concerning the subject -matter hereof. If any provision of this License is held to be -unenforceable, such provision shall be reformed only to the extent -necessary to make it enforceable. Any law or regulation which provides -that the language of a contract shall be construed against the drafter -shall not be used to construe this License against a Contributor. - -10. Versions of the License ---------------------------- - -10.1. New Versions - -Mozilla Foundation is the license steward. Except as provided in Section -10.3, no one other than the license steward has the right to modify or -publish new versions of this License. Each version will be given a -distinguishing version number. - -10.2. Effect of New Versions - -You may distribute the Covered Software under the terms of the version -of the License under which You originally received the Covered Software, -or under the terms of any subsequent version published by the license -steward. - -10.3. Modified Versions - -If you create software not governed by this License, and you want to -create a new license for such software, you may create and use a -modified version of this License if you rename the license and remove -any references to the name of the license steward (except to note that -such modified license differs from this License). - -10.4. Distributing Source Code Form that is Incompatible With Secondary -Licenses - -If You choose to distribute Source Code Form that is Incompatible With -Secondary Licenses under the terms of this version of the License, the -notice described in Exhibit B of this License must be attached. - -Exhibit A - Source Code Form License Notice -------------------------------------------- - - 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/. - -If it is not possible or desirable to put the notice in a particular -file, then You may include the notice in a location (such as a LICENSE -file in a relevant directory) where a recipient would be likely to look -for such a notice. - -You may add additional accurate notices of copyright ownership. - -Exhibit B - "Incompatible With Secondary Licenses" Notice ---------------------------------------------------------- - - This Source Code Form is "Incompatible With Secondary Licenses", as - defined by the Mozilla Public License, v. 2.0. diff --git a/v2/vendor/github.com/go-sql-driver/mysql/README.md b/v2/vendor/github.com/go-sql-driver/mysql/README.md deleted file mode 100644 index 4968cb0..0000000 --- a/v2/vendor/github.com/go-sql-driver/mysql/README.md +++ /dev/null @@ -1,581 +0,0 @@ -# Go-MySQL-Driver - -A MySQL-Driver for Go's [database/sql](https://golang.org/pkg/database/sql/) package - -![Go-MySQL-Driver logo](https://raw.github.com/wiki/go-sql-driver/mysql/gomysql_m.png "Golang Gopher holding the MySQL Dolphin") - ---------------------------------------- - * [Features](#features) - * [Requirements](#requirements) - * [Installation](#installation) - * [Usage](#usage) - * [DSN (Data Source Name)](#dsn-data-source-name) - * [Password](#password) - * [Protocol](#protocol) - * [Address](#address) - * [Parameters](#parameters) - * [Examples](#examples) - * [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) - * [time.Time support](#timetime-support) - * [Unicode support](#unicode-support) - * [Testing / Development](#testing--development) - * [License](#license) - ---------------------------------------- - -## Features - * Lightweight and [fast](https://github.com/go-sql-driver/sql-benchmark "golang MySQL-Driver performance") - * Native Go implementation. No C-bindings, just pure Go - * Connections over TCP/IPv4, TCP/IPv6, Unix domain sockets or [custom protocols](https://godoc.org/github.com/go-sql-driver/mysql#DialFunc) - * Automatic handling of broken connections - * Automatic Connection Pooling *(by database/sql package)* - * Supports queries larger than 16MB - * Full [`sql.RawBytes`](https://golang.org/pkg/database/sql/#RawBytes) support. - * Intelligent `LONG DATA` handling in prepared statements - * Secure `LOAD DATA LOCAL INFILE` support with file allowlisting and `io.Reader` support - * Optional `time.Time` parsing - * Optional placeholder interpolation - -## Requirements - -* Go 1.19 or higher. We aim to support the 3 latest versions of Go. -* MySQL (5.7+) and MariaDB (10.3+) are supported. -* [TiDB](https://github.com/pingcap/tidb) is supported by PingCAP. - * Do not ask questions about TiDB in our issue tracker or forum. - * [Document](https://docs.pingcap.com/tidb/v6.1/dev-guide-sample-application-golang) - * [Forum](https://ask.pingcap.com/) -* go-mysql would work with Percona Server, Google CloudSQL or Sphinx (2.2.3+). - * Maintainers won't support them. Do not expect issues are investigated and resolved by maintainers. - * Investigate issues yourself and please send a pull request to fix it. - ---------------------------------------- - -## Installation -Simple install the package to your [$GOPATH](https://github.com/golang/go/wiki/GOPATH "GOPATH") with the [go tool](https://golang.org/cmd/go/ "go command") from shell: -```bash -go get -u github.com/go-sql-driver/mysql -``` -Make sure [Git is installed](https://git-scm.com/downloads) on your machine and in your system's `PATH`. - -## Usage -_Go MySQL Driver_ is an implementation of Go's `database/sql/driver` interface. You only need to import the driver and can use the full [`database/sql`](https://golang.org/pkg/database/sql/) API then. - -Use `mysql` as `driverName` and a valid [DSN](#dsn-data-source-name) as `dataSourceName`: - -```go -import ( - "database/sql" - "time" - - _ "github.com/go-sql-driver/mysql" -) - -// ... - -db, err := sql.Open("mysql", "user:password@/dbname") -if err != nil { - panic(err) -} -// See "Important settings" section. -db.SetConnMaxLifetime(time.Minute * 3) -db.SetMaxOpenConns(10) -db.SetMaxIdleConns(10) -``` - -[Examples are available in our Wiki](https://github.com/go-sql-driver/mysql/wiki/Examples "Go-MySQL-Driver Examples"). - -### Important settings - -`db.SetConnMaxLifetime()` is required to ensure connections are closed by the driver safely before connection is closed by MySQL server, OS, or other middlewares. Since some middlewares close idle connections by 5 minutes, we recommend timeout shorter than 5 minutes. This setting helps load balancing and changing system variables too. - -`db.SetMaxOpenConns()` is highly recommended to limit the number of connection used by the application. There is no recommended limit number because it depends on application and MySQL server. - -`db.SetMaxIdleConns()` is recommended to be set same to `db.SetMaxOpenConns()`. When it is smaller than `SetMaxOpenConns()`, connections can be opened and closed much more frequently than you expect. Idle connections can be closed by the `db.SetConnMaxLifetime()`. If you want to close idle connections more rapidly, you can use `db.SetConnMaxIdleTime()` since Go 1.15. - - -### DSN (Data Source Name) - -The Data Source Name has a common format, like e.g. [PEAR DB](http://pear.php.net/manual/en/package.database.db.intro-dsn.php) uses it, but without type-prefix (optional parts marked by squared brackets): -``` -[username[:password]@][protocol[(address)]]/dbname[?param1=value1&...¶mN=valueN] -``` - -A DSN in its fullest form: -``` -username:password@protocol(address)/dbname?param=value -``` - -Except for the databasename, all values are optional. So the minimal DSN is: -``` -/dbname -``` - -If you do not want to preselect a database, leave `dbname` empty: -``` -/ -``` -This has the same effect as an empty DSN string: -``` - -``` - -`dbname` is escaped by [PathEscape()](https://pkg.go.dev/net/url#PathEscape) since v1.8.0. If your database name is `dbname/withslash`, it becomes: - -``` -/dbname%2Fwithslash -``` - -Alternatively, [Config.FormatDSN](https://godoc.org/github.com/go-sql-driver/mysql#Config.FormatDSN) can be used to create a DSN string by filling a struct. - -#### Password -Passwords can consist of any character. Escaping is **not** necessary. - -#### Protocol -See [net.Dial](https://golang.org/pkg/net/#Dial) for more information which networks are available. -In general you should use a Unix domain socket if available and TCP otherwise for best performance. - -#### Address -For TCP and UDP networks, addresses have the form `host[:port]`. -If `port` is omitted, the default port will be used. -If `host` is a literal IPv6 address, it must be enclosed in square brackets. -The functions [net.JoinHostPort](https://golang.org/pkg/net/#JoinHostPort) and [net.SplitHostPort](https://golang.org/pkg/net/#SplitHostPort) manipulate addresses in this form. - -For Unix domain sockets the address is the absolute path to the MySQL-Server-socket, e.g. `/var/run/mysqld/mysqld.sock` or `/tmp/mysql.sock`. - -#### Parameters -*Parameters are case-sensitive!* - -Notice that any of `true`, `TRUE`, `True` or `1` is accepted to stand for a true boolean value. Not surprisingly, false can be specified as any of: `false`, `FALSE`, `False` or `0`. - -##### `allowAllFiles` - -``` -Type: bool -Valid Values: true, false -Default: false -``` - -`allowAllFiles=true` disables the file allowlist for `LOAD DATA LOCAL INFILE` and allows *all* files. -[*Might be insecure!*](https://dev.mysql.com/doc/refman/8.0/en/load-data.html#load-data-local) - -##### `allowCleartextPasswords` - -``` -Type: bool -Valid Values: true, false -Default: false -``` - -`allowCleartextPasswords=true` allows using the [cleartext client side plugin](https://dev.mysql.com/doc/en/cleartext-pluggable-authentication.html) if required by an account, such as one defined with the [PAM authentication plugin](http://dev.mysql.com/doc/en/pam-authentication-plugin.html). Sending passwords in clear text may be a security problem in some configurations. To avoid problems if there is any possibility that the password would be intercepted, clients should connect to MySQL Server using a method that protects the password. Possibilities include [TLS / SSL](#tls), IPsec, or a private network. - - -##### `allowFallbackToPlaintext` - -``` -Type: bool -Valid Values: true, false -Default: false -``` - -`allowFallbackToPlaintext=true` acts like a `--ssl-mode=PREFERRED` MySQL client as described in [Command Options for Connecting to the Server](https://dev.mysql.com/doc/refman/5.7/en/connection-options.html#option_general_ssl-mode) - -##### `allowNativePasswords` - -``` -Type: bool -Valid Values: true, false -Default: true -``` -`allowNativePasswords=false` disallows the usage of MySQL native password method. - -##### `allowOldPasswords` - -``` -Type: bool -Valid Values: true, false -Default: false -``` -`allowOldPasswords=true` allows the usage of the insecure old password method. This should be avoided, but is necessary in some cases. See also [the old_passwords wiki page](https://github.com/go-sql-driver/mysql/wiki/old_passwords). - -##### `charset` - -``` -Type: string -Valid Values: -Default: none -``` - -Sets the charset used for client-server interaction (`"SET NAMES "`). If multiple charsets are set (separated by a comma), the following charset is used if setting the charset fails. This enables for example support for `utf8mb4` ([introduced in MySQL 5.5.3](http://dev.mysql.com/doc/refman/5.5/en/charset-unicode-utf8mb4.html)) with fallback to `utf8` for older servers (`charset=utf8mb4,utf8`). - -See also [Unicode Support](#unicode-support). - -##### `checkConnLiveness` - -``` -Type: bool -Valid Values: true, false -Default: true -``` - -On supported platforms connections retrieved from the connection pool are checked for liveness before using them. If the check fails, the respective connection is marked as bad and the query retried with another connection. -`checkConnLiveness=false` disables this liveness check of connections. - -##### `collation` - -``` -Type: string -Valid Values: -Default: utf8mb4_general_ci -``` - -Sets the collation used for client-server interaction on connection. In contrast to `charset`, `collation` does not issue additional queries. If the specified collation is unavailable on the target server, the connection will fail. - -A list of valid charsets for a server is retrievable with `SHOW COLLATION`. - -The default collation (`utf8mb4_general_ci`) is supported from MySQL 5.5. You should use an older collation (e.g. `utf8_general_ci`) for older MySQL. - -Collations for charset "ucs2", "utf16", "utf16le", and "utf32" can not be used ([ref](https://dev.mysql.com/doc/refman/5.7/en/charset-connection.html#charset-connection-impermissible-client-charset)). - -See also [Unicode Support](#unicode-support). - -##### `clientFoundRows` - -``` -Type: bool -Valid Values: true, false -Default: false -``` - -`clientFoundRows=true` causes an UPDATE to return the number of matching rows instead of the number of rows changed. - -##### `columnsWithAlias` - -``` -Type: bool -Valid Values: true, false -Default: false -``` - -When `columnsWithAlias` is true, calls to `sql.Rows.Columns()` will return the table alias and the column name separated by a dot. For example: - -``` -SELECT u.id FROM users as u -``` - -will return `u.id` instead of just `id` if `columnsWithAlias=true`. - -##### `interpolateParams` - -``` -Type: bool -Valid Values: true, false -Default: false -``` - -If `interpolateParams` is true, placeholders (`?`) in calls to `db.Query()` and `db.Exec()` are interpolated into a single query string with given parameters. This reduces the number of roundtrips, since the driver has to prepare a statement, execute it with given parameters and close the statement again with `interpolateParams=false`. - -*This can not be used together with the multibyte encodings BIG5, CP932, GB2312, GBK or SJIS. These are rejected as they may [introduce a SQL injection vulnerability](http://stackoverflow.com/a/12118602/3430118)!* - -##### `loc` - -``` -Type: string -Valid Values: -Default: UTC -``` - -Sets the location for time.Time values (when using `parseTime=true`). *"Local"* sets the system's location. See [time.LoadLocation](https://golang.org/pkg/time/#LoadLocation) for details. - -Note that this sets the location for time.Time values but does not change MySQL's [time_zone setting](https://dev.mysql.com/doc/refman/5.5/en/time-zone-support.html). For that see the [time_zone system variable](#system-variables), which can also be set as a DSN parameter. - -Please keep in mind, that param values must be [url.QueryEscape](https://golang.org/pkg/net/url/#QueryEscape)'ed. Alternatively you can manually replace the `/` with `%2F`. For example `US/Pacific` would be `loc=US%2FPacific`. - -##### `timeTruncate` - -``` -Type: duration -Default: 0 -``` - -[Truncate time values](https://pkg.go.dev/time#Duration.Truncate) to the specified duration. The value must be a decimal number with a unit suffix (*"ms"*, *"s"*, *"m"*, *"h"*), such as *"30s"*, *"0.5m"* or *"1m30s"*. - -##### `maxAllowedPacket` -``` -Type: decimal number -Default: 64*1024*1024 -``` - -Max packet size allowed in bytes. The default value is 64 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` - -``` -Type: bool -Valid Values: true, false -Default: false -``` - -Allow multiple statements in one query. This can be used to bach multiple queries. Use [Rows.NextResultSet()](https://pkg.go.dev/database/sql#Rows.NextResultSet) to get result of the second and subsequent queries. - -When `multiStatements` is used, `?` parameters must only be used in the first statement. [interpolateParams](#interpolateparams) can be used to avoid this limitation unless prepared statement is used explicitly. - -It's possible to access the last inserted ID and number of affected rows for multiple statements by using `sql.Conn.Raw()` and the `mysql.Result`. For example: - -```go -conn, _ := db.Conn(ctx) -conn.Raw(func(conn any) error { - ex := conn.(driver.Execer) - res, err := ex.Exec(` - UPDATE point SET x = 1 WHERE y = 2; - UPDATE point SET x = 2 WHERE y = 3; - `, nil) - // Both slices have 2 elements. - log.Print(res.(mysql.Result).AllRowsAffected()) - log.Print(res.(mysql.Result).AllLastInsertIds()) -}) -``` - -##### `parseTime` - -``` -Type: bool -Valid Values: true, false -Default: false -``` - -`parseTime=true` changes the output type of `DATE` and `DATETIME` values to `time.Time` instead of `[]byte` / `string` -The date or datetime like `0000-00-00 00:00:00` is converted into zero value of `time.Time`. - - -##### `readTimeout` - -``` -Type: duration -Default: 0 -``` - -I/O read timeout. The value must be a decimal number with a unit suffix (*"ms"*, *"s"*, *"m"*, *"h"*), such as *"30s"*, *"0.5m"* or *"1m30s"*. - -##### `rejectReadOnly` - -``` -Type: bool -Valid Values: true, false -Default: false -``` - - -`rejectReadOnly=true` causes the driver to reject read-only connections. This -is for a possible race condition during an automatic failover, where the mysql -client gets connected to a read-only replica after the failover. - -Note that this should be a fairly rare case, as an automatic failover normally -happens when the primary is down, and the race condition shouldn't happen -unless it comes back up online as soon as the failover is kicked off. On the -other hand, when this happens, a MySQL application can get stuck on a -read-only connection until restarted. It is however fairly easy to reproduce, -for example, using a manual failover on AWS Aurora's MySQL-compatible cluster. - -If you are not relying on read-only transactions to reject writes that aren't -supposed to happen, setting this on some MySQL providers (such as AWS Aurora) -is safer for failovers. - -Note that ERROR 1290 can be returned for a `read-only` server and this option will -cause a retry for that error. However the same error number is used for some -other cases. You should ensure your application will never cause an ERROR 1290 -except for `read-only` mode when enabling this option. - - -##### `serverPubKey` - -``` -Type: string -Valid Values: -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` - -``` -Type: duration -Default: OS default -``` - -Timeout for establishing connections, aka dial timeout. The value must be a decimal number with a unit suffix (*"ms"*, *"s"*, *"m"*, *"h"*), such as *"30s"*, *"0.5m"* or *"1m30s"*. - - -##### `tls` - -``` -Type: bool / string -Valid Values: true, false, skip-verify, preferred, -Default: false -``` - -`tls=true` enables TLS / SSL encrypted connection to the server. Use `skip-verify` if you want to use a self-signed or invalid certificate (server side) or use `preferred` to use TLS only when advertised by the server. This is similar to `skip-verify`, but additionally allows a fallback to a connection which is not encrypted. Neither `skip-verify` nor `preferred` add any reliable security. You can use a custom TLS config after registering it with [`mysql.RegisterTLSConfig`](https://godoc.org/github.com/go-sql-driver/mysql#RegisterTLSConfig). - - -##### `writeTimeout` - -``` -Type: duration -Default: 0 -``` - -I/O write timeout. The value must be a decimal number with a unit suffix (*"ms"*, *"s"*, *"m"*, *"h"*), such as *"30s"*, *"0.5m"* or *"1m30s"*. - -##### `connectionAttributes` - -``` -Type: comma-delimited string of user-defined "key:value" pairs -Valid Values: (:,:,...) -Default: none -``` - -[Connection attributes](https://dev.mysql.com/doc/refman/8.0/en/performance-schema-connection-attribute-tables.html) are key-value pairs that application programs can pass to the server at connect time. - -##### System Variables - -Any other parameters are interpreted as system variables: - * `=`: `SET =` - * `=`: `SET =` - * `=%27%27`: `SET =''` - -Rules: -* The values for string variables must be quoted with `'`. -* The values must also be [url.QueryEscape](http://golang.org/pkg/net/url/#QueryEscape)'ed! - (which implies values of string variables must be wrapped with `%27`). - -Examples: - * `autocommit=1`: `SET autocommit=1` - * [`time_zone=%27Europe%2FParis%27`](https://dev.mysql.com/doc/refman/5.5/en/time-zone-support.html): `SET time_zone='Europe/Paris'` - * [`transaction_isolation=%27REPEATABLE-READ%27`](https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_transaction_isolation): `SET transaction_isolation='REPEATABLE-READ'` - - -#### Examples -``` -user@unix(/path/to/socket)/dbname -``` - -``` -root:pw@unix(/tmp/mysql.sock)/myDatabase?loc=Local -``` - -``` -user:password@tcp(localhost:5555)/dbname?tls=skip-verify&autocommit=true -``` - -Treat warnings as errors by setting the system variable [`sql_mode`](https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html): -``` -user:password@/dbname?sql_mode=TRADITIONAL -``` - -TCP via IPv6: -``` -user:password@tcp([de:ad:be:ef::ca:fe]:80)/dbname?timeout=90s&collation=utf8mb4_unicode_ci -``` - -TCP on a remote host, e.g. Amazon RDS: -``` -id:password@tcp(your-amazonaws-uri.com:3306)/dbname -``` - -Google Cloud SQL on App Engine: -``` -user:password@unix(/cloudsql/project-id:region-name:instance-name)/dbname -``` - -TCP using default port (3306) on localhost: -``` -user:password@tcp/dbname?charset=utf8mb4,utf8&sys_var=esc%40ped -``` - -Use the default protocol (tcp) and host (localhost:3306): -``` -user:password@/dbname -``` - -No Database preselected: -``` -user:password@/ -``` - - -### 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. - -## `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. All Unsigned database type names will be returned `UNSIGNED ` with `INT`, `TINYINT`, `SMALLINT`, `MEDIUMINT`, `BIGINT`. - -## `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 -For this feature you need direct access to the package. Therefore you must change the import path (no `_`): -```go -import "github.com/go-sql-driver/mysql" -``` - -Files must be explicitly allowed by registering them with `mysql.RegisterLocalFile(filepath)` (recommended) or the allowlist check must be deactivated by using the DSN parameter `allowAllFiles=true` ([*Might be insecure!*](https://dev.mysql.com/doc/refman/8.0/en/load-data.html#load-data-local)). - -To use a `io.Reader` a handler function must be registered with `mysql.RegisterReaderHandler(name, handler)` which returns a `io.Reader` or `io.ReadCloser`. The Reader is available with the filepath `Reader::` then. Choose different names for different handlers and `DeregisterReaderHandler` when you don't need it anymore. - -See the [godoc of Go-MySQL-Driver](https://godoc.org/github.com/go-sql-driver/mysql "golang mysql driver documentation") for details. - - -### `time.Time` support -The default internal output type of MySQL `DATE` and `DATETIME` values is `[]byte` which allows you to scan the value into a `[]byte`, `string` or `sql.RawBytes` variable in your program. - -However, many want to scan MySQL `DATE` and `DATETIME` values into `time.Time` variables, which is the logical equivalent in Go to `DATE` and `DATETIME` in MySQL. You can do that by changing the internal output type from `[]byte` to `time.Time` with the DSN parameter `parseTime=true`. You can set the default [`time.Time` location](https://golang.org/pkg/time/#Location) with the `loc` DSN parameter. - -**Caution:** As of Go 1.1, this makes `time.Time` the only variable type you can scan `DATE` and `DATETIME` values into. This breaks for example [`sql.RawBytes` support](https://github.com/go-sql-driver/mysql/wiki/Examples#rawbytes). - - -### Unicode support -Since version 1.5 Go-MySQL-Driver automatically uses the collation ` utf8mb4_general_ci` by default. - -Other charsets / collations can be set using the [`charset`](#charset) or [`collation`](#collation) DSN parameter. - -- When only the `charset` is specified, the `SET NAMES ` query is sent and the server's default collation is used. -- When both the `charset` and `collation` are specified, the `SET NAMES COLLATE ` query is sent. -- When only the `collation` is specified, the collation is specified in the protocol handshake and the `SET NAMES` query is not sent. This can save one roundtrip, but note that the server may ignore the specified collation silently and use the server's default charset/collation instead. - -See http://dev.mysql.com/doc/refman/8.0/en/charset-unicode.html for more details on MySQL's Unicode support. - -## Testing / Development -To run the driver tests you may need to adjust the configuration. See the [Testing Wiki-Page](https://github.com/go-sql-driver/mysql/wiki/Testing "Testing") for details. - -Go-MySQL-Driver is not feature-complete yet. Your help is very appreciated. -If you want to contribute, you can work on an [open issue](https://github.com/go-sql-driver/mysql/issues?state=open) or review a [pull request](https://github.com/go-sql-driver/mysql/pulls). - -See the [Contribution Guidelines](https://github.com/go-sql-driver/mysql/blob/master/.github/CONTRIBUTING.md) for details. - ---------------------------------------- - -## License -Go-MySQL-Driver is licensed under the [Mozilla Public License Version 2.0](https://raw.github.com/go-sql-driver/mysql/master/LICENSE) - -Mozilla summarizes the license scope as follows: -> MPL: The copyleft applies to any files containing MPLed code. - - -That means: - * You can **use** the **unchanged** source code both in private and commercially. - * When distributing, you **must publish** the source code of any **changed files** licensed under the MPL 2.0 under a) the MPL 2.0 itself or b) a compatible license (e.g. GPL 3.0 or Apache License 2.0). - * You **needn't publish** the source code of your library as long as the files licensed under the MPL 2.0 are **unchanged**. - -Please read the [MPL 2.0 FAQ](https://www.mozilla.org/en-US/MPL/2.0/FAQ/) if you have further questions regarding the license. - -You can read the full terms here: [LICENSE](https://raw.github.com/go-sql-driver/mysql/master/LICENSE). - -![Go Gopher and MySQL Dolphin](https://raw.github.com/wiki/go-sql-driver/mysql/go-mysql-driver_m.jpg "Golang Gopher transporting the MySQL Dolphin in a wheelbarrow") diff --git a/v2/vendor/github.com/go-sql-driver/mysql/atomic_bool.go b/v2/vendor/github.com/go-sql-driver/mysql/atomic_bool.go deleted file mode 100644 index 1b7e19f..0000000 --- a/v2/vendor/github.com/go-sql-driver/mysql/atomic_bool.go +++ /dev/null @@ -1,19 +0,0 @@ -// Go MySQL Driver - A MySQL-Driver for Go's database/sql package. -// -// Copyright 2022 The Go-MySQL-Driver Authors. All rights reserved. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this file, -// You can obtain one at http://mozilla.org/MPL/2.0/. -//go:build go1.19 -// +build go1.19 - -package mysql - -import "sync/atomic" - -/****************************************************************************** -* Sync utils * -******************************************************************************/ - -type atomicBool = atomic.Bool diff --git a/v2/vendor/github.com/go-sql-driver/mysql/atomic_bool_go118.go b/v2/vendor/github.com/go-sql-driver/mysql/atomic_bool_go118.go deleted file mode 100644 index 2e9a7f0..0000000 --- a/v2/vendor/github.com/go-sql-driver/mysql/atomic_bool_go118.go +++ /dev/null @@ -1,47 +0,0 @@ -// Go MySQL Driver - A MySQL-Driver for Go's database/sql package. -// -// Copyright 2022 The Go-MySQL-Driver Authors. All rights reserved. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this file, -// You can obtain one at http://mozilla.org/MPL/2.0/. -//go:build !go1.19 -// +build !go1.19 - -package mysql - -import "sync/atomic" - -/****************************************************************************** -* Sync utils * -******************************************************************************/ - -// atomicBool is an implementation of atomic.Bool for older version of Go. -// it is a wrapper around uint32 for usage as a boolean value with -// atomic access. -type atomicBool struct { - _ noCopy - value uint32 -} - -// Load returns whether the current boolean value is true -func (ab *atomicBool) Load() bool { - return atomic.LoadUint32(&ab.value) > 0 -} - -// Store sets the value of the bool regardless of the previous value -func (ab *atomicBool) Store(value bool) { - if value { - atomic.StoreUint32(&ab.value, 1) - } else { - atomic.StoreUint32(&ab.value, 0) - } -} - -// Swap sets the value of the bool and returns the old value. -func (ab *atomicBool) Swap(value bool) bool { - if value { - return atomic.SwapUint32(&ab.value, 1) > 0 - } - return atomic.SwapUint32(&ab.value, 0) > 0 -} diff --git a/v2/vendor/github.com/go-sql-driver/mysql/auth.go b/v2/vendor/github.com/go-sql-driver/mysql/auth.go deleted file mode 100644 index 74e1bd0..0000000 --- a/v2/vendor/github.com/go-sql-driver/mysql/auth.go +++ /dev/null @@ -1,484 +0,0 @@ -// 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/sha512" - "crypto/x509" - "encoding/pem" - "fmt" - "sync" - - "filippo.io/edwards25519" -) - -// 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= 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 := os.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 { - 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) -} - -// authEd25519 does ed25519 authentication used by MariaDB. -func authEd25519(scramble []byte, password string) ([]byte, error) { - // Derived from https://github.com/MariaDB/server/blob/d8e6bb00888b1f82c031938f4c8ac5d97f6874c3/plugin/auth_ed25519/ref10/sign.c - // Code style is from https://cs.opensource.google/go/go/+/refs/tags/go1.21.5:src/crypto/ed25519/ed25519.go;l=207 - h := sha512.Sum512([]byte(password)) - - s, err := edwards25519.NewScalar().SetBytesWithClamping(h[:32]) - if err != nil { - return nil, err - } - A := (&edwards25519.Point{}).ScalarBaseMult(s) - - mh := sha512.New() - mh.Write(h[32:]) - mh.Write(scramble) - messageDigest := mh.Sum(nil) - r, err := edwards25519.NewScalar().SetUniformBytes(messageDigest) - if err != nil { - return nil, err - } - - R := (&edwards25519.Point{}).ScalarBaseMult(r) - - kh := sha512.New() - kh.Write(R.Bytes()) - kh.Write(A.Bytes()) - kh.Write(scramble) - hramDigest := kh.Sum(nil) - k, err := edwards25519.NewScalar().SetUniformBytes(hramDigest) - if err != nil { - return nil, err - } - - S := k.MultiplyAdd(k, s, r) - - return append(R.Bytes(), S.Bytes()...), 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 - } - if len(mc.cfg.Passwd) == 0 { - return nil, nil - } - // 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 - } - // unlike caching_sha2_password, sha256_password does not accept - // cleartext password on unix transport. - if mc.cfg.TLS != nil { - // 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 - - case "client_ed25519": - if len(authData) != 32 { - return nil, ErrMalformPkt - } - return authEd25519(authData, mc.cfg.Passwd) - - default: - mc.log("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://dev.mysql.com/blog-archive/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.resultUnchanged().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, err := mc.buf.takeSmallBuffer(4 + 1) - if err != nil { - return err - } - data[4] = cachingSha2PasswordRequestPublicKey - err = mc.writePacket(data) - if err != nil { - return err - } - - if data, err = mc.readPacket(); err != nil { - return err - } - - if data[0] != iAuthMoreData { - return fmt.Errorf("unexpected resp from server for caching_sha2_password, perform full authentication") - } - - // parse public key - block, rest := pem.Decode(data[1:]) - if block == nil { - return fmt.Errorf("no pem data found, data: %s", rest) - } - 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.resultUnchanged().readResultOK() - - default: - return ErrMalformPkt - } - default: - return ErrMalformPkt - } - - case "sha256_password": - switch len(authData) { - case 0: - return nil // auth successful - default: - block, _ := pem.Decode(authData) - if block == nil { - return fmt.Errorf("no Pem data found, data: %s", 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.resultUnchanged().readResultOK() - } - - default: - return nil // auth successful - } - - return err -} diff --git a/v2/vendor/github.com/go-sql-driver/mysql/buffer.go b/v2/vendor/github.com/go-sql-driver/mysql/buffer.go deleted file mode 100644 index 0774c5c..0000000 --- a/v2/vendor/github.com/go-sql-driver/mysql/buffer.go +++ /dev/null @@ -1,182 +0,0 @@ -// Go MySQL Driver - A MySQL-Driver for Go's database/sql package -// -// Copyright 2013 The Go-MySQL-Driver Authors. All rights reserved. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this file, -// You can obtain one at http://mozilla.org/MPL/2.0/. - -package mysql - -import ( - "io" - "net" - "time" -) - -const defaultBufSize = 4096 -const maxCachedBufSize = 256 * 1024 - -// A buffer which is used for both reading and writing. -// This is possible since communication on each connection is synchronous. -// In other words, we can't write and read simultaneously on the same connection. -// The buffer is similar to bufio.Reader / Writer but zero-copy-ish -// Also highly optimized for this particular use case. -// This buffer is backed by two byte slices in a double-buffering scheme -type buffer struct { - buf []byte // buf is a byte buffer who's length and capacity are equal. - nc net.Conn - idx int - length int - timeout time.Duration - dbuf [2][]byte // dbuf is an array with the two byte slices that back this buffer - flipcnt uint // flipccnt is the current buffer counter for double-buffering -} - -// newBuffer allocates and returns a new buffer. -func newBuffer(nc net.Conn) buffer { - fg := make([]byte, defaultBufSize) - return buffer{ - buf: fg, - nc: nc, - dbuf: [2][]byte{fg, nil}, - } -} - -// flip replaces the active buffer with the background buffer -// this is a delayed flip that simply increases the buffer counter; -// the actual flip will be performed the next time we call `buffer.fill` -func (b *buffer) flip() { - b.flipcnt += 1 -} - -// fill reads into the buffer until at least _need_ bytes are in it -func (b *buffer) fill(need int) error { - n := b.length - // fill data into its double-buffering target: if we've called - // flip on this buffer, we'll be copying to the background buffer, - // and then filling it with network data; otherwise we'll just move - // the contents of the current buffer to the front before filling it - dest := b.dbuf[b.flipcnt&1] - - // grow buffer if necessary to fit the whole packet. - if need > len(dest) { - // Round up to the next multiple of the default size - dest = make([]byte, ((need/defaultBufSize)+1)*defaultBufSize) - - // if the allocated buffer is not too large, move it to backing storage - // to prevent extra allocations on applications that perform large reads - if len(dest) <= maxCachedBufSize { - b.dbuf[b.flipcnt&1] = dest - } - } - - // if we're filling the fg buffer, move the existing data to the start of it. - // if we're filling the bg buffer, copy over the data - if n > 0 { - copy(dest[:n], b.buf[b.idx:]) - } - - b.buf = dest - b.idx = 0 - - for { - if b.timeout > 0 { - if err := b.nc.SetReadDeadline(time.Now().Add(b.timeout)); err != nil { - return err - } - } - - nn, err := b.nc.Read(b.buf[n:]) - n += nn - - switch err { - case nil: - if n < need { - continue - } - b.length = n - return nil - - case io.EOF: - if n >= need { - b.length = n - return nil - } - return io.ErrUnexpectedEOF - - default: - return err - } - } -} - -// returns next N bytes from buffer. -// The returned slice is only guaranteed to be valid until the next read -func (b *buffer) readNext(need int) ([]byte, error) { - if b.length < need { - // refill - if err := b.fill(need); err != nil { - return nil, err - } - } - - offset := b.idx - b.idx += need - b.length -= need - return b.buf[offset:b.idx], nil -} - -// takeBuffer returns a buffer with the requested size. -// If possible, a slice from the existing buffer is returned. -// Otherwise a bigger buffer is made. -// Only one buffer (total) can be used at a time. -func (b *buffer) takeBuffer(length int) ([]byte, error) { - if b.length > 0 { - return nil, ErrBusyBuffer - } - - // test (cheap) general case first - if length <= cap(b.buf) { - return b.buf[:length], nil - } - - if length < maxPacketSize { - b.buf = make([]byte, length) - return b.buf, nil - } - - // buffer is larger than we want to store. - return make([]byte, length), nil -} - -// takeSmallBuffer is shortcut which can be used if length is -// known to be smaller than defaultBufSize. -// Only one buffer (total) can be used at a time. -func (b *buffer) takeSmallBuffer(length int) ([]byte, error) { - if b.length > 0 { - return nil, ErrBusyBuffer - } - return b.buf[:length], nil -} - -// takeCompleteBuffer returns the complete existing buffer. -// This can be used if the necessary buffer size is unknown. -// cap and len of the returned buffer will be equal. -// Only one buffer (total) can be used at a time. -func (b *buffer) takeCompleteBuffer() ([]byte, error) { - if b.length > 0 { - return nil, ErrBusyBuffer - } - return b.buf, nil -} - -// store stores buf, an updated buffer, if its suitable to do so. -func (b *buffer) store(buf []byte) error { - if b.length > 0 { - return ErrBusyBuffer - } else if cap(buf) <= maxPacketSize && cap(buf) > cap(b.buf) { - b.buf = buf[:cap(buf)] - } - return nil -} diff --git a/v2/vendor/github.com/go-sql-driver/mysql/collations.go b/v2/vendor/github.com/go-sql-driver/mysql/collations.go deleted file mode 100644 index 1cdf97b..0000000 --- a/v2/vendor/github.com/go-sql-driver/mysql/collations.go +++ /dev/null @@ -1,266 +0,0 @@ -// Go MySQL Driver - A MySQL-Driver for Go's database/sql package -// -// Copyright 2014 The Go-MySQL-Driver Authors. All rights reserved. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this file, -// You can obtain one at http://mozilla.org/MPL/2.0/. - -package mysql - -const defaultCollation = "utf8mb4_general_ci" -const binaryCollationID = 63 - -// A list of available collations mapped to the internal ID. -// To update this map use the following MySQL query: -// -// SELECT COLLATION_NAME, ID FROM information_schema.COLLATIONS WHERE ID<256 ORDER BY ID -// -// Handshake packet have only 1 byte for collation_id. So we can't use collations with ID > 255. -// -// ucs2, utf16, and utf32 can't be used for connection charset. -// https://dev.mysql.com/doc/refman/5.7/en/charset-connection.html#charset-connection-impermissible-client-charset -// They are commented out to reduce this map. -var collations = map[string]byte{ - "big5_chinese_ci": 1, - "latin2_czech_cs": 2, - "dec8_swedish_ci": 3, - "cp850_general_ci": 4, - "latin1_german1_ci": 5, - "hp8_english_ci": 6, - "koi8r_general_ci": 7, - "latin1_swedish_ci": 8, - "latin2_general_ci": 9, - "swe7_swedish_ci": 10, - "ascii_general_ci": 11, - "ujis_japanese_ci": 12, - "sjis_japanese_ci": 13, - "cp1251_bulgarian_ci": 14, - "latin1_danish_ci": 15, - "hebrew_general_ci": 16, - "tis620_thai_ci": 18, - "euckr_korean_ci": 19, - "latin7_estonian_cs": 20, - "latin2_hungarian_ci": 21, - "koi8u_general_ci": 22, - "cp1251_ukrainian_ci": 23, - "gb2312_chinese_ci": 24, - "greek_general_ci": 25, - "cp1250_general_ci": 26, - "latin2_croatian_ci": 27, - "gbk_chinese_ci": 28, - "cp1257_lithuanian_ci": 29, - "latin5_turkish_ci": 30, - "latin1_german2_ci": 31, - "armscii8_general_ci": 32, - "utf8_general_ci": 33, - "cp1250_czech_cs": 34, - //"ucs2_general_ci": 35, - "cp866_general_ci": 36, - "keybcs2_general_ci": 37, - "macce_general_ci": 38, - "macroman_general_ci": 39, - "cp852_general_ci": 40, - "latin7_general_ci": 41, - "latin7_general_cs": 42, - "macce_bin": 43, - "cp1250_croatian_ci": 44, - "utf8mb4_general_ci": 45, - "utf8mb4_bin": 46, - "latin1_bin": 47, - "latin1_general_ci": 48, - "latin1_general_cs": 49, - "cp1251_bin": 50, - "cp1251_general_ci": 51, - "cp1251_general_cs": 52, - "macroman_bin": 53, - //"utf16_general_ci": 54, - //"utf16_bin": 55, - //"utf16le_general_ci": 56, - "cp1256_general_ci": 57, - "cp1257_bin": 58, - "cp1257_general_ci": 59, - //"utf32_general_ci": 60, - //"utf32_bin": 61, - //"utf16le_bin": 62, - "binary": 63, - "armscii8_bin": 64, - "ascii_bin": 65, - "cp1250_bin": 66, - "cp1256_bin": 67, - "cp866_bin": 68, - "dec8_bin": 69, - "greek_bin": 70, - "hebrew_bin": 71, - "hp8_bin": 72, - "keybcs2_bin": 73, - "koi8r_bin": 74, - "koi8u_bin": 75, - "utf8_tolower_ci": 76, - "latin2_bin": 77, - "latin5_bin": 78, - "latin7_bin": 79, - "cp850_bin": 80, - "cp852_bin": 81, - "swe7_bin": 82, - "utf8_bin": 83, - "big5_bin": 84, - "euckr_bin": 85, - "gb2312_bin": 86, - "gbk_bin": 87, - "sjis_bin": 88, - "tis620_bin": 89, - //"ucs2_bin": 90, - "ujis_bin": 91, - "geostd8_general_ci": 92, - "geostd8_bin": 93, - "latin1_spanish_ci": 94, - "cp932_japanese_ci": 95, - "cp932_bin": 96, - "eucjpms_japanese_ci": 97, - "eucjpms_bin": 98, - "cp1250_polish_ci": 99, - //"utf16_unicode_ci": 101, - //"utf16_icelandic_ci": 102, - //"utf16_latvian_ci": 103, - //"utf16_romanian_ci": 104, - //"utf16_slovenian_ci": 105, - //"utf16_polish_ci": 106, - //"utf16_estonian_ci": 107, - //"utf16_spanish_ci": 108, - //"utf16_swedish_ci": 109, - //"utf16_turkish_ci": 110, - //"utf16_czech_ci": 111, - //"utf16_danish_ci": 112, - //"utf16_lithuanian_ci": 113, - //"utf16_slovak_ci": 114, - //"utf16_spanish2_ci": 115, - //"utf16_roman_ci": 116, - //"utf16_persian_ci": 117, - //"utf16_esperanto_ci": 118, - //"utf16_hungarian_ci": 119, - //"utf16_sinhala_ci": 120, - //"utf16_german2_ci": 121, - //"utf16_croatian_ci": 122, - //"utf16_unicode_520_ci": 123, - //"utf16_vietnamese_ci": 124, - //"ucs2_unicode_ci": 128, - //"ucs2_icelandic_ci": 129, - //"ucs2_latvian_ci": 130, - //"ucs2_romanian_ci": 131, - //"ucs2_slovenian_ci": 132, - //"ucs2_polish_ci": 133, - //"ucs2_estonian_ci": 134, - //"ucs2_spanish_ci": 135, - //"ucs2_swedish_ci": 136, - //"ucs2_turkish_ci": 137, - //"ucs2_czech_ci": 138, - //"ucs2_danish_ci": 139, - //"ucs2_lithuanian_ci": 140, - //"ucs2_slovak_ci": 141, - //"ucs2_spanish2_ci": 142, - //"ucs2_roman_ci": 143, - //"ucs2_persian_ci": 144, - //"ucs2_esperanto_ci": 145, - //"ucs2_hungarian_ci": 146, - //"ucs2_sinhala_ci": 147, - //"ucs2_german2_ci": 148, - //"ucs2_croatian_ci": 149, - //"ucs2_unicode_520_ci": 150, - //"ucs2_vietnamese_ci": 151, - //"ucs2_general_mysql500_ci": 159, - //"utf32_unicode_ci": 160, - //"utf32_icelandic_ci": 161, - //"utf32_latvian_ci": 162, - //"utf32_romanian_ci": 163, - //"utf32_slovenian_ci": 164, - //"utf32_polish_ci": 165, - //"utf32_estonian_ci": 166, - //"utf32_spanish_ci": 167, - //"utf32_swedish_ci": 168, - //"utf32_turkish_ci": 169, - //"utf32_czech_ci": 170, - //"utf32_danish_ci": 171, - //"utf32_lithuanian_ci": 172, - //"utf32_slovak_ci": 173, - //"utf32_spanish2_ci": 174, - //"utf32_roman_ci": 175, - //"utf32_persian_ci": 176, - //"utf32_esperanto_ci": 177, - //"utf32_hungarian_ci": 178, - //"utf32_sinhala_ci": 179, - //"utf32_german2_ci": 180, - //"utf32_croatian_ci": 181, - //"utf32_unicode_520_ci": 182, - //"utf32_vietnamese_ci": 183, - "utf8_unicode_ci": 192, - "utf8_icelandic_ci": 193, - "utf8_latvian_ci": 194, - "utf8_romanian_ci": 195, - "utf8_slovenian_ci": 196, - "utf8_polish_ci": 197, - "utf8_estonian_ci": 198, - "utf8_spanish_ci": 199, - "utf8_swedish_ci": 200, - "utf8_turkish_ci": 201, - "utf8_czech_ci": 202, - "utf8_danish_ci": 203, - "utf8_lithuanian_ci": 204, - "utf8_slovak_ci": 205, - "utf8_spanish2_ci": 206, - "utf8_roman_ci": 207, - "utf8_persian_ci": 208, - "utf8_esperanto_ci": 209, - "utf8_hungarian_ci": 210, - "utf8_sinhala_ci": 211, - "utf8_german2_ci": 212, - "utf8_croatian_ci": 213, - "utf8_unicode_520_ci": 214, - "utf8_vietnamese_ci": 215, - "utf8_general_mysql500_ci": 223, - "utf8mb4_unicode_ci": 224, - "utf8mb4_icelandic_ci": 225, - "utf8mb4_latvian_ci": 226, - "utf8mb4_romanian_ci": 227, - "utf8mb4_slovenian_ci": 228, - "utf8mb4_polish_ci": 229, - "utf8mb4_estonian_ci": 230, - "utf8mb4_spanish_ci": 231, - "utf8mb4_swedish_ci": 232, - "utf8mb4_turkish_ci": 233, - "utf8mb4_czech_ci": 234, - "utf8mb4_danish_ci": 235, - "utf8mb4_lithuanian_ci": 236, - "utf8mb4_slovak_ci": 237, - "utf8mb4_spanish2_ci": 238, - "utf8mb4_roman_ci": 239, - "utf8mb4_persian_ci": 240, - "utf8mb4_esperanto_ci": 241, - "utf8mb4_hungarian_ci": 242, - "utf8mb4_sinhala_ci": 243, - "utf8mb4_german2_ci": 244, - "utf8mb4_croatian_ci": 245, - "utf8mb4_unicode_520_ci": 246, - "utf8mb4_vietnamese_ci": 247, - "gb18030_chinese_ci": 248, - "gb18030_bin": 249, - "gb18030_unicode_520_ci": 250, - "utf8mb4_0900_ai_ci": 255, -} - -// A denylist of collations which is unsafe to interpolate parameters. -// These multibyte encodings may contains 0x5c (`\`) in their trailing bytes. -var unsafeCollations = map[string]bool{ - "big5_chinese_ci": true, - "sjis_japanese_ci": true, - "gbk_chinese_ci": true, - "big5_bin": true, - "gb2312_bin": true, - "gbk_bin": true, - "sjis_bin": true, - "cp932_japanese_ci": true, - "cp932_bin": true, - "gb18030_chinese_ci": true, - "gb18030_bin": true, - "gb18030_unicode_520_ci": true, -} diff --git a/v2/vendor/github.com/go-sql-driver/mysql/conncheck.go b/v2/vendor/github.com/go-sql-driver/mysql/conncheck.go deleted file mode 100644 index 0ea7217..0000000 --- a/v2/vendor/github.com/go-sql-driver/mysql/conncheck.go +++ /dev/null @@ -1,55 +0,0 @@ -// Go MySQL Driver - A MySQL-Driver for Go's database/sql package -// -// Copyright 2019 The Go-MySQL-Driver Authors. All rights reserved. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this file, -// You can obtain one at http://mozilla.org/MPL/2.0/. - -//go:build linux || darwin || dragonfly || freebsd || netbsd || openbsd || solaris || illumos -// +build linux darwin dragonfly freebsd netbsd openbsd solaris illumos - -package mysql - -import ( - "errors" - "io" - "net" - "syscall" -) - -var errUnexpectedRead = errors.New("unexpected read from socket") - -func connCheck(conn net.Conn) error { - var sysErr error - - sysConn, ok := conn.(syscall.Conn) - if !ok { - return nil - } - rawConn, err := sysConn.SyscallConn() - if err != nil { - return err - } - - err = rawConn.Read(func(fd uintptr) bool { - var buf [1]byte - n, err := syscall.Read(int(fd), buf[:]) - switch { - case n == 0 && err == nil: - sysErr = io.EOF - case n > 0: - sysErr = errUnexpectedRead - case err == syscall.EAGAIN || err == syscall.EWOULDBLOCK: - sysErr = nil - default: - sysErr = err - } - return true - }) - if err != nil { - return err - } - - return sysErr -} diff --git a/v2/vendor/github.com/go-sql-driver/mysql/conncheck_dummy.go b/v2/vendor/github.com/go-sql-driver/mysql/conncheck_dummy.go deleted file mode 100644 index a56c138..0000000 --- a/v2/vendor/github.com/go-sql-driver/mysql/conncheck_dummy.go +++ /dev/null @@ -1,18 +0,0 @@ -// Go MySQL Driver - A MySQL-Driver for Go's database/sql package -// -// Copyright 2019 The Go-MySQL-Driver Authors. All rights reserved. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this file, -// You can obtain one at http://mozilla.org/MPL/2.0/. - -//go:build !linux && !darwin && !dragonfly && !freebsd && !netbsd && !openbsd && !solaris && !illumos -// +build !linux,!darwin,!dragonfly,!freebsd,!netbsd,!openbsd,!solaris,!illumos - -package mysql - -import "net" - -func connCheck(conn net.Conn) error { - return nil -} diff --git a/v2/vendor/github.com/go-sql-driver/mysql/connection.go b/v2/vendor/github.com/go-sql-driver/mysql/connection.go deleted file mode 100644 index eff978d..0000000 --- a/v2/vendor/github.com/go-sql-driver/mysql/connection.go +++ /dev/null @@ -1,688 +0,0 @@ -// Go MySQL Driver - A MySQL-Driver for Go's database/sql package -// -// Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this file, -// You can obtain one at http://mozilla.org/MPL/2.0/. - -package mysql - -import ( - "context" - "database/sql" - "database/sql/driver" - "encoding/json" - "io" - "net" - "strconv" - "strings" - "time" -) - -type mysqlConn struct { - buf buffer - netConn net.Conn - rawConn net.Conn // underlying connection when netConn is TLS connection. - result mysqlResult // managed by clearResult() and handleOkPacket(). - cfg *Config - connector *connector - maxAllowedPacket int - maxWriteSize int - writeTimeout time.Duration - flags clientFlag - status statusFlag - sequence uint8 - parseTime bool - - // for context support (Go 1.8+) - watching bool - watcher chan<- context.Context - closech chan struct{} - finished chan<- struct{} - canceled atomicError // set non-nil if conn is canceled - closed atomicBool // set when conn is closed, before closech is closed -} - -// Helper function to call per-connection logger. -func (mc *mysqlConn) log(v ...any) { - mc.cfg.Logger.Print(v...) -} - -// Handles parameters set in DSN after the connection is established -func (mc *mysqlConn) handleParams() (err error) { - var cmdSet strings.Builder - - for param, val := range mc.cfg.Params { - switch param { - // Charset: character_set_connection, character_set_client, character_set_results - case "charset": - charsets := strings.Split(val, ",") - for _, cs := range charsets { - // ignore errors here - a charset may not exist - if mc.cfg.Collation != "" { - err = mc.exec("SET NAMES " + cs + " COLLATE " + mc.cfg.Collation) - } else { - err = mc.exec("SET NAMES " + cs) - } - if err == nil { - break - } - } - if err != nil { - return - } - - // Other system vars accumulated in a single SET command - default: - if cmdSet.Len() == 0 { - // Heuristic: 29 chars for each other key=value to reduce reallocations - cmdSet.Grow(4 + len(param) + 3 + len(val) + 30*(len(mc.cfg.Params)-1)) - cmdSet.WriteString("SET ") - } else { - cmdSet.WriteString(", ") - } - cmdSet.WriteString(param) - cmdSet.WriteString(" = ") - cmdSet.WriteString(val) - } - } - - if cmdSet.Len() > 0 { - err = mc.exec(cmdSet.String()) - if err != nil { - return - } - } - - return -} - -func (mc *mysqlConn) markBadConn(err error) error { - if mc == nil { - return err - } - if err != errBadConnNoWrite { - return err - } - return driver.ErrBadConn -} - -func (mc *mysqlConn) Begin() (driver.Tx, error) { - return mc.begin(false) -} - -func (mc *mysqlConn) begin(readOnly bool) (driver.Tx, error) { - if mc.closed.Load() { - mc.log(ErrInvalidConn) - return nil, driver.ErrBadConn - } - var q string - if readOnly { - q = "START TRANSACTION READ ONLY" - } else { - q = "START TRANSACTION" - } - err := mc.exec(q) - if err == nil { - return &mysqlTx{mc}, err - } - return nil, mc.markBadConn(err) -} - -func (mc *mysqlConn) Close() (err error) { - // Makes Close idempotent - if !mc.closed.Load() { - err = mc.writeCommandPacket(comQuit) - } - - mc.cleanup() - mc.clearResult() - return -} - -// Closes the network connection and unsets internal variables. Do not call this -// function after successfully authentication, call Close instead. This function -// is called before auth or on auth failure because MySQL will have already -// closed the network connection. -func (mc *mysqlConn) cleanup() { - if mc.closed.Swap(true) { - return - } - - // Makes cleanup idempotent - close(mc.closech) - conn := mc.rawConn - if conn == nil { - return - } - if err := conn.Close(); err != nil { - mc.log(err) - } - // This function can be called from multiple goroutines. - // So we can not mc.clearResult() here. - // Caller should do it if they are in safe goroutine. -} - -func (mc *mysqlConn) error() error { - if mc.closed.Load() { - if err := mc.canceled.Value(); err != nil { - return err - } - return ErrInvalidConn - } - return nil -} - -func (mc *mysqlConn) Prepare(query string) (driver.Stmt, error) { - if mc.closed.Load() { - mc.log(ErrInvalidConn) - return nil, driver.ErrBadConn - } - // Send command - err := mc.writeCommandPacketStr(comStmtPrepare, query) - if err != nil { - // STMT_PREPARE is safe to retry. So we can return ErrBadConn here. - mc.log(err) - return nil, driver.ErrBadConn - } - - stmt := &mysqlStmt{ - mc: mc, - } - - // Read Result - columnCount, err := stmt.readPrepareResultPacket() - if err == nil { - if stmt.paramCount > 0 { - if err = mc.readUntilEOF(); err != nil { - return nil, err - } - } - - if columnCount > 0 { - err = mc.readUntilEOF() - } - } - - return stmt, err -} - -func (mc *mysqlConn) interpolateParams(query string, args []driver.Value) (string, error) { - // Number of ? should be same to len(args) - if strings.Count(query, "?") != len(args) { - return "", driver.ErrSkip - } - - buf, err := mc.buf.takeCompleteBuffer() - if err != nil { - // can not take the buffer. Something must be wrong with the connection - mc.log(err) - return "", ErrInvalidConn - } - buf = buf[:0] - argPos := 0 - - for i := 0; i < len(query); i++ { - q := strings.IndexByte(query[i:], '?') - if q == -1 { - buf = append(buf, query[i:]...) - break - } - buf = append(buf, query[i:i+q]...) - i += q - - arg := args[argPos] - argPos++ - - if arg == nil { - buf = append(buf, "NULL"...) - continue - } - - switch v := arg.(type) { - case int64: - buf = strconv.AppendInt(buf, v, 10) - case uint64: - // Handle uint64 explicitly because our custom ConvertValue emits unsigned values - buf = strconv.AppendUint(buf, v, 10) - case float64: - buf = strconv.AppendFloat(buf, v, 'g', -1, 64) - case bool: - if v { - buf = append(buf, '1') - } else { - buf = append(buf, '0') - } - case time.Time: - if v.IsZero() { - buf = append(buf, "'0000-00-00'"...) - } else { - buf = append(buf, '\'') - buf, err = appendDateTime(buf, v.In(mc.cfg.Loc), mc.cfg.timeTruncate) - if err != nil { - return "", err - } - buf = append(buf, '\'') - } - case json.RawMessage: - buf = append(buf, '\'') - if mc.status&statusNoBackslashEscapes == 0 { - buf = escapeBytesBackslash(buf, v) - } else { - buf = escapeBytesQuotes(buf, v) - } - buf = append(buf, '\'') - case []byte: - if v == nil { - buf = append(buf, "NULL"...) - } else { - buf = append(buf, "_binary'"...) - if mc.status&statusNoBackslashEscapes == 0 { - buf = escapeBytesBackslash(buf, v) - } else { - buf = escapeBytesQuotes(buf, v) - } - buf = append(buf, '\'') - } - case string: - buf = append(buf, '\'') - if mc.status&statusNoBackslashEscapes == 0 { - buf = escapeStringBackslash(buf, v) - } else { - buf = escapeStringQuotes(buf, v) - } - buf = append(buf, '\'') - default: - return "", driver.ErrSkip - } - - if len(buf)+4 > mc.maxAllowedPacket { - return "", driver.ErrSkip - } - } - if argPos != len(args) { - return "", driver.ErrSkip - } - return string(buf), nil -} - -func (mc *mysqlConn) Exec(query string, args []driver.Value) (driver.Result, error) { - if mc.closed.Load() { - mc.log(ErrInvalidConn) - return nil, driver.ErrBadConn - } - if len(args) != 0 { - if !mc.cfg.InterpolateParams { - return nil, driver.ErrSkip - } - // try to interpolate the parameters to save extra roundtrips for preparing and closing a statement - prepared, err := mc.interpolateParams(query, args) - if err != nil { - return nil, err - } - query = prepared - } - - err := mc.exec(query) - if err == nil { - copied := mc.result - return &copied, err - } - return nil, mc.markBadConn(err) -} - -// Internal function to execute commands -func (mc *mysqlConn) exec(query string) error { - handleOk := mc.clearResult() - // Send command - if err := mc.writeCommandPacketStr(comQuery, query); err != nil { - return mc.markBadConn(err) - } - - // Read Result - resLen, err := handleOk.readResultSetHeaderPacket() - if err != nil { - return err - } - - if resLen > 0 { - // columns - if err := mc.readUntilEOF(); err != nil { - return err - } - - // rows - if err := mc.readUntilEOF(); err != nil { - return err - } - } - - return handleOk.discardResults() -} - -func (mc *mysqlConn) Query(query string, args []driver.Value) (driver.Rows, error) { - return mc.query(query, args) -} - -func (mc *mysqlConn) query(query string, args []driver.Value) (*textRows, error) { - handleOk := mc.clearResult() - - if mc.closed.Load() { - mc.log(ErrInvalidConn) - return nil, driver.ErrBadConn - } - if len(args) != 0 { - if !mc.cfg.InterpolateParams { - return nil, driver.ErrSkip - } - // try client-side prepare to reduce roundtrip - prepared, err := mc.interpolateParams(query, args) - if err != nil { - return nil, err - } - query = prepared - } - // Send command - err := mc.writeCommandPacketStr(comQuery, query) - if err == nil { - // Read Result - var resLen int - resLen, err = handleOk.readResultSetHeaderPacket() - if err == nil { - rows := new(textRows) - rows.mc = mc - - if resLen == 0 { - rows.rs.done = true - - switch err := rows.NextResultSet(); err { - case nil, io.EOF: - return rows, nil - default: - return nil, err - } - } - - // Columns - rows.rs.columns, err = mc.readColumns(resLen) - return rows, err - } - } - return nil, mc.markBadConn(err) -} - -// Gets the value of the given MySQL System Variable -// The returned byte slice is only valid until the next read -func (mc *mysqlConn) getSystemVar(name string) ([]byte, error) { - // Send command - handleOk := mc.clearResult() - if err := mc.writeCommandPacketStr(comQuery, "SELECT @@"+name); err != nil { - return nil, err - } - - // Read Result - resLen, err := handleOk.readResultSetHeaderPacket() - if err == nil { - rows := new(textRows) - rows.mc = mc - rows.rs.columns = []mysqlField{{fieldType: fieldTypeVarChar}} - - if resLen > 0 { - // Columns - if err := mc.readUntilEOF(); err != nil { - return nil, err - } - } - - dest := make([]driver.Value, resLen) - if err = rows.readRow(dest); err == nil { - return dest[0].([]byte), mc.readUntilEOF() - } - } - return nil, err -} - -// finish is called when the query has canceled. -func (mc *mysqlConn) cancel(err error) { - mc.canceled.Set(err) - mc.cleanup() -} - -// finish is called when the query has succeeded. -func (mc *mysqlConn) finish() { - if !mc.watching || mc.finished == nil { - return - } - select { - case mc.finished <- struct{}{}: - mc.watching = false - case <-mc.closech: - } -} - -// Ping implements driver.Pinger interface -func (mc *mysqlConn) Ping(ctx context.Context) (err error) { - if mc.closed.Load() { - mc.log(ErrInvalidConn) - return driver.ErrBadConn - } - - if err = mc.watchCancel(ctx); err != nil { - return - } - defer mc.finish() - - handleOk := mc.clearResult() - if err = mc.writeCommandPacket(comPing); err != nil { - return mc.markBadConn(err) - } - - return handleOk.readResultOK() -} - -// BeginTx implements driver.ConnBeginTx interface -func (mc *mysqlConn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, error) { - if mc.closed.Load() { - return nil, driver.ErrBadConn - } - - if err := mc.watchCancel(ctx); err != nil { - return nil, err - } - defer mc.finish() - - if sql.IsolationLevel(opts.Isolation) != sql.LevelDefault { - level, err := mapIsolationLevel(opts.Isolation) - if err != nil { - return nil, err - } - err = mc.exec("SET TRANSACTION ISOLATION LEVEL " + level) - if err != nil { - return nil, err - } - } - - return mc.begin(opts.ReadOnly) -} - -func (mc *mysqlConn) QueryContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Rows, error) { - dargs, err := namedValueToValue(args) - if err != nil { - return nil, err - } - - if err := mc.watchCancel(ctx); err != nil { - return nil, err - } - - rows, err := mc.query(query, dargs) - if err != nil { - mc.finish() - return nil, err - } - rows.finish = mc.finish - return rows, err -} - -func (mc *mysqlConn) ExecContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Result, error) { - dargs, err := namedValueToValue(args) - if err != nil { - return nil, err - } - - if err := mc.watchCancel(ctx); err != nil { - return nil, err - } - defer mc.finish() - - return mc.Exec(query, dargs) -} - -func (mc *mysqlConn) PrepareContext(ctx context.Context, query string) (driver.Stmt, error) { - if err := mc.watchCancel(ctx); err != nil { - return nil, err - } - - stmt, err := mc.Prepare(query) - mc.finish() - if err != nil { - return nil, err - } - - select { - default: - case <-ctx.Done(): - stmt.Close() - return nil, ctx.Err() - } - return stmt, nil -} - -func (stmt *mysqlStmt) QueryContext(ctx context.Context, args []driver.NamedValue) (driver.Rows, error) { - dargs, err := namedValueToValue(args) - if err != nil { - return nil, err - } - - if err := stmt.mc.watchCancel(ctx); err != nil { - return nil, err - } - - rows, err := stmt.query(dargs) - if err != nil { - stmt.mc.finish() - return nil, err - } - rows.finish = stmt.mc.finish - return rows, err -} - -func (stmt *mysqlStmt) ExecContext(ctx context.Context, args []driver.NamedValue) (driver.Result, error) { - dargs, err := namedValueToValue(args) - if err != nil { - return nil, err - } - - if err := stmt.mc.watchCancel(ctx); err != nil { - return nil, err - } - defer stmt.mc.finish() - - return stmt.Exec(dargs) -} - -func (mc *mysqlConn) watchCancel(ctx context.Context) error { - if mc.watching { - // Reach here if canceled, - // so the connection is already invalid - mc.cleanup() - return nil - } - // 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 { - return nil - } - // When watcher is not alive, can't watch it. - if mc.watcher == nil { - return nil - } - - mc.watching = true - mc.watcher <- ctx - return nil -} - -func (mc *mysqlConn) startWatcher() { - watcher := make(chan context.Context, 1) - mc.watcher = watcher - finished := make(chan struct{}) - mc.finished = finished - go func() { - for { - var ctx context.Context - select { - case ctx = <-watcher: - case <-mc.closech: - return - } - - select { - case <-ctx.Done(): - mc.cancel(ctx.Err()) - case <-finished: - case <-mc.closech: - return - } - } - }() -} - -func (mc *mysqlConn) CheckNamedValue(nv *driver.NamedValue) (err error) { - nv.Value, err = converter{}.ConvertValue(nv.Value) - return -} - -// ResetSession implements driver.SessionResetter. -// (From Go 1.10) -func (mc *mysqlConn) ResetSession(ctx context.Context) error { - if mc.closed.Load() { - return driver.ErrBadConn - } - - // Perform a stale connection check. We only perform this check for - // the first query on a connection that has been checked out of the - // connection pool: a fresh connection from the pool is more likely - // to be stale, and it has not performed any previous writes that - // could cause data corruption, so it's safe to return ErrBadConn - // if the check fails. - if mc.cfg.CheckConnLiveness { - conn := mc.netConn - if mc.rawConn != nil { - conn = mc.rawConn - } - var err error - if mc.cfg.ReadTimeout != 0 { - err = conn.SetReadDeadline(time.Now().Add(mc.cfg.ReadTimeout)) - } - if err == nil { - err = connCheck(conn) - } - if err != nil { - mc.log("closing bad idle connection: ", err) - return driver.ErrBadConn - } - } - - return nil -} - -// IsValid implements driver.Validator interface -// (From Go 1.15) -func (mc *mysqlConn) IsValid() bool { - return !mc.closed.Load() -} diff --git a/v2/vendor/github.com/go-sql-driver/mysql/connector.go b/v2/vendor/github.com/go-sql-driver/mysql/connector.go deleted file mode 100644 index b670775..0000000 --- a/v2/vendor/github.com/go-sql-driver/mysql/connector.go +++ /dev/null @@ -1,197 +0,0 @@ -// 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 ( - "context" - "database/sql/driver" - "net" - "os" - "strconv" - "strings" -) - -type connector struct { - cfg *Config // immutable private copy. - encodedAttributes string // Encoded connection attributes. -} - -func encodeConnectionAttributes(cfg *Config) string { - connAttrsBuf := make([]byte, 0) - - // default connection attributes - connAttrsBuf = appendLengthEncodedString(connAttrsBuf, connAttrClientName) - connAttrsBuf = appendLengthEncodedString(connAttrsBuf, connAttrClientNameValue) - connAttrsBuf = appendLengthEncodedString(connAttrsBuf, connAttrOS) - connAttrsBuf = appendLengthEncodedString(connAttrsBuf, connAttrOSValue) - connAttrsBuf = appendLengthEncodedString(connAttrsBuf, connAttrPlatform) - connAttrsBuf = appendLengthEncodedString(connAttrsBuf, connAttrPlatformValue) - connAttrsBuf = appendLengthEncodedString(connAttrsBuf, connAttrPid) - connAttrsBuf = appendLengthEncodedString(connAttrsBuf, strconv.Itoa(os.Getpid())) - serverHost, _, _ := net.SplitHostPort(cfg.Addr) - if serverHost != "" { - connAttrsBuf = appendLengthEncodedString(connAttrsBuf, connAttrServerHost) - connAttrsBuf = appendLengthEncodedString(connAttrsBuf, serverHost) - } - - // user-defined connection attributes - for _, connAttr := range strings.Split(cfg.ConnectionAttributes, ",") { - k, v, found := strings.Cut(connAttr, ":") - if !found { - continue - } - connAttrsBuf = appendLengthEncodedString(connAttrsBuf, k) - connAttrsBuf = appendLengthEncodedString(connAttrsBuf, v) - } - - return string(connAttrsBuf) -} - -func newConnector(cfg *Config) *connector { - encodedAttributes := encodeConnectionAttributes(cfg) - return &connector{ - cfg: cfg, - encodedAttributes: encodedAttributes, - } -} - -// Connect implements driver.Connector interface. -// Connect returns a connection to the database. -func (c *connector) Connect(ctx context.Context) (driver.Conn, error) { - var err error - - // Invoke beforeConnect if present, with a copy of the configuration - cfg := c.cfg - if c.cfg.beforeConnect != nil { - cfg = c.cfg.Clone() - err = c.cfg.beforeConnect(ctx, cfg) - if err != nil { - return nil, err - } - } - - // New mysqlConn - mc := &mysqlConn{ - maxAllowedPacket: maxPacketSize, - maxWriteSize: maxPacketSize - 1, - closech: make(chan struct{}), - cfg: cfg, - connector: c, - } - mc.parseTime = mc.cfg.ParseTime - - // Connect to Server - dialsLock.RLock() - dial, ok := dials[mc.cfg.Net] - dialsLock.RUnlock() - if ok { - dctx := ctx - if mc.cfg.Timeout > 0 { - var cancel context.CancelFunc - dctx, cancel = context.WithTimeout(ctx, c.cfg.Timeout) - defer cancel() - } - mc.netConn, err = dial(dctx, mc.cfg.Addr) - } else { - nd := net.Dialer{Timeout: mc.cfg.Timeout} - mc.netConn, err = nd.DialContext(ctx, mc.cfg.Net, mc.cfg.Addr) - } - if err != nil { - return nil, err - } - mc.rawConn = mc.netConn - - // Enable TCP Keepalives on TCP connections - if tc, ok := mc.netConn.(*net.TCPConn); ok { - if err := tc.SetKeepAlive(true); err != nil { - c.cfg.Logger.Print(err) - } - } - - // Call startWatcher for context support (From Go 1.8) - mc.startWatcher() - if err := mc.watchCancel(ctx); err != nil { - mc.cleanup() - return nil, err - } - defer mc.finish() - - mc.buf = newBuffer(mc.netConn) - - // Set I/O timeouts - mc.buf.timeout = mc.cfg.ReadTimeout - mc.writeTimeout = mc.cfg.WriteTimeout - - // Reading Handshake Initialization Packet - authData, plugin, err := mc.readHandshakePacket() - if err != nil { - mc.cleanup() - return nil, err - } - - if plugin == "" { - plugin = defaultAuthPlugin - } - - // Send Client Authentication Packet - authResp, err := mc.auth(authData, plugin) - if err != nil { - // try the default auth plugin, if using the requested plugin failed - c.cfg.Logger.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() - return nil, err - } - - // Handle response to auth packet, switch methods if possible - if err = mc.handleAuthResult(authData, plugin); err != nil { - // Authentication failed and MySQL has already closed the connection - // (https://dev.mysql.com/doc/internals/en/authentication-fails.html). - // Do not send COM_QUIT, just cleanup and return the error. - mc.cleanup() - return nil, err - } - - if mc.cfg.MaxAllowedPacket > 0 { - mc.maxAllowedPacket = mc.cfg.MaxAllowedPacket - } else { - // Get max allowed packet size - maxap, err := mc.getSystemVar("max_allowed_packet") - if err != nil { - mc.Close() - return nil, err - } - mc.maxAllowedPacket = stringToInt(maxap) - 1 - } - if mc.maxAllowedPacket < maxPacketSize { - mc.maxWriteSize = mc.maxAllowedPacket - } - - // Handle DSN Params - err = mc.handleParams() - if err != nil { - mc.Close() - return nil, err - } - - return mc, nil -} - -// Driver implements driver.Connector interface. -// Driver returns &MySQLDriver{}. -func (c *connector) Driver() driver.Driver { - return &MySQLDriver{} -} diff --git a/v2/vendor/github.com/go-sql-driver/mysql/const.go b/v2/vendor/github.com/go-sql-driver/mysql/const.go deleted file mode 100644 index 22526e0..0000000 --- a/v2/vendor/github.com/go-sql-driver/mysql/const.go +++ /dev/null @@ -1,187 +0,0 @@ -// Go MySQL Driver - A MySQL-Driver for Go's database/sql package -// -// Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this file, -// You can obtain one at http://mozilla.org/MPL/2.0/. - -package mysql - -import "runtime" - -const ( - defaultAuthPlugin = "mysql_native_password" - defaultMaxAllowedPacket = 64 << 20 // 64 MiB. See https://github.com/go-sql-driver/mysql/issues/1355 - minProtocolVersion = 10 - maxPacketSize = 1<<24 - 1 - timeFormat = "2006-01-02 15:04:05.999999" - - // Connection attributes - // See https://dev.mysql.com/doc/refman/8.0/en/performance-schema-connection-attribute-tables.html#performance-schema-connection-attributes-available - connAttrClientName = "_client_name" - connAttrClientNameValue = "Go-MySQL-Driver" - connAttrOS = "_os" - connAttrOSValue = runtime.GOOS - connAttrPlatform = "_platform" - connAttrPlatformValue = runtime.GOARCH - connAttrPid = "_pid" - connAttrServerHost = "_server_host" -) - -// MySQL constants documentation: -// http://dev.mysql.com/doc/internals/en/client-server-protocol.html - -const ( - iOK byte = 0x00 - iAuthMoreData byte = 0x01 - iLocalInFile byte = 0xfb - iEOF byte = 0xfe - iERR byte = 0xff -) - -// https://dev.mysql.com/doc/internals/en/capability-flags.html#packet-Protocol::CapabilityFlags -type clientFlag uint32 - -const ( - clientLongPassword clientFlag = 1 << iota - clientFoundRows - clientLongFlag - clientConnectWithDB - clientNoSchema - clientCompress - clientODBC - clientLocalFiles - clientIgnoreSpace - clientProtocol41 - clientInteractive - clientSSL - clientIgnoreSIGPIPE - clientTransactions - clientReserved - clientSecureConn - clientMultiStatements - clientMultiResults - clientPSMultiResults - clientPluginAuth - clientConnectAttrs - clientPluginAuthLenEncClientData - clientCanHandleExpiredPasswords - clientSessionTrack - clientDeprecateEOF -) - -const ( - comQuit byte = iota + 1 - comInitDB - comQuery - comFieldList - comCreateDB - comDropDB - comRefresh - comShutdown - comStatistics - comProcessInfo - comConnect - comProcessKill - comDebug - comPing - comTime - comDelayedInsert - comChangeUser - comBinlogDump - comTableDump - comConnectOut - comRegisterSlave - comStmtPrepare - comStmtExecute - comStmtSendLongData - comStmtClose - comStmtReset - comSetOption - comStmtFetch -) - -// https://dev.mysql.com/doc/internals/en/com-query-response.html#packet-Protocol::ColumnType -type fieldType byte - -const ( - fieldTypeDecimal fieldType = iota - fieldTypeTiny - fieldTypeShort - fieldTypeLong - fieldTypeFloat - fieldTypeDouble - fieldTypeNULL - fieldTypeTimestamp - fieldTypeLongLong - fieldTypeInt24 - fieldTypeDate - fieldTypeTime - fieldTypeDateTime - fieldTypeYear - fieldTypeNewDate - fieldTypeVarChar - fieldTypeBit -) -const ( - fieldTypeJSON fieldType = iota + 0xf5 - fieldTypeNewDecimal - fieldTypeEnum - fieldTypeSet - fieldTypeTinyBLOB - fieldTypeMediumBLOB - fieldTypeLongBLOB - fieldTypeBLOB - fieldTypeVarString - fieldTypeString - fieldTypeGeometry -) - -type fieldFlag uint16 - -const ( - flagNotNULL fieldFlag = 1 << iota - flagPriKey - flagUniqueKey - flagMultipleKey - flagBLOB - flagUnsigned - flagZeroFill - flagBinary - flagEnum - flagAutoIncrement - flagTimestamp - flagSet - flagUnknown1 - flagUnknown2 - flagUnknown3 - flagUnknown4 -) - -// http://dev.mysql.com/doc/internals/en/status-flags.html -type statusFlag uint16 - -const ( - statusInTrans statusFlag = 1 << iota - statusInAutocommit - statusReserved // Not in documentation - statusMoreResultsExists - statusNoGoodIndexUsed - statusNoIndexUsed - statusCursorExists - statusLastRowSent - statusDbDropped - statusNoBackslashEscapes - statusMetadataChanged - statusQueryWasSlow - statusPsOutParams - statusInTransReadonly - statusSessionStateChanged -) - -const ( - cachingSha2PasswordRequestPublicKey = 2 - cachingSha2PasswordFastAuthSuccess = 3 - cachingSha2PasswordPerformFullAuthentication = 4 -) diff --git a/v2/vendor/github.com/go-sql-driver/mysql/driver.go b/v2/vendor/github.com/go-sql-driver/mysql/driver.go deleted file mode 100644 index 105316b..0000000 --- a/v2/vendor/github.com/go-sql-driver/mysql/driver.go +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this file, -// You can obtain one at http://mozilla.org/MPL/2.0/. - -// Package mysql provides a MySQL driver for Go's database/sql package. -// -// The driver should be used via the database/sql package: -// -// import "database/sql" -// import _ "github.com/go-sql-driver/mysql" -// -// db, err := sql.Open("mysql", "user:password@/dbname") -// -// See https://github.com/go-sql-driver/mysql#usage for details -package mysql - -import ( - "context" - "database/sql" - "database/sql/driver" - "net" - "sync" -) - -// MySQLDriver is exported to make the driver directly accessible. -// In general the driver is used via the database/sql package. -type MySQLDriver struct{} - -// DialFunc is a function which can be used to establish the network connection. -// Custom dial functions must be registered with RegisterDial -// -// Deprecated: users should register a DialContextFunc instead -type DialFunc func(addr string) (net.Conn, error) - -// DialContextFunc is a function which can be used to establish the network connection. -// Custom dial functions must be registered with RegisterDialContext -type DialContextFunc func(ctx context.Context, addr string) (net.Conn, error) - -var ( - dialsLock sync.RWMutex - dials map[string]DialContextFunc -) - -// RegisterDialContext registers a custom dial function. It can then be used by the -// network address mynet(addr), where mynet is the registered new network. -// The current context for the connection and its address is passed to the dial function. -func RegisterDialContext(net string, dial DialContextFunc) { - dialsLock.Lock() - defer dialsLock.Unlock() - if dials == nil { - dials = make(map[string]DialContextFunc) - } - dials[net] = dial -} - -// DeregisterDialContext removes the custom dial function registered with the given net. -func DeregisterDialContext(net string) { - dialsLock.Lock() - defer dialsLock.Unlock() - if dials != nil { - delete(dials, net) - } -} - -// RegisterDial registers a custom dial function. It can then be used by the -// network address mynet(addr), where mynet is the registered new network. -// addr is passed as a parameter to the dial function. -// -// Deprecated: users should call RegisterDialContext instead -func RegisterDial(network string, dial DialFunc) { - RegisterDialContext(network, func(_ context.Context, addr string) (net.Conn, error) { - return dial(addr) - }) -} - -// Open new Connection. -// See https://github.com/go-sql-driver/mysql#dsn-data-source-name for how -// the DSN string is formatted -func (d MySQLDriver) Open(dsn string) (driver.Conn, error) { - cfg, err := ParseDSN(dsn) - if err != nil { - return nil, err - } - c := newConnector(cfg) - return c.Connect(context.Background()) -} - -// This variable can be replaced with -ldflags like below: -// go build "-ldflags=-X github.com/go-sql-driver/mysql.driverName=custom" -var driverName = "mysql" - -func init() { - if driverName != "" { - sql.Register(driverName, &MySQLDriver{}) - } -} - -// NewConnector returns new driver.Connector. -func NewConnector(cfg *Config) (driver.Connector, error) { - cfg = cfg.Clone() - // normalize the contents of cfg so calls to NewConnector have the same - // behavior as MySQLDriver.OpenConnector - if err := cfg.normalize(); err != nil { - return nil, err - } - return newConnector(cfg), nil -} - -// OpenConnector implements driver.DriverContext. -func (d MySQLDriver) OpenConnector(dsn string) (driver.Connector, error) { - cfg, err := ParseDSN(dsn) - if err != nil { - return nil, err - } - return newConnector(cfg), nil -} diff --git a/v2/vendor/github.com/go-sql-driver/mysql/dsn.go b/v2/vendor/github.com/go-sql-driver/mysql/dsn.go deleted file mode 100644 index 65f5a02..0000000 --- a/v2/vendor/github.com/go-sql-driver/mysql/dsn.go +++ /dev/null @@ -1,653 +0,0 @@ -// Go MySQL Driver - A MySQL-Driver for Go's database/sql package -// -// Copyright 2016 The Go-MySQL-Driver Authors. All rights reserved. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this file, -// You can obtain one at http://mozilla.org/MPL/2.0/. - -package mysql - -import ( - "bytes" - "context" - "crypto/rsa" - "crypto/tls" - "errors" - "fmt" - "math/big" - "net" - "net/url" - "sort" - "strconv" - "strings" - "time" -) - -var ( - errInvalidDSNUnescaped = errors.New("invalid DSN: did you forget to escape a param value?") - errInvalidDSNAddr = errors.New("invalid DSN: network address not terminated (missing closing brace)") - errInvalidDSNNoSlash = errors.New("invalid DSN: missing the slash separating the database name") - errInvalidDSNUnsafeCollation = errors.New("invalid DSN: interpolateParams can not be used with unsafe collations") -) - -// Config is a configuration parsed from a DSN string. -// If a new Config is created instead of being parsed from a DSN string, -// the NewConfig function should be used, which sets default values. -type Config struct { - // non boolean fields - - User string // Username - Passwd string // Password (requires User) - Net string // Network (e.g. "tcp", "tcp6", "unix". default: "tcp") - Addr string // Address (default: "127.0.0.1:3306" for "tcp" and "/tmp/mysql.sock" for "unix") - DBName string // Database name - Params map[string]string // Connection parameters - ConnectionAttributes string // Connection Attributes, comma-delimited string of user-defined "key:value" pairs - Collation string // Connection collation - Loc *time.Location // Location for time.Time values - MaxAllowedPacket int // Max packet size allowed - ServerPubKey string // Server public key name - TLSConfig string // TLS configuration name - TLS *tls.Config // TLS configuration, its priority is higher than TLSConfig - Timeout time.Duration // Dial timeout - ReadTimeout time.Duration // I/O read timeout - WriteTimeout time.Duration // I/O write timeout - Logger Logger // Logger - - // boolean fields - - AllowAllFiles bool // Allow all files to be used with LOAD DATA LOCAL INFILE - AllowCleartextPasswords bool // Allows the cleartext client side plugin - AllowFallbackToPlaintext bool // Allows fallback to unencrypted connection if server does not support TLS - AllowNativePasswords bool // Allows the native password authentication method - AllowOldPasswords bool // Allows the old insecure password method - CheckConnLiveness bool // Check connections for liveness before using them - ClientFoundRows bool // Return number of matching rows instead of rows changed - ColumnsWithAlias bool // Prepend table alias to column names - InterpolateParams bool // Interpolate placeholders into query string - MultiStatements bool // Allow multiple statements in one query - ParseTime bool // Parse time values to time.Time - RejectReadOnly bool // Reject read-only connections - - // unexported fields. new options should be come here - - beforeConnect func(context.Context, *Config) error // Invoked before a connection is established - pubKey *rsa.PublicKey // Server public key - timeTruncate time.Duration // Truncate time.Time values to the specified duration -} - -// Functional Options Pattern -// https://dave.cheney.net/2014/10/17/functional-options-for-friendly-apis -type Option func(*Config) error - -// NewConfig creates a new Config and sets default values. -func NewConfig() *Config { - cfg := &Config{ - Loc: time.UTC, - MaxAllowedPacket: defaultMaxAllowedPacket, - Logger: defaultLogger, - AllowNativePasswords: true, - CheckConnLiveness: true, - } - - return cfg -} - -// Apply applies the given options to the Config object. -func (c *Config) Apply(opts ...Option) error { - for _, opt := range opts { - err := opt(c) - if err != nil { - return err - } - } - return nil -} - -// TimeTruncate sets the time duration to truncate time.Time values in -// query parameters. -func TimeTruncate(d time.Duration) Option { - return func(cfg *Config) error { - cfg.timeTruncate = d - return nil - } -} - -// BeforeConnect sets the function to be invoked before a connection is established. -func BeforeConnect(fn func(context.Context, *Config) error) Option { - return func(cfg *Config) error { - cfg.beforeConnect = fn - return nil - } -} - -func (cfg *Config) Clone() *Config { - cp := *cfg - if cp.TLS != nil { - cp.TLS = cfg.TLS.Clone() - } - if len(cp.Params) > 0 { - cp.Params = make(map[string]string, len(cfg.Params)) - for k, v := range cfg.Params { - cp.Params[k] = v - } - } - if cfg.pubKey != nil { - cp.pubKey = &rsa.PublicKey{ - N: new(big.Int).Set(cfg.pubKey.N), - E: cfg.pubKey.E, - } - } - return &cp -} - -func (cfg *Config) normalize() error { - if cfg.InterpolateParams && cfg.Collation != "" && unsafeCollations[cfg.Collation] { - return errInvalidDSNUnsafeCollation - } - - // Set default network if empty - if cfg.Net == "" { - cfg.Net = "tcp" - } - - // Set default address if empty - if cfg.Addr == "" { - switch cfg.Net { - case "tcp": - cfg.Addr = "127.0.0.1:3306" - case "unix": - cfg.Addr = "/tmp/mysql.sock" - default: - return errors.New("default addr for network '" + cfg.Net + "' unknown") - } - } else if cfg.Net == "tcp" { - cfg.Addr = ensureHavePort(cfg.Addr) - } - - if cfg.TLS == nil { - switch cfg.TLSConfig { - case "false", "": - // don't set anything - case "true": - cfg.TLS = &tls.Config{} - case "skip-verify": - cfg.TLS = &tls.Config{InsecureSkipVerify: true} - case "preferred": - cfg.TLS = &tls.Config{InsecureSkipVerify: true} - cfg.AllowFallbackToPlaintext = true - default: - cfg.TLS = getTLSConfigClone(cfg.TLSConfig) - if cfg.TLS == nil { - return errors.New("invalid value / unknown config name: " + cfg.TLSConfig) - } - } - } - - if cfg.TLS != nil && cfg.TLS.ServerName == "" && !cfg.TLS.InsecureSkipVerify { - host, _, err := net.SplitHostPort(cfg.Addr) - if err == nil { - cfg.TLS.ServerName = host - } - } - - if cfg.ServerPubKey != "" { - cfg.pubKey = getServerPubKey(cfg.ServerPubKey) - if cfg.pubKey == nil { - return errors.New("invalid value / unknown server pub key name: " + cfg.ServerPubKey) - } - } - - if cfg.Logger == nil { - cfg.Logger = defaultLogger - } - - return nil -} - -func writeDSNParam(buf *bytes.Buffer, hasParam *bool, name, value string) { - buf.Grow(1 + len(name) + 1 + len(value)) - if !*hasParam { - *hasParam = true - buf.WriteByte('?') - } else { - buf.WriteByte('&') - } - buf.WriteString(name) - buf.WriteByte('=') - buf.WriteString(value) -} - -// FormatDSN formats the given Config into a DSN string which can be passed to -// the driver. -// -// Note: use [NewConnector] and [database/sql.OpenDB] to open a connection from a [*Config]. -func (cfg *Config) FormatDSN() string { - var buf bytes.Buffer - - // [username[:password]@] - if len(cfg.User) > 0 { - buf.WriteString(cfg.User) - if len(cfg.Passwd) > 0 { - buf.WriteByte(':') - buf.WriteString(cfg.Passwd) - } - buf.WriteByte('@') - } - - // [protocol[(address)]] - if len(cfg.Net) > 0 { - buf.WriteString(cfg.Net) - if len(cfg.Addr) > 0 { - buf.WriteByte('(') - buf.WriteString(cfg.Addr) - buf.WriteByte(')') - } - } - - // /dbname - buf.WriteByte('/') - buf.WriteString(url.PathEscape(cfg.DBName)) - - // [?param1=value1&...¶mN=valueN] - hasParam := false - - if cfg.AllowAllFiles { - hasParam = true - buf.WriteString("?allowAllFiles=true") - } - - if cfg.AllowCleartextPasswords { - writeDSNParam(&buf, &hasParam, "allowCleartextPasswords", "true") - } - - if cfg.AllowFallbackToPlaintext { - writeDSNParam(&buf, &hasParam, "allowFallbackToPlaintext", "true") - } - - if !cfg.AllowNativePasswords { - writeDSNParam(&buf, &hasParam, "allowNativePasswords", "false") - } - - if cfg.AllowOldPasswords { - writeDSNParam(&buf, &hasParam, "allowOldPasswords", "true") - } - - if !cfg.CheckConnLiveness { - writeDSNParam(&buf, &hasParam, "checkConnLiveness", "false") - } - - if cfg.ClientFoundRows { - writeDSNParam(&buf, &hasParam, "clientFoundRows", "true") - } - - if col := cfg.Collation; col != "" { - writeDSNParam(&buf, &hasParam, "collation", col) - } - - if cfg.ColumnsWithAlias { - writeDSNParam(&buf, &hasParam, "columnsWithAlias", "true") - } - - if cfg.InterpolateParams { - writeDSNParam(&buf, &hasParam, "interpolateParams", "true") - } - - if cfg.Loc != time.UTC && cfg.Loc != nil { - writeDSNParam(&buf, &hasParam, "loc", url.QueryEscape(cfg.Loc.String())) - } - - if cfg.MultiStatements { - writeDSNParam(&buf, &hasParam, "multiStatements", "true") - } - - if cfg.ParseTime { - writeDSNParam(&buf, &hasParam, "parseTime", "true") - } - - if cfg.timeTruncate > 0 { - writeDSNParam(&buf, &hasParam, "timeTruncate", cfg.timeTruncate.String()) - } - - if cfg.ReadTimeout > 0 { - writeDSNParam(&buf, &hasParam, "readTimeout", cfg.ReadTimeout.String()) - } - - if cfg.RejectReadOnly { - writeDSNParam(&buf, &hasParam, "rejectReadOnly", "true") - } - - if len(cfg.ServerPubKey) > 0 { - writeDSNParam(&buf, &hasParam, "serverPubKey", url.QueryEscape(cfg.ServerPubKey)) - } - - if cfg.Timeout > 0 { - writeDSNParam(&buf, &hasParam, "timeout", cfg.Timeout.String()) - } - - if len(cfg.TLSConfig) > 0 { - writeDSNParam(&buf, &hasParam, "tls", url.QueryEscape(cfg.TLSConfig)) - } - - if cfg.WriteTimeout > 0 { - writeDSNParam(&buf, &hasParam, "writeTimeout", cfg.WriteTimeout.String()) - } - - if cfg.MaxAllowedPacket != defaultMaxAllowedPacket { - writeDSNParam(&buf, &hasParam, "maxAllowedPacket", strconv.Itoa(cfg.MaxAllowedPacket)) - } - - // other params - if cfg.Params != nil { - var params []string - for param := range cfg.Params { - params = append(params, param) - } - sort.Strings(params) - for _, param := range params { - writeDSNParam(&buf, &hasParam, param, url.QueryEscape(cfg.Params[param])) - } - } - - return buf.String() -} - -// ParseDSN parses the DSN string to a Config -func ParseDSN(dsn string) (cfg *Config, err error) { - // New config with some default values - cfg = NewConfig() - - // [user[:password]@][net[(addr)]]/dbname[?param1=value1¶mN=valueN] - // Find the last '/' (since the password or the net addr might contain a '/') - foundSlash := false - for i := len(dsn) - 1; i >= 0; i-- { - if dsn[i] == '/' { - foundSlash = true - var j, k int - - // left part is empty if i <= 0 - if i > 0 { - // [username[:password]@][protocol[(address)]] - // Find the last '@' in dsn[:i] - for j = i; j >= 0; j-- { - if dsn[j] == '@' { - // username[:password] - // Find the first ':' in dsn[:j] - for k = 0; k < j; k++ { - if dsn[k] == ':' { - cfg.Passwd = dsn[k+1 : j] - break - } - } - cfg.User = dsn[:k] - - break - } - } - - // [protocol[(address)]] - // Find the first '(' in dsn[j+1:i] - for k = j + 1; k < i; k++ { - if dsn[k] == '(' { - // dsn[i-1] must be == ')' if an address is specified - if dsn[i-1] != ')' { - if strings.ContainsRune(dsn[k+1:i], ')') { - return nil, errInvalidDSNUnescaped - } - return nil, errInvalidDSNAddr - } - cfg.Addr = dsn[k+1 : i-1] - break - } - } - cfg.Net = dsn[j+1 : k] - } - - // dbname[?param1=value1&...¶mN=valueN] - // Find the first '?' in dsn[i+1:] - for j = i + 1; j < len(dsn); j++ { - if dsn[j] == '?' { - if err = parseDSNParams(cfg, dsn[j+1:]); err != nil { - return - } - break - } - } - - dbname := dsn[i+1 : j] - if cfg.DBName, err = url.PathUnescape(dbname); err != nil { - return nil, fmt.Errorf("invalid dbname %q: %w", dbname, err) - } - - break - } - } - - if !foundSlash && len(dsn) > 0 { - return nil, errInvalidDSNNoSlash - } - - if err = cfg.normalize(); err != nil { - return nil, err - } - return -} - -// parseDSNParams parses the DSN "query string" -// Values must be url.QueryEscape'ed -func parseDSNParams(cfg *Config, params string) (err error) { - for _, v := range strings.Split(params, "&") { - key, value, found := strings.Cut(v, "=") - if !found { - continue - } - - // cfg params - switch key { - // Disable INFILE allowlist / enable all files - case "allowAllFiles": - var isBool bool - cfg.AllowAllFiles, isBool = readBool(value) - if !isBool { - return errors.New("invalid bool value: " + value) - } - - // Use cleartext authentication mode (MySQL 5.5.10+) - case "allowCleartextPasswords": - var isBool bool - cfg.AllowCleartextPasswords, isBool = readBool(value) - if !isBool { - return errors.New("invalid bool value: " + value) - } - - // Allow fallback to unencrypted connection if server does not support TLS - case "allowFallbackToPlaintext": - var isBool bool - cfg.AllowFallbackToPlaintext, isBool = readBool(value) - if !isBool { - return errors.New("invalid bool value: " + value) - } - - // Use native password authentication - case "allowNativePasswords": - var isBool bool - cfg.AllowNativePasswords, isBool = readBool(value) - if !isBool { - return errors.New("invalid bool value: " + value) - } - - // Use old authentication mode (pre MySQL 4.1) - case "allowOldPasswords": - var isBool bool - cfg.AllowOldPasswords, isBool = readBool(value) - if !isBool { - return errors.New("invalid bool value: " + value) - } - - // Check connections for Liveness before using them - case "checkConnLiveness": - var isBool bool - cfg.CheckConnLiveness, isBool = readBool(value) - if !isBool { - return errors.New("invalid bool value: " + value) - } - - // Switch "rowsAffected" mode - case "clientFoundRows": - var isBool bool - cfg.ClientFoundRows, isBool = readBool(value) - if !isBool { - return errors.New("invalid bool value: " + value) - } - - // Collation - case "collation": - cfg.Collation = value - - case "columnsWithAlias": - var isBool bool - cfg.ColumnsWithAlias, isBool = readBool(value) - if !isBool { - return errors.New("invalid bool value: " + value) - } - - // Compression - case "compress": - return errors.New("compression not implemented yet") - - // Enable client side placeholder substitution - case "interpolateParams": - var isBool bool - cfg.InterpolateParams, isBool = readBool(value) - if !isBool { - return errors.New("invalid bool value: " + value) - } - - // Time Location - case "loc": - if value, err = url.QueryUnescape(value); err != nil { - return - } - cfg.Loc, err = time.LoadLocation(value) - if err != nil { - return - } - - // multiple statements in one query - case "multiStatements": - var isBool bool - cfg.MultiStatements, isBool = readBool(value) - if !isBool { - return errors.New("invalid bool value: " + value) - } - - // time.Time parsing - case "parseTime": - var isBool bool - cfg.ParseTime, isBool = readBool(value) - if !isBool { - return errors.New("invalid bool value: " + value) - } - - // time.Time truncation - case "timeTruncate": - cfg.timeTruncate, err = time.ParseDuration(value) - if err != nil { - return fmt.Errorf("invalid timeTruncate value: %v, error: %w", value, err) - } - - // I/O read Timeout - case "readTimeout": - cfg.ReadTimeout, err = time.ParseDuration(value) - if err != nil { - return - } - - // Reject read-only connections - case "rejectReadOnly": - var isBool bool - cfg.RejectReadOnly, isBool = readBool(value) - if !isBool { - 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) - } - cfg.ServerPubKey = name - - // Strict mode - case "strict": - panic("strict mode has been removed. See https://github.com/go-sql-driver/mysql/wiki/strict-mode") - - // Dial Timeout - case "timeout": - cfg.Timeout, err = time.ParseDuration(value) - if err != nil { - return - } - - // TLS-Encryption - case "tls": - boolValue, isBool := readBool(value) - if isBool { - if boolValue { - cfg.TLSConfig = "true" - } else { - cfg.TLSConfig = "false" - } - } else if vl := strings.ToLower(value); vl == "skip-verify" || vl == "preferred" { - cfg.TLSConfig = vl - } else { - name, err := url.QueryUnescape(value) - if err != nil { - return fmt.Errorf("invalid value for TLS config name: %v", err) - } - cfg.TLSConfig = name - } - - // I/O write Timeout - case "writeTimeout": - cfg.WriteTimeout, err = time.ParseDuration(value) - if err != nil { - return - } - case "maxAllowedPacket": - cfg.MaxAllowedPacket, err = strconv.Atoi(value) - if err != nil { - return - } - - // Connection attributes - case "connectionAttributes": - connectionAttributes, err := url.QueryUnescape(value) - if err != nil { - return fmt.Errorf("invalid connectionAttributes value: %v", err) - } - cfg.ConnectionAttributes = connectionAttributes - - default: - // lazy init - if cfg.Params == nil { - cfg.Params = make(map[string]string) - } - - if cfg.Params[key], err = url.QueryUnescape(value); err != nil { - return - } - } - } - - return -} - -func ensureHavePort(addr string) string { - if _, _, err := net.SplitHostPort(addr); err != nil { - return net.JoinHostPort(addr, "3306") - } - return addr -} diff --git a/v2/vendor/github.com/go-sql-driver/mysql/errors.go b/v2/vendor/github.com/go-sql-driver/mysql/errors.go deleted file mode 100644 index a7ef889..0000000 --- a/v2/vendor/github.com/go-sql-driver/mysql/errors.go +++ /dev/null @@ -1,83 +0,0 @@ -// Go MySQL Driver - A MySQL-Driver for Go's database/sql package -// -// Copyright 2013 The Go-MySQL-Driver Authors. All rights reserved. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this file, -// You can obtain one at http://mozilla.org/MPL/2.0/. - -package mysql - -import ( - "errors" - "fmt" - "log" - "os" -) - -// Various errors the driver might return. Can change between driver versions. -var ( - ErrInvalidConn = errors.New("invalid connection") - ErrMalformPkt = errors.New("malformed packet") - ErrNoTLS = errors.New("TLS requested but server does not support TLS") - ErrCleartextPassword = errors.New("this user requires clear text authentication. If you still want to use it, please add 'allowCleartextPasswords=1' to your DSN") - ErrNativePassword = errors.New("this user requires mysql native password authentication") - ErrOldPassword = errors.New("this user requires old password authentication. If you still want to use it, please add 'allowOldPasswords=1' to your DSN. See also https://github.com/go-sql-driver/mysql/wiki/old_passwords") - ErrUnknownPlugin = errors.New("this authentication plugin is not supported") - ErrOldProtocol = errors.New("MySQL server does not support required protocol 41+") - ErrPktSync = errors.New("commands out of sync. You can't run this command now") - ErrPktSyncMul = errors.New("commands out of sync. Did you run multiple statements at once?") - ErrPktTooLarge = errors.New("packet for query is too large. Try adjusting the `Config.MaxAllowedPacket`") - ErrBusyBuffer = errors.New("busy buffer") - - // errBadConnNoWrite is used for connection errors where nothing was sent to the database yet. - // If this happens first in a function starting a database interaction, it should be replaced by driver.ErrBadConn - // to trigger a resend. - // See https://github.com/go-sql-driver/mysql/pull/302 - errBadConnNoWrite = errors.New("bad connection") -) - -var defaultLogger = Logger(log.New(os.Stderr, "[mysql] ", log.Ldate|log.Ltime|log.Lshortfile)) - -// Logger is used to log critical error messages. -type Logger interface { - Print(v ...any) -} - -// NopLogger is a nop implementation of the Logger interface. -type NopLogger struct{} - -// Print implements Logger interface. -func (nl *NopLogger) Print(_ ...any) {} - -// SetLogger is used to set the default logger for critical errors. -// The initial logger is os.Stderr. -func SetLogger(logger Logger) error { - if logger == nil { - return errors.New("logger is nil") - } - defaultLogger = logger - return nil -} - -// MySQLError is an error type which represents a single MySQL error -type MySQLError struct { - Number uint16 - SQLState [5]byte - Message string -} - -func (me *MySQLError) Error() string { - if me.SQLState != [5]byte{} { - return fmt.Sprintf("Error %d (%s): %s", me.Number, me.SQLState, me.Message) - } - - return fmt.Sprintf("Error %d: %s", me.Number, me.Message) -} - -func (me *MySQLError) Is(err error) bool { - if merr, ok := err.(*MySQLError); ok { - return merr.Number == me.Number - } - return false -} diff --git a/v2/vendor/github.com/go-sql-driver/mysql/fields.go b/v2/vendor/github.com/go-sql-driver/mysql/fields.go deleted file mode 100644 index 2860842..0000000 --- a/v2/vendor/github.com/go-sql-driver/mysql/fields.go +++ /dev/null @@ -1,222 +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/. - -package mysql - -import ( - "database/sql" - "reflect" -) - -func (mf *mysqlField) typeDatabaseName() string { - switch mf.fieldType { - case fieldTypeBit: - return "BIT" - case fieldTypeBLOB: - if mf.charSet != binaryCollationID { - 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: - if mf.flags&flagUnsigned != 0 { - return "UNSIGNED MEDIUMINT" - } - return "MEDIUMINT" - case fieldTypeJSON: - return "JSON" - case fieldTypeLong: - if mf.flags&flagUnsigned != 0 { - return "UNSIGNED INT" - } - return "INT" - case fieldTypeLongBLOB: - if mf.charSet != binaryCollationID { - return "LONGTEXT" - } - return "LONGBLOB" - case fieldTypeLongLong: - if mf.flags&flagUnsigned != 0 { - return "UNSIGNED BIGINT" - } - return "BIGINT" - case fieldTypeMediumBLOB: - if mf.charSet != binaryCollationID { - return "MEDIUMTEXT" - } - return "MEDIUMBLOB" - case fieldTypeNewDate: - return "DATE" - case fieldTypeNewDecimal: - return "DECIMAL" - case fieldTypeNULL: - return "NULL" - case fieldTypeSet: - return "SET" - case fieldTypeShort: - if mf.flags&flagUnsigned != 0 { - return "UNSIGNED SMALLINT" - } - return "SMALLINT" - case fieldTypeString: - if mf.flags&flagEnum != 0 { - return "ENUM" - } else if mf.flags&flagSet != 0 { - return "SET" - } - if mf.charSet == binaryCollationID { - return "BINARY" - } - return "CHAR" - case fieldTypeTime: - return "TIME" - case fieldTypeTimestamp: - return "TIMESTAMP" - case fieldTypeTiny: - if mf.flags&flagUnsigned != 0 { - return "UNSIGNED TINYINT" - } - return "TINYINT" - case fieldTypeTinyBLOB: - if mf.charSet != binaryCollationID { - return "TINYTEXT" - } - return "TINYBLOB" - case fieldTypeVarChar: - if mf.charSet == binaryCollationID { - return "VARBINARY" - } - return "VARCHAR" - case fieldTypeVarString: - if mf.charSet == binaryCollationID { - 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(sql.NullTime{}) - scanTypeUint8 = reflect.TypeOf(uint8(0)) - scanTypeUint16 = reflect.TypeOf(uint16(0)) - scanTypeUint32 = reflect.TypeOf(uint32(0)) - scanTypeUint64 = reflect.TypeOf(uint64(0)) - scanTypeString = reflect.TypeOf("") - scanTypeNullString = reflect.TypeOf(sql.NullString{}) - scanTypeBytes = reflect.TypeOf([]byte{}) - scanTypeUnknown = reflect.TypeOf(new(any)) -) - -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 fieldTypeBit, fieldTypeTinyBLOB, fieldTypeMediumBLOB, fieldTypeLongBLOB, - fieldTypeBLOB, fieldTypeVarString, fieldTypeString, fieldTypeGeometry: - if mf.charSet == binaryCollationID { - return scanTypeBytes - } - fallthrough - case fieldTypeDecimal, fieldTypeNewDecimal, fieldTypeVarChar, - fieldTypeEnum, fieldTypeSet, fieldTypeJSON, fieldTypeTime: - if mf.flags&flagNotNULL != 0 { - return scanTypeString - } - return scanTypeNullString - - 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 - } -} diff --git a/v2/vendor/github.com/go-sql-driver/mysql/infile.go b/v2/vendor/github.com/go-sql-driver/mysql/infile.go deleted file mode 100644 index 0c8af9f..0000000 --- a/v2/vendor/github.com/go-sql-driver/mysql/infile.go +++ /dev/null @@ -1,182 +0,0 @@ -// Go MySQL Driver - A MySQL-Driver for Go's database/sql package -// -// Copyright 2013 The Go-MySQL-Driver Authors. All rights reserved. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this file, -// You can obtain one at http://mozilla.org/MPL/2.0/. - -package mysql - -import ( - "fmt" - "io" - "os" - "strings" - "sync" -) - -var ( - fileRegister map[string]bool - fileRegisterLock sync.RWMutex - readerRegister map[string]func() io.Reader - readerRegisterLock sync.RWMutex -) - -// RegisterLocalFile adds the given file to the file allowlist, -// so that it can be used by "LOAD DATA LOCAL INFILE ". -// Alternatively you can allow the use of all local files with -// the DSN parameter 'allowAllFiles=true' -// -// filePath := "/home/gopher/data.csv" -// mysql.RegisterLocalFile(filePath) -// err := db.Exec("LOAD DATA LOCAL INFILE '" + filePath + "' INTO TABLE foo") -// if err != nil { -// ... -func RegisterLocalFile(filePath string) { - fileRegisterLock.Lock() - // lazy map init - if fileRegister == nil { - fileRegister = make(map[string]bool) - } - - fileRegister[strings.Trim(filePath, `"`)] = true - fileRegisterLock.Unlock() -} - -// DeregisterLocalFile removes the given filepath from the allowlist. -func DeregisterLocalFile(filePath string) { - fileRegisterLock.Lock() - delete(fileRegister, strings.Trim(filePath, `"`)) - fileRegisterLock.Unlock() -} - -// RegisterReaderHandler registers a handler function which is used -// to receive a io.Reader. -// The Reader can be used by "LOAD DATA LOCAL INFILE Reader::". -// If the handler returns a io.ReadCloser Close() is called when the -// request is finished. -// -// mysql.RegisterReaderHandler("data", func() io.Reader { -// var csvReader io.Reader // Some Reader that returns CSV data -// ... // Open Reader here -// return csvReader -// }) -// err := db.Exec("LOAD DATA LOCAL INFILE 'Reader::data' INTO TABLE foo") -// if err != nil { -// ... -func RegisterReaderHandler(name string, handler func() io.Reader) { - readerRegisterLock.Lock() - // lazy map init - if readerRegister == nil { - readerRegister = make(map[string]func() io.Reader) - } - - readerRegister[name] = handler - readerRegisterLock.Unlock() -} - -// DeregisterReaderHandler removes the ReaderHandler function with -// the given name from the registry. -func DeregisterReaderHandler(name string) { - readerRegisterLock.Lock() - delete(readerRegister, name) - readerRegisterLock.Unlock() -} - -func deferredClose(err *error, closer io.Closer) { - closeErr := closer.Close() - if *err == nil { - *err = closeErr - } -} - -const defaultPacketSize = 16 * 1024 // 16KB is small enough for disk readahead and large enough for TCP - -func (mc *okHandler) handleInFileRequest(name string) (err error) { - var rdr io.Reader - var data []byte - packetSize := defaultPacketSize - if mc.maxWriteSize < packetSize { - packetSize = mc.maxWriteSize - } - - if idx := strings.Index(name, "Reader::"); idx == 0 || (idx > 0 && name[idx-1] == '/') { // io.Reader - // The server might return an an absolute path. See issue #355. - name = name[idx+8:] - - readerRegisterLock.RLock() - handler, inMap := readerRegister[name] - readerRegisterLock.RUnlock() - - if inMap { - rdr = handler() - if rdr != nil { - if cl, ok := rdr.(io.Closer); ok { - defer deferredClose(&err, cl) - } - } else { - err = fmt.Errorf("reader '%s' is ", name) - } - } else { - err = fmt.Errorf("reader '%s' is not registered", name) - } - } else { // File - name = strings.Trim(name, `"`) - fileRegisterLock.RLock() - fr := fileRegister[name] - fileRegisterLock.RUnlock() - if mc.cfg.AllowAllFiles || fr { - var file *os.File - var fi os.FileInfo - - if file, err = os.Open(name); err == nil { - defer deferredClose(&err, file) - - // get file size - if fi, err = file.Stat(); err == nil { - rdr = file - if fileSize := int(fi.Size()); fileSize < packetSize { - packetSize = fileSize - } - } - } - } else { - err = fmt.Errorf("local file '%s' is not registered", name) - } - } - - // send content packets - // if packetSize == 0, the Reader contains no data - if err == nil && packetSize > 0 { - data := make([]byte, 4+packetSize) - var n int - for err == nil { - n, err = rdr.Read(data[4:]) - if n > 0 { - if ioErr := mc.conn().writePacket(data[:4+n]); ioErr != nil { - return ioErr - } - } - } - if err == io.EOF { - err = nil - } - } - - // send empty packet (termination) - if data == nil { - data = make([]byte, 4) - } - if ioErr := mc.conn().writePacket(data[:4]); ioErr != nil { - return ioErr - } - - // read OK packet - if err == nil { - return mc.readResultOK() - } - - mc.conn().readPacket() - return err -} diff --git a/v2/vendor/github.com/go-sql-driver/mysql/nulltime.go b/v2/vendor/github.com/go-sql-driver/mysql/nulltime.go deleted file mode 100644 index 316a48a..0000000 --- a/v2/vendor/github.com/go-sql-driver/mysql/nulltime.go +++ /dev/null @@ -1,71 +0,0 @@ -// Go MySQL Driver - A MySQL-Driver for Go's database/sql package -// -// Copyright 2013 The Go-MySQL-Driver Authors. All rights reserved. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this file, -// You can obtain one at http://mozilla.org/MPL/2.0/. - -package mysql - -import ( - "database/sql" - "database/sql/driver" - "fmt" - "time" -) - -// NullTime represents a time.Time that may be NULL. -// NullTime implements the Scanner interface so -// it can be used as a scan destination: -// -// var nt NullTime -// err := db.QueryRow("SELECT time FROM foo WHERE id=?", id).Scan(&nt) -// ... -// if nt.Valid { -// // use nt.Time -// } else { -// // NULL value -// } -// -// # This NullTime implementation is not driver-specific -// -// Deprecated: NullTime doesn't honor the loc DSN parameter. -// NullTime.Scan interprets a time as UTC, not the loc DSN parameter. -// Use sql.NullTime instead. -type NullTime sql.NullTime - -// Scan implements the Scanner interface. -// The value type must be time.Time or string / []byte (formatted time-string), -// otherwise Scan fails. -func (nt *NullTime) Scan(value any) (err error) { - if value == nil { - nt.Time, nt.Valid = time.Time{}, false - return - } - - switch v := value.(type) { - case time.Time: - nt.Time, nt.Valid = v, true - return - case []byte: - nt.Time, err = parseDateTime(v, time.UTC) - nt.Valid = (err == nil) - return - case string: - nt.Time, err = parseDateTime([]byte(v), time.UTC) - nt.Valid = (err == nil) - return - } - - nt.Valid = false - return fmt.Errorf("can't convert %T to time.Time", value) -} - -// Value implements the driver Valuer interface. -func (nt NullTime) Value() (driver.Value, error) { - if !nt.Valid { - return nil, nil - } - return nt.Time, nil -} diff --git a/v2/vendor/github.com/go-sql-driver/mysql/packets.go b/v2/vendor/github.com/go-sql-driver/mysql/packets.go deleted file mode 100644 index 90a3472..0000000 --- a/v2/vendor/github.com/go-sql-driver/mysql/packets.go +++ /dev/null @@ -1,1406 +0,0 @@ -// Go MySQL Driver - A MySQL-Driver for Go's database/sql package -// -// Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this file, -// You can obtain one at http://mozilla.org/MPL/2.0/. - -package mysql - -import ( - "bytes" - "crypto/tls" - "database/sql/driver" - "encoding/binary" - "encoding/json" - "fmt" - "io" - "math" - "strconv" - "time" -) - -// Packets documentation: -// http://dev.mysql.com/doc/internals/en/client-server-protocol.html - -// Read packet to buffer 'data' -func (mc *mysqlConn) readPacket() ([]byte, error) { - var prevData []byte - for { - // read packet header - data, err := mc.buf.readNext(4) - if err != nil { - if cerr := mc.canceled.Value(); cerr != nil { - return nil, cerr - } - mc.log(err) - mc.Close() - return nil, ErrInvalidConn - } - - // packet length [24 bit] - pktLen := int(uint32(data[0]) | uint32(data[1])<<8 | uint32(data[2])<<16) - - // check packet sync [8 bit] - if data[3] != mc.sequence { - mc.Close() - if data[3] > mc.sequence { - return nil, ErrPktSyncMul - } - return nil, ErrPktSync - } - mc.sequence++ - - // packets with length 0 terminate a previous packet which is a - // multiple of (2^24)-1 bytes long - if pktLen == 0 { - // there was no previous packet - if prevData == nil { - mc.log(ErrMalformPkt) - mc.Close() - return nil, ErrInvalidConn - } - - return prevData, nil - } - - // read packet body [pktLen bytes] - data, err = mc.buf.readNext(pktLen) - if err != nil { - if cerr := mc.canceled.Value(); cerr != nil { - return nil, cerr - } - mc.log(err) - mc.Close() - return nil, ErrInvalidConn - } - - // return data if this was the last packet - if pktLen < maxPacketSize { - // zero allocations for non-split packets - if prevData == nil { - return data, nil - } - - return append(prevData, data...), nil - } - - prevData = append(prevData, data...) - } -} - -// Write packet buffer 'data' -func (mc *mysqlConn) writePacket(data []byte) error { - pktLen := len(data) - 4 - - if pktLen > mc.maxAllowedPacket { - return ErrPktTooLarge - } - - for { - var size int - if pktLen >= maxPacketSize { - data[0] = 0xff - data[1] = 0xff - data[2] = 0xff - size = maxPacketSize - } else { - data[0] = byte(pktLen) - data[1] = byte(pktLen >> 8) - data[2] = byte(pktLen >> 16) - size = pktLen - } - data[3] = mc.sequence - - // Write packet - if mc.writeTimeout > 0 { - if err := mc.netConn.SetWriteDeadline(time.Now().Add(mc.writeTimeout)); err != nil { - return err - } - } - - n, err := mc.netConn.Write(data[:4+size]) - if err == nil && n == 4+size { - mc.sequence++ - if size != maxPacketSize { - return nil - } - pktLen -= size - data = data[size:] - continue - } - - // Handle error - if err == nil { // n != len(data) - mc.cleanup() - mc.log(ErrMalformPkt) - } else { - if cerr := mc.canceled.Value(); cerr != nil { - return cerr - } - if n == 0 && pktLen == len(data)-4 { - // only for the first loop iteration when nothing was written yet - return errBadConnNoWrite - } - mc.cleanup() - mc.log(err) - } - return ErrInvalidConn - } -} - -/****************************************************************************** -* Initialization Process * -******************************************************************************/ - -// Handshake Initialization Packet -// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::Handshake -func (mc *mysqlConn) readHandshakePacket() (data []byte, plugin string, err error) { - data, err = mc.readPacket() - if err != nil { - // 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 { - return nil, "", mc.handleErrorPacket(data) - } - - // protocol version [1 byte] - if data[0] < minProtocolVersion { - return nil, "", fmt.Errorf( - "unsupported protocol version %d. Version %d or higher is required", - data[0], - minProtocolVersion, - ) - } - - // server version [null terminated string] - // connection id [4 bytes] - pos := 1 + bytes.IndexByte(data[1:], 0x00) + 1 + 4 - - // first part of the password cipher [8 bytes] - authData := data[pos : pos+8] - - // (filler) always 0x00 [1 byte] - pos += 8 + 1 - - // capability flags (lower 2 bytes) [2 bytes] - mc.flags = clientFlag(binary.LittleEndian.Uint16(data[pos : pos+2])) - if mc.flags&clientProtocol41 == 0 { - return nil, "", ErrOldProtocol - } - if mc.flags&clientSSL == 0 && mc.cfg.TLS != nil { - if mc.cfg.AllowFallbackToPlaintext { - mc.cfg.TLS = nil - } else { - return nil, "", ErrNoTLS - } - } - pos += 2 - - if len(data) > pos { - // character set [1 byte] - // status flags [2 bytes] - // capability flags (upper 2 bytes) [2 bytes] - // length of auth-plugin-data [1 byte] - // reserved (all [00]) [10 bytes] - pos += 1 + 2 + 2 + 1 + 10 - - // second part of the password cipher [minimum 13 bytes], - // where len=MAX(13, length of auth-plugin-data - 8) - // - // The web documentation is ambiguous about the length. However, - // according to mysql-5.7/sql/auth/sql_authentication.cc line 538, - // the 13th byte is "\0 byte, terminating the second part of - // a scramble". So the second part of the password cipher is - // a NULL terminated string that's at least 13 bytes with the - // last byte being NULL. - // - // The official Python library uses the fixed length 12 - // which seems to work but technically could have a hidden bug. - authData = append(authData, data[pos:pos+12]...) - pos += 13 - - // EOF if version (>= 5.5.7 and < 5.5.10) or (>= 5.6.0 and < 5.6.2) - // \NUL otherwise - if end := bytes.IndexByte(data[pos:], 0x00); end != -1 { - plugin = string(data[pos : pos+end]) - } else { - plugin = string(data[pos:]) - } - - // make a memory safe copy of the cipher slice - var b [20]byte - copy(b[:], authData) - return b[:], plugin, nil - } - - // make a memory safe copy of the cipher slice - var b [8]byte - copy(b[:], authData) - return b[:], plugin, nil -} - -// Client Authentication Packet -// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::HandshakeResponse -func (mc *mysqlConn) writeHandshakeResponsePacket(authResp []byte, plugin string) error { - // Adjust client flags based on server support - clientFlags := clientProtocol41 | - clientSecureConn | - clientLongPassword | - clientTransactions | - clientLocalFiles | - clientPluginAuth | - clientMultiResults | - clientConnectAttrs | - mc.flags&clientLongFlag - - if mc.cfg.ClientFoundRows { - clientFlags |= clientFoundRows - } - - // To enable TLS / SSL - if mc.cfg.TLS != nil { - clientFlags |= clientSSL - } - - if mc.cfg.MultiStatements { - clientFlags |= clientMultiStatements - } - - // encode length of the auth plugin data - 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 + len(authRespLEI) + len(authResp) + 21 + 1 - - // To specify a db name - if n := len(mc.cfg.DBName); n > 0 { - clientFlags |= clientConnectWithDB - pktLen += n + 1 - } - - // encode length of the connection attributes - var connAttrsLEIBuf [9]byte - connAttrsLen := len(mc.connector.encodedAttributes) - connAttrsLEI := appendLengthEncodedInteger(connAttrsLEIBuf[:0], uint64(connAttrsLen)) - pktLen += len(connAttrsLEI) + len(mc.connector.encodedAttributes) - - // Calculate packet length and get buffer with that size - data, err := mc.buf.takeBuffer(pktLen + 4) - if err != nil { - // cannot take the buffer. Something must be wrong with the connection - mc.log(err) - return errBadConnNoWrite - } - - // ClientFlags [32 bit] - data[4] = byte(clientFlags) - data[5] = byte(clientFlags >> 8) - data[6] = byte(clientFlags >> 16) - data[7] = byte(clientFlags >> 24) - - // MaxPacketSize [32 bit] (none) - data[8] = 0x00 - data[9] = 0x00 - data[10] = 0x00 - data[11] = 0x00 - - // Collation ID [1 byte] - cname := mc.cfg.Collation - if cname == "" { - cname = defaultCollation - } - var found bool - data[12], found = collations[cname] - if !found { - // Note possibility for false negatives: - // could be triggered although the collation is valid if the - // collations map does not contain entries the server supports. - return fmt.Errorf("unknown collation: %q", cname) - } - - // Filler [23 bytes] (all 0x00) - pos := 13 - for ; pos < 13+23; pos++ { - data[pos] = 0 - } - - // SSL Connection Request Packet - // http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::SSLRequest - if mc.cfg.TLS != nil { - // Send TLS / SSL request packet - if err := mc.writePacket(data[:(4+4+1+23)+4]); err != nil { - return err - } - - // Switch to TLS - tlsConn := tls.Client(mc.netConn, mc.cfg.TLS) - if err := tlsConn.Handshake(); err != nil { - return err - } - mc.netConn = tlsConn - mc.buf.nc = tlsConn - } - - // User [null terminated string] - if len(mc.cfg.User) > 0 { - pos += copy(data[pos:], mc.cfg.User) - } - data[pos] = 0x00 - pos++ - - // Auth Data [length encoded integer] - pos += copy(data[pos:], authRespLEI) - pos += copy(data[pos:], authResp) - - // Databasename [null terminated string] - if len(mc.cfg.DBName) > 0 { - pos += copy(data[pos:], mc.cfg.DBName) - data[pos] = 0x00 - pos++ - } - - pos += copy(data[pos:], plugin) - data[pos] = 0x00 - pos++ - - // Connection Attributes - pos += copy(data[pos:], connAttrsLEI) - pos += copy(data[pos:], []byte(mc.connector.encodedAttributes)) - - // Send Auth packet - return mc.writePacket(data[:pos]) -} - -// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::AuthSwitchResponse -func (mc *mysqlConn) writeAuthSwitchPacket(authData []byte) error { - pktLen := 4 + len(authData) - data, err := mc.buf.takeSmallBuffer(pktLen) - if err != nil { - // cannot take the buffer. Something must be wrong with the connection - mc.log(err) - return errBadConnNoWrite - } - - // Add the auth data [EOF] - copy(data[4:], authData) - return mc.writePacket(data) -} - -/****************************************************************************** -* Command Packets * -******************************************************************************/ - -func (mc *mysqlConn) writeCommandPacket(command byte) error { - // Reset Packet Sequence - mc.sequence = 0 - - data, err := mc.buf.takeSmallBuffer(4 + 1) - if err != nil { - // cannot take the buffer. Something must be wrong with the connection - mc.log(err) - return errBadConnNoWrite - } - - // Add command byte - data[4] = command - - // Send CMD packet - return mc.writePacket(data) -} - -func (mc *mysqlConn) writeCommandPacketStr(command byte, arg string) error { - // Reset Packet Sequence - mc.sequence = 0 - - pktLen := 1 + len(arg) - data, err := mc.buf.takeBuffer(pktLen + 4) - if err != nil { - // cannot take the buffer. Something must be wrong with the connection - mc.log(err) - return errBadConnNoWrite - } - - // Add command byte - data[4] = command - - // Add arg - copy(data[5:], arg) - - // Send CMD packet - return mc.writePacket(data) -} - -func (mc *mysqlConn) writeCommandPacketUint32(command byte, arg uint32) error { - // Reset Packet Sequence - mc.sequence = 0 - - data, err := mc.buf.takeSmallBuffer(4 + 1 + 4) - if err != nil { - // cannot take the buffer. Something must be wrong with the connection - mc.log(err) - return errBadConnNoWrite - } - - // Add command byte - data[4] = command - - // Add arg [32 bit] - data[5] = byte(arg) - data[6] = byte(arg >> 8) - data[7] = byte(arg >> 16) - data[8] = byte(arg >> 24) - - // Send CMD packet - return mc.writePacket(data) -} - -/****************************************************************************** -* Result Packets * -******************************************************************************/ - -func (mc *mysqlConn) readAuthResult() ([]byte, string, error) { - data, err := mc.readPacket() - if err != nil { - return nil, "", err - } - - // packet indicator - switch data[0] { - - case iOK: - // resultUnchanged, since auth happens before any queries or - // commands have been executed. - return nil, "", mc.resultUnchanged().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 a 'Result OK'-Packet -func (mc *okHandler) readResultOK() error { - data, err := mc.conn().readPacket() - if err != nil { - return err - } - - if data[0] == iOK { - return mc.handleOkPacket(data) - } - return mc.conn().handleErrorPacket(data) -} - -// Result Set Header Packet -// http://dev.mysql.com/doc/internals/en/com-query-response.html#packet-ProtocolText::Resultset -func (mc *okHandler) readResultSetHeaderPacket() (int, error) { - // handleOkPacket replaces both values; other cases leave the values unchanged. - mc.result.affectedRows = append(mc.result.affectedRows, 0) - mc.result.insertIds = append(mc.result.insertIds, 0) - - data, err := mc.conn().readPacket() - if err == nil { - switch data[0] { - - case iOK: - return 0, mc.handleOkPacket(data) - - case iERR: - return 0, mc.conn().handleErrorPacket(data) - - case iLocalInFile: - return 0, mc.handleInFileRequest(string(data[1:])) - } - - // column count - num, _, _ := readLengthEncodedInteger(data) - // ignore remaining data in the packet. see #1478. - return int(num), nil - } - return 0, err -} - -// Error Packet -// http://dev.mysql.com/doc/internals/en/generic-response-packets.html#packet-ERR_Packet -func (mc *mysqlConn) handleErrorPacket(data []byte) error { - if data[0] != iERR { - return ErrMalformPkt - } - - // 0xff [1 byte] - - // Error Number [16 bit uint] - errno := binary.LittleEndian.Uint16(data[1:3]) - - // 1792: ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION - // 1290: ER_OPTION_PREVENTS_STATEMENT (returned by Aurora during failover) - if (errno == 1792 || errno == 1290) && mc.cfg.RejectReadOnly { - // Oops; we are connected to a read-only connection, and won't be able - // to issue any write statements. Since RejectReadOnly is configured, - // we throw away this connection hoping this one would have write - // permission. This is specifically for a possible race condition - // during failover (e.g. on AWS Aurora). See README.md for more. - // - // We explicitly close the connection before returning - // driver.ErrBadConn to ensure that `database/sql` purges this - // connection and initiates a new one for next statement next time. - mc.Close() - return driver.ErrBadConn - } - - me := &MySQLError{Number: errno} - - pos := 3 - - // SQL State [optional: # + 5bytes string] - if data[3] == 0x23 { - copy(me.SQLState[:], data[4:4+5]) - pos = 9 - } - - // Error Message [string] - me.Message = string(data[pos:]) - - return me -} - -func readStatus(b []byte) statusFlag { - return statusFlag(b[0]) | statusFlag(b[1])<<8 -} - -// Returns an instance of okHandler for codepaths where mysqlConn.result doesn't -// need to be cleared first (e.g. during authentication, or while additional -// resultsets are being fetched.) -func (mc *mysqlConn) resultUnchanged() *okHandler { - return (*okHandler)(mc) -} - -// okHandler represents the state of the connection when mysqlConn.result has -// been prepared for processing of OK packets. -// -// To correctly populate mysqlConn.result (updated by handleOkPacket()), all -// callpaths must either: -// -// 1. first clear it using clearResult(), or -// 2. confirm that they don't need to (by calling resultUnchanged()). -// -// Both return an instance of type *okHandler. -type okHandler mysqlConn - -// Exposes the underlying type's methods. -func (mc *okHandler) conn() *mysqlConn { - return (*mysqlConn)(mc) -} - -// clearResult clears the connection's stored affectedRows and insertIds -// fields. -// -// It returns a handler that can process OK responses. -func (mc *mysqlConn) clearResult() *okHandler { - mc.result = mysqlResult{} - return (*okHandler)(mc) -} - -// Ok Packet -// http://dev.mysql.com/doc/internals/en/generic-response-packets.html#packet-OK_Packet -func (mc *okHandler) handleOkPacket(data []byte) error { - var n, m int - var affectedRows, insertId uint64 - - // 0x00 [1 byte] - - // Affected rows [Length Coded Binary] - affectedRows, _, n = readLengthEncodedInteger(data[1:]) - - // Insert id [Length Coded Binary] - insertId, _, m = readLengthEncodedInteger(data[1+n:]) - - // Update for the current statement result (only used by - // readResultSetHeaderPacket). - if len(mc.result.affectedRows) > 0 { - mc.result.affectedRows[len(mc.result.affectedRows)-1] = int64(affectedRows) - } - if len(mc.result.insertIds) > 0 { - mc.result.insertIds[len(mc.result.insertIds)-1] = int64(insertId) - } - - // server_status [2 bytes] - mc.status = readStatus(data[1+n+m : 1+n+m+2]) - if mc.status&statusMoreResultsExists != 0 { - return nil - } - - // warning count [2 bytes] - - return nil -} - -// Read Packets as Field Packets until EOF-Packet or an Error appears -// http://dev.mysql.com/doc/internals/en/com-query-response.html#packet-Protocol::ColumnDefinition41 -func (mc *mysqlConn) readColumns(count int) ([]mysqlField, error) { - columns := make([]mysqlField, count) - - for i := 0; ; i++ { - data, err := mc.readPacket() - if err != nil { - return nil, err - } - - // EOF Packet - if data[0] == iEOF && (len(data) == 5 || len(data) == 1) { - if i == count { - return columns, nil - } - return nil, fmt.Errorf("column count mismatch n:%d len:%d", count, len(columns)) - } - - // Catalog - pos, err := skipLengthEncodedString(data) - if err != nil { - return nil, err - } - - // Database [len coded string] - n, err := skipLengthEncodedString(data[pos:]) - if err != nil { - return nil, err - } - pos += n - - // Table [len coded string] - if mc.cfg.ColumnsWithAlias { - tableName, _, n, err := readLengthEncodedString(data[pos:]) - if err != nil { - return nil, err - } - pos += n - columns[i].tableName = string(tableName) - } else { - n, err = skipLengthEncodedString(data[pos:]) - if err != nil { - return nil, err - } - pos += n - } - - // Original table [len coded string] - n, err = skipLengthEncodedString(data[pos:]) - if err != nil { - return nil, err - } - pos += n - - // Name [len coded string] - name, _, n, err := readLengthEncodedString(data[pos:]) - if err != nil { - return nil, err - } - columns[i].name = string(name) - pos += n - - // Original name [len coded string] - n, err = skipLengthEncodedString(data[pos:]) - if err != nil { - return nil, err - } - pos += n - - // Filler [uint8] - pos++ - - // Charset [charset, collation uint8] - columns[i].charSet = data[pos] - pos += 2 - - // Length [uint32] - columns[i].length = binary.LittleEndian.Uint32(data[pos : pos+4]) - pos += 4 - - // Field type [uint8] - columns[i].fieldType = fieldType(data[pos]) - pos++ - - // Flags [uint16] - columns[i].flags = fieldFlag(binary.LittleEndian.Uint16(data[pos : pos+2])) - pos += 2 - - // Decimals [uint8] - columns[i].decimals = data[pos] - //pos++ - - // Default value [len coded binary] - //if pos < len(data) { - // defaultVal, _, err = bytesToLengthCodedBinary(data[pos:]) - //} - } -} - -// Read Packets as Field Packets until EOF-Packet or an Error appears -// http://dev.mysql.com/doc/internals/en/com-query-response.html#packet-ProtocolText::ResultsetRow -func (rows *textRows) readRow(dest []driver.Value) error { - mc := rows.mc - - if rows.rs.done { - return io.EOF - } - - data, err := mc.readPacket() - if err != nil { - return err - } - - // EOF Packet - if data[0] == iEOF && len(data) == 5 { - // server_status [2 bytes] - rows.mc.status = readStatus(data[3:]) - rows.rs.done = true - if !rows.HasNextResultSet() { - rows.mc = nil - } - return io.EOF - } - if data[0] == iERR { - rows.mc = nil - return mc.handleErrorPacket(data) - } - - // RowSet Packet - var ( - n int - isNull bool - pos int = 0 - ) - - for i := range dest { - // Read bytes and convert to string - var buf []byte - buf, isNull, n, err = readLengthEncodedString(data[pos:]) - pos += n - - if err != nil { - return err - } - - if isNull { - dest[i] = nil - continue - } - - switch rows.rs.columns[i].fieldType { - case fieldTypeTimestamp, - fieldTypeDateTime, - fieldTypeDate, - fieldTypeNewDate: - if mc.parseTime { - dest[i], err = parseDateTime(buf, mc.cfg.Loc) - } else { - dest[i] = buf - } - - case fieldTypeTiny, fieldTypeShort, fieldTypeInt24, fieldTypeYear, fieldTypeLong: - dest[i], err = strconv.ParseInt(string(buf), 10, 64) - - case fieldTypeLongLong: - if rows.rs.columns[i].flags&flagUnsigned != 0 { - dest[i], err = strconv.ParseUint(string(buf), 10, 64) - } else { - dest[i], err = strconv.ParseInt(string(buf), 10, 64) - } - - case fieldTypeFloat: - var d float64 - d, err = strconv.ParseFloat(string(buf), 32) - dest[i] = float32(d) - - case fieldTypeDouble: - dest[i], err = strconv.ParseFloat(string(buf), 64) - - default: - dest[i] = buf - } - if err != nil { - return err - } - } - - return nil -} - -// Reads Packets until EOF-Packet or an Error appears. Returns count of Packets read -func (mc *mysqlConn) readUntilEOF() error { - for { - data, err := mc.readPacket() - if err != nil { - return err - } - - switch data[0] { - case iERR: - return mc.handleErrorPacket(data) - case iEOF: - if len(data) == 5 { - mc.status = readStatus(data[3:]) - } - return nil - } - } -} - -/****************************************************************************** -* Prepared Statements * -******************************************************************************/ - -// Prepare Result Packets -// http://dev.mysql.com/doc/internals/en/com-stmt-prepare-response.html -func (stmt *mysqlStmt) readPrepareResultPacket() (uint16, error) { - data, err := stmt.mc.readPacket() - if err == nil { - // packet indicator [1 byte] - if data[0] != iOK { - return 0, stmt.mc.handleErrorPacket(data) - } - - // statement id [4 bytes] - stmt.id = binary.LittleEndian.Uint32(data[1:5]) - - // Column count [16 bit uint] - columnCount := binary.LittleEndian.Uint16(data[5:7]) - - // Param count [16 bit uint] - stmt.paramCount = int(binary.LittleEndian.Uint16(data[7:9])) - - // Reserved [8 bit] - - // Warning count [16 bit uint] - - return columnCount, nil - } - return 0, err -} - -// http://dev.mysql.com/doc/internals/en/com-stmt-send-long-data.html -func (stmt *mysqlStmt) writeCommandLongData(paramID int, arg []byte) error { - maxLen := stmt.mc.maxAllowedPacket - 1 - pktLen := maxLen - - // After the header (bytes 0-3) follows before the data: - // 1 byte command - // 4 bytes stmtID - // 2 bytes paramID - const dataOffset = 1 + 4 + 2 - - // Cannot use the write buffer since - // a) the buffer is too small - // b) it is in use - data := make([]byte, 4+1+4+2+len(arg)) - - copy(data[4+dataOffset:], arg) - - for argLen := len(arg); argLen > 0; argLen -= pktLen - dataOffset { - if dataOffset+argLen < maxLen { - pktLen = dataOffset + argLen - } - - stmt.mc.sequence = 0 - // Add command byte [1 byte] - data[4] = comStmtSendLongData - - // Add stmtID [32 bit] - data[5] = byte(stmt.id) - data[6] = byte(stmt.id >> 8) - data[7] = byte(stmt.id >> 16) - data[8] = byte(stmt.id >> 24) - - // Add paramID [16 bit] - data[9] = byte(paramID) - data[10] = byte(paramID >> 8) - - // Send CMD packet - err := stmt.mc.writePacket(data[:4+pktLen]) - if err == nil { - data = data[pktLen-dataOffset:] - continue - } - return err - - } - - // Reset Packet Sequence - stmt.mc.sequence = 0 - return nil -} - -// Execute Prepared Statement -// http://dev.mysql.com/doc/internals/en/com-stmt-execute.html -func (stmt *mysqlStmt) writeExecutePacket(args []driver.Value) error { - if len(args) != stmt.paramCount { - return fmt.Errorf( - "argument count mismatch (got: %d; has: %d)", - len(args), - stmt.paramCount, - ) - } - - const minPktLen = 4 + 1 + 4 + 1 + 4 - mc := stmt.mc - - // Determine threshold dynamically to avoid packet size shortage. - longDataSize := mc.maxAllowedPacket / (stmt.paramCount + 1) - if longDataSize < 64 { - longDataSize = 64 - } - - // Reset packet-sequence - mc.sequence = 0 - - var data []byte - var err error - - if len(args) == 0 { - data, err = mc.buf.takeBuffer(minPktLen) - } else { - data, err = mc.buf.takeCompleteBuffer() - // In this case the len(data) == cap(data) which is used to optimise the flow below. - } - if err != nil { - // cannot take the buffer. Something must be wrong with the connection - mc.log(err) - return errBadConnNoWrite - } - - // command [1 byte] - data[4] = comStmtExecute - - // statement_id [4 bytes] - data[5] = byte(stmt.id) - data[6] = byte(stmt.id >> 8) - data[7] = byte(stmt.id >> 16) - data[8] = byte(stmt.id >> 24) - - // flags (0: CURSOR_TYPE_NO_CURSOR) [1 byte] - data[9] = 0x00 - - // iteration_count (uint32(1)) [4 bytes] - data[10] = 0x01 - data[11] = 0x00 - data[12] = 0x00 - data[13] = 0x00 - - if len(args) > 0 { - pos := minPktLen - - var nullMask []byte - if maskLen, typesLen := (len(args)+7)/8, 1+2*len(args); pos+maskLen+typesLen >= cap(data) { - // buffer has to be extended but we don't know by how much so - // we depend on append after all data with known sizes fit. - // We stop at that because we deal with a lot of columns here - // which makes the required allocation size hard to guess. - tmp := make([]byte, pos+maskLen+typesLen) - copy(tmp[:pos], data[:pos]) - data = tmp - nullMask = data[pos : pos+maskLen] - // No need to clean nullMask as make ensures that. - pos += maskLen - } else { - nullMask = data[pos : pos+maskLen] - for i := range nullMask { - nullMask[i] = 0 - } - pos += maskLen - } - - // newParameterBoundFlag 1 [1 byte] - data[pos] = 0x01 - pos++ - - // type of each parameter [len(args)*2 bytes] - paramTypes := data[pos:] - pos += len(args) * 2 - - // value of each parameter [n bytes] - paramValues := data[pos:pos] - valuesCap := cap(paramValues) - - for i, arg := range args { - // build NULL-bitmap - if arg == nil { - nullMask[i/8] |= 1 << (uint(i) & 7) - paramTypes[i+i] = byte(fieldTypeNULL) - paramTypes[i+i+1] = 0x00 - continue - } - - if v, ok := arg.(json.RawMessage); ok { - arg = []byte(v) - } - // cache types and values - switch v := arg.(type) { - case int64: - paramTypes[i+i] = byte(fieldTypeLongLong) - paramTypes[i+i+1] = 0x00 - - if cap(paramValues)-len(paramValues)-8 >= 0 { - paramValues = paramValues[:len(paramValues)+8] - binary.LittleEndian.PutUint64( - paramValues[len(paramValues)-8:], - uint64(v), - ) - } else { - paramValues = append(paramValues, - uint64ToBytes(uint64(v))..., - ) - } - - case uint64: - paramTypes[i+i] = byte(fieldTypeLongLong) - paramTypes[i+i+1] = 0x80 // type is unsigned - - if cap(paramValues)-len(paramValues)-8 >= 0 { - paramValues = paramValues[:len(paramValues)+8] - binary.LittleEndian.PutUint64( - paramValues[len(paramValues)-8:], - uint64(v), - ) - } else { - paramValues = append(paramValues, - uint64ToBytes(uint64(v))..., - ) - } - - case float64: - paramTypes[i+i] = byte(fieldTypeDouble) - paramTypes[i+i+1] = 0x00 - - if cap(paramValues)-len(paramValues)-8 >= 0 { - paramValues = paramValues[:len(paramValues)+8] - binary.LittleEndian.PutUint64( - paramValues[len(paramValues)-8:], - math.Float64bits(v), - ) - } else { - paramValues = append(paramValues, - uint64ToBytes(math.Float64bits(v))..., - ) - } - - case bool: - paramTypes[i+i] = byte(fieldTypeTiny) - paramTypes[i+i+1] = 0x00 - - if v { - paramValues = append(paramValues, 0x01) - } else { - paramValues = append(paramValues, 0x00) - } - - case []byte: - // Common case (non-nil value) first - if v != nil { - paramTypes[i+i] = byte(fieldTypeString) - paramTypes[i+i+1] = 0x00 - - if len(v) < longDataSize { - paramValues = appendLengthEncodedInteger(paramValues, - uint64(len(v)), - ) - paramValues = append(paramValues, v...) - } else { - if err := stmt.writeCommandLongData(i, v); err != nil { - return err - } - } - continue - } - - // Handle []byte(nil) as a NULL value - nullMask[i/8] |= 1 << (uint(i) & 7) - paramTypes[i+i] = byte(fieldTypeNULL) - paramTypes[i+i+1] = 0x00 - - case string: - paramTypes[i+i] = byte(fieldTypeString) - paramTypes[i+i+1] = 0x00 - - if len(v) < longDataSize { - paramValues = appendLengthEncodedInteger(paramValues, - uint64(len(v)), - ) - paramValues = append(paramValues, v...) - } else { - if err := stmt.writeCommandLongData(i, []byte(v)); err != nil { - return err - } - } - - case time.Time: - paramTypes[i+i] = byte(fieldTypeString) - paramTypes[i+i+1] = 0x00 - - var a [64]byte - var b = a[:0] - - if v.IsZero() { - b = append(b, "0000-00-00"...) - } else { - b, err = appendDateTime(b, v.In(mc.cfg.Loc), mc.cfg.timeTruncate) - if err != nil { - return err - } - } - - paramValues = appendLengthEncodedInteger(paramValues, - uint64(len(b)), - ) - paramValues = append(paramValues, b...) - - default: - return fmt.Errorf("cannot convert type: %T", arg) - } - } - - // Check if param values exceeded the available buffer - // In that case we must build the data packet with the new values buffer - if valuesCap != cap(paramValues) { - data = append(data[:pos], paramValues...) - if err = mc.buf.store(data); err != nil { - mc.log(err) - return errBadConnNoWrite - } - } - - pos += len(paramValues) - data = data[:pos] - } - - return mc.writePacket(data) -} - -// For each remaining resultset in the stream, discards its rows and updates -// mc.affectedRows and mc.insertIds. -func (mc *okHandler) discardResults() error { - for mc.status&statusMoreResultsExists != 0 { - resLen, err := mc.readResultSetHeaderPacket() - if err != nil { - return err - } - if resLen > 0 { - // columns - if err := mc.conn().readUntilEOF(); err != nil { - return err - } - // rows - if err := mc.conn().readUntilEOF(); err != nil { - return err - } - } - } - return nil -} - -// http://dev.mysql.com/doc/internals/en/binary-protocol-resultset-row.html -func (rows *binaryRows) readRow(dest []driver.Value) error { - data, err := rows.mc.readPacket() - if err != nil { - return err - } - - // packet indicator [1 byte] - if data[0] != iOK { - // EOF Packet - if data[0] == iEOF && len(data) == 5 { - rows.mc.status = readStatus(data[3:]) - rows.rs.done = true - if !rows.HasNextResultSet() { - rows.mc = nil - } - return io.EOF - } - mc := rows.mc - rows.mc = nil - - // Error otherwise - return mc.handleErrorPacket(data) - } - - // NULL-bitmap, [(column-count + 7 + 2) / 8 bytes] - pos := 1 + (len(dest)+7+2)>>3 - nullMask := data[1:pos] - - for i := range dest { - // Field is NULL - // (byte >> bit-pos) % 2 == 1 - if ((nullMask[(i+2)>>3] >> uint((i+2)&7)) & 1) == 1 { - dest[i] = nil - continue - } - - // Convert to byte-coded string - switch rows.rs.columns[i].fieldType { - case fieldTypeNULL: - dest[i] = nil - continue - - // Numeric Types - case fieldTypeTiny: - if rows.rs.columns[i].flags&flagUnsigned != 0 { - dest[i] = int64(data[pos]) - } else { - dest[i] = int64(int8(data[pos])) - } - pos++ - continue - - case fieldTypeShort, fieldTypeYear: - if rows.rs.columns[i].flags&flagUnsigned != 0 { - dest[i] = int64(binary.LittleEndian.Uint16(data[pos : pos+2])) - } else { - dest[i] = int64(int16(binary.LittleEndian.Uint16(data[pos : pos+2]))) - } - pos += 2 - continue - - case fieldTypeInt24, fieldTypeLong: - if rows.rs.columns[i].flags&flagUnsigned != 0 { - dest[i] = int64(binary.LittleEndian.Uint32(data[pos : pos+4])) - } else { - dest[i] = int64(int32(binary.LittleEndian.Uint32(data[pos : pos+4]))) - } - pos += 4 - continue - - case fieldTypeLongLong: - if rows.rs.columns[i].flags&flagUnsigned != 0 { - val := binary.LittleEndian.Uint64(data[pos : pos+8]) - if val > math.MaxInt64 { - dest[i] = uint64ToString(val) - } else { - dest[i] = int64(val) - } - } else { - dest[i] = int64(binary.LittleEndian.Uint64(data[pos : pos+8])) - } - pos += 8 - continue - - case fieldTypeFloat: - dest[i] = math.Float32frombits(binary.LittleEndian.Uint32(data[pos : pos+4])) - pos += 4 - continue - - case fieldTypeDouble: - dest[i] = math.Float64frombits(binary.LittleEndian.Uint64(data[pos : pos+8])) - pos += 8 - continue - - // Length coded Binary Strings - case fieldTypeDecimal, fieldTypeNewDecimal, fieldTypeVarChar, - fieldTypeBit, fieldTypeEnum, fieldTypeSet, fieldTypeTinyBLOB, - fieldTypeMediumBLOB, fieldTypeLongBLOB, fieldTypeBLOB, - fieldTypeVarString, fieldTypeString, fieldTypeGeometry, fieldTypeJSON: - var isNull bool - var n int - dest[i], isNull, n, err = readLengthEncodedString(data[pos:]) - pos += n - if err == nil { - if !isNull { - continue - } else { - dest[i] = nil - continue - } - } - return err - - case - fieldTypeDate, fieldTypeNewDate, // Date YYYY-MM-DD - fieldTypeTime, // Time [-][H]HH:MM:SS[.fractal] - fieldTypeTimestamp, fieldTypeDateTime: // Timestamp YYYY-MM-DD HH:MM:SS[.fractal] - - num, isNull, n := readLengthEncodedInteger(data[pos:]) - pos += n - - switch { - case isNull: - dest[i] = nil - continue - case rows.rs.columns[i].fieldType == fieldTypeTime: - // database/sql does not support an equivalent to TIME, return a string - var dstlen uint8 - switch decimals := rows.rs.columns[i].decimals; decimals { - case 0x00, 0x1f: - dstlen = 8 - case 1, 2, 3, 4, 5, 6: - dstlen = 8 + 1 + decimals - default: - return fmt.Errorf( - "protocol error, illegal decimals value %d", - rows.rs.columns[i].decimals, - ) - } - dest[i], err = formatBinaryTime(data[pos:pos+int(num)], dstlen) - case rows.mc.parseTime: - dest[i], err = parseBinaryDateTime(num, data[pos:], rows.mc.cfg.Loc) - default: - var dstlen uint8 - if rows.rs.columns[i].fieldType == fieldTypeDate { - dstlen = 10 - } else { - switch decimals := rows.rs.columns[i].decimals; decimals { - case 0x00, 0x1f: - dstlen = 19 - case 1, 2, 3, 4, 5, 6: - dstlen = 19 + 1 + decimals - default: - return fmt.Errorf( - "protocol error, illegal decimals value %d", - rows.rs.columns[i].decimals, - ) - } - } - dest[i], err = formatBinaryDateTime(data[pos:pos+int(num)], dstlen) - } - - if err == nil { - pos += int(num) - continue - } else { - return err - } - - // Please report if this happens! - default: - return fmt.Errorf("unknown field type %d", rows.rs.columns[i].fieldType) - } - } - - return nil -} diff --git a/v2/vendor/github.com/go-sql-driver/mysql/result.go b/v2/vendor/github.com/go-sql-driver/mysql/result.go deleted file mode 100644 index d516314..0000000 --- a/v2/vendor/github.com/go-sql-driver/mysql/result.go +++ /dev/null @@ -1,50 +0,0 @@ -// Go MySQL Driver - A MySQL-Driver for Go's database/sql package -// -// Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this file, -// You can obtain one at http://mozilla.org/MPL/2.0/. - -package mysql - -import "database/sql/driver" - -// Result exposes data not available through *connection.Result. -// -// This is accessible by executing statements using sql.Conn.Raw() and -// downcasting the returned result: -// -// res, err := rawConn.Exec(...) -// res.(mysql.Result).AllRowsAffected() -type Result interface { - driver.Result - // AllRowsAffected returns a slice containing the affected rows for each - // executed statement. - AllRowsAffected() []int64 - // AllLastInsertIds returns a slice containing the last inserted ID for each - // executed statement. - AllLastInsertIds() []int64 -} - -type mysqlResult struct { - // One entry in both slices is created for every executed statement result. - affectedRows []int64 - insertIds []int64 -} - -func (res *mysqlResult) LastInsertId() (int64, error) { - return res.insertIds[len(res.insertIds)-1], nil -} - -func (res *mysqlResult) RowsAffected() (int64, error) { - return res.affectedRows[len(res.affectedRows)-1], nil -} - -func (res *mysqlResult) AllLastInsertIds() []int64 { - return append([]int64{}, res.insertIds...) // defensive copy -} - -func (res *mysqlResult) AllRowsAffected() []int64 { - return append([]int64{}, res.affectedRows...) // defensive copy -} diff --git a/v2/vendor/github.com/go-sql-driver/mysql/rows.go b/v2/vendor/github.com/go-sql-driver/mysql/rows.go deleted file mode 100644 index 81fa606..0000000 --- a/v2/vendor/github.com/go-sql-driver/mysql/rows.go +++ /dev/null @@ -1,232 +0,0 @@ -// Go MySQL Driver - A MySQL-Driver for Go's database/sql package -// -// Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this file, -// You can obtain one at http://mozilla.org/MPL/2.0/. - -package mysql - -import ( - "database/sql/driver" - "io" - "math" - "reflect" -) - -type resultSet struct { - columns []mysqlField - columnNames []string - done bool -} - -type mysqlRows struct { - mc *mysqlConn - rs resultSet - finish func() -} - -type binaryRows struct { - mysqlRows -} - -type textRows struct { - mysqlRows -} - -func (rows *mysqlRows) Columns() []string { - if rows.rs.columnNames != nil { - return rows.rs.columnNames - } - - columns := make([]string, len(rows.rs.columns)) - if rows.mc != nil && rows.mc.cfg.ColumnsWithAlias { - for i := range columns { - if tableName := rows.rs.columns[i].tableName; len(tableName) > 0 { - columns[i] = tableName + "." + rows.rs.columns[i].name - } else { - columns[i] = rows.rs.columns[i].name - } - } - } else { - for i := range columns { - columns[i] = rows.rs.columns[i].name - } - } - - rows.rs.columnNames = 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) { - if f := rows.finish; f != nil { - f() - rows.finish = nil - } - - mc := rows.mc - if mc == nil { - return nil - } - if err := mc.error(); err != nil { - return err - } - - // flip the buffer for this connection if we need to drain it. - // note that for a successful query (i.e. one where rows.next() - // has been called until it returns false), `rows.mc` will be nil - // by the time the user calls `(*Rows).Close`, so we won't reach this - // see: https://github.com/golang/go/commit/651ddbdb5056ded455f47f9c494c67b389622a47 - mc.buf.flip() - - // Remove unread packets from stream - if !rows.rs.done { - err = mc.readUntilEOF() - } - if err == nil { - handleOk := mc.clearResult() - if err = handleOk.discardResults(); err != nil { - return err - } - } - - rows.mc = nil - return err -} - -func (rows *mysqlRows) HasNextResultSet() (b bool) { - if rows.mc == nil { - return false - } - return rows.mc.status&statusMoreResultsExists != 0 -} - -func (rows *mysqlRows) nextResultSet() (int, error) { - if rows.mc == nil { - return 0, io.EOF - } - if err := rows.mc.error(); err != nil { - return 0, err - } - - // Remove unread packets from stream - if !rows.rs.done { - if err := rows.mc.readUntilEOF(); err != nil { - return 0, err - } - rows.rs.done = true - } - - if !rows.HasNextResultSet() { - rows.mc = nil - return 0, io.EOF - } - rows.rs = resultSet{} - // rows.mc.affectedRows and rows.mc.insertIds accumulate on each call to - // nextResultSet. - resLen, err := rows.mc.resultUnchanged().readResultSetHeaderPacket() - if err != nil { - // Clean up about multi-results flag - rows.rs.done = true - rows.mc.status = rows.mc.status & (^statusMoreResultsExists) - } - return resLen, err -} - -func (rows *mysqlRows) nextNotEmptyResultSet() (int, error) { - for { - resLen, err := rows.nextResultSet() - if err != nil { - return 0, err - } - - if resLen > 0 { - return resLen, nil - } - - rows.rs.done = true - } -} - -func (rows *binaryRows) NextResultSet() error { - resLen, err := rows.nextNotEmptyResultSet() - if err != nil { - return err - } - - rows.rs.columns, err = rows.mc.readColumns(resLen) - return err -} - -func (rows *binaryRows) Next(dest []driver.Value) error { - if mc := rows.mc; mc != nil { - if err := mc.error(); err != nil { - return err - } - - // Fetch next row from stream - return rows.readRow(dest) - } - return io.EOF -} - -func (rows *textRows) NextResultSet() (err error) { - resLen, err := rows.nextNotEmptyResultSet() - if err != nil { - return err - } - - rows.rs.columns, err = rows.mc.readColumns(resLen) - return err -} - -func (rows *textRows) Next(dest []driver.Value) error { - if mc := rows.mc; mc != nil { - if err := mc.error(); err != nil { - return err - } - - // Fetch next row from stream - return rows.readRow(dest) - } - return io.EOF -} diff --git a/v2/vendor/github.com/go-sql-driver/mysql/statement.go b/v2/vendor/github.com/go-sql-driver/mysql/statement.go deleted file mode 100644 index 0436f22..0000000 --- a/v2/vendor/github.com/go-sql-driver/mysql/statement.go +++ /dev/null @@ -1,217 +0,0 @@ -// Go MySQL Driver - A MySQL-Driver for Go's database/sql package -// -// Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this file, -// You can obtain one at http://mozilla.org/MPL/2.0/. - -package mysql - -import ( - "database/sql/driver" - "encoding/json" - "fmt" - "io" - "reflect" -) - -type mysqlStmt struct { - mc *mysqlConn - id uint32 - paramCount int -} - -func (stmt *mysqlStmt) Close() error { - if stmt.mc == nil || stmt.mc.closed.Load() { - // driver.Stmt.Close can be called more than once, thus this function - // has to be idempotent. - // See also Issue #450 and golang/go#16019. - //errLog.Print(ErrInvalidConn) - return driver.ErrBadConn - } - - err := stmt.mc.writeCommandPacketUint32(comStmtClose, stmt.id) - stmt.mc = nil - return err -} - -func (stmt *mysqlStmt) NumInput() int { - return stmt.paramCount -} - -func (stmt *mysqlStmt) ColumnConverter(idx int) driver.ValueConverter { - return converter{} -} - -func (stmt *mysqlStmt) CheckNamedValue(nv *driver.NamedValue) (err error) { - nv.Value, err = converter{}.ConvertValue(nv.Value) - return -} - -func (stmt *mysqlStmt) Exec(args []driver.Value) (driver.Result, error) { - if stmt.mc.closed.Load() { - stmt.mc.log(ErrInvalidConn) - return nil, driver.ErrBadConn - } - // Send command - err := stmt.writeExecutePacket(args) - if err != nil { - return nil, stmt.mc.markBadConn(err) - } - - mc := stmt.mc - handleOk := stmt.mc.clearResult() - - // Read Result - resLen, err := handleOk.readResultSetHeaderPacket() - if err != nil { - return nil, err - } - - if resLen > 0 { - // Columns - if err = mc.readUntilEOF(); err != nil { - return nil, err - } - - // Rows - if err := mc.readUntilEOF(); err != nil { - return nil, err - } - } - - if err := handleOk.discardResults(); err != nil { - return nil, err - } - - copied := mc.result - return &copied, nil -} - -func (stmt *mysqlStmt) Query(args []driver.Value) (driver.Rows, error) { - return stmt.query(args) -} - -func (stmt *mysqlStmt) query(args []driver.Value) (*binaryRows, error) { - if stmt.mc.closed.Load() { - stmt.mc.log(ErrInvalidConn) - return nil, driver.ErrBadConn - } - // Send command - err := stmt.writeExecutePacket(args) - if err != nil { - return nil, stmt.mc.markBadConn(err) - } - - mc := stmt.mc - - // Read Result - handleOk := stmt.mc.clearResult() - resLen, err := handleOk.readResultSetHeaderPacket() - if err != nil { - return nil, err - } - - rows := new(binaryRows) - - if resLen > 0 { - rows.mc = mc - rows.rs.columns, err = mc.readColumns(resLen) - } else { - rows.rs.done = true - - switch err := rows.NextResultSet(); err { - case nil, io.EOF: - return rows, nil - default: - return nil, err - } - } - - return rows, err -} - -var jsonType = reflect.TypeOf(json.RawMessage{}) - -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 any) (driver.Value, error) { - if driver.IsValue(v) { - 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 sv, nil - } - // A value returned from the Valuer interface can be "a type handled by - // a database driver's NamedValueChecker interface" so we should accept - // uint64 here as well. - if u, ok := sv.(uint64); ok { - return u, nil - } - return nil, fmt.Errorf("non-Value type %T returned from Value", sv) - } - rv := reflect.ValueOf(v) - switch rv.Kind() { - case reflect.Ptr: - // indirect pointers - if rv.IsNil() { - return nil, nil - } else { - return c.ConvertValue(rv.Elem().Interface()) - } - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - return rv.Int(), nil - case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: - return rv.Uint(), nil - case reflect.Float32, reflect.Float64: - return rv.Float(), nil - case reflect.Bool: - return rv.Bool(), nil - case reflect.Slice: - switch t := rv.Type(); { - case t == jsonType: - return v, nil - case t.Elem().Kind() == reflect.Uint8: - return rv.Bytes(), nil - default: - return nil, fmt.Errorf("unsupported type %T, a slice of %s", v, t.Elem().Kind()) - } - case reflect.String: - return rv.String(), nil - } - 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() -} diff --git a/v2/vendor/github.com/go-sql-driver/mysql/transaction.go b/v2/vendor/github.com/go-sql-driver/mysql/transaction.go deleted file mode 100644 index 4a4b610..0000000 --- a/v2/vendor/github.com/go-sql-driver/mysql/transaction.go +++ /dev/null @@ -1,31 +0,0 @@ -// Go MySQL Driver - A MySQL-Driver for Go's database/sql package -// -// Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this file, -// You can obtain one at http://mozilla.org/MPL/2.0/. - -package mysql - -type mysqlTx struct { - mc *mysqlConn -} - -func (tx *mysqlTx) Commit() (err error) { - if tx.mc == nil || tx.mc.closed.Load() { - return ErrInvalidConn - } - err = tx.mc.exec("COMMIT") - tx.mc = nil - return -} - -func (tx *mysqlTx) Rollback() (err error) { - if tx.mc == nil || tx.mc.closed.Load() { - return ErrInvalidConn - } - err = tx.mc.exec("ROLLBACK") - tx.mc = nil - return -} diff --git a/v2/vendor/github.com/go-sql-driver/mysql/utils.go b/v2/vendor/github.com/go-sql-driver/mysql/utils.go deleted file mode 100644 index cda24fe..0000000 --- a/v2/vendor/github.com/go-sql-driver/mysql/utils.go +++ /dev/null @@ -1,843 +0,0 @@ -// Go MySQL Driver - A MySQL-Driver for Go's database/sql package -// -// Copyright 2012 The Go-MySQL-Driver Authors. All rights reserved. -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this file, -// You can obtain one at http://mozilla.org/MPL/2.0/. - -package mysql - -import ( - "crypto/tls" - "database/sql" - "database/sql/driver" - "encoding/binary" - "errors" - "fmt" - "io" - "strconv" - "strings" - "sync" - "sync/atomic" - "time" -) - -// Registry for custom tls.Configs -var ( - tlsConfigLock sync.RWMutex - tlsConfigRegistry map[string]*tls.Config -) - -// RegisterTLSConfig registers a custom tls.Config to be used with sql.Open. -// Use the key as a value in the DSN where tls=value. -// -// Note: The provided tls.Config is exclusively owned by the driver after -// registering it. -// -// rootCertPool := x509.NewCertPool() -// pem, err := os.ReadFile("/path/ca-cert.pem") -// if err != nil { -// log.Fatal(err) -// } -// if ok := rootCertPool.AppendCertsFromPEM(pem); !ok { -// log.Fatal("Failed to append PEM.") -// } -// clientCert := make([]tls.Certificate, 0, 1) -// certs, err := tls.LoadX509KeyPair("/path/client-cert.pem", "/path/client-key.pem") -// if err != nil { -// log.Fatal(err) -// } -// clientCert = append(clientCert, certs) -// mysql.RegisterTLSConfig("custom", &tls.Config{ -// RootCAs: rootCertPool, -// Certificates: clientCert, -// }) -// db, err := sql.Open("mysql", "user@tcp(localhost:3306)/test?tls=custom") -func RegisterTLSConfig(key string, config *tls.Config) error { - if _, isBool := readBool(key); isBool || strings.ToLower(key) == "skip-verify" || strings.ToLower(key) == "preferred" { - return fmt.Errorf("key '%s' is reserved", key) - } - - tlsConfigLock.Lock() - if tlsConfigRegistry == nil { - tlsConfigRegistry = make(map[string]*tls.Config) - } - - tlsConfigRegistry[key] = config - tlsConfigLock.Unlock() - return nil -} - -// DeregisterTLSConfig removes the tls.Config associated with key. -func DeregisterTLSConfig(key string) { - tlsConfigLock.Lock() - if tlsConfigRegistry != nil { - delete(tlsConfigRegistry, key) - } - tlsConfigLock.Unlock() -} - -func getTLSConfigClone(key string) (config *tls.Config) { - tlsConfigLock.RLock() - if v, ok := tlsConfigRegistry[key]; ok { - config = v.Clone() - } - tlsConfigLock.RUnlock() - return -} - -// Returns the bool value of the input. -// The 2nd return value indicates if the input was a valid bool value -func readBool(input string) (value bool, valid bool) { - switch input { - case "1", "true", "TRUE", "True": - return true, true - case "0", "false", "FALSE", "False": - return false, true - } - - // Not a valid bool value - return -} - -/****************************************************************************** -* Time related utils * -******************************************************************************/ - -func parseDateTime(b []byte, loc *time.Location) (time.Time, error) { - const base = "0000-00-00 00:00:00.000000" - switch len(b) { - case 10, 19, 21, 22, 23, 24, 25, 26: // up to "YYYY-MM-DD HH:MM:SS.MMMMMM" - if string(b) == base[:len(b)] { - return time.Time{}, nil - } - - year, err := parseByteYear(b) - if err != nil { - return time.Time{}, err - } - if b[4] != '-' { - return time.Time{}, fmt.Errorf("bad value for field: `%c`", b[4]) - } - - m, err := parseByte2Digits(b[5], b[6]) - if err != nil { - return time.Time{}, err - } - month := time.Month(m) - - if b[7] != '-' { - return time.Time{}, fmt.Errorf("bad value for field: `%c`", b[7]) - } - - day, err := parseByte2Digits(b[8], b[9]) - if err != nil { - return time.Time{}, err - } - if len(b) == 10 { - return time.Date(year, month, day, 0, 0, 0, 0, loc), nil - } - - if b[10] != ' ' { - return time.Time{}, fmt.Errorf("bad value for field: `%c`", b[10]) - } - - hour, err := parseByte2Digits(b[11], b[12]) - if err != nil { - return time.Time{}, err - } - if b[13] != ':' { - return time.Time{}, fmt.Errorf("bad value for field: `%c`", b[13]) - } - - min, err := parseByte2Digits(b[14], b[15]) - if err != nil { - return time.Time{}, err - } - if b[16] != ':' { - return time.Time{}, fmt.Errorf("bad value for field: `%c`", b[16]) - } - - sec, err := parseByte2Digits(b[17], b[18]) - if err != nil { - return time.Time{}, err - } - if len(b) == 19 { - return time.Date(year, month, day, hour, min, sec, 0, loc), nil - } - - if b[19] != '.' { - return time.Time{}, fmt.Errorf("bad value for field: `%c`", b[19]) - } - nsec, err := parseByteNanoSec(b[20:]) - if err != nil { - return time.Time{}, err - } - return time.Date(year, month, day, hour, min, sec, nsec, loc), nil - default: - return time.Time{}, fmt.Errorf("invalid time bytes: %s", b) - } -} - -func parseByteYear(b []byte) (int, error) { - year, n := 0, 1000 - for i := 0; i < 4; i++ { - v, err := bToi(b[i]) - if err != nil { - return 0, err - } - year += v * n - n /= 10 - } - return year, nil -} - -func parseByte2Digits(b1, b2 byte) (int, error) { - d1, err := bToi(b1) - if err != nil { - return 0, err - } - d2, err := bToi(b2) - if err != nil { - return 0, err - } - return d1*10 + d2, nil -} - -func parseByteNanoSec(b []byte) (int, error) { - ns, digit := 0, 100000 // max is 6-digits - for i := 0; i < len(b); i++ { - v, err := bToi(b[i]) - if err != nil { - return 0, err - } - ns += v * digit - digit /= 10 - } - // nanoseconds has 10-digits. (needs to scale digits) - // 10 - 6 = 4, so we have to multiple 1000. - return ns * 1000, nil -} - -func bToi(b byte) (int, error) { - if b < '0' || b > '9' { - return 0, errors.New("not [0-9]") - } - return int(b - '0'), nil -} - -func parseBinaryDateTime(num uint64, data []byte, loc *time.Location) (driver.Value, error) { - switch num { - case 0: - return time.Time{}, nil - case 4: - return time.Date( - int(binary.LittleEndian.Uint16(data[:2])), // year - time.Month(data[2]), // month - int(data[3]), // day - 0, 0, 0, 0, - loc, - ), nil - case 7: - return time.Date( - int(binary.LittleEndian.Uint16(data[:2])), // year - time.Month(data[2]), // month - int(data[3]), // day - int(data[4]), // hour - int(data[5]), // minutes - int(data[6]), // seconds - 0, - loc, - ), nil - case 11: - return time.Date( - int(binary.LittleEndian.Uint16(data[:2])), // year - time.Month(data[2]), // month - int(data[3]), // day - int(data[4]), // hour - int(data[5]), // minutes - int(data[6]), // seconds - int(binary.LittleEndian.Uint32(data[7:11]))*1000, // nanoseconds - loc, - ), nil - } - return nil, fmt.Errorf("invalid DATETIME packet length %d", num) -} - -func appendDateTime(buf []byte, t time.Time, timeTruncate time.Duration) ([]byte, error) { - if timeTruncate > 0 { - t = t.Truncate(timeTruncate) - } - - year, month, day := t.Date() - hour, min, sec := t.Clock() - nsec := t.Nanosecond() - - if year < 1 || year > 9999 { - return buf, errors.New("year is not in the range [1, 9999]: " + strconv.Itoa(year)) // use errors.New instead of fmt.Errorf to avoid year escape to heap - } - year100 := year / 100 - year1 := year % 100 - - var localBuf [len("2006-01-02T15:04:05.999999999")]byte // does not escape - localBuf[0], localBuf[1], localBuf[2], localBuf[3] = digits10[year100], digits01[year100], digits10[year1], digits01[year1] - localBuf[4] = '-' - localBuf[5], localBuf[6] = digits10[month], digits01[month] - localBuf[7] = '-' - localBuf[8], localBuf[9] = digits10[day], digits01[day] - - if hour == 0 && min == 0 && sec == 0 && nsec == 0 { - return append(buf, localBuf[:10]...), nil - } - - localBuf[10] = ' ' - localBuf[11], localBuf[12] = digits10[hour], digits01[hour] - localBuf[13] = ':' - localBuf[14], localBuf[15] = digits10[min], digits01[min] - localBuf[16] = ':' - localBuf[17], localBuf[18] = digits10[sec], digits01[sec] - - if nsec == 0 { - return append(buf, localBuf[:19]...), nil - } - nsec100000000 := nsec / 100000000 - nsec1000000 := (nsec / 1000000) % 100 - nsec10000 := (nsec / 10000) % 100 - nsec100 := (nsec / 100) % 100 - nsec1 := nsec % 100 - localBuf[19] = '.' - - // milli second - localBuf[20], localBuf[21], localBuf[22] = - digits01[nsec100000000], digits10[nsec1000000], digits01[nsec1000000] - // micro second - localBuf[23], localBuf[24], localBuf[25] = - digits10[nsec10000], digits01[nsec10000], digits10[nsec100] - // nano second - localBuf[26], localBuf[27], localBuf[28] = - digits01[nsec100], digits10[nsec1], digits01[nsec1] - - // trim trailing zeros - n := len(localBuf) - for n > 0 && localBuf[n-1] == '0' { - n-- - } - - return append(buf, localBuf[:n]...), nil -} - -// zeroDateTime is used in formatBinaryDateTime to avoid an allocation -// if the DATE or DATETIME has the zero value. -// It must never be changed. -// The current behavior depends on database/sql copying the result. -var zeroDateTime = []byte("0000-00-00 00:00:00.000000") - -const digits01 = "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789" -const digits10 = "0000000000111111111122222222223333333333444444444455555555556666666666777777777788888888889999999999" - -func 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, - // negative time and 100+ hours are automatically added if needed - if len(src) == 0 { - return zeroDateTime[:length], nil - } - var dst []byte // return value - var p1, p2, p3 byte // current digit pair - - 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 := year / 100 - p1 = byte(year - 100*uint16(pt)) - p2, p3 = src[2], src[3] - dst = append(dst, - digits10[pt], digits01[pt], - digits10[p1], digits01[p1], '-', - digits10[p2], digits01[p2], '-', - digits10[p3], digits01[p3], - ) - if length == 10 { - return dst, nil - } - if len(src) == 4 { - return append(dst, zeroDateTime[10:length]...), nil - } - dst = append(dst, ' ') - p1 = src[4] // hour - src = src[5:] - - // p1 is 2-digit hour, src is after hour - p2, p3 = src[0], src[1] - dst = append(dst, - digits10[p1], digits01[p1], ':', - digits10[p2], digits01[p2], ':', - digits10[p3], digits01[p3], - ) - return appendMicrosecs(dst, src[2:], int(length)-20), nil -} - -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 { - return zeroDateTime[11 : 11+length], nil - } - var dst []byte // return value - - switch length { - case - 8, // time (can be up to 10 when negative and 100+ hours) - 10, 11, 12, 13, 14, 15: // time with fractional seconds - default: - return nil, fmt.Errorf("illegal TIME length %d", length) - } - switch len(src) { - case 8, 12: - default: - return nil, fmt.Errorf("invalid TIME packet length %d", len(src)) - } - // +2 to enable negative time and 100+ hours - dst = make([]byte, 0, length+2) - if src[0] == 1 { - dst = append(dst, '-') - } - 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 -} - -/****************************************************************************** -* Convert from and to bytes * -******************************************************************************/ - -func uint64ToBytes(n uint64) []byte { - return []byte{ - byte(n), - byte(n >> 8), - byte(n >> 16), - byte(n >> 24), - byte(n >> 32), - byte(n >> 40), - byte(n >> 48), - byte(n >> 56), - } -} - -func uint64ToString(n uint64) []byte { - var a [20]byte - i := 20 - - // U+0030 = 0 - // ... - // U+0039 = 9 - - var q uint64 - for n >= 10 { - i-- - q = n / 10 - a[i] = uint8(n-q*10) + 0x30 - n = q - } - - i-- - a[i] = uint8(n) + 0x30 - - return a[i:] -} - -// treats string value as unsigned integer representation -func stringToInt(b []byte) int { - val := 0 - for i := range b { - val *= 10 - val += int(b[i] - 0x30) - } - return val -} - -// returns the string read as a bytes slice, whether the value is NULL, -// the number of bytes read and an error, in case the string is longer than -// the input slice -func readLengthEncodedString(b []byte) ([]byte, bool, int, error) { - // Get length - num, isNull, n := readLengthEncodedInteger(b) - if num < 1 { - return b[n:n], isNull, n, nil - } - - n += int(num) - - // Check data length - if len(b) >= n { - return b[n-int(num) : n : n], false, n, nil - } - return nil, false, n, io.EOF -} - -// returns the number of bytes skipped and an error, in case the string is -// longer than the input slice -func skipLengthEncodedString(b []byte) (int, error) { - // Get length - num, _, n := readLengthEncodedInteger(b) - if num < 1 { - return n, nil - } - - n += int(num) - - // Check data length - if len(b) >= n { - return n, nil - } - return n, io.EOF -} - -// returns the number read, whether the value is NULL and the number of bytes read -func readLengthEncodedInteger(b []byte) (uint64, bool, int) { - // See issue #349 - if len(b) == 0 { - return 0, true, 1 - } - - switch b[0] { - // 251: NULL - case 0xfb: - return 0, true, 1 - - // 252: value of following 2 - case 0xfc: - return uint64(b[1]) | uint64(b[2])<<8, false, 3 - - // 253: value of following 3 - case 0xfd: - return uint64(b[1]) | uint64(b[2])<<8 | uint64(b[3])<<16, false, 4 - - // 254: value of following 8 - case 0xfe: - return uint64(b[1]) | uint64(b[2])<<8 | uint64(b[3])<<16 | - uint64(b[4])<<24 | uint64(b[5])<<32 | uint64(b[6])<<40 | - uint64(b[7])<<48 | uint64(b[8])<<56, - false, 9 - } - - // 0-250: value of first byte - return uint64(b[0]), false, 1 -} - -// encodes a uint64 value and appends it to the given bytes slice -func appendLengthEncodedInteger(b []byte, n uint64) []byte { - switch { - case n <= 250: - return append(b, byte(n)) - - case n <= 0xffff: - return append(b, 0xfc, byte(n), byte(n>>8)) - - case n <= 0xffffff: - return append(b, 0xfd, byte(n), byte(n>>8), byte(n>>16)) - } - return append(b, 0xfe, byte(n), byte(n>>8), byte(n>>16), byte(n>>24), - byte(n>>32), byte(n>>40), byte(n>>48), byte(n>>56)) -} - -func appendLengthEncodedString(b []byte, s string) []byte { - b = appendLengthEncodedInteger(b, uint64(len(s))) - return append(b, s...) -} - -// reserveBuffer checks cap(buf) and expand buffer to len(buf) + appendSize. -// If cap(buf) is not enough, reallocate new buffer. -func reserveBuffer(buf []byte, appendSize int) []byte { - newSize := len(buf) + appendSize - if cap(buf) < newSize { - // Grow buffer exponentially - newBuf := make([]byte, len(buf)*2+appendSize) - copy(newBuf, buf) - buf = newBuf - } - return buf[:newSize] -} - -// escapeBytesBackslash escapes []byte with backslashes (\) -// This escapes the contents of a string (provided as []byte) by adding backslashes before special -// characters, and turning others into specific escape sequences, such as -// turning newlines into \n and null bytes into \0. -// https://github.com/mysql/mysql-server/blob/mysql-5.7.5/mysys/charset.c#L823-L932 -func escapeBytesBackslash(buf, v []byte) []byte { - pos := len(buf) - buf = reserveBuffer(buf, len(v)*2) - - for _, c := range v { - switch c { - case '\x00': - buf[pos+1] = '0' - buf[pos] = '\\' - pos += 2 - case '\n': - buf[pos+1] = 'n' - buf[pos] = '\\' - pos += 2 - case '\r': - buf[pos+1] = 'r' - buf[pos] = '\\' - pos += 2 - case '\x1a': - buf[pos+1] = 'Z' - buf[pos] = '\\' - pos += 2 - case '\'': - buf[pos+1] = '\'' - buf[pos] = '\\' - pos += 2 - case '"': - buf[pos+1] = '"' - buf[pos] = '\\' - pos += 2 - case '\\': - buf[pos+1] = '\\' - buf[pos] = '\\' - pos += 2 - default: - buf[pos] = c - pos++ - } - } - - return buf[:pos] -} - -// escapeStringBackslash is similar to escapeBytesBackslash but for string. -func escapeStringBackslash(buf []byte, v string) []byte { - pos := len(buf) - buf = reserveBuffer(buf, len(v)*2) - - for i := 0; i < len(v); i++ { - c := v[i] - switch c { - case '\x00': - buf[pos+1] = '0' - buf[pos] = '\\' - pos += 2 - case '\n': - buf[pos+1] = 'n' - buf[pos] = '\\' - pos += 2 - case '\r': - buf[pos+1] = 'r' - buf[pos] = '\\' - pos += 2 - case '\x1a': - buf[pos+1] = 'Z' - buf[pos] = '\\' - pos += 2 - case '\'': - buf[pos+1] = '\'' - buf[pos] = '\\' - pos += 2 - case '"': - buf[pos+1] = '"' - buf[pos] = '\\' - pos += 2 - case '\\': - buf[pos+1] = '\\' - buf[pos] = '\\' - pos += 2 - default: - buf[pos] = c - pos++ - } - } - - return buf[:pos] -} - -// escapeBytesQuotes escapes apostrophes in []byte by doubling them up. -// This escapes the contents of a string by doubling up any apostrophes that -// it contains. This is used when the NO_BACKSLASH_ESCAPES SQL_MODE is in -// effect on the server. -// https://github.com/mysql/mysql-server/blob/mysql-5.7.5/mysys/charset.c#L963-L1038 -func escapeBytesQuotes(buf, v []byte) []byte { - pos := len(buf) - buf = reserveBuffer(buf, len(v)*2) - - for _, c := range v { - if c == '\'' { - buf[pos+1] = '\'' - buf[pos] = '\'' - pos += 2 - } else { - buf[pos] = c - pos++ - } - } - - return buf[:pos] -} - -// escapeStringQuotes is similar to escapeBytesQuotes but for string. -func escapeStringQuotes(buf []byte, v string) []byte { - pos := len(buf) - buf = reserveBuffer(buf, len(v)*2) - - for i := 0; i < len(v); i++ { - c := v[i] - if c == '\'' { - buf[pos+1] = '\'' - buf[pos] = '\'' - pos += 2 - } else { - buf[pos] = c - pos++ - } - } - - return buf[:pos] -} - -/****************************************************************************** -* Sync utils * -******************************************************************************/ - -// noCopy may be embedded into structs which must not be copied -// after the first use. -// -// See https://github.com/golang/go/issues/8005#issuecomment-190753527 -// for details. -type noCopy struct{} - -// Lock is a no-op used by -copylocks checker from `go vet`. -func (*noCopy) Lock() {} - -// Unlock is a no-op used by -copylocks checker from `go vet`. -// noCopy should implement sync.Locker from Go 1.11 -// https://github.com/golang/go/commit/c2eba53e7f80df21d51285879d51ab81bcfbf6bc -// https://github.com/golang/go/issues/26165 -func (*noCopy) Unlock() {} - -// atomicError is a wrapper for atomically accessed error values -type atomicError struct { - _ noCopy - value atomic.Value -} - -// Set sets the error value regardless of the previous value. -// The value must not be nil -func (ae *atomicError) Set(value error) { - ae.value.Store(value) -} - -// Value returns the current error value -func (ae *atomicError) Value() error { - if v := ae.value.Load(); v != nil { - // this will panic if the value doesn't implement the error interface - return v.(error) - } - return nil -} - -func namedValueToValue(named []driver.NamedValue) ([]driver.Value, error) { - dargs := make([]driver.Value, len(named)) - for n, param := range named { - if len(param.Name) > 0 { - // TODO: support the use of Named Parameters #561 - return nil, errors.New("mysql: driver does not support the use of Named Parameters") - } - dargs[n] = param.Value - } - return dargs, nil -} - -func mapIsolationLevel(level driver.IsolationLevel) (string, error) { - switch sql.IsolationLevel(level) { - case sql.LevelRepeatableRead: - return "REPEATABLE READ", nil - case sql.LevelReadCommitted: - return "READ COMMITTED", nil - case sql.LevelReadUncommitted: - return "READ UNCOMMITTED", nil - case sql.LevelSerializable: - return "SERIALIZABLE", nil - default: - return "", fmt.Errorf("mysql: unsupported isolation level: %v", level) - } -} diff --git a/v2/vendor/github.com/google/uuid/CHANGELOG.md b/v2/vendor/github.com/google/uuid/CHANGELOG.md new file mode 100644 index 0000000..7ec5ac7 --- /dev/null +++ b/v2/vendor/github.com/google/uuid/CHANGELOG.md @@ -0,0 +1,41 @@ +# Changelog + +## [1.6.0](https://github.com/google/uuid/compare/v1.5.0...v1.6.0) (2024-01-16) + + +### Features + +* add Max UUID constant ([#149](https://github.com/google/uuid/issues/149)) ([c58770e](https://github.com/google/uuid/commit/c58770eb495f55fe2ced6284f93c5158a62e53e3)) + + +### Bug Fixes + +* fix typo in version 7 uuid documentation ([#153](https://github.com/google/uuid/issues/153)) ([016b199](https://github.com/google/uuid/commit/016b199544692f745ffc8867b914129ecb47ef06)) +* Monotonicity in UUIDv7 ([#150](https://github.com/google/uuid/issues/150)) ([a2b2b32](https://github.com/google/uuid/commit/a2b2b32373ff0b1a312b7fdf6d38a977099698a6)) + +## [1.5.0](https://github.com/google/uuid/compare/v1.4.0...v1.5.0) (2023-12-12) + + +### Features + +* Validate UUID without creating new UUID ([#141](https://github.com/google/uuid/issues/141)) ([9ee7366](https://github.com/google/uuid/commit/9ee7366e66c9ad96bab89139418a713dc584ae29)) + +## [1.4.0](https://github.com/google/uuid/compare/v1.3.1...v1.4.0) (2023-10-26) + + +### Features + +* UUIDs slice type with Strings() convenience method ([#133](https://github.com/google/uuid/issues/133)) ([cd5fbbd](https://github.com/google/uuid/commit/cd5fbbdd02f3e3467ac18940e07e062be1f864b4)) + +### Fixes + +* Clarify that Parse's job is to parse but not necessarily validate strings. (Documents current behavior) + +## [1.3.1](https://github.com/google/uuid/compare/v1.3.0...v1.3.1) (2023-08-18) + + +### Bug Fixes + +* Use .EqualFold() to parse urn prefixed UUIDs ([#118](https://github.com/google/uuid/issues/118)) ([574e687](https://github.com/google/uuid/commit/574e6874943741fb99d41764c705173ada5293f0)) + +## Changelog diff --git a/v2/vendor/github.com/google/uuid/CONTRIBUTING.md b/v2/vendor/github.com/google/uuid/CONTRIBUTING.md new file mode 100644 index 0000000..a502fdc --- /dev/null +++ b/v2/vendor/github.com/google/uuid/CONTRIBUTING.md @@ -0,0 +1,26 @@ +# How to contribute + +We definitely welcome patches and contribution to this project! + +### Tips + +Commits must be formatted according to the [Conventional Commits Specification](https://www.conventionalcommits.org). + +Always try to include a test case! If it is not possible or not necessary, +please explain why in the pull request description. + +### Releasing + +Commits that would precipitate a SemVer change, as described in the Conventional +Commits Specification, will trigger [`release-please`](https://github.com/google-github-actions/release-please-action) +to create a release candidate pull request. Once submitted, `release-please` +will create a release. + +For tips on how to work with `release-please`, see its documentation. + +### Legal requirements + +In order to protect both you and ourselves, you will need to sign the +[Contributor License Agreement](https://cla.developers.google.com/clas). + +You may have already signed it for other Google projects. diff --git a/v2/vendor/github.com/google/uuid/CONTRIBUTORS b/v2/vendor/github.com/google/uuid/CONTRIBUTORS new file mode 100644 index 0000000..b4bb97f --- /dev/null +++ b/v2/vendor/github.com/google/uuid/CONTRIBUTORS @@ -0,0 +1,9 @@ +Paul Borman +bmatsuo +shawnps +theory +jboverfelt +dsymonds +cd1 +wallclockbuilder +dansouza diff --git a/v2/vendor/filippo.io/edwards25519/LICENSE b/v2/vendor/github.com/google/uuid/LICENSE similarity index 96% rename from v2/vendor/filippo.io/edwards25519/LICENSE rename to v2/vendor/github.com/google/uuid/LICENSE index 6a66aea..5dc6826 100644 --- a/v2/vendor/filippo.io/edwards25519/LICENSE +++ b/v2/vendor/github.com/google/uuid/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2009 The Go Authors. All rights reserved. +Copyright (c) 2009,2014 Google Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are diff --git a/v2/vendor/github.com/google/uuid/README.md b/v2/vendor/github.com/google/uuid/README.md new file mode 100644 index 0000000..3e9a618 --- /dev/null +++ b/v2/vendor/github.com/google/uuid/README.md @@ -0,0 +1,21 @@ +# uuid +The uuid package generates and inspects UUIDs based on +[RFC 4122](https://datatracker.ietf.org/doc/html/rfc4122) +and DCE 1.1: Authentication and Security Services. + +This package is based on the github.com/pborman/uuid package (previously named +code.google.com/p/go-uuid). It differs from these earlier packages in that +a UUID is a 16 byte array rather than a byte slice. One loss due to this +change is the ability to represent an invalid UUID (vs a NIL UUID). + +###### Install +```sh +go get github.com/google/uuid +``` + +###### Documentation +[![Go Reference](https://pkg.go.dev/badge/github.com/google/uuid.svg)](https://pkg.go.dev/github.com/google/uuid) + +Full `go doc` style documentation for the package can be viewed online without +installing this package by using the GoDoc site here: +http://pkg.go.dev/github.com/google/uuid diff --git a/v2/vendor/github.com/google/uuid/dce.go b/v2/vendor/github.com/google/uuid/dce.go new file mode 100644 index 0000000..fa820b9 --- /dev/null +++ b/v2/vendor/github.com/google/uuid/dce.go @@ -0,0 +1,80 @@ +// Copyright 2016 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import ( + "encoding/binary" + "fmt" + "os" +) + +// A Domain represents a Version 2 domain +type Domain byte + +// Domain constants for DCE Security (Version 2) UUIDs. +const ( + Person = Domain(0) + Group = Domain(1) + Org = Domain(2) +) + +// NewDCESecurity returns a DCE Security (Version 2) UUID. +// +// The domain should be one of Person, Group or Org. +// On a POSIX system the id should be the users UID for the Person +// domain and the users GID for the Group. The meaning of id for +// the domain Org or on non-POSIX systems is site defined. +// +// For a given domain/id pair the same token may be returned for up to +// 7 minutes and 10 seconds. +func NewDCESecurity(domain Domain, id uint32) (UUID, error) { + uuid, err := NewUUID() + if err == nil { + uuid[6] = (uuid[6] & 0x0f) | 0x20 // Version 2 + uuid[9] = byte(domain) + binary.BigEndian.PutUint32(uuid[0:], id) + } + return uuid, err +} + +// NewDCEPerson returns a DCE Security (Version 2) UUID in the person +// domain with the id returned by os.Getuid. +// +// NewDCESecurity(Person, uint32(os.Getuid())) +func NewDCEPerson() (UUID, error) { + return NewDCESecurity(Person, uint32(os.Getuid())) +} + +// NewDCEGroup returns a DCE Security (Version 2) UUID in the group +// domain with the id returned by os.Getgid. +// +// NewDCESecurity(Group, uint32(os.Getgid())) +func NewDCEGroup() (UUID, error) { + return NewDCESecurity(Group, uint32(os.Getgid())) +} + +// Domain returns the domain for a Version 2 UUID. Domains are only defined +// for Version 2 UUIDs. +func (uuid UUID) Domain() Domain { + return Domain(uuid[9]) +} + +// ID returns the id for a Version 2 UUID. IDs are only defined for Version 2 +// UUIDs. +func (uuid UUID) ID() uint32 { + return binary.BigEndian.Uint32(uuid[0:4]) +} + +func (d Domain) String() string { + switch d { + case Person: + return "Person" + case Group: + return "Group" + case Org: + return "Org" + } + return fmt.Sprintf("Domain%d", int(d)) +} diff --git a/v2/vendor/github.com/google/uuid/doc.go b/v2/vendor/github.com/google/uuid/doc.go new file mode 100644 index 0000000..5b8a4b9 --- /dev/null +++ b/v2/vendor/github.com/google/uuid/doc.go @@ -0,0 +1,12 @@ +// Copyright 2016 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package uuid generates and inspects UUIDs. +// +// UUIDs are based on RFC 4122 and DCE 1.1: Authentication and Security +// Services. +// +// A UUID is a 16 byte (128 bit) array. UUIDs may be used as keys to +// maps or compared directly. +package uuid diff --git a/v2/vendor/github.com/google/uuid/hash.go b/v2/vendor/github.com/google/uuid/hash.go new file mode 100644 index 0000000..dc60082 --- /dev/null +++ b/v2/vendor/github.com/google/uuid/hash.go @@ -0,0 +1,59 @@ +// Copyright 2016 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import ( + "crypto/md5" + "crypto/sha1" + "hash" +) + +// Well known namespace IDs and UUIDs +var ( + NameSpaceDNS = Must(Parse("6ba7b810-9dad-11d1-80b4-00c04fd430c8")) + NameSpaceURL = Must(Parse("6ba7b811-9dad-11d1-80b4-00c04fd430c8")) + NameSpaceOID = Must(Parse("6ba7b812-9dad-11d1-80b4-00c04fd430c8")) + NameSpaceX500 = Must(Parse("6ba7b814-9dad-11d1-80b4-00c04fd430c8")) + Nil UUID // empty UUID, all zeros + + // The Max UUID is special form of UUID that is specified to have all 128 bits set to 1. + Max = UUID{ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + } +) + +// NewHash returns a new UUID derived from the hash of space concatenated with +// data generated by h. The hash should be at least 16 byte in length. The +// first 16 bytes of the hash are used to form the UUID. The version of the +// UUID will be the lower 4 bits of version. NewHash is used to implement +// NewMD5 and NewSHA1. +func NewHash(h hash.Hash, space UUID, data []byte, version int) UUID { + h.Reset() + h.Write(space[:]) //nolint:errcheck + h.Write(data) //nolint:errcheck + s := h.Sum(nil) + var uuid UUID + copy(uuid[:], s) + uuid[6] = (uuid[6] & 0x0f) | uint8((version&0xf)<<4) + uuid[8] = (uuid[8] & 0x3f) | 0x80 // RFC 4122 variant + return uuid +} + +// NewMD5 returns a new MD5 (Version 3) UUID based on the +// supplied name space and data. It is the same as calling: +// +// NewHash(md5.New(), space, data, 3) +func NewMD5(space UUID, data []byte) UUID { + return NewHash(md5.New(), space, data, 3) +} + +// NewSHA1 returns a new SHA1 (Version 5) UUID based on the +// supplied name space and data. It is the same as calling: +// +// NewHash(sha1.New(), space, data, 5) +func NewSHA1(space UUID, data []byte) UUID { + return NewHash(sha1.New(), space, data, 5) +} diff --git a/v2/vendor/github.com/google/uuid/marshal.go b/v2/vendor/github.com/google/uuid/marshal.go new file mode 100644 index 0000000..14bd340 --- /dev/null +++ b/v2/vendor/github.com/google/uuid/marshal.go @@ -0,0 +1,38 @@ +// Copyright 2016 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import "fmt" + +// MarshalText implements encoding.TextMarshaler. +func (uuid UUID) MarshalText() ([]byte, error) { + var js [36]byte + encodeHex(js[:], uuid) + return js[:], nil +} + +// UnmarshalText implements encoding.TextUnmarshaler. +func (uuid *UUID) UnmarshalText(data []byte) error { + id, err := ParseBytes(data) + if err != nil { + return err + } + *uuid = id + return nil +} + +// MarshalBinary implements encoding.BinaryMarshaler. +func (uuid UUID) MarshalBinary() ([]byte, error) { + return uuid[:], nil +} + +// UnmarshalBinary implements encoding.BinaryUnmarshaler. +func (uuid *UUID) UnmarshalBinary(data []byte) error { + if len(data) != 16 { + return fmt.Errorf("invalid UUID (got %d bytes)", len(data)) + } + copy(uuid[:], data) + return nil +} diff --git a/v2/vendor/github.com/google/uuid/node.go b/v2/vendor/github.com/google/uuid/node.go new file mode 100644 index 0000000..d651a2b --- /dev/null +++ b/v2/vendor/github.com/google/uuid/node.go @@ -0,0 +1,90 @@ +// Copyright 2016 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import ( + "sync" +) + +var ( + nodeMu sync.Mutex + ifname string // name of interface being used + nodeID [6]byte // hardware for version 1 UUIDs + zeroID [6]byte // nodeID with only 0's +) + +// NodeInterface returns the name of the interface from which the NodeID was +// derived. The interface "user" is returned if the NodeID was set by +// SetNodeID. +func NodeInterface() string { + defer nodeMu.Unlock() + nodeMu.Lock() + return ifname +} + +// SetNodeInterface selects the hardware address to be used for Version 1 UUIDs. +// If name is "" then the first usable interface found will be used or a random +// Node ID will be generated. If a named interface cannot be found then false +// is returned. +// +// SetNodeInterface never fails when name is "". +func SetNodeInterface(name string) bool { + defer nodeMu.Unlock() + nodeMu.Lock() + return setNodeInterface(name) +} + +func setNodeInterface(name string) bool { + iname, addr := getHardwareInterface(name) // null implementation for js + if iname != "" && addr != nil { + ifname = iname + copy(nodeID[:], addr) + return true + } + + // We found no interfaces with a valid hardware address. If name + // does not specify a specific interface generate a random Node ID + // (section 4.1.6) + if name == "" { + ifname = "random" + randomBits(nodeID[:]) + return true + } + return false +} + +// NodeID returns a slice of a copy of the current Node ID, setting the Node ID +// if not already set. +func NodeID() []byte { + defer nodeMu.Unlock() + nodeMu.Lock() + if nodeID == zeroID { + setNodeInterface("") + } + nid := nodeID + return nid[:] +} + +// SetNodeID sets the Node ID to be used for Version 1 UUIDs. The first 6 bytes +// of id are used. If id is less than 6 bytes then false is returned and the +// Node ID is not set. +func SetNodeID(id []byte) bool { + if len(id) < 6 { + return false + } + defer nodeMu.Unlock() + nodeMu.Lock() + copy(nodeID[:], id) + ifname = "user" + return true +} + +// NodeID returns the 6 byte node id encoded in uuid. It returns nil if uuid is +// not valid. The NodeID is only well defined for version 1 and 2 UUIDs. +func (uuid UUID) NodeID() []byte { + var node [6]byte + copy(node[:], uuid[10:]) + return node[:] +} diff --git a/v2/vendor/github.com/google/uuid/node_js.go b/v2/vendor/github.com/google/uuid/node_js.go new file mode 100644 index 0000000..b2a0bc8 --- /dev/null +++ b/v2/vendor/github.com/google/uuid/node_js.go @@ -0,0 +1,12 @@ +// Copyright 2017 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build js + +package uuid + +// getHardwareInterface returns nil values for the JS version of the code. +// This removes the "net" dependency, because it is not used in the browser. +// Using the "net" library inflates the size of the transpiled JS code by 673k bytes. +func getHardwareInterface(name string) (string, []byte) { return "", nil } diff --git a/v2/vendor/github.com/google/uuid/node_net.go b/v2/vendor/github.com/google/uuid/node_net.go new file mode 100644 index 0000000..0cbbcdd --- /dev/null +++ b/v2/vendor/github.com/google/uuid/node_net.go @@ -0,0 +1,33 @@ +// Copyright 2017 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !js + +package uuid + +import "net" + +var interfaces []net.Interface // cached list of interfaces + +// getHardwareInterface returns the name and hardware address of interface name. +// If name is "" then the name and hardware address of one of the system's +// interfaces is returned. If no interfaces are found (name does not exist or +// there are no interfaces) then "", nil is returned. +// +// Only addresses of at least 6 bytes are returned. +func getHardwareInterface(name string) (string, []byte) { + if interfaces == nil { + var err error + interfaces, err = net.Interfaces() + if err != nil { + return "", nil + } + } + for _, ifs := range interfaces { + if len(ifs.HardwareAddr) >= 6 && (name == "" || name == ifs.Name) { + return ifs.Name, ifs.HardwareAddr + } + } + return "", nil +} diff --git a/v2/vendor/github.com/google/uuid/null.go b/v2/vendor/github.com/google/uuid/null.go new file mode 100644 index 0000000..d7fcbf2 --- /dev/null +++ b/v2/vendor/github.com/google/uuid/null.go @@ -0,0 +1,118 @@ +// Copyright 2021 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import ( + "bytes" + "database/sql/driver" + "encoding/json" + "fmt" +) + +var jsonNull = []byte("null") + +// NullUUID represents a UUID that may be null. +// NullUUID implements the SQL driver.Scanner interface so +// it can be used as a scan destination: +// +// var u uuid.NullUUID +// err := db.QueryRow("SELECT name FROM foo WHERE id=?", id).Scan(&u) +// ... +// if u.Valid { +// // use u.UUID +// } else { +// // NULL value +// } +// +type NullUUID struct { + UUID UUID + Valid bool // Valid is true if UUID is not NULL +} + +// Scan implements the SQL driver.Scanner interface. +func (nu *NullUUID) Scan(value interface{}) error { + if value == nil { + nu.UUID, nu.Valid = Nil, false + return nil + } + + err := nu.UUID.Scan(value) + if err != nil { + nu.Valid = false + return err + } + + nu.Valid = true + return nil +} + +// Value implements the driver Valuer interface. +func (nu NullUUID) Value() (driver.Value, error) { + if !nu.Valid { + return nil, nil + } + // Delegate to UUID Value function + return nu.UUID.Value() +} + +// MarshalBinary implements encoding.BinaryMarshaler. +func (nu NullUUID) MarshalBinary() ([]byte, error) { + if nu.Valid { + return nu.UUID[:], nil + } + + return []byte(nil), nil +} + +// UnmarshalBinary implements encoding.BinaryUnmarshaler. +func (nu *NullUUID) UnmarshalBinary(data []byte) error { + if len(data) != 16 { + return fmt.Errorf("invalid UUID (got %d bytes)", len(data)) + } + copy(nu.UUID[:], data) + nu.Valid = true + return nil +} + +// MarshalText implements encoding.TextMarshaler. +func (nu NullUUID) MarshalText() ([]byte, error) { + if nu.Valid { + return nu.UUID.MarshalText() + } + + return jsonNull, nil +} + +// UnmarshalText implements encoding.TextUnmarshaler. +func (nu *NullUUID) UnmarshalText(data []byte) error { + id, err := ParseBytes(data) + if err != nil { + nu.Valid = false + return err + } + nu.UUID = id + nu.Valid = true + return nil +} + +// MarshalJSON implements json.Marshaler. +func (nu NullUUID) MarshalJSON() ([]byte, error) { + if nu.Valid { + return json.Marshal(nu.UUID) + } + + return jsonNull, nil +} + +// UnmarshalJSON implements json.Unmarshaler. +func (nu *NullUUID) UnmarshalJSON(data []byte) error { + if bytes.Equal(data, jsonNull) { + *nu = NullUUID{} + return nil // valid null UUID + } + err := json.Unmarshal(data, &nu.UUID) + nu.Valid = err == nil + return err +} diff --git a/v2/vendor/github.com/google/uuid/sql.go b/v2/vendor/github.com/google/uuid/sql.go new file mode 100644 index 0000000..2e02ec0 --- /dev/null +++ b/v2/vendor/github.com/google/uuid/sql.go @@ -0,0 +1,59 @@ +// Copyright 2016 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import ( + "database/sql/driver" + "fmt" +) + +// Scan implements sql.Scanner so UUIDs can be read from databases transparently. +// Currently, database types that map to string and []byte are supported. Please +// consult database-specific driver documentation for matching types. +func (uuid *UUID) Scan(src interface{}) error { + switch src := src.(type) { + case nil: + return nil + + case string: + // if an empty UUID comes from a table, we return a null UUID + if src == "" { + return nil + } + + // see Parse for required string format + u, err := Parse(src) + if err != nil { + return fmt.Errorf("Scan: %v", err) + } + + *uuid = u + + case []byte: + // if an empty UUID comes from a table, we return a null UUID + if len(src) == 0 { + return nil + } + + // assumes a simple slice of bytes if 16 bytes + // otherwise attempts to parse + if len(src) != 16 { + return uuid.Scan(string(src)) + } + copy((*uuid)[:], src) + + default: + return fmt.Errorf("Scan: unable to scan type %T into UUID", src) + } + + return nil +} + +// Value implements sql.Valuer so that UUIDs can be written to databases +// transparently. Currently, UUIDs map to strings. Please consult +// database-specific driver documentation for matching types. +func (uuid UUID) Value() (driver.Value, error) { + return uuid.String(), nil +} diff --git a/v2/vendor/github.com/google/uuid/time.go b/v2/vendor/github.com/google/uuid/time.go new file mode 100644 index 0000000..c351129 --- /dev/null +++ b/v2/vendor/github.com/google/uuid/time.go @@ -0,0 +1,134 @@ +// Copyright 2016 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import ( + "encoding/binary" + "sync" + "time" +) + +// A Time represents a time as the number of 100's of nanoseconds since 15 Oct +// 1582. +type Time int64 + +const ( + lillian = 2299160 // Julian day of 15 Oct 1582 + unix = 2440587 // Julian day of 1 Jan 1970 + epoch = unix - lillian // Days between epochs + g1582 = epoch * 86400 // seconds between epochs + g1582ns100 = g1582 * 10000000 // 100s of a nanoseconds between epochs +) + +var ( + timeMu sync.Mutex + lasttime uint64 // last time we returned + clockSeq uint16 // clock sequence for this run + + timeNow = time.Now // for testing +) + +// UnixTime converts t the number of seconds and nanoseconds using the Unix +// epoch of 1 Jan 1970. +func (t Time) UnixTime() (sec, nsec int64) { + sec = int64(t - g1582ns100) + nsec = (sec % 10000000) * 100 + sec /= 10000000 + return sec, nsec +} + +// GetTime returns the current Time (100s of nanoseconds since 15 Oct 1582) and +// clock sequence as well as adjusting the clock sequence as needed. An error +// is returned if the current time cannot be determined. +func GetTime() (Time, uint16, error) { + defer timeMu.Unlock() + timeMu.Lock() + return getTime() +} + +func getTime() (Time, uint16, error) { + t := timeNow() + + // If we don't have a clock sequence already, set one. + if clockSeq == 0 { + setClockSequence(-1) + } + now := uint64(t.UnixNano()/100) + g1582ns100 + + // If time has gone backwards with this clock sequence then we + // increment the clock sequence + if now <= lasttime { + clockSeq = ((clockSeq + 1) & 0x3fff) | 0x8000 + } + lasttime = now + return Time(now), clockSeq, nil +} + +// ClockSequence returns the current clock sequence, generating one if not +// already set. The clock sequence is only used for Version 1 UUIDs. +// +// The uuid package does not use global static storage for the clock sequence or +// the last time a UUID was generated. Unless SetClockSequence is used, a new +// random clock sequence is generated the first time a clock sequence is +// requested by ClockSequence, GetTime, or NewUUID. (section 4.2.1.1) +func ClockSequence() int { + defer timeMu.Unlock() + timeMu.Lock() + return clockSequence() +} + +func clockSequence() int { + if clockSeq == 0 { + setClockSequence(-1) + } + return int(clockSeq & 0x3fff) +} + +// SetClockSequence sets the clock sequence to the lower 14 bits of seq. Setting to +// -1 causes a new sequence to be generated. +func SetClockSequence(seq int) { + defer timeMu.Unlock() + timeMu.Lock() + setClockSequence(seq) +} + +func setClockSequence(seq int) { + if seq == -1 { + var b [2]byte + randomBits(b[:]) // clock sequence + seq = int(b[0])<<8 | int(b[1]) + } + oldSeq := clockSeq + clockSeq = uint16(seq&0x3fff) | 0x8000 // Set our variant + if oldSeq != clockSeq { + lasttime = 0 + } +} + +// Time returns the time in 100s of nanoseconds since 15 Oct 1582 encoded in +// uuid. The time is only defined for version 1, 2, 6 and 7 UUIDs. +func (uuid UUID) Time() Time { + var t Time + switch uuid.Version() { + case 6: + time := binary.BigEndian.Uint64(uuid[:8]) // Ignore uuid[6] version b0110 + t = Time(time) + case 7: + time := binary.BigEndian.Uint64(uuid[:8]) + t = Time((time>>16)*10000 + g1582ns100) + default: // forward compatible + time := int64(binary.BigEndian.Uint32(uuid[0:4])) + time |= int64(binary.BigEndian.Uint16(uuid[4:6])) << 32 + time |= int64(binary.BigEndian.Uint16(uuid[6:8])&0xfff) << 48 + t = Time(time) + } + return t +} + +// ClockSequence returns the clock sequence encoded in uuid. +// The clock sequence is only well defined for version 1 and 2 UUIDs. +func (uuid UUID) ClockSequence() int { + return int(binary.BigEndian.Uint16(uuid[8:10])) & 0x3fff +} diff --git a/v2/vendor/github.com/google/uuid/util.go b/v2/vendor/github.com/google/uuid/util.go new file mode 100644 index 0000000..5ea6c73 --- /dev/null +++ b/v2/vendor/github.com/google/uuid/util.go @@ -0,0 +1,43 @@ +// Copyright 2016 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import ( + "io" +) + +// randomBits completely fills slice b with random data. +func randomBits(b []byte) { + if _, err := io.ReadFull(rander, b); err != nil { + panic(err.Error()) // rand should never fail + } +} + +// xvalues returns the value of a byte as a hexadecimal digit or 255. +var xvalues = [256]byte{ + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255, 255, + 255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +} + +// xtob converts hex characters x1 and x2 into a byte. +func xtob(x1, x2 byte) (byte, bool) { + b1 := xvalues[x1] + b2 := xvalues[x2] + return (b1 << 4) | b2, b1 != 255 && b2 != 255 +} diff --git a/v2/vendor/github.com/google/uuid/uuid.go b/v2/vendor/github.com/google/uuid/uuid.go new file mode 100644 index 0000000..5232b48 --- /dev/null +++ b/v2/vendor/github.com/google/uuid/uuid.go @@ -0,0 +1,365 @@ +// Copyright 2018 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import ( + "bytes" + "crypto/rand" + "encoding/hex" + "errors" + "fmt" + "io" + "strings" + "sync" +) + +// A UUID is a 128 bit (16 byte) Universal Unique IDentifier as defined in RFC +// 4122. +type UUID [16]byte + +// A Version represents a UUID's version. +type Version byte + +// A Variant represents a UUID's variant. +type Variant byte + +// Constants returned by Variant. +const ( + Invalid = Variant(iota) // Invalid UUID + RFC4122 // The variant specified in RFC4122 + Reserved // Reserved, NCS backward compatibility. + Microsoft // Reserved, Microsoft Corporation backward compatibility. + Future // Reserved for future definition. +) + +const randPoolSize = 16 * 16 + +var ( + rander = rand.Reader // random function + poolEnabled = false + poolMu sync.Mutex + poolPos = randPoolSize // protected with poolMu + pool [randPoolSize]byte // protected with poolMu +) + +type invalidLengthError struct{ len int } + +func (err invalidLengthError) Error() string { + return fmt.Sprintf("invalid UUID length: %d", err.len) +} + +// IsInvalidLengthError is matcher function for custom error invalidLengthError +func IsInvalidLengthError(err error) bool { + _, ok := err.(invalidLengthError) + return ok +} + +// Parse decodes s into a UUID or returns an error if it cannot be parsed. Both +// the standard UUID forms defined in RFC 4122 +// (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and +// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx) are decoded. In addition, +// Parse accepts non-standard strings such as the raw hex encoding +// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx and 38 byte "Microsoft style" encodings, +// e.g. {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}. Only the middle 36 bytes are +// examined in the latter case. Parse should not be used to validate strings as +// it parses non-standard encodings as indicated above. +func Parse(s string) (UUID, error) { + var uuid UUID + switch len(s) { + // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + case 36: + + // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + case 36 + 9: + if !strings.EqualFold(s[:9], "urn:uuid:") { + return uuid, fmt.Errorf("invalid urn prefix: %q", s[:9]) + } + s = s[9:] + + // {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} + case 36 + 2: + s = s[1:] + + // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + case 32: + var ok bool + for i := range uuid { + uuid[i], ok = xtob(s[i*2], s[i*2+1]) + if !ok { + return uuid, errors.New("invalid UUID format") + } + } + return uuid, nil + default: + return uuid, invalidLengthError{len(s)} + } + // s is now at least 36 bytes long + // it must be of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + if s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' { + return uuid, errors.New("invalid UUID format") + } + for i, x := range [16]int{ + 0, 2, 4, 6, + 9, 11, + 14, 16, + 19, 21, + 24, 26, 28, 30, 32, 34, + } { + v, ok := xtob(s[x], s[x+1]) + if !ok { + return uuid, errors.New("invalid UUID format") + } + uuid[i] = v + } + return uuid, nil +} + +// ParseBytes is like Parse, except it parses a byte slice instead of a string. +func ParseBytes(b []byte) (UUID, error) { + var uuid UUID + switch len(b) { + case 36: // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + case 36 + 9: // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + if !bytes.EqualFold(b[:9], []byte("urn:uuid:")) { + return uuid, fmt.Errorf("invalid urn prefix: %q", b[:9]) + } + b = b[9:] + case 36 + 2: // {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} + b = b[1:] + case 32: // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + var ok bool + for i := 0; i < 32; i += 2 { + uuid[i/2], ok = xtob(b[i], b[i+1]) + if !ok { + return uuid, errors.New("invalid UUID format") + } + } + return uuid, nil + default: + return uuid, invalidLengthError{len(b)} + } + // s is now at least 36 bytes long + // it must be of the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx + if b[8] != '-' || b[13] != '-' || b[18] != '-' || b[23] != '-' { + return uuid, errors.New("invalid UUID format") + } + for i, x := range [16]int{ + 0, 2, 4, 6, + 9, 11, + 14, 16, + 19, 21, + 24, 26, 28, 30, 32, 34, + } { + v, ok := xtob(b[x], b[x+1]) + if !ok { + return uuid, errors.New("invalid UUID format") + } + uuid[i] = v + } + return uuid, nil +} + +// MustParse is like Parse but panics if the string cannot be parsed. +// It simplifies safe initialization of global variables holding compiled UUIDs. +func MustParse(s string) UUID { + uuid, err := Parse(s) + if err != nil { + panic(`uuid: Parse(` + s + `): ` + err.Error()) + } + return uuid +} + +// FromBytes creates a new UUID from a byte slice. Returns an error if the slice +// does not have a length of 16. The bytes are copied from the slice. +func FromBytes(b []byte) (uuid UUID, err error) { + err = uuid.UnmarshalBinary(b) + return uuid, err +} + +// Must returns uuid if err is nil and panics otherwise. +func Must(uuid UUID, err error) UUID { + if err != nil { + panic(err) + } + return uuid +} + +// Validate returns an error if s is not a properly formatted UUID in one of the following formats: +// xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx +// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx +// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +// {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} +// It returns an error if the format is invalid, otherwise nil. +func Validate(s string) error { + switch len(s) { + // Standard UUID format + case 36: + + // UUID with "urn:uuid:" prefix + case 36 + 9: + if !strings.EqualFold(s[:9], "urn:uuid:") { + return fmt.Errorf("invalid urn prefix: %q", s[:9]) + } + s = s[9:] + + // UUID enclosed in braces + case 36 + 2: + if s[0] != '{' || s[len(s)-1] != '}' { + return fmt.Errorf("invalid bracketed UUID format") + } + s = s[1 : len(s)-1] + + // UUID without hyphens + case 32: + for i := 0; i < len(s); i += 2 { + _, ok := xtob(s[i], s[i+1]) + if !ok { + return errors.New("invalid UUID format") + } + } + + default: + return invalidLengthError{len(s)} + } + + // Check for standard UUID format + if len(s) == 36 { + if s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' { + return errors.New("invalid UUID format") + } + for _, x := range []int{0, 2, 4, 6, 9, 11, 14, 16, 19, 21, 24, 26, 28, 30, 32, 34} { + if _, ok := xtob(s[x], s[x+1]); !ok { + return errors.New("invalid UUID format") + } + } + } + + return nil +} + +// String returns the string form of uuid, xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx +// , or "" if uuid is invalid. +func (uuid UUID) String() string { + var buf [36]byte + encodeHex(buf[:], uuid) + return string(buf[:]) +} + +// URN returns the RFC 2141 URN form of uuid, +// urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, or "" if uuid is invalid. +func (uuid UUID) URN() string { + var buf [36 + 9]byte + copy(buf[:], "urn:uuid:") + encodeHex(buf[9:], uuid) + return string(buf[:]) +} + +func encodeHex(dst []byte, uuid UUID) { + hex.Encode(dst, uuid[:4]) + dst[8] = '-' + hex.Encode(dst[9:13], uuid[4:6]) + dst[13] = '-' + hex.Encode(dst[14:18], uuid[6:8]) + dst[18] = '-' + hex.Encode(dst[19:23], uuid[8:10]) + dst[23] = '-' + hex.Encode(dst[24:], uuid[10:]) +} + +// Variant returns the variant encoded in uuid. +func (uuid UUID) Variant() Variant { + switch { + case (uuid[8] & 0xc0) == 0x80: + return RFC4122 + case (uuid[8] & 0xe0) == 0xc0: + return Microsoft + case (uuid[8] & 0xe0) == 0xe0: + return Future + default: + return Reserved + } +} + +// Version returns the version of uuid. +func (uuid UUID) Version() Version { + return Version(uuid[6] >> 4) +} + +func (v Version) String() string { + if v > 15 { + return fmt.Sprintf("BAD_VERSION_%d", v) + } + return fmt.Sprintf("VERSION_%d", v) +} + +func (v Variant) String() string { + switch v { + case RFC4122: + return "RFC4122" + case Reserved: + return "Reserved" + case Microsoft: + return "Microsoft" + case Future: + return "Future" + case Invalid: + return "Invalid" + } + return fmt.Sprintf("BadVariant%d", int(v)) +} + +// SetRand sets the random number generator to r, which implements io.Reader. +// If r.Read returns an error when the package requests random data then +// a panic will be issued. +// +// Calling SetRand with nil sets the random number generator to the default +// generator. +func SetRand(r io.Reader) { + if r == nil { + rander = rand.Reader + return + } + rander = r +} + +// EnableRandPool enables internal randomness pool used for Random +// (Version 4) UUID generation. The pool contains random bytes read from +// the random number generator on demand in batches. Enabling the pool +// may improve the UUID generation throughput significantly. +// +// Since the pool is stored on the Go heap, this feature may be a bad fit +// for security sensitive applications. +// +// Both EnableRandPool and DisableRandPool are not thread-safe and should +// only be called when there is no possibility that New or any other +// UUID Version 4 generation function will be called concurrently. +func EnableRandPool() { + poolEnabled = true +} + +// DisableRandPool disables the randomness pool if it was previously +// enabled with EnableRandPool. +// +// Both EnableRandPool and DisableRandPool are not thread-safe and should +// only be called when there is no possibility that New or any other +// UUID Version 4 generation function will be called concurrently. +func DisableRandPool() { + poolEnabled = false + defer poolMu.Unlock() + poolMu.Lock() + poolPos = randPoolSize +} + +// UUIDs is a slice of UUID types. +type UUIDs []UUID + +// Strings returns a string slice containing the string form of each UUID in uuids. +func (uuids UUIDs) Strings() []string { + var uuidStrs = make([]string, len(uuids)) + for i, uuid := range uuids { + uuidStrs[i] = uuid.String() + } + return uuidStrs +} diff --git a/v2/vendor/github.com/google/uuid/version1.go b/v2/vendor/github.com/google/uuid/version1.go new file mode 100644 index 0000000..4631096 --- /dev/null +++ b/v2/vendor/github.com/google/uuid/version1.go @@ -0,0 +1,44 @@ +// Copyright 2016 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import ( + "encoding/binary" +) + +// NewUUID returns a Version 1 UUID based on the current NodeID and clock +// sequence, and the current time. If the NodeID has not been set by SetNodeID +// or SetNodeInterface then it will be set automatically. If the NodeID cannot +// be set NewUUID returns nil. If clock sequence has not been set by +// SetClockSequence then it will be set automatically. If GetTime fails to +// return the current NewUUID returns nil and an error. +// +// In most cases, New should be used. +func NewUUID() (UUID, error) { + var uuid UUID + now, seq, err := GetTime() + if err != nil { + return uuid, err + } + + timeLow := uint32(now & 0xffffffff) + timeMid := uint16((now >> 32) & 0xffff) + timeHi := uint16((now >> 48) & 0x0fff) + timeHi |= 0x1000 // Version 1 + + binary.BigEndian.PutUint32(uuid[0:], timeLow) + binary.BigEndian.PutUint16(uuid[4:], timeMid) + binary.BigEndian.PutUint16(uuid[6:], timeHi) + binary.BigEndian.PutUint16(uuid[8:], seq) + + nodeMu.Lock() + if nodeID == zeroID { + setNodeInterface("") + } + copy(uuid[10:], nodeID[:]) + nodeMu.Unlock() + + return uuid, nil +} diff --git a/v2/vendor/github.com/google/uuid/version4.go b/v2/vendor/github.com/google/uuid/version4.go new file mode 100644 index 0000000..7697802 --- /dev/null +++ b/v2/vendor/github.com/google/uuid/version4.go @@ -0,0 +1,76 @@ +// Copyright 2016 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import "io" + +// New creates a new random UUID or panics. New is equivalent to +// the expression +// +// uuid.Must(uuid.NewRandom()) +func New() UUID { + return Must(NewRandom()) +} + +// NewString creates a new random UUID and returns it as a string or panics. +// NewString is equivalent to the expression +// +// uuid.New().String() +func NewString() string { + return Must(NewRandom()).String() +} + +// NewRandom returns a Random (Version 4) UUID. +// +// The strength of the UUIDs is based on the strength of the crypto/rand +// package. +// +// Uses the randomness pool if it was enabled with EnableRandPool. +// +// A note about uniqueness derived from the UUID Wikipedia entry: +// +// Randomly generated UUIDs have 122 random bits. One's annual risk of being +// hit by a meteorite is estimated to be one chance in 17 billion, that +// means the probability is about 0.00000000006 (6 × 10−11), +// equivalent to the odds of creating a few tens of trillions of UUIDs in a +// year and having one duplicate. +func NewRandom() (UUID, error) { + if !poolEnabled { + return NewRandomFromReader(rander) + } + return newRandomFromPool() +} + +// NewRandomFromReader returns a UUID based on bytes read from a given io.Reader. +func NewRandomFromReader(r io.Reader) (UUID, error) { + var uuid UUID + _, err := io.ReadFull(r, uuid[:]) + if err != nil { + return Nil, err + } + uuid[6] = (uuid[6] & 0x0f) | 0x40 // Version 4 + uuid[8] = (uuid[8] & 0x3f) | 0x80 // Variant is 10 + return uuid, nil +} + +func newRandomFromPool() (UUID, error) { + var uuid UUID + poolMu.Lock() + if poolPos == randPoolSize { + _, err := io.ReadFull(rander, pool[:]) + if err != nil { + poolMu.Unlock() + return Nil, err + } + poolPos = 0 + } + copy(uuid[:], pool[poolPos:(poolPos+16)]) + poolPos += 16 + poolMu.Unlock() + + uuid[6] = (uuid[6] & 0x0f) | 0x40 // Version 4 + uuid[8] = (uuid[8] & 0x3f) | 0x80 // Variant is 10 + return uuid, nil +} diff --git a/v2/vendor/github.com/google/uuid/version6.go b/v2/vendor/github.com/google/uuid/version6.go new file mode 100644 index 0000000..339a959 --- /dev/null +++ b/v2/vendor/github.com/google/uuid/version6.go @@ -0,0 +1,56 @@ +// Copyright 2023 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import "encoding/binary" + +// UUID version 6 is a field-compatible version of UUIDv1, reordered for improved DB locality. +// It is expected that UUIDv6 will primarily be used in contexts where there are existing v1 UUIDs. +// Systems that do not involve legacy UUIDv1 SHOULD consider using UUIDv7 instead. +// +// see https://datatracker.ietf.org/doc/html/draft-peabody-dispatch-new-uuid-format-03#uuidv6 +// +// NewV6 returns a Version 6 UUID based on the current NodeID and clock +// sequence, and the current time. If the NodeID has not been set by SetNodeID +// or SetNodeInterface then it will be set automatically. If the NodeID cannot +// be set NewV6 set NodeID is random bits automatically . If clock sequence has not been set by +// SetClockSequence then it will be set automatically. If GetTime fails to +// return the current NewV6 returns Nil and an error. +func NewV6() (UUID, error) { + var uuid UUID + now, seq, err := GetTime() + if err != nil { + return uuid, err + } + + /* + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | time_high | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | time_mid | time_low_and_version | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |clk_seq_hi_res | clk_seq_low | node (0-1) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | node (2-5) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + + binary.BigEndian.PutUint64(uuid[0:], uint64(now)) + binary.BigEndian.PutUint16(uuid[8:], seq) + + uuid[6] = 0x60 | (uuid[6] & 0x0F) + uuid[8] = 0x80 | (uuid[8] & 0x3F) + + nodeMu.Lock() + if nodeID == zeroID { + setNodeInterface("") + } + copy(uuid[10:], nodeID[:]) + nodeMu.Unlock() + + return uuid, nil +} diff --git a/v2/vendor/github.com/google/uuid/version7.go b/v2/vendor/github.com/google/uuid/version7.go new file mode 100644 index 0000000..3167b64 --- /dev/null +++ b/v2/vendor/github.com/google/uuid/version7.go @@ -0,0 +1,104 @@ +// Copyright 2023 Google Inc. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package uuid + +import ( + "io" +) + +// UUID version 7 features a time-ordered value field derived from the widely +// implemented and well known Unix Epoch timestamp source, +// the number of milliseconds seconds since midnight 1 Jan 1970 UTC, leap seconds excluded. +// As well as improved entropy characteristics over versions 1 or 6. +// +// see https://datatracker.ietf.org/doc/html/draft-peabody-dispatch-new-uuid-format-03#name-uuid-version-7 +// +// Implementations SHOULD utilize UUID version 7 over UUID version 1 and 6 if possible. +// +// NewV7 returns a Version 7 UUID based on the current time(Unix Epoch). +// Uses the randomness pool if it was enabled with EnableRandPool. +// On error, NewV7 returns Nil and an error +func NewV7() (UUID, error) { + uuid, err := NewRandom() + if err != nil { + return uuid, err + } + makeV7(uuid[:]) + return uuid, nil +} + +// NewV7FromReader returns a Version 7 UUID based on the current time(Unix Epoch). +// it use NewRandomFromReader fill random bits. +// On error, NewV7FromReader returns Nil and an error. +func NewV7FromReader(r io.Reader) (UUID, error) { + uuid, err := NewRandomFromReader(r) + if err != nil { + return uuid, err + } + + makeV7(uuid[:]) + return uuid, nil +} + +// makeV7 fill 48 bits time (uuid[0] - uuid[5]), set version b0111 (uuid[6]) +// uuid[8] already has the right version number (Variant is 10) +// see function NewV7 and NewV7FromReader +func makeV7(uuid []byte) { + /* + 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | unix_ts_ms | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | unix_ts_ms | ver | rand_a (12 bit seq) | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |var| rand_b | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | rand_b | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + _ = uuid[15] // bounds check + + t, s := getV7Time() + + uuid[0] = byte(t >> 40) + uuid[1] = byte(t >> 32) + uuid[2] = byte(t >> 24) + uuid[3] = byte(t >> 16) + uuid[4] = byte(t >> 8) + uuid[5] = byte(t) + + uuid[6] = 0x70 | (0x0F & byte(s>>8)) + uuid[7] = byte(s) +} + +// lastV7time is the last time we returned stored as: +// +// 52 bits of time in milliseconds since epoch +// 12 bits of (fractional nanoseconds) >> 8 +var lastV7time int64 + +const nanoPerMilli = 1000000 + +// getV7Time returns the time in milliseconds and nanoseconds / 256. +// The returned (milli << 12 + seq) is guarenteed to be greater than +// (milli << 12 + seq) returned by any previous call to getV7Time. +func getV7Time() (milli, seq int64) { + timeMu.Lock() + defer timeMu.Unlock() + + nano := timeNow().UnixNano() + milli = nano / nanoPerMilli + // Sequence number is between 0 and 3906 (nanoPerMilli>>8) + seq = (nano - milli*nanoPerMilli) >> 8 + now := milli<<12 + seq + if now <= lastV7time { + now = lastV7time + 1 + milli = now >> 12 + seq = now & 0xfff + } + lastV7time = now + return milli, seq +} diff --git a/v2/vendor/github.com/pingcap/errors/.gitignore b/v2/vendor/github.com/pingcap/errors/.gitignore new file mode 100644 index 0000000..0c9e329 --- /dev/null +++ b/v2/vendor/github.com/pingcap/errors/.gitignore @@ -0,0 +1,25 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test +.idea + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe +*.test +*.prof diff --git a/v2/vendor/github.com/pingcap/errors/.travis.yml b/v2/vendor/github.com/pingcap/errors/.travis.yml new file mode 100644 index 0000000..eaaabc5 --- /dev/null +++ b/v2/vendor/github.com/pingcap/errors/.travis.yml @@ -0,0 +1,11 @@ +arch: + - amd64 + +language: go +go_import_path: github.com/pingcap/errors +go: + - 1.13.x + - stable + +script: + - go test -v ./... diff --git a/v2/vendor/github.com/pingcap/errors/LICENSE b/v2/vendor/github.com/pingcap/errors/LICENSE new file mode 100644 index 0000000..835ba3e --- /dev/null +++ b/v2/vendor/github.com/pingcap/errors/LICENSE @@ -0,0 +1,23 @@ +Copyright (c) 2015, Dave Cheney +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/v2/vendor/github.com/pingcap/errors/README.md b/v2/vendor/github.com/pingcap/errors/README.md new file mode 100644 index 0000000..6483ba2 --- /dev/null +++ b/v2/vendor/github.com/pingcap/errors/README.md @@ -0,0 +1,52 @@ +# errors [![Travis-CI](https://travis-ci.org/pkg/errors.svg)](https://travis-ci.org/pkg/errors) [![AppVeyor](https://ci.appveyor.com/api/projects/status/b98mptawhudj53ep/branch/master?svg=true)](https://ci.appveyor.com/project/davecheney/errors/branch/master) [![GoDoc](https://godoc.org/github.com/pkg/errors?status.svg)](http://godoc.org/github.com/pkg/errors) [![Report card](https://goreportcard.com/badge/github.com/pkg/errors)](https://goreportcard.com/report/github.com/pkg/errors) [![Sourcegraph](https://sourcegraph.com/github.com/pkg/errors/-/badge.svg)](https://sourcegraph.com/github.com/pkg/errors?badge) + +Package errors provides simple error handling primitives. + +`go get github.com/pkg/errors` + +The traditional error handling idiom in Go is roughly akin to +```go +if err != nil { + return err +} +``` +which applied recursively up the call stack results in error reports without context or debugging information. The errors package allows programmers to add context to the failure path in their code in a way that does not destroy the original value of the error. + +## Adding context to an error + +The errors.Wrap function returns a new error that adds context to the original error. For example +```go +_, err := ioutil.ReadAll(r) +if err != nil { + return errors.Wrap(err, "read failed") +} +``` +## Retrieving the cause of an error + +Using `errors.Wrap` constructs a stack of errors, adding context to the preceding error. Depending on the nature of the error it may be necessary to reverse the operation of errors.Wrap to retrieve the original error for inspection. Any error value which implements this interface can be inspected by `errors.Cause`. +```go +type causer interface { + Cause() error +} +``` +`errors.Cause` will recursively retrieve the topmost error which does not implement `causer`, which is assumed to be the original cause. For example: +```go +switch err := errors.Cause(err).(type) { +case *MyError: + // handle specifically +default: + // unknown error +} +``` + +[Read the package documentation for more information](https://godoc.org/github.com/pkg/errors). + +## Contributing + +We welcome pull requests, bug fixes and issue reports. With that said, the bar for adding new symbols to this package is intentionally set high. + +Before proposing a change, please discuss your change by raising an issue. + +## License + +BSD-2-Clause diff --git a/v2/vendor/github.com/pingcap/errors/compatible_shim.go b/v2/vendor/github.com/pingcap/errors/compatible_shim.go new file mode 100644 index 0000000..0835a0c --- /dev/null +++ b/v2/vendor/github.com/pingcap/errors/compatible_shim.go @@ -0,0 +1,98 @@ +// Copyright 2020 PingCAP, Inc. +// +// 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, +// See the License for the specific language governing permissions and +// limitations under the License. + +package errors + +import ( + "encoding/json" + "strconv" + "strings" +) + +// class2RFCCode is used for compatible with old version of TiDB. When +// marshal Error to json, old version of TiDB contain a 'class' field +// which is represented for error class. In order to parse and convert +// json to errors.Error, using this map to convert error class to RFC +// error code text. here is reference: +// https://github.com/pingcap/parser/blob/release-3.0/terror/terror.go#L58 +var class2RFCCode = map[int]string{ + 1: "autoid", + 2: "ddl", + 3: "domain", + 4: "evaluator", + 5: "executor", + 6: "expression", + 7: "admin", + 8: "kv", + 9: "meta", + 10: "planner", + 11: "parser", + 12: "perfschema", + 13: "privilege", + 14: "schema", + 15: "server", + 16: "struct", + 17: "variable", + 18: "xeval", + 19: "table", + 20: "types", + 21: "global", + 22: "mocktikv", + 23: "json", + 24: "tikv", + 25: "session", + 26: "plugin", + 27: "util", +} +var rfcCode2class map[string]int + +func init() { + rfcCode2class = make(map[string]int) + for k, v := range class2RFCCode { + rfcCode2class[v] = k + } +} + +// MarshalJSON implements json.Marshaler interface. +// aware that this function cannot save a 'registered' status, +// since we cannot access the registry when unmarshaling, +// and the original global registry would be removed here. +// This function is reserved for compatibility. +func (e *Error) MarshalJSON() ([]byte, error) { + ec := strings.Split(string(e.codeText), ":")[0] + return json.Marshal(&jsonError{ + Class: rfcCode2class[ec], + Code: int(e.code), + Msg: e.GetMsg(), + RFCCode: string(e.codeText), + }) +} + +// UnmarshalJSON implements json.Unmarshaler interface. +// aware that this function cannot create a 'registered' error, +// since we cannot access the registry in this context, +// and the original global registry is removed. +// This function is reserved for compatibility. +func (e *Error) UnmarshalJSON(data []byte) error { + tErr := &jsonError{} + if err := json.Unmarshal(data, &tErr); err != nil { + return Trace(err) + } + e.codeText = ErrCodeText(tErr.RFCCode) + if tErr.RFCCode == "" && tErr.Class > 0 { + e.codeText = ErrCodeText(class2RFCCode[tErr.Class] + ":" + strconv.Itoa(tErr.Code)) + } + e.code = ErrCode(tErr.Code) + e.message = tErr.Msg + return nil +} diff --git a/v2/vendor/github.com/pingcap/errors/errors.go b/v2/vendor/github.com/pingcap/errors/errors.go new file mode 100644 index 0000000..2e1d3f6 --- /dev/null +++ b/v2/vendor/github.com/pingcap/errors/errors.go @@ -0,0 +1,324 @@ +// Package errors provides simple error handling primitives. +// +// The traditional error handling idiom in Go is roughly akin to +// +// if err != nil { +// return err +// } +// +// which applied recursively up the call stack results in error reports +// without context or debugging information. The errors package allows +// programmers to add context to the failure path in their code in a way +// that does not destroy the original value of the error. +// +// Adding context to an error +// +// The errors.Annotate function returns a new error that adds context to the +// original error by recording a stack trace at the point Annotate is called, +// and the supplied message. For example +// +// _, err := ioutil.ReadAll(r) +// if err != nil { +// return errors.Annotate(err, "read failed") +// } +// +// If additional control is required the errors.AddStack and errors.WithMessage +// functions destructure errors.Annotate into its component operations of annotating +// an error with a stack trace and an a message, respectively. +// +// Retrieving the cause of an error +// +// Using errors.Annotate constructs a stack of errors, adding context to the +// preceding error. Depending on the nature of the error it may be necessary +// to reverse the operation of errors.Annotate to retrieve the original error +// for inspection. Any error value which implements this interface +// +// type causer interface { +// Cause() error +// } +// +// can be inspected by errors.Cause. errors.Cause will recursively retrieve +// the topmost error which does not implement causer, which is assumed to be +// the original cause. For example: +// +// switch err := errors.Cause(err).(type) { +// case *MyError: +// // handle specifically +// default: +// // unknown error +// } +// +// causer interface is not exported by this package, but is considered a part +// of stable public API. +// errors.Unwrap is also available: this will retrieve the next error in the chain. +// +// Formatted printing of errors +// +// All error values returned from this package implement fmt.Formatter and can +// be formatted by the fmt package. The following verbs are supported +// +// %s print the error. If the error has a Cause it will be +// printed recursively +// %v see %s +// %+v extended format. Each Frame of the error's StackTrace will +// be printed in detail. +// +// Retrieving the stack trace of an error or wrapper +// +// New, Errorf, Annotate, and Annotatef record a stack trace at the point they are invoked. +// This information can be retrieved with the StackTracer interface that returns +// a StackTrace. Where errors.StackTrace is defined as +// +// type StackTrace []Frame +// +// The Frame type represents a call site in the stack trace. Frame supports +// the fmt.Formatter interface that can be used for printing information about +// the stack trace of this error. For example: +// +// if stacked := errors.GetStackTracer(err); stacked != nil { +// for _, f := range stacked.StackTrace() { +// fmt.Printf("%+s:%d", f) +// } +// } +// +// See the documentation for Frame.Format for more details. +// +// errors.Find can be used to search for an error in the error chain. +package errors + +import ( + "fmt" + "io" +) + +// New returns an error with the supplied message. +// New also records the stack trace at the point it was called. +func New(message string) error { + return &fundamental{ + msg: message, + stack: callers(), + } +} + +// Errorf formats according to a format specifier and returns the string +// as a value that satisfies error. +// Errorf also records the stack trace at the point it was called. +func Errorf(format string, args ...interface{}) error { + return &fundamental{ + msg: fmt.Sprintf(format, args...), + stack: callers(), + } +} + +// StackTraceAware is an optimization to avoid repetitive traversals of an error chain. +// HasStack checks for this marker first. +// Annotate/Wrap and Annotatef/Wrapf will produce this marker. +type StackTraceAware interface { + HasStack() bool +} + +// HasStack tells whether a StackTracer exists in the error chain +func HasStack(err error) bool { + if errWithStack, ok := err.(StackTraceAware); ok { + return errWithStack.HasStack() + } + return GetStackTracer(err) != nil +} + +// fundamental is an error that has a message and a stack, but no caller. +type fundamental struct { + msg string + *stack +} + +func (f *fundamental) Error() string { return f.msg } + +func (f *fundamental) Format(s fmt.State, verb rune) { + switch verb { + case 'v': + if s.Flag('+') { + io.WriteString(s, f.msg) + f.stack.Format(s, verb) + return + } + fallthrough + case 's': + io.WriteString(s, f.msg) + case 'q': + fmt.Fprintf(s, "%q", f.msg) + } +} + +// WithStack annotates err with a stack trace at the point WithStack was called. +// If err is nil, WithStack returns nil. +// +// For most use cases this is deprecated and AddStack should be used (which will ensure just one stack trace). +// However, one may want to use this in some situations, for example to create a 2nd trace across a goroutine. +func WithStack(err error) error { + if err == nil { + return nil + } + + return &withStack{ + err, + callers(), + } +} + +// AddStack is similar to WithStack. +// However, it will first check with HasStack to see if a stack trace already exists in the causer chain before creating another one. +func AddStack(err error) error { + if HasStack(err) { + return err + } + return WithStack(err) +} + +type withStack struct { + error + *stack +} + +func (w *withStack) Cause() error { return w.error } + +func (w *withStack) Format(s fmt.State, verb rune) { + switch verb { + case 'v': + if s.Flag('+') { + fmt.Fprintf(s, "%+v", w.Cause()) + w.stack.Format(s, verb) + return + } + fallthrough + case 's': + io.WriteString(s, w.Error()) + case 'q': + fmt.Fprintf(s, "%q", w.Error()) + } +} + +// Wrap returns an error annotating err with a stack trace +// at the point Wrap is called, and the supplied message. +// If err is nil, Wrap returns nil. +// +// For most use cases this is deprecated in favor of Annotate. +// Annotate avoids creating duplicate stack traces. +func Wrap(err error, message string) error { + if err == nil { + return nil + } + hasStack := HasStack(err) + err = &withMessage{ + cause: err, + msg: message, + causeHasStack: hasStack, + } + return &withStack{ + err, + callers(), + } +} + +// Wrapf returns an error annotating err with a stack trace +// at the point Wrapf is call, and the format specifier. +// If err is nil, Wrapf returns nil. +// +// For most use cases this is deprecated in favor of Annotatef. +// Annotatef avoids creating duplicate stack traces. +func Wrapf(err error, format string, args ...interface{}) error { + if err == nil { + return nil + } + hasStack := HasStack(err) + err = &withMessage{ + cause: err, + msg: fmt.Sprintf(format, args...), + causeHasStack: hasStack, + } + return &withStack{ + err, + callers(), + } +} + +// WithMessage annotates err with a new message. +// If err is nil, WithMessage returns nil. +func WithMessage(err error, message string) error { + if err == nil { + return nil + } + return &withMessage{ + cause: err, + msg: message, + causeHasStack: HasStack(err), + } +} + +type withMessage struct { + cause error + msg string + causeHasStack bool +} + +func (w *withMessage) Error() string { return w.msg + ": " + w.cause.Error() } +func (w *withMessage) Cause() error { return w.cause } +func (w *withMessage) HasStack() bool { return w.causeHasStack } + +func (w *withMessage) Format(s fmt.State, verb rune) { + switch verb { + case 'v': + if s.Flag('+') { + fmt.Fprintf(s, "%+v\n", w.Cause()) + io.WriteString(s, w.msg) + return + } + fallthrough + case 's', 'q': + io.WriteString(s, w.Error()) + } +} + +// Cause returns the underlying cause of the error, if possible. +// An error value has a cause if it implements the following +// interface: +// +// type causer interface { +// Cause() error +// } +// +// If the error does not implement Cause, the original error will +// be returned. If the error is nil, nil will be returned without further +// investigation. +func Cause(err error) error { + cause := Unwrap(err) + if cause == nil { + return err + } + return Cause(cause) +} + +// Unwrap uses causer to return the next error in the chain or nil. +// This goes one-level deeper, whereas Cause goes as far as possible +func Unwrap(err error) error { + type causer interface { + Cause() error + } + if unErr, ok := err.(causer); ok { + return unErr.Cause() + } + return nil +} + +// Find an error in the chain that matches a test function. +// returns nil if no error is found. +func Find(origErr error, test func(error) bool) error { + var foundErr error + WalkDeep(origErr, func(err error) bool { + if test(err) { + foundErr = err + return true + } + return false + }) + return foundErr +} diff --git a/v2/vendor/github.com/pingcap/errors/group.go b/v2/vendor/github.com/pingcap/errors/group.go new file mode 100644 index 0000000..e5a969a --- /dev/null +++ b/v2/vendor/github.com/pingcap/errors/group.go @@ -0,0 +1,42 @@ +package errors + +// ErrorGroup is an interface for multiple errors that are not a chain. +// This happens for example when executing multiple operations in parallel. +type ErrorGroup interface { + Errors() []error +} + +// Errors uses the ErrorGroup interface to return a slice of errors. +// If the ErrorGroup interface is not implemented it returns an array containing just the given error. +func Errors(err error) []error { + if eg, ok := err.(ErrorGroup); ok { + return eg.Errors() + } + return []error{err} +} + +// WalkDeep does a depth-first traversal of all errors. +// Any ErrorGroup is traversed (after going deep). +// The visitor function can return true to end the traversal early +// In that case, WalkDeep will return true, otherwise false. +func WalkDeep(err error, visitor func(err error) bool) bool { + // Go deep + unErr := err + for unErr != nil { + if done := visitor(unErr); done { + return true + } + unErr = Unwrap(unErr) + } + + // Go wide + if group, ok := err.(ErrorGroup); ok { + for _, err := range group.Errors() { + if early := WalkDeep(err, visitor); early { + return true + } + } + } + + return false +} diff --git a/v2/vendor/github.com/pingcap/errors/juju_adaptor.go b/v2/vendor/github.com/pingcap/errors/juju_adaptor.go new file mode 100644 index 0000000..ece86cd --- /dev/null +++ b/v2/vendor/github.com/pingcap/errors/juju_adaptor.go @@ -0,0 +1,145 @@ +package errors + +import ( + "fmt" + "strings" +) + +// ==================== juju adaptor start ======================== + +// Trace just calls AddStack. +func Trace(err error) error { + if err == nil { + return nil + } + return AddStack(err) +} + +// Annotate adds a message and ensures there is a stack trace. +func Annotate(err error, message string) error { + if err == nil { + return nil + } + hasStack := HasStack(err) + err = &withMessage{ + cause: err, + msg: message, + causeHasStack: hasStack, + } + if hasStack { + return err + } + return &withStack{ + err, + callers(), + } +} + +// Annotatef adds a message and ensures there is a stack trace. +func Annotatef(err error, format string, args ...interface{}) error { + if err == nil { + return nil + } + hasStack := HasStack(err) + err = &withMessage{ + cause: err, + msg: fmt.Sprintf(format, args...), + causeHasStack: hasStack, + } + if hasStack { + return err + } + return &withStack{ + err, + callers(), + } +} + +var emptyStack stack + +// NewNoStackError creates error without error stack +// later duplicate trace will no longer generate Stack too. +func NewNoStackError(msg string) error { + return &fundamental{ + msg: msg, + stack: &emptyStack, + } +} + +// SuspendStack suspends stack generate for error. +func SuspendStack(err error) error { + if err == nil { + return err + } + cleared := clearStack(err) + if cleared { + return err + } + return &withStack{ + err, + &emptyStack, + } +} + +func clearStack(err error) (cleared bool) { + switch typedErr := err.(type) { + case *withMessage: + return clearStack(typedErr.Cause()) + case *fundamental: + typedErr.stack = &emptyStack + return true + case *withStack: + typedErr.stack = &emptyStack + clearStack(typedErr.Cause()) + return true + default: + return false + } +} + +// ErrorStack will format a stack trace if it is available, otherwise it will be Error() +// If the error is nil, the empty string is returned +// Note that this just calls fmt.Sprintf("%+v", err) +func ErrorStack(err error) string { + if err == nil { + return "" + } + return fmt.Sprintf("%+v", err) +} + +// IsNotFound reports whether err was not found error. +func IsNotFound(err error) bool { + return strings.Contains(err.Error(), "not found") +} + +// NotFoundf represents an error with not found message. +func NotFoundf(format string, args ...interface{}) error { + return Errorf(format+" not found", args...) +} + +// BadRequestf represents an error with bad request message. +func BadRequestf(format string, args ...interface{}) error { + return Errorf(format+" bad request", args...) +} + +// NotSupportedf represents an error with not supported message. +func NotSupportedf(format string, args ...interface{}) error { + return Errorf(format+" not supported", args...) +} + +// NotValidf represents an error with not valid message. +func NotValidf(format string, args ...interface{}) error { + return Errorf(format+" not valid", args...) +} + +// IsAlreadyExists reports whether err was already exists error. +func IsAlreadyExists(err error) bool { + return strings.Contains(err.Error(), "already exists") +} + +// AlreadyExistsf represents an error with already exists message. +func AlreadyExistsf(format string, args ...interface{}) error { + return Errorf(format+" already exists", args...) +} + +// ==================== juju adaptor end ======================== diff --git a/v2/vendor/github.com/pingcap/errors/normalize.go b/v2/vendor/github.com/pingcap/errors/normalize.go new file mode 100644 index 0000000..40a6ec1 --- /dev/null +++ b/v2/vendor/github.com/pingcap/errors/normalize.go @@ -0,0 +1,316 @@ +// Copyright 2020 PingCAP, Inc. +// +// 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, +// See the License for the specific language governing permissions and +// limitations under the License. + +package errors + +import ( + "fmt" + "runtime" + "strconv" + + "go.uber.org/atomic" +) + +// RedactLogEnabled defines whether the arguments of Error need to be redacted. +var RedactLogEnabled atomic.Bool + +// ErrCode represents a specific error type in a error class. +// Same error code can be used in different error classes. +type ErrCode int + +// ErrCodeText is a textual error code that represents a specific error type in a error class. +type ErrCodeText string + +type ErrorID string +type RFCErrorCode string + +// Error is the 'prototype' of a type of errors. +// Use DefineError to make a *Error: +// var ErrUnavailable = errors.Normalize("Region %d is unavailable", errors.RFCCodeText("Unavailable")) +// +// "throw" it at runtime: +// func Somewhat() error { +// ... +// if err != nil { +// // generate a stackful error use the message template at defining, +// // also see FastGen(it's stackless), GenWithStack(it uses custom message template). +// return ErrUnavailable.GenWithStackByArgs(region.ID) +// } +// } +// +// testing whether an error belongs to a prototype: +// if ErrUnavailable.Equal(err) { +// // handle this error. +// } +type Error struct { + code ErrCode + // codeText is the textual describe of the error code + codeText ErrCodeText + // message is a template of the description of this error. + // printf-style formatting is enabled. + message string + // redactArgsPos defines the positions of arguments in message that need to be redacted. + // And it is controlled by the global var RedactLogEnabled. + // For example, an original error is `Duplicate entry 'PRIMARY' for key 'key'`, + // when RedactLogEnabled is ON and redactArgsPos is [0, 1], the error is `Duplicate entry '?' for key '?'`. + redactArgsPos []int + // Cause is used to warp some third party error. + cause error + args []interface{} + file string + line int +} + +// Code returns the numeric code of this error. +// ID() will return textual error if there it is, +// when you just want to get the purely numeric error +// (e.g., for mysql protocol transmission.), this would be useful. +func (e *Error) Code() ErrCode { + return e.code +} + +// Code returns ErrorCode, by the RFC: +// +// The error code is a 3-tuple of abbreviated component name, error class and error code, +// joined by a colon like {Component}:{ErrorClass}:{InnerErrorCode}. +func (e *Error) RFCCode() RFCErrorCode { + return RFCErrorCode(e.ID()) +} + +// ID returns the ID of this error. +func (e *Error) ID() ErrorID { + if e.codeText != "" { + return ErrorID(e.codeText) + } + return ErrorID(strconv.Itoa(int(e.code))) +} + +// Location returns the location where the error is created, +// implements juju/errors locationer interface. +func (e *Error) Location() (file string, line int) { + return e.file, e.line +} + +// MessageTemplate returns the error message template of this error. +func (e *Error) MessageTemplate() string { + return e.message +} + +// Error implements error interface. +func (e *Error) Error() string { + if e == nil { + return "" + } + describe := e.codeText + if len(describe) == 0 { + describe = ErrCodeText(strconv.Itoa(int(e.code))) + } + if e.cause != nil { + return fmt.Sprintf("[%s]%s: %s", e.RFCCode(), e.GetMsg(), e.cause.Error()) + } + return fmt.Sprintf("[%s]%s", e.RFCCode(), e.GetMsg()) +} + +func (e *Error) GetMsg() string { + if len(e.args) > 0 { + return fmt.Sprintf(e.message, e.args...) + } + return e.message +} + +func (e *Error) fillLineAndFile(skip int) { + // skip this + _, file, line, ok := runtime.Caller(skip + 1) + if !ok { + e.file = "" + e.line = -1 + return + } + e.file = file + e.line = line +} + +// GenWithStack generates a new *Error with the same class and code, and a new formatted message. +func (e *Error) GenWithStack(format string, args ...interface{}) error { + // TODO: RedactErrorArg + err := *e + err.message = format + err.args = args + err.fillLineAndFile(1) + return AddStack(&err) +} + +// GenWithStackByArgs generates a new *Error with the same class and code, and new arguments. +func (e *Error) GenWithStackByArgs(args ...interface{}) error { + RedactErrorArg(args, e.redactArgsPos) + err := *e + err.args = args + err.fillLineAndFile(1) + return AddStack(&err) +} + +// FastGen generates a new *Error with the same class and code, and a new formatted message. +// This will not call runtime.Caller to get file and line. +func (e *Error) FastGen(format string, args ...interface{}) error { + // TODO: RedactErrorArg + err := *e + err.message = format + err.args = args + return SuspendStack(&err) +} + +// FastGen generates a new *Error with the same class and code, and a new arguments. +// This will not call runtime.Caller to get file and line. +func (e *Error) FastGenByArgs(args ...interface{}) error { + RedactErrorArg(args, e.redactArgsPos) + err := *e + err.args = args + return SuspendStack(&err) +} + +// Equal checks if err is equal to e. +func (e *Error) Equal(err error) bool { + originErr := Cause(err) + if originErr == nil { + return false + } + if error(e) == originErr { + return true + } + inErr, ok := originErr.(*Error) + if !ok { + return false + } + idEquals := e.ID() == inErr.ID() + return idEquals +} + +// NotEqual checks if err is not equal to e. +func (e *Error) NotEqual(err error) bool { + return !e.Equal(err) +} + +// RedactErrorArg redacts the args by position if RedactLogEnabled is enabled. +func RedactErrorArg(args []interface{}, position []int) { + if RedactLogEnabled.Load() { + for _, pos := range position { + if len(args) > pos { + args[pos] = "?" + } + } + } +} + +// ErrorEqual returns a boolean indicating whether err1 is equal to err2. +func ErrorEqual(err1, err2 error) bool { + e1 := Cause(err1) + e2 := Cause(err2) + + if e1 == e2 { + return true + } + + if e1 == nil || e2 == nil { + return e1 == e2 + } + + te1, ok1 := e1.(*Error) + te2, ok2 := e2.(*Error) + if ok1 && ok2 { + return te1.Equal(te2) + } + + return e1.Error() == e2.Error() +} + +// ErrorNotEqual returns a boolean indicating whether err1 isn't equal to err2. +func ErrorNotEqual(err1, err2 error) bool { + return !ErrorEqual(err1, err2) +} + +type jsonError struct { + // Deprecated field, please use `RFCCode` instead. + Class int `json:"class"` + Code int `json:"code"` + Msg string `json:"message"` + RFCCode string `json:"rfccode"` +} + +func (e *Error) Wrap(err error) *Error { + if err != nil { + newErr := *e + newErr.cause = err + return &newErr + } + return nil +} + +func (e *Error) Cause() error { + root := Unwrap(e.cause) + if root == nil { + return e.cause + } + return root +} + +func (e *Error) FastGenWithCause(args ...interface{}) error { + err := *e + if e.cause != nil { + err.message = e.cause.Error() + } + err.args = args + return SuspendStack(&err) +} + +func (e *Error) GenWithStackByCause(args ...interface{}) error { + err := *e + if e.cause != nil { + err.message = e.cause.Error() + } + err.args = args + err.fillLineAndFile(1) + return AddStack(&err) +} + +type NormalizeOption func(*Error) + +func RedactArgs(pos []int) NormalizeOption { + return func(e *Error) { + e.redactArgsPos = pos + } +} + +// RFCCodeText returns a NormalizeOption to set RFC error code. +func RFCCodeText(codeText string) NormalizeOption { + return func(e *Error) { + e.codeText = ErrCodeText(codeText) + } +} + +// MySQLErrorCode returns a NormalizeOption to set error code. +func MySQLErrorCode(code int) NormalizeOption { + return func(e *Error) { + e.code = ErrCode(code) + } +} + +// Normalize creates a new Error object. +func Normalize(message string, opts ...NormalizeOption) *Error { + e := &Error{ + message: message, + } + for _, opt := range opts { + opt(e) + } + return e +} diff --git a/v2/vendor/github.com/pingcap/errors/stack.go b/v2/vendor/github.com/pingcap/errors/stack.go new file mode 100644 index 0000000..bb1e6a8 --- /dev/null +++ b/v2/vendor/github.com/pingcap/errors/stack.go @@ -0,0 +1,226 @@ +package errors + +import ( + "bytes" + "fmt" + "io" + "path" + "runtime" + "strconv" + "strings" +) + +// StackTracer retrieves the StackTrace +// Generally you would want to use the GetStackTracer function to do that. +type StackTracer interface { + StackTrace() StackTrace +} + +// GetStackTracer will return the first StackTracer in the causer chain. +// This function is used by AddStack to avoid creating redundant stack traces. +// +// You can also use the StackTracer interface on the returned error to get the stack trace. +func GetStackTracer(origErr error) StackTracer { + var stacked StackTracer + WalkDeep(origErr, func(err error) bool { + if stackTracer, ok := err.(StackTracer); ok { + stacked = stackTracer + return true + } + return false + }) + return stacked +} + +// Frame represents a program counter inside a stack frame. +type Frame uintptr + +// pc returns the program counter for this frame; +// multiple frames may have the same PC value. +func (f Frame) pc() uintptr { return uintptr(f) - 1 } + +// file returns the full path to the file that contains the +// function for this Frame's pc. +func (f Frame) file() string { + fn := runtime.FuncForPC(f.pc()) + if fn == nil { + return "unknown" + } + file, _ := fn.FileLine(f.pc()) + return file +} + +// line returns the line number of source code of the +// function for this Frame's pc. +func (f Frame) line() int { + fn := runtime.FuncForPC(f.pc()) + if fn == nil { + return 0 + } + _, line := fn.FileLine(f.pc()) + return line +} + +// Format formats the frame according to the fmt.Formatter interface. +// +// %s source file +// %d source line +// %n function name +// %v equivalent to %s:%d +// +// Format accepts flags that alter the printing of some verbs, as follows: +// +// %+s function name and path of source file relative to the compile time +// GOPATH separated by \n\t (\n\t) +// %+v equivalent to %+s:%d +func (f Frame) Format(s fmt.State, verb rune) { + f.format(s, s, verb) +} + +// format allows stack trace printing calls to be made with a bytes.Buffer. +func (f Frame) format(w io.Writer, s fmt.State, verb rune) { + switch verb { + case 's': + switch { + case s.Flag('+'): + pc := f.pc() + fn := runtime.FuncForPC(pc) + if fn == nil { + io.WriteString(w, "unknown") + } else { + file, _ := fn.FileLine(pc) + io.WriteString(w, fn.Name()) + io.WriteString(w, "\n\t") + io.WriteString(w, file) + } + default: + io.WriteString(w, path.Base(f.file())) + } + case 'd': + io.WriteString(w, strconv.Itoa(f.line())) + case 'n': + name := runtime.FuncForPC(f.pc()).Name() + io.WriteString(w, funcname(name)) + case 'v': + f.format(w, s, 's') + io.WriteString(w, ":") + f.format(w, s, 'd') + } +} + +// StackTrace is stack of Frames from innermost (newest) to outermost (oldest). +type StackTrace []Frame + +// Format formats the stack of Frames according to the fmt.Formatter interface. +// +// %s lists source files for each Frame in the stack +// %v lists the source file and line number for each Frame in the stack +// +// Format accepts flags that alter the printing of some verbs, as follows: +// +// %+v Prints filename, function, and line number for each Frame in the stack. +func (st StackTrace) Format(s fmt.State, verb rune) { + var b bytes.Buffer + switch verb { + case 'v': + switch { + case s.Flag('+'): + b.Grow(len(st) * stackMinLen) + for _, fr := range st { + b.WriteByte('\n') + fr.format(&b, s, verb) + } + case s.Flag('#'): + fmt.Fprintf(&b, "%#v", []Frame(st)) + default: + st.formatSlice(&b, s, verb) + } + case 's': + st.formatSlice(&b, s, verb) + } + io.Copy(s, &b) +} + +// formatSlice will format this StackTrace into the given buffer as a slice of +// Frame, only valid when called with '%s' or '%v'. +func (st StackTrace) formatSlice(b *bytes.Buffer, s fmt.State, verb rune) { + b.WriteByte('[') + if len(st) == 0 { + b.WriteByte(']') + return + } + + b.Grow(len(st) * (stackMinLen / 4)) + st[0].format(b, s, verb) + for _, fr := range st[1:] { + b.WriteByte(' ') + fr.format(b, s, verb) + } + b.WriteByte(']') +} + +// stackMinLen is a best-guess at the minimum length of a stack trace. It +// doesn't need to be exact, just give a good enough head start for the buffer +// to avoid the expensive early growth. +const stackMinLen = 96 + +// stack represents a stack of program counters. +type stack []uintptr + +func (s *stack) Format(st fmt.State, verb rune) { + switch verb { + case 'v': + switch { + case st.Flag('+'): + var b bytes.Buffer + b.Grow(len(*s) * stackMinLen) + for _, pc := range *s { + f := Frame(pc) + b.WriteByte('\n') + f.format(&b, st, 'v') + } + io.Copy(st, &b) + } + } +} + +func (s *stack) StackTrace() StackTrace { + f := make([]Frame, len(*s)) + for i := 0; i < len(f); i++ { + f[i] = Frame((*s)[i]) + } + return f +} + +func callers() *stack { + return callersSkip(4) +} + +func callersSkip(skip int) *stack { + const depth = 32 + var pcs [depth]uintptr + n := runtime.Callers(skip, pcs[:]) + var st stack = pcs[0:n] + return &st +} + +// funcname removes the path prefix component of a function's name reported by func.Name(). +func funcname(name string) string { + i := strings.LastIndex(name, "/") + name = name[i+1:] + i = strings.Index(name, ".") + return name[i+1:] +} + +// NewStack is for library implementers that want to generate a stack trace. +// Normally you should insted use AddStack to get an error with a stack trace. +// +// The result of this function can be turned into a stack trace by calling .StackTrace() +// +// This function takes an argument for the number of stack frames to skip. +// This avoids putting stack generation function calls like this one in the stack trace. +// A value of 0 will give you the line that called NewStack(0) +// A library author wrapping this in their own function will want to use a value of at least 1. +func NewStack(skip int) StackTracer { + return callersSkip(skip + 3) +} diff --git a/v2/vendor/github.com/siddontang/go-log/LICENSE b/v2/vendor/github.com/siddontang/go-log/LICENSE new file mode 100644 index 0000000..7ece9fd --- /dev/null +++ b/v2/vendor/github.com/siddontang/go-log/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 siddontang + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/v2/vendor/github.com/siddontang/go-log/log/doc.go b/v2/vendor/github.com/siddontang/go-log/log/doc.go new file mode 100644 index 0000000..7477f3a --- /dev/null +++ b/v2/vendor/github.com/siddontang/go-log/log/doc.go @@ -0,0 +1,20 @@ +// Package log supplies more advanced features than go orign log package. +// +// It supports log different level: trace, debug, info, warn, error, fatal. +// +// It also supports different log handlers which you can log to stdout, file, socket, etc... +// +// Use +// +// import "github.com/siddontang/go-log/log" +// +// //log with different level +// log.Info("hello world") +// log.Error("hello world") +// +// //create a logger with specified handler +// h := NewStreamHandler(os.Stdout) +// l := log.NewDefault(h) +// l.Info("hello world") +// +package log diff --git a/v2/vendor/github.com/siddontang/go-log/log/filehandler.go b/v2/vendor/github.com/siddontang/go-log/log/filehandler.go new file mode 100644 index 0000000..454865d --- /dev/null +++ b/v2/vendor/github.com/siddontang/go-log/log/filehandler.go @@ -0,0 +1,230 @@ +package log + +import ( + "fmt" + "os" + "path" + "time" +) + +// FileHandler writes log to a file. +type FileHandler struct { + fd *os.File +} + +// NewFileHandler creates a FileHander +func NewFileHandler(fileName string, flag int) (*FileHandler, error) { + dir := path.Dir(fileName) + os.Mkdir(dir, 0777) + + f, err := os.OpenFile(fileName, flag, 0755) + if err != nil { + return nil, err + } + + h := new(FileHandler) + + h.fd = f + + return h, nil +} + +// Write implements Handler interface +func (h *FileHandler) Write(b []byte) (n int, err error) { + return h.fd.Write(b) +} + +// Close implements Handler interface +func (h *FileHandler) Close() error { + return h.fd.Close() +} + +// RotatingFileHandler writes log a file, if file size exceeds maxBytes, +// it will backup current file and open a new one. +// +// max backup file number is set by backupCount, it will delete oldest if backups too many. +type RotatingFileHandler struct { + fd *os.File + + fileName string + maxBytes int + curBytes int + backupCount int +} + +// NewRotatingFileHandler creates a RotatingFileHandler +func NewRotatingFileHandler(fileName string, maxBytes int, backupCount int) (*RotatingFileHandler, error) { + dir := path.Dir(fileName) + os.MkdirAll(dir, 0777) + + h := new(RotatingFileHandler) + + if maxBytes <= 0 { + return nil, fmt.Errorf("invalid max bytes") + } + + h.fileName = fileName + h.maxBytes = maxBytes + h.backupCount = backupCount + + var err error + h.fd, err = os.OpenFile(fileName, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) + if err != nil { + return nil, err + } + + f, err := h.fd.Stat() + if err != nil { + return nil, err + } + h.curBytes = int(f.Size()) + + return h, nil +} + +// Write implements Handler interface +func (h *RotatingFileHandler) Write(p []byte) (n int, err error) { + h.doRollover() + n, err = h.fd.Write(p) + h.curBytes += n + return +} + +// Close implements Handler interface +func (h *RotatingFileHandler) Close() error { + if h.fd != nil { + return h.fd.Close() + } + return nil +} + +func (h *RotatingFileHandler) doRollover() { + if h.curBytes < h.maxBytes { + return + } + + f, err := h.fd.Stat() + if err != nil { + return + } + + if h.maxBytes <= 0 { + return + } else if f.Size() < int64(h.maxBytes) { + h.curBytes = int(f.Size()) + return + } + + if h.backupCount > 0 { + h.fd.Close() + + for i := h.backupCount - 1; i > 0; i-- { + sfn := fmt.Sprintf("%s.%d", h.fileName, i) + dfn := fmt.Sprintf("%s.%d", h.fileName, i+1) + + os.Rename(sfn, dfn) + } + + dfn := fmt.Sprintf("%s.1", h.fileName) + os.Rename(h.fileName, dfn) + + h.fd, _ = os.OpenFile(h.fileName, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) + h.curBytes = 0 + f, err := h.fd.Stat() + if err != nil { + return + } + h.curBytes = int(f.Size()) + } +} + +// TimeRotatingFileHandler writes log to a file, +// it will backup current and open a new one, with a period time you sepecified. +// +// refer: http://docs.python.org/2/library/logging.handlers.html. +// same like python TimedRotatingFileHandler. +type TimeRotatingFileHandler struct { + fd *os.File + + baseName string + interval int64 + suffix string + rolloverAt int64 +} + +// TimeRotating way +const ( + WhenSecond = iota + WhenMinute + WhenHour + WhenDay +) + +// NewTimeRotatingFileHandler creates a TimeRotatingFileHandler +func NewTimeRotatingFileHandler(baseName string, when int8, interval int) (*TimeRotatingFileHandler, error) { + dir := path.Dir(baseName) + os.MkdirAll(dir, 0777) + + h := new(TimeRotatingFileHandler) + + h.baseName = baseName + + switch when { + case WhenSecond: + h.interval = 1 + h.suffix = "2006-01-02_15-04-05" + case WhenMinute: + h.interval = 60 + h.suffix = "2006-01-02_15-04" + case WhenHour: + h.interval = 3600 + h.suffix = "2006-01-02_15" + case WhenDay: + h.interval = 3600 * 24 + h.suffix = "2006-01-02" + default: + return nil, fmt.Errorf("invalid when_rotate: %d", when) + } + + h.interval = h.interval * int64(interval) + + var err error + h.fd, err = os.OpenFile(h.baseName, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) + if err != nil { + return nil, err + } + + fInfo, _ := h.fd.Stat() + h.rolloverAt = fInfo.ModTime().Unix() + h.interval + + return h, nil +} + +func (h *TimeRotatingFileHandler) doRollover() { + //refer http://hg.python.org/cpython/file/2.7/Lib/logging/handlers.py + now := time.Now() + + if h.rolloverAt <= now.Unix() { + fName := h.baseName + now.Format(h.suffix) + h.fd.Close() + e := os.Rename(h.baseName, fName) + if e != nil { + panic(e) + } + + h.fd, _ = os.OpenFile(h.baseName, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) + + h.rolloverAt = time.Now().Unix() + h.interval + } +} + +// Write implements Handler interface +func (h *TimeRotatingFileHandler) Write(b []byte) (n int, err error) { + h.doRollover() + return h.fd.Write(b) +} + +// Close implements Handler interface +func (h *TimeRotatingFileHandler) Close() error { + return h.fd.Close() +} diff --git a/v2/vendor/github.com/siddontang/go-log/log/handler.go b/v2/vendor/github.com/siddontang/go-log/log/handler.go new file mode 100644 index 0000000..30a6c4f --- /dev/null +++ b/v2/vendor/github.com/siddontang/go-log/log/handler.go @@ -0,0 +1,54 @@ +package log + +import ( + "io" +) + +//Handler writes logs to somewhere +type Handler interface { + Write(p []byte) (n int, err error) + Close() error +} + +// StreamHandler writes logs to a specified io Writer, maybe stdout, stderr, etc... +type StreamHandler struct { + w io.Writer +} + +// NewStreamHandler creates a StreamHandler +func NewStreamHandler(w io.Writer) (*StreamHandler, error) { + h := new(StreamHandler) + + h.w = w + + return h, nil +} + +// Write implements Handler interface +func (h *StreamHandler) Write(b []byte) (n int, err error) { + return h.w.Write(b) +} + +// Close implements Handler interface +func (h *StreamHandler) Close() error { + return nil +} + +// NullHandler does nothing, it discards anything. +type NullHandler struct { +} + +// NewNullHandler creates a NullHandler +func NewNullHandler() (*NullHandler, error) { + return new(NullHandler), nil +} + +// // Write implements Handler interface +func (h *NullHandler) Write(b []byte) (n int, err error) { + return len(b), nil +} + +// Close implements Handler interface +func (h *NullHandler) Close() error { + return nil +} diff --git a/v2/vendor/github.com/siddontang/go-log/log/log.go b/v2/vendor/github.com/siddontang/go-log/log/log.go new file mode 100644 index 0000000..555eaf2 --- /dev/null +++ b/v2/vendor/github.com/siddontang/go-log/log/log.go @@ -0,0 +1,157 @@ +package log + +import ( + "fmt" + "os" +) + +var logger = NewDefault(newStdHandler()) + +// SetDefaultLogger changes the global logger +func SetDefaultLogger(l *Logger) { + logger = l +} + +// SetLevel changes the logger level +func SetLevel(level Level) { + logger.SetLevel(level) +} + +// SetLevelByName changes the logger level by name +func SetLevelByName(name string) { + logger.SetLevelByName(name) +} + +// Fatal records the log with fatal level and exits +func Fatal(args ...interface{}) { + logger.Output(2, LevelFatal, fmt.Sprint(args...)) + os.Exit(1) +} + +// Fatalf records the log with fatal level and exits +func Fatalf(format string, args ...interface{}) { + logger.Output(2, LevelFatal, fmt.Sprintf(format, args...)) + os.Exit(1) +} + +// Fatalln records the log with fatal level and exits +func Fatalln(args ...interface{}) { + logger.Output(2, LevelFatal, fmt.Sprintln(args...)) + os.Exit(1) +} + +// Panic records the log with fatal level and panics +func Panic(args ...interface{}) { + msg := fmt.Sprint(args...) + logger.Output(2, LevelError, msg) + panic(msg) +} + +// Panicf records the log with fatal level and panics +func Panicf(format string, args ...interface{}) { + msg := fmt.Sprintf(format, args...) + logger.Output(2, LevelError, msg) + panic(msg) +} + +// Panicln records the log with fatal level and panics +func Panicln(args ...interface{}) { + msg := fmt.Sprintln(args...) + logger.Output(2, LevelError, msg) + panic(msg) +} + +// Print records the log with trace level +func Print(args ...interface{}) { + logger.Output(2, LevelTrace, fmt.Sprint(args...)) +} + +// Print records the log with trace level +func PrintJson(body interface{}) { + logger.OutputJson(2, LevelTrace, body) +} + +// Printf records the log with trace level +func Printf(format string, args ...interface{}) { + logger.Output(2, LevelTrace, fmt.Sprintf(format, args...)) +} + +// Println records the log with trace level +func Println(args ...interface{}) { + logger.Output(2, LevelTrace, fmt.Sprintln(args...)) +} + +// Debug records the log with debug level +func Debug(args ...interface{}) { + logger.Output(2, LevelDebug, fmt.Sprint(args...)) +} + +// Debug records the log with debug level +func DebugJson(body interface{}) { + logger.OutputJson(2, LevelDebug, body) +} + +// Debugf records the log with debug level +func Debugf(format string, args ...interface{}) { + logger.Output(2, LevelDebug, fmt.Sprintf(format, args...)) +} + +// Debugln records the log with debug level +func Debugln(args ...interface{}) { + logger.Output(2, LevelDebug, fmt.Sprintln(args...)) +} + +// Error records the log with error level +func Error(args ...interface{}) { + logger.Output(2, LevelError, fmt.Sprint(args...)) +} + +// Error records the log with error level +func ErrorJson(body interface{}) { + logger.OutputJson(2, LevelError, body) +} + +// Errorf records the log with error level +func Errorf(format string, args ...interface{}) { + logger.Output(2, LevelError, fmt.Sprintf(format, args...)) +} + +// Errorln records the log with error level +func Errorln(args ...interface{}) { + logger.Output(2, LevelError, fmt.Sprintln(args...)) +} + +// Info records the log with info level +func Info(args ...interface{}) { + logger.Output(2, LevelInfo, fmt.Sprint(args...)) +} + +// Info records the log with info level by json format +func InfoJson(body interface{}) { + logger.OutputJson(2, LevelInfo, body) +} + +// Infof records the log with info level +func Infof(format string, args ...interface{}) { + logger.Output(2, LevelInfo, fmt.Sprintf(format, args...)) +} + +// Infoln records the log with info level +func Infoln(args ...interface{}) { + logger.Output(2, LevelInfo, fmt.Sprintln(args...)) +} + +// Warn records the log with warn level +func Warn(args ...interface{}) { + logger.Output(2, LevelWarn, fmt.Sprint(args...)) +} + +// Warnf records the log with warn level +func Warnf(format string, args ...interface{}) { + logger.Output(2, LevelWarn, fmt.Sprintf(format, args...)) +} + +// Warnln records the log with warn level +func Warnln(args ...interface{}) { + logger.Output(2, LevelWarn, fmt.Sprintln(args...)) +} diff --git a/v2/vendor/github.com/siddontang/go-log/log/logger.go b/v2/vendor/github.com/siddontang/go-log/log/logger.go new file mode 100644 index 0000000..8b02c08 --- /dev/null +++ b/v2/vendor/github.com/siddontang/go-log/log/logger.go @@ -0,0 +1,358 @@ +package log + +import ( + "encoding/json" + "fmt" + "os" + "runtime" + "strconv" + "strings" + "sync" + "time" + + "github.com/siddontang/go-log/loggers" +) + +const ( + timeFormat = "2006/01/02 15:04:05" + maxBufPoolSize = 16 +) + +// Logger flag +const ( + Ltime = 1 << iota // time format "2006/01/02 15:04:05" + Lfile // file.go:123 + Llevel // [Trace|Debug|Info...] +) + +// Level type +type Level int + +// Log level, from low to high, more high means more serious +const ( + LevelTrace Level = iota + LevelDebug + LevelInfo + LevelWarn + LevelError + LevelFatal +) + +// String returns level String +func (l Level) String() string { + switch l { + case LevelTrace: + return "trace" + case LevelDebug: + return "debug" + case LevelInfo: + return "info" + case LevelWarn: + return "warn" + case LevelError: + return "error" + case LevelFatal: + return "fatal" + } + // return default info + return "info" +} + +// Logger is the logger to record log +type Logger struct { + // TODO: support logger.Contextual + loggers.Advanced + + level Level + flag int + + hLock sync.Mutex + handler Handler + + bufs sync.Pool +} + +// New creates a logger with specified handler and flag +func New(handler Handler, flag int) *Logger { + var l = new(Logger) + + l.level = LevelInfo + l.handler = handler + + l.flag = flag + + l.bufs = sync.Pool{ + New: func() interface{} { + return make([]byte, 0, 1024) + }, + } + + return l +} + +// NewDefault creates default logger with specified handler and flag: Ltime|Lfile|Llevel +func NewDefault(handler Handler) *Logger { + return New(handler, Ltime|Lfile|Llevel) +} + +func newStdHandler() *StreamHandler { + h, _ := NewStreamHandler(os.Stdout) + return h +} + +// Close closes the logger +func (l *Logger) Close() { + l.hLock.Lock() + defer l.hLock.Unlock() + l.handler.Close() +} + +// SetLevel sets log level, any log level less than it will not log +func (l *Logger) SetLevel(level Level) { + l.level = level +} + +// SetLevelByName sets log level by name +func (l *Logger) SetLevelByName(name string) { + level := LevelInfo + switch strings.ToLower(name) { + case "trace": + level = LevelTrace + case "debug": + level = LevelDebug + case "warn", "warning": + level = LevelWarn + case "error": + level = LevelError + case "fatal": + level = LevelFatal + default: + level = LevelInfo + } + + l.SetLevel(level) +} + +// Output records the log with special callstack depth and log level. +func (l *Logger) Output(callDepth int, level Level, msg string) { + if l.level > level { + return + } + + buf := l.bufs.Get().([]byte) + buf = buf[0:0] + defer l.bufs.Put(buf) + + if l.flag&Ltime > 0 { + now := time.Now().Format(timeFormat) + buf = append(buf, '[') + buf = append(buf, now...) + buf = append(buf, "] "...) + } + + if l.flag&Llevel > 0 { + buf = append(buf, '[') + buf = append(buf, level.String()...) + buf = append(buf, "] "...) + } + + if l.flag&Lfile > 0 { + _, file, line, ok := runtime.Caller(callDepth) + if !ok { + file = "???" + line = 0 + } else { + for i := len(file) - 1; i > 0; i-- { + if file[i] == '/' { + file = file[i+1:] + break + } + } + } + + buf = append(buf, file...) + buf = append(buf, ':') + + buf = strconv.AppendInt(buf, int64(line), 10) + buf = append(buf, ' ') + } + + buf = append(buf, msg...) + if len(msg) == 0 || msg[len(msg)-1] != '\n' { + buf = append(buf, '\n') + } + + l.hLock.Lock() + l.handler.Write(buf) + l.hLock.Unlock() +} + +// Output json format records the log with special callstack depth and log level. +func (l *Logger) OutputJson(callDepth int, level Level, body interface{}) { + if l.level > level { + return + } + + buf := l.bufs.Get().([]byte) + buf = buf[0:0] + defer l.bufs.Put(buf) + + type JsonLog struct { + Time string `json:"log_time"` + Level string `json:"log_level"` + File string `json:"log_file"` + Line string `json:"log_line"` + Body interface{} `json:"log_body"` + } + + var jsonlog JsonLog + if l.flag&Ltime > 0 { + now := time.Now().Format(timeFormat) + jsonlog.Time = now + } + + if l.flag&Llevel > 0 { + jsonlog.Level = level.String() + } + + if l.flag&Lfile > 0 { + _, file, line, ok := runtime.Caller(callDepth) + if !ok { + file = "???" + line = 0 + } else { + for i := len(file) - 1; i > 0; i-- { + if file[i] == '/' { + file = file[i+1:] + break + } + } + } + + jsonlog.File = file + jsonlog.Line = string(strconv.AppendInt(buf, int64(line), 10)) + } + + jsonlog.Body = body + + msg, _ := json.Marshal(jsonlog) + msg = append(msg, '\n') + + l.hLock.Lock() + l.handler.Write(msg) + l.hLock.Unlock() +} + +// Fatal records the log with fatal level and exits +func (l *Logger) Fatal(args ...interface{}) { + l.Output(2, LevelFatal, fmt.Sprint(args...)) + os.Exit(1) +} + +// Fatalf records the log with fatal level and exits +func (l *Logger) Fatalf(format string, args ...interface{}) { + l.Output(2, LevelFatal, fmt.Sprintf(format, args...)) + os.Exit(1) +} + +// Fatalln records the log with fatal level and exits +func (l *Logger) Fatalln(args ...interface{}) { + l.Output(2, LevelFatal, fmt.Sprintln(args...)) + os.Exit(1) +} + +// Panic records the log with fatal level and panics +func (l *Logger) Panic(args ...interface{}) { + msg := fmt.Sprint(args...) + l.Output(2, LevelError, msg) + panic(msg) +} + +// Panicf records the log with fatal level and panics +func (l *Logger) Panicf(format string, args ...interface{}) { + msg := fmt.Sprintf(format, args...) + l.Output(2, LevelError, msg) + panic(msg) +} + +// Panicln records the log with fatal level and panics +func (l *Logger) Panicln(args ...interface{}) { + msg := fmt.Sprintln(args...) + l.Output(2, LevelError, msg) + panic(msg) +} + +// Print records the log with trace level +func (l *Logger) Print(args ...interface{}) { + l.Output(2, LevelTrace, fmt.Sprint(args...)) +} + +// Printf records the log with trace level +func (l *Logger) Printf(format string, args ...interface{}) { + l.Output(2, LevelTrace, fmt.Sprintf(format, args...)) +} + +// Println records the log with trace level +func (l *Logger) Println(args ...interface{}) { + l.Output(2, LevelTrace, fmt.Sprintln(args...)) +} + +// Debug records the log with debug level +func (l *Logger) Debug(args ...interface{}) { + l.Output(2, LevelDebug, fmt.Sprint(args...)) +} + +// Debugf records the log with debug level +func (l *Logger) Debugf(format string, args ...interface{}) { + l.Output(2, LevelDebug, fmt.Sprintf(format, args...)) +} + +// Debugln records the log with debug level +func (l *Logger) Debugln(args ...interface{}) { + l.Output(2, LevelDebug, fmt.Sprintln(args...)) +} + +// Error records the log with error level +func (l *Logger) Error(args ...interface{}) { + l.Output(2, LevelError, fmt.Sprint(args...)) +} + +// Errorf records the log with error level +func (l *Logger) Errorf(format string, args ...interface{}) { + l.Output(2, LevelError, fmt.Sprintf(format, args...)) +} + +// Errorln records the log with error level +func (l *Logger) Errorln(args ...interface{}) { + l.Output(2, LevelError, fmt.Sprintln(args...)) +} + +// Info records the log with info level +func (l *Logger) Info(args ...interface{}) { + l.Output(2, LevelInfo, fmt.Sprint(args...)) +} + +// Infof records the log with info level +func (l *Logger) Infof(format string, args ...interface{}) { + l.Output(2, LevelInfo, fmt.Sprintf(format, args...)) +} + +// Infoln records the log with info level +func (l *Logger) Infoln(args ...interface{}) { + l.Output(2, LevelInfo, fmt.Sprintln(args...)) +} + +// Warn records the log with warn level +func (l *Logger) Warn(args ...interface{}) { + l.Output(2, LevelWarn, fmt.Sprint(args...)) +} + +// Warnf records the log with warn level +func (l *Logger) Warnf(format string, args ...interface{}) { + l.Output(2, LevelWarn, fmt.Sprintf(format, args...)) +} + +// Warnln records the log with warn level +func (l *Logger) Warnln(args ...interface{}) { + l.Output(2, LevelWarn, fmt.Sprintln(args...)) +} diff --git a/v2/vendor/github.com/siddontang/go-log/loggers/loggers.go b/v2/vendor/github.com/siddontang/go-log/loggers/loggers.go new file mode 100644 index 0000000..2723b24 --- /dev/null +++ b/v2/vendor/github.com/siddontang/go-log/loggers/loggers.go @@ -0,0 +1,68 @@ +// MIT License + +// Copyright (c) 2017 Birkir A. Barkarson + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +package loggers + +// Standard is the interface used by Go's standard library's log package. +type Standard interface { + Fatal(args ...interface{}) + Fatalf(format string, args ...interface{}) + Fatalln(args ...interface{}) + + Panic(args ...interface{}) + Panicf(format string, args ...interface{}) + Panicln(args ...interface{}) + + Print(args ...interface{}) + Printf(format string, args ...interface{}) + Println(args ...interface{}) +} + +// Advanced is an interface with commonly used log level methods. +type Advanced interface { + Standard + + Debug(args ...interface{}) + Debugf(format string, args ...interface{}) + Debugln(args ...interface{}) + + Error(args ...interface{}) + Errorf(format string, args ...interface{}) + Errorln(args ...interface{}) + + Info(args ...interface{}) + Infof(format string, args ...interface{}) + Infoln(args ...interface{}) + + Warn(args ...interface{}) + Warnf(format string, args ...interface{}) + Warnln(args ...interface{}) +} + +// Contextual is an interface that allows context addition to a log statement before +// calling the final print (message/level) method. +type Contextual interface { + Advanced + + WithField(key string, value interface{}) Advanced + WithFields(fields ...interface{}) Advanced +} diff --git a/v2/vendor/github.com/siddontang/go/LICENSE b/v2/vendor/github.com/siddontang/go/LICENSE new file mode 100644 index 0000000..80511a0 --- /dev/null +++ b/v2/vendor/github.com/siddontang/go/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2014 siddontang + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/v2/vendor/github.com/siddontang/go/hack/hack.go b/v2/vendor/github.com/siddontang/go/hack/hack.go new file mode 100644 index 0000000..74ee83c --- /dev/null +++ b/v2/vendor/github.com/siddontang/go/hack/hack.go @@ -0,0 +1,27 @@ +package hack + +import ( + "reflect" + "unsafe" +) + +// no copy to change slice to string +// use your own risk +func String(b []byte) (s string) { + pbytes := (*reflect.SliceHeader)(unsafe.Pointer(&b)) + pstring := (*reflect.StringHeader)(unsafe.Pointer(&s)) + pstring.Data = pbytes.Data + pstring.Len = pbytes.Len + return +} + +// no copy to change string to slice +// use your own risk +func Slice(s string) (b []byte) { + pbytes := (*reflect.SliceHeader)(unsafe.Pointer(&b)) + pstring := (*reflect.StringHeader)(unsafe.Pointer(&s)) + pbytes.Data = pstring.Data + pbytes.Len = pstring.Len + pbytes.Cap = pstring.Len + return +} diff --git a/v2/vendor/github.com/xyproto/cookie/v2/cookie.go b/v2/vendor/github.com/xyproto/cookie/v2/cookie.go index 5323df3..69bf486 100644 --- a/v2/vendor/github.com/xyproto/cookie/v2/cookie.go +++ b/v2/vendor/github.com/xyproto/cookie/v2/cookie.go @@ -9,7 +9,7 @@ import ( "crypto/sha1" "encoding/base64" "fmt" - "io/ioutil" + "io" "log" "net/http" "strconv" @@ -55,7 +55,7 @@ func SecureCookie(req *http.Request, name, cookieSecret string) (string, bool) { buf := bytes.NewBufferString(val) encoder := base64.NewDecoder(base64.StdEncoding, buf) - res, _ := ioutil.ReadAll(encoder) + res, _ := io.ReadAll(encoder) return string(res), true } return "", false @@ -89,7 +89,7 @@ func SetCookiePath(w http.ResponseWriter, name, value string, age int64, path st // The cookie is cleared by setting the expiration date to 1970-01-01. // Note that browsers *may* be configured to not delete the cookie. func ClearCookie(w http.ResponseWriter, cookieName, cookiePath string) { - ignoredContent := "SNUSNU" // random string + const ignoredContent = "SNUSNU" // random string cookie := fmt.Sprintf("%s=%s; path=%s; expires=Thu, 01 Jan 1970 00:00:00 GMT", cookieName, ignoredContent, cookiePath) SetHeader(w, "Set-Cookie", cookie, true) } diff --git a/v2/vendor/github.com/xyproto/env/v2/LICENSE b/v2/vendor/github.com/xyproto/env/v2/LICENSE new file mode 100644 index 0000000..eb3c334 --- /dev/null +++ b/v2/vendor/github.com/xyproto/env/v2/LICENSE @@ -0,0 +1,11 @@ +Copyright 2023 Alexander F. Rødseth + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/v2/vendor/github.com/xyproto/env/v2/cache.go b/v2/vendor/github.com/xyproto/env/v2/cache.go new file mode 100644 index 0000000..71dae71 --- /dev/null +++ b/v2/vendor/github.com/xyproto/env/v2/cache.go @@ -0,0 +1,109 @@ +// Package env provides convenience functions for retrieving data from environment variables +package env + +import ( + "errors" + "os" + "runtime" + "strings" + "sync" +) + +// Setting useCaching to true makes the functions below stop callig os.Getenv, +// only call os.Environ once and then use the environment map to read variables from. +var ( + useCaching = true + environment map[string]string + mut sync.RWMutex +) + +// getenv calls os.Getenv if useCaching is false. +// If useCaching is true, the environment map is initialized (if needed), +// and the value is fetched from the map instead of calling os.Getenv. +func getenv(name string) string { + if !useCaching { + return os.Getenv(name) + } + mut.RLock() + if environment == nil { + mut.RUnlock() + Load() + mut.RLock() + } + value, ok := environment[name] + mut.RUnlock() + if !ok { + return "" + } + return value +} + +// Load reads all environment variables into the environment map. It also instructs env to use the cache. +// If a program uses os.Setenv, then Load() should be called after that, in order to read the new values. +// This function can be used both as an "init and enable cache" function and as a "reload" function. +func Load() { + mut.Lock() + environment = make(map[string]string) + // Read all the environment variables into the map + for _, statement := range os.Environ() { + pair := strings.SplitN(statement, "=", 2) + environment[pair[0]] = pair[1] + } + mut.Unlock() + useCaching = true +} + +// Unload clears the cache and configures env to not use the cache. +func Unload() { + environment = nil + useCaching = false +} + +// Set calls os.Setenv. +// If caching is enabled, the value in the environment map is also set and there +// is no need to call Load() to re-read the environment variables from the system. +func Set(name, value string) error { + if useCaching { + mut.RLock() + if environment == nil { + mut.RUnlock() + Load() + } else { + mut.RUnlock() + } + mut.Lock() + if value == "" { + delete(environment, name) + } else { + environment[name] = value + } + mut.Unlock() + } + return os.Setenv(name, value) +} + +// Unset will clear an environment variable by calling os.Setenv(name, ""). +// The cache entry will also be cleared if useCaching is true. +func Unset(name string) error { + return Set(name, "") +} + +// userHomeDir is the same as os.UserHomeDir, except that "getenv" is called instead of "os.Getenv", +// and the two switches are refactored into one. +func userHomeDir() (string, error) { + env, enverr := "HOME", "$HOME" + switch runtime.GOOS { + case "android": + return "/sdcard", nil + case "ios": + return "/", nil + case "windows": + env, enverr = "USERPROFILE", "%userprofile%" + case "plan9": + env, enverr = "home", "$home" + } + if v := getenv(env); v != "" { + return v, nil + } + return "", errors.New(enverr + " is not defined") +} diff --git a/v2/vendor/github.com/xyproto/env/v2/env.go b/v2/vendor/github.com/xyproto/env/v2/env.go new file mode 100644 index 0000000..91f00c4 --- /dev/null +++ b/v2/vendor/github.com/xyproto/env/v2/env.go @@ -0,0 +1,302 @@ +// Package env provides convenience functions for retrieving data from environment variables +package env + +import ( + "os" + "path/filepath" + "strconv" + "strings" + "time" +) + +// Str does the same as os.Getenv, but allows the user to provide a default value (optional). +// Only the first optional argument is used, the rest is discarded. +func Str(name string, optionalDefault ...string) string { + // Retrieve the environment variable as a (possibly empty) string + value := getenv(name) + + // If empty and a default value was provided, return that + if value == "" && len(optionalDefault) > 0 { + return optionalDefault[0] + } + + // If not, return the value of the environment variable + return value +} + +// File does the same as Str, but expands a leading "~" or "$HOME" string to the home +// directory of the current user. +func File(name string, optionalDefault ...string) string { + return ExpandUser(Str(name, optionalDefault...)) +} + +// Dir does the same as File +func Dir(name string, optionalDefault ...string) string { + return ExpandUser(Str(name, optionalDefault...)) +} + +// Path returns the elements in the $PATH environment variable +func Path() []string { + return filepath.SplitList(Str("PATH")) +} + +// StrAlt will return the string value of the first given environment variable name, +// or, if that is not available, use the string value of the second given environment variable. +// If none are available, the optional default string is returned. +func StrAlt(name1, name2 string, optionalDefault ...string) string { + // Retrieve the environment variable as a (possibly empty) string + value := getenv(name1) + + // If it is empty, try the second name + if value == "" { + value = getenv(name2) + } + + // If empty and a default value was provided, return that + if value == "" && len(optionalDefault) > 0 { + return optionalDefault[0] + } + + // If not, return the non-empty value + return value +} + +// Bool returns the bool value of the given environment variable name. +// Returns false if it is not declared or empty. +func Bool(envName string) bool { + return AsBool(Str(envName)) +} + +// BoolSimple returns the bool value of the given environment variable name. +// Returns false if it is not declared or empty. Only "1" is true. +func BoolSimple(envName string) bool { + return AsBoolSimple(Str(envName)) +} + +// Has returns true if the given environment variable name is set and not empty. +func Has(envName string) bool { + return Str(envName) != "" +} + +// Is returns true if the given environment variable is the given string value. +// The whitespace of both values are trimmed before the comparison. +func Is(envName, value string) bool { + return strings.TrimSpace(Str(envName)) == strings.TrimSpace(value) +} + +// Int returns the number stored in the environment variable, or the provided default value. +func Int(envName string, defaultValue int) int { + i, err := strconv.Atoi(Str(envName)) + if err != nil { + return defaultValue + } + return i +} + +// Int64 returns the number stored in the environment variable, or the provided default value. +func Int64(envName string, defaultValue int64) int64 { + i64, err := strconv.ParseInt(Str(envName), 10, 64) + if err != nil { + return defaultValue + } + return i64 +} + +// Int32 returns the number stored in the environment variable, or the provided default value. +func Int32(envName string, defaultValue int32) int32 { + i32, err := strconv.ParseInt(Str(envName), 10, 32) + if err != nil { + return defaultValue + } + return int32(i32) +} + +// Int16 returns the number stored in the environment variable, or the provided default value. +func Int16(envName string, defaultValue int16) int16 { + i16, err := strconv.ParseInt(Str(envName), 10, 16) + if err != nil { + return defaultValue + } + return int16(i16) +} + +// Int8 returns the number stored in the environment variable, or the provided default value. +func Int8(envName string, defaultValue int8) int8 { + i8, err := strconv.ParseInt(Str(envName), 10, 8) + if err != nil { + return defaultValue + } + return int8(i8) +} + +// UInt64 returns the number stored in the environment variable, or the provided default value. +func UInt64(envName string, defaultValue uint64) uint64 { + ui64, err := strconv.ParseUint(Str(envName), 10, 64) + if err != nil { + return defaultValue + } + return ui64 +} + +// UInt32 returns the number stored in the environment variable, or the provided default value. +func UInt32(envName string, defaultValue uint32) uint32 { + ui32, err := strconv.ParseUint(Str(envName), 10, 32) + if err != nil { + return defaultValue + } + return uint32(ui32) +} + +// UInt16 returns the number stored in the environment variable, or the provided default value. +func UInt16(envName string, defaultValue uint16) uint16 { + ui16, err := strconv.ParseUint(Str(envName), 10, 16) + if err != nil { + return defaultValue + } + return uint16(ui16) +} + +// UInt8 returns the number stored in the environment variable, or the provided default value. +func UInt8(envName string, defaultValue uint8) uint8 { + ui8, err := strconv.ParseUint(Str(envName), 10, 8) + if err != nil { + return defaultValue + } + return uint8(ui8) +} + +// Float64 returns the number stored in the environment variable, or the provided default value. +func Float64(envName string, defaultValue float64) float64 { + f64, err := strconv.ParseFloat(Str(envName), 64) + if err != nil { + return defaultValue + } + return f64 +} + +// Float32 returns the number stored in the environment variable, or the provided default value. +func Float32(envName string, defaultValue float32) float32 { + f32, err := strconv.ParseFloat(Str(envName), 32) + if err != nil { + return defaultValue + } + return float32(f32) +} + +// DurationSeconds interprets the environment variable value as seconds +// and returns a time.Duration. The given default number is interpreted +// as the number of seconds. +func DurationSeconds(envName string, defaultValue int64) time.Duration { + i64, err := strconv.ParseInt(Str(envName), 10, 64) + if err != nil { + return time.Duration(defaultValue) * time.Second + } + return time.Duration(i64) * time.Second +} + +// DurationMinutes interprets the environment variable value as minutes +// and returns a time.Duration. The given default number is interpreted +// as the number of minutes. +func DurationMinutes(envName string, defaultValue int64) time.Duration { + i64, err := strconv.ParseInt(Str(envName), 10, 64) + if err != nil { + return time.Duration(defaultValue) * time.Minute + } + return time.Duration(i64) * time.Minute +} + +// DurationHours interprets the environment variable value as hours +// and returns a time.Duration. The given default number is interpreted +// as the number of hours. +func DurationHours(envName string, defaultValue int64) time.Duration { + i64, err := strconv.ParseInt(Str(envName), 10, 64) + if err != nil { + return time.Duration(defaultValue) * time.Hour + } + return time.Duration(i64) * time.Hour +} + +// Contains checks if the given environment variable contains the given string +func Contains(envName string, value string) bool { + return strings.Contains(Str(envName), value) +} + +// True checks if the given string is likely to be interpreted as a "true" value +func True(s string) bool { + switch s { + case "1", "ABSOLUTELY", "AFFIRMATIVE", "Absolutely", "Affirmative", "ENABLE", "ENABLED", "Enable", "Enabled", "POSITIVE", "Positive", "T", "TRUE", "True", "Y", "YES", "Yes", "absolutely", "affirmative", "enable", "enabled", "positive", "t", "true", "y", "yes": + return true + } + return false +} + +// False checks if the given string is likely to be interpreted as a "false" value +func False(s string) bool { + switch s { + case "", "0", "BLANK", "Blank", "DENIED", "DISABLE", "DISABLED", "Denied", "Disable", "Disabled", "F", "FALSE", "False", "N", "NEGATIVE", "NIL", "NO", "NOPE", "NULL", "Negative", "Nil", "No", "Nope", "Null", "blank", "denied", "disable", "disabled", "f", "false", "n", "negative", "nil", "no", "nope", "null": + return true + } + return false +} + +// AsBool can be used to interpret a string value as either true or false. Examples of true values are "yes" and "1". +func AsBool(s string) bool { + return True(s) +} + +// AsBoolSimple can be used to interpret a string value as either true or false. Only "1" is true, anything else is false. +func AsBoolSimple(s string) bool { + return s == "1" +} + +// HomeDir returns the path to the home directory of the user, if available. +// If not available, $LOGNAME or $USER are used to construct a path starting with /home/. +// If $LOGNAME and $USER are not available, just "/tmp" is returned. +// The returned string is what the home directory should have been named, if it would have existed. +// No checks are made for if the directory exists. +func HomeDir() string { + homeDir, err := userHomeDir() + if err != nil { + // Use $LOGNAME, $USER or "user", in that order + userName := StrAlt("LOGNAME", "USER", "user") + // If the user name is "root", use /root + if userName == "root" { + return "/root" + } + // If the user name is "user", use either $HOME or /tmp + if userName == "user" { + return Str("HOME", "/tmp") + } + // Use $HOME if it's available, and a constructed home directory path if not + return Str("HOME", "/home/"+userName) + } + return homeDir +} + +// ExpandUser replaces a leading ~ or $HOME with the path +// to the home directory of the current user +func ExpandUser(path string) string { + // this is a simpler alternative to using os.UserHomeDir (which requires Go 1.12 or later) + if strings.HasPrefix(path, "~") { + // Expand ~ to the home directory + path = strings.Replace(path, "~", HomeDir(), 1) + } else if strings.HasPrefix(path, "$HOME") { + // Expand a leading $HOME variable to the home directory + path = strings.Replace(path, "$HOME", HomeDir(), 1) + } + return path +} + +// Environ returns either the cached environment, or os.Environ() +func Environ() []string { + if useCaching { + var xs []string + mut.RLock() + defer mut.RUnlock() + for k, v := range environment { + xs = append(xs, k+"="+v) + } + return xs + } + return os.Environ() +} diff --git a/v2/vendor/github.com/xyproto/env/v2/etc.go b/v2/vendor/github.com/xyproto/env/v2/etc.go new file mode 100644 index 0000000..6794d53 --- /dev/null +++ b/v2/vendor/github.com/xyproto/env/v2/etc.go @@ -0,0 +1,36 @@ +package env + +import ( + "bytes" + "fmt" + "os" + "strings" +) + +// isDir checks if the given path is a directory (could also be a symlink) +func isDir(path string) bool { + fi, err := os.Stat(path) + return err == nil && fi.IsDir() +} + +// EtcEnvironment tries to find the value of the given variable name in /etc/environment. +// The variable name could be ie. "JAVA_HOME". +func EtcEnvironment(envVarName string) (string, error) { + // Find the definition of ie. JAVA_HOME within /etc/environment + data, err := os.ReadFile("/etc/environment") + if err != nil { + return "", err + } + lines := bytes.Split(data, []byte{'\n'}) + for _, line := range lines { + if bytes.Contains(line, []byte(envVarName)) && bytes.Count(line, []byte("=")) == 1 { + fields := bytes.SplitN(line, []byte("="), 2) + javaPath := strings.TrimSpace(string(fields[1])) + if !isDir(javaPath) { + continue + } + return javaPath, nil + } + } + return "", fmt.Errorf("could not find the value of %s in /etc/environment", envVarName) +} diff --git a/v2/vendor/github.com/xyproto/env/v2/session.go b/v2/vendor/github.com/xyproto/env/v2/session.go new file mode 100644 index 0000000..e9ef0ec --- /dev/null +++ b/v2/vendor/github.com/xyproto/env/v2/session.go @@ -0,0 +1,25 @@ +package env + +import "strings" + +// WaylandSession returns true of XDG_SESSION_TYPE is "wayland" or if +// DESKTOP_SESSION contains "wayland". +func WaylandSession() bool { + return Str("XDG_SESSION_TYPE") == "wayland" || Has("WAYLAND_DISPLAY") || strings.Contains(Str("DESKTOP_SESSION"), "wayland") +} + +// XSession returns true if DISPLAY is set. +// X being available is not neccessarily in opposition to Wayland running. +func XSession() bool { + return Has("DISPLAY") +} + +// OnlyXSession returns true if DISPLAY is set and WaylandSession() is false. +func OnlyXSession() bool { + return Has("DISPLAY") && !WaylandSession() +} + +// XOrWaylandSession returns true if DISPLAY is set or WaylandSession() returns true. +func XOrWaylandSession() bool { + return Has("DISPLAY") || WaylandSession() +} diff --git a/v2/vendor/github.com/xyproto/simplemaria/.gitignore b/v2/vendor/github.com/xyproto/simplemaria/.gitignore index 528cd5b..14c0d4b 100644 --- a/v2/vendor/github.com/xyproto/simplemaria/.gitignore +++ b/v2/vendor/github.com/xyproto/simplemaria/.gitignore @@ -1 +1,7 @@ -example/example +*.bak +*.o +*.swp +*.tmp +.DS_Store +cmd/example/example +include.txt diff --git a/v2/vendor/github.com/xyproto/simplemaria/.travis.yml b/v2/vendor/github.com/xyproto/simplemaria/.travis.yml deleted file mode 100644 index 3c7be10..0000000 --- a/v2/vendor/github.com/xyproto/simplemaria/.travis.yml +++ /dev/null @@ -1,21 +0,0 @@ -language: go - -services: - - mysql - -go: - - "1.9" - - "1.10" - - "1.11" - -os: - - linux - -dist: trusty -sudo: false - -install: true - -script: - - env GO111MODULE=on go build - - env GO111MODULE=on go test diff --git a/v2/vendor/github.com/xyproto/simplemaria/README.md b/v2/vendor/github.com/xyproto/simplemaria/README.md index e904a1c..35cd5bf 100644 --- a/v2/vendor/github.com/xyproto/simplemaria/README.md +++ b/v2/vendor/github.com/xyproto/simplemaria/README.md @@ -1,7 +1,7 @@ SimpleMaria =========== -[![Build Status](https://travis-ci.org/xyproto/simplemaria.svg?branch=master)](https://travis-ci.org/xyproto/simplemaria) [![GoDoc](https://godoc.org/github.com/xyproto/simplemaria?status.svg)](http://godoc.org/github.com/xyproto/simplemaria) +[![GoDoc](https://godoc.org/github.com/xyproto/simplemaria?status.svg)](http://godoc.org/github.com/xyproto/simplemaria) An easy way to use a MariaDB/MySQL database from Go. @@ -85,6 +85,6 @@ A MariaDB/MySQL Database must be up and running locally for `go test` to work. Version, license and author --------------------------- -* Version: 1.3.2 +* Version: 1.3.4 * License: BSD-3 * Author: Alexander F. Rødseth <xyproto@archlinux.org> diff --git a/v2/vendor/github.com/xyproto/simplemaria/encdec.go b/v2/vendor/github.com/xyproto/simplemaria/encdec.go index 461461e..64217cc 100644 --- a/v2/vendor/github.com/xyproto/simplemaria/encdec.go +++ b/v2/vendor/github.com/xyproto/simplemaria/encdec.go @@ -4,7 +4,7 @@ import ( "bytes" "compress/flate" "encoding/hex" - "io/ioutil" + "io" ) // MariaDB/MySQL does not handle some characters well. @@ -38,7 +38,7 @@ func Decode(code *string) error { } buf := bytes.NewBuffer(unhexedBytes) decompressorReader := flate.NewReader(buf) - decompressedBytes, err := ioutil.ReadAll(decompressorReader) + decompressedBytes, err := io.ReadAll(decompressorReader) decompressorReader.Close() if err != nil { return err diff --git a/v2/vendor/github.com/xyproto/simplemaria/helpers.go b/v2/vendor/github.com/xyproto/simplemaria/helpers.go index 6bec1cf..fa928f3 100644 --- a/v2/vendor/github.com/xyproto/simplemaria/helpers.go +++ b/v2/vendor/github.com/xyproto/simplemaria/helpers.go @@ -108,28 +108,31 @@ func splitConnectionString(connectionString string) (string, string, bool, strin return username, password, hasPassword, host, port, dbname } -// Build a DSN func buildConnectionString(username, password string, hasPassword bool, host, port, dbname string) string { + // Build the new connection string without "tcp()" + var newConnectionString string - // Build the new connection string + if username != "" { + if hasPassword { + newConnectionString = username + ":" + password + } else { + newConnectionString = username + } + newConnectionString += "@" // Include '@' only if there's a username + } - newConnectionString := "" - if (host != "") && (port != "") { - newConnectionString += "tcp(" + host + ":" + port + ")" + if host != "" && port != "" { + newConnectionString += host + ":" + port } else if host != "" { - newConnectionString += "tcp(" + host + ")" + newConnectionString += host } else if port != "" { - newConnectionString += "tcp(" + ":" + port + ")" - log.Fatalln("There is only a port. This should not happen.") + // Only having a port is unusual and generally not recommended + log.Fatalln("Only a port is specified without a host, which is invalid.") } - if (username != "") && hasPassword { - newConnectionString = username + ":" + password + "@" + newConnectionString - } else if username != "" { - newConnectionString = username + "@" + newConnectionString - } else if hasPassword { - newConnectionString = ":" + password + "@" + newConnectionString + + if dbname != "" { + newConnectionString += "/" + dbname } - newConnectionString += "/" if Verbose { log.Println("DSN:", newConnectionString) diff --git a/v2/vendor/github.com/xyproto/simplemaria/simplemaria.go b/v2/vendor/github.com/xyproto/simplemaria/simplemaria.go index 4db395c..3f82c33 100644 --- a/v2/vendor/github.com/xyproto/simplemaria/simplemaria.go +++ b/v2/vendor/github.com/xyproto/simplemaria/simplemaria.go @@ -4,14 +4,16 @@ package simplemaria import ( - "database/sql" "errors" "fmt" - // Use the mysql database driver - _ "github.com/go-sql-driver/mysql" "log" "strconv" - "strings" + + "github.com/xyproto/env/v2" + + "database/sql" + + _ "github.com/go-mysql-org/go-mysql/driver" ) const ( @@ -40,12 +42,12 @@ type ( ) const ( - // The default "username:password@host:port/database" that the database is running at - defaultDatabaseServer = "" // "username:password@server:port/" - defaultDatabaseName = "test" // "main" - defaultStringType = "TEXT" // "VARCHAR(65535)" + defaultDatabaseServer = "localhost" // "username:password@server:port/" + defaultDatabaseName = "test" // "main" + defaultStringType = "TEXT" // "VARCHAR(65535)" defaultPort = 3306 + defaultUser = "user" // Requires MySQL >= 5.53 and MariaDB >= ? for utf8mb4 charset = "utf8mb4" // "utf8" @@ -108,9 +110,19 @@ func TestConnectionHostWithDSN(connectionString string) (err error) { // Create a new database connection. // connectionString may be on the form "username:password@host:port/database". func NewHost(connectionString string) *Host { - - newConnectionString, dbname := rebuildConnectionString(connectionString) - + // Use env.Str to fetch environment variables with defaults + hostname := env.Str("MARIADB_HOST", defaultDatabaseServer) + port := env.Str("MARIADB_PORT", strconv.Itoa(defaultPort)) + user := env.Str("MARIADB_USER", defaultUser) + password := env.Str("MARIADB_PASSWORD") + dbname := env.Str("MARIADB_DBNAME", defaultDatabaseName) + // Rebuild the connection string with potential new values from environment + var newConnectionString string + if password != "" { + newConnectionString = fmt.Sprintf("%s:%s@%s:%s/%s", user, password, hostname, port, dbname) + } else { + newConnectionString = fmt.Sprintf("%s@%s:%s/%s", user, hostname, port, dbname) + } db, err := sql.Open("mysql", newConnectionString) if err != nil { log.Fatalln("Could not connect to " + newConnectionString + "!") @@ -150,10 +162,20 @@ func NewHostWithDSN(connectionString string, dbname string) *Host { // The default database connection func New() *Host { - connectionString := defaultDatabaseServer + defaultDatabaseName - if !strings.HasSuffix(defaultDatabaseServer, "/") { - connectionString = defaultDatabaseServer + "/" + defaultDatabaseName + user := env.Str("MARIADB_USER", defaultUser) + password := env.Str("MARIADB_PASSWORD") + host := env.Str("MARIADB_HOST", defaultDatabaseServer) + port := env.Str("MARIADB_PORT", strconv.Itoa(defaultPort)) + dbname := env.Str("MARIADB_DBNAME", defaultDatabaseName) + + // Build the connection string based on whether a password is provided + var connectionString string + if password == "" { + connectionString = fmt.Sprintf("%s@%s:%s/%s", user, host, port, dbname) + } else { + connectionString = fmt.Sprintf("%s:%s@%s:%s/%s", user, password, host, port, dbname) } + return NewHost(connectionString) } diff --git a/v2/vendor/go.uber.org/atomic/.codecov.yml b/v2/vendor/go.uber.org/atomic/.codecov.yml new file mode 100644 index 0000000..571116c --- /dev/null +++ b/v2/vendor/go.uber.org/atomic/.codecov.yml @@ -0,0 +1,19 @@ +coverage: + range: 80..100 + round: down + precision: 2 + + status: + project: # measuring the overall project coverage + default: # context, you can create multiple ones with custom titles + enabled: yes # must be yes|true to enable this status + target: 100 # specify the target coverage for each commit status + # option: "auto" (must increase from parent commit or pull request base) + # option: "X%" a static target percentage to hit + if_not_found: success # if parent is not found report status as success, error, or failure + if_ci_failed: error # if ci fails report status as success, error, or failure + +# Also update COVER_IGNORE_PKGS in the Makefile. +ignore: + - /internal/gen-atomicint/ + - /internal/gen-valuewrapper/ diff --git a/v2/vendor/go.uber.org/atomic/.gitignore b/v2/vendor/go.uber.org/atomic/.gitignore new file mode 100644 index 0000000..2e337a0 --- /dev/null +++ b/v2/vendor/go.uber.org/atomic/.gitignore @@ -0,0 +1,15 @@ +/bin +.DS_Store +/vendor +cover.html +cover.out +lint.log + +# Binaries +*.test + +# Profiling output +*.prof + +# Output of fossa analyzer +/fossa diff --git a/v2/vendor/go.uber.org/atomic/CHANGELOG.md b/v2/vendor/go.uber.org/atomic/CHANGELOG.md new file mode 100644 index 0000000..6f87f33 --- /dev/null +++ b/v2/vendor/go.uber.org/atomic/CHANGELOG.md @@ -0,0 +1,127 @@ +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [1.11.0] - 2023-05-02 +### Fixed +- Fix initialization of `Value` wrappers. + +### Added +- Add `String` method to `atomic.Pointer[T]` type allowing users to safely print +underlying values of pointers. + +[1.11.0]: https://github.com/uber-go/atomic/compare/v1.10.0...v1.11.0 + +## [1.10.0] - 2022-08-11 +### Added +- Add `atomic.Float32` type for atomic operations on `float32`. +- Add `CompareAndSwap` and `Swap` methods to `atomic.String`, `atomic.Error`, + and `atomic.Value`. +- Add generic `atomic.Pointer[T]` type for atomic operations on pointers of any + type. This is present only for Go 1.18 or higher, and is a drop-in for + replacement for the standard library's `sync/atomic.Pointer` type. + +### Changed +- Deprecate `CAS` methods on all types in favor of corresponding + `CompareAndSwap` methods. + +Thanks to @eNV25 and @icpd for their contributions to this release. + +[1.10.0]: https://github.com/uber-go/atomic/compare/v1.9.0...v1.10.0 + +## [1.9.0] - 2021-07-15 +### Added +- Add `Float64.Swap` to match int atomic operations. +- Add `atomic.Time` type for atomic operations on `time.Time` values. + +[1.9.0]: https://github.com/uber-go/atomic/compare/v1.8.0...v1.9.0 + +## [1.8.0] - 2021-06-09 +### Added +- Add `atomic.Uintptr` type for atomic operations on `uintptr` values. +- Add `atomic.UnsafePointer` type for atomic operations on `unsafe.Pointer` values. + +[1.8.0]: https://github.com/uber-go/atomic/compare/v1.7.0...v1.8.0 + +## [1.7.0] - 2020-09-14 +### Added +- Support JSON serialization and deserialization of primitive atomic types. +- Support Text marshalling and unmarshalling for string atomics. + +### Changed +- Disallow incorrect comparison of atomic values in a non-atomic way. + +### Removed +- Remove dependency on `golang.org/x/{lint, tools}`. + +[1.7.0]: https://github.com/uber-go/atomic/compare/v1.6.0...v1.7.0 + +## [1.6.0] - 2020-02-24 +### Changed +- Drop library dependency on `golang.org/x/{lint, tools}`. + +[1.6.0]: https://github.com/uber-go/atomic/compare/v1.5.1...v1.6.0 + +## [1.5.1] - 2019-11-19 +- Fix bug where `Bool.CAS` and `Bool.Toggle` do work correctly together + causing `CAS` to fail even though the old value matches. + +[1.5.1]: https://github.com/uber-go/atomic/compare/v1.5.0...v1.5.1 + +## [1.5.0] - 2019-10-29 +### Changed +- With Go modules, only the `go.uber.org/atomic` import path is supported now. + If you need to use the old import path, please add a `replace` directive to + your `go.mod`. + +[1.5.0]: https://github.com/uber-go/atomic/compare/v1.4.0...v1.5.0 + +## [1.4.0] - 2019-05-01 +### Added + - Add `atomic.Error` type for atomic operations on `error` values. + +[1.4.0]: https://github.com/uber-go/atomic/compare/v1.3.2...v1.4.0 + +## [1.3.2] - 2018-05-02 +### Added +- Add `atomic.Duration` type for atomic operations on `time.Duration` values. + +[1.3.2]: https://github.com/uber-go/atomic/compare/v1.3.1...v1.3.2 + +## [1.3.1] - 2017-11-14 +### Fixed +- Revert optimization for `atomic.String.Store("")` which caused data races. + +[1.3.1]: https://github.com/uber-go/atomic/compare/v1.3.0...v1.3.1 + +## [1.3.0] - 2017-11-13 +### Added +- Add `atomic.Bool.CAS` for compare-and-swap semantics on bools. + +### Changed +- Optimize `atomic.String.Store("")` by avoiding an allocation. + +[1.3.0]: https://github.com/uber-go/atomic/compare/v1.2.0...v1.3.0 + +## [1.2.0] - 2017-04-12 +### Added +- Shadow `atomic.Value` from `sync/atomic`. + +[1.2.0]: https://github.com/uber-go/atomic/compare/v1.1.0...v1.2.0 + +## [1.1.0] - 2017-03-10 +### Added +- Add atomic `Float64` type. + +### Changed +- Support new `go.uber.org/atomic` import path. + +[1.1.0]: https://github.com/uber-go/atomic/compare/v1.0.0...v1.1.0 + +## [1.0.0] - 2016-07-18 + +- Initial release. + +[1.0.0]: https://github.com/uber-go/atomic/releases/tag/v1.0.0 diff --git a/v2/vendor/go.uber.org/atomic/LICENSE.txt b/v2/vendor/go.uber.org/atomic/LICENSE.txt new file mode 100644 index 0000000..8765c9f --- /dev/null +++ b/v2/vendor/go.uber.org/atomic/LICENSE.txt @@ -0,0 +1,19 @@ +Copyright (c) 2016 Uber Technologies, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/v2/vendor/go.uber.org/atomic/Makefile b/v2/vendor/go.uber.org/atomic/Makefile new file mode 100644 index 0000000..46c945b --- /dev/null +++ b/v2/vendor/go.uber.org/atomic/Makefile @@ -0,0 +1,79 @@ +# Directory to place `go install`ed binaries into. +export GOBIN ?= $(shell pwd)/bin + +GOLINT = $(GOBIN)/golint +GEN_ATOMICINT = $(GOBIN)/gen-atomicint +GEN_ATOMICWRAPPER = $(GOBIN)/gen-atomicwrapper +STATICCHECK = $(GOBIN)/staticcheck + +GO_FILES ?= $(shell find . '(' -path .git -o -path vendor ')' -prune -o -name '*.go' -print) + +# Also update ignore section in .codecov.yml. +COVER_IGNORE_PKGS = \ + go.uber.org/atomic/internal/gen-atomicint \ + go.uber.org/atomic/internal/gen-atomicwrapper + +.PHONY: build +build: + go build ./... + +.PHONY: test +test: + go test -race ./... + +.PHONY: gofmt +gofmt: + $(eval FMT_LOG := $(shell mktemp -t gofmt.XXXXX)) + gofmt -e -s -l $(GO_FILES) > $(FMT_LOG) || true + @[ ! -s "$(FMT_LOG)" ] || (echo "gofmt failed:" && cat $(FMT_LOG) && false) + +$(GOLINT): + cd tools && go install golang.org/x/lint/golint + +$(STATICCHECK): + cd tools && go install honnef.co/go/tools/cmd/staticcheck + +$(GEN_ATOMICWRAPPER): $(wildcard ./internal/gen-atomicwrapper/*) + go build -o $@ ./internal/gen-atomicwrapper + +$(GEN_ATOMICINT): $(wildcard ./internal/gen-atomicint/*) + go build -o $@ ./internal/gen-atomicint + +.PHONY: golint +golint: $(GOLINT) + $(GOLINT) ./... + +.PHONY: staticcheck +staticcheck: $(STATICCHECK) + $(STATICCHECK) ./... + +.PHONY: lint +lint: gofmt golint staticcheck generatenodirty + +# comma separated list of packages to consider for code coverage. +COVER_PKG = $(shell \ + go list -find ./... | \ + grep -v $(foreach pkg,$(COVER_IGNORE_PKGS),-e "^$(pkg)$$") | \ + paste -sd, -) + +.PHONY: cover +cover: + go test -coverprofile=cover.out -coverpkg $(COVER_PKG) -v ./... + go tool cover -html=cover.out -o cover.html + +.PHONY: generate +generate: $(GEN_ATOMICINT) $(GEN_ATOMICWRAPPER) + go generate ./... + +.PHONY: generatenodirty +generatenodirty: + @[ -z "$$(git status --porcelain)" ] || ( \ + echo "Working tree is dirty. Commit your changes first."; \ + git status; \ + exit 1 ) + @make generate + @status=$$(git status --porcelain); \ + [ -z "$$status" ] || ( \ + echo "Working tree is dirty after `make generate`:"; \ + echo "$$status"; \ + echo "Please ensure that the generated code is up-to-date." ) diff --git a/v2/vendor/go.uber.org/atomic/README.md b/v2/vendor/go.uber.org/atomic/README.md new file mode 100644 index 0000000..96b47a1 --- /dev/null +++ b/v2/vendor/go.uber.org/atomic/README.md @@ -0,0 +1,63 @@ +# atomic [![GoDoc][doc-img]][doc] [![Build Status][ci-img]][ci] [![Coverage Status][cov-img]][cov] [![Go Report Card][reportcard-img]][reportcard] + +Simple wrappers for primitive types to enforce atomic access. + +## Installation + +```shell +$ go get -u go.uber.org/atomic@v1 +``` + +### Legacy Import Path + +As of v1.5.0, the import path `go.uber.org/atomic` is the only supported way +of using this package. If you are using Go modules, this package will fail to +compile with the legacy import path path `github.com/uber-go/atomic`. + +We recommend migrating your code to the new import path but if you're unable +to do so, or if your dependencies are still using the old import path, you +will have to add a `replace` directive to your `go.mod` file downgrading the +legacy import path to an older version. + +``` +replace github.com/uber-go/atomic => github.com/uber-go/atomic v1.4.0 +``` + +You can do so automatically by running the following command. + +```shell +$ go mod edit -replace github.com/uber-go/atomic=github.com/uber-go/atomic@v1.4.0 +``` + +## Usage + +The standard library's `sync/atomic` is powerful, but it's easy to forget which +variables must be accessed atomically. `go.uber.org/atomic` preserves all the +functionality of the standard library, but wraps the primitive types to +provide a safer, more convenient API. + +```go +var atom atomic.Uint32 +atom.Store(42) +atom.Sub(2) +atom.CAS(40, 11) +``` + +See the [documentation][doc] for a complete API specification. + +## Development Status + +Stable. + +--- + +Released under the [MIT License](LICENSE.txt). + +[doc-img]: https://godoc.org/github.com/uber-go/atomic?status.svg +[doc]: https://godoc.org/go.uber.org/atomic +[ci-img]: https://github.com/uber-go/atomic/actions/workflows/go.yml/badge.svg +[ci]: https://github.com/uber-go/atomic/actions/workflows/go.yml +[cov-img]: https://codecov.io/gh/uber-go/atomic/branch/master/graph/badge.svg +[cov]: https://codecov.io/gh/uber-go/atomic +[reportcard-img]: https://goreportcard.com/badge/go.uber.org/atomic +[reportcard]: https://goreportcard.com/report/go.uber.org/atomic diff --git a/v2/vendor/go.uber.org/atomic/bool.go b/v2/vendor/go.uber.org/atomic/bool.go new file mode 100644 index 0000000..f0a2ddd --- /dev/null +++ b/v2/vendor/go.uber.org/atomic/bool.go @@ -0,0 +1,88 @@ +// @generated Code generated by gen-atomicwrapper. + +// Copyright (c) 2020-2023 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package atomic + +import ( + "encoding/json" +) + +// Bool is an atomic type-safe wrapper for bool values. +type Bool struct { + _ nocmp // disallow non-atomic comparison + + v Uint32 +} + +var _zeroBool bool + +// NewBool creates a new Bool. +func NewBool(val bool) *Bool { + x := &Bool{} + if val != _zeroBool { + x.Store(val) + } + return x +} + +// Load atomically loads the wrapped bool. +func (x *Bool) Load() bool { + return truthy(x.v.Load()) +} + +// Store atomically stores the passed bool. +func (x *Bool) Store(val bool) { + x.v.Store(boolToInt(val)) +} + +// CAS is an atomic compare-and-swap for bool values. +// +// Deprecated: Use CompareAndSwap. +func (x *Bool) CAS(old, new bool) (swapped bool) { + return x.CompareAndSwap(old, new) +} + +// CompareAndSwap is an atomic compare-and-swap for bool values. +func (x *Bool) CompareAndSwap(old, new bool) (swapped bool) { + return x.v.CompareAndSwap(boolToInt(old), boolToInt(new)) +} + +// Swap atomically stores the given bool and returns the old +// value. +func (x *Bool) Swap(val bool) (old bool) { + return truthy(x.v.Swap(boolToInt(val))) +} + +// MarshalJSON encodes the wrapped bool into JSON. +func (x *Bool) MarshalJSON() ([]byte, error) { + return json.Marshal(x.Load()) +} + +// UnmarshalJSON decodes a bool from JSON. +func (x *Bool) UnmarshalJSON(b []byte) error { + var v bool + if err := json.Unmarshal(b, &v); err != nil { + return err + } + x.Store(v) + return nil +} diff --git a/v2/vendor/go.uber.org/atomic/bool_ext.go b/v2/vendor/go.uber.org/atomic/bool_ext.go new file mode 100644 index 0000000..a2e60e9 --- /dev/null +++ b/v2/vendor/go.uber.org/atomic/bool_ext.go @@ -0,0 +1,53 @@ +// Copyright (c) 2020 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package atomic + +import ( + "strconv" +) + +//go:generate bin/gen-atomicwrapper -name=Bool -type=bool -wrapped=Uint32 -pack=boolToInt -unpack=truthy -cas -swap -json -file=bool.go + +func truthy(n uint32) bool { + return n == 1 +} + +func boolToInt(b bool) uint32 { + if b { + return 1 + } + return 0 +} + +// Toggle atomically negates the Boolean and returns the previous value. +func (b *Bool) Toggle() (old bool) { + for { + old := b.Load() + if b.CAS(old, !old) { + return old + } + } +} + +// String encodes the wrapped value as a string. +func (b *Bool) String() string { + return strconv.FormatBool(b.Load()) +} diff --git a/v2/vendor/go.uber.org/atomic/doc.go b/v2/vendor/go.uber.org/atomic/doc.go new file mode 100644 index 0000000..ae7390e --- /dev/null +++ b/v2/vendor/go.uber.org/atomic/doc.go @@ -0,0 +1,23 @@ +// Copyright (c) 2020 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +// Package atomic provides simple wrappers around numerics to enforce atomic +// access. +package atomic diff --git a/v2/vendor/go.uber.org/atomic/duration.go b/v2/vendor/go.uber.org/atomic/duration.go new file mode 100644 index 0000000..7c23868 --- /dev/null +++ b/v2/vendor/go.uber.org/atomic/duration.go @@ -0,0 +1,89 @@ +// @generated Code generated by gen-atomicwrapper. + +// Copyright (c) 2020-2023 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package atomic + +import ( + "encoding/json" + "time" +) + +// Duration is an atomic type-safe wrapper for time.Duration values. +type Duration struct { + _ nocmp // disallow non-atomic comparison + + v Int64 +} + +var _zeroDuration time.Duration + +// NewDuration creates a new Duration. +func NewDuration(val time.Duration) *Duration { + x := &Duration{} + if val != _zeroDuration { + x.Store(val) + } + return x +} + +// Load atomically loads the wrapped time.Duration. +func (x *Duration) Load() time.Duration { + return time.Duration(x.v.Load()) +} + +// Store atomically stores the passed time.Duration. +func (x *Duration) Store(val time.Duration) { + x.v.Store(int64(val)) +} + +// CAS is an atomic compare-and-swap for time.Duration values. +// +// Deprecated: Use CompareAndSwap. +func (x *Duration) CAS(old, new time.Duration) (swapped bool) { + return x.CompareAndSwap(old, new) +} + +// CompareAndSwap is an atomic compare-and-swap for time.Duration values. +func (x *Duration) CompareAndSwap(old, new time.Duration) (swapped bool) { + return x.v.CompareAndSwap(int64(old), int64(new)) +} + +// Swap atomically stores the given time.Duration and returns the old +// value. +func (x *Duration) Swap(val time.Duration) (old time.Duration) { + return time.Duration(x.v.Swap(int64(val))) +} + +// MarshalJSON encodes the wrapped time.Duration into JSON. +func (x *Duration) MarshalJSON() ([]byte, error) { + return json.Marshal(x.Load()) +} + +// UnmarshalJSON decodes a time.Duration from JSON. +func (x *Duration) UnmarshalJSON(b []byte) error { + var v time.Duration + if err := json.Unmarshal(b, &v); err != nil { + return err + } + x.Store(v) + return nil +} diff --git a/v2/vendor/go.uber.org/atomic/duration_ext.go b/v2/vendor/go.uber.org/atomic/duration_ext.go new file mode 100644 index 0000000..4c18b0a --- /dev/null +++ b/v2/vendor/go.uber.org/atomic/duration_ext.go @@ -0,0 +1,40 @@ +// Copyright (c) 2020 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package atomic + +import "time" + +//go:generate bin/gen-atomicwrapper -name=Duration -type=time.Duration -wrapped=Int64 -pack=int64 -unpack=time.Duration -cas -swap -json -imports time -file=duration.go + +// Add atomically adds to the wrapped time.Duration and returns the new value. +func (d *Duration) Add(delta time.Duration) time.Duration { + return time.Duration(d.v.Add(int64(delta))) +} + +// Sub atomically subtracts from the wrapped time.Duration and returns the new value. +func (d *Duration) Sub(delta time.Duration) time.Duration { + return time.Duration(d.v.Sub(int64(delta))) +} + +// String encodes the wrapped value as a string. +func (d *Duration) String() string { + return d.Load().String() +} diff --git a/v2/vendor/go.uber.org/atomic/error.go b/v2/vendor/go.uber.org/atomic/error.go new file mode 100644 index 0000000..b7e3f12 --- /dev/null +++ b/v2/vendor/go.uber.org/atomic/error.go @@ -0,0 +1,72 @@ +// @generated Code generated by gen-atomicwrapper. + +// Copyright (c) 2020-2023 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package atomic + +// Error is an atomic type-safe wrapper for error values. +type Error struct { + _ nocmp // disallow non-atomic comparison + + v Value +} + +var _zeroError error + +// NewError creates a new Error. +func NewError(val error) *Error { + x := &Error{} + if val != _zeroError { + x.Store(val) + } + return x +} + +// Load atomically loads the wrapped error. +func (x *Error) Load() error { + return unpackError(x.v.Load()) +} + +// Store atomically stores the passed error. +func (x *Error) Store(val error) { + x.v.Store(packError(val)) +} + +// CompareAndSwap is an atomic compare-and-swap for error values. +func (x *Error) CompareAndSwap(old, new error) (swapped bool) { + if x.v.CompareAndSwap(packError(old), packError(new)) { + return true + } + + if old == _zeroError { + // If the old value is the empty value, then it's possible the + // underlying Value hasn't been set and is nil, so retry with nil. + return x.v.CompareAndSwap(nil, packError(new)) + } + + return false +} + +// Swap atomically stores the given error and returns the old +// value. +func (x *Error) Swap(val error) (old error) { + return unpackError(x.v.Swap(packError(val))) +} diff --git a/v2/vendor/go.uber.org/atomic/error_ext.go b/v2/vendor/go.uber.org/atomic/error_ext.go new file mode 100644 index 0000000..d31fb63 --- /dev/null +++ b/v2/vendor/go.uber.org/atomic/error_ext.go @@ -0,0 +1,39 @@ +// Copyright (c) 2020-2022 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package atomic + +// atomic.Value panics on nil inputs, or if the underlying type changes. +// Stabilize by always storing a custom struct that we control. + +//go:generate bin/gen-atomicwrapper -name=Error -type=error -wrapped=Value -pack=packError -unpack=unpackError -compareandswap -swap -file=error.go + +type packedError struct{ Value error } + +func packError(v error) interface{} { + return packedError{v} +} + +func unpackError(v interface{}) error { + if err, ok := v.(packedError); ok { + return err.Value + } + return nil +} diff --git a/v2/vendor/go.uber.org/atomic/float32.go b/v2/vendor/go.uber.org/atomic/float32.go new file mode 100644 index 0000000..62c3633 --- /dev/null +++ b/v2/vendor/go.uber.org/atomic/float32.go @@ -0,0 +1,77 @@ +// @generated Code generated by gen-atomicwrapper. + +// Copyright (c) 2020-2023 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package atomic + +import ( + "encoding/json" + "math" +) + +// Float32 is an atomic type-safe wrapper for float32 values. +type Float32 struct { + _ nocmp // disallow non-atomic comparison + + v Uint32 +} + +var _zeroFloat32 float32 + +// NewFloat32 creates a new Float32. +func NewFloat32(val float32) *Float32 { + x := &Float32{} + if val != _zeroFloat32 { + x.Store(val) + } + return x +} + +// Load atomically loads the wrapped float32. +func (x *Float32) Load() float32 { + return math.Float32frombits(x.v.Load()) +} + +// Store atomically stores the passed float32. +func (x *Float32) Store(val float32) { + x.v.Store(math.Float32bits(val)) +} + +// Swap atomically stores the given float32 and returns the old +// value. +func (x *Float32) Swap(val float32) (old float32) { + return math.Float32frombits(x.v.Swap(math.Float32bits(val))) +} + +// MarshalJSON encodes the wrapped float32 into JSON. +func (x *Float32) MarshalJSON() ([]byte, error) { + return json.Marshal(x.Load()) +} + +// UnmarshalJSON decodes a float32 from JSON. +func (x *Float32) UnmarshalJSON(b []byte) error { + var v float32 + if err := json.Unmarshal(b, &v); err != nil { + return err + } + x.Store(v) + return nil +} diff --git a/v2/vendor/go.uber.org/atomic/float32_ext.go b/v2/vendor/go.uber.org/atomic/float32_ext.go new file mode 100644 index 0000000..b0cd8d9 --- /dev/null +++ b/v2/vendor/go.uber.org/atomic/float32_ext.go @@ -0,0 +1,76 @@ +// Copyright (c) 2020-2022 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package atomic + +import ( + "math" + "strconv" +) + +//go:generate bin/gen-atomicwrapper -name=Float32 -type=float32 -wrapped=Uint32 -pack=math.Float32bits -unpack=math.Float32frombits -swap -json -imports math -file=float32.go + +// Add atomically adds to the wrapped float32 and returns the new value. +func (f *Float32) Add(delta float32) float32 { + for { + old := f.Load() + new := old + delta + if f.CAS(old, new) { + return new + } + } +} + +// Sub atomically subtracts from the wrapped float32 and returns the new value. +func (f *Float32) Sub(delta float32) float32 { + return f.Add(-delta) +} + +// CAS is an atomic compare-and-swap for float32 values. +// +// Deprecated: Use CompareAndSwap +func (f *Float32) CAS(old, new float32) (swapped bool) { + return f.CompareAndSwap(old, new) +} + +// CompareAndSwap is an atomic compare-and-swap for float32 values. +// +// Note: CompareAndSwap handles NaN incorrectly. NaN != NaN using Go's inbuilt operators +// but CompareAndSwap allows a stored NaN to compare equal to a passed in NaN. +// This avoids typical CompareAndSwap loops from blocking forever, e.g., +// +// for { +// old := atom.Load() +// new = f(old) +// if atom.CompareAndSwap(old, new) { +// break +// } +// } +// +// If CompareAndSwap did not match NaN to match, then the above would loop forever. +func (f *Float32) CompareAndSwap(old, new float32) (swapped bool) { + return f.v.CompareAndSwap(math.Float32bits(old), math.Float32bits(new)) +} + +// String encodes the wrapped value as a string. +func (f *Float32) String() string { + // 'g' is the behavior for floats with %v. + return strconv.FormatFloat(float64(f.Load()), 'g', -1, 32) +} diff --git a/v2/vendor/go.uber.org/atomic/float64.go b/v2/vendor/go.uber.org/atomic/float64.go new file mode 100644 index 0000000..5bc11ca --- /dev/null +++ b/v2/vendor/go.uber.org/atomic/float64.go @@ -0,0 +1,77 @@ +// @generated Code generated by gen-atomicwrapper. + +// Copyright (c) 2020-2023 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package atomic + +import ( + "encoding/json" + "math" +) + +// Float64 is an atomic type-safe wrapper for float64 values. +type Float64 struct { + _ nocmp // disallow non-atomic comparison + + v Uint64 +} + +var _zeroFloat64 float64 + +// NewFloat64 creates a new Float64. +func NewFloat64(val float64) *Float64 { + x := &Float64{} + if val != _zeroFloat64 { + x.Store(val) + } + return x +} + +// Load atomically loads the wrapped float64. +func (x *Float64) Load() float64 { + return math.Float64frombits(x.v.Load()) +} + +// Store atomically stores the passed float64. +func (x *Float64) Store(val float64) { + x.v.Store(math.Float64bits(val)) +} + +// Swap atomically stores the given float64 and returns the old +// value. +func (x *Float64) Swap(val float64) (old float64) { + return math.Float64frombits(x.v.Swap(math.Float64bits(val))) +} + +// MarshalJSON encodes the wrapped float64 into JSON. +func (x *Float64) MarshalJSON() ([]byte, error) { + return json.Marshal(x.Load()) +} + +// UnmarshalJSON decodes a float64 from JSON. +func (x *Float64) UnmarshalJSON(b []byte) error { + var v float64 + if err := json.Unmarshal(b, &v); err != nil { + return err + } + x.Store(v) + return nil +} diff --git a/v2/vendor/go.uber.org/atomic/float64_ext.go b/v2/vendor/go.uber.org/atomic/float64_ext.go new file mode 100644 index 0000000..48c52b0 --- /dev/null +++ b/v2/vendor/go.uber.org/atomic/float64_ext.go @@ -0,0 +1,76 @@ +// Copyright (c) 2020-2022 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package atomic + +import ( + "math" + "strconv" +) + +//go:generate bin/gen-atomicwrapper -name=Float64 -type=float64 -wrapped=Uint64 -pack=math.Float64bits -unpack=math.Float64frombits -swap -json -imports math -file=float64.go + +// Add atomically adds to the wrapped float64 and returns the new value. +func (f *Float64) Add(delta float64) float64 { + for { + old := f.Load() + new := old + delta + if f.CAS(old, new) { + return new + } + } +} + +// Sub atomically subtracts from the wrapped float64 and returns the new value. +func (f *Float64) Sub(delta float64) float64 { + return f.Add(-delta) +} + +// CAS is an atomic compare-and-swap for float64 values. +// +// Deprecated: Use CompareAndSwap +func (f *Float64) CAS(old, new float64) (swapped bool) { + return f.CompareAndSwap(old, new) +} + +// CompareAndSwap is an atomic compare-and-swap for float64 values. +// +// Note: CompareAndSwap handles NaN incorrectly. NaN != NaN using Go's inbuilt operators +// but CompareAndSwap allows a stored NaN to compare equal to a passed in NaN. +// This avoids typical CompareAndSwap loops from blocking forever, e.g., +// +// for { +// old := atom.Load() +// new = f(old) +// if atom.CompareAndSwap(old, new) { +// break +// } +// } +// +// If CompareAndSwap did not match NaN to match, then the above would loop forever. +func (f *Float64) CompareAndSwap(old, new float64) (swapped bool) { + return f.v.CompareAndSwap(math.Float64bits(old), math.Float64bits(new)) +} + +// String encodes the wrapped value as a string. +func (f *Float64) String() string { + // 'g' is the behavior for floats with %v. + return strconv.FormatFloat(f.Load(), 'g', -1, 64) +} diff --git a/v2/vendor/go.uber.org/atomic/gen.go b/v2/vendor/go.uber.org/atomic/gen.go new file mode 100644 index 0000000..1e9ef4f --- /dev/null +++ b/v2/vendor/go.uber.org/atomic/gen.go @@ -0,0 +1,27 @@ +// Copyright (c) 2020 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package atomic + +//go:generate bin/gen-atomicint -name=Int32 -wrapped=int32 -file=int32.go +//go:generate bin/gen-atomicint -name=Int64 -wrapped=int64 -file=int64.go +//go:generate bin/gen-atomicint -name=Uint32 -wrapped=uint32 -unsigned -file=uint32.go +//go:generate bin/gen-atomicint -name=Uint64 -wrapped=uint64 -unsigned -file=uint64.go +//go:generate bin/gen-atomicint -name=Uintptr -wrapped=uintptr -unsigned -file=uintptr.go diff --git a/v2/vendor/go.uber.org/atomic/int32.go b/v2/vendor/go.uber.org/atomic/int32.go new file mode 100644 index 0000000..5320eac --- /dev/null +++ b/v2/vendor/go.uber.org/atomic/int32.go @@ -0,0 +1,109 @@ +// @generated Code generated by gen-atomicint. + +// Copyright (c) 2020-2023 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package atomic + +import ( + "encoding/json" + "strconv" + "sync/atomic" +) + +// Int32 is an atomic wrapper around int32. +type Int32 struct { + _ nocmp // disallow non-atomic comparison + + v int32 +} + +// NewInt32 creates a new Int32. +func NewInt32(val int32) *Int32 { + return &Int32{v: val} +} + +// Load atomically loads the wrapped value. +func (i *Int32) Load() int32 { + return atomic.LoadInt32(&i.v) +} + +// Add atomically adds to the wrapped int32 and returns the new value. +func (i *Int32) Add(delta int32) int32 { + return atomic.AddInt32(&i.v, delta) +} + +// Sub atomically subtracts from the wrapped int32 and returns the new value. +func (i *Int32) Sub(delta int32) int32 { + return atomic.AddInt32(&i.v, -delta) +} + +// Inc atomically increments the wrapped int32 and returns the new value. +func (i *Int32) Inc() int32 { + return i.Add(1) +} + +// Dec atomically decrements the wrapped int32 and returns the new value. +func (i *Int32) Dec() int32 { + return i.Sub(1) +} + +// CAS is an atomic compare-and-swap. +// +// Deprecated: Use CompareAndSwap. +func (i *Int32) CAS(old, new int32) (swapped bool) { + return i.CompareAndSwap(old, new) +} + +// CompareAndSwap is an atomic compare-and-swap. +func (i *Int32) CompareAndSwap(old, new int32) (swapped bool) { + return atomic.CompareAndSwapInt32(&i.v, old, new) +} + +// Store atomically stores the passed value. +func (i *Int32) Store(val int32) { + atomic.StoreInt32(&i.v, val) +} + +// Swap atomically swaps the wrapped int32 and returns the old value. +func (i *Int32) Swap(val int32) (old int32) { + return atomic.SwapInt32(&i.v, val) +} + +// MarshalJSON encodes the wrapped int32 into JSON. +func (i *Int32) MarshalJSON() ([]byte, error) { + return json.Marshal(i.Load()) +} + +// UnmarshalJSON decodes JSON into the wrapped int32. +func (i *Int32) UnmarshalJSON(b []byte) error { + var v int32 + if err := json.Unmarshal(b, &v); err != nil { + return err + } + i.Store(v) + return nil +} + +// String encodes the wrapped value as a string. +func (i *Int32) String() string { + v := i.Load() + return strconv.FormatInt(int64(v), 10) +} diff --git a/v2/vendor/go.uber.org/atomic/int64.go b/v2/vendor/go.uber.org/atomic/int64.go new file mode 100644 index 0000000..460821d --- /dev/null +++ b/v2/vendor/go.uber.org/atomic/int64.go @@ -0,0 +1,109 @@ +// @generated Code generated by gen-atomicint. + +// Copyright (c) 2020-2023 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package atomic + +import ( + "encoding/json" + "strconv" + "sync/atomic" +) + +// Int64 is an atomic wrapper around int64. +type Int64 struct { + _ nocmp // disallow non-atomic comparison + + v int64 +} + +// NewInt64 creates a new Int64. +func NewInt64(val int64) *Int64 { + return &Int64{v: val} +} + +// Load atomically loads the wrapped value. +func (i *Int64) Load() int64 { + return atomic.LoadInt64(&i.v) +} + +// Add atomically adds to the wrapped int64 and returns the new value. +func (i *Int64) Add(delta int64) int64 { + return atomic.AddInt64(&i.v, delta) +} + +// Sub atomically subtracts from the wrapped int64 and returns the new value. +func (i *Int64) Sub(delta int64) int64 { + return atomic.AddInt64(&i.v, -delta) +} + +// Inc atomically increments the wrapped int64 and returns the new value. +func (i *Int64) Inc() int64 { + return i.Add(1) +} + +// Dec atomically decrements the wrapped int64 and returns the new value. +func (i *Int64) Dec() int64 { + return i.Sub(1) +} + +// CAS is an atomic compare-and-swap. +// +// Deprecated: Use CompareAndSwap. +func (i *Int64) CAS(old, new int64) (swapped bool) { + return i.CompareAndSwap(old, new) +} + +// CompareAndSwap is an atomic compare-and-swap. +func (i *Int64) CompareAndSwap(old, new int64) (swapped bool) { + return atomic.CompareAndSwapInt64(&i.v, old, new) +} + +// Store atomically stores the passed value. +func (i *Int64) Store(val int64) { + atomic.StoreInt64(&i.v, val) +} + +// Swap atomically swaps the wrapped int64 and returns the old value. +func (i *Int64) Swap(val int64) (old int64) { + return atomic.SwapInt64(&i.v, val) +} + +// MarshalJSON encodes the wrapped int64 into JSON. +func (i *Int64) MarshalJSON() ([]byte, error) { + return json.Marshal(i.Load()) +} + +// UnmarshalJSON decodes JSON into the wrapped int64. +func (i *Int64) UnmarshalJSON(b []byte) error { + var v int64 + if err := json.Unmarshal(b, &v); err != nil { + return err + } + i.Store(v) + return nil +} + +// String encodes the wrapped value as a string. +func (i *Int64) String() string { + v := i.Load() + return strconv.FormatInt(int64(v), 10) +} diff --git a/v2/vendor/go.uber.org/atomic/nocmp.go b/v2/vendor/go.uber.org/atomic/nocmp.go new file mode 100644 index 0000000..54b7417 --- /dev/null +++ b/v2/vendor/go.uber.org/atomic/nocmp.go @@ -0,0 +1,35 @@ +// Copyright (c) 2020 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package atomic + +// nocmp is an uncomparable struct. Embed this inside another struct to make +// it uncomparable. +// +// type Foo struct { +// nocmp +// // ... +// } +// +// This DOES NOT: +// +// - Disallow shallow copies of structs +// - Disallow comparison of pointers to uncomparable structs +type nocmp [0]func() diff --git a/v2/vendor/go.uber.org/atomic/pointer_go118.go b/v2/vendor/go.uber.org/atomic/pointer_go118.go new file mode 100644 index 0000000..1fb6c03 --- /dev/null +++ b/v2/vendor/go.uber.org/atomic/pointer_go118.go @@ -0,0 +1,31 @@ +// Copyright (c) 2022 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +//go:build go1.18 +// +build go1.18 + +package atomic + +import "fmt" + +// String returns a human readable representation of a Pointer's underlying value. +func (p *Pointer[T]) String() string { + return fmt.Sprint(p.Load()) +} diff --git a/v2/vendor/go.uber.org/atomic/pointer_go118_pre119.go b/v2/vendor/go.uber.org/atomic/pointer_go118_pre119.go new file mode 100644 index 0000000..e0f47db --- /dev/null +++ b/v2/vendor/go.uber.org/atomic/pointer_go118_pre119.go @@ -0,0 +1,60 @@ +// Copyright (c) 2022 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +//go:build go1.18 && !go1.19 +// +build go1.18,!go1.19 + +package atomic + +import "unsafe" + +type Pointer[T any] struct { + _ nocmp // disallow non-atomic comparison + p UnsafePointer +} + +// NewPointer creates a new Pointer. +func NewPointer[T any](v *T) *Pointer[T] { + var p Pointer[T] + if v != nil { + p.p.Store(unsafe.Pointer(v)) + } + return &p +} + +// Load atomically loads the wrapped value. +func (p *Pointer[T]) Load() *T { + return (*T)(p.p.Load()) +} + +// Store atomically stores the passed value. +func (p *Pointer[T]) Store(val *T) { + p.p.Store(unsafe.Pointer(val)) +} + +// Swap atomically swaps the wrapped pointer and returns the old value. +func (p *Pointer[T]) Swap(val *T) (old *T) { + return (*T)(p.p.Swap(unsafe.Pointer(val))) +} + +// CompareAndSwap is an atomic compare-and-swap. +func (p *Pointer[T]) CompareAndSwap(old, new *T) (swapped bool) { + return p.p.CompareAndSwap(unsafe.Pointer(old), unsafe.Pointer(new)) +} diff --git a/v2/vendor/go.uber.org/atomic/pointer_go119.go b/v2/vendor/go.uber.org/atomic/pointer_go119.go new file mode 100644 index 0000000..6726f17 --- /dev/null +++ b/v2/vendor/go.uber.org/atomic/pointer_go119.go @@ -0,0 +1,61 @@ +// Copyright (c) 2022 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +//go:build go1.19 +// +build go1.19 + +package atomic + +import "sync/atomic" + +// Pointer is an atomic pointer of type *T. +type Pointer[T any] struct { + _ nocmp // disallow non-atomic comparison + p atomic.Pointer[T] +} + +// NewPointer creates a new Pointer. +func NewPointer[T any](v *T) *Pointer[T] { + var p Pointer[T] + if v != nil { + p.p.Store(v) + } + return &p +} + +// Load atomically loads the wrapped value. +func (p *Pointer[T]) Load() *T { + return p.p.Load() +} + +// Store atomically stores the passed value. +func (p *Pointer[T]) Store(val *T) { + p.p.Store(val) +} + +// Swap atomically swaps the wrapped pointer and returns the old value. +func (p *Pointer[T]) Swap(val *T) (old *T) { + return p.p.Swap(val) +} + +// CompareAndSwap is an atomic compare-and-swap. +func (p *Pointer[T]) CompareAndSwap(old, new *T) (swapped bool) { + return p.p.CompareAndSwap(old, new) +} diff --git a/v2/vendor/go.uber.org/atomic/string.go b/v2/vendor/go.uber.org/atomic/string.go new file mode 100644 index 0000000..061466c --- /dev/null +++ b/v2/vendor/go.uber.org/atomic/string.go @@ -0,0 +1,72 @@ +// @generated Code generated by gen-atomicwrapper. + +// Copyright (c) 2020-2023 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package atomic + +// String is an atomic type-safe wrapper for string values. +type String struct { + _ nocmp // disallow non-atomic comparison + + v Value +} + +var _zeroString string + +// NewString creates a new String. +func NewString(val string) *String { + x := &String{} + if val != _zeroString { + x.Store(val) + } + return x +} + +// Load atomically loads the wrapped string. +func (x *String) Load() string { + return unpackString(x.v.Load()) +} + +// Store atomically stores the passed string. +func (x *String) Store(val string) { + x.v.Store(packString(val)) +} + +// CompareAndSwap is an atomic compare-and-swap for string values. +func (x *String) CompareAndSwap(old, new string) (swapped bool) { + if x.v.CompareAndSwap(packString(old), packString(new)) { + return true + } + + if old == _zeroString { + // If the old value is the empty value, then it's possible the + // underlying Value hasn't been set and is nil, so retry with nil. + return x.v.CompareAndSwap(nil, packString(new)) + } + + return false +} + +// Swap atomically stores the given string and returns the old +// value. +func (x *String) Swap(val string) (old string) { + return unpackString(x.v.Swap(packString(val))) +} diff --git a/v2/vendor/go.uber.org/atomic/string_ext.go b/v2/vendor/go.uber.org/atomic/string_ext.go new file mode 100644 index 0000000..019109c --- /dev/null +++ b/v2/vendor/go.uber.org/atomic/string_ext.go @@ -0,0 +1,54 @@ +// Copyright (c) 2020-2023 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package atomic + +//go:generate bin/gen-atomicwrapper -name=String -type=string -wrapped Value -pack packString -unpack unpackString -compareandswap -swap -file=string.go + +func packString(s string) interface{} { + return s +} + +func unpackString(v interface{}) string { + if s, ok := v.(string); ok { + return s + } + return "" +} + +// String returns the wrapped value. +func (s *String) String() string { + return s.Load() +} + +// MarshalText encodes the wrapped string into a textual form. +// +// This makes it encodable as JSON, YAML, XML, and more. +func (s *String) MarshalText() ([]byte, error) { + return []byte(s.Load()), nil +} + +// UnmarshalText decodes text and replaces the wrapped string with it. +// +// This makes it decodable from JSON, YAML, XML, and more. +func (s *String) UnmarshalText(b []byte) error { + s.Store(string(b)) + return nil +} diff --git a/v2/vendor/go.uber.org/atomic/time.go b/v2/vendor/go.uber.org/atomic/time.go new file mode 100644 index 0000000..cc2a230 --- /dev/null +++ b/v2/vendor/go.uber.org/atomic/time.go @@ -0,0 +1,55 @@ +// @generated Code generated by gen-atomicwrapper. + +// Copyright (c) 2020-2023 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package atomic + +import ( + "time" +) + +// Time is an atomic type-safe wrapper for time.Time values. +type Time struct { + _ nocmp // disallow non-atomic comparison + + v Value +} + +var _zeroTime time.Time + +// NewTime creates a new Time. +func NewTime(val time.Time) *Time { + x := &Time{} + if val != _zeroTime { + x.Store(val) + } + return x +} + +// Load atomically loads the wrapped time.Time. +func (x *Time) Load() time.Time { + return unpackTime(x.v.Load()) +} + +// Store atomically stores the passed time.Time. +func (x *Time) Store(val time.Time) { + x.v.Store(packTime(val)) +} diff --git a/v2/vendor/go.uber.org/atomic/time_ext.go b/v2/vendor/go.uber.org/atomic/time_ext.go new file mode 100644 index 0000000..1e3dc97 --- /dev/null +++ b/v2/vendor/go.uber.org/atomic/time_ext.go @@ -0,0 +1,36 @@ +// Copyright (c) 2021 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package atomic + +import "time" + +//go:generate bin/gen-atomicwrapper -name=Time -type=time.Time -wrapped=Value -pack=packTime -unpack=unpackTime -imports time -file=time.go + +func packTime(t time.Time) interface{} { + return t +} + +func unpackTime(v interface{}) time.Time { + if t, ok := v.(time.Time); ok { + return t + } + return time.Time{} +} diff --git a/v2/vendor/go.uber.org/atomic/uint32.go b/v2/vendor/go.uber.org/atomic/uint32.go new file mode 100644 index 0000000..4adc294 --- /dev/null +++ b/v2/vendor/go.uber.org/atomic/uint32.go @@ -0,0 +1,109 @@ +// @generated Code generated by gen-atomicint. + +// Copyright (c) 2020-2023 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package atomic + +import ( + "encoding/json" + "strconv" + "sync/atomic" +) + +// Uint32 is an atomic wrapper around uint32. +type Uint32 struct { + _ nocmp // disallow non-atomic comparison + + v uint32 +} + +// NewUint32 creates a new Uint32. +func NewUint32(val uint32) *Uint32 { + return &Uint32{v: val} +} + +// Load atomically loads the wrapped value. +func (i *Uint32) Load() uint32 { + return atomic.LoadUint32(&i.v) +} + +// Add atomically adds to the wrapped uint32 and returns the new value. +func (i *Uint32) Add(delta uint32) uint32 { + return atomic.AddUint32(&i.v, delta) +} + +// Sub atomically subtracts from the wrapped uint32 and returns the new value. +func (i *Uint32) Sub(delta uint32) uint32 { + return atomic.AddUint32(&i.v, ^(delta - 1)) +} + +// Inc atomically increments the wrapped uint32 and returns the new value. +func (i *Uint32) Inc() uint32 { + return i.Add(1) +} + +// Dec atomically decrements the wrapped uint32 and returns the new value. +func (i *Uint32) Dec() uint32 { + return i.Sub(1) +} + +// CAS is an atomic compare-and-swap. +// +// Deprecated: Use CompareAndSwap. +func (i *Uint32) CAS(old, new uint32) (swapped bool) { + return i.CompareAndSwap(old, new) +} + +// CompareAndSwap is an atomic compare-and-swap. +func (i *Uint32) CompareAndSwap(old, new uint32) (swapped bool) { + return atomic.CompareAndSwapUint32(&i.v, old, new) +} + +// Store atomically stores the passed value. +func (i *Uint32) Store(val uint32) { + atomic.StoreUint32(&i.v, val) +} + +// Swap atomically swaps the wrapped uint32 and returns the old value. +func (i *Uint32) Swap(val uint32) (old uint32) { + return atomic.SwapUint32(&i.v, val) +} + +// MarshalJSON encodes the wrapped uint32 into JSON. +func (i *Uint32) MarshalJSON() ([]byte, error) { + return json.Marshal(i.Load()) +} + +// UnmarshalJSON decodes JSON into the wrapped uint32. +func (i *Uint32) UnmarshalJSON(b []byte) error { + var v uint32 + if err := json.Unmarshal(b, &v); err != nil { + return err + } + i.Store(v) + return nil +} + +// String encodes the wrapped value as a string. +func (i *Uint32) String() string { + v := i.Load() + return strconv.FormatUint(uint64(v), 10) +} diff --git a/v2/vendor/go.uber.org/atomic/uint64.go b/v2/vendor/go.uber.org/atomic/uint64.go new file mode 100644 index 0000000..0e2eddb --- /dev/null +++ b/v2/vendor/go.uber.org/atomic/uint64.go @@ -0,0 +1,109 @@ +// @generated Code generated by gen-atomicint. + +// Copyright (c) 2020-2023 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package atomic + +import ( + "encoding/json" + "strconv" + "sync/atomic" +) + +// Uint64 is an atomic wrapper around uint64. +type Uint64 struct { + _ nocmp // disallow non-atomic comparison + + v uint64 +} + +// NewUint64 creates a new Uint64. +func NewUint64(val uint64) *Uint64 { + return &Uint64{v: val} +} + +// Load atomically loads the wrapped value. +func (i *Uint64) Load() uint64 { + return atomic.LoadUint64(&i.v) +} + +// Add atomically adds to the wrapped uint64 and returns the new value. +func (i *Uint64) Add(delta uint64) uint64 { + return atomic.AddUint64(&i.v, delta) +} + +// Sub atomically subtracts from the wrapped uint64 and returns the new value. +func (i *Uint64) Sub(delta uint64) uint64 { + return atomic.AddUint64(&i.v, ^(delta - 1)) +} + +// Inc atomically increments the wrapped uint64 and returns the new value. +func (i *Uint64) Inc() uint64 { + return i.Add(1) +} + +// Dec atomically decrements the wrapped uint64 and returns the new value. +func (i *Uint64) Dec() uint64 { + return i.Sub(1) +} + +// CAS is an atomic compare-and-swap. +// +// Deprecated: Use CompareAndSwap. +func (i *Uint64) CAS(old, new uint64) (swapped bool) { + return i.CompareAndSwap(old, new) +} + +// CompareAndSwap is an atomic compare-and-swap. +func (i *Uint64) CompareAndSwap(old, new uint64) (swapped bool) { + return atomic.CompareAndSwapUint64(&i.v, old, new) +} + +// Store atomically stores the passed value. +func (i *Uint64) Store(val uint64) { + atomic.StoreUint64(&i.v, val) +} + +// Swap atomically swaps the wrapped uint64 and returns the old value. +func (i *Uint64) Swap(val uint64) (old uint64) { + return atomic.SwapUint64(&i.v, val) +} + +// MarshalJSON encodes the wrapped uint64 into JSON. +func (i *Uint64) MarshalJSON() ([]byte, error) { + return json.Marshal(i.Load()) +} + +// UnmarshalJSON decodes JSON into the wrapped uint64. +func (i *Uint64) UnmarshalJSON(b []byte) error { + var v uint64 + if err := json.Unmarshal(b, &v); err != nil { + return err + } + i.Store(v) + return nil +} + +// String encodes the wrapped value as a string. +func (i *Uint64) String() string { + v := i.Load() + return strconv.FormatUint(uint64(v), 10) +} diff --git a/v2/vendor/go.uber.org/atomic/uintptr.go b/v2/vendor/go.uber.org/atomic/uintptr.go new file mode 100644 index 0000000..7d5b000 --- /dev/null +++ b/v2/vendor/go.uber.org/atomic/uintptr.go @@ -0,0 +1,109 @@ +// @generated Code generated by gen-atomicint. + +// Copyright (c) 2020-2023 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package atomic + +import ( + "encoding/json" + "strconv" + "sync/atomic" +) + +// Uintptr is an atomic wrapper around uintptr. +type Uintptr struct { + _ nocmp // disallow non-atomic comparison + + v uintptr +} + +// NewUintptr creates a new Uintptr. +func NewUintptr(val uintptr) *Uintptr { + return &Uintptr{v: val} +} + +// Load atomically loads the wrapped value. +func (i *Uintptr) Load() uintptr { + return atomic.LoadUintptr(&i.v) +} + +// Add atomically adds to the wrapped uintptr and returns the new value. +func (i *Uintptr) Add(delta uintptr) uintptr { + return atomic.AddUintptr(&i.v, delta) +} + +// Sub atomically subtracts from the wrapped uintptr and returns the new value. +func (i *Uintptr) Sub(delta uintptr) uintptr { + return atomic.AddUintptr(&i.v, ^(delta - 1)) +} + +// Inc atomically increments the wrapped uintptr and returns the new value. +func (i *Uintptr) Inc() uintptr { + return i.Add(1) +} + +// Dec atomically decrements the wrapped uintptr and returns the new value. +func (i *Uintptr) Dec() uintptr { + return i.Sub(1) +} + +// CAS is an atomic compare-and-swap. +// +// Deprecated: Use CompareAndSwap. +func (i *Uintptr) CAS(old, new uintptr) (swapped bool) { + return i.CompareAndSwap(old, new) +} + +// CompareAndSwap is an atomic compare-and-swap. +func (i *Uintptr) CompareAndSwap(old, new uintptr) (swapped bool) { + return atomic.CompareAndSwapUintptr(&i.v, old, new) +} + +// Store atomically stores the passed value. +func (i *Uintptr) Store(val uintptr) { + atomic.StoreUintptr(&i.v, val) +} + +// Swap atomically swaps the wrapped uintptr and returns the old value. +func (i *Uintptr) Swap(val uintptr) (old uintptr) { + return atomic.SwapUintptr(&i.v, val) +} + +// MarshalJSON encodes the wrapped uintptr into JSON. +func (i *Uintptr) MarshalJSON() ([]byte, error) { + return json.Marshal(i.Load()) +} + +// UnmarshalJSON decodes JSON into the wrapped uintptr. +func (i *Uintptr) UnmarshalJSON(b []byte) error { + var v uintptr + if err := json.Unmarshal(b, &v); err != nil { + return err + } + i.Store(v) + return nil +} + +// String encodes the wrapped value as a string. +func (i *Uintptr) String() string { + v := i.Load() + return strconv.FormatUint(uint64(v), 10) +} diff --git a/v2/vendor/go.uber.org/atomic/unsafe_pointer.go b/v2/vendor/go.uber.org/atomic/unsafe_pointer.go new file mode 100644 index 0000000..34868ba --- /dev/null +++ b/v2/vendor/go.uber.org/atomic/unsafe_pointer.go @@ -0,0 +1,65 @@ +// Copyright (c) 2021-2022 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package atomic + +import ( + "sync/atomic" + "unsafe" +) + +// UnsafePointer is an atomic wrapper around unsafe.Pointer. +type UnsafePointer struct { + _ nocmp // disallow non-atomic comparison + + v unsafe.Pointer +} + +// NewUnsafePointer creates a new UnsafePointer. +func NewUnsafePointer(val unsafe.Pointer) *UnsafePointer { + return &UnsafePointer{v: val} +} + +// Load atomically loads the wrapped value. +func (p *UnsafePointer) Load() unsafe.Pointer { + return atomic.LoadPointer(&p.v) +} + +// Store atomically stores the passed value. +func (p *UnsafePointer) Store(val unsafe.Pointer) { + atomic.StorePointer(&p.v, val) +} + +// Swap atomically swaps the wrapped unsafe.Pointer and returns the old value. +func (p *UnsafePointer) Swap(val unsafe.Pointer) (old unsafe.Pointer) { + return atomic.SwapPointer(&p.v, val) +} + +// CAS is an atomic compare-and-swap. +// +// Deprecated: Use CompareAndSwap +func (p *UnsafePointer) CAS(old, new unsafe.Pointer) (swapped bool) { + return p.CompareAndSwap(old, new) +} + +// CompareAndSwap is an atomic compare-and-swap. +func (p *UnsafePointer) CompareAndSwap(old, new unsafe.Pointer) (swapped bool) { + return atomic.CompareAndSwapPointer(&p.v, old, new) +} diff --git a/v2/vendor/go.uber.org/atomic/value.go b/v2/vendor/go.uber.org/atomic/value.go new file mode 100644 index 0000000..52caedb --- /dev/null +++ b/v2/vendor/go.uber.org/atomic/value.go @@ -0,0 +1,31 @@ +// Copyright (c) 2020 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package atomic + +import "sync/atomic" + +// Value shadows the type of the same name from sync/atomic +// https://godoc.org/sync/atomic#Value +type Value struct { + _ nocmp // disallow non-atomic comparison + + atomic.Value +} diff --git a/v2/vendor/modules.txt b/v2/vendor/modules.txt index bd64794..4c5052f 100644 --- a/v2/vendor/modules.txt +++ b/v2/vendor/modules.txt @@ -1,22 +1,41 @@ -# filippo.io/edwards25519 v1.1.0 -## explicit; go 1.20 -filippo.io/edwards25519 -filippo.io/edwards25519/field -# github.com/go-sql-driver/mysql v1.8.1 -## explicit; go 1.18 -github.com/go-sql-driver/mysql -# github.com/xyproto/cookie/v2 v2.2.4 +# github.com/go-mysql-org/go-mysql v1.7.0 +## explicit; go 1.16 +github.com/go-mysql-org/go-mysql/client +github.com/go-mysql-org/go-mysql/driver +github.com/go-mysql-org/go-mysql/mysql +github.com/go-mysql-org/go-mysql/packet +github.com/go-mysql-org/go-mysql/utils +# github.com/google/uuid v1.6.0 +## explicit +github.com/google/uuid +# github.com/pingcap/errors v0.11.5-0.20210425183316-da1aaba5fb63 +## explicit; go 1.14 +github.com/pingcap/errors +# github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726 +## explicit +github.com/siddontang/go/hack +# github.com/siddontang/go-log v0.0.0-20190221022429-1e957dd83bed +## explicit +github.com/siddontang/go-log/log +github.com/siddontang/go-log/loggers +# github.com/xyproto/cookie/v2 v2.2.5 ## explicit; go 1.17 github.com/xyproto/cookie/v2 +# github.com/xyproto/env/v2 v2.2.5 +## explicit; go 1.19 +github.com/xyproto/env/v2 # github.com/xyproto/pinterface v1.5.3 ## explicit; go 1.8 github.com/xyproto/pinterface # github.com/xyproto/randomstring v1.0.5 ## explicit; go 1.17 github.com/xyproto/randomstring -# github.com/xyproto/simplemaria v1.3.2 -## explicit; go 1.19 +# github.com/xyproto/simplemaria v1.3.4 +## explicit; go 1.21 github.com/xyproto/simplemaria +# go.uber.org/atomic v1.11.0 +## explicit; go 1.18 +go.uber.org/atomic # golang.org/x/crypto v0.23.0 ## explicit; go 1.18 golang.org/x/crypto/bcrypt