Replace deprecated go-mysql library (#994)
This commit is contained in:
parent
6e1daf90ee
commit
732a064231
5
go.mod
5
go.mod
@ -4,15 +4,14 @@ go 1.16
|
||||
|
||||
require (
|
||||
github.com/go-ini/ini v1.62.0
|
||||
github.com/go-mysql-org/go-mysql v1.3.0
|
||||
github.com/go-sql-driver/mysql v1.5.0
|
||||
github.com/openark/golib v0.0.0-20210531070646-355f37940af8
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/satori/go.uuid v1.2.0
|
||||
github.com/siddontang/go-mysql v1.1.0
|
||||
github.com/smartystreets/goconvey v1.6.4 // indirect
|
||||
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83
|
||||
golang.org/x/net v0.0.0-20210224082022-3d97a244fca7
|
||||
golang.org/x/text v0.3.5
|
||||
golang.org/x/text v0.3.6
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
|
||||
gopkg.in/ini.v1 v1.62.0 // indirect
|
||||
)
|
||||
|
89
go.sum
89
go.sum
@ -1,32 +1,53 @@
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/cznic/golex v0.0.0-20181122101858-9c343928389c/go.mod h1:+bmmJDNmKlhWNG+gwWCkaBoTy39Fs+bzRxVBzoTQbIc=
|
||||
github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548/go.mod h1:e6NPNENfs9mPDVNRekM7lKScauxd5kXTr1Mfyig6TDM=
|
||||
github.com/cznic/parser v0.0.0-20160622100904-31edd927e5b1/go.mod h1:2B43mz36vGZNZEwkWi8ayRSSUXLfjL8OkbzwW4NcPMM=
|
||||
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/cznic/y v0.0.0-20170802143616-045f81c6662a/go.mod h1:1rk5VM7oSnA4vjp+hrLQ3HWHa+Y4yPCa3/CsJrcNnvs=
|
||||
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-ini/ini v1.62.0 h1:7VJT/ZXjzqSrvtraFp4ONq80hTcRQth1c9ZnQ3uNQvU=
|
||||
github.com/go-ini/ini v1.62.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
|
||||
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-mysql-org/go-mysql v1.3.0 h1:lpNqkwdPzIrYSZGdqt8HIgAXZaK6VxBNfr8f7Z4FgGg=
|
||||
github.com/go-mysql-org/go-mysql v1.3.0/go.mod h1:3lFZKf7l95Qo70+3XB2WpiSf9wu2s3na3geLMaIIrqQ=
|
||||
github.com/go-sql-driver/mysql v1.3.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
|
||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/jmoiron/sqlx v1.3.3/go.mod h1:2BljVx/86SuTyjE+aPYlHCTNvZrnJXghYGpNiXLBMCQ=
|
||||
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
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/openark/golib v0.0.0-20210531070646-355f37940af8 h1:9ciIHNuyFqRWi9NpMNw9sVLB6z1ItpP5ZhTY9Q1xVu4=
|
||||
github.com/openark/golib v0.0.0-20210531070646-355f37940af8/go.mod h1:1jj8x1eDVZxgc/Z4VyamX4qTbAdHPUQA6NeVtCd8Sl8=
|
||||
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 h1:DCJQB8jrHbQ1VVlMFIrbj2ApScNNotVmkSNplu2yUt4=
|
||||
github.com/pingcap/errors v0.11.0/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
|
||||
github.com/pingcap/parser v0.0.0-20190506092653-e336082eb825/go.mod h1:1FNvfp9+J0wvc4kl8eGNh7Rqrxveg15jJoWo/a0uHwA=
|
||||
github.com/pingcap/tipb v0.0.0-20190428032612-535e1abaa330/go.mod h1:RtkHW8WbcNxj8lsbzjaILci01CtYnYbIkQhjyZWrWVI=
|
||||
github.com/pingcap/errors v0.11.5-0.20201029093017-5a7df2af2ac7/go.mod h1:G7x87le1poQzLB/TqvTJI2ILrSgobnq4Ut7luOwvfvI=
|
||||
github.com/pingcap/errors v0.11.5-0.20201126102027-b0a155152ca3 h1:LllgC9eGfqzkfubMgjKIDyZYaa609nNWAyNZtpy2B3M=
|
||||
github.com/pingcap/errors v0.11.5-0.20201126102027-b0a155152ca3/go.mod h1:G7x87le1poQzLB/TqvTJI2ILrSgobnq4Ut7luOwvfvI=
|
||||
github.com/pingcap/log v0.0.0-20200511115504-543df19646ad/go.mod h1:4rbK1p9ILyIfb6hU7OG2CiWSqMXnp3JMbiaVJ6mvoY8=
|
||||
github.com/pingcap/log v0.0.0-20210317133921-96f4fcab92a4/go.mod h1:4rbK1p9ILyIfb6hU7OG2CiWSqMXnp3JMbiaVJ6mvoY8=
|
||||
github.com/pingcap/parser v0.0.0-20210415081931-48e7f467fd74/go.mod h1:xZC8I7bug4GJ5KtHhgAikjTfU4kBv1Sbo3Pf1MZ6lVw=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
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-20190728182440-6a916e37a237/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
|
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24 h1:pntxY8Ary0t43dCZ5dqY4YTJCObLY1kIXl0uzMv+7DE=
|
||||
@ -35,38 +56,76 @@ github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726 h1:xT+JlYxNGqyT+XcU8
|
||||
github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw=
|
||||
github.com/siddontang/go-log v0.0.0-20180807004314-8d05993dda07 h1:oI+RNwuC9jF2g2lP0u0cVEEZrc/AYBCuFdvwrLWM/6Q=
|
||||
github.com/siddontang/go-log v0.0.0-20180807004314-8d05993dda07/go.mod h1:yFdBgwXP24JziuRl2NMUahT7nGLNOKi1SIiFxMttVD4=
|
||||
github.com/siddontang/go-mysql v1.1.0 h1:NfkS1skrPwUd3hsUqhc6jrv24dKTNMANxKRmDsf1fMc=
|
||||
github.com/siddontang/go-mysql v1.1.0/go.mod h1:+W4RCzesQDI11HvIkaDjS8yM36SpAnGNQ7jmTLn5BnU=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
|
||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
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 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
|
||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
||||
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc=
|
||||
go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
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.0.0-20210220033148-5ea612d1eb83 h1:/ZScEX8SfEmUGRHs0gxpqteO5nfNW6axyZbBdw9A12g=
|
||||
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
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-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210224082022-3d97a244fca7 h1:OgUuv8lsRpBibGNbSizVwKWlysjaNzmC9gYMhPVfqFM=
|
||||
golang.org/x/net v0.0.0-20210224082022-3d97a244fca7/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/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-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ=
|
||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
|
||||
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-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/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.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/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU=
|
||||
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright 2016 GitHub Inc.
|
||||
Copyright 2021 GitHub Inc.
|
||||
See https://github.com/github/gh-ost/blob/master/LICENSE
|
||||
*/
|
||||
|
||||
@ -13,8 +13,8 @@ import (
|
||||
"github.com/github/gh-ost/go/mysql"
|
||||
"github.com/github/gh-ost/go/sql"
|
||||
|
||||
gomysql "github.com/siddontang/go-mysql/mysql"
|
||||
"github.com/siddontang/go-mysql/replication"
|
||||
gomysql "github.com/go-mysql-org/go-mysql/mysql"
|
||||
"github.com/go-mysql-org/go-mysql/replication"
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
|
@ -6,9 +6,9 @@ import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
|
||||
. "github.com/go-mysql-org/go-mysql/mysql"
|
||||
"github.com/go-mysql-org/go-mysql/packet"
|
||||
"github.com/pingcap/errors"
|
||||
. "github.com/siddontang/go-mysql/mysql"
|
||||
"github.com/siddontang/go-mysql/packet"
|
||||
)
|
||||
|
||||
const defaultAuthPluginName = AUTH_NATIVE_PASSWORD
|
||||
@ -46,7 +46,7 @@ func (c *Conn) readInitialHandshake() error {
|
||||
pos := 1 + bytes.IndexByte(data[1:], 0x00) + 1
|
||||
|
||||
// connection id length is 4
|
||||
c.connectionID = uint32(binary.LittleEndian.Uint32(data[pos : pos+4]))
|
||||
c.connectionID = binary.LittleEndian.Uint32(data[pos : pos+4])
|
||||
pos += 4
|
||||
|
||||
c.salt = []byte{}
|
||||
@ -106,7 +106,7 @@ func (c *Conn) readInitialHandshake() error {
|
||||
// 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.
|
||||
// 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) {
|
||||
@ -199,7 +199,7 @@ func (c *Conn) writeAuthHandshake() error {
|
||||
|
||||
// Charset [1 byte]
|
||||
// use default collation id 33 here, is utf-8
|
||||
data[12] = byte(DEFAULT_COLLATION_ID)
|
||||
data[12] = DEFAULT_COLLATION_ID
|
||||
|
||||
// SSL Connection Request Packet
|
||||
// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::SSLRequest
|
@ -7,9 +7,9 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
. "github.com/go-mysql-org/go-mysql/mysql"
|
||||
"github.com/go-mysql-org/go-mysql/packet"
|
||||
"github.com/pingcap/errors"
|
||||
. "github.com/siddontang/go-mysql/mysql"
|
||||
"github.com/siddontang/go-mysql/packet"
|
||||
)
|
||||
|
||||
type Conn struct {
|
||||
@ -33,6 +33,9 @@ type Conn struct {
|
||||
connectionID uint32
|
||||
}
|
||||
|
||||
// This function will be called for every row in resultset from ExecuteSelectStreaming.
|
||||
type SelectPerRowCallback func(row []FieldValue) error
|
||||
|
||||
func getNetProto(addr string) string {
|
||||
proto := "tcp"
|
||||
if strings.Contains(addr, "/") {
|
||||
@ -165,6 +168,28 @@ func (c *Conn) Execute(command string, args ...interface{}) (*Result, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// ExecuteSelectStreaming will call perRowCallback for every row in resultset
|
||||
// WITHOUT saving any row data to Result.{Values/RawPkg/RowDatas} fields.
|
||||
//
|
||||
// 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
|
||||
// })
|
||||
//
|
||||
func (c *Conn) ExecuteSelectStreaming(command string, result *Result, perRowCallback SelectPerRowCallback) error {
|
||||
if err := c.writeCommandStr(COM_QUERY, command); err != nil {
|
||||
return errors.Trace(err)
|
||||
}
|
||||
|
||||
return c.readResultStreaming(false, result, perRowCallback)
|
||||
}
|
||||
|
||||
func (c *Conn) Begin() error {
|
||||
_, err := c.exec("BEGIN")
|
||||
return errors.Trace(err)
|
476
vendor/github.com/go-mysql-org/go-mysql/client/pool.go
generated
vendored
Normal file
476
vendor/github.com/go-mysql-org/go-mysql/client/pool.go
generated
vendored
Normal file
@ -0,0 +1,476 @@
|
||||
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.SetWriteDeadline(deadline)
|
||||
_ = conn.SetReadDeadline(deadline)
|
||||
err := conn.Ping()
|
||||
if err != nil {
|
||||
pool.logFunc(`Pool: ping query fail: %s`, err.Error())
|
||||
}
|
||||
return err
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"github.com/siddontang/go-mysql/utils"
|
||||
"github.com/go-mysql-org/go-mysql/utils"
|
||||
)
|
||||
|
||||
func (c *Conn) writeCommand(command byte) error {
|
@ -7,9 +7,9 @@ import (
|
||||
"encoding/binary"
|
||||
"encoding/pem"
|
||||
|
||||
. "github.com/go-mysql-org/go-mysql/mysql"
|
||||
"github.com/go-mysql-org/go-mysql/utils"
|
||||
"github.com/pingcap/errors"
|
||||
. "github.com/siddontang/go-mysql/mysql"
|
||||
"github.com/siddontang/go-mysql/utils"
|
||||
"github.com/siddontang/go/hack"
|
||||
)
|
||||
|
||||
@ -39,7 +39,7 @@ func (c *Conn) handleOKPacket(data []byte) (*Result, error) {
|
||||
var n int
|
||||
var pos = 1
|
||||
|
||||
r := new(Result)
|
||||
r := &Result{Resultset: &Resultset{}}
|
||||
|
||||
r.AffectedRows, _, n = LengthEncodedInt(data[pos:])
|
||||
pos += n
|
||||
@ -101,6 +101,10 @@ func (c *Conn) handleAuthResult() error {
|
||||
}
|
||||
c.authPluginName = switchToPlugin
|
||||
auth, addNull, err := c.genAuthResponse(data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = c.WriteAuthSwitchPacket(auth, addNull); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -138,7 +142,7 @@ func (c *Conn) handleAuthResult() error {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
errors.Errorf("invalid packet")
|
||||
return errors.Errorf("invalid packet %x", data[0])
|
||||
}
|
||||
} else if c.authPluginName == AUTH_SHA256_PASSWORD {
|
||||
if len(data) == 0 {
|
||||
@ -169,7 +173,6 @@ func (c *Conn) readAuthResult() ([]byte, string, error) {
|
||||
// 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
|
||||
@ -230,6 +233,42 @@ func (c *Conn) readResult(binary bool) (*Result, error) {
|
||||
return c.readResultset(firstPkgBuf, binary)
|
||||
}
|
||||
|
||||
func (c *Conn) readResultStreaming(binary bool, result *Result, perRowCb SelectPerRowCallback) error {
|
||||
firstPkgBuf, err := c.ReadPacketReuseMem(utils.ByteSliceGet(16)[:0])
|
||||
defer utils.ByteSlicePut(firstPkgBuf)
|
||||
|
||||
if err != nil {
|
||||
return errors.Trace(err)
|
||||
}
|
||||
|
||||
if firstPkgBuf[0] == 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(firstPkgBuf)
|
||||
if err != nil {
|
||||
return errors.Trace(err)
|
||||
}
|
||||
|
||||
result.Status = okResult.Status
|
||||
result.AffectedRows = okResult.AffectedRows
|
||||
result.InsertId = okResult.InsertId
|
||||
if result.Resultset == nil {
|
||||
result.Resultset = NewResultset(0)
|
||||
} else {
|
||||
result.Reset(0)
|
||||
}
|
||||
return nil
|
||||
} else if firstPkgBuf[0] == ERR_HEADER {
|
||||
return c.handleErrorPacket(append([]byte{}, firstPkgBuf...))
|
||||
} else if firstPkgBuf[0] == LocalInFile_HEADER {
|
||||
return ErrMalformPacket
|
||||
}
|
||||
|
||||
return c.readResultsetStreaming(firstPkgBuf, binary, result, perRowCb)
|
||||
}
|
||||
|
||||
func (c *Conn) readResultset(data []byte, binary bool) (*Result, error) {
|
||||
// column count
|
||||
count, _, n := LengthEncodedInt(data)
|
||||
@ -253,6 +292,31 @@ func (c *Conn) readResultset(data []byte, binary bool) (*Result, error) {
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *Conn) readResultsetStreaming(data []byte, binary bool, result *Result, perRowCb SelectPerRowCallback) 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))
|
||||
}
|
||||
|
||||
if err := c.readResultColumns(result); err != nil {
|
||||
return errors.Trace(err)
|
||||
}
|
||||
|
||||
if err := c.readResultRowsStreaming(result, binary, perRowCb); err != nil {
|
||||
return errors.Trace(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Conn) readResultColumns(result *Result) (err error) {
|
||||
var i int = 0
|
||||
var data []byte
|
||||
@ -341,3 +405,47 @@ func (c *Conn) readResultRows(result *Result, isBinary bool) (err error) {
|
||||
|
||||
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
|
||||
}
|
@ -5,14 +5,13 @@ import (
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
. "github.com/go-mysql-org/go-mysql/mysql"
|
||||
"github.com/pingcap/errors"
|
||||
. "github.com/siddontang/go-mysql/mysql"
|
||||
)
|
||||
|
||||
type Stmt struct {
|
||||
conn *Conn
|
||||
id uint32
|
||||
query string
|
||||
|
||||
params int
|
||||
columns int
|
||||
@ -55,7 +54,7 @@ func (s *Stmt) write(args ...interface{}) error {
|
||||
//NULL-bitmap, length: (num-params+7)
|
||||
nullBitmap := make([]byte, (paramsNum+7)>>3)
|
||||
|
||||
var length int = int(1 + 4 + 1 + 4 + ((paramsNum + 7) >> 3) + 1 + (paramsNum << 1))
|
||||
length := 1 + 4 + 1 + 4 + ((paramsNum + 7) >> 3) + 1 + (paramsNum << 1)
|
||||
|
||||
var newParamBoundFlag byte = 0
|
||||
|
||||
@ -91,11 +90,11 @@ func (s *Stmt) write(args ...interface{}) error {
|
||||
case uint16:
|
||||
paramTypes[i<<1] = MYSQL_TYPE_SHORT
|
||||
paramTypes[(i<<1)+1] = 0x80
|
||||
paramValues[i] = Uint16ToBytes(uint16(v))
|
||||
paramValues[i] = Uint16ToBytes(v)
|
||||
case uint32:
|
||||
paramTypes[i<<1] = MYSQL_TYPE_LONG
|
||||
paramTypes[(i<<1)+1] = 0x80
|
||||
paramValues[i] = Uint32ToBytes(uint32(v))
|
||||
paramValues[i] = Uint32ToBytes(v)
|
||||
case uint:
|
||||
paramTypes[i<<1] = MYSQL_TYPE_LONGLONG
|
||||
paramTypes[(i<<1)+1] = 0x80
|
||||
@ -103,14 +102,13 @@ func (s *Stmt) write(args ...interface{}) error {
|
||||
case uint64:
|
||||
paramTypes[i<<1] = MYSQL_TYPE_LONGLONG
|
||||
paramTypes[(i<<1)+1] = 0x80
|
||||
paramValues[i] = Uint64ToBytes(uint64(v))
|
||||
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
|
@ -1,7 +1,7 @@
|
||||
package mysql
|
||||
|
||||
const (
|
||||
ER_ERROR_FIRST uint16 = 1000
|
||||
ER_ERROR_FIRST = 1000
|
||||
ER_HASHCHK = 1000
|
||||
ER_NISAMCHK = 1001
|
||||
ER_NO = 1002
|
@ -591,7 +591,7 @@ var MySQLErrName = map[uint16]string{
|
||||
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 occured on the master. Message: %-.64s",
|
||||
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",
|
@ -3,7 +3,7 @@ package mysql
|
||||
import (
|
||||
"encoding/binary"
|
||||
|
||||
"github.com/siddontang/go-mysql/utils"
|
||||
"github.com/go-mysql-org/go-mysql/utils"
|
||||
)
|
||||
|
||||
type FieldData []byte
|
||||
@ -130,7 +130,7 @@ func (f *Field) Parse(p FieldData) (err error) {
|
||||
f.DefaultValue = p[pos:(pos + int(f.DefaultValueLength))]
|
||||
}
|
||||
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p FieldData) Parse() (f *Field, err error) {
|
@ -3,12 +3,12 @@ package mysql
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/pingcap/errors"
|
||||
"github.com/siddontang/go-log/log"
|
||||
"github.com/siddontang/go/hack"
|
||||
)
|
||||
|
||||
// MariadbGTID represent mariadb gtid, [domain ID]-[server-id]-[sequence]
|
||||
@ -113,15 +113,9 @@ func ParseMariadbGTIDSet(str string) (GTIDSet, error) {
|
||||
if str == "" {
|
||||
return s, nil
|
||||
}
|
||||
|
||||
sp := strings.Split(str, ",")
|
||||
|
||||
//todo, handle redundant same uuid
|
||||
for i := 0; i < len(sp); i++ {
|
||||
err := s.Update(sp[i])
|
||||
err := s.Update(str)
|
||||
if err != nil {
|
||||
return nil, errors.Trace(err)
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return s, nil
|
||||
}
|
||||
@ -147,17 +141,29 @@ func (s *MariadbGTIDSet) AddSet(gtid *MariadbGTID) error {
|
||||
|
||||
// Update updates mariadb gtid set
|
||||
func (s *MariadbGTIDSet) Update(GTIDStr string) error {
|
||||
gtid, err := ParseMariadbGTID(GTIDStr)
|
||||
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 err
|
||||
}
|
||||
|
||||
err = s.AddSet(gtid)
|
||||
return errors.Trace(err)
|
||||
}
|
||||
err = s.AddSet(gtid)
|
||||
if err != nil {
|
||||
return errors.Trace(err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *MariadbGTIDSet) String() string {
|
||||
return hack.String(s.Encode())
|
||||
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
|
@ -32,8 +32,10 @@ func parseInterval(str string) (i Interval, err error) {
|
||||
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 = i.Stop + 1
|
||||
i.Stop++
|
||||
}
|
||||
default:
|
||||
err = errors.Errorf("invalid interval format, must n[-n]")
|
||||
}
|
||||
@ -230,14 +232,14 @@ func (s *UUIDSet) String() string {
|
||||
}
|
||||
|
||||
func (s *UUIDSet) encode(w io.Writer) {
|
||||
w.Write(s.SID.Bytes())
|
||||
_, _ = w.Write(s.SID.Bytes())
|
||||
n := int64(len(s.Intervals))
|
||||
|
||||
binary.Write(w, binary.LittleEndian, n)
|
||||
_ = 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)
|
||||
_ = binary.Write(w, binary.LittleEndian, i.Start)
|
||||
_ = binary.Write(w, binary.LittleEndian, i.Stop)
|
||||
}
|
||||
}
|
||||
|
||||
@ -292,7 +294,7 @@ func (s *UUIDSet) Decode(data []byte) error {
|
||||
func (s *UUIDSet) Clone() *UUIDSet {
|
||||
clone := new(UUIDSet)
|
||||
|
||||
clone.SID, _ = uuid.FromString(s.SID.String())
|
||||
copy(clone.SID[:], s.SID[:])
|
||||
clone.Intervals = s.Intervals.Normalize()
|
||||
|
||||
return clone
|
||||
@ -318,7 +320,6 @@ func ParseMysqlGTIDSet(str string) (GTIDSet, error) {
|
||||
} else {
|
||||
s.AddSet(set)
|
||||
}
|
||||
|
||||
}
|
||||
return s, nil
|
||||
}
|
||||
@ -362,13 +363,13 @@ func (s *MysqlGTIDSet) AddSet(set *UUIDSet) {
|
||||
}
|
||||
|
||||
func (s *MysqlGTIDSet) Update(GTIDStr string) error {
|
||||
uuidSet, err := ParseUUIDSet(GTIDStr)
|
||||
gtidSet, err := ParseMysqlGTIDSet(GTIDStr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, uuidSet := range gtidSet.(*MysqlGTIDSet).Sets {
|
||||
s.AddSet(uuidSet)
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -414,15 +415,28 @@ func (s *MysqlGTIDSet) Equal(o GTIDSet) bool {
|
||||
}
|
||||
|
||||
return true
|
||||
|
||||
}
|
||||
|
||||
func (s *MysqlGTIDSet) String() string {
|
||||
var buf bytes.Buffer
|
||||
sep := ""
|
||||
// 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.String())
|
||||
buf.WriteString(set)
|
||||
sep = ","
|
||||
}
|
||||
|
||||
@ -432,7 +446,7 @@ func (s *MysqlGTIDSet) String() string {
|
||||
func (s *MysqlGTIDSet) Encode() []byte {
|
||||
var buf bytes.Buffer
|
||||
|
||||
binary.Write(&buf, binary.LittleEndian, uint64(len(s.Sets)))
|
||||
_ = binary.Write(&buf, binary.LittleEndian, uint64(len(s.Sets)))
|
||||
|
||||
for i := range s.Sets {
|
||||
s.Sets[i].encode(&buf)
|
@ -20,7 +20,7 @@ func ParseBinaryUint16(data []byte) uint16 {
|
||||
}
|
||||
|
||||
func ParseBinaryInt24(data []byte) int32 {
|
||||
u32 := uint32(ParseBinaryUint24(data))
|
||||
u32 := ParseBinaryUint24(data)
|
||||
if u32&0x00800000 != 0 {
|
||||
u32 |= 0xFF000000
|
||||
}
|
80
vendor/github.com/go-mysql-org/go-mysql/mysql/position.go
generated
vendored
Normal file
80
vendor/github.com/go-mysql-org/go-mysql/mysql/position.go
generated
vendored
Normal file
@ -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
|
||||
}
|
||||
}
|
@ -27,9 +27,9 @@ var (
|
||||
}
|
||||
)
|
||||
|
||||
func NewResultset(resultsetCount int) *Resultset {
|
||||
func NewResultset(fieldsCount int) *Resultset {
|
||||
r := resultsetPool.Get().(*Resultset)
|
||||
r.reset(resultsetCount)
|
||||
r.Reset(fieldsCount)
|
||||
return r
|
||||
}
|
||||
|
||||
@ -37,7 +37,7 @@ func (r *Resultset) returnToPool() {
|
||||
resultsetPool.Put(r)
|
||||
}
|
||||
|
||||
func (r *Resultset) reset(count int) {
|
||||
func (r *Resultset) Reset(fieldsCount int) {
|
||||
r.RawPkg = r.RawPkg[:0]
|
||||
|
||||
r.Fields = r.Fields[:0]
|
||||
@ -52,14 +52,14 @@ func (r *Resultset) reset(count int) {
|
||||
r.FieldNames = make(map[string]int)
|
||||
}
|
||||
|
||||
if count == 0 {
|
||||
if fieldsCount == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
if cap(r.Fields) < count {
|
||||
r.Fields = make([]*Field, count)
|
||||
if cap(r.Fields) < fieldsCount {
|
||||
r.Fields = make([]*Field, fieldsCount)
|
||||
} else {
|
||||
r.Fields = r.Fields[:count]
|
||||
r.Fields = r.Fields[:fieldsCount]
|
||||
}
|
||||
}
|
||||
|
||||
@ -142,7 +142,7 @@ func (r *Resultset) GetUint(row, column int) (uint64, error) {
|
||||
case uint32:
|
||||
return uint64(v), nil
|
||||
case uint64:
|
||||
return uint64(v), nil
|
||||
return v, nil
|
||||
case float32:
|
||||
return uint64(v), nil
|
||||
case float64:
|
@ -17,7 +17,7 @@ func formatTextValue(value interface{}) ([]byte, error) {
|
||||
case int32:
|
||||
return strconv.AppendInt(nil, int64(v), 10), nil
|
||||
case int64:
|
||||
return strconv.AppendInt(nil, int64(v), 10), nil
|
||||
return strconv.AppendInt(nil, v, 10), nil
|
||||
case int:
|
||||
return strconv.AppendInt(nil, int64(v), 10), nil
|
||||
case uint8:
|
||||
@ -27,13 +27,13 @@ func formatTextValue(value interface{}) ([]byte, error) {
|
||||
case uint32:
|
||||
return strconv.AppendUint(nil, uint64(v), 10), nil
|
||||
case uint64:
|
||||
return strconv.AppendUint(nil, uint64(v), 10), nil
|
||||
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, float64(v), 'f', -1, 64), nil
|
||||
return strconv.AppendFloat(nil, v, 'f', -1, 64), nil
|
||||
case []byte:
|
||||
return v, nil
|
||||
case string:
|
||||
@ -64,7 +64,7 @@ func formatBinaryValue(value interface{}) ([]byte, error) {
|
||||
case uint32:
|
||||
return Uint64ToBytes(uint64(v)), nil
|
||||
case uint64:
|
||||
return Uint64ToBytes(uint64(v)), nil
|
||||
return Uint64ToBytes(v), nil
|
||||
case uint:
|
||||
return Uint64ToBytes(uint64(v)), nil
|
||||
case float32:
|
||||
@ -146,7 +146,10 @@ func BuildSimpleTextResultset(names []string, values [][]interface{}) (*Resultse
|
||||
}
|
||||
if r.Fields[j] == nil {
|
||||
r.Fields[j] = &Field{Name: hack.Slice(names[j]), Type: typ}
|
||||
formatField(r.Fields[j], value)
|
||||
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
|
||||
@ -154,7 +157,10 @@ func BuildSimpleTextResultset(names []string, values [][]interface{}) (*Resultse
|
||||
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
|
||||
formatField(r.Fields[j], value)
|
||||
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")
|
||||
}
|
@ -3,8 +3,8 @@ package mysql
|
||||
import (
|
||||
"strconv"
|
||||
|
||||
"github.com/go-mysql-org/go-mysql/utils"
|
||||
"github.com/pingcap/errors"
|
||||
"github.com/siddontang/go-mysql/utils"
|
||||
)
|
||||
|
||||
type RowData []byte
|
@ -114,7 +114,7 @@ func RandomBuf(size int) ([]byte, error) {
|
||||
|
||||
// avoid to generate '\0'
|
||||
for i, b := range buf {
|
||||
if uint8(b) == 0 {
|
||||
if b == 0 {
|
||||
buf[i] = '0'
|
||||
}
|
||||
}
|
@ -13,9 +13,9 @@ import (
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
|
||||
. "github.com/go-mysql-org/go-mysql/mysql"
|
||||
"github.com/go-mysql-org/go-mysql/utils"
|
||||
"github.com/pingcap/errors"
|
||||
. "github.com/siddontang/go-mysql/mysql"
|
||||
"github.com/siddontang/go-mysql/utils"
|
||||
)
|
||||
|
||||
type BufPool struct {
|
||||
@ -134,7 +134,7 @@ func (c *Conn) ReadPacketTo(w io.Writer) error {
|
||||
}
|
||||
|
||||
length := int(uint32(c.header[0]) | uint32(c.header[1])<<8 | uint32(c.header[2])<<16)
|
||||
sequence := uint8(c.header[3])
|
||||
sequence := c.header[3]
|
||||
|
||||
if sequence != c.Sequence {
|
||||
return errors.Errorf("invalid sequence %d != %d", sequence, c.Sequence)
|
@ -7,8 +7,8 @@ import (
|
||||
"path"
|
||||
"time"
|
||||
|
||||
. "github.com/go-mysql-org/go-mysql/mysql"
|
||||
"github.com/pingcap/errors"
|
||||
. "github.com/siddontang/go-mysql/mysql"
|
||||
)
|
||||
|
||||
// StartBackup: Like mysqlbinlog remote raw backup
|
||||
@ -22,7 +22,9 @@ func (b *BinlogSyncer) StartBackup(backupDir string, p Position, timeout time.Du
|
||||
// Force use raw mode
|
||||
b.parser.SetRawMode(true)
|
||||
|
||||
os.MkdirAll(backupDir, 0755)
|
||||
if err := os.MkdirAll(backupDir, 0755); err != nil {
|
||||
return errors.Trace(err)
|
||||
}
|
||||
|
||||
s, err := b.StartSync(p)
|
||||
if err != nil {
|
||||
@ -82,7 +84,6 @@ func (b *BinlogSyncer) StartBackup(backupDir string, p Position, timeout time.Du
|
||||
if _, err = f.Write(BinLogFileHeader); err != nil {
|
||||
return errors.Trace(err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if n, err := f.Write(e.RawData); err != nil {
|
@ -2,9 +2,10 @@ package replication
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/pingcap/errors"
|
||||
"github.com/siddontang/go-log/log"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
@ -10,11 +10,11 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/go-mysql-org/go-mysql/client"
|
||||
. "github.com/go-mysql-org/go-mysql/mysql"
|
||||
"github.com/pingcap/errors"
|
||||
uuid "github.com/satori/go.uuid"
|
||||
"github.com/siddontang/go-log/log"
|
||||
"github.com/siddontang/go-mysql/client"
|
||||
. "github.com/siddontang/go-mysql/mysql"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -104,6 +104,10 @@ type BinlogSyncerConfig struct {
|
||||
// https://mariadb.com/kb/en/library/com_binlog_dump/
|
||||
// https://mariadb.com/kb/en/library/annotate_rows_event/
|
||||
DumpCommandFlag uint16
|
||||
|
||||
//Option function is used to set outside of BinlogSyncerConfig, between mysql connection and COM_REGISTER_SLAVE
|
||||
//For MariaDB: slave_gtid_ignore_duplicates、skip_replication、slave_until_gtid
|
||||
Option func(*client.Conn) error
|
||||
}
|
||||
|
||||
// BinlogSyncer syncs binlog event from server.
|
||||
@ -179,7 +183,10 @@ func (b *BinlogSyncer) close() {
|
||||
b.cancel()
|
||||
|
||||
if b.c != nil {
|
||||
b.c.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
|
||||
err := b.c.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
|
||||
if err != nil {
|
||||
log.Warnf(`could not set read deadline: %s`, err)
|
||||
}
|
||||
}
|
||||
|
||||
// kill last connection id
|
||||
@ -223,18 +230,26 @@ func (b *BinlogSyncer) registerSlave() error {
|
||||
return errors.Trace(err)
|
||||
}
|
||||
|
||||
if b.cfg.Option != nil {
|
||||
if err = b.cfg.Option(b.c); err != nil {
|
||||
return errors.Trace(err)
|
||||
}
|
||||
}
|
||||
|
||||
if len(b.cfg.Charset) != 0 {
|
||||
b.c.SetCharset(b.cfg.Charset)
|
||||
if err = b.c.SetCharset(b.cfg.Charset); err != nil {
|
||||
return errors.Trace(err)
|
||||
}
|
||||
}
|
||||
|
||||
//set read timeout
|
||||
if b.cfg.ReadTimeout > 0 {
|
||||
b.c.SetReadDeadline(time.Now().Add(b.cfg.ReadTimeout))
|
||||
_ = b.c.SetReadDeadline(time.Now().Add(b.cfg.ReadTimeout))
|
||||
}
|
||||
|
||||
if b.cfg.RecvBufferSize > 0 {
|
||||
if tcp, ok := b.c.Conn.Conn.(*net.TCPConn); ok {
|
||||
tcp.SetReadBuffer(b.cfg.RecvBufferSize)
|
||||
_ = tcp.SetReadBuffer(b.cfg.RecvBufferSize)
|
||||
}
|
||||
}
|
||||
|
||||
@ -268,7 +283,6 @@ func (b *BinlogSyncer) registerSlave() error {
|
||||
// if _, err = b.c.Execute(`SET @master_binlog_checksum=@@global.binlog_checksum`); err != nil {
|
||||
// return errors.Trace(err)
|
||||
// }
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -697,7 +711,7 @@ func (b *BinlogSyncer) onStream(s *BinlogStreamer) {
|
||||
|
||||
//set read timeout
|
||||
if b.cfg.ReadTimeout > 0 {
|
||||
b.c.SetReadDeadline(time.Now().Add(b.cfg.ReadTimeout))
|
||||
_ = b.c.SetReadDeadline(time.Now().Add(b.cfg.ReadTimeout))
|
||||
}
|
||||
|
||||
// Reset retry count on successful packet receieve
|
@ -11,8 +11,9 @@ import (
|
||||
"unicode"
|
||||
|
||||
"github.com/pingcap/errors"
|
||||
"github.com/satori/go.uuid"
|
||||
. "github.com/siddontang/go-mysql/mysql"
|
||||
uuid "github.com/satori/go.uuid"
|
||||
|
||||
. "github.com/go-mysql-org/go-mysql/mysql"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -100,7 +101,7 @@ func (h *EventHeader) Decode(data []byte) error {
|
||||
}
|
||||
|
||||
func (h *EventHeader) Dump(w io.Writer) {
|
||||
fmt.Fprintf(w, "=== %s ===\n", EventType(h.EventType))
|
||||
fmt.Fprintf(w, "=== %s ===\n", h.EventType)
|
||||
fmt.Fprintf(w, "Date: %s\n", time.Unix(int64(h.Timestamp), 0).Format(TimeFormat))
|
||||
fmt.Fprintf(w, "Log position: %d\n", h.LogPos)
|
||||
fmt.Fprintf(w, "Event size: %d\n", h.EventSize)
|
||||
@ -309,7 +310,7 @@ func (e *QueryEvent) Decode(data []byte) error {
|
||||
e.ExecutionTime = binary.LittleEndian.Uint32(data[pos:])
|
||||
pos += 4
|
||||
|
||||
schemaLength := uint8(data[pos])
|
||||
schemaLength := data[pos]
|
||||
pos++
|
||||
|
||||
e.ErrorCode = binary.LittleEndian.Uint16(data[pos:])
|
||||
@ -368,7 +369,7 @@ type GTIDEvent struct {
|
||||
|
||||
func (e *GTIDEvent) Decode(data []byte) error {
|
||||
pos := 0
|
||||
e.CommitFlag = uint8(data[pos])
|
||||
e.CommitFlag = data[pos]
|
||||
pos++
|
||||
e.SID = data[pos : pos+SidLength]
|
||||
pos += SidLength
|
||||
@ -376,7 +377,7 @@ func (e *GTIDEvent) Decode(data []byte) error {
|
||||
pos += 8
|
||||
|
||||
if len(data) >= 42 {
|
||||
if uint8(data[pos]) == LogicalTimestampTypeCode {
|
||||
if data[pos] == LogicalTimestampTypeCode {
|
||||
pos++
|
||||
e.LastCommitted = int64(binary.LittleEndian.Uint64(data[pos:]))
|
||||
pos += PartLogicalTimestampLength
|
||||
@ -394,11 +395,9 @@ func (e *GTIDEvent) Decode(data []byte) error {
|
||||
e.ImmediateCommitTimestamp &= ^(uint64(1) << 55)
|
||||
e.OriginalCommitTimestamp = FixedLengthInt(data[pos : pos+7])
|
||||
pos += 7
|
||||
|
||||
} else {
|
||||
// Otherwise OriginalCommitTimestamp == ImmediateCommitTimestamp
|
||||
e.OriginalCommitTimestamp = e.ImmediateCommitTimestamp
|
||||
|
||||
}
|
||||
|
||||
// TRANSACTION_LENGTH_MIN_LENGTH = 1
|
||||
@ -422,13 +421,10 @@ func (e *GTIDEvent) Decode(data []byte) error {
|
||||
e.ImmediateServerVersion &= ^(uint32(1) << 31)
|
||||
e.OriginalServerVersion = binary.LittleEndian.Uint32(data[pos:])
|
||||
pos += 4
|
||||
|
||||
} else {
|
||||
// Otherwise OriginalServerVersion == ImmediateServerVersion
|
||||
e.OriginalServerVersion = e.ImmediateServerVersion
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@ -510,7 +506,7 @@ func (e *ExecuteLoadQueryEvent) Decode(data []byte) error {
|
||||
e.ExecutionTime = binary.LittleEndian.Uint32(data[pos:])
|
||||
pos += 4
|
||||
|
||||
e.SchemaLength = uint8(data[pos])
|
||||
e.SchemaLength = data[pos]
|
||||
pos++
|
||||
|
||||
e.ErrorCode = binary.LittleEndian.Uint16(data[pos:])
|
||||
@ -528,7 +524,7 @@ func (e *ExecuteLoadQueryEvent) Decode(data []byte) error {
|
||||
e.EndPos = binary.LittleEndian.Uint32(data[pos:])
|
||||
pos += 4
|
||||
|
||||
e.DupHandlingFlags = uint8(data[pos])
|
||||
e.DupHandlingFlags = data[pos]
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -601,7 +597,7 @@ func (e *MariadbGTIDEvent) Decode(data []byte) error {
|
||||
pos += 8
|
||||
e.GTID.DomainID = binary.LittleEndian.Uint32(data[pos:])
|
||||
pos += 4
|
||||
e.Flags = uint8(data[pos])
|
||||
e.Flags = data[pos]
|
||||
pos += 1
|
||||
|
||||
if (e.Flags & BINLOG_MARIADB_FL_GROUP_COMMIT_ID) > 0 {
|
@ -5,8 +5,8 @@ import (
|
||||
"fmt"
|
||||
"math"
|
||||
|
||||
. "github.com/go-mysql-org/go-mysql/mysql"
|
||||
"github.com/pingcap/errors"
|
||||
. "github.com/siddontang/go-mysql/mysql"
|
||||
"github.com/siddontang/go/hack"
|
||||
)
|
||||
|
||||
@ -149,7 +149,7 @@ func (d *jsonBinaryDecoder) decodeObjectOrArray(data []byte, isSmall bool, isObj
|
||||
count := d.decodeCount(data, isSmall)
|
||||
size := d.decodeCount(data[offsetSize:], isSmall)
|
||||
|
||||
if d.isDataShort(data, int(size)) {
|
||||
if d.isDataShort(data, size) {
|
||||
// Before MySQL 5.7.22, json type generated column may have invalid value,
|
||||
// bug ref: https://bugs.mysql.com/bug.php?id=88791
|
||||
// As generated column value is not used in replication, we can just ignore
|
||||
@ -452,7 +452,6 @@ func (d *jsonBinaryDecoder) decodeDateTime(data []byte) interface{} {
|
||||
frac := v % (1 << 24)
|
||||
|
||||
return fmt.Sprintf("%04d-%02d-%02d %02d:%02d:%02d.%06d", year, month, day, hour, minute, second, frac)
|
||||
|
||||
}
|
||||
|
||||
func (d *jsonBinaryDecoder) decodeCount(data []byte, isSmall bool) int {
|
@ -80,7 +80,7 @@ func (p *BinlogParser) ParseFile(name string, offset int64, onEvent OnEventFunc)
|
||||
offset = 4
|
||||
} else if offset > 4 {
|
||||
// FORMAT_DESCRIPTION event should be read by default always (despite that fact passed offset may be higher than 4)
|
||||
if _, err = f.Seek(4, os.SEEK_SET); err != nil {
|
||||
if _, err = f.Seek(4, io.SeekStart); err != nil {
|
||||
return errors.Errorf("seek %s to %d error %v", name, offset, err)
|
||||
}
|
||||
|
||||
@ -89,7 +89,7 @@ func (p *BinlogParser) ParseFile(name string, offset int64, onEvent OnEventFunc)
|
||||
}
|
||||
}
|
||||
|
||||
if _, err = f.Seek(offset, os.SEEK_SET); err != nil {
|
||||
if _, err = f.Seek(offset, io.SeekStart); err != nil {
|
||||
return errors.Errorf("seek %s to %d error %v", name, offset, err)
|
||||
}
|
||||
|
||||
@ -157,7 +157,6 @@ func (p *BinlogParser) parseSingleEvent(r io.Reader, onEvent OnEventFunc) (bool,
|
||||
}
|
||||
|
||||
func (p *BinlogParser) ParseReader(r io.Reader, onEvent OnEventFunc) error {
|
||||
|
||||
for {
|
||||
if atomic.LoadUint32(&p.stopProcessing) == 1 {
|
||||
break
|
@ -12,8 +12,9 @@ import (
|
||||
"github.com/pingcap/errors"
|
||||
"github.com/shopspring/decimal"
|
||||
"github.com/siddontang/go-log/log"
|
||||
. "github.com/siddontang/go-mysql/mysql"
|
||||
"github.com/siddontang/go/hack"
|
||||
|
||||
. "github.com/go-mysql-org/go-mysql/mysql"
|
||||
)
|
||||
|
||||
var errMissingTableMapEvent = errors.New("invalid table id, no corresponding table map event")
|
||||
@ -145,7 +146,7 @@ func (e *TableMapEvent) Decode(data []byte) error {
|
||||
}
|
||||
|
||||
func bitmapByteSize(columnCount int) int {
|
||||
return int(columnCount+7) / 8
|
||||
return (columnCount + 7) / 8
|
||||
}
|
||||
|
||||
// see mysql sql/log_event.h
|
||||
@ -238,10 +239,8 @@ func (e *TableMapEvent) decodeMeta(data []byte) error {
|
||||
}
|
||||
|
||||
func (e *TableMapEvent) decodeOptionalMeta(data []byte) (err error) {
|
||||
|
||||
pos := 0
|
||||
for pos < len(data) {
|
||||
|
||||
// optional metadata fields are stored in Type, Length, Value(TLV) format
|
||||
// Type takes 1 byte. Length is a packed integer value. Values takes Length bytes
|
||||
t := data[pos]
|
||||
@ -637,7 +636,6 @@ func (e *TableMapEvent) EnumSetCollationMap() map[int]uint64 {
|
||||
}
|
||||
|
||||
func (e *TableMapEvent) collationMap(includeType func(int) bool, defaultCharset, columnCharset []uint64) map[int]uint64 {
|
||||
|
||||
if len(defaultCharset) != 0 {
|
||||
defaultCollation := defaultCharset[0]
|
||||
|
||||
@ -666,7 +664,6 @@ func (e *TableMapEvent) collationMap(includeType func(int) bool, defaultCharset,
|
||||
}
|
||||
|
||||
if len(columnCharset) != 0 {
|
||||
|
||||
p := 0
|
||||
ret := make(map[int]uint64)
|
||||
for i := 0; i < int(e.ColumnCount); i++ {
|
||||
@ -739,7 +736,6 @@ func (e *TableMapEvent) GeometryTypeMap() map[int]uint64 {
|
||||
// Table_map_log_event::print_columns in mysql-8.0/sql/log_event.cc and mariadb-10.5/sql/log_event_client.cc
|
||||
|
||||
func (e *TableMapEvent) realType(i int) byte {
|
||||
|
||||
typ := e.ColumnType[i]
|
||||
|
||||
switch typ {
|
||||
@ -757,7 +753,6 @@ func (e *TableMapEvent) realType(i int) byte {
|
||||
}
|
||||
|
||||
func (e *TableMapEvent) IsNumericColumn(i int) bool {
|
||||
|
||||
switch e.realType(i) {
|
||||
case MYSQL_TYPE_TINY,
|
||||
MYSQL_TYPE_SHORT,
|
||||
@ -772,14 +767,12 @@ func (e *TableMapEvent) IsNumericColumn(i int) bool {
|
||||
default:
|
||||
return false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// IsCharacterColumn returns true if the column type is considered as character type.
|
||||
// Note that JSON/GEOMETRY types are treated as character type in mariadb.
|
||||
// (JSON is an alias for LONGTEXT in mariadb: https://mariadb.com/kb/en/json-data-type/)
|
||||
func (e *TableMapEvent) IsCharacterColumn(i int) bool {
|
||||
|
||||
switch e.realType(i) {
|
||||
case MYSQL_TYPE_STRING,
|
||||
MYSQL_TYPE_VAR_STRING,
|
||||
@ -796,7 +789,6 @@ func (e *TableMapEvent) IsCharacterColumn(i int) bool {
|
||||
default:
|
||||
return false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (e *TableMapEvent) IsEnumColumn(i int) bool {
|
||||
@ -847,6 +839,7 @@ type RowsEvent struct {
|
||||
|
||||
//rows: invalid: int64, float64, bool, []byte, string
|
||||
Rows [][]interface{}
|
||||
SkippedColumns [][]int
|
||||
|
||||
parseTime bool
|
||||
timestampStringLocation *time.Location
|
||||
@ -854,7 +847,7 @@ type RowsEvent struct {
|
||||
ignoreJSONDecodeErr bool
|
||||
}
|
||||
|
||||
func (e *RowsEvent) Decode(data []byte) error {
|
||||
func (e *RowsEvent) Decode(data []byte) (err2 error) {
|
||||
pos := 0
|
||||
e.TableID = FixedLengthInt(data[0:e.tableIDSize])
|
||||
pos += e.tableIDSize
|
||||
@ -898,7 +891,9 @@ func (e *RowsEvent) Decode(data []byte) error {
|
||||
// ... repeat rows until event-end
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
log.Fatalf("parse rows event panic %v, data %q, parsed rows %#v, table map %#v\n%s", r, data, e, e.Table, Pstack())
|
||||
errStr := fmt.Sprintf("parse rows event panic %v, data %q, parsed rows %#v, table map %#v", r, data, e, e.Table)
|
||||
log.Errorf("%s\n%s", errStr, Pstack())
|
||||
err2 = errors.Trace(errors.New(errStr))
|
||||
}
|
||||
}()
|
||||
|
||||
@ -907,6 +902,7 @@ func (e *RowsEvent) Decode(data []byte) error {
|
||||
if e.needBitmap2 {
|
||||
rowsLen += e.ColumnCount
|
||||
}
|
||||
e.SkippedColumns = make([][]int, 0, rowsLen)
|
||||
e.Rows = make([][]interface{}, 0, rowsLen)
|
||||
|
||||
for pos < len(data) {
|
||||
@ -932,6 +928,7 @@ func isBitSet(bitmap []byte, i int) bool {
|
||||
|
||||
func (e *RowsEvent) decodeRows(data []byte, table *TableMapEvent, bitmap []byte) (int, error) {
|
||||
row := make([]interface{}, e.ColumnCount)
|
||||
skips := make([]int, 0)
|
||||
|
||||
pos := 0
|
||||
|
||||
@ -953,6 +950,7 @@ func (e *RowsEvent) decodeRows(data []byte, table *TableMapEvent, bitmap []byte)
|
||||
var err error
|
||||
for i := 0; i < int(e.ColumnCount); i++ {
|
||||
if !isBitSet(bitmap, i) {
|
||||
skips = append(skips, i)
|
||||
continue
|
||||
}
|
||||
|
||||
@ -973,6 +971,7 @@ func (e *RowsEvent) decodeRows(data []byte, table *TableMapEvent, bitmap []byte)
|
||||
}
|
||||
|
||||
e.Rows = append(e.Rows, row)
|
||||
e.SkippedColumns = append(e.SkippedColumns, skips)
|
||||
return pos, nil
|
||||
}
|
||||
|
||||
@ -1002,7 +1001,7 @@ func (e *RowsEvent) decodeValue(data []byte, tp byte, meta uint16) (v interface{
|
||||
|
||||
if b0&0x30 != 0x30 {
|
||||
length = int(uint16(b1) | (uint16((b0&0x30)^0x30) << 4))
|
||||
tp = byte(b0 | 0x30)
|
||||
tp = b0 | 0x30
|
||||
} else {
|
||||
length = int(meta & 0xFF)
|
||||
tp = b0
|
||||
@ -1045,7 +1044,7 @@ func (e *RowsEvent) decodeValue(data []byte, tp byte, meta uint16) (v interface{
|
||||
n = int(nbits+7) / 8
|
||||
|
||||
//use int64 for bit
|
||||
v, err = decodeBit(data, int(nbits), int(n))
|
||||
v, err = decodeBit(data, int(nbits), n)
|
||||
case MYSQL_TYPE_TIMESTAMP:
|
||||
n = 4
|
||||
t := binary.LittleEndian.Uint32(data)
|
||||
@ -1092,11 +1091,7 @@ func (e *RowsEvent) decodeValue(data []byte, tp byte, meta uint16) (v interface{
|
||||
if i32 == 0 {
|
||||
v = "00:00:00"
|
||||
} else {
|
||||
sign := ""
|
||||
if i32 < 0 {
|
||||
sign = "-"
|
||||
}
|
||||
v = fmt.Sprintf("%s%02d:%02d:%02d", sign, i32/10000, (i32%10000)/100, i32%100)
|
||||
v = fmt.Sprintf("%02d:%02d:%02d", i32/10000, (i32%10000)/100, i32%100)
|
||||
}
|
||||
case MYSQL_TYPE_TIME2:
|
||||
v, n, err = decodeTime2(data, meta)
|
||||
@ -1158,14 +1153,15 @@ func (e *RowsEvent) decodeValue(data []byte, tp byte, meta uint16) (v interface{
|
||||
default:
|
||||
err = fmt.Errorf("unsupport type %d in binlog and don't know how to handle", tp)
|
||||
}
|
||||
return
|
||||
|
||||
return v, n, err
|
||||
}
|
||||
|
||||
func decodeString(data []byte, length int) (v string, n int) {
|
||||
if length < 256 {
|
||||
length = int(data[0])
|
||||
|
||||
n = int(length) + 1
|
||||
n = length + 1
|
||||
v = hack.String(data[1:n])
|
||||
} else {
|
||||
length = int(binary.LittleEndian.Uint16(data[0:]))
|
||||
@ -1192,9 +1188,9 @@ func decodeDecimalDecompressValue(compIndx int, data []byte, mask uint8) (size i
|
||||
|
||||
func decodeDecimal(data []byte, precision int, decimals int, useDecimal bool) (interface{}, int, error) {
|
||||
//see python mysql replication and https://github.com/jeremycole/mysql_binlog
|
||||
integral := (precision - decimals)
|
||||
uncompIntegral := int(integral / digitsPerInteger)
|
||||
uncompFractional := int(decimals / digitsPerInteger)
|
||||
integral := precision - decimals
|
||||
uncompIntegral := integral / digitsPerInteger
|
||||
uncompFractional := decimals / digitsPerInteger
|
||||
compIntegral := integral - (uncompIntegral * digitsPerInteger)
|
||||
compFractional := decimals - (uncompFractional * digitsPerInteger)
|
||||
|
@ -31,6 +31,6 @@ func ByteSlicePut(data []byte) {
|
||||
select {
|
||||
case byteSliceChan <- data:
|
||||
default:
|
||||
byteSlicePool.Put(data)
|
||||
byteSlicePool.Put(data) //nolint:staticcheck
|
||||
}
|
||||
}
|
1
vendor/github.com/pingcap/errors/.gitignore
generated
vendored
1
vendor/github.com/pingcap/errors/.gitignore
generated
vendored
@ -6,6 +6,7 @@
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
.idea
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
|
99
vendor/github.com/pingcap/errors/compatible_shim.go
generated
vendored
Normal file
99
vendor/github.com/pingcap/errors/compatible_shim.go
generated
vendored
Normal file
@ -0,0 +1,99 @@
|
||||
// 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
|
||||
}
|
11
vendor/github.com/pingcap/errors/go.mod
generated
vendored
Normal file
11
vendor/github.com/pingcap/errors/go.mod
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
module github.com/pingcap/errors
|
||||
|
||||
go 1.14
|
||||
|
||||
require (
|
||||
github.com/pingcap/check v0.0.0-20190102082844-67f458068fc8
|
||||
github.com/pingcap/log v0.0.0-20200511115504-543df19646ad
|
||||
github.com/pkg/errors v0.9.1
|
||||
go.uber.org/atomic v1.6.0
|
||||
go.uber.org/zap v1.15.0
|
||||
)
|
66
vendor/github.com/pingcap/errors/go.sum
generated
vendored
Normal file
66
vendor/github.com/pingcap/errors/go.sum
generated
vendored
Normal file
@ -0,0 +1,66 @@
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
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/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
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 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
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/log v0.0.0-20200511115504-543df19646ad h1:SveG82rmu/GFxYanffxsSF503SiQV+2JLnWEiGiF+Tc=
|
||||
github.com/pingcap/log v0.0.0-20200511115504-543df19646ad/go.mod h1:4rbK1p9ILyIfb6hU7OG2CiWSqMXnp3JMbiaVJ6mvoY8=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
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/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
|
||||
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/multierr v1.5.0 h1:KCa4XfM8CWFCpxXRGok+Q0SS/0XBhMDbHHGABQLvD2A=
|
||||
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
|
||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4=
|
||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
||||
go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go.uber.org/zap v1.15.0 h1:ZZCA22JRF2gQE5FoNmhmrf7jeJJ2uhqDUNRYKm8dvmM=
|
||||
go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
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/sync v0.0.0-20190423024810-112230192c58/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/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5 h1:hKsoRgsbwY1NafxrwTs+k64bikrLBkAgPir1TNCj3Zs=
|
||||
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/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 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
|
||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
45
vendor/github.com/pingcap/errors/juju_adaptor.go
generated
vendored
45
vendor/github.com/pingcap/errors/juju_adaptor.go
generated
vendored
@ -9,6 +9,9 @@ import (
|
||||
|
||||
// Trace just calls AddStack.
|
||||
func Trace(err error) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
return AddStack(err)
|
||||
}
|
||||
|
||||
@ -52,6 +55,48 @@ func Annotatef(err error, format string, args ...interface{}) error {
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
|
313
vendor/github.com/pingcap/errors/normalize.go
generated
vendored
Normal file
313
vendor/github.com/pingcap/errors/normalize.go
generated
vendored
Normal file
@ -0,0 +1,313 @@
|
||||
// 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 "<nil>"
|
||||
}
|
||||
describe := e.codeText
|
||||
if len(describe) == 0 {
|
||||
describe = ErrCodeText(strconv.Itoa(int(e.code)))
|
||||
}
|
||||
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 = "<unknown>"
|
||||
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
|
||||
}
|
33
vendor/github.com/siddontang/go-mysql/mysql/position.go
generated
vendored
33
vendor/github.com/siddontang/go-mysql/mysql/position.go
generated
vendored
@ -1,33 +0,0 @@
|
||||
package mysql
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// For binlog filename + position based replication
|
||||
type Position struct {
|
||||
Name string
|
||||
Pos uint32
|
||||
}
|
||||
|
||||
func (p Position) Compare(o Position) int {
|
||||
// First compare binlog name
|
||||
if p.Name > o.Name {
|
||||
return 1
|
||||
} else if p.Name < o.Name {
|
||||
return -1
|
||||
} else {
|
||||
// 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)
|
||||
}
|
19
vendor/go.uber.org/atomic/.codecov.yml
generated
vendored
Normal file
19
vendor/go.uber.org/atomic/.codecov.yml
generated
vendored
Normal file
@ -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/
|
12
vendor/go.uber.org/atomic/.gitignore
generated
vendored
Normal file
12
vendor/go.uber.org/atomic/.gitignore
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
/bin
|
||||
.DS_Store
|
||||
/vendor
|
||||
cover.html
|
||||
cover.out
|
||||
lint.log
|
||||
|
||||
# Binaries
|
||||
*.test
|
||||
|
||||
# Profiling output
|
||||
*.prof
|
27
vendor/go.uber.org/atomic/.travis.yml
generated
vendored
Normal file
27
vendor/go.uber.org/atomic/.travis.yml
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
sudo: false
|
||||
language: go
|
||||
go_import_path: go.uber.org/atomic
|
||||
|
||||
env:
|
||||
global:
|
||||
- GO111MODULE=on
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- go: oldstable
|
||||
- go: stable
|
||||
env: LINT=1
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- vendor
|
||||
|
||||
before_install:
|
||||
- go version
|
||||
|
||||
script:
|
||||
- test -z "$LINT" || make lint
|
||||
- make cover
|
||||
|
||||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
76
vendor/go.uber.org/atomic/CHANGELOG.md
generated
vendored
Normal file
76
vendor/go.uber.org/atomic/CHANGELOG.md
generated
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
# 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.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.6.0] - 2020-02-24
|
||||
### Changed
|
||||
- Drop library dependency on `golang.org/x/{lint, tools}`.
|
||||
|
||||
## [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.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.4.0] - 2019-05-01
|
||||
### Added
|
||||
- Add `atomic.Error` type for atomic operations on `error` values.
|
||||
|
||||
## [1.3.2] - 2018-05-02
|
||||
### Added
|
||||
- Add `atomic.Duration` type for atomic operations on `time.Duration` values.
|
||||
|
||||
## [1.3.1] - 2017-11-14
|
||||
### Fixed
|
||||
- Revert optimization for `atomic.String.Store("")` which caused data races.
|
||||
|
||||
## [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.2.0] - 2017-04-12
|
||||
### Added
|
||||
- Shadow `atomic.Value` from `sync/atomic`.
|
||||
|
||||
## [1.1.0] - 2017-03-10
|
||||
### Added
|
||||
- Add atomic `Float64` type.
|
||||
|
||||
### Changed
|
||||
- Support new `go.uber.org/atomic` import path.
|
||||
|
||||
## [1.0.0] - 2016-07-18
|
||||
|
||||
- Initial release.
|
||||
|
||||
[1.7.0]: https://github.com/uber-go/atomic/compare/v1.6.0...v1.7.0
|
||||
[1.6.0]: https://github.com/uber-go/atomic/compare/v1.5.1...v1.6.0
|
||||
[1.5.1]: https://github.com/uber-go/atomic/compare/v1.5.0...v1.5.1
|
||||
[1.5.0]: https://github.com/uber-go/atomic/compare/v1.4.0...v1.5.0
|
||||
[1.4.0]: https://github.com/uber-go/atomic/compare/v1.3.2...v1.4.0
|
||||
[1.3.2]: https://github.com/uber-go/atomic/compare/v1.3.1...v1.3.2
|
||||
[1.3.1]: https://github.com/uber-go/atomic/compare/v1.3.0...v1.3.1
|
||||
[1.3.0]: https://github.com/uber-go/atomic/compare/v1.2.0...v1.3.0
|
||||
[1.2.0]: https://github.com/uber-go/atomic/compare/v1.1.0...v1.2.0
|
||||
[1.1.0]: https://github.com/uber-go/atomic/compare/v1.0.0...v1.1.0
|
||||
[1.0.0]: https://github.com/uber-go/atomic/releases/tag/v1.0.0
|
19
vendor/go.uber.org/atomic/LICENSE.txt
generated
vendored
Normal file
19
vendor/go.uber.org/atomic/LICENSE.txt
generated
vendored
Normal file
@ -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.
|
78
vendor/go.uber.org/atomic/Makefile
generated
vendored
Normal file
78
vendor/go.uber.org/atomic/Makefile
generated
vendored
Normal file
@ -0,0 +1,78 @@
|
||||
# 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."; \
|
||||
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." )
|
63
vendor/go.uber.org/atomic/README.md
generated
vendored
Normal file
63
vendor/go.uber.org/atomic/README.md
generated
vendored
Normal file
@ -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://travis-ci.com/uber-go/atomic.svg?branch=master
|
||||
[ci]: https://travis-ci.com/uber-go/atomic
|
||||
[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
|
81
vendor/go.uber.org/atomic/bool.go
generated
vendored
Normal file
81
vendor/go.uber.org/atomic/bool.go
generated
vendored
Normal file
@ -0,0 +1,81 @@
|
||||
// @generated Code generated by gen-atomicwrapper.
|
||||
|
||||
// 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 (
|
||||
"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(v bool) *Bool {
|
||||
x := &Bool{}
|
||||
if v != _zeroBool {
|
||||
x.Store(v)
|
||||
}
|
||||
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(v bool) {
|
||||
x.v.Store(boolToInt(v))
|
||||
}
|
||||
|
||||
// CAS is an atomic compare-and-swap for bool values.
|
||||
func (x *Bool) CAS(o, n bool) bool {
|
||||
return x.v.CAS(boolToInt(o), boolToInt(n))
|
||||
}
|
||||
|
||||
// Swap atomically stores the given bool and returns the old
|
||||
// value.
|
||||
func (x *Bool) Swap(o bool) bool {
|
||||
return truthy(x.v.Swap(boolToInt(o)))
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
53
vendor/go.uber.org/atomic/bool_ext.go
generated
vendored
Normal file
53
vendor/go.uber.org/atomic/bool_ext.go
generated
vendored
Normal file
@ -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() 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())
|
||||
}
|
23
vendor/go.uber.org/atomic/doc.go
generated
vendored
Normal file
23
vendor/go.uber.org/atomic/doc.go
generated
vendored
Normal file
@ -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
|
82
vendor/go.uber.org/atomic/duration.go
generated
vendored
Normal file
82
vendor/go.uber.org/atomic/duration.go
generated
vendored
Normal file
@ -0,0 +1,82 @@
|
||||
// @generated Code generated by gen-atomicwrapper.
|
||||
|
||||
// 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 (
|
||||
"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(v time.Duration) *Duration {
|
||||
x := &Duration{}
|
||||
if v != _zeroDuration {
|
||||
x.Store(v)
|
||||
}
|
||||
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(v time.Duration) {
|
||||
x.v.Store(int64(v))
|
||||
}
|
||||
|
||||
// CAS is an atomic compare-and-swap for time.Duration values.
|
||||
func (x *Duration) CAS(o, n time.Duration) bool {
|
||||
return x.v.CAS(int64(o), int64(n))
|
||||
}
|
||||
|
||||
// Swap atomically stores the given time.Duration and returns the old
|
||||
// value.
|
||||
func (x *Duration) Swap(o time.Duration) time.Duration {
|
||||
return time.Duration(x.v.Swap(int64(o)))
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
40
vendor/go.uber.org/atomic/duration_ext.go
generated
vendored
Normal file
40
vendor/go.uber.org/atomic/duration_ext.go
generated
vendored
Normal file
@ -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(n time.Duration) time.Duration {
|
||||
return time.Duration(d.v.Add(int64(n)))
|
||||
}
|
||||
|
||||
// Sub atomically subtracts from the wrapped time.Duration and returns the new value.
|
||||
func (d *Duration) Sub(n time.Duration) time.Duration {
|
||||
return time.Duration(d.v.Sub(int64(n)))
|
||||
}
|
||||
|
||||
// String encodes the wrapped value as a string.
|
||||
func (d *Duration) String() string {
|
||||
return d.Load().String()
|
||||
}
|
51
vendor/go.uber.org/atomic/error.go
generated
vendored
Normal file
51
vendor/go.uber.org/atomic/error.go
generated
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
// @generated Code generated by gen-atomicwrapper.
|
||||
|
||||
// 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
|
||||
|
||||
// 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(v error) *Error {
|
||||
x := &Error{}
|
||||
if v != _zeroError {
|
||||
x.Store(v)
|
||||
}
|
||||
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(v error) {
|
||||
x.v.Store(packError(v))
|
||||
}
|
39
vendor/go.uber.org/atomic/error_ext.go
generated
vendored
Normal file
39
vendor/go.uber.org/atomic/error_ext.go
generated
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
// 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
|
||||
|
||||
// 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 -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
|
||||
}
|
76
vendor/go.uber.org/atomic/float64.go
generated
vendored
Normal file
76
vendor/go.uber.org/atomic/float64.go
generated
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
// @generated Code generated by gen-atomicwrapper.
|
||||
|
||||
// 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 (
|
||||
"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(v float64) *Float64 {
|
||||
x := &Float64{}
|
||||
if v != _zeroFloat64 {
|
||||
x.Store(v)
|
||||
}
|
||||
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(v float64) {
|
||||
x.v.Store(math.Float64bits(v))
|
||||
}
|
||||
|
||||
// CAS is an atomic compare-and-swap for float64 values.
|
||||
func (x *Float64) CAS(o, n float64) bool {
|
||||
return x.v.CAS(math.Float64bits(o), math.Float64bits(n))
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
47
vendor/go.uber.org/atomic/float64_ext.go
generated
vendored
Normal file
47
vendor/go.uber.org/atomic/float64_ext.go
generated
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
// 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=Float64 -type=float64 -wrapped=Uint64 -pack=math.Float64bits -unpack=math.Float64frombits -cas -json -imports math -file=float64.go
|
||||
|
||||
// Add atomically adds to the wrapped float64 and returns the new value.
|
||||
func (f *Float64) Add(s float64) float64 {
|
||||
for {
|
||||
old := f.Load()
|
||||
new := old + s
|
||||
if f.CAS(old, new) {
|
||||
return new
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sub atomically subtracts from the wrapped float64 and returns the new value.
|
||||
func (f *Float64) Sub(s float64) float64 {
|
||||
return f.Add(-s)
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
26
vendor/go.uber.org/atomic/gen.go
generated
vendored
Normal file
26
vendor/go.uber.org/atomic/gen.go
generated
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
// 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
|
8
vendor/go.uber.org/atomic/go.mod
generated
vendored
Normal file
8
vendor/go.uber.org/atomic/go.mod
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
module go.uber.org/atomic
|
||||
|
||||
require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/stretchr/testify v1.3.0
|
||||
)
|
||||
|
||||
go 1.13
|
9
vendor/go.uber.org/atomic/go.sum
generated
vendored
Normal file
9
vendor/go.uber.org/atomic/go.sum
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
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/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
102
vendor/go.uber.org/atomic/int32.go
generated
vendored
Normal file
102
vendor/go.uber.org/atomic/int32.go
generated
vendored
Normal file
@ -0,0 +1,102 @@
|
||||
// @generated Code generated by gen-atomicint.
|
||||
|
||||
// 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 (
|
||||
"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(i int32) *Int32 {
|
||||
return &Int32{v: i}
|
||||
}
|
||||
|
||||
// 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(n int32) int32 {
|
||||
return atomic.AddInt32(&i.v, n)
|
||||
}
|
||||
|
||||
// Sub atomically subtracts from the wrapped int32 and returns the new value.
|
||||
func (i *Int32) Sub(n int32) int32 {
|
||||
return atomic.AddInt32(&i.v, -n)
|
||||
}
|
||||
|
||||
// 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.
|
||||
func (i *Int32) CAS(old, new int32) bool {
|
||||
return atomic.CompareAndSwapInt32(&i.v, old, new)
|
||||
}
|
||||
|
||||
// Store atomically stores the passed value.
|
||||
func (i *Int32) Store(n int32) {
|
||||
atomic.StoreInt32(&i.v, n)
|
||||
}
|
||||
|
||||
// Swap atomically swaps the wrapped int32 and returns the old value.
|
||||
func (i *Int32) Swap(n int32) int32 {
|
||||
return atomic.SwapInt32(&i.v, n)
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
102
vendor/go.uber.org/atomic/int64.go
generated
vendored
Normal file
102
vendor/go.uber.org/atomic/int64.go
generated
vendored
Normal file
@ -0,0 +1,102 @@
|
||||
// @generated Code generated by gen-atomicint.
|
||||
|
||||
// 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 (
|
||||
"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(i int64) *Int64 {
|
||||
return &Int64{v: i}
|
||||
}
|
||||
|
||||
// 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(n int64) int64 {
|
||||
return atomic.AddInt64(&i.v, n)
|
||||
}
|
||||
|
||||
// Sub atomically subtracts from the wrapped int64 and returns the new value.
|
||||
func (i *Int64) Sub(n int64) int64 {
|
||||
return atomic.AddInt64(&i.v, -n)
|
||||
}
|
||||
|
||||
// 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.
|
||||
func (i *Int64) CAS(old, new int64) bool {
|
||||
return atomic.CompareAndSwapInt64(&i.v, old, new)
|
||||
}
|
||||
|
||||
// Store atomically stores the passed value.
|
||||
func (i *Int64) Store(n int64) {
|
||||
atomic.StoreInt64(&i.v, n)
|
||||
}
|
||||
|
||||
// Swap atomically swaps the wrapped int64 and returns the old value.
|
||||
func (i *Int64) Swap(n int64) int64 {
|
||||
return atomic.SwapInt64(&i.v, n)
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
35
vendor/go.uber.org/atomic/nocmp.go
generated
vendored
Normal file
35
vendor/go.uber.org/atomic/nocmp.go
generated
vendored
Normal file
@ -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()
|
54
vendor/go.uber.org/atomic/string.go
generated
vendored
Normal file
54
vendor/go.uber.org/atomic/string.go
generated
vendored
Normal file
@ -0,0 +1,54 @@
|
||||
// @generated Code generated by gen-atomicwrapper.
|
||||
|
||||
// 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
|
||||
|
||||
// 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(v string) *String {
|
||||
x := &String{}
|
||||
if v != _zeroString {
|
||||
x.Store(v)
|
||||
}
|
||||
return x
|
||||
}
|
||||
|
||||
// Load atomically loads the wrapped string.
|
||||
func (x *String) Load() string {
|
||||
if v := x.v.Load(); v != nil {
|
||||
return v.(string)
|
||||
}
|
||||
return _zeroString
|
||||
}
|
||||
|
||||
// Store atomically stores the passed string.
|
||||
func (x *String) Store(v string) {
|
||||
x.v.Store(v)
|
||||
}
|
43
vendor/go.uber.org/atomic/string_ext.go
generated
vendored
Normal file
43
vendor/go.uber.org/atomic/string_ext.go
generated
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
// 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-atomicwrapper -name=String -type=string -wrapped=Value -file=string.go
|
||||
|
||||
// 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
|
||||
}
|
102
vendor/go.uber.org/atomic/uint32.go
generated
vendored
Normal file
102
vendor/go.uber.org/atomic/uint32.go
generated
vendored
Normal file
@ -0,0 +1,102 @@
|
||||
// @generated Code generated by gen-atomicint.
|
||||
|
||||
// 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 (
|
||||
"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(i uint32) *Uint32 {
|
||||
return &Uint32{v: i}
|
||||
}
|
||||
|
||||
// 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(n uint32) uint32 {
|
||||
return atomic.AddUint32(&i.v, n)
|
||||
}
|
||||
|
||||
// Sub atomically subtracts from the wrapped uint32 and returns the new value.
|
||||
func (i *Uint32) Sub(n uint32) uint32 {
|
||||
return atomic.AddUint32(&i.v, ^(n - 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.
|
||||
func (i *Uint32) CAS(old, new uint32) bool {
|
||||
return atomic.CompareAndSwapUint32(&i.v, old, new)
|
||||
}
|
||||
|
||||
// Store atomically stores the passed value.
|
||||
func (i *Uint32) Store(n uint32) {
|
||||
atomic.StoreUint32(&i.v, n)
|
||||
}
|
||||
|
||||
// Swap atomically swaps the wrapped uint32 and returns the old value.
|
||||
func (i *Uint32) Swap(n uint32) uint32 {
|
||||
return atomic.SwapUint32(&i.v, n)
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
102
vendor/go.uber.org/atomic/uint64.go
generated
vendored
Normal file
102
vendor/go.uber.org/atomic/uint64.go
generated
vendored
Normal file
@ -0,0 +1,102 @@
|
||||
// @generated Code generated by gen-atomicint.
|
||||
|
||||
// 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 (
|
||||
"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(i uint64) *Uint64 {
|
||||
return &Uint64{v: i}
|
||||
}
|
||||
|
||||
// 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(n uint64) uint64 {
|
||||
return atomic.AddUint64(&i.v, n)
|
||||
}
|
||||
|
||||
// Sub atomically subtracts from the wrapped uint64 and returns the new value.
|
||||
func (i *Uint64) Sub(n uint64) uint64 {
|
||||
return atomic.AddUint64(&i.v, ^(n - 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.
|
||||
func (i *Uint64) CAS(old, new uint64) bool {
|
||||
return atomic.CompareAndSwapUint64(&i.v, old, new)
|
||||
}
|
||||
|
||||
// Store atomically stores the passed value.
|
||||
func (i *Uint64) Store(n uint64) {
|
||||
atomic.StoreUint64(&i.v, n)
|
||||
}
|
||||
|
||||
// Swap atomically swaps the wrapped uint64 and returns the old value.
|
||||
func (i *Uint64) Swap(n uint64) uint64 {
|
||||
return atomic.SwapUint64(&i.v, n)
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
31
vendor/go.uber.org/atomic/value.go
generated
vendored
Normal file
31
vendor/go.uber.org/atomic/value.go
generated
vendored
Normal file
@ -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 {
|
||||
atomic.Value
|
||||
|
||||
_ nocmp // disallow non-atomic comparison
|
||||
}
|
22
vendor/modules.txt
vendored
22
vendor/modules.txt
vendored
@ -1,6 +1,13 @@
|
||||
# github.com/go-ini/ini v1.62.0
|
||||
## explicit
|
||||
github.com/go-ini/ini
|
||||
# github.com/go-mysql-org/go-mysql v1.3.0
|
||||
## explicit
|
||||
github.com/go-mysql-org/go-mysql/client
|
||||
github.com/go-mysql-org/go-mysql/mysql
|
||||
github.com/go-mysql-org/go-mysql/packet
|
||||
github.com/go-mysql-org/go-mysql/replication
|
||||
github.com/go-mysql-org/go-mysql/utils
|
||||
# github.com/go-sql-driver/mysql v1.5.0
|
||||
## explicit
|
||||
github.com/go-sql-driver/mysql
|
||||
@ -9,10 +16,8 @@ github.com/go-sql-driver/mysql
|
||||
github.com/openark/golib/log
|
||||
github.com/openark/golib/sqlutils
|
||||
github.com/openark/golib/tests
|
||||
# github.com/pingcap/errors v0.11.0
|
||||
# github.com/pingcap/errors v0.11.5-0.20201126102027-b0a155152ca3
|
||||
github.com/pingcap/errors
|
||||
# github.com/pkg/errors v0.9.1
|
||||
## explicit
|
||||
# github.com/satori/go.uuid v1.2.0
|
||||
## explicit
|
||||
github.com/satori/go.uuid
|
||||
@ -23,15 +28,10 @@ github.com/siddontang/go/hack
|
||||
# github.com/siddontang/go-log v0.0.0-20180807004314-8d05993dda07
|
||||
github.com/siddontang/go-log/log
|
||||
github.com/siddontang/go-log/loggers
|
||||
# github.com/siddontang/go-mysql v1.1.0
|
||||
## explicit
|
||||
github.com/siddontang/go-mysql/client
|
||||
github.com/siddontang/go-mysql/mysql
|
||||
github.com/siddontang/go-mysql/packet
|
||||
github.com/siddontang/go-mysql/replication
|
||||
github.com/siddontang/go-mysql/utils
|
||||
# github.com/smartystreets/goconvey v1.6.4
|
||||
## explicit
|
||||
# go.uber.org/atomic v1.7.0
|
||||
go.uber.org/atomic
|
||||
# golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83
|
||||
## explicit
|
||||
golang.org/x/crypto/ssh/terminal
|
||||
@ -45,7 +45,7 @@ golang.org/x/sys/unix
|
||||
golang.org/x/sys/windows
|
||||
# golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1
|
||||
golang.org/x/term
|
||||
# golang.org/x/text v0.3.5
|
||||
# golang.org/x/text v0.3.6
|
||||
## explicit
|
||||
golang.org/x/text/encoding
|
||||
golang.org/x/text/encoding/charmap
|
||||
|
Loading…
Reference in New Issue
Block a user