diff --git a/example/example_test.go b/example/example_test.go index 45147eaa..04e19573 100644 --- a/example/example_test.go +++ b/example/example_test.go @@ -43,7 +43,7 @@ func TestGetLiveCell(t *testing.T) { } func TestAccount(t *testing.T) { - account := "00001.0001.bit" + account := "0๐Ÿ˜Š๐Ÿ˜Š0๐Ÿ˜Š0๐Ÿ˜Š0๐Ÿ˜Š1๐Ÿ˜Š.0001.bit" fmt.Println(account[strings.Index(account, "."):]) accountCharSet, err := common.AccountToAccountChars(account[:strings.Index(account, ".")]) fmt.Println(toolib.JsonString(accountCharSet), err) diff --git a/go.mod b/go.mod index 5c175073..51a710d6 100644 --- a/go.mod +++ b/go.mod @@ -3,17 +3,17 @@ module das_sub_account go 1.15 require ( - github.com/DeAccountSystems/das-lib v0.0.0-20220607033455-1b6e6e92f767 + github.com/DeAccountSystems/das-lib v0.0.0-20220620082742-eb52ca54a597 github.com/elazarl/goproxy v0.0.0-20220115173737-adb46da277ac // indirect github.com/fsnotify/fsnotify v1.4.9 github.com/gin-gonic/gin v1.7.2 github.com/go-redis/redis v6.15.9+incompatible github.com/nervosnetwork/ckb-sdk-go v0.101.3 github.com/parnurzeal/gorequest v0.2.16 - github.com/scorpiotzh/mylog v1.0.9 + github.com/scorpiotzh/mylog v1.0.10 github.com/scorpiotzh/toolib v1.1.3 github.com/urfave/cli/v2 v2.3.0 - go.mongodb.org/mongo-driver v1.8.3 + go.mongodb.org/mongo-driver v1.9.1 gorm.io/gorm v1.22.1 moul.io/http2curl v1.0.0 // indirect ) diff --git a/go.sum b/go.sum index 23e88337..4542778d 100644 --- a/go.sum +++ b/go.sum @@ -18,8 +18,8 @@ cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiy cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= collectd.org v0.3.0/go.mod h1:A/8DzQBkF6abtvrT2j/AU/4tiBgJWYyh0y/oB/4MlWE= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/Andrew-M-C/go.emoji v0.0.0-20211011074904-61cf526972e1 h1:KiwHOlG8KfvACyQI/qNWZJM9NEYbKelVTf6kJLG7qJ4= -github.com/Andrew-M-C/go.emoji v0.0.0-20211011074904-61cf526972e1/go.mod h1:cd0gn4deVZGTGyC4O1RoSRfHpVL/aBt/D7PZ8S1YQJg= +github.com/Andrew-M-C/go.emoji v1.0.1 h1:OpTpSPqJIg+OXxeDOxM9fYDvKHOuS1GTLVV9tuPGSAs= +github.com/Andrew-M-C/go.emoji v1.0.1/go.mod h1:XKiW1Wc2U6EhAbS7SSvolGTr7sBRRD2GYjGK/huPXCw= github.com/Azure/azure-sdk-for-go/sdk/azcore v0.21.1/go.mod h1:fBF9PQNqB8scdgpZ3ufzaLntG0AG7C1WjPMsiFOmfHM= github.com/Azure/azure-sdk-for-go/sdk/internal v0.8.3/go.mod h1:KLF4gFr6DcKFZwSuH8w8yEK6DpFl3LP5rhdvAb7Yz5I= github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.3.0/go.mod h1:tPaiy8S5bQ+S5sOiDlINkp7+Ef339+Nz5L5XO+cnOHo= @@ -27,8 +27,8 @@ github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= -github.com/DeAccountSystems/das-lib v0.0.0-20220607033455-1b6e6e92f767 h1:kvLl8SOlreDvs9zUnocjjQgiY6YoFD1HDO+o9pH5waU= -github.com/DeAccountSystems/das-lib v0.0.0-20220607033455-1b6e6e92f767/go.mod h1:ige8f+izCtnfXlKpc4iLR4CJHoaqYIoypL531X/KJp0= +github.com/DeAccountSystems/das-lib v0.0.0-20220620082742-eb52ca54a597 h1:UzjQsqRNPcLC+QZXFnb2AnfTCyoOC9l6uF0rn3p/7T0= +github.com/DeAccountSystems/das-lib v0.0.0-20220620082742-eb52ca54a597/go.mod h1:wmYE6+PqJvY/n9z/vwdG+zvoHeV57dXpLrtPrSvSAtw= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 h1:fLjPD/aNc3UIOA6tDi6QXUemppXK3P9BI7mr2hd6gx8= @@ -393,8 +393,8 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/scorpiotzh/mylog v1.0.9 h1:d7OGBnPeVy4zzldxULEuU3KY2TItrO4V/SRw4b/PjhY= -github.com/scorpiotzh/mylog v1.0.9/go.mod h1:pWl6kLNpTQK77W9eTWS70qaUsU9LKggSwm0rEyQ2Zyw= +github.com/scorpiotzh/mylog v1.0.10 h1:3ngGfBrWaljnKToeHuDzmaVyYE0QTGJJ024hQUqUzyQ= +github.com/scorpiotzh/mylog v1.0.10/go.mod h1:pWl6kLNpTQK77W9eTWS70qaUsU9LKggSwm0rEyQ2Zyw= github.com/scorpiotzh/toolib v1.1.3 h1:XSj4GC/XpiGfGbuFfzL1IhXW/B81wzQTMN9TCk+KcJQ= github.com/scorpiotzh/toolib v1.1.3/go.mod h1:ewfWxp6NUrCLuaJAf+wL5iqYRGqp9VAAyNuRsydk2OE= github.com/segmentio/kafka-go v0.1.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= @@ -460,8 +460,8 @@ github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6Ut github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.mongodb.org/mongo-driver v1.8.3 h1:TDKlTkGDKm9kkJVUOAXDK5/fkqKHJVwYQSpoRfB43R4= -go.mongodb.org/mongo-driver v1.8.3/go.mod h1:0sQWfOeY63QTntERDJJ/0SuKK0T1uVSgKCuAROlKEPY= +go.mongodb.org/mongo-driver v1.9.1 h1:m078y9v7sBItkt1aaoe2YlvWEXcD263e1a4E1fBrJ1c= +go.mongodb.org/mongo-driver v1.9.1/go.mod h1:0sQWfOeY63QTntERDJJ/0SuKK0T1uVSgKCuAROlKEPY= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= diff --git a/vendor/github.com/Andrew-M-C/go.emoji/official/emoji-sequences.go b/vendor/github.com/Andrew-M-C/go.emoji/official/emoji-sequences.go index 5fcf0bf0..7150b516 100644 --- a/vendor/github.com/Andrew-M-C/go.emoji/official/emoji-sequences.go +++ b/vendor/github.com/Andrew-M-C/go.emoji/official/emoji-sequences.go @@ -2,9 +2,9 @@ // Package official indicates official unicode emoji variables. // -// Reference: https://www.unicode.org/Public/emoji/14.0/ +// Reference: https://www.unicode.org/Public/emoji/15.0/ // -// Date: 2021-06-08, 05:19:16 GMT +// Date: 2022-05-06, 16:14:52 GMT package official func initAllSequences() { @@ -1612,6 +1612,8 @@ func initAllSequences() { AllSequences.AddSequence([]rune{0x1f6d6, 0xfe0e}, "Basic_Emoji ==> ๐Ÿ›–") AllSequences.AddSequence([]rune{0x1f6d7}, "Basic_Emoji ==> ๐Ÿ›—") AllSequences.AddSequence([]rune{0x1f6d7, 0xfe0e}, "Basic_Emoji ==> ๐Ÿ›—") + AllSequences.AddSequence([]rune{0x1f6dc}, "Basic_Emoji ==> ๐Ÿ›œ") + AllSequences.AddSequence([]rune{0x1f6dc, 0xfe0e}, "Basic_Emoji ==> ๐Ÿ›œ") AllSequences.AddSequence([]rune{0x1f6dd}, "Basic_Emoji ==> ๐Ÿ›") AllSequences.AddSequence([]rune{0x1f6dd, 0xfe0e}, "Basic_Emoji ==> ๐Ÿ›") AllSequences.AddSequence([]rune{0x1f6de}, "Basic_Emoji ==> ๐Ÿ›ž") @@ -2160,6 +2162,12 @@ func initAllSequences() { AllSequences.AddSequence([]rune{0x1fa73, 0xfe0e}, "Basic_Emoji ==> ๐Ÿฉณ") AllSequences.AddSequence([]rune{0x1fa74}, "Basic_Emoji ==> ๐Ÿฉด") AllSequences.AddSequence([]rune{0x1fa74, 0xfe0e}, "Basic_Emoji ==> ๐Ÿฉด") + AllSequences.AddSequence([]rune{0x1fa75}, "Basic_Emoji ==> ๐Ÿฉต") + AllSequences.AddSequence([]rune{0x1fa75, 0xfe0e}, "Basic_Emoji ==> ๐Ÿฉต") + AllSequences.AddSequence([]rune{0x1fa76}, "Basic_Emoji ==> ๐Ÿฉถ") + AllSequences.AddSequence([]rune{0x1fa76, 0xfe0e}, "Basic_Emoji ==> ๐Ÿฉถ") + AllSequences.AddSequence([]rune{0x1fa77}, "Basic_Emoji ==> ๐Ÿฉท") + AllSequences.AddSequence([]rune{0x1fa77, 0xfe0e}, "Basic_Emoji ==> ๐Ÿฉท") AllSequences.AddSequence([]rune{0x1fa78}, "Basic_Emoji ==> ๐Ÿฉธ") AllSequences.AddSequence([]rune{0x1fa78, 0xfe0e}, "Basic_Emoji ==> ๐Ÿฉธ") AllSequences.AddSequence([]rune{0x1fa79}, "Basic_Emoji ==> ๐Ÿฉน") @@ -2184,6 +2192,10 @@ func initAllSequences() { AllSequences.AddSequence([]rune{0x1fa85, 0xfe0e}, "Basic_Emoji ==> ๐Ÿช…") AllSequences.AddSequence([]rune{0x1fa86}, "Basic_Emoji ==> ๐Ÿช†") AllSequences.AddSequence([]rune{0x1fa86, 0xfe0e}, "Basic_Emoji ==> ๐Ÿช†") + AllSequences.AddSequence([]rune{0x1fa87}, "Basic_Emoji ==> ๐Ÿช‡") + AllSequences.AddSequence([]rune{0x1fa87, 0xfe0e}, "Basic_Emoji ==> ๐Ÿช‡") + AllSequences.AddSequence([]rune{0x1fa88}, "Basic_Emoji ==> ๐Ÿชˆ") + AllSequences.AddSequence([]rune{0x1fa88, 0xfe0e}, "Basic_Emoji ==> ๐Ÿชˆ") AllSequences.AddSequence([]rune{0x1fa90}, "Basic_Emoji ==> ๐Ÿช") AllSequences.AddSequence([]rune{0x1fa90, 0xfe0e}, "Basic_Emoji ==> ๐Ÿช") AllSequences.AddSequence([]rune{0x1fa91}, "Basic_Emoji ==> ๐Ÿช‘") @@ -2242,6 +2254,12 @@ func initAllSequences() { AllSequences.AddSequence([]rune{0x1faab, 0xfe0e}, "Basic_Emoji ==> ๐Ÿชซ") AllSequences.AddSequence([]rune{0x1faac}, "Basic_Emoji ==> ๐Ÿชฌ") AllSequences.AddSequence([]rune{0x1faac, 0xfe0e}, "Basic_Emoji ==> ๐Ÿชฌ") + AllSequences.AddSequence([]rune{0x1faad}, "Basic_Emoji ==> ๐Ÿชญ") + AllSequences.AddSequence([]rune{0x1faad, 0xfe0e}, "Basic_Emoji ==> ๐Ÿชญ") + AllSequences.AddSequence([]rune{0x1faae}, "Basic_Emoji ==> ๐Ÿชฎ") + AllSequences.AddSequence([]rune{0x1faae, 0xfe0e}, "Basic_Emoji ==> ๐Ÿชฎ") + AllSequences.AddSequence([]rune{0x1faaf}, "Basic_Emoji ==> ๐Ÿชฏ") + AllSequences.AddSequence([]rune{0x1faaf, 0xfe0e}, "Basic_Emoji ==> ๐Ÿชฏ") AllSequences.AddSequence([]rune{0x1fab0}, "Basic_Emoji ==> ๐Ÿชฐ") AllSequences.AddSequence([]rune{0x1fab0, 0xfe0e}, "Basic_Emoji ==> ๐Ÿชฐ") AllSequences.AddSequence([]rune{0x1fab1}, "Basic_Emoji ==> ๐Ÿชฑ") @@ -2264,6 +2282,14 @@ func initAllSequences() { AllSequences.AddSequence([]rune{0x1fab9, 0xfe0e}, "Basic_Emoji ==> ๐Ÿชน") AllSequences.AddSequence([]rune{0x1faba}, "Basic_Emoji ==> ๐Ÿชบ") AllSequences.AddSequence([]rune{0x1faba, 0xfe0e}, "Basic_Emoji ==> ๐Ÿชบ") + AllSequences.AddSequence([]rune{0x1fabb}, "Basic_Emoji ==> ๐Ÿชป") + AllSequences.AddSequence([]rune{0x1fabb, 0xfe0e}, "Basic_Emoji ==> ๐Ÿชป") + AllSequences.AddSequence([]rune{0x1fabc}, "Basic_Emoji ==> ๐Ÿชผ") + AllSequences.AddSequence([]rune{0x1fabc, 0xfe0e}, "Basic_Emoji ==> ๐Ÿชผ") + AllSequences.AddSequence([]rune{0x1fabd}, "Basic_Emoji ==> ๐Ÿชฝ") + AllSequences.AddSequence([]rune{0x1fabd, 0xfe0e}, "Basic_Emoji ==> ๐Ÿชฝ") + AllSequences.AddSequence([]rune{0x1fabf}, "Basic_Emoji ==> ๐Ÿชฟ") + AllSequences.AddSequence([]rune{0x1fabf, 0xfe0e}, "Basic_Emoji ==> ๐Ÿชฟ") AllSequences.AddSequence([]rune{0x1fac0}, "Basic_Emoji ==> ๐Ÿซ€") AllSequences.AddSequence([]rune{0x1fac0, 0xfe0e}, "Basic_Emoji ==> ๐Ÿซ€") AllSequences.AddSequence([]rune{0x1fac1}, "Basic_Emoji ==> ๐Ÿซ") @@ -2276,6 +2302,10 @@ func initAllSequences() { AllSequences.AddSequence([]rune{0x1fac4, 0xfe0e}, "Basic_Emoji ==> ๐Ÿซ„") AllSequences.AddSequence([]rune{0x1fac5}, "Basic_Emoji ==> ๐Ÿซ…") AllSequences.AddSequence([]rune{0x1fac5, 0xfe0e}, "Basic_Emoji ==> ๐Ÿซ…") + AllSequences.AddSequence([]rune{0x1face}, "Basic_Emoji ==> ๐ŸซŽ") + AllSequences.AddSequence([]rune{0x1face, 0xfe0e}, "Basic_Emoji ==> ๐ŸซŽ") + AllSequences.AddSequence([]rune{0x1facf}, "Basic_Emoji ==> ๐Ÿซ") + AllSequences.AddSequence([]rune{0x1facf, 0xfe0e}, "Basic_Emoji ==> ๐Ÿซ") AllSequences.AddSequence([]rune{0x1fad0}, "Basic_Emoji ==> ๐Ÿซ") AllSequences.AddSequence([]rune{0x1fad0, 0xfe0e}, "Basic_Emoji ==> ๐Ÿซ") AllSequences.AddSequence([]rune{0x1fad1}, "Basic_Emoji ==> ๐Ÿซ‘") @@ -2296,6 +2326,10 @@ func initAllSequences() { AllSequences.AddSequence([]rune{0x1fad8, 0xfe0e}, "Basic_Emoji ==> ๐Ÿซ˜") AllSequences.AddSequence([]rune{0x1fad9}, "Basic_Emoji ==> ๐Ÿซ™") AllSequences.AddSequence([]rune{0x1fad9, 0xfe0e}, "Basic_Emoji ==> ๐Ÿซ™") + AllSequences.AddSequence([]rune{0x1fada}, "Basic_Emoji ==> ๐Ÿซš") + AllSequences.AddSequence([]rune{0x1fada, 0xfe0e}, "Basic_Emoji ==> ๐Ÿซš") + AllSequences.AddSequence([]rune{0x1fadb}, "Basic_Emoji ==> ๐Ÿซ›") + AllSequences.AddSequence([]rune{0x1fadb, 0xfe0e}, "Basic_Emoji ==> ๐Ÿซ›") AllSequences.AddSequence([]rune{0x1fae0}, "Basic_Emoji ==> ๐Ÿซ ") AllSequences.AddSequence([]rune{0x1fae0, 0xfe0e}, "Basic_Emoji ==> ๐Ÿซ ") AllSequences.AddSequence([]rune{0x1fae1}, "Basic_Emoji ==> ๐Ÿซก") @@ -2312,6 +2346,8 @@ func initAllSequences() { AllSequences.AddSequence([]rune{0x1fae6, 0xfe0e}, "Basic_Emoji ==> ๐Ÿซฆ") AllSequences.AddSequence([]rune{0x1fae7}, "Basic_Emoji ==> ๐Ÿซง") AllSequences.AddSequence([]rune{0x1fae7, 0xfe0e}, "Basic_Emoji ==> ๐Ÿซง") + AllSequences.AddSequence([]rune{0x1fae8}, "Basic_Emoji ==> ๐Ÿซจ") + AllSequences.AddSequence([]rune{0x1fae8, 0xfe0e}, "Basic_Emoji ==> ๐Ÿซจ") AllSequences.AddSequence([]rune{0x1faf0}, "Basic_Emoji ==> ๐Ÿซฐ") AllSequences.AddSequence([]rune{0x1faf0, 0xfe0e}, "Basic_Emoji ==> ๐Ÿซฐ") AllSequences.AddSequence([]rune{0x1faf1}, "Basic_Emoji ==> ๐Ÿซฑ") @@ -2326,6 +2362,10 @@ func initAllSequences() { AllSequences.AddSequence([]rune{0x1faf5, 0xfe0e}, "Basic_Emoji ==> ๐Ÿซต") AllSequences.AddSequence([]rune{0x1faf6}, "Basic_Emoji ==> ๐Ÿซถ") AllSequences.AddSequence([]rune{0x1faf6, 0xfe0e}, "Basic_Emoji ==> ๐Ÿซถ") + AllSequences.AddSequence([]rune{0x1faf7}, "Basic_Emoji ==> ๐Ÿซท") + AllSequences.AddSequence([]rune{0x1faf7, 0xfe0e}, "Basic_Emoji ==> ๐Ÿซท") + AllSequences.AddSequence([]rune{0x1faf8}, "Basic_Emoji ==> ๐Ÿซธ") + AllSequences.AddSequence([]rune{0x1faf8, 0xfe0e}, "Basic_Emoji ==> ๐Ÿซธ") AllSequences.AddSequence([]rune{0x00a9, 0xfe0f}, "Basic_Emoji ==> ยฉ๏ธ") AllSequences.AddSequence([]rune{0x00ae, 0xfe0f}, "Basic_Emoji ==> ยฎ๏ธ") AllSequences.AddSequence([]rune{0x203c, 0xfe0f}, "Basic_Emoji ==> โ€ผ๏ธ") @@ -3451,6 +3491,16 @@ func initAllSequences() { AllSequences.AddSequence([]rune{0x1faf6, 0x1f3fd}, "RGI_Emoji_Modifier_Sequence ==> ๐Ÿซถ๐Ÿฝ") AllSequences.AddSequence([]rune{0x1faf6, 0x1f3fe}, "RGI_Emoji_Modifier_Sequence ==> ๐Ÿซถ๐Ÿพ") AllSequences.AddSequence([]rune{0x1faf6, 0x1f3ff}, "RGI_Emoji_Modifier_Sequence ==> ๐Ÿซถ๐Ÿฟ") + AllSequences.AddSequence([]rune{0x1faf7, 0x1f3fb}, "RGI_Emoji_Modifier_Sequence ==> ๐Ÿซท๐Ÿป") + AllSequences.AddSequence([]rune{0x1faf7, 0x1f3fc}, "RGI_Emoji_Modifier_Sequence ==> ๐Ÿซท๐Ÿผ") + AllSequences.AddSequence([]rune{0x1faf7, 0x1f3fd}, "RGI_Emoji_Modifier_Sequence ==> ๐Ÿซท๐Ÿฝ") + AllSequences.AddSequence([]rune{0x1faf7, 0x1f3fe}, "RGI_Emoji_Modifier_Sequence ==> ๐Ÿซท๐Ÿพ") + AllSequences.AddSequence([]rune{0x1faf7, 0x1f3ff}, "RGI_Emoji_Modifier_Sequence ==> ๐Ÿซท๐Ÿฟ") + AllSequences.AddSequence([]rune{0x1faf8, 0x1f3fb}, "RGI_Emoji_Modifier_Sequence ==> ๐Ÿซธ๐Ÿป") + AllSequences.AddSequence([]rune{0x1faf8, 0x1f3fc}, "RGI_Emoji_Modifier_Sequence ==> ๐Ÿซธ๐Ÿผ") + AllSequences.AddSequence([]rune{0x1faf8, 0x1f3fd}, "RGI_Emoji_Modifier_Sequence ==> ๐Ÿซธ๐Ÿฝ") + AllSequences.AddSequence([]rune{0x1faf8, 0x1f3fe}, "RGI_Emoji_Modifier_Sequence ==> ๐Ÿซธ๐Ÿพ") + AllSequences.AddSequence([]rune{0x1faf8, 0x1f3ff}, "RGI_Emoji_Modifier_Sequence ==> ๐Ÿซธ๐Ÿฟ") AllSequences.AddSequence([]rune{0x1f468, 0x200d, 0x2764, 0xfe0f, 0x200d, 0x1f468}, "RGI_Emoji_ZWJ_Sequence ==> ๐Ÿ‘จโ€โค๏ธโ€๐Ÿ‘จ") AllSequences.AddSequence([]rune{0x1f468, 0x200d, 0x2764, 0xfe0f, 0x200d, 0x1f48b, 0x200d, 0x1f468}, "RGI_Emoji_ZWJ_Sequence ==> ๐Ÿ‘จโ€โค๏ธโ€๐Ÿ’‹โ€๐Ÿ‘จ") AllSequences.AddSequence([]rune{0x1f468, 0x200d, 0x1f466}, "RGI_Emoji_ZWJ_Sequence ==> ๐Ÿ‘จโ€๐Ÿ‘ฆ") @@ -4794,6 +4844,7 @@ func initAllSequences() { AllSequences.AddSequence([]rune{0x1f3f4, 0x200d, 0x2620, 0xfe0f}, "RGI_Emoji_ZWJ_Sequence ==> ๐Ÿดโ€โ˜ ๏ธ") AllSequences.AddSequence([]rune{0x1f408, 0x200d, 0x2b1b}, "RGI_Emoji_ZWJ_Sequence ==> ๐Ÿˆโ€โฌ›") AllSequences.AddSequence([]rune{0x1f415, 0x200d, 0x1f9ba}, "RGI_Emoji_ZWJ_Sequence ==> ๐Ÿ•โ€๐Ÿฆบ") + AllSequences.AddSequence([]rune{0x1f426, 0x200d, 0x2b1b}, "RGI_Emoji_ZWJ_Sequence ==> ๐Ÿฆโ€โฌ›") AllSequences.AddSequence([]rune{0x1f43b, 0x200d, 0x2744, 0xfe0f}, "RGI_Emoji_ZWJ_Sequence ==> ๐Ÿปโ€โ„๏ธ") AllSequences.AddSequence([]rune{0x1f441, 0xfe0f, 0x200d, 0x1f5e8, 0xfe0f}, "RGI_Emoji_ZWJ_Sequence ==> ๐Ÿ‘๏ธโ€๐Ÿ—จ๏ธ") AllSequences.AddSequence([]rune{0x1f62e, 0x200d, 0x1f4a8}, "RGI_Emoji_ZWJ_Sequence ==> ๐Ÿ˜ฎโ€๐Ÿ’จ") diff --git a/vendor/github.com/Andrew-M-C/go.emoji/official/emoji-sequences.txt b/vendor/github.com/Andrew-M-C/go.emoji/official/emoji-sequences.txt index e8aa0fc9..f137a983 100644 --- a/vendor/github.com/Andrew-M-C/go.emoji/official/emoji-sequences.txt +++ b/vendor/github.com/Andrew-M-C/go.emoji/official/emoji-sequences.txt @@ -1,13 +1,13 @@ # emoji-sequences.txt -# Date: 2021-08-26, 17:22:22 GMT -# ยฉ 2021 Unicodeยฎ, Inc. +# Date: 2022-05-06, 16:14:52 GMT +# ยฉ 2022 Unicodeยฎ, Inc. # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. -# For terms of use, see http://www.unicode.org/terms_of_use.html +# For terms of use, see https://www.unicode.org/terms_of_use.html # # Emoji Sequence Data for UTS #51 -# Version: 14.0 +# Version: 15.0 # -# For documentation and usage, see http://www.unicode.org/reports/tr51 +# For documentation and usage, see https://www.unicode.org/reports/tr51 # # Format: # code_point(s) ; type_field ; description # comments @@ -238,6 +238,7 @@ 1F6D1..1F6D2 ; Basic_Emoji ; stop sign # E3.0 [2] (๐Ÿ›‘..๐Ÿ›’) 1F6D5 ; Basic_Emoji ; hindu temple # E12.0 [1] (๐Ÿ›•) 1F6D6..1F6D7 ; Basic_Emoji ; hut # E13.0 [2] (๐Ÿ›–..๐Ÿ›—) +1F6DC ; Basic_Emoji ; wireless # E15.0 [1] (๐Ÿ›œ) 1F6DD..1F6DF ; Basic_Emoji ; playground slide # E14.0 [3] (๐Ÿ›..๐Ÿ›Ÿ) 1F6EB..1F6EC ; Basic_Emoji ; airplane departure # E1.0 [2] (๐Ÿ›ซ..๐Ÿ›ฌ) 1F6F4..1F6F6 ; Basic_Emoji ; kick scooter # E3.0 [3] (๐Ÿ›ด..๐Ÿ›ถ) @@ -294,21 +295,30 @@ 1F9E7..1F9FF ; Basic_Emoji ; red envelope # E11.0 [25] (๐Ÿงง..๐Ÿงฟ) 1FA70..1FA73 ; Basic_Emoji ; ballet shoes # E12.0 [4] (๐Ÿฉฐ..๐Ÿฉณ) 1FA74 ; Basic_Emoji ; thong sandal # E13.0 [1] (๐Ÿฉด) +1FA75..1FA77 ; Basic_Emoji ; light blue heart # E15.0 [3] (๐Ÿฉต..๐Ÿฉท) 1FA78..1FA7A ; Basic_Emoji ; drop of blood # E12.0 [3] (๐Ÿฉธ..๐Ÿฉบ) 1FA7B..1FA7C ; Basic_Emoji ; x-ray # E14.0 [2] (๐Ÿฉป..๐Ÿฉผ) 1FA80..1FA82 ; Basic_Emoji ; yo-yo # E12.0 [3] (๐Ÿช€..๐Ÿช‚) 1FA83..1FA86 ; Basic_Emoji ; boomerang # E13.0 [4] (๐Ÿชƒ..๐Ÿช†) +1FA87..1FA88 ; Basic_Emoji ; maracas # E15.0 [2] (๐Ÿช‡..๐Ÿชˆ) 1FA90..1FA95 ; Basic_Emoji ; ringed planet # E12.0 [6] (๐Ÿช..๐Ÿช•) 1FA96..1FAA8 ; Basic_Emoji ; military helmet # E13.0 [19] (๐Ÿช–..๐Ÿชจ) 1FAA9..1FAAC ; Basic_Emoji ; mirror ball # E14.0 [4] (๐Ÿชฉ..๐Ÿชฌ) +1FAAD..1FAAF ; Basic_Emoji ; folding hand fan # E15.0 [3] (๐Ÿชญ..๐Ÿชฏ) 1FAB0..1FAB6 ; Basic_Emoji ; fly # E13.0 [7] (๐Ÿชฐ..๐Ÿชถ) 1FAB7..1FABA ; Basic_Emoji ; lotus # E14.0 [4] (๐Ÿชท..๐Ÿชบ) +1FABB..1FABD ; Basic_Emoji ; hyacinth # E15.0 [3] (๐Ÿชป..๐Ÿชฝ) +1FABF ; Basic_Emoji ; goose # E15.0 [1] (๐Ÿชฟ) 1FAC0..1FAC2 ; Basic_Emoji ; anatomical heart # E13.0 [3] (๐Ÿซ€..๐Ÿซ‚) 1FAC3..1FAC5 ; Basic_Emoji ; pregnant man # E14.0 [3] (๐Ÿซƒ..๐Ÿซ…) +1FACE..1FACF ; Basic_Emoji ; moose # E15.0 [2] (๐ŸซŽ..๐Ÿซ) 1FAD0..1FAD6 ; Basic_Emoji ; blueberries # E13.0 [7] (๐Ÿซ..๐Ÿซ–) 1FAD7..1FAD9 ; Basic_Emoji ; pouring liquid # E14.0 [3] (๐Ÿซ—..๐Ÿซ™) +1FADA..1FADB ; Basic_Emoji ; ginger root # E15.0 [2] (๐Ÿซš..๐Ÿซ›) 1FAE0..1FAE7 ; Basic_Emoji ; melting face # E14.0 [8] (๐Ÿซ ..๐Ÿซง) +1FAE8 ; Basic_Emoji ; shaking face # E15.0 [1] (๐Ÿซจ) 1FAF0..1FAF6 ; Basic_Emoji ; hand with index finger and thumb crossed # E14.0 [7] (๐Ÿซฐ..๐Ÿซถ) +1FAF7..1FAF8 ; Basic_Emoji ; leftwards pushing hand # E15.0 [2] (๐Ÿซท..๐Ÿซธ) 00A9 FE0F ; Basic_Emoji ; copyright # E0.6 [1] (ยฉ๏ธ) 00AE FE0F ; Basic_Emoji ; registered # E0.6 [1] (ยฎ๏ธ) 203C FE0F ; Basic_Emoji ; double exclamation mark # E0.6 [1] (โ€ผ๏ธ) @@ -517,7 +527,7 @@ 1F6F0 FE0F ; Basic_Emoji ; satellite # E0.7 [1] (๐Ÿ›ฐ๏ธ) 1F6F3 FE0F ; Basic_Emoji ; passenger ship # E0.7 [1] (๐Ÿ›ณ๏ธ) -# Total elements: 1366 +# Total elements: 1386 # ================================================ @@ -1463,7 +1473,17 @@ 1FAF6 1F3FD ; RGI_Emoji_Modifier_Sequence ; heart hands: medium skin tone # E14.0 [1] (๐Ÿซถ๐Ÿฝ) 1FAF6 1F3FE ; RGI_Emoji_Modifier_Sequence ; heart hands: medium-dark skin tone # E14.0 [1] (๐Ÿซถ๐Ÿพ) 1FAF6 1F3FF ; RGI_Emoji_Modifier_Sequence ; heart hands: dark skin tone # E14.0 [1] (๐Ÿซถ๐Ÿฟ) +1FAF7 1F3FB ; RGI_Emoji_Modifier_Sequence ; leftwards pushing hand: light skin tone # E15.0 [1] (๐Ÿซท๐Ÿป) +1FAF7 1F3FC ; RGI_Emoji_Modifier_Sequence ; leftwards pushing hand: medium-light skin tone # E15.0 [1] (๐Ÿซท๐Ÿผ) +1FAF7 1F3FD ; RGI_Emoji_Modifier_Sequence ; leftwards pushing hand: medium skin tone # E15.0 [1] (๐Ÿซท๐Ÿฝ) +1FAF7 1F3FE ; RGI_Emoji_Modifier_Sequence ; leftwards pushing hand: medium-dark skin tone # E15.0 [1] (๐Ÿซท๐Ÿพ) +1FAF7 1F3FF ; RGI_Emoji_Modifier_Sequence ; leftwards pushing hand: dark skin tone # E15.0 [1] (๐Ÿซท๐Ÿฟ) +1FAF8 1F3FB ; RGI_Emoji_Modifier_Sequence ; rightwards pushing hand: light skin tone # E15.0 [1] (๐Ÿซธ๐Ÿป) +1FAF8 1F3FC ; RGI_Emoji_Modifier_Sequence ; rightwards pushing hand: medium-light skin tone # E15.0 [1] (๐Ÿซธ๐Ÿผ) +1FAF8 1F3FD ; RGI_Emoji_Modifier_Sequence ; rightwards pushing hand: medium skin tone # E15.0 [1] (๐Ÿซธ๐Ÿฝ) +1FAF8 1F3FE ; RGI_Emoji_Modifier_Sequence ; rightwards pushing hand: medium-dark skin tone # E15.0 [1] (๐Ÿซธ๐Ÿพ) +1FAF8 1F3FF ; RGI_Emoji_Modifier_Sequence ; rightwards pushing hand: dark skin tone # E15.0 [1] (๐Ÿซธ๐Ÿฟ) -# Total elements: 645 +# Total elements: 655 #EOF diff --git a/vendor/github.com/Andrew-M-C/go.emoji/official/emoji-zwj-sequences.txt b/vendor/github.com/Andrew-M-C/go.emoji/official/emoji-zwj-sequences.txt index 1d64edcd..c71fe183 100644 --- a/vendor/github.com/Andrew-M-C/go.emoji/official/emoji-zwj-sequences.txt +++ b/vendor/github.com/Andrew-M-C/go.emoji/official/emoji-zwj-sequences.txt @@ -1,13 +1,13 @@ # emoji-zwj-sequences.txt -# Date: 2021-06-08, 05:19:16 GMT -# ยฉ 2021 Unicodeยฎ, Inc. +# Date: 2022-05-06, 16:14:52 GMT +# ยฉ 2022 Unicodeยฎ, Inc. # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. -# For terms of use, see http://www.unicode.org/terms_of_use.html +# For terms of use, see https://www.unicode.org/terms_of_use.html # # Emoji ZWJ Sequences for UTS #51 -# Version: 14.0 +# Version: 15.0 # -# For documentation and usage, see http://www.unicode.org/reports/tr51 +# For documentation and usage, see https://www.unicode.org/reports/tr51 # # Format: # code_point(s) ; type_field ; description # comments @@ -1398,6 +1398,7 @@ 1F3F4 200D 2620 FE0F ; RGI_Emoji_ZWJ_Sequence ; pirate flag # E11.0 [1] (๐Ÿดโ€โ˜ ๏ธ) 1F408 200D 2B1B ; RGI_Emoji_ZWJ_Sequence ; black cat # E13.0 [1] (๐Ÿˆโ€โฌ›) 1F415 200D 1F9BA ; RGI_Emoji_ZWJ_Sequence ; service dog # E12.0 [1] (๐Ÿ•โ€๐Ÿฆบ) +1F426 200D 2B1B ; RGI_Emoji_ZWJ_Sequence ; black bird # E15.0 [1] (๐Ÿฆโ€โฌ›) 1F43B 200D 2744 FE0F ; RGI_Emoji_ZWJ_Sequence ; polar bear # E13.0 [1] (๐Ÿปโ€โ„๏ธ) 1F441 FE0F 200D 1F5E8 FE0F ; RGI_Emoji_ZWJ_Sequence ; eye in speech bubble # E2.0 [1] (๐Ÿ‘๏ธโ€๐Ÿ—จ๏ธ) 1F62E 200D 1F4A8 ; RGI_Emoji_ZWJ_Sequence ; face exhaling # E13.1 [1] (๐Ÿ˜ฎโ€๐Ÿ’จ) @@ -1405,6 +1406,6 @@ 1F636 200D 1F32B FE0F ; RGI_Emoji_ZWJ_Sequence ; face in clouds # E13.1 [1] (๐Ÿ˜ถโ€๐ŸŒซ๏ธ) 1F9D1 200D 1F384 ; RGI_Emoji_ZWJ_Sequence ; mx claus # E13.0 [1] (๐Ÿง‘โ€๐ŸŽ„) -# Total elements: 13 +# Total elements: 14 #EOF diff --git a/vendor/github.com/DeAccountSystems/das-lib/common/action.go b/vendor/github.com/DeAccountSystems/das-lib/common/action.go index 508e298f..91fbd5e3 100644 --- a/vendor/github.com/DeAccountSystems/das-lib/common/action.go +++ b/vendor/github.com/DeAccountSystems/das-lib/common/action.go @@ -34,18 +34,18 @@ const ( DasActionCancelOffer DasAction = "cancel_offer" DasActionAcceptOffer DasAction = "accept_offer" - DasActionEnableSubAccount DasAction = "enable_sub_account" - DasActionCreateSubAccount DasAction = "create_sub_account" - DasActionEditSubAccount DasAction = "edit_sub_account" - DasActionRenewSubAccount DasAction = "renew_sub_account" - DasActionRecycleSubAccount DasAction = "recycle_sub_account" - - DasActionLockAccountForCrossChain DasAction = "lock_account_for_cross_chain" - DasActionUnlockAccountForCrossChain DasAction = "unlock_account_for_cross_chain" + DasActionEnableSubAccount DasAction = "enable_sub_account" + DasActionCreateSubAccount DasAction = "create_sub_account" + DasActionEditSubAccount DasAction = "edit_sub_account" + DasActionRenewSubAccount DasAction = "renew_sub_account" + DasActionRecycleSubAccount DasAction = "recycle_sub_account" DasActionLockSubAccountForCrossChain DasAction = "lock_sub_account_for_cross_chain" DasActionUnlockSubAccountForCrossChain DasAction = "unlock_sub_account_for_cross_chain" - DasActionRecycleExpiredAccount DasAction = "recycle_expired_account" + DasActionLockAccountForCrossChain DasAction = "lock_account_for_cross_chain" + DasActionUnlockAccountForCrossChain DasAction = "unlock_account_for_cross_chain" + DasActionForceRecoverAccountStatus DasAction = "force_recover_account_status" + DasActionRecycleExpiredAccount DasAction = "recycle_expired_account" ) const ( diff --git a/vendor/github.com/DeAccountSystems/das-lib/common/char_set.go b/vendor/github.com/DeAccountSystems/das-lib/common/char_set.go index 1e2b3d18..b08e7ce3 100644 --- a/vendor/github.com/DeAccountSystems/das-lib/common/char_set.go +++ b/vendor/github.com/DeAccountSystems/das-lib/common/char_set.go @@ -17,7 +17,7 @@ const ( var CharSetTypeEmojiMap = make(map[string]struct{}) const ( - CharSetTypeNumber = "0123456789" + CharSetTypeNumber = "0123456789-" CharSetTypeEn = "abcdefghijklmnopqrstuvwxyz" ) @@ -42,12 +42,13 @@ func AccountCharsToAccount(accountChars *molecule.AccountChars) string { } func AccountToAccountChars(account string) ([]AccountCharSet, error) { - if strings.HasSuffix(account, DasAccountSuffix) { - account = strings.TrimSuffix(account, DasAccountSuffix) + if index := strings.Index(account, "."); index > 0 { + account = account[:index] } + chars := []rune(account) var list []AccountCharSet - for _, v := range account { + for _, v := range chars { char := string(v) var charSetName AccountCharType if _, ok := CharSetTypeEmojiMap[char]; ok { diff --git a/vendor/github.com/DeAccountSystems/das-lib/core/config_cell.go b/vendor/github.com/DeAccountSystems/das-lib/core/config_cell.go index 874736ea..694ca8f2 100644 --- a/vendor/github.com/DeAccountSystems/das-lib/core/config_cell.go +++ b/vendor/github.com/DeAccountSystems/das-lib/core/config_cell.go @@ -59,7 +59,16 @@ func (d *DasCore) InitDasConfigCell() error { DasConfigCellMap.Store(common.ConfigCellTypeArgsCharSetHanS, &DasConfigCellInfo{Name: "CharSetHanS"}) DasConfigCellMap.Store(common.ConfigCellTypeArgsCharSetHanT, &DasConfigCellInfo{Name: "CharSetHanT"}) - return d.AsyncDasConfigCell() + if err := d.AsyncDasConfigCell(); err != nil { + return fmt.Errorf("AsyncDasConfigCell err: %s", err.Error()) + } + builder, err := d.ConfigCellDataBuilderByTypeArgs(common.ConfigCellTypeArgsCharSetEmoji) + if err != nil { + return fmt.Errorf("ConfigCellDataBuilderByTypeArgs err: %s", err.Error()) + } + common.InitEmoji(builder.ConfigCellEmojis) + + return nil } func (d *DasCore) RunAsyncDasConfigCell(t time.Duration) { @@ -118,12 +127,6 @@ func (d *DasCore) AsyncDasConfigCell() error { } } } - - builder, err := d.ConfigCellDataBuilderByTypeArgs(common.ConfigCellTypeArgsCharSetEmoji) - if err != nil { - return fmt.Errorf("ConfigCellDataBuilderByTypeArgs err: %s", err.Error()) - } - common.InitEmoji(builder.ConfigCellEmojis) return nil } diff --git a/vendor/github.com/DeAccountSystems/das-lib/txbuilder/tx.go b/vendor/github.com/DeAccountSystems/das-lib/txbuilder/tx.go index 414a5ef9..a3561f40 100644 --- a/vendor/github.com/DeAccountSystems/das-lib/txbuilder/tx.go +++ b/vendor/github.com/DeAccountSystems/das-lib/txbuilder/tx.go @@ -41,6 +41,9 @@ func (d *DasTxBuilder) addInputsForTx(inputs []*types.CellInput) error { var cellDepList []*types.CellDep for i, v := range inputs { + if v == nil { + return fmt.Errorf("input is nil") + } item, err := d.getInputCell(v.PreviousOutput) if err != nil { return fmt.Errorf("getInputCell err: %s", err.Error()) diff --git a/vendor/github.com/DeAccountSystems/das-lib/witness/account_cell.go b/vendor/github.com/DeAccountSystems/das-lib/witness/account_cell.go index 6a056795..e297484a 100644 --- a/vendor/github.com/DeAccountSystems/das-lib/witness/account_cell.go +++ b/vendor/github.com/DeAccountSystems/das-lib/witness/account_cell.go @@ -367,7 +367,8 @@ func (a *AccountCellDataBuilder) GenWitness(p *AccountCellParam) ([]byte, []byte return witness, common.Blake2b(newAccountCellData.AsSlice()), nil case common.DasActionCreateSubAccount: oldDataEntityOpt := a.getOldDataEntityOpt(p) - newAccountCellData := a.getNewAccountCellDataBuilder().Build() + newBuilder := a.getNewAccountCellDataBuilder() + newAccountCellData := newBuilder.Build() newAccountCellDataBytes := molecule.GoBytes2MoleculeBytes(newAccountCellData.AsSlice()) newDataEntity := molecule.NewDataEntityBuilder().Entity(newAccountCellDataBytes). @@ -392,7 +393,7 @@ func (a *AccountCellDataBuilder) GenWitness(p *AccountCellParam) ([]byte, []byte tmp := molecule.NewDataBuilder().Old(*oldDataEntityOpt).New(newDataEntityOpt).Build() witness := GenDasDataWitness(common.ActionDataTypeAccountCell, &tmp) return witness, common.Blake2b(newAccountCellData.AsSlice()), nil - case common.DasActionUnlockAccountForCrossChain: + case common.DasActionUnlockAccountForCrossChain, common.DasActionForceRecoverAccountStatus: oldDataEntityOpt := a.getOldDataEntityOpt(p) newBuilder := a.getNewAccountCellDataBuilder() newBuilder.Status(molecule.GoU8ToMoleculeU8(p.Status)) @@ -406,6 +407,29 @@ func (a *AccountCellDataBuilder) GenWitness(p *AccountCellParam) ([]byte, []byte tmp := molecule.NewDataBuilder().Old(*oldDataEntityOpt).New(newDataEntityOpt).Build() witness := GenDasDataWitness(common.ActionDataTypeAccountCell, &tmp) return witness, common.Blake2b(newAccountCellData.AsSlice()), nil + case common.DasActionRecycleExpiredAccount: + if p.SubAction == "previous" { + oldDataEntityOpt := a.getOldDataEntityOpt(p) + newBuilder := a.getNewAccountCellDataBuilder() + newAccountCellData := newBuilder.Build() + newAccountCellDataBytes := molecule.GoBytes2MoleculeBytes(newAccountCellData.AsSlice()) + + newDataEntity := molecule.NewDataEntityBuilder().Entity(newAccountCellDataBytes). + Version(DataEntityVersion3).Index(molecule.GoU32ToMoleculeU32(p.NewIndex)).Build() + newDataEntityOpt := molecule.NewDataEntityOptBuilder().Set(newDataEntity).Build() + + tmp := molecule.NewDataBuilder().Old(*oldDataEntityOpt).New(newDataEntityOpt).Build() + witness := GenDasDataWitness(common.ActionDataTypeAccountCell, &tmp) + return witness, common.Blake2b(newAccountCellData.AsSlice()), nil + } else if p.SubAction == "current" { + oldDataEntityOpt := a.getOldDataEntityOpt(p) + + tmp := molecule.NewDataBuilder().Old(*oldDataEntityOpt).Build() + witness := GenDasDataWitness(common.ActionDataTypeAccountCell, &tmp) + return witness, nil, nil + } else { + return nil, nil, fmt.Errorf("not exist sub action [%s]", p.SubAction) + } } return nil, nil, fmt.Errorf("not exist action [%s]", p.Action) } diff --git a/vendor/github.com/DeAccountSystems/das-lib/witness/account_sale_cell.go b/vendor/github.com/DeAccountSystems/das-lib/witness/account_sale_cell.go index cf875ccf..6c9438a0 100644 --- a/vendor/github.com/DeAccountSystems/das-lib/witness/account_sale_cell.go +++ b/vendor/github.com/DeAccountSystems/das-lib/witness/account_sale_cell.go @@ -131,7 +131,7 @@ func (a *AccountSaleCellDataBuilder) GenWitness(p *AccountSaleCellParam) ([]byte tmp := molecule.NewDataBuilder().New(newDataEntityOpt).Build() witness := GenDasDataWitness(common.ActionDataTypeAccountSaleCell, &tmp) return witness, common.Blake2b(newAccountSaleCellData.AsSlice()), nil - case common.DasActionCancelAccountSale, common.DasActionBuyAccount: + case common.DasActionCancelAccountSale, common.DasActionBuyAccount, common.DasActionForceRecoverAccountStatus: oldDataEntityOpt := a.getOldDataEntityOpt(p) tmp := molecule.NewDataBuilder().Old(*oldDataEntityOpt).Build() diff --git a/vendor/github.com/DeAccountSystems/das-lib/witness/config_cell.go b/vendor/github.com/DeAccountSystems/das-lib/witness/config_cell.go index e9eabe34..434e1474 100644 --- a/vendor/github.com/DeAccountSystems/das-lib/witness/config_cell.go +++ b/vendor/github.com/DeAccountSystems/das-lib/witness/config_cell.go @@ -24,6 +24,7 @@ type ConfigCellDataBuilder struct { ConfigCellSubAccount *molecule.ConfigCellSubAccount ConfigCellRecordKeys []string ConfigCellEmojis []string + ConfigCellCharSetEn []string ConfigCellUnavailableAccountMap map[string]struct{} ConfigCellPreservedAccountMap map[string]struct{} ConfigCellSubAccountWhiteListMap map[string]struct{} @@ -137,6 +138,18 @@ func ConfigCellDataBuilderRefByTypeArgs(builder *ConfigCellDataBuilder, tx *type return fmt.Errorf("char set emoji err: %s", err.Error()) } builder.ConfigCellEmojis = strings.Split(string(configCellDataBys[4:dataLength]), string([]byte{0x00})) + case common.ConfigCellTypeArgsCharSetDigit: + dataLength, err := molecule.Bytes2GoU32(configCellDataBys[:4]) + if err != nil { + return fmt.Errorf("char set emoji err: %s", err.Error()) + } + fmt.Println(strings.Split(string(configCellDataBys[4:dataLength]), string([]byte{0x00}))) + case common.ConfigCellTypeArgsCharSetEn: + dataLength, err := molecule.Bytes2GoU32(configCellDataBys[:4]) + if err != nil { + return fmt.Errorf("char set emoji err: %s", err.Error()) + } + builder.ConfigCellCharSetEn = strings.Split(string(configCellDataBys[4:dataLength]), string([]byte{0x00})) case common.ConfigCellTypeArgsUnavailable: if builder.ConfigCellUnavailableAccountMap == nil { builder.ConfigCellUnavailableAccountMap = make(map[string]struct{}) diff --git a/vendor/github.com/DeAccountSystems/das-lib/witness/witness_parser.go b/vendor/github.com/DeAccountSystems/das-lib/witness/witness_parser.go index 83ba95ab..cbef2e46 100644 --- a/vendor/github.com/DeAccountSystems/das-lib/witness/witness_parser.go +++ b/vendor/github.com/DeAccountSystems/das-lib/witness/witness_parser.go @@ -682,7 +682,7 @@ func ParserOfferCell(witnessByte []byte) interface{} { } func ParserSubAccount(witnessByte []byte) interface{} { - builder, _ := SubAccountBuilderFromBytes(witnessByte) + builder, _ := SubAccountBuilderFromBytes(witnessByte[common.WitnessDasTableTypeEndIndex:]) if builder == nil { return parserDefaultWitness(witnessByte) } @@ -1107,7 +1107,7 @@ func ParserConfigCellSubAccount(witnessByte []byte) interface{} { return map[string]interface{}{ "witness": common.Bytes2Hex(witnessByte), "witness_hash": common.Bytes2Hex(common.Blake2b(configCellSubAccount.AsSlice())), - "name": "ConfigCellReverseRecord", + "name": "ConfigCellSubAccount", "data": map[string]interface{}{ "basic_capacity": ConvertCapacity(basicCapacity), "prepared_fee_capacity": ConvertCapacity(preparedFeeCapacity), diff --git a/vendor/github.com/scorpiotzh/mylog/README.md b/vendor/github.com/scorpiotzh/mylog/README.md index 26f28414..031b8984 100644 --- a/vendor/github.com/scorpiotzh/mylog/README.md +++ b/vendor/github.com/scorpiotzh/mylog/README.md @@ -23,8 +23,7 @@ log.Errorf("aaa %s aaa", "bbb") * log > file ```go -InitMyLog(nil) -log := NewLogger("file", LevelDebug) +log := NewLoggerDefault("test", LevelDebug, nil) log.Debug("aaaaa") log.Debugf("aaa %s aaa", "bbb") diff --git a/vendor/github.com/scorpiotzh/mylog/init.go b/vendor/github.com/scorpiotzh/mylog/init.go index 5551ac8d..62c3d7bf 100644 --- a/vendor/github.com/scorpiotzh/mylog/init.go +++ b/vendor/github.com/scorpiotzh/mylog/init.go @@ -41,8 +41,8 @@ func initLog() *zap.SugaredLogger { return zapLogger.Sugar() } -func NewLogger(name string, level int) *logger { - return &logger{ +func NewLogger(name string, level int) *Logger { + return &Logger{ name: name, level: level, log: initLog(), @@ -75,8 +75,8 @@ func initDefaultLog(fileOut *lumberjack.Logger) *zap.SugaredLogger { return zapLogger.Sugar() } -func NewLoggerDefault(name string, level int, fileOut *lumberjack.Logger) *logger { - return &logger{ +func NewLoggerDefault(name string, level int, fileOut *lumberjack.Logger) *Logger { + return &Logger{ name: name, level: level, log: initDefaultLog(fileOut), diff --git a/vendor/github.com/scorpiotzh/mylog/log.go b/vendor/github.com/scorpiotzh/mylog/log.go index 1c8e98a5..f7a87cce 100644 --- a/vendor/github.com/scorpiotzh/mylog/log.go +++ b/vendor/github.com/scorpiotzh/mylog/log.go @@ -24,17 +24,17 @@ const ( colorFatal = 91 ) -type logger struct { +type Logger struct { log *zap.SugaredLogger name string level int } -func (l *logger) ErrStack() { +func (l *Logger) ErrStack() { l.Warn(string(debug.Stack())) } -func (l *logger) Debugf(format string, a ...interface{}) { +func (l *Logger) Debugf(format string, a ...interface{}) { if l.level > LevelDebug { return } @@ -42,7 +42,7 @@ func (l *logger) Debugf(format string, a ...interface{}) { l.log.Debug(msg) } -func (l *logger) Infof(format string, a ...interface{}) { +func (l *Logger) Infof(format string, a ...interface{}) { if l.level > LevelInfo { return } @@ -50,7 +50,7 @@ func (l *logger) Infof(format string, a ...interface{}) { l.log.Info(msg) } -func (l *logger) Warnf(format string, a ...interface{}) { +func (l *Logger) Warnf(format string, a ...interface{}) { if l.level > LevelWarn { return } @@ -58,7 +58,7 @@ func (l *logger) Warnf(format string, a ...interface{}) { l.log.Warn(msg) } -func (l *logger) Errorf(format string, a ...interface{}) { +func (l *Logger) Errorf(format string, a ...interface{}) { if l.level > LevelError { return } @@ -66,7 +66,7 @@ func (l *logger) Errorf(format string, a ...interface{}) { l.log.Error(msg) } -func (l *logger) Panicf(format string, a ...interface{}) { +func (l *Logger) Panicf(format string, a ...interface{}) { if l.level > LevelPanic { return } @@ -74,7 +74,7 @@ func (l *logger) Panicf(format string, a ...interface{}) { l.log.Panic(msg) } -func (l *logger) Fatalf(format string, a ...interface{}) { +func (l *Logger) Fatalf(format string, a ...interface{}) { if l.level > LevelFatal { return } @@ -82,7 +82,7 @@ func (l *logger) Fatalf(format string, a ...interface{}) { l.log.Fatal(msg) } -func (l *logger) Debug(a ...interface{}) { +func (l *Logger) Debug(a ...interface{}) { if l.level > LevelDebug { return } @@ -90,7 +90,7 @@ func (l *logger) Debug(a ...interface{}) { l.log.Debug(msg) } -func (l *logger) Info(a ...interface{}) { +func (l *Logger) Info(a ...interface{}) { if l.level > LevelInfo { return } @@ -98,7 +98,7 @@ func (l *logger) Info(a ...interface{}) { l.log.Info(msg) } -func (l *logger) Warn(a ...interface{}) { +func (l *Logger) Warn(a ...interface{}) { if l.level > LevelWarn { return } @@ -106,7 +106,7 @@ func (l *logger) Warn(a ...interface{}) { l.log.Warn(msg) } -func (l *logger) Error(a ...interface{}) { +func (l *Logger) Error(a ...interface{}) { if l.level > LevelError { return } @@ -114,7 +114,7 @@ func (l *logger) Error(a ...interface{}) { l.log.Error(msg) } -func (l *logger) Panic(a ...interface{}) { +func (l *Logger) Panic(a ...interface{}) { if l.level > LevelPanic { return } @@ -122,7 +122,7 @@ func (l *logger) Panic(a ...interface{}) { l.log.Panic(msg) } -func (l *logger) Fatal(a ...interface{}) { +func (l *Logger) Fatal(a ...interface{}) { if l.level > LevelFatal { return } diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/bsoncodec.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/bsoncodec.go index 2c861b5c..96195bcc 100644 --- a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/bsoncodec.go +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/bsoncodec.go @@ -43,7 +43,7 @@ type Unmarshaler interface { } // ValueUnmarshaler is an interface implemented by types that can unmarshal a -// BSON value representaiton of themselves. The BSON bytes and type can be +// BSON value representation of themselves. The BSON bytes and type can be // assumed to be valid. UnmarshalBSONValue must copy the BSON value bytes if it // wishes to retain the data after returning. type ValueUnmarshaler interface { diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/default_value_decoders.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/default_value_decoders.go index 32fd1427..20f4797d 100644 --- a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/default_value_decoders.go +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/default_value_decoders.go @@ -53,7 +53,7 @@ type DefaultValueDecoders struct{} // RegisterDefaultDecoders will register the decoder methods attached to DefaultValueDecoders with // the provided RegistryBuilder. // -// There is no support for decoding map[string]interface{} becuase there is no decoder for +// There is no support for decoding map[string]interface{} because there is no decoder for // interface{}, so users must either register this decoder themselves or use the // EmptyInterfaceDecoder available in the bson package. func (dvd DefaultValueDecoders) RegisterDefaultDecoders(rb *RegistryBuilder) { @@ -1504,6 +1504,18 @@ func (dvd DefaultValueDecoders) UnmarshalerDecodeValue(dc DecodeContext, vr bson return err } + // If the target Go value is a pointer and the BSON field value is empty, set the value to the + // zero value of the pointer (nil) and don't call UnmarshalBSON. UnmarshalBSON has no way to + // change the pointer value from within the function (only the value at the pointer address), + // so it can't set the pointer to "nil" itself. Since the most common Go value for an empty BSON + // field value is "nil", we set "nil" here and don't call UnmarshalBSON. This behavior matches + // the behavior of the Go "encoding/json" unmarshaler when the target Go value is a pointer and + // the JSON field value is "null". + if val.Kind() == reflect.Ptr && len(src) == 0 { + val.Set(reflect.Zero(val.Type())) + return nil + } + fn := val.Convert(tUnmarshaler).MethodByName("UnmarshalBSON") errVal := fn.Call([]reflect.Value{reflect.ValueOf(src)})[0] if !errVal.IsNil() { diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/registry.go b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/registry.go index 02b9341f..f6f3800d 100644 --- a/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/registry.go +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsoncodec/registry.go @@ -298,7 +298,7 @@ func (rb *RegistryBuilder) Build() *Registry { return registry } -// LookupEncoder inspects the registry for an encoder for the given type. The lookup precendence works as follows: +// LookupEncoder inspects the registry for an encoder for the given type. The lookup precedence works as follows: // // 1. An encoder registered for the exact type. If the given type represents an interface, an encoder registered using // RegisterTypeEncoder for the interface will be selected. @@ -376,7 +376,7 @@ func (r *Registry) lookupInterfaceEncoder(t reflect.Type, allowAddr bool) (Value return nil, false } -// LookupDecoder inspects the registry for an decoder for the given type. The lookup precendence works as follows: +// LookupDecoder inspects the registry for an decoder for the given type. The lookup precedence works as follows: // // 1. A decoder registered for the exact type. If the given type represents an interface, a decoder registered using // RegisterTypeDecoder for the interface will be selected. diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_parser.go b/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_parser.go index 8a690e37..54c76bf7 100644 --- a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_parser.go +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/extjson_parser.go @@ -423,7 +423,7 @@ func (ejp *extJSONParser) readValue(t bsontype.Type) (*extJSONValue, error) { if ejp.canonical { return nil, invalidJSONErrorForType("object", t) } - return nil, invalidJSONErrorForType("ISO-8601 Internet Date/Time Format as decribed in RFC-3339", t) + return nil, invalidJSONErrorForType("ISO-8601 Internet Date/Time Format as described in RFC-3339", t) } ejp.advanceState() diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/value_reader.go b/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/value_reader.go index 5e147373..458588b6 100644 --- a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/value_reader.go +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/value_reader.go @@ -384,9 +384,13 @@ func (vr *valueReader) ReadBinary() (b []byte, btype byte, err error) { if err != nil { return nil, 0, err } + // Make a copy of the returned byte slice because it's just a subslice from the valueReader's + // buffer and is not safe to return in the unmarshaled value. + cp := make([]byte, len(b)) + copy(cp, b) vr.pop() - return b, btype, nil + return cp, btype, nil } func (vr *valueReader) ReadBoolean() (bool, error) { @@ -737,6 +741,9 @@ func (vr *valueReader) ReadValue() (ValueReader, error) { return vr, nil } +// readBytes reads length bytes from the valueReader starting at the current offset. Note that the +// returned byte slice is a subslice from the valueReader buffer and must be converted or copied +// before returning in an unmarshaled value. func (vr *valueReader) readBytes(length int32) ([]byte, error) { if length < 0 { return nil, fmt.Errorf("invalid length: %d", length) @@ -748,6 +755,7 @@ func (vr *valueReader) readBytes(length int32) ([]byte, error) { start := vr.offset vr.offset += int64(length) + return vr.d[start : start+int64(length)], nil } diff --git a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/value_writer.go b/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/value_writer.go index a39c4ea4..f95a08af 100644 --- a/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/value_writer.go +++ b/vendor/go.mongodb.org/mongo-driver/bson/bsonrw/value_writer.go @@ -529,7 +529,7 @@ func (vw *valueWriter) WriteDocumentEnd() error { vw.pop() if vw.stack[vw.frame].mode == mCodeWithScope { - // We ignore the error here because of the gaurantee of writeLength. + // We ignore the error here because of the guarantee of writeLength. // See the docs for writeLength for more info. _ = vw.writeLength() vw.pop() diff --git a/vendor/go.mongodb.org/mongo-driver/bson/doc.go b/vendor/go.mongodb.org/mongo-driver/bson/doc.go index 094be934..5e3825a2 100644 --- a/vendor/go.mongodb.org/mongo-driver/bson/doc.go +++ b/vendor/go.mongodb.org/mongo-driver/bson/doc.go @@ -118,7 +118,7 @@ // types, this tag is ignored. // // 3. truncate: If the truncate struct tag is specified on a field with a non-float numeric type, BSON doubles unmarshalled -// into that field will be trucated at the decimal point. For example, if 3.14 is unmarshalled into a field of type int, +// into that field will be truncated at the decimal point. For example, if 3.14 is unmarshalled into a field of type int, // it will be unmarshalled as 3. If this tag is not specified, the decoder will throw an error if the value cannot be // decoded without losing precision. For float64 or non-numeric types, this tag is ignored. // diff --git a/vendor/go.mongodb.org/mongo-driver/bson/marshal.go b/vendor/go.mongodb.org/mongo-driver/bson/marshal.go index 79f03858..db8d8ee9 100644 --- a/vendor/go.mongodb.org/mongo-driver/bson/marshal.go +++ b/vendor/go.mongodb.org/mongo-driver/bson/marshal.go @@ -225,10 +225,13 @@ func MarshalExtJSONAppendWithContext(ec bsoncodec.EncodeContext, dst []byte, val return *sw, nil } +// IndentExtJSON will prefix and indent the provided extended JSON src and append it to dst. func IndentExtJSON(dst *bytes.Buffer, src []byte, prefix, indent string) error { return json.Indent(dst, src, prefix, indent) } +// MarshalExtJSONIndent returns the extended JSON encoding of val with each line with prefixed +// and indented. func MarshalExtJSONIndent(val interface{}, canonical, escapeHTML bool, prefix, indent string) ([]byte, error) { marshaled, err := MarshalExtJSON(val, canonical, escapeHTML) if err != nil { diff --git a/vendor/go.mongodb.org/mongo-driver/bson/registry.go b/vendor/go.mongodb.org/mongo-driver/bson/registry.go index 09062d20..16d7573e 100644 --- a/vendor/go.mongodb.org/mongo-driver/bson/registry.go +++ b/vendor/go.mongodb.org/mongo-driver/bson/registry.go @@ -13,7 +13,7 @@ import "go.mongodb.org/mongo-driver/bson/bsoncodec" var DefaultRegistry = NewRegistryBuilder().Build() // NewRegistryBuilder creates a new RegistryBuilder configured with the default encoders and -// deocders from the bsoncodec.DefaultValueEncoders and bsoncodec.DefaultValueDecoders types and the +// decoders from the bsoncodec.DefaultValueEncoders and bsoncodec.DefaultValueDecoders types and the // PrimitiveCodecs type in this package. func NewRegistryBuilder() *bsoncodec.RegistryBuilder { rb := bsoncodec.NewRegistryBuilder() diff --git a/vendor/go.mongodb.org/mongo-driver/bson/unmarshal.go b/vendor/go.mongodb.org/mongo-driver/bson/unmarshal.go index 6f9ca04d..f936ba18 100644 --- a/vendor/go.mongodb.org/mongo-driver/bson/unmarshal.go +++ b/vendor/go.mongodb.org/mongo-driver/bson/unmarshal.go @@ -23,7 +23,7 @@ type Unmarshaler interface { } // ValueUnmarshaler is an interface implemented by types that can unmarshal a -// BSON value representaiton of themselves. The BSON bytes and type can be +// BSON value representation of themselves. The BSON bytes and type can be // assumed to be valid. UnmarshalBSONValue must copy the BSON value bytes if it // wishes to retain the data after returning. type ValueUnmarshaler interface { diff --git a/vendor/go.mongodb.org/mongo-driver/event/monitoring.go b/vendor/go.mongodb.org/mongo-driver/event/monitoring.go index d95deef0..ac05e401 100644 --- a/vendor/go.mongodb.org/mongo-driver/event/monitoring.go +++ b/vendor/go.mongodb.org/mongo-driver/event/monitoring.go @@ -70,19 +70,22 @@ const ( ReasonStale = "stale" ReasonConnectionErrored = "connectionError" ReasonTimedOut = "timeout" + ReasonError = "error" ) // strings for pool command monitoring types const ( - ConnectionClosed = "ConnectionClosed" PoolCreated = "ConnectionPoolCreated" + PoolReady = "ConnectionPoolReady" + PoolCleared = "ConnectionPoolCleared" + PoolClosedEvent = "ConnectionPoolClosed" ConnectionCreated = "ConnectionCreated" ConnectionReady = "ConnectionReady" + ConnectionClosed = "ConnectionClosed" + GetStarted = "ConnectionCheckOutStarted" GetFailed = "ConnectionCheckOutFailed" GetSucceeded = "ConnectionCheckedOut" ConnectionReturned = "ConnectionCheckedIn" - PoolCleared = "ConnectionPoolCleared" - PoolClosedEvent = "ConnectionPoolClosed" ) // MonitorPoolOptions contains pool options as formatted in pool events diff --git a/vendor/go.mongodb.org/mongo-driver/internal/const.go b/vendor/go.mongodb.org/mongo-driver/internal/const.go index f2d2d88d..a7ef69d1 100644 --- a/vendor/go.mongodb.org/mongo-driver/internal/const.go +++ b/vendor/go.mongodb.org/mongo-driver/internal/const.go @@ -9,11 +9,6 @@ package internal // import "go.mongodb.org/mongo-driver/internal" // Version is the current version of the driver. var Version = "local build" -// SetMockServiceID enables a mode in which the driver mocks server support for returning a "serviceId" field in "hello" -// command responses by using the value of "topologyVersion.processId". This is used for testing load balancer support -// until an upstream service can support running behind a load balancer. -var SetMockServiceID = false - // LegacyHello is the legacy version of the hello command. var LegacyHello = "isMaster" diff --git a/vendor/go.mongodb.org/mongo-driver/internal/randutil/randutil.go b/vendor/go.mongodb.org/mongo-driver/internal/randutil/randutil.go index 631f9532..d7b753b7 100644 --- a/vendor/go.mongodb.org/mongo-driver/internal/randutil/randutil.go +++ b/vendor/go.mongodb.org/mongo-driver/internal/randutil/randutil.go @@ -1,7 +1,16 @@ +// Copyright (C) MongoDB, Inc. 2022-present. +// +// 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 + // Package randutil provides common random number utilities. package randutil import ( + crand "crypto/rand" + "fmt" + "io" "math/rand" "sync" ) @@ -52,3 +61,17 @@ func (lr *LockedRand) Shuffle(n int, swap func(i, j int)) { lr.r.Shuffle(n, swap) lr.mu.Unlock() } + +// CryptoSeed returns a random int64 read from the "crypto/rand" random number generator. It is +// intended to be used to seed pseudorandom number generators at package initialization. It panics +// if it encounters any errors. +func CryptoSeed() int64 { + var b [8]byte + _, err := io.ReadFull(crand.Reader, b[:]) + if err != nil { + panic(fmt.Errorf("failed to read 8 bytes from a \"crypto/rand\".Reader: %v", err)) + } + + return (int64(b[0]) << 0) | (int64(b[1]) << 8) | (int64(b[2]) << 16) | (int64(b[3]) << 24) | + (int64(b[4]) << 32) | (int64(b[5]) << 40) | (int64(b[6]) << 48) | (int64(b[7]) << 56) +} diff --git a/vendor/go.mongodb.org/mongo-driver/internal/string_util.go b/vendor/go.mongodb.org/mongo-driver/internal/string_util.go index db1e1890..6cafa791 100644 --- a/vendor/go.mongodb.org/mongo-driver/internal/string_util.go +++ b/vendor/go.mongodb.org/mongo-driver/internal/string_util.go @@ -33,7 +33,7 @@ func StringSliceFromRawValue(name string, val bson.RawValue) ([]string, error) { return nil, err } - var strs []string + strs := make([]string, 0, len(arrayValues)) for _, arrayVal := range arrayValues { str, ok := arrayVal.StringValueOK() if !ok { diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/bulk_write.go b/vendor/go.mongodb.org/mongo-driver/mongo/bulk_write.go index fb5c91a1..e748ced6 100644 --- a/vendor/go.mongodb.org/mongo-driver/mongo/bulk_write.go +++ b/vendor/go.mongodb.org/mongo-driver/mongo/bulk_write.go @@ -35,6 +35,7 @@ type bulkWrite struct { selector description.ServerSelector writeConcern *writeconcern.WriteConcern result BulkWriteResult + let interface{} } func (bw *bulkWrite) execute(ctx context.Context) error { @@ -113,7 +114,7 @@ func (bw *bulkWrite) runBatch(ctx context.Context, batch bulkWriteBatch) (BulkWr batchErr.Labels = writeErr.Labels batchErr.WriteConcernError = convertDriverWriteConcernError(writeErr.WriteConcernError) } - batchRes.InsertedCount = int64(res.N) + batchRes.InsertedCount = res.N case *DeleteOneModel, *DeleteManyModel: res, err := bw.runDelete(ctx, batch) if err != nil { @@ -125,7 +126,7 @@ func (bw *bulkWrite) runBatch(ctx context.Context, batch bulkWriteBatch) (BulkWr batchErr.Labels = writeErr.Labels batchErr.WriteConcernError = convertDriverWriteConcernError(writeErr.WriteConcernError) } - batchRes.DeletedCount = int64(res.N) + batchRes.DeletedCount = res.N case *ReplaceOneModel, *UpdateOneModel, *UpdateManyModel: res, err := bw.runUpdate(ctx, batch) if err != nil { @@ -137,8 +138,8 @@ func (bw *bulkWrite) runBatch(ctx context.Context, batch bulkWriteBatch) (BulkWr batchErr.Labels = writeErr.Labels batchErr.WriteConcernError = convertDriverWriteConcernError(writeErr.WriteConcernError) } - batchRes.MatchedCount = int64(res.N) - batchRes.ModifiedCount = int64(res.NModified) + batchRes.MatchedCount = res.N + batchRes.ModifiedCount = res.NModified batchRes.UpsertedCount = int64(len(res.Upserted)) for _, upsert := range res.Upserted { batchRes.UpsertedIDs[int64(batch.indexes[upsert.Index])] = upsert.ID @@ -228,6 +229,13 @@ func (bw *bulkWrite) runDelete(ctx context.Context, batch bulkWriteBatch) (opera Database(bw.collection.db.name).Collection(bw.collection.name). Deployment(bw.collection.client.deployment).Crypt(bw.collection.client.cryptFLE).Hint(hasHint). ServerAPI(bw.collection.client.serverAPI) + if bw.let != nil { + let, err := transformBsoncoreDocument(bw.collection.registry, bw.let, true, "let") + if err != nil { + return operation.DeleteResult{}, err + } + op = op.Let(let) + } if bw.ordered != nil { op = op.Ordered(*bw.ordered) } @@ -309,6 +317,13 @@ func (bw *bulkWrite) runUpdate(ctx context.Context, batch bulkWriteBatch) (opera Database(bw.collection.db.name).Collection(bw.collection.name). Deployment(bw.collection.client.deployment).Crypt(bw.collection.client.cryptFLE).Hint(hasHint). ArrayFilters(hasArrayFilters).ServerAPI(bw.collection.client.serverAPI) + if bw.let != nil { + let, err := transformBsoncoreDocument(bw.collection.registry, bw.let, true, "let") + if err != nil { + return operation.UpdateResult{}, err + } + op = op.Let(let) + } if bw.ordered != nil { op = op.Ordered(*bw.ordered) } diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/change_stream.go b/vendor/go.mongodb.org/mongo-driver/mongo/change_stream.go index f2a194d7..a76eb7c9 100644 --- a/vendor/go.mongodb.org/mongo-driver/mongo/change_stream.go +++ b/vendor/go.mongodb.org/mongo-driver/mongo/change_stream.go @@ -69,21 +69,22 @@ type ChangeStream struct { // TryNext. If continued access is required, a copy must be made. Current bson.Raw - aggregate *operation.Aggregate - pipelineSlice []bsoncore.Document - cursor changeStreamCursor - cursorOptions driver.CursorOptions - batch []bsoncore.Document - resumeToken bson.Raw - err error - sess *session.Client - client *Client - registry *bsoncodec.Registry - streamType StreamType - options *options.ChangeStreamOptions - selector description.ServerSelector - operationTime *primitive.Timestamp - wireVersion *description.VersionRange + aggregate *operation.Aggregate + pipelineSlice []bsoncore.Document + pipelineOptions map[string]bsoncore.Value + cursor changeStreamCursor + cursorOptions driver.CursorOptions + batch []bsoncore.Document + resumeToken bson.Raw + err error + sess *session.Client + client *Client + registry *bsoncodec.Registry + streamType StreamType + options *options.ChangeStreamOptions + selector description.ServerSelector + operationTime *primitive.Timestamp + wireVersion *description.VersionRange } type changeStreamConfig struct { @@ -143,6 +144,37 @@ func newChangeStream(ctx context.Context, config changeStreamConfig, pipeline in if cs.options.MaxAwaitTime != nil { cs.cursorOptions.MaxTimeMS = int64(*cs.options.MaxAwaitTime / time.Millisecond) } + if cs.options.Custom != nil { + // Marshal all custom options before passing to the initial aggregate. Return + // any errors from Marshaling. + customOptions := make(map[string]bsoncore.Value) + for optionName, optionValue := range cs.options.Custom { + bsonType, bsonData, err := bson.MarshalValueWithRegistry(cs.registry, optionValue) + if err != nil { + cs.err = err + closeImplicitSession(cs.sess) + return nil, cs.Err() + } + optionValueBSON := bsoncore.Value{Type: bsonType, Data: bsonData} + customOptions[optionName] = optionValueBSON + } + cs.aggregate.CustomOptions(customOptions) + } + if cs.options.CustomPipeline != nil { + // Marshal all custom pipeline options before building pipeline slice. Return + // any errors from Marshaling. + cs.pipelineOptions = make(map[string]bsoncore.Value) + for optionName, optionValue := range cs.options.CustomPipeline { + bsonType, bsonData, err := bson.MarshalValueWithRegistry(cs.registry, optionValue) + if err != nil { + cs.err = err + closeImplicitSession(cs.sess) + return nil, cs.Err() + } + optionValueBSON := bsoncore.Value{Type: bsonType, Data: bsonData} + cs.pipelineOptions[optionName] = optionValueBSON + } + } switch cs.streamType { case ClientStream: @@ -212,7 +244,7 @@ func (cs *ChangeStream) executeOperation(ctx context.Context, resuming bool) err cs.aggregate.Deployment(cs.createOperationDeployment(server, conn)) if resuming { - cs.replaceOptions(ctx, cs.wireVersion) + cs.replaceOptions(cs.wireVersion) csOptDoc := cs.createPipelineOptionsDoc() pipIdx, pipDoc := bsoncore.AppendDocumentStart(nil) @@ -390,6 +422,11 @@ func (cs *ChangeStream) createPipelineOptionsDoc() bsoncore.Document { plDoc = bsoncore.AppendTimestampElement(plDoc, "startAtOperationTime", cs.options.StartAtOperationTime.T, cs.options.StartAtOperationTime.I) } + // Append custom pipeline options. + for optionName, optionValue := range cs.pipelineOptions { + plDoc = bsoncore.AppendValueElement(plDoc, optionName, optionValue) + } + if plDoc, cs.err = bsoncore.AppendDocumentEnd(plDoc, plDocIdx); cs.err != nil { return nil } @@ -408,7 +445,7 @@ func (cs *ChangeStream) pipelineToBSON() (bsoncore.Document, error) { return pipelineArr, cs.err } -func (cs *ChangeStream) replaceOptions(ctx context.Context, wireVersion *description.VersionRange) { +func (cs *ChangeStream) replaceOptions(wireVersion *description.VersionRange) { // Cached resume token: use the resume token as the resumeAfter option and set no other resume options if cs.resumeToken != nil { cs.options.SetResumeAfter(cs.resumeToken) diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/client.go b/vendor/go.mongodb.org/mongo-driver/mongo/client.go index 63630ebe..ddc08bd5 100644 --- a/vendor/go.mongodb.org/mongo-driver/mongo/client.go +++ b/vendor/go.mongodb.org/mongo-driver/mongo/client.go @@ -843,7 +843,7 @@ func (c *Client) Database(name string, opts ...*options.DatabaseOptions) *Databa // databases are included in the result. It cannot be nil. An empty document (e.g. bson.D{}) should be used to include // all databases. // -// The opts paramter can be used to specify options for this operation (see the options.ListDatabasesOptions documentation). +// The opts parameter can be used to specify options for this operation (see the options.ListDatabasesOptions documentation). // // For more information about the command, see https://docs.mongodb.com/manual/reference/command/listDatabases/. func (c *Client) ListDatabases(ctx context.Context, filter interface{}, opts ...*options.ListDatabasesOptions) (ListDatabasesResult, error) { diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/collection.go b/vendor/go.mongodb.org/mongo-driver/mongo/collection.go index a5aaa35e..590d9280 100644 --- a/vendor/go.mongodb.org/mongo-driver/mongo/collection.go +++ b/vendor/go.mongodb.org/mongo-driver/mongo/collection.go @@ -225,6 +225,7 @@ func (coll *Collection) BulkWrite(ctx context.Context, models []WriteModel, collection: coll, selector: selector, writeConcern: wc, + let: bwo.Let, } err = op.execute(ctx) @@ -454,6 +455,13 @@ func (coll *Collection) delete(ctx context.Context, filter interface{}, deleteOn if do.Hint != nil { op = op.Hint(true) } + if do.Let != nil { + let, err := transformBsoncoreDocument(coll.registry, do.Let, true, "let") + if err != nil { + return nil, err + } + op = op.Let(let) + } // deleteMany cannot be retried retryMode := driver.RetryNone @@ -465,7 +473,7 @@ func (coll *Collection) delete(ctx context.Context, filter interface{}, deleteOn if rr&expectedRr == 0 { return nil, err } - return &DeleteResult{DeletedCount: int64(op.Result().N)}, err + return &DeleteResult{DeletedCount: op.Result().N}, err } // DeleteOne executes a delete command to delete at most one document from the collection. @@ -548,6 +556,13 @@ func (coll *Collection) updateOrReplace(ctx context.Context, filter bsoncore.Doc Database(coll.db.name).Collection(coll.name). Deployment(coll.client.deployment).Crypt(coll.client.cryptFLE).Hint(uo.Hint != nil). ArrayFilters(uo.ArrayFilters != nil).Ordered(true).ServerAPI(coll.client.serverAPI) + if uo.Let != nil { + let, err := transformBsoncoreDocument(coll.registry, uo.Let, true, "let") + if err != nil { + return nil, err + } + op = op.Let(let) + } if uo.BypassDocumentValidation != nil && *uo.BypassDocumentValidation { op = op.BypassDocumentValidation(*uo.BypassDocumentValidation) @@ -567,8 +582,8 @@ func (coll *Collection) updateOrReplace(ctx context.Context, filter bsoncore.Doc opRes := op.Result() res := &UpdateResult{ - MatchedCount: int64(opRes.N), - ModifiedCount: int64(opRes.NModified), + MatchedCount: opRes.N, + ModifiedCount: opRes.NModified, UpsertedCount: int64(len(opRes.Upserted)), } if len(opRes.Upserted) > 0 { @@ -693,11 +708,15 @@ func (coll *Collection) ReplaceOne(ctx context.Context, filter interface{}, updateOptions := make([]*options.UpdateOptions, 0, len(opts)) for _, opt := range opts { + if opt == nil { + continue + } uOpts := options.Update() uOpts.BypassDocumentValidation = opt.BypassDocumentValidation uOpts.Collation = opt.Collation uOpts.Upsert = opt.Upsert uOpts.Hint = opt.Hint + uOpts.Let = opt.Let updateOptions = append(updateOptions, uOpts) } @@ -736,8 +755,7 @@ func (coll *Collection) Aggregate(ctx context.Context, pipeline interface{}, } // aggreate is the helper method for Aggregate -func aggregate(a aggregateParams) (*Cursor, error) { - +func aggregate(a aggregateParams) (cur *Cursor, err error) { if a.ctx == nil { a.ctx = context.Background() } @@ -748,6 +766,12 @@ func aggregate(a aggregateParams) (*Cursor, error) { } sess := sessionFromContext(a.ctx) + // Always close any created implicit sessions if aggregate returns an error. + defer func() { + if err != nil && sess != nil { + closeImplicitSession(sess) + } + }() if sess == nil && a.client.sessionPool != nil { sess, err = session.NewClientSession(a.client.sessionPool, a.client.id, session.Implicit) if err != nil { @@ -821,7 +845,6 @@ func aggregate(a aggregateParams) (*Cursor, error) { if ao.Hint != nil { hintVal, err := transformValue(a.registry, ao.Hint, false, "hint") if err != nil { - closeImplicitSession(sess) return nil, err } op.Hint(hintVal) @@ -829,11 +852,24 @@ func aggregate(a aggregateParams) (*Cursor, error) { if ao.Let != nil { let, err := transformBsoncoreDocument(a.registry, ao.Let, true, "let") if err != nil { - closeImplicitSession(sess) return nil, err } op.Let(let) } + if ao.Custom != nil { + // Marshal all custom options before passing to the aggregate operation. Return + // any errors from Marshaling. + customOptions := make(map[string]bsoncore.Value) + for optionName, optionValue := range ao.Custom { + bsonType, bsonData, err := bson.MarshalValueWithRegistry(a.registry, optionValue) + if err != nil { + return nil, err + } + optionValueBSON := bsoncore.Value{Type: bsonType, Data: bsonData} + customOptions[optionName] = optionValueBSON + } + op.CustomOptions(customOptions) + } retry := driver.RetryNone if a.retryRead && !hasOutputStage { @@ -843,7 +879,6 @@ func aggregate(a aggregateParams) (*Cursor, error) { err = op.Execute(a.ctx) if err != nil { - closeImplicitSession(sess) if wce, ok := err.(driver.WriteCommandError); ok && wce.WriteConcernError != nil { return nil, *convertDriverWriteConcernError(wce.WriteConcernError) } @@ -852,7 +887,6 @@ func aggregate(a aggregateParams) (*Cursor, error) { bc, err := op.Result(cursorOpts) if err != nil { - closeImplicitSession(sess) return nil, replaceErrors(err) } cursor, err := newCursorWithSession(bc, a.registry, sess) @@ -1100,7 +1134,7 @@ func (coll *Collection) Distinct(ctx context.Context, fieldName string, filter i // // For more information about the command, see https://docs.mongodb.com/manual/reference/command/find/. func (coll *Collection) Find(ctx context.Context, filter interface{}, - opts ...*options.FindOptions) (*Cursor, error) { + opts ...*options.FindOptions) (cur *Cursor, err error) { if ctx == nil { ctx = context.Background() @@ -1112,6 +1146,12 @@ func (coll *Collection) Find(ctx context.Context, filter interface{}, } sess := sessionFromContext(ctx) + // Always close any created implicit sessions if Find returns an error. + defer func() { + if err != nil && sess != nil { + closeImplicitSession(sess) + } + }() if sess == nil && coll.client.sessionPool != nil { var err error sess, err = session.NewClientSession(coll.client.sessionPool, coll.client.id, session.Implicit) @@ -1122,7 +1162,6 @@ func (coll *Collection) Find(ctx context.Context, filter interface{}, err = coll.client.validSession(sess) if err != nil { - closeImplicitSession(sess) return nil, err } @@ -1169,11 +1208,17 @@ func (coll *Collection) Find(ctx context.Context, filter interface{}, if fo.Hint != nil { hint, err := transformValue(coll.registry, fo.Hint, false, "hint") if err != nil { - closeImplicitSession(sess) return nil, err } op.Hint(hint) } + if fo.Let != nil { + let, err := transformBsoncoreDocument(coll.registry, fo.Let, true, "let") + if err != nil { + return nil, err + } + op.Let(let) + } if fo.Limit != nil { limit := *fo.Limit if limit < 0 { @@ -1186,7 +1231,6 @@ func (coll *Collection) Find(ctx context.Context, filter interface{}, if fo.Max != nil { max, err := transformBsoncoreDocument(coll.registry, fo.Max, true, "max") if err != nil { - closeImplicitSession(sess) return nil, err } op.Max(max) @@ -1200,7 +1244,6 @@ func (coll *Collection) Find(ctx context.Context, filter interface{}, if fo.Min != nil { min, err := transformBsoncoreDocument(coll.registry, fo.Min, true, "min") if err != nil { - closeImplicitSession(sess) return nil, err } op.Min(min) @@ -1214,7 +1257,6 @@ func (coll *Collection) Find(ctx context.Context, filter interface{}, if fo.Projection != nil { proj, err := transformBsoncoreDocument(coll.registry, fo.Projection, true, "projection") if err != nil { - closeImplicitSession(sess) return nil, err } op.Projection(proj) @@ -1234,7 +1276,6 @@ func (coll *Collection) Find(ctx context.Context, filter interface{}, if fo.Sort != nil { sort, err := transformBsoncoreDocument(coll.registry, fo.Sort, false, "sort") if err != nil { - closeImplicitSession(sess) return nil, err } op.Sort(sort) @@ -1246,13 +1287,11 @@ func (coll *Collection) Find(ctx context.Context, filter interface{}, op = op.Retry(retry) if err = op.Execute(ctx); err != nil { - closeImplicitSession(sess) return nil, replaceErrors(err) } bc, err := op.Result(cursorOpts) if err != nil { - closeImplicitSession(sess) return nil, replaceErrors(err) } return newCursorWithSession(bc, coll.registry, sess) @@ -1276,6 +1315,9 @@ func (coll *Collection) FindOne(ctx context.Context, filter interface{}, findOpts := make([]*options.FindOptions, 0, len(opts)) for _, opt := range opts { + if opt == nil { + continue + } findOpts = append(findOpts, &options.FindOptions{ AllowPartialResults: opt.AllowPartialResults, BatchSize: opt.BatchSize, @@ -1406,6 +1448,13 @@ func (coll *Collection) FindOneAndDelete(ctx context.Context, filter interface{} } op = op.Hint(hint) } + if fod.Let != nil { + let, err := transformBsoncoreDocument(coll.registry, fod.Let, true, "let") + if err != nil { + return &SingleResult{err: err} + } + op = op.Let(let) + } return coll.findAndModify(ctx, op) } @@ -1478,6 +1527,13 @@ func (coll *Collection) FindOneAndReplace(ctx context.Context, filter interface{ } op = op.Hint(hint) } + if fo.Let != nil { + let, err := transformBsoncoreDocument(coll.registry, fo.Let, true, "let") + if err != nil { + return &SingleResult{err: err} + } + op = op.Let(let) + } return coll.findAndModify(ctx, op) } @@ -1561,6 +1617,13 @@ func (coll *Collection) FindOneAndUpdate(ctx context.Context, filter interface{} } op = op.Hint(hint) } + if fo.Let != nil { + let, err := transformBsoncoreDocument(coll.registry, fo.Let, true, "let") + if err != nil { + return &SingleResult{err: err} + } + op = op.Let(let) + } return coll.findAndModify(ctx, op) } diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/cursor.go b/vendor/go.mongodb.org/mongo-driver/mongo/cursor.go index 3ec03baf..533cfce0 100644 --- a/vendor/go.mongodb.org/mongo-driver/mongo/cursor.go +++ b/vendor/go.mongodb.org/mongo-driver/mongo/cursor.go @@ -15,6 +15,7 @@ import ( "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/bsoncodec" + "go.mongodb.org/mongo-driver/x/bsonx" "go.mongodb.org/mongo-driver/x/bsonx/bsoncore" "go.mongodb.org/mongo-driver/x/mongo/driver" "go.mongodb.org/mongo-driver/x/mongo/driver/session" @@ -67,6 +68,47 @@ func newEmptyCursor() *Cursor { return &Cursor{bc: driver.NewEmptyBatchCursor()} } +// NewCursorFromDocuments creates a new Cursor pre-loaded with the provided documents, error and registry. If no registry is provided, +// bson.DefaultRegistry will be used. +// +// The documents parameter must be a slice of documents. The slice may be nil or empty, but all elements must be non-nil. +func NewCursorFromDocuments(documents []interface{}, err error, registry *bsoncodec.Registry) (*Cursor, error) { + if registry == nil { + registry = bson.DefaultRegistry + } + + // Convert documents slice to a sequence-style byte array. + var docsBytes []byte + for _, doc := range documents { + switch t := doc.(type) { + case nil: + return nil, ErrNilDocument + case bsonx.Doc: + doc = t.Copy() + case []byte: + // Slight optimization so we'll just use MarshalBSON and not go through the codec machinery. + doc = bson.Raw(t) + } + var marshalErr error + docsBytes, marshalErr = bson.MarshalAppendWithRegistry(registry, docsBytes, doc) + if marshalErr != nil { + return nil, marshalErr + } + } + + c := &Cursor{ + bc: driver.NewBatchCursorFromDocuments(docsBytes), + registry: registry, + err: err, + } + + // Initialize batch and batchLength here. The underlying batch cursor will be preloaded with the + // provided contents, and thus already has a batch before calls to Next/TryNext. + c.batch = c.bc.Batch() + c.batchLength = c.bc.Batch().DocumentCount() + return c, nil +} + // ID returns the ID of this cursor, or 0 if the cursor has been closed or exhausted. func (c *Cursor) ID() int64 { return c.bc.ID() } diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/database.go b/vendor/go.mongodb.org/mongo-driver/mongo/database.go index 20787334..b0066f04 100644 --- a/vendor/go.mongodb.org/mongo-driver/mongo/database.go +++ b/vendor/go.mongodb.org/mongo-driver/mongo/database.go @@ -303,6 +303,9 @@ func (db *Database) Drop(ctx context.Context) error { // documentation). // // For more information about the command, see https://docs.mongodb.com/manual/reference/command/listCollections/. +// +// BUG(benjirewis): ListCollectionSpecifications prevents listing more than 100 collections per database when running +// against MongoDB version 2.6. func (db *Database) ListCollectionSpecifications(ctx context.Context, filter interface{}, opts ...*options.ListCollectionsOptions) ([]*CollectionSpecification, error) { @@ -337,6 +340,9 @@ func (db *Database) ListCollectionSpecifications(ctx context.Context, filter int // documentation). // // For more information about the command, see https://docs.mongodb.com/manual/reference/command/listCollections/. +// +// BUG(benjirewis): ListCollections prevents listing more than 100 collections per database when running against +// MongoDB version 2.6. func (db *Database) ListCollections(ctx context.Context, filter interface{}, opts ...*options.ListCollectionsOptions) (*Cursor, error) { if ctx == nil { ctx = context.Background() @@ -382,6 +388,9 @@ func (db *Database) ListCollections(ctx context.Context, filter interface{}, opt cursorOpts.BatchSize = *lco.BatchSize op = op.BatchSize(*lco.BatchSize) } + if lco.AuthorizedCollections != nil { + op = op.AuthorizedCollections(*lco.AuthorizedCollections) + } retry := driver.RetryNone if db.client.retryReads { @@ -415,6 +424,9 @@ func (db *Database) ListCollections(ctx context.Context, filter interface{}, opt // documentation). // // For more information about the command, see https://docs.mongodb.com/manual/reference/command/listCollections/. +// +// BUG(benjirewis): ListCollectionNames prevents listing more than 100 collections per database when running against +// MongoDB version 2.6. func (db *Database) ListCollectionNames(ctx context.Context, filter interface{}, opts ...*options.ListCollectionsOptions) ([]string, error) { opts = append(opts, options.ListCollections().SetNameOnly(true)) diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/description/server.go b/vendor/go.mongodb.org/mongo-driver/mongo/description/server.go index 798de60e..405efe94 100644 --- a/vendor/go.mongodb.org/mongo-driver/mongo/description/server.go +++ b/vendor/go.mongodb.org/mongo-driver/mongo/description/server.go @@ -286,10 +286,6 @@ func NewServer(addr address.Address, response bson.Raw) Server { desc.LastError = err return desc } - - if internal.SetMockServiceID { - desc.ServiceID = &desc.TopologyVersion.ProcessID - } } } diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/description/server_selector.go b/vendor/go.mongodb.org/mongo-driver/mongo/description/server_selector.go index 753c45b6..8e810cb9 100644 --- a/vendor/go.mongodb.org/mongo-driver/mongo/description/server_selector.go +++ b/vendor/go.mongodb.org/mongo-driver/mongo/description/server_selector.go @@ -143,7 +143,7 @@ func readPrefSelector(rp *readpref.ReadPref, isOutputAggregate bool) ServerSelec return ServerSelectorFunc(func(t Topology, candidates []Server) ([]Server, error) { if t.Kind == LoadBalanced { // In LoadBalanced mode, there should only be one server in the topology and it must be selected. We check - // this before checking MaxStaleness support becuase there's no monitoring in this mode, so the candidate + // this before checking MaxStaleness support because there's no monitoring in this mode, so the candidate // server wouldn't have a wire version set, which would result in an error. return candidates, nil } diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/errors.go b/vendor/go.mongodb.org/mongo-driver/mongo/errors.go index 2c3ae157..a16efab0 100644 --- a/vendor/go.mongodb.org/mongo-driver/mongo/errors.go +++ b/vendor/go.mongodb.org/mongo-driver/mongo/errors.go @@ -56,6 +56,7 @@ func replaceErrors(err error) error { Labels: de.Labels, Name: de.Name, Wrapped: de.Wrapped, + Raw: bson.Raw(de.Raw), } } if qe, ok := err.(driver.QueryFailureError); ok { @@ -63,6 +64,7 @@ func replaceErrors(err error) error { ce := CommandError{ Name: qe.Message, Wrapped: qe.Wrapped, + Raw: bson.Raw(qe.Response), } dollarErr, err := qe.Response.LookupErr("$err") @@ -207,6 +209,7 @@ type ServerError interface { } var _ ServerError = CommandError{} +var _ ServerError = WriteError{} var _ ServerError = WriteException{} var _ ServerError = BulkWriteException{} @@ -217,6 +220,7 @@ type CommandError struct { Labels []string // Categories to which the error belongs Name string // A human-readable name corresponding to the error code Wrapped error // The underlying error, if one exists. + Raw bson.Raw // The original server response containing the error. } // Error implements the error interface. @@ -276,6 +280,9 @@ type WriteError struct { Code int Message string Details bson.Raw + + // The original write error from the server response. + Raw bson.Raw } func (we WriteError) Error() string { @@ -286,6 +293,30 @@ func (we WriteError) Error() string { return msg } +// HasErrorCode returns true if the error has the specified code. +func (we WriteError) HasErrorCode(code int) bool { + return we.Code == code +} + +// HasErrorLabel returns true if the error contains the specified label. WriteErrors do not contain labels, +// so we always return false. +func (we WriteError) HasErrorLabel(label string) bool { + return false +} + +// HasErrorMessage returns true if the error contains the specified message. +func (we WriteError) HasErrorMessage(message string) bool { + return strings.Contains(we.Message, message) +} + +// HasErrorCodeWithMessage returns true if the error has the specified code and Message contains the specified message. +func (we WriteError) HasErrorCodeWithMessage(code int, message string) bool { + return we.Code == code && strings.Contains(we.Message, message) +} + +// serverError implements the ServerError interface. +func (we WriteError) serverError() {} + // WriteErrors is a group of write errors that occurred during execution of a write operation. type WriteErrors []WriteError @@ -307,6 +338,7 @@ func writeErrorsFromDriverWriteErrors(errs driver.WriteErrors) WriteErrors { Code: int(err.Code), Message: err.Message, Details: bson.Raw(err.Details), + Raw: bson.Raw(err.Raw), }) } return wes @@ -319,6 +351,7 @@ type WriteConcernError struct { Code int Message string Details bson.Raw + Raw bson.Raw // The original write concern error from the server response. } // Error implements the error interface. @@ -340,6 +373,9 @@ type WriteException struct { // The categories to which the exception belongs. Labels []string + + // The original server response containing the error. + Raw bson.Raw } // Error implements the error interface. @@ -426,6 +462,7 @@ func convertDriverWriteConcernError(wce *driver.WriteConcernError) *WriteConcern Code: int(wce.Code), Message: wce.Message, Details: bson.Raw(wce.Details), + Raw: bson.Raw(wce.Raw), } } @@ -559,6 +596,7 @@ func processWriteError(err error) (returnResult, error) { WriteConcernError: convertDriverWriteConcernError(tt.WriteConcernError), WriteErrors: writeErrorsFromDriverWriteErrors(tt.WriteErrors), Labels: tt.Labels, + Raw: bson.Raw(tt.Raw), } default: return rrNone, replaceErrors(err) diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/mongo.go b/vendor/go.mongodb.org/mongo-driver/mongo/mongo.go index 89eec434..da29175c 100644 --- a/vendor/go.mongodb.org/mongo-driver/mongo/mongo.go +++ b/vendor/go.mongodb.org/mongo-driver/mongo/mongo.go @@ -175,7 +175,7 @@ func ensureDollarKey(doc bsoncore.Document) error { func ensureNoDollarKey(doc bsoncore.Document) error { if elem, err := doc.IndexErr(0); err == nil && strings.HasPrefix(elem.Key(), "$") { - return errors.New("replacement document cannot contains keys beginning with '$") + return errors.New("replacement document cannot contain keys beginning with '$'") } return nil diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/options/aggregateoptions.go b/vendor/go.mongodb.org/mongo-driver/mongo/options/aggregateoptions.go index e1f710fd..cf0da5fc 100644 --- a/vendor/go.mongodb.org/mongo-driver/mongo/options/aggregateoptions.go +++ b/vendor/go.mongodb.org/mongo-driver/mongo/options/aggregateoptions.go @@ -6,7 +6,11 @@ package options -import "time" +import ( + "time" + + "go.mongodb.org/mongo-driver/bson" +) // AggregateOptions represents options that can be used to configure an Aggregate operation. type AggregateOptions struct { @@ -50,6 +54,11 @@ type AggregateOptions struct { // Values must be constant or closed expressions that do not reference document fields. Parameters can then be // accessed as variables in an aggregate expression context (e.g. "$$var"). Let interface{} + + // Custom options to be added to aggregate expression. Key-value pairs of the BSON map should correlate with desired + // option names and values. Values must be Marshalable. Custom options may conflict with non-custom options, and custom + // options bypass client-side validation. Prefer using non-custom options where possible. + Custom bson.M } // Aggregate creates a new AggregateOptions instance. @@ -111,6 +120,15 @@ func (ao *AggregateOptions) SetLet(let interface{}) *AggregateOptions { return ao } +// SetCustom sets the value for the Custom field. Key-value pairs of the BSON map should correlate +// with desired option names and values. Values must be Marshalable. Custom options may conflict +// with non-custom options, and custom options bypass client-side validation. Prefer using non-custom +// options where possible. +func (ao *AggregateOptions) SetCustom(c bson.M) *AggregateOptions { + ao.Custom = c + return ao +} + // MergeAggregateOptions combines the given AggregateOptions instances into a single AggregateOptions in a last-one-wins // fashion. func MergeAggregateOptions(opts ...*AggregateOptions) *AggregateOptions { @@ -146,6 +164,9 @@ func MergeAggregateOptions(opts ...*AggregateOptions) *AggregateOptions { if ao.Let != nil { aggOpts.Let = ao.Let } + if ao.Custom != nil { + aggOpts.Custom = ao.Custom + } } return aggOpts diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/options/bulkwriteoptions.go b/vendor/go.mongodb.org/mongo-driver/mongo/options/bulkwriteoptions.go index 57f98f83..2786ab2c 100644 --- a/vendor/go.mongodb.org/mongo-driver/mongo/options/bulkwriteoptions.go +++ b/vendor/go.mongodb.org/mongo-driver/mongo/options/bulkwriteoptions.go @@ -19,6 +19,12 @@ type BulkWriteOptions struct { // If true, no writes will be executed after one fails. The default value is true. Ordered *bool + + // Specifies parameters for all update and delete commands in the BulkWrite. This option is only valid for MongoDB + // versions >= 5.0. Older servers will report an error for using this option. This must be a document mapping + // parameter names to values. Values must be constant or closed expressions that do not reference document fields. + // Parameters can then be accessed as variables in an aggregate expression context (e.g. "$$var"). + Let interface{} } // BulkWrite creates a new *BulkWriteOptions instance. @@ -40,6 +46,15 @@ func (b *BulkWriteOptions) SetBypassDocumentValidation(bypass bool) *BulkWriteOp return b } +// SetLet sets the value for the Let field. Let specifies parameters for all update and delete commands in the BulkWrite. +// This option is only valid for MongoDB versions >= 5.0. Older servers will report an error for using this option. +// This must be a document mapping parameter names to values. Values must be constant or closed expressions that do not +// reference document fields. Parameters can then be accessed as variables in an aggregate expression context (e.g. "$$var"). +func (b *BulkWriteOptions) SetLet(let interface{}) *BulkWriteOptions { + b.Let = &let + return b +} + // MergeBulkWriteOptions combines the given BulkWriteOptions instances into a single BulkWriteOptions in a last-one-wins // fashion. func MergeBulkWriteOptions(opts ...*BulkWriteOptions) *BulkWriteOptions { @@ -54,6 +69,9 @@ func MergeBulkWriteOptions(opts ...*BulkWriteOptions) *BulkWriteOptions { if opt.BypassDocumentValidation != nil { b.BypassDocumentValidation = opt.BypassDocumentValidation } + if opt.Let != nil { + b.Let = opt.Let + } } return b diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/options/changestreamoptions.go b/vendor/go.mongodb.org/mongo-driver/mongo/options/changestreamoptions.go index fe19f45e..eb9b0643 100644 --- a/vendor/go.mongodb.org/mongo-driver/mongo/options/changestreamoptions.go +++ b/vendor/go.mongodb.org/mongo-driver/mongo/options/changestreamoptions.go @@ -9,6 +9,7 @@ package options import ( "time" + "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/bson/primitive" ) @@ -46,6 +47,16 @@ type ChangeStreamOptions struct { // corresponding to an oplog entry immediately after the specified token will be returned. If this is specified, // ResumeAfter and StartAtOperationTime must not be set. This option is only valid for MongoDB versions >= 4.1.1. StartAfter interface{} + + // Custom options to be added to the initial aggregate for the change stream. Key-value pairs of the BSON map should + // correlate with desired option names and values. Values must be Marshalable. Custom options may conflict with + // non-custom options, and custom options bypass client-side validation. Prefer using non-custom options where possible. + Custom bson.M + + // Custom options to be added to the $changeStream stage in the initial aggregate. Key-value pairs of the BSON map should + // correlate with desired option names and values. Values must be Marshalable. Custom pipeline options bypass client-side + // validation. Prefer using non-custom options where possible. + CustomPipeline bson.M } // ChangeStream creates a new ChangeStreamOptions instance. @@ -97,6 +108,23 @@ func (cso *ChangeStreamOptions) SetStartAfter(sa interface{}) *ChangeStreamOptio return cso } +// SetCustom sets the value for the Custom field. Key-value pairs of the BSON map should correlate +// with desired option names and values. Values must be Marshalable. Custom options may conflict +// with non-custom options, and custom options bypass client-side validation. Prefer using non-custom +// options where possible. +func (cso *ChangeStreamOptions) SetCustom(c bson.M) *ChangeStreamOptions { + cso.Custom = c + return cso +} + +// SetCustomPipeline sets the value for the CustomPipeline field. Key-value pairs of the BSON map +// should correlate with desired option names and values. Values must be Marshalable. Custom pipeline +// options bypass client-side validation. Prefer using non-custom options where possible. +func (cso *ChangeStreamOptions) SetCustomPipeline(cp bson.M) *ChangeStreamOptions { + cso.CustomPipeline = cp + return cso +} + // MergeChangeStreamOptions combines the given ChangeStreamOptions instances into a single ChangeStreamOptions in a // last-one-wins fashion. func MergeChangeStreamOptions(opts ...*ChangeStreamOptions) *ChangeStreamOptions { @@ -126,6 +154,12 @@ func MergeChangeStreamOptions(opts ...*ChangeStreamOptions) *ChangeStreamOptions if cso.StartAfter != nil { csOpts.StartAfter = cso.StartAfter } + if cso.Custom != nil { + csOpts.Custom = cso.Custom + } + if cso.CustomPipeline != nil { + csOpts.CustomPipeline = cso.CustomPipeline + } } return csOpts diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/options/clientoptions.go b/vendor/go.mongodb.org/mongo-driver/mongo/options/clientoptions.go index da5f630d..115cc642 100644 --- a/vendor/go.mongodb.org/mongo-driver/mongo/options/clientoptions.go +++ b/vendor/go.mongodb.org/mongo-driver/mongo/options/clientoptions.go @@ -574,7 +574,7 @@ func (c *ClientOptions) SetMaxConnIdleTime(d time.Duration) *ClientOptions { // SetMaxPoolSize specifies that maximum number of connections allowed in the driver's connection pool to each server. // Requests to a server will block if this maximum is reached. This can also be set through the "maxPoolSize" URI option -// (e.g. "maxPoolSize=100"). The default is 100. If this is 0, it will be set to math.MaxInt64. +// (e.g. "maxPoolSize=100"). If this is 0, maximum connection pool size is not limited. The default is 100. func (c *ClientOptions) SetMaxPoolSize(u uint64) *ClientOptions { c.MaxPoolSize = &u return c diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/options/deleteoptions.go b/vendor/go.mongodb.org/mongo-driver/mongo/options/deleteoptions.go index fcea40a5..0473d81f 100644 --- a/vendor/go.mongodb.org/mongo-driver/mongo/options/deleteoptions.go +++ b/vendor/go.mongodb.org/mongo-driver/mongo/options/deleteoptions.go @@ -20,6 +20,12 @@ type DeleteOptions struct { // operation. The driver will return an error if the hint parameter is a multi-key map. The default value is nil, // which means that no hint will be sent. Hint interface{} + + // Specifies parameters for the delete expression. This option is only valid for MongoDB versions >= 5.0. Older + // servers will report an error for using this option. This must be a document mapping parameter names to values. + // Values must be constant or closed expressions that do not reference document fields. Parameters can then be + // accessed as variables in an aggregate expression context (e.g. "$$var"). + Let interface{} } // Delete creates a new DeleteOptions instance. @@ -39,6 +45,12 @@ func (do *DeleteOptions) SetHint(hint interface{}) *DeleteOptions { return do } +// SetLet sets the value for the Let field. +func (do *DeleteOptions) SetLet(let interface{}) *DeleteOptions { + do.Let = let + return do +} + // MergeDeleteOptions combines the given DeleteOptions instances into a single DeleteOptions in a last-one-wins fashion. func MergeDeleteOptions(opts ...*DeleteOptions) *DeleteOptions { dOpts := Delete() @@ -52,6 +64,9 @@ func MergeDeleteOptions(opts ...*DeleteOptions) *DeleteOptions { if do.Hint != nil { dOpts.Hint = do.Hint } + if do.Let != nil { + dOpts.Let = do.Let + } } return dOpts diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/options/findoptions.go b/vendor/go.mongodb.org/mongo-driver/mongo/options/findoptions.go index ad9409c9..0dd09f51 100644 --- a/vendor/go.mongodb.org/mongo-driver/mongo/options/findoptions.go +++ b/vendor/go.mongodb.org/mongo-driver/mongo/options/findoptions.go @@ -99,6 +99,12 @@ type FindOptions struct { // A document specifying the order in which documents should be returned. The driver will return an error if the // sort parameter is a multi-key map. Sort interface{} + + // Specifies parameters for the find expression. This option is only valid for MongoDB versions >= 5.0. Older + // servers will report an error for using this option. This must be a document mapping parameter names to values. + // Values must be constant or closed expressions that do not reference document fields. Parameters can then be + // accessed as variables in an aggregate expression context (e.g. "$$var"). + Let interface{} } // Find creates a new FindOptions instance. @@ -148,6 +154,12 @@ func (f *FindOptions) SetHint(hint interface{}) *FindOptions { return f } +// SetLet sets the value for the Let field. +func (f *FindOptions) SetLet(let interface{}) *FindOptions { + f.Let = let + return f +} + // SetLimit sets the value for the Limit field. func (f *FindOptions) SetLimit(i int64) *FindOptions { f.Limit = &i @@ -258,6 +270,9 @@ func MergeFindOptions(opts ...*FindOptions) *FindOptions { if opt.Hint != nil { fo.Hint = opt.Hint } + if opt.Let != nil { + fo.Let = opt.Let + } if opt.Limit != nil { fo.Limit = opt.Limit } @@ -624,6 +639,12 @@ type FindOneAndReplaceOptions struct { // will return an error if the hint parameter is a multi-key map. The default value is nil, which means that no hint // will be sent. Hint interface{} + + // Specifies parameters for the find one and replace expression. This option is only valid for MongoDB versions >= 5.0. Older + // servers will report an error for using this option. This must be a document mapping parameter names to values. + // Values must be constant or closed expressions that do not reference document fields. Parameters can then be + // accessed as variables in an aggregate expression context (e.g. "$$var"). + Let interface{} } // FindOneAndReplace creates a new FindOneAndReplaceOptions instance. @@ -679,6 +700,12 @@ func (f *FindOneAndReplaceOptions) SetHint(hint interface{}) *FindOneAndReplaceO return f } +// SetLet sets the value for the Let field. +func (f *FindOneAndReplaceOptions) SetLet(let interface{}) *FindOneAndReplaceOptions { + f.Let = let + return f +} + // MergeFindOneAndReplaceOptions combines the given FindOneAndReplaceOptions instances into a single // FindOneAndReplaceOptions in a last-one-wins fashion. func MergeFindOneAndReplaceOptions(opts ...*FindOneAndReplaceOptions) *FindOneAndReplaceOptions { @@ -711,6 +738,9 @@ func MergeFindOneAndReplaceOptions(opts ...*FindOneAndReplaceOptions) *FindOneAn if opt.Hint != nil { fo.Hint = opt.Hint } + if opt.Let != nil { + fo.Let = opt.Let + } } return fo @@ -762,6 +792,12 @@ type FindOneAndUpdateOptions struct { // will return an error if the hint parameter is a multi-key map. The default value is nil, which means that no hint // will be sent. Hint interface{} + + // Specifies parameters for the find one and update expression. This option is only valid for MongoDB versions >= 5.0. Older + // servers will report an error for using this option. This must be a document mapping parameter names to values. + // Values must be constant or closed expressions that do not reference document fields. Parameters can then be + // accessed as variables in an aggregate expression context (e.g. "$$var"). + Let interface{} } // FindOneAndUpdate creates a new FindOneAndUpdateOptions instance. @@ -823,6 +859,12 @@ func (f *FindOneAndUpdateOptions) SetHint(hint interface{}) *FindOneAndUpdateOpt return f } +// SetLet sets the value for the Let field. +func (f *FindOneAndUpdateOptions) SetLet(let interface{}) *FindOneAndUpdateOptions { + f.Let = let + return f +} + // MergeFindOneAndUpdateOptions combines the given FindOneAndUpdateOptions instances into a single // FindOneAndUpdateOptions in a last-one-wins fashion. func MergeFindOneAndUpdateOptions(opts ...*FindOneAndUpdateOptions) *FindOneAndUpdateOptions { @@ -858,6 +900,9 @@ func MergeFindOneAndUpdateOptions(opts ...*FindOneAndUpdateOptions) *FindOneAndU if opt.Hint != nil { fo.Hint = opt.Hint } + if opt.Let != nil { + fo.Let = opt.Let + } } return fo @@ -890,6 +935,12 @@ type FindOneAndDeleteOptions struct { // will return an error if the hint parameter is a multi-key map. The default value is nil, which means that no hint // will be sent. Hint interface{} + + // Specifies parameters for the find one and delete expression. This option is only valid for MongoDB versions >= 5.0. Older + // servers will report an error for using this option. This must be a document mapping parameter names to values. + // Values must be constant or closed expressions that do not reference document fields. Parameters can then be + // accessed as variables in an aggregate expression context (e.g. "$$var"). + Let interface{} } // FindOneAndDelete creates a new FindOneAndDeleteOptions instance. @@ -927,6 +978,12 @@ func (f *FindOneAndDeleteOptions) SetHint(hint interface{}) *FindOneAndDeleteOpt return f } +// SetLet sets the value for the Let field. +func (f *FindOneAndDeleteOptions) SetLet(let interface{}) *FindOneAndDeleteOptions { + f.Let = let + return f +} + // MergeFindOneAndDeleteOptions combines the given FindOneAndDeleteOptions instances into a single // FindOneAndDeleteOptions in a last-one-wins fashion. func MergeFindOneAndDeleteOptions(opts ...*FindOneAndDeleteOptions) *FindOneAndDeleteOptions { @@ -950,6 +1007,9 @@ func MergeFindOneAndDeleteOptions(opts ...*FindOneAndDeleteOptions) *FindOneAndD if opt.Hint != nil { fo.Hint = opt.Hint } + if opt.Let != nil { + fo.Let = opt.Let + } } return fo diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/options/indexoptions.go b/vendor/go.mongodb.org/mongo-driver/mongo/options/indexoptions.go index 076eedd7..ed71fb41 100644 --- a/vendor/go.mongodb.org/mongo-driver/mongo/options/indexoptions.go +++ b/vendor/go.mongodb.org/mongo-driver/mongo/options/indexoptions.go @@ -389,6 +389,9 @@ func MergeIndexOptions(opts ...*IndexOptions) *IndexOptions { i := Index() for _, opt := range opts { + if opt == nil { + continue + } if opt.Background != nil { i.Background = opt.Background } diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/options/listcollectionsoptions.go b/vendor/go.mongodb.org/mongo-driver/mongo/options/listcollectionsoptions.go index 4c2ce3e6..6f4b1cca 100644 --- a/vendor/go.mongodb.org/mongo-driver/mongo/options/listcollectionsoptions.go +++ b/vendor/go.mongodb.org/mongo-driver/mongo/options/listcollectionsoptions.go @@ -13,6 +13,10 @@ type ListCollectionsOptions struct { // The maximum number of documents to be included in each batch returned by the server. BatchSize *int32 + + // If true, and NameOnly is true, limits the documents returned to only contain collections the user is authorized to use. The default value + // is false. This option is only valid for MongoDB server versions >= 4.0. Server versions < 4.0 ignore this option. + AuthorizedCollections *bool } // ListCollections creates a new ListCollectionsOptions instance. @@ -32,6 +36,13 @@ func (lc *ListCollectionsOptions) SetBatchSize(size int32) *ListCollectionsOptio return lc } +// SetAuthorizedCollections sets the value for the AuthorizedCollections field. This option is only valid for MongoDB server versions >= 4.0. Server +// versions < 4.0 ignore this option. +func (lc *ListCollectionsOptions) SetAuthorizedCollections(b bool) *ListCollectionsOptions { + lc.AuthorizedCollections = &b + return lc +} + // MergeListCollectionsOptions combines the given ListCollectionsOptions instances into a single *ListCollectionsOptions // in a last-one-wins fashion. func MergeListCollectionsOptions(opts ...*ListCollectionsOptions) *ListCollectionsOptions { @@ -46,6 +57,9 @@ func MergeListCollectionsOptions(opts ...*ListCollectionsOptions) *ListCollectio if opt.BatchSize != nil { lc.BatchSize = opt.BatchSize } + if opt.AuthorizedCollections != nil { + lc.AuthorizedCollections = opt.AuthorizedCollections + } } return lc diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/options/listdatabasesoptions.go b/vendor/go.mongodb.org/mongo-driver/mongo/options/listdatabasesoptions.go index 42fe1704..f19d89c6 100644 --- a/vendor/go.mongodb.org/mongo-driver/mongo/options/listdatabasesoptions.go +++ b/vendor/go.mongodb.org/mongo-driver/mongo/options/listdatabasesoptions.go @@ -40,7 +40,7 @@ func (ld *ListDatabasesOptions) SetAuthorizedDatabases(b bool) *ListDatabasesOpt func MergeListDatabasesOptions(opts ...*ListDatabasesOptions) *ListDatabasesOptions { ld := ListDatabases() for _, opt := range opts { - if opts == nil { + if opt == nil { continue } if opt.NameOnly != nil { diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/options/mongooptions.go b/vendor/go.mongodb.org/mongo-driver/mongo/options/mongooptions.go index ff6f6c80..179b7356 100644 --- a/vendor/go.mongodb.org/mongo-driver/mongo/options/mongooptions.go +++ b/vendor/go.mongodb.org/mongo-driver/mongo/options/mongooptions.go @@ -22,7 +22,7 @@ type Collation struct { Locale string `bson:",omitempty"` // The locale CaseLevel bool `bson:",omitempty"` // The case level CaseFirst string `bson:",omitempty"` // The case ordering - Strength int `bson:",omitempty"` // The number of comparision levels to use + Strength int `bson:",omitempty"` // The number of comparison levels to use NumericOrdering bool `bson:",omitempty"` // Whether to order numbers based on numerical order and not collation order Alternate string `bson:",omitempty"` // Whether spaces and punctuation are considered base characters MaxVariable string `bson:",omitempty"` // Which characters are affected by alternate: "shifted" diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/options/replaceoptions.go b/vendor/go.mongodb.org/mongo-driver/mongo/options/replaceoptions.go index 543c81ce..9cb9ab87 100644 --- a/vendor/go.mongodb.org/mongo-driver/mongo/options/replaceoptions.go +++ b/vendor/go.mongodb.org/mongo-driver/mongo/options/replaceoptions.go @@ -30,6 +30,12 @@ type ReplaceOptions struct { // If true, a new document will be inserted if the filter does not match any documents in the collection. The // default value is false. Upsert *bool + + // Specifies parameters for the aggregate expression. This option is only valid for MongoDB versions >= 5.0. Older + // servers will report an error for using this option. This must be a document mapping parameter names to values. + // Values must be constant or closed expressions that do not reference document fields. Parameters can then be + // accessed as variables in an aggregate expression context (e.g. "$$var"). + Let interface{} } // Replace creates a new ReplaceOptions instance. @@ -61,6 +67,12 @@ func (ro *ReplaceOptions) SetUpsert(b bool) *ReplaceOptions { return ro } +// SetLet sets the value for the Let field. +func (ro *ReplaceOptions) SetLet(l interface{}) *ReplaceOptions { + ro.Let = l + return ro +} + // MergeReplaceOptions combines the given ReplaceOptions instances into a single ReplaceOptions in a last-one-wins // fashion. func MergeReplaceOptions(opts ...*ReplaceOptions) *ReplaceOptions { @@ -81,6 +93,9 @@ func MergeReplaceOptions(opts ...*ReplaceOptions) *ReplaceOptions { if ro.Upsert != nil { rOpts.Upsert = ro.Upsert } + if ro.Let != nil { + rOpts.Let = ro.Let + } } return rOpts diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/options/updateoptions.go b/vendor/go.mongodb.org/mongo-driver/mongo/options/updateoptions.go index 4d1e7e47..fd0631de 100644 --- a/vendor/go.mongodb.org/mongo-driver/mongo/options/updateoptions.go +++ b/vendor/go.mongodb.org/mongo-driver/mongo/options/updateoptions.go @@ -35,6 +35,12 @@ type UpdateOptions struct { // If true, a new document will be inserted if the filter does not match any documents in the collection. The // default value is false. Upsert *bool + + // Specifies parameters for the update expression. This option is only valid for MongoDB versions >= 5.0. Older + // servers will report an error for using this option. This must be a document mapping parameter names to values. + // Values must be constant or closed expressions that do not reference document fields. Parameters can then be + // accessed as variables in an aggregate expression context (e.g. "$$var"). + Let interface{} } // Update creates a new UpdateOptions instance. @@ -72,6 +78,12 @@ func (uo *UpdateOptions) SetUpsert(b bool) *UpdateOptions { return uo } +// SetLet sets the value for the Let field. +func (uo *UpdateOptions) SetLet(l interface{}) *UpdateOptions { + uo.Let = l + return uo +} + // MergeUpdateOptions combines the given UpdateOptions instances into a single UpdateOptions in a last-one-wins fashion. func MergeUpdateOptions(opts ...*UpdateOptions) *UpdateOptions { uOpts := Update() @@ -94,6 +106,9 @@ func MergeUpdateOptions(opts ...*UpdateOptions) *UpdateOptions { if uo.Upsert != nil { uOpts.Upsert = uo.Upsert } + if uo.Let != nil { + uOpts.Let = uo.Let + } } return uOpts diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/readpref/readpref.go b/vendor/go.mongodb.org/mongo-driver/mongo/readpref/readpref.go index b651b69e..a3ac0edf 100644 --- a/vendor/go.mongodb.org/mongo-driver/mongo/readpref/readpref.go +++ b/vendor/go.mongodb.org/mongo-driver/mongo/readpref/readpref.go @@ -65,6 +65,9 @@ func New(mode Mode, opts ...Option) (*ReadPref, error) { } for _, opt := range opts { + if opt == nil { + continue + } err := opt(rp) if err != nil { return nil, err diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/session.go b/vendor/go.mongodb.org/mongo-driver/mongo/session.go index c1a2c8ea..93bc5cb4 100644 --- a/vendor/go.mongodb.org/mongo-driver/mongo/session.go +++ b/vendor/go.mongodb.org/mongo-driver/mongo/session.go @@ -100,13 +100,16 @@ func SessionFromContext(ctx context.Context) Session { // resources are properly cleaned up, context deadlines and cancellations will not be respected during this call. For a // usage example, see the Client.StartSession method documentation. // -// ClusterTime, OperationTime, Client, and ID return the session's current operation time, the session's current cluster +// ClusterTime, OperationTime, Client, and ID return the session's current cluster time, the session's current operation // time, the Client associated with the session, and the ID document associated with the session, respectively. The ID // document for a session is in the form {"id": }. // // EndSession method should abort any existing transactions and close the session. // -// AdvanceClusterTime and AdvanceOperationTime are for internal use only and must not be called. +// AdvanceClusterTime advances the cluster time for a session. This method will return an error if the session has ended. +// +// AdvanceOperationTime advances the operation time for a session. This method will return an error if the session has +// ended. type Session interface { // Functions to modify session state. StartTransaction(...*options.TransactionOptions) error diff --git a/vendor/go.mongodb.org/mongo-driver/mongo/single_result.go b/vendor/go.mongodb.org/mongo-driver/mongo/single_result.go index c693dfae..47602502 100644 --- a/vendor/go.mongodb.org/mongo-driver/mongo/single_result.go +++ b/vendor/go.mongodb.org/mongo-driver/mongo/single_result.go @@ -28,6 +28,31 @@ type SingleResult struct { reg *bsoncodec.Registry } +// NewSingleResultFromDocument creates a SingleResult with the provided error, registry, and an underlying Cursor pre-loaded with +// the provided document, error and registry. If no registry is provided, bson.DefaultRegistry will be used. If an error distinct +// from the one provided occurs during creation of the SingleResult, that error will be stored on the returned SingleResult. +// +// The document parameter must be a non-nil document. +func NewSingleResultFromDocument(document interface{}, err error, registry *bsoncodec.Registry) *SingleResult { + if document == nil { + return &SingleResult{err: ErrNilDocument} + } + if registry == nil { + registry = bson.DefaultRegistry + } + + cur, createErr := NewCursorFromDocuments([]interface{}{document}, err, registry) + if createErr != nil { + return &SingleResult{err: createErr} + } + + return &SingleResult{ + cur: cur, + err: err, + reg: registry, + } +} + // Decode will unmarshal the document represented by this SingleResult into v. If there was an error from the operation // that created this SingleResult, that error will be returned. If the operation returned no documents, Decode will // return ErrNoDocuments. @@ -71,6 +96,7 @@ func (sr *SingleResult) setRdrContents() error { return nil case sr.cur != nil: defer sr.cur.Close(context.TODO()) + if !sr.cur.Next(context.TODO()) { if err := sr.cur.Err(); err != nil { return err diff --git a/vendor/go.mongodb.org/mongo-driver/version/version.go b/vendor/go.mongodb.org/mongo-driver/version/version.go index 5311a54c..3adbbb66 100644 --- a/vendor/go.mongodb.org/mongo-driver/version/version.go +++ b/vendor/go.mongodb.org/mongo-driver/version/version.go @@ -7,4 +7,4 @@ package version // import "go.mongodb.org/mongo-driver/version" // Driver is the current version of the driver. -var Driver = "v1.8.3" +var Driver = "v1.9.1" diff --git a/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/bson_documentbuilder.go b/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/bson_documentbuilder.go index b0d45212..52162f8a 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/bson_documentbuilder.go +++ b/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/bson_documentbuilder.go @@ -45,7 +45,7 @@ func (db *DocumentBuilder) AppendInt32(key string, i32 int32) *DocumentBuilder { return db } -// AppendDocument will append a bson embeded document element using key +// AppendDocument will append a bson embedded document element using key // and doc to DocumentBuilder.doc func (db *DocumentBuilder) AppendDocument(key string, doc []byte) *DocumentBuilder { db.doc = AppendDocumentElement(db.doc, key, doc) diff --git a/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/bsoncore.go b/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/bsoncore.go index b8db838a..5b0c3a04 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/bsoncore.go +++ b/vendor/go.mongodb.org/mongo-driver/x/bsonx/bsoncore/bsoncore.go @@ -15,7 +15,7 @@ // enough bytes. This library attempts to do no validation, it will only return // false if there are not enough bytes for an item to be read. For example, the // ReadDocument function checks the length, if that length is larger than the -// number of bytes availble, it will return false, if there are enough bytes, it +// number of bytes available, it will return false, if there are enough bytes, it // will return those bytes and true. It is the consumers responsibility to // validate those bytes. // @@ -69,7 +69,7 @@ func AppendHeader(dst []byte, t bsontype.Type, key string) []byte { // was read. // ReadType will return the first byte of the provided []byte as a type. If -// there is no availble byte, false is returned. +// there is no available byte, false is returned. func ReadType(src []byte) (bsontype.Type, []byte, bool) { if len(src) < 1 { return 0, src, false @@ -231,7 +231,7 @@ func AppendDocumentEnd(dst []byte, index int32) ([]byte, error) { // AppendDocument will append doc to dst and return the extended buffer. func AppendDocument(dst []byte, doc []byte) []byte { return append(dst, doc...) } -// AppendDocumentElement will append a BSON embeded document element using key +// AppendDocumentElement will append a BSON embedded document element using key // and doc to dst and return the extended buffer. func AppendDocumentElement(dst []byte, key string, doc []byte) []byte { return AppendDocument(AppendHeader(dst, bsontype.EmbeddedDocument, key), doc) diff --git a/vendor/go.mongodb.org/mongo-driver/x/bsonx/reflectionfree_d_codec.go b/vendor/go.mongodb.org/mongo-driver/x/bsonx/reflectionfree_d_codec.go index 94aa8f33..7e68e55c 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/bsonx/reflectionfree_d_codec.go +++ b/vendor/go.mongodb.org/mongo-driver/x/bsonx/reflectionfree_d_codec.go @@ -223,7 +223,7 @@ func (r *reflectionFreeDCodec) decodeValue(dc bsoncodec.DecodeContext, vr bsonrw func (r *reflectionFreeDCodec) encodeDocumentValue(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter, v interface{}) error { switch val := v.(type) { case int: - return r.encodeInt(ec, vw, val) + return r.encodeInt(vw, val) case int8: return vw.WriteInt32(int32(val)) case int16: @@ -292,69 +292,69 @@ func (r *reflectionFreeDCodec) encodeDocumentValue(ec bsoncodec.EncodeContext, v case []primitive.D: return r.encodeSliceD(ec, vw, val) case []int: - return r.encodeSliceInt(ec, vw, val) + return r.encodeSliceInt(vw, val) case []int8: - return r.encodeSliceInt8(ec, vw, val) + return r.encodeSliceInt8(vw, val) case []int16: - return r.encodeSliceInt16(ec, vw, val) + return r.encodeSliceInt16(vw, val) case []int32: - return r.encodeSliceInt32(ec, vw, val) + return r.encodeSliceInt32(vw, val) case []int64: return r.encodeSliceInt64(ec, vw, val) case []uint: return r.encodeSliceUint(ec, vw, val) case []uint16: - return r.encodeSliceUint16(ec, vw, val) + return r.encodeSliceUint16(vw, val) case []uint32: return r.encodeSliceUint32(ec, vw, val) case []uint64: return r.encodeSliceUint64(ec, vw, val) case [][]byte: - return r.encodeSliceByteSlice(ec, vw, val) + return r.encodeSliceByteSlice(vw, val) case []primitive.Binary: - return r.encodeSliceBinary(ec, vw, val) + return r.encodeSliceBinary(vw, val) case []bool: - return r.encodeSliceBoolean(ec, vw, val) + return r.encodeSliceBoolean(vw, val) case []primitive.CodeWithScope: return r.encodeSliceCWS(ec, vw, val) case []primitive.DBPointer: - return r.encodeSliceDBPointer(ec, vw, val) + return r.encodeSliceDBPointer(vw, val) case []primitive.DateTime: - return r.encodeSliceDateTime(ec, vw, val) + return r.encodeSliceDateTime(vw, val) case []time.Time: - return r.encodeSliceTimeTime(ec, vw, val) + return r.encodeSliceTimeTime(vw, val) case []primitive.Decimal128: - return r.encodeSliceDecimal128(ec, vw, val) + return r.encodeSliceDecimal128(vw, val) case []float32: - return r.encodeSliceFloat32(ec, vw, val) + return r.encodeSliceFloat32(vw, val) case []float64: - return r.encodeSliceFloat64(ec, vw, val) + return r.encodeSliceFloat64(vw, val) case []primitive.JavaScript: - return r.encodeSliceJavaScript(ec, vw, val) + return r.encodeSliceJavaScript(vw, val) case []primitive.MinKey: - return r.encodeSliceMinKey(ec, vw, val) + return r.encodeSliceMinKey(vw, val) case []primitive.MaxKey: - return r.encodeSliceMaxKey(ec, vw, val) + return r.encodeSliceMaxKey(vw, val) case []primitive.Null: - return r.encodeSliceNull(ec, vw, val) + return r.encodeSliceNull(vw, val) case []primitive.ObjectID: - return r.encodeSliceObjectID(ec, vw, val) + return r.encodeSliceObjectID(vw, val) case []primitive.Regex: - return r.encodeSliceRegex(ec, vw, val) + return r.encodeSliceRegex(vw, val) case []string: - return r.encodeSliceString(ec, vw, val) + return r.encodeSliceString(vw, val) case []primitive.Symbol: - return r.encodeSliceSymbol(ec, vw, val) + return r.encodeSliceSymbol(vw, val) case []primitive.Timestamp: - return r.encodeSliceTimestamp(ec, vw, val) + return r.encodeSliceTimestamp(vw, val) case []primitive.Undefined: - return r.encodeSliceUndefined(ec, vw, val) + return r.encodeSliceUndefined(vw, val) default: return fmt.Errorf("value of type %T not supported", v) } } -func (r *reflectionFreeDCodec) encodeInt(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter, val int) error { +func (r *reflectionFreeDCodec) encodeInt(vw bsonrw.ValueWriter, val int) error { if fitsIn32Bits(int64(val)) { return vw.WriteInt32(int32(val)) } @@ -399,7 +399,7 @@ func (r *reflectionFreeDCodec) encodeDocument(ec bsoncodec.EncodeContext, vw bso return dw.WriteDocumentEnd() } -func (r *reflectionFreeDCodec) encodeSliceByteSlice(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter, arr [][]byte) error { +func (r *reflectionFreeDCodec) encodeSliceByteSlice(vw bsonrw.ValueWriter, arr [][]byte) error { aw, err := vw.WriteArray() if err != nil { return err @@ -419,7 +419,7 @@ func (r *reflectionFreeDCodec) encodeSliceByteSlice(ec bsoncodec.EncodeContext, return aw.WriteArrayEnd() } -func (r *reflectionFreeDCodec) encodeSliceBinary(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter, arr []primitive.Binary) error { +func (r *reflectionFreeDCodec) encodeSliceBinary(vw bsonrw.ValueWriter, arr []primitive.Binary) error { aw, err := vw.WriteArray() if err != nil { return err @@ -439,7 +439,7 @@ func (r *reflectionFreeDCodec) encodeSliceBinary(ec bsoncodec.EncodeContext, vw return aw.WriteArrayEnd() } -func (r *reflectionFreeDCodec) encodeSliceBoolean(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter, arr []bool) error { +func (r *reflectionFreeDCodec) encodeSliceBoolean(vw bsonrw.ValueWriter, arr []bool) error { aw, err := vw.WriteArray() if err != nil { return err @@ -479,7 +479,7 @@ func (r *reflectionFreeDCodec) encodeSliceCWS(ec bsoncodec.EncodeContext, vw bso return aw.WriteArrayEnd() } -func (r *reflectionFreeDCodec) encodeSliceDBPointer(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter, arr []primitive.DBPointer) error { +func (r *reflectionFreeDCodec) encodeSliceDBPointer(vw bsonrw.ValueWriter, arr []primitive.DBPointer) error { aw, err := vw.WriteArray() if err != nil { return err @@ -499,7 +499,7 @@ func (r *reflectionFreeDCodec) encodeSliceDBPointer(ec bsoncodec.EncodeContext, return aw.WriteArrayEnd() } -func (r *reflectionFreeDCodec) encodeSliceDateTime(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter, arr []primitive.DateTime) error { +func (r *reflectionFreeDCodec) encodeSliceDateTime(vw bsonrw.ValueWriter, arr []primitive.DateTime) error { aw, err := vw.WriteArray() if err != nil { return err @@ -519,7 +519,7 @@ func (r *reflectionFreeDCodec) encodeSliceDateTime(ec bsoncodec.EncodeContext, v return aw.WriteArrayEnd() } -func (r *reflectionFreeDCodec) encodeSliceTimeTime(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter, arr []time.Time) error { +func (r *reflectionFreeDCodec) encodeSliceTimeTime(vw bsonrw.ValueWriter, arr []time.Time) error { aw, err := vw.WriteArray() if err != nil { return err @@ -540,7 +540,7 @@ func (r *reflectionFreeDCodec) encodeSliceTimeTime(ec bsoncodec.EncodeContext, v return aw.WriteArrayEnd() } -func (r *reflectionFreeDCodec) encodeSliceDecimal128(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter, arr []primitive.Decimal128) error { +func (r *reflectionFreeDCodec) encodeSliceDecimal128(vw bsonrw.ValueWriter, arr []primitive.Decimal128) error { aw, err := vw.WriteArray() if err != nil { return err @@ -560,7 +560,7 @@ func (r *reflectionFreeDCodec) encodeSliceDecimal128(ec bsoncodec.EncodeContext, return aw.WriteArrayEnd() } -func (r *reflectionFreeDCodec) encodeSliceFloat32(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter, arr []float32) error { +func (r *reflectionFreeDCodec) encodeSliceFloat32(vw bsonrw.ValueWriter, arr []float32) error { aw, err := vw.WriteArray() if err != nil { return err @@ -580,7 +580,7 @@ func (r *reflectionFreeDCodec) encodeSliceFloat32(ec bsoncodec.EncodeContext, vw return aw.WriteArrayEnd() } -func (r *reflectionFreeDCodec) encodeSliceFloat64(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter, arr []float64) error { +func (r *reflectionFreeDCodec) encodeSliceFloat64(vw bsonrw.ValueWriter, arr []float64) error { aw, err := vw.WriteArray() if err != nil { return err @@ -600,7 +600,7 @@ func (r *reflectionFreeDCodec) encodeSliceFloat64(ec bsoncodec.EncodeContext, vw return aw.WriteArrayEnd() } -func (r *reflectionFreeDCodec) encodeSliceJavaScript(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter, arr []primitive.JavaScript) error { +func (r *reflectionFreeDCodec) encodeSliceJavaScript(vw bsonrw.ValueWriter, arr []primitive.JavaScript) error { aw, err := vw.WriteArray() if err != nil { return err @@ -620,7 +620,7 @@ func (r *reflectionFreeDCodec) encodeSliceJavaScript(ec bsoncodec.EncodeContext, return aw.WriteArrayEnd() } -func (r *reflectionFreeDCodec) encodeSliceMinKey(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter, arr []primitive.MinKey) error { +func (r *reflectionFreeDCodec) encodeSliceMinKey(vw bsonrw.ValueWriter, arr []primitive.MinKey) error { aw, err := vw.WriteArray() if err != nil { return err @@ -640,7 +640,7 @@ func (r *reflectionFreeDCodec) encodeSliceMinKey(ec bsoncodec.EncodeContext, vw return aw.WriteArrayEnd() } -func (r *reflectionFreeDCodec) encodeSliceMaxKey(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter, arr []primitive.MaxKey) error { +func (r *reflectionFreeDCodec) encodeSliceMaxKey(vw bsonrw.ValueWriter, arr []primitive.MaxKey) error { aw, err := vw.WriteArray() if err != nil { return err @@ -660,7 +660,7 @@ func (r *reflectionFreeDCodec) encodeSliceMaxKey(ec bsoncodec.EncodeContext, vw return aw.WriteArrayEnd() } -func (r *reflectionFreeDCodec) encodeSliceNull(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter, arr []primitive.Null) error { +func (r *reflectionFreeDCodec) encodeSliceNull(vw bsonrw.ValueWriter, arr []primitive.Null) error { aw, err := vw.WriteArray() if err != nil { return err @@ -680,7 +680,7 @@ func (r *reflectionFreeDCodec) encodeSliceNull(ec bsoncodec.EncodeContext, vw bs return aw.WriteArrayEnd() } -func (r *reflectionFreeDCodec) encodeSliceObjectID(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter, arr []primitive.ObjectID) error { +func (r *reflectionFreeDCodec) encodeSliceObjectID(vw bsonrw.ValueWriter, arr []primitive.ObjectID) error { aw, err := vw.WriteArray() if err != nil { return err @@ -700,7 +700,7 @@ func (r *reflectionFreeDCodec) encodeSliceObjectID(ec bsoncodec.EncodeContext, v return aw.WriteArrayEnd() } -func (r *reflectionFreeDCodec) encodeSliceRegex(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter, arr []primitive.Regex) error { +func (r *reflectionFreeDCodec) encodeSliceRegex(vw bsonrw.ValueWriter, arr []primitive.Regex) error { aw, err := vw.WriteArray() if err != nil { return err @@ -720,7 +720,7 @@ func (r *reflectionFreeDCodec) encodeSliceRegex(ec bsoncodec.EncodeContext, vw b return aw.WriteArrayEnd() } -func (r *reflectionFreeDCodec) encodeSliceString(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter, arr []string) error { +func (r *reflectionFreeDCodec) encodeSliceString(vw bsonrw.ValueWriter, arr []string) error { aw, err := vw.WriteArray() if err != nil { return err @@ -740,7 +740,7 @@ func (r *reflectionFreeDCodec) encodeSliceString(ec bsoncodec.EncodeContext, vw return aw.WriteArrayEnd() } -func (r *reflectionFreeDCodec) encodeSliceSymbol(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter, arr []primitive.Symbol) error { +func (r *reflectionFreeDCodec) encodeSliceSymbol(vw bsonrw.ValueWriter, arr []primitive.Symbol) error { aw, err := vw.WriteArray() if err != nil { return err @@ -760,7 +760,7 @@ func (r *reflectionFreeDCodec) encodeSliceSymbol(ec bsoncodec.EncodeContext, vw return aw.WriteArrayEnd() } -func (r *reflectionFreeDCodec) encodeSliceTimestamp(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter, arr []primitive.Timestamp) error { +func (r *reflectionFreeDCodec) encodeSliceTimestamp(vw bsonrw.ValueWriter, arr []primitive.Timestamp) error { aw, err := vw.WriteArray() if err != nil { return err @@ -780,7 +780,7 @@ func (r *reflectionFreeDCodec) encodeSliceTimestamp(ec bsoncodec.EncodeContext, return aw.WriteArrayEnd() } -func (r *reflectionFreeDCodec) encodeSliceUndefined(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter, arr []primitive.Undefined) error { +func (r *reflectionFreeDCodec) encodeSliceUndefined(vw bsonrw.ValueWriter, arr []primitive.Undefined) error { aw, err := vw.WriteArray() if err != nil { return err @@ -840,7 +840,7 @@ func (r *reflectionFreeDCodec) encodeSliceD(ec bsoncodec.EncodeContext, vw bsonr return aw.WriteArrayEnd() } -func (r *reflectionFreeDCodec) encodeSliceInt(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter, arr []int) error { +func (r *reflectionFreeDCodec) encodeSliceInt(vw bsonrw.ValueWriter, arr []int) error { aw, err := vw.WriteArray() if err != nil { return err @@ -852,7 +852,7 @@ func (r *reflectionFreeDCodec) encodeSliceInt(ec bsoncodec.EncodeContext, vw bso return err } - if err := r.encodeInt(ec, arrayValWriter, val); err != nil { + if err := r.encodeInt(arrayValWriter, val); err != nil { return err } } @@ -860,7 +860,7 @@ func (r *reflectionFreeDCodec) encodeSliceInt(ec bsoncodec.EncodeContext, vw bso return aw.WriteArrayEnd() } -func (r *reflectionFreeDCodec) encodeSliceInt8(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter, arr []int8) error { +func (r *reflectionFreeDCodec) encodeSliceInt8(vw bsonrw.ValueWriter, arr []int8) error { aw, err := vw.WriteArray() if err != nil { return err @@ -880,7 +880,7 @@ func (r *reflectionFreeDCodec) encodeSliceInt8(ec bsoncodec.EncodeContext, vw bs return aw.WriteArrayEnd() } -func (r *reflectionFreeDCodec) encodeSliceInt16(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter, arr []int16) error { +func (r *reflectionFreeDCodec) encodeSliceInt16(vw bsonrw.ValueWriter, arr []int16) error { aw, err := vw.WriteArray() if err != nil { return err @@ -900,7 +900,7 @@ func (r *reflectionFreeDCodec) encodeSliceInt16(ec bsoncodec.EncodeContext, vw b return aw.WriteArrayEnd() } -func (r *reflectionFreeDCodec) encodeSliceInt32(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter, arr []int32) error { +func (r *reflectionFreeDCodec) encodeSliceInt32(vw bsonrw.ValueWriter, arr []int32) error { aw, err := vw.WriteArray() if err != nil { return err @@ -960,7 +960,7 @@ func (r *reflectionFreeDCodec) encodeSliceUint(ec bsoncodec.EncodeContext, vw bs return aw.WriteArrayEnd() } -func (r *reflectionFreeDCodec) encodeSliceUint16(ec bsoncodec.EncodeContext, vw bsonrw.ValueWriter, arr []uint16) error { +func (r *reflectionFreeDCodec) encodeSliceUint16(vw bsonrw.ValueWriter, arr []uint16) error { aw, err := vw.WriteArray() if err != nil { return err diff --git a/vendor/go.mongodb.org/mongo-driver/x/bsonx/registry.go b/vendor/go.mongodb.org/mongo-driver/x/bsonx/registry.go index ac21df22..7518bc04 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/bsonx/registry.go +++ b/vendor/go.mongodb.org/mongo-driver/x/bsonx/registry.go @@ -10,7 +10,7 @@ import ( var DefaultRegistry = NewRegistryBuilder().Build() // NewRegistryBuilder creates a new RegistryBuilder configured with the default encoders and -// deocders from the bsoncodec.DefaultValueEncoders and bsoncodec.DefaultValueDecoders types and the +// decoders from the bsoncodec.DefaultValueEncoders and bsoncodec.DefaultValueDecoders types and the // PrimitiveCodecs type in this package. func NewRegistryBuilder() *bsoncodec.RegistryBuilder { rb := bsoncodec.NewRegistryBuilder() diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/aws_conv.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/aws_conv.go index fa0b0d0e..eb0032ce 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/aws_conv.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/aws_conv.go @@ -76,7 +76,7 @@ func (ac *awsConversation) Step(challenge []byte) (response []byte, err error) { switch ac.state { case clientStarting: ac.state = clientFirst - response, err = ac.firstMsg() + response = ac.firstMsg() case clientFirst: ac.state = clientFinal response, err = ac.finalMsg(challenge) @@ -270,7 +270,7 @@ func (ac *awsConversation) getCredentials() (*awsv4.StaticProvider, error) { return creds, err } -func (ac *awsConversation) firstMsg() ([]byte, error) { +func (ac *awsConversation) firstMsg() []byte { // Values are cached for use in final message parameters ac.nonce = make([]byte, 32) _, _ = rand.Read(ac.nonce) @@ -279,7 +279,7 @@ func (ac *awsConversation) firstMsg() ([]byte, error) { msg = bsoncore.AppendInt32Element(msg, "p", 110) msg = bsoncore.AppendBinaryElement(msg, "r", 0x00, ac.nonce) msg, _ = bsoncore.AppendDocumentEnd(msg, idx) - return msg, nil + return msg } func (ac *awsConversation) finalMsg(s1 []byte) ([]byte, error) { diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/gssapi.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/gssapi.go index 6e9f398d..4b860ba6 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/gssapi.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/gssapi.go @@ -4,8 +4,9 @@ // 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 -//+build gssapi -//+build windows linux darwin +//go:build gssapi && (windows || linux || darwin) +// +build gssapi +// +build windows linux darwin package auth diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/gssapi_not_enabled.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/gssapi_not_enabled.go index d88b764f..50522cbb 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/gssapi_not_enabled.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/gssapi_not_enabled.go @@ -4,7 +4,8 @@ // 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 -//+build !gssapi +//go:build !gssapi +// +build !gssapi package auth diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/gssapi_not_supported.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/gssapi_not_supported.go index 55caa284..10312c22 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/gssapi_not_supported.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/gssapi_not_supported.go @@ -4,7 +4,8 @@ // 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 -//+build gssapi,!windows,!linux,!darwin +//go:build gssapi && !windows && !linux && !darwin +// +build gssapi,!windows,!linux,!darwin package auth diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/internal/awsv4/signer.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/internal/awsv4/signer.go index 9567a6d6..23508c1f 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/internal/awsv4/signer.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/internal/awsv4/signer.go @@ -234,7 +234,7 @@ func (ctx *signingCtx) buildCredentialString() { } func (ctx *signingCtx) buildCanonicalHeaders(r rule, header http.Header) { - var headers []string + headers := make([]string, 0, len(header)) headers = append(headers, "host") for k, v := range header { if !r.IsValid(k) { diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/internal/gssapi/gss.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/internal/gssapi/gss.go index 44faae4e..abfa4db4 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/internal/gssapi/gss.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/internal/gssapi/gss.go @@ -4,8 +4,9 @@ // 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 -//+build gssapi -//+build linux darwin +//go:build gssapi && (linux || darwin) +// +build gssapi +// +build linux darwin package gssapi diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/internal/gssapi/sspi.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/internal/gssapi/sspi.go index f3c3c75c..36e9633f 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/internal/gssapi/sspi.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/auth/internal/gssapi/sspi.go @@ -4,7 +4,8 @@ // 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 -//+build gssapi,windows +//go:build gssapi && windows +// +build gssapi,windows package gssapi diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/batch_cursor.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/batch_cursor.go index 8f521f58..a25e35d3 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/batch_cursor.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/batch_cursor.go @@ -184,6 +184,21 @@ func NewEmptyBatchCursor() *BatchCursor { return &BatchCursor{currentBatch: new(bsoncore.DocumentSequence)} } +// NewBatchCursorFromDocuments returns a batch cursor with current batch set to a sequence-style +// DocumentSequence containing the provided documents. +func NewBatchCursorFromDocuments(documents []byte) *BatchCursor { + return &BatchCursor{ + currentBatch: &bsoncore.DocumentSequence{ + Data: documents, + Style: bsoncore.SequenceStyle, + }, + // BatchCursors created with this function have no associated ID nor server, so no getMore + // calls will be made. + id: 0, + server: nil, + } +} + // ID returns the cursor ID for this batch cursor. func (bc *BatchCursor) ID() int64 { return bc.id diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/connstring/connstring.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/connstring/connstring.go index f5f8631b..57ce349b 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/connstring/connstring.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/connstring/connstring.go @@ -24,7 +24,7 @@ import ( ) // random is a package-global pseudo-random number generator. -var random = randutil.NewLockedRand(rand.NewSource(time.Now().UnixNano())) +var random = randutil.NewLockedRand(rand.NewSource(randutil.CryptoSeed())) // ParseAndValidate parses the provided URI into a ConnString object. // It check that all values are valid. @@ -746,7 +746,9 @@ func (p *parser) addOption(pair string) error { p.ReadPreference = value case "readpreferencetags": if value == "" { - // for when readPreferenceTags= at end of URI + // If "readPreferenceTags=" is supplied, append an empty map to tag sets to + // represent a wild-card. + p.ReadPreferenceTagSets = append(p.ReadPreferenceTagSets, map[string]string{}) break } diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/crypt.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/crypt.go index 36e0bc4a..b06e0581 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/crypt.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/crypt.go @@ -197,7 +197,7 @@ func (c *crypt) executeStateMachine(ctx context.Context, cryptCtx *mongocrypt.Co case mongocrypt.NeedMongoKeys: err = c.retrieveKeys(ctx, cryptCtx) case mongocrypt.NeedKms: - err = c.decryptKeys(ctx, cryptCtx) + err = c.decryptKeys(cryptCtx) case mongocrypt.Ready: return cryptCtx.Finish() default: @@ -265,14 +265,14 @@ func (c *crypt) retrieveKeys(ctx context.Context, cryptCtx *mongocrypt.Context) return cryptCtx.CompleteOperation() } -func (c *crypt) decryptKeys(ctx context.Context, cryptCtx *mongocrypt.Context) error { +func (c *crypt) decryptKeys(cryptCtx *mongocrypt.Context) error { for { kmsCtx := cryptCtx.NextKmsContext() if kmsCtx == nil { break } - if err := c.decryptKey(ctx, kmsCtx); err != nil { + if err := c.decryptKey(kmsCtx); err != nil { return err } } @@ -280,7 +280,7 @@ func (c *crypt) decryptKeys(ctx context.Context, cryptCtx *mongocrypt.Context) e return cryptCtx.FinishKmsContexts() } -func (c *crypt) decryptKey(ctx context.Context, kmsCtx *mongocrypt.KmsContext) error { +func (c *crypt) decryptKey(kmsCtx *mongocrypt.KmsContext) error { host, err := kmsCtx.HostName() if err != nil { return err diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/dns/dns.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/dns/dns.go index c48d932a..16268b59 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/dns/dns.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/dns/dns.go @@ -86,7 +86,7 @@ func (r *Resolver) fetchSeedlistFromSRV(host string, srvName string, stopOnErr b trimmedHost := strings.TrimSuffix(host, ".") - var parsedHosts []string + parsedHosts := make([]string, 0, len(addresses)) for _, address := range addresses { trimmedAddressTarget := strings.TrimSuffix(address.Target, ".") err := validateSRVResult(trimmedAddressTarget, trimmedHost) diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/driver.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/driver.go index c7637406..9a2ccda7 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/driver.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/driver.go @@ -54,7 +54,12 @@ type Connection interface { WriteWireMessage(context.Context, []byte) error ReadWireMessage(ctx context.Context, dst []byte) ([]byte, error) Description() description.Server + + // Close closes any underlying connection and returns or frees any resources held by the + // connection. Close is idempotent and can be called multiple times, although subsequent calls + // to Close may return an error. A connection cannot be used after it is closed. Close() error + ID() string ServerConnectionID() *int32 Address() address.Address diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/errors.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/errors.go index 5deb04eb..fd1e2ad1 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/errors.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/errors.go @@ -82,6 +82,7 @@ type WriteCommandError struct { WriteConcernError *WriteConcernError WriteErrors WriteErrors Labels []string + Raw bsoncore.Document } // UnsupportedStorageEngine returns whether or not the WriteCommandError comes from a retryable write being attempted @@ -129,6 +130,7 @@ type WriteConcernError struct { Details bsoncore.Document Labels []string TopologyVersion *description.TopologyVersion + Raw bsoncore.Document } func (wce WriteConcernError) Error() string { @@ -189,6 +191,7 @@ type WriteError struct { Code int64 Message string Details bsoncore.Document + Raw bsoncore.Document } func (we WriteError) Error() string { return we.Message } @@ -218,6 +221,7 @@ type Error struct { Name string Wrapped error TopologyVersion *description.TopologyVersion + Raw bsoncore.Document } // UnsupportedStorageEngine returns whether e came as a result of an unsupported storage engine @@ -417,6 +421,7 @@ func ExtractErrorFromServerResponse(doc bsoncore.Document) error { we.Details = make([]byte, len(info)) copy(we.Details, info) } + we.Raw = doc wcError.WriteErrors = append(wcError.WriteErrors, we) } case "writeConcernError": @@ -425,6 +430,7 @@ func ExtractErrorFromServerResponse(doc bsoncore.Document) error { break } wcError.WriteConcernError = new(WriteConcernError) + wcError.WriteConcernError.Raw = doc if code, exists := doc.Lookup("code").AsInt64OK(); exists { wcError.WriteConcernError.Code = code } @@ -472,6 +478,7 @@ func ExtractErrorFromServerResponse(doc bsoncore.Document) error { Name: codeName, Labels: labels, TopologyVersion: tv, + Raw: doc, } } @@ -480,6 +487,7 @@ func ExtractErrorFromServerResponse(doc bsoncore.Document) error { if wcError.WriteConcernError != nil { wcError.WriteConcernError.TopologyVersion = tv } + wcError.Raw = doc return wcError } diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/binary.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/binary.go index 3794ee5c..9e887375 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/binary.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/binary.go @@ -4,6 +4,7 @@ // 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 +//go:build cse // +build cse package mongocrypt diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/errors.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/errors.go index 8c235c5b..3401e738 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/errors.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/errors.go @@ -4,6 +4,7 @@ // 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 +//go:build cse // +build cse package mongocrypt diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/errors_not_enabled.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/errors_not_enabled.go index 816099ab..706a0f9e 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/errors_not_enabled.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/errors_not_enabled.go @@ -4,6 +4,7 @@ // 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 +//go:build !cse // +build !cse package mongocrypt diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/mongocrypt.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/mongocrypt.go index edfedf1a..ba547ad4 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/mongocrypt.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/mongocrypt.go @@ -4,6 +4,7 @@ // 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 +//go:build cse // +build cse package mongocrypt diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/mongocrypt_context.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/mongocrypt_context.go index dc0dd514..a5380196 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/mongocrypt_context.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/mongocrypt_context.go @@ -4,6 +4,7 @@ // 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 +//go:build cse // +build cse package mongocrypt diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/mongocrypt_context_not_enabled.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/mongocrypt_context_not_enabled.go index b0ff1689..624888a2 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/mongocrypt_context_not_enabled.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/mongocrypt_context_not_enabled.go @@ -4,6 +4,7 @@ // 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 +//go:build !cse // +build !cse package mongocrypt diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/mongocrypt_kms_context.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/mongocrypt_kms_context.go index 69a72d5c..296a2231 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/mongocrypt_kms_context.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/mongocrypt_kms_context.go @@ -4,6 +4,7 @@ // 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 +//go:build cse // +build cse package mongocrypt diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/mongocrypt_kms_context_not_enabled.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/mongocrypt_kms_context_not_enabled.go index f2632a86..272367ea 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/mongocrypt_kms_context_not_enabled.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/mongocrypt_kms_context_not_enabled.go @@ -4,6 +4,7 @@ // 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 +//go:build !cse // +build !cse package mongocrypt diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/mongocrypt_not_enabled.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/mongocrypt_not_enabled.go index d91cc674..92f49976 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/mongocrypt_not_enabled.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/mongocrypt/mongocrypt_not_enabled.go @@ -4,6 +4,7 @@ // 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 +//go:build !cse // +build !cse package mongocrypt diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/ocsp/ocsp.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/ocsp/ocsp.go index 764dcb43..ed625706 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/ocsp/ocsp.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/ocsp/ocsp.go @@ -18,7 +18,6 @@ import ( "io/ioutil" "math/big" "net/http" - "net/url" "time" "golang.org/x/crypto/ocsp" @@ -28,9 +27,6 @@ import ( var ( tlsFeatureExtensionOID = asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 1, 24} mustStapleFeatureValue = big.NewInt(5) - - defaultRequestTimeout = 5 * time.Second - errGotOCSPResponse = errors.New("done") ) // Error represents an OCSP verification error @@ -126,10 +122,7 @@ func getParsedResponse(ctx context.Context, cfg config, connState tls.Connection if cfg.disableEndpointChecking { return nil, nil } - externalResponse, err := contactResponders(ctx, cfg) - if err != nil { - return nil, err - } + externalResponse := contactResponders(ctx, cfg) if externalResponse == nil { // None of the responders were available. return nil, nil @@ -210,33 +203,21 @@ func isMustStapleCertificate(cert *x509.Certificate) (bool, error) { return false, nil } -// contactResponders will send a request to the OCSP responders reported by cfg.serverCert. The first response that -// conclusively identifies cfg.serverCert as good or revoked will be returned. If all responders are unavailable or no -// responder returns a conclusive status, (nil, nil) will be returned. -func contactResponders(ctx context.Context, cfg config) (*ResponseDetails, error) { +// contactResponders will send a request to all OCSP responders reported by cfg.serverCert. The +// first response that conclusively identifies cfg.serverCert as good or revoked will be returned. +// If all responders are unavailable or no responder returns a conclusive status, it returns nil. +// contactResponders will wait for up to 5 seconds to get a certificate status response. +func contactResponders(ctx context.Context, cfg config) *ResponseDetails { if len(cfg.serverCert.OCSPServer) == 0 { - return nil, nil + return nil } - requestCtx := ctx // Either ctx or a new context derived from ctx with a five second timeout. - userContextUsed := true - var cancelFn context.CancelFunc - - // Use a context with defaultRequestTimeout if ctx does not have a deadline set or the current deadline is further - // out than defaultRequestTimeout. If the current deadline is less than less than defaultRequestTimeout out, respect - // it. Calling context.WithTimeout would do this for us, but we need to know which context we're using. - wantDeadline := time.Now().Add(defaultRequestTimeout) - if deadline, ok := ctx.Deadline(); !ok || deadline.After(wantDeadline) { - userContextUsed = false - requestCtx, cancelFn = context.WithDeadline(ctx, wantDeadline) - } - defer func() { - if cancelFn != nil { - cancelFn() - } - }() + // Limit all OCSP responder calls to a maximum of 5 seconds or when the passed-in context expires, + // whichever happens first. + ctx, cancel := context.WithTimeout(ctx, 5*time.Second) + defer cancel() - group, groupCtx := errgroup.WithContext(requestCtx) + group, ctx := errgroup.WithContext(ctx) ocspResponses := make(chan *ocsp.Response, len(cfg.serverCert.OCSPServer)) defer close(ocspResponses) @@ -244,6 +225,11 @@ func contactResponders(ctx context.Context, cfg config) (*ResponseDetails, error // Re-assign endpoint so it gets re-scoped rather than using the iteration variable in the goroutine. See // https://golang.org/doc/faq#closures_and_goroutines. endpoint := endpoint + + // Start a group of goroutines that each attempt to request the certificate status from one + // of the OCSP endpoints listed in the server certificate. We want to "soft fail" on all + // errors, so this function never returns actual errors. Only a "done" error is returned + // when a response is received so the errgroup cancels any other in-progress requests. group.Go(func() error { // Use bytes.NewReader instead of bytes.NewBuffer because a bytes.Buffer is an owning representation and the // docs recommend not using the underlying []byte after creating the buffer, so a new copy of the request @@ -252,35 +238,16 @@ func contactResponders(ctx context.Context, cfg config) (*ResponseDetails, error if err != nil { return nil } - request = request.WithContext(groupCtx) - - // Execute the request and handle errors as follows: - // - // 1. If the original context expired or was cancelled, propagate the error up so the caller will abort the - // verification and return control to the user. - // - // 2. If any other errors occurred, including the defaultRequestTimeout expiring, or the response has a - // non-200 status code, suppress the error because we want to ignore this responder and wait for a different - // one to responsd. + request = request.WithContext(ctx) + httpResponse, err := http.DefaultClient.Do(request) if err != nil { - urlErr, ok := err.(*url.Error) - if !ok { - return nil - } - - timeout := urlErr.Timeout() - cancelled := urlErr.Err == context.Canceled // Timeout() does not return true for context.Cancelled. - if cancelled || (userContextUsed && timeout) { - // Handle the original context expiring or being cancelled. The url.Error type supports Unwrap, so - // users can use errors.Is to check for context errors. - return err - } - return nil // Ignore all other errors. + return nil } defer func() { _ = httpResponse.Body.Close() }() + if httpResponse.StatusCode != 200 { return nil } @@ -292,26 +259,27 @@ func contactResponders(ctx context.Context, cfg config) (*ResponseDetails, error ocspResponse, err := ocsp.ParseResponseForCert(httpBytes, cfg.serverCert, cfg.issuer) if err != nil || verifyResponse(cfg, ocspResponse) != nil || ocspResponse.Status == ocsp.Unknown { - // If there was an error parsing/validating the response or the response was inconclusive, suppress - // the error because we want to ignore this responder. + // If there was an error parsing/validating the response or the response was + // inconclusive, suppress the error because we want to ignore this responder. return nil } - // Store the response and return a sentinel error so the error group will exit and any in-flight requests - // will be cancelled. + // Send the conclusive response on the response channel and return a "done" error that + // will cause the errgroup to cancel all other in-progress requests. ocspResponses <- ocspResponse - return errGotOCSPResponse + return errors.New("done") }) } - if err := group.Wait(); err != nil && err != errGotOCSPResponse { - return nil, err - } - if len(ocspResponses) == 0 { - // None of the responders gave a conclusive response. - return nil, nil + _ = group.Wait() + select { + case res := <-ocspResponses: + return extractResponseDetails(res) + default: + // If there is no OCSP response on the response channel, all OCSP calls either failed or + // were inconclusive. Return nil. + return nil } - return extractResponseDetails(<-ocspResponses), nil } // verifyResponse checks that the provided OCSP response is valid. diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation.go index 56c10c44..f1647bef 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation.go @@ -47,6 +47,11 @@ const ( readSnapshotMinWireVersion int32 = 13 ) +// RetryablePoolError is a connection pool error that can be retried while executing an operation. +type RetryablePoolError interface { + Retryable() bool +} + // InvalidOperationError is returned from Validate and indicates that a required field is missing // from an instance of Operation. type InvalidOperationError struct{ MissingField string } @@ -305,40 +310,8 @@ func (op Operation) Execute(ctx context.Context, scratch []byte) error { } } - srvr, conn, err := op.getServerAndConnection(ctx) - if err != nil { - return err - } - defer conn.Close() - - desc := description.SelectedServer{Server: conn.Description(), Kind: op.Deployment.Kind()} - scratch = scratch[:0] - - if desc.WireVersion == nil || desc.WireVersion.Max < 4 { - switch op.Legacy { - case LegacyFind: - return op.legacyFind(ctx, scratch, srvr, conn, desc) - case LegacyGetMore: - return op.legacyGetMore(ctx, scratch, srvr, conn, desc) - case LegacyKillCursors: - return op.legacyKillCursors(ctx, scratch, srvr, conn, desc) - } - } - if desc.WireVersion == nil || desc.WireVersion.Max < 3 { - switch op.Legacy { - case LegacyListCollections: - return op.legacyListCollections(ctx, scratch, srvr, conn, desc) - case LegacyListIndexes: - return op.legacyListIndexes(ctx, scratch, srvr, conn, desc) - } - } - - var res bsoncore.Document - var operationErr WriteCommandError - var original error var retries int - retryable := op.retryable(desc.Server) - if retryable && op.RetryMode != nil { + if op.RetryMode != nil { switch op.Type { case Write: if op.Client == nil { @@ -350,15 +323,6 @@ func (op Operation) Execute(ctx context.Context, scratch []byte) error { case RetryContext: retries = -1 } - - op.Client.RetryWrite = false - if *op.RetryMode > RetryNone { - op.Client.RetryWrite = true - if !op.Client.Committing && !op.Client.Aborting { - op.Client.IncrementTxnNumber() - } - } - case Read: switch *op.RetryMode { case RetryOnce, RetryOncePerCommand: @@ -368,10 +332,107 @@ func (op Operation) Execute(ctx context.Context, scratch []byte) error { } } } + + var srvr Server + var conn Connection + var res bsoncore.Document + var operationErr WriteCommandError + var prevErr error batching := op.Batches.Valid() retryEnabled := op.RetryMode != nil && op.RetryMode.Enabled() + retrySupported := false + first := true currIndex := 0 + + // resetForRetry records the error that caused the retry, decrements retries, and resets the + // retry loop variables to request a new server and a new connection for the next attempt. + resetForRetry := func(err error) { + retries-- + prevErr = err + // If we got a connection, close it immediately to release pool resources for + // subsequent retries. + if conn != nil { + conn.Close() + } + // Set the server and connection to nil to request a new server and connection. + srvr = nil + conn = nil + } + for { + // If the server or connection are nil, try to select a new server and get a new connection. + if srvr == nil || conn == nil { + srvr, conn, err = op.getServerAndConnection(ctx) + if err != nil { + // If the returned error is retryable and there are retries remaining (negative + // retries means retry indefinitely), then retry the operation. Set the server + // and connection to nil to request a new server and connection. + if rerr, ok := err.(RetryablePoolError); ok && rerr.Retryable() && retries != 0 { + resetForRetry(err) + continue + } + + // If this is a retry and there's an error from a previous attempt, return the previous + // error instead of the current connection error. + if prevErr != nil { + return prevErr + } + return err + } + defer conn.Close() + } + + // Run steps that must only be run on the first attempt, but not again for retries. + if first { + // Determine if retries are supported for the current operation on the current server + // description. Per the retryable writes specification, only determine this for the + // first server selected: + // + // If the server selected for the first attempt of a retryable write operation does + // not support retryable writes, drivers MUST execute the write as if retryable writes + // were not enabled. + retrySupported = op.retryable(conn.Description()) + + // If retries are supported for the current operation on the current server description, + // client retries are enabled, the operation type is write, and we haven't incremented + // the txn number yet, enable retry writes on the session and increment the txn number. + // Calling IncrementTxnNumber() for server descriptions or topologies that do not + // support retries (e.g. standalone topologies) will cause server errors. Only do this + // check for the first attempt to keep retried writes in the same transaction. + if retrySupported && op.RetryMode != nil && op.Type == Write && op.Client != nil { + op.Client.RetryWrite = false + if op.RetryMode.Enabled() { + op.Client.RetryWrite = true + if !op.Client.Committing && !op.Client.Aborting { + op.Client.IncrementTxnNumber() + } + } + } + + first = false + } + + desc := description.SelectedServer{Server: conn.Description(), Kind: op.Deployment.Kind()} + scratch = scratch[:0] + if desc.WireVersion == nil || desc.WireVersion.Max < 4 { + switch op.Legacy { + case LegacyFind: + return op.legacyFind(ctx, scratch, srvr, conn, desc) + case LegacyGetMore: + return op.legacyGetMore(ctx, scratch, srvr, conn, desc) + case LegacyKillCursors: + return op.legacyKillCursors(ctx, scratch, srvr, conn, desc) + } + } + if desc.WireVersion == nil || desc.WireVersion.Max < 3 { + switch op.Legacy { + case LegacyListCollections: + return op.legacyListCollections(ctx, scratch, srvr, conn, desc) + case LegacyListIndexes: + return op.legacyListIndexes(ctx, scratch, srvr, conn, desc) + } + } + if batching { targetBatchSize := desc.MaxDocumentSize maxDocSize := desc.MaxDocumentSize @@ -455,7 +516,7 @@ func (op Operation) Execute(ctx context.Context, scratch []byte) error { var perr error switch tt := err.(type) { case WriteCommandError: - if e := err.(WriteCommandError); retryable && op.Type == Write && e.UnsupportedStorageEngine() { + if e := err.(WriteCommandError); retrySupported && op.Type == Write && e.UnsupportedStorageEngine() { return ErrUnsupportedStorageEngine } @@ -470,23 +531,16 @@ func (op Operation) Execute(ctx context.Context, scratch []byte) error { tt.Labels = append(tt.Labels, RetryableWriteError) } - if retryable && retryableErr && retries != 0 { - retries-- - original = err - conn.Close() // Avoid leaking the connection. - srvr, conn, err = op.getServerAndConnection(ctx) - if err != nil || conn == nil || !op.retryable(conn.Description()) { - if conn != nil { - conn.Close() - } - return original - } - defer conn.Close() // Avoid leaking the new connection. + // If retries are supported for the current operation on the first server description, + // the error is considered retryable, and there are retries remaining (negative retries + // means retry indefinitely), then retry the operation. + if retrySupported && retryableErr && retries != 0 { if op.Client != nil && op.Client.Committing { // Apply majority write concern for retries op.Client.UpdateCommitTransactionWriteConcern() op.WriteConcern = op.Client.CurrentWc } + resetForRetry(tt) continue } @@ -520,6 +574,7 @@ func (op Operation) Execute(ctx context.Context, scratch []byte) error { Code: int32(tt.WriteConcernError.Code), Message: tt.WriteConcernError.Message, Labels: tt.Labels, + Raw: tt.Raw, } // The UnknownTransactionCommitResult label is added to all writeConcernErrors besides unknownReplWriteConcernCode // and unsatisfiableWriteConcernCode @@ -534,13 +589,15 @@ func (op Operation) Execute(ctx context.Context, scratch []byte) error { operationErr.WriteConcernError = tt.WriteConcernError operationErr.WriteErrors = append(operationErr.WriteErrors, tt.WriteErrors...) operationErr.Labels = tt.Labels + operationErr.Raw = tt.Raw case Error: if tt.HasErrorLabel(TransientTransactionError) || tt.HasErrorLabel(UnknownTransactionCommitResult) { if err := op.Client.ClearPinnedResources(); err != nil { return err } } - if e := err.(Error); retryable && op.Type == Write && e.UnsupportedStorageEngine() { + + if e := err.(Error); retrySupported && op.Type == Write && e.UnsupportedStorageEngine() { return ErrUnsupportedStorageEngine } @@ -561,23 +618,16 @@ func (op Operation) Execute(ctx context.Context, scratch []byte) error { retryableErr = tt.RetryableRead() } - if retryable && retryableErr && retries != 0 { - retries-- - original = err - conn.Close() // Avoid leaking the connection. - srvr, conn, err = op.getServerAndConnection(ctx) - if err != nil || conn == nil || !op.retryable(conn.Description()) { - if conn != nil { - conn.Close() - } - return original - } - defer conn.Close() // Avoid leaking the new connection. + // If retries are supported for the current operation on the first server description, + // the error is considered retryable, and there are retries remaining (negative retries + // means retry indefinitely), then retry the operation. + if retrySupported && retryableErr && retries != 0 { if op.Client != nil && op.Client.Committing { // Apply majority write concern for retries op.Client.UpdateCommitTransactionWriteConcern() op.WriteConcern = op.Client.CurrentWc } + resetForRetry(tt) continue } @@ -629,8 +679,11 @@ func (op Operation) Execute(ctx context.Context, scratch []byte) error { return err } + // If we're batching and there are batches remaining, advance to the next batch. This isn't + // a retry, so increment the transaction number, reset the retries number, and don't set + // server or connection to nil to continue using the same connection. if batching && len(op.Batches.Documents) > 0 { - if retryable && op.Client != nil && op.RetryMode != nil { + if retrySupported && op.Client != nil && op.RetryMode != nil { if *op.RetryMode > RetryNone { op.Client.IncrementTxnNumber() } @@ -813,8 +866,10 @@ func (Operation) decompressWireMessage(wm []byte) ([]byte, error) { func (op Operation) createWireMessage(ctx context.Context, dst []byte, desc description.SelectedServer, conn Connection) ([]byte, startedInformation, error) { - - if desc.WireVersion == nil || desc.WireVersion.Max < wiremessage.OpmsgWireVersion { + // If topology is not LoadBalanced, API version is not declared, and wire version is unknown + // or less than 6, use OP_QUERY. Otherwise, use OP_MSG. + if desc.Kind != description.LoadBalanced && op.ServerAPI == nil && + (desc.WireVersion == nil || desc.WireVersion.Max < wiremessage.OpmsgWireVersion) { return op.createQueryWireMessage(dst, desc) } return op.createMsgWireMessage(ctx, dst, desc, conn) diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/abort_transaction.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/abort_transaction.go index e8cf3b76..608733b4 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/abort_transaction.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/abort_transaction.go @@ -44,7 +44,7 @@ func (at *AbortTransaction) processResponse(driver.ResponseInfo) error { return err } -// Execute runs this operations and returns an error if the operaiton did not execute successfully. +// Execute runs this operations and returns an error if the operation did not execute successfully. func (at *AbortTransaction) Execute(ctx context.Context) error { if at.deployment == nil { return errors.New("the AbortTransaction operation must have a Deployment set before Execute can be called") diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/aggregate.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/aggregate.go index 9163fb7c..e3554e33 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/aggregate.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/aggregate.go @@ -21,7 +21,7 @@ import ( "go.mongodb.org/mongo-driver/x/mongo/driver/session" ) -// Performs an aggregate operation +// Aggregate represents an aggregate operation. type Aggregate struct { allowDiskUse *bool batchSize *int32 @@ -46,6 +46,7 @@ type Aggregate struct { serverAPI *driver.ServerAPIOptions let bsoncore.Document hasOutputStage bool + customOptions map[string]bsoncore.Value result driver.CursorResponse } @@ -67,6 +68,8 @@ func (a *Aggregate) Result(opts driver.CursorOptions) (*driver.BatchCursor, erro return driver.NewBatchCursor(a.result, clientSession, clock, opts) } +// ResultCursorResponse returns the underlying CursorResponse result of executing this +// operation. func (a *Aggregate) ResultCursorResponse() driver.CursorResponse { return a.result } @@ -79,7 +82,7 @@ func (a *Aggregate) processResponse(info driver.ResponseInfo) error { } -// Execute runs this operations and returns an error if the operaiton did not execute successfully. +// Execute runs this operations and returns an error if the operation did not execute successfully. func (a *Aggregate) Execute(ctx context.Context) error { if a.deployment == nil { return errors.New("the Aggregate operation must have a Deployment set before Execute can be called") @@ -153,6 +156,9 @@ func (a *Aggregate) command(dst []byte, desc description.SelectedServer) ([]byte if a.let != nil { dst = bsoncore.AppendDocumentElement(dst, "let", a.let) } + for optionName, optionValue := range a.customOptions { + dst = bsoncore.AppendValueElement(dst, optionName, optionValue) + } cursorDoc, _ = bsoncore.AppendDocumentEnd(cursorDoc, cursorIdx) dst = bsoncore.AppendDocumentElement(dst, "cursor", cursorDoc) @@ -391,3 +397,13 @@ func (a *Aggregate) HasOutputStage(hos bool) *Aggregate { a.hasOutputStage = hos return a } + +// CustomOptions specifies extra options to use in the aggregate command. +func (a *Aggregate) CustomOptions(co map[string]bsoncore.Value) *Aggregate { + if a == nil { + a = new(Aggregate) + } + + a.customOptions = co + return a +} diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/command.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/command.go index 27d02729..07b21c56 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/command.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/command.go @@ -69,7 +69,7 @@ func (c *Command) ResultCursor() (*driver.BatchCursor, error) { return c.resultCursor, nil } -// Execute runs this operations and returns an error if the operaiton did not execute successfully. +// Execute runs this operations and returns an error if the operation did not execute successfully. func (c *Command) Execute(ctx context.Context) error { if c.deployment == nil { return errors.New("the Command operation must have a Deployment set before Execute can be called") diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/commit_transaction.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/commit_transaction.go index 7be5c7cb..14ed7bcd 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/commit_transaction.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/commit_transaction.go @@ -44,7 +44,7 @@ func (ct *CommitTransaction) processResponse(driver.ResponseInfo) error { return err } -// Execute runs this operations and returns an error if the operaiton did not execute successfully. +// Execute runs this operations and returns an error if the operation did not execute successfully. func (ct *CommitTransaction) Execute(ctx context.Context) error { if ct.deployment == nil { return errors.New("the CommitTransaction operation must have a Deployment set before Execute can be called") diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/count.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/count.go index 8266fa59..8404f364 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/count.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/count.go @@ -20,7 +20,7 @@ import ( "go.mongodb.org/mongo-driver/x/mongo/driver/session" ) -// Performs a count operation +// Count represents a count operation. type Count struct { maxTimeMS *int64 query bsoncore.Document @@ -39,12 +39,13 @@ type Count struct { serverAPI *driver.ServerAPIOptions } +// CountResult represents a count result returned by the server. type CountResult struct { // The number of documents found N int64 } -func buildCountResult(response bsoncore.Document, srvr driver.Server) (CountResult, error) { +func buildCountResult(response bsoncore.Document) (CountResult, error) { elements, err := response.Elements() if err != nil { return CountResult{}, err @@ -94,11 +95,11 @@ func (c *Count) Result() CountResult { return c.result } func (c *Count) processResponse(info driver.ResponseInfo) error { var err error - c.result, err = buildCountResult(info.ServerResponse, info.Server) + c.result, err = buildCountResult(info.ServerResponse) return err } -// Execute runs this operations and returns an error if the operaiton did not execute successfully. +// Execute runs this operations and returns an error if the operation did not execute successfully. func (c *Count) Execute(ctx context.Context) error { if c.deployment == nil { return errors.New("the Count operation must have a Deployment set before Execute can be called") diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/create.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/create.go index 9a8b8bfc..48fee42b 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/create.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/create.go @@ -18,7 +18,7 @@ import ( "go.mongodb.org/mongo-driver/x/mongo/driver/session" ) -// Create a create operation +// Create represents a create operation. type Create struct { capped *bool collation bsoncore.Document @@ -56,7 +56,7 @@ func (c *Create) processResponse(driver.ResponseInfo) error { return nil } -// Execute runs this operations and returns an error if the operaiton did not execute successfully. +// Execute runs this operations and returns an error if the operation did not execute successfully. func (c *Create) Execute(ctx context.Context) error { if c.deployment == nil { return errors.New("the Create operation must have a Deployment set before Execute can be called") @@ -127,7 +127,7 @@ func (c *Create) command(dst []byte, desc description.SelectedServer) ([]byte, e return dst, nil } -// Specifies if the collection is capped. +// Capped specifies if the collection is capped. func (c *Create) Capped(capped bool) *Create { if c == nil { c = new(Create) @@ -147,7 +147,7 @@ func (c *Create) Collation(collation bsoncore.Document) *Create { return c } -// Specifies the name of the collection to create. +// CollectionName specifies the name of the collection to create. func (c *Create) CollectionName(collectionName string) *Create { if c == nil { c = new(Create) @@ -157,7 +157,7 @@ func (c *Create) CollectionName(collectionName string) *Create { return c } -// Specifies a default configuration for indexes on the collection. +// IndexOptionDefaults specifies a default configuration for indexes on the collection. func (c *Create) IndexOptionDefaults(indexOptionDefaults bsoncore.Document) *Create { if c == nil { c = new(Create) @@ -167,7 +167,7 @@ func (c *Create) IndexOptionDefaults(indexOptionDefaults bsoncore.Document) *Cre return c } -// Specifies the maximum number of documents allowed in a capped collection. +// Max specifies the maximum number of documents allowed in a capped collection. func (c *Create) Max(max int64) *Create { if c == nil { c = new(Create) @@ -177,7 +177,7 @@ func (c *Create) Max(max int64) *Create { return c } -// Specifies the agggregtion pipeline to be run against the source to create the view. +// Pipeline specifies the agggregtion pipeline to be run against the source to create the view. func (c *Create) Pipeline(pipeline bsoncore.Document) *Create { if c == nil { c = new(Create) @@ -187,7 +187,7 @@ func (c *Create) Pipeline(pipeline bsoncore.Document) *Create { return c } -// Specifies the maximum size in bytes for a capped collection. +// Size specifies the maximum size in bytes for a capped collection. func (c *Create) Size(size int64) *Create { if c == nil { c = new(Create) @@ -197,7 +197,7 @@ func (c *Create) Size(size int64) *Create { return c } -// Specifies the storage engine to use for the index. +// StorageEngine specifies the storage engine to use for the index. func (c *Create) StorageEngine(storageEngine bsoncore.Document) *Create { if c == nil { c = new(Create) @@ -207,7 +207,7 @@ func (c *Create) StorageEngine(storageEngine bsoncore.Document) *Create { return c } -// Specifies what should happen if a document being inserted does not pass validation. +// ValidationAction specifies what should happen if a document being inserted does not pass validation. func (c *Create) ValidationAction(validationAction string) *Create { if c == nil { c = new(Create) @@ -217,7 +217,8 @@ func (c *Create) ValidationAction(validationAction string) *Create { return c } -// Specifies how strictly the server applies validation rules to existing documents in the collection during update operations. +// ValidationLevel specifies how strictly the server applies validation rules to existing documents in the collection +// during update operations. func (c *Create) ValidationLevel(validationLevel string) *Create { if c == nil { c = new(Create) @@ -227,7 +228,7 @@ func (c *Create) ValidationLevel(validationLevel string) *Create { return c } -// Specifies validation rules for the collection. +// Validator specifies validation rules for the collection. func (c *Create) Validator(validator bsoncore.Document) *Create { if c == nil { c = new(Create) @@ -237,7 +238,7 @@ func (c *Create) Validator(validator bsoncore.Document) *Create { return c } -// Specifies the name of the source collection or view on which the view will be created. +// ViewOn specifies the name of the source collection or view on which the view will be created. func (c *Create) ViewOn(viewOn string) *Create { if c == nil { c = new(Create) diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/createIndexes.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/createIndexes.go index b9ceefe0..6bf98dee 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/createIndexes.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/createIndexes.go @@ -38,6 +38,7 @@ type CreateIndexes struct { serverAPI *driver.ServerAPIOptions } +// CreateIndexesResult represents a createIndexes result returned by the server. type CreateIndexesResult struct { // If the collection was created automatically. CreatedCollectionAutomatically bool @@ -47,7 +48,7 @@ type CreateIndexesResult struct { IndexesBefore int32 } -func buildCreateIndexesResult(response bsoncore.Document, srvr driver.Server) (CreateIndexesResult, error) { +func buildCreateIndexesResult(response bsoncore.Document) (CreateIndexesResult, error) { elements, err := response.Elements() if err != nil { return CreateIndexesResult{}, err @@ -90,11 +91,11 @@ func (ci *CreateIndexes) Result() CreateIndexesResult { return ci.result } func (ci *CreateIndexes) processResponse(info driver.ResponseInfo) error { var err error - ci.result, err = buildCreateIndexesResult(info.ServerResponse, info.Server) + ci.result, err = buildCreateIndexesResult(info.ServerResponse) return err } -// Execute runs this operations and returns an error if the operaiton did not execute successfully. +// Execute runs this operations and returns an error if the operation did not execute successfully. func (ci *CreateIndexes) Execute(ctx context.Context) error { if ci.deployment == nil { return errors.New("the CreateIndexes operation must have a Deployment set before Execute can be called") @@ -133,9 +134,9 @@ func (ci *CreateIndexes) command(dst []byte, desc description.SelectedServer) ([ return dst, nil } -// The number of data-bearing members of a replica set, including the primary, that must complete the index builds -// successfully before the primary marks the indexes as ready. This should either be a string or int32 value. -// +// CommitQuorum specifies the number of data-bearing members of a replica set, including the primary, that must +// complete the index builds successfully before the primary marks the indexes as ready. This should either be a +// string or int32 value. func (ci *CreateIndexes) CommitQuorum(commitQuorum bsoncore.Value) *CreateIndexes { if ci == nil { ci = new(CreateIndexes) @@ -145,7 +146,7 @@ func (ci *CreateIndexes) CommitQuorum(commitQuorum bsoncore.Value) *CreateIndexe return ci } -// An array containing index specification documents for the indexes being created. +// Indexes specifies an array containing index specification documents for the indexes being created. func (ci *CreateIndexes) Indexes(indexes bsoncore.Document) *CreateIndexes { if ci == nil { ci = new(CreateIndexes) diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/delete.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/delete.go index 33976348..beb893c7 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/delete.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/delete.go @@ -36,14 +36,16 @@ type Delete struct { hint *bool result DeleteResult serverAPI *driver.ServerAPIOptions + let bsoncore.Document } +// DeleteResult represents a delete result returned by the server. type DeleteResult struct { // Number of documents successfully deleted. - N int32 + N int64 } -func buildDeleteResult(response bsoncore.Document, srvr driver.Server) (DeleteResult, error) { +func buildDeleteResult(response bsoncore.Document) (DeleteResult, error) { elements, err := response.Elements() if err != nil { return DeleteResult{}, err @@ -53,9 +55,9 @@ func buildDeleteResult(response bsoncore.Document, srvr driver.Server) (DeleteRe switch element.Key() { case "n": var ok bool - dr.N, ok = element.Value().AsInt32OK() + dr.N, ok = element.Value().AsInt64OK() if !ok { - return dr, fmt.Errorf("response field 'n' is type int32, but received BSON type %s", element.Value().Type) + return dr, fmt.Errorf("response field 'n' is type int32 or int64, but received BSON type %s", element.Value().Type) } } } @@ -73,12 +75,12 @@ func NewDelete(deletes ...bsoncore.Document) *Delete { func (d *Delete) Result() DeleteResult { return d.result } func (d *Delete) processResponse(info driver.ResponseInfo) error { - dr, err := buildDeleteResult(info.ServerResponse, info.Server) + dr, err := buildDeleteResult(info.ServerResponse) d.result.N += dr.N return err } -// Execute runs this operations and returns an error if the operaiton did not execute successfully. +// Execute runs this operations and returns an error if the operation did not execute successfully. func (d *Delete) Execute(ctx context.Context) error { if d.deployment == nil { return errors.New("the Delete operation must have a Deployment set before Execute can be called") @@ -121,6 +123,9 @@ func (d *Delete) command(dst []byte, desc description.SelectedServer) ([]byte, e return nil, errUnacknowledgedHint } } + if d.let != nil { + dst = bsoncore.AppendDocumentElement(dst, "let", d.let) + } return dst, nil } @@ -269,3 +274,13 @@ func (d *Delete) ServerAPI(serverAPI *driver.ServerAPIOptions) *Delete { d.serverAPI = serverAPI return d } + +// Let specifies the let document to use. This option is only valid for server versions 5.0 and above. +func (d *Delete) Let(let bsoncore.Document) *Delete { + if d == nil { + d = new(Delete) + } + + d.let = let + return d +} diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/distinct.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/distinct.go index 0ac804af..4591c1ad 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/distinct.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/distinct.go @@ -40,12 +40,13 @@ type Distinct struct { serverAPI *driver.ServerAPIOptions } +// DistinctResult represents a distinct result returned by the server. type DistinctResult struct { // The distinct values for the field. Values bsoncore.Value } -func buildDistinctResult(response bsoncore.Document, srvr driver.Server) (DistinctResult, error) { +func buildDistinctResult(response bsoncore.Document) (DistinctResult, error) { elements, err := response.Elements() if err != nil { return DistinctResult{}, err @@ -73,11 +74,11 @@ func (d *Distinct) Result() DistinctResult { return d.result } func (d *Distinct) processResponse(info driver.ResponseInfo) error { var err error - d.result, err = buildDistinctResult(info.ServerResponse, info.Server) + d.result, err = buildDistinctResult(info.ServerResponse) return err } -// Execute runs this operations and returns an error if the operaiton did not execute successfully. +// Execute runs this operations and returns an error if the operation did not execute successfully. func (d *Distinct) Execute(ctx context.Context) error { if d.deployment == nil { return errors.New("the Distinct operation must have a Deployment set before Execute can be called") diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/drop_collection.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/drop_collection.go index 9f8f8c52..fab279dc 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/drop_collection.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/drop_collection.go @@ -34,6 +34,7 @@ type DropCollection struct { serverAPI *driver.ServerAPIOptions } +// DropCollectionResult represents a dropCollection result returned by the server. type DropCollectionResult struct { // The number of indexes in the dropped collection. NIndexesWas int32 @@ -41,7 +42,7 @@ type DropCollectionResult struct { Ns string } -func buildDropCollectionResult(response bsoncore.Document, srvr driver.Server) (DropCollectionResult, error) { +func buildDropCollectionResult(response bsoncore.Document) (DropCollectionResult, error) { elements, err := response.Elements() if err != nil { return DropCollectionResult{}, err @@ -76,11 +77,11 @@ func (dc *DropCollection) Result() DropCollectionResult { return dc.result } func (dc *DropCollection) processResponse(info driver.ResponseInfo) error { var err error - dc.result, err = buildDropCollectionResult(info.ServerResponse, info.Server) + dc.result, err = buildDropCollectionResult(info.ServerResponse) return err } -// Execute runs this operations and returns an error if the operaiton did not execute successfully. +// Execute runs this operations and returns an error if the operation did not execute successfully. func (dc *DropCollection) Execute(ctx context.Context) error { if dc.deployment == nil { return errors.New("the DropCollection operation must have a Deployment set before Execute can be called") diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/drop_database.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/drop_database.go index f2dc4ed7..be2220c6 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/drop_database.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/drop_database.go @@ -36,7 +36,7 @@ func NewDropDatabase() *DropDatabase { return &DropDatabase{} } -// Execute runs this operations and returns an error if the operaiton did not execute successfully. +// Execute runs this operations and returns an error if the operation did not execute successfully. func (dd *DropDatabase) Execute(ctx context.Context) error { if dd.deployment == nil { return errors.New("the DropDatabase operation must have a Deployment set before Execute can be called") diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/drop_indexes.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/drop_indexes.go index 51aedc1c..127f3951 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/drop_indexes.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/drop_indexes.go @@ -36,12 +36,13 @@ type DropIndexes struct { serverAPI *driver.ServerAPIOptions } +// DropIndexesResult represents a dropIndexes result returned by the server. type DropIndexesResult struct { // Number of indexes that existed before the drop was executed. NIndexesWas int32 } -func buildDropIndexesResult(response bsoncore.Document, srvr driver.Server) (DropIndexesResult, error) { +func buildDropIndexesResult(response bsoncore.Document) (DropIndexesResult, error) { elements, err := response.Elements() if err != nil { return DropIndexesResult{}, err @@ -72,11 +73,11 @@ func (di *DropIndexes) Result() DropIndexesResult { return di.result } func (di *DropIndexes) processResponse(info driver.ResponseInfo) error { var err error - di.result, err = buildDropIndexesResult(info.ServerResponse, info.Server) + di.result, err = buildDropIndexesResult(info.ServerResponse) return err } -// Execute runs this operations and returns an error if the operaiton did not execute successfully. +// Execute runs this operations and returns an error if the operation did not execute successfully. func (di *DropIndexes) Execute(ctx context.Context) error { if di.deployment == nil { return errors.New("the DropIndexes operation must have a Deployment set before Execute can be called") diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/end_sessions.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/end_sessions.go index 0580c0ad..8384fb2d 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/end_sessions.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/end_sessions.go @@ -42,7 +42,7 @@ func (es *EndSessions) processResponse(driver.ResponseInfo) error { return err } -// Execute runs this operations and returns an error if the operaiton did not execute successfully. +// Execute runs this operations and returns an error if the operation did not execute successfully. func (es *EndSessions) Execute(ctx context.Context) error { if es.deployment == nil { return errors.New("the EndSessions operation must have a Deployment set before Execute can be called") @@ -70,7 +70,7 @@ func (es *EndSessions) command(dst []byte, desc description.SelectedServer) ([]b return dst, nil } -// sessionIDs specify the sessions to be expired. +// SessionIDs specifies the sessions to be expired. func (es *EndSessions) SessionIDs(sessionIDs bsoncore.Document) *EndSessions { if es == nil { es = new(EndSessions) diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/find.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/find.go index 4d23d494..3689a34b 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/find.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/find.go @@ -30,6 +30,7 @@ type Find struct { comment *string filter bsoncore.Document hint bsoncore.Value + let bsoncore.Document limit *int64 max bsoncore.Document maxTimeMS *int64 @@ -78,7 +79,7 @@ func (f *Find) processResponse(info driver.ResponseInfo) error { return err } -// Execute runs this operations and returns an error if the operaiton did not execute successfully. +// Execute runs this operations and returns an error if the operation did not execute successfully. func (f *Find) Execute(ctx context.Context) error { if f.deployment == nil { return errors.New("the Find operation must have a Deployment set before Execute can be called") @@ -136,6 +137,9 @@ func (f *Find) command(dst []byte, desc description.SelectedServer) ([]byte, err if f.hint.Type != bsontype.Type(0) { dst = bsoncore.AppendValueElement(dst, "hint", f.hint) } + if f.let != nil { + dst = bsoncore.AppendDocumentElement(dst, "let", f.let) + } if f.limit != nil { dst = bsoncore.AppendInt64Element(dst, "limit", *f.limit) } @@ -261,6 +265,16 @@ func (f *Find) Hint(hint bsoncore.Value) *Find { return f } +// Let specifies the let document to use. This option is only valid for server versions 5.0 and above. +func (f *Find) Let(let bsoncore.Document) *Find { + if f == nil { + f = new(Find) + } + + f.let = let + return f +} + // Limit sets a limit on the number of documents to return. func (f *Find) Limit(limit int64) *Find { if f == nil { @@ -321,7 +335,7 @@ func (f *Find) OplogReplay(oplogReplay bool) *Find { return f } -// Project limits the fields returned for all documents. +// Projection limits the fields returned for all documents. func (f *Find) Projection(projection bsoncore.Document) *Find { if f == nil { f = new(Find) diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/find_and_modify.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/find_and_modify.go index 656d56a8..3e09ca44 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/find_and_modify.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/find_and_modify.go @@ -46,10 +46,12 @@ type FindAndModify struct { crypt driver.Crypt hint bsoncore.Value serverAPI *driver.ServerAPIOptions + let bsoncore.Document result FindAndModifyResult } +// LastErrorObject represents information about updates and upserts returned by the server. type LastErrorObject struct { // True if an update modified an existing document UpdatedExisting bool @@ -57,6 +59,7 @@ type LastErrorObject struct { Upserted interface{} } +// FindAndModifyResult represents a findAndModify result returned by the server. type FindAndModifyResult struct { // Either the old or modified document, depending on the value of the new parameter. Value bsoncore.Document @@ -64,7 +67,7 @@ type FindAndModifyResult struct { LastErrorObject LastErrorObject } -func buildFindAndModifyResult(response bsoncore.Document, srvr driver.Server) (FindAndModifyResult, error) { +func buildFindAndModifyResult(response bsoncore.Document) (FindAndModifyResult, error) { elements, err := response.Elements() if err != nil { return FindAndModifyResult{}, err @@ -109,12 +112,12 @@ func (fam *FindAndModify) Result() FindAndModifyResult { return fam.result } func (fam *FindAndModify) processResponse(info driver.ResponseInfo) error { var err error - fam.result, err = buildFindAndModifyResult(info.ServerResponse, info.Server) + fam.result, err = buildFindAndModifyResult(info.ServerResponse) return err } -// Execute runs this operations and returns an error if the operaiton did not execute successfully. +// Execute runs this operations and returns an error if the operation did not execute successfully. func (fam *FindAndModify) Execute(ctx context.Context) error { if fam.deployment == nil { return errors.New("the FindAndModify operation must have a Deployment set before Execute can be called") @@ -200,6 +203,9 @@ func (fam *FindAndModify) command(dst []byte, desc description.SelectedServer) ( } dst = bsoncore.AppendValueElement(dst, "hint", fam.hint) } + if fam.let != nil { + dst = bsoncore.AppendDocumentElement(dst, "let", fam.let) + } return dst, nil } @@ -436,3 +442,13 @@ func (fam *FindAndModify) ServerAPI(serverAPI *driver.ServerAPIOptions) *FindAnd fam.serverAPI = serverAPI return fam } + +// Let specifies the let document to use. This option is only valid for server versions 5.0 and above. +func (fam *FindAndModify) Let(let bsoncore.Document) *FindAndModify { + if fam == nil { + fam = new(FindAndModify) + } + + fam.let = let + return fam +} diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/hello.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/hello.go index d222ada9..5e75c08e 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/hello.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/hello.go @@ -159,7 +159,9 @@ func (h *Hello) handshakeCommand(dst []byte, desc description.SelectedServer) ([ // command appends all necessary command fields. func (h *Hello) command(dst []byte, desc description.SelectedServer) ([]byte, error) { - if h.serverAPI != nil || desc.Server.HelloOK { + // Use "hello" if topology is LoadBalanced, API version is declared or server + // has responded with "helloOk". Otherwise, use legacy hello. + if desc.Kind == description.LoadBalanced || h.serverAPI != nil || desc.Server.HelloOK { dst = bsoncore.AppendInt32Element(dst, "hello", 1) } else { dst = bsoncore.AppendInt32Element(dst, internal.LegacyHello, 1) diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/insert.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/insert.go index d422ba59..993eac10 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/insert.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/insert.go @@ -38,12 +38,13 @@ type Insert struct { serverAPI *driver.ServerAPIOptions } +// InsertResult represents an insert result returned by the server. type InsertResult struct { // Number of documents successfully inserted. - N int32 + N int64 } -func buildInsertResult(response bsoncore.Document, srvr driver.Server) (InsertResult, error) { +func buildInsertResult(response bsoncore.Document) (InsertResult, error) { elements, err := response.Elements() if err != nil { return InsertResult{}, err @@ -53,9 +54,9 @@ func buildInsertResult(response bsoncore.Document, srvr driver.Server) (InsertRe switch element.Key() { case "n": var ok bool - ir.N, ok = element.Value().AsInt32OK() + ir.N, ok = element.Value().AsInt64OK() if !ok { - return ir, fmt.Errorf("response field 'n' is type int32, but received BSON type %s", element.Value().Type) + return ir, fmt.Errorf("response field 'n' is type int32 or int64, but received BSON type %s", element.Value().Type) } } } @@ -73,12 +74,12 @@ func NewInsert(documents ...bsoncore.Document) *Insert { func (i *Insert) Result() InsertResult { return i.result } func (i *Insert) processResponse(info driver.ResponseInfo) error { - ir, err := buildInsertResult(info.ServerResponse, info.Server) + ir, err := buildInsertResult(info.ServerResponse) i.result.N += ir.N return err } -// Execute runs this operations and returns an error if the operaiton did not execute successfully. +// Execute runs this operations and returns an error if the operation did not execute successfully. func (i *Insert) Execute(ctx context.Context) error { if i.deployment == nil { return errors.New("the Insert operation must have a Deployment set before Execute can be called") diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/listDatabases.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/listDatabases.go index d6b31e32..6b469b6f 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/listDatabases.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/listDatabases.go @@ -39,6 +39,7 @@ type ListDatabases struct { result ListDatabasesResult } +// ListDatabasesResult represents a listDatabases result returned by the server. type ListDatabasesResult struct { // An array of documents, one document for each database Databases []databaseRecord @@ -52,7 +53,7 @@ type databaseRecord struct { Empty bool } -func buildListDatabasesResult(response bsoncore.Document, srvr driver.Server) (ListDatabasesResult, error) { +func buildListDatabasesResult(response bsoncore.Document) (ListDatabasesResult, error) { elements, err := response.Elements() if err != nil { return ListDatabasesResult{}, err @@ -133,12 +134,12 @@ func (ld *ListDatabases) Result() ListDatabasesResult { return ld.result } func (ld *ListDatabases) processResponse(info driver.ResponseInfo) error { var err error - ld.result, err = buildListDatabasesResult(info.ServerResponse, info.Server) + ld.result, err = buildListDatabasesResult(info.ServerResponse) return err } -// Execute runs this operations and returns an error if the operaiton did not execute successfully. +// Execute runs this operations and returns an error if the operation did not execute successfully. func (ld *ListDatabases) Execute(ctx context.Context) error { if ld.deployment == nil { return errors.New("the ListDatabases operation must have a Deployment set before Execute can be called") diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/list_collections.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/list_collections.go index 6c98a670..de30afd3 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/list_collections.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/list_collections.go @@ -20,20 +20,21 @@ import ( // ListCollections performs a listCollections operation. type ListCollections struct { - filter bsoncore.Document - nameOnly *bool - session *session.Client - clock *session.ClusterClock - monitor *event.CommandMonitor - crypt driver.Crypt - database string - deployment driver.Deployment - readPreference *readpref.ReadPref - selector description.ServerSelector - retry *driver.RetryMode - result driver.CursorResponse - batchSize *int32 - serverAPI *driver.ServerAPIOptions + filter bsoncore.Document + nameOnly *bool + authorizedCollections *bool + session *session.Client + clock *session.ClusterClock + monitor *event.CommandMonitor + crypt driver.Crypt + database string + deployment driver.Deployment + readPreference *readpref.ReadPref + selector description.ServerSelector + retry *driver.RetryMode + result driver.CursorResponse + batchSize *int32 + serverAPI *driver.ServerAPIOptions } // NewListCollections constructs and returns a new ListCollections. @@ -63,7 +64,7 @@ func (lc *ListCollections) processResponse(info driver.ResponseInfo) error { return err } -// Execute runs this operations and returns an error if the operaiton did not execute successfully. +// Execute runs this operations and returns an error if the operation did not execute successfully. func (lc *ListCollections) Execute(ctx context.Context) error { if lc.deployment == nil { return errors.New("the ListCollections operation must have a Deployment set before Execute can be called") @@ -89,7 +90,6 @@ func (lc *ListCollections) Execute(ctx context.Context) error { } func (lc *ListCollections) command(dst []byte, desc description.SelectedServer) ([]byte, error) { - dst = bsoncore.AppendInt32Element(dst, "listCollections", 1) if lc.filter != nil { dst = bsoncore.AppendDocumentElement(dst, "filter", lc.filter) @@ -97,6 +97,10 @@ func (lc *ListCollections) command(dst []byte, desc description.SelectedServer) if lc.nameOnly != nil { dst = bsoncore.AppendBooleanElement(dst, "nameOnly", *lc.nameOnly) } + if lc.authorizedCollections != nil { + dst = bsoncore.AppendBooleanElement(dst, "authorizedCollections", *lc.authorizedCollections) + } + cursorDoc := bsoncore.NewDocumentBuilder() if lc.batchSize != nil { cursorDoc.AppendInt32("batchSize", *lc.batchSize) @@ -126,6 +130,17 @@ func (lc *ListCollections) NameOnly(nameOnly bool) *ListCollections { return lc } +// AuthorizedCollections specifies whether to only return collections the user +// is authorized to use. +func (lc *ListCollections) AuthorizedCollections(authorizedCollections bool) *ListCollections { + if lc == nil { + lc = new(ListCollections) + } + + lc.authorizedCollections = &authorizedCollections + return lc +} + // Session sets the session for this operation. func (lc *ListCollections) Session(session *session.Client) *ListCollections { if lc == nil { diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/list_indexes.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/list_indexes.go index 99bc45b2..171e2b5a 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/list_indexes.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/list_indexes.go @@ -58,7 +58,7 @@ func (li *ListIndexes) processResponse(info driver.ResponseInfo) error { } -// Execute runs this operations and returns an error if the operaiton did not execute successfully. +// Execute runs this operations and returns an error if the operation did not execute successfully. func (li *ListIndexes) Execute(ctx context.Context) error { if li.deployment == nil { return errors.New("the ListIndexes operation must have a Deployment set before Execute can be called") diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/update.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/update.go index 3f22fc06..3cd11848 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/update.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/operation/update.go @@ -39,6 +39,7 @@ type Update struct { result UpdateResult crypt driver.Crypt serverAPI *driver.ServerAPIOptions + let bsoncore.Document } // Upsert contains the information for an upsert in an Update operation. @@ -50,14 +51,14 @@ type Upsert struct { // UpdateResult contains information for the result of an Update operation. type UpdateResult struct { // Number of documents matched. - N int32 + N int64 // Number of documents modified. - NModified int32 + NModified int64 // Information about upserted documents. Upserted []Upsert } -func buildUpdateResult(response bsoncore.Document, srvr driver.Server) (UpdateResult, error) { +func buildUpdateResult(response bsoncore.Document) (UpdateResult, error) { elements, err := response.Elements() if err != nil { return UpdateResult{}, err @@ -67,15 +68,15 @@ func buildUpdateResult(response bsoncore.Document, srvr driver.Server) (UpdateRe switch element.Key() { case "nModified": var ok bool - ur.NModified, ok = element.Value().Int32OK() + ur.NModified, ok = element.Value().AsInt64OK() if !ok { - return ur, fmt.Errorf("response field 'nModified' is type int32, but received BSON type %s", element.Value().Type) + return ur, fmt.Errorf("response field 'nModified' is type int32 or int64, but received BSON type %s", element.Value().Type) } case "n": var ok bool - ur.N, ok = element.Value().Int32OK() + ur.N, ok = element.Value().AsInt64OK() if !ok { - return ur, fmt.Errorf("response field 'n' is type int32, but received BSON type %s", element.Value().Type) + return ur, fmt.Errorf("response field 'n' is type int32 or int64, but received BSON type %s", element.Value().Type) } case "upserted": arr, ok := element.Value().ArrayOK() @@ -116,7 +117,7 @@ func NewUpdate(updates ...bsoncore.Document) *Update { func (u *Update) Result() UpdateResult { return u.result } func (u *Update) processResponse(info driver.ResponseInfo) error { - ur, err := buildUpdateResult(info.ServerResponse, info.Server) + ur, err := buildUpdateResult(info.ServerResponse) u.result.N += ur.N u.result.NModified += ur.NModified @@ -130,7 +131,7 @@ func (u *Update) processResponse(info driver.ResponseInfo) error { } -// Execute runs this operations and returns an error if the operaiton did not execute successfully. +// Execute runs this operations and returns an error if the operation did not execute successfully. func (u *Update) Execute(ctx context.Context) error { if u.deployment == nil { return errors.New("the Update operation must have a Deployment set before Execute can be called") @@ -185,6 +186,9 @@ func (u *Update) command(dst []byte, desc description.SelectedServer) ([]byte, e return nil, errors.New("the 'arrayFilters' command parameter requires a minimum server wire version of 6") } } + if u.let != nil { + dst = bsoncore.AppendDocumentElement(dst, "let", u.let) + } return dst, nil } @@ -357,3 +361,13 @@ func (u *Update) ServerAPI(serverAPI *driver.ServerAPIOptions) *Update { u.serverAPI = serverAPI return u } + +// Let specifies the let document to use. This option is only valid for server versions 5.0 and above. +func (u *Update) Let(let bsoncore.Document) *Update { + if u == nil { + u = new(Update) + } + + u.let = let + return u +} diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/session/client_session.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/session/client_session.go index 3449c85e..9e01f9fe 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/session/client_session.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/session/client_session.go @@ -40,7 +40,7 @@ var ErrAbortTwice = errors.New("cannot call abortTransaction twice") // ErrCommitAfterAbort is returned if commit is called after an abort. var ErrCommitAfterAbort = errors.New("cannot call commitTransaction after calling abortTransaction") -// ErrUnackWCUnsupported is returned if an unacknowledged write concern is supported for a transaciton. +// ErrUnackWCUnsupported is returned if an unacknowledged write concern is supported for a transaction. var ErrUnackWCUnsupported = errors.New("transactions do not support unacknowledged write concerns") // ErrSnapshotTransaction is returned if an transaction is started on a snapshot session. @@ -364,7 +364,7 @@ func (c *Client) TransactionRunning() bool { return c != nil && (c.TransactionState == Starting || c.TransactionState == InProgress) } -// TransactionCommitted returns true of the client session just committed a transaciton. +// TransactionCommitted returns true of the client session just committed a transaction. func (c *Client) TransactionCommitted() bool { return c.TransactionState == Committed } diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/connection.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/connection.go index 732be09b..c91a1b5e 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/connection.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/connection.go @@ -27,6 +27,13 @@ import ( "go.mongodb.org/mongo-driver/x/mongo/driver/wiremessage" ) +// Connection state constants. +const ( + connDisconnected int64 = iota + connConnected + connInitialized +) + var globalConnectionID uint64 = 1 var ( @@ -38,10 +45,10 @@ var ( func nextConnectionID() uint64 { return atomic.AddUint64(&globalConnectionID, 1) } type connection struct { - // connected must be accessed using the atomic package and should be at the beginning of the struct. + // state must be accessed using the atomic package and should be at the beginning of the struct. // - atomic bug: https://pkg.go.dev/sync/atomic#pkg-note-BUG // - suggested layout: https://go101.org/article/memory-layout.html - connected int64 + state int64 id string nc net.Conn // When nil, the connection is closed. @@ -56,7 +63,6 @@ type connection struct { zliblevel int zstdLevel int connectDone chan struct{} - connectErr error config *connectionConfig cancelConnectContext context.CancelFunc connectContextMade chan struct{} @@ -73,11 +79,8 @@ type connection struct { } // newConnection handles the creation of a connection. It does not connect the connection. -func newConnection(addr address.Address, opts ...ConnectionOption) (*connection, error) { - cfg, err := newConnectionConfig(opts...) - if err != nil { - return nil, err - } +func newConnection(addr address.Address, opts ...ConnectionOption) *connection { + cfg := newConnectionConfig(opts...) id := fmt.Sprintf("%s[-%d]", addr, nextConnectionID()) @@ -97,21 +100,9 @@ func newConnection(addr address.Address, opts ...ConnectionOption) (*connection, if !c.config.loadBalanced { c.setGenerationNumber() } - atomic.StoreInt64(&c.connected, initialized) + atomic.StoreInt64(&c.state, connInitialized) - return c, nil -} - -func (c *connection) processInitializationError(err error) { - atomic.StoreInt64(&c.connected, disconnected) - if c.nc != nil { - _ = c.nc.Close() - } - - c.connectErr = ConnectionError{Wrapped: err, init: true} - if c.config.errorHandlingCallback != nil { - c.config.errorHandlingCallback(c.connectErr, c.generation, c.desc.ServiceID) - } + return c } // setGenerationNumber sets the connection's generation number if a callback has been provided to do so in connection @@ -135,14 +126,28 @@ func (c *connection) hasGenerationNumber() bool { return c.desc.LoadBalanced() } -// connect handles the I/O for a connection. It will dial, configure TLS, and perform -// initialization handshakes. -func (c *connection) connect(ctx context.Context) { - if !atomic.CompareAndSwapInt64(&c.connected, initialized, connected) { - return +// connect handles the I/O for a connection. It will dial, configure TLS, and perform initialization +// handshakes. All errors returned by connect are considered "before the handshake completes" and +// must be handled by calling the appropriate SDAM handshake error handler. +func (c *connection) connect(ctx context.Context) (err error) { + if !atomic.CompareAndSwapInt64(&c.state, connInitialized, connConnected) { + return nil } + defer close(c.connectDone) + // If connect returns an error, set the connection status as disconnected and close the + // underlying net.Conn if it was created. + defer func() { + if err != nil { + atomic.StoreInt64(&c.state, connDisconnected) + + if c.nc != nil { + _ = c.nc.Close() + } + } + }() + // Create separate contexts for dialing a connection and doing the MongoDB/auth handshakes. // // handshakeCtx is simply a cancellable version of ctx because there's no default timeout that needs to be applied @@ -181,12 +186,9 @@ func (c *connection) connect(ctx context.Context) { close(c.connectContextMade) // Assign the result of DialContext to a temporary net.Conn to ensure that c.nc is not set in an error case. - var err error - var tempNc net.Conn - tempNc, err = c.config.dialer.DialContext(dialCtx, c.addr.Network(), c.addr.String()) + tempNc, err := c.config.dialer.DialContext(dialCtx, c.addr.Network(), c.addr.String()) if err != nil { - c.processInitializationError(err) - return + return ConnectionError{Wrapped: err, init: true} } c.nc = tempNc @@ -201,18 +203,15 @@ func (c *connection) connect(ctx context.Context) { } tlsNc, err := configureTLS(dialCtx, c.config.tlsConnectionSource, c.nc, c.addr, tlsConfig, ocspOpts) if err != nil { - c.processInitializationError(err) - return + return ConnectionError{Wrapped: err, init: true} } c.nc = tlsNc } - c.bumpIdleDeadline() - // running hello and authentication is handled by a handshaker on the configuration instance. handshaker := c.config.handshaker if handshaker == nil { - return + return nil } var handshakeInfo driver.HandshakeInformation @@ -247,8 +246,7 @@ func (c *connection) connect(ctx context.Context) { // We have a failed handshake here if err != nil { - c.processInitializationError(err) - return + return ConnectionError{Wrapped: err, init: true} } if len(c.desc.Compression) > 0 { @@ -279,13 +277,13 @@ func (c *connection) connect(ctx context.Context) { } } } + return nil } -func (c *connection) wait() error { +func (c *connection) wait() { if c.connectDone != nil { <-c.connectDone } - return c.connectErr } func (c *connection) closeConnectContext() { @@ -330,7 +328,7 @@ func (c *connection) cancellationListenerCallback() { func (c *connection) writeWireMessage(ctx context.Context, wm []byte) error { var err error - if atomic.LoadInt64(&c.connected) != connected { + if atomic.LoadInt64(&c.state) != connConnected { return ConnectionError{ConnectionID: c.id, message: "connection is closed"} } select { @@ -364,7 +362,6 @@ func (c *connection) writeWireMessage(ctx context.Context, wm []byte) error { } } - c.bumpIdleDeadline() return nil } @@ -387,7 +384,7 @@ func (c *connection) write(ctx context.Context, wm []byte) (err error) { // readWireMessage reads a wiremessage from the connection. The dst parameter will be overwritten. func (c *connection) readWireMessage(ctx context.Context, dst []byte) ([]byte, error) { - if atomic.LoadInt64(&c.connected) != connected { + if atomic.LoadInt64(&c.state) != connConnected { return dst, ConnectionError{ConnectionID: c.id, message: "connection is closed"} } @@ -429,7 +426,6 @@ func (c *connection) readWireMessage(ctx context.Context, dst []byte) ([]byte, e } } - c.bumpIdleDeadline() return dst, nil } @@ -490,7 +486,7 @@ func (c *connection) read(ctx context.Context, dst []byte) (bytesRead []byte, er func (c *connection) close() error { // Overwrite the connection state as the first step so only the first close call will execute. - if !atomic.CompareAndSwapInt64(&c.connected, connected, disconnected) { + if !atomic.CompareAndSwapInt64(&c.state, connConnected, connDisconnected) { return nil } @@ -503,7 +499,7 @@ func (c *connection) close() error { } func (c *connection) closed() bool { - return atomic.LoadInt64(&c.connected) == disconnected + return atomic.LoadInt64(&c.state) == connDisconnected } func (c *connection) idleTimeoutExpired() bool { @@ -600,6 +596,10 @@ type Connection struct { refCount int cleanupPoolFn func() + // cleanupServerFn resets the server state when a connection is returned to the connection pool + // via Close() or expired via Expire(). + cleanupServerFn func() + mu sync.RWMutex } @@ -701,6 +701,10 @@ func (c *Connection) cleanupReferences() error { c.cleanupPoolFn() c.cleanupPoolFn = nil } + if c.cleanupServerFn != nil { + c.cleanupServerFn() + c.cleanupServerFn = nil + } c.connection = nil return err } @@ -806,7 +810,6 @@ func configureTLS(ctx context.Context, config *tls.Config, ocspOpts *ocsp.VerifyOptions, ) (net.Conn, error) { - // Ensure config.ServerName is always set for SNI. if config.ServerName == "" { hostname := addr.String() @@ -820,27 +823,15 @@ func configureTLS(ctx context.Context, } client := tlsConnSource.Client(nc, config) - errChan := make(chan error, 1) - go func() { - errChan <- client.Handshake() - }() - - select { - case err := <-errChan: - if err != nil { - return nil, err - } - - // Only do OCSP verification if TLS verification is requested. - if config.InsecureSkipVerify { - break - } + if err := clientHandshake(ctx, client); err != nil { + return nil, err + } + // Only do OCSP verification if TLS verification is requested. + if !config.InsecureSkipVerify { if ocspErr := ocsp.Verify(ctx, client.ConnectionState(), ocspOpts); ocspErr != nil { return nil, ocspErr } - case <-ctx.Done(): - return nil, ctx.Err() } return client, nil } diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/connection_options.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/connection_options.go index 9c6ce05c..24507aa1 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/connection_options.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/connection_options.go @@ -53,13 +53,12 @@ type connectionConfig struct { zstdLevel *int ocspCache ocsp.Cache disableOCSPEndpointCheck bool - errorHandlingCallback func(err error, startGenNum uint64, svcID *primitive.ObjectID) tlsConnectionSource tlsConnectionSource loadBalanced bool getGenerationFn generationNumberFn } -func newConnectionConfig(opts ...ConnectionOption) (*connectionConfig, error) { +func newConnectionConfig(opts ...ConnectionOption) *connectionConfig { cfg := &connectionConfig{ connectTimeout: 30 * time.Second, dialer: nil, @@ -67,131 +66,111 @@ func newConnectionConfig(opts ...ConnectionOption) (*connectionConfig, error) { } for _, opt := range opts { - err := opt(cfg) - if err != nil { - return nil, err + if opt == nil { + continue } + opt(cfg) } if cfg.dialer == nil { cfg.dialer = &net.Dialer{} } - return cfg, nil + return cfg } // ConnectionOption is used to configure a connection. -type ConnectionOption func(*connectionConfig) error +type ConnectionOption func(*connectionConfig) func withTLSConnectionSource(fn func(tlsConnectionSource) tlsConnectionSource) ConnectionOption { - return func(c *connectionConfig) error { + return func(c *connectionConfig) { c.tlsConnectionSource = fn(c.tlsConnectionSource) - return nil - } -} - -func withErrorHandlingCallback(fn func(err error, startGenNum uint64, svcID *primitive.ObjectID)) ConnectionOption { - return func(c *connectionConfig) error { - c.errorHandlingCallback = fn - return nil } } // WithCompressors sets the compressors that can be used for communication. func WithCompressors(fn func([]string) []string) ConnectionOption { - return func(c *connectionConfig) error { + return func(c *connectionConfig) { c.compressors = fn(c.compressors) - return nil } } // WithConnectTimeout configures the maximum amount of time a dial will wait for a // Connect to complete. The default is 30 seconds. func WithConnectTimeout(fn func(time.Duration) time.Duration) ConnectionOption { - return func(c *connectionConfig) error { + return func(c *connectionConfig) { c.connectTimeout = fn(c.connectTimeout) - return nil } } // WithDialer configures the Dialer to use when making a new connection to MongoDB. func WithDialer(fn func(Dialer) Dialer) ConnectionOption { - return func(c *connectionConfig) error { + return func(c *connectionConfig) { c.dialer = fn(c.dialer) - return nil } } // WithHandshaker configures the Handshaker that wll be used to initialize newly // dialed connections. func WithHandshaker(fn func(Handshaker) Handshaker) ConnectionOption { - return func(c *connectionConfig) error { + return func(c *connectionConfig) { c.handshaker = fn(c.handshaker) - return nil } } // WithIdleTimeout configures the maximum idle time to allow for a connection. func WithIdleTimeout(fn func(time.Duration) time.Duration) ConnectionOption { - return func(c *connectionConfig) error { + return func(c *connectionConfig) { c.idleTimeout = fn(c.idleTimeout) - return nil } } // WithReadTimeout configures the maximum read time for a connection. func WithReadTimeout(fn func(time.Duration) time.Duration) ConnectionOption { - return func(c *connectionConfig) error { + return func(c *connectionConfig) { c.readTimeout = fn(c.readTimeout) - return nil } } // WithWriteTimeout configures the maximum write time for a connection. func WithWriteTimeout(fn func(time.Duration) time.Duration) ConnectionOption { - return func(c *connectionConfig) error { + return func(c *connectionConfig) { c.writeTimeout = fn(c.writeTimeout) - return nil } } // WithTLSConfig configures the TLS options for a connection. func WithTLSConfig(fn func(*tls.Config) *tls.Config) ConnectionOption { - return func(c *connectionConfig) error { + return func(c *connectionConfig) { c.tlsConfig = fn(c.tlsConfig) - return nil } } // WithMonitor configures a event for command monitoring. func WithMonitor(fn func(*event.CommandMonitor) *event.CommandMonitor) ConnectionOption { - return func(c *connectionConfig) error { + return func(c *connectionConfig) { c.cmdMonitor = fn(c.cmdMonitor) - return nil } } // WithZlibLevel sets the zLib compression level. func WithZlibLevel(fn func(*int) *int) ConnectionOption { - return func(c *connectionConfig) error { + return func(c *connectionConfig) { c.zlibLevel = fn(c.zlibLevel) - return nil } } // WithZstdLevel sets the zstd compression level. func WithZstdLevel(fn func(*int) *int) ConnectionOption { - return func(c *connectionConfig) error { + return func(c *connectionConfig) { c.zstdLevel = fn(c.zstdLevel) - return nil } } // WithOCSPCache specifies a cache to use for OCSP verification. func WithOCSPCache(fn func(ocsp.Cache) ocsp.Cache) ConnectionOption { - return func(c *connectionConfig) error { + return func(c *connectionConfig) { c.ocspCache = fn(c.ocspCache) - return nil } } @@ -199,23 +178,20 @@ func WithOCSPCache(fn func(ocsp.Cache) ocsp.Cache) ConnectionOption { // to true, the driver will only check stapled responses and will continue the connection without reaching out to // OCSP responders. func WithDisableOCSPEndpointCheck(fn func(bool) bool) ConnectionOption { - return func(c *connectionConfig) error { + return func(c *connectionConfig) { c.disableOCSPEndpointCheck = fn(c.disableOCSPEndpointCheck) - return nil } } // WithConnectionLoadBalanced specifies whether or not the connection is to a server behind a load balancer. func WithConnectionLoadBalanced(fn func(bool) bool) ConnectionOption { - return func(c *connectionConfig) error { + return func(c *connectionConfig) { c.loadBalanced = fn(c.loadBalanced) - return nil } } func withGenerationNumberFn(fn func(generationNumberFn) generationNumberFn) ConnectionOption { - return func(c *connectionConfig) error { + return func(c *connectionConfig) { c.getGenerationFn = fn(c.getGenerationFn) - return nil } } diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/errors.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/errors.go index cf0778bd..d3192cbb 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/errors.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/errors.go @@ -11,7 +11,7 @@ type ConnectionError struct { ConnectionID string Wrapped error - // init will be set to true if this error occured during connection initialization or + // init will be set to true if this error occurred during connection initialization or // during a connection handshake. init bool message string @@ -21,7 +21,7 @@ type ConnectionError struct { func (e ConnectionError) Error() string { message := e.message if e.init { - fullMsg := "error occured during connection handshake" + fullMsg := "error occurred during connection handshake" if message != "" { fullMsg = fmt.Sprintf("%s: %s", fullMsg, message) } diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/fsm.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/fsm.go index 004eb21e..46bcd19a 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/fsm.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/fsm.go @@ -18,7 +18,7 @@ import ( var ( // SupportedWireVersions is the range of wire versions supported by the driver. - SupportedWireVersions = description.NewVersionRange(2, 14) + SupportedWireVersions = description.NewVersionRange(2, 15) ) const ( @@ -46,7 +46,7 @@ func newFSM() *fsm { // // apply should operation on immutable descriptions so we don't have to lock for the entire time we're applying the // server description. -func (f *fsm) apply(s description.Server) (description.Topology, description.Server, error) { +func (f *fsm) apply(s description.Server) (description.Topology, description.Server) { newServers := make([]description.Server, len(f.Servers)) copy(newServers, f.Servers) @@ -77,7 +77,7 @@ func (f *fsm) apply(s description.Server) (description.Topology, description.Ser } if _, ok := f.findServer(s.Addr); !ok { - return f.Topology, s, nil + return f.Topology, s } updatedDesc := s @@ -107,7 +107,7 @@ func (f *fsm) apply(s description.Server) (description.Topology, description.Ser MinSupportedMongoDBVersion, ) f.Topology.CompatibilityErr = f.compatibilityErr - return f.Topology, s, nil + return f.Topology, s } if server.WireVersion.Min > SupportedWireVersions.Max { @@ -119,14 +119,14 @@ func (f *fsm) apply(s description.Server) (description.Topology, description.Ser SupportedWireVersions.Max, ) f.Topology.CompatibilityErr = f.compatibilityErr - return f.Topology, s, nil + return f.Topology, s } } } f.compatible.Store(true) f.compatibilityErr = nil - return f.Topology, updatedDesc, nil + return f.Topology, updatedDesc } func (f *fsm) applyToReplicaSetNoPrimary(s description.Server) description.Server { @@ -376,12 +376,10 @@ func (f *fsm) removeServerByAddr(addr address.Address) { } } -func (f *fsm) replaceServer(s description.Server) bool { +func (f *fsm) replaceServer(s description.Server) { if i, ok := f.findServer(s.Addr); ok { f.setServer(i, s) - return true } - return false } func (f *fsm) setServer(i int, s description.Server) { diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/hanging_tls_conn_1_16.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/hanging_tls_conn_1_16.go new file mode 100644 index 00000000..b4a690c4 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/hanging_tls_conn_1_16.go @@ -0,0 +1,37 @@ +// Copyright (C) MongoDB, Inc. 2022-present. +// +// 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 + +//go:build !go1.17 +// +build !go1.17 + +package topology + +import ( + "crypto/tls" + "time" +) + +// hangingTLSConn is an implementation of tlsConn that wraps the tls.Conn type and overrides the Handshake function to +// sleep for a fixed amount of time. +type hangingTLSConn struct { + *tls.Conn + sleepTime time.Duration +} + +var _ tlsConn = (*hangingTLSConn)(nil) + +func newHangingTLSConn(conn *tls.Conn, sleepTime time.Duration) *hangingTLSConn { + return &hangingTLSConn{ + Conn: conn, + sleepTime: sleepTime, + } +} + +// Handshake implements the tlsConn interface on Go 1.16 and less. +func (h *hangingTLSConn) Handshake() error { + time.Sleep(h.sleepTime) + return h.Conn.Handshake() +} diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/hanging_tls_conn_1_17.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/hanging_tls_conn_1_17.go new file mode 100644 index 00000000..1058b86c --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/hanging_tls_conn_1_17.go @@ -0,0 +1,44 @@ +// Copyright (C) MongoDB, Inc. 2022-present. +// +// 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 + +//go:build go1.17 +// +build go1.17 + +package topology + +import ( + "context" + "crypto/tls" + "time" +) + +// hangingTLSConn is an implementation of tlsConn that wraps the tls.Conn type and overrides the HandshakeContext function to +// sleep for a fixed amount of time. +type hangingTLSConn struct { + *tls.Conn + sleepTime time.Duration +} + +var _ tlsConn = (*hangingTLSConn)(nil) + +func newHangingTLSConn(conn *tls.Conn, sleepTime time.Duration) *hangingTLSConn { + return &hangingTLSConn{ + Conn: conn, + sleepTime: sleepTime, + } +} + +// HandshakeContext implements the tlsConn interface on Go 1.17 and higher. +func (h *hangingTLSConn) HandshakeContext(ctx context.Context) error { + timer := time.NewTimer(h.sleepTime) + defer timer.Stop() + select { + case <-timer.C: + case <-ctx.Done(): + } + + return h.Conn.HandshakeContext(ctx) +} diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/pool.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/pool.go index a652594b..f63ed796 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/pool.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/pool.go @@ -16,14 +16,22 @@ import ( "go.mongodb.org/mongo-driver/bson/primitive" "go.mongodb.org/mongo-driver/event" "go.mongodb.org/mongo-driver/mongo/address" + "go.mongodb.org/mongo-driver/x/mongo/driver" ) -// ErrPoolConnected is returned from an attempt to connect an already connected pool -var ErrPoolConnected = PoolError("attempted to Connect to an already connected pool") +// Connection pool state constants. +const ( + poolPaused int = iota + poolReady + poolClosed +) + +// ErrPoolNotPaused is returned when attempting to mark a connection pool "ready" that is not +// currently "paused". +var ErrPoolNotPaused = PoolError("only a paused pool can be marked ready") -// ErrPoolDisconnected is returned from an attempt to Close an already disconnected -// or disconnecting pool. -var ErrPoolDisconnected = PoolError("attempted to check out a connection from closed connection pool") +// ErrPoolClosed is returned when attempting to check out a connection from a closed pool. +var ErrPoolClosed = PoolError("attempted to check out a connection from closed connection pool") // ErrConnectionClosed is returned from an attempt to use an already closed connection. var ErrConnectionClosed = ConnectionError{ConnectionID: "", message: "connection is closed"} @@ -36,14 +44,36 @@ type PoolError string func (pe PoolError) Error() string { return string(pe) } +// poolClearedError is an error returned when the connection pool is cleared or currently paused. It +// is a retryable error. +type poolClearedError struct { + err error + address address.Address +} + +func (pce poolClearedError) Error() string { + return fmt.Sprintf( + "connection pool for %v was cleared because another operation failed with: %v", + pce.address, + pce.err) +} + +// Retryable returns true. All poolClearedErrors are retryable. +func (poolClearedError) Retryable() bool { return true } + +// Assert that poolClearedError is a driver.RetryablePoolError. +var _ driver.RetryablePoolError = poolClearedError{} + // poolConfig contains all aspects of the pool that can be configured type poolConfig struct { - Address address.Address - MinPoolSize uint64 - MaxPoolSize uint64 - MaxConnecting uint64 - MaxIdleTime time.Duration - PoolMonitor *event.PoolMonitor + Address address.Address + MinPoolSize uint64 + MaxPoolSize uint64 + MaxConnecting uint64 + MaxIdleTime time.Duration + MaintainInterval time.Duration + PoolMonitor *event.PoolMonitor + handshakeErrFn func(error, uint64, *primitive.ObjectID) } type pool struct { @@ -52,7 +82,6 @@ type pool struct { // - atomic bug: https://pkg.go.dev/sync/atomic#pkg-note-BUG // - suggested layout: https://go101.org/article/memory-layout.html - connected int64 // connected is the connected state of the connection pool. nextID uint64 // nextID is the next pool ID for a new connection. pinnedCursorConnections uint64 pinnedTransactionConnections uint64 @@ -63,30 +92,49 @@ type pool struct { maxConnecting uint64 monitor *event.PoolMonitor + // handshakeErrFn is used to handle any errors that happen during connection establishment and + // handshaking. + handshakeErrFn func(error, uint64, *primitive.ObjectID) + connOpts []ConnectionOption generation *poolGenerationMap - maintainInterval time.Duration // maintainInterval is the maintain() loop interval. - cancelBackground context.CancelFunc // cancelBackground is called to signal background goroutines to stop. - backgroundDone *sync.WaitGroup // backgroundDone waits for all background goroutines to return. + maintainInterval time.Duration // maintainInterval is the maintain() loop interval. + maintainReady chan struct{} // maintainReady is a signal channel that starts the maintain() loop when ready() is called. + backgroundDone *sync.WaitGroup // backgroundDone waits for all background goroutines to return. - connsCond *sync.Cond // connsCond guards conns, newConnWait. - conns map[uint64]*connection // conns holds all currently open connections. - newConnWait wantConnQueue // newConnWait holds all wantConn requests for new connections. + stateMu sync.RWMutex // stateMu guards state, lastClearErr + state int // state is the current state of the connection pool. + lastClearErr error // lastClearErr is the last error that caused the pool to be cleared. + + // createConnectionsCond is the condition variable that controls when the createConnections() + // loop runs or waits. Its lock guards cancelBackgroundCtx, conns, and newConnWait. Any changes + // to the state of the guarded values must be made while holding the lock to prevent undefined + // behavior in the createConnections() waiting logic. + createConnectionsCond *sync.Cond + cancelBackgroundCtx context.CancelFunc // cancelBackgroundCtx is called to signal background goroutines to stop. + conns map[uint64]*connection // conns holds all currently open connections. + newConnWait wantConnQueue // newConnWait holds all wantConn requests for new connections. idleMu sync.Mutex // idleMu guards idleConns, idleConnWait idleConns []*connection // idleConns holds all idle connections. idleConnWait wantConnQueue // idleConnWait holds all wantConn requests for idle connections. } +// getState returns the current state of the pool. Callers must not hold the stateMu lock. +func (p *pool) getState() int { + p.stateMu.RLock() + defer p.stateMu.RUnlock() + + return p.state +} + // connectionPerished checks if a given connection is perished and should be removed from the pool. func connectionPerished(conn *connection) (string, bool) { switch { - case atomic.LoadInt64(&conn.pool.connected) != connected: - return event.ReasonPoolClosed, true case conn.closed(): // A connection would only be closed if it encountered a network error during an operation and closed itself. - return event.ReasonConnectionErrored, true + return event.ReasonError, true case conn.idleTimeoutExpired(): return event.ReasonIdle, true case conn.pool.stale(conn): @@ -106,22 +154,50 @@ func newPool(config poolConfig, connOpts ...ConnectionOption) *pool { maxConnecting = config.MaxConnecting } + maintainInterval := 10 * time.Second + if config.MaintainInterval != 0 { + maintainInterval = config.MaintainInterval + } + pool := &pool{ - address: config.Address, - minSize: config.MinPoolSize, - maxSize: config.MaxPoolSize, - maxConnecting: maxConnecting, - monitor: config.PoolMonitor, - connOpts: connOpts, - generation: newPoolGenerationMap(), - connected: disconnected, - maintainInterval: 10 * time.Second, - connsCond: sync.NewCond(&sync.Mutex{}), - conns: make(map[uint64]*connection, config.MaxPoolSize), - idleConns: make([]*connection, 0, config.MaxPoolSize), + address: config.Address, + minSize: config.MinPoolSize, + maxSize: config.MaxPoolSize, + maxConnecting: maxConnecting, + monitor: config.PoolMonitor, + handshakeErrFn: config.handshakeErrFn, + connOpts: connOpts, + generation: newPoolGenerationMap(), + state: poolPaused, + maintainInterval: maintainInterval, + maintainReady: make(chan struct{}, 1), + backgroundDone: &sync.WaitGroup{}, + createConnectionsCond: sync.NewCond(&sync.Mutex{}), + conns: make(map[uint64]*connection, config.MaxPoolSize), + idleConns: make([]*connection, 0, config.MaxPoolSize), } pool.connOpts = append(pool.connOpts, withGenerationNumberFn(func(_ generationNumberFn) generationNumberFn { return pool.getGenerationForNewConnection })) + pool.generation.connect() + + // Create a Context with cancellation that's used to signal the createConnections() and + // maintain() background goroutines to stop. Also create a "backgroundDone" WaitGroup that is + // used to wait for the background goroutines to return. + var ctx context.Context + ctx, pool.cancelBackgroundCtx = context.WithCancel(context.Background()) + + for i := 0; i < int(pool.maxConnecting); i++ { + pool.backgroundDone.Add(1) + go pool.createConnections(ctx, pool.backgroundDone) + } + + // If maintainInterval is not positive, don't start the maintain() goroutine. Expect that + // negative values are only used in testing; this config value is not user-configurable. + if maintainInterval > 0 { + pool.backgroundDone.Add(1) + go pool.maintain(ctx, pool.backgroundDone) + } + if pool.monitor != nil { pool.monitor.Event(&event.PoolEvent{ Type: event.PoolCreated, @@ -141,52 +217,63 @@ func (p *pool) stale(conn *connection) bool { return conn == nil || p.generation.stale(conn.desc.ServiceID, conn.generation) } -// connect puts the pool into the connected state and starts the background connection creation and -// monitoring goroutines. connect must be called before connections can be checked out. An unused, -// connected pool must be disconnected or it will leak goroutines and will not be garbage collected. -func (p *pool) connect() error { - if !atomic.CompareAndSwapInt64(&p.connected, disconnected, connecting) { - return ErrPoolConnected +// ready puts the pool into the "ready" state and starts the background connection creation and +// monitoring goroutines. ready must be called before connections can be checked out. An unused, +// connected pool must be closed or it will leak goroutines and will not be garbage collected. +func (p *pool) ready() error { + // While holding the stateMu lock, set the pool to "ready" if it is currently "paused". + p.stateMu.Lock() + if p.state == poolReady { + p.stateMu.Unlock() + return nil + } + if p.state != poolPaused { + p.stateMu.Unlock() + return ErrPoolNotPaused } - p.generation.connect() + p.lastClearErr = nil + p.state = poolReady + p.stateMu.Unlock() - // Create a Context with cancellation that's used to signal the createConnections() and - // maintain() background goroutines to stop. Also create a "backgroundDone" WaitGroup that is - // used to wait for the background goroutines to return. Always create a new Context and - // WaitGroup each time we start new set of background goroutines to prevent interaction between - // current and previous sets of background goroutines. - var ctx context.Context - ctx, p.cancelBackground = context.WithCancel(context.Background()) - p.backgroundDone = &sync.WaitGroup{} + // Signal maintain() to wake up immediately when marking the pool "ready". + select { + case p.maintainReady <- struct{}{}: + default: + } - for i := 0; i < int(p.maxConnecting); i++ { - p.backgroundDone.Add(1) - go p.createConnections(ctx, p.backgroundDone) + if p.monitor != nil { + p.monitor.Event(&event.PoolEvent{ + Type: event.PoolReady, + Address: p.address.String(), + }) } - p.backgroundDone.Add(1) - go p.maintain(ctx, p.backgroundDone) - atomic.StoreInt64(&p.connected, connected) return nil } -// disconnect disconnects the pool, closes all connections associated with the pool, and stops all -// background goroutines. All subsequent checkOut requests will return an error. An unused, -// connected pool must be disconnected or it will leak goroutines and will not be garbage collected. -func (p *pool) disconnect(ctx context.Context) error { - if !atomic.CompareAndSwapInt64(&p.connected, connected, disconnecting) { - return ErrPoolDisconnected +// close closes the pool, closes all connections associated with the pool, and stops all background +// goroutines. All subsequent checkOut requests will return an error. An unused, ready pool must be +// closed or it will leak goroutines and will not be garbage collected. +func (p *pool) close(ctx context.Context) { + p.stateMu.Lock() + if p.state == poolClosed { + p.stateMu.Unlock() + return } + p.state = poolClosed + p.stateMu.Unlock() + + // Call cancelBackgroundCtx() to exit the maintain() and createConnections() background + // goroutines. Broadcast to the createConnectionsCond to wake up all createConnections() + // goroutines. We must hold the createConnectionsCond lock here because we're changing the + // condition by cancelling the "background goroutine" Context, even tho cancelling the Context + // is also synchronized by a lock. Otherwise, we run into an intermittent bug that prevents the + // createConnections() goroutines from exiting. + p.createConnectionsCond.L.Lock() + p.cancelBackgroundCtx() + p.createConnectionsCond.Broadcast() + p.createConnectionsCond.L.Unlock() - // Call cancelBackground() to exit the maintain() background goroutine and broadcast to the - // connsCond to wake up all createConnections() goroutines. We must hold the connsCond lock here - // because we're changing the condition by cancelling the "background goroutine" Context, even - // tho cancelling the Context is also synchronized by a lock. Otherwise, we run into an - // intermittent bug that prevents the createConnections() goroutines from exiting. - p.connsCond.L.Lock() - p.cancelBackground() - p.connsCond.L.Unlock() - p.connsCond.Broadcast() // Wait for all background goroutines to exit. p.backgroundDone.Wait() @@ -218,8 +305,8 @@ func (p *pool) disconnect(ctx context.Context) error { } } - // Empty the idle connections stack and try to deliver ErrPoolDisconnected to any waiting - // wantConns from idleConnWait while holding the idleMu lock. + // Empty the idle connections stack and try to deliver ErrPoolClosed to any waiting wantConns + // from idleConnWait while holding the idleMu lock. p.idleMu.Lock() p.idleConns = p.idleConns[:0] for { @@ -227,15 +314,14 @@ func (p *pool) disconnect(ctx context.Context) error { if w == nil { break } - w.tryDeliver(nil, ErrPoolDisconnected) + w.tryDeliver(nil, ErrPoolClosed) } p.idleMu.Unlock() - // Collect all conns from the pool and try to deliver ErrPoolDisconnected to any waiting - // wantConns from newConnWait while holding the connsCond lock. We can't call removeConnection - // on the connections or cancel on the wantConns while holding any locks, so do that after we - // release the lock. - p.connsCond.L.Lock() + // Collect all conns from the pool and try to deliver ErrPoolClosed to any waiting wantConns + // from newConnWait while holding the createConnectionsCond lock. We can't call removeConnection + // on the connections while holding any locks, so do that after we release the lock. + p.createConnectionsCond.L.Lock() conns := make([]*connection, 0, len(p.conns)) for _, conn := range p.conns { conns = append(conns, conn) @@ -245,9 +331,9 @@ func (p *pool) disconnect(ctx context.Context) error { if w == nil { break } - w.tryDeliver(nil, ErrPoolDisconnected) + w.tryDeliver(nil, ErrPoolClosed) } - p.connsCond.L.Unlock() + p.createConnectionsCond.L.Unlock() // Now that we're not holding any locks, remove all of the connections we collected from the // pool. @@ -256,16 +342,12 @@ func (p *pool) disconnect(ctx context.Context) error { _ = p.closeConnection(conn) // We don't care about errors while closing the connection. } - atomic.StoreInt64(&p.connected, disconnected) - if p.monitor != nil { p.monitor.Event(&event.PoolEvent{ Type: event.PoolClosedEvent, Address: p.address.String(), }) } - - return nil } func (p *pool) pinConnectionToCursor() { @@ -287,11 +369,26 @@ func (p *pool) unpinConnectionFromTransaction() { } // checkOut checks out a connection from the pool. If an idle connection is not available, the -// checkOut enters a queue waiting for either the next idle or new connection. If the pool is -// disconnected, checkOut returns an error. +// checkOut enters a queue waiting for either the next idle or new connection. If the pool is not +// ready, checkOut returns an error. // Based partially on https://cs.opensource.google/go/go/+/refs/tags/go1.16.6:src/net/http/transport.go;l=1324 func (p *pool) checkOut(ctx context.Context) (conn *connection, err error) { - if atomic.LoadInt64(&p.connected) != connected { + if p.monitor != nil { + p.monitor.Event(&event.PoolEvent{ + Type: event.GetStarted, + Address: p.address.String(), + }) + } + + // Check the pool state while holding a stateMu read lock. If the pool state is not "ready", + // return an error. Do all of this while holding the stateMu read lock to prevent a state change between + // checking the state and entering the wait queue. Not holding the stateMu read lock here may + // allow a checkOut() to enter the wait queue after clear() pauses the pool and clears the wait + // queue, resulting in createConnections() doing work while the pool is "paused". + p.stateMu.RLock() + switch p.state { + case poolClosed: + p.stateMu.RUnlock() if p.monitor != nil { p.monitor.Event(&event.PoolEvent{ Type: event.GetFailed, @@ -299,7 +396,18 @@ func (p *pool) checkOut(ctx context.Context) (conn *connection, err error) { Reason: event.ReasonPoolClosed, }) } - return nil, ErrPoolDisconnected + return nil, ErrPoolClosed + case poolPaused: + err := poolClearedError{err: p.lastClearErr, address: p.address} + p.stateMu.RUnlock() + if p.monitor != nil { + p.monitor.Event(&event.PoolEvent{ + Type: event.GetFailed, + Address: p.address.String(), + Reason: event.ReasonConnectionErrored, + }) + } + return nil, err } if ctx == nil { @@ -321,6 +429,10 @@ func (p *pool) checkOut(ctx context.Context) (conn *connection, err error) { // immediately deliver an idle connection to the wantConn, so we can return the connection or // error from the wantConn without waiting for "ready". if delivered := p.getOrQueueForIdleConn(w); delivered { + // If delivered = true, we didn't enter the wait queue and will return either a connection + // or an error, so unlock the stateMu lock here. + p.stateMu.RUnlock() + if w.err != nil { if p.monitor != nil { p.monitor.Event(&event.PoolEvent{ @@ -345,6 +457,7 @@ func (p *pool) checkOut(ctx context.Context) (conn *connection, err error) { // If we didn't get an immediately available idle connection, also get in the queue for a new // connection while we're waiting for an idle connection. p.queueForNewConn(w) + p.stateMu.RUnlock() // Wait for either the wantConn to be ready or for the Context to time out. select { @@ -392,9 +505,9 @@ func (p *pool) closeConnection(conn *connection) error { return ErrWrongPool } - if atomic.LoadInt64(&conn.connected) == connected { + if atomic.LoadInt64(&conn.state) == connConnected { conn.closeConnectContext() - _ = conn.wait() // Make sure that the connection has finished connecting + conn.wait() // Make sure that the connection has finished connecting. } err := conn.close() @@ -419,19 +532,19 @@ func (p *pool) removeConnection(conn *connection, reason string) error { return ErrWrongPool } - p.connsCond.L.Lock() + p.createConnectionsCond.L.Lock() _, ok := p.conns[conn.poolID] if !ok { // If the connection has been removed from the pool already, exit without doing any // additional state changes. - p.connsCond.L.Unlock() + p.createConnectionsCond.L.Unlock() return nil } delete(p.conns, conn.poolID) - // Signal the connsCond so any goroutines waiting for a new connection slot in the pool will - // proceed. - p.connsCond.Signal() - p.connsCond.L.Unlock() + // Signal the createConnectionsCond so any goroutines waiting for a new connection slot in the + // pool will proceed. + p.createConnectionsCond.Signal() + p.createConnectionsCond.L.Unlock() // Only update the generation numbers map if the connection has retrieved its generation number. // Otherwise, we'd decrement the count for the generation even though it had never been @@ -453,7 +566,7 @@ func (p *pool) removeConnection(conn *connection, reason string) error { } // checkIn returns an idle connection to the pool. If the connection is perished or the pool is -// disconnected, it is removed from the connection pool and closed. +// closed, it is removed from the connection pool and closed. func (p *pool) checkIn(conn *connection) error { if conn == nil { return nil @@ -483,6 +596,14 @@ func (p *pool) checkInNoEvent(conn *connection) error { return ErrWrongPool } + // Bump the connection idle deadline here because we're about to make the connection "available". + // The idle deadline is used to determine when a connection has reached its max idle time and + // should be closed. A connection reaches its max idle time when it has been "available" in the + // idle connections stack for more than the configured duration (maxIdleTimeMS). Set it before + // we call connectionPerished(), which checks the idle deadline, because a newly "available" + // connection should never be perished due to max idle time. + conn.bumpIdleDeadline() + if reason, perished := connectionPerished(conn); perished { _ = p.removeConnection(conn, reason) go func() { @@ -491,6 +612,14 @@ func (p *pool) checkInNoEvent(conn *connection) error { return nil } + if conn.pool.getState() == poolClosed { + _ = p.removeConnection(conn, event.ReasonPoolClosed) + go func() { + _ = p.closeConnection(conn) + }() + return nil + } + p.idleMu.Lock() defer p.idleMu.Unlock() @@ -514,16 +643,70 @@ func (p *pool) checkInNoEvent(conn *connection) error { return nil } -// clear clears the pool by incrementing the generation -func (p *pool) clear(serviceID *primitive.ObjectID) { - if p.monitor != nil { +// clear marks all connections as stale by incrementing the generation number, stops all background +// goroutines, removes all requests from idleConnWait and newConnWait, and sets the pool state to +// "paused". If serviceID is nil, clear marks all connections as stale. If serviceID is not nil, +// clear marks only connections associated with the given serviceID stale (for use in load balancer +// mode). +func (p *pool) clear(err error, serviceID *primitive.ObjectID) { + if p.getState() == poolClosed { + return + } + + p.generation.clear(serviceID) + + // If serviceID is nil (i.e. not in load balancer mode), transition the pool to a paused state + // by stopping all background goroutines, clearing the wait queues, and setting the pool state + // to "paused". + sendEvent := true + if serviceID == nil { + // While holding the stateMu lock, set the pool state to "paused" if it's currently "ready", + // and set lastClearErr to the error that caused the pool to be cleared. If the pool is + // already paused, don't send another "ConnectionPoolCleared" event. + p.stateMu.Lock() + if p.state == poolPaused { + sendEvent = false + } + if p.state == poolReady { + p.state = poolPaused + } + p.lastClearErr = err + p.stateMu.Unlock() + + pcErr := poolClearedError{err: err, address: p.address} + + // Clear the idle connections wait queue. + p.idleMu.Lock() + for { + w := p.idleConnWait.popFront() + if w == nil { + break + } + w.tryDeliver(nil, pcErr) + } + p.idleMu.Unlock() + + // Clear the new connections wait queue. This effectively pauses the createConnections() + // background goroutine because newConnWait is empty and checkOut() won't insert any more + // wantConns into newConnWait until the pool is marked "ready" again. + p.createConnectionsCond.L.Lock() + for { + w := p.newConnWait.popFront() + if w == nil { + break + } + w.tryDeliver(nil, pcErr) + } + p.createConnectionsCond.L.Unlock() + } + + if sendEvent && p.monitor != nil { p.monitor.Event(&event.PoolEvent{ Type: event.PoolCleared, Address: p.address.String(), ServiceID: serviceID, }) } - p.generation.clear(serviceID) } // getOrQueueForIdleConn attempts to deliver an idle connection to the given wantConn. If there is @@ -568,17 +751,17 @@ func (p *pool) getOrQueueForIdleConn(w *wantConn) bool { } func (p *pool) queueForNewConn(w *wantConn) { - p.connsCond.L.Lock() - defer p.connsCond.L.Unlock() + p.createConnectionsCond.L.Lock() + defer p.createConnectionsCond.L.Unlock() p.newConnWait.cleanFront() p.newConnWait.pushBack(w) - p.connsCond.Signal() + p.createConnectionsCond.Signal() } func (p *pool) totalConnectionCount() int { - p.connsCond.L.Lock() - defer p.connsCond.L.Unlock() + p.createConnectionsCond.L.Lock() + defer p.createConnectionsCond.L.Unlock() return len(p.conns) } @@ -609,11 +792,11 @@ func (p *pool) createConnections(ctx context.Context, wg *sync.WaitGroup) { // waiting wantConn and new connection. If the Context is cancelled or there are any // errors, wait returns with "ok = false". wait := func() (*wantConn, *connection, bool) { - p.connsCond.L.Lock() - defer p.connsCond.L.Unlock() + p.createConnectionsCond.L.Lock() + defer p.createConnectionsCond.L.Unlock() for !condition() { - p.connsCond.Wait() + p.createConnectionsCond.Wait() } if ctx.Err() != nil { @@ -626,12 +809,7 @@ func (p *pool) createConnections(ctx context.Context, wg *sync.WaitGroup) { return nil, nil, false } - conn, err := newConnection(p.address, p.connOpts...) - if err != nil { - w.tryDeliver(nil, err) - return nil, nil, false - } - + conn := newConnection(p.address, p.connOpts...) conn.pool = p conn.poolID = atomic.AddUint64(&p.nextID, 1) p.conns[conn.poolID] = conn @@ -653,12 +831,24 @@ func (p *pool) createConnections(ctx context.Context, wg *sync.WaitGroup) { }) } - conn.connect(context.Background()) - err := conn.wait() + // Pass the createConnections context to connect to allow pool close to cancel connection + // establishment so shutdown doesn't block indefinitely if connectTimeout=0. + err := conn.connect(ctx) if err != nil { - _ = p.removeConnection(conn, event.ReasonConnectionErrored) - _ = p.closeConnection(conn) w.tryDeliver(nil, err) + + // If there's an error connecting the new connection, call the handshake error handler + // that implements the SDAM handshake error handling logic. This must be called after + // delivering the connection error to the waiting wantConn. If it's called before, the + // handshake error handler may clear the connection pool, leading to a different error + // message being delivered to the same waiting wantConn in idleConnWait when the wait + // queues are cleared. + if p.handshakeErrFn != nil { + p.handshakeErrFn(err, conn.generation, conn.desc.ServiceID) + } + + _ = p.removeConnection(conn, event.ReasonError) + _ = p.closeConnection(conn) continue } @@ -710,11 +900,30 @@ func (p *pool) maintain(ctx context.Context, wg *sync.WaitGroup) { wantConns := make([]*wantConn, 0, p.minSize) defer func() { for _, w := range wantConns { - w.tryDeliver(nil, ErrPoolDisconnected) + w.tryDeliver(nil, ErrPoolClosed) } }() for { + select { + case <-ticker.C: + case <-p.maintainReady: + case <-ctx.Done(): + return + } + + // Only maintain the pool while it's in the "ready" state. If the pool state is not "ready", + // wait for the next tick or "ready" signal. Do all of this while holding the stateMu read + // lock to prevent a state change between checking the state and entering the wait queue. + // Not holding the stateMu read lock here may allow maintain() to request wantConns after + // clear() pauses the pool and clears the wait queue, resulting in createConnections() + // doing work while the pool is "paused". + p.stateMu.RLock() + if p.state != poolReady { + p.stateMu.RUnlock() + continue + } + p.removePerishedConns() // Remove any wantConns that are no longer waiting. @@ -744,14 +953,7 @@ func (p *pool) maintain(ctx context.Context, wg *sync.WaitGroup) { } }() } - - // Wait for the next tick at the bottom of the loop so that maintain() runs once immediately - // after connect() is called. Exit the loop if the Context is cancelled. - select { - case <-ticker.C: - case <-ctx.Done(): - return - } + p.stateMu.RUnlock() } } @@ -915,15 +1117,13 @@ func (q *wantConnQueue) peekFront() *wantConn { return nil } -// cleanFront pops any wantConns that are no longer waiting from the head of the -// queue, reporting whether any were popped. -func (q *wantConnQueue) cleanFront() (cleaned bool) { +// cleanFront pops any wantConns that are no longer waiting from the head of the queue. +func (q *wantConnQueue) cleanFront() { for { w := q.peekFront() if w == nil || w.waiting() { - return cleaned + return } q.popFront() - cleaned = true } } diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/pool_generation_counter.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/pool_generation_counter.go index e32f0b8e..47fac2f6 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/pool_generation_counter.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/pool_generation_counter.go @@ -13,6 +13,12 @@ import ( "go.mongodb.org/mongo-driver/bson/primitive" ) +// Pool generation state constants. +const ( + generationDisconnected int64 = iota + generationConnected +) + // generationStats represents the version of a pool. It tracks the generation number as well as the number of // connections that have been created in the generation. type generationStats struct { @@ -42,11 +48,11 @@ func newPoolGenerationMap() *poolGenerationMap { } func (p *poolGenerationMap) connect() { - atomic.StoreInt64(&p.state, connected) + atomic.StoreInt64(&p.state, generationConnected) } func (p *poolGenerationMap) disconnect() { - atomic.StoreInt64(&p.state, disconnected) + atomic.StoreInt64(&p.state, generationDisconnected) } // addConnection increments the connection count for the generation associated with the given service ID and returns the @@ -102,7 +108,7 @@ func (p *poolGenerationMap) clear(serviceIDPtr *primitive.ObjectID) { func (p *poolGenerationMap) stale(serviceIDPtr *primitive.ObjectID, knownGeneration uint64) bool { // If the map has been disconnected, all connections should be considered stale to ensure that they're closed. - if atomic.LoadInt64(&p.state) == disconnected { + if atomic.LoadInt64(&p.state) == generationDisconnected { return true } @@ -127,6 +133,17 @@ func (p *poolGenerationMap) getGeneration(serviceIDPtr *primitive.ObjectID) uint return 0 } +func (p *poolGenerationMap) getNumConns(serviceIDPtr *primitive.ObjectID) uint64 { + serviceID := getServiceID(serviceIDPtr) + p.Lock() + defer p.Unlock() + + if stats, ok := p.generationMap[serviceID]; ok { + return stats.numConns + } + return 0 +} + func getServiceID(oid *primitive.ObjectID) primitive.ObjectID { if oid == nil { return primitive.NilObjectID diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/rtt_monitor.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/rtt_monitor.go index c7963bbf..d91290e9 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/rtt_monitor.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/rtt_monitor.go @@ -25,7 +25,7 @@ const ( type rttConfig struct { interval time.Duration minRTTWindow time.Duration // Window size to calculate minimum RTT over. - createConnectionFn func() (*connection, error) + createConnectionFn func() *connection createOperationFn func(driver.Connection) *operation.Hello } @@ -80,11 +80,12 @@ func (r *rttMonitor) start() { var conn *connection defer func() { if conn != nil { - // If the connection exists, we need to wait for it to be connected. We can ignore the - // error from conn.wait(). If the connection wasn't successfully opened, its state was - // set back to disconnected, so calling conn.close() will be a noop. + // If the connection exists, we need to wait for it to be connected because + // conn.connect() and conn.close() cannot be called concurrently. If the connection + // wasn't successfully opened, its state was set back to disconnected, so calling + // conn.close() will be a no-op. conn.closeConnectContext() - _ = conn.wait() + conn.wait() _ = conn.close() } }() @@ -106,15 +107,10 @@ func (r *rttMonitor) start() { // error, runHello closes the connection. func (r *rttMonitor) runHello(conn *connection) *connection { if conn == nil || conn.closed() { - conn, err := r.cfg.createConnectionFn() - if err != nil { - return nil - } + conn := r.cfg.createConnectionFn() - conn.connect(r.ctx) - err = conn.wait() + err := conn.connect(r.ctx) if err != nil { - _ = conn.close() return nil } diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/server.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/server.go index 28453460..3f8620d0 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/server.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/server.go @@ -25,6 +25,26 @@ import ( const minHeartbeatInterval = 500 * time.Millisecond +// Server state constants. +const ( + serverDisconnected int64 = iota + serverDisconnecting + serverConnected +) + +func serverStateString(state int64) string { + switch state { + case serverDisconnected: + return "Disconnected" + case serverDisconnecting: + return "Disconnecting" + case serverConnected: + return "Connected" + } + + return "" +} + var ( // ErrServerClosed occurs when an attempt to Get a connection is made after // the server has been closed. @@ -54,39 +74,15 @@ func (ss *SelectedServer) Description() description.SelectedServer { } } -// These constants represent the connection states of a server. -const ( - disconnected int64 = iota - disconnecting - connected - connecting - initialized -) - -func connectionStateString(state int64) string { - switch state { - case 0: - return "Disconnected" - case 1: - return "Disconnecting" - case 2: - return "Connected" - case 3: - return "Connecting" - case 4: - return "Initialized" - } - - return "" -} - // Server is a single server within a topology. type Server struct { - // connectionstate must be accessed using the atomic package and should be at the beginning of - // the struct. + // The following integer fields must be accessed using the atomic package and should be at the + // beginning of the struct. // - atomic bug: https://pkg.go.dev/sync/atomic#pkg-note-BUG // - suggested layout: https://go101.org/article/memory-layout.html - connectionstate int64 + + state int64 + operationCount int64 cfg *serverConfig address address.Address @@ -134,11 +130,8 @@ type updateTopologyCallback func(description.Server) description.Server // ConnectServer creates a new Server and then initializes it using the // Connect method. func ConnectServer(addr address.Address, updateCallback updateTopologyCallback, topologyID primitive.ObjectID, opts ...ServerOption) (*Server, error) { - srvr, err := NewServer(addr, topologyID, opts...) - if err != nil { - return nil, err - } - err = srvr.Connect(updateCallback) + srvr := NewServer(addr, topologyID, opts...) + err := srvr.Connect(updateCallback) if err != nil { return nil, err } @@ -147,14 +140,12 @@ func ConnectServer(addr address.Address, updateCallback updateTopologyCallback, // NewServer creates a new server. The mongodb server at the address will be monitored // on an internal monitoring goroutine. -func NewServer(addr address.Address, topologyID primitive.ObjectID, opts ...ServerOption) (*Server, error) { - cfg, err := newServerConfig(opts...) - if err != nil { - return nil, err - } - +func NewServer(addr address.Address, topologyID primitive.ObjectID, opts ...ServerOption) *Server { + cfg := newServerConfig(opts...) globalCtx, globalCtxCancel := context.WithCancel(context.Background()) s := &Server{ + state: serverDisconnected, + cfg: cfg, address: addr, @@ -178,26 +169,27 @@ func NewServer(addr address.Address, topologyID primitive.ObjectID, opts ...Serv s.rttMonitor = newRTTMonitor(rttCfg) pc := poolConfig{ - Address: addr, - MinPoolSize: cfg.minConns, - MaxPoolSize: cfg.maxConns, - MaxConnecting: cfg.maxConnecting, - MaxIdleTime: cfg.connectionPoolMaxIdleTime, - PoolMonitor: cfg.poolMonitor, + Address: addr, + MinPoolSize: cfg.minConns, + MaxPoolSize: cfg.maxConns, + MaxConnecting: cfg.maxConnecting, + MaxIdleTime: cfg.poolMaxIdleTime, + MaintainInterval: cfg.poolMaintainInterval, + PoolMonitor: cfg.poolMonitor, + handshakeErrFn: s.ProcessHandshakeError, } connectionOpts := copyConnectionOpts(cfg.connectionOpts) - connectionOpts = append(connectionOpts, withErrorHandlingCallback(s.ProcessHandshakeError)) s.pool = newPool(pc, connectionOpts...) s.publishServerOpeningEvent(s.address) - return s, nil + return s } // Connect initializes the Server by starting background monitoring goroutines. // This method must be called before a Server can be used. func (s *Server) Connect(updateCallback updateTopologyCallback) error { - if !atomic.CompareAndSwapInt64(&s.connectionstate, disconnected, connected) { + if !atomic.CompareAndSwapInt64(&s.state, serverDisconnected, serverConnected) { return ErrServerConnected } @@ -214,7 +206,15 @@ func (s *Server) Connect(updateCallback updateTopologyCallback) error { s.closewg.Add(1) go s.update() } - return s.pool.connect() + + // The CMAP spec describes that pools should only be marked "ready" when the server description + // is updated to something other than "Unknown". However, we maintain the previous Server + // behavior here and immediately mark the pool as ready during Connect() to simplify and speed + // up the Client startup behavior. The risk of marking a pool as ready proactively during + // Connect() is that we could attempt to create connections to a server that was configured + // erroneously until the first server check or checkOut() failure occurs, when the SDAM error + // handler would transition the Server back to "Unknown" and set the pool to "paused". + return s.pool.ready() } // Disconnect closes sockets to the server referenced by this Server. @@ -227,7 +227,7 @@ func (s *Server) Connect(updateCallback updateTopologyCallback) error { // any in flight read or write operations. If this method returns with no // errors, all connections associated with this Server have been closed. func (s *Server) Disconnect(ctx context.Context) error { - if !atomic.CompareAndSwapInt64(&s.connectionstate, connected, disconnecting) { + if !atomic.CompareAndSwapInt64(&s.state, serverConnected, serverDisconnecting) { return ErrServerClosed } @@ -242,38 +242,42 @@ func (s *Server) Disconnect(ctx context.Context) error { s.cancelCheck() s.rttMonitor.disconnect() - err := s.pool.disconnect(ctx) - if err != nil { - return err - } + s.pool.close(ctx) s.closewg.Wait() - atomic.StoreInt64(&s.connectionstate, disconnected) + atomic.StoreInt64(&s.state, serverDisconnected) return nil } // Connection gets a connection to the server. func (s *Server) Connection(ctx context.Context) (driver.Connection, error) { - - if s.pool.monitor != nil { - s.pool.monitor.Event(&event.PoolEvent{ - Type: "ConnectionCheckOutStarted", - Address: s.pool.address.String(), - }) - } - - if atomic.LoadInt64(&s.connectionstate) != connected { + if atomic.LoadInt64(&s.state) != serverConnected { return nil, ErrServerClosed } - connImpl, err := s.pool.checkOut(ctx) + // Increment the operation count before calling checkOut to make sure that all connection + // requests are included in the operation count, including those in the wait queue. If we got an + // error instead of a connection, immediately decrement the operation count. + atomic.AddInt64(&s.operationCount, 1) + conn, err := s.pool.checkOut(ctx) if err != nil { - // The error has already been handled by connection.connect, which calls Server.ProcessHandshakeError. + atomic.AddInt64(&s.operationCount, -1) return nil, err } - return &Connection{connection: connImpl}, nil + return &Connection{ + connection: conn, + cleanupServerFn: func() { + // Decrement the operation count whenever the caller is done with the connection. Note + // that cleanupServerFn() is not called while the connection is pinned to a cursor or + // transaction, so the operation count is not decremented until the cursor is closed or + // the transaction is committed or aborted. Use an int64 instead of a uint64 to mitigate + // the impact of any possible bugs that could cause the uint64 to underflow, which would + // make the server much less selectable. + atomic.AddInt64(&s.operationCount, -1) + }, + }, nil } // ProcessHandshakeError implements SDAM error handling for errors that occur before a connection @@ -295,11 +299,17 @@ func (s *Server) ProcessHandshakeError(err error, startingGenerationNumber uint6 return } + // Must hold the processErrorLock while updating the server description and clearing the pool. + // Not holding the lock leads to possible out-of-order processing of pool.clear() and + // pool.ready() calls from concurrent server description updates. + s.processErrorLock.Lock() + defer s.processErrorLock.Unlock() + // Since the only kind of ConnectionError we receive from pool.Get will be an initialization error, we should set // the description.Server appropriately. The description should not have a TopologyVersion because the staleness // checking logic above has already determined that this description is not stale. s.updateDescription(description.NewServerFromError(s.address, wrappedConnErr, nil)) - s.pool.clear(serviceID) + s.pool.clear(err, serviceID) s.cancelCheck() } @@ -323,7 +333,7 @@ func (s *Server) SelectedDescription() description.SelectedServer { // updated server descriptions will be sent. The channel will have a buffer // size of one, and will be pre-populated with the current description. func (s *Server) Subscribe() (*ServerSubscription, error) { - if atomic.LoadInt64(&s.connectionstate) != connected { + if atomic.LoadInt64(&s.state) != serverConnected { return nil, ErrSubscribeAfterClosed } ch := make(chan description.Server, 1) @@ -379,6 +389,9 @@ func (s *Server) ProcessError(err error, conn driver.Connection) driver.ProcessE return driver.NoChange } + // Must hold the processErrorLock while updating the server description and clearing the pool. + // Not holding the lock leads to possible out-of-order processing of pool.clear() and + // pool.ready() calls from concurrent server description updates. s.processErrorLock.Lock() defer s.processErrorLock.Unlock() @@ -403,8 +416,9 @@ func (s *Server) ProcessError(err error, conn driver.Connection) driver.ProcessE // If the node is shutting down or is older than 4.2, we synchronously clear the pool if cerr.NodeIsShuttingDown() || desc.WireVersion == nil || desc.WireVersion.Max < 8 { res = driver.ConnectionPoolCleared - s.pool.clear(desc.ServiceID) + s.pool.clear(err, desc.ServiceID) } + return res } if wcerr, ok := getWriteConcernErrorForProcessing(err); ok { @@ -421,7 +435,7 @@ func (s *Server) ProcessError(err error, conn driver.Connection) driver.ProcessE // If the node is shutting down or is older than 4.2, we synchronously clear the pool if wcerr.NodeIsShuttingDown() || desc.WireVersion == nil || desc.WireVersion.Max < 8 { res = driver.ConnectionPoolCleared - s.pool.clear(desc.ServiceID) + s.pool.clear(err, desc.ServiceID) } return res } @@ -443,7 +457,7 @@ func (s *Server) ProcessError(err error, conn driver.Connection) driver.ProcessE // monitoring check. The check is cancelled last to avoid a post-cancellation reconnect racing with // updateDescription. s.updateDescription(description.NewServerFromError(s.address, err, nil)) - s.pool.clear(desc.ServiceID) + s.pool.clear(err, desc.ServiceID) s.cancelCheck() return driver.ConnectionPoolCleared } @@ -521,7 +535,7 @@ func (s *Server) update() { // Perform the next check. desc, err := s.check() if err == errCheckCancelled { - if atomic.LoadInt64(&s.connectionstate) != connected { + if atomic.LoadInt64(&s.state) != serverConnected { continue } @@ -531,13 +545,18 @@ func (s *Server) update() { continue } + // Must hold the processErrorLock while updating the server description and clearing the + // pool. Not holding the lock leads to possible out-of-order processing of pool.clear() and + // pool.ready() calls from concurrent server description updates. + s.processErrorLock.Lock() s.updateDescription(desc) - if desc.LastError != nil { + if err := desc.LastError; err != nil { // Clear the pool once the description has been updated to Unknown. Pass in a nil service ID to clear // because the monitoring routine only runs for non-load balanced deployments in which servers don't return // IDs. - s.pool.clear(nil) + s.pool.clear(err, nil) } + s.processErrorLock.Unlock() // If the server supports streaming or we're already streaming, we want to move to streaming the next response // without waiting. If the server has transitioned to Unknown from a network error, we want to do another @@ -573,6 +592,18 @@ func (s *Server) updateDescription(desc description.Server) { _ = recover() }() + // Anytime we update the server description to something other than "unknown", set the pool to + // "ready". Do this before updating the description so that connections can be checked out as + // soon as the server is selectable. If the pool is already ready, this operation is a no-op. + // Note that this behavior is roughly consistent with the current Go driver behavior (connects + // to all servers, even non-data-bearing nodes) but deviates slightly from CMAP spec, which + // specifies a more restricted set of server descriptions and topologies that should mark the + // pool ready. We don't have access to the topology here, so prefer the current Go driver + // behavior for simplicity. + if desc.Kind != description.Unknown { + _ = s.pool.ready() + } + // Use the updateTopologyCallback to update the parent Topology and get the description that should be stored. callback, ok := s.updateTopologyCallback.Load().(updateTopologyCallback) if ok && callback != nil { @@ -594,7 +625,7 @@ func (s *Server) updateDescription(desc description.Server) { // createConnection creates a new connection instance but does not call connect on it. The caller must call connect // before the connection can be used for network operations. -func (s *Server) createConnection() (*connection, error) { +func (s *Server) createConnection() *connection { opts := copyConnectionOpts(s.cfg.connectionOpts) opts = append(opts, WithConnectTimeout(func(time.Duration) time.Duration { return s.cfg.heartbeatTimeout }), @@ -620,10 +651,7 @@ func copyConnectionOpts(opts []ConnectionOption) []ConnectionOption { } func (s *Server) setupHeartbeatConnection() error { - conn, err := s.createConnection() - if err != nil { - return err - } + conn := s.createConnection() // Take the lock when assigning the context and connection because they're accessed by cancelCheck. s.heartbeatLock.Lock() @@ -635,8 +663,7 @@ func (s *Server) setupHeartbeatConnection() error { s.conn = conn s.heartbeatLock.Unlock() - s.conn.connect(s.heartbeatCtx) - return s.conn.wait() + return s.conn.connect(s.heartbeatCtx) } // cancelCheck cancels in-progress connection dials and reads. It does not set any fields on the server. @@ -655,11 +682,11 @@ func (s *Server) cancelCheck() { return } - // If the connection exists, we need to wait for it to be connected conn.connect() and conn.close() cannot be called - // concurrently. We can ignore the error from conn.wait(). If the connection wasn't successfully opened, its state - // was set back to disconnected, so calling conn.close() will be a noop. + // If the connection exists, we need to wait for it to be connected because conn.connect() and + // conn.close() cannot be called concurrently. If the connection wasn't successfully opened, its + // state was set back to disconnected, so calling conn.close() will be a no-op. conn.closeConnectContext() - _ = conn.wait() + conn.wait() _ = conn.close() } @@ -792,16 +819,21 @@ func (s *Server) MinRTT() time.Duration { return s.rttMonitor.getMinRTT() } +// OperationCount returns the current number of in-progress operations for this server. +func (s *Server) OperationCount() int64 { + return atomic.LoadInt64(&s.operationCount) +} + // String implements the Stringer interface. func (s *Server) String() string { desc := s.Description() - connState := atomic.LoadInt64(&s.connectionstate) + state := atomic.LoadInt64(&s.state) str := fmt.Sprintf("Addr: %s, Type: %s, State: %s", - s.address, desc.Kind, connectionStateString(connState)) + s.address, desc.Kind, serverStateString(state)) if len(desc.Tags) != 0 { str += fmt.Sprintf(", Tag sets: %s", desc.Tags) } - if connState == connected { + if state == serverConnected { str += fmt.Sprintf(", Average RTT: %s, Min RTT: %s", desc.AverageRTT, s.MinRTT()) } if desc.LastError != nil { diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/server_options.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/server_options.go index 37258aaf..a4b7dcc2 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/server_options.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/server_options.go @@ -19,25 +19,28 @@ import ( var defaultRegistry = bson.NewRegistryBuilder().Build() type serverConfig struct { - clock *session.ClusterClock - compressionOpts []string - connectionOpts []ConnectionOption - appname string - heartbeatInterval time.Duration - heartbeatTimeout time.Duration - maxConns uint64 - minConns uint64 - maxConnecting uint64 - poolMonitor *event.PoolMonitor - serverMonitor *event.ServerMonitor - connectionPoolMaxIdleTime time.Duration - registry *bsoncodec.Registry - monitoringDisabled bool - serverAPI *driver.ServerAPIOptions - loadBalanced bool -} - -func newServerConfig(opts ...ServerOption) (*serverConfig, error) { + clock *session.ClusterClock + compressionOpts []string + connectionOpts []ConnectionOption + appname string + heartbeatInterval time.Duration + heartbeatTimeout time.Duration + serverMonitor *event.ServerMonitor + registry *bsoncodec.Registry + monitoringDisabled bool + serverAPI *driver.ServerAPIOptions + loadBalanced bool + + // Connection pool options. + maxConns uint64 + minConns uint64 + maxConnecting uint64 + poolMonitor *event.PoolMonitor + poolMaxIdleTime time.Duration + poolMaintainInterval time.Duration +} + +func newServerConfig(opts ...ServerOption) *serverConfig { cfg := &serverConfig{ heartbeatInterval: 10 * time.Second, heartbeatTimeout: 10 * time.Second, @@ -46,72 +49,65 @@ func newServerConfig(opts ...ServerOption) (*serverConfig, error) { } for _, opt := range opts { - err := opt(cfg) - if err != nil { - return nil, err + if opt == nil { + continue } + opt(cfg) } - return cfg, nil + return cfg } // ServerOption configures a server. -type ServerOption func(*serverConfig) error +type ServerOption func(*serverConfig) func withMonitoringDisabled(fn func(bool) bool) ServerOption { - return func(cfg *serverConfig) error { + return func(cfg *serverConfig) { cfg.monitoringDisabled = fn(cfg.monitoringDisabled) - return nil } } // WithConnectionOptions configures the server's connections. func WithConnectionOptions(fn func(...ConnectionOption) []ConnectionOption) ServerOption { - return func(cfg *serverConfig) error { + return func(cfg *serverConfig) { cfg.connectionOpts = fn(cfg.connectionOpts...) - return nil } } // WithCompressionOptions configures the server's compressors. func WithCompressionOptions(fn func(...string) []string) ServerOption { - return func(cfg *serverConfig) error { + return func(cfg *serverConfig) { cfg.compressionOpts = fn(cfg.compressionOpts...) - return nil } } // WithServerAppName configures the server's application name. func WithServerAppName(fn func(string) string) ServerOption { - return func(cfg *serverConfig) error { + return func(cfg *serverConfig) { cfg.appname = fn(cfg.appname) - return nil } } // WithHeartbeatInterval configures a server's heartbeat interval. func WithHeartbeatInterval(fn func(time.Duration) time.Duration) ServerOption { - return func(cfg *serverConfig) error { + return func(cfg *serverConfig) { cfg.heartbeatInterval = fn(cfg.heartbeatInterval) - return nil } } // WithHeartbeatTimeout configures how long to wait for a heartbeat socket to // connection. func WithHeartbeatTimeout(fn func(time.Duration) time.Duration) ServerOption { - return func(cfg *serverConfig) error { + return func(cfg *serverConfig) { cfg.heartbeatTimeout = fn(cfg.heartbeatTimeout) - return nil } } // WithMaxConnections configures the maximum number of connections to allow for -// a given server. If max is 0, then the default will be math.MaxInt64. +// a given server. If max is 0, then maximum connection pool size is not limited. func WithMaxConnections(fn func(uint64) uint64) ServerOption { - return func(cfg *serverConfig) error { + return func(cfg *serverConfig) { cfg.maxConns = fn(cfg.maxConns) - return nil } } @@ -119,9 +115,8 @@ func WithMaxConnections(fn func(uint64) uint64) ServerOption { // a given server. If min is 0, then there is no lower limit to the number of // connections. func WithMinConnections(fn func(uint64) uint64) ServerOption { - return func(cfg *serverConfig) error { + return func(cfg *serverConfig) { cfg.minConns = fn(cfg.minConns) - return nil } } @@ -129,9 +124,8 @@ func WithMinConnections(fn func(uint64) uint64) ServerOption { // pool may establish simultaneously. If maxConnecting is 0, the default value // of 2 is used. func WithMaxConnecting(fn func(uint64) uint64) ServerOption { - return func(cfg *serverConfig) error { + return func(cfg *serverConfig) { cfg.maxConnecting = fn(cfg.maxConnecting) - return nil } } @@ -139,57 +133,58 @@ func WithMaxConnecting(fn func(uint64) uint64) ServerOption { // before being removed. If connectionPoolMaxIdleTime is 0, then no idle time is set and connections will not be removed // because of their age func WithConnectionPoolMaxIdleTime(fn func(time.Duration) time.Duration) ServerOption { - return func(cfg *serverConfig) error { - cfg.connectionPoolMaxIdleTime = fn(cfg.connectionPoolMaxIdleTime) - return nil + return func(cfg *serverConfig) { + cfg.poolMaxIdleTime = fn(cfg.poolMaxIdleTime) + } +} + +// WithConnectionPoolMaintainInterval configures the interval that the background connection pool +// maintenance goroutine runs. +func WithConnectionPoolMaintainInterval(fn func(time.Duration) time.Duration) ServerOption { + return func(cfg *serverConfig) { + cfg.poolMaintainInterval = fn(cfg.poolMaintainInterval) } } // WithConnectionPoolMonitor configures the monitor for all connection pool actions func WithConnectionPoolMonitor(fn func(*event.PoolMonitor) *event.PoolMonitor) ServerOption { - return func(cfg *serverConfig) error { + return func(cfg *serverConfig) { cfg.poolMonitor = fn(cfg.poolMonitor) - return nil } } // WithServerMonitor configures the monitor for all SDAM events for a server func WithServerMonitor(fn func(*event.ServerMonitor) *event.ServerMonitor) ServerOption { - return func(cfg *serverConfig) error { + return func(cfg *serverConfig) { cfg.serverMonitor = fn(cfg.serverMonitor) - return nil } } // WithClock configures the ClusterClock for the server to use. func WithClock(fn func(clock *session.ClusterClock) *session.ClusterClock) ServerOption { - return func(cfg *serverConfig) error { + return func(cfg *serverConfig) { cfg.clock = fn(cfg.clock) - return nil } } // WithRegistry configures the registry for the server to use when creating // cursors. func WithRegistry(fn func(*bsoncodec.Registry) *bsoncodec.Registry) ServerOption { - return func(cfg *serverConfig) error { + return func(cfg *serverConfig) { cfg.registry = fn(cfg.registry) - return nil } } // WithServerAPI configures the server API options for the server to use. func WithServerAPI(fn func(serverAPI *driver.ServerAPIOptions) *driver.ServerAPIOptions) ServerOption { - return func(cfg *serverConfig) error { + return func(cfg *serverConfig) { cfg.serverAPI = fn(cfg.serverAPI) - return nil } } // WithServerLoadBalanced specifies whether or not the server is behind a load balancer. func WithServerLoadBalanced(fn func(bool) bool) ServerOption { - return func(cfg *serverConfig) error { + return func(cfg *serverConfig) { cfg.loadBalanced = fn(cfg.loadBalanced) - return nil } } diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/tls_connection_source_1_16.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/tls_connection_source_1_16.go new file mode 100644 index 00000000..387f2ec0 --- /dev/null +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/tls_connection_source_1_16.go @@ -0,0 +1,58 @@ +// Copyright (C) MongoDB, Inc. 2017-present. +// +// 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 + +//go:build !go1.17 +// +build !go1.17 + +package topology + +import ( + "context" + "crypto/tls" + "net" +) + +type tlsConn interface { + net.Conn + + // Only require Handshake on the interface for Go 1.16 and less. + Handshake() error + ConnectionState() tls.ConnectionState +} + +var _ tlsConn = (*tls.Conn)(nil) + +type tlsConnectionSource interface { + Client(net.Conn, *tls.Config) tlsConn +} + +type tlsConnectionSourceFn func(net.Conn, *tls.Config) tlsConn + +var _ tlsConnectionSource = (tlsConnectionSourceFn)(nil) + +func (t tlsConnectionSourceFn) Client(nc net.Conn, cfg *tls.Config) tlsConn { + return t(nc, cfg) +} + +var defaultTLSConnectionSource tlsConnectionSourceFn = func(nc net.Conn, cfg *tls.Config) tlsConn { + return tls.Client(nc, cfg) +} + +// clientHandshake will perform a handshake with a goroutine and wait for its completion on Go 1.16 and less +// when HandshakeContext is not available. +func clientHandshake(ctx context.Context, client tlsConn) error { + errChan := make(chan error, 1) + go func() { + errChan <- client.Handshake() + }() + + select { + case err := <-errChan: + return err + case <-ctx.Done(): + return ctx.Err() + } +} diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/tls_connection_source.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/tls_connection_source_1_17.go similarity index 66% rename from vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/tls_connection_source.go rename to vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/tls_connection_source_1_17.go index 718a9abb..c9822e06 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/tls_connection_source.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/tls_connection_source_1_17.go @@ -1,19 +1,25 @@ -// Copyright (C) MongoDB, Inc. 2017-present. +// Copyright (C) MongoDB, Inc. 2022-present. // // 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 +//go:build go1.17 +// +build go1.17 + package topology import ( + "context" "crypto/tls" "net" ) type tlsConn interface { net.Conn - Handshake() error + + // Require HandshakeContext on the interface for Go 1.17 and higher. + HandshakeContext(ctx context.Context) error ConnectionState() tls.ConnectionState } @@ -34,3 +40,8 @@ func (t tlsConnectionSourceFn) Client(nc net.Conn, cfg *tls.Config) tlsConn { var defaultTLSConnectionSource tlsConnectionSourceFn = func(nc net.Conn, cfg *tls.Config) tlsConn { return tls.Client(nc, cfg) } + +// clientHandshake will perform a handshake on Go 1.17 and higher with HandshakeContext. +func clientHandshake(ctx context.Context, client tlsConn) error { + return client.HandshakeContext(ctx) +} diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/topology.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/topology.go index 0f3ccdfd..97ec5e52 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/topology.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/topology.go @@ -13,14 +13,13 @@ package topology // import "go.mongodb.org/mongo-driver/x/mongo/driver/topology" import ( "context" "errors" + "fmt" "math/rand" "strings" "sync" "sync/atomic" "time" - "fmt" - "go.mongodb.org/mongo-driver/bson/primitive" "go.mongodb.org/mongo-driver/event" "go.mongodb.org/mongo-driver/internal/randutil" @@ -30,6 +29,14 @@ import ( "go.mongodb.org/mongo-driver/x/mongo/driver/dns" ) +// Topology state constants. +const ( + topologyDisconnected int64 = iota + topologyDisconnecting + topologyConnected + topologyConnecting +) + // ErrSubscribeAfterClosed is returned when a user attempts to subscribe to a // closed Server or Topology. var ErrSubscribeAfterClosed = errors.New("cannot subscribe after closeConnection") @@ -50,7 +57,7 @@ var ErrServerSelectionTimeout = errors.New("server selection timeout") type MonitorMode uint8 // random is a package-global pseudo-random number generator. -var random = randutil.NewLockedRand(rand.NewSource(time.Now().UnixNano())) +var random = randutil.NewLockedRand(rand.NewSource(randutil.CryptoSeed())) // These constants are the available monitoring modes. const ( @@ -60,7 +67,7 @@ const ( // Topology represents a MongoDB deployment. type Topology struct { - connectionstate int64 + state int64 cfg *config @@ -148,7 +155,7 @@ func New(opts ...Option) (*Topology, error) { // Connect initializes a Topology and starts the monitoring process. This function // must be called to properly monitor the topology. func (t *Topology) Connect() error { - if !atomic.CompareAndSwapInt64(&t.connectionstate, disconnected, connecting) { + if !atomic.CompareAndSwapInt64(&t.state, topologyDisconnected, topologyConnecting) { return ErrTopologyConnected } @@ -230,14 +237,14 @@ func (t *Topology) Connect() error { t.subscriptionsClosed = false // explicitly set in case topology was disconnected and then reconnected - atomic.StoreInt64(&t.connectionstate, connected) + atomic.StoreInt64(&t.state, topologyConnected) return nil } // Disconnect closes the topology. It stops the monitoring thread and // closes all open subscriptions. func (t *Topology) Disconnect(ctx context.Context) error { - if !atomic.CompareAndSwapInt64(&t.connectionstate, connected, disconnecting) { + if !atomic.CompareAndSwapInt64(&t.state, topologyConnected, topologyDisconnecting) { return ErrTopologyClosed } @@ -269,7 +276,7 @@ func (t *Topology) Disconnect(ctx context.Context) error { t.desc.Store(description.Topology{}) - atomic.StoreInt64(&t.connectionstate, disconnected) + atomic.StoreInt64(&t.state, topologyDisconnected) t.publishTopologyClosedEvent() return nil } @@ -291,7 +298,7 @@ func (t *Topology) Kind() description.TopologyKind { return t.Description().Kind // and will be pre-populated with the current description.Topology. // Subscribe implements the driver.Subscriber interface. func (t *Topology) Subscribe() (*driver.Subscription, error) { - if atomic.LoadInt64(&t.connectionstate) != connected { + if atomic.LoadInt64(&t.state) != topologyConnected { return nil, errors.New("cannot subscribe to Topology that is not connected") } ch := make(chan description.Topology, 1) @@ -339,7 +346,7 @@ func (t *Topology) Unsubscribe(sub *driver.Subscription) error { // RequestImmediateCheck will send heartbeats to all the servers in the // topology right away, instead of waiting for the heartbeat timeout. func (t *Topology) RequestImmediateCheck() { - if atomic.LoadInt64(&t.connectionstate) != connected { + if atomic.LoadInt64(&t.state) != topologyConnected { return } t.serversLock.Lock() @@ -353,7 +360,7 @@ func (t *Topology) RequestImmediateCheck() { // server selection spec, and will time out after severSelectionTimeout or when the // parent context is done. func (t *Topology) SelectServer(ctx context.Context, ss description.ServerSelector) (driver.Server, error) { - if atomic.LoadInt64(&t.connectionstate) != connected { + if atomic.LoadInt64(&t.state) != topologyConnected { return nil, ErrTopologyClosed } var ssTimeoutCh <-chan time.Time @@ -399,26 +406,77 @@ func (t *Topology) SelectServer(ctx context.Context, ss description.ServerSelect continue } - selected := suitable[random.Intn(len(suitable))] - selectedS, err := t.FindServer(selected) - switch { - case err != nil: + // If there's only one suitable server description, try to find the associated server and + // return it. This is an optimization primarily for standalone and load-balanced deployments. + if len(suitable) == 1 { + server, err := t.FindServer(suitable[0]) + if err != nil { + return nil, err + } + if server == nil { + continue + } + return server, nil + } + + // Randomly select 2 suitable server descriptions and find servers for them. We select two + // so we can pick the one with the one with fewer in-progress operations below. + desc1, desc2 := pick2(suitable) + server1, err := t.FindServer(desc1) + if err != nil { return nil, err - case selectedS != nil: - return selectedS, nil - default: - // We don't have an actual server for the provided description. - // This could happen for a number of reasons, including that the - // server has since stopped being a part of this topology, or that - // the server selector returned no suitable servers. } + server2, err := t.FindServer(desc2) + if err != nil { + return nil, err + } + + // If we don't have an actual server for one or both of the provided descriptions, either + // return the one server we have, or try again if they're both nil. This could happen for a + // number of reasons, including that the server has since stopped being a part of this + // topology. + if server1 == nil || server2 == nil { + if server1 == nil && server2 == nil { + continue + } + if server1 != nil { + return server1, nil + } + return server2, nil + } + + // Of the two randomly selected suitable servers, pick the one with fewer in-use connections. + // We use in-use connections as an analog for in-progress operations because they are almost + // always the same value for a given server. + if server1.OperationCount() < server2.OperationCount() { + return server1, nil + } + return server2, nil } } +// pick2 returns 2 random server descriptions from the input slice of server descriptions, +// guaranteeing that the same element from the slice is not picked twice. The order of server +// descriptions in the input slice may be modified. If fewer than 2 server descriptions are +// provided, pick2 will panic. +func pick2(ds []description.Server) (description.Server, description.Server) { + // Select a random index from the input slice and keep the server description from that index. + idx := random.Intn(len(ds)) + s1 := ds[idx] + + // Swap the selected index to the end and reslice to remove it so we don't pick the same server + // description twice. + ds[idx], ds[len(ds)-1] = ds[len(ds)-1], ds[idx] + ds = ds[:len(ds)-1] + + // Select another random index from the input slice and return both selected server descriptions. + return s1, ds[random.Intn(len(ds))] +} + // FindServer will attempt to find a server that fits the given server description. // This method will return nil, nil if a matching server could not be found. func (t *Topology) FindServer(selected description.Server) (*SelectedServer, error) { - if atomic.LoadInt64(&t.connectionstate) != connected { + if atomic.LoadInt64(&t.state) != topologyConnected { return nil, ErrTopologyClosed } t.serversLock.Lock() @@ -498,7 +556,7 @@ func (t *Topology) selectServerFromDescription(desc description.Topology, func (t *Topology) pollSRVRecords() { defer t.pollingwg.Done() - serverConfig, _ := newServerConfig(t.cfg.serverOpts...) + serverConfig := newServerConfig(t.cfg.serverOpts...) heartbeatInterval := serverConfig.heartbeatInterval pollTicker := time.NewTicker(t.rescanSRVInterval) @@ -628,7 +686,6 @@ func (t *Topology) processSRVResults(parsedHosts []string) bool { t.subLock.Unlock() return true - } // apply updates the Topology and its underlying FSM based on the provided server description and returns the server @@ -649,11 +706,7 @@ func (t *Topology) apply(ctx context.Context, desc description.Server) descripti } var current description.Topology - var err error - current, desc, err = t.fsm.apply(desc) - if err != nil { - return desc - } + current, desc = t.fsm.apply(desc) if !oldDesc.Equal(desc) { t.publishServerDescriptionChangedEvent(oldDesc, desc) diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/topology_options.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/topology_options.go index aca85b0b..b405739c 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/topology_options.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/topology/topology_options.go @@ -48,6 +48,9 @@ func newConfig(opts ...Option) (*config, error) { } for _, opt := range opts { + if opt == nil { + continue + } err := opt(cfg) if err != nil { return nil, err @@ -190,6 +193,7 @@ func WithConnString(fn func(connstring.ConnString) connstring.ConnString) Option AppName: cs.AppName, Authenticator: authenticator, Compressors: cs.Compressors, + LoadBalanced: cs.LoadBalancedSet && cs.LoadBalanced, } if cs.AuthMechanism == "" { // Required for SASL mechanism negotiation during handshake @@ -200,7 +204,10 @@ func WithConnString(fn func(connstring.ConnString) connstring.ConnString) Option } else { // We need to add a non-auth Handshaker to the connection options connOpts = append(connOpts, WithHandshaker(func(h driver.Handshaker) driver.Handshaker { - return operation.NewHello().AppName(cs.AppName).Compressors(cs.Compressors) + return operation.NewHello(). + AppName(cs.AppName). + Compressors(cs.Compressors). + LoadBalanced(cs.LoadBalancedSet && cs.LoadBalanced) })) } diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/uuid/uuid.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/uuid/uuid.go index 50d26344..09783873 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/uuid/uuid.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/uuid/uuid.go @@ -9,7 +9,6 @@ package uuid // import "go.mongodb.org/mongo-driver/x/mongo/driver/uuid" import ( "io" "math/rand" - "time" "go.mongodb.org/mongo-driver/internal/randutil" ) @@ -17,17 +16,17 @@ import ( // UUID represents a UUID. type UUID [16]byte -// random is a package-global pseudo-random number generator. -var random = randutil.NewLockedRand(rand.NewSource(time.Now().UnixNano())) +// A source is a UUID generator that reads random values from a randutil.LockedRand. +// It is safe to use from multiple goroutines. +type source struct { + random *randutil.LockedRand +} -// New returns a random UUIDv4. It uses a "math/rand" pseudo-random number generator seeded with the -// package initialization time. -// -// New should not be used to generate cryptographically-secure random UUIDs. -func New() (UUID, error) { +// new returns a random UUIDv4 with bytes read from the source's random number generator. +func (s *source) new() (UUID, error) { var uuid [16]byte - _, err := io.ReadFull(random, uuid[:]) + _, err := io.ReadFull(s.random, uuid[:]) if err != nil { return [16]byte{}, err } @@ -37,6 +36,26 @@ func New() (UUID, error) { return uuid, nil } +// newGlobalSource returns a source that uses a "math/rand" pseudo-random number generator seeded +// with a cryptographically-secure random number. It is intended to be used to initialize the +// package-global UUID generator. +func newGlobalSource() *source { + return &source{ + random: randutil.NewLockedRand(rand.NewSource(randutil.CryptoSeed())), + } +} + +// globalSource is a package-global pseudo-random UUID generator. +var globalSource = newGlobalSource() + +// New returns a random UUIDv4. It uses a "math/rand" pseudo-random number generator seeded with a +// cryptographically-secure random number at package initialization. +// +// New should not be used to generate cryptographically-secure random UUIDs. +func New() (UUID, error) { + return globalSource.new() +} + // Equal returns true if two UUIDs are equal. func Equal(a, b UUID) bool { return a == b diff --git a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/wiremessage/wiremessage.go b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/wiremessage/wiremessage.go index abf9ad1c..47f086e8 100644 --- a/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/wiremessage/wiremessage.go +++ b/vendor/go.mongodb.org/mongo-driver/x/mongo/driver/wiremessage/wiremessage.go @@ -391,7 +391,7 @@ func ReadMsgSectionRawDocumentSequence(src []byte) (identifier string, data []by return "", nil, rem, false } - // After these assignments, rem will be the data containing the identifer string + the document sequence bytes and + // After these assignments, rem will be the data containing the identifier string + the document sequence bytes and // rest will be the rest of the wire message after this document sequence. rem, rest := rem[:length-4], rem[length-4:] diff --git a/vendor/modules.txt b/vendor/modules.txt index 844115e6..bf3a22f1 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1,6 +1,6 @@ -# github.com/Andrew-M-C/go.emoji v0.0.0-20211011074904-61cf526972e1 +# github.com/Andrew-M-C/go.emoji v1.0.1 github.com/Andrew-M-C/go.emoji/official -# github.com/DeAccountSystems/das-lib v0.0.0-20220607033455-1b6e6e92f767 +# github.com/DeAccountSystems/das-lib v0.0.0-20220620082742-eb52ca54a597 ## explicit github.com/DeAccountSystems/das-lib/common github.com/DeAccountSystems/das-lib/core @@ -136,7 +136,7 @@ github.com/parnurzeal/gorequest github.com/pkg/errors # github.com/russross/blackfriday/v2 v2.0.1 github.com/russross/blackfriday/v2 -# github.com/scorpiotzh/mylog v1.0.9 +# github.com/scorpiotzh/mylog v1.0.10 ## explicit github.com/scorpiotzh/mylog # github.com/scorpiotzh/toolib v1.1.3 @@ -168,7 +168,7 @@ github.com/xdg-go/scram github.com/xdg-go/stringprep # github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d github.com/youmark/pkcs8 -# go.mongodb.org/mongo-driver v1.8.3 +# go.mongodb.org/mongo-driver v1.9.1 ## explicit go.mongodb.org/mongo-driver/bson go.mongodb.org/mongo-driver/bson/bsoncodec