Skip to content

Commit 3dc4a46

Browse files
author
iwysiu
committed
GODRIVER-1469 ensure gridfs index checking supports indexes created in the shell
1 parent 6f5e216 commit 3dc4a46

File tree

2 files changed

+122
-9
lines changed

2 files changed

+122
-9
lines changed

mongo/gridfs/bucket.go

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,8 @@ package gridfs // import "go.mongodb.org/mongo-driver/mongo/gridfs"
99
import (
1010
"bytes"
1111
"context"
12-
13-
"io"
14-
1512
"errors"
16-
13+
"io"
1714
"time"
1815

1916
"go.mongodb.org/mongo-driver/bson"
@@ -472,16 +469,59 @@ func createIndexIfNotExists(ctx context.Context, iv mongo.IndexView, model mongo
472469
return err
473470
}
474471

475-
keyElemDoc := keyElem.Document()
476-
modelKeysDoc, err := bson.Marshal(model.Keys)
472+
keyElemDoc := bsoncore.Value{Type: keyElem.Type, Data: keyElem.Value}.Document()
473+
474+
modelKeysBytes, err := bson.Marshal(model.Keys)
477475
if err != nil {
478476
return err
479477
}
478+
modelKeysDoc := bsoncore.Document(modelKeysBytes)
480479

481480
if bytes.Equal(modelKeysDoc, keyElemDoc) {
482481
found = true
483482
break
484483
}
484+
485+
keyElemElems, err := keyElemDoc.Elements()
486+
if err != nil {
487+
return err
488+
}
489+
modelKeysElems, err := modelKeysDoc.Elements()
490+
if err != nil {
491+
return err
492+
}
493+
494+
if len(keyElemElems) != len(modelKeysElems) {
495+
continue
496+
}
497+
498+
docsEqual := true
499+
for _, elem := range keyElemElems {
500+
key := elem.Key()
501+
modelVal, err := modelKeysDoc.LookupErr(key)
502+
if err != nil {
503+
docsEqual = false
504+
break
505+
}
506+
507+
val := elem.Value()
508+
if !val.IsNumber() || !modelVal.IsNumber() {
509+
if val.Equal(modelVal) {
510+
continue
511+
}
512+
docsEqual = false
513+
break
514+
}
515+
516+
if val.AsInt64() != modelVal.AsInt64() {
517+
docsEqual = false
518+
break
519+
}
520+
}
521+
if docsEqual {
522+
found = true
523+
break
524+
}
485525
}
486526

487527
if !found {

mongo/integration/gridfs_test.go

Lines changed: 76 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,14 @@ import (
1414
"testing"
1515
"time"
1616

17+
"go.mongodb.org/mongo-driver/bson"
18+
"go.mongodb.org/mongo-driver/event"
1719
"go.mongodb.org/mongo-driver/internal/testutil/assert"
1820
"go.mongodb.org/mongo-driver/internal/testutil/israce"
1921
"go.mongodb.org/mongo-driver/mongo"
2022
"go.mongodb.org/mongo-driver/mongo/gridfs"
2123
"go.mongodb.org/mongo-driver/mongo/integration/mtest"
2224
"go.mongodb.org/mongo-driver/mongo/options"
23-
"go.mongodb.org/mongo-driver/x/bsonx"
2425
)
2526

2627
func TestGridFS(x *testing.T) {
@@ -45,6 +46,66 @@ func TestGridFS(x *testing.T) {
4546
findIndex(findCtx, mt, mt.DB.Collection("fs.files"), false, "key", "filename")
4647
findIndex(findCtx, mt, mt.DB.Collection("fs.chunks"), true, "key", "files_id")
4748
})
49+
// should not create a new index if index is numerically the same
50+
mt.Run("numericallyEqualIndexes", func(mt *mtest.T) {
51+
//add indexes with floats to collections manually
52+
res := mt.DB.RunCommand(context.Background(),
53+
bson.D{
54+
{"createIndexes", "fs.files"},
55+
{"indexes", bson.A{
56+
bson.D{
57+
{"key", bson.D{{"filename", float64(1.0)}, {"uploadDate", float64(1.0)}}},
58+
{"name", "filename_1_uploadDate_1"},
59+
},
60+
}},
61+
},
62+
)
63+
assert.Nil(mt, res.Err(), "createIndexes error: %v", res.Err())
64+
65+
res = mt.DB.RunCommand(context.Background(),
66+
bson.D{
67+
{"createIndexes", "fs.chunks"},
68+
{"indexes", bson.A{
69+
bson.D{
70+
{"key", bson.D{{"files_id", float64(1.0)}, {"n", float64(1.0)}}},
71+
{"name", "files_id_1_n_1"},
72+
{"unique", true},
73+
},
74+
}},
75+
},
76+
)
77+
assert.Nil(mt, res.Err(), "createIndexes error: %v", res.Err())
78+
79+
mt.ClearEvents()
80+
mt.Run("OpenUploadStream", func(mt *mtest.T) {
81+
bucket, err := gridfs.NewBucket(mt.DB)
82+
assert.Nil(mt, err, "NewBucket error: %v", err)
83+
84+
_, err = bucket.OpenUploadStream("filename")
85+
assert.Nil(mt, err, "OpenUploadStream error: %v", err)
86+
87+
mt.FilterStartedEvents(func(evt *event.CommandStartedEvent) bool {
88+
return evt.CommandName == "createIndexes"
89+
})
90+
evt := mt.GetStartedEvent()
91+
assert.Nil(mt, evt, "Expected that createIndexes wasn't called: %v", evt)
92+
})
93+
mt.Run("UploadFromStream", func(mt *mtest.T) {
94+
var fileContent []byte
95+
bucket, err := gridfs.NewBucket(mt.DB)
96+
assert.Nil(mt, err, "NewBucket error: %v", err)
97+
98+
_, err = bucket.UploadFromStream("filename", bytes.NewBuffer(fileContent))
99+
assert.Nil(mt, err, "UploadFromStream error: %v", err)
100+
101+
mt.FilterStartedEvents(func(evt *event.CommandStartedEvent) bool {
102+
return evt.CommandName == "createIndexes"
103+
})
104+
evt := mt.GetStartedEvent()
105+
assert.Nil(mt, evt, "Expected that createIndexes wasn't called: %v", evt)
106+
})
107+
})
108+
48109
mt.RunOpts("round trip", mtest.NewOptions().MaxServerVersion("3.6"), func(mt *mtest.T) {
49110
skipRoundTripTest(mt)
50111
oneK := 1024
@@ -130,15 +191,27 @@ func findIndex(ctx context.Context, mt *mtest.T, coll *mongo.Collection, unique
130191
assert.True(mt, foundIndex, "index %v not found", keys)
131192
}
132193

194+
func countIndexes(ctx context.Context, mt *mtest.T, coll *mongo.Collection) int {
195+
mt.Helper()
196+
cur, err := coll.Indexes().List(ctx)
197+
assert.Nil(mt, err, "Indexes List error: %v", err)
198+
199+
var count int
200+
for cur.Next(ctx) {
201+
count++
202+
}
203+
return count
204+
}
205+
133206
func skipRoundTripTest(mt *mtest.T) {
134207
if runtime.GOOS != "darwin" {
135208
return
136209
}
137210

138-
var serverStatus bsonx.Doc
211+
var serverStatus bson.Raw
139212
err := mt.DB.RunCommand(
140213
context.Background(),
141-
bsonx.Doc{{"serverStatus", bsonx.Int32(1)}},
214+
bson.D{{"serverStatus", 1}},
142215
).Decode(&serverStatus)
143216
assert.Nil(mt, err, "serverStatus error %v", err)
144217

0 commit comments

Comments
 (0)