update deps
This commit is contained in:
+10
-9
@@ -16,7 +16,7 @@ require (
|
||||
github.com/go-pkgz/lcw v0.8.1
|
||||
github.com/go-pkgz/lgr v0.10.4
|
||||
github.com/go-pkgz/repeater v1.1.3
|
||||
github.com/go-pkgz/rest v1.13.0
|
||||
github.com/go-pkgz/rest v1.14.0
|
||||
github.com/go-pkgz/syncs v1.2.0
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible
|
||||
github.com/google/uuid v1.3.0
|
||||
@@ -34,13 +34,13 @@ require (
|
||||
github.com/stretchr/testify v1.7.1
|
||||
go.etcd.io/bbolt v1.3.6
|
||||
go.uber.org/goleak v1.1.12
|
||||
golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29
|
||||
golang.org/x/image v0.0.0-20220321031419-a8550c1d254a
|
||||
golang.org/x/net v0.0.0-20220403103023-749bd193bc2b
|
||||
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4
|
||||
golang.org/x/image v0.0.0-20220413100746-70e8d0d3baa9
|
||||
golang.org/x/net v0.0.0-20220412020605-290c469a71a5
|
||||
)
|
||||
|
||||
require (
|
||||
cloud.google.com/go/compute v1.5.0 // indirect
|
||||
cloud.google.com/go/compute v1.6.0 // indirect
|
||||
github.com/andybalholm/cascadia v1.3.1 // indirect
|
||||
github.com/aymerick/douceur v0.2.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
@@ -61,16 +61,17 @@ require (
|
||||
github.com/nullrocks/identicon v0.0.0-20180626043057-7875f45b0022 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/stretchr/objx v0.3.0 // indirect
|
||||
github.com/valyala/fasthttp v1.35.0 // indirect
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
|
||||
github.com/xdg-go/scram v1.1.1 // indirect
|
||||
github.com/xdg-go/stringprep v1.0.3 // indirect
|
||||
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect
|
||||
go.mongodb.org/mongo-driver v1.8.4 // indirect
|
||||
golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a // indirect
|
||||
go.mongodb.org/mongo-driver v1.9.0 // indirect
|
||||
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 // indirect
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
|
||||
golang.org/x/sys v0.0.0-20220405052023-b1e9470b6e64 // indirect
|
||||
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 // indirect
|
||||
golang.org/x/time v0.0.0-20220411224347-583f2d630306 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/protobuf v1.28.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
||||
|
||||
+40
-18
@@ -37,8 +37,9 @@ cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM7
|
||||
cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow=
|
||||
cloud.google.com/go/compute v1.2.0/go.mod h1:xlogom/6gr8RJGBe7nT2eGsQYAFUbbv8dbC29qE3Xmw=
|
||||
cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM=
|
||||
cloud.google.com/go/compute v1.5.0 h1:b1zWmYuuHz7gO9kDcM/EpHGr06UgsYNRpNJzI2kFiLM=
|
||||
cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M=
|
||||
cloud.google.com/go/compute v1.6.0 h1:XdQIN5mdPTSBVwSIVDuY5e8ZzVAccsHvD3qTEz4zIps=
|
||||
cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s=
|
||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
||||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||
@@ -72,8 +73,9 @@ github.com/alicebob/gopher-json v0.0.0-20180125190556-5a6b3ba71ee6 h1:45bxf7AZMw
|
||||
github.com/alicebob/gopher-json v0.0.0-20180125190556-5a6b3ba71ee6/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc=
|
||||
github.com/alicebob/miniredis/v2 v2.11.4 h1:GsuyeunTx7EllZBU3/6Ji3dhMQZDpC9rLf1luJ+6M5M=
|
||||
github.com/alicebob/miniredis/v2 v2.11.4/go.mod h1:VL3UDEfAH59bSa7MuHMuFToxkqyHh69s/WUbYlOAuyg=
|
||||
github.com/andybalholm/brotli v1.0.0 h1:7UCwP93aiSfvWpapti8g88vVVGp2qqtGyePsSuDafo4=
|
||||
github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
|
||||
github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY=
|
||||
github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||
github.com/andybalholm/cascadia v1.3.1 h1:nhxRkql1kdYCc8Snf7D5/D3spOX+dBgjA6u8x004T2c=
|
||||
github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA=
|
||||
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
|
||||
@@ -154,8 +156,8 @@ github.com/go-pkgz/repeater v1.1.3 h1:q6+JQF14ESSy28Dd7F+wRelY4F+41HJ0LEy/szNnMi
|
||||
github.com/go-pkgz/repeater v1.1.3/go.mod h1:hVTavuO5x3Gxnu8zW7d6sQBfAneKV8X2FjU48kGfpKw=
|
||||
github.com/go-pkgz/rest v1.5.0/go.mod h1:nQaM3RhSTUAmbBZWY4hfe4buyeC9VckvhoCktiQXJxI=
|
||||
github.com/go-pkgz/rest v1.12.2/go.mod h1:KUWAqbDteYGS/CiXftomQsKjtEOifXsJ36Ka0skYbmk=
|
||||
github.com/go-pkgz/rest v1.13.0 h1:1larroBzcOYC5ySdrCLaXIEG1SGNnPborxm6uK+2RLQ=
|
||||
github.com/go-pkgz/rest v1.13.0/go.mod h1:KUWAqbDteYGS/CiXftomQsKjtEOifXsJ36Ka0skYbmk=
|
||||
github.com/go-pkgz/rest v1.14.0 h1:brDLCzIGoe0IiUZqRFpsiCVM9m3L88A7z62qS0V9Yfk=
|
||||
github.com/go-pkgz/rest v1.14.0/go.mod h1:KUWAqbDteYGS/CiXftomQsKjtEOifXsJ36Ka0skYbmk=
|
||||
github.com/go-pkgz/syncs v1.2.0 h1:aiizQFILlMZ4KtRNaYLcDffRbUQZH9fclsgr5KybWyY=
|
||||
github.com/go-pkgz/syncs v1.2.0/go.mod h1:fjThZdM2FkC/oSeiqBTOZOtHpbrCh4HuHbipB5qZJJM=
|
||||
github.com/go-redis/redis/v7 v7.4.0/go.mod h1:JDNMw23GTyLNC4GZu9njt15ctBQVn7xjRfnwdHj/Dcg=
|
||||
@@ -251,6 +253,8 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0=
|
||||
github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM=
|
||||
github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM=
|
||||
github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY=
|
||||
github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c=
|
||||
@@ -286,6 +290,7 @@ github.com/klauspost/compress v1.10.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYs
|
||||
github.com/klauspost/compress v1.10.10/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/klauspost/compress v1.14.2/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/klauspost/compress v1.15.1 h1:y9FcTHGyrebwfP0ZZqFiaxTaiDnUrGkJkI+f583BL1A=
|
||||
github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
@@ -375,9 +380,11 @@ github.com/tidwall/tinyqueue v0.0.0-20180302190814-1e39f5511563 h1:Otn9S136ELckZ
|
||||
github.com/tidwall/tinyqueue v0.0.0-20180302190814-1e39f5511563/go.mod h1:mLqSmt7Dv/CNneF2wfcChfN1rvapyQr01LGKnKex0DQ=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasthttp v1.14.0 h1:67bfuW9azCMwW/Jlq/C+VeihNpAuJMWkYPBig1gdi3A=
|
||||
github.com/valyala/fasthttp v1.14.0/go.mod h1:ol1PCaL0dX20wC0htZ7sYCsvCYmrouYra0zHzaclZhE=
|
||||
github.com/valyala/fasthttp v1.35.0 h1:wwkR8mZn2NbigFsaw2Zj5r+xkmzjbrA/lyTmiSlal/Y=
|
||||
github.com/valyala/fasthttp v1.35.0/go.mod h1:t/G+3rLek+CyY9bnIE+YlMRddxVAAGjhxndDB4i4C0I=
|
||||
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
|
||||
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
||||
github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs=
|
||||
@@ -413,8 +420,8 @@ github.com/yuin/gopher-lua v0.0.0-20191220021717-ab39c6098bdb/go.mod h1:gqRgreBU
|
||||
go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU=
|
||||
go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4=
|
||||
go.mongodb.org/mongo-driver v1.8.3/go.mod h1:0sQWfOeY63QTntERDJJ/0SuKK0T1uVSgKCuAROlKEPY=
|
||||
go.mongodb.org/mongo-driver v1.8.4 h1:NruvZPPL0PBcRJKmbswoWSrmHeUvzdxA3GCPfD/NEOA=
|
||||
go.mongodb.org/mongo-driver v1.8.4/go.mod h1:0sQWfOeY63QTntERDJJ/0SuKK0T1uVSgKCuAROlKEPY=
|
||||
go.mongodb.org/mongo-driver v1.9.0 h1:WISF656tVHlYe/kd+istlX++s+UbjL5X8f8qKCwl/Ms=
|
||||
go.mongodb.org/mongo-driver v1.9.0/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=
|
||||
@@ -433,8 +440,9 @@ golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPh
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20220208050332-20e1d8d225ab/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29 h1:tkVvjkPTB7pnW3jnid7kNyAMPVWllTNOf/qKDze4p9o=
|
||||
golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 h1:kUhD7nTDoI3fVd9G4ORWrbV5NY0liEs/Jg2pv5f+bBA=
|
||||
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
@@ -448,8 +456,8 @@ golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMk
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
|
||||
golang.org/x/image v0.0.0-20220321031419-a8550c1d254a h1:LnH9RNcpPv5Kzi15lXg42lYMPUf0x8CuPv1YnvBWZAg=
|
||||
golang.org/x/image v0.0.0-20220321031419-a8550c1d254a/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
|
||||
golang.org/x/image v0.0.0-20220413100746-70e8d0d3baa9 h1:LRtI4W37N+KFebI/qV0OFiLUv4GLOWeEW5hn/KEJvxE=
|
||||
golang.org/x/image v0.0.0-20220413100746-70e8d0d3baa9/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
@@ -516,8 +524,10 @@ golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qx
|
||||
golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220403103023-749bd193bc2b h1:vI32FkLJNAWtGD4BwkThwEy6XS7ZLLMHkSkYfF8M0W0=
|
||||
golang.org/x/net v0.0.0-20220403103023-749bd193bc2b/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220412020605-290c469a71a5 h1:bRb386wvrE+oBNdF1d/Xh9mQrfQ4ecYhW5qJ5GvTGT4=
|
||||
golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
@@ -534,8 +544,10 @@ golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ
|
||||
golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a h1:qfl7ob3DIEs3Ml9oLuPwY2N04gymzAW04WsUQHIClgM=
|
||||
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
|
||||
golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
|
||||
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 h1:OSnWWcOd/CtWQC2cYSBgbTSJv3ciqd8r54ySIW2y3RE=
|
||||
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@@ -613,8 +625,10 @@ golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220207234003-57398862261d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220405052023-b1e9470b6e64 h1:D1v9ucDTYBtbz5vNuBbAhIMAGhQhJ6Ym5ah3maMVNX4=
|
||||
golang.org/x/sys v0.0.0-20220405052023-b1e9470b6e64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad h1:ntjMns5wyP/fN65tdBD4g8J5w8n015+iIIs9rtjXkY0=
|
||||
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
@@ -632,8 +646,8 @@ golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxb
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 h1:M73Iuj3xbbb9Uk1DYhzydthsj6oOd6l9bpuFcNoUvTs=
|
||||
golang.org/x/time v0.0.0-20220224211638-0e9765cccd65/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20220411224347-583f2d630306 h1:+gHMid33q6pen7kv9xvT+JRinntgeXO2AeZVd0AWD3w=
|
||||
golang.org/x/time v0.0.0-20220411224347-583f2d630306/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
@@ -727,6 +741,8 @@ google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tD
|
||||
google.golang.org/api v0.66.0/go.mod h1:I1dmXYpX7HGwz/ejRxwQp2qj5bFAz93HiCU1C1oYd9M=
|
||||
google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g=
|
||||
google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA=
|
||||
google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8=
|
||||
google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
@@ -801,6 +817,11 @@ google.golang.org/genproto v0.0.0-20220201184016-50beb8ab5c44/go.mod h1:5CzLGKJ6
|
||||
google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
|
||||
google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
|
||||
google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
|
||||
google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
|
||||
google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E=
|
||||
google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
|
||||
google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
@@ -828,6 +849,7 @@ google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnD
|
||||
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
|
||||
google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
|
||||
google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
|
||||
google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
|
||||
+8
-11
@@ -93,37 +93,32 @@ Adds the HTTP Deprecation response header, see [draft-dalal-deprecation-header-0
|
||||
BasicAuth middleware requires basic auth and matches user & passwd with client-provided checker. In case if no basic auth headers returns
|
||||
`StatusUnauthorized`, in case if checker failed - `StatusForbidden`
|
||||
|
||||
## Rewrite middleware
|
||||
### Rewrite middleware
|
||||
|
||||
Rewrites requests with from->to rule. Supports regex (like nginx) and prevents multiple rewrites. For example `Rewrite("^/sites/(.*)/settings/$", "/sites/settings/$1")` will change request's URL from `/sites/id1/settings/` to `/sites/settings/id1`
|
||||
|
||||
## NoCache middleware
|
||||
### NoCache middleware
|
||||
|
||||
Sets a number of HTTP headers to prevent a router (handler's) response from being cached by an upstream proxy and/or client.
|
||||
|
||||
## Headers middleware
|
||||
### Headers middleware
|
||||
|
||||
Sets headers (passed as key:value) to requests. I.e. `rest.Headers("Server:MyServer", "X-Blah:Foo")`
|
||||
|
||||
## Gzip middleware
|
||||
### Gzip middleware
|
||||
|
||||
Compresses response with gzip.
|
||||
|
||||
## RealIP middleware
|
||||
### RealIP middleware
|
||||
|
||||
RealIP is a middleware that sets a http.Request's RemoteAddr to the results of parsing either the X-Forwarded-For or X-Real-IP headers.
|
||||
|
||||
## Maybe middleware
|
||||
### Maybe middleware
|
||||
|
||||
Maybe middleware will allow you to change the flow of the middleware stack execution depending on return
|
||||
value of maybeFn(request). This is useful for example if you'd like to skip a middleware handler if
|
||||
a request does not satisfy the maybeFn logic.
|
||||
|
||||
## Headers middleware
|
||||
|
||||
Headers middleware adds headers to request
|
||||
|
||||
|
||||
## Helpers
|
||||
|
||||
- `rest.Wrap` - converts a list of middlewares to nested handlers calls (in reverse order)
|
||||
@@ -134,6 +129,8 @@ Headers middleware adds headers to request
|
||||
- `rest.SendErrorJSON` - makes `{error: blah, details: blah}` json body and responds with given error code. Also, adds context to the logged message
|
||||
- `rest.NewErrorLogger` - creates a struct providing shorter form of logger call
|
||||
- `rest.FileServer` - creates a file server for static assets with directory listing disabled
|
||||
- `realip.Get` - returns client's IP address
|
||||
- `rest.ParseFromTo` - parses "from" and "to" request's query params with various formats
|
||||
|
||||
## Profiler
|
||||
|
||||
|
||||
+15
@@ -296,6 +296,21 @@ func (l *Middleware) sanitizeQuery(rawQuery string) string {
|
||||
return query.Encode()
|
||||
}
|
||||
|
||||
// AnonymizeIP is a function to reset the last part of IPv4 to 0.
|
||||
// from 123.212.12.78 it will make 123.212.12.0
|
||||
func AnonymizeIP(ip string) string {
|
||||
if ip == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
parts := strings.Split(ip, ".")
|
||||
if len(parts) != 4 {
|
||||
return ip
|
||||
}
|
||||
|
||||
return strings.Join(parts[:3], ".") + ".0"
|
||||
}
|
||||
|
||||
// customResponseWriter is an HTTP response logger that keeps HTTP status code and
|
||||
// the number of bytes written.
|
||||
// It implements http.ResponseWriter, http.Flusher and http.Hijacker.
|
||||
|
||||
+31
@@ -5,6 +5,7 @@ import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
@@ -67,3 +68,33 @@ func renderJSONWithStatus(w http.ResponseWriter, data interface{}, code int) {
|
||||
w.WriteHeader(code)
|
||||
_, _ = w.Write(buf.Bytes())
|
||||
}
|
||||
|
||||
// ParseFromTo parses from and to query params of the request
|
||||
func ParseFromTo(r *http.Request) (from, to time.Time, err error) {
|
||||
parseTimeStamp := func(ts string) (time.Time, error) {
|
||||
formats := []string{
|
||||
"2006-01-02T15:04:05.000000000",
|
||||
"2006-01-02T15:04:05",
|
||||
"2006-01-02T15:04",
|
||||
"20060102",
|
||||
time.RFC3339,
|
||||
time.RFC3339Nano,
|
||||
}
|
||||
|
||||
for _, f := range formats {
|
||||
if t, e := time.Parse(f, ts); e == nil {
|
||||
return t, nil
|
||||
}
|
||||
}
|
||||
return time.Time{}, errors.Errorf("can't parse date %q", ts)
|
||||
}
|
||||
|
||||
if from, err = parseTimeStamp(r.URL.Query().Get("from")); err != nil {
|
||||
return from, to, errors.Wrap(err, "incorrect from time")
|
||||
}
|
||||
|
||||
if to, err = parseTimeStamp(r.URL.Query().Get("to")); err != nil {
|
||||
return from, to, errors.Wrap(err, "incorrect to time")
|
||||
}
|
||||
return from, to, nil
|
||||
}
|
||||
|
||||
+1
-1
@@ -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 {
|
||||
|
||||
Generated
Vendored
+13
-1
@@ -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() {
|
||||
|
||||
+2
-2
@@ -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.
|
||||
|
||||
+1
-1
@@ -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()
|
||||
|
||||
+9
-1
@@ -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
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -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()
|
||||
|
||||
+1
-1
@@ -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.
|
||||
//
|
||||
|
||||
+3
@@ -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 {
|
||||
|
||||
+1
-1
@@ -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()
|
||||
|
||||
+1
-1
@@ -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 {
|
||||
|
||||
+6
-3
@@ -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
|
||||
|
||||
+23
@@ -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)
|
||||
}
|
||||
|
||||
+1
-1
@@ -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 {
|
||||
|
||||
+15
@@ -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 {
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
+54
-17
@@ -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)
|
||||
|
||||
+1
-1
@@ -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) {
|
||||
|
||||
+78
-15
@@ -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
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
+42
@@ -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() }
|
||||
|
||||
|
||||
+12
@@ -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))
|
||||
|
||||
|
||||
+1
-1
@@ -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
|
||||
}
|
||||
|
||||
+38
@@ -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)
|
||||
|
||||
+2
-2
@@ -196,7 +196,7 @@ func (b *Bucket) OpenDownloadStream(fileID interface{}) (*DownloadStream, error)
|
||||
}
|
||||
|
||||
// DownloadToStream downloads the file with the specified fileID and writes it to the provided io.Writer.
|
||||
// Returns the number of bytes written to the steam and an error, or nil if there was no error.
|
||||
// Returns the number of bytes written to the stream and an error, or nil if there was no error.
|
||||
//
|
||||
// If this download requires a custom read deadline to be set on the bucket, it cannot be done concurrently with other
|
||||
// read operations operations on this bucket that also require a custom deadline.
|
||||
@@ -554,7 +554,7 @@ func (b *Bucket) createIndexes(ctx context.Context) error {
|
||||
|
||||
_, err = docRes.DecodeBytes()
|
||||
if err != mongo.ErrNoDocuments {
|
||||
// nil, or error that occured during the FindOne operation
|
||||
// nil, or error that occurred during the FindOne operation
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+22
-1
@@ -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
|
||||
|
||||
+18
@@ -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
|
||||
|
||||
+34
@@ -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
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+15
@@ -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
|
||||
|
||||
+60
@@ -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
|
||||
|
||||
+3
@@ -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
|
||||
}
|
||||
|
||||
Generated
Vendored
+14
@@ -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
|
||||
|
||||
+1
-1
@@ -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 {
|
||||
|
||||
+1
-1
@@ -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"
|
||||
|
||||
+15
@@ -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
|
||||
|
||||
+15
@@ -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
|
||||
|
||||
+3
@@ -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
|
||||
|
||||
+5
-2
@@ -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": <BSON binary value>}.
|
||||
//
|
||||
// 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
|
||||
|
||||
+26
@@ -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
|
||||
|
||||
+1
-1
@@ -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.4"
|
||||
var Driver = "v1.9.0"
|
||||
|
||||
Generated
Vendored
+1
-1
@@ -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)
|
||||
|
||||
+3
-3
@@ -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)
|
||||
|
||||
+51
-51
@@ -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
|
||||
|
||||
+1
-1
@@ -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()
|
||||
|
||||
+3
-3
@@ -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) {
|
||||
|
||||
+3
-2
@@ -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
|
||||
|
||||
|
||||
Generated
Vendored
+2
-1
@@ -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
|
||||
|
||||
|
||||
Generated
Vendored
+2
-1
@@ -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
|
||||
|
||||
|
||||
Generated
Vendored
+1
-1
@@ -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) {
|
||||
|
||||
Generated
Vendored
+3
-2
@@ -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
|
||||
|
||||
|
||||
Generated
Vendored
+2
-1
@@ -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
|
||||
|
||||
|
||||
+15
@@ -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
|
||||
|
||||
Generated
Vendored
+1
-1
@@ -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.
|
||||
|
||||
+4
-4
@@ -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
|
||||
|
||||
+1
-1
@@ -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)
|
||||
|
||||
+5
@@ -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
|
||||
|
||||
+8
@@ -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
|
||||
}
|
||||
|
||||
|
||||
+1
@@ -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
|
||||
|
||||
+1
@@ -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
|
||||
|
||||
Generated
Vendored
+1
@@ -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
|
||||
|
||||
Generated
Vendored
+1
@@ -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
|
||||
|
||||
Generated
Vendored
+1
@@ -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
|
||||
|
||||
Generated
Vendored
+1
@@ -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
|
||||
|
||||
Generated
Vendored
+1
@@ -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
|
||||
|
||||
Generated
Vendored
+1
@@ -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
|
||||
|
||||
Generated
Vendored
+1
@@ -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
|
||||
|
||||
+1
-1
@@ -261,7 +261,7 @@ func contactResponders(ctx context.Context, cfg config) (*ResponseDetails, error
|
||||
//
|
||||
// 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.
|
||||
// one to respond.
|
||||
httpResponse, err := http.DefaultClient.Do(request)
|
||||
if err != nil {
|
||||
urlErr, ok := err.(*url.Error)
|
||||
|
||||
+126
-71
@@ -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)
|
||||
|
||||
Generated
Vendored
+1
-1
@@ -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")
|
||||
|
||||
+18
-2
@@ -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
|
||||
}
|
||||
|
||||
+1
-1
@@ -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")
|
||||
|
||||
Generated
Vendored
+1
-1
@@ -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")
|
||||
|
||||
+5
-4
@@ -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")
|
||||
|
||||
+14
-13
@@ -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)
|
||||
|
||||
Generated
Vendored
+8
-7
@@ -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)
|
||||
|
||||
+18
-3
@@ -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
|
||||
}
|
||||
|
||||
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
|
||||
@@ -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
|
||||
}
|
||||
|
||||
+4
-3
@@ -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")
|
||||
|
||||
Generated
Vendored
+4
-3
@@ -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")
|
||||
|
||||
Generated
Vendored
+1
-1
@@ -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")
|
||||
|
||||
Generated
Vendored
+4
-3
@@ -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")
|
||||
|
||||
Generated
Vendored
+2
-2
@@ -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)
|
||||
|
||||
+16
-2
@@ -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)
|
||||
|
||||
Generated
Vendored
+19
-3
@@ -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
|
||||
}
|
||||
|
||||
+3
-1
@@ -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)
|
||||
|
||||
+4
-3
@@ -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
|
||||
}
|
||||
|
||||
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
|
||||
@@ -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")
|
||||
|
||||
Generated
Vendored
+4
-3
@@ -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")
|
||||
|
||||
Generated
Vendored
+31
-16
@@ -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 {
|
||||
|
||||
Generated
Vendored
+1
-1
@@ -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")
|
||||
|
||||
+17
-3
@@ -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.
|
||||
@@ -57,7 +58,7 @@ type UpdateResult struct {
|
||||
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
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Generated
Vendored
+2
-2
@@ -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
|
||||
}
|
||||
|
||||
+56
-65
@@ -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
|
||||
}
|
||||
|
||||
Generated
Vendored
+22
-46
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -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)
|
||||
}
|
||||
|
||||
+7
-9
@@ -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) {
|
||||
|
||||
Generated
Vendored
+37
@@ -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()
|
||||
}
|
||||
Generated
Vendored
+44
@@ -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)
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user